Ejemplo n.º 1
0
        protected override void LoadComplete()
        {
            base.LoadComplete();

            // hook up notifications to components.
            BeatmapManager.PostNotification = n => notificationOverlay?.Post(n);
            BeatmapManager.GetStableStorage = GetStorageForStableInstall;

            AddRange(new Drawable[] {
                new VolumeControlReceptor
                {
                    RelativeSizeAxes = Axes.Both,
                    ActionRequested  = action => volume.Adjust(action)
                },
                mainContent = new Container
                {
                    RelativeSizeAxes = Axes.Both,
                },
                volume         = new VolumeControl(),
                overlayContent = new Container {
                    RelativeSizeAxes = Axes.Both
                },
                new OnScreenDisplay(),
            });

            LoadComponentAsync(screenStack = new Loader(), d =>
            {
                screenStack.ModePushed += screenAdded;
                screenStack.Exited     += screenRemoved;
                mainContent.Add(screenStack);
            });

            //overlay elements
            LoadComponentAsync(direct = new DirectOverlay {
                Depth = -1
            }, mainContent.Add);
            LoadComponentAsync(social = new SocialOverlay {
                Depth = -1
            }, mainContent.Add);
            LoadComponentAsync(chat = new ChatOverlay {
                Depth = -1
            }, mainContent.Add);
            LoadComponentAsync(settings = new MainSettings
            {
                GetToolbarHeight = () => ToolbarOffset,
                Depth            = -1
            }, overlayContent.Add);
            LoadComponentAsync(userProfile = new UserProfileOverlay {
                Depth = -2
            }, mainContent.Add);
            LoadComponentAsync(beatmapSetOverlay = new BeatmapSetOverlay {
                Depth = -3
            }, mainContent.Add);
            LoadComponentAsync(musicController = new MusicController
            {
                Depth    = -4,
                Position = new Vector2(0, Toolbar.HEIGHT),
                Anchor   = Anchor.TopRight,
                Origin   = Anchor.TopRight,
            }, overlayContent.Add);

            LoadComponentAsync(notificationOverlay = new NotificationOverlay
            {
                Depth  = -4,
                Anchor = Anchor.TopRight,
                Origin = Anchor.TopRight,
            }, overlayContent.Add);

            LoadComponentAsync(dialogOverlay = new DialogOverlay
            {
                Depth = -5,
            }, overlayContent.Add);

            Logger.NewEntry += entry =>
            {
                if (entry.Level < LogLevel.Important)
                {
                    return;
                }

                notificationOverlay.Post(new SimpleNotification
                {
                    Text = $@"{entry.Level}: {entry.Message}"
                });
            };

            dependencies.Cache(settings);
            dependencies.Cache(social);
            dependencies.Cache(direct);
            dependencies.Cache(chat);
            dependencies.Cache(userProfile);
            dependencies.Cache(musicController);
            dependencies.Cache(beatmapSetOverlay);
            dependencies.Cache(notificationOverlay);
            dependencies.Cache(dialogOverlay);

            // ensure only one of these overlays are open at once.
            var singleDisplayOverlays = new OverlayContainer[] { chat, social, direct };

            foreach (var overlay in singleDisplayOverlays)
            {
                overlay.StateChanged += state =>
                {
                    if (state == Visibility.Hidden)
                    {
                        return;
                    }

                    foreach (var c in singleDisplayOverlays)
                    {
                        if (c == overlay)
                        {
                            continue;
                        }
                        c.State = Visibility.Hidden;
                    }
                };
            }

            LoadComponentAsync(Toolbar = new Toolbar
            {
                Depth  = -4,
                OnHome = delegate
                {
                    hideAllOverlays();
                    intro?.ChildScreen?.MakeCurrent();
                },
            }, overlayContent.Add);

            settings.StateChanged += delegate
            {
                switch (settings.State)
                {
                case Visibility.Hidden:
                    intro.MoveToX(0, SettingsOverlay.TRANSITION_LENGTH, Easing.OutQuint);
                    break;

                case Visibility.Visible:
                    intro.MoveToX(SettingsOverlay.SIDEBAR_WIDTH / 2, SettingsOverlay.TRANSITION_LENGTH, Easing.OutQuint);
                    break;
                }
            };

            Cursor.State = Visibility.Hidden;
        }
