Beispiel #1
0
        protected override void LoadComplete()
        {
            base.LoadComplete();

            Children = new Drawable[]
            {
                isActiveBox = new Box
                {
                    Colour           = Color4.Black,
                    Width            = 0.5f,
                    RelativeSizeAxes = Axes.Both,
                },
                cursorInWindowBox = new Box
                {
                    Colour           = Color4.Black,
                    RelativeSizeAxes = Axes.Both,
                    Width            = 0.5f,
                    Anchor           = Anchor.TopRight,
                    Origin           = Anchor.TopRight,
                },
            };

            isActive.BindValueChanged(active => isActiveBox.Colour = active.NewValue ? Color4.Green : Color4.Red, true);
            cursorInWindow?.BindValueChanged(active => cursorInWindowBox.Colour = active.NewValue ? Color4.Green : Color4.Red, true);
        }
        protected override void LoadComplete()
        {
            base.LoadComplete();

            Direction.BindValueChanged(OnDirectionChanged, true);
        }
Beispiel #3
0
        private void load(IScrollingInfo scrollingInfo)
        {
            const float angle_variance = 15; // should be less than 45
            const float roundness      = 80;
            const float initial_height = 10;

            var colour = Interpolation.ValueAt(0.4f, column.AccentColour, Color4.White, 0, 1);

            InternalChildren = new Drawable[]
            {
                largeFaint = new CircularContainer
                {
                    Anchor           = Anchor.Centre,
                    Origin           = Anchor.Centre,
                    RelativeSizeAxes = Axes.Both,
                    Masking          = true,
                    // we want our size to be very small so the glow dominates it.
                    Size       = new Vector2(default_large_faint_size),
                    Blending   = BlendingParameters.Additive,
                    EdgeEffect = new EdgeEffectParameters
                    {
                        Type      = EdgeEffectType.Glow,
                        Colour    = Interpolation.ValueAt(0.1f, column.AccentColour, Color4.White, 0, 1).Opacity(0.3f),
                        Roundness = 160,
                        Radius    = 200,
                    },
                },
                mainGlow1 = new CircularContainer
                {
                    Anchor           = Anchor.Centre,
                    Origin           = Anchor.Centre,
                    RelativeSizeAxes = Axes.Both,
                    Masking          = true,
                    Blending         = BlendingParameters.Additive,
                    EdgeEffect       = new EdgeEffectParameters
                    {
                        Type      = EdgeEffectType.Glow,
                        Colour    = Interpolation.ValueAt(0.6f, column.AccentColour, Color4.White, 0, 1),
                        Roundness = 20,
                        Radius    = 50,
                    },
                },
                new CircularContainer
                {
                    Anchor           = Anchor.Centre,
                    Origin           = Anchor.Centre,
                    RelativeSizeAxes = Axes.Both,
                    Masking          = true,
                    Size             = new Vector2(0.01f, initial_height),
                    Blending         = BlendingParameters.Additive,
                    Rotation         = RNG.NextSingle(-angle_variance, angle_variance),
                    EdgeEffect       = new EdgeEffectParameters
                    {
                        Type      = EdgeEffectType.Glow,
                        Colour    = colour,
                        Roundness = roundness,
                        Radius    = 40,
                    },
                },
                new CircularContainer
                {
                    Anchor           = Anchor.Centre,
                    Origin           = Anchor.Centre,
                    RelativeSizeAxes = Axes.Both,
                    Masking          = true,
                    Size             = new Vector2(0.01f, initial_height),
                    Blending         = BlendingParameters.Additive,
                    Rotation         = RNG.NextSingle(-angle_variance, angle_variance),
                    EdgeEffect       = new EdgeEffectParameters
                    {
                        Type      = EdgeEffectType.Glow,
                        Colour    = colour,
                        Roundness = roundness,
                        Radius    = 40,
                    },
                }
            };

            direction.BindTo(scrollingInfo.Direction);
            direction.BindValueChanged(onDirectionChanged, true);
        }
        public void TestPauseResume(ExecutionMode threadMode)
        {
            var gameCreated = new ManualResetEventSlim();

            IBindable <GameThreadState> updateThreadState = null;

            var task = Task.Factory.StartNew(() =>
            {
                using (host = new ExecutionModeGameHost(@"host", threadMode))
                {
                    game = new TestTestGame();
                    gameCreated.Set();
                    host.Run(game);
                }
            }, TaskCreationOptions.LongRunning);

            Assert.IsTrue(gameCreated.Wait(timeout));
            Assert.IsTrue(game.BecameAlive.Wait(timeout));

            // check scheduling is working before suspend
            var completed = new ManualResetEventSlim();

            game.Schedule(() =>
            {
                updateThreadState = host.UpdateThread.State.GetBoundCopy();
                updateThreadState.BindValueChanged(state =>
                {
                    if (state.NewValue != GameThreadState.Starting)
                    {
                        Assert.IsTrue(ThreadSafety.IsUpdateThread);
                    }
                });
                completed.Set();
            });

            Assert.IsTrue(completed.Wait(timeout / 10));
            Assert.AreEqual(GameThreadState.Running, updateThreadState.Value);

            host.Suspend();

            // in single-threaded execution, the main thread may already be in the process of updating one last time.
            int gameUpdates = 0;

            game.Scheduler.AddDelayed(() => ++ gameUpdates, 0, true);
            Assert.That(() => gameUpdates, Is.LessThan(2).After(timeout / 10));
            Assert.AreEqual(GameThreadState.Paused, updateThreadState.Value);

            // check that scheduler doesn't process while suspended..
            completed.Reset();
            game.Schedule(() => completed.Set());
            Assert.IsFalse(completed.Wait(timeout / 10));

            // ..and does after resume.
            host.Resume();
            Assert.IsTrue(completed.Wait(timeout / 10));
            Assert.AreEqual(GameThreadState.Running, updateThreadState.Value);

            game.Exit();
            Assert.IsTrue(task.Wait(timeout));
            Assert.AreEqual(GameThreadState.Exited, updateThreadState.Value);
        }
Beispiel #5
0
        private void load(ISkinSource skin, IScrollingInfo scrollingInfo)
        {
            string lightImage = skin.GetManiaSkinConfig <string>(LegacyManiaSkinConfigurationLookups.LightImage)?.Value
                                ?? "mania-stage-light";

            float leftLineWidth = GetColumnSkinConfig <float>(skin, LegacyManiaSkinConfigurationLookups.LeftLineWidth)
                                  ?.Value ?? 1;
            float rightLineWidth = GetColumnSkinConfig <float>(skin, LegacyManiaSkinConfigurationLookups.RightLineWidth)
                                   ?.Value ?? 1;

            bool hasLeftLine  = leftLineWidth > 0;
            bool hasRightLine = rightLineWidth > 0 && skin.GetConfig <LegacySkinConfiguration.LegacySetting, decimal>(LegacySkinConfiguration.LegacySetting.Version)?.Value >= 2.4m ||
                                isLastColumn;

            hitPosition = GetColumnSkinConfig <float>(skin, LegacyManiaSkinConfigurationLookups.HitPosition)?.Value
                          ?? Stage.HIT_TARGET_POSITION;

            float lightPosition = GetColumnSkinConfig <float>(skin, LegacyManiaSkinConfigurationLookups.LightPosition)?.Value
                                  ?? 0;

            Color4 lineColour = GetColumnSkinConfig <Color4>(skin, LegacyManiaSkinConfigurationLookups.ColumnLineColour)?.Value
                                ?? Color4.White;

            Color4 backgroundColour = GetColumnSkinConfig <Color4>(skin, LegacyManiaSkinConfigurationLookups.ColumnBackgroundColour)?.Value
                                      ?? Color4.Black;

            Color4 lightColour = GetColumnSkinConfig <Color4>(skin, LegacyManiaSkinConfigurationLookups.ColumnLightColour)?.Value
                                 ?? Color4.White;

            InternalChildren = new Drawable[]
            {
                new Box
                {
                    RelativeSizeAxes = Axes.Both,
                    Colour           = backgroundColour
                },
                borderLineContainer = new Container
                {
                    RelativeSizeAxes = Axes.Both,
                    Children         = new[]
                    {
                        new Box
                        {
                            RelativeSizeAxes = Axes.Y,
                            Width            = leftLineWidth,
                            Scale            = new Vector2(0.740f, 1),
                            Colour           = lineColour,
                            Alpha            = hasLeftLine ? 1 : 0
                        },
                        new Box
                        {
                            Anchor           = Anchor.TopRight,
                            Origin           = Anchor.TopRight,
                            RelativeSizeAxes = Axes.Y,
                            Width            = rightLineWidth,
                            Scale            = new Vector2(0.740f, 1),
                            Colour           = lineColour,
                            Alpha            = hasRightLine ? 1 : 0
                        }
                    }
                },
                lightContainer = new Container
                {
                    Origin           = Anchor.BottomCentre,
                    RelativeSizeAxes = Axes.Both,
                    Padding          = new MarginPadding {
                        Bottom = lightPosition
                    },
                    Child = light = new Sprite
                    {
                        Anchor           = Anchor.BottomCentre,
                        Origin           = Anchor.BottomCentre,
                        Colour           = lightColour,
                        Texture          = skin.GetTexture(lightImage),
                        RelativeSizeAxes = Axes.X,
                        Width            = 1,
                        Alpha            = 0
                    }
                }
            };

            direction.BindTo(scrollingInfo.Direction);
            direction.BindValueChanged(onDirectionChanged, true);
        }
Beispiel #6
0
 private void load(OsuColour colours)
 {
     positionBindable.BindValueChanged(pos => Position = pos.NewValue);
     positionBindable.BindTo(HitObject.PositionBindable);
 }
Beispiel #7
0
        private void load(IBindable <WorkingBeatmap> beatmap, OsuColour colours, OsuConfigManager config)
        {
            CentreMarker centreMarker;

            // We don't want the centre marker to scroll
            AddInternal(centreMarker = new CentreMarker());

            AddRange(new Drawable[]
            {
                controlPoints = new TimelineControlPointDisplay
                {
                    RelativeSizeAxes = Axes.X,
                    Height           = timeline_expanded_height,
                },
                mainContent = new Container
                {
                    RelativeSizeAxes = Axes.X,
                    Height           = timeline_height,
                    Depth            = float.MaxValue,
                    Children         = new[]
                    {
                        waveform = new WaveformGraph
                        {
                            RelativeSizeAxes = Axes.Both,
                            BaseColour       = colours.Blue.Opacity(0.2f),
                            LowColour        = colours.BlueLighter,
                            MidColour        = colours.BlueDark,
                            HighColour       = colours.BlueDarker,
                        },
                        centreMarker.CreateProxy(),
                        ticks = new TimelineTickDisplay(),
                        new Box
                        {
                            Name             = "zero marker",
                            RelativeSizeAxes = Axes.Y,
                            Width            = 2,
                            Origin           = Anchor.TopCentre,
                            Colour           = colours.YellowDarker,
                        },
                        userContent,
                    }
                },
            });

            waveformOpacity = config.GetBindable <float>(OsuSetting.EditorWaveformOpacity);

            Beatmap.BindTo(beatmap);
            Beatmap.BindValueChanged(b =>
            {
                waveform.Waveform = b.NewValue.Waveform;
                track             = b.NewValue.Track;

                // todo: i don't think this is safe, the track may not be loaded yet.
                if (track.Length > 0)
                {
                    MaxZoom = getZoomLevelForVisibleMilliseconds(500);
                    MinZoom = getZoomLevelForVisibleMilliseconds(10000);
                    Zoom    = getZoomLevelForVisibleMilliseconds(2000);
                }
            }, true);
        }
Beispiel #8
0
 private void load(IScrollingInfo scrollingInfo)
 {
     direction.BindTo(scrollingInfo.Direction);
     direction.BindValueChanged(onDirectionChanged, true);
 }
Beispiel #9
0
 public SliderTailCircle(Slider slider)
 {
     pathBindable.BindTo(slider.PathBindable);
     pathBindable.BindValueChanged(_ => Position = slider.EndPosition);
 }
Beispiel #10
0
        private void load(AudioManager audio, OsuConfigManager config, OsuGame game)
        {
            Mods.Value = base.Mods.Value.Select(m => m.CreateCopy()).ToArray();

            if (Beatmap.Value is DummyWorkingBeatmap)
            {
                return;
            }

            IBeatmap playableBeatmap = loadPlayableBeatmap();

            if (playableBeatmap == null)
            {
                return;
            }

            sampleRestart = audio.Samples.Get(@"Gameplay/restart");

            mouseWheelDisabled = config.GetBindable <bool>(OsuSetting.MouseDisableWheel);

            if (game != null)
            {
                LocalUserPlaying.BindTo(game.LocalUserPlaying);
            }

            DrawableRuleset = ruleset.CreateDrawableRulesetWith(playableBeatmap, Mods.Value);

            ScoreProcessor = ruleset.CreateScoreProcessor();
            ScoreProcessor.ApplyBeatmap(playableBeatmap);
            ScoreProcessor.Mods.BindTo(Mods);

            HealthProcessor = ruleset.CreateHealthProcessor(playableBeatmap.HitObjects[0].StartTime);
            HealthProcessor.ApplyBeatmap(playableBeatmap);

            if (!ScoreProcessor.Mode.Disabled)
            {
                config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode);
            }

            InternalChild = GameplayClockContainer = new GameplayClockContainer(Beatmap.Value, DrawableRuleset.GameplayStartTime);

            AddInternal(gameplayBeatmap  = new GameplayBeatmap(playableBeatmap));
            AddInternal(screenSuspension = new ScreenSuspensionHandler(GameplayClockContainer));

            dependencies.CacheAs(gameplayBeatmap);

            var beatmapSkinProvider = new BeatmapSkinProvidingContainer(Beatmap.Value.Skin);

            // the beatmapSkinProvider is used as the fallback source here to allow the ruleset-specific skin implementation
            // full access to all skin sources.
            var rulesetSkinProvider = new SkinProvidingContainer(ruleset.CreateLegacySkinProvider(beatmapSkinProvider, playableBeatmap));

            // load the skinning hierarchy first.
            // this is intentionally done in two stages to ensure things are in a loaded state before exposing the ruleset to skin sources.
            GameplayClockContainer.Add(beatmapSkinProvider.WithChild(rulesetSkinProvider));

            rulesetSkinProvider.AddRange(new[]
            {
                // underlay and gameplay should have access the to skinning sources.
                createUnderlayComponents(),
                createGameplayComponents(Beatmap.Value, playableBeatmap)
            });

            // also give the HUD a ruleset container to allow rulesets to potentially override HUD elements (used to disable combo counters etc.)
            // we may want to limit this in the future to disallow rulesets from outright replacing elements the user expects to be there.
            var hudRulesetContainer = new SkinProvidingContainer(ruleset.CreateLegacySkinProvider(beatmapSkinProvider, playableBeatmap));

            // add the overlay components as a separate step as they proxy some elements from the above underlay/gameplay components.
            GameplayClockContainer.Add(hudRulesetContainer.WithChild(createOverlayComponents(Beatmap.Value)));

            if (!DrawableRuleset.AllowGameplayOverlays)
            {
                HUDOverlay.ShowHud.Value    = false;
                HUDOverlay.ShowHud.Disabled = true;
                BreakOverlay.Hide();
                skipOverlay.Hide();
            }

            DrawableRuleset.IsPaused.BindValueChanged(paused =>
            {
                updateGameplayState();
                samplePlaybackDisabled.Value = paused.NewValue;
            });
            DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updateGameplayState());

            DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updatePauseOnFocusLostState(), true);

            // bind clock into components that require it
            DrawableRuleset.IsPaused.BindTo(GameplayClockContainer.IsPaused);

            DrawableRuleset.OnNewResult += r =>
            {
                HealthProcessor.ApplyResult(r);
                ScoreProcessor.ApplyResult(r);
                gameplayBeatmap.ApplyResult(r);
            };

            DrawableRuleset.OnRevertResult += r =>
            {
                HealthProcessor.RevertResult(r);
                ScoreProcessor.RevertResult(r);
            };

            // Bind the judgement processors to ourselves
            ScoreProcessor.HasCompleted.ValueChanged += updateCompletionState;
            HealthProcessor.Failed += onFail;

            foreach (var mod in Mods.Value.OfType <IApplicableToScoreProcessor>())
            {
                mod.ApplyToScoreProcessor(ScoreProcessor);
            }

            foreach (var mod in Mods.Value.OfType <IApplicableToHealthProcessor>())
            {
                mod.ApplyToHealthProcessor(HealthProcessor);
            }

            IsBreakTime.BindTo(breakTracker.IsBreakTime);
            IsBreakTime.BindValueChanged(onBreakTimeChanged, true);
        }
Beispiel #11
0
        private void load()
        {
            beatmaps.ItemAdded += beatmapAdded;

            Beatmap.BindValueChanged(updateBeatmap, true);
        }
Beispiel #12
0
 protected override void LoadComplete()
 {
     base.LoadComplete();
     DragActive.BindValueChanged(active => LayoutDuration = active.NewValue ? 200 : 0);
 }
Beispiel #13
0
 private void load()
 {
     isConnected.BindTo(client.IsConnected);
     isConnected.BindValueChanged(c => Scheduler.AddOnce(poll), true);
 }
Beispiel #14
0
        protected override void LoadComplete()
        {
            base.LoadComplete();

            accentColour.BindValueChanged(colour => colouredSprite.Colour = colour.NewValue, true);
        }
 private void load()
 {
     operationInProgress = ongoingOperationTracker.InProgress.GetBoundCopy();
     operationInProgress.BindValueChanged(_ => updateState());
 }
Beispiel #16
0
 private void load()
 {
     InternalChildren = new Drawable[]
     {
         new Box
         {
             RelativeSizeAxes = Axes.Both,
             Colour           = new Color4(106, 100, 104, 255),
         },
         new GridContainer
         {
             RelativeSizeAxes = Axes.Both,
             Content          = new[]
             {
                 new Drawable[]
                 {
                     //Listas de elementos
                     new Container
                     {
                         RelativeSizeAxes = Axes.Both,
                         Children         = new Drawable []
                         {
                             new Box
                             {
                                 RelativeSizeAxes = Axes.Both,
                                 Colour           = Color4.Gray,
                             },
                             new ProjectObjectManagerContainer <Card>
                             {
                                 Anchor = Anchor.TopLeft,
                                 Origin = Anchor.TopLeft,
                                 Height = 1 / 2f,
                             },
                             new ProjectObjectListingContainer <Tile>
                             {
                                 Anchor = Anchor.BottomLeft,
                                 Origin = Anchor.BottomLeft,
                                 Height = 1 / 2f,
                             },
                         },
                     },
                     new Container
                     {
                         RelativeSizeAxes = Axes.Both,
                         Children         = new Drawable[]
                         {
                             eventGraphicsContainer = new Container
                             {
                                 RelativeSizeAxes = Axes.Both,
                                 Children         = new Drawable[]
                                 {
                                     new Container
                                     {
                                         RelativeSizeAxes = Axes.Both,
                                         Padding          = new MarginPadding {
                                             Horizontal = 60, Vertical = 50
                                         },
                                         Child = new EventListing
                                         {
                                             RelativeSizeAxes = Axes.Both,
                                         },
                                     },
                                 },
                             },
                             noSelectionContainer = new Container
                             {
                                 RelativeSizeAxes = Axes.Both,
                                 Anchor           = Anchor.Centre,
                                 Origin           = Anchor.Centre,
                                 Child            = new SpriteText
                                 {
                                     Anchor = Anchor.Centre,
                                     Origin = Anchor.Centre,
                                     Text   = @"Selecciona un objeto con eventos para editarlo",
                                 },
                             },
                             eventEditOverlay,
                         },
                     },
                 },
             },
             ColumnDimensions = new[]
             {
                 new Dimension(GridSizeMode.Relative, 0.25f),
                 new Dimension(),
             },
         },
     };
     currentEditing.BindTo(editor.CurrentEditingElement);
     currentEditing.BindValueChanged(checkData, true);
 }
Beispiel #17
0
        private void load(AudioManager audio, OsuConfigManager config, OsuGameBase game)
        {
            Mods.Value = base.Mods.Value.Select(m => m.DeepClone()).ToArray();

            if (Beatmap.Value is DummyWorkingBeatmap)
            {
                return;
            }

            IBeatmap playableBeatmap = loadPlayableBeatmap();

            if (playableBeatmap == null)
            {
                return;
            }

            sampleRestart = audio.Samples.Get(@"Gameplay/restart");

            mouseWheelDisabled = config.GetBindable <bool>(OsuSetting.MouseDisableWheel);

            if (game != null)
            {
                gameActive.BindTo(game.IsActive);
            }

            if (game is OsuGame osuGame)
            {
                LocalUserPlaying.BindTo(osuGame.LocalUserPlaying);
            }

            DrawableRuleset = GameplayRuleset.CreateDrawableRulesetWith(playableBeatmap, Mods.Value);
            dependencies.CacheAs(DrawableRuleset);

            ScoreProcessor = GameplayRuleset.CreateScoreProcessor();
            ScoreProcessor.ApplyBeatmap(playableBeatmap);
            ScoreProcessor.Mods.BindTo(Mods);

            dependencies.CacheAs(ScoreProcessor);

            HealthProcessor = GameplayRuleset.CreateHealthProcessor(playableBeatmap.HitObjects[0].StartTime);
            HealthProcessor.ApplyBeatmap(playableBeatmap);

            dependencies.CacheAs(HealthProcessor);

            if (!ScoreProcessor.Mode.Disabled)
            {
                config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode);
            }

            InternalChild = GameplayClockContainer = CreateGameplayClockContainer(Beatmap.Value, DrawableRuleset.GameplayStartTime);

            AddInternal(GameplayBeatmap  = new GameplayBeatmap(playableBeatmap));
            AddInternal(screenSuspension = new ScreenSuspensionHandler(GameplayClockContainer));

            dependencies.CacheAs(GameplayBeatmap);

            var rulesetSkinProvider = new RulesetSkinProvidingContainer(GameplayRuleset, playableBeatmap, Beatmap.Value.Skin);

            // load the skinning hierarchy first.
            // this is intentionally done in two stages to ensure things are in a loaded state before exposing the ruleset to skin sources.
            GameplayClockContainer.Add(rulesetSkinProvider);

            rulesetSkinProvider.AddRange(new[]
            {
                // underlay and gameplay should have access to the skinning sources.
                createUnderlayComponents(),
                createGameplayComponents(Beatmap.Value, playableBeatmap)
            });

            // add the overlay components as a separate step as they proxy some elements from the above underlay/gameplay components.
            // also give the overlays the ruleset skin provider to allow rulesets to potentially override HUD elements (used to disable combo counters etc.)
            // we may want to limit this in the future to disallow rulesets from outright replacing elements the user expects to be there.
            rulesetSkinProvider.Add(createOverlayComponents(Beatmap.Value));

            if (!DrawableRuleset.AllowGameplayOverlays)
            {
                HUDOverlay.ShowHud.Value    = false;
                HUDOverlay.ShowHud.Disabled = true;
                BreakOverlay.Hide();
            }

            DrawableRuleset.FrameStableClock.WaitingOnFrames.BindValueChanged(waiting =>
            {
                if (waiting.NewValue)
                {
                    GameplayClockContainer.Stop();
                }
                else
                {
                    GameplayClockContainer.Start();
                }
            });

            DrawableRuleset.IsPaused.BindValueChanged(paused =>
            {
                updateGameplayState();
                updateSampleDisabledState();
            });

            DrawableRuleset.FrameStableClock.IsCatchingUp.BindValueChanged(_ => updateSampleDisabledState());

            DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updateGameplayState());

            // bind clock into components that require it
            DrawableRuleset.IsPaused.BindTo(GameplayClockContainer.IsPaused);

            DrawableRuleset.NewResult += r =>
            {
                HealthProcessor.ApplyResult(r);
                ScoreProcessor.ApplyResult(r);
                GameplayBeatmap.ApplyResult(r);
            };

            DrawableRuleset.RevertResult += r =>
            {
                HealthProcessor.RevertResult(r);
                ScoreProcessor.RevertResult(r);
            };

            DimmableStoryboard.HasStoryboardEnded.ValueChanged += storyboardEnded =>
            {
                if (storyboardEnded.NewValue)
                {
                    progressToResults(true);
                }
            };

            // Bind the judgement processors to ourselves
            ScoreProcessor.HasCompleted.BindValueChanged(scoreCompletionChanged);
            HealthProcessor.Failed += onFail;

            // Provide judgement processors to mods after they're loaded so that they're on the gameplay clock,
            // this is required for mods that apply transforms to these processors.
            ScoreProcessor.OnLoadComplete += _ =>
            {
                foreach (var mod in Mods.Value.OfType <IApplicableToScoreProcessor>())
                {
                    mod.ApplyToScoreProcessor(ScoreProcessor);
                }
            };

            HealthProcessor.OnLoadComplete += _ =>
            {
                foreach (var mod in Mods.Value.OfType <IApplicableToHealthProcessor>())
                {
                    mod.ApplyToHealthProcessor(HealthProcessor);
                }
            };

            IsBreakTime.BindTo(breakTracker.IsBreakTime);
            IsBreakTime.BindValueChanged(onBreakTimeChanged, true);
        }
Beispiel #18
0
        private void load(ProjectEditor editor)
        {
            InternalChildren = new Drawable[]
            {
                new Box
                {
                    RelativeSizeAxes = Axes.Both,
                    Colour           = new Colour4(106, 100, 104, 255),
                },
                new GridContainer
                {
                    RelativeSizeAxes = Axes.Both,
                    Content          = new[]
                    {
                        new Drawable[]
                        {
                            //Listas de elementos
                            new Container
                            {
                                RelativeSizeAxes = Axes.Both,
                                Children         = new Drawable[]
                                {
                                    new Box
                                    {
                                        RelativeSizeAxes = Axes.Both,
                                        Colour           = Colour4.Gray,
                                    },
                                    new ProjectObjectManagerContainer <Card>(true)
                                    {
                                        Anchor = Anchor.TopLeft,
                                        Origin = Anchor.TopLeft,
                                        Height = 1 / 3f,
                                    },
                                    new ProjectObjectManagerContainer <Token>(true)
                                    {
                                        Anchor = Anchor.CentreLeft,
                                        Origin = Anchor.CentreLeft,
                                        Height = 1 / 3f,
                                    },
                                    new ProjectObjectManagerContainer <Board>(true)
                                    {
                                        Anchor = Anchor.BottomLeft,
                                        Origin = Anchor.BottomLeft,
                                        Height = 1 / 3f,
                                    },
                                },
                            },
                            //Area de edición
                            new Container
                            {
                                RelativeSizeAxes = Axes.Both,
                                Children         = new Drawable[]
                                {
                                    activeEditContainer = new BasicScrollContainer
                                    {
                                        RelativeSizeAxes = Axes.Both,
                                        Child            = new FillFlowContainer
                                        {
                                            RelativeSizeAxes = Axes.X,
                                            AutoSizeAxes     = Axes.Y,
                                            Direction        = FillDirection.Vertical,
                                            Children         = new Drawable[]
                                            {
                                                new Container
                                                {
                                                    RelativeSizeAxes = Axes.X,
                                                    AutoSizeAxes     = Axes.Y,
                                                    Padding          = new MarginPadding {
                                                        Horizontal = 60, Vertical = 50
                                                    },
                                                    Children = new Drawable[]
                                                    {
                                                        visualEditor = new ElementVisualEditorContainer(),
                                                        new SpriteText
                                                        {
                                                            Anchor   = Anchor.TopRight,
                                                            Origin   = Anchor.TopRight,
                                                            Position = new Vector2(-675, 10),
                                                            Text     = @"Nombre:",
                                                        },
                                                        nameTextBox = new BasicTextBox
                                                        {
                                                            CommitOnFocusLost = true,
                                                            Anchor            = Anchor.TopRight,
                                                            Origin            = Anchor.TopRight,
                                                            Position          = new Vector2(-250, 0),
                                                            Height            = 35,
                                                            Width             = 400,
                                                        },
                                                        new SpriteText
                                                        {
                                                            Anchor   = Anchor.TopRight,
                                                            Origin   = Anchor.TopRight,
                                                            Position = new Vector2(-675, 80),
                                                            Text     = @"Descripción:",
                                                        },
                                                        descriptionTextBox = new BasicTextBox
                                                        {
                                                            CommitOnFocusLost = true,
                                                            Anchor            = Anchor.TopRight,
                                                            Origin            = Anchor.TopRight,
                                                            Position          = new Vector2(-250, 70),
                                                            Height            = 35,
                                                            Width             = 400,
                                                        },
                                                        new GamesToGoButton
                                                        {
                                                            Anchor = Anchor.TopRight,
                                                            Origin = Anchor.TopRight,
                                                            Height = 35,
                                                            Width  = 200,
                                                            Text   = @"Borrar Elemento",
                                                            Action = () => editor.DeleteElement(currentEditing.Value),
                                                        },
                                                    },
                                                },
                                                new Container
                                                {
                                                    RelativeSizeAxes = Axes.X,
                                                    AutoSizeAxes     = Axes.Y,
                                                    Children         = new Drawable[]
                                                    {
                                                        new FillFlowContainer
                                                        {
                                                            RelativeSizeAxes = Axes.Both,
                                                            Direction        = FillDirection.Full,
                                                            Spacing          = new Vector2(10),
                                                            Padding          = new MarginPadding {
                                                                Horizontal = 50
                                                            },
                                                            Children = new Drawable[]
                                                            {
                                                                elementSize = new VectorTextBoxContainer(4, false)
                                                                {
                                                                    TextX = @"Tamaño X:",
                                                                    TextY = @"Tamaño Y:",
                                                                },
                                                                elementOrientation = new LabeledDropdown <ElementOrientation>
                                                                {
                                                                    Text    = @"Orientación:",
                                                                    Element = new GamesToGoDropdown <ElementOrientation>
                                                                    {
                                                                        Width = 200,
                                                                    },
                                                                },
                                                                elementSideVisible = new LabeledDropdown <ElementSideVisible>
                                                                {
                                                                    Text    = @"Lado visible:",
                                                                    Element = new GamesToGoDropdown <ElementSideVisible>
                                                                    {
                                                                        Width = 200,
                                                                    },
                                                                },
                                                                elementPrivacy = new LabeledDropdown <ElementPrivacy>
                                                                {
                                                                    Text    = @"Privacidad:",
                                                                    Element = new GamesToGoDropdown <ElementPrivacy>
                                                                    {
                                                                        Width = 200,
                                                                    },
                                                                },
                                                                elementPosition = new VectorTextBoxContainer(4, true)
                                                                {
                                                                    TextX = @"Posición en X:",
                                                                    TextY = @"Posición en Y:",
                                                                },
                                                                elementArrangement = new VectorTextBoxContainer(4, true)
                                                                {
                                                                    TextX = @"Orden en X:",
                                                                    TextY = @"Orden en Y:",
                                                                },
                                                            },
                                                        },
                                                        elementSubElements = new Container
                                                        {
                                                            RelativeSizeAxes = Axes.X,
                                                            Width            = 1 / 3f,
                                                            Height           = 500,
                                                            Anchor           = Anchor.TopRight,
                                                            Origin           = Anchor.TopRight,
                                                            Child            = tilesManagerContainer = new BoardObjectManagerContainer(),
                                                        },
                                                    },
                                                },
                                            },
                                        },
                                    },
                                    tileOverlay,
                                    noSelectionContainer = new Container
                                    {
                                        RelativeSizeAxes = Axes.Both,
                                        Anchor           = Anchor.Centre,
                                        Origin           = Anchor.Centre,
                                        Child            = new SpriteText
                                        {
                                            Anchor = Anchor.Centre,
                                            Origin = Anchor.Centre,
                                            Text   = @"Selecciona un objeto para editarlo",
                                        },
                                    },
                                },
                            },
                        },
                    },
                    ColumnDimensions = new[]
                    {
                        new Dimension(GridSizeMode.Relative, 0.25f),
                        new Dimension(),
                    },
                },
            };
            currentEditing.BindTo(editor.CurrentEditingElement);
            currentEditing.BindValueChanged(checkData, true);

            nameTextBox.OnCommit += delegate
            {
                if (currentEditing.Value != null)
                {
                    currentEditing.Value.Name.Value = nameTextBox.Text;
                }
            };

            descriptionTextBox.OnCommit += delegate
            {
                if (currentEditing.Value != null)
                {
                    currentEditing.Value.Description.Value = descriptionTextBox.Text;
                }
            };

            elementPosition.Current.BindValueChanged(_ => visualEditor.UpdatePreview());
            elementOrientation.Current.BindValueChanged(_ => visualEditor.UpdatePreview());
            elementSideVisible.Current.BindValueChanged(_ => visualEditor.UpdatePreview());
            elementSize.Current.BindValueChanged(_ => visualEditor.UpdatePreview());
            tilesManagerContainer.ElementsAdded   = _ => visualEditor.UpdatePreview();
            tilesManagerContainer.ElementsRemoved = _ => visualEditor.UpdatePreview();
        }
        private void load(IAPIProvider api, BeatmapManager beatmaps)
        {
            FillFlowContainer textSprites;

            AddRangeInternal(new Drawable[]
            {
                shakeContainer = new ShakeContainer
                {
                    Depth            = -1,
                    RelativeSizeAxes = Axes.Both,
                    Masking          = true,
                    CornerRadius     = 5,
                    Children         = new Drawable[]
                    {
                        button = new HeaderButton {
                            RelativeSizeAxes = Axes.Both
                        },
                        new Container
                        {
                            // cannot nest inside here due to the structure of button (putting things in its own content).
                            // requires framework fix.
                            Padding = new MarginPadding {
                                Horizontal = 10
                            },
                            RelativeSizeAxes = Axes.Both,
                            Children         = new Drawable[]
                            {
                                textSprites = new FillFlowContainer
                                {
                                    Depth            = -1,
                                    Anchor           = Anchor.CentreLeft,
                                    Origin           = Anchor.CentreLeft,
                                    AutoSizeAxes     = Axes.Both,
                                    AutoSizeDuration = 500,
                                    AutoSizeEasing   = Easing.OutQuint,
                                    Direction        = FillDirection.Vertical,
                                },
                                new SpriteIcon
                                {
                                    Depth  = -1,
                                    Anchor = Anchor.CentreRight,
                                    Origin = Anchor.CentreRight,
                                    Icon   = FontAwesome.Solid.Download,
                                    Size   = new Vector2(16),
                                    Margin = new MarginPadding {
                                        Right = 5
                                    },
                                },
                            }
                        },
                        new DownloadProgressBar(BeatmapSet.Value)
                        {
                            Depth  = -2,
                            Anchor = Anchor.BottomLeft,
                            Origin = Anchor.BottomLeft,
                        },
                    },
                },
            });

            button.Action = () =>
            {
                if (State.Value != DownloadState.NotDownloaded)
                {
                    shakeContainer.Shake();
                    return;
                }

                beatmaps.Download(BeatmapSet.Value, noVideo);
            };

            localUser.BindTo(api.LocalUser);
            localUser.BindValueChanged(userChanged, true);
            button.Enabled.BindValueChanged(enabledChanged, true);

            State.BindValueChanged(state =>
            {
                switch (state.NewValue)
                {
                case DownloadState.Downloading:
                    textSprites.Children = new Drawable[]
                    {
                        new OsuSpriteText
                        {
                            Text = "下载中...",
                            Font = OsuFont.GetFont(size: 13, weight: FontWeight.Bold)
                        },
                    };
                    break;

                case DownloadState.Downloaded:
                    textSprites.Children = new Drawable[]
                    {
                        new OsuSpriteText
                        {
                            Text = "导入中...",
                            Font = OsuFont.GetFont(size: 13, weight: FontWeight.Bold)
                        },
                    };
                    break;

                case DownloadState.LocallyAvailable:
                    this.FadeOut(200);
                    break;

                case DownloadState.NotDownloaded:
                    textSprites.Children = new Drawable[]
                    {
                        new OsuSpriteText
                        {
                            Text = "下载",
                            Font = OsuFont.GetFont(size: 13, weight: FontWeight.Bold)
                        },
                        new OsuSpriteText
                        {
                            Text = BeatmapSet.Value.OnlineInfo.HasVideo && noVideo ? "不带视频" : string.Empty,
                            Font = OsuFont.GetFont(size: 11, weight: FontWeight.Bold)
                        },
                    };
                    this.FadeIn(200);
                    break;
                }
            }, true);
        }
Beispiel #20
0
 protected override void LoadComplete()
 {
     base.LoadComplete();
     gameActive.BindValueChanged(_ => updateActive(), true);
 }
Beispiel #21
0
        protected override void LoadComplete()
        {
            base.LoadComplete();

            enabled.BindTo(tabletHandler.Enabled);
            enabled.BindValueChanged(_ => Scheduler.AddOnce(updateVisibility));

            rotation.BindTo(tabletHandler.Rotation);

            areaOffset.BindTo(tabletHandler.AreaOffset);
            areaOffset.BindValueChanged(val =>
            {
                offsetX.Value = val.NewValue.X;
                offsetY.Value = val.NewValue.Y;
            }, true);

            offsetX.BindValueChanged(val => areaOffset.Value = new Vector2(val.NewValue, areaOffset.Value.Y));
            offsetY.BindValueChanged(val => areaOffset.Value = new Vector2(areaOffset.Value.X, val.NewValue));

            areaSize.BindTo(tabletHandler.AreaSize);
            areaSize.BindValueChanged(val =>
            {
                sizeX.Value = val.NewValue.X;
                sizeY.Value = val.NewValue.Y;
            }, true);

            sizeX.BindValueChanged(val =>
            {
                areaSize.Value = new Vector2(val.NewValue, areaSize.Value.Y);

                aspectRatioApplication?.Cancel();
                aspectRatioApplication = Schedule(() => applyAspectRatio(sizeX));
            });

            sizeY.BindValueChanged(val =>
            {
                areaSize.Value = new Vector2(areaSize.Value.X, val.NewValue);

                aspectRatioApplication?.Cancel();
                aspectRatioApplication = Schedule(() => applyAspectRatio(sizeY));
            });

            updateAspectRatio();
            aspectRatio.BindValueChanged(aspect =>
            {
                aspectRatioApplication?.Cancel();
                aspectRatioApplication = Schedule(() => forceAspectRatio(aspect.NewValue));
            });

            tablet.BindTo(tabletHandler.Tablet);
            tablet.BindValueChanged(val =>
            {
                Scheduler.AddOnce(updateVisibility);

                var tab = val.NewValue;

                bool tabletFound = tab != null;
                if (!tabletFound)
                {
                    return;
                }

                offsetX.MaxValue = tab.Size.X;
                offsetX.Default  = tab.Size.X / 2;
                sizeX.Default    = sizeX.MaxValue = tab.Size.X;

                offsetY.MaxValue = tab.Size.Y;
                offsetY.Default  = tab.Size.Y / 2;
                sizeY.Default    = sizeY.MaxValue = tab.Size.Y;

                areaSize.Default = new Vector2(sizeX.Default, sizeY.Default);
            }, true);
        }
Beispiel #22
0
 protected override void LoadComplete()
 {
     base.LoadComplete();
     Beatmap.BindValueChanged(b => waveform.Waveform = b.Waveform);
     waveform.Waveform = Beatmap.Value.Waveform;
 }
Beispiel #23
0
 protected override void LoadComplete()
 {
     base.LoadComplete();
     Beatmap.BindValueChanged(v => updateText(), true);
 }
 private void load()
 {
     apiState.BindTo(api.State);
     apiState.BindValueChanged(onlineStateChanged, true);
 }
Beispiel #25
0
 protected override void LoadComplete()
 {
     base.LoadComplete();
     accentColour.BindValueChanged(colour => Colour = LegacyColourCompatibility.DisallowZeroAlpha(colour.NewValue), true);
 }
Beispiel #26
0
 private void load()
 {
     pathBindable.BindTo(slider.PathBindable);
     pathBindable.BindValueChanged(_ => UpdatePosition(), true);
 }
 private void load()
 {
     scaleBindable.BindValueChanged(scale => scaleContainer.Scale = new Vector2(scale.NewValue), true);
     scaleBindable.BindTo(HitObject.ScaleBindable);
 }
Beispiel #28
0
        private void load(OsuConfigManager config)
        {
            FlowContent.Spacing = new Vector2(0, 5);

            Children = new Drawable[]
            {
                skinDropdown = new SkinSettingsDropdown(),
                new ExportSkinButton(),
                new SettingsSlider <float, SizeSlider>
                {
                    LabelText    = "Gameplay cursor size",
                    Current      = config.GetBindable <float>(OsuSetting.GameplayCursorSize),
                    KeyboardStep = 0.01f
                },
                new SettingsCheckbox
                {
                    LabelText = "Adjust gameplay cursor size based on current beatmap",
                    Current   = config.GetBindable <bool>(OsuSetting.AutoCursorSize)
                },
                new SettingsCheckbox
                {
                    LabelText = "Beatmap skins",
                    Current   = config.GetBindable <bool>(OsuSetting.BeatmapSkins)
                },
                new SettingsCheckbox
                {
                    LabelText = "Beatmap colours",
                    Current   = config.GetBindable <bool>(OsuSetting.BeatmapColours)
                },
                new SettingsCheckbox
                {
                    LabelText = "Beatmap hitsounds",
                    Current   = config.GetBindable <bool>(OsuSetting.BeatmapHitsounds)
                },
            };

            managerUpdated = skins.ItemUpdated.GetBoundCopy();
            managerUpdated.BindValueChanged(itemUpdated);

            managerRemoved = skins.ItemRemoved.GetBoundCopy();
            managerRemoved.BindValueChanged(itemRemoved);

            config.BindWith(OsuSetting.Skin, configBindable);

            skinDropdown.Current = dropdownBindable;
            updateItems();

            // Todo: This should not be necessary when OsuConfigManager is databased
            if (skinDropdown.Items.All(s => s.ID != configBindable.Value))
            {
                configBindable.Value = 0;
            }

            configBindable.BindValueChanged(id => Scheduler.AddOnce(updateSelectedSkinFromConfig), true);
            dropdownBindable.BindValueChanged(skin =>
            {
                if (skin.NewValue == random_skin_info)
                {
                    skins.SelectRandomSkin();
                    return;
                }

                configBindable.Value = skin.NewValue.ID;
            });
        }
Beispiel #29
0
        private void load()
        {
            try
            {
                using (var str = File.OpenRead(typeof(OsuGameBase).Assembly.Location))
                    VersionHash = str.ComputeMD5Hash();
            }
            catch
            {
                // special case for android builds, which can't read DLLs from a packed apk.
                // should eventually be handled in a better way.
                VersionHash = $"{Version}-{RuntimeInfo.OS}".ComputeMD5Hash();
            }

            Resources.AddStore(new DllResourceStore(OsuResources.ResourceAssembly));

            dependencies.Cache(contextFactory = new DatabaseContextFactory(Storage));

            dependencies.Cache(realmFactory = new RealmContextFactory(Storage));

            updateThreadState = Host.UpdateThread.State.GetBoundCopy();
            updateThreadState.BindValueChanged(updateThreadStateChanged);

            AddInternal(realmFactory);

            dependencies.CacheAs(Storage);

            var largeStore = new LargeTextureStore(Host.CreateTextureLoaderStore(new NamespacedResourceStore <byte[]>(Resources, @"Textures")));

            largeStore.AddStore(Host.CreateTextureLoaderStore(new OnlineStore()));
            dependencies.Cache(largeStore);

            dependencies.CacheAs(this);
            dependencies.CacheAs(LocalConfig);

            AddFont(Resources, @"Fonts/osuFont");

            AddFont(Resources, @"Fonts/Torus/Torus-Regular");
            AddFont(Resources, @"Fonts/Torus/Torus-Light");
            AddFont(Resources, @"Fonts/Torus/Torus-SemiBold");
            AddFont(Resources, @"Fonts/Torus/Torus-Bold");

            AddFont(Resources, @"Fonts/Inter/Inter-Regular");
            AddFont(Resources, @"Fonts/Inter/Inter-RegularItalic");
            AddFont(Resources, @"Fonts/Inter/Inter-Light");
            AddFont(Resources, @"Fonts/Inter/Inter-LightItalic");
            AddFont(Resources, @"Fonts/Inter/Inter-SemiBold");
            AddFont(Resources, @"Fonts/Inter/Inter-SemiBoldItalic");
            AddFont(Resources, @"Fonts/Inter/Inter-Bold");
            AddFont(Resources, @"Fonts/Inter/Inter-BoldItalic");

            AddFont(Resources, @"Fonts/Noto/Noto-Basic");
            AddFont(Resources, @"Fonts/Noto/Noto-Hangul");
            AddFont(Resources, @"Fonts/Noto/Noto-CJK-Basic");
            AddFont(Resources, @"Fonts/Noto/Noto-CJK-Compatibility");
            AddFont(Resources, @"Fonts/Noto/Noto-Thai");

            AddFont(Resources, @"Fonts/Venera/Venera-Light");
            AddFont(Resources, @"Fonts/Venera/Venera-Bold");
            AddFont(Resources, @"Fonts/Venera/Venera-Black");

            Audio.Samples.PlaybackConcurrency = SAMPLE_CONCURRENCY;

            runMigrations();

            dependencies.Cache(SkinManager = new SkinManager(Storage, contextFactory, Host, Resources, Audio));
            dependencies.CacheAs <ISkinSource>(SkinManager);

            // needs to be done here rather than inside SkinManager to ensure thread safety of CurrentSkinInfo.
            SkinManager.ItemRemoved.BindValueChanged(weakRemovedInfo =>
            {
                if (weakRemovedInfo.NewValue.TryGetTarget(out var removedInfo))
                {
                    Schedule(() =>
                    {
                        // check the removed skin is not the current user choice. if it is, switch back to default.
                        if (removedInfo.ID == SkinManager.CurrentSkinInfo.Value.ID)
                        {
                            SkinManager.CurrentSkinInfo.Value = SkinInfo.Default;
                        }
                    });
                }
            });

            EndpointConfiguration endpoints = UseDevelopmentServer ? (EndpointConfiguration) new DevelopmentEndpointConfiguration() : new ProductionEndpointConfiguration();

            MessageFormatter.WebsiteRootUrl = endpoints.WebsiteRootUrl;

            dependencies.CacheAs(API ??= new APIAccess(LocalConfig, endpoints, VersionHash));

            dependencies.CacheAs(spectatorClient   = new OnlineSpectatorClient(endpoints));
            dependencies.CacheAs(multiplayerClient = new OnlineMultiplayerClient(endpoints));

            var defaultBeatmap = new DummyWorkingBeatmap(Audio, Textures);

            dependencies.Cache(RulesetStore = new RulesetStore(contextFactory, Storage));
            dependencies.Cache(fileStore    = new FileStore(contextFactory, Storage));

            // ordering is important here to ensure foreign keys rules are not broken in ModelStore.Cleanup()
            dependencies.Cache(ScoreManager   = new ScoreManager(RulesetStore, () => BeatmapManager, Storage, API, contextFactory, Host, () => difficultyCache, LocalConfig));
            dependencies.Cache(BeatmapManager = new BeatmapManager(Storage, contextFactory, RulesetStore, API, Audio, Resources, Host, defaultBeatmap, true));

            // this should likely be moved to ArchiveModelManager when another case appears where it is necessary
            // to have inter-dependent model managers. this could be obtained with an IHasForeign<T> interface to
            // allow lookups to be done on the child (ScoreManager in this case) to perform the cascading delete.
            List <ScoreInfo> getBeatmapScores(BeatmapSetInfo set)
            {
                var beatmapIds = BeatmapManager.QueryBeatmaps(b => b.BeatmapSetInfoID == set.ID).Select(b => b.ID).ToList();

                return(ScoreManager.QueryScores(s => beatmapIds.Contains(s.Beatmap.ID)).ToList());
            }

            BeatmapManager.ItemRemoved.BindValueChanged(i =>
            {
                if (i.NewValue.TryGetTarget(out var item))
                {
                    ScoreManager.Delete(getBeatmapScores(item), true);
                }
            });

            BeatmapManager.ItemUpdated.BindValueChanged(i =>
            {
                if (i.NewValue.TryGetTarget(out var item))
                {
                    ScoreManager.Undelete(getBeatmapScores(item), true);
                }
            });

            dependencies.Cache(difficultyCache = new BeatmapDifficultyCache());
            AddInternal(difficultyCache);

            dependencies.Cache(userCache = new UserLookupCache());
            AddInternal(userCache);

            var scorePerformanceManager = new ScorePerformanceCache();

            dependencies.Cache(scorePerformanceManager);
            AddInternal(scorePerformanceManager);

            migrateDataToRealm();

            dependencies.Cache(settingsStore      = new SettingsStore(contextFactory));
            dependencies.Cache(rulesetConfigCache = new RulesetConfigCache(settingsStore));

            var powerStatus = CreateBatteryInfo();

            if (powerStatus != null)
            {
                dependencies.CacheAs(powerStatus);
            }

            dependencies.Cache(SessionStatics = new SessionStatics());
            dependencies.Cache(new OsuColour());

            RegisterImportHandler(BeatmapManager);
            RegisterImportHandler(ScoreManager);
            RegisterImportHandler(SkinManager);

            // drop track volume game-wide to leave some head-room for UI effects / samples.
            // this means that for the time being, gameplay sample playback is louder relative to the audio track, compared to stable.
            // we may want to revisit this if users notice or complain about the difference (consider this a bit of a trial).
            Audio.Tracks.AddAdjustment(AdjustableProperty.Volume, globalTrackVolumeAdjust);

            Beatmap = new NonNullableBindable <WorkingBeatmap>(defaultBeatmap);

            dependencies.CacheAs <IBindable <WorkingBeatmap> >(Beatmap);
            dependencies.CacheAs(Beatmap);

            fileStore.Cleanup();

            // add api components to hierarchy.
            if (API is APIAccess apiAccess)
            {
                AddInternal(apiAccess);
            }
            AddInternal(spectatorClient);
            AddInternal(multiplayerClient);

            AddInternal(rulesetConfigCache);

            GlobalActionContainer globalBindings;

            var mainContent = new Drawable[]
            {
                MenuCursorContainer = new MenuCursorContainer {
                    RelativeSizeAxes = Axes.Both
                },
                // to avoid positional input being blocked by children, ensure the GlobalActionContainer is above everything.
                globalBindings = new GlobalActionContainer(this)
            };

            MenuCursorContainer.Child = new PopoverContainer
            {
                RelativeSizeAxes = Axes.Both,
                Child            = content = new OsuTooltipContainer(MenuCursorContainer.Cursor)
                {
                    RelativeSizeAxes = Axes.Both
                }
            };

            base.Content.Add(CreateScalingContainer().WithChildren(mainContent));

            KeyBindingStore = new RealmKeyBindingStore(realmFactory);
            KeyBindingStore.Register(globalBindings);

            foreach (var r in RulesetStore.AvailableRulesets)
            {
                KeyBindingStore.Register(r);
            }

            dependencies.Cache(globalBindings);

            PreviewTrackManager previewTrackManager;

            dependencies.Cache(previewTrackManager = new PreviewTrackManager());
            Add(previewTrackManager);

            AddInternal(MusicController = new MusicController());
            dependencies.CacheAs(MusicController);

            Ruleset.BindValueChanged(onRulesetChanged);
        }
 protected override void LoadComplete()
 {
     base.LoadComplete();
     IsCreated.BindValueChanged(created => Alpha = created.NewValue ? 1 : 0, true);
 }