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();
     }
 }