Ejemplo n.º 2
0
        protected override void LoadComplete()
        {
            base.LoadComplete();

            Add(new Drawable[] {
                new VolumeControlReceptor
                {
                    RelativeSizeAxes = Axes.Both,
                    ActionRequested  = delegate(InputState state) { volume.Adjust(state); }
                },
                mainContent = new Container
                {
                    RelativeSizeAxes = Axes.Both,
                },
                volume         = new VolumeControl(),
                overlayContent = new Container {
                    RelativeSizeAxes = Axes.Both
                },
                new GlobalHotkeys //exists because UserInputManager is at a level below us.
                {
                    Handler = globalHotkeyPressed
                }
            });

            (screenStack = new Loader()).LoadAsync(this, d =>
            {
                screenStack.ModePushed += screenAdded;
                screenStack.Exited     += screenRemoved;
                mainContent.Add(screenStack);
            });

            //overlay elements
            (chat = new ChatOverlay {
                Depth = 0
            }).LoadAsync(this, overlayContent.Add);
            (options = new OptionsOverlay {
                Depth = -1
            }).LoadAsync(this, overlayContent.Add);
            (musicController = new MusicController
            {
                Depth = -2,
                Position = new Vector2(0, Toolbar.HEIGHT),
                Anchor = Anchor.TopRight,
                Origin = Anchor.TopRight,
            }).LoadAsync(this, overlayContent.Add);

            (notificationManager = new NotificationManager
            {
                Depth = -2,
                Anchor = Anchor.TopRight,
                Origin = Anchor.TopRight,
            }).LoadAsync(this, overlayContent.Add);

            (dialogOverlay = new DialogOverlay
            {
                Depth = -4,
            }).LoadAsync(this, overlayContent.Add);

            Logger.NewEntry += entry =>
            {
                if (entry.Level < LogLevel.Important)
                {
                    return;
                }

                notificationManager.Post(new SimpleNotification
                {
                    Text = $@"{entry.Level}: {entry.Message}"
                });
            };

            Dependencies.Cache(options);
            Dependencies.Cache(musicController);
            Dependencies.Cache(notificationManager);
            Dependencies.Cache(dialogOverlay);

            (Toolbar = new Toolbar
            {
                Depth = -3,
                OnHome = delegate { intro?.ChildScreen?.MakeCurrent(); },
                OnPlayModeChange = delegate(PlayMode m) { PlayMode.Value = m; },
            }).LoadAsync(this, t =>
            {
                PlayMode.ValueChanged += delegate { Toolbar.SetGameMode(PlayMode.Value); };
                PlayMode.TriggerChange();
                overlayContent.Add(Toolbar);
            });

            options.StateChanged += delegate
            {
                switch (options.State)
                {
                case Visibility.Hidden:
                    intro.MoveToX(0, OptionsOverlay.TRANSITION_LENGTH, EasingTypes.OutQuint);
                    break;

                case Visibility.Visible:
                    intro.MoveToX(OptionsOverlay.SIDEBAR_WIDTH / 2, OptionsOverlay.TRANSITION_LENGTH, EasingTypes.OutQuint);
                    break;
                }
            };

            Cursor.State = Visibility.Hidden;
        }
Ejemplo n.º 3
0
Archivo: OsuGame.cs Proyecto: mist9/osu
        protected override void LoadComplete()
        {
            base.LoadComplete();

            AddRange(new Drawable[] {
                new VolumeControlReceptor
                {
                    RelativeSizeAxes = Axes.Both,
                    ActionRequested  = delegate(InputState state) { volume.Adjust(state); }
                },
                mainContent = new Container
                {
                    RelativeSizeAxes = Axes.Both,
                },
                volume         = new VolumeControl(),
                overlayContent = new Container {
                    RelativeSizeAxes = Axes.Both
                },
                new OnScreenDisplay(),
                new GlobalHotkeys //exists because UserInputManager is at a level below us.
                {
                    Handler = globalHotkeyPressed
                }
            });

            LoadComponentAsync(screenStack = new Loader(), d =>
            {
                screenStack.ModePushed += screenAdded;
                screenStack.Exited     += screenRemoved;
                mainContent.Add(screenStack);
            });

            //overlay elements
            LoadComponentAsync(direct = new DirectOverlay {
                Depth = -1
            }, mainContent.Add);
            LoadComponentAsync(social = new SocialOverlay {
                Depth = -1
            }, mainContent.Add);
            LoadComponentAsync(chat = new ChatOverlay {
                Depth = -1
            }, mainContent.Add);
            LoadComponentAsync(userProfile = new UserProfileOverlay {
                Depth = -1
            }, mainContent.Add);
            LoadComponentAsync(settings = new SettingsOverlay {
                Depth = -1
            }, overlayContent.Add);
            LoadComponentAsync(musicController = new MusicController
            {
                Depth    = -2,
                Position = new Vector2(0, Toolbar.HEIGHT),
                Anchor   = Anchor.TopRight,
                Origin   = Anchor.TopRight,
            }, overlayContent.Add);

            LoadComponentAsync(notificationManager = new NotificationManager
            {
                Depth  = -2,
                Anchor = Anchor.TopRight,
                Origin = Anchor.TopRight,
            }, overlayContent.Add);

            LoadComponentAsync(dialogOverlay = new DialogOverlay
            {
                Depth = -4,
            }, overlayContent.Add);

            Logger.NewEntry += entry =>
            {
                if (entry.Level < LogLevel.Important)
                {
                    return;
                }

                notificationManager.Post(new SimpleNotification
                {
                    Text = $@"{entry.Level}: {entry.Message}"
                });
            };

            Dependencies.Cache(settings);
            Dependencies.Cache(social);
            Dependencies.Cache(chat);
            Dependencies.Cache(userProfile);
            Dependencies.Cache(musicController);
            Dependencies.Cache(notificationManager);
            Dependencies.Cache(dialogOverlay);

            // ensure both overlays aren't presented at the same time
            chat.StateChanged   += (container, state) => social.State = state == Visibility.Visible ? Visibility.Hidden : social.State;
            social.StateChanged += (container, state) => chat.State = state == Visibility.Visible ? Visibility.Hidden : chat.State;

            LoadComponentAsync(Toolbar = new Toolbar
            {
                Depth  = -3,
                OnHome = delegate { intro?.ChildScreen?.MakeCurrent(); },
            }, overlayContent.Add);

            settings.StateChanged += delegate
            {
                switch (settings.State)
                {
                case Visibility.Hidden:
                    intro.MoveToX(0, SettingsOverlay.TRANSITION_LENGTH, EasingTypes.OutQuint);
                    break;

                case Visibility.Visible:
                    intro.MoveToX(SettingsOverlay.SIDEBAR_WIDTH / 2, SettingsOverlay.TRANSITION_LENGTH, EasingTypes.OutQuint);
                    break;
                }
            };

            Cursor.State = Visibility.Hidden;
        }
