Exemplo n.º 1
0
        private MainMenu CreateMainMenu()
        {
            var bookPropertiesItem = new MenuItem("譜面プロパティ(&P)", (s, e) =>
            {
                var form = new BookPropertiesForm(ScoreBook, CurrentSoundSource);
                if (form.ShowDialog(this) != DialogResult.OK)
                {
                    return;
                }

                ScoreBook.Title             = form.Title;
                ScoreBook.ArtistName        = form.ArtistName;
                ScoreBook.NotesDesignerName = form.NotesDesignerName;
                CurrentSoundSource          = form.SoundSource;
            });

            var exportPluginItems = PluginManager.ScoreBookExportPlugins.Select(p => new MenuItem(p.DisplayName, (s, e) =>
            {
                var dialog = new SaveFileDialog()
                {
                    Filter = p.Filter, Title = "エクスポート先選択"
                };
                if (dialog.ShowDialog(this) != DialogResult.OK)
                {
                    return;
                }
                var args = new ScoreBookExportPluginArgs(() => ScoreBook.Clone())
                {
                    OutputPath = dialog.FileName
                };
                ExportFile(new Exporter(p, args));
            }));

            var fileMenuItems = new MenuItem[]
            {
                new MenuItem("新規作成(&N)", (s, e) => Clear())
                {
                    Shortcut = Shortcut.CtrlN
                },
                new MenuItem("開く(&O)", (s, e) => OpenFile())
                {
                    Shortcut = Shortcut.CtrlO
                },
                new MenuItem("保存(&S)", (s, e) => SaveFile())
                {
                    Shortcut = Shortcut.CtrlS
                },
                new MenuItem("名前をつけて保存(&A)", (s, e) => SaveAs())
                {
                    Shortcut = Shortcut.CtrlShiftS
                },
                new MenuItem("-"),
                new MenuItem("エクスポート(&E)", exportPluginItems.ToArray()),
                new MenuItem("-"),
                bookPropertiesItem,
                new MenuItem("-"),
                new MenuItem("終了(&X)", (s, e) => Close())
            };

            var undoItem = new MenuItem("元に戻す", (s, e) => OperationManager.Undo())
            {
                Shortcut = Shortcut.CtrlZ,
                Enabled  = false
            };
            var redoItem = new MenuItem("やり直す", (s, e) => OperationManager.Redo())
            {
                Shortcut = Shortcut.CtrlY,
                Enabled  = false
            };

            var removeEventsItem = new MenuItem("選択範囲内イベントを削除", (s, e) =>
            {
                int head = NoteView.SelectedRange.StartTick + (NoteView.SelectedRange.Duration < 0 ? NoteView.SelectedRange.Duration : 0);
                int tail = NoteView.SelectedRange.StartTick + (NoteView.SelectedRange.Duration < 0 ? 0 : NoteView.SelectedRange.Duration);
                IEnumerable <IOperation> RemoveFilter <T>(List <T> list) where T: EventBase
                {
                    return(list.Where(p => p.Tick != 0 && p.Tick >= head && p.Tick <= tail).Select(p => new RemoveEventOperation <T>(p, list)));
                }

                var events = NoteView.Score.Events;
                var ops    = new[]
                {
                    RemoveFilter(events.BPMChangeEvents),
                    RemoveFilter(events.TimeSignatureChangeEvents),
                    RemoveFilter(events.HighSpeedChangeEvents)
                }.SelectMany(p => p);

                OperationManager.ExecuteAndPush(new CompositeOperation("イベント削除", ops.ToArray()));
            });

            var editMenuItems = new MenuItem[]
            {
                undoItem, redoItem,
                new MenuItem("-"),
                removeEventsItem
            };

            var previewItem = new MenuItem("譜面プレビュー", (s, e) =>
            {
                IsPreviewMode         = !IsPreviewMode;
                ((MenuItem)s).Checked = IsPreviewMode;
            }, Shortcut.CtrlP);

            var viewMenuItems = new MenuItem[]
            {
                previewItem
            };

            var addBpmItem = new MenuItem("BPM", (s, e) =>
            {
                var form = new BPMSelectionForm()
                {
                    BPM = NoteView.Score.Events.BPMChangeEvents.OrderBy(p => p.Tick).LastOrDefault(p => p.Tick <= NoteView.CurrentTick)?.BPM ?? 120m
                };
                if (form.ShowDialog(this) != DialogResult.OK)
                {
                    return;
                }

                var item = new BPMChangeEvent()
                {
                    Tick = NoteView.CurrentTick,
                    BPM  = form.BPM
                };

                IOperation op = ProcessAddEvent(item, NoteView.Score.Events.BPMChangeEvents);
                OperationManager.ExecuteAndPush(op);
                NoteView.Invalidate();
            });

            var addTimeSignatureItem = new MenuItem("拍子", (s, e) =>
            {
                var form = new TimesignatureSelectionForm();
                if (form.ShowDialog(this) != DialogResult.OK)
                {
                    return;
                }

                var item = new TimeSignatureChangeEvent()
                {
                    Tick                = NoteView.CurrentTick,
                    Numerator           = form.Numerator,
                    DenominatorExponent = form.DenominatorExponent
                };

                IOperation op = ProcessAddEvent(item, NoteView.Score.Events.TimeSignatureChangeEvents);
                OperationManager.ExecuteAndPush(op);
                NoteView.Invalidate();
            });

            var addHighSpeedItem = new MenuItem("ハイスピード", (s, e) =>
            {
                var form = new HighSpeedSelectionForm()
                {
                    SpeedRatio = NoteView.Score.Events.HighSpeedChangeEvents.OrderBy(p => p.Tick).LastOrDefault(p => p.Tick <= NoteView.CurrentTick)?.SpeedRatio ?? 1.0m
                };
                if (form.ShowDialog(this) != DialogResult.OK)
                {
                    return;
                }

                var item = new HighSpeedChangeEvent()
                {
                    Tick       = NoteView.CurrentTick,
                    SpeedRatio = form.SpeedRatio
                };

                IOperation op = ProcessAddEvent(item, NoteView.Score.Events.HighSpeedChangeEvents);
                OperationManager.ExecuteAndPush(op);
                NoteView.Invalidate();
            });

            IOperation ProcessAddEvent <T>(T item, List <T> list) where T : EventBase
            {
                var prev  = list.SingleOrDefault(p => p.Tick == item.Tick);
                var addOp = new AddEventOperation <T>(item, list);

                if (prev == null)
                {
                    return(addOp);
                }
                var removeOp = new RemoveEventOperation <T>(prev, list);

                return(new CompositeOperation(addOp.Description, new IOperation[] { removeOp, addOp }));
            }

            var insertMenuItems = new MenuItem[]
            {
                addBpmItem, addTimeSignatureItem, addHighSpeedItem
            };

            var previewOnlyNotesItem = new MenuItem("ベル/敵弾でガイド音を鳴らさない", (s, e) =>
            {
                var item     = s as MenuItem;
                item.Checked = !item.Checked;
                ApplicationSettings.Default.PreviewOnlyNotes = item.Checked;
            })
            {
                Checked = ApplicationSettings.Default.PreviewOnlyNotes
            };

            var playItem = new MenuItem("再生/停止", (s, e) =>
            {
                if (PreviewManager.Playing)
                {
                    PreviewManager.Stop();
                    return;
                }
                if (CurrentSoundSource == null)
                {
                    MessageBox.Show(this, "プレビュー用音源ファイルが設定されていません。", Program.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
                if (!File.Exists(CurrentSoundSource.FilePath))
                {
                    MessageBox.Show(this, "プレビュー用音源ファイルが見つかりません。", Program.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                int startTick       = NoteView.CurrentTick;
                EventHandler lambda = null;
                lambda = (p, q) =>
                {
                    previewOnlyNotesItem.Enabled = true;
                    PreviewManager.Finished     -= lambda;
                    NoteView.CurrentTick         = startTick;
                    NoteView.Editable            = CanEdit;
                };

                try
                {
                    var score = NoteView.Restore();
                    PreviewManager.TicksPerBeat = score.TicksPerBeat;
                    if (!PreviewManager.Start(score, CurrentSoundSource, startTick, ApplicationSettings.Default.PreviewOnlyNotes))
                    {
                        return;
                    }
                    previewOnlyNotesItem.Enabled = false;
                    PreviewManager.Finished     += lambda;
                    NoteView.Editable            = CanEdit;
                }
                catch (Exception ex)
                {
                    Program.DumpExceptionTo(ex, "sound_exception.json");
                    PreviewManager.Stop();
                }
            }, (Shortcut)Keys.Space);

            var playMenuItems = new MenuItem[]
            {
                playItem, new MenuItem("-"),
                previewOnlyNotesItem
            };

            var helpMenuItems = new MenuItem[]
            {
                new MenuItem("Wikiを開く", (s, e) => System.Diagnostics.Process.Start("https://github.com/paralleltree/Yuzu/wiki"), Shortcut.F1),
                new MenuItem("バージョン情報", (s, e) => new VersionInfoForm().ShowDialog(this))
            };

            OperationManager.OperationHistoryChanged += (s, e) =>
            {
                undoItem.Enabled = OperationManager.CanUndo;
                redoItem.Enabled = OperationManager.CanRedo;
            };

            return(new MainMenu(new MenuItem[]
            {
                new MenuItem("ファイル(&F)", fileMenuItems),
                new MenuItem("編集(&E)", editMenuItems),
                new MenuItem("表示(&V)", viewMenuItems),
                new MenuItem("挿入(&I)", insertMenuItems),
                new MenuItem("再生(&P)", playMenuItems),
                new MenuItem("ヘルプ(&H)", helpMenuItems)
            }));
        }
Exemplo n.º 2
0
 public ScoreBook GetScoreBook() => ScoreBook.Clone();