diff --git a/android/assets/text/application/application_cs.properties b/android/assets/text/application/application_cs.properties index aa1ba71c06fe683a95de26cb8e66af4466979fb9..56ead3c480f04de599cb2ae3745d417d228200c2 100644 --- a/android/assets/text/application/application_cs.properties +++ b/android/assets/text/application/application_cs.properties @@ -30,8 +30,14 @@ victoryscreen_button_changegame=Jinou hru victoryscreen_text_tutorial=Gratuluji! A teÄŹ to zkus sám… game_robbery_title=LupiÄŤi +game_robbery_description=ProcviÄŤovánĂ pracovnĂ pamÄ›ti game_kidnapping_title=Ăšnos +game_kidnapping_description=ProcviÄŤovánĂ sluchovĂ© pamÄ›ti game_pursuit_title=PronásledovánĂ +game_pursuit_description=ProcviÄŤovánĂ prostorovĂ© orientace game_night_watch_title=HlĂdka +game_night_watch_description=ProcviÄŤovánĂ zrakovĂ© pamÄ›ti game_shooting_range_title=StĹ™elnice +game_shooting_range_description=ProcviÄŤovánĂ pozornosti game_in_the_darkness_title=PotmÄ› +game_in_the_darkness_description=ProcviÄŤovánĂ seriality diff --git a/android/assets/text/application/application_de.properties b/android/assets/text/application/application_de.properties index 21e1e091870378dbb71f8f40e7744091a5b78a95..5547f8875c7e6eac5c76ca5d8df7229e7e4bdbec 100644 --- a/android/assets/text/application/application_de.properties +++ b/android/assets/text/application/application_de.properties @@ -30,8 +30,14 @@ victoryscreen_button_changegame=Anderes Spiel victoryscreen_text_tutorial=Gratulation! Und nun versuch es selbst… game_robbery_title=Einbrecher +game_robbery_description=Training des Arbeitsgedächtnisses game_kidnapping_title=EntfĂĽhrung +game_kidnapping_description=Training des Hörgedächtnisses game_pursuit_title=Verfolgung +game_pursuit_description=Training der räumlichen Orientierung game_night_watch_title=Wache +game_night_watch_description=Training des Sehgedächtnisses game_shooting_range_title=SchieĂźstand +game_shooting_range_description=Aufmerksamkeitstraining game_in_the_darkness_title=Im Dunkeln +game_in_the_darkness_description=Training der Serialität diff --git a/android/assets/text/application/application_sk.properties b/android/assets/text/application/application_sk.properties index 19f13ef37032923c4c13a9f4427fcda5662ad5fa..6b5d594ee17e6d8542ffa7d1328b7c13cbf06833 100644 --- a/android/assets/text/application/application_sk.properties +++ b/android/assets/text/application/application_sk.properties @@ -30,8 +30,14 @@ victoryscreen_button_changegame=InĂş hru victoryscreen_text_tutorial=Gratulujem! A teraz to skĂşs sám… game_robbery_title=LupiÄŤi +game_robbery_description=PrecviÄŤovanie pracovnej pamäti game_kidnapping_title=Ăšnos +game_kidnapping_description=PrecviÄŤovanie sluchovej pamäti game_pursuit_title=Prenasledovanie +game_pursuit_description=PrecviÄŤovanie priestorovej orientácie game_night_watch_title=Hliadka +game_night_watch_description=PrecviÄŤovanie zrakovej pamäti game_shooting_range_title=Strelnica +game_shooting_range_description=PrecviÄŤovanie pozornosti game_in_the_darkness_title=Potme +game_in_the_darkness_description=PrecviÄŤovanie seriality diff --git a/core/assets/common/_global/application/mainmenu/childitem_arrow.png b/core/assets/common/_global/application/mainmenu/childitem_arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..1c2e214bfd50466514a105e4dbf4c1fd3a380522 Binary files /dev/null and b/core/assets/common/_global/application/mainmenu/childitem_arrow.png differ diff --git a/core/assets/common/_global/application/mainmenu/childitem_background.9.png b/core/assets/common/_global/application/mainmenu/childitem_background.9.png new file mode 100644 index 0000000000000000000000000000000000000000..38b98c4a079d6ab5ccad765d98b8725f4d8ab4e6 Binary files /dev/null and b/core/assets/common/_global/application/mainmenu/childitem_background.9.png differ diff --git a/core/assets/common/_global/application/mainmenu/childitem_restart.png b/core/assets/common/_global/application/mainmenu/childitem_restart.png new file mode 100644 index 0000000000000000000000000000000000000000..5ce500f7fc58e5546933fcb7a9cb531ac6abbf50 Binary files /dev/null and b/core/assets/common/_global/application/mainmenu/childitem_restart.png differ diff --git a/core/assets/common/_global/application/mainmenu/icon_about_pressed.png b/core/assets/common/_global/application/mainmenu/icon_about_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..956acd6e1595579d130d06e7b81d2bbc6334e8f2 Binary files /dev/null and b/core/assets/common/_global/application/mainmenu/icon_about_pressed.png differ diff --git a/core/assets/common/_global/application/mainmenu/icon_about_unpressed.png b/core/assets/common/_global/application/mainmenu/icon_about_unpressed.png new file mode 100644 index 0000000000000000000000000000000000000000..36a8ae98285632018093f699e26df35945b739d1 Binary files /dev/null and b/core/assets/common/_global/application/mainmenu/icon_about_unpressed.png differ diff --git a/core/assets/common/_global/application/mainmenu/icon_encyclopedia_pressed.png b/core/assets/common/_global/application/mainmenu/icon_encyclopedia_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..b8983a736688baf9d24ca78bf51625c482ac3266 Binary files /dev/null and b/core/assets/common/_global/application/mainmenu/icon_encyclopedia_pressed.png differ diff --git a/core/assets/common/_global/application/mainmenu/icon_encyclopedia_unpressed.png b/core/assets/common/_global/application/mainmenu/icon_encyclopedia_unpressed.png new file mode 100644 index 0000000000000000000000000000000000000000..d1081904892ad04dd85db4e33e899dbc85775c40 Binary files /dev/null and b/core/assets/common/_global/application/mainmenu/icon_encyclopedia_unpressed.png differ diff --git a/core/assets/common/_global/application/mainmenu/icon_games_pressed.png b/core/assets/common/_global/application/mainmenu/icon_games_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..4ad3d1e5e669e9df4be1ec07feee59a3d21ed87e Binary files /dev/null and b/core/assets/common/_global/application/mainmenu/icon_games_pressed.png differ diff --git a/core/assets/common/_global/application/mainmenu/icon_games_unpressed.png b/core/assets/common/_global/application/mainmenu/icon_games_unpressed.png new file mode 100644 index 0000000000000000000000000000000000000000..71ecaaf1d30c38ebf018b2227c2a4ee7c5b958c7 Binary files /dev/null and b/core/assets/common/_global/application/mainmenu/icon_games_unpressed.png differ diff --git a/core/assets/common/_global/application/mainmenu/icon_halloffame_pressed.png b/core/assets/common/_global/application/mainmenu/icon_halloffame_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..62d2fd5a721d858c3bcd766f586469a9688df942 Binary files /dev/null and b/core/assets/common/_global/application/mainmenu/icon_halloffame_pressed.png differ diff --git a/core/assets/common/_global/application/mainmenu/icon_halloffame_unpressed.png b/core/assets/common/_global/application/mainmenu/icon_halloffame_unpressed.png new file mode 100644 index 0000000000000000000000000000000000000000..0425b12933793c5e6356503804663492960be088 Binary files /dev/null and b/core/assets/common/_global/application/mainmenu/icon_halloffame_unpressed.png differ diff --git a/core/assets/common/_global/application/mainmenu/icon_logout_pressed.png b/core/assets/common/_global/application/mainmenu/icon_logout_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..1aa1015c36053e7572e3e01b36127df711fc9b7d Binary files /dev/null and b/core/assets/common/_global/application/mainmenu/icon_logout_pressed.png differ diff --git a/core/assets/common/_global/application/mainmenu/icon_logout_unpressed.png b/core/assets/common/_global/application/mainmenu/icon_logout_unpressed.png new file mode 100644 index 0000000000000000000000000000000000000000..60dae7f05210d1bcbc7cdb26d2ddfd05092c6df0 Binary files /dev/null and b/core/assets/common/_global/application/mainmenu/icon_logout_unpressed.png differ diff --git a/core/assets/common/_global/application/mainmenu/icon_statistics_pressed.png b/core/assets/common/_global/application/mainmenu/icon_statistics_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..8b46d28277c6edec3d2ba1252b12ade90bcd76c1 Binary files /dev/null and b/core/assets/common/_global/application/mainmenu/icon_statistics_pressed.png differ diff --git a/core/assets/common/_global/application/mainmenu/icon_statistics_unpressed.png b/core/assets/common/_global/application/mainmenu/icon_statistics_unpressed.png new file mode 100644 index 0000000000000000000000000000000000000000..2f9f7d4d558861eab834d542ea4b9804ec1adf2f Binary files /dev/null and b/core/assets/common/_global/application/mainmenu/icon_statistics_unpressed.png differ diff --git a/core/assets/common/_global/application/mainmenu/user_background.9.png b/core/assets/common/_global/application/mainmenu/user_background.9.png new file mode 100644 index 0000000000000000000000000000000000000000..a1e2e2c3f5294b01ed3336b74c07e1097068bffa Binary files /dev/null and b/core/assets/common/_global/application/mainmenu/user_background.9.png differ diff --git a/core/assets/common/_global/application/usermenu/menubutton_background.9.png b/core/assets/common/_global/application/usermenu/menubutton_background.9.png new file mode 100644 index 0000000000000000000000000000000000000000..ffda5082419b9f370e9e7727519ad0c2095452fb Binary files /dev/null and b/core/assets/common/_global/application/usermenu/menubutton_background.9.png differ diff --git a/core/assets/common/_global/application/usermenu/menuitem_background.9.png b/core/assets/common/_global/application/usermenu/menuitem_background.9.png new file mode 100644 index 0000000000000000000000000000000000000000..4c225cd9d79e0cb1f1db21936dfeb08ebf7a92f3 Binary files /dev/null and b/core/assets/common/_global/application/usermenu/menuitem_background.9.png differ diff --git a/core/assets/common/_global/application/usermenu/menuitem_triangle.png b/core/assets/common/_global/application/usermenu/menuitem_triangle.png new file mode 100644 index 0000000000000000000000000000000000000000..fd0c20a4445a41ce1d023437f96b24012d8e0f02 Binary files /dev/null and b/core/assets/common/_global/application/usermenu/menuitem_triangle.png differ diff --git a/core/assets/common/_global/application/usermenu/sample.jpg b/core/assets/common/_global/application/usermenu/sample.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1e3cd607ba82ceadb66dd3d99cc9cc3e952fc81d Binary files /dev/null and b/core/assets/common/_global/application/usermenu/sample.jpg differ diff --git a/core/src/cz/nic/tablexia/Tablexia.java b/core/src/cz/nic/tablexia/Tablexia.java index 2c22eb55531c60bcf6337e8b9d48d0fbf87730e1..7bb3db82f3249019b2f2c6b64e63a19f742fc962 100644 --- a/core/src/cz/nic/tablexia/Tablexia.java +++ b/core/src/cz/nic/tablexia/Tablexia.java @@ -14,6 +14,7 @@ import net.engio.mbassy.listener.Handler; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.Locale; +import java.util.Map; import cz.nic.tablexia.bus.ApplicationBus; import cz.nic.tablexia.bus.ApplicationBus.ApplicationEvent; @@ -26,7 +27,6 @@ import cz.nic.tablexia.menu.AbstractMenu; import cz.nic.tablexia.menu.MenuController; import cz.nic.tablexia.menu.main.MainMenu; import cz.nic.tablexia.screen.AbstractTablexiaScreen; -import cz.nic.tablexia.screen.loader.LoaderScreen; import cz.nic.tablexia.util.Log; import cz.nic.tablexia.util.Utility; import cz.nic.tablexia.util.ui.TablexiaButton; @@ -90,12 +90,16 @@ public class Tablexia extends TablexiaApplication { } private Class<? extends AbstractTablexiaScreen> showLastOrInitialScreen() { - AbstractTablexiaScreen<?> screenToChange = TablexiaStorage.getInstance().getCurrentScreen(TablexiaSettings.getInstance().getSelectedUser()); + AbstractTablexiaScreen<?> screenToChange = TablexiaStorage.getInstance().getSavedScreen(TablexiaSettings.getInstance().getSelectedUser()); if (screenToChange != null) { setScreenIfIsDifferent(screenToChange, ScreenTransaction.FADE); } else { - screenToChange = Utility.getScreenForScreenClass(TablexiaSettings.INITIAL_SCREEN); - setScreenIfIsDifferent(screenToChange, ScreenTransaction.MOVE_LEFT); + ScreenTransaction screenTransaction = ScreenTransaction.FADE; + if (TablexiaSettings.LOADER_SCREEN.equals(TablexiaApplication.getActualScreenClass())) { + screenTransaction = ScreenTransaction.MOVE_LEFT; + } + screenToChange = Utility.getScreenForScreenClass(TablexiaSettings.INITIAL_SCREEN, null); + setScreenIfIsDifferent(screenToChange, screenTransaction); } return screenToChange.getClass(); } @@ -115,7 +119,7 @@ public class Tablexia extends TablexiaApplication { private void startLoading(Locale locale) { // sync loaded screen with loader image - setScreenIfIsDifferent(new LoaderScreen()); + setScreenIfIsDifferent(Utility.getScreenForScreenClass(TablexiaSettings.LOADER_SCREEN, null)); // async internal assets loading ApplicationFontManager.getInstance().load(); @@ -170,8 +174,6 @@ public class Tablexia extends TablexiaApplication { public void run() { if (selectedUserEvent.isUserSelected()) { showLastOrInitialScreen(); - } else { - setScreenIfIsDifferent(new LoaderScreen(), TablexiaApplication.ScreenTransaction.FADE); } } }); @@ -212,15 +214,6 @@ public class Tablexia extends TablexiaApplication { startLoading(TablexiaSettings.getInstance().getLocale()); } - @Override - public void pause() { - if (menuController != null && getScreen() != null && getScreen().canBePaused()) { - // don't use menu open animation for android and iOS pause event (animation is run after resume) - menuController.doMenuAction(MainMenu.class, AbstractMenu.MenuAction.OPEN, Gdx.app.getType().equals(Application.ApplicationType.Desktop), false); - } - super.pause(); - } - @Override public void render() { // render other screens @@ -359,12 +352,18 @@ public class Tablexia extends TablexiaApplication { public static class ChangeScreenEvent implements ApplicationEvent { - private Class<? extends AbstractTablexiaScreen<?>> screen; - private ScreenTransaction screenTransaction; + private Class<? extends AbstractTablexiaScreen<?>> screen; + private ScreenTransaction screenTransaction; + private Map<String, String> screenInitialState; public ChangeScreenEvent(Class<? extends AbstractTablexiaScreen<?>> screen, ScreenTransaction screenTransaction) { + this(screen, screenTransaction, null); + } + + public ChangeScreenEvent(Class<? extends AbstractTablexiaScreen<?>> screen, ScreenTransaction screenTransaction, Map<String, String> screenInitialState) { this.screen = screen; this.screenTransaction = screenTransaction; + this.screenInitialState = screenInitialState; } public Class<? extends AbstractTablexiaScreen<?>> getScreen() { @@ -374,6 +373,10 @@ public class Tablexia extends TablexiaApplication { public ScreenTransaction getScreenTransaction() { return screenTransaction; } + + public Map<String, String> getScreenInitialState() { + return screenInitialState; + } } @Handler @@ -392,7 +395,7 @@ public class Tablexia extends TablexiaApplication { @Override public void run() { - setScreenIfIsDifferent(Utility.getScreenForScreenClass(screenClass), changeScreenEvent.getScreenTransaction()); + setScreenIfIsDifferent(Utility.getScreenForScreenClass(screenClass, changeScreenEvent.getScreenInitialState()), changeScreenEvent.getScreenTransaction()); } }); } diff --git a/core/src/cz/nic/tablexia/TablexiaApplication.java b/core/src/cz/nic/tablexia/TablexiaApplication.java index 30858f50f1dccdfd8e8ea50ed5eb51019068176a..70bdaf0ba7198e34d8bfed8c355b4abc84b49403 100644 --- a/core/src/cz/nic/tablexia/TablexiaApplication.java +++ b/core/src/cz/nic/tablexia/TablexiaApplication.java @@ -25,6 +25,7 @@ import cz.nic.tablexia.loader.application.ApplicationAtlasManager; import cz.nic.tablexia.menu.MenuController; import cz.nic.tablexia.screen.AbstractTablexiaScreen; import cz.nic.tablexia.screen.AbstractTablexiaScreen.ScreenLoadingListener; +import cz.nic.tablexia.util.Log; import static com.badlogic.gdx.scenes.scene2d.actions.Actions.fadeIn; import static com.badlogic.gdx.scenes.scene2d.actions.Actions.fadeOut; @@ -42,8 +43,8 @@ public abstract class TablexiaApplication implements ApplicationListener { private static final Color BACKGROUND_COLOR = new Color(0f, 0f, 0f, 1f); private static final int DIMMER_TRANSACTION_SPEED = 1; + private static AbstractTablexiaScreen<?> screen; private AbstractTablexiaScreen<?> lastScreen; - private AbstractTablexiaScreen<?> screen; private InputMultiplexer inputMultiplexer; private DebugInfo debugInfo; private Actor screenDimmer; @@ -51,12 +52,21 @@ public abstract class TablexiaApplication implements ApplicationListener { private Stage stage; +//////////////////////////// TablexiaApplication API + public Stage getStage() { return stage; } + public static Class<? extends AbstractTablexiaScreen> getActualScreenClass() { + if (screen == null) { + return null; + } + return screen.getClass(); + } - //////////////////////////// LIBGDX LIFECYCLE + +//////////////////////////// LIBGDX LIFECYCLE @Override public void dispose() { @@ -73,6 +83,7 @@ public abstract class TablexiaApplication implements ApplicationListener { if (screen != null) { screen.hide(); screen.dispose(); + screen = null; } } @@ -262,7 +273,7 @@ public abstract class TablexiaApplication implements ApplicationListener { * @param newScreen new screen to change for * @param screenTransaction screen transaction type */ - public void setScreen(final AbstractTablexiaScreen<?> newScreen, ScreenTransaction screenTransaction) { + public void setScreen(final AbstractTablexiaScreen<?> newScreen, final ScreenTransaction screenTransaction) { if (screenTransaction == null) { setScreen(newScreen); } else { @@ -291,7 +302,7 @@ public abstract class TablexiaApplication implements ApplicationListener { new Runnable() { @Override public void run() { - newScreen.performScreenVisible(); + processScreenVisible(screen); } }); } @@ -309,10 +320,14 @@ public abstract class TablexiaApplication implements ApplicationListener { @SuppressWarnings("unchecked") private void processNewScreen(AbstractTablexiaScreen<?> newScreen) { if (newScreen != null) { - inputMultiplexer.addProcessor(newScreen.getInputProcessor()); - newScreen.show(); - newScreen.resize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); - ApplicationBus.getInstance().post(new ScreenChangedEvent((Class<? extends AbstractTablexiaScreen<?>>) newScreen.getClass())).asynchronously(); + try { + inputMultiplexer.addProcessor(newScreen.getInputProcessor()); + newScreen.show(); + newScreen.resize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); + ApplicationBus.getInstance().post(new ScreenChangedEvent((Class<? extends AbstractTablexiaScreen<?>>) newScreen.getClass())).asynchronously(); + } catch (Throwable t) { + performScreenLoadingErrorAction(newScreen, t); + } } } @@ -326,6 +341,19 @@ public abstract class TablexiaApplication implements ApplicationListener { } } + private void processScreenVisible(AbstractTablexiaScreen<?> lastScreen) { + try { + lastScreen.performScreenVisible(); + } catch (Throwable t) { + performScreenLoadingErrorAction(lastScreen, t); + } + } + + private void performScreenLoadingErrorAction(AbstractTablexiaScreen<?> screen, Throwable t) { + Log.err(TablexiaApplication.this.getClass(), "Cannot load screen: " + screen.getClass(), t); + ApplicationBus.getInstance().post(new Tablexia.ChangeScreenEvent(TablexiaSettings.INITIAL_SCREEN, ScreenTransaction.FADE)).asynchronously(); + } + //////////////////////////// SCREEN TRANSACTIONS diff --git a/core/src/cz/nic/tablexia/TablexiaSettings.java b/core/src/cz/nic/tablexia/TablexiaSettings.java index 67fb403f944b418f7f5e628cb65208308c7764ea..82163b12c22f4b93af262bfb7787ba9488dc246d 100644 --- a/core/src/cz/nic/tablexia/TablexiaSettings.java +++ b/core/src/cz/nic/tablexia/TablexiaSettings.java @@ -12,6 +12,7 @@ import cz.nic.tablexia.loader.application.ApplicationTextManager; import cz.nic.tablexia.model.User; import cz.nic.tablexia.screen.AbstractTablexiaScreen; import cz.nic.tablexia.screen.gamemenu.GameMenuScreen; +import cz.nic.tablexia.screen.loader.LoaderScreen; import cz.nic.tablexia.util.Log; public class TablexiaSettings { @@ -21,6 +22,7 @@ public class TablexiaSettings { private static final int MIN_SCREEN_HEIGHT = (int) (DEFAULT_SCREEN_WIDTH * MAXIMUM_RATIO); private static final boolean DEBUG_SHOW_BOUNDING_BOXES = true; + public static final Class<? extends AbstractTablexiaScreen<?>> LOADER_SCREEN = LoaderScreen.class; public static final Class<? extends AbstractTablexiaScreen<?>> INITIAL_SCREEN = GameMenuScreen.class; public static final int AVATAR_COUNT = 8; @@ -31,8 +33,9 @@ public class TablexiaSettings { public static final String DEV_VERSION_TYPE = "-SNAPSHOT-"; - private final BuildType BUILD_TYPE; - private final String VERSION_NAME = TablexiaBuildConfig.VERSION_NAME; + private static final String APP_NAME = "Tablexia"; + private final String VERSION_NAME = TablexiaBuildConfig.VERSION_NAME; + private final BuildType BUILD_TYPE; private Preferences preferences; private LocaleDefinition systemLocale; @@ -42,19 +45,21 @@ public class TablexiaSettings { public enum BuildType { - RELEASE("release", false, Log.TablexiaLogLevel.ERROR), - DEBUG("debug", true, Log.TablexiaLogLevel.DEBUG), - DEVEL("devel", true, Log.TablexiaLogLevel.DEBUG); + RELEASE("release", false, false, Log.TablexiaLogLevel.ERROR), + DEBUG("debug", true, true, Log.TablexiaLogLevel.DEBUG), + DEVEL("devel", true, true, Log.TablexiaLogLevel.DEBUG); private final static BuildType FALLBACK_VARIANT = BuildType.DEVEL; private final String key; private final boolean isDebug; + private boolean showBuildTypeInName; private final Log.TablexiaLogLevel logLevel; - BuildType(String key, boolean isDebug, Log.TablexiaLogLevel logLevel) { + BuildType(String key, boolean isDebug, boolean showBuildTypeInName, Log.TablexiaLogLevel logLevel) { this.key = key; this.isDebug = isDebug; + this.showBuildTypeInName = showBuildTypeInName; this.logLevel = logLevel; } @@ -62,6 +67,10 @@ public class TablexiaSettings { return key; } + public String getAppName() { + return showBuildTypeInName ? APP_NAME + " " + key.toUpperCase() : APP_NAME; + } + public boolean isDebug() { return isDebug; } @@ -129,6 +138,10 @@ public class TablexiaSettings { //////////////////////////// SETTINGS ACCESS + public String getAppName() { + return getBuildType().getAppName(); + } + public boolean isDebug() { return BUILD_TYPE.isDebug(); } @@ -179,14 +192,16 @@ public class TablexiaSettings { } public void setSelectedUser(User selectedUser) { - this.selectedUser = selectedUser; - if (selectedUser == null) { - preferences.remove(SELECTED_USER); - } else { - preferences.putLong(SELECTED_USER, selectedUser.getId()); + if (this.selectedUser == null || !this.selectedUser.equals(selectedUser)) { + this.selectedUser = selectedUser; + if (selectedUser == null) { + preferences.remove(SELECTED_USER); + } else { + preferences.putLong(SELECTED_USER, selectedUser.getId()); + } + preferences.flush(); + ApplicationBus.getInstance().publishAsync(new SelectedUserEvent(selectedUser != null)); } - preferences.flush(); - ApplicationBus.getInstance().publishAsync(new SelectedUserEvent(selectedUser != null)); } public User getSelectedUser() { @@ -235,6 +250,10 @@ public class TablexiaSettings { return localeKey; } + public String getDescriptionKey() { + return descriptionKey; + } + public Locale getLocale() { return locale != null ? locale : instance.systemLocale.locale; } diff --git a/core/src/cz/nic/tablexia/TablexiaStorage.java b/core/src/cz/nic/tablexia/TablexiaStorage.java index 560d471db67b2a748b4427d0cf6fe734899b8f2d..5c6291475bfb70399fd810915a5a18547521db51 100644 --- a/core/src/cz/nic/tablexia/TablexiaStorage.java +++ b/core/src/cz/nic/tablexia/TablexiaStorage.java @@ -159,7 +159,7 @@ public class TablexiaStorage { private static final int SCREEN_QUERY_USERID_INDEX = 1; - public AbstractTablexiaScreen<?> getCurrentScreen(User selectedUser) { + public AbstractTablexiaScreen<?> getSavedScreen(User selectedUser) { AbstractTablexiaScreen<?> result = null; if (selectedUser != null) { try { @@ -170,7 +170,7 @@ public class TablexiaStorage { String screenClassName = resultSet.getString(SCREEN_QUERY_SCREEN_INDEX); if (screenClassName != null) { try { - result = Utility.getScreenForScreenClass(ClassReflection.forName(screenClassName)); + result = Utility.getScreenForScreenClass(ClassReflection.forName(screenClassName), null); } catch (ReflectionException e) { Log.err(getClass(), "Cannot load screen class: " + screenClassName, e); } @@ -186,7 +186,7 @@ public class TablexiaStorage { } public void resetScreenState(AbstractTablexiaScreen screen) { - if (screen.hasState()) { + if (screen.canResetState()) { resetScreenState(); } } @@ -203,8 +203,8 @@ public class TablexiaStorage { } public Map<String, String> loadScreenState(AbstractTablexiaScreen screen, User selectedUser) { - if (screen.hasState() && selectedUser != null) { - Map<String, String> screenState = new HashMap<String, String>(); + Map<String, String> screenState = new HashMap<String, String>(); + if (selectedUser != null) { try { PreparedStatement statement = prepareStatement(SCREEN_STATE_SELECT); statement.setString(STATE_QUERY_SCREEN_INDEX, screen.getClass().getName()); @@ -222,13 +222,12 @@ public class TablexiaStorage { } catch (SQLException e) { Log.err(getClass(), "Cannot select screen state from DB!", e); } - return screenState.size() > 0 ? screenState : null; } - return null; + return screenState; } public void saveScreenState(AbstractTablexiaScreen screen, Map<String, String> screenState, User selectedUser) { - if (screen.hasState() && selectedUser != null) { + if (selectedUser != null) { try { connection.setAutoCommit(false); resetScreenState(); diff --git a/core/src/cz/nic/tablexia/bus/event/MenuControlEvent.java b/core/src/cz/nic/tablexia/bus/event/MenuControlEvent.java index f5003c32cce26189c18f8e4f033d65dcfc4ad18b..866c3dd8200f814141920bb872a2ae4296e02676 100644 --- a/core/src/cz/nic/tablexia/bus/event/MenuControlEvent.java +++ b/core/src/cz/nic/tablexia/bus/event/MenuControlEvent.java @@ -1,19 +1,20 @@ package cz.nic.tablexia.bus.event; import cz.nic.tablexia.bus.ApplicationBus; +import cz.nic.tablexia.menu.AbstractMenu; public class MenuControlEvent implements ApplicationBus.ApplicationEvent { - private boolean open; - private boolean animated; + private AbstractMenu.MenuAction menuAction; + private boolean animated; - public MenuControlEvent(boolean open, boolean animated) { - this.open = open; + public MenuControlEvent(AbstractMenu.MenuAction menuAction, boolean animated) { + this.menuAction = menuAction; this.animated = animated; } - public boolean isOpen() { - return open; + public AbstractMenu.MenuAction getMenuAction() { + return menuAction; } public boolean isAnimated() { diff --git a/core/src/cz/nic/tablexia/game/AbstractTablexiaGame.java b/core/src/cz/nic/tablexia/game/AbstractTablexiaGame.java index 544e8284d81c659ba0e17e334d2d3862bf10bbc0..3f1e2b1535af28980e5fad3566879f138e7e2340 100644 --- a/core/src/cz/nic/tablexia/game/AbstractTablexiaGame.java +++ b/core/src/cz/nic/tablexia/game/AbstractTablexiaGame.java @@ -25,6 +25,7 @@ import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; +import cz.nic.tablexia.Tablexia; import cz.nic.tablexia.TablexiaApplication; import cz.nic.tablexia.TablexiaSettings; import cz.nic.tablexia.TablexiaStorage; @@ -35,8 +36,10 @@ import cz.nic.tablexia.game.common.TablexiaRandom; import cz.nic.tablexia.game.difficulty.GameDifficulty; import cz.nic.tablexia.loader.application.ApplicationFontManager; import cz.nic.tablexia.loader.application.ApplicationTextManager; +import cz.nic.tablexia.menu.AbstractMenu; import cz.nic.tablexia.model.game.Game; import cz.nic.tablexia.screen.AbstractTablexiaScreen; +import cz.nic.tablexia.screen.gamemenu.GameMenuScreen; import cz.nic.tablexia.util.Log; import cz.nic.tablexia.util.ui.TablexiaButton; import cz.nic.tablexia.util.ui.dialog.TwoButtonDialog; @@ -137,11 +140,6 @@ public abstract class AbstractTablexiaGame<T> extends AbstractTablexiaScreen<T> private boolean inGameLoading; public AbstractTablexiaGame() { - this(true); - } - - public AbstractTablexiaGame(boolean screenState) { - super(screenState); inGameLoading = false; gamePhase = GamePhase.PREPARED; } @@ -149,16 +147,36 @@ public abstract class AbstractTablexiaGame<T> extends AbstractTablexiaScreen<T> //////////////////////////// SCREEN PAUSE + @Override public boolean canBePaused() { return gamePhase.isPause(); } + @Override + public boolean canStopActions () { + return true; + } + + @Handler + public void handleMenuPauseEvent(AbstractMenu.MenuPauseEvent menuPauseEvent) { + if (menuPauseEvent.isPause()) { + performScreenPaused(); + } else { + performScreenResumed(); + } + } + //////////////////////////// ABSTRACT TABLEXIA SCREEN LIFECYCLE @Override protected final void screenLoaded(final Map<String, String> screenState) { - performGameLoaded(screenState); + try { + performGameLoaded(screenState); + } catch (Throwable t) { + Log.err(getClass(), "Cannot resume screen state!", t); + TablexiaStorage.getInstance().resetScreenState(this); + } if(inGameLoading) { performShowTransaction(new Runnable() { @Override @@ -175,8 +193,8 @@ public abstract class AbstractTablexiaGame<T> extends AbstractTablexiaScreen<T> gamePhase = GamePhase.STARTED; // if game is restored -> open menu and pause game - if (screenState != null) { - ApplicationBus.getInstance().publishAsync(new MenuControlEvent(true, true)); + if (screenState.size() > 0) { + ApplicationBus.getInstance().publishAsync(new MenuControlEvent(AbstractMenu.MenuAction.OPEN, true)); } } @@ -207,6 +225,7 @@ public abstract class AbstractTablexiaGame<T> extends AbstractTablexiaScreen<T> @Override protected final void screenPaused(Map<String, String> screenState) { if (gamePhase == GamePhase.STARTED) { + ApplicationBus.getInstance().post(new MenuControlEvent(AbstractMenu.MenuAction.OPEN, true)).asynchronously(); performGamePaused(screenState); screenState.put(GAME_STATE_GAME_ID, String.valueOf(game.getId())); Log.info(getClass(), "[DB] Stored game object to screen state: " + game); @@ -240,7 +259,7 @@ public abstract class AbstractTablexiaGame<T> extends AbstractTablexiaScreen<T> game = null; //load game db object from screen state - if (screenState != null) { + if (screenState.size() > 0) { // restore from game state String gameIdStr = screenState.get(GAME_STATE_GAME_ID); game = gameIdStr != null ? Game.getGameForId(Long.valueOf(gameIdStr)) : null; @@ -576,7 +595,8 @@ public abstract class AbstractTablexiaGame<T> extends AbstractTablexiaScreen<T> @Override protected void leftButtonAction() { - backToInitialScreen(); + Map<String, String> gameMenuState = GameMenuScreen.createScreenState(GameMenuScreen.GameMenuPageDefinition.getGameMenuPageForGameDefinition(GameDefinition.getGameDefinitionForClass(AbstractTablexiaGame.this.getClass()))); + ApplicationBus.getInstance().post(new Tablexia.ChangeScreenEvent(GameMenuScreen.class, TablexiaApplication.ScreenTransaction.FADE, gameMenuState)).asynchronously(); } @Override diff --git a/core/src/cz/nic/tablexia/game/GameDefinition.java b/core/src/cz/nic/tablexia/game/GameDefinition.java index ee4a4c93e3946eb667a349957a556f93407a0436..7156751c1f3df271e9fc35f936a14857e70d31e3 100644 --- a/core/src/cz/nic/tablexia/game/GameDefinition.java +++ b/core/src/cz/nic/tablexia/game/GameDefinition.java @@ -1,7 +1,7 @@ package cz.nic.tablexia.game; -import cz.nic.tablexia.Tablexia.ChangeScreenEvent; -import cz.nic.tablexia.TablexiaApplication.ScreenTransaction; +import cz.nic.tablexia.Tablexia; +import cz.nic.tablexia.TablexiaApplication; import cz.nic.tablexia.bus.ApplicationBus; import cz.nic.tablexia.bus.ApplicationBus.ApplicationEvent; import cz.nic.tablexia.game.games.in_the_darkness.InTheDarknessGame; @@ -15,29 +15,31 @@ import cz.nic.tablexia.loader.application.ApplicationTextManager; import cz.nic.tablexia.menu.AbstractMenu; import cz.nic.tablexia.menu.IMenuItem; import cz.nic.tablexia.model.game.Game; +import cz.nic.tablexia.screen.gamemenu.GameMenuScreen; +import cz.nic.tablexia.screen.gamemenu.event.ShowGameMenuPageEvent; public enum GameDefinition implements ApplicationEvent, IMenuItem { - ROBBERY(1, "game_robbery_title", RobberyGame.class, false, new RobberyGame.GameResultResolver()), - PURSUIT(2, "game_pursuit_title", PursuitGame.class, false, new PursuitGame.GameResultResolver()), - KIDNAPPING(3, "game_kidnapping_title", KidnappingGame.class, false, new GameResultResolver() { + ROBBERY(1, "game_robbery_title", "game_robbery_description", RobberyGame.class, false, new RobberyGame.GameResultResolver()), + PURSUIT(2, "game_pursuit_title", "game_pursuit_description", PursuitGame.class, false, new PursuitGame.GameResultResolver()), + KIDNAPPING(3, "game_kidnapping_title", "game_kidnapping_description", KidnappingGame.class, false, new GameResultResolver() { @Override public AbstractTablexiaGame.GameResult getGameResult(Game game) { return AbstractTablexiaGame.GameResult.NO_STAR; } }), - NIGHT_WATCH(4, "game_night_watch_title", NightWatchGame.class, false,new NightWatchGame.GameResultResolver()), - SHOOTING_RANGE(5, "game_shooting_range_title", ShootingRangeGame.class, false, new ShootingRangeResultResolver()), - IN_THE_DARKNESS(6, "game_in_the_darkness_title", InTheDarknessGame.class, true, new InTheDarknessGame.GameResultResolver()); + NIGHT_WATCH(4, "game_night_watch_title", "game_night_watch_description", NightWatchGame.class, false,new NightWatchGame.GameResultResolver()), + SHOOTING_RANGE(5, "game_shooting_range_title", "game_shooting_range_description", ShootingRangeGame.class, false, new ShootingRangeResultResolver()), + IN_THE_DARKNESS(6, "game_in_the_darkness_title", "game_in_the_darkness_description", InTheDarknessGame.class, true, new InTheDarknessGame.GameResultResolver()); public interface GameResultResolver { AbstractTablexiaGame.GameResult getGameResult(Game game); } - private int gameNumber; private String menuTextKey; + private String descriptionResource; private Class<? extends AbstractTablexiaGame<?>> screenClass; private boolean hasTutorial; private GameResultResolver gameResultResolver; @@ -46,9 +48,10 @@ public enum GameDefinition implements ApplicationEvent, IMenuItem { return new GameDefinition[]{ROBBERY, PURSUIT, KIDNAPPING, NIGHT_WATCH, SHOOTING_RANGE, IN_THE_DARKNESS}; } - GameDefinition(int gameNumber, String nameResource, Class<? extends AbstractTablexiaGame<?>> screenClass, boolean hasTutorial, GameResultResolver gameResultResolver) { + GameDefinition(int gameNumber, String nameResource, String descriptionResource, Class<? extends AbstractTablexiaGame<?>> screenClass, boolean hasTutorial, GameResultResolver gameResultResolver) { this.gameNumber = gameNumber; this.menuTextKey = nameResource; + this.descriptionResource = descriptionResource; this.screenClass = screenClass; this.hasTutorial = hasTutorial; this.gameResultResolver = gameResultResolver; @@ -63,6 +66,15 @@ public enum GameDefinition implements ApplicationEvent, IMenuItem { return ApplicationTextManager.getInstance().getResult().get(menuTextKey); } + @Override + public String getDescription() { + return ApplicationTextManager.getInstance().getResult().get(descriptionResource); + } + + public Class<? extends AbstractTablexiaGame<?>> getScreenClass() { + return screenClass; + } + public boolean hasTutorial() { return hasTutorial; } @@ -70,7 +82,13 @@ public enum GameDefinition implements ApplicationEvent, IMenuItem { @Override public void performAction() { ApplicationBus.getInstance().publishAsync(this); - ApplicationBus.getInstance().publishAsync(new ChangeScreenEvent(screenClass, ScreenTransaction.FADE)); + if (TablexiaApplication.getActualScreenClass() == GameMenuScreen.class) { + ApplicationBus.getInstance().publishAsync(new ShowGameMenuPageEvent(GameDefinition.this, true)); + } else { + ApplicationBus.getInstance().publishAsync(new Tablexia.ChangeScreenEvent(GameMenuScreen.class, + TablexiaApplication.ScreenTransaction.FADE, + GameMenuScreen.createScreenState(GameMenuScreen.GameMenuPageDefinition.getGameMenuPageForGameDefinition(this)))); + } } @Override diff --git a/core/src/cz/nic/tablexia/game/games/in_the_darkness/InTheDarknessGame.java b/core/src/cz/nic/tablexia/game/games/in_the_darkness/InTheDarknessGame.java index a25d9049af2d952c2b50ff0e7691a028bdd7e7d8..552fc0a476447c0e7386b5efda0f4ac0533c260b 100644 --- a/core/src/cz/nic/tablexia/game/games/in_the_darkness/InTheDarknessGame.java +++ b/core/src/cz/nic/tablexia/game/games/in_the_darkness/InTheDarknessGame.java @@ -545,12 +545,8 @@ public class InTheDarknessGame extends AbstractTablexiaGame<List<MapWidget>> imp private ActionsStripWidget showActionsStripWidget(Map<String, String> gameState) { // Sprite actionStripBackground = new Sprite(displaySize.x - (actionStripWidgetWidth / 2), displaySize.y - (displaySize.y / 2), actionStripWidgetWidth, displaySize.y, ResourceManager.getInstance().getTexture(ResourceManager.BACKGROUND_ACTIONSTRIP_TEXTURE), getVertexBufferObjectManager()); // GameLayer.BACKGROUND_TEXTURE_LAYER.getLayerEntity().attachChild(actionStripBackground); - Float scrollPanePosition = null; - String selectedActionsString = null; - if (gameState != null) { - scrollPanePosition = Float.valueOf(gameState.get(GAME_STATE_KEY_SCROLL_PANE_POSITION)); - selectedActionsString = gameState.get(GAME_STATE_KEY_SELECTED_ACTIONS); - } + Float scrollPanePosition = gameState.containsKey(GAME_STATE_KEY_SCROLL_PANE_POSITION) ? Float.valueOf(gameState.get(GAME_STATE_KEY_SCROLL_PANE_POSITION)) : null; + String selectedActionsString = gameState.containsKey(GAME_STATE_KEY_SELECTED_ACTIONS) ? gameState.get(GAME_STATE_KEY_SELECTED_ACTIONS) : null; ActionsStripWidget actionStripWidget = new ActionsStripWidget(ACTION_STRIP_WIDGET_WIDTH, contentGroup.getHeight(), scrollPanePosition, selectedActionsString, this); actionStripWidget.setPosition(getStage().getWidth() - actionStripWidget.getWidth(), -SCREEN_Y_CORRECTION_OFFSET); diff --git a/core/src/cz/nic/tablexia/game/games/robbery/AbstractRobberyScreen.java b/core/src/cz/nic/tablexia/game/games/robbery/AbstractRobberyScreen.java index 0e07347d6c8aa90a05203bdf99b4e678530cdde3..0f0283ecf93d05be5e7e6815f4d01e32707342fc 100644 --- a/core/src/cz/nic/tablexia/game/games/robbery/AbstractRobberyScreen.java +++ b/core/src/cz/nic/tablexia/game/games/robbery/AbstractRobberyScreen.java @@ -15,7 +15,6 @@ public abstract class AbstractRobberyScreen extends AbstractTablexiaScreen<GameR private RobberyGame robberyGame; public AbstractRobberyScreen(RobberyGame robberyGame) { - super(false); this.robberyGame = robberyGame; } @@ -37,8 +36,9 @@ public abstract class AbstractRobberyScreen extends AbstractTablexiaScreen<GameR //////////////////////////// SCREEN PAUSE - public boolean canBePaused() { - return true; + @Override + public boolean isScreenPaused() { + return robberyGame.isScreenPaused(); } diff --git a/core/src/cz/nic/tablexia/game/games/robbery/RobberyGame.java b/core/src/cz/nic/tablexia/game/games/robbery/RobberyGame.java index af090f5ae68d2d89784b40e051144a40bbe40eae..cf184cc61b16b3675e0f826ad91108522b9d1602 100644 --- a/core/src/cz/nic/tablexia/game/games/robbery/RobberyGame.java +++ b/core/src/cz/nic/tablexia/game/games/robbery/RobberyGame.java @@ -196,7 +196,6 @@ public class RobberyGame extends AbstractTablexiaGame<GameRule> { //////////////////////////// ABSTRACT TABLEXIA GAME - @Override protected List<SummaryMessage> getSummaryMessageForGameResult(Game game) { String identification = game.getUser().getGender() == User.Gender.MALE ? getText(SUMMARY_IDENTIFICATION_MALE_TEXT_KEY) : getText(SUMMARY_IDENTIFICATION_FEMALE_TEXT_KEY); diff --git a/core/src/cz/nic/tablexia/loader/TablexiaAtlasManager.java b/core/src/cz/nic/tablexia/loader/TablexiaAtlasManager.java index 9fa277df79cdab5dbd5642998d981807a6178d52..65eb3e964a724fce2d2416ae5f87dbb89bd6439a 100644 --- a/core/src/cz/nic/tablexia/loader/TablexiaAtlasManager.java +++ b/core/src/cz/nic/tablexia/loader/TablexiaAtlasManager.java @@ -44,6 +44,10 @@ public class TablexiaAtlasManager extends TablexiaAbstractFileManager { } public TextureRegion getTextureRegionFromAtlas(String atlasName, String regionName, Integer index) { + return getTextureRegionFromAtlas(atlasName, regionName, index, true); + } + + public TextureRegion getTextureRegionFromAtlas(String atlasName, String regionName, Integer index, boolean useBleedingFix) { TextureAtlas atlas = getAsset(atlasName, TextureAtlas.class); if (atlas == null) { Log.err(getClass(), "Cannot get region: " + regionName + " -> Atlas with name: " + atlasName + " not found!"); @@ -61,19 +65,23 @@ public class TablexiaAtlasManager extends TablexiaAbstractFileManager { return null; } - // create new smaller region -> fix texture bleeding - float x = region.getRegionX(); - float y = region.getRegionY(); - float width = region.getRegionWidth(); - float height = region.getRegionHeight(); - float invTexWidth = 1f / region.getTexture().getWidth(); - float invTexHeight = 1f / region.getTexture().getHeight(); - - return new TextureRegion(region.getTexture(), - (x + BLEEDING_EDGE_OFFSET) * invTexWidth, - (y + BLEEDING_EDGE_OFFSET) * invTexHeight, - (x + width - BLEEDING_EDGE_OFFSET) * invTexWidth, - (y + height - BLEEDING_EDGE_OFFSET) * invTexHeight); + if (useBleedingFix) { + // create new smaller region -> fix texture bleeding + float x = region.getRegionX(); + float y = region.getRegionY(); + float width = region.getRegionWidth(); + float height = region.getRegionHeight(); + float invTexWidth = 1f / region.getTexture().getWidth(); + float invTexHeight = 1f / region.getTexture().getHeight(); + + return new TextureRegion(region.getTexture(), + (x + BLEEDING_EDGE_OFFSET) * invTexWidth, + (y + BLEEDING_EDGE_OFFSET) * invTexHeight, + (x + width - BLEEDING_EDGE_OFFSET) * invTexWidth, + (y + height - BLEEDING_EDGE_OFFSET) * invTexHeight); + } else { + return region; + } } public NinePatch getPatchFromAtlas(String atlasName, String patchName) { diff --git a/core/src/cz/nic/tablexia/loader/application/ApplicationAtlasManager.java b/core/src/cz/nic/tablexia/loader/application/ApplicationAtlasManager.java index 33794e0b218c13502ceb4707dda7a084458aa7bb..ce42c499f8bf16d8661cc09a2bcfaf3843844b92 100644 --- a/core/src/cz/nic/tablexia/loader/application/ApplicationAtlasManager.java +++ b/core/src/cz/nic/tablexia/loader/application/ApplicationAtlasManager.java @@ -5,7 +5,6 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion; import cz.nic.tablexia.loader.IApplicationLoader; import cz.nic.tablexia.loader.TablexiaAtlasManager; -import cz.nic.tablexia.screen.encyclopedia.assets.EncyclopediaAssets; public class ApplicationAtlasManager extends TablexiaAtlasManager implements IApplicationLoader { @@ -32,10 +31,32 @@ public class ApplicationAtlasManager extends TablexiaAtlasManager implements IAp private static final String APPLICATION_PATH = GLOBAL_PATH + "application/"; private static final String APPLICATION_ATLAS = APPLICATION_PATH + "application.atlas"; - public static final String MAINMENU_PATH = "mainmenu/"; - public static final String MAINMENU_BACKGROUND = MAINMENU_PATH + "background"; - public static final String MAINMENU_BORDER_SWITCH = MAINMENU_PATH + "background_border_switch"; - public static final String MAINMENU_BORDER_NOSWITCH = MAINMENU_PATH + "background_border_noswitch"; + public static final String MAINMENU_PATH = "mainmenu/"; + public static final String MAINMENU_BACKGROUND = MAINMENU_PATH + "background"; + public static final String MAINMENU_BORDER_SWITCH = MAINMENU_PATH + "background_border_switch"; + public static final String MAINMENU_BORDER_NOSWITCH = MAINMENU_PATH + "background_border_noswitch"; + public static final String MAINMENU_ICON_ABOUT_PRESSED = MAINMENU_PATH + "icon_about_pressed"; + public static final String MAINMENU_ICON_ABOUT_UNPRESSED = MAINMENU_PATH + "icon_about_unpressed"; + public static final String MAINMENU_ICON_ENCYCLOPEDIA_PRESSED = MAINMENU_PATH + "icon_encyclopedia_pressed"; + public static final String MAINMENU_ICON_ENCYCLOPEDIA_UNPRESSED = MAINMENU_PATH + "icon_encyclopedia_unpressed"; + public static final String MAINMENU_ICON_GAMES_PRESSED = MAINMENU_PATH + "icon_games_pressed"; + public static final String MAINMENU_ICON_GAMES_UNPRESSED = MAINMENU_PATH + "icon_games_unpressed"; + public static final String MAINMENU_ICON_HALLOFFAME_PRESSED = MAINMENU_PATH + "icon_halloffame_pressed"; + public static final String MAINMENU_ICON_HALLOFFAME_UNPRESSED = MAINMENU_PATH + "icon_halloffame_unpressed"; + public static final String MAINMENU_ICON_LOGOUT_PRESSED = MAINMENU_PATH + "icon_logout_pressed"; + public static final String MAINMENU_ICON_LOGOUT_UNPRESSED = MAINMENU_PATH + "icon_logout_unpressed"; + public static final String MAINMENU_ICON_STATISTICS_PRESSED = MAINMENU_PATH + "icon_statistics_pressed"; + public static final String MAINMENU_ICON_STATISTICS_UNPRESSED = MAINMENU_PATH + "icon_statistics_unpressed"; + public static final String MAINMENU_CHILDITEM_BACKGROUND = MAINMENU_PATH + "childitem_background"; + public static final String MAINMENU_CHILDITEM_ARROW = MAINMENU_PATH + "childitem_arrow"; + public static final String MAINMENU_CHILDITEM_RESTART = MAINMENU_PATH + "childitem_restart"; + + public static final String USERMENU_PATH = "usermenu/"; + public static final String USERMENU_MENUITEM_BACKGROUND = USERMENU_PATH + "menuitem_background"; + public static final String USERMENU_MENUITEM_TRIANGLE = USERMENU_PATH + "menuitem_triangle"; + public static final String USERMENU_MENUBUTTON_BACKGROUND = USERMENU_PATH + "menubutton_background"; + //TODO remove + public static final String USERMENU_MENUITEM_SAMPLE = USERMENU_PATH + "sample"; public static final String DIALOG_PATH = "dialog/"; public static final String DIALOG_BUBBLE_CLASSIC = DIALOG_PATH + "bubble_classic"; @@ -76,6 +97,10 @@ public class ApplicationAtlasManager extends TablexiaAtlasManager implements IAp return getTextureRegionFromAtlas(APPLICATION_ATLAS, textureName, null); } + public TextureRegion getTextureRegion(String textureName, boolean useBleedingFix) { + return getTextureRegionFromAtlas(APPLICATION_ATLAS, textureName, null, useBleedingFix); + } + public NinePatch getPatch(String patchName) { return getPatchFromAtlas(APPLICATION_ATLAS, patchName); } diff --git a/core/src/cz/nic/tablexia/menu/AbstractMenu.java b/core/src/cz/nic/tablexia/menu/AbstractMenu.java index 18870549b54a65547208aac83e93b827d29279f2..44e944ab464b7eb335c633f1a0ce65ac8988bfd6 100644 --- a/core/src/cz/nic/tablexia/menu/AbstractMenu.java +++ b/core/src/cz/nic/tablexia/menu/AbstractMenu.java @@ -4,15 +4,18 @@ import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.g2d.Sprite; import com.badlogic.gdx.math.Interpolation; import com.badlogic.gdx.scenes.scene2d.Action; +import com.badlogic.gdx.scenes.scene2d.Group; import com.badlogic.gdx.scenes.scene2d.InputEvent; import com.badlogic.gdx.scenes.scene2d.actions.Actions; import com.badlogic.gdx.scenes.scene2d.ui.Button; +import com.badlogic.gdx.scenes.scene2d.ui.Container; import com.badlogic.gdx.scenes.scene2d.ui.HorizontalGroup; import com.badlogic.gdx.scenes.scene2d.ui.Image; import com.badlogic.gdx.scenes.scene2d.ui.Stack; import com.badlogic.gdx.scenes.scene2d.ui.Table; import com.badlogic.gdx.scenes.scene2d.ui.TextButton; import com.badlogic.gdx.scenes.scene2d.ui.TextButton.TextButtonStyle; +import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup; import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; import com.badlogic.gdx.scenes.scene2d.utils.SpriteDrawable; import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; @@ -35,6 +38,8 @@ import cz.nic.tablexia.util.ui.TablexiaNoBlendingImage; */ public abstract class AbstractMenu extends Stack implements Disposable { + private static final int MENU_ITEMS_ALIGN = Align.left; + protected enum MenuControlType { MANUAL (ApplicationAtlasManager.MAINMENU_BORDER_SWITCH, true, false), @@ -113,7 +118,7 @@ public abstract class AbstractMenu extends Stack implements Disposable { private static final int OPEN_MENU_BUTTON_HEIGHT = 75; private static final int OPEN_MENU_BUTTON_TOP_OFFSET = 60; - private Table menuTableLayout; + private VerticalGroup menuItemsLayout; private TextButtonStyle menuButtonStyle; private float menuHidePositionX; private float menuClosePositionX; @@ -126,25 +131,33 @@ public abstract class AbstractMenu extends Stack implements Disposable { private boolean isClosing; private boolean isOpening; + private Image background; + private Image border; + public AbstractMenu(Float width, Float height) { + background = new TablexiaNoBlendingImage(ApplicationAtlasManager.getInstance().getTextureRegion(ApplicationAtlasManager.MAINMENU_BACKGROUND)); + border = new Image(ApplicationAtlasManager.getInstance().getTextureRegion(getMenuControlType().getAssetName())); + setBounds(0, 0, width, height); setDebug(TablexiaSettings.getInstance().isShowBoundingBoxes()); // don't click through the menu addListener(new ClickListener()); - Image background = new TablexiaNoBlendingImage(ApplicationAtlasManager.getInstance().getTextureRegion(ApplicationAtlasManager.MAINMENU_BACKGROUND)); - Image border = new Image(ApplicationAtlasManager.getInstance().getTextureRegion(getMenuControlType().getAssetName())); + // menu layout + menuItemsLayout = new VerticalGroup(); + Container<Group> layoutContainer = new Container<Group>(); + layoutContainer.setDebug(true, false); + layoutContainer.setActor(createMenuLayout(menuItemsLayout)); + layoutContainer.align(Align.left); - float totalWidth = background.getWidth() + border.getWidth(); - background.getDrawable().setMinHeight(height); - background.getDrawable().setMinWidth(width * (background.getWidth() / totalWidth)); - border.getDrawable().setMinHeight(height); - border.getDrawable().setMinWidth(width * (border.getWidth() / totalWidth)); + Stack backgroundStack = new Stack(); + backgroundStack.add(background); + backgroundStack.add(layoutContainer); HorizontalGroup horizontalGroup = new HorizontalGroup(); horizontalGroup.setHeight(height); - horizontalGroup.addActor(background); + horizontalGroup.addActor(backgroundStack); horizontalGroup.addActor(border); addActor(horizontalGroup); @@ -152,11 +165,6 @@ public abstract class AbstractMenu extends Stack implements Disposable { isClosing = false; isOpening = false; - // menu layout - menuTableLayout = new Table(); - menuTableLayout.setFillParent(true); - addActor(menuTableLayout); - // menu button style menuButtonStyle = new TextButtonStyle(); menuButtonStyle.font = ApplicationFontManager.getInstance().getFont(ApplicationFontManager.APPLICATION_DEFAULT_FONT_REGULAR); @@ -190,11 +198,31 @@ public abstract class AbstractMenu extends Stack implements Disposable { hideMenu(false); } + protected Image getBackground() { + return background; + } + + @Override + protected void sizeChanged() { + if (background != null && border != null) { + float totalWidth = background.getWidth() + border.getWidth(); + background.getDrawable().setMinHeight(getHeight()); + background.getDrawable().setMinWidth(getWidth() * (background.getWidth() / totalWidth)); + border.getDrawable().setMinHeight(getHeight()); + border.getDrawable().setMinWidth(getWidth() * (border.getWidth() / totalWidth)); + super.sizeChanged(); + } + } + @Override public void dispose() { //nothing needed } + protected Group createMenuLayout(VerticalGroup menuLayout) { + return menuLayout; + } + protected abstract MenuControlType getMenuControlType(); protected abstract boolean isScreenPause(); @@ -205,21 +233,46 @@ public abstract class AbstractMenu extends Stack implements Disposable { protected abstract List<? extends IMenuItem> getMenuItems(); public void initMenuItems() { - menuTableLayout.reset(); - menuTableLayout.setDebug(TablexiaSettings.getInstance().isShowBoundingBoxes()); + menuItemsLayout.clear(); + menuItemsLayout.align(MENU_ITEMS_ALIGN); + menuItemsLayout.fill(); for (final IMenuItem menuItem : getMenuItems()) { - addMenuItem(menuItem); + Group menuItemContainer = createMenuItem(menuItem); + menuItemContainer.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + doMenuAction(menuItem.getMenuAction(), true, true); + performMenuAction(menuItem); + } + }); + menuItemsLayout.addActor(menuItemContainer); IMenuItem[] subMenu = menuItem.getSubmenu(); if (subMenu != null) { - for (IMenuItem submenuItem : subMenu) { - addMenuItem(submenuItem); + for (final IMenuItem submenuItem : subMenu) { + Group submenuItemContainer = createSubMenuItem(submenuItem); + submenuItemContainer.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + doMenuAction(submenuItem.getMenuAction(), true, true); + performMenuAction(submenuItem); + } + }); + menuItemsLayout.addActor(submenuItemContainer); } } } } - private void addMenuItem(final IMenuItem menuItem) { + protected Group createMenuItem(final IMenuItem menuItem) { + return createDefaultMenuItem(menuItem); + } + + protected Group createSubMenuItem(final IMenuItem menuItem) { + return createDefaultMenuItem(menuItem); + } + + private Group createDefaultMenuItem(final IMenuItem menuItem) { TextButton menuButton = new TextButton(menuItem.getTitle(), menuButtonStyle); menuButton.addListener(new ClickListener() { @@ -230,8 +283,8 @@ public abstract class AbstractMenu extends Stack implements Disposable { } }); - menuTableLayout.add(menuButton).expandX(); - menuTableLayout.row(); + + return menuButton; } protected void performMenuAction(final IMenuItem menuItem) { diff --git a/core/src/cz/nic/tablexia/menu/IMenuItem.java b/core/src/cz/nic/tablexia/menu/IMenuItem.java index 1c329b114d9562abaeb8033a53b62322b8da70d1..3901fbeb4f24841825043e389525e372a5a0a3bb 100644 --- a/core/src/cz/nic/tablexia/menu/IMenuItem.java +++ b/core/src/cz/nic/tablexia/menu/IMenuItem.java @@ -3,6 +3,7 @@ package cz.nic.tablexia.menu; public interface IMenuItem { String getTitle(); + String getDescription(); void performAction(); AbstractMenu.MenuAction getMenuAction(); IMenuItem[] getSubmenu(); diff --git a/core/src/cz/nic/tablexia/menu/MenuController.java b/core/src/cz/nic/tablexia/menu/MenuController.java index d89844b917e236fac1887cf58e8b091628efb0a9..ee0488658887f340e9f3f38996a5ae7e8b1f535c 100644 --- a/core/src/cz/nic/tablexia/menu/MenuController.java +++ b/core/src/cz/nic/tablexia/menu/MenuController.java @@ -15,6 +15,7 @@ import java.util.HashMap; import java.util.Map; import cz.nic.tablexia.Tablexia; +import cz.nic.tablexia.TablexiaApplication; import cz.nic.tablexia.TablexiaSettings; import cz.nic.tablexia.bus.ApplicationBus; import cz.nic.tablexia.bus.event.MenuControlEvent; @@ -35,6 +36,8 @@ public class MenuController extends Group implements Disposable { private final Actor screenDimmer; private final Map<Class<? extends AbstractMenu>, AbstractMenu> menus; + private boolean loadingComplete = false; + public MenuController(float width, float height) { setBounds(0, 0, width, height); // click through the viewport @@ -139,11 +142,7 @@ public class MenuController extends Group implements Disposable { @Handler public void handleMenuControlEvent(MenuControlEvent menuControlEvent) { - if (menuControlEvent.isOpen()) { - doMenuAction(MainMenu.class, AbstractMenu.MenuAction.OPEN, menuControlEvent.isAnimated(), false); - } else { - doMenuAction(MainMenu.class, AbstractMenu.MenuAction.CLOSE, menuControlEvent.isAnimated(), false); - } + doMenuAction(MainMenu.class, menuControlEvent.getMenuAction(), menuControlEvent.isAnimated(), false); } @@ -151,44 +150,27 @@ public class MenuController extends Group implements Disposable { @Handler public void handleApplicationLoadingCompleteEvent(Tablexia.ApplicationLoadingCompleteEvent applicationLoadingCompleteEvent) { - if (TablexiaSettings.getInstance().getSelectedUser() == null) { - doMenuAction(UserMenu.class, AbstractMenu.MenuAction.OPEN, true, true); - } else { - showMainMenuOnNextScreen(); - } + loadingComplete = true; + screenVisibleEvent(null); } @Handler public void handleSelectedUserEvent(TablexiaSettings.SelectedUserEvent selectedUserEvent) { - if (selectedUserEvent.isUserSelected()) { - showMainMenuOnNextScreen(); - } else { - openUserMenuOnNextScreen(); + if (!selectedUserEvent.isUserSelected()) { + doMenuAction(MainMenu.class, AbstractMenu.MenuAction.HIDE, true, true); } } - -//////////////////////////// NEXT SCREEN VISIBLE ACTIONS - - private AbstractMenu.MenuAction nextScreenVisibleMenuAction; - private Class<? extends AbstractMenu> nextScreenVisibleMenuType; - - private void openUserMenuOnNextScreen() { - nextScreenVisibleMenuAction = AbstractMenu.MenuAction.OPEN; - nextScreenVisibleMenuType = UserMenu.class; - } - - private void showMainMenuOnNextScreen() { - nextScreenVisibleMenuAction = AbstractMenu.MenuAction.SHOW; - nextScreenVisibleMenuType = MainMenu.class; - } - @Handler public void screenVisibleEvent(AbstractTablexiaScreen.ScreenVisibleEvent screenVisibleEvent) { - if (nextScreenVisibleMenuType != null && nextScreenVisibleMenuAction != null) { - doMenuAction(nextScreenVisibleMenuType, nextScreenVisibleMenuAction, true, true); - nextScreenVisibleMenuType = null; - nextScreenVisibleMenuAction = null; + if (TablexiaSettings.LOADER_SCREEN.equals(TablexiaApplication.getActualScreenClass())) { + if (loadingComplete && TablexiaSettings.getInstance().getSelectedUser() == null) { + doMenuAction(UserMenu.class, AbstractMenu.MenuAction.OPEN, true, true); + } + } else { + if (TablexiaSettings.getInstance().getSelectedUser() != null) { + doMenuAction(MainMenu.class, AbstractMenu.MenuAction.SHOW, true, true); + } } } } diff --git a/core/src/cz/nic/tablexia/menu/main/LocaleSelectBox.java b/core/src/cz/nic/tablexia/menu/main/LocaleSelectBox.java new file mode 100644 index 0000000000000000000000000000000000000000..a9b4fe4a7b2d0fca97c566739dafaae53b54dec2 --- /dev/null +++ b/core/src/cz/nic/tablexia/menu/main/LocaleSelectBox.java @@ -0,0 +1,111 @@ +package cz.nic.tablexia.menu.main; + +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.GlyphLayout; +import com.badlogic.gdx.graphics.g2d.NinePatch; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.badlogic.gdx.utils.Align; + +import java.util.ArrayList; +import java.util.List; + +import cz.nic.tablexia.TablexiaSettings; +import cz.nic.tablexia.bus.ApplicationBus; +import cz.nic.tablexia.loader.application.ApplicationAtlasManager; +import cz.nic.tablexia.loader.application.ApplicationFontManager; +import cz.nic.tablexia.loader.application.ApplicationTextManager; +import cz.nic.tablexia.util.ui.AbstractTablexiaSelectBox; + +/** + * Created by Matyáš Latner. + */ +public class LocaleSelectBox extends AbstractTablexiaSelectBox<LocaleSelectBox.LocaleItem> { + + private static final Color LOCALE_TEXT_COLOR = new Color(0.098f, 0.086f, 0.075f, 1f); + private static final int LOCALE_TEXT_ALIGN = Align.center; + + private final float textSize; + + public class LocaleItem extends Actor { + + private final NinePatch background; + private final BitmapFont font; + private final String text; + private final GlyphLayout glyphLayout; + private final TablexiaSettings.LocaleDefinition localeDefinition; + + public LocaleItem(TablexiaSettings.LocaleDefinition localeDefinition) { + this.localeDefinition = localeDefinition; + + background = ApplicationAtlasManager.getInstance().getPatch(ApplicationAtlasManager.USERMENU_MENUITEM_BACKGROUND); + font = ApplicationFontManager.getInstance().getDefaultApplicationRegularFont(); + text = ApplicationTextManager.getInstance().getText(localeDefinition.getDescriptionKey()); + glyphLayout = new GlyphLayout(); + } + + public TablexiaSettings.LocaleDefinition getLocaleDefinition() { + return localeDefinition; + } + + @Override + public void draw(Batch batch, float parentAlpha) { + LOCALE_TEXT_COLOR.a = parentAlpha; + font.setColor(LOCALE_TEXT_COLOR); + + background.draw(batch, getX(), getY(), getWidth(), getHeight()); + + font.getData().setScale(textSize); + glyphLayout.setText(font, text, LOCALE_TEXT_COLOR, getWidth(), LOCALE_TEXT_ALIGN, false); + font.draw(batch, glyphLayout, getX(), getY() + getHeight() / 2 + font.getLineHeight() / 3); + font.getData().setScale(1f); + } + } + + private final ChangeListener changeListener = new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + TablexiaSettings.getInstance().setLocale(((LocaleSelectBox)event.getTarget()).getSelected().getLocaleDefinition()); + } + }; + + public LocaleSelectBox(float itemHeight, float textSize) { + super(itemHeight); + this.textSize = textSize; + ApplicationBus.getInstance().subscribe(this); + prepareLocales(); + } + + private void prepareLocales() { + removeCaptureListener(changeListener); + LocaleItem selectedLocaleItem = null; + + List<LocaleItem> localeItems = new ArrayList<LocaleItem>(); + for (TablexiaSettings.LocaleDefinition localeDefinition: TablexiaSettings.LocaleDefinition.values()) { + LocaleItem localeItem = new LocaleItem(localeDefinition); + localeItems.add(localeItem); + if (localeDefinition.equals(TablexiaSettings.getInstance().getLocaleDefinition())) { + selectedLocaleItem = localeItem; + } + } + setItems(localeItems.toArray(new LocaleItem[]{})); + if (selectedLocaleItem != null) { + setSelected(selectedLocaleItem); + } + addCaptureListener(changeListener); + } + + @Override + protected void drawSelectedItem(Batch batch, float parentAlpha, LocaleItem selected, float width, float height) { + selected.setBounds(getX(), getY(), width, height); + selected.draw(batch, parentAlpha); + } + + @Override + protected void drawListItem(Batch batch, float parentAlpha, LocaleItem item, float x, float y, float width, float height) { + item.setBounds(x, y, width, height); + item.draw(batch, parentAlpha); + } +} diff --git a/core/src/cz/nic/tablexia/menu/main/MainMenu.java b/core/src/cz/nic/tablexia/menu/main/MainMenu.java index 9f7e4c1e6f1c345f9176e2cf910cf7422e7ccb0e..ae46883f2ea0e8a0a3cbf0ebcb80c52aa98d3845 100644 --- a/core/src/cz/nic/tablexia/menu/main/MainMenu.java +++ b/core/src/cz/nic/tablexia/menu/main/MainMenu.java @@ -1,9 +1,38 @@ package cz.nic.tablexia.menu.main; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.scenes.scene2d.Group; +import com.badlogic.gdx.scenes.scene2d.InputEvent; +import com.badlogic.gdx.scenes.scene2d.Touchable; +import com.badlogic.gdx.scenes.scene2d.ui.Cell; +import com.badlogic.gdx.scenes.scene2d.ui.Container; +import com.badlogic.gdx.scenes.scene2d.ui.Image; +import com.badlogic.gdx.scenes.scene2d.ui.Label; +import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane; +import com.badlogic.gdx.scenes.scene2d.ui.Stack; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup; +import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; +import com.badlogic.gdx.scenes.scene2d.utils.NinePatchDrawable; +import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; +import com.badlogic.gdx.utils.Align; + +import net.engio.mbassy.listener.Handler; + import java.util.List; +import cz.nic.tablexia.TablexiaApplication; +import cz.nic.tablexia.TablexiaSettings; +import cz.nic.tablexia.bus.ApplicationBus; +import cz.nic.tablexia.game.AbstractTablexiaGame; +import cz.nic.tablexia.game.GameDefinition; +import cz.nic.tablexia.loader.application.ApplicationAtlasManager; +import cz.nic.tablexia.loader.application.ApplicationFontManager; import cz.nic.tablexia.menu.AbstractMenu; import cz.nic.tablexia.menu.IMenuItem; +import cz.nic.tablexia.screen.gamemenu.GameMenuScreen; +import cz.nic.tablexia.screen.gamemenu.pages.GameMenuPage; /** * MainMenu container @@ -12,10 +41,301 @@ import cz.nic.tablexia.menu.IMenuItem; */ public class MainMenu extends AbstractMenu { + private static final float MAINMENU_PADDING = 10f; + private static final float SCROLLBAR_PADDING_BOTTOM = 10f; + private static final float SCROLLBAR_PADDING_TOP = 10f; + private static final int SELECTBOX_USER_HEIGHT = 70; + private static final int SELECTBOX_LOCALE_HEIGHT = 30; + private static final float SELECTBOX_LOCALE_TEXT_SCALE = 0.65f; + private static final float SELECTBOX_LOCALE_WIDTH_RATIO = 2f/5; + private static final int APP_NAME_TEXT_ALIGN = Align.left; + private static final float APP_NAME_TEXT_SCALE = 0.5f; + private static final float APP_NAME_TEXT_PADDING_LEFT = 10f; + private static final float APP_NAME_WIDTH_RATIO = 3f/5; + + private static final Color HIGHLITED_COLOR = new Color(0.780f, 0.698f, 0.600f, 1); + private static final Color DIVIDER_COLOR = new Color(0.780f, 0.698f, 0.600f, 1); + private static final int DIVIDER_WIDTH = 205; + + private static class MenuItemGroup extends Container<Table> { + + private static final String MENU_ITEM_FONT_TYPE = ApplicationFontManager.APPLICATION_DEFAULT_FONT_BOLD; + private static final Color MENU_ITEM_FONT_COLOR = new Color(0.325f, 0.278f, 0.255f, 1); + private static final int ICON_RIGHT_SPACE = 15; + private static final float ICON_SCALE = 0.8f; + + private final Image iconUnpressedImage; + private final Image iconPressedImage; + private final TextureRegionDrawable highlitedBackground; + + public MenuItemGroup(String iconUnpressed, String iconPressed, String title) { + Table layoutTable = new Table(); + layoutTable.setFillParent(true); + setActor(layoutTable); + addListener(new ClickListener() { + + @Override + public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) { + setPressed(); + return super.touchDown(event, x, y, pointer, button); + } + + @Override + public void touchUp(InputEvent event, float x, float y, int pointer, int button) { + setUnpressed(); + super.touchUp(event, x, y, pointer, button); + } + }); + setTouchable(Touchable.enabled); + setUnpressed(); + + // highliter + highlitedBackground = new TextureRegionDrawable(ApplicationAtlasManager.getInstance().getColorTextureRegion(HIGHLITED_COLOR)); + + // icons + Stack iconStack = new Stack(); + layoutTable.add(iconStack); + iconPressedImage = createIcon(iconPressed, iconStack); + iconUnpressedImage = createIcon(iconUnpressed, iconStack); + + // title + if (title != null) { + Label label = new Label(title, new Label.LabelStyle(ApplicationFontManager.getInstance().getFont(MENU_ITEM_FONT_TYPE), MENU_ITEM_FONT_COLOR)); + layoutTable.add(label).expandX().align(Align.left).padLeft(ICON_RIGHT_SPACE); + } + layoutTable.row(); + + // divider + Image divider = new Image(ApplicationAtlasManager.getInstance().getColorTexture(DIVIDER_COLOR)); + divider.getDrawable().setMinWidth(DIVIDER_WIDTH); + layoutTable.add(); + layoutTable.add(divider); + } + + @Override + protected void setParent(Group parent) { + super.setParent(parent); + minWidth(parent.getWidth()); + } + + private Image createIcon(String iconName, Stack iconStack) { + Image icon = null; + if (iconName != null) { + icon = new Image(ApplicationAtlasManager.getInstance().getTextureRegion(iconName)); + icon.setOrigin(Align.center); + icon.setScale(ICON_SCALE); + iconStack.add(icon); + } + + return icon; + } + + public void setUnpressed() { + setBackground(null); + if (iconUnpressedImage != null) { + iconUnpressedImage.setVisible(true); + } + if (iconPressedImage != null) { + iconPressedImage.setVisible(false); + } + } + + public void setPressed() { + setBackground(highlitedBackground); + if (iconUnpressedImage != null) { + iconUnpressedImage.setVisible(false); + } + if (iconPressedImage != null) { + iconPressedImage.setVisible(true); + } + } + } + + private static class SubMenuItemGroup extends Container<Table> { + + private static final String TITLE_FONT_TYPE = ApplicationFontManager.APPLICATION_DEFAULT_FONT_BOLD; + private static final Color TITLE_FONT_COLOR = new Color(0.325f, 0.278f, 0.255f, 1); + private static final float TITLE_FONT_SCALE = 0.9f; + + private static final String DESCRIPTION_FONT_TYPE = ApplicationFontManager.APPLICATION_DEFAULT_FONT_REGULAR; + private static final Color DESCRIPTION_FONT_COLOR = new Color(0.325f, 0.278f, 0.255f, 1); + private static final float DESCRIPTION_FONT_SCALE = 0.6f; + + private static final float LABELS_PADDING_LEFT = 15f; + private static final float LABELS_PADDING_DEFAULT = 5f; + private static final Color HIGHLITER_COLOR = new Color(0.647f, 0.22f, 0.22f, 1); + private static final float ARROW_PADING_RIGHT = 15f; + private static final float LAYOUT_PADDING = 2f; + private static final float CONTAINER_BOTTOM_PADDING = 4f; + private static final float LEFT_PADDING = 5f; + + private final Table layoutContainer; + private final Image arrowIcon; + private final Image restartIcon; + private final Cell<Image> iconCell; + private final Image highliter; + private NinePatchDrawable background; + private TextureRegionDrawable highlitedBackground; + + private Class<? extends AbstractTablexiaGame> abstractTablexiaGameClass; + private GameMenuScreen.GameMenuPageDefinition gameMenuPageDefinition; + + public SubMenuItemGroup(String title, String description, Class<? extends AbstractTablexiaGame> abstractTablexiaGameClass) { + this.abstractTablexiaGameClass = abstractTablexiaGameClass; + this.gameMenuPageDefinition = GameMenuScreen.GameMenuPageDefinition.getGameMenuPageForGameDefinition(GameDefinition.getGameDefinitionForClass(abstractTablexiaGameClass)); + + padLeft(LEFT_PADDING); + layoutContainer = new Table(); + layoutContainer.pad(LAYOUT_PADDING); + layoutContainer.setTouchable(Touchable.enabled); + layoutContainer.addListener(new ClickListener() { + + @Override + public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) { + setPressed(); + return super.touchDown(event, x, y, pointer, button); + } + + @Override + public void touchUp(InputEvent event, float x, float y, int pointer, int button) { + setUnpressed(); + super.touchUp(event, x, y, pointer, button); + } + }); + + background = new NinePatchDrawable(ApplicationAtlasManager.getInstance().getPatch(ApplicationAtlasManager.MAINMENU_CHILDITEM_BACKGROUND)); + highlitedBackground = new TextureRegionDrawable(ApplicationAtlasManager.getInstance().getColorTextureRegion(HIGHLITED_COLOR)); + + fill(true, false); + setActor(layoutContainer); + padBottom(CONTAINER_BOTTOM_PADDING); + + // highliter + highliter = new Image(ApplicationAtlasManager.getInstance().getColorTexture(HIGHLITER_COLOR)); + layoutContainer.add(highliter); + + // texts + Label titleLabel = new Label(title, new Label.LabelStyle(ApplicationFontManager.getInstance().getFont(TITLE_FONT_TYPE), TITLE_FONT_COLOR)); + titleLabel.setFontScale(TITLE_FONT_SCALE); + Label descritopnLabel = new Label(description, new Label.LabelStyle(ApplicationFontManager.getInstance().getFont(DESCRIPTION_FONT_TYPE), DESCRIPTION_FONT_COLOR)); + descritopnLabel.setFontScale(DESCRIPTION_FONT_SCALE); + Table labelsContainer = new Table(); + labelsContainer.add(titleLabel).align(Align.left); + labelsContainer.row(); + labelsContainer.add(descritopnLabel).align(Align.left); + labelsContainer.pad(LABELS_PADDING_DEFAULT, LABELS_PADDING_LEFT, LABELS_PADDING_DEFAULT, LABELS_PADDING_DEFAULT); + layoutContainer.add(labelsContainer); + + // arrow + arrowIcon = new Image(ApplicationAtlasManager.getInstance().getTextureRegion(ApplicationAtlasManager.MAINMENU_CHILDITEM_ARROW, false)); + restartIcon = new Image(ApplicationAtlasManager.getInstance().getTextureRegion(ApplicationAtlasManager.MAINMENU_CHILDITEM_RESTART, false)); + iconCell = layoutContainer.add(); + iconCell.expandX().align(Align.right).padRight(ARROW_PADING_RIGHT); + changeIconToArrow(); + + // highliter size + highliter.getDrawable().setMinWidth(5); + highliter.getDrawable().setMinHeight(layoutContainer.getMinHeight()); + unhighlite(); + + setUnpressed(); + ApplicationBus.getInstance().subscribe(this); + } + + private void highlite() { + highliter.setVisible(true); + } + + private void unhighlite() { + highliter.setVisible(false); + } + + private void changeIconToArrow() { + restartIcon.remove(); + iconCell.setActor(arrowIcon); + } + + private void changeIconToRestart() { + arrowIcon.remove(); + iconCell.setActor(restartIcon); + } + + private void setUnpressed() { + layoutContainer.setBackground(background); + } + + private void setPressed() { + layoutContainer.setBackground(highlitedBackground); + } + + @Handler + public void onScreenChangedEvent(TablexiaApplication.ScreenChangedEvent screenChangedEvent) { + if (screenChangedEvent.getScreenClass() == abstractTablexiaGameClass) { + highlite(); + changeIconToRestart(); + } else { + unhighlite(); + changeIconToArrow(); + } + } + + @Handler + public void onGameMenuPageScrollEvent(GameMenuPage.GameMenuPageScrolledEvent gameMenuPageScrolledEvent) { + if (gameMenuPageScrolledEvent.getGameMenuPageDefinition() == gameMenuPageDefinition) { + highlite(); + } else { + unhighlite(); + } + } + } + public MainMenu(Float width, Float height) { super(width, height); } + @Override + protected Group createMenuLayout(VerticalGroup menuLayout) { + Table layoutTable = new Table(); + layoutTable.pad(MAINMENU_PADDING); + BitmapFont font = ApplicationFontManager.getInstance().getDefaultApplicationRegularFont(); + + // User SelectBox + layoutTable.add(new UserSelectBox(SELECTBOX_USER_HEIGHT)).expand().fill(); + layoutTable.row(); + + // Menu ScrollPane + ScrollPane scrollPane = new ScrollPane(menuLayout); + scrollPane.setScrollingDisabled(true, false); + layoutTable.add(scrollPane).expand().fill().padBottom(SCROLLBAR_PADDING_BOTTOM).padTop(SCROLLBAR_PADDING_TOP); + layoutTable.setFillParent(true); + layoutTable.row(); + + // Locale SelectBox and App name + Table footerTable = new Table(); + float footerContentWidth = getBackground().getDrawable().getMinWidth() - (2 * MAINMENU_PADDING) - APP_NAME_TEXT_PADDING_LEFT; + footerTable.add(new LocaleSelectBox(SELECTBOX_LOCALE_HEIGHT, SELECTBOX_LOCALE_TEXT_SCALE)).width(footerContentWidth * SELECTBOX_LOCALE_WIDTH_RATIO); + Label appName = new Label(TablexiaSettings.getInstance().getAppName() + System.lineSeparator() + TablexiaSettings.getInstance().getVersionName(), new Label.LabelStyle(font, Color.BLACK)); + appName.setAlignment(APP_NAME_TEXT_ALIGN); + appName.setFontScale(APP_NAME_TEXT_SCALE); + appName.setWrap(true); + footerTable.add(appName).width(footerContentWidth * APP_NAME_WIDTH_RATIO).padLeft(APP_NAME_TEXT_PADDING_LEFT); + layoutTable.add(footerTable).expand().fill(); + + return layoutTable; + } + + @Override + protected Group createMenuItem(IMenuItem menuItem) { + MainMenuDefinition mainMenuDefinition = (MainMenuDefinition) menuItem; + return new MenuItemGroup(mainMenuDefinition.getIconUnpressed(), mainMenuDefinition.getIconPressed(), menuItem.getTitle()); + } + + @Override + protected Group createSubMenuItem(IMenuItem menuItem) { + GameDefinition gameDefinition = ((GameDefinition) menuItem); + return new SubMenuItemGroup(gameDefinition.getTitle(), gameDefinition.getDescription(), gameDefinition.getScreenClass()); + } + @Override protected boolean isScreenPause() { return true; diff --git a/core/src/cz/nic/tablexia/menu/main/MainMenuDefinition.java b/core/src/cz/nic/tablexia/menu/main/MainMenuDefinition.java index f227de0b72e87471c083e204ef50cd0bd5a27cda..bb133282df5e9e86673d97cfb71d92ebb96b5295 100644 --- a/core/src/cz/nic/tablexia/menu/main/MainMenuDefinition.java +++ b/core/src/cz/nic/tablexia/menu/main/MainMenuDefinition.java @@ -9,43 +9,47 @@ import cz.nic.tablexia.TablexiaSettings; import cz.nic.tablexia.bus.ApplicationBus; import cz.nic.tablexia.bus.ApplicationBus.ApplicationEvent; import cz.nic.tablexia.game.GameDefinition; +import cz.nic.tablexia.loader.application.ApplicationAtlasManager; import cz.nic.tablexia.loader.application.ApplicationTextManager; import cz.nic.tablexia.menu.AbstractMenu; import cz.nic.tablexia.menu.IMenuItem; import cz.nic.tablexia.screen.about.AboutScreen; import cz.nic.tablexia.screen.encyclopedia.EncyclopediaScreen; import cz.nic.tablexia.screen.halloffame.HallOfFameScreen; -import cz.nic.tablexia.screen.preferences.PreferencesScreen; import cz.nic.tablexia.screen.statistics.StatisticsScreen; import cz.nic.tablexia.screen.viewport.ViewportDebugScreen; public enum MainMenuDefinition implements IMenuItem { - GAMES (false, "mainmenu_games", GameDefinition.values(), null, null), // TODO open menu event - HALL_OF_FAME (false, "mainmenu_halloffame", null, AbstractMenu.MenuAction.CLOSE, new Tablexia.ChangeScreenEvent(HallOfFameScreen.class, TablexiaApplication.ScreenTransaction.FADE)), - STATISTICS (false, "mainmenu_statistics", null, AbstractMenu.MenuAction.CLOSE, new Tablexia.ChangeScreenEvent(StatisticsScreen.class, TablexiaApplication.ScreenTransaction.FADE)), - ENCYCLOPEDIA (false, "mainmenu_encyclopedia", null, AbstractMenu.MenuAction.CLOSE, new Tablexia.ChangeScreenEvent(EncyclopediaScreen.class, TablexiaApplication.ScreenTransaction.FADE)), - PREFERENCES (false, "mainmenu_preferences", null, AbstractMenu.MenuAction.CLOSE, new Tablexia.ChangeScreenEvent(PreferencesScreen.class, TablexiaApplication.ScreenTransaction.FADE)), - ABOUT_APPLICATION (false, "mainmenu_about", null, AbstractMenu.MenuAction.CLOSE, new Tablexia.ChangeScreenEvent(AboutScreen.class, TablexiaApplication.ScreenTransaction.FADE)), - LOGOUT (false, "mainmenu_logout", null, AbstractMenu.MenuAction.HIDE, null) { + GAMES (false, ApplicationAtlasManager.MAINMENU_ICON_GAMES_UNPRESSED, ApplicationAtlasManager.MAINMENU_ICON_GAMES_PRESSED, "mainmenu_games", GameDefinition.values(), null, null), // TODO open menu event + HALL_OF_FAME (false, ApplicationAtlasManager.MAINMENU_ICON_HALLOFFAME_UNPRESSED, ApplicationAtlasManager.MAINMENU_ICON_HALLOFFAME_PRESSED, "mainmenu_halloffame", null, AbstractMenu.MenuAction.CLOSE, new Tablexia.ChangeScreenEvent(HallOfFameScreen.class, TablexiaApplication.ScreenTransaction.FADE)), + STATISTICS (false, ApplicationAtlasManager.MAINMENU_ICON_STATISTICS_UNPRESSED, ApplicationAtlasManager.MAINMENU_ICON_STATISTICS_PRESSED, "mainmenu_statistics", null, AbstractMenu.MenuAction.CLOSE, new Tablexia.ChangeScreenEvent(StatisticsScreen.class, TablexiaApplication.ScreenTransaction.FADE)), + ENCYCLOPEDIA (false, ApplicationAtlasManager.MAINMENU_ICON_ENCYCLOPEDIA_UNPRESSED, ApplicationAtlasManager.MAINMENU_ICON_ENCYCLOPEDIA_PRESSED, "mainmenu_encyclopedia", null, AbstractMenu.MenuAction.CLOSE, new Tablexia.ChangeScreenEvent(EncyclopediaScreen.class, TablexiaApplication.ScreenTransaction.FADE)), + ABOUT_APPLICATION (false, ApplicationAtlasManager.MAINMENU_ICON_ABOUT_UNPRESSED, ApplicationAtlasManager.MAINMENU_ICON_ABOUT_PRESSED, "mainmenu_about", null, AbstractMenu.MenuAction.CLOSE, new Tablexia.ChangeScreenEvent(AboutScreen.class, TablexiaApplication.ScreenTransaction.FADE)), + LOGOUT (false, ApplicationAtlasManager.MAINMENU_ICON_LOGOUT_UNPRESSED, ApplicationAtlasManager.MAINMENU_ICON_LOGOUT_PRESSED, "mainmenu_logout", null, AbstractMenu.MenuAction.HIDE, null) { @Override public void performAction() { TablexiaSettings.getInstance().setSelectedUser(null); + ApplicationBus.getInstance().post(new Tablexia.ChangeScreenEvent(TablexiaSettings.LOADER_SCREEN, TablexiaApplication.ScreenTransaction.FADE)).asynchronously(); } }, - SCREEN_DEBUG (true, "mainmenu_screendebug", null, AbstractMenu.MenuAction.CLOSE, new Tablexia.ChangeScreenEvent(ViewportDebugScreen.class, TablexiaApplication.ScreenTransaction.FADE)); + SCREEN_DEBUG (true, ApplicationAtlasManager.MAINMENU_ICON_ABOUT_UNPRESSED, ApplicationAtlasManager.MAINMENU_ICON_ABOUT_PRESSED, "mainmenu_screendebug", null, AbstractMenu.MenuAction.CLOSE, new Tablexia.ChangeScreenEvent(ViewportDebugScreen.class, TablexiaApplication.ScreenTransaction.FADE)); private boolean debug; - private String menuTextKey; + private String iconUnpressed; + private String iconPressed; + private String menuTextKey; private IMenuItem[] submenu; private AbstractMenu.MenuAction menuAction; private ApplicationEvent action; - MainMenuDefinition(boolean debug, String nameResource, IMenuItem[] submenu, AbstractMenu.MenuAction menuAction, ApplicationEvent action) { + MainMenuDefinition(boolean debug, String iconUnpressed, String iconPressed, String nameResource, IMenuItem[] submenu, AbstractMenu.MenuAction menuAction, ApplicationEvent action) { this.debug = debug; - this.menuTextKey = nameResource; + this.iconUnpressed = iconUnpressed; + this.iconPressed = iconPressed; + this.menuTextKey = nameResource; this.submenu = submenu; this.menuAction = menuAction; this.action = action; @@ -60,11 +64,24 @@ public enum MainMenuDefinition implements IMenuItem { return ApplicationTextManager.getInstance().getText(menuTextKey); } + @Override + public String getDescription() { + return null; + } + @Override public void performAction() { ApplicationBus.getInstance().publishAsync(this.getAction()); } + public String getIconUnpressed() { + return iconUnpressed; + } + + public String getIconPressed() { + return iconPressed; + } + public IMenuItem[] getSubmenu() { return submenu; } diff --git a/core/src/cz/nic/tablexia/menu/main/UserSelectBox.java b/core/src/cz/nic/tablexia/menu/main/UserSelectBox.java new file mode 100644 index 0000000000000000000000000000000000000000..770be22d421864fa2e86aaed08752b498e43e627 --- /dev/null +++ b/core/src/cz/nic/tablexia/menu/main/UserSelectBox.java @@ -0,0 +1,187 @@ +package cz.nic.tablexia.menu.main; + +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.GlyphLayout; +import com.badlogic.gdx.graphics.g2d.NinePatch; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; +import com.badlogic.gdx.utils.Align; + +import net.engio.mbassy.listener.Handler; + +import java.util.ArrayList; +import java.util.List; + +import cz.nic.tablexia.Tablexia; +import cz.nic.tablexia.TablexiaApplication; +import cz.nic.tablexia.TablexiaSettings; +import cz.nic.tablexia.bus.ApplicationBus; +import cz.nic.tablexia.loader.application.ApplicationAtlasManager; +import cz.nic.tablexia.loader.application.ApplicationFontManager; +import cz.nic.tablexia.loader.application.ApplicationTextManager; +import cz.nic.tablexia.model.User; +import cz.nic.tablexia.screen.createuser.PanoramaScreen; +import cz.nic.tablexia.util.ui.AbstractTablexiaSelectBox; + +/** + * Created by Matyáš Latner. + */ +public class UserSelectBox extends AbstractTablexiaSelectBox<UserSelectBox.IUserItem> { + + private static final int TRIANGLE_WIDTH = 12; + private static final int TRIANGLE_HEIGHT = 12; + private static final int TRIANGLE_BOTTOM_OFFSET = 3; + private static final int TRIANGLE_RIGHT_OFFSET = 3; + private static final int TEXT_LEFT_OFFSET = 20; + private static final int IMAGE_BORDER_OFFSET = 4; + private static final int SELECTOR_RIGHT_OFFSET = 10; + private static final int SELECTOR_BOTTOM_OFFSET = 4; + private static final int SELECTOR_WIDTH = 5; + private static final int SELECTOR_TOP_OFFSET = 8; + private static final Color FOREGROUND_COLOR = new Color(0.322f, 0.278f, 0.255f, 1f); + private static final Color NEWUSER_TEXT_COLOR = new Color(0.098f, 0.086f, 0.075f, 1f); + private static final int NEWUSER_TEXT_ALIGN = Align.center; + private static final int ITEMS_OVERLAP_SIZE = 1; + + + private TextureRegionDrawable triangle; + private TextureRegionDrawable selector; + + public interface IUserItem { + void performAction(); + void setBounds (float x, float y, float width, float height); + void draw(Batch batch, float parentAlpha); + } + + public static class UserItem extends Actor implements IUserItem { + + private final NinePatch background; + private final BitmapFont font; + private final TextureRegionDrawable image; + private final User user; + + public UserItem(User user) { + this.user = user; + + background = ApplicationAtlasManager.getInstance().getPatch(ApplicationAtlasManager.USERMENU_MENUITEM_BACKGROUND); + font = ApplicationFontManager.getInstance().getDefaultApplicationRegularFont(); + image = new TextureRegionDrawable(ApplicationAtlasManager.getInstance().getTextureRegion(ApplicationAtlasManager.USERMENU_MENUITEM_SAMPLE)); + } + + public void performAction() { + user.performAction(); + } + + @Override + public void draw(Batch batch, float parentAlpha) { + FOREGROUND_COLOR.a = parentAlpha; + font.setColor(FOREGROUND_COLOR); + + background.draw(batch, getX(), getY(), getWidth(), getHeight()); + + float imageWidth = getHeight(); + image.draw(batch, getX() + IMAGE_BORDER_OFFSET, getY() + IMAGE_BORDER_OFFSET, imageWidth - IMAGE_BORDER_OFFSET * 2, getHeight() - IMAGE_BORDER_OFFSET * 2); + + float textPositionX = getX() + imageWidth + TEXT_LEFT_OFFSET; + float textPositionY = getY() + getHeight() / 2; + font.draw(batch, user.getName(), textPositionX, textPositionY + font.getLineHeight() / 3); + } + } + + public static class NewUserItem extends Actor implements IUserItem { + + private final NinePatch background; + private final BitmapFont font; + private final String text; + private final GlyphLayout glyphLayout; + + public NewUserItem() { + background = ApplicationAtlasManager.getInstance().getPatch(ApplicationAtlasManager.USERMENU_MENUBUTTON_BACKGROUND); + font = ApplicationFontManager.getInstance().getDefaultApplicationBoldFont(); + text = ApplicationTextManager.getInstance().getText(ApplicationTextManager.ApplicationTextsAssets.USERMENU_NEWUSER); + glyphLayout = new GlyphLayout(); + } + + public void performAction() { + TablexiaSettings.getInstance().setSelectedUser(null); + ApplicationBus.getInstance().post(new Tablexia.ChangeScreenEvent(PanoramaScreen.class, TablexiaApplication.ScreenTransaction.FADE)).asynchronously(); + } + + @Override + public void draw(Batch batch, float parentAlpha) { + NEWUSER_TEXT_COLOR.a = parentAlpha; + font.setColor(NEWUSER_TEXT_COLOR); + + background.draw(batch, getX(), getY(), getWidth(), getHeight()); + + glyphLayout.setText(font, text, NEWUSER_TEXT_COLOR, getWidth(), NEWUSER_TEXT_ALIGN, false); + font.draw(batch, glyphLayout, getX(), getY() + getHeight() / 2 + font.getLineHeight() / 3); + } + } + + private final ChangeListener changeListener = new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + // TODO add confirm dialog inside + getSelected().performAction(); + } + }; + + public UserSelectBox(float itemHeight) { + super(itemHeight); + ApplicationBus.getInstance().subscribe(this); + + selector = (new TextureRegionDrawable(ApplicationAtlasManager.getInstance().getColorTextureRegion(FOREGROUND_COLOR))); + triangle = (new TextureRegionDrawable(ApplicationAtlasManager.getInstance().getTextureRegion(ApplicationAtlasManager.USERMENU_MENUITEM_TRIANGLE))); + + prepareActiveUsers(); + } + + @Handler + public void onSelectedUserEvent(TablexiaSettings.SelectedUserEvent selectedUserEvent) { + if (selectedUserEvent.isUserSelected()) { + prepareActiveUsers(); + } + } + + private void prepareActiveUsers() { + removeCaptureListener(changeListener); + UserItem selectedUserItem = null; + List<IUserItem> userItems = new ArrayList<IUserItem>(); + for (User user: User.selectActiveUsers()) { + UserItem userItem = new UserItem(user); + userItems.add(userItem); + if (user.equals(TablexiaSettings.getInstance().getSelectedUser())) { + selectedUserItem = userItem; + } + } + userItems.add(new NewUserItem()); + setItems(userItems.toArray(new IUserItem[]{})); + if (selectedUserItem != null) { + setSelected(selectedUserItem); + } + addCaptureListener(changeListener); + } + + @Override + protected void drawSelectedItem(Batch batch, float parentAlpha, IUserItem selected, float width, float height) { + selected.setBounds(getX(), getY(), width, height); + selected.draw(batch, parentAlpha); + triangle.draw(batch, getX() + getWidth() - TRIANGLE_WIDTH - TRIANGLE_RIGHT_OFFSET, getY() + TRIANGLE_BOTTOM_OFFSET, TRIANGLE_WIDTH, TRIANGLE_HEIGHT); + } + + @Override + protected void drawListItem(Batch batch, float parentAlpha, IUserItem item, float x, float y, float width, float height) { + height = height + ITEMS_OVERLAP_SIZE; + item.setBounds(x, y, width, height); + item.draw(batch, parentAlpha); + if (getSelection() != null && getSelection().contains(item)) { + selector.draw(batch, x + width - SELECTOR_RIGHT_OFFSET, y + SELECTOR_BOTTOM_OFFSET, SELECTOR_WIDTH, height - SELECTOR_TOP_OFFSET); + } + } + + +} diff --git a/core/src/cz/nic/tablexia/menu/user/UserMenu.java b/core/src/cz/nic/tablexia/menu/user/UserMenu.java index df04fe8188e7fdae284c905a5fcefe4bcd80873e..e2cc77eb58e077f67a59acb953305f97db62f70a 100644 --- a/core/src/cz/nic/tablexia/menu/user/UserMenu.java +++ b/core/src/cz/nic/tablexia/menu/user/UserMenu.java @@ -59,6 +59,11 @@ public class UserMenu extends AbstractMenu { return ApplicationTextManager.getInstance().getText(ApplicationTextManager.ApplicationTextsAssets.USERMENU_NEWUSER); } + @Override + public String getDescription() { + return null; + } + @Override public void performAction() { ApplicationBus.getInstance().post(new Tablexia.ChangeScreenEvent(PanoramaScreen.class, TablexiaApplication.ScreenTransaction.MOVE_UP)).asynchronously(); diff --git a/core/src/cz/nic/tablexia/model/User.java b/core/src/cz/nic/tablexia/model/User.java index 900f12e22ce128cfce64de650016b535b513a823..6b10477f2dfcf1a935eb165e4a0186bf37e9f684 100644 --- a/core/src/cz/nic/tablexia/model/User.java +++ b/core/src/cz/nic/tablexia/model/User.java @@ -40,7 +40,7 @@ public class User extends UserMenu.UserMenuItem { } } - private final Long id; + private final long id; private final String name; private final int age; private final Gender gender; @@ -86,6 +86,17 @@ public class User extends UserMenu.UserMenuItem { return intro; } + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (!(obj instanceof User)) { + return false; + } + return ((User)obj).getId().equals(getId()); + } + @Override public String toString() { return "USER[id: " + id + ", name: " + name + ", age: " + age + ", gen: " + gender.name() + ", del: " + deleted + ", help: " + help + ", intro: " + intro + "]"; @@ -99,6 +110,11 @@ public class User extends UserMenu.UserMenuItem { return getName(); } + @Override + public String getDescription() { + return null; + } + @Override public void performAction() { TablexiaSettings.getInstance().setSelectedUser(this); diff --git a/core/src/cz/nic/tablexia/screen/AbstractTablexiaScreen.java b/core/src/cz/nic/tablexia/screen/AbstractTablexiaScreen.java index 676fdcd7d1cf0c49f2bfe64c7d5785c57957ad86..5162e91c42b32aa4947260767048af33a8cfc79b 100644 --- a/core/src/cz/nic/tablexia/screen/AbstractTablexiaScreen.java +++ b/core/src/cz/nic/tablexia/screen/AbstractTablexiaScreen.java @@ -16,8 +16,6 @@ import com.badlogic.gdx.utils.Disposable; import com.badlogic.gdx.utils.I18NBundle; import com.badlogic.gdx.utils.async.AsyncTask; -import net.engio.mbassy.listener.Handler; - import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -35,14 +33,12 @@ import cz.nic.tablexia.TablexiaSettings; import cz.nic.tablexia.TablexiaStorage; import cz.nic.tablexia.bus.ApplicationBus; import cz.nic.tablexia.bus.ApplicationBus.ApplicationEvent; -import cz.nic.tablexia.bus.event.MenuControlEvent; import cz.nic.tablexia.loader.TablexiaAbstractFileManager; import cz.nic.tablexia.loader.TablexiaAtlasManager; import cz.nic.tablexia.loader.TablexiaDataManager; import cz.nic.tablexia.loader.TablexiaSoundManager; import cz.nic.tablexia.loader.application.ApplicationAtlasManager; import cz.nic.tablexia.loader.application.ApplicationFontManager; -import cz.nic.tablexia.menu.AbstractMenu; import cz.nic.tablexia.model.User; import cz.nic.tablexia.util.Log; import cz.nic.tablexia.util.Utility; @@ -162,7 +158,6 @@ public abstract class AbstractTablexiaScreen<T> extends ScreenAdapter { private boolean loadingComplete; private boolean loadingStarted; private boolean loadAsync; - private boolean hasState; private TablexiaAbstractFileManager.AssetsStorageType storageType; private Map<String, Music> notDisposedMusics; @@ -200,12 +195,21 @@ public abstract class AbstractTablexiaScreen<T> extends ScreenAdapter { private class DataManager extends TablexiaDataManager<T> { + private Map<String, String> initialState; + + public void setInitialState(Map<String, String> initialState) { + this.initialState = initialState; + } + public class DataLoader implements AsyncTask<T> { @Override public T call() throws Exception { // restore screen state screenState = TablexiaStorage.getInstance().loadScreenState(AbstractTablexiaScreen.this, getSelectedUser()); + if (initialState != null) { + screenState.putAll(initialState); + } return prepareScreenData(screenState); } } @@ -240,16 +244,11 @@ public abstract class AbstractTablexiaScreen<T> extends ScreenAdapter { public AbstractTablexiaScreen() { - this(true, true, TablexiaAbstractFileManager.AssetsStorageType.EXTERNAL); - } - - public AbstractTablexiaScreen(boolean hasState) { - this(hasState, true, TablexiaAbstractFileManager.AssetsStorageType.EXTERNAL); + this(true, TablexiaAbstractFileManager.AssetsStorageType.EXTERNAL); } - public AbstractTablexiaScreen(boolean hasState, boolean loadAsync, TablexiaAbstractFileManager.AssetsStorageType storageType) { + public AbstractTablexiaScreen(boolean loadAsync, TablexiaAbstractFileManager.AssetsStorageType storageType) { stage = prepareStage(); - this.hasState = hasState; this.loadAsync = loadAsync; this.storageType = storageType; atlasManager = new TablexiaAtlasManager(storageType); @@ -268,27 +267,27 @@ public abstract class AbstractTablexiaScreen<T> extends ScreenAdapter { screenAtlasPath = prepareScreenAtlasPath(screenAssetsPath, screenName); } - public boolean hasState() { - return hasState; + public void setInitialState(Map<String, String> initialState) { + dataManager.setInitialState(initialState); } + //////////////////////////// SCREEN PAUSE public boolean canBePaused() { + return true; + } + + public boolean canStopActions () { return false; } - protected boolean isScreenPaused() { - return canBePaused() && isScreenPaused; + public boolean canResetState () { + return true; } - @Handler - public void handleMenuPauseEvent(AbstractMenu.MenuPauseEvent menuPauseEvent) { - if (menuPauseEvent.isPause()) { - performScreenPaused(); - } else { - performScreenResumed(); - } + public boolean isScreenPaused() { + return canBePaused() && isScreenPaused && canStopActions(); } @@ -399,7 +398,6 @@ public abstract class AbstractTablexiaScreen<T> extends ScreenAdapter { public void pause() { if (loadingComplete && canBePaused() && !isScreenPaused()) { performScreenPaused(); - ApplicationBus.getInstance().post(new MenuControlEvent(true, true)).asynchronously(); } } @@ -451,7 +449,7 @@ public abstract class AbstractTablexiaScreen<T> extends ScreenAdapter { screenResized(width, height); } - private final void performScreenPaused() { + protected final void performScreenPaused() { if (!isScreenPaused) { isScreenPaused = true; Log.info(getClass(), "[ ------- Screen Paused ------- ]"); @@ -462,7 +460,7 @@ public abstract class AbstractTablexiaScreen<T> extends ScreenAdapter { } } - private final void performScreenResumed() { + protected final void performScreenResumed() { if (isScreenPaused) { isScreenPaused = false; Log.info(getClass(), "[ ------- Screen Resumed ------- ]"); diff --git a/core/src/cz/nic/tablexia/screen/about/AboutScreen.java b/core/src/cz/nic/tablexia/screen/about/AboutScreen.java index 759c730bc49d129fed3916465bcc456b7c094152..0f188b3ddc3375d3aced1afd3149eee44155c39a 100644 --- a/core/src/cz/nic/tablexia/screen/about/AboutScreen.java +++ b/core/src/cz/nic/tablexia/screen/about/AboutScreen.java @@ -10,7 +10,7 @@ import java.util.Map; import cz.nic.tablexia.screen.AbstractTablexiaScreen; public class AboutScreen extends AbstractTablexiaScreen<Void> { - + @Override protected void screenLoaded(Map<String, String> screenState) { Label label = new Label(getClass().getSimpleName(), new LabelStyle(getDefaultRegularFont(), Color.WHITE)); diff --git a/core/src/cz/nic/tablexia/screen/createuser/FormScreen.java b/core/src/cz/nic/tablexia/screen/createuser/FormScreen.java index 63933115490a576ab6f9b9983096f16203b76609..929cb043042f0bd96646c6c6de94f721d992a65a 100644 --- a/core/src/cz/nic/tablexia/screen/createuser/FormScreen.java +++ b/core/src/cz/nic/tablexia/screen/createuser/FormScreen.java @@ -57,6 +57,11 @@ public class FormScreen extends AbstractTablexiaScreen<Void> { private String mugshot; // private User user = new User(); + @Override + public boolean canBePaused() { + return false; + } + @Override protected void screenLoaded(Map<String, String> screenState) { getStage().setDebugAll(TablexiaSettings.getInstance().isShowBoundingBoxes()); diff --git a/core/src/cz/nic/tablexia/screen/createuser/PanoramaScreen.java b/core/src/cz/nic/tablexia/screen/createuser/PanoramaScreen.java index dc9cc8922db8f56d43e944d9e31266dffbb342a0..a31f8221509c2171419b624e35ecf5df18ea3adc 100644 --- a/core/src/cz/nic/tablexia/screen/createuser/PanoramaScreen.java +++ b/core/src/cz/nic/tablexia/screen/createuser/PanoramaScreen.java @@ -63,6 +63,11 @@ public class PanoramaScreen extends AbstractTablexiaScreen<int[][]> { private TextureRegion clickmap; + @Override + public boolean canBePaused() { + return false; + } + @Override protected int[][] prepareScreenData(Map<String, String> screenState) { clickmap = getScreenTextureRegion(GFX_PATH + "newspaper/clickmap"); diff --git a/core/src/cz/nic/tablexia/screen/gamemenu/GameMenuScreen.java b/core/src/cz/nic/tablexia/screen/gamemenu/GameMenuScreen.java index 159da9b8cfb096ca1d03ae03e3d83ee976d521dc..529c7e3f496aa1b979385551b2757420e2e5a978 100644 --- a/core/src/cz/nic/tablexia/screen/gamemenu/GameMenuScreen.java +++ b/core/src/cz/nic/tablexia/screen/gamemenu/GameMenuScreen.java @@ -7,12 +7,14 @@ import com.badlogic.gdx.scenes.scene2d.ui.Image; import net.engio.mbassy.listener.Handler; +import java.util.HashMap; import java.util.Map; import cz.nic.tablexia.TablexiaSettings; import cz.nic.tablexia.bus.ApplicationBus; import cz.nic.tablexia.game.GameDefinition; import cz.nic.tablexia.screen.AbstractTablexiaScreen; +import cz.nic.tablexia.screen.gamemenu.event.ShowGameMenuPageEvent; import cz.nic.tablexia.screen.gamemenu.pages.GameMenuPage; import cz.nic.tablexia.screen.gamemenu.pages.OfficeMenuPage; import cz.nic.tablexia.util.Utility; @@ -20,6 +22,49 @@ import cz.nic.tablexia.util.ui.ViewPager; public class GameMenuScreen extends AbstractTablexiaScreen<int[][]> { + public static final String SCREEN_STATE_PAGE_NUMBER = "pageNumber"; + + public enum GameMenuPageDefinition { + + OFFICE_PAGE (0, null), + ROBBERY_PAGE (1, GameDefinition.ROBBERY), + PURSUIT_PAGE (2, GameDefinition.PURSUIT), + KIDNAPPING_PAGE (3, GameDefinition.KIDNAPPING), + NIGH_WATCH_PAGE (4, GameDefinition.NIGHT_WATCH), + SHOOTING_RANGE_PAGE (5, GameDefinition.SHOOTING_RANGE), + IN_THE_DARKNESS_PAGE (6, GameDefinition.IN_THE_DARKNESS); + + private int pageNumber; + private GameDefinition gameDefinition; + + GameMenuPageDefinition(int pageNumber, GameDefinition gameDefinition) { + this.pageNumber = pageNumber; + this.gameDefinition = gameDefinition; + } + + public int getPageNumber() { + return pageNumber; + } + + public static GameMenuPageDefinition getGameMenuPageForNumber (int gameMenuPageNumber) { + for (GameMenuPageDefinition gameMenuPageDefinition : GameMenuPageDefinition.values()){ + if (gameMenuPageDefinition.getPageNumber() == gameMenuPageNumber) { + return gameMenuPageDefinition; + } + } + return null; + } + + public static GameMenuPageDefinition getGameMenuPageForGameDefinition (GameDefinition gameDefinition) { + for (GameMenuPageDefinition gameMenuPageDefinition : GameMenuPageDefinition.values()){ + if (gameMenuPageDefinition.gameDefinition != null && gameMenuPageDefinition.gameDefinition == gameDefinition) { + return gameMenuPageDefinition; + } + } + return null; + } + } + private ViewPager vp; @Override @@ -39,7 +84,7 @@ public class GameMenuScreen extends AbstractTablexiaScreen<int[][]> { } vp.setSize(getStage().getWidth(), getStage().getHeight()); - vp.setCullingArea(new Rectangle(0,0,vp.getWidth(), vp.getHeight())); + vp.setCullingArea(new Rectangle(0, 0, vp.getWidth(), vp.getHeight())); getStage().addActor(vp); Image im = new Image(getScreenTextureRegion(GameMenuAssets.VIGNETTE)); @@ -48,11 +93,15 @@ public class GameMenuScreen extends AbstractTablexiaScreen<int[][]> { getStage().addActor(im); ApplicationBus.getInstance().subscribe(this); + + if (screenState.containsKey(GameMenuScreen.SCREEN_STATE_PAGE_NUMBER)) { + vp.scrollToPage(Integer.valueOf(screenState.get(GameMenuScreen.SCREEN_STATE_PAGE_NUMBER)), false); + } } @Handler - public void handleShowStreet(OfficeMenuPage.ShowStreetEvent message) { - vp.scrollToPage(1); + public void handleShowGameMenuPageEvent(ShowGameMenuPageEvent showGameMenuPageEvent) { + vp.scrollToPage(showGameMenuPageEvent.getGameMenuPageDefinition().getPageNumber(), showGameMenuPageEvent.isSmoothScroll()); } @Override @@ -63,4 +112,10 @@ public class GameMenuScreen extends AbstractTablexiaScreen<int[][]> { } return Utility.createColorMap(clickmap); } + + public static Map<String, String> createScreenState(GameMenuPageDefinition gameMenuPageDefinition) { + HashMap<String, String> screenState = new HashMap<String, String>(); + screenState.put(GameMenuScreen.SCREEN_STATE_PAGE_NUMBER, String.valueOf(gameMenuPageDefinition.getPageNumber())); + return screenState; + } } diff --git a/core/src/cz/nic/tablexia/screen/gamemenu/event/ShowGameMenuPageEvent.java b/core/src/cz/nic/tablexia/screen/gamemenu/event/ShowGameMenuPageEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..9035b6840cfb21773d067d5bed1c6f7ce08be74b --- /dev/null +++ b/core/src/cz/nic/tablexia/screen/gamemenu/event/ShowGameMenuPageEvent.java @@ -0,0 +1,41 @@ +package cz.nic.tablexia.screen.gamemenu.event; + +import cz.nic.tablexia.bus.ApplicationBus; +import cz.nic.tablexia.game.GameDefinition; +import cz.nic.tablexia.screen.gamemenu.GameMenuScreen; + +/** + * Created by Matyáš Latner. + */ +public class ShowGameMenuPageEvent implements ApplicationBus.ApplicationEvent { + + private static final boolean DEFAULT_SMOOTH_SCROLL = true; + + private GameMenuScreen.GameMenuPageDefinition gameMenuPageDefinition; + private boolean smoothScroll; + + public ShowGameMenuPageEvent(GameDefinition gameDefinition) { + this(gameDefinition, DEFAULT_SMOOTH_SCROLL); + } + + public ShowGameMenuPageEvent(GameDefinition gameDefinition, boolean smoothScroll) { + this(GameMenuScreen.GameMenuPageDefinition.getGameMenuPageForGameDefinition(gameDefinition), smoothScroll); + } + + public ShowGameMenuPageEvent(GameMenuScreen.GameMenuPageDefinition gameMenuPageDefinition) { + this(gameMenuPageDefinition, DEFAULT_SMOOTH_SCROLL); + } + + public ShowGameMenuPageEvent(GameMenuScreen.GameMenuPageDefinition gameMenuPageDefinition, boolean smoothScroll) { + this.gameMenuPageDefinition = gameMenuPageDefinition; + this.smoothScroll = smoothScroll; + } + + public GameMenuScreen.GameMenuPageDefinition getGameMenuPageDefinition() { + return gameMenuPageDefinition; + } + + public boolean isSmoothScroll() { + return smoothScroll; + } +} diff --git a/core/src/cz/nic/tablexia/screen/gamemenu/pages/GameMenuPage.java b/core/src/cz/nic/tablexia/screen/gamemenu/pages/GameMenuPage.java index a5160c811c5fde19ede38e3573a4875e2afae9d9..4ecd04e751a9f6a508d0aa4f7a5a30e47dbacbb4 100644 --- a/core/src/cz/nic/tablexia/screen/gamemenu/pages/GameMenuPage.java +++ b/core/src/cz/nic/tablexia/screen/gamemenu/pages/GameMenuPage.java @@ -12,11 +12,15 @@ import com.badlogic.gdx.scenes.scene2d.ui.Label; import com.badlogic.gdx.scenes.scene2d.ui.Stack; import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; +import cz.nic.tablexia.Tablexia; +import cz.nic.tablexia.TablexiaApplication; import cz.nic.tablexia.TablexiaSettings; +import cz.nic.tablexia.bus.ApplicationBus; import cz.nic.tablexia.game.GameDefinition; import cz.nic.tablexia.game.difficulty.GameDifficulty; import cz.nic.tablexia.screen.AbstractTablexiaScreen; import cz.nic.tablexia.screen.gamemenu.GameMenuAssets; +import cz.nic.tablexia.screen.gamemenu.GameMenuScreen; import cz.nic.tablexia.util.ui.Switch; import cz.nic.tablexia.util.ui.ViewPager; @@ -93,7 +97,8 @@ public class GameMenuPage extends MenuPage implements ViewPager.ScrollListener { @Override public void clicked(InputEvent event, float x, float y) { super.clicked(event, x, y); - GameMenuPage.this.game.performAction(); // TODO launch game using events + ApplicationBus.getInstance().publishAsync(new Tablexia.ChangeScreenEvent(GameMenuPage.this.game.getScreenClass(), + TablexiaApplication.ScreenTransaction.FADE)); } }); @@ -216,6 +221,20 @@ public class GameMenuPage extends MenuPage implements ViewPager.ScrollListener { @Override public void onScrolledToPage() { + ApplicationBus.getInstance().post(new GameMenuPageScrolledEvent(GameMenuScreen.GameMenuPageDefinition.getGameMenuPageForGameDefinition(game))).asynchronously(); //Log.info(((Object) this).getClass().getName(), "Scrolled to page: " + game.name()); } + + public static class GameMenuPageScrolledEvent implements ApplicationBus.ApplicationEvent { + + private GameMenuScreen.GameMenuPageDefinition gameMenuPageDefinition; + + GameMenuPageScrolledEvent(GameMenuScreen.GameMenuPageDefinition gameMenuPageDefinition) { + this.gameMenuPageDefinition = gameMenuPageDefinition; + } + + public GameMenuScreen.GameMenuPageDefinition getGameMenuPageDefinition() { + return gameMenuPageDefinition; + } + } } diff --git a/core/src/cz/nic/tablexia/screen/gamemenu/pages/OfficeMenuPage.java b/core/src/cz/nic/tablexia/screen/gamemenu/pages/OfficeMenuPage.java index 0f159a12c0ad283bd6aefdd303a1cbabd92dcdda..a6f55d788e79c8ac1ee42ef884ff5b282a883924 100644 --- a/core/src/cz/nic/tablexia/screen/gamemenu/pages/OfficeMenuPage.java +++ b/core/src/cz/nic/tablexia/screen/gamemenu/pages/OfficeMenuPage.java @@ -18,16 +18,19 @@ import cz.nic.tablexia.loader.application.ApplicationAtlasManager; import cz.nic.tablexia.screen.AbstractTablexiaScreen; import cz.nic.tablexia.screen.encyclopedia.EncyclopediaScreen; import cz.nic.tablexia.screen.gamemenu.GameMenuAssets; +import cz.nic.tablexia.screen.gamemenu.GameMenuScreen; +import cz.nic.tablexia.screen.gamemenu.event.ShowGameMenuPageEvent; import cz.nic.tablexia.screen.halloffame.HallOfFameScreen; import cz.nic.tablexia.screen.profile.ProfileScreen; import cz.nic.tablexia.screen.statistics.StatisticsScreen; import cz.nic.tablexia.util.Log; import cz.nic.tablexia.util.ui.TablexiaNoBlendingImage; +import cz.nic.tablexia.util.ui.ViewPager; /** * Created by lhoracek on 3/4/15. */ -public class OfficeMenuPage extends MenuPage { +public class OfficeMenuPage extends MenuPage implements ViewPager.ScrollListener { public static final Color STREET_COLOR = Color.YELLOW; public static final Color HALLOFFAME_COLOR = Color.GREEN; @@ -96,7 +99,7 @@ public class OfficeMenuPage extends MenuPage { } else if (color.equals(HALLOFFAME_COLOR)) { ApplicationBus.getInstance().publishAsync(new Tablexia.ChangeScreenEvent(HallOfFameScreen.class, TablexiaApplication.ScreenTransaction.FADE)); } else if (color.equals(STREET_COLOR)) { - ApplicationBus.getInstance().publishAsync(new ShowStreetEvent()); + ApplicationBus.getInstance().publishAsync(new ShowGameMenuPageEvent(GameMenuScreen.GameMenuPageDefinition.getGameMenuPageForNumber(1))); } else if (color.equals(PROFILE_COLOR)) { ApplicationBus.getInstance().publishAsync(new Tablexia.ChangeScreenEvent(ProfileScreen.class, TablexiaApplication.ScreenTransaction.FADE)); } @@ -139,7 +142,6 @@ public class OfficeMenuPage extends MenuPage { encyclopedia.setVisible(false); statistics.setVisible(false); hallOfFame.setVisible(false); - } /** @@ -159,9 +161,13 @@ public class OfficeMenuPage extends MenuPage { return new Color(getScreen().getData()[clickX][clickY]); } - /** - * Event fired by clicking on door telling viewpager to page to first game - */ - public static class ShowStreetEvent implements ApplicationBus.ApplicationEvent { + @Override + public void onScroll(float offset) { + // nothing needed + } + + @Override + public void onScrolledToPage() { + ApplicationBus.getInstance().post(new GameMenuPage.GameMenuPageScrolledEvent(GameMenuScreen.GameMenuPageDefinition.OFFICE_PAGE)).asynchronously(); } } diff --git a/core/src/cz/nic/tablexia/screen/halloffame/HallOfFameScreen.java b/core/src/cz/nic/tablexia/screen/halloffame/HallOfFameScreen.java index 97bf7fcbfa632da164d5f5673d1529dfdea8c38e..30380e38e29acdc260ea4fd869be3cc4daabc283 100644 --- a/core/src/cz/nic/tablexia/screen/halloffame/HallOfFameScreen.java +++ b/core/src/cz/nic/tablexia/screen/halloffame/HallOfFameScreen.java @@ -78,7 +78,7 @@ public class HallOfFameScreen extends AbstractTablexiaScreen<Void> { getStage().addActor(scrollPane); - if (screenState != null && screenState.containsKey(SCREEN_STATE_SCROLL_POSITION_X)) { + if (screenState.containsKey(SCREEN_STATE_SCROLL_POSITION_X)) { scrollPane.layout(); scrollPane.setScrollPercentX(Float.valueOf(screenState.get(SCREEN_STATE_SCROLL_POSITION_X))); scrollPane.updateVisualScroll(); diff --git a/core/src/cz/nic/tablexia/screen/loader/LoaderScreen.java b/core/src/cz/nic/tablexia/screen/loader/LoaderScreen.java index c98a4d4c81644971b54ce1c08af7e1a841ddefde..5fad63d40dc062a8162ed08bf131d7926984aa0d 100644 --- a/core/src/cz/nic/tablexia/screen/loader/LoaderScreen.java +++ b/core/src/cz/nic/tablexia/screen/loader/LoaderScreen.java @@ -18,8 +18,14 @@ public class LoaderScreen extends AbstractTablexiaScreen<Void> { private static final String LOADER_SMALL_HAND = BASE_PATH + "screen_loader_smallhand.png"; private static final String LOADER_BIG_HAND = BASE_PATH + "screen_loader_bighand.png"; - public LoaderScreen() { - super(false); + @Override + public boolean canBePaused() { + return false; + } + + @Override + public boolean canResetState() { + return false; } @Override diff --git a/core/src/cz/nic/tablexia/screen/preferences/PreferencesScreen.java b/core/src/cz/nic/tablexia/screen/preferences/PreferencesScreen.java deleted file mode 100644 index b698e0193e96fdea97dc19ad2a9ceb0a6ce2b91e..0000000000000000000000000000000000000000 --- a/core/src/cz/nic/tablexia/screen/preferences/PreferencesScreen.java +++ /dev/null @@ -1,84 +0,0 @@ -package cz.nic.tablexia.screen.preferences; - -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.scenes.scene2d.Actor; -import com.badlogic.gdx.scenes.scene2d.ui.Container; -import com.badlogic.gdx.scenes.scene2d.ui.Label; -import com.badlogic.gdx.scenes.scene2d.ui.List; -import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane; -import com.badlogic.gdx.scenes.scene2d.ui.SelectBox; -import com.badlogic.gdx.scenes.scene2d.ui.Table; -import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; -import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; - -import java.util.Map; - -import cz.nic.tablexia.TablexiaSettings; -import cz.nic.tablexia.loader.application.ApplicationAtlasManager; -import cz.nic.tablexia.screen.AbstractTablexiaScreen; - -public class PreferencesScreen extends AbstractTablexiaScreen<Void> { - - public static final String LANGUAGE_LABEL_KEY = "language_label"; - - private Container<Table> preferencesContainer; - - @Override - protected String prepareScreenAtlasPath(String screenAssetsPath, String screenName) { - // no atlas loading - return null; - } - - @Override - protected void screenLoaded(Map<String, String> screenState) { - BitmapFont font = getDefaultRegularFont(); - Label.LabelStyle labelStyle = new Label.LabelStyle(font, Color.WHITE); - - preferencesContainer = new Container<Table>(); - preferencesContainer.setBackground(new TextureRegionDrawable(getApplicationTextureRegion(ApplicationAtlasManager.BACKGROUND_WOODEN))); - getStage().addActor(preferencesContainer); - - Table preferencesLayout = new Table(); - preferencesContainer.setActor(preferencesLayout); - preferencesContainer.left().top(); - preferencesContainer.pad(getStage().getWidth() / 10); - preferencesContainer.setBounds(0, 0, getStage().getWidth(), getStage().getHeight()); - - // Languages Label - Label languagesLabel = new Label(getText(LANGUAGE_LABEL_KEY), labelStyle); - preferencesLayout.add(languagesLabel); - - // Languages SelectBox - ScrollPane.ScrollPaneStyle scrollPaneStyle = new ScrollPane.ScrollPaneStyle(); - scrollPaneStyle.background = new TextureRegionDrawable(getColorTextureRegion(Color.GRAY)); - scrollPaneStyle.background.setMinWidth(50); // temporary size - scrollPaneStyle.background.setMinHeight(50); - List.ListStyle listStyle = new List.ListStyle(); - listStyle.selection = new TextureRegionDrawable(getColorTextureRegion(Color.GRAY)); - listStyle.font = font; - SelectBox.SelectBoxStyle selectBoxStyle = new SelectBox.SelectBoxStyle(); - selectBoxStyle.font = font; - selectBoxStyle.scrollStyle = scrollPaneStyle; - selectBoxStyle.listStyle = listStyle; - selectBoxStyle.background = new TextureRegionDrawable(getColorTextureRegion(Color.GRAY)); - selectBoxStyle.background.setMinWidth(50); // temporary size - selectBoxStyle.background.setMinHeight(50); - SelectBox<TablexiaSettings.LocaleDefinition> languagesSelectBox = new SelectBox<TablexiaSettings.LocaleDefinition>(selectBoxStyle); - languagesSelectBox.setItems(TablexiaSettings.LocaleDefinition.values()); - languagesSelectBox.setSelected(TablexiaSettings.getInstance().getLocaleDefinition()); - languagesSelectBox.addCaptureListener(new ChangeListener() { - - @Override - public void changed(ChangeEvent event, Actor actor) { - TablexiaSettings.getInstance().setLocale(((SelectBox<TablexiaSettings.LocaleDefinition>) event.getTarget()).getSelected()); - } - }); - preferencesLayout.add(languagesSelectBox).expandX().left(); - } - - @Override - public void screenResized(int width, int height) { - preferencesContainer.setBounds(0, 0, getStage().getWidth(), getStage().getHeight()); - } -} diff --git a/core/src/cz/nic/tablexia/screen/viewport/FullscreenImageDebugScreen.java b/core/src/cz/nic/tablexia/screen/viewport/FullscreenImageDebugScreen.java index 33ba9b3ed45fb67c4a5e74c0f29c9aac9394ab0b..d1c1e6b7f805fff60daf60b7bf39a37ae72124a5 100644 --- a/core/src/cz/nic/tablexia/screen/viewport/FullscreenImageDebugScreen.java +++ b/core/src/cz/nic/tablexia/screen/viewport/FullscreenImageDebugScreen.java @@ -16,8 +16,9 @@ public class FullscreenImageDebugScreen extends AbstractTablexiaScreen<Void> { private static final String LOADER_SMALL_HAND = BASE_PATH + "screen_loader_smallhand.png"; private static final String LOADER_BIG_HAND = BASE_PATH + "screen_loader_bighand.png"; - public FullscreenImageDebugScreen() { - super(false); + @Override + public boolean canBePaused() { + return false; } @Override diff --git a/core/src/cz/nic/tablexia/util/Utility.java b/core/src/cz/nic/tablexia/util/Utility.java index 4debcebea529072f92bdb3b18e1def459242589f..defe618fcedaf8880b910788a16814e9237fb36a 100644 --- a/core/src/cz/nic/tablexia/util/Utility.java +++ b/core/src/cz/nic/tablexia/util/Utility.java @@ -12,9 +12,13 @@ import cz.nic.tablexia.screen.AbstractTablexiaScreen; public class Utility { - public static AbstractTablexiaScreen<?> getScreenForScreenClass(Class<? extends AbstractTablexiaScreen<?>> screenClass) { + public static AbstractTablexiaScreen<?> getScreenForScreenClass(Class<? extends AbstractTablexiaScreen<?>> screenClass, Map<String, String> initialState) { try { - return (AbstractTablexiaScreen<?>) ClassReflection.getConstructors(screenClass)[0].newInstance(new Object[]{}); + AbstractTablexiaScreen<?> abstractTablexiaScreen = (AbstractTablexiaScreen<?>) ClassReflection.getConstructors(screenClass)[0].newInstance(new Object[]{}); + if (initialState != null) { + abstractTablexiaScreen.setInitialState(initialState); + } + return abstractTablexiaScreen; } catch (ReflectionException e) { Log.err(Utility.class, "Cannot instantiate screen class: " + screenClass + " ! (Do you have only one parameter less constructor in screen class?)", e); } diff --git a/core/src/cz/nic/tablexia/util/ui/AbstractTablexiaSelectBox.java b/core/src/cz/nic/tablexia/util/ui/AbstractTablexiaSelectBox.java new file mode 100644 index 0000000000000000000000000000000000000000..ec8eaaca257080ee378e6ce41f9f13bf725f808d --- /dev/null +++ b/core/src/cz/nic/tablexia/util/ui/AbstractTablexiaSelectBox.java @@ -0,0 +1,512 @@ +package cz.nic.tablexia.util.ui; + +import com.badlogic.gdx.Input; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.math.Interpolation; +import com.badlogic.gdx.math.Rectangle; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.InputEvent; +import com.badlogic.gdx.scenes.scene2d.InputListener; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.Touchable; +import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane; +import com.badlogic.gdx.scenes.scene2d.ui.Widget; +import com.badlogic.gdx.scenes.scene2d.utils.ArraySelection; +import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; +import com.badlogic.gdx.scenes.scene2d.utils.Cullable; +import com.badlogic.gdx.scenes.scene2d.utils.Disableable; +import com.badlogic.gdx.scenes.scene2d.utils.Drawable; +import com.badlogic.gdx.utils.Array; +import com.badlogic.gdx.utils.ObjectSet; + +import static com.badlogic.gdx.scenes.scene2d.actions.Actions.fadeIn; +import static com.badlogic.gdx.scenes.scene2d.actions.Actions.fadeOut; +import static com.badlogic.gdx.scenes.scene2d.actions.Actions.removeActor; +import static com.badlogic.gdx.scenes.scene2d.actions.Actions.sequence; + +/** + * Created by Matyáš Latner. + */ +public abstract class AbstractTablexiaSelectBox<T> extends Widget implements Disableable { + static final Vector2 temp = new Vector2(); + + final Array<T> items = new Array(); + final ArraySelection<T> selection = new ArraySelection(items); + TablexiaSelectBoxList selectBoxList; + private float prefWidth, prefHeight; + private ClickListener clickListener; + boolean disabled; + + public AbstractTablexiaSelectBox(float itemHeight) { + setSize(getPrefWidth(), itemHeight); + + selection.setActor(this); + selection.setRequired(true); + + selectBoxList = new TablexiaSelectBoxList(this, itemHeight); + + addListener(clickListener = new ClickListener() { + public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) { + if (pointer == 0 && button != 0) return false; + if (disabled) return false; + if (selectBoxList.hasParent()) + hideList(); + else + showList(); + return true; + } + }); + } + + /** Set the max number of items to display when the select box is opened. Set to 0 (the default) to display as many as fit in + * the stage height. */ + public void setMaxListCount (int maxListCount) { + selectBoxList.maxListCount = maxListCount; + } + + /** @return Max number of items to display when the box is opened, or <= 0 to display them all. */ + public int getMaxListCount () { + return selectBoxList.maxListCount; + } + + protected void setStage (Stage stage) { + if (stage == null) selectBoxList.hide(); + super.setStage(stage); + } + + /** Set the backing Array that makes up the choices available in the SelectBox */ + public void setItems (T... newItems) { + if (newItems == null) throw new IllegalArgumentException("newItems cannot be null."); + float oldPrefWidth = getPrefWidth(); + + items.clear(); + items.addAll(newItems); + selection.validate(); + selectBoxList.list.setItems(items); + + invalidate(); + if (oldPrefWidth != getPrefWidth()) invalidateHierarchy(); + } + + /** Sets the items visible in the select box. */ + public void setItems (Array<T> newItems) { + if (newItems == null) throw new IllegalArgumentException("newItems cannot be null."); + float oldPrefWidth = getPrefWidth(); + + items.clear(); + items.addAll(newItems); + selection.validate(); + selectBoxList.list.setItems(items); + + invalidate(); + if (oldPrefWidth != getPrefWidth()) invalidateHierarchy(); + } + + public void clearItems () { + if (items.size == 0) return; + items.clear(); + selection.clear(); + invalidateHierarchy(); + } + + /** Returns the internal items array. If modified, {@link #setItems(Array)} must be called to reflect the changes. */ + public Array<T> getItems () { + return items; + } + + @Override + public void layout () { + prefHeight = getHeight(); + float maxItemWidth = 0; + prefWidth = maxItemWidth; + prefWidth = Math.max(prefWidth, maxItemWidth); + } + + @Override + public void draw (Batch batch, float parentAlpha) { + validate(); + + Color color = getColor(); + float width = getWidth(); + float height = getHeight(); + + batch.setColor(color.r, color.g, color.b, color.a * parentAlpha); + + T selected = selection.first(); + if (selected != null) { + drawSelectedItem(batch, parentAlpha, selected, width, height); + } + } + + protected abstract void drawSelectedItem(Batch batch, float parentAlpha, T selected, float width, float height); + + protected abstract void drawListItem(Batch batch, float parentAlpha, T item, float x, float y, float width, float height); + + /** Get the set of selected items, useful when multiple items are selected + * @return a Selection object containing the selected elements */ + public ArraySelection<T> getSelection () { + return selection; + } + + /** Returns the first selected item, or null. For multiple selections use {@link AbstractTablexiaSelectBox#getSelection()}. */ + public T getSelected () { + return selection.first(); + } + + /** Sets the selection to only the passed item, if it is a possible choice, else selects the first item. */ + public void setSelected (T item) { + if (items.contains(item, false)) + selection.set(item); + else if (items.size > 0) + selection.set(items.first()); + else + selection.clear(); + } + + /** @return The index of the first selected item. The top item has an index of 0. Nothing selected has an index of -1. */ + public int getSelectedIndex () { + ObjectSet<T> selected = selection.items(); + return selected.size == 0 ? -1 : items.indexOf(selected.first(), false); + } + + /** Sets the selection to only the selected index. */ + public void setSelectedIndex (int index) { + selection.set(items.get(index)); + } + + public void setDisabled (boolean disabled) { + if (disabled && !this.disabled) hideList(); + this.disabled = disabled; + } + + public boolean isDisabled () { + return disabled; + } + + public float getPrefWidth () { + validate(); + return prefWidth; + } + + public float getPrefHeight () { + validate(); + return prefHeight; + } + + public void showList () { + if (items.size == 0) return; + selectBoxList.show(getStage()); + } + + public void hideList () { + selectBoxList.hide(); + } + + /** Returns the list shown when the select box is open. */ + public TablexiaList getList () { + return selectBoxList.list; + } + + /** Returns the scroll pane containing the list that is shown when the select box is open. */ + public ScrollPane getScrollPane () { + return selectBoxList; + } + + protected void onShow (Actor selectBoxList, boolean below) { + selectBoxList.getColor().a = 0; + selectBoxList.addAction(fadeIn(0.3f, Interpolation.fade)); + } + + protected void onHide (Actor selectBoxList) { + selectBoxList.getColor().a = 1; + selectBoxList.addAction(sequence(fadeOut(0.15f, Interpolation.fade), removeActor())); + } + + /** @author Nathan Sweet */ + class TablexiaSelectBoxList extends ScrollPane { + private final AbstractTablexiaSelectBox<T> selectBox; + int maxListCount; + private final Vector2 screenPosition = new Vector2(); + final TablexiaList list; + private InputListener hideListener; + private Actor previousScrollFocus; + + public TablexiaSelectBoxList (final AbstractTablexiaSelectBox<T> selectBox, float itemHeight) { + super(null, new ScrollPaneStyle()); + this.selectBox = selectBox; + + setOverscroll(false, false); + setFadeScrollBars(false); + setScrollingDisabled(true, false); + + list = new TablexiaList(itemHeight); + list.setTouchable(Touchable.disabled); + setWidget(list); + + list.addListener(new ClickListener() { + public void clicked (InputEvent event, float x, float y) { + selectBox.selection.choose(list.getSelected()); + hide(); + } + + public boolean mouseMoved (InputEvent event, float x, float y) { + list.setSelectedIndex(Math.min(selectBox.items.size - 1, (int)((list.getHeight() - y) / list.getItemHeight()))); + return true; + } + }); + + addListener(new InputListener() { + public void exit (InputEvent event, float x, float y, int pointer, Actor toActor) { + if (toActor == null || !isAscendantOf(toActor)) list.selection.set(selectBox.getSelected()); + } + }); + + hideListener = new InputListener() { + public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) { + Actor target = event.getTarget(); + if (isAscendantOf(target)) return false; + list.selection.set(selectBox.getSelected()); + hide(); + return false; + } + + public boolean keyDown (InputEvent event, int keycode) { + if (keycode == Input.Keys.ESCAPE) hide(); + return false; + } + }; + } + + public void show (Stage stage) { + if (list.isTouchable()) return; + + stage.removeCaptureListener(hideListener); + stage.addCaptureListener(hideListener); + stage.addActor(this); + + selectBox.localToStageCoordinates(screenPosition.set(0, 0)); + + // Show the list above or below the select box, limited to a number of items and the available height in the stage. + float itemHeight = list.getItemHeight(); + float height = itemHeight * (maxListCount <= 0 ? selectBox.items.size : Math.min(maxListCount, selectBox.items.size)); + Drawable scrollPaneBackground = getStyle().background; + if (scrollPaneBackground != null) + height += scrollPaneBackground.getTopHeight() + scrollPaneBackground.getBottomHeight(); + + float heightBelow = screenPosition.y; + float heightAbove = stage.getCamera().viewportHeight - screenPosition.y - selectBox.getHeight(); + boolean below = true; + if (height > heightBelow) { + if (heightAbove > heightBelow) { + below = false; + height = Math.min(height, heightAbove); + } else + height = heightBelow; + } + + if (below) + setY(screenPosition.y - height); + else + setY(screenPosition.y + selectBox.getHeight()); + setX(screenPosition.x); + setHeight(height); + validate(); + float width = Math.max(getPrefWidth(), selectBox.getWidth()); + if (getPrefHeight() > height) width += getScrollBarWidth(); + if (scrollPaneBackground != null) { + // Assume left and right padding are the same, so right padding can include a shadow. + width += Math.max(0, scrollPaneBackground.getRightWidth() - scrollPaneBackground.getLeftWidth()); + } + setWidth(width); + + validate(); + scrollTo(0, list.getHeight() - selectBox.getSelectedIndex() * itemHeight - itemHeight / 2, 0, 0, true, true); + updateVisualScroll(); + + previousScrollFocus = null; + Actor actor = stage.getScrollFocus(); + if (actor != null && !actor.isDescendantOf(this)) previousScrollFocus = actor; + stage.setScrollFocus(this); + + list.selection.set(selectBox.getSelected()); + list.setTouchable(Touchable.enabled); + clearActions(); + selectBox.onShow(this, below); + } + + public void hide () { + if (!list.isTouchable() || !hasParent()) return; + list.setTouchable(Touchable.disabled); + + Stage stage = getStage(); + if (stage != null) { + stage.removeCaptureListener(hideListener); + if (previousScrollFocus != null && previousScrollFocus.getStage() == null) previousScrollFocus = null; + Actor actor = stage.getScrollFocus(); + if (actor == null || isAscendantOf(actor)) stage.setScrollFocus(previousScrollFocus); + } + + clearActions(); + selectBox.onHide(this); + } + + public void draw (Batch batch, float parentAlpha) { + selectBox.localToStageCoordinates(temp.set(0, 0)); + if (!temp.equals(screenPosition)) hide(); + super.draw(batch, parentAlpha); + } + + public void act (float delta) { + super.act(delta); + toFront(); + } + } + + public class TablexiaList extends Widget implements Cullable { + private final Array<T> items = new Array(); + final ArraySelection<T> selection = new ArraySelection(items); + private Rectangle cullingArea; + private float prefWidth, prefHeight; + private float itemHeight; + + public TablexiaList (float itemHeight) { + this.itemHeight = itemHeight; + selection.setActor(this); + selection.setRequired(true); + + setSize(getPrefWidth(), getPrefHeight()); + + addListener(new InputListener() { + public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) { + if (pointer == 0 && button != 0) return false; + if (selection.isDisabled()) return false; + TablexiaList.this.touchDown(y); + return true; + } + }); + } + + void touchDown (float y) { + if (items.size == 0) return; + float height = getHeight(); + int index = (int)((height - y) / itemHeight); + index = Math.max(0, index); + index = Math.min(items.size - 1, index); + selection.choose(items.get(index)); + } + + public void layout () { + prefWidth = 0; + prefHeight = items.size * itemHeight; + } + + @Override + public void draw (Batch batch, float parentAlpha) { + validate(); + float itemY = getHeight(); + + for (int i = 0; i < items.size; i++) { + if (cullingArea == null || (itemY - itemHeight <= cullingArea.y + cullingArea.height && itemY >= cullingArea.y)) { + drawListItem(batch, parentAlpha, items.get(i), 0, getY() + itemY - itemHeight, getWidth(), itemHeight); + } else if (itemY < cullingArea.y) { + break; + } + itemY -= itemHeight; + } + } + + public ArraySelection<T> getSelection () { + return selection; + } + + /** Returns the first selected item, or null. */ + public T getSelected () { + return selection.first(); + } + + /** Sets the selection to only the passed item, if it is a possible choice. */ + public void setSelected (T item) { + if (items.contains(item, false)) + selection.set(item); + else if (selection.getRequired() && items.size > 0) + selection.set(items.first()); + else + selection.clear(); + } + + /** @return The index of the first selected item. The top item has an index of 0. Nothing selected has an index of -1. */ + public int getSelectedIndex () { + ObjectSet<T> selected = selection.items(); + return selected.size == 0 ? -1 : items.indexOf(selected.first(), false); + } + + /** Sets the selection to only the selected index. */ + public void setSelectedIndex (int index) { + if (index < -1 || index >= items.size) + throw new IllegalArgumentException("index must be >= -1 and < " + items.size + ": " + index); + if (index == -1) { + selection.clear(); + } else { + selection.set(items.get(index)); + } + } + + public void setItems (T... newItems) { + if (newItems == null) throw new IllegalArgumentException("newItems cannot be null."); + float oldPrefWidth = getPrefWidth(), oldPrefHeight = getPrefHeight(); + + items.clear(); + items.addAll(newItems); + selection.validate(); + + invalidate(); + if (oldPrefWidth != getPrefWidth() || oldPrefHeight != getPrefHeight()) invalidateHierarchy(); + } + + /** Sets the items visible in the list, clearing the selection if it is no longer valid. If a selection is + * {@link ArraySelection#getRequired()}, the first item is selected. */ + public void setItems (Array newItems) { + if (newItems == null) throw new IllegalArgumentException("newItems cannot be null."); + float oldPrefWidth = getPrefWidth(), oldPrefHeight = getPrefHeight(); + + items.clear(); + items.addAll(newItems); + selection.validate(); + + invalidate(); + if (oldPrefWidth != getPrefWidth() || oldPrefHeight != getPrefHeight()) invalidateHierarchy(); + } + + public void clearItems () { + if (items.size == 0) return; + items.clear(); + selection.clear(); + invalidateHierarchy(); + } + + /** Returns the internal items array. If modified, {@link #setItems(Array)} must be called to reflect the changes. */ + public Array<T> getItems () { + return items; + } + + public float getItemHeight () { + return itemHeight; + } + + public float getPrefWidth () { + validate(); + return prefWidth; + } + + public float getPrefHeight () { + validate(); + return prefHeight; + } + + public void setCullingArea (Rectangle cullingArea) { + this.cullingArea = cullingArea; + } + } +} diff --git a/core/src/cz/nic/tablexia/util/ui/ViewPager.java b/core/src/cz/nic/tablexia/util/ui/ViewPager.java index 192fb7436c674c58ce1f62a3921a09947c311d0d..2ab1e19387a4825529c82f6ba927a5a24ff2b3a6 100644 --- a/core/src/cz/nic/tablexia/util/ui/ViewPager.java +++ b/core/src/cz/nic/tablexia/util/ui/ViewPager.java @@ -146,11 +146,13 @@ public class ViewPager extends ScrollPane { * Smooth scroll to child with given index * * @param page + * @param smoothScroll */ - public void scrollToPage(int page) { + public void scrollToPage(int page, boolean smoothScroll) { if (content.getChildren().size <= page) { throw new IllegalArgumentException("Page index " + page + " out of bounds"); } + layout(); final float width = getWidth(); final float maxX = getMaxX(); @@ -162,7 +164,12 @@ public class ViewPager extends ScrollPane { pageX = a.getX(); pageWidth = a.getWidth(); } + setSmoothScrolling(smoothScroll); setScrollX(MathUtils.clamp(pageX - (width - pageWidth) / 2, 0, maxX)); + if (!smoothScroll) { + updateVisualScroll(); + setSmoothScrolling(true); + } } } @@ -188,9 +195,8 @@ public class ViewPager extends ScrollPane { } } - public static interface ScrollListener { - public void onScroll(float offset); - - public void onScrolledToPage(); + public interface ScrollListener { + void onScroll(float offset); + void onScrolledToPage(); } }