private void load(OsuColour colours, OsuConfigManager config) { var loadableBeatmap = Beatmap.Value; if (loadableBeatmap is DummyWorkingBeatmap) { isNewBeatmap = true; loadableBeatmap = beatmapManager.CreateNew(Ruleset.Value, api.LocalUser.Value); // required so we can get the track length in EditorClock. // this is safe as nothing has yet got a reference to this new beatmap. loadableBeatmap.LoadTrack(); // this is a bit haphazard, but guards against setting the lease Beatmap bindable if // the editor has already been exited. if (!ValidForPush) { return; } } try { playableBeatmap = loadableBeatmap.GetPlayableBeatmap(loadableBeatmap.BeatmapInfo.Ruleset); // clone these locally for now to avoid incurring overhead on GetPlayableBeatmap usages. // eventually we will want to improve how/where this is done as there are issues with *not* cloning it in all cases. playableBeatmap.ControlPointInfo = playableBeatmap.ControlPointInfo.DeepClone(); } catch (Exception e) { Logger.Error(e, "Could not load beatmap successfully!"); // couldn't load, hard abort! this.Exit(); return; } // Todo: should probably be done at a DrawableRuleset level to share logic with Player. clock = new EditorClock(playableBeatmap, beatDivisor) { IsCoupled = false }; clock.ChangeSource(loadableBeatmap.Track); dependencies.CacheAs(clock); AddInternal(clock); clock.SeekingOrStopped.BindValueChanged(_ => updateSampleDisabledState()); // todo: remove caching of this and consume via editorBeatmap? dependencies.Cache(beatDivisor); AddInternal(editorBeatmap = new EditorBeatmap(playableBeatmap, loadableBeatmap.GetSkin(), loadableBeatmap.BeatmapInfo)); dependencies.CacheAs(editorBeatmap); canSave = editorBeatmap.BeatmapInfo.Ruleset.CreateInstance() is ILegacyRuleset; if (canSave) { changeHandler = new EditorChangeHandler(editorBeatmap); dependencies.CacheAs <IEditorChangeHandler>(changeHandler); } beatDivisor.Value = editorBeatmap.BeatmapInfo.BeatDivisor; beatDivisor.BindValueChanged(divisor => editorBeatmap.BeatmapInfo.BeatDivisor = divisor.NewValue); updateLastSavedHash(); Schedule(() => { // we need to avoid changing the beatmap from an asynchronous load thread. it can potentially cause weirdness including crashes. // this assumes that nothing during the rest of this load() method is accessing Beatmap.Value (loadableBeatmap should be preferred). // generally this is quite safe, as the actual load of editor content comes after menuBar.Mode.ValueChanged is fired in its own LoadComplete. Beatmap.Value = loadableBeatmap; }); OsuMenuItem undoMenuItem; OsuMenuItem redoMenuItem; AddInternal(new OsuContextMenuContainer { RelativeSizeAxes = Axes.Both, Children = new[] { new Container { Name = "Screen container", RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Top = 40, Bottom = 60 }, Child = screenContainer = new Container <EditorScreen> { RelativeSizeAxes = Axes.Both, Masking = true } }, new Container { Name = "Top bar", RelativeSizeAxes = Axes.X, Height = 40, Children = new Drawable[] { new EditorMenuBar { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, RelativeSizeAxes = Axes.Both, Items = new[] { new MenuItem("File") { Items = createFileMenuItems() }, new MenuItem(CommonStrings.ButtonsEdit) { Items = new[] { undoMenuItem = new EditorMenuItem("Undo", MenuItemType.Standard, Undo), redoMenuItem = new EditorMenuItem("Redo", MenuItemType.Standard, Redo), new EditorMenuItemSpacer(), cutMenuItem = new EditorMenuItem("Cut", MenuItemType.Standard, Cut), copyMenuItem = new EditorMenuItem("Copy", MenuItemType.Standard, Copy), pasteMenuItem = new EditorMenuItem("Paste", MenuItemType.Standard, Paste), } }, new MenuItem("View") { Items = new MenuItem[] { new WaveformOpacityMenuItem(config.GetBindable <float>(OsuSetting.EditorWaveformOpacity)), new HitAnimationsMenuItem(config.GetBindable <bool>(OsuSetting.EditorHitAnimations)) } } } }, new ScreenSelectionTabControl { Anchor = Anchor.BottomRight, Origin = Anchor.BottomRight, X = -15, Current = Mode, }, }, }, new Container { Name = "Bottom bar", Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, RelativeSizeAxes = Axes.X, Height = 60, Children = new Drawable[] { new Box { RelativeSizeAxes = Axes.Both, Colour = colours.Gray2 }, new Container { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Vertical = 5, Horizontal = 10 }, Child = new GridContainer { RelativeSizeAxes = Axes.Both, ColumnDimensions = new[] { new Dimension(GridSizeMode.Absolute, 220), new Dimension(), new Dimension(GridSizeMode.Absolute, 220), new Dimension(GridSizeMode.Absolute, 120), }, Content = new[] { new Drawable[] { new Container { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Right = 10 }, Child = new TimeInfoContainer { RelativeSizeAxes = Axes.Both }, }, new SummaryTimeline { RelativeSizeAxes = Axes.Both, }, new Container { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Left = 10 }, Child = new PlaybackControl { RelativeSizeAxes = Axes.Both }, }, testGameplayButton = new TestGameplayButton { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Left = 10 }, Size = new Vector2(1), Action = testGameplay } }, } }, } } }, } }); changeHandler?.CanUndo.BindValueChanged(v => undoMenuItem.Action.Disabled = !v.NewValue, true); changeHandler?.CanRedo.BindValueChanged(v => redoMenuItem.Action.Disabled = !v.NewValue, true); }
private void load(OverlayColourProvider colourProvider, Editor editor) { Anchor = Anchor.BottomLeft; Origin = Anchor.BottomLeft; RelativeSizeAxes = Axes.X; Height = 60; Masking = true; EdgeEffect = new EdgeEffectParameters { Colour = Color4.Black.Opacity(0.2f), Type = EdgeEffectType.Shadow, Radius = 10f, }; InternalChildren = new Drawable[] { new Box { RelativeSizeAxes = Axes.Both, Colour = colourProvider.Background4, }, new Container { RelativeSizeAxes = Axes.Both, Child = new GridContainer { RelativeSizeAxes = Axes.Both, ColumnDimensions = new[] { new Dimension(GridSizeMode.Absolute, 170), new Dimension(), new Dimension(GridSizeMode.Absolute, 220), new Dimension(GridSizeMode.Absolute, 120), }, Content = new[] { new Drawable[] { new TimeInfoContainer { RelativeSizeAxes = Axes.Both }, new SummaryTimeline { RelativeSizeAxes = Axes.Both }, new PlaybackControl { RelativeSizeAxes = Axes.Both }, TestGameplayButton = new TestGameplayButton { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Left = 10 }, Size = new Vector2(1), Action = editor.TestGameplay, } }, } }, } }; }