Ejemplo n.º 4
0
        protected override void LoadComplete()
        {
            base.LoadComplete();

            // The next time this is updated is in UpdateAfterChildren, which occurs too late and results
            // in the cursor being shown for a few frames during the intro.
            // This prevents the cursor from showing until we have a screen with CursorVisible = true
            CursorOverrideContainer.CanShowCursor = currentScreen?.CursorVisible ?? false;

            // hook up notifications to components.
            SkinManager.PostNotification    = n => notifications?.Post(n);
            BeatmapManager.PostNotification = n => notifications?.Post(n);

            BeatmapManager.GetStableStorage = GetStorageForStableInstall;

            AddRange(new Drawable[]
            {
                new VolumeControlReceptor
                {
                    RelativeSizeAxes = Axes.Both,
                    ActionRequested  = action => volume.Adjust(action)
                },
                mainContent = new Container {
                    RelativeSizeAxes = Axes.Both
                },
                overlayContent = new Container {
                    RelativeSizeAxes = Axes.Both, Depth = float.MinValue
                },
            });

            loadComponentSingleFile(screenStack = new Loader(), d =>
            {
                screenStack.ModePushed += screenAdded;
                screenStack.Exited     += screenRemoved;
                mainContent.Add(screenStack);
            });

            loadComponentSingleFile(Toolbar = new Toolbar
            {
                Depth  = -5,
                OnHome = delegate
                {
                    hideAllOverlays();
                    intro?.ChildScreen?.MakeCurrent();
                },
            }, overlayContent.Add);

            loadComponentSingleFile(volume          = new VolumeControl(), Add);
            loadComponentSingleFile(onscreenDisplay = new OnScreenDisplay(), Add);

            //overlay elements
            loadComponentSingleFile(direct = new DirectOverlay {
                Depth = -1
            }, mainContent.Add);
            loadComponentSingleFile(social = new SocialOverlay {
                Depth = -1
            }, mainContent.Add);
            loadComponentSingleFile(chat = new ChatOverlay {
                Depth = -1
            }, mainContent.Add);
            loadComponentSingleFile(settings = new MainSettings
            {
                GetToolbarHeight = () => ToolbarOffset,
                Depth            = -1
            }, overlayContent.Add);
            loadComponentSingleFile(userProfile = new UserProfileOverlay {
                Depth = -2
            }, mainContent.Add);
            loadComponentSingleFile(beatmapSetOverlay = new BeatmapSetOverlay {
                Depth = -3
            }, mainContent.Add);
            loadComponentSingleFile(musicController = new MusicController
            {
                Depth    = -4,
                Position = new Vector2(0, Toolbar.HEIGHT),
                Anchor   = Anchor.TopRight,
                Origin   = Anchor.TopRight,
            }, overlayContent.Add);

            loadComponentSingleFile(notifications = new NotificationOverlay
            {
                GetToolbarHeight = () => ToolbarOffset,
                Depth            = -4,
                Anchor           = Anchor.TopRight,
                Origin           = Anchor.TopRight,
            }, overlayContent.Add);

            loadComponentSingleFile(dialogOverlay = new DialogOverlay
            {
                Depth = -6,
            }, overlayContent.Add);

            forwardLoggedErrorsToNotifications();

            dependencies.Cache(settings);
            dependencies.Cache(onscreenDisplay);
            dependencies.Cache(social);
            dependencies.Cache(direct);
            dependencies.Cache(chat);
            dependencies.Cache(userProfile);
            dependencies.Cache(musicController);
            dependencies.Cache(beatmapSetOverlay);
            dependencies.Cache(notifications);
            dependencies.Cache(dialogOverlay);

            // ensure only one of these overlays are open at once.
            var singleDisplayOverlays = new OverlayContainer[] { chat, social, direct };

            foreach (var overlay in singleDisplayOverlays)
            {
                overlay.StateChanged += state =>
                {
                    if (state == Visibility.Hidden)
                    {
                        return;
                    }

                    foreach (var c in singleDisplayOverlays)
                    {
                        if (c == overlay)
                        {
                            continue;
                        }
                        c.State = Visibility.Hidden;
                    }
                };
            }

            // eventually informational overlays should be displayed in a stack, but for now let's only allow one to stay open at a time.
            var informationalOverlays = new OverlayContainer[] { beatmapSetOverlay, userProfile };

            foreach (var overlay in informationalOverlays)
            {
                overlay.StateChanged += state =>
                {
                    if (state == Visibility.Hidden)
                    {
                        return;
                    }

                    foreach (var c in informationalOverlays)
                    {
                        if (c == overlay)
                        {
                            continue;
                        }
                        c.State = Visibility.Hidden;
                    }
                };
            }

            void updateScreenOffset()
            {
                float offset = 0;

                if (settings.State == Visibility.Visible)
                {
                    offset += ToolbarButton.WIDTH / 2;
                }
                if (notifications.State == Visibility.Visible)
                {
                    offset -= ToolbarButton.WIDTH / 2;
                }

                screenStack.MoveToX(offset, SettingsOverlay.TRANSITION_LENGTH, Easing.OutQuint);
            }

            settings.StateChanged      += _ => updateScreenOffset();
            notifications.StateChanged += _ => updateScreenOffset();

            notifications.Enabled.BindTo(ShowOverlays);

            ShowOverlays.ValueChanged += show =>
            {
                //central game screen change logic.
                if (!show)
                {
                    hideAllOverlays();
                    musicController.State = Visibility.Hidden;
                    Toolbar.State         = Visibility.Hidden;
                }
                else
                {
                    Toolbar.State = Visibility.Visible;
                }
            };
        }
Ejemplo n.º 5
0
        protected override void LoadComplete()
        {
            base.LoadComplete();

            Add(new Drawable[] {
                new VolumeControlReceptor
                {
                    RelativeSizeAxes = Axes.Both,
                    ActionRequested  = delegate(InputState state) { volume.Adjust(state); }
                },
                mainContent = new Container
                {
                    RelativeSizeAxes = Axes.Both,
                },
                volume         = new VolumeControl(),
                overlayContent = new Container {
                    RelativeSizeAxes = Axes.Both
                },
                new GlobalHotkeys //exists because UserInputManager is at a level below us.
                {
                    Handler = globalHotkeyPressed
                }
            });

            (modeStack = new Intro()).Preload(this, d =>
            {
                mainContent.Add(d);

                modeStack.ModePushed += modeAdded;
                modeStack.Exited     += modeRemoved;
                modeStack.DisplayAsRoot();
            });

            //overlay elements
            (chat = new ChatConsole(API)
            {
                Depth = 0
            }).Preload(this, overlayContent.Add);
            (Options = new OptionsOverlay {
                Depth = 1
            }).Preload(this, overlayContent.Add);
            (musicController = new MusicController()
            {
                Depth = 3
            }).Preload(this, overlayContent.Add);
            (Toolbar = new Toolbar
            {
                Depth = 2,
                OnHome = delegate { mainMenu?.MakeCurrent(); },
                OnSettings = Options.ToggleVisibility,
                OnPlayModeChange = delegate(PlayMode m) { PlayMode.Value = m; },
                OnMusicController = musicController.ToggleVisibility
            }).Preload(this, t =>
            {
                PlayMode.ValueChanged += delegate { Toolbar.SetGameMode(PlayMode.Value); };
                PlayMode.TriggerChange();
                overlayContent.Add(Toolbar);
            });

            Cursor.Alpha = 0;
        }
Ejemplo n.º 6
0
        protected override void LoadComplete()
        {
            base.LoadComplete();

            Add(new Drawable[] {
                new VolumeControlReceptor
                {
                    RelativeSizeAxes = Axes.Both,
                    ActionRequested  = delegate(InputState state) { volume.Adjust(state); }
                },
                mainContent = new Container
                {
                    RelativeSizeAxes = Axes.Both,
                },
                volume         = new VolumeControl(),
                overlayContent = new Container {
                    RelativeSizeAxes = Axes.Both
                },
                new GlobalHotkeys //exists because UserInputManager is at a level below us.
                {
                    Handler = globalHotkeyPressed
                }
            });

            (modeStack = new Intro()).Preload(this, d =>
            {
                mainContent.Add(d);

                modeStack.ModePushed += modeAdded;
                modeStack.Exited     += modeRemoved;
                modeStack.DisplayAsRoot();
            });

            //overlay elements
            (chat = new ChatOverlay {
                Depth = 0
            }).Preload(this, overlayContent.Add);
            (options = new OptionsOverlay {
                Depth = -1
            }).Preload(this, overlayContent.Add);
            (musicController = new MusicController()
            {
                Depth = -3
            }).Preload(this, overlayContent.Add);

            Dependencies.Cache(options);
            Dependencies.Cache(musicController);

            (Toolbar = new Toolbar
            {
                Depth = -2,
                OnHome = delegate { mainMenu?.MakeCurrent(); },
                OnPlayModeChange = delegate(PlayMode m) { PlayMode.Value = m; },
            }).Preload(this, t =>
            {
                PlayMode.ValueChanged += delegate { Toolbar.SetGameMode(PlayMode.Value); };
                PlayMode.TriggerChange();
                overlayContent.Add(Toolbar);
            });

            options.StateChanged += delegate
            {
                switch (options.State)
                {
                case Visibility.Hidden:
                    intro.MoveToX(0, OptionsOverlay.TRANSITION_LENGTH, EasingTypes.OutQuint);
                    break;

                case Visibility.Visible:
                    intro.MoveToX(OptionsOverlay.SIDEBAR_WIDTH / 2, OptionsOverlay.TRANSITION_LENGTH, EasingTypes.OutQuint);
                    break;
                }
            };

            Cursor.Alpha = 0;
        }
Ejemplo n.º 7
0
        protected override void LoadComplete()
        {
            base.LoadComplete();

            // hook up notifications to components.
            BeatmapManager.PostNotification = n => notificationOverlay?.Post(n);
            BeatmapManager.GetStableStorage = GetStorageForStableInstall;

            AddRange(new Drawable[] {
                new VolumeControlReceptor
                {
                    RelativeSizeAxes = Axes.Both,
                    ActionRequested  = delegate(InputState state) { volume.Adjust(state); }
                },
                mainContent = new Container
                {
                    RelativeSizeAxes = Axes.Both,
                },
                volume         = new VolumeControl(),
                overlayContent = new Container {
                    RelativeSizeAxes = Axes.Both
                },
                new OnScreenDisplay(),
            });

            LoadComponentAsync(screenStack = new Loader(), d =>
            {
                screenStack.ModePushed += screenAdded;
                screenStack.Exited     += screenRemoved;
                mainContent.Add(screenStack);
            });

            //overlay elements
            LoadComponentAsync(direct = new DirectOverlay {
                Depth = -1
            }, mainContent.Add);
            LoadComponentAsync(social = new SocialOverlay {
                Depth = -1
            }, mainContent.Add);
            LoadComponentAsync(chat = new ChatOverlay {
                Depth = -1
            }, mainContent.Add);
            LoadComponentAsync(settings = new SettingsOverlay {
                Depth = -1
            }, overlayContent.Add);
            LoadComponentAsync(userProfile = new UserProfileOverlay {
                Depth = -2
            }, mainContent.Add);
            LoadComponentAsync(musicController = new MusicController
            {
                Depth    = -3,
                Position = new Vector2(0, Toolbar.HEIGHT),
                Anchor   = Anchor.TopRight,
                Origin   = Anchor.TopRight,
            }, overlayContent.Add);

            LoadComponentAsync(notificationOverlay = new NotificationOverlay
            {
                Depth  = -3,
                Anchor = Anchor.TopRight,
                Origin = Anchor.TopRight,
            }, overlayContent.Add);

            LoadComponentAsync(dialogOverlay = new DialogOverlay
            {
                Depth = -5,
            }, overlayContent.Add);

            Logger.NewEntry += entry =>
            {
                if (entry.Level < LogLevel.Important)
                {
                    return;
                }

                notificationOverlay.Post(new SimpleNotification
                {
                    Text = $@"{entry.Level}: {entry.Message}"
                });
            };

            dependencies.Cache(settings);
            dependencies.Cache(social);
            dependencies.Cache(chat);
            dependencies.Cache(userProfile);
            dependencies.Cache(musicController);
            dependencies.Cache(notificationOverlay);
            dependencies.Cache(dialogOverlay);

            // ensure both overlays aren't presented at the same time
            chat.StateChanged   += (container, state) => social.State = state == Visibility.Visible ? Visibility.Hidden : social.State;
            social.StateChanged += (container, state) => chat.State = state == Visibility.Visible ? Visibility.Hidden : chat.State;

            LoadComponentAsync(Toolbar = new Toolbar
            {
                Depth  = -4,
                OnHome = delegate
                {
                    //Create variable double step home exit
                    //If overlay was visible, home button will only close it
                    //Pressing home twice will go to main menu. This behavior should match Key.Escape
                    var overlayWasVisible = false;
                    foreach (var container in overlayContainers())
                    {
                        if (container.State == Visibility.Visible)
                        {
                            container.State   = Visibility.Hidden;
                            overlayWasVisible = true;
                        }
                    }
                    //Execute double exit if overlay was active
                    if (!overlayWasVisible)
                    {
                        intro?.ChildScreen?.MakeCurrent();
                    }
                },
            }, overlayContent.Add);

            settings.StateChanged += delegate
            {
                switch (settings.State)
                {
                case Visibility.Hidden:
                    intro.MoveToX(0, SettingsOverlay.TRANSITION_LENGTH, Easing.OutQuint);
                    break;

                case Visibility.Visible:
                    intro.MoveToX(SettingsOverlay.SIDEBAR_WIDTH / 2, SettingsOverlay.TRANSITION_LENGTH, Easing.OutQuint);
                    break;
                }
            };

            Cursor.State = Visibility.Hidden;
        }
Ejemplo n.º 8
0
        protected override void LoadComplete()
        {
            base.LoadComplete();

            // hook up notifications to components.
            BeatmapManager.PostNotification = n => notifications?.Post(n);
            BeatmapManager.GetStableStorage = GetStorageForStableInstall;

            AddRange(new Drawable[]
            {
                new VolumeControlReceptor
                {
                    RelativeSizeAxes = Axes.Both,
                    ActionRequested  = action => volume.Adjust(action)
                },
                mainContent = new Container {
                    RelativeSizeAxes = Axes.Both
                },
                overlayContent = new Container {
                    RelativeSizeAxes = Axes.Both, Depth = float.MinValue
                },
            });

            loadComponentSingleFile(screenStack = new Loader(), d =>
            {
                screenStack.ModePushed += screenAdded;
                screenStack.Exited     += screenRemoved;
                mainContent.Add(screenStack);
            });

            loadComponentSingleFile(Toolbar = new Toolbar
            {
                Depth  = -5,
                OnHome = delegate
                {
                    hideAllOverlays();
                    intro?.ChildScreen?.MakeCurrent();
                },
            }, overlayContent.Add);

            loadComponentSingleFile(volume = new VolumeControl(), Add);
            loadComponentSingleFile(new OnScreenDisplay(), Add);

            //overlay elements
            loadComponentSingleFile(direct = new DirectOverlay {
                Depth = -1
            }, mainContent.Add);
            loadComponentSingleFile(social = new SocialOverlay {
                Depth = -1
            }, mainContent.Add);
            loadComponentSingleFile(chat = new ChatOverlay {
                Depth = -1
            }, mainContent.Add);
            loadComponentSingleFile(settings = new MainSettings
            {
                GetToolbarHeight = () => ToolbarOffset,
                Depth            = -1
            }, overlayContent.Add);
            loadComponentSingleFile(userProfile = new UserProfileOverlay {
                Depth = -2
            }, mainContent.Add);
            loadComponentSingleFile(beatmapSetOverlay = new BeatmapSetOverlay {
                Depth = -3
            }, mainContent.Add);
            loadComponentSingleFile(musicController = new MusicController
            {
                Depth    = -4,
                Position = new Vector2(0, Toolbar.HEIGHT),
                Anchor   = Anchor.TopRight,
                Origin   = Anchor.TopRight,
            }, overlayContent.Add);

            loadComponentSingleFile(notifications = new NotificationOverlay
            {
                GetToolbarHeight = () => ToolbarOffset,
                Depth            = -4,
                Anchor           = Anchor.TopRight,
                Origin           = Anchor.TopRight,
            }, overlayContent.Add);

            loadComponentSingleFile(dialogOverlay = new DialogOverlay
            {
                Depth = -6,
            }, overlayContent.Add);

            Logger.NewEntry += entry =>
            {
                if (entry.Level < LogLevel.Important)
                {
                    return;
                }

                notifications.Post(new SimpleNotification
                {
                    Text = $@"{entry.Level}: {entry.Message}"
                });
            };

            dependencies.Cache(settings);
            dependencies.Cache(social);
            dependencies.Cache(direct);
            dependencies.Cache(chat);
            dependencies.Cache(userProfile);
            dependencies.Cache(musicController);
            dependencies.Cache(beatmapSetOverlay);
            dependencies.Cache(notifications);
            dependencies.Cache(dialogOverlay);

            // ensure only one of these overlays are open at once.
            var singleDisplayOverlays = new OverlayContainer[] { chat, social, direct };

            foreach (var overlay in singleDisplayOverlays)
            {
                overlay.StateChanged += state =>
                {
                    if (state == Visibility.Hidden)
                    {
                        return;
                    }

                    foreach (var c in singleDisplayOverlays)
                    {
                        if (c == overlay)
                        {
                            continue;
                        }
                        c.State = Visibility.Hidden;
                    }
                };
            }

            // eventually informational overlays should be displayed in a stack, but for now let's only allow one to stay open at a time.
            var informationalOverlays = new OverlayContainer[] { beatmapSetOverlay, userProfile };

            foreach (var overlay in informationalOverlays)
            {
                overlay.StateChanged += state =>
                {
                    if (state == Visibility.Hidden)
                    {
                        return;
                    }

                    foreach (var c in informationalOverlays)
                    {
                        if (c == overlay)
                        {
                            continue;
                        }
                        c.State = Visibility.Hidden;
                    }
                };
            }

            void updateScreenOffset()
            {
                float offset = 0;

                if (settings.State == Visibility.Visible)
                {
                    offset += ToolbarButton.WIDTH / 2;
                }
                if (notifications.State == Visibility.Visible)
                {
                    offset -= ToolbarButton.WIDTH / 2;
                }

                screenStack.MoveToX(offset, SettingsOverlay.TRANSITION_LENGTH, Easing.OutQuint);
            }

            settings.StateChanged      += _ => updateScreenOffset();
            notifications.StateChanged += _ => updateScreenOffset();

            Cursor.State = Visibility.Hidden;
        }