Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
yotta
/
pictogram
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
60
Merge Requests
0
Pipelines
Wiki
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
4829118e
authored
Feb 02, 2017
by
Sebastián Collado Montañez
Browse files
Options
_('Browse Files')
Download
Plain Diff
Merge branch 'develop' of
http://scm.ujaen.es/softuno/pictogram
into develop
parents
ed935499
5dca384a
Show whitespace changes
Inline
Side-by-side
Showing
32 changed files
with
2342 additions
and
86 deletions
android/Pictogram/commonlibrary/src/main/java/com/yottacode/pictogram/tools/PCBcontext.java
android/Pictogram/supervisor_tablet/build.gradle
android/Pictogram/supervisor_tablet/supervisor_tablet.iml
android/Pictogram/tabletlibrary/src/main/java/com/yottacode/pictogram/tabletlibrary/cropper/CropImageView.java
android/Pictogram/tabletlibrary/src/main/java/com/yottacode/pictogram/tabletlibrary/cropper/MainCropImage.java
android/Pictogram/tabletlibrary/src/main/java/com/yottacode/pictogram/tabletlibrary/cropper/cropwindow/edge/Edge.java
android/Pictogram/tabletlibrary/src/main/java/com/yottacode/pictogram/tabletlibrary/cropper/cropwindow/edge/EdgePair.java
android/Pictogram/tabletlibrary/src/main/java/com/yottacode/pictogram/tabletlibrary/cropper/cropwindow/handle/CenterHandleHelper.java
android/Pictogram/tabletlibrary/src/main/java/com/yottacode/pictogram/tabletlibrary/cropper/cropwindow/handle/CornerHandleHelper.java
android/Pictogram/tabletlibrary/src/main/java/com/yottacode/pictogram/tabletlibrary/cropper/cropwindow/handle/Handle.java
android/Pictogram/tabletlibrary/src/main/java/com/yottacode/pictogram/tabletlibrary/cropper/cropwindow/handle/HandleHelper.java
android/Pictogram/tabletlibrary/src/main/java/com/yottacode/pictogram/tabletlibrary/cropper/cropwindow/handle/HorizontalHandleHelper.java
android/Pictogram/tabletlibrary/src/main/java/com/yottacode/pictogram/tabletlibrary/cropper/cropwindow/handle/VerticalHandleHelper.java
android/Pictogram/tabletlibrary/src/main/java/com/yottacode/pictogram/tabletlibrary/cropper/util/AspectRatioUtil.java
android/Pictogram/tabletlibrary/src/main/java/com/yottacode/pictogram/tabletlibrary/cropper/util/HandleUtil.java
android/Pictogram/tabletlibrary/src/main/java/com/yottacode/pictogram/tabletlibrary/cropper/util/MathUtil.java
android/Pictogram/tabletlibrary/src/main/java/com/yottacode/pictogram/tabletlibrary/cropper/util/PaintUtil.java
android/Pictogram/tabletlibrary/src/main/java/com/yottacode/pictogram/tabletlibrary/gui/communicator/PictoMenu.java
android/Pictogram/tabletlibrary/src/main/res/layout/crop_layout.xml
android/Pictogram/tabletlibrary/src/main/res/values/attrs.xml
android/Pictogram/tabletlibrary/src/main/res/values/colors.xml
android/Pictogram/tabletlibrary/src/main/res/values/dimen.xml
android/Pictogram/tabletlibrary/src/main/res/values/strings.xml
android/Pictogram/tabletlibrary/tabletlibrary.iml
android/Pictogram/watch/build.gradle
android/Pictogram/watch/watch.iml
android/Pictogram/yotta_tablet/yotta_tablet.iml
sails/src/api/models/Student.js
sails/src/assets/app/i18n/en-gb.json
sails/src/assets/app/i18n/es-es.json
sails/src/assets/scripts/app.js
sails/src/assets/scripts/modules/student/views/setup.html
android/Pictogram/commonlibrary/src/main/java/com/yottacode/pictogram/tools/PCBcontext.java
View file @
4829118e
...
@@ -64,7 +64,7 @@ public final class PCBcontext {
...
@@ -64,7 +64,7 @@ public final class PCBcontext {
Log
.
i
(
PCBcontext
.
class
.
getCanonicalName
(),
"User set at student "
+
student
.
get_name_stu
());
Log
.
i
(
PCBcontext
.
class
.
getCanonicalName
(),
"User set at student "
+
student
.
get_name_stu
());
wrapper
.
setToken
(
token
);
wrapper
.
setToken
(
token
);
pcbdb
=
new
PCBDBHelper
(
null
,
1
,
student
);
pcbdb
=
new
PCBDBHelper
(
null
,
2
,
student
);
pcbdb
.
user_online
(
token
!=
null
);
pcbdb
.
user_online
(
token
!=
null
);
room
=
new
Room
();
room
=
new
Room
();
actionLog
=
new
ActionLog
();
actionLog
=
new
ActionLog
();
...
...
android/Pictogram/supervisor_tablet/build.gradle
View file @
4829118e
...
@@ -34,6 +34,9 @@ android {
...
@@ -34,6 +34,9 @@ android {
resValue
"string"
,
"server"
,
"https://pre.yottacode.com"
resValue
"string"
,
"server"
,
"https://pre.yottacode.com"
resValue
"bool"
,
"ssl_connect"
,
"true"
resValue
"bool"
,
"ssl_connect"
,
"true"
}
}
LocalFlavor
{
resValue
"string"
,
"server"
,
"http://192.168.1.35:1337"
resValue
"bool"
,
"ssl_connect"
,
"false"
}
}
}
}
}
...
...
android/Pictogram/supervisor_tablet/supervisor_tablet.iml
View file @
4829118e
...
@@ -41,13 +41,6 @@
...
@@ -41,13 +41,6 @@
<sourceFolder
url=
"file://$MODULE_DIR$/src/DevFlavorDebug/java"
isTestSource=
"false"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/DevFlavorDebug/java"
isTestSource=
"false"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/DevFlavorDebug/rs"
isTestSource=
"false"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/DevFlavorDebug/rs"
isTestSource=
"false"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/DevFlavorDebug/shaders"
isTestSource=
"false"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/DevFlavorDebug/shaders"
isTestSource=
"false"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/build/generated/source/r/androidTest/DevFlavor/debug"
isTestSource=
"true"
generated=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/build/generated/source/aidl/androidTest/DevFlavor/debug"
isTestSource=
"true"
generated=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/DevFlavor/debug"
isTestSource=
"true"
generated=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/build/generated/source/rs/androidTest/DevFlavor/debug"
isTestSource=
"true"
generated=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/build/generated/source/apt/androidTest/DevFlavor/debug"
isTestSource=
"true"
generated=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/build/generated/res/rs/androidTest/DevFlavor/debug"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/build/generated/res/resValues/androidTest/DevFlavor/debug"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/testDevFlavorDebug/res"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/testDevFlavorDebug/res"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/testDevFlavorDebug/resources"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/testDevFlavorDebug/resources"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/testDevFlavorDebug/assets"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/testDevFlavorDebug/assets"
type=
"java-test-resource"
/>
...
@@ -55,6 +48,13 @@
...
@@ -55,6 +48,13 @@
<sourceFolder
url=
"file://$MODULE_DIR$/src/testDevFlavorDebug/java"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/testDevFlavorDebug/java"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/testDevFlavorDebug/rs"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/testDevFlavorDebug/rs"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/testDevFlavorDebug/shaders"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/testDevFlavorDebug/shaders"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/build/generated/source/r/androidTest/DevFlavor/debug"
isTestSource=
"true"
generated=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/build/generated/source/aidl/androidTest/DevFlavor/debug"
isTestSource=
"true"
generated=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/DevFlavor/debug"
isTestSource=
"true"
generated=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/build/generated/source/rs/androidTest/DevFlavor/debug"
isTestSource=
"true"
generated=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/build/generated/source/apt/androidTest/DevFlavor/debug"
isTestSource=
"true"
generated=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/build/generated/res/rs/androidTest/DevFlavor/debug"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/build/generated/res/resValues/androidTest/DevFlavor/debug"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/DevFlavor/res"
type=
"java-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/DevFlavor/res"
type=
"java-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/DevFlavor/resources"
type=
"java-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/DevFlavor/resources"
type=
"java-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/DevFlavor/assets"
type=
"java-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/DevFlavor/assets"
type=
"java-resource"
/>
...
@@ -62,13 +62,6 @@
...
@@ -62,13 +62,6 @@
<sourceFolder
url=
"file://$MODULE_DIR$/src/DevFlavor/java"
isTestSource=
"false"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/DevFlavor/java"
isTestSource=
"false"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/DevFlavor/rs"
isTestSource=
"false"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/DevFlavor/rs"
isTestSource=
"false"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/DevFlavor/shaders"
isTestSource=
"false"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/DevFlavor/shaders"
isTestSource=
"false"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTestDevFlavor/res"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTestDevFlavor/resources"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTestDevFlavor/assets"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTestDevFlavor/aidl"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTestDevFlavor/java"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTestDevFlavor/rs"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTestDevFlavor/shaders"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/testDevFlavor/res"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/testDevFlavor/res"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/testDevFlavor/resources"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/testDevFlavor/resources"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/testDevFlavor/assets"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/testDevFlavor/assets"
type=
"java-test-resource"
/>
...
@@ -76,6 +69,13 @@
...
@@ -76,6 +69,13 @@
<sourceFolder
url=
"file://$MODULE_DIR$/src/testDevFlavor/java"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/testDevFlavor/java"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/testDevFlavor/rs"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/testDevFlavor/rs"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/testDevFlavor/shaders"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/testDevFlavor/shaders"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTestDevFlavor/res"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTestDevFlavor/resources"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTestDevFlavor/assets"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTestDevFlavor/aidl"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTestDevFlavor/java"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTestDevFlavor/rs"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTestDevFlavor/shaders"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/debug/res"
type=
"java-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/debug/res"
type=
"java-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/debug/resources"
type=
"java-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/debug/resources"
type=
"java-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/debug/assets"
type=
"java-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/debug/assets"
type=
"java-resource"
/>
...
@@ -97,13 +97,6 @@
...
@@ -97,13 +97,6 @@
<sourceFolder
url=
"file://$MODULE_DIR$/src/main/java"
isTestSource=
"false"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/main/java"
isTestSource=
"false"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/main/rs"
isTestSource=
"false"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/main/rs"
isTestSource=
"false"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/main/shaders"
isTestSource=
"false"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/main/shaders"
isTestSource=
"false"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/res"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/resources"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/assets"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/aidl"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/java"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/rs"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/shaders"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/test/res"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/test/res"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/test/resources"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/test/resources"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/test/assets"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/test/assets"
type=
"java-test-resource"
/>
...
@@ -111,9 +104,13 @@
...
@@ -111,9 +104,13 @@
<sourceFolder
url=
"file://$MODULE_DIR$/src/test/java"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/test/java"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/test/rs"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/test/rs"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/test/shaders"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/test/shaders"
isTestSource=
"true"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/blame"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/res"
type=
"java-test-resource"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/classes"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/resources"
type=
"java-test-resource"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/dependency-cache"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/assets"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/aidl"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/java"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/rs"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/shaders"
isTestSource=
"true"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/animated-vector-drawable/24.2.1/jars"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/animated-vector-drawable/24.2.1/jars"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/appcompat-v7/24.2.1/jars"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/appcompat-v7/24.2.1/jars"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-compat/24.2.1/jars"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-compat/24.2.1/jars"
/>
...
@@ -124,13 +121,6 @@
...
@@ -124,13 +121,6 @@
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v4/24.2.1/jars"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v4/24.2.1/jars"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-vector-drawable/24.2.1/jars"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-vector-drawable/24.2.1/jars"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/incremental"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/incremental"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/incremental-safeguard"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/manifests"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/res"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/rs"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/symbols"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/outputs"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/tmp"
/>
</content>
</content>
<orderEntry
type=
"jdk"
jdkName=
"Android API 24 Platform"
jdkType=
"Android SDK"
/>
<orderEntry
type=
"jdk"
jdkName=
"Android API 24 Platform"
jdkType=
"Android SDK"
/>
<orderEntry
type=
"sourceFolder"
forTests=
"false"
/>
<orderEntry
type=
"sourceFolder"
forTests=
"false"
/>
...
...
android/Pictogram/tabletlibrary/src/main/java/com/yottacode/pictogram/tabletlibrary/cropper/CropImageView.java
0 → 100644
View file @
4829118e
package
com
.
yottacode
.
pictogram
.
tabletlibrary
.
cropper
;
import
android.content.Context
;
import
android.content.res.Resources
;
import
android.content.res.TypedArray
;
import
android.graphics.Bitmap
;
import
android.graphics.Canvas
;
import
android.graphics.Matrix
;
import
android.graphics.Paint
;
import
android.graphics.PointF
;
import
android.graphics.RectF
;
import
android.graphics.drawable.BitmapDrawable
;
import
android.graphics.drawable.Drawable
;
import
android.support.annotation.NonNull
;
import
android.support.annotation.Nullable
;
import
android.util.AttributeSet
;
import
android.util.DisplayMetrics
;
import
android.util.Log
;
import
android.view.MotionEvent
;
import
android.widget.ImageView
;
import
android.widget.RelativeLayout
;
import
com.yottacode.pictogram.tabletlibrary.R
;
import
com.yottacode.pictogram.tabletlibrary.cropper.cropwindow.edge.Edge
;
import
com.yottacode.pictogram.tabletlibrary.cropper.cropwindow.handle.Handle
;
import
com.yottacode.pictogram.tabletlibrary.cropper.util.AspectRatioUtil
;
import
com.yottacode.pictogram.tabletlibrary.cropper.util.HandleUtil
;
import
com.yottacode.pictogram.tabletlibrary.cropper.util.PaintUtil
;
/**
* Custom view that provides cropping capabilities to an image.
*
* Class to see it on the image to crop
*/
public
class
CropImageView
extends
ImageView
{
// Private Constants ///////////////////////////////////////////////////////////////////////////
@SuppressWarnings
(
"unused"
)
private
static
final
String
TAG
=
CropImageView
.
class
.
getName
();
@SuppressWarnings
(
"unused"
)
public
static
final
int
GUIDELINES_OFF
=
0
;
public
static
final
int
GUIDELINES_ON_TOUCH
=
1
;
public
static
final
int
GUIDELINES_ON
=
2
;
// Member Variables ////////////////////////////////////////////////////////////////////////////
// The Paint used to draw the white rectangle around the crop area.
private
Paint
mBorderPaint
;
// The Paint used to draw the guidelines within the crop area when pressed.
private
Paint
mGuidelinePaint
;
// The Paint used to draw the corners of the Border
private
Paint
mCornerPaint
;
// The Paint used to darken the surrounding areas outside the crop area.
private
Paint
mSurroundingAreaOverlayPaint
;
// The radius (in pixels) of the touchable area around the handle.
// We are basing this value off of the recommended 48dp touch target size.
private
float
mHandleRadius
;
// An edge of the crop window will snap to the corresponding edge of a
// specified bounding box when the crop window edge is less than or equal to
// this distance (in pixels) away from the bounding box edge.
private
float
mSnapRadius
;
// Thickness of the line (in pixels) used to draw the corner handle.
private
float
mCornerThickness
;
// Thickness of the line (in pixels) used to draw the border of the crop window.
private
float
mBorderThickness
;
// Length of one side of the corner handle.
private
float
mCornerLength
;
// The bounding box around the Bitmap that we are cropping.
@NonNull
private
RectF
mBitmapRect
=
new
RectF
();
// Holds the x and y offset between the exact touch location and the exact
// handle location that is activated. There may be an offset because we
// allow for some leeway (specified by 'mHandleRadius') in activating a
// handle. However, we want to maintain these offset values while the handle
// is being dragged so that the handle doesn't jump.
@NonNull
private
PointF
mTouchOffset
=
new
PointF
();
// The Handle that is currently pressed; null if no Handle is pressed.
private
Handle
mPressedHandle
;
// Flag indicating if the crop area should always be a certain aspect ratio (indicated by mTargetAspectRatio).
private
boolean
mFixAspectRatio
;
// Current aspect ratio of the image.
private
int
mAspectRatioX
=
1
;
private
int
mAspectRatioY
=
1
;
// Mode indicating how/whether to show the guidelines; must be one of GUIDELINES_OFF, GUIDELINES_ON_TOUCH, GUIDELINES_ON.
private
int
mGuidelinesMode
=
1
;
// Constructors ////////////////////////////////////////////////////////////////////////////////
public
CropImageView
(
Context
context
)
{
super
(
context
);
init
(
context
,
null
);
}
public
CropImageView
(
Context
context
,
AttributeSet
attrs
)
{
super
(
context
,
attrs
);
init
(
context
,
attrs
);
}
public
CropImageView
(
Context
context
,
AttributeSet
attrs
,
int
defStyleAttr
)
{
super
(
context
,
attrs
,
defStyleAttr
);
init
(
context
,
attrs
);
}
private
void
init
(
@NonNull
Context
context
,
@Nullable
AttributeSet
attrs
)
{
final
TypedArray
typedArray
=
context
.
obtainStyledAttributes
(
attrs
,
R
.
styleable
.
CropImageView
,
0
,
0
);
mGuidelinesMode
=
typedArray
.
getInteger
(
R
.
styleable
.
CropImageView_guidelines
,
1
);
mFixAspectRatio
=
typedArray
.
getBoolean
(
R
.
styleable
.
CropImageView_fixAspectRatio
,
false
);
mAspectRatioX
=
typedArray
.
getInteger
(
R
.
styleable
.
CropImageView_aspectRatioX
,
1
);
mAspectRatioY
=
typedArray
.
getInteger
(
R
.
styleable
.
CropImageView_aspectRatioY
,
1
);
typedArray
.
recycle
();
final
Resources
resources
=
context
.
getResources
();
mBorderPaint
=
PaintUtil
.
newBorderPaint
(
resources
);
mGuidelinePaint
=
PaintUtil
.
newGuidelinePaint
(
resources
);
mSurroundingAreaOverlayPaint
=
PaintUtil
.
newSurroundingAreaOverlayPaint
(
resources
);
mCornerPaint
=
PaintUtil
.
newCornerPaint
(
resources
);
mHandleRadius
=
resources
.
getDimension
(
R
.
dimen
.
target_radius
);
mSnapRadius
=
resources
.
getDimension
(
R
.
dimen
.
snap_radius
);
mBorderThickness
=
resources
.
getDimension
(
R
.
dimen
.
border_thickness
);
mCornerThickness
=
resources
.
getDimension
(
R
.
dimen
.
corner_thickness
);
mCornerLength
=
resources
.
getDimension
(
R
.
dimen
.
corner_length
);
}
// View Methods ////////////////////////////////////////////////////////////////////////////////
@Override
protected
void
onLayout
(
boolean
changed
,
int
left
,
int
top
,
int
right
,
int
bottom
)
{
super
.
onLayout
(
changed
,
left
,
top
,
right
,
bottom
);
mBitmapRect
=
getBitmapRect
();
initCropWindow
(
mBitmapRect
);
}
@Override
protected
void
onDraw
(
Canvas
canvas
)
{
super
.
onDraw
(
canvas
);
drawDarkenedSurroundingArea
(
canvas
);
drawGuidelines
(
canvas
);
drawBorder
(
canvas
);
drawCorners
(
canvas
);
}
@Override
public
boolean
onTouchEvent
(
MotionEvent
event
)
{
// If this View is not enabled, don't allow for touch interactions.
if
(!
isEnabled
())
{
return
false
;
}
switch
(
event
.
getAction
())
{
case
MotionEvent
.
ACTION_DOWN
:
onActionDown
(
event
.
getX
(),
event
.
getY
());
return
true
;
case
MotionEvent
.
ACTION_UP
:
case
MotionEvent
.
ACTION_CANCEL
:
getParent
().
requestDisallowInterceptTouchEvent
(
false
);
onActionUp
();
return
true
;
case
MotionEvent
.
ACTION_MOVE
:
onActionMove
(
event
.
getX
(),
event
.
getY
());
getParent
().
requestDisallowInterceptTouchEvent
(
true
);
return
true
;
default
:
return
false
;
}
}
// Public Methods //////////////////////////////////////////////////////////////////////////////
/**
* Sets the guidelines for the CropOverlayView to be either on, off, or to show when resizing
* the application.
*
* @param guidelinesMode Integer that signals whether the guidelines should be on, off, or only
* showing when resizing.
*/
public
void
setGuidelines
(
int
guidelinesMode
)
{
mGuidelinesMode
=
guidelinesMode
;
invalidate
();
// Request onDraw() to get called again.
}
/**
* Sets whether the aspect ratio is fixed or not; true fixes the aspect ratio, while false
* allows it to be changed.
*
* @param fixAspectRatio Boolean that signals whether the aspect ratio should be maintained.
*
* @see {@link #setAspectRatio(int, int)}
*/
public
void
setFixedAspectRatio
(
boolean
fixAspectRatio
)
{
mFixAspectRatio
=
fixAspectRatio
;
requestLayout
();
// Request measure/layout to be run again.
}
/**
* Sets the both the X and Y values of the aspectRatio. These only apply iff fixed aspect ratio
* is set.
*
* @param aspectRatioX new X value of the aspect ratio; must be greater than 0
* @param aspectRatioY new Y value of the aspect ratio; must be greater than 0
*
* @see {@link #setFixedAspectRatio(boolean)}
*/
public
void
setAspectRatio
(
int
aspectRatioX
,
int
aspectRatioY
)
{
if
(
aspectRatioX
<=
0
||
aspectRatioY
<=
0
)
{
throw
new
IllegalArgumentException
(
"Cannot set aspect ratio value to a number less than or equal to 0."
);
}
mAspectRatioX
=
aspectRatioX
;
mAspectRatioY
=
aspectRatioY
;
if
(
mFixAspectRatio
)
{
requestLayout
();
// Request measure/layout to be run again.
}
}
/**
* Gets the cropped image based on the current crop window.
*
* @return a new Bitmap representing the cropped image
*/
public
Bitmap
getCroppedImage
()
{
// Implementation reference: http://stackoverflow.com/a/26930938/1068656
final
Drawable
drawable
=
this
.
getDrawable
();
if
(
drawable
==
null
||
!(
drawable
instanceof
BitmapDrawable
))
{
return
null
;
}
// Get image matrix values and place them in an array.
final
float
[]
matrixValues
=
new
float
[
9
];
this
.
getImageMatrix
().
getValues
(
matrixValues
);
// Extract the scale values. Note, we currently do not handle any other transformations (e.g. skew).
final
float
scaleX
=
matrixValues
[
Matrix
.
MSCALE_X
];
//==1
final
float
scaleY
=
matrixValues
[
Matrix
.
MSCALE_Y
];
//==1
// Extract the translation values.
final
float
transX
=
matrixValues
[
Matrix
.
MTRANS_X
];
final
float
transY
=
matrixValues
[
Matrix
.
MTRANS_Y
];
final
Bitmap
originalBitmap
=
((
BitmapDrawable
)
drawable
).
getBitmap
();
Log
.
i
(
"DETALLES"
,
"ScaleX: "
+
scaleX
+
"- ScaleY: "
+
scaleY
);
Log
.
i
(
"DETALLES"
,
"transX: "
+
transX
+
"- transY: "
+
transY
);
Log
.
i
(
"DETALLES"
,
"Edge Left: "
+
Edge
.
LEFT
.
getCoordinate
()
+
"- Edge Top: "
+
Edge
.
TOP
.
getCoordinate
());
Log
.
i
(
"DETALLES"
,
"ancho original: "
+
originalBitmap
.
getWidth
()
+
" Alto original: "
+
originalBitmap
.
getHeight
());
final
float
cropWidth
=
Edge
.
getWidth
();
final
float
cropHeight
=
Edge
.
getHeight
();
Log
.
i
(
"DETALLES"
,
"ancho original: "
+
originalBitmap
.
getWidth
()
+
" Alto original: "
+
originalBitmap
.
getHeight
());
Log
.
i
(
"DETALLES"
,
"ancho: "
+
cropWidth
+
" Alto: "
+
cropHeight
);
// Ensure that the left and top edges are not outside of the ImageView bounds.
/*final float bitmapLeft = (transX < 0) ? Math.abs(transX) : 0;
final float bitmapTop = (transY < 0) ? Math.abs(transY) : 0;*/
// Get the original bitmap object.
//final Bitmap originalBitmap = ((BitmapDrawable) drawable).getBitmap();
final
float
bitmapLeft
=
((
findViewById
(
R
.
id
.
ScrollView
)).
getWidth
()
-
originalBitmap
.
getWidth
())/
2
;
final
float
bitmapTop
=
((
findViewById
(
R
.
id
.
ScrollView
)).
getHeight
()
-
originalBitmap
.
getHeight
())/
2
;
Log
.
i
(
"DETALLES"
,
"bitmapLeft: "
+
bitmapLeft
+
"- bitmapTop: "
+
bitmapTop
);
// Calculate the top-left corner of the crop window relative to the ~original~ bitmap size.
final
float
cropX
=
(
bitmapLeft
+
Edge
.
LEFT
.
getCoordinate
());
final
float
cropY
=
(
bitmapTop
+
Edge
.
TOP
.
getCoordinate
());
Log
.
i
(
"DETALLES"
,
"Edge Left: "
+
Edge
.
LEFT
.
getCoordinate
()
+
"- Edge Top: "
+
Edge
.
TOP
.
getCoordinate
());
Log
.
i
(
"DETALLES"
,
"Posicion X: "
+
cropX
+
"- Posicion Y: "
+
cropY
);
// Calculate the crop window size relative to the ~original~ bitmap size.
// Make sure the right and bottom edges are not outside the ImageView bounds (this is just to address rounding discrepancies).
/*final float cropWidth = Edge.getWidth();
final float cropHeight = Edge.getHeight();
Log.i("DETALLES","ancho original: "+originalBitmap.getWidth() + " Alto original: "+originalBitmap.getHeight());
Log.i("DETALLES","ancho: "+cropWidth + " Alto: "+cropHeight);*/
// Crop the subset from the original Bitmap.
return
Bitmap
.
createBitmap
(
originalBitmap
,
(
int
)
cropX
,
(
int
)
cropY
,
(
int
)
cropWidth
,
(
int
)
cropHeight
);
}
// Private Methods /////////////////////////////////////////////////////////////////////////////
/**
* Gets the bounding rectangle of the bitmap within the ImageView.
*/
private
RectF
getBitmapRect
()
{
final
Drawable
drawable
=
getDrawable
();
if
(
drawable
==
null
)
{
return
new
RectF
();
}
// Get image matrix values and place them in an array.
final
float
[]
matrixValues
=
new
float
[
9
];
getImageMatrix
().
getValues
(
matrixValues
);
// Extract the scale and translation values from the matrix.
final
float
scaleX
=
matrixValues
[
Matrix
.
MSCALE_X
];
final
float
scaleY
=
matrixValues
[
Matrix
.
MSCALE_Y
];
final
float
transX
=
matrixValues
[
Matrix
.
MTRANS_X
];
final
float
transY
=
matrixValues
[
Matrix
.
MTRANS_Y
];
// Get the width and height of the original bitmap.
final
int
drawableIntrinsicWidth
=
drawable
.
getIntrinsicWidth
();
final
int
drawableIntrinsicHeight
=
drawable
.
getIntrinsicHeight
();
// Calculate the dimensions as seen on screen.
final
int
drawableDisplayWidth
=
Math
.
round
(
drawableIntrinsicWidth
*
scaleX
);
final
int
drawableDisplayHeight
=
Math
.
round
(
drawableIntrinsicHeight
*
scaleY
);
// Get the Rect of the displayed image within the ImageView.
final
float
left
=
Math
.
max
(
transX
,
0
);
final
float
top
=
Math
.
max
(
transY
,
0
);
final
float
right
=
Math
.
min
(
left
+
drawableDisplayWidth
,
getWidth
());
final
float
bottom
=
Math
.
min
(
top
+
drawableDisplayHeight
,
getHeight
());
return
new
RectF
(
left
,
top
,
right
,
bottom
);
}
/**
* Initialize the crop window by setting the proper {@link Edge} values.
* <p/>
* If fixed aspect ratio is turned off, the initial crop window will be set to the displayed
* image with 10% margin. If fixed aspect ratio is turned on, the initial crop window will
* conform to the aspect ratio with at least one dimension maximized.
*/
private
void
initCropWindow
(
@NonNull
RectF
bitmapRect
)
{
if
(
mFixAspectRatio
)
{
// Initialize the crop window with the proper aspect ratio.
initCropWindowWithFixedAspectRatio
(
bitmapRect
);
}
else
{
// Initialize crop window to have 10% padding w/ respect to Drawable's bounds.
final
float
horizontalPadding
=
0.1f
*
bitmapRect
.
width
();
final
float
verticalPadding
=
0.1f
*
bitmapRect
.
height
();
Edge
.
LEFT
.
setCoordinate
(
bitmapRect
.
left
+
horizontalPadding
);
Edge
.
TOP
.
setCoordinate
(
bitmapRect
.
top
+
verticalPadding
);
Edge
.
RIGHT
.
setCoordinate
(
bitmapRect
.
right
-
horizontalPadding
);
Edge
.
BOTTOM
.
setCoordinate
(
bitmapRect
.
bottom
-
verticalPadding
);
}
}
private
void
initCropWindowWithFixedAspectRatio
(
@NonNull
RectF
bitmapRect
)
{
// If the image aspect ratio is wider than the crop aspect ratio,
// then the image height is the determining initial length. Else, vice-versa.
if
(
AspectRatioUtil
.
calculateAspectRatio
(
bitmapRect
)
>
getTargetAspectRatio
())
{
final
float
cropWidth
=
AspectRatioUtil
.
calculateWidth
(
bitmapRect
.
height
(),
getTargetAspectRatio
());
Edge
.
LEFT
.
setCoordinate
(
bitmapRect
.
centerX
()
-
cropWidth
/
2
f
);
Edge
.
TOP
.
setCoordinate
(
bitmapRect
.
top
);
Edge
.
RIGHT
.
setCoordinate
(
bitmapRect
.
centerX
()
+
cropWidth
/
2
f
);
Edge
.
BOTTOM
.
setCoordinate
(
bitmapRect
.
bottom
);
}
else
{
final
float
cropHeight
=
AspectRatioUtil
.
calculateHeight
(
bitmapRect
.
width
(),
getTargetAspectRatio
());
Edge
.
LEFT
.
setCoordinate
(
bitmapRect
.
left
);
Edge
.
TOP
.
setCoordinate
(
bitmapRect
.
centerY
()
-
cropHeight
/
2
f
);
Edge
.
RIGHT
.
setCoordinate
(
bitmapRect
.
right
);
Edge
.
BOTTOM
.
setCoordinate
(
bitmapRect
.
centerY
()
+
cropHeight
/
2
f
);
}
}
private
void
drawDarkenedSurroundingArea
(
@NonNull
Canvas
canvas
)
{
final
RectF
bitmapRect
=
mBitmapRect
;
final
float
left
=
Edge
.
LEFT
.
getCoordinate
();
final
float
top
=
Edge
.
TOP
.
getCoordinate
();
final
float
right
=
Edge
.
RIGHT
.
getCoordinate
();
final
float
bottom
=
Edge
.
BOTTOM
.
getCoordinate
();
/*-
-------------------------------------
| top |
-------------------------------------
| | | |
| | | |
| left | | right |
| | | |
| | | |
-------------------------------------
| bottom |
-------------------------------------
*/
// Draw "top", "bottom", "left", then "right" quadrants according to diagram above.
canvas
.
drawRect
(
bitmapRect
.
left
,
bitmapRect
.
top
,
bitmapRect
.
right
,
top
,
mSurroundingAreaOverlayPaint
);
canvas
.
drawRect
(
bitmapRect
.
left
,
bottom
,
bitmapRect
.
right
,
bitmapRect
.
bottom
,
mSurroundingAreaOverlayPaint
);
canvas
.
drawRect
(
bitmapRect
.
left
,
top
,
left
,
bottom
,
mSurroundingAreaOverlayPaint
);
canvas
.
drawRect
(
right
,
top
,
bitmapRect
.
right
,
bottom
,
mSurroundingAreaOverlayPaint
);
}
private
void
drawGuidelines
(
@NonNull
Canvas
canvas
)
{
if
(!
shouldGuidelinesBeShown
())
{
return
;
}
final
float
left
=
Edge
.
LEFT
.
getCoordinate
();
final
float
top
=
Edge
.
TOP
.
getCoordinate
();
final
float
right
=
Edge
.
RIGHT
.
getCoordinate
();
final
float
bottom
=
Edge
.
BOTTOM
.
getCoordinate
();
// Draw vertical guidelines.
final
float
oneThirdCropWidth
=
Edge
.
getWidth
()
/
3
;
final
float
x1
=
left
+
oneThirdCropWidth
;
canvas
.
drawLine
(
x1
,
top
,
x1
,
bottom
,
mGuidelinePaint
);
final
float
x2
=
right
-
oneThirdCropWidth
;
canvas
.
drawLine
(
x2
,
top
,
x2
,
bottom
,
mGuidelinePaint
);
// Draw horizontal guidelines.
final
float
oneThirdCropHeight
=
Edge
.
getHeight
()
/
3
;
final
float
y1
=
top
+
oneThirdCropHeight
;
canvas
.
drawLine
(
left
,
y1
,
right
,
y1
,
mGuidelinePaint
);
final
float
y2
=
bottom
-
oneThirdCropHeight
;
canvas
.
drawLine
(
left
,
y2
,
right
,
y2
,
mGuidelinePaint
);
}
private
void
drawBorder
(
@NonNull
Canvas
canvas
)
{
canvas
.
drawRect
(
Edge
.
LEFT
.
getCoordinate
(),
Edge
.
TOP
.
getCoordinate
(),
Edge
.
RIGHT
.
getCoordinate
(),
Edge
.
BOTTOM
.
getCoordinate
(),
mBorderPaint
);
}
private
void
drawCorners
(
@NonNull
Canvas
canvas
)
{
final
float
left
=
Edge
.
LEFT
.
getCoordinate
();
final
float
top
=
Edge
.
TOP
.
getCoordinate
();
final
float
right
=
Edge
.
RIGHT
.
getCoordinate
();
final
float
bottom
=
Edge
.
BOTTOM
.
getCoordinate
();
// Absolute value of the offset by which to draw the corner line such that its inner edge is flush with the border's inner edge.
final
float
lateralOffset
=
(
mCornerThickness
-
mBorderThickness
)
/
2
f
;
// Absolute value of the offset by which to start the corner line such that the line is drawn all the way to form a corner edge with the adjacent side.
final
float
startOffset
=
mCornerThickness
-
(
mBorderThickness
/
2
f
);
// Top-left corner: left side
canvas
.
drawLine
(
left
-
lateralOffset
,
top
-
startOffset
,
left
-
lateralOffset
,
top
+
mCornerLength
,
mCornerPaint
);
// Top-left corner: top side
canvas
.
drawLine
(
left
-
startOffset
,
top
-
lateralOffset
,
left
+
mCornerLength
,
top
-
lateralOffset
,
mCornerPaint
);
// Top-right corner: right side
canvas
.
drawLine
(
right
+
lateralOffset
,
top
-
startOffset
,
right
+
lateralOffset
,
top
+
mCornerLength
,
mCornerPaint
);
// Top-right corner: top side
canvas
.
drawLine
(
right
+
startOffset
,
top
-
lateralOffset
,
right
-
mCornerLength
,
top
-
lateralOffset
,
mCornerPaint
);
// Bottom-left corner: left side
canvas
.
drawLine
(
left
-
lateralOffset
,
bottom
+
startOffset
,
left
-
lateralOffset
,
bottom
-
mCornerLength
,
mCornerPaint
);
// Bottom-left corner: bottom side
canvas
.
drawLine
(
left
-
startOffset
,
bottom
+
lateralOffset
,
left
+
mCornerLength
,
bottom
+
lateralOffset
,
mCornerPaint
);
// Bottom-right corner: right side
canvas
.
drawLine
(
right
+
lateralOffset
,
bottom
+
startOffset
,
right
+
lateralOffset
,
bottom
-
mCornerLength
,
mCornerPaint
);
// Bottom-right corner: bottom side
canvas
.
drawLine
(
right
+
startOffset
,
bottom
+
lateralOffset
,
right
-
mCornerLength
,
bottom
+
lateralOffset
,
mCornerPaint
);
}
private
boolean
shouldGuidelinesBeShown
()
{
return
((
mGuidelinesMode
==
GUIDELINES_ON
)
||
((
mGuidelinesMode
==
GUIDELINES_ON_TOUCH
)
&&
(
mPressedHandle
!=
null
)));
}
private
float
getTargetAspectRatio
()
{
return
mAspectRatioX
/
(
float
)
mAspectRatioY
;
}
/**
* Handles a {@link MotionEvent#ACTION_DOWN} event.
*
* @param x the x-coordinate of the down action
* @param y the y-coordinate of the down action
*/
private
void
onActionDown
(
float
x
,
float
y
)
{
final
float
left
=
Edge
.
LEFT
.
getCoordinate
();
final
float
top
=
Edge
.
TOP
.
getCoordinate
();
final
float
right
=
Edge
.
RIGHT
.
getCoordinate
();
final
float
bottom
=
Edge
.
BOTTOM
.
getCoordinate
();
mPressedHandle
=
HandleUtil
.
getPressedHandle
(
x
,
y
,
left
,
top
,
right
,
bottom
,
mHandleRadius
);
// Calculate the offset of the touch point from the precise location of the handle.
// Save these values in member variable 'mTouchOffset' so that we can maintain this offset as we drag the handle.
if
(
mPressedHandle
!=
null
)
{
HandleUtil
.
getOffset
(
mPressedHandle
,
x
,
y
,
left
,
top
,
right
,
bottom
,
mTouchOffset
);
invalidate
();
}
}
/**
* Handles a {@link MotionEvent#ACTION_UP} or {@link MotionEvent#ACTION_CANCEL} event.
*/
private
void
onActionUp
()
{
if
(
mPressedHandle
!=
null
)
{
mPressedHandle
=
null
;
invalidate
();
}
}
/**
* Handles a {@link MotionEvent#ACTION_MOVE} event.
*
* @param x the x-coordinate of the move event
* @param y the y-coordinate of the move event
*/
private
void
onActionMove
(
float
x
,
float
y
)
{
if
(
mPressedHandle
==
null
)
{
return
;
}
// Adjust the coordinates for the finger position's offset (i.e. the distance from the initial touch to the precise handle location).
// We want to maintain the initial touch's distance to the pressed handle so that the crop window size does not "jump".
x
+=
mTouchOffset
.
x
;
y
+=
mTouchOffset
.
y
;
// Calculate the new crop window size/position.
if
(
mFixAspectRatio
)
{
mPressedHandle
.
updateCropWindow
(
x
,
y
,
getTargetAspectRatio
(),
mBitmapRect
,
mSnapRadius
);
}
else
{
mPressedHandle
.
updateCropWindow
(
x
,
y
,
mBitmapRect
,
mSnapRadius
);
}
invalidate
();
}
}
android/Pictogram/tabletlibrary/src/main/java/com/yottacode/pictogram/tabletlibrary/cropper/MainCropImage.java
0 → 100644
View file @
4829118e
package
com
.
yottacode
.
pictogram
.
tabletlibrary
.
cropper
;
import
android.app.Activity
;
import
android.graphics.Bitmap
;
import
android.os.Bundle
;
import
android.view.View
;
import
android.view.Window
;
import
android.widget.AdapterView
;
import
android.widget.Button
;
import
android.widget.CompoundButton
;
import
android.widget.CompoundButton.OnCheckedChangeListener
;
import
android.widget.ImageView
;
import
android.widget.SeekBar
;
import
android.widget.SeekBar.OnSeekBarChangeListener
;
import
android.widget.Spinner
;
import
android.widget.TextView
;
import
android.widget.ToggleButton
;
import
com.yottacode.pictogram.tabletlibrary.cropper.CropImageView
;
import
com.yottacode.pictogram.tabletlibrary.R
;
public
class
MainCropImage
extends
Activity
{
// Private Constants ///////////////////////////////////////////////////////////////////////////
private
static
final
int
GUIDELINES_ON_TOUCH
=
1
;
// Activity Methods ////////////////////////////////////////////////////////////////////////////
@Override
public
void
onCreate
(
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
requestWindowFeature
(
Window
.
FEATURE_NO_TITLE
);
setContentView
(
R
.
layout
.
crop_layout
);
// Initialize Views.
//final ToggleButton fixedAspectRatioToggleButton = (ToggleButton) findViewById(R.id.fixedAspectRatioToggle);
//final TextView aspectRatioXTextView = (TextView) findViewById(R.id.aspectRatioX);
//final SeekBar aspectRatioXSeekBar = (SeekBar) findViewById(R.id.aspectRatioXSeek);
//final TextView aspectRatioYTextView = (TextView) findViewById(R.id.aspectRatioY);
//final SeekBar aspectRatioYSeekBar = (SeekBar) findViewById(R.id.aspectRatioYSeek);
//final Spinner guidelinesSpinner = (Spinner) findViewById(R.id.showGuidelinesSpin);
final
CropImageView
cropImageView
=
(
CropImageView
)
findViewById
(
R
.
id
.
CropImageView
);
final
ImageView
croppedImageView
=
(
ImageView
)
findViewById
(
R
.
id
.
croppedImageView
);
final
Button
cropButton
=
(
Button
)
findViewById
(
R
.
id
.
Button_crop
);
cropImageView
.
setGuidelines
(
CropImageView
.
GUIDELINES_ON
);
//To show the guidelines
cropImageView
.
setAspectRatio
(
1
,
1
);
// Initializes fixedAspectRatio toggle button.
/*fixedAspectRatioToggleButton.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
cropImageView.setFixedAspectRatio(isChecked);
cropImageView.setAspectRatio(aspectRatioXSeekBar.getProgress(), aspectRatioYSeekBar.getProgress());
aspectRatioXSeekBar.setEnabled(isChecked);
aspectRatioYSeekBar.setEnabled(isChecked);
}
});*/
// Set seek bars to be disabled until toggle button is checked.
/*aspectRatioXSeekBar.setEnabled(false);
aspectRatioYSeekBar.setEnabled(false);
aspectRatioXTextView.setText(String.valueOf(aspectRatioXSeekBar.getProgress()));
aspectRatioYTextView.setText(String.valueOf(aspectRatioXSeekBar.getProgress()));*/
// Initialize aspect ratio X SeekBar.
/*aspectRatioXSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar aspectRatioXSeekBar, int progress, boolean fromUser) {
if (progress < 1) {
aspectRatioXSeekBar.setProgress(1);
}
cropImageView.setAspectRatio(aspectRatioXSeekBar.getProgress(), aspectRatioYSeekBar.getProgress());
aspectRatioXTextView.setText(String.valueOf(aspectRatioXSeekBar.getProgress()));
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// Do nothing.
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// Do nothing.
}
});*/
// Initialize aspect ratio Y SeekBar.
/*aspectRatioYSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar aspectRatioYSeekBar, int progress, boolean fromUser) {
if (progress < 1) {
aspectRatioYSeekBar.setProgress(1);
}
cropImageView.setAspectRatio(aspectRatioXSeekBar.getProgress(), aspectRatioYSeekBar.getProgress());
aspectRatioYTextView.setText(String.valueOf(aspectRatioYSeekBar.getProgress()));
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// Do nothing.
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// Do nothing.
}
});*/
// Set up the Guidelines Spinner.
/*guidelinesSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
cropImageView.setGuidelines(i);
}
public void onNothingSelected(AdapterView<?> adapterView) {
// Do nothing.
}
});
guidelinesSpinner.setSelection(GUIDELINES_ON_TOUCH);*/
// Initialize the Crop button.
cropButton
.
setOnClickListener
(
new
View
.
OnClickListener
()
{
@Override
public
void
onClick
(
View
v
)
{
final
Bitmap
croppedImage
=
cropImageView
.
getCroppedImage
();
croppedImageView
.
setImageBitmap
(
croppedImage
);
}
});
}
}
android/Pictogram/tabletlibrary/src/main/java/com/yottacode/pictogram/tabletlibrary/cropper/cropwindow/edge/Edge.java
0 → 100644
View file @
4829118e
/*
* Copyright 2013, Edmodo, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with the License.
* You may obtain a copy of the License in the LICENSE file, or at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS"
* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
package
com
.
yottacode
.
pictogram
.
tabletlibrary
.
cropper
.
cropwindow
.
edge
;
import
android.graphics.RectF
;
import
android.support.annotation.NonNull
;
import
com.yottacode.pictogram.tabletlibrary.cropper.util.AspectRatioUtil
;
/**
* Enum representing an edge in the crop window.
*/
public
enum
Edge
{
LEFT
,
TOP
,
RIGHT
,
BOTTOM
;
// Private Constants ///////////////////////////////////////////////////////////////////////////
// Minimum distance in pixels that one edge can get to its opposing edge.
// This is an arbitrary value that simply prevents the crop window from becoming too small.
public
static
final
int
MIN_CROP_LENGTH_PX
=
40
;
// Member Variables ////////////////////////////////////////////////////////////////////////////
// The coordinate value of this edge.
// This will be the x-coordinate for LEFT and RIGHT edges and the y-coordinate for TOP and BOTTOM edges.
private
float
mCoordinate
;
// Public Methods //////////////////////////////////////////////////////////////////////////////
/**
* Sets the coordinate of the Edge. The coordinate will represent the x-coordinate for LEFT and
* RIGHT Edges and the y-coordinate for TOP and BOTTOM edges.
*
* @param coordinate the position of the edge
*/
public
void
setCoordinate
(
float
coordinate
)
{
mCoordinate
=
coordinate
;
}
/**
* Add the given number of pixels to the current coordinate position of this Edge.
*
* @param distance the number of pixels to add
*/
public
void
offset
(
float
distance
)
{
mCoordinate
+=
distance
;
}
/**
* Gets the coordinate of the Edge
*
* @return the Edge coordinate (x-coordinate for LEFT and RIGHT Edges and the y-coordinate for
* TOP and BOTTOM edges)
*/
public
float
getCoordinate
()
{
return
mCoordinate
;
}
/**
* Sets the Edge to the given x-y coordinate but also adjusting for snapping to the image bounds
* and parent view border constraints.
*
* @param x the x-coordinate
* @param y the y-coordinate
* @param imageRect the bounding rectangle of the image
* @param imageSnapRadius the radius (in pixels) at which the edge should snap to the image
*/
public
void
adjustCoordinate
(
float
x
,
float
y
,
@NonNull
RectF
imageRect
,
float
imageSnapRadius
,
float
aspectRatio
)
{
switch
(
this
)
{
case
LEFT:
mCoordinate
=
adjustLeft
(
x
,
imageRect
,
imageSnapRadius
,
aspectRatio
);
break
;
case
TOP:
mCoordinate
=
adjustTop
(
y
,
imageRect
,
imageSnapRadius
,
aspectRatio
);
break
;
case
RIGHT:
mCoordinate
=
adjustRight
(
x
,
imageRect
,
imageSnapRadius
,
aspectRatio
);
break
;
case
BOTTOM:
mCoordinate
=
adjustBottom
(
y
,
imageRect
,
imageSnapRadius
,
aspectRatio
);
break
;
}
}
/**
* Adjusts this Edge position such that the resulting window will have the given aspect ratio.
*
* @param aspectRatio the aspect ratio to achieve
*/
public
void
adjustCoordinate
(
float
aspectRatio
)
{
final
float
left
=
Edge
.
LEFT
.
getCoordinate
();
final
float
top
=
Edge
.
TOP
.
getCoordinate
();
final
float
right
=
Edge
.
RIGHT
.
getCoordinate
();
final
float
bottom
=
Edge
.
BOTTOM
.
getCoordinate
();
switch
(
this
)
{
case
LEFT:
mCoordinate
=
AspectRatioUtil
.
calculateLeft
(
top
,
right
,
bottom
,
aspectRatio
);
break
;
case
TOP:
mCoordinate
=
AspectRatioUtil
.
calculateTop
(
left
,
right
,
bottom
,
aspectRatio
);
break
;
case
RIGHT:
mCoordinate
=
AspectRatioUtil
.
calculateRight
(
left
,
top
,
bottom
,
aspectRatio
);
break
;
case
BOTTOM:
mCoordinate
=
AspectRatioUtil
.
calculateBottom
(
left
,
top
,
right
,
aspectRatio
);
break
;
}
}
/**
* Returns whether or not you can re-scale the image based on whether any edge would be out of
* bounds. Checks all the edges for a possibility of jumping out of bounds.
*
* @param edge the Edge that is about to be expanded
* @param imageRect the rectangle of the picture
* @param aspectRatio the desired aspectRatio of the picture
*
* @return whether or not the new image would be out of bounds.
*/
public
boolean
isNewRectangleOutOfBounds
(
@NonNull
Edge
edge
,
@NonNull
RectF
imageRect
,
float
aspectRatio
)
{
final
float
offset
=
edge
.
snapOffset
(
imageRect
);
switch
(
this
)
{
case
LEFT:
if
(
edge
.
equals
(
Edge
.
TOP
))
{
final
float
top
=
imageRect
.
top
;
final
float
bottom
=
Edge
.
BOTTOM
.
getCoordinate
()
-
offset
;
final
float
right
=
Edge
.
RIGHT
.
getCoordinate
();
final
float
left
=
AspectRatioUtil
.
calculateLeft
(
top
,
right
,
bottom
,
aspectRatio
);
return
isOutOfBounds
(
top
,
left
,
bottom
,
right
,
imageRect
);
}
else
if
(
edge
.
equals
(
Edge
.
BOTTOM
))
{
final
float
bottom
=
imageRect
.
bottom
;
final
float
top
=
Edge
.
TOP
.
getCoordinate
()
-
offset
;
final
float
right
=
Edge
.
RIGHT
.
getCoordinate
();
final
float
left
=
AspectRatioUtil
.
calculateLeft
(
top
,
right
,
bottom
,
aspectRatio
);
return
isOutOfBounds
(
top
,
left
,
bottom
,
right
,
imageRect
);
}
break
;
case
TOP:
if
(
edge
.
equals
(
Edge
.
LEFT
))
{
final
float
left
=
imageRect
.
left
;
final
float
right
=
Edge
.
RIGHT
.
getCoordinate
()
-
offset
;
final
float
bottom
=
Edge
.
BOTTOM
.
getCoordinate
();
final
float
top
=
AspectRatioUtil
.
calculateTop
(
left
,
right
,
bottom
,
aspectRatio
);
return
isOutOfBounds
(
top
,
left
,
bottom
,
right
,
imageRect
);
}
else
if
(
edge
.
equals
(
Edge
.
RIGHT
))
{
final
float
right
=
imageRect
.
right
;
final
float
left
=
Edge
.
LEFT
.
getCoordinate
()
-
offset
;
final
float
bottom
=
Edge
.
BOTTOM
.
getCoordinate
();
final
float
top
=
AspectRatioUtil
.
calculateTop
(
left
,
right
,
bottom
,
aspectRatio
);
return
isOutOfBounds
(
top
,
left
,
bottom
,
right
,
imageRect
);
}
break
;
case
RIGHT:
if
(
edge
.
equals
(
Edge
.
TOP
))
{
final
float
top
=
imageRect
.
top
;
final
float
bottom
=
Edge
.
BOTTOM
.
getCoordinate
()
-
offset
;
final
float
left
=
Edge
.
LEFT
.
getCoordinate
();
final
float
right
=
AspectRatioUtil
.
calculateRight
(
left
,
top
,
bottom
,
aspectRatio
);
return
isOutOfBounds
(
top
,
left
,
bottom
,
right
,
imageRect
);
}
else
if
(
edge
.
equals
(
Edge
.
BOTTOM
))
{
final
float
bottom
=
imageRect
.
bottom
;
final
float
top
=
Edge
.
TOP
.
getCoordinate
()
-
offset
;
final
float
left
=
Edge
.
LEFT
.
getCoordinate
();
final
float
right
=
AspectRatioUtil
.
calculateRight
(
left
,
top
,
bottom
,
aspectRatio
);
return
isOutOfBounds
(
top
,
left
,
bottom
,
right
,
imageRect
);
}
break
;
case
BOTTOM:
if
(
edge
.
equals
(
Edge
.
LEFT
))
{
final
float
left
=
imageRect
.
left
;
final
float
right
=
Edge
.
RIGHT
.
getCoordinate
()
-
offset
;
final
float
top
=
Edge
.
TOP
.
getCoordinate
();
final
float
bottom
=
AspectRatioUtil
.
calculateBottom
(
left
,
top
,
right
,
aspectRatio
);
return
isOutOfBounds
(
top
,
left
,
bottom
,
right
,
imageRect
);
}
else
if
(
edge
.
equals
(
Edge
.
RIGHT
))
{
final
float
right
=
imageRect
.
right
;
final
float
left
=
Edge
.
LEFT
.
getCoordinate
()
-
offset
;
final
float
top
=
Edge
.
TOP
.
getCoordinate
();
final
float
bottom
=
AspectRatioUtil
.
calculateBottom
(
left
,
top
,
right
,
aspectRatio
);
return
isOutOfBounds
(
top
,
left
,
bottom
,
right
,
imageRect
);
}
break
;
}
return
true
;
}
/**
* Returns whether the new rectangle would be out of bounds.
*
* @param imageRect the Image to be compared with
*
* @return whether it would be out of bounds
*/
private
boolean
isOutOfBounds
(
float
top
,
float
left
,
float
bottom
,
float
right
,
@NonNull
RectF
imageRect
)
{
return
(
top
<
imageRect
.
top
||
left
<
imageRect
.
left
||
bottom
>
imageRect
.
bottom
||
right
>
imageRect
.
right
);
}
/**
* Snap this Edge to the given image boundaries.
*
* @param imageRect the bounding rectangle of the image to snap to
*
* @return the amount (in pixels) that this coordinate was changed (i.e. the new coordinate
* minus the old coordinate value)
*/
public
float
snapToRect
(
@NonNull
RectF
imageRect
)
{
final
float
oldCoordinate
=
mCoordinate
;
switch
(
this
)
{
case
LEFT:
mCoordinate
=
imageRect
.
left
;
break
;
case
TOP:
mCoordinate
=
imageRect
.
top
;
break
;
case
RIGHT:
mCoordinate
=
imageRect
.
right
;
break
;
case
BOTTOM:
mCoordinate
=
imageRect
.
bottom
;
break
;
}
return
mCoordinate
-
oldCoordinate
;
}
/**
* Returns the potential snap offset of snapToRect, without changing the coordinate.
*
* @param imageRect the bounding rectangle of the image to snap to
*
* @return the amount (in pixels) that this coordinate was changed (i.e. the new coordinate
* minus the old coordinate value)
*/
public
float
snapOffset
(
@NonNull
RectF
imageRect
)
{
final
float
oldCoordinate
=
mCoordinate
;
final
float
newCoordinate
;
switch
(
this
)
{
case
LEFT:
newCoordinate
=
imageRect
.
left
;
break
;
case
TOP:
newCoordinate
=
imageRect
.
top
;
break
;
case
RIGHT:
newCoordinate
=
imageRect
.
right
;
break
;
default
:
// BOTTOM
newCoordinate
=
imageRect
.
bottom
;
break
;
}
return
newCoordinate
-
oldCoordinate
;
}
/**
* Gets the current width of the crop window.
*/
public
static
float
getWidth
()
{
return
Edge
.
RIGHT
.
getCoordinate
()
-
Edge
.
LEFT
.
getCoordinate
();
}
/**
* Gets the current height of the crop window.
*/
public
static
float
getHeight
()
{
return
Edge
.
BOTTOM
.
getCoordinate
()
-
Edge
.
TOP
.
getCoordinate
();
}
/**
* Determines if this Edge is outside the inner margins of the given bounding rectangle. The
* margins come inside the actual frame by SNAPRADIUS amount; therefore, determines if the point
* is outside the inner "margin" frame.
*/
public
boolean
isOutsideMargin
(
@NonNull
RectF
rect
,
float
margin
)
{
final
boolean
result
;
switch
(
this
)
{
case
LEFT:
result
=
mCoordinate
-
rect
.
left
<
margin
;
break
;
case
TOP:
result
=
mCoordinate
-
rect
.
top
<
margin
;
break
;
case
RIGHT:
result
=
rect
.
right
-
mCoordinate
<
margin
;
break
;
default
:
// BOTTOM
result
=
rect
.
bottom
-
mCoordinate
<
margin
;
break
;
}
return
result
;
}
// Private Methods /////////////////////////////////////////////////////////////////////////////
/**
* Get the resulting x-position of the left edge of the crop window given the handle's position
* and the image's bounding box and snap radius.
*
* @param x the x-position that the left edge is dragged to
* @param imageRect the bounding box of the image that is being cropped
* @param imageSnapRadius the snap distance to the image edge (in pixels)
*
* @return the actual x-position of the left edge
*/
private
static
float
adjustLeft
(
float
x
,
@NonNull
RectF
imageRect
,
float
imageSnapRadius
,
float
aspectRatio
)
{
final
float
resultX
;
if
(
x
-
imageRect
.
left
<
imageSnapRadius
)
{
resultX
=
imageRect
.
left
;
}
else
{
// Select the minimum of the three possible values to use
float
resultXHoriz
=
Float
.
POSITIVE_INFINITY
;
float
resultXVert
=
Float
.
POSITIVE_INFINITY
;
// Checks if the window is too small horizontally
if
(
x
>=
Edge
.
RIGHT
.
getCoordinate
()
-
MIN_CROP_LENGTH_PX
)
{
resultXHoriz
=
Edge
.
RIGHT
.
getCoordinate
()
-
MIN_CROP_LENGTH_PX
;
}
// Checks if the window is too small vertically
if
(((
Edge
.
RIGHT
.
getCoordinate
()
-
x
)
/
aspectRatio
)
<=
MIN_CROP_LENGTH_PX
)
{
resultXVert
=
Edge
.
RIGHT
.
getCoordinate
()
-
(
MIN_CROP_LENGTH_PX
*
aspectRatio
);
}
resultX
=
Math
.
min
(
x
,
Math
.
min
(
resultXHoriz
,
resultXVert
));
}
return
resultX
;
}
/**
* Get the resulting x-position of the right edge of the crop window given the handle's position
* and the image's bounding box and snap radius.
*
* @param x the x-position that the right edge is dragged to
* @param imageRect the bounding box of the image that is being cropped
* @param imageSnapRadius the snap distance to the image edge (in pixels)
*
* @return the actual x-position of the right edge
*/
private
static
float
adjustRight
(
float
x
,
@NonNull
RectF
imageRect
,
float
imageSnapRadius
,
float
aspectRatio
)
{
final
float
resultX
;
// If close to the edge...
if
(
imageRect
.
right
-
x
<
imageSnapRadius
)
{
resultX
=
imageRect
.
right
;
}
else
{
// Select the maximum of the three possible values to use
float
resultXHoriz
=
Float
.
NEGATIVE_INFINITY
;
float
resultXVert
=
Float
.
NEGATIVE_INFINITY
;
// Checks if the window is too small horizontally
if
(
x
<=
Edge
.
LEFT
.
getCoordinate
()
+
MIN_CROP_LENGTH_PX
)
{
resultXHoriz
=
Edge
.
LEFT
.
getCoordinate
()
+
MIN_CROP_LENGTH_PX
;
}
// Checks if the window is too small vertically
if
(((
x
-
Edge
.
LEFT
.
getCoordinate
())
/
aspectRatio
)
<=
MIN_CROP_LENGTH_PX
)
{
resultXVert
=
Edge
.
LEFT
.
getCoordinate
()
+
(
MIN_CROP_LENGTH_PX
*
aspectRatio
);
}
resultX
=
Math
.
max
(
x
,
Math
.
max
(
resultXHoriz
,
resultXVert
));
}
return
resultX
;
}
/**
* Get the resulting y-position of the top edge of the crop window given the handle's position
* and the image's bounding box and snap radius.
*
* @param y the x-position that the top edge is dragged to
* @param imageRect the bounding box of the image that is being cropped
* @param imageSnapRadius the snap distance to the image edge (in pixels)
*
* @return the actual y-position of the top edge
*/
private
static
float
adjustTop
(
float
y
,
@NonNull
RectF
imageRect
,
float
imageSnapRadius
,
float
aspectRatio
)
{
final
float
resultY
;
if
(
y
-
imageRect
.
top
<
imageSnapRadius
)
{
resultY
=
imageRect
.
top
;
}
else
{
// Select the minimum of the three possible values to use
float
resultYVert
=
Float
.
POSITIVE_INFINITY
;
float
resultYHoriz
=
Float
.
POSITIVE_INFINITY
;
// Checks if the window is too small vertically
if
(
y
>=
Edge
.
BOTTOM
.
getCoordinate
()
-
MIN_CROP_LENGTH_PX
)
resultYHoriz
=
Edge
.
BOTTOM
.
getCoordinate
()
-
MIN_CROP_LENGTH_PX
;
// Checks if the window is too small horizontally
if
(((
Edge
.
BOTTOM
.
getCoordinate
()
-
y
)
*
aspectRatio
)
<=
MIN_CROP_LENGTH_PX
)
resultYVert
=
Edge
.
BOTTOM
.
getCoordinate
()
-
(
MIN_CROP_LENGTH_PX
/
aspectRatio
);
resultY
=
Math
.
min
(
y
,
Math
.
min
(
resultYHoriz
,
resultYVert
));
}
return
resultY
;
}
/**
* Get the resulting y-position of the bottom edge of the crop window given the handle's
* position and the image's bounding box and snap radius.
*
* @param y the x-position that the bottom edge is dragged to
* @param imageRect the bounding box of the image that is being cropped
* @param imageSnapRadius the snap distance to the image edge (in pixels)
*
* @return the actual y-position of the bottom edge
*/
private
static
float
adjustBottom
(
float
y
,
@NonNull
RectF
imageRect
,
float
imageSnapRadius
,
float
aspectRatio
)
{
final
float
resultY
;
if
(
imageRect
.
bottom
-
y
<
imageSnapRadius
)
{
resultY
=
imageRect
.
bottom
;
}
else
{
// Select the maximum of the three possible values to use
float
resultYVert
=
Float
.
NEGATIVE_INFINITY
;
float
resultYHoriz
=
Float
.
NEGATIVE_INFINITY
;
// Checks if the window is too small vertically
if
(
y
<=
Edge
.
TOP
.
getCoordinate
()
+
MIN_CROP_LENGTH_PX
)
{
resultYVert
=
Edge
.
TOP
.
getCoordinate
()
+
MIN_CROP_LENGTH_PX
;
}
// Checks if the window is too small horizontally
if
(((
y
-
Edge
.
TOP
.
getCoordinate
())
*
aspectRatio
)
<=
MIN_CROP_LENGTH_PX
)
{
resultYHoriz
=
Edge
.
TOP
.
getCoordinate
()
+
(
MIN_CROP_LENGTH_PX
/
aspectRatio
);
}
resultY
=
Math
.
max
(
y
,
Math
.
max
(
resultYHoriz
,
resultYVert
));
}
return
resultY
;
}
}
android/Pictogram/tabletlibrary/src/main/java/com/yottacode/pictogram/tabletlibrary/cropper/cropwindow/edge/EdgePair.java
0 → 100644
View file @
4829118e
package
com
.
yottacode
.
pictogram
.
tabletlibrary
.
cropper
.
cropwindow
.
edge
;
/**
* Simple class to hold a pair of Edges.
*/
public
class
EdgePair
{
// Member Variables ////////////////////////////////////////////////////////
public
Edge
primary
;
public
Edge
secondary
;
// Constructor /////////////////////////////////////////////////////////////
public
EdgePair
(
Edge
edge1
,
Edge
edge2
)
{
primary
=
edge1
;
secondary
=
edge2
;
}
}
android/Pictogram/tabletlibrary/src/main/java/com/yottacode/pictogram/tabletlibrary/cropper/cropwindow/handle/CenterHandleHelper.java
0 → 100644
View file @
4829118e
package
com
.
yottacode
.
pictogram
.
tabletlibrary
.
cropper
.
cropwindow
.
handle
;
import
android.graphics.RectF
;
import
android.support.annotation.NonNull
;
import
com.yottacode.pictogram.tabletlibrary.cropper.cropwindow.edge.Edge
;
/**
* HandleHelper class to handle the center handle.
*/
class
CenterHandleHelper
extends
HandleHelper
{
// Constructor /////////////////////////////////////////////////////////////////////////////////
CenterHandleHelper
()
{
super
(
null
,
null
);
}
// HandleHelper Methods ////////////////////////////////////////////////////////////////////////
@Override
void
updateCropWindow
(
float
x
,
float
y
,
@NonNull
RectF
imageRect
,
float
snapRadius
)
{
float
left
=
Edge
.
LEFT
.
getCoordinate
();
float
top
=
Edge
.
TOP
.
getCoordinate
();
float
right
=
Edge
.
RIGHT
.
getCoordinate
();
float
bottom
=
Edge
.
BOTTOM
.
getCoordinate
();
final
float
currentCenterX
=
(
left
+
right
)
/
2
;
final
float
currentCenterY
=
(
top
+
bottom
)
/
2
;
final
float
offsetX
=
x
-
currentCenterX
;
final
float
offsetY
=
y
-
currentCenterY
;
// Adjust the crop window.
Edge
.
LEFT
.
offset
(
offsetX
);
Edge
.
TOP
.
offset
(
offsetY
);
Edge
.
RIGHT
.
offset
(
offsetX
);
Edge
.
BOTTOM
.
offset
(
offsetY
);
// Check if we have gone out of bounds on the sides, and fix.
if
(
Edge
.
LEFT
.
isOutsideMargin
(
imageRect
,
snapRadius
))
{
final
float
offset
=
Edge
.
LEFT
.
snapToRect
(
imageRect
);
Edge
.
RIGHT
.
offset
(
offset
);
}
else
if
(
Edge
.
RIGHT
.
isOutsideMargin
(
imageRect
,
snapRadius
))
{
final
float
offset
=
Edge
.
RIGHT
.
snapToRect
(
imageRect
);
Edge
.
LEFT
.
offset
(
offset
);
}
// Check if we have gone out of bounds on the top or bottom, and fix.
if
(
Edge
.
TOP
.
isOutsideMargin
(
imageRect
,
snapRadius
))
{
final
float
offset
=
Edge
.
TOP
.
snapToRect
(
imageRect
);
Edge
.
BOTTOM
.
offset
(
offset
);
}
else
if
(
Edge
.
BOTTOM
.
isOutsideMargin
(
imageRect
,
snapRadius
))
{
final
float
offset
=
Edge
.
BOTTOM
.
snapToRect
(
imageRect
);
Edge
.
TOP
.
offset
(
offset
);
}
}
@Override
void
updateCropWindow
(
float
x
,
float
y
,
float
targetAspectRatio
,
@NonNull
RectF
imageRect
,
float
snapRadius
)
{
updateCropWindow
(
x
,
y
,
imageRect
,
snapRadius
);
}
}
android/Pictogram/tabletlibrary/src/main/java/com/yottacode/pictogram/tabletlibrary/cropper/cropwindow/handle/CornerHandleHelper.java
0 → 100644
View file @
4829118e
package
com
.
yottacode
.
pictogram
.
tabletlibrary
.
cropper
.
cropwindow
.
handle
;
import
android.graphics.RectF
;
import
android.support.annotation.NonNull
;
import
com.yottacode.pictogram.tabletlibrary.cropper.cropwindow.edge.Edge
;
import
com.yottacode.pictogram.tabletlibrary.cropper.cropwindow.edge.EdgePair
;
/**
* HandleHelper class to handle corner Handles (i.e. top-left, top-right, bottom-left, and
* bottom-right handles).
*/
class
CornerHandleHelper
extends
HandleHelper
{
// Constructor /////////////////////////////////////////////////////////////////////////////////
CornerHandleHelper
(
Edge
horizontalEdge
,
Edge
verticalEdge
)
{
super
(
horizontalEdge
,
verticalEdge
);
}
// HandleHelper Methods ////////////////////////////////////////////////////////////////////////
@Override
void
updateCropWindow
(
float
x
,
float
y
,
float
targetAspectRatio
,
@NonNull
RectF
imageRect
,
float
snapRadius
)
{
final
EdgePair
activeEdges
=
getActiveEdges
(
x
,
y
,
targetAspectRatio
);
final
Edge
primaryEdge
=
activeEdges
.
primary
;
final
Edge
secondaryEdge
=
activeEdges
.
secondary
;
primaryEdge
.
adjustCoordinate
(
x
,
y
,
imageRect
,
snapRadius
,
targetAspectRatio
);
secondaryEdge
.
adjustCoordinate
(
targetAspectRatio
);
if
(
secondaryEdge
.
isOutsideMargin
(
imageRect
,
snapRadius
))
{
secondaryEdge
.
snapToRect
(
imageRect
);
primaryEdge
.
adjustCoordinate
(
targetAspectRatio
);
}
}
}
android/Pictogram/tabletlibrary/src/main/java/com/yottacode/pictogram/tabletlibrary/cropper/cropwindow/handle/Handle.java
0 → 100644
View file @
4829118e
package
com
.
yottacode
.
pictogram
.
tabletlibrary
.
cropper
.
cropwindow
.
handle
;
import
android.graphics.RectF
;
import
android.support.annotation.NonNull
;
import
com.yottacode.pictogram.tabletlibrary.cropper.cropwindow.edge.Edge
;
/**
* Enum representing a pressable, draggable Handle on the crop window.
*/
public
enum
Handle
{
TOP_LEFT
(
new
CornerHandleHelper
(
Edge
.
TOP
,
Edge
.
LEFT
)),
TOP_RIGHT
(
new
CornerHandleHelper
(
Edge
.
TOP
,
Edge
.
RIGHT
)),
BOTTOM_LEFT
(
new
CornerHandleHelper
(
Edge
.
BOTTOM
,
Edge
.
LEFT
)),
BOTTOM_RIGHT
(
new
CornerHandleHelper
(
Edge
.
BOTTOM
,
Edge
.
RIGHT
)),
LEFT
(
new
VerticalHandleHelper
(
Edge
.
LEFT
)),
TOP
(
new
HorizontalHandleHelper
(
Edge
.
TOP
)),
RIGHT
(
new
VerticalHandleHelper
(
Edge
.
RIGHT
)),
BOTTOM
(
new
HorizontalHandleHelper
(
Edge
.
BOTTOM
)),
CENTER
(
new
CenterHandleHelper
());
// Member Variables ////////////////////////////////////////////////////////////////////////////
private
HandleHelper
mHelper
;
// Constructors ////////////////////////////////////////////////////////////////////////////////
Handle
(
HandleHelper
helper
)
{
mHelper
=
helper
;
}
// Public Methods //////////////////////////////////////////////////////////
public
void
updateCropWindow
(
float
x
,
float
y
,
@NonNull
RectF
imageRect
,
float
snapRadius
)
{
mHelper
.
updateCropWindow
(
x
,
y
,
imageRect
,
snapRadius
);
}
public
void
updateCropWindow
(
float
x
,
float
y
,
float
targetAspectRatio
,
@NonNull
RectF
imageRect
,
float
snapRadius
)
{
mHelper
.
updateCropWindow
(
x
,
y
,
targetAspectRatio
,
imageRect
,
snapRadius
);
}
}
android/Pictogram/tabletlibrary/src/main/java/com/yottacode/pictogram/tabletlibrary/cropper/cropwindow/handle/HandleHelper.java
0 → 100644
View file @
4829118e
package
com
.
yottacode
.
pictogram
.
tabletlibrary
.
cropper
.
cropwindow
.
handle
;
import
android.graphics.RectF
;
import
android.support.annotation.NonNull
;
import
com.yottacode.pictogram.tabletlibrary.cropper.cropwindow.edge.Edge
;
import
com.yottacode.pictogram.tabletlibrary.cropper.cropwindow.edge.EdgePair
;
import
com.yottacode.pictogram.tabletlibrary.cropper.util.AspectRatioUtil
;
/**
* Abstract helper class to handle operations on a crop window Handle.
*/
abstract
class
HandleHelper
{
// Member Variables ////////////////////////////////////////////////////////
private
static
final
float
UNFIXED_ASPECT_RATIO_CONSTANT
=
1
;
private
Edge
mHorizontalEdge
;
private
Edge
mVerticalEdge
;
// Save the Pair object as a member variable to avoid having to instantiate
// a new Object every time getActiveEdges() is called.
private
EdgePair
mActiveEdges
;
// Constructor /////////////////////////////////////////////////////////////////////////////////
/**
* Constructor.
*
* @param horizontalEdge the horizontal edge associated with this handle; may be null
* @param verticalEdge the vertical edge associated with this handle; may be null
*/
HandleHelper
(
Edge
horizontalEdge
,
Edge
verticalEdge
)
{
mHorizontalEdge
=
horizontalEdge
;
mVerticalEdge
=
verticalEdge
;
mActiveEdges
=
new
EdgePair
(
mHorizontalEdge
,
mVerticalEdge
);
}
// Package-Private Methods /////////////////////////////////////////////////////////////////////
/**
* Updates the crop window by directly setting the Edge coordinates.
*
* @param x the new x-coordinate of this handle
* @param y the new y-coordinate of this handle
* @param imageRect the bounding rectangle of the image
* @param snapRadius the maximum distance (in pixels) at which the crop window should snap to
* the image
*/
void
updateCropWindow
(
float
x
,
float
y
,
@NonNull
RectF
imageRect
,
float
snapRadius
)
{
final
EdgePair
activeEdges
=
getActiveEdges
();
final
Edge
primaryEdge
=
activeEdges
.
primary
;
final
Edge
secondaryEdge
=
activeEdges
.
secondary
;
if
(
primaryEdge
!=
null
)
primaryEdge
.
adjustCoordinate
(
x
,
y
,
imageRect
,
snapRadius
,
UNFIXED_ASPECT_RATIO_CONSTANT
);
if
(
secondaryEdge
!=
null
)
secondaryEdge
.
adjustCoordinate
(
x
,
y
,
imageRect
,
snapRadius
,
UNFIXED_ASPECT_RATIO_CONSTANT
);
}
/**
* Updates the crop window by directly setting the Edge coordinates; this method maintains a
* given aspect ratio.
*
* @param x the new x-coordinate of this handle
* @param y the new y-coordinate of this handle
* @param targetAspectRatio the aspect ratio to maintain
* @param imageRect the bounding rectangle of the image
* @param snapRadius the maximum distance (in pixels) at which the crop window should
* snap to the image
*/
abstract
void
updateCropWindow
(
float
x
,
float
y
,
float
targetAspectRatio
,
@NonNull
RectF
imageRect
,
float
snapRadius
);
/**
* Gets the Edges associated with this handle (i.e. the Edges that should be moved when this
* handle is dragged). This is used when we are not maintaining the aspect ratio.
*
* @return the active edge as a pair (the pair may contain null values for the
* <code>primary</code>, <code>secondary</code> or both fields)
*/
EdgePair
getActiveEdges
()
{
return
mActiveEdges
;
}
/**
* Gets the Edges associated with this handle as an ordered Pair. The <code>primary</code> Edge
* in the pair is the determining side. This method is used when we need to maintain the aspect
* ratio.
*
* @param x the x-coordinate of the touch point
* @param y the y-coordinate of the touch point
* @param targetAspectRatio the aspect ratio that we are maintaining
*
* @return the active edges as an ordered pair
*/
EdgePair
getActiveEdges
(
float
x
,
float
y
,
float
targetAspectRatio
)
{
// Calculate the aspect ratio if this handle were dragged to the given x-y coordinate.
final
float
potentialAspectRatio
=
getAspectRatio
(
x
,
y
);
// If the touched point is wider than the aspect ratio, then x is the determining side. Else, y is the determining side.
if
(
potentialAspectRatio
>
targetAspectRatio
)
{
mActiveEdges
.
primary
=
mVerticalEdge
;
mActiveEdges
.
secondary
=
mHorizontalEdge
;
}
else
{
mActiveEdges
.
primary
=
mHorizontalEdge
;
mActiveEdges
.
secondary
=
mVerticalEdge
;
}
return
mActiveEdges
;
}
// Private Methods /////////////////////////////////////////////////////////////////////////////
/**
* Gets the aspect ratio of the resulting crop window if this handle were dragged to the given
* point.
*
* @param x the x-coordinate
* @param y the y-coordinate
*
* @return the aspect ratio
*/
private
float
getAspectRatio
(
float
x
,
float
y
)
{
// Replace the active edge coordinate with the given touch coordinate.
final
float
left
=
(
mVerticalEdge
==
Edge
.
LEFT
)
?
x
:
Edge
.
LEFT
.
getCoordinate
();
final
float
top
=
(
mHorizontalEdge
==
Edge
.
TOP
)
?
y
:
Edge
.
TOP
.
getCoordinate
();
final
float
right
=
(
mVerticalEdge
==
Edge
.
RIGHT
)
?
x
:
Edge
.
RIGHT
.
getCoordinate
();
final
float
bottom
=
(
mHorizontalEdge
==
Edge
.
BOTTOM
)
?
y
:
Edge
.
BOTTOM
.
getCoordinate
();
return
AspectRatioUtil
.
calculateAspectRatio
(
left
,
top
,
right
,
bottom
);
}
}
android/Pictogram/tabletlibrary/src/main/java/com/yottacode/pictogram/tabletlibrary/cropper/cropwindow/handle/HorizontalHandleHelper.java
0 → 100644
View file @
4829118e
package
com
.
yottacode
.
pictogram
.
tabletlibrary
.
cropper
.
cropwindow
.
handle
;
import
android.graphics.RectF
;
import
android.support.annotation.NonNull
;
import
com.yottacode.pictogram.tabletlibrary.cropper.cropwindow.edge.Edge
;
import
com.yottacode.pictogram.tabletlibrary.cropper.util.AspectRatioUtil
;
/**
* Handle helper class to handle horizontal handles (i.e. top and bottom handles).
*/
class
HorizontalHandleHelper
extends
HandleHelper
{
// Member Variables ////////////////////////////////////////////////////////////////////////////
private
Edge
mEdge
;
// Constructor /////////////////////////////////////////////////////////////////////////////////
HorizontalHandleHelper
(
Edge
edge
)
{
super
(
edge
,
null
);
mEdge
=
edge
;
}
// HandleHelper Methods ////////////////////////////////////////////////////////////////////////
@Override
void
updateCropWindow
(
float
x
,
float
y
,
float
targetAspectRatio
,
@NonNull
RectF
imageRect
,
float
snapRadius
)
{
// Adjust this Edge accordingly.
mEdge
.
adjustCoordinate
(
x
,
y
,
imageRect
,
snapRadius
,
targetAspectRatio
);
float
left
=
Edge
.
LEFT
.
getCoordinate
();
float
right
=
Edge
.
RIGHT
.
getCoordinate
();
// After this Edge is moved, our crop window is now out of proportion.
final
float
targetWidth
=
AspectRatioUtil
.
calculateWidth
(
Edge
.
getHeight
(),
targetAspectRatio
);
// Adjust the crop window so that it maintains the given aspect ratio by
// moving the adjacent edges symmetrically in or out.
final
float
difference
=
targetWidth
-
Edge
.
getWidth
();
final
float
halfDifference
=
difference
/
2
;
left
-=
halfDifference
;
right
+=
halfDifference
;
Edge
.
LEFT
.
setCoordinate
(
left
);
Edge
.
RIGHT
.
setCoordinate
(
right
);
// Check if we have gone out of bounds on the sides, and fix.
if
(
Edge
.
LEFT
.
isOutsideMargin
(
imageRect
,
snapRadius
)
&&
!
mEdge
.
isNewRectangleOutOfBounds
(
Edge
.
LEFT
,
imageRect
,
targetAspectRatio
))
{
final
float
offset
=
Edge
.
LEFT
.
snapToRect
(
imageRect
);
Edge
.
RIGHT
.
offset
(-
offset
);
mEdge
.
adjustCoordinate
(
targetAspectRatio
);
}
if
(
Edge
.
RIGHT
.
isOutsideMargin
(
imageRect
,
snapRadius
)
&&
!
mEdge
.
isNewRectangleOutOfBounds
(
Edge
.
RIGHT
,
imageRect
,
targetAspectRatio
))
{
final
float
offset
=
Edge
.
RIGHT
.
snapToRect
(
imageRect
);
Edge
.
LEFT
.
offset
(-
offset
);
mEdge
.
adjustCoordinate
(
targetAspectRatio
);
}
}
}
android/Pictogram/tabletlibrary/src/main/java/com/yottacode/pictogram/tabletlibrary/cropper/cropwindow/handle/VerticalHandleHelper.java
0 → 100644
View file @
4829118e
package
com
.
yottacode
.
pictogram
.
tabletlibrary
.
cropper
.
cropwindow
.
handle
;
import
android.graphics.RectF
;
import
android.support.annotation.NonNull
;
import
com.yottacode.pictogram.tabletlibrary.cropper.cropwindow.edge.Edge
;
import
com.yottacode.pictogram.tabletlibrary.cropper.util.AspectRatioUtil
;
/**
* HandleHelper class to handle vertical handles (i.e. left and right handles).
*/
class
VerticalHandleHelper
extends
HandleHelper
{
// Member Variables ////////////////////////////////////////////////////////////////////////////
private
Edge
mEdge
;
// Constructor /////////////////////////////////////////////////////////////////////////////////
VerticalHandleHelper
(
Edge
edge
)
{
super
(
null
,
edge
);
mEdge
=
edge
;
}
// HandleHelper Methods ////////////////////////////////////////////////////////////////////////
@Override
void
updateCropWindow
(
float
x
,
float
y
,
float
targetAspectRatio
,
@NonNull
RectF
imageRect
,
float
snapRadius
)
{
// Adjust this Edge accordingly.
mEdge
.
adjustCoordinate
(
x
,
y
,
imageRect
,
snapRadius
,
targetAspectRatio
);
float
top
=
Edge
.
TOP
.
getCoordinate
();
float
bottom
=
Edge
.
BOTTOM
.
getCoordinate
();
// After this Edge is moved, our crop window is now out of proportion.
final
float
targetHeight
=
AspectRatioUtil
.
calculateHeight
(
Edge
.
getWidth
(),
targetAspectRatio
);
// Adjust the crop window so that it maintains the given aspect ratio by
// moving the adjacent edges symmetrically in or out.
final
float
difference
=
targetHeight
-
Edge
.
getHeight
();
final
float
halfDifference
=
difference
/
2
;
top
-=
halfDifference
;
bottom
+=
halfDifference
;
Edge
.
TOP
.
setCoordinate
(
top
);
Edge
.
BOTTOM
.
setCoordinate
(
bottom
);
// Check if we have gone out of bounds on the top or bottom, and fix.
if
(
Edge
.
TOP
.
isOutsideMargin
(
imageRect
,
snapRadius
)
&&
!
mEdge
.
isNewRectangleOutOfBounds
(
Edge
.
TOP
,
imageRect
,
targetAspectRatio
))
{
final
float
offset
=
Edge
.
TOP
.
snapToRect
(
imageRect
);
Edge
.
BOTTOM
.
offset
(-
offset
);
mEdge
.
adjustCoordinate
(
targetAspectRatio
);
}
if
(
Edge
.
BOTTOM
.
isOutsideMargin
(
imageRect
,
snapRadius
)
&&
!
mEdge
.
isNewRectangleOutOfBounds
(
Edge
.
BOTTOM
,
imageRect
,
targetAspectRatio
))
{
final
float
offset
=
Edge
.
BOTTOM
.
snapToRect
(
imageRect
);
Edge
.
TOP
.
offset
(-
offset
);
mEdge
.
adjustCoordinate
(
targetAspectRatio
);
}
}
}
android/Pictogram/tabletlibrary/src/main/java/com/yottacode/pictogram/tabletlibrary/cropper/util/AspectRatioUtil.java
0 → 100644
View file @
4829118e
package
com
.
yottacode
.
pictogram
.
tabletlibrary
.
cropper
.
util
;
import
android.graphics.RectF
;
import
android.support.annotation.NonNull
;
/**
* Utility class for handling calculations involving a fixed aspect ratio.
*/
public
class
AspectRatioUtil
{
/**
* Calculates the aspect ratio given a rectangle.
*/
public
static
float
calculateAspectRatio
(
float
left
,
float
top
,
float
right
,
float
bottom
)
{
final
float
width
=
right
-
left
;
final
float
height
=
bottom
-
top
;
return
width
/
height
;
}
/**
* Calculates the aspect ratio given a rectangle.
*/
public
static
float
calculateAspectRatio
(
@NonNull
RectF
rect
)
{
return
rect
.
width
()
/
rect
.
height
();
}
/**
* Calculates the x-coordinate of the left edge given the other sides of the rectangle and an
* aspect ratio.
*/
public
static
float
calculateLeft
(
float
top
,
float
right
,
float
bottom
,
float
targetAspectRatio
)
{
final
float
height
=
bottom
-
top
;
// targetAspectRatio = width / height
// width = targetAspectRatio * height
// right - left = targetAspectRatio * height
return
right
-
(
targetAspectRatio
*
height
);
}
/**
* Calculates the y-coordinate of the top edge given the other sides of the rectangle and an
* aspect ratio.
*/
public
static
float
calculateTop
(
float
left
,
float
right
,
float
bottom
,
float
targetAspectRatio
)
{
final
float
width
=
right
-
left
;
// targetAspectRatio = width / height
// width = targetAspectRatio * height
// height = width / targetAspectRatio
// bottom - top = width / targetAspectRatio
return
bottom
-
(
width
/
targetAspectRatio
);
}
/**
* Calculates the x-coordinate of the right edge given the other sides of the rectangle and an
* aspect ratio.
*/
public
static
float
calculateRight
(
float
left
,
float
top
,
float
bottom
,
float
targetAspectRatio
)
{
final
float
height
=
bottom
-
top
;
// targetAspectRatio = width / height
// width = targetAspectRatio * height
// right - left = targetAspectRatio * height
return
(
targetAspectRatio
*
height
)
+
left
;
}
/**
* Calculates the y-coordinate of the bottom edge given the other sides of the rectangle and an
* aspect ratio.
*/
public
static
float
calculateBottom
(
float
left
,
float
top
,
float
right
,
float
targetAspectRatio
)
{
final
float
width
=
right
-
left
;
// targetAspectRatio = width / height
// width = targetAspectRatio * height
// height = width / targetAspectRatio
// bottom - top = width / targetAspectRatio
return
(
width
/
targetAspectRatio
)
+
top
;
}
/**
* Calculates the width of a rectangle given the top and bottom edges and an aspect ratio.
*/
public
static
float
calculateWidth
(
float
height
,
float
targetAspectRatio
)
{
return
targetAspectRatio
*
height
;
}
/**
* Calculates the height of a rectangle given the left and right edges and an aspect ratio.
*/
public
static
float
calculateHeight
(
float
width
,
float
targetAspectRatio
)
{
return
width
/
targetAspectRatio
;
}
}
android/Pictogram/tabletlibrary/src/main/java/com/yottacode/pictogram/tabletlibrary/cropper/util/HandleUtil.java
0 → 100644
View file @
4829118e
package
com
.
yottacode
.
pictogram
.
tabletlibrary
.
cropper
.
util
;
import
android.graphics.PointF
;
import
android.support.annotation.NonNull
;
import
com.yottacode.pictogram.tabletlibrary.cropper.cropwindow.handle.Handle
;
/**
* Utility class to perform basic operations with Handles.
*/
public
class
HandleUtil
{
// Public Methods //////////////////////////////////////////////////////////////////////////////
/**
* Determines which, if any, of the handles are pressed given the touch coordinates, the
* bounding box, and the touch radius.
*
* @param x the x-coordinate of the touch point
* @param y the y-coordinate of the touch point
* @param left the x-coordinate of the left bound
* @param top the y-coordinate of the top bound
* @param right the x-coordinate of the right bound
* @param bottom the y-coordinate of the bottom bound
* @param targetRadius the target radius in pixels
*
* @return the Handle that was pressed; null if no Handle was pressed
*/
public
static
Handle
getPressedHandle
(
float
x
,
float
y
,
float
left
,
float
top
,
float
right
,
float
bottom
,
float
targetRadius
)
{
// Find the closest corner handle to the touch point.
// If the touch point is in the target zone of this closest handle, then this is the pressed handle.
// Else, check if any of the edges are in the target zone of the touch point.
// Else, check if the touch point is within the crop window bounds; if so, then choose the center handle.
Handle
closestHandle
=
null
;
float
closestDistance
=
Float
.
POSITIVE_INFINITY
;
final
float
distanceToTopLeft
=
MathUtil
.
calculateDistance
(
x
,
y
,
left
,
top
);
if
(
distanceToTopLeft
<
closestDistance
)
{
closestDistance
=
distanceToTopLeft
;
closestHandle
=
Handle
.
TOP_LEFT
;
}
final
float
distanceToTopRight
=
MathUtil
.
calculateDistance
(
x
,
y
,
right
,
top
);
if
(
distanceToTopRight
<
closestDistance
)
{
closestDistance
=
distanceToTopRight
;
closestHandle
=
Handle
.
TOP_RIGHT
;
}
final
float
distanceToBottomLeft
=
MathUtil
.
calculateDistance
(
x
,
y
,
left
,
bottom
);
if
(
distanceToBottomLeft
<
closestDistance
)
{
closestDistance
=
distanceToBottomLeft
;
closestHandle
=
Handle
.
BOTTOM_LEFT
;
}
final
float
distanceToBottomRight
=
MathUtil
.
calculateDistance
(
x
,
y
,
right
,
bottom
);
if
(
distanceToBottomRight
<
closestDistance
)
{
closestDistance
=
distanceToBottomRight
;
closestHandle
=
Handle
.
BOTTOM_RIGHT
;
}
if
(
closestDistance
<=
targetRadius
)
{
return
closestHandle
;
}
// If we get to this point, none of the corner handles were in the touch target zone, so then we check the edges.
if
(
HandleUtil
.
isInHorizontalTargetZone
(
x
,
y
,
left
,
right
,
top
,
targetRadius
))
{
return
Handle
.
TOP
;
}
else
if
(
HandleUtil
.
isInHorizontalTargetZone
(
x
,
y
,
left
,
right
,
bottom
,
targetRadius
))
{
return
Handle
.
BOTTOM
;
}
else
if
(
HandleUtil
.
isInVerticalTargetZone
(
x
,
y
,
left
,
top
,
bottom
,
targetRadius
))
{
return
Handle
.
LEFT
;
}
else
if
(
HandleUtil
.
isInVerticalTargetZone
(
x
,
y
,
right
,
top
,
bottom
,
targetRadius
))
{
return
Handle
.
RIGHT
;
}
// If we get to this point, none of the corners or edges are in the touch target zone.
// Check to see if the touch point is within the bounds of the crop window. If so, choose the center handle.
if
(
isWithinBounds
(
x
,
y
,
left
,
top
,
right
,
bottom
))
{
return
Handle
.
CENTER
;
}
return
null
;
}
/**
* Calculates the offset of the touch point from the precise location of the specified handle.
* <p/>
* The offset will be returned in the 'touchOffsetOutput' parameter; the x-offset will be the
* first value and the y-offset will be the second value.
*/
public
static
void
getOffset
(
@NonNull
Handle
handle
,
float
x
,
float
y
,
float
left
,
float
top
,
float
right
,
float
bottom
,
@NonNull
PointF
touchOffsetOutput
)
{
float
touchOffsetX
=
0
;
float
touchOffsetY
=
0
;
// Calculate the offset from the appropriate handle.
switch
(
handle
)
{
case
TOP_LEFT:
touchOffsetX
=
left
-
x
;
touchOffsetY
=
top
-
y
;
break
;
case
TOP_RIGHT:
touchOffsetX
=
right
-
x
;
touchOffsetY
=
top
-
y
;
break
;
case
BOTTOM_LEFT:
touchOffsetX
=
left
-
x
;
touchOffsetY
=
bottom
-
y
;
break
;
case
BOTTOM_RIGHT:
touchOffsetX
=
right
-
x
;
touchOffsetY
=
bottom
-
y
;
break
;
case
LEFT:
touchOffsetX
=
left
-
x
;
touchOffsetY
=
0
;
break
;
case
TOP:
touchOffsetX
=
0
;
touchOffsetY
=
top
-
y
;
break
;
case
RIGHT:
touchOffsetX
=
right
-
x
;
touchOffsetY
=
0
;
break
;
case
BOTTOM:
touchOffsetX
=
0
;
touchOffsetY
=
bottom
-
y
;
break
;
case
CENTER:
final
float
centerX
=
(
right
+
left
)
/
2
;
final
float
centerY
=
(
top
+
bottom
)
/
2
;
touchOffsetX
=
centerX
-
x
;
touchOffsetY
=
centerY
-
y
;
break
;
}
touchOffsetOutput
.
x
=
touchOffsetX
;
touchOffsetOutput
.
y
=
touchOffsetY
;
}
// Private Methods /////////////////////////////////////////////////////////////////////////////
/**
* Determines if the specified coordinate is in the target touch zone for a horizontal bar
* handle.
*
* @param x the x-coordinate of the touch point
* @param y the y-coordinate of the touch point
* @param handleXStart the left x-coordinate of the horizontal bar handle
* @param handleXEnd the right x-coordinate of the horizontal bar handle
* @param handleY the y-coordinate of the horizontal bar handle
* @param targetRadius the target radius in pixels
*
* @return true if the touch point is in the target touch zone; false otherwise
*/
private
static
boolean
isInHorizontalTargetZone
(
float
x
,
float
y
,
float
handleXStart
,
float
handleXEnd
,
float
handleY
,
float
targetRadius
)
{
return
(
x
>
handleXStart
&&
x
<
handleXEnd
&&
Math
.
abs
(
y
-
handleY
)
<=
targetRadius
);
}
/**
* Determines if the specified coordinate is in the target touch zone for a vertical bar
* handle.
*
* @param x the x-coordinate of the touch point
* @param y the y-coordinate of the touch point
* @param handleX the x-coordinate of the vertical bar handle
* @param handleYStart the top y-coordinate of the vertical bar handle
* @param handleYEnd the bottom y-coordinate of the vertical bar handle
* @param targetRadius the target radius in pixels
*
* @return true if the touch point is in the target touch zone; false otherwise
*/
private
static
boolean
isInVerticalTargetZone
(
float
x
,
float
y
,
float
handleX
,
float
handleYStart
,
float
handleYEnd
,
float
targetRadius
)
{
return
(
Math
.
abs
(
x
-
handleX
)
<=
targetRadius
&&
y
>
handleYStart
&&
y
<
handleYEnd
);
}
private
static
boolean
isWithinBounds
(
float
x
,
float
y
,
float
left
,
float
top
,
float
right
,
float
bottom
)
{
return
x
>=
left
&&
x
<=
right
&&
y
>=
top
&&
y
<=
bottom
;
}
}
android/Pictogram/tabletlibrary/src/main/java/com/yottacode/pictogram/tabletlibrary/cropper/util/MathUtil.java
0 → 100644
View file @
4829118e
package
com
.
yottacode
.
pictogram
.
tabletlibrary
.
cropper
.
util
;
public
class
MathUtil
{
/**
* Calculates the distance between two points (x1, y1) and (x2, y2).
*/
public
static
float
calculateDistance
(
float
x1
,
float
y1
,
float
x2
,
float
y2
)
{
final
float
side1
=
x2
-
x1
;
final
float
side2
=
y2
-
y1
;
return
(
float
)
Math
.
sqrt
(
side1
*
side1
+
side2
*
side2
);
}
}
android/Pictogram/tabletlibrary/src/main/java/com/yottacode/pictogram/tabletlibrary/cropper/util/PaintUtil.java
0 → 100644
View file @
4829118e
package
com
.
yottacode
.
pictogram
.
tabletlibrary
.
cropper
.
util
;
import
android.content.res.Resources
;
import
android.graphics.Paint
;
import
android.support.annotation.NonNull
;
import
com.yottacode.pictogram.tabletlibrary.R
;
/**
* Utility class for handling all of the Paint used to draw the CropOverlayView.
*/
public
class
PaintUtil
{
// Public Methods //////////////////////////////////////////////////////////
/**
* Creates the Paint object for drawing the crop window border.
*/
public
static
Paint
newBorderPaint
(
@NonNull
Resources
resources
)
{
final
Paint
paint
=
new
Paint
();
paint
.
setStyle
(
Paint
.
Style
.
STROKE
);
paint
.
setStrokeWidth
(
resources
.
getDimension
(
R
.
dimen
.
border_thickness
));
paint
.
setColor
(
resources
.
getColor
(
R
.
color
.
border
));
return
paint
;
}
/**
* Creates the Paint object for drawing the crop window guidelines.
*/
public
static
Paint
newGuidelinePaint
(
@NonNull
Resources
resources
)
{
final
Paint
paint
=
new
Paint
();
paint
.
setStyle
(
Paint
.
Style
.
STROKE
);
paint
.
setStrokeWidth
(
resources
.
getDimension
(
R
.
dimen
.
guideline_thickness
));
paint
.
setColor
(
resources
.
getColor
(
R
.
color
.
guideline
));
return
paint
;
}
/**
* Creates the Paint object for drawing the translucent overlay outside the crop window.
*
* @return the new Paint object
*/
public
static
Paint
newSurroundingAreaOverlayPaint
(
@NonNull
Resources
resources
)
{
final
Paint
paint
=
new
Paint
();
paint
.
setStyle
(
Paint
.
Style
.
FILL
);
paint
.
setColor
(
resources
.
getColor
(
R
.
color
.
surrounding_area
));
return
paint
;
}
/**
* Creates the Paint object for drawing the corners of the border
*/
public
static
Paint
newCornerPaint
(
@NonNull
Resources
resources
)
{
final
Paint
paint
=
new
Paint
();
paint
.
setStyle
(
Paint
.
Style
.
STROKE
);
paint
.
setStrokeWidth
(
resources
.
getDimension
(
R
.
dimen
.
corner_thickness
));
paint
.
setColor
(
resources
.
getColor
(
R
.
color
.
corner
));
return
paint
;
}
}
android/Pictogram/tabletlibrary/src/main/java/com/yottacode/pictogram/tabletlibrary/gui/communicator/PictoMenu.java
View file @
4829118e
...
@@ -6,12 +6,14 @@ import android.content.Context;
...
@@ -6,12 +6,14 @@ import android.content.Context;
import
android.content.DialogInterface
;
import
android.content.DialogInterface
;
import
android.content.Intent
;
import
android.content.Intent
;
import
android.database.Cursor
;
import
android.database.Cursor
;
import
android.graphics.Bitmap
;
import
android.net.Uri
;
import
android.net.Uri
;
import
android.provider.MediaStore
;
import
android.provider.MediaStore
;
import
android.text.InputType
;
import
android.text.InputType
;
import
android.util.Log
;
import
android.util.Log
;
import
android.view.View
;
import
android.view.View
;
import
android.view.inputmethod.InputMethodManager
;
import
android.view.inputmethod.InputMethodManager
;
import
android.widget.Button
;
import
android.widget.EditText
;
import
android.widget.EditText
;
import
android.widget.ImageButton
;
import
android.widget.ImageButton
;
import
android.widget.ImageView
;
import
android.widget.ImageView
;
...
@@ -24,6 +26,7 @@ import com.yottacode.pictogram.grammar.Vocabulary;
...
@@ -24,6 +26,7 @@ import com.yottacode.pictogram.grammar.Vocabulary;
import
com.yottacode.pictogram.grammar.iLocalPicto
;
import
com.yottacode.pictogram.grammar.iLocalPicto
;
import
com.yottacode.pictogram.net.PictoUploader
;
import
com.yottacode.pictogram.net.PictoUploader
;
import
com.yottacode.pictogram.tabletlibrary.R
;
import
com.yottacode.pictogram.tabletlibrary.R
;
import
com.yottacode.pictogram.tabletlibrary.cropper.CropImageView
;
import
com.yottacode.pictogram.tools.PCBcontext
;
import
com.yottacode.pictogram.tools.PCBcontext
;
import
java.io.IOException
;
import
java.io.IOException
;
...
@@ -417,8 +420,29 @@ public class PictoMenu {
...
@@ -417,8 +420,29 @@ public class PictoMenu {
public
List
<
RadialMenuWidget
.
RadialMenuEntry
>
getChildren
()
{
return
children
;
}
public
List
<
RadialMenuWidget
.
RadialMenuEntry
>
getChildren
()
{
return
children
;
}
public
void
menuActiviated
()
public
void
menuActiviated
()
{
{
ll
.
getChildAt
(
1
).
setX
(
ll
.
getChildAt
(
1
).
getX
()
+
30
);
/*ll.getChildAt(1).setX(ll.getChildAt(1).getX() + 30);
children
=
new
ArrayList
<>(
Arrays
.
asList
(
new
EditTextPicto
(
p
),
new
EditImage
(
p
)));
children = new ArrayList<>(Arrays.asList(new EditTextPicto(p),new EditImage(p)));*/
activity
.
setContentView
(
R
.
layout
.
crop_layout
);
final
CropImageView
cropImageView
=
(
CropImageView
)
activity
.
findViewById
(
R
.
id
.
CropImageView
);
cropImageView
.
setImageResource
(
R
.
drawable
.
descarga
);
final
ImageView
croppedImageView
=
(
ImageView
)
activity
.
findViewById
(
R
.
id
.
croppedImageView
);
final
Button
cropButton
=
(
Button
)
activity
.
findViewById
(
R
.
id
.
Button_crop
);
cropImageView
.
setGuidelines
(
CropImageView
.
GUIDELINES_ON
);
//To show the guidelines
cropImageView
.
setFixedAspectRatio
(
true
);
cropImageView
.
setAspectRatio
(
1
,
1
);
cropButton
.
setOnClickListener
(
new
View
.
OnClickListener
()
{
@Override
public
void
onClick
(
View
v
)
{
final
Bitmap
croppedImage
=
cropImageView
.
getCroppedImage
();
croppedImageView
.
setImageBitmap
(
croppedImage
);
}
});
}
}
public
void
menuDisabled
(){
public
void
menuDisabled
(){
ll
.
getChildAt
(
1
).
setX
(
ll
.
getChildAt
(
1
).
getX
()
-
30
);
ll
.
getChildAt
(
1
).
setX
(
ll
.
getChildAt
(
1
).
getX
()
-
30
);
...
...
android/Pictogram/tabletlibrary/src/main/res/layout/crop_layout.xml
0 → 100644
View file @
4829118e
<?xml version="1.0" encoding="utf-8"?>
<!--<ScrollView
android:id="@+id/scrollview"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".cropper.MainCropImage"
android:background="@color/black_translucent">
-->
<ScrollView
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:background=
"@color/black_translucent"
android:layout_alignParentTop=
"true"
android:layout_alignParentStart=
"true"
android:id=
"@+id/ScrollView"
>
<RelativeLayout
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:orientation=
"vertical"
android:id=
"@+id/TotalLayout"
>
<TextView
android:id=
"@+id/title"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:text=
"@string/titleCropper"
android:textSize=
"24sp"
android:textStyle=
"bold"
android:textColor=
"@color/common_google_signin_btn_text_dark_pressed"
android:layout_weight=
"1"
android:textAlignment=
"center"
android:layout_gravity=
"top"
android:layout_alignParentTop=
"true"
android:layout_alignParentStart=
"true"
/>
<com.yottacode.pictogram.tabletlibrary.cropper.CropImageView
android:id=
"@+id/CropImageView"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_marginTop=
"2dp"
android:adjustViewBounds=
"true"
android:scaleType=
"centerInside"
android:layout_below=
"@+id/title"
android:layout_alignParentStart=
"true"
/>
<Button
android:id=
"@+id/Button_crop"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:minWidth=
"120dp"
android:text=
"@string/crop"
android:textColor=
"#33B5E5"
android:textSize=
"20sp"
android:layout_gravity=
"center_vertical"
android:layout_marginTop=
"2dp"
android:layout_below=
"@+id/title"
android:layout_centerHorizontal=
"true"
/>
<ImageView
android:id=
"@+id/croppedImageView"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_marginTop=
"2dp"
android:adjustViewBounds=
"true"
android:contentDescription=
"@string/croppedImageDesc"
android:scaleType=
"centerInside"
/>
</RelativeLayout>
</ScrollView>
android/Pictogram/tabletlibrary/src/main/res/values/attrs.xml
0 → 100644
View file @
4829118e
<resources>
<declare-styleable
name=
"CropImageView"
>
<attr
name=
"guidelines"
>
<enum
name=
"off"
value=
"0"
/>
<enum
name=
"onTouch"
value=
"1"
/>
<enum
name=
"on"
value=
"2"
/>
</attr>
<attr
name=
"fixAspectRatio"
format=
"boolean"
/>
<attr
name=
"aspectRatioX"
format=
"integer"
/>
<attr
name=
"aspectRatioY"
format=
"integer"
/>
</declare-styleable>
</resources>
\ No newline at end of file
android/Pictogram/tabletlibrary/src/main/res/values/colors.xml
0 → 100644
View file @
4829118e
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color
name=
"white_translucent"
>
#AAFFFFFF
</color>
<color
name=
"black_translucent"
>
#b0000000
</color>
<color
name=
"border"
>
@color/white_translucent
</color>
<color
name=
"guideline"
>
@color/white_translucent
</color>
<color
name=
"corner"
>
@android:color/white
</color>
<color
name=
"surrounding_area"
>
@color/black_translucent
</color>
</resources>
android/Pictogram/tabletlibrary/src/main/res/values/dimen.xml
0 → 100644
View file @
4829118e
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen
name=
"border_thickness"
>
3dp
</dimen>
<dimen
name=
"corner_thickness"
>
5dp
</dimen>
<dimen
name=
"guideline_thickness"
>
1px
</dimen>
<dimen
name=
"target_radius"
>
24dp
</dimen>
<dimen
name=
"snap_radius"
>
3dp
</dimen>
<dimen
name=
"corner_length"
>
20dp
</dimen>
<dimen
name=
"content_padding"
>
16dp
</dimen>
<dimen
name=
"content_padding_half"
>
8dp
</dimen>
</resources>
android/Pictogram/tabletlibrary/src/main/res/values/strings.xml
View file @
4829118e
...
@@ -37,4 +37,20 @@
...
@@ -37,4 +37,20 @@
<string
name=
"session_eval_notevuated"
>
no evaluado
</string>
<string
name=
"session_eval_notevuated"
>
no evaluado
</string>
<string
name=
"session_eval_discarded"
>
inválido
</string>
<string
name=
"session_eval_discarded"
>
inválido
</string>
<!-- Cropper -->
<string
name=
"titleCropper"
>
Cropper
</string>
<string
name=
"fixedAspectRatio"
>
fixedAspectRatio =\u0020
</string>
<string
name=
"aspectRatioXHeader"
>
aspectRatioX =\u0020
</string>
<string
name=
"aspectRatioYHeader"
>
aspectRatioY =\u0020
</string>
<string
name=
"showGuidelines"
>
showGuidelines =\u0020
</string>
<string
name=
"crop"
>
Crop
</string>
<string
name=
"croppedImageDesc"
>
The cropped image.
</string>
<string-array
name=
"showGuidelinesArray"
>
<item>
Off
</item>
<item>
On Touch
</item>
<item>
On
</item>
</string-array>
</resources>
</resources>
android/Pictogram/tabletlibrary/tabletlibrary.iml
View file @
4829118e
...
@@ -69,13 +69,6 @@
...
@@ -69,13 +69,6 @@
<sourceFolder
url=
"file://$MODULE_DIR$/src/main/java"
isTestSource=
"false"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/main/java"
isTestSource=
"false"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/main/rs"
isTestSource=
"false"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/main/rs"
isTestSource=
"false"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/main/shaders"
isTestSource=
"false"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/main/shaders"
isTestSource=
"false"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/res"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/resources"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/assets"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/aidl"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/java"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/rs"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/shaders"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/test/res"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/test/res"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/test/resources"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/test/resources"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/test/assets"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/test/assets"
type=
"java-test-resource"
/>
...
@@ -83,7 +76,13 @@
...
@@ -83,7 +76,13 @@
<sourceFolder
url=
"file://$MODULE_DIR$/src/test/java"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/test/java"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/test/rs"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/test/rs"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/test/shaders"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/test/shaders"
isTestSource=
"true"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/annotations"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/res"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/resources"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/assets"
type=
"java-test-resource"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/aidl"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/java"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/rs"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/shaders"
isTestSource=
"true"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/blame"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/blame"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/bundles"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/bundles"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/classes"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/classes"
/>
...
@@ -99,16 +98,10 @@
...
@@ -99,16 +98,10 @@
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-vector-drawable/24.2.1/jars"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-vector-drawable/24.2.1/jars"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/incremental"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/incremental"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/incremental-safeguard"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/incremental-safeguard"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/jniLibs"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/lint"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/lint"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/manifests"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/manifests"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/res"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/res"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/rs"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/rs"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/shaders"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/symbols"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/transforms"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/typedefs.txt"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/outputs"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/tmp"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/tmp"
/>
</content>
</content>
<orderEntry
type=
"jdk"
jdkName=
"Android API 24 Platform"
jdkType=
"Android SDK"
/>
<orderEntry
type=
"jdk"
jdkName=
"Android API 24 Platform"
jdkType=
"Android SDK"
/>
...
...
android/Pictogram/watch/build.gradle
View file @
4829118e
...
@@ -25,6 +25,9 @@ android {
...
@@ -25,6 +25,9 @@ android {
DefaultFlavor
{
DefaultFlavor
{
resValue
"string"
,
"server"
,
"https://dev.yottacode.com"
resValue
"string"
,
"server"
,
"https://dev.yottacode.com"
}
}
LocalFlavor
{
resValue
"string"
,
"server"
,
"http://192.168.1.35:1337"
}
}
}
}
}
...
...
android/Pictogram/watch/watch.iml
View file @
4829118e
...
@@ -111,9 +111,6 @@
...
@@ -111,9 +111,6 @@
<sourceFolder
url=
"file://$MODULE_DIR$/src/test/java"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/test/java"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/test/rs"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/test/rs"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/test/shaders"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/test/shaders"
isTestSource=
"true"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/blame"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/classes"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/dependency-cache"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/recyclerview-v7/23.0.1/jars"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/recyclerview-v7/23.0.1/jars"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v4/23.0.1/jars"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v4/23.0.1/jars"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services-base/9.2.1/jars"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services-base/9.2.1/jars"
/>
...
@@ -122,13 +119,6 @@
...
@@ -122,13 +119,6 @@
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services-wearable/9.2.1/jars"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services-wearable/9.2.1/jars"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.support/wearable/2.0.0-alpha2/jars"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.support/wearable/2.0.0-alpha2/jars"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/incremental"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/incremental"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/incremental-safeguard"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/manifests"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/res"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/rs"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/symbols"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/outputs"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/tmp"
/>
</content>
</content>
<orderEntry
type=
"jdk"
jdkName=
"Android API 24 Platform"
jdkType=
"Android SDK"
/>
<orderEntry
type=
"jdk"
jdkName=
"Android API 24 Platform"
jdkType=
"Android SDK"
/>
<orderEntry
type=
"sourceFolder"
forTests=
"false"
/>
<orderEntry
type=
"sourceFolder"
forTests=
"false"
/>
...
...
android/Pictogram/yotta_tablet/yotta_tablet.iml
View file @
4829118e
...
@@ -111,10 +111,6 @@
...
@@ -111,10 +111,6 @@
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/java"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/java"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/rs"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/rs"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/shaders"
isTestSource=
"true"
/>
<sourceFolder
url=
"file://$MODULE_DIR$/src/androidTest/shaders"
isTestSource=
"true"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/assets"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/blame"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/classes"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/dependency-cache"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/animated-vector-drawable/24.2.1/jars"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/animated-vector-drawable/24.2.1/jars"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/appcompat-v7/24.2.1/jars"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/appcompat-v7/24.2.1/jars"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-compat/24.2.1/jars"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-compat/24.2.1/jars"
/>
...
@@ -125,17 +121,6 @@
...
@@ -125,17 +121,6 @@
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v4/24.2.1/jars"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v4/24.2.1/jars"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-vector-drawable/24.2.1/jars"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-vector-drawable/24.2.1/jars"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/incremental"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/incremental"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/incremental-safeguard"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/jniLibs"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/manifests"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/pre-dexed"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/res"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/rs"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/shaders"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/symbols"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/intermediates/transforms"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/outputs"
/>
<excludeFolder
url=
"file://$MODULE_DIR$/build/tmp"
/>
</content>
</content>
<orderEntry
type=
"jdk"
jdkName=
"Android API 24 Platform"
jdkType=
"Android SDK"
/>
<orderEntry
type=
"jdk"
jdkName=
"Android API 24 Platform"
jdkType=
"Android SDK"
/>
<orderEntry
type=
"sourceFolder"
forTests=
"false"
/>
<orderEntry
type=
"sourceFolder"
forTests=
"false"
/>
...
...
sails/src/api/models/Student.js
View file @
4829118e
...
@@ -179,6 +179,10 @@ module.exports = {
...
@@ -179,6 +179,10 @@ module.exports = {
size
:
'large'
,
size
:
'large'
,
picto_background
:
'#0000ff'
,
picto_background
:
'#0000ff'
,
tape_background
:
'#00ffff'
,
tape_background
:
'#00ffff'
,
delivery
:
0
// 0 -> delete strip after delivery
// 1 -> keep strip and on delivery
// 2 --> keep strip and several deliveries
};
};
sails
.
log
.
verbose
(
'Requested attributes for Student'
,
attributes
);
sails
.
log
.
verbose
(
'Requested attributes for Student'
,
attributes
);
...
@@ -213,6 +217,13 @@ module.exports = {
...
@@ -213,6 +217,13 @@ module.exports = {
if
(
typeof
validAttributes
.
legend
!==
'boolean'
)
{
if
(
typeof
validAttributes
.
legend
!==
'boolean'
)
{
delete
validAttributes
.
legend
;
delete
validAttributes
.
legend
;
}
}
if
(
typeof
validAttributes
.
delivery
!==
'number'
)
{
delete
validAttributes
.
delivery
;
}
else
{
if
(
validAttributes
.
delivery
!=
0
&&
validAttributes
.
delivery
!=
1
&&
validAttributes
.
delivery
!=
2
)
{
delete
validAttributes
.
delivery
;
}
}
if
(
!
((
/^
(
small|normal|large
)
$/
).
test
(
validAttributes
.
legend_size
)))
{
if
(
!
((
/^
(
small|normal|large
)
$/
).
test
(
validAttributes
.
legend_size
)))
{
delete
validAttributes
.
legend_size
;
delete
validAttributes
.
legend_size
;
}
}
...
...
sails/src/assets/app/i18n/en-gb.json
View file @
4829118e
...
@@ -77,6 +77,8 @@
...
@@ -77,6 +77,8 @@
"delete"
:
"Delete"
,
"delete"
:
"Delete"
,
"delete_strip_after_delivery"
:
"Empty strip after delivery"
,
"delete_strip_after_delivery"
:
"Empty strip after delivery"
,
"delete_template"
:
"Delete from templates"
,
"delete_template"
:
"Delete from templates"
,
"delivery_behavior"
:
"Strip delivery"
,
"delivery_note"
:
"A <i>strip delivery</i> occurs when the kid runs the speech of the pictograms on it"
,
"description"
:
"Description"
,
"description"
:
"Description"
,
"device"
:
"Device"
,
"device"
:
"Device"
,
"device_setup"
:
"Device setup"
,
"device_setup"
:
"Device setup"
,
...
@@ -146,6 +148,8 @@
...
@@ -146,6 +148,8 @@
"January"
:
"January"
,
"January"
:
"January"
,
"July"
:
"July"
,
"July"
:
"July"
,
"June"
:
"June"
,
"June"
:
"June"
,
"keep_strip_and_deliveries"
:
"Keep strip and allow several deliveries"
,
"keep_strip_and_one_delivery"
:
"Keep strip and allow only one delivery"
,
"language"
:
"Language"
,
"language"
:
"Language"
,
"large"
:
"Large"
,
"large"
:
"Large"
,
"large_picto"
:
"Large pictograms"
,
"large_picto"
:
"Large pictograms"
,
...
@@ -204,6 +208,7 @@
...
@@ -204,6 +208,7 @@
"no_students_for_user"
:
"You are not associated to any students. Please ask your office to link your account to a Pictogram student."
,
"no_students_for_user"
:
"You are not associated to any students. Please ask your office to link your account to a Pictogram student."
,
"no_space_in_category"
:
"No space left in category"
,
"no_space_in_category"
:
"No space left in category"
,
"normal"
:
"Normal"
,
"normal"
:
"Normal"
,
"note"
:
"Note"
,
"notes"
:
"Notes"
,
"notes"
:
"Notes"
,
"November"
:
"November"
,
"November"
:
"November"
,
"num_peers"
:
"Peers"
,
"num_peers"
:
"Peers"
,
...
...
sails/src/assets/app/i18n/es-es.json
View file @
4829118e
...
@@ -77,6 +77,8 @@
...
@@ -77,6 +77,8 @@
"delete"
:
"Eliminar"
,
"delete"
:
"Eliminar"
,
"delete_strip_after_delivery"
:
"Limpiar cinta tras entrega"
,
"delete_strip_after_delivery"
:
"Limpiar cinta tras entrega"
,
"delete_template"
:
"Eliminar de plantillas"
,
"delete_template"
:
"Eliminar de plantillas"
,
"delivery_behavior"
:
"Entrega de tira"
,
"delivery_note"
:
"Se considera una <i>entrega</i> la locución de los pictogramas en la cinta de frase"
,
"description"
:
"Descripción"
,
"description"
:
"Descripción"
,
"device"
:
"Dispositivo"
,
"device"
:
"Dispositivo"
,
"device_setup"
:
"Configuración del dispositivo"
,
"device_setup"
:
"Configuración del dispositivo"
,
...
@@ -146,6 +148,8 @@
...
@@ -146,6 +148,8 @@
"January"
:
"Enero"
,
"January"
:
"Enero"
,
"July"
:
"Julio"
,
"July"
:
"Julio"
,
"June"
:
"Junio"
,
"June"
:
"Junio"
,
"keep_strip_and_deliveries"
:
"Mantener cinta y permitir varias entregas"
,
"keep_strip_and_one_delivery"
:
"Mantener cinta y permitir sólo una entrega"
,
"language"
:
"Idioma"
,
"language"
:
"Idioma"
,
"large"
:
"Grande"
,
"large"
:
"Grande"
,
"large_picto"
:
"Pictogramas grandes"
,
"large_picto"
:
"Pictogramas grandes"
,
...
@@ -204,6 +208,7 @@
...
@@ -204,6 +208,7 @@
"no_subscribed"
:
"Sin conexión a la cuenta del estudiante"
,
"no_subscribed"
:
"Sin conexión a la cuenta del estudiante"
,
"nobegin"
:
"Sin iniciar"
,
"nobegin"
:
"Sin iniciar"
,
"normal"
:
"Normal"
,
"normal"
:
"Normal"
,
"note"
:
"Nota"
,
"notes"
:
"Notas"
,
"notes"
:
"Notas"
,
"November"
:
"Noviembre"
,
"November"
:
"Noviembre"
,
"num_peers"
:
"Conectados"
,
"num_peers"
:
"Conectados"
,
...
...
sails/src/assets/scripts/app.js
View file @
4829118e
...
@@ -89,11 +89,6 @@ dashboardApp.config(function ($stateProvider, $urlRouterProvider) {
...
@@ -89,11 +89,6 @@ dashboardApp.config(function ($stateProvider, $urlRouterProvider) {
templateUrl
:
'modules/login/views/login_setting_password.html'
,
templateUrl
:
'modules/login/views/login_setting_password.html'
,
controller
:
'LoginSettingPasswordCtrl'
controller
:
'LoginSettingPasswordCtrl'
})
})
.
state
(
'loginadmin'
,
{
url
:
'/loginadmin'
,
templateUrl
:
'modules/login/views/login_admin.html'
,
controller
:
'LoginAdminCtrl'
,
})
.
state
(
'signin'
,
{
.
state
(
'signin'
,
{
url
:
'/signin'
,
url
:
'/signin'
,
templateUrl
:
'modules/login/views/signin.html'
,
templateUrl
:
'modules/login/views/signin.html'
,
...
@@ -128,7 +123,7 @@ dashboardApp.config(function ($stateProvider, $urlRouterProvider) {
...
@@ -128,7 +123,7 @@ dashboardApp.config(function ($stateProvider, $urlRouterProvider) {
controller
:
'InstructionsCtrl'
,
controller
:
'InstructionsCtrl'
,
})
})
.
state
(
'supervisors_list'
,
{
.
state
(
'supervisors_list'
,
{
url
:
'/supervisor
s_
list'
,
url
:
'/supervisor
/
list'
,
parent
:
'supervisor'
,
parent
:
'supervisor'
,
templateUrl
:
'modules/supervisor/views/supervisors_list.html'
,
templateUrl
:
'modules/supervisor/views/supervisors_list.html'
,
controller
:
'SupervisorsCtrl'
,
controller
:
'SupervisorsCtrl'
,
...
@@ -177,19 +172,24 @@ dashboardApp.config(function ($stateProvider, $urlRouterProvider) {
...
@@ -177,19 +172,24 @@ dashboardApp.config(function ($stateProvider, $urlRouterProvider) {
controller
:
'AdminCtrl'
,
controller
:
'AdminCtrl'
,
abstract
:
true
,
abstract
:
true
,
})
})
.
state
(
'licenses'
,
{
.
state
(
'admin_login'
,
{
url
:
'/admin/login'
,
templateUrl
:
'modules/login/views/login_admin.html'
,
// TODO: habría que mover esta vista a modules/admin/views
controller
:
'LoginAdminCtrl'
,
// TODO: y el controlador, también
})
.
state
(
'admin_licenses'
,
{
url
:
'/admin/licenses'
,
url
:
'/admin/licenses'
,
parent
:
'admin'
,
parent
:
'admin'
,
templateUrl
:
'modules/admin/views/licenses.html'
,
templateUrl
:
'modules/admin/views/licenses.html'
,
controller
:
'AdminLicensesCtrl'
,
controller
:
'AdminLicensesCtrl'
,
})
})
.
state
(
'offices'
,
{
.
state
(
'
admin_
offices'
,
{
url
:
'/admin/offices'
,
url
:
'/admin/offices'
,
parent
:
'admin'
,
parent
:
'admin'
,
templateUrl
:
'modules/admin/views/offices.html'
,
templateUrl
:
'modules/admin/views/offices.html'
,
controller
:
'AdminOfficesCtrl'
,
controller
:
'AdminOfficesCtrl'
,
})
})
.
state
(
'supervisors'
,
{
.
state
(
'
admin_
supervisors'
,
{
url
:
'/admin/supervisors'
,
url
:
'/admin/supervisors'
,
parent
:
'admin'
,
parent
:
'admin'
,
templateUrl
:
'modules/admin/views/supervisors.html'
,
templateUrl
:
'modules/admin/views/supervisors.html'
,
...
...
sails/src/assets/scripts/modules/student/views/setup.html
View file @
4829118e
...
@@ -236,18 +236,57 @@
...
@@ -236,18 +236,57 @@
{{ 'highlight' | translate }}
{{ 'highlight' | translate }}
</span>
</span>
</div>
</div>
</fieldset>
</div>
<div
class=
"col-md-5"
>
<fieldset>
<label
translate
>
delivery_behavior
</label>
<div
class=
"input-group"
>
<div
class=
"input-group"
>
<span
class=
"input-group-addon"
>
<span
class=
"input-group-addon"
>
<input
type=
"checkbox"
<input
type=
"radio"
id=
"studentSetupDeleteStripAfterDelivery"
id=
"delivery0"
ng-model=
"studentData.attributes.input_feedback.delete_strip_after_delivery"
ng-model=
"studentData.attributes.delivery"
ng-value=
"0"
ng-change=
"update_attributes()"
>
ng-change=
"update_attributes()"
>
</span>
</span>
<span
class=
"form-control"
for=
"
studentSetupDeleteStripAfterDelivery
"
>
<span
class=
"form-control"
for=
"
delivery0
"
>
{{ 'delete_strip_after_delivery' | translate }}
{{ 'delete_strip_after_delivery' | translate }}
</span>
</span>
</div>
</div>
<div
class=
"input-group"
>
<span
class=
"input-group-addon"
>
<input
type=
"radio"
id=
"delivery1"
ng-model=
"studentData.attributes.delivery"
ng-value=
"1"
ng-change=
"update_attributes()"
>
</span>
<span
class=
"form-control"
for=
"delivery1"
>
{{ 'keep_strip_and_one_delivery' | translate }}
</span>
</div>
<div
class=
"input-group"
>
<span
class=
"input-group-addon"
>
<input
type=
"radio"
id=
"delivery2"
ng-model=
"studentData.attributes.delivery"
ng-value=
"2"
ng-change=
"update_attributes()"
>
</span>
<span
class=
"form-control"
for=
"delivery2"
>
{{ 'keep_strip_and_deliveries' | translate }}
</span>
</div>
</fieldset>
</fieldset>
<div
class=
"alert alert-warning"
role=
"alert"
>
<p>
<strong
translate
>
note
</strong>
</p>
<p
translate
>
delivery_note
</p>
</div>
</div>
</div>
</form>
</form>
</div>
</div>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment