├── .gitignore
├── README.md
├── art
├── google-play-badge.png
├── hall_scheme_1.png
└── hall_scheme_1_zoom.png
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── library
├── .gitignore
├── build.gradle
├── gradle.properties
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── assets
│ └── fonts
│ │ └── Roboto-Medium.ttf
│ ├── java
│ └── by
│ │ └── anatoldeveloper
│ │ └── hallscheme
│ │ ├── hall
│ │ ├── HallScheme.java
│ │ ├── ImageClickListener.java
│ │ ├── MaxSeatsClickListener.java
│ │ ├── ScenePosition.java
│ │ ├── Seat.java
│ │ ├── SeatListener.java
│ │ ├── Zone.java
│ │ └── ZoneListener.java
│ │ └── view
│ │ └── ZoomableImageView.java
│ └── res
│ └── values
│ ├── attrs.xml
│ ├── colors.xml
│ └── strings.xml
├── sample
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── assets
│ └── fonts
│ │ └── DroidSansMono.ttf
│ ├── java
│ └── by
│ │ └── anatoldeveloper
│ │ └── hallscheme
│ │ └── example
│ │ ├── MainActivity.java
│ │ ├── SeatExample.java
│ │ ├── ZoneExample.java
│ │ └── schemes
│ │ ├── SchemeBasic.java
│ │ ├── SchemeCustomTypeface.java
│ │ ├── SchemeDarkTheme.java
│ │ ├── SchemeMaxSelectedSeats.java
│ │ ├── SchemeWithMarkers.java
│ │ ├── SchemeWithScene.java
│ │ └── SchemeWithZones.java
│ └── res
│ ├── layout
│ ├── activity_main.xml
│ ├── basic_scheme_fragment.xml
│ ├── halls_fragment.xml
│ └── scheme_with_button.xml
│ ├── menu
│ └── main_menu.xml
│ ├── mipmap-hdpi
│ └── ic_launcher.png
│ ├── mipmap-mdpi
│ └── ic_launcher.png
│ ├── mipmap-xhdpi
│ └── ic_launcher.png
│ ├── mipmap-xxhdpi
│ └── ic_launcher.png
│ ├── mipmap-xxxhdpi
│ └── ic_launcher.png
│ ├── values-w820dp
│ └── dimens.xml
│ └── values
│ ├── colors.xml
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.ap_
4 |
5 | # Files for the dex VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # Generated files
12 | bin/
13 | gen/
14 |
15 | # Local configuration file (sdk path, etc)
16 | local.properties
17 |
18 | # IntelliJ IDEA
19 | .idea/
20 | *.iml
21 | *.iws
22 | *.ipr
23 |
24 | # Gradle
25 | .gradle
26 | build/
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | HallScheme
2 | ====================
3 |
4 | [](https://android-arsenal.com/details/1/2935)
5 |
6 | ### Description
7 |
8 | HallScheme is a lightweight simple library for creating rectangle halls.
9 |
10 | 
11 |
12 | 
13 |
14 | ### Demo
15 |
16 | [](https://play.google.com/store/apps/details?id=by.anatoldeveloper.hallscheme.example)
17 |
18 | ### Integration
19 |
20 | **1)** Add as a dependency to your ``build.gradle``:
21 |
22 | ```groovy
23 | dependencies {
24 | compile 'com.github.Nublo:hallscheme:1.1.1'
25 | }
26 | ```
27 |
28 | **2)** Add ``by.anatoldeveloper.ZoomableImage`` to your layout XML file. Content is automatically centered within free space.
29 |
30 | ```xml
31 |
35 |
36 |
40 |
41 |
42 | ```
43 |
44 | **3)** Customize `Seat` interface:
45 |
46 | ```
47 | public class SeatExample implements Seat {
48 |
49 | public int id;
50 | public int color = Color.RED;
51 | public String marker;
52 | public String selectedSeatMarker;
53 | public HallScheme.SeatStatus status;
54 |
55 | @Override
56 | public int id() {
57 | return id;
58 | }
59 |
60 | @Override
61 | public int color() {
62 | return color;
63 | }
64 |
65 | @Override
66 | public String marker() {
67 | return marker;
68 | }
69 |
70 | @Override
71 | public String selectedSeat() {
72 | return selectedSeatMarker;
73 | }
74 |
75 | @Override
76 | public HallScheme.SeatStatus status() {
77 | return status;
78 | }
79 |
80 | @Override
81 | public void setStatus(HallScheme.SeatStatus status) {
82 | this.status = status;
83 | }
84 |
85 | }
86 | ```
87 |
88 | **4)** Attach ZoomableImage to `HallScheme` and add a 2-dimesional `Seat` array:
89 |
90 | ```
91 | ZoomableImageView imageView = (ZoomableImageView) rootView.findViewById(R.id.zoomable_image);
92 | Seat seats[][] = new Seat[10][10];
93 | HallScheme scheme = new HallScheme(imageView, seats, getActivity());
94 | ```
95 |
96 | **5)** Set `SeatListener` to `HallScheme` to handle click events on seats:
97 |
98 | ```
99 | scheme.setSeatListener(new SeatListener() {
100 |
101 | @Override
102 | public void selectSeat(int id) {
103 | Toast.makeText(getActivity(), "select seat " + id, Toast.LENGTH_SHORT).show();
104 | }
105 |
106 | @Override
107 | public void unSelectSeat(int id) {
108 | Toast.makeText(getActivity(), "unSelect seat " + id, Toast.LENGTH_SHORT).show();
109 | }
110 |
111 | });
112 | ```
113 |
114 | ### Seat interface
115 | To use the library you should implement custom `Seat`. It has the following methods:
116 |
117 | **a)** `int id()` should return current `id` for current `Seat`. It will also be later returned when you attach `SeatListener` for scheme.
118 |
119 | **b)** `int color()` should return the color of the checked `Seat`.
120 |
121 | **c)** `String marker()` should return text representation for empty `Seat`. For example you can use it to see row and column.
122 |
123 | **d)** `String selectedSeat();` should return `Seat` number when the `Seat` is checked.
124 |
125 | **e)** `HallScheme.SeatStatus status();` should return current state of the `Seat`. The following statuses are supported:
126 |
127 | + `FREE` - seat is free and can be checked;
128 | + `CHOSEN` - seat is chosen and can be unchecked;
129 | + `BUSY` - seat cannot be used;
130 | + `INFO` - the seat is empty, but you can use to show some text there;
131 | + `EMPTY` - the seat is empty.
132 |
133 | **f)** `void setStatus(HallScheme.SeatStatus status);` update current `Seat` status.
134 |
135 | ### Features:
136 |
137 | **a)** Zoomable image.
138 |
139 | Zooming can be enabled/disabled either from code:
140 |
141 | `imageView.setZoomByDoubleTap(false);`
142 |
143 | or from xml:
144 |
145 |
146 |
152 |
153 |
158 |
159 |
160 | **b)** Fling while touching image.
161 |
162 | **c)** Smooth animation available either on double tap or on gesture move.
163 |
164 | **d)** Showing scheme scene from any of 4 sides.
165 |
166 | `hallScheme.setScenePosition(ScenePosition.NORTH);`
167 |
168 | + `NORTH`
169 | + `SOUTH`
170 | + `EAST`
171 | + `WEST`
172 |
173 | **e)** Adding text to show row or hall numbers.
174 |
175 | **f)** Handling clicking on seats on your scheme.
176 |
177 | **g)** Full customization for drawing:
178 |
179 | + Setting background color for scheme:
180 |
181 | ```java
182 | scheme.setBackgroundColor(Color.RED);
183 | ```
184 | + Setting color for `BUSY` seats:
185 |
186 | ```java
187 | scheme.setUnavailableSeatBackgroundColor(Color.RED);
188 | ```
189 | + Setting background color for `CHOSEN` seats:
190 |
191 | ```java
192 | scheme.setChosenSeatBackgroundColor(Color.RED);
193 | ```
194 | + Setting text color for `CHOSEN` seats:
195 |
196 | ```java
197 | scheme.setChosenSeatTextColor(Color.RED);
198 | ```
199 | + Setting color for `INFO` seats:
200 |
201 | ```java
202 | scheme.setMarkerColor(Color.RED);
203 | ```
204 | + Setting text color for Scene:
205 |
206 | ```java
207 | scheme.setScenePaintColor(Color.RED);
208 | ```
209 | + Setting background color for Scene:
210 |
211 | ```java
212 | scheme.setSceneBackgroundColor(Color.RED);
213 | ```
214 | + Setting custom typeface for Scene:
215 |
216 | ```java
217 | scheme.setTypeface(typeface);
218 | ```
219 |
220 | **h)** Setting custom name for scene:
221 |
222 | scheme.setSceneName("Custom name");
223 |
224 | **i)** Setting limit of checked seats and set listener for this event:
225 |
226 | scheme.setMaxSelectedSeats(4);
227 | scheme.setMaxSeatsClickListener(new MaxSeatsClickListener() {
228 | @Override
229 | public void maxSeatsReached(int id) {
230 | // Do something
231 | }
232 | });
233 |
234 | By default it is unlimitted. So user can check as many seats as he wants.
235 |
236 | **j)** Programmatically click on scheme:
237 |
238 | scheme.clickSchemeProgrammatically(3, 4);
239 |
240 | So if seat was checked it becomes unchecked and `Seatlistener` will be notified.
241 | If seat was unchecked and limit is not reached seat becomes checked and `SeatListener` will be notified, otherway(when limit reached) seat will not be checked and `MaxSeatsListener` will be notified.
242 |
243 | **k)** Adding seat areas.
244 |
245 | Seat area will be drawn like a solid rectangle on scene and can have size from 1x1 block to all scheme. When user is clicking on seat area listener will be notified. Clicking on seat area is not counting in `maxSelectedSeats`.
246 |
247 | You can see how to use seat areas in examples. Main principle like with seats. You should set left top corner, width, height and color. Name for seat area is not used in current library implementation.
248 |
249 |
250 | ### Restrictions
251 |
252 | Image is currently drawing on standart `Bitmap`. Maximum size of `Bitmap` depends on underlying OpenGL implementation and it varies depending on device. It shouldn't be less then `2048x2048`. With current implementation your hall dimension(either rows or columns) shouldn't be more then `58`. Maximum scheme that can be drawn is `58x58`. Of course, if you know that devices using your app will have bigger maximum size - you can draw larger schemes.
253 |
254 | ### ChangeLog
255 |
256 | **Version 1.1.1:**
257 |
258 | + Remove dependency from appcompat library
259 |
260 | **Version 1.1.0:**
261 |
262 | + Ability to set custom typeface
263 | + Disable zooming by double tap
264 | + Programmatically click seat on scheme
265 | + Limiting checked seats
266 | + Added seat areas
267 |
268 | ### License
269 |
270 | ```
271 | The MIT License (MIT)
272 |
273 | Copyright (c) 2016 Varyvonchyk Anatol
274 |
275 | Permission is hereby granted, free of charge, to any person obtaining a copy
276 | of this software and associated documentation files (the "Software"), to deal
277 | in the Software without restriction, including without limitation the rights
278 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
279 | copies of the Software, and to permit persons to whom the Software is
280 | furnished to do so, subject to the following conditions:
281 |
282 | The above copyright notice and this permission notice shall be included in all
283 | copies or substantial portions of the Software.
284 |
285 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
286 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
287 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
288 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
289 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
290 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
291 | SOFTWARE.
292 | ```
--------------------------------------------------------------------------------
/art/google-play-badge.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nublo/HallScheme/7ac4bf085dae23c14d0b40c70e61d2f0e43a1bbb/art/google-play-badge.png
--------------------------------------------------------------------------------
/art/hall_scheme_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nublo/HallScheme/7ac4bf085dae23c14d0b40c70e61d2f0e43a1bbb/art/hall_scheme_1.png
--------------------------------------------------------------------------------
/art/hall_scheme_1_zoom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nublo/HallScheme/7ac4bf085dae23c14d0b40c70e61d2f0e43a1bbb/art/hall_scheme_1_zoom.png
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.2.3'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | jcenter()
18 | }
19 | }
20 |
21 | task clean(type: Delete) {
22 | delete rootProject.buildDir
23 | }
24 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 |
20 | VERSION_NAME=1.1.1
21 | VERSION_CODE=3
22 | GROUP=com.github.Nublo
23 |
24 | POM_DESCRIPTION=Simple Library for creating rectangle halls
25 | POM_URL=https://github.com/Nublo/HallScheme
26 | POM_SCM_URL=https://github.com/Nublo/HallScheme
27 | POM_SCM_CONNECTION=scm:git@github.com:Nublo/HallScheme.git
28 | POM_SCM_DEV_CONNECTION=scm:git@github.com:Nublo/HallScheme.git
29 | POM_LICENCE_NAME=The MIT License (MIT)
30 | POM_LICENCE_URL=https://opensource.org/licenses/MIT
31 | POM_LICENCE_DIST=repo
32 | POM_DEVELOPER_ID=Nublo
33 | POM_DEVELOPER_NAME=Varyvonchyk Anatol
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nublo/HallScheme/7ac4bf085dae23c14d0b40c70e61d2f0e43a1bbb/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Oct 28 19:41:59 MSK 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-3.2.1-all.zip
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/library/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/library/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply from: 'https://raw.github.com/chrisbanes/gradle-mvn-push/master/gradle-mvn-push.gradle'
3 |
4 | android {
5 | compileSdkVersion 25
6 | buildToolsVersion "25.0.1"
7 |
8 | defaultConfig {
9 | minSdkVersion 14
10 | targetSdkVersion 25
11 | versionCode 1
12 | versionName "1.0.0"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/library/gradle.properties:
--------------------------------------------------------------------------------
1 | POM_NAME=HallScheme
2 | POM_ARTIFACT_ID=hallscheme
3 | POM_PACKAGING=aar
--------------------------------------------------------------------------------
/library/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in D:\android\sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/library/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/library/src/main/assets/fonts/Roboto-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nublo/HallScheme/7ac4bf085dae23c14d0b40c70e61d2f0e43a1bbb/library/src/main/assets/fonts/Roboto-Medium.ttf
--------------------------------------------------------------------------------
/library/src/main/java/by/anatoldeveloper/hallscheme/hall/HallScheme.java:
--------------------------------------------------------------------------------
1 | package by.anatoldeveloper.hallscheme.hall;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.Canvas;
6 | import android.graphics.Color;
7 | import android.graphics.Paint;
8 | import android.graphics.Point;
9 | import android.graphics.Rect;
10 | import android.graphics.Typeface;
11 | import android.os.Build;
12 |
13 | import java.util.ArrayList;
14 | import java.util.List;
15 |
16 | import by.anatoldeveloper.hallscheme.R;
17 | import by.anatoldeveloper.hallscheme.view.ZoomableImageView;
18 |
19 | /**
20 | * Created by Nublo on 28.10.2015.
21 | * Copyright Nublo
22 | */
23 | public class HallScheme {
24 |
25 | private int width, height;
26 | private Seat[][] seats;
27 |
28 | private final Rect textBounds = new Rect();
29 | private Paint textPaint, backgroundPaint, markerPaint, scenePaint;
30 | private int seatWidth, seatGap, offset;
31 | private int schemeBackgroundColor, unavailableSeatColor, chosenColor, sceneBackgroundColor;
32 | private int selectedSeats, maxSelectedSeats;
33 | private Typeface typeface;
34 | private String sceneName;
35 |
36 | private Scene scene;
37 | private ZoomableImageView image;
38 | private SeatListener listener;
39 | private MaxSeatsClickListener maxSeatsClickListener;
40 | private List zones;
41 | private ZoneListener zoneListener;
42 |
43 | public HallScheme(ZoomableImageView image, Seat[][] seats, Context context) {
44 | this.selectedSeats = 0;
45 | this.maxSelectedSeats = -1;
46 | this.image = image;
47 | this.seats = seats;
48 | nullifyMap();
49 |
50 | image.setClickListener(new ImageClickListener() {
51 | @Override
52 | public void onClick(Point p) {
53 | p.x -= scene.getLeftYOffset();
54 | p.y -= scene.getTopXOffset();
55 | clickScheme(p);
56 | }
57 | });
58 |
59 | typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Medium.ttf");
60 | sceneName = context.getString(R.string.scene);
61 |
62 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
63 | schemeBackgroundColor = context.getResources().getColor(R.color.light_grey);
64 | unavailableSeatColor = context.getResources().getColor(R.color.disabled_color);
65 | chosenColor = context.getResources().getColor(R.color.orange);
66 | markerPaint = initTextPaint(context.getResources().getColor(R.color.black_gray));
67 | scenePaint = initTextPaint(context.getResources().getColor(R.color.black_gray));
68 | } else {
69 | schemeBackgroundColor = context.getColor(R.color.light_grey);
70 | unavailableSeatColor = context.getColor(R.color.disabled_color);
71 | chosenColor = context.getColor(R.color.orange);
72 | markerPaint = initTextPaint(context.getColor(R.color.black_gray));
73 | scenePaint = initTextPaint(context.getColor(R.color.black_gray));
74 | }
75 | sceneBackgroundColor = unavailableSeatColor;
76 | textPaint = initTextPaint(Color.WHITE);
77 | scenePaint.setTextSize(35);
78 |
79 | backgroundPaint = new Paint();
80 | backgroundPaint.setStyle(Paint.Style.FILL);
81 | backgroundPaint.setColor(schemeBackgroundColor);
82 | backgroundPaint.setStrokeWidth(0);
83 |
84 | seatWidth = 30;
85 | seatGap = 5;
86 | offset = 30;
87 | height = seats.length;
88 | width = seats[0].length;
89 | this.scene = new Scene(ScenePosition.NONE, 0, 0, offset/2);
90 | image.setImageBitmap(getImageBitmap());
91 | }
92 |
93 | public void setScenePosition(ScenePosition position) {
94 | scene = new Scene(position, width, height, offset/2);
95 | image.setImageBitmap(getImageBitmap());
96 | }
97 |
98 | public void setSceneName(String name) {
99 | sceneName = name;
100 | image.setImageBitmap(getImageBitmap());
101 | }
102 |
103 | public void setBackgroundColor(int color) {
104 | schemeBackgroundColor = color;
105 | image.setImageBitmap(getImageBitmap());
106 | }
107 |
108 | public void setUnavailableSeatBackgroundColor(int color) {
109 | unavailableSeatColor = color;
110 | image.setImageBitmap(getImageBitmap());
111 | }
112 |
113 | public void setChosenSeatTextColor(int color) {
114 | textPaint.setColor(color);
115 | image.setImageBitmap(getImageBitmap());
116 | }
117 |
118 | public void setChosenSeatBackgroundColor(int color) {
119 | chosenColor = color;
120 | image.setImageBitmap(getImageBitmap());
121 | }
122 |
123 | public void setMarkerColor(int color) {
124 | markerPaint.setColor(color);
125 | image.setImageBitmap(getImageBitmap());
126 | }
127 |
128 | public void setSceneTextColor(int color) {
129 | scenePaint.setColor(color);
130 | image.setImageBitmap(getImageBitmap());
131 | }
132 |
133 | public void setSceneBackgroundColor(int color) {
134 | sceneBackgroundColor = color;
135 | image.setImageBitmap(getImageBitmap());
136 | }
137 |
138 | public void setMaxSelectedSeats(int maxSelectedSeats) {
139 | this.maxSelectedSeats = maxSelectedSeats;
140 | }
141 |
142 | public void setSeatListener(SeatListener listener) {
143 | this.listener = listener;
144 | }
145 |
146 | public void setMaxSeatsClickListener(MaxSeatsClickListener maxSeatsClickListener) {
147 | this.maxSeatsClickListener = maxSeatsClickListener;
148 | }
149 |
150 | /**
151 | * Set custom typeface to scheme.
152 | * Be careful when using. Bold typefaces can be drawn incorrectly.
153 | * @param typeface - Typeface to be setted
154 | */
155 | public void setTypeface(Typeface typeface) {
156 | this.typeface = typeface;
157 | markerPaint.setTypeface(typeface);
158 | scenePaint.setTypeface(typeface);
159 | textPaint.setTypeface(typeface);
160 | image.setImageBitmap(getImageBitmap());
161 | }
162 |
163 | public void setZones(List zones) {
164 | this.zones = zones;
165 | image.setImageBitmap(getImageBitmap());
166 | }
167 |
168 | public void setZoneListener(ZoneListener zoneListener) {
169 | this.zoneListener = zoneListener;
170 | }
171 |
172 | private Paint initTextPaint(int color) {
173 | Paint paint = new Paint();
174 | paint.setColor(color);
175 | paint.setStyle(Paint.Style.FILL);
176 | paint.setStrokeMiter(0);
177 | paint.setTextSize(25);
178 | paint.setTypeface(typeface);
179 | return paint;
180 | }
181 |
182 | private void clickScheme(Point point) {
183 | if (findZoneClick(point))
184 | return;
185 | Point p = new Point(point.x - offset/2, point.y - offset/2);
186 | int row = p.x / (seatWidth + seatGap);
187 | int seat = p.y / (seatWidth + seatGap);
188 | if (canSeatPress(p, row, seat)) {
189 | clickScheme(row, seat);
190 | }
191 | }
192 |
193 | public boolean findZoneClick(Point p) {
194 | for (Zone zone : zones) {
195 | int topX = offset/2 + zone.leftTopX() * (seatWidth + seatGap);
196 | int topY = offset/2 + zone.leftTopY() * (seatWidth + seatGap);
197 | int bottomX = offset/2 + (zone.leftTopX() + zone.width()) * (seatWidth + seatGap) - seatGap;
198 | int bottomY = offset/2 + (zone.leftTopY() + zone.height()) * (seatWidth + seatGap) - seatGap;
199 | if (p.x >= topX && p.x <= bottomX && p.y >= topY && p.y <= bottomY) {
200 | if (zoneListener != null)
201 | zoneListener.zoneClick(zone.id());
202 | return true;
203 | }
204 | }
205 | return false;
206 | }
207 |
208 | public void clickSchemeProgrammatically(int row, int seat) {
209 | if (SeatStatus.canSeatBePressed(seats[row][seat].status())) {
210 | clickScheme(seat, row);
211 | }
212 | }
213 |
214 | private void clickScheme(int row, int seat) {
215 | Seat pressedSeat = seats[seat][row];
216 | if (updateSelectedSeatCount(pressedSeat)) {
217 | notifySeatListener(pressedSeat);
218 | pressedSeat.setStatus(pressedSeat.status().pressSeat());
219 | image.setImageBitmap(getImageBitmap());
220 | } else if (maxSeatsClickListener != null) {
221 | maxSeatsClickListener.maxSeatsReached(pressedSeat.id());
222 | }
223 | }
224 |
225 | /**
226 | * Increases or decreases current selected seats count
227 | * @param seat Seat that has been clicked
228 | * @return false If selected seats reached max limit, false otherwise
229 | */
230 | public boolean updateSelectedSeatCount(Seat seat) {
231 | if (seat.status() == SeatStatus.FREE) {
232 | if (maxSelectedSeats == -1 || selectedSeats + 1 <= maxSelectedSeats) {
233 | selectedSeats++;
234 | } else if (selectedSeats + 1 > maxSelectedSeats) {
235 | return false;
236 | }
237 | return true;
238 | }
239 | selectedSeats--;
240 | return true;
241 | }
242 |
243 | public boolean canSeatPress(Point p, int row, int seat) {
244 | if (row >= width || (p.x % (seatWidth + seatGap) >= seatWidth)
245 | || p.x <= 0) {
246 | return false;
247 | }
248 | if (seat >= height || (p.y % (seatWidth + seatGap) >= seatWidth)
249 | || p.y <= 0) {
250 | return false;
251 | }
252 | return SeatStatus.canSeatBePressed(seats[seat][row].status());
253 | }
254 |
255 | private Bitmap getImageBitmap() {
256 | int bitmapHeight = height * (seatWidth + seatGap) - seatGap + offset + scene.getTopXOffset() + scene.getBottomXOffset();
257 | int bitmapWidth = width * (seatWidth + seatGap) - seatGap + offset + scene.getLeftYOffset() + scene.getRightYOffset();
258 |
259 | Bitmap tempBitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888);
260 | Canvas tempCanvas = new Canvas(tempBitmap);
261 | backgroundPaint.setColor(schemeBackgroundColor);
262 | tempCanvas.drawRect(0, 0, bitmapWidth, bitmapHeight, backgroundPaint);
263 |
264 | for (int i = 0; i < height; i++) {
265 | for (int j = 0; j < width; j++) {
266 | if (seats[i][j].status() == SeatStatus.EMPTY)
267 | continue;
268 | if (seats[i][j].status() == SeatStatus.INFO) {
269 | drawTextCentred(tempCanvas, markerPaint, seats[i][j].marker(),
270 | offset / 2 + (seatWidth + seatGap) * j + seatWidth / 2 + scene.getLeftYOffset(),
271 | offset / 2 + (seatWidth + seatGap) * i + seatWidth / 2 + scene.getTopXOffset());
272 | continue;
273 | }
274 | if (seats[i][j].status() == SeatStatus.BUSY) {
275 | backgroundPaint.setColor(unavailableSeatColor);
276 | } else if (seats[i][j].status() == SeatStatus.FREE) {
277 | backgroundPaint.setColor(seats[i][j].color());
278 | } else if (seats[i][j].status() == SeatStatus.CHOSEN) {
279 | backgroundPaint.setColor(chosenColor);
280 | }
281 | tempCanvas.drawRect(offset/2 + (seatWidth + seatGap) * j + scene.getLeftYOffset(),
282 | offset/2 + (seatWidth + seatGap) * i + scene.getTopXOffset(),
283 | offset/2 + (seatWidth + seatGap) * j + seatWidth + scene.getLeftYOffset(),
284 | offset/2 + (seatWidth + seatGap) * i + seatWidth + scene.getTopXOffset(),
285 | backgroundPaint);
286 | if (seats[i][j].status() == SeatStatus.CHOSEN) {
287 | drawTextCentred(tempCanvas, textPaint, seats[i][j].selectedSeat(),
288 | offset / 2 + (seatWidth + seatGap) * j + seatWidth / 2 + scene.getLeftYOffset(),
289 | offset / 2 + (seatWidth + seatGap) * i + seatWidth / 2 + scene.getTopXOffset());
290 | }
291 | }
292 | }
293 |
294 | for(Zone zone : zones) {
295 | if (zone.width() == 0 || zone.height() == 0
296 | || zone.leftTopX() + zone.width() > width
297 | || zone.leftTopY() + zone.height() > height)
298 | continue;
299 | backgroundPaint.setColor(zone.color());
300 | int topX = offset/2 + zone.leftTopX() * (seatWidth + seatGap) + scene.getLeftYOffset();
301 | int topY = offset/2 + zone.leftTopY() * (seatWidth + seatGap) + scene.getTopXOffset();
302 | int bottomX = offset/2 + (zone.leftTopX() + zone.width()) * (seatWidth + seatGap) - seatGap + scene.getLeftYOffset();
303 | int bottomY = offset/2 + (zone.leftTopY() + zone.height()) * (seatWidth + seatGap) - seatGap + scene.getTopXOffset();
304 | tempCanvas.drawRect(topX, topY, bottomX, bottomY, backgroundPaint);
305 | }
306 |
307 | drawScene(tempCanvas);
308 |
309 | return tempBitmap;
310 | }
311 |
312 | private void drawScene(Canvas canvas) {
313 | if (scene.position == ScenePosition.NONE) {
314 | return;
315 | }
316 | backgroundPaint.setColor(sceneBackgroundColor);
317 | int topX=0, topY=0, bottomX=0, bottomY=0;
318 | if (scene.position == ScenePosition.NORTH) {
319 | int totalWidth = width * (seatWidth + seatGap) - seatGap + offset;
320 | topX = offset / 2;
321 | topY = totalWidth / 2 - width * 6;
322 | bottomX = topX + scene.dimension;
323 | bottomY = topY + scene.dimensionSecond;
324 | }
325 | if (scene.position == ScenePosition.SOUTH) {
326 | int totalWidth = width * (seatWidth + seatGap) - seatGap + offset;
327 | topX = height * (seatWidth + seatGap) - seatGap + offset;
328 | topY = totalWidth / 2 - width * 6;
329 | bottomX = topX + scene.dimension;
330 | bottomY = topY + scene.dimensionSecond;
331 | }
332 | if (scene.position == ScenePosition.EAST) {
333 | int totalHeight = height * (seatWidth + seatGap) - seatGap + offset;
334 | topX = totalHeight / 2 - height * 6;
335 | topY = offset / 2;
336 | bottomX = topX + scene.dimensionSecond;
337 | bottomY = topY + scene.dimension;
338 | }
339 | if (scene.position == ScenePosition.WEST) {
340 | int totalHeight = height * (seatWidth + seatGap) - seatGap + offset;
341 | topX = totalHeight / 2 - height * 6;
342 | topY = width * (seatWidth + seatGap) - seatGap + offset;
343 | bottomX = topX + scene.dimensionSecond;
344 | bottomY = topY + scene.dimension;
345 | }
346 | canvas.drawRect(topY, topX, bottomY, bottomX, backgroundPaint);
347 | canvas.save();
348 | if (scene.position == ScenePosition.EAST) {
349 | canvas.rotate(270, (topY+bottomY)/2, (topX+bottomX)/2);
350 | } else if (scene.position == ScenePosition.WEST) {
351 | canvas.rotate(90, (topY+bottomY)/2, (topX+bottomX)/2);
352 | }
353 | drawTextCentred(canvas, scenePaint, sceneName, (topY+bottomY)/2, (topX+bottomX)/2);
354 | canvas.restore();
355 | }
356 |
357 | private void drawTextCentred(Canvas canvas, Paint paint, String text, float cx, float cy){
358 | paint.getTextBounds(text, 0, text.length(), textBounds);
359 | canvas.drawText(text, cx - textBounds.exactCenterX(), cy - textBounds.exactCenterY(), paint);
360 | }
361 |
362 | private void nullifyMap() {
363 | width = 0;
364 | height = 0;
365 | zones = new ArrayList<>();
366 | image.setShouldOnMeasureBeCalled(true);
367 | }
368 |
369 | public void notifySeatListener(Seat s) {
370 | if (s.status() == SeatStatus.FREE) {
371 | if (listener != null)
372 | listener.selectSeat(s.id());
373 | } else {
374 | if (listener != null)
375 | listener.unSelectSeat(s.id());
376 | }
377 | }
378 |
379 | public static class Scene {
380 |
381 | private ScenePosition position;
382 | private int dimension;
383 | public int dimensionSecond;
384 | public int width, height, offset;
385 |
386 | public void setScenePosition(ScenePosition position, int offset) {
387 | this.position = position;
388 | this.offset = offset;
389 | dimension = 90;
390 | switch (position) {
391 | case NORTH:
392 | dimensionSecond = width * 12;
393 | break;
394 | case SOUTH:
395 | dimensionSecond = width * 12;
396 | break;
397 | case EAST:
398 | dimensionSecond = height * 12;
399 | break;
400 | case WEST:
401 | dimensionSecond = height * 12;
402 | break;
403 | case NONE:
404 | dimensionSecond = 0;
405 | dimension = 0;
406 | break;
407 | default:
408 | dimensionSecond = 0;
409 | dimension = 0;
410 | this.position = ScenePosition.NONE;
411 | break;
412 | }
413 | }
414 |
415 | public Scene(ScenePosition position, int width, int height, int offset) {
416 | this.width = width;
417 | this.height = height;
418 | setScenePosition(position, offset);
419 | }
420 |
421 | public int getTopXOffset() {
422 | if (position == ScenePosition.NORTH) {
423 | return dimension + offset;
424 | }
425 | return 0;
426 | }
427 |
428 | public int getLeftYOffset() {
429 | if (position == ScenePosition.EAST) {
430 | return dimension + offset;
431 | }
432 | return 0;
433 | }
434 |
435 | public int getBottomXOffset() {
436 | if (position == ScenePosition.SOUTH) {
437 | return dimension + offset;
438 | }
439 | return 0;
440 | }
441 |
442 | public int getRightYOffset() {
443 | if (position == ScenePosition.WEST) {
444 | return dimension + offset;
445 | }
446 | return 0;
447 | }
448 |
449 | @Override
450 | public String toString() {
451 | return String.format("Left - %d, Right- %d, Top - %d, Bottom - %d", getLeftYOffset(), getRightYOffset(), getTopXOffset(), getBottomXOffset());
452 | }
453 |
454 | }
455 |
456 | public enum SeatStatus {
457 | FREE, BUSY, EMPTY, CHOSEN, INFO;
458 |
459 | public static boolean canSeatBePressed(SeatStatus status) {
460 | return (status == FREE || status == CHOSEN);
461 | }
462 |
463 | public SeatStatus pressSeat() {
464 | if (this == FREE)
465 | return CHOSEN;
466 | if (this == CHOSEN)
467 | return FREE;
468 | return this;
469 | }
470 |
471 | }
472 |
473 | @Override
474 | public String toString() {
475 | return String.format("height = %d; width = %d", height, width);
476 | }
477 |
478 | }
--------------------------------------------------------------------------------
/library/src/main/java/by/anatoldeveloper/hallscheme/hall/ImageClickListener.java:
--------------------------------------------------------------------------------
1 | package by.anatoldeveloper.hallscheme.hall;
2 |
3 | import android.graphics.Point;
4 |
5 | /**
6 | * Created by Nublo on 12.11.2015.
7 | * Copyright Nublo
8 | */
9 | public interface ImageClickListener {
10 |
11 | void onClick(Point p);
12 |
13 | }
--------------------------------------------------------------------------------
/library/src/main/java/by/anatoldeveloper/hallscheme/hall/MaxSeatsClickListener.java:
--------------------------------------------------------------------------------
1 | package by.anatoldeveloper.hallscheme.hall;
2 |
3 | /**
4 | * Created by Nublo on 02.01.2016.
5 | * Copyright Nublo
6 | */
7 | public interface MaxSeatsClickListener {
8 |
9 | void maxSeatsReached(int id);
10 |
11 | }
--------------------------------------------------------------------------------
/library/src/main/java/by/anatoldeveloper/hallscheme/hall/ScenePosition.java:
--------------------------------------------------------------------------------
1 | package by.anatoldeveloper.hallscheme.hall;
2 |
3 | /**
4 | * Created by Nublo on 05.12.2015.
5 | * Copyright Nublo
6 | */
7 | public enum ScenePosition {
8 | NORTH, SOUTH, EAST, WEST, NONE
9 | }
--------------------------------------------------------------------------------
/library/src/main/java/by/anatoldeveloper/hallscheme/hall/Seat.java:
--------------------------------------------------------------------------------
1 | package by.anatoldeveloper.hallscheme.hall;
2 |
3 | /**
4 | * Created by Nublo on 28.10.2015.
5 | * Copyright Nublo
6 | */
7 | public interface Seat {
8 |
9 | int id();
10 | int color();
11 | String marker();
12 | String selectedSeat();
13 | HallScheme.SeatStatus status();
14 | void setStatus(HallScheme.SeatStatus status);
15 |
16 | }
--------------------------------------------------------------------------------
/library/src/main/java/by/anatoldeveloper/hallscheme/hall/SeatListener.java:
--------------------------------------------------------------------------------
1 | package by.anatoldeveloper.hallscheme.hall;
2 |
3 | /**
4 | * Created by Nublo on 12.11.2015.
5 | * Copyright Nublo
6 | */
7 | public interface SeatListener {
8 |
9 | void selectSeat(int id);
10 | void unSelectSeat(int id);
11 |
12 | }
--------------------------------------------------------------------------------
/library/src/main/java/by/anatoldeveloper/hallscheme/hall/Zone.java:
--------------------------------------------------------------------------------
1 | package by.anatoldeveloper.hallscheme.hall;
2 |
3 | /**
4 | * Created by Nublo on 28.10.2015.
5 | * Copyright Nublo
6 | */
7 | public interface Zone {
8 |
9 | int id();
10 | int leftTopX();
11 | int leftTopY();
12 | int width();
13 | int height();
14 | int color();
15 | String name();
16 |
17 | }
--------------------------------------------------------------------------------
/library/src/main/java/by/anatoldeveloper/hallscheme/hall/ZoneListener.java:
--------------------------------------------------------------------------------
1 | package by.anatoldeveloper.hallscheme.hall;
2 |
3 | /**
4 | * Created by Moneyman.ru on 08.01.2016.
5 | * Copyright Moneyman.ru
6 | */
7 | public interface ZoneListener {
8 |
9 | void zoneClick(int id);
10 |
11 | }
--------------------------------------------------------------------------------
/library/src/main/java/by/anatoldeveloper/hallscheme/view/ZoomableImageView.java:
--------------------------------------------------------------------------------
1 | package by.anatoldeveloper.hallscheme.view;
2 |
3 | import android.animation.ValueAnimator;
4 | import android.content.Context;
5 | import android.content.res.TypedArray;
6 | import android.graphics.Bitmap;
7 | import android.graphics.Matrix;
8 | import android.graphics.Point;
9 | import android.graphics.PointF;
10 | import android.util.AttributeSet;
11 | import android.view.GestureDetector;
12 | import android.view.MotionEvent;
13 | import android.view.ScaleGestureDetector;
14 | import android.view.View;
15 | import android.view.animation.DecelerateInterpolator;
16 | import android.widget.ImageView;
17 |
18 | import by.anatoldeveloper.hallscheme.R;
19 | import by.anatoldeveloper.hallscheme.hall.ImageClickListener;
20 |
21 | /**
22 | * Created by Nublo on 28.10.2015.
23 | * Copyright Nublo
24 | */
25 | public class ZoomableImageView extends ImageView {
26 |
27 | private final static int ANIMATION_ZOOM_DURATION = 400;
28 | private final static float ANIMATION_ZOOM_PARAMETER = 1.3f;
29 | private static final int SWIPE_MIN_DISTANCE = 100;
30 | private static final int SWIPE_THRESHOLD_VELOCITY = 800;
31 |
32 | private Matrix matrix = new Matrix();
33 |
34 | private static final int NONE = 0;
35 | private static final int DRAG = 1;
36 | private static final int ZOOM = 2;
37 | private static final int CLICK = 3;
38 | private int mode = NONE;
39 |
40 | private boolean isClick;
41 |
42 | private PointF last = new PointF();
43 | private PointF start = new PointF();
44 | private float minScale = 1f;
45 | private float maxScale = 3.0f;
46 | private float[] m;
47 |
48 | private float redundantXSpace, redundantYSpace;
49 | private float width, height;
50 | private float saveScale = 1f;
51 | private float right, bottom, origWidth, origHeight, bmWidth, bmHeight;
52 |
53 | private ScaleGestureDetector mScaleDetector;
54 | private GestureDetector mGestureDetector;
55 | private boolean shouldOnMeasureBeCalled = true;
56 | private int onMeasure = 0;
57 |
58 | private ImageClickListener listener;
59 | private boolean zoomByDoubleTap;
60 |
61 | public ZoomableImageView(Context context, AttributeSet attr)
62 | {
63 | super(context, attr);
64 | TypedArray a = context.getTheme().obtainStyledAttributes(attr, R.styleable.ZoomableImageView, 0, 0);
65 | try {
66 | zoomByDoubleTap = a.getBoolean(R.styleable.ZoomableImageView_doubleTap, true);
67 | } finally {
68 | a.recycle();
69 | }
70 | super.setClickable(true);
71 | mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
72 | mGestureDetector = new GestureDetector(context, new GestureListener());
73 | matrix.setTranslate(1f, 1f);
74 | m = new float[9];
75 | setImageMatrix(matrix);
76 | setScaleType(ScaleType.MATRIX);
77 |
78 | setOnTouchListener(new OnTouchListener()
79 | {
80 |
81 | @Override
82 | public boolean onTouch(View v, MotionEvent event)
83 | {
84 | mScaleDetector.onTouchEvent(event);
85 | mGestureDetector.onTouchEvent(event);
86 |
87 | matrix.getValues(m);
88 | float x = m[Matrix.MTRANS_X];
89 | float y = m[Matrix.MTRANS_Y];
90 | PointF curr = new PointF(event.getX(), event.getY());
91 |
92 | switch (event.getAction())
93 | {
94 | case MotionEvent.ACTION_DOWN:
95 | last.set(event.getX(), event.getY());
96 | start.set(last);
97 | mode = DRAG;
98 | isClick = true;
99 | break;
100 | case MotionEvent.ACTION_POINTER_DOWN:
101 | last.set(event.getX(), event.getY());
102 | start.set(last);
103 | mode = ZOOM;
104 | break;
105 | case MotionEvent.ACTION_MOVE:
106 | if (isClick && (Math.abs(curr.x - last.x) > CLICK || Math.abs(curr.y-last.y) > CLICK)) {
107 | isClick = false;
108 | }
109 | if (mode == ZOOM || (mode == DRAG && saveScale > minScale))
110 | {
111 | float deltaX = curr.x - last.x;
112 | float deltaY = curr.y - last.y;
113 | float scaleWidth = Math.round(origWidth * saveScale);
114 | float scaleHeight = Math.round(origHeight * saveScale);
115 | if (scaleWidth < width)
116 | {
117 | deltaX = 0;
118 | if (y + deltaY > 0)
119 | deltaY = -y;
120 | else if (y + deltaY < -bottom)
121 | deltaY = -(y + bottom);
122 | }
123 | else if (scaleHeight < height)
124 | {
125 | deltaY = 0;
126 | if (x + deltaX > 0)
127 | deltaX = -x;
128 | else if (x + deltaX < -right)
129 | deltaX = -(x + right);
130 | }
131 | else
132 | {
133 | if (x + deltaX > 0)
134 | deltaX = -x;
135 | else if (x + deltaX < -right)
136 | deltaX = -(x + right);
137 |
138 | if (y + deltaY > 0)
139 | deltaY = -y;
140 | else if (y + deltaY < -bottom)
141 | deltaY = -(y + bottom);
142 | }
143 | matrix.postTranslate(deltaX, deltaY);
144 | last.set(curr.x, curr.y);
145 | }
146 | break;
147 |
148 | case MotionEvent.ACTION_UP:
149 | mode = NONE;
150 | int xDiff = (int) Math.abs(curr.x - start.x);
151 | int yDiff = (int) Math.abs(curr.y - start.y);
152 | if (xDiff < CLICK && yDiff < CLICK)
153 | performClick();
154 | if (isClick) {
155 | v.performClick();
156 | if (listener != null) {
157 | listener.onClick(new Point((int)((event.getX()-x)/m[0]), (int)((event.getY()-y)/m[0])));
158 | }
159 | }
160 | break;
161 |
162 | case MotionEvent.ACTION_POINTER_UP:
163 | mode = NONE;
164 | break;
165 | }
166 | setImageMatrix(matrix);
167 | invalidate();
168 | return true;
169 | }
170 |
171 | });
172 | }
173 |
174 | public void setClickListener(ImageClickListener listener) {
175 | this.listener = listener;
176 | }
177 |
178 | public void setZoomByDoubleTap(boolean zoomByDoubleTap) {
179 | this.zoomByDoubleTap = zoomByDoubleTap;
180 | }
181 |
182 | @Override
183 | public boolean performClick() {
184 | return super.performClick();
185 | }
186 |
187 | @Override
188 | public void setImageBitmap(Bitmap bm)
189 | {
190 | super.setImageBitmap(bm);
191 | bmWidth = bm.getWidth();
192 | bmHeight = bm.getHeight();
193 | }
194 |
195 | public void setShouldOnMeasureBeCalled(boolean b) {
196 | if (b) {
197 | onMeasure = 0;
198 | }
199 | this.shouldOnMeasureBeCalled = b;
200 | }
201 |
202 | public void zoom(boolean zoomIn) {
203 | float endScale;
204 | if (zoomIn) endScale = saveScale * ANIMATION_ZOOM_PARAMETER;
205 | else endScale = saveScale / ANIMATION_ZOOM_PARAMETER;
206 | if (endScale > maxScale) endScale = maxScale;
207 | if (endScale < minScale) endScale = minScale;
208 | ValueAnimator zoomAnimation = ValueAnimator.ofFloat(saveScale, endScale);
209 | zoomAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
210 | @Override
211 | public void onAnimationUpdate(ValueAnimator valueAnimator) {
212 | float value = (Float) valueAnimator.getAnimatedValue();
213 | zoomScale(value);
214 | }
215 | });
216 | zoomAnimation.setDuration(ANIMATION_ZOOM_DURATION);
217 | zoomAnimation.start();
218 | }
219 |
220 | public void zoomScale(float endScale) {
221 | scale(endScale/saveScale, width/2, height/2);
222 | setImageMatrix(matrix);
223 | invalidate();
224 | }
225 |
226 | private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener
227 | {
228 |
229 | @Override
230 | public boolean onScaleBegin(ScaleGestureDetector detector) {
231 | mode = ZOOM;
232 | return true;
233 | }
234 |
235 | @Override
236 | public boolean onScale(ScaleGestureDetector detector) {
237 | scale(detector.getScaleFactor(), detector.getFocusX(), detector.getFocusY());
238 | return true;
239 | }
240 | }
241 |
242 | private void scale(float scaleFactor, float xCenter, float yCenter) {
243 | float origScale = saveScale;
244 | saveScale *= scaleFactor;
245 | if (saveScale > maxScale) {
246 | saveScale = maxScale;
247 | scaleFactor = maxScale / origScale;
248 | }
249 | else if (saveScale < minScale) {
250 | saveScale = minScale;
251 | scaleFactor = minScale / origScale;
252 | }
253 | right = width * saveScale - width - (2 * redundantXSpace * saveScale);
254 | bottom = height * saveScale - height - (2 * redundantYSpace * saveScale);
255 | if (origWidth * saveScale <= width || origHeight * saveScale <= height)
256 | {
257 | matrix.postScale(scaleFactor, scaleFactor, width / 2, height / 2);
258 | if (scaleFactor < 1)
259 | {
260 | matrix.getValues(m);
261 | float x = m[Matrix.MTRANS_X];
262 | float y = m[Matrix.MTRANS_Y];
263 | if (scaleFactor < 1)
264 | {
265 | if (Math.round(origWidth * saveScale) < width)
266 | {
267 | if (y < -bottom)
268 | matrix.postTranslate(0, -(y + bottom));
269 | else if (y > 0)
270 | matrix.postTranslate(0, -y);
271 | }
272 | else
273 | {
274 | if (x < -right)
275 | matrix.postTranslate(-(x + right), 0);
276 | else if (x > 0)
277 | matrix.postTranslate(-x, 0);
278 | }
279 | }
280 | }
281 | }
282 | else
283 | {
284 | matrix.postScale(scaleFactor, scaleFactor, xCenter, yCenter);
285 | matrix.getValues(m);
286 | float x = m[Matrix.MTRANS_X];
287 | float y = m[Matrix.MTRANS_Y];
288 | if (scaleFactor < 1) {
289 | if (x < -right)
290 | matrix.postTranslate(-(x + right), 0);
291 | else if (x > 0)
292 | matrix.postTranslate(-x, 0);
293 | if (y < -bottom)
294 | matrix.postTranslate(0, -(y + bottom));
295 | else if (y > 0)
296 | matrix.postTranslate(0, -y);
297 | }
298 | }
299 | }
300 |
301 | private class GestureListener extends GestureDetector.SimpleOnGestureListener {
302 |
303 | @Override
304 | public boolean onDoubleTap( MotionEvent e ) {
305 | if (zoomByDoubleTap)
306 | zoom(true);
307 | return false;
308 | }
309 |
310 | @Override
311 | public void onLongPress( MotionEvent e ) {}
312 |
313 | @Override
314 | public boolean onScroll( MotionEvent e1, MotionEvent e2, float distanceX, float distanceY ) { return false;}
315 |
316 | @Override
317 | public boolean onFling( MotionEvent e1, MotionEvent e2, float velocityX, float velocityY ) {
318 | if (e1 == null || e2 == null) return false;
319 | if ( e1.getPointerCount() > 1 || e2.getPointerCount() > 1 ) return false;
320 | if ( mScaleDetector.isInProgress() || mode == ZOOM) return false;
321 | if ( (Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY || Math.abs(velocityY) > SWIPE_THRESHOLD_VELOCITY) &&
322 | (Math.abs(e2.getX() - e1.getX()) > SWIPE_MIN_DISTANCE || Math.abs(e2.getY() - e1.getY()) > SWIPE_MIN_DISTANCE)) {
323 | float diffX = e2.getX() - e1.getX();
324 | float diffY = e2.getY() - e1.getY();
325 | //animateFling(velocityX/20, velocityY/20);
326 | animateFling(diffX, diffY);
327 | return true;
328 | }
329 | return false;
330 | }
331 | }
332 |
333 | private void animateFling(final float diffX, final float diffY) {
334 | ValueAnimator flingAnimation = ValueAnimator.ofFloat(diffX/5, 0);
335 | flingAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
336 | @Override
337 | public void onAnimationUpdate(ValueAnimator valueAnimator) {
338 | float newDiffX = (float) valueAnimator.getAnimatedValue();
339 | float newDiffY = (newDiffX * diffY)/diffX;
340 | flingMatrix(newDiffX, newDiffY);
341 | }
342 | });
343 | flingAnimation.setDuration(300);
344 | flingAnimation.setInterpolator(new DecelerateInterpolator());
345 | flingAnimation.start();
346 | }
347 |
348 | private void flingMatrix(float xValue, float yValue) {
349 | right = width * saveScale - width - (2 * redundantXSpace * saveScale);
350 | bottom = height * saveScale - height - (2 * redundantYSpace * saveScale);
351 | matrix.getValues(m);
352 | float x = m[Matrix.MTRANS_X];
353 | float y = m[Matrix.MTRANS_Y];
354 | float xFreeSpace = width - (origWidth * saveScale);
355 | xFreeSpace = (xFreeSpace < 0) ? 0.0f : xFreeSpace / 2;
356 | if ((x + xValue - xFreeSpace) <= -right) {
357 | xValue = -(x + right + xFreeSpace);
358 | }
359 | else if ((x + xValue - xFreeSpace) >= 0) {
360 | xValue = -x;
361 | }
362 | float yFreeSpace = height - (origHeight * saveScale);
363 | yFreeSpace = (yFreeSpace < 0) ? 0.0f : yFreeSpace / 2;
364 | if ((y + yValue - yFreeSpace) <= -bottom) {
365 | yValue = -(y + bottom + yFreeSpace);
366 | } else if ((y + yValue - yFreeSpace) >= 0) {
367 | yValue = -y;
368 | }
369 | matrix.postTranslate(xValue, yValue);
370 | setImageMatrix(matrix);
371 | invalidate();
372 | }
373 |
374 | @Override
375 | protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)
376 | {
377 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
378 | if (!shouldOnMeasureBeCalled && onMeasure > 2) {
379 | return;
380 | } else if (!shouldOnMeasureBeCalled) {
381 | onMeasure++;
382 | }
383 | width = MeasureSpec.getSize(widthMeasureSpec);
384 | height = MeasureSpec.getSize(heightMeasureSpec);
385 | //Fit to screen.
386 | float scale = Math.min(width / bmWidth, height / bmHeight);
387 | matrix.setScale(scale, scale);
388 | setImageMatrix(matrix);
389 | saveScale = 1f;
390 |
391 | // Center the image
392 | redundantYSpace = height - (scale * bmHeight);
393 | redundantXSpace = width - (scale * bmWidth);
394 | redundantYSpace /= 2;
395 | redundantXSpace /= 2;
396 |
397 | matrix.postTranslate(redundantXSpace, redundantYSpace);
398 |
399 | origWidth = width - 2 * redundantXSpace;
400 | origHeight = height - 2 * redundantYSpace;
401 | right = width * saveScale - width - (2 * redundantXSpace * saveScale);
402 | bottom = height * saveScale - height - (2 * redundantYSpace * saveScale);
403 | setImageMatrix(matrix);
404 | }
405 |
406 | }
--------------------------------------------------------------------------------
/library/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/library/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #A8B4BA
4 | #282828
5 | #FF6600
6 | #FFFFFF
7 | #FFD8E2E6
8 | #FF424242
9 | #FFF7F7F7
10 | #FF4F7514
11 | #FF661141
12 |
13 |
--------------------------------------------------------------------------------
/library/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | HallScheme
3 | Scene
4 |
5 |
--------------------------------------------------------------------------------
/sample/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/sample/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 25
5 | buildToolsVersion "25.0.1"
6 |
7 | defaultConfig {
8 | applicationId "by.anatoldeveloper.hallscheme.example"
9 | minSdkVersion 14
10 | targetSdkVersion 25
11 | versionCode 2
12 | versionName "1.1.0"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile 'com.android.support:appcompat-v7:25.0.1'
24 | compile project(':library')
25 | }
26 |
--------------------------------------------------------------------------------
/sample/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in D:\android\sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/sample/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
11 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/sample/src/main/assets/fonts/DroidSansMono.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nublo/HallScheme/7ac4bf085dae23c14d0b40c70e61d2f0e43a1bbb/sample/src/main/assets/fonts/DroidSansMono.ttf
--------------------------------------------------------------------------------
/sample/src/main/java/by/anatoldeveloper/hallscheme/example/MainActivity.java:
--------------------------------------------------------------------------------
1 | package by.anatoldeveloper.hallscheme.example;
2 |
3 | import android.content.Intent;
4 | import android.net.Uri;
5 | import android.os.Bundle;
6 | import android.support.v4.app.Fragment;
7 | import android.support.v7.app.AppCompatActivity;
8 | import android.view.LayoutInflater;
9 | import android.view.Menu;
10 | import android.view.MenuItem;
11 | import android.view.View;
12 | import android.view.ViewGroup;
13 | import android.widget.AdapterView;
14 | import android.widget.ArrayAdapter;
15 | import android.widget.ListView;
16 |
17 | import by.anatoldeveloper.hallscheme.example.schemes.SchemeBasic;
18 | import by.anatoldeveloper.hallscheme.example.schemes.SchemeCustomTypeface;
19 | import by.anatoldeveloper.hallscheme.example.schemes.SchemeDarkTheme;
20 | import by.anatoldeveloper.hallscheme.example.schemes.SchemeMaxSelectedSeats;
21 | import by.anatoldeveloper.hallscheme.example.schemes.SchemeWithMarkers;
22 | import by.anatoldeveloper.hallscheme.example.schemes.SchemeWithScene;
23 | import by.anatoldeveloper.hallscheme.example.schemes.SchemeWithZones;
24 |
25 | /**
26 | * Created by Nublo on 06.12.2015.
27 | * Copyright Nublo
28 | */
29 |
30 | public class MainActivity extends AppCompatActivity {
31 |
32 | @Override
33 | protected void onCreate(Bundle savedInstanceState) {
34 | super.onCreate(savedInstanceState);
35 | setContentView(R.layout.activity_main);
36 | getSupportFragmentManager().beginTransaction().replace(R.id.main_fragment, new ListFragment()).commit();
37 | }
38 |
39 | @Override
40 | public boolean onCreateOptionsMenu(Menu menu) {
41 | getMenuInflater().inflate(R.menu.main_menu, menu);
42 | return true;
43 | }
44 |
45 | @Override
46 | public boolean onOptionsItemSelected(MenuItem item) {
47 | switch (item.getItemId()) {
48 | case R.id.open_on_github:
49 | openOnGithub();
50 | return true;
51 | default:
52 | return super.onOptionsItemSelected(item);
53 | }
54 | }
55 |
56 | private void openOnGithub() {
57 | Intent openBrowser = new Intent(Intent.ACTION_VIEW);
58 | openBrowser.setData(Uri.parse("https://github.com/Nublo/HallScheme"));
59 | startActivity(openBrowser);
60 | }
61 |
62 | public static class ListFragment extends Fragment {
63 |
64 | private static final String[] halls = {"Basic hall scheme", "Scheme with scene", "Scheme with markers",
65 | "Custom colors scheme", "Custom typeface", "Maximum selected seats", "Scheme with zones"};
66 |
67 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
68 | View rootView = inflater.inflate(R.layout.halls_fragment, container, false);
69 | ListView hallListView = (ListView) rootView.findViewById(R.id.hall_examples);
70 | ArrayAdapter listAdapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_list_item_1, halls);
71 | hallListView.setAdapter(listAdapter);
72 |
73 | hallListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
74 | @Override
75 | public void onItemClick(AdapterView> parent, View view, int position, long id) {
76 | switch (position) {
77 | case 0 :
78 | replaceFragmentAndAddToBackStack(new SchemeBasic());
79 | break;
80 | case 1 :
81 | replaceFragmentAndAddToBackStack(new SchemeWithScene());
82 | break;
83 | case 2 :
84 | replaceFragmentAndAddToBackStack(new SchemeWithMarkers());
85 | break;
86 | case 3 :
87 | replaceFragmentAndAddToBackStack(new SchemeDarkTheme());
88 | break;
89 | case 4 :
90 | replaceFragmentAndAddToBackStack(new SchemeCustomTypeface());
91 | break;
92 | case 5 :
93 | replaceFragmentAndAddToBackStack(new SchemeMaxSelectedSeats());
94 | break;
95 | case 6 :
96 | replaceFragmentAndAddToBackStack(new SchemeWithZones());
97 | break;
98 | }
99 | }
100 | });
101 | return rootView;
102 | }
103 |
104 | public void replaceFragmentAndAddToBackStack(Fragment fragment) {
105 | getActivity().getSupportFragmentManager()
106 | .beginTransaction()
107 | .replace(R.id.main_fragment, fragment)
108 | .addToBackStack(null)
109 | .commit();
110 | }
111 |
112 | }
113 |
114 | }
--------------------------------------------------------------------------------
/sample/src/main/java/by/anatoldeveloper/hallscheme/example/SeatExample.java:
--------------------------------------------------------------------------------
1 | package by.anatoldeveloper.hallscheme.example;
2 |
3 | import android.graphics.Color;
4 |
5 | import by.anatoldeveloper.hallscheme.hall.HallScheme;
6 | import by.anatoldeveloper.hallscheme.hall.Seat;
7 |
8 | /**
9 | * Created by Nublo on 05.12.2015.
10 | * Copyright Nublo
11 | */
12 | public class SeatExample implements Seat {
13 |
14 | public int id;
15 | public int color = Color.RED;
16 | public String marker;
17 | public String selectedSeatMarker;
18 | public HallScheme.SeatStatus status;
19 |
20 | @Override
21 | public int id() {
22 | return id;
23 | }
24 |
25 | @Override
26 | public int color() {
27 | return color;
28 | }
29 |
30 | @Override
31 | public String marker() {
32 | return marker;
33 | }
34 |
35 | @Override
36 | public String selectedSeat() {
37 | return selectedSeatMarker;
38 | }
39 |
40 | @Override
41 | public HallScheme.SeatStatus status() {
42 | return status;
43 | }
44 |
45 | @Override
46 | public void setStatus(HallScheme.SeatStatus status) {
47 | this.status = status;
48 | }
49 |
50 | }
--------------------------------------------------------------------------------
/sample/src/main/java/by/anatoldeveloper/hallscheme/example/ZoneExample.java:
--------------------------------------------------------------------------------
1 | package by.anatoldeveloper.hallscheme.example;
2 |
3 | import by.anatoldeveloper.hallscheme.hall.Zone;
4 |
5 | /**
6 | * Created by Nublo on 08.01.2016.
7 | * Copyright Nublo
8 | */
9 | public class ZoneExample implements Zone {
10 |
11 | public int id;
12 | public int leftTopX;
13 | public int leftTopY;
14 | public int width;
15 | public int height;
16 | public int color;
17 | public String name;
18 |
19 | public ZoneExample() {
20 |
21 | }
22 |
23 | public ZoneExample(int id, int leftTopX, int leftTopY, int width, int height, int color, String name) {
24 | this.id = id;
25 | this.leftTopX = leftTopX;
26 | this.leftTopY = leftTopY;
27 | this.width = width;
28 | this.height = height;
29 | this.color = color;
30 | this.name = name;
31 | }
32 |
33 | @Override
34 | public int id() {
35 | return id;
36 | }
37 |
38 | @Override
39 | public int leftTopX() {
40 | return leftTopX;
41 | }
42 |
43 | @Override
44 | public int leftTopY() {
45 | return leftTopY;
46 | }
47 |
48 | @Override
49 | public int width() {
50 | return width;
51 | }
52 |
53 | @Override
54 | public int height() {
55 | return height;
56 | }
57 |
58 | @Override
59 | public int color() {
60 | return color;
61 | }
62 |
63 | @Override
64 | public String name() {
65 | return name;
66 | }
67 |
68 | }
--------------------------------------------------------------------------------
/sample/src/main/java/by/anatoldeveloper/hallscheme/example/schemes/SchemeBasic.java:
--------------------------------------------------------------------------------
1 | package by.anatoldeveloper.hallscheme.example.schemes;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.Nullable;
5 | import android.support.v4.app.Fragment;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.widget.Toast;
10 |
11 | import by.anatoldeveloper.hallscheme.example.R;
12 | import by.anatoldeveloper.hallscheme.example.SeatExample;
13 | import by.anatoldeveloper.hallscheme.hall.HallScheme;
14 | import by.anatoldeveloper.hallscheme.hall.Seat;
15 | import by.anatoldeveloper.hallscheme.hall.SeatListener;
16 | import by.anatoldeveloper.hallscheme.view.ZoomableImageView;
17 |
18 | /**
19 | * Created by Nublo on 05.12.2015.
20 | * Copyright Nublo
21 | */
22 | public class SchemeBasic extends Fragment {
23 |
24 | @Nullable
25 | @Override
26 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
27 | View rootView = inflater.inflate(R.layout.basic_scheme_fragment, container, false);
28 | ZoomableImageView imageView = (ZoomableImageView) rootView.findViewById(R.id.zoomable_image);
29 | HallScheme scheme = new HallScheme(imageView, basicScheme(), getActivity());
30 | scheme.setSeatListener(new SeatListener() {
31 |
32 | @Override
33 | public void selectSeat(int id) {
34 | Toast.makeText(getActivity(), "select seat " + id, Toast.LENGTH_SHORT).show();
35 | }
36 |
37 | @Override
38 | public void unSelectSeat(int id) {
39 | Toast.makeText(getActivity(), "unSelect seat " + id, Toast.LENGTH_SHORT).show();
40 | }
41 |
42 | });
43 | return rootView;
44 | }
45 |
46 | public Seat[][] basicScheme() {
47 | Seat seats[][] = new Seat[10][10];
48 | for (int i = 0; i < 10; i++)
49 | for(int j = 0; j < 10; j++) {
50 | SeatExample seat = new SeatExample();
51 | seat.id = i * 10 + (j+1);
52 | seat.selectedSeatMarker = String.valueOf(j+1);
53 | seat.status = HallScheme.SeatStatus.FREE;
54 | seats[i][j] = seat;
55 | }
56 | return seats;
57 | }
58 |
59 | }
--------------------------------------------------------------------------------
/sample/src/main/java/by/anatoldeveloper/hallscheme/example/schemes/SchemeCustomTypeface.java:
--------------------------------------------------------------------------------
1 | package by.anatoldeveloper.hallscheme.example.schemes;
2 |
3 | import android.graphics.Color;
4 | import android.graphics.Typeface;
5 | import android.os.Bundle;
6 | import android.support.annotation.Nullable;
7 | import android.support.v4.app.Fragment;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.widget.Button;
12 | import android.widget.Toast;
13 |
14 | import by.anatoldeveloper.hallscheme.example.R;
15 | import by.anatoldeveloper.hallscheme.example.SeatExample;
16 | import by.anatoldeveloper.hallscheme.hall.HallScheme;
17 | import by.anatoldeveloper.hallscheme.hall.ScenePosition;
18 | import by.anatoldeveloper.hallscheme.hall.Seat;
19 | import by.anatoldeveloper.hallscheme.hall.SeatListener;
20 | import by.anatoldeveloper.hallscheme.view.ZoomableImageView;
21 |
22 | /**
23 | * Created by Nublo on 03.01.2016.
24 | * Copyright Nublo
25 | */
26 | public class SchemeCustomTypeface extends Fragment {
27 |
28 | boolean doubleTap = false;
29 |
30 | @Nullable
31 | @Override
32 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
33 | View rootView = inflater.inflate(R.layout.scheme_with_button, container, false);
34 | final ZoomableImageView imageView = (ZoomableImageView) rootView.findViewById(R.id.zoomable_image);
35 | final Button zoomButton = (Button) rootView.findViewById(R.id.scheme_button);
36 | zoomButton.setOnClickListener(new View.OnClickListener() {
37 | @Override
38 | public void onClick(View v) {
39 | doubleTap = !doubleTap;
40 | imageView.setZoomByDoubleTap(doubleTap);
41 | if (doubleTap) {
42 | zoomButton.setText(getString(R.string.double_tap_enabled));
43 | } else {
44 | zoomButton.setText(getString(R.string.double_tap_disabled));
45 | }
46 | }
47 | });
48 | HallScheme scheme = new HallScheme(imageView, basicScheme(), getActivity());
49 | scheme.setScenePosition(ScenePosition.NORTH);
50 | scheme.setSeatListener(new SeatListener() {
51 |
52 | @Override
53 | public void selectSeat(int id) {
54 | Toast.makeText(getActivity(), "select seat " + id, Toast.LENGTH_SHORT).show();
55 | }
56 |
57 | @Override
58 | public void unSelectSeat(int id) {
59 | Toast.makeText(getActivity(), "unSelect seat " + id, Toast.LENGTH_SHORT).show();
60 | }
61 |
62 | });
63 | scheme.setTypeface(Typeface.createFromAsset(getActivity().getAssets(), "fonts/DroidSansMono.ttf"));
64 | return rootView;
65 | }
66 |
67 | public Seat[][] basicScheme() {
68 | Seat seats[][] = new Seat[7][14];
69 | int k = 0;
70 | for (int i = 0; i < 7; i++)
71 | for(int j = 0; j < 14; j++) {
72 | SeatExample seat = new SeatExample();
73 | seat.id = ++k;
74 | seat.selectedSeatMarker = String.valueOf(j+1);
75 | seat.status = HallScheme.SeatStatus.BUSY;
76 | if (j == 0 || j == 13) {
77 | seat.marker = String.valueOf(i+1);
78 | seat.status = HallScheme.SeatStatus.INFO;
79 | }
80 | if (j > 5 && j < 8) {
81 | seat.status = HallScheme.SeatStatus.EMPTY;
82 | }
83 | if (((j > 0 && j < 6) || (j > 7 && j < 13)) && i < 2) {
84 | seat.status = HallScheme.SeatStatus.FREE;
85 | seat.color = Color.RED;
86 | }
87 | if (((j > 0 && j < 6) || (j > 7 && j < 13)) && i > 4) {
88 | seat.status = HallScheme.SeatStatus.FREE;
89 | seat.color = Color.GREEN;
90 | }
91 | seats[i][j] = seat;
92 | }
93 | return seats;
94 | }
95 |
96 | }
--------------------------------------------------------------------------------
/sample/src/main/java/by/anatoldeveloper/hallscheme/example/schemes/SchemeDarkTheme.java:
--------------------------------------------------------------------------------
1 | package by.anatoldeveloper.hallscheme.example.schemes;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.Nullable;
5 | import android.support.v4.app.Fragment;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.widget.Toast;
10 |
11 | import by.anatoldeveloper.hallscheme.example.R;
12 | import by.anatoldeveloper.hallscheme.example.SeatExample;
13 | import by.anatoldeveloper.hallscheme.hall.HallScheme;
14 | import by.anatoldeveloper.hallscheme.hall.ScenePosition;
15 | import by.anatoldeveloper.hallscheme.hall.Seat;
16 | import by.anatoldeveloper.hallscheme.hall.SeatListener;
17 | import by.anatoldeveloper.hallscheme.view.ZoomableImageView;
18 |
19 | /**
20 | * Created by Nublo on 06.12.2015.
21 | * Copyright Nublo
22 | */
23 | public class SchemeDarkTheme extends Fragment {
24 |
25 | @Nullable
26 | @Override
27 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
28 | View rootView = inflater.inflate(R.layout.basic_scheme_fragment, container, false);
29 | rootView.setBackgroundColor(getActivity().getResources().getColor(R.color.dark_grey));
30 | ZoomableImageView imageView = (ZoomableImageView) rootView.findViewById(R.id.zoomable_image);
31 | HallScheme scheme = new HallScheme(imageView, schemeWithDifferentColors(), getActivity());
32 | scheme.setBackgroundColor(getActivity().getResources().getColor(R.color.dark_grey));
33 | scheme.setScenePosition(ScenePosition.EAST);
34 | scheme.setSceneTextColor(getActivity().getResources().getColor(R.color.dark_grey));
35 | scheme.setChosenSeatTextColor(getActivity().getResources().getColor(R.color.dark_grey));
36 | scheme.setSceneBackgroundColor(getActivity().getResources().getColor(R.color.white));
37 | scheme.setMarkerColor(getActivity().getResources().getColor(R.color.white));
38 | scheme.setChosenSeatBackgroundColor(getActivity().getResources().getColor(R.color.white));
39 | scheme.setSeatListener(new SeatListener() {
40 |
41 | @Override
42 | public void selectSeat(int id) {
43 | Toast.makeText(getActivity(), "select seat " + id, Toast.LENGTH_SHORT).show();
44 | }
45 |
46 | @Override
47 | public void unSelectSeat(int id) {
48 | Toast.makeText(getActivity(), "unSelect seat " + id, Toast.LENGTH_SHORT).show();
49 | }
50 |
51 | });
52 | return rootView;
53 | }
54 |
55 | public Seat[][] schemeWithDifferentColors() {
56 | Seat seats[][] = new Seat[14][12];
57 | for (int i = 0; i < 14; i++)
58 | for(int j = 0; j < 12; j++) {
59 | SeatExample seat = new SeatExample();
60 | seat.id = i * 10 + (j+1);
61 | seat.selectedSeatMarker = String.valueOf(i+1);
62 | seat.status = HallScheme.SeatStatus.BUSY;
63 | if (j < 2) {
64 | seat.status = HallScheme.SeatStatus.FREE;
65 | seat.color = getActivity().getResources().getColor(R.color.dark_green);
66 | }
67 | if (j == 11) {
68 | seat.status = HallScheme.SeatStatus.FREE;
69 | seat.color = getActivity().getResources().getColor(R.color.dark_purple);
70 | }
71 | if (i == 0 || i == 13) {
72 | seat.status = HallScheme.SeatStatus.EMPTY;
73 | }
74 | if ((i == 1 || i == 12) && j != 11) {
75 | seat.status = HallScheme.SeatStatus.EMPTY;
76 | }
77 | if ((i == 2 || i == 11) && (j < 2 || j == 7)) {
78 | seat.status = HallScheme.SeatStatus.EMPTY;
79 | }
80 | if ((i == 3 || i == 10) && (j < 1 || j == 7)) {
81 | seat.status = HallScheme.SeatStatus.EMPTY;
82 | }
83 | if ((i == 4 || i == 9) && (j > 7)) {
84 | seat.status = HallScheme.SeatStatus.EMPTY;
85 | }
86 | if (j == 7) {
87 | seat.status = HallScheme.SeatStatus.EMPTY;
88 | }
89 | if (i == 0 && j == 11) {
90 | seat.status = HallScheme.SeatStatus.INFO;
91 | seat.marker = String.valueOf(11);
92 | }
93 | if (i == 1 && (j > 7 && j < 11)) {
94 | seat.status = HallScheme.SeatStatus.INFO;
95 | seat.marker = String.valueOf(j);
96 | }
97 | if (i == 1 && (j > 1 && j < 7)) {
98 | seat.status = HallScheme.SeatStatus.INFO;
99 | seat.marker = String.valueOf(j+1);
100 | }
101 | if (i == 2 && j == 1) {
102 | seat.status = HallScheme.SeatStatus.INFO;
103 | seat.marker = String.valueOf(j+1);
104 | }
105 | if (i == 3 && j == 0) {
106 | seat.status = HallScheme.SeatStatus.INFO;
107 | seat.marker = String.valueOf(j+1);
108 | }
109 | seats[i][j] = seat;
110 | }
111 | return seats;
112 | }
113 |
114 | }
--------------------------------------------------------------------------------
/sample/src/main/java/by/anatoldeveloper/hallscheme/example/schemes/SchemeMaxSelectedSeats.java:
--------------------------------------------------------------------------------
1 | package by.anatoldeveloper.hallscheme.example.schemes;
2 |
3 | import android.graphics.Color;
4 | import android.os.Bundle;
5 | import android.support.annotation.Nullable;
6 | import android.support.v4.app.Fragment;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.Button;
11 | import android.widget.Toast;
12 |
13 | import by.anatoldeveloper.hallscheme.example.R;
14 | import by.anatoldeveloper.hallscheme.example.SeatExample;
15 | import by.anatoldeveloper.hallscheme.hall.HallScheme;
16 | import by.anatoldeveloper.hallscheme.hall.MaxSeatsClickListener;
17 | import by.anatoldeveloper.hallscheme.hall.ScenePosition;
18 | import by.anatoldeveloper.hallscheme.hall.Seat;
19 | import by.anatoldeveloper.hallscheme.hall.SeatListener;
20 | import by.anatoldeveloper.hallscheme.view.ZoomableImageView;
21 |
22 | /**
23 | * Created by Nublo on 30.01.2016.
24 | * Copyright Nublo
25 | */
26 | public class SchemeMaxSelectedSeats extends Fragment {
27 |
28 | @Nullable
29 | @Override
30 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
31 | View rootView = inflater.inflate(R.layout.scheme_with_button, container, false);
32 | ZoomableImageView imageView = (ZoomableImageView) rootView.findViewById(R.id.zoomable_image);
33 | final HallScheme scheme = new HallScheme(imageView, basicScheme(), getActivity());
34 | scheme.setScenePosition(ScenePosition.NORTH);
35 | scheme.setSeatListener(new SeatListener() {
36 |
37 | @Override
38 | public void selectSeat(int id) {
39 | Toast.makeText(getActivity(), "select seat " + id, Toast.LENGTH_SHORT).show();
40 | }
41 |
42 | @Override
43 | public void unSelectSeat(int id) {
44 | Toast.makeText(getActivity(), "unSelect seat " + id, Toast.LENGTH_SHORT).show();
45 | }
46 |
47 | });
48 | scheme.setMaxSelectedSeats(5);
49 | scheme.setMaxSeatsClickListener(new MaxSeatsClickListener() {
50 | @Override
51 | public void maxSeatsReached(int id) {
52 | Toast.makeText(getActivity(), "Maximum selected seat limit reached", Toast.LENGTH_SHORT).show();
53 | }
54 | });
55 | Button clickButton = (Button) rootView.findViewById(R.id.scheme_button);
56 | clickButton.setText(getString(R.string.programmatically_click));
57 | clickButton.setOnClickListener(new View.OnClickListener() {
58 | @Override
59 | public void onClick(View v) {
60 | scheme.clickSchemeProgrammatically(1, 1);
61 | }
62 | });
63 | return rootView;
64 | }
65 |
66 | public Seat[][] basicScheme() {
67 | Seat seats[][] = new Seat[7][14];
68 | int k = 0;
69 | for (int i = 0; i < 7; i++)
70 | for(int j = 0; j < 14; j++) {
71 | SeatExample seat = new SeatExample();
72 | seat.id = ++k;
73 | seat.selectedSeatMarker = String.valueOf(j+1);
74 | seat.status = HallScheme.SeatStatus.BUSY;
75 | if (j == 0 || j == 13) {
76 | seat.marker = String.valueOf(i+1);
77 | seat.status = HallScheme.SeatStatus.INFO;
78 | }
79 | if (j > 5 && j < 8) {
80 | seat.status = HallScheme.SeatStatus.EMPTY;
81 | }
82 | if (((j > 0 && j < 6) || (j > 7 && j < 13)) && i < 2) {
83 | seat.status = HallScheme.SeatStatus.FREE;
84 | seat.color = Color.RED;
85 | }
86 | if (((j > 0 && j < 6) || (j > 7 && j < 13)) && i > 4) {
87 | seat.status = HallScheme.SeatStatus.FREE;
88 | seat.color = Color.GREEN;
89 | }
90 | seats[i][j] = seat;
91 | }
92 | return seats;
93 | }
94 |
95 | }
--------------------------------------------------------------------------------
/sample/src/main/java/by/anatoldeveloper/hallscheme/example/schemes/SchemeWithMarkers.java:
--------------------------------------------------------------------------------
1 | package by.anatoldeveloper.hallscheme.example.schemes;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.Nullable;
5 | import android.support.v4.app.Fragment;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.widget.Toast;
10 |
11 | import by.anatoldeveloper.hallscheme.example.R;
12 | import by.anatoldeveloper.hallscheme.example.SeatExample;
13 | import by.anatoldeveloper.hallscheme.hall.HallScheme;
14 | import by.anatoldeveloper.hallscheme.hall.ScenePosition;
15 | import by.anatoldeveloper.hallscheme.hall.Seat;
16 | import by.anatoldeveloper.hallscheme.hall.SeatListener;
17 | import by.anatoldeveloper.hallscheme.view.ZoomableImageView;
18 |
19 | /**
20 | * Created by Nublo on 06.12.2015.
21 | * Copyright Nublo
22 | */
23 | public class SchemeWithMarkers extends Fragment {
24 |
25 | @Nullable
26 | @Override
27 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
28 | View rootView = inflater.inflate(R.layout.basic_scheme_fragment, container, false);
29 | ZoomableImageView imageView = (ZoomableImageView) rootView.findViewById(R.id.zoomable_image);
30 | HallScheme scheme = new HallScheme(imageView, basicScheme(), getActivity());
31 | scheme.setSceneName(getString(R.string.custom_name));
32 | scheme.setScenePosition(ScenePosition.NORTH);
33 | scheme.setSeatListener(new SeatListener() {
34 |
35 | @Override
36 | public void selectSeat(int id) {
37 | Toast.makeText(getActivity(), "select seat " + id, Toast.LENGTH_SHORT).show();
38 | }
39 |
40 | @Override
41 | public void unSelectSeat(int id) {
42 | Toast.makeText(getActivity(), "unSelect seat " + id, Toast.LENGTH_SHORT).show();
43 | }
44 |
45 | });
46 | return rootView;
47 | }
48 |
49 | public Seat[][] basicScheme() {
50 | Seat seats[][] = new Seat[12][18];
51 | int k = 0;
52 | for (int i = 0; i < 12; i++)
53 | for(int j = 0; j < 18; j++) {
54 | SeatExample seat = new SeatExample();
55 | seat.id = ++k;
56 | seat.selectedSeatMarker = String.valueOf(i+1);
57 | seat.status = HallScheme.SeatStatus.BUSY;
58 | if (j == 0 || j == 17) {
59 | seat.status = HallScheme.SeatStatus.EMPTY;
60 | if (i > 2 && i < 10) {
61 | seat.marker = String.valueOf(i);
62 | seat.status = HallScheme.SeatStatus.INFO;
63 | }
64 | }
65 | if (((j > 0 && j < 3) || (j > 14 && j < 17)) && i == 0) {
66 | seat.status = HallScheme.SeatStatus.EMPTY;
67 | if (j == 2 || j == 15) {
68 | seat.marker = String.valueOf(i+1);
69 | seat.status = HallScheme.SeatStatus.INFO;
70 | }
71 | }
72 | if (((j > 0 && j < 2) || (j > 15 && j < 17)) && i == 1) {
73 | seat.status = HallScheme.SeatStatus.EMPTY;
74 | if (j == 1 || j == 16) {
75 | seat.marker = String.valueOf(i+1);
76 | seat.status = HallScheme.SeatStatus.INFO;
77 | }
78 | }
79 | if (i == 2)
80 | seat.status = HallScheme.SeatStatus.EMPTY;
81 | if (i > 9 && (j == 1 || j == 16)) {
82 | seat.status = HallScheme.SeatStatus.INFO;
83 | seat.marker = String.valueOf(i);
84 | }
85 | seats[i][j] = seat;
86 | }
87 | return seats;
88 | }
89 |
90 | }
--------------------------------------------------------------------------------
/sample/src/main/java/by/anatoldeveloper/hallscheme/example/schemes/SchemeWithScene.java:
--------------------------------------------------------------------------------
1 | package by.anatoldeveloper.hallscheme.example.schemes;
2 |
3 | import android.graphics.Color;
4 | import android.os.Bundle;
5 | import android.support.annotation.Nullable;
6 | import android.support.v4.app.Fragment;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.Toast;
11 |
12 | import by.anatoldeveloper.hallscheme.example.R;
13 | import by.anatoldeveloper.hallscheme.example.SeatExample;
14 | import by.anatoldeveloper.hallscheme.hall.HallScheme;
15 | import by.anatoldeveloper.hallscheme.hall.ScenePosition;
16 | import by.anatoldeveloper.hallscheme.hall.Seat;
17 | import by.anatoldeveloper.hallscheme.hall.SeatListener;
18 | import by.anatoldeveloper.hallscheme.view.ZoomableImageView;
19 |
20 | /**
21 | * Created by Nublo on 05.12.2015.
22 | * Copyright Nublo
23 | */
24 | public class SchemeWithScene extends Fragment {
25 |
26 | @Nullable
27 | @Override
28 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
29 | View rootView = inflater.inflate(R.layout.basic_scheme_fragment, container, false);
30 | ZoomableImageView imageView = (ZoomableImageView) rootView.findViewById(R.id.zoomable_image);
31 | HallScheme scheme = new HallScheme(imageView, schemeWithScene(), getActivity());
32 | scheme.setScenePosition(ScenePosition.SOUTH);
33 | scheme.setSeatListener(new SeatListener() {
34 |
35 | @Override
36 | public void selectSeat(int id) {
37 | Toast.makeText(getActivity(), "select seat " + id, Toast.LENGTH_SHORT).show();
38 | }
39 |
40 | @Override
41 | public void unSelectSeat(int id) {
42 | Toast.makeText(getActivity(), "unSelect seat " + id, Toast.LENGTH_SHORT).show();
43 | }
44 |
45 | });
46 | return rootView;
47 | }
48 |
49 | public Seat[][] schemeWithScene() {
50 | Seat seats[][] = new Seat[16][29];
51 | int k = 0;
52 | for (int i = 0; i < 16; i++)
53 | for(int j = 0; j < 29; j++) {
54 | SeatExample seat = new SeatExample();
55 | seat.id = ++k;
56 | seat.selectedSeatMarker = String.valueOf(j+1);
57 | seat.status = HallScheme.SeatStatus.EMPTY;
58 | seats[i][j] = seat;
59 | if (i < 5 && j < 4) {
60 | seat.status = HallScheme.SeatStatus.BUSY;
61 | if (i < 4) {
62 | seat.status = HallScheme.SeatStatus.FREE;
63 | seat.color = Color.argb(255, 60, 179, 113);
64 | }
65 | }
66 | if (j > 1 && j < 5 && i > 4) {
67 | seat.status = HallScheme.SeatStatus.BUSY;
68 | if (i > 13) {
69 | seat.status = HallScheme.SeatStatus.FREE;
70 | seat.color = Color.argb(255, 148, 51, 145);
71 | }
72 | }
73 | if (j == 4 && i > 1 && i < 5)
74 | seat.status = HallScheme.SeatStatus.BUSY;
75 | if (i < 5 && j > 24) {
76 | seat.status = HallScheme.SeatStatus.BUSY;
77 | if (i < 4) {
78 | seat.status = HallScheme.SeatStatus.FREE;
79 | seat.color = Color.argb(255, 60, 179, 113);
80 | }
81 | }
82 | if (j > 23 && j < 27 && i > 4) {
83 | seat.status = HallScheme.SeatStatus.BUSY;
84 | if (i > 13) {
85 | seat.status = HallScheme.SeatStatus.FREE;
86 | seat.color = Color.argb(255, 148, 51, 145);
87 | }
88 | }
89 | if (j == 24 && i > 1 && i < 5)
90 | seat.status = HallScheme.SeatStatus.BUSY;
91 | if (i > 3 && j > 6 && j < 22) {
92 | seat.status = HallScheme.SeatStatus.BUSY;
93 | if (i > 13) {
94 | seat.status = HallScheme.SeatStatus.FREE;
95 | seat.color = Color.argb(255, 43, 108, 196);
96 | }
97 | }
98 |
99 | }
100 | return seats;
101 | }
102 |
103 | }
--------------------------------------------------------------------------------
/sample/src/main/java/by/anatoldeveloper/hallscheme/example/schemes/SchemeWithZones.java:
--------------------------------------------------------------------------------
1 | package by.anatoldeveloper.hallscheme.example.schemes;
2 |
3 | import android.graphics.Color;
4 | import android.os.Bundle;
5 | import android.support.annotation.Nullable;
6 | import android.support.v4.app.Fragment;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.Toast;
11 |
12 | import java.util.ArrayList;
13 | import java.util.List;
14 |
15 | import by.anatoldeveloper.hallscheme.example.R;
16 | import by.anatoldeveloper.hallscheme.example.SeatExample;
17 | import by.anatoldeveloper.hallscheme.example.ZoneExample;
18 | import by.anatoldeveloper.hallscheme.hall.HallScheme;
19 | import by.anatoldeveloper.hallscheme.hall.ScenePosition;
20 | import by.anatoldeveloper.hallscheme.hall.Seat;
21 | import by.anatoldeveloper.hallscheme.hall.SeatListener;
22 | import by.anatoldeveloper.hallscheme.hall.Zone;
23 | import by.anatoldeveloper.hallscheme.hall.ZoneListener;
24 | import by.anatoldeveloper.hallscheme.view.ZoomableImageView;
25 |
26 | /**
27 | * Created by Nublo on 31.01.2016.
28 | * Copyright Nublo
29 | */
30 | public class SchemeWithZones extends Fragment {
31 |
32 | @Nullable
33 | @Override
34 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
35 | View rootView = inflater.inflate(R.layout.basic_scheme_fragment, container, false);
36 | ZoomableImageView imageView = (ZoomableImageView) rootView.findViewById(R.id.zoomable_image);
37 | HallScheme scheme = new HallScheme(imageView, schemeWithScene(), getActivity());
38 | scheme.setScenePosition(ScenePosition.SOUTH);
39 | scheme.setSeatListener(new SeatListener() {
40 |
41 | @Override
42 | public void selectSeat(int id) {
43 | Toast.makeText(getActivity(), "select seat " + id, Toast.LENGTH_SHORT).show();
44 | }
45 |
46 | @Override
47 | public void unSelectSeat(int id) {
48 | Toast.makeText(getActivity(), "unSelect seat " + id, Toast.LENGTH_SHORT).show();
49 | }
50 |
51 | });
52 | scheme.setZones(zones());
53 | scheme.setZoneListener(new ZoneListener() {
54 | @Override
55 | public void zoneClick(int id) {
56 | Toast.makeText(getActivity(), "Zone click " + id, Toast.LENGTH_SHORT).show();
57 | }
58 | });
59 | return rootView;
60 | }
61 |
62 | public Seat[][] schemeWithScene() {
63 | Seat seats[][] = new Seat[23][26];
64 | int k = 0;
65 | for (int i = 0; i < 23; i++)
66 | for(int j = 0; j < 26; j++) {
67 | SeatExample seat = new SeatExample();
68 | seat.id = ++k;
69 | seat.selectedSeatMarker = String.valueOf(j+1);
70 | seat.status = HallScheme.SeatStatus.EMPTY;
71 | seats[i][j] = seat;
72 | if (i == 22 && (j < 5 || j > 20)) {
73 | seat.status = HallScheme.SeatStatus.BUSY;
74 | }
75 | if (i == 21 && (j < 6 || j > 19)) {
76 | seat.status = HallScheme.SeatStatus.BUSY;
77 | }
78 | if (i == 20 && (j < 7 || j > 18)) {
79 | seat.status = HallScheme.SeatStatus.BUSY;
80 | }
81 | if (i > 16 && i < 21 && (j < 7 || j > 18)) {
82 | seat.status = HallScheme.SeatStatus.BUSY;
83 | }
84 | if (i > 7 && i < 16 && (j < 6 || j > 19)) {
85 | seat.status = HallScheme.SeatStatus.BUSY;
86 | }
87 | if (i == 4 && (j < 5 || j > 20)) {
88 | seat.status = HallScheme.SeatStatus.BUSY;
89 | }
90 | if (i > 4 && i < 8 && (j < 3 || j > 22)) {
91 | seat.status = HallScheme.SeatStatus.FREE;
92 | seat.color = Color.GREEN;
93 | }
94 |
95 | }
96 | return seats;
97 | }
98 |
99 | public List zones() {
100 | List zones = new ArrayList<>();
101 | ZoneExample zone1 = new ZoneExample(1, 8, 17, 10, 6, getActivity().getResources().getColor(R.color.dark_green), "Not used in current version");
102 | ZoneExample zone2 = new ZoneExample(2, 8, 4, 10, 12, Color.DKGRAY, "Not used in current version");
103 | ZoneExample zone3 = new ZoneExample(3, 0, 0, 26, 2, getActivity().getResources().getColor(R.color.dark_purple), "Not used in current version");
104 | zones.add(zone1);
105 | zones.add(zone2);
106 | zones.add(zone3);
107 | return zones;
108 | }
109 |
110 | }
--------------------------------------------------------------------------------
/sample/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/basic_scheme_fragment.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/halls_fragment.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/scheme_with_button.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
21 |
22 |
--------------------------------------------------------------------------------
/sample/src/main/res/menu/main_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nublo/HallScheme/7ac4bf085dae23c14d0b40c70e61d2f0e43a1bbb/sample/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nublo/HallScheme/7ac4bf085dae23c14d0b40c70e61d2f0e43a1bbb/sample/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nublo/HallScheme/7ac4bf085dae23c14d0b40c70e61d2f0e43a1bbb/sample/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nublo/HallScheme/7ac4bf085dae23c14d0b40c70e61d2f0e43a1bbb/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nublo/HallScheme/7ac4bf085dae23c14d0b40c70e61d2f0e43a1bbb/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | HallScheme
3 | Custom name
4 | View on github
5 | Double tap enabled
6 | Double tap disabled
7 | Programmatically click
8 |
9 |
--------------------------------------------------------------------------------
/sample/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':sample', ':library'
2 |
--------------------------------------------------------------------------------