private void load(BeatmapManager manager, BeatmapSetOverlay beatmapOverlay, DialogOverlay overlay)
        {
            restoreHiddenRequested = s => s.Beatmaps.ForEach(manager.Restore);
            dialogOverlay          = overlay;
            if (beatmapOverlay != null)
            {
                viewDetails = beatmapOverlay.FetchAndShowBeatmapSet;
            }

            Children = new Drawable[]
            {
                new DelayedLoadUnloadWrapper(() =>
                                             new PanelBackground(manager.GetWorkingBeatmap(beatmapSet.Beatmaps.FirstOrDefault()))
                {
                    RelativeSizeAxes = Axes.Both,
                    OnLoadComplete   = d => d.FadeInFromZero(1000, Easing.OutQuint),
                }, 300, 5000
                                             ),
                new FillFlowContainer
                {
                    Direction = FillDirection.Vertical,
                    Padding   = new MarginPadding {
                        Top = 5, Left = 18, Right = 10, Bottom = 10
                    },
                    AutoSizeAxes = Axes.Both,
                    Children     = new Drawable[]
                    {
                        new OsuSpriteText
                        {
                            Font     = @"Exo2.0-BoldItalic",
                            Text     = new LocalisedString((beatmapSet.Metadata.TitleUnicode, beatmapSet.Metadata.Title)),
                            TextSize = 22,
                            Shadow   = true,
                        },
示例#2
0
        private void load(OsuColour colour, LocalisationEngine locale, BeatmapSetOverlay beatmapSetOverlay)
        {
            coloredBackground.Colour = underscoreLine.Colour = colour.Gray4;

            Stats.Add(new OsuSpriteText
            {
                Text     = $"accuracy: {Score.Accuracy:P2}",
                Anchor   = Anchor.TopRight,
                Origin   = Anchor.TopRight,
                Colour   = colour.GrayA,
                TextSize = 11,
                Font     = "Exo2.0-RegularItalic",
                Depth    = -1,
            });

            metadata.Add(new MetadataContainer(Score.Beatmap.Metadata.Title, Score.Beatmap.Metadata.Artist)
            {
                AutoSizeAxes = Axes.Both,
                Action       = () =>
                {
                    if (Score.Beatmap.OnlineBeatmapSetID.HasValue)
                    {
                        beatmapSetOverlay?.ShowBeatmapSet(Score.Beatmap.OnlineBeatmapSetID.Value);
                    }
                },
                Child = new FillFlowContainer
                {
                    AutoSizeAxes = Axes.Both,
                    Children     = new Drawable[]
                    {
                        new OsuSpriteText
                        {
                            Current = locale.GetUnicodePreference(
                                $"{Score.Beatmap.Metadata.TitleUnicode ?? Score.Beatmap.Metadata.Title} [{Score.Beatmap.Version}] ",
                                $"{Score.Beatmap.Metadata.Title ?? Score.Beatmap.Metadata.TitleUnicode} [{Score.Beatmap.Version}] "
                                ),
                            TextSize = 15,
                            Font     = "Exo2.0-SemiBoldItalic",
                        },
                        new OsuSpriteText
                        {
                            Current  = locale.GetUnicodePreference(Score.Beatmap.Metadata.ArtistUnicode, Score.Beatmap.Metadata.Artist),
                            TextSize = 12,
                            Padding  = new MarginPadding {
                                Top = 3
                            },
                            Font = "Exo2.0-RegularItalic",
                        },
                    },
                },
            });

            foreach (Mod mod in Score.Mods)
            {
                modsContainer.Add(new ModIcon(mod)
                {
                    Scale = new Vector2(0.5f)
                });
            }
        }
示例#3
0
        private void load(BeatmapManager beatmaps, OsuColour colours, BeatmapSetOverlay beatmapSetOverlay)
        {
            AddInternal(content = new Container
            {
                RelativeSizeAxes = Axes.Both,
                Masking          = true,
                EdgeEffect       = edgeEffectNormal,
                Children         = new[]
                {
                    CreateBackground(),
                    new DownloadProgressBar(SetInfo)
                    {
                        Anchor = Anchor.BottomLeft,
                        Origin = Anchor.BottomLeft,
                        Depth  = -1,
                    },
                }
            });

            Action = ViewBeatmap = () =>
            {
                Debug.Assert(SetInfo.OnlineBeatmapSetID != null);
                beatmapSetOverlay?.FetchAndShowBeatmapSet(SetInfo.OnlineBeatmapSetID.Value);
            };
        }
示例#4
0
        private void load(BeatmapManager beatmaps, OsuColour colours, BeatmapSetOverlay beatmapSetOverlay)
        {
            this.beatmaps = beatmaps;
            this.beatmapSetOverlay = beatmapSetOverlay;
            this.colours = colours;

            AddInternal(content = new Container
            {
                RelativeSizeAxes = Axes.Both,
                Masking = true,
                EdgeEffect = edgeEffectNormal,
                Children = new[]
                {
                    CreateBackground(),
                    progressBar = new ProgressBar
                    {
                        Anchor = Anchor.BottomLeft,
                        Origin = Anchor.BottomLeft,
                        Height = 0,
                        Alpha = 0,
                        BackgroundColour = Color4.Black.Opacity(0.7f),
                        FillColour = colours.Blue,
                        Depth = -1,
                    },
                }
            });

            var downloadRequest = beatmaps.GetExistingDownload(SetInfo);

            if (downloadRequest != null)
                attachDownload(downloadRequest);

            beatmaps.BeatmapDownloadBegan += attachDownload;
            beatmaps.ItemAdded += setAdded;
        }
示例#5
0
        private void load(BeatmapSetOverlay beatmapSetOverlay)
        {
            Action = () =>
            {
                if (beatmap.OnlineBeatmapID != null)
                {
                    beatmapSetOverlay?.FetchAndShowBeatmap(beatmap.OnlineBeatmapID.Value);
                }
                else if (beatmap.BeatmapSet?.OnlineBeatmapSetID != null)
                {
                    beatmapSetOverlay?.FetchAndShowBeatmapSet(beatmap.BeatmapSet.OnlineBeatmapSetID.Value);
                }
            };

            Child = new FillFlowContainer
            {
                AutoSizeAxes = Axes.Both,
                Children     = new Drawable[]
                {
                    new OsuSpriteText
                    {
                        Text = new LocalisedString(($"{beatmap.Metadata.TitleUnicode ?? beatmap.Metadata.Title} [{beatmap.Version}] ",
                                                    $"{beatmap.Metadata.Title ?? beatmap.Metadata.TitleUnicode} [{beatmap.Version}] ")),
                        TextSize = 15,
                        Font     = "Exo2.0-SemiBoldItalic",
                    },
示例#6
0
        private void load(LocalisationEngine localisation, BeatmapManager manager, BeatmapSetOverlay beatmapOverlay, DialogOverlay overlay)
        {
            if (localisation == null)
            {
                throw new ArgumentNullException(nameof(localisation));
            }

            restoreHiddenRequested = s => s.Beatmaps.ForEach(manager.Restore);
            dialogOverlay          = overlay;
            if (beatmapOverlay != null)
            {
                viewDetails = beatmapOverlay.FetchAndShowBeatmapSet;
            }

            Children = new Drawable[]
            {
                new DelayedLoadUnloadWrapper(() =>
                                             new PanelBackground(manager.GetWorkingBeatmap(beatmapSet.Beatmaps.FirstOrDefault()))
                {
                    RelativeSizeAxes = Axes.Both,
                    OnLoadComplete   = d => d.FadeInFromZero(1000, Easing.OutQuint),
                }, 300, 5000
                                             ),
                new FillFlowContainer
                {
                    Direction = FillDirection.Vertical,
                    Padding   = new MarginPadding {
                        Top = 5, Left = 18, Right = 10, Bottom = 10
                    },
                    AutoSizeAxes = Axes.Both,
                    Children     = new Drawable[]
                    {
                        new OsuSpriteText
                        {
                            Font     = @"Exo2.0-BoldItalic",
                            Current  = localisation.GetUnicodePreference(beatmapSet.Metadata.TitleUnicode, beatmapSet.Metadata.Title),
                            TextSize = 22,
                            Shadow   = true,
                        },
                        new OsuSpriteText
                        {
                            Font     = @"Exo2.0-SemiBoldItalic",
                            Current  = localisation.GetUnicodePreference(beatmapSet.Metadata.ArtistUnicode, beatmapSet.Metadata.Artist),
                            TextSize = 17,
                            Shadow   = true,
                        },
                        new FillFlowContainer <FilterableDifficultyIcon>
                        {
                            Margin = new MarginPadding {
                                Top = 5
                            },
                            AutoSizeAxes = Axes.Both,
                            Children     = ((CarouselBeatmapSet)Item).Beatmaps.Select(b => new FilterableDifficultyIcon(b)).ToList()
                        }
                    }
                }
            };
        }
示例#7
0
        private void load(BeatmapSetOverlay beatmapOverlay)
        {
            restoreHiddenRequested = s => s.Beatmaps.ForEach(manager.Restore);

            if (beatmapOverlay != null)
            {
                viewDetails = beatmapOverlay.FetchAndShowBeatmapSet;
            }
        }
示例#8
0
        private void load(BeatmapSetOverlay beatmapSetOverlay)
        {
            Action = () =>
            {
                beatmapSetOverlay?.FetchAndShowBeatmap(beatmapInfo.OnlineID);
            };

            Child = new FillFlowContainer
            {
                AutoSizeAxes = Axes.Both,
                Children     = CreateText(beatmapInfo),
            };
        }
示例#9
0
        private void load(BeatmapSetOverlay beatmapOverlay)
        {
            restoreHiddenRequested = s =>
            {
                foreach (var b in s.Beatmaps)
                {
                    manager.Restore(b);
                }
            };

            if (beatmapOverlay != null)
            {
                viewDetails = beatmapOverlay.FetchAndShowBeatmapSet;
            }
        }
示例#10
0
        private void load(BeatmapSetOverlay beatmapSetOverlay)
        {
            Action = () =>
            {
                if (beatmap.OnlineBeatmapID != null)
                {
                    beatmapSetOverlay?.FetchAndShowBeatmap(beatmap.OnlineBeatmapID.Value);
                }
                else if (beatmap.BeatmapSet?.OnlineBeatmapSetID != null)
                {
                    beatmapSetOverlay?.FetchAndShowBeatmapSet(beatmap.BeatmapSet.OnlineBeatmapSetID.Value);
                }
            };

            Child = new FillFlowContainer
            {
                AutoSizeAxes = Axes.Both,
                Children     = CreateText(beatmap),
            };
        }
示例#11
0
文件: DirectPanel.cs 项目: binn/osu
        private void load(APIAccess api, BeatmapManager beatmaps, OsuColour colours, NotificationOverlay notifications, BeatmapSetOverlay beatmapSetOverlay)
        {
            this.api               = api;
            this.beatmaps          = beatmaps;
            this.notifications     = notifications;
            this.beatmapSetOverlay = beatmapSetOverlay;

            AddInternal(content = new Container
            {
                RelativeSizeAxes = Axes.Both,
                Masking          = true,
                EdgeEffect       = edgeEffectNormal,
                Children         = new[]
                {
                    // temporary blackness until the actual background loads.
                    BlackBackground = new Box
                    {
                        RelativeSizeAxes = Axes.Both,
                        Colour           = Color4.Black,
                    },
                    CreateBackground(),
                    progressBar = new ProgressBar
                    {
                        Anchor           = Anchor.BottomLeft,
                        Origin           = Anchor.BottomLeft,
                        Height           = 0,
                        Alpha            = 0,
                        BackgroundColour = Color4.Black.Opacity(0.7f),
                        FillColour       = colours.Blue,
                        Depth            = -1,
                    },
                }
            });

            var downloadRequest = beatmaps.GetExistingDownload(SetInfo);

            if (downloadRequest != null)
            {
                attachDownload(downloadRequest);
            }
        }
示例#12
0
        private void load(BeatmapManager beatmaps, OsuColour colours, BeatmapSetOverlay beatmapSetOverlay)
        {
            this.beatmapSetOverlay = beatmapSetOverlay;

            AddInternal(content = new Container
            {
                RelativeSizeAxes = Axes.Both,
                Masking          = true,
                EdgeEffect       = edgeEffectNormal,
                Children         = new[]
                {
                    CreateBackground(),
                    new DownloadProgressBar(SetInfo)
                    {
                        Anchor = Anchor.BottomLeft,
                        Origin = Anchor.BottomLeft,
                        Depth  = -1,
                    },
                }
            });
        }
示例#13
0
        private void load(LocalisationEngine locale, BeatmapSetOverlay beatmapSetOverlay)
        {
            Action = () =>
            {
                if (beatmap.OnlineBeatmapID != null)
                {
                    beatmapSetOverlay?.FetchAndShowBeatmap(beatmap.OnlineBeatmapID.Value);
                }
                else if (beatmap.BeatmapSet?.OnlineBeatmapSetID != null)
                {
                    beatmapSetOverlay?.FetchAndShowBeatmapSet(beatmap.BeatmapSet.OnlineBeatmapSetID.Value);
                }
            };

            Child = new FillFlowContainer
            {
                AutoSizeAxes = Axes.Both,
                Children     = new Drawable[]
                {
                    new OsuSpriteText
                    {
                        Current = locale.GetUnicodePreference(
                            $"{beatmap.Metadata.TitleUnicode ?? beatmap.Metadata.Title} [{beatmap.Version}] ",
                            $"{beatmap.Metadata.Title ?? beatmap.Metadata.TitleUnicode} [{beatmap.Version}] "
                            ),
                        TextSize = 15,
                        Font     = "Exo2.0-SemiBoldItalic",
                    },
                    new OsuSpriteText
                    {
                        Current  = locale.GetUnicodePreference(beatmap.Metadata.ArtistUnicode, beatmap.Metadata.Artist),
                        TextSize = 12,
                        Padding  = new MarginPadding {
                            Top = 3
                        },
                        Font = "Exo2.0-RegularItalic",
                    },
                },
            };
        }
示例#14
0
        private void load(BeatmapManager manager, BeatmapSetOverlay beatmapOverlay)
        {
            restoreHiddenRequested = s => s.Beatmaps.ForEach(manager.Restore);

            if (beatmapOverlay != null)
            {
                viewDetails = beatmapOverlay.FetchAndShowBeatmapSet;
            }

            Children = new Drawable[]
            {
                new DelayedLoadUnloadWrapper(() =>
                {
                    var background = new PanelBackground(manager.GetWorkingBeatmap(beatmapSet.Beatmaps.FirstOrDefault()))
                    {
                        RelativeSizeAxes = Axes.Both,
                    };

                    background.OnLoadComplete += d => d.FadeInFromZero(1000, Easing.OutQuint);

                    return(background);
                }, 300, 5000
                                             ),
                new FillFlowContainer
                {
                    Direction = FillDirection.Vertical,
                    Padding   = new MarginPadding {
                        Top = 5, Left = 18, Right = 10, Bottom = 10
                    },
                    AutoSizeAxes = Axes.Both,
                    Children     = new Drawable[]
                    {
                        new OsuSpriteText
                        {
                            Text   = new LocalisedString((beatmapSet.Metadata.TitleUnicode, beatmapSet.Metadata.Title)),
                            Font   = OsuFont.GetFont(weight: FontWeight.Bold, size: 22, italics: true),
                            Shadow = true,
                        },
示例#15
0
        private void load(OsuColour colour, LocalisationEngine locale, BeatmapSetOverlay beatmapSetOverlay)
        {
            stats.Add(new OsuSpriteText
            {
                Text     = $"{Math.Round(score.PP ?? 0)}pp",
                Anchor   = Anchor.TopRight,
                Origin   = Anchor.TopRight,
                TextSize = 18,
                Font     = "Exo2.0-BoldItalic",
            });

            if (weight.HasValue)
            {
                stats.Add(new OsuSpriteText
                {
                    Text     = $"weighted: {Math.Round(score.PP * weight ?? 0)}pp ({weight.Value.ToString("0%", CultureInfo.CurrentCulture)})",
                    Anchor   = Anchor.TopRight,
                    Origin   = Anchor.TopRight,
                    Colour   = colour.GrayA,
                    TextSize = 11,
                    Font     = "Exo2.0-RegularItalic",
                });
            }

            stats.Add(new OsuSpriteText
            {
                Text     = "accuracy: " + score.Accuracy.ToString("0.00%"),
                Anchor   = Anchor.TopRight,
                Origin   = Anchor.TopRight,
                Colour   = colour.GrayA,
                TextSize = 11,
                Font     = "Exo2.0-RegularItalic",
            });

            metadata.Add(new OsuHoverContainer
            {
                AutoSizeAxes = Axes.Both,
                Action       = () =>
                {
                    if (score.Beatmap.OnlineBeatmapSetID.HasValue)
                    {
                        beatmapSetOverlay.ShowBeatmapSet(score.Beatmap.OnlineBeatmapSetID.Value);
                    }
                },
                Child = new FillFlowContainer
                {
                    AutoSizeAxes = Axes.Both,
                    Children     = new Drawable[]
                    {
                        new OsuSpriteText
                        {
                            Current = locale.GetUnicodePreference(
                                $"{score.Beatmap.Metadata.TitleUnicode ?? score.Beatmap.Metadata.Title} [{score.Beatmap.Version}] ",
                                $"{score.Beatmap.Metadata.Title ?? score.Beatmap.Metadata.TitleUnicode} [{score.Beatmap.Version}] "
                                ),
                            TextSize = 15,
                            Font     = "Exo2.0-SemiBoldItalic",
                        },
                        new OsuSpriteText
                        {
                            Current  = locale.GetUnicodePreference(score.Beatmap.Metadata.ArtistUnicode, score.Beatmap.Metadata.Artist),
                            TextSize = 12,
                            Padding  = new MarginPadding {
                                Top = 3
                            },
                            Font = "Exo2.0-RegularItalic",
                        },
                    },
                },
            });

            foreach (Mod mod in score.Mods)
            {
                modContainer.Add(new ModIcon(mod)
                {
                    AutoSizeAxes = Axes.Both,
                    Scale        = new Vector2(0.5f),
                });
            }
        }
示例#16
0
        protected override void LoadComplete()
        {
            // this needs to be cached before base.LoadComplete as it is used by MenuCursorContainer.
            dependencies.Cache(screenshotManager = new ScreenshotManager());

            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
            MenuCursorContainer.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 VolumeOverlay(), overlayContent.Add);
            loadComponentSingleFile(onscreenDisplay = new OnScreenDisplay(), Add);

            loadComponentSingleFile(screenshotManager, 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;
                    }
                };
            }

            var singleDisplaySideOverlays = new OverlayContainer[] { settings, notifications };

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

                    foreach (var c in singleDisplaySideOverlays)
                    {
                        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(AllowOpeningOverlays);

            HideOverlaysOnEnter.ValueChanged += hide =>
            {
                //central game screen change logic.
                if (hide)
                {
                    hideAllOverlays();
                    musicController.State = Visibility.Hidden;
                    Toolbar.State         = Visibility.Hidden;
                }
                else
                {
                    Toolbar.State = Visibility.Visible;
                }
            };
        }
 public TestSceneOnlineBeatmapSetOverlay()
 {
     Add(overlay = new BeatmapSetOverlay());
 }
示例#18
0
文件: OsuGame.cs 项目: uosJad/osu
        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;
        }
 public TestCaseBeatmapSetOverlay()
 {
     Add(overlay = new BeatmapSetOverlay());
 }
示例#20
0
        private void load(SongSelect songSelect, BeatmapManager manager, BeatmapSetOverlay beatmapOverlay)
        {
            this.beatmapOverlay = beatmapOverlay;

            if (songSelect != null)
            {
                startRequested = b => songSelect.FinaliseSelection(b);
                editRequested  = songSelect.Edit;
            }

            if (manager != null)
            {
                hideRequested = manager.Hide;
            }

            Children = new Drawable[]
            {
                background = new Box
                {
                    RelativeSizeAxes = Axes.Both,
                },
                triangles = new Triangles
                {
                    TriangleScale    = 2,
                    RelativeSizeAxes = Axes.Both,
                    ColourLight      = OsuColour.FromHex(@"3a7285"),
                    ColourDark       = OsuColour.FromHex(@"123744")
                },
                new FillFlowContainer
                {
                    Padding      = new MarginPadding(5),
                    Direction    = FillDirection.Horizontal,
                    AutoSizeAxes = Axes.Both,
                    Anchor       = Anchor.CentreLeft,
                    Origin       = Anchor.CentreLeft,
                    Children     = new Drawable[]
                    {
                        new DifficultyIcon(beatmap)
                        {
                            Scale = new Vector2(1.8f),
                        },
                        new FillFlowContainer
                        {
                            Padding = new MarginPadding {
                                Left = 5
                            },
                            Direction    = FillDirection.Vertical,
                            AutoSizeAxes = Axes.Both,
                            Children     = new Drawable[]
                            {
                                new FillFlowContainer
                                {
                                    Direction    = FillDirection.Horizontal,
                                    Spacing      = new Vector2(4, 0),
                                    AutoSizeAxes = Axes.Both,
                                    Children     = new[]
                                    {
                                        new OsuSpriteText
                                        {
                                            Font     = @"Exo2.0-Medium",
                                            Text     = beatmap.Version,
                                            TextSize = 20,
                                            Anchor   = Anchor.BottomLeft,
                                            Origin   = Anchor.BottomLeft
                                        },
                                        new OsuSpriteText
                                        {
                                            Font     = @"Exo2.0-Medium",
                                            Text     = "mapped by",
                                            TextSize = 16,
                                            Anchor   = Anchor.BottomLeft,
                                            Origin   = Anchor.BottomLeft
                                        },
                                        new OsuSpriteText
                                        {
                                            Font     = @"Exo2.0-MediumItalic",
                                            Text     = $"{(beatmap.Metadata ?? beatmap.BeatmapSet.Metadata).Author.Username}",
                                            TextSize = 16,
                                            Anchor   = Anchor.BottomLeft,
                                            Origin   = Anchor.BottomLeft
                                        },
                                    }
                                },
                                starCounter = new StarCounter
                                {
                                    CountStars = (float)beatmap.StarDifficulty,
                                    Scale      = new Vector2(0.8f),
                                }
                            }
                        }
                    }
                }
            };
        }
示例#21
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;
        }
示例#22
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
            MenuCursorContainer.CanShowCursor = currentScreen?.CursorVisible ?? false;

            // todo: all archive managers should be able to be looped here.
            SkinManager.PostNotification = n => notifications?.Post(n);
            SkinManager.GetStableStorage = GetStorageForStableInstall;

            BeatmapManager.PostNotification = n => notifications?.Post(n);
            BeatmapManager.GetStableStorage = GetStorageForStableInstall;

            BeatmapManager.PresentBeatmap = PresentBeatmap;

            AddRange(new Drawable[]
            {
                new VolumeControlReceptor
                {
                    RelativeSizeAxes      = Axes.Both,
                    ActionRequested       = action => volume.Adjust(action),
                    ScrollActionRequested = (action, amount, isPrecise) => volume.Adjust(action, amount, isPrecise),
                },
                screenContainer = new ScalingContainer(ScalingMode.ExcludeOverlays)
                {
                    RelativeSizeAxes = Axes.Both,
                },
                mainContent = new Container
                {
                    RelativeSizeAxes = Axes.Both,
                },
                overlayContent = new Container {
                    RelativeSizeAxes = Axes.Both, Depth = float.MinValue
                },
                idleTracker = new IdleTracker(6000)
            });

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

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

            loadComponentSingleFile(volume          = new VolumeOverlay(), overlayContent.Add);
            loadComponentSingleFile(onscreenDisplay = new OnScreenDisplay(), Add);

            loadComponentSingleFile(screenshotManager, Add);

            //overlay elements
            loadComponentSingleFile(direct = new DirectOverlay {
                Depth = -1
            }, mainContent.Add);
            loadComponentSingleFile(social = new SocialOverlay {
                Depth = -1
            }, mainContent.Add);
            loadComponentSingleFile(channelManager = new ChannelManager(), AddInternal);
            loadComponentSingleFile(chatOverlay    = 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    = -5,
                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(accountCreation = new AccountCreationOverlay
            {
                Depth = -6,
            }, overlayContent.Add);

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

            loadComponentSingleFile(externalLinkOpener = new ExternalLinkOpener
            {
                Depth = -8,
            }, overlayContent.Add);

            dependencies.Cache(idleTracker);
            dependencies.Cache(settings);
            dependencies.Cache(onscreenDisplay);
            dependencies.Cache(social);
            dependencies.Cache(direct);
            dependencies.Cache(chatOverlay);
            dependencies.Cache(channelManager);
            dependencies.Cache(userProfile);
            dependencies.Cache(musicController);
            dependencies.Cache(beatmapSetOverlay);
            dependencies.Cache(notifications);
            dependencies.Cache(dialogOverlay);
            dependencies.Cache(accountCreation);

            chatOverlay.StateChanged += state => channelManager.HighPollRate.Value = state == Visibility.Visible;

            Add(externalLinkOpener = new ExternalLinkOpener());

            var singleDisplaySideOverlays = new OverlayContainer[] { settings, notifications };

            overlays.AddRange(singleDisplaySideOverlays);

            foreach (var overlay in singleDisplaySideOverlays)
            {
                overlay.StateChanged += state =>
                {
                    if (state == Visibility.Hidden)
                    {
                        return;
                    }
                    singleDisplaySideOverlays.Where(o => o != overlay).ForEach(o => o.Hide());
                };
            }

            // 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 };

            overlays.AddRange(informationalOverlays);

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

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

            overlays.AddRange(singleDisplayOverlays);

            foreach (var overlay in singleDisplayOverlays)
            {
                overlay.StateChanged += state =>
                {
                    // informational overlays should be dismissed on a show or hide of a full overlay.
                    informationalOverlays.ForEach(o => o.Hide());

                    if (state == Visibility.Hidden)
                    {
                        return;
                    }

                    singleDisplayOverlays.Where(o => o != overlay).ForEach(o => o.Hide());
                };
            }

            OverlayActivationMode.ValueChanged += v =>
            {
                if (v != OverlayActivation.All)
                {
                    CloseAllOverlays();
                }
            };

            void updateScreenOffset()
            {
                float offset = 0;

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

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

            settings.StateChanged      += _ => updateScreenOffset();
            notifications.StateChanged += _ => updateScreenOffset();
        }
示例#23
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
            MenuCursorContainer.CanShowCursor = menuScreen?.CursorVisible ?? false;

            // todo: all archive managers should be able to be looped here.
            SkinManager.PostNotification = n => notifications?.Post(n);
            SkinManager.GetStableStorage = GetStorageForStableInstall;

            BeatmapManager.PostNotification = n => notifications?.Post(n);
            BeatmapManager.GetStableStorage = GetStorageForStableInstall;
            BeatmapManager.PresentImport    = items => PresentBeatmap(items.First());

            ScoreManager.PostNotification = n => notifications?.Post(n);
            ScoreManager.GetStableStorage = GetStorageForStableInstall;
            ScoreManager.PresentImport    = items => PresentScore(items.First());

            Container logoContainer;

            BackButton.Receptor receptor;

            dependencies.CacheAs(idleTracker = new GameIdleTracker(6000));

            AddRange(new Drawable[]
            {
                new VolumeControlReceptor
                {
                    RelativeSizeAxes      = Axes.Both,
                    ActionRequested       = action => volume.Adjust(action),
                    ScrollActionRequested = (action, amount, isPrecise) => volume.Adjust(action, amount, isPrecise),
                },
                screenContainer = new ScalingContainer(ScalingMode.ExcludeOverlays)
                {
                    RelativeSizeAxes = Axes.Both,
                    Children         = new Drawable[]
                    {
                        receptor    = new BackButton.Receptor(),
                        ScreenStack = new OsuScreenStack {
                            RelativeSizeAxes = Axes.Both
                        },
                        BackButton = new BackButton(receptor)
                        {
                            Anchor = Anchor.BottomLeft,
                            Origin = Anchor.BottomLeft,
                            Action = () =>
                            {
                                if ((ScreenStack.CurrentScreen as IOsuScreen)?.AllowBackButton == true)
                                {
                                    ScreenStack.Exit();
                                }
                            }
                        },
                        logoContainer = new Container {
                            RelativeSizeAxes = Axes.Both
                        },
                    }
                },
                overlayContent = new Container {
                    RelativeSizeAxes = Axes.Both
                },
                rightFloatingOverlayContent = new Container {
                    RelativeSizeAxes = Axes.Both
                },
                leftFloatingOverlayContent = new Container {
                    RelativeSizeAxes = Axes.Both
                },
                topMostOverlayContent = new Container {
                    RelativeSizeAxes = Axes.Both
                },
                idleTracker
            });

            ScreenStack.ScreenPushed += screenPushed;
            ScreenStack.ScreenExited += screenExited;

            loadComponentSingleFile(osuLogo, logo =>
            {
                logoContainer.Add(logo);

                // Loader has to be created after the logo has finished loading as Loader performs logo transformations on entering.
                ScreenStack.Push(CreateLoader().With(l => l.RelativeSizeAxes = Axes.Both));
            });

            loadComponentSingleFile(Toolbar = new Toolbar
            {
                OnHome = delegate
                {
                    CloseAllOverlays(false);
                    menuScreen?.MakeCurrent();
                },
            }, d =>
            {
                topMostOverlayContent.Add(d);
                toolbarElements.Add(d);
            });

            loadComponentSingleFile(volume = new VolumeOverlay(), leftFloatingOverlayContent.Add, true);

            loadComponentSingleFile(new OnScreenDisplay(), Add, true);

            loadComponentSingleFile(musicController = new MusicController(), Add, true);

            loadComponentSingleFile(notifications = new NotificationOverlay
            {
                GetToolbarHeight = () => ToolbarOffset,
                Anchor           = Anchor.TopRight,
                Origin           = Anchor.TopRight,
            }, rightFloatingOverlayContent.Add, true);

            loadComponentSingleFile(screenshotManager, Add);

            //overlay elements
            loadComponentSingleFile(direct         = new DirectOverlay(), overlayContent.Add, true);
            loadComponentSingleFile(social         = new SocialOverlay(), overlayContent.Add, true);
            loadComponentSingleFile(channelManager = new ChannelManager(), AddInternal, true);
            loadComponentSingleFile(chatOverlay    = new ChatOverlay(), overlayContent.Add, true);
            loadComponentSingleFile(Settings       = new SettingsOverlay {
                GetToolbarHeight = () => ToolbarOffset
            }, leftFloatingOverlayContent.Add, true);
            var changelogOverlay = loadComponentSingleFile(new ChangelogOverlay(), overlayContent.Add, true);

            loadComponentSingleFile(userProfile       = new UserProfileOverlay(), overlayContent.Add, true);
            loadComponentSingleFile(beatmapSetOverlay = new BeatmapSetOverlay(), overlayContent.Add, true);

            loadComponentSingleFile(new LoginOverlay
            {
                GetToolbarHeight = () => ToolbarOffset,
                Anchor           = Anchor.TopRight,
                Origin           = Anchor.TopRight,
            }, rightFloatingOverlayContent.Add, true);

            loadComponentSingleFile(new NowPlayingOverlay
            {
                GetToolbarHeight = () => ToolbarOffset,
                Anchor           = Anchor.TopRight,
                Origin           = Anchor.TopRight,
            }, d =>
            {
                rightFloatingOverlayContent.Add(d);
                toolbarElements.Add(d);
            }, true);

            loadComponentSingleFile(new AccountCreationOverlay(), topMostOverlayContent.Add, true);
            loadComponentSingleFile(new DialogOverlay(), topMostOverlayContent.Add, true);
            loadComponentSingleFile(externalLinkOpener = new ExternalLinkOpener(), topMostOverlayContent.Add);

            chatOverlay.State.ValueChanged += state => channelManager.HighPollRate.Value = state.NewValue == Visibility.Visible;

            Add(externalLinkOpener = new ExternalLinkOpener());

            var singleDisplaySideOverlays = new OverlayContainer[] { Settings, notifications };

            overlays.AddRange(singleDisplaySideOverlays);

            foreach (var overlay in singleDisplaySideOverlays)
            {
                overlay.State.ValueChanged += state =>
                {
                    if (state.NewValue == Visibility.Hidden)
                    {
                        return;
                    }

                    singleDisplaySideOverlays.Where(o => o != overlay).ForEach(o => o.Hide());
                };
            }

            // 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 };

            overlays.AddRange(informationalOverlays);

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

                    informationalOverlays.Where(o => o != overlay).ForEach(o => o.Hide());
                };
            }

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

            overlays.AddRange(singleDisplayOverlays);

            foreach (var overlay in singleDisplayOverlays)
            {
                overlay.State.ValueChanged += state =>
                {
                    // informational overlays should be dismissed on a show or hide of a full overlay.
                    informationalOverlays.ForEach(o => o.Hide());

                    if (state.NewValue == Visibility.Hidden)
                    {
                        return;
                    }

                    singleDisplayOverlays.Where(o => o != overlay).ForEach(o => o.Hide());
                };
            }

            OverlayActivationMode.ValueChanged += mode =>
            {
                if (mode.NewValue != OverlayActivation.All)
                {
                    CloseAllOverlays();
                }
            };

            void updateScreenOffset()
            {
                float offset = 0;

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

                screenContainer.MoveToX(offset, SettingsPanel.TRANSITION_LENGTH, Easing.OutQuint);
            }

            Settings.State.ValueChanged      += _ => updateScreenOffset();
            notifications.State.ValueChanged += _ => updateScreenOffset();
        }