Esempio n. 1
0
 public SoundPreviewManager(NoteView noteView)
 {
     ClapSource  = new SoundSource("guide.mp3", 0.036);
     NoteView    = noteView;
     Timer.Tick += Tick;
     SoundManager.ExceptionThrown += (s, e) => noteView.InvokeIfRequired(() =>
     {
         Stop();
         ExceptionThrown?.Invoke(this, EventArgs.Empty);
     });
 }
Esempio n. 2
0
 protected void LoadBook(ScoreBook book)
 {
     ScoreBook = book;
     NoteView.LoadScore(book.Score);
     NoteViewScrollBar.Value   = NoteViewScrollBar.GetMaximumValue();
     NoteViewScrollBar.Minimum = -Math.Max(NoteView.UnitBeatTick * 4 * 20, NoteView.Notes.GetLastTick());
     UpdateThumbHeight();
     SetText(book.Path);
     LastExportData = null;
     if (!string.IsNullOrEmpty(book.Path))
     {
         SoundConfiguration.Default.ScoreSound.TryGetValue(book.Path, out CurrentMusicSource);
     }
     else
     {
         CurrentMusicSource = null;
     }
 }
Esempio n. 3
0
 protected void LoadBook(ScoreBook book)
 {
     ScoreBook = book;
     OperationManager.Clear();
     NoteView.Initialize(book.Score);
     NoteViewScrollBar.Value       = NoteViewScrollBar.GetMaximumValue();
     NoteViewScrollBar.Minimum     = -Math.Max(NoteView.UnitBeatTick * 4 * 20, NoteView.Notes.GetLastTick());
     NoteViewScrollBar.SmallChange = NoteView.UnitBeatTick;
     UpdateThumbHeight();
     SetText(book.Path);
     LastExportData = null;
     if (!string.IsNullOrEmpty(book.Path))
     {
         SoundSettings.Default.ScoreSound.TryGetValue(book.Path, out CurrentMusicSource);
     }
     else
     {
         CurrentMusicSource = null;
     }
 }
Esempio n. 4
0
        private ToolStrip CreateNewNoteTypeToolStrip(NoteView noteView)
        {
            var tapButton = new ToolStripButton("TAP", Resources.TapIcon, (s, e) => noteView.NewNoteType = NoteType.Tap)
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };
            var exTapButton = new ToolStripButton("ExTAP", Resources.ExTapIcon, (s, e) => noteView.NewNoteType = NoteType.ExTap)
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };
            var holdButton = new ToolStripButton("HOLD", Resources.HoldIcon, (s, e) => noteView.NewNoteType = NoteType.Hold)
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };
            var slideButton = new ToolStripButton("SLIDE", Resources.SlideIcon, (s, e) =>
            {
                noteView.NewNoteType           = NoteType.Slide;
                noteView.IsNewSlideStepVisible = false;
            })
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };
            var slideStepButton = new ToolStripButton(MainFormStrings.SlideStep, Resources.SlideStepIcon, (s, e) =>
            {
                noteView.NewNoteType           = NoteType.Slide;
                noteView.IsNewSlideStepVisible = true;
            })
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };
            var airActionButton = new ToolStripButton("AIR-ACTION", Resources.AirActionIcon, (s, e) => noteView.NewNoteType = NoteType.AirAction)
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };
            var flickButton = new ToolStripButton("FLICK", Resources.FlickIcon, (s, e) => noteView.NewNoteType = NoteType.Flick)
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };
            var damageButton = new ToolStripButton("DAMAGE", Resources.DamgeIcon, (s, e) => noteView.NewNoteType = NoteType.Damage)
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };

            var airKind = new CheckableToolStripSplitButton()
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };

            airKind.Text   = "AIR";
            airKind.Click += (s, e) => noteView.NewNoteType = NoteType.Air;
            airKind.DropDown.Items.AddRange(new ToolStripItem[]
            {
                new ToolStripMenuItem(MainFormStrings.AirUp, Resources.AirUpIcon, (s, e) => noteView.AirDirection               = new AirDirection(VerticalAirDirection.Up, HorizontalAirDirection.Center)),
                new ToolStripMenuItem(MainFormStrings.AirLeftUp, Resources.AirLeftUpIcon, (s, e) => noteView.AirDirection       = new AirDirection(VerticalAirDirection.Up, HorizontalAirDirection.Left)),
                new ToolStripMenuItem(MainFormStrings.AirRightUp, Resources.AirRightUpIcon, (s, e) => noteView.AirDirection     = new AirDirection(VerticalAirDirection.Up, HorizontalAirDirection.Right)),
                new ToolStripMenuItem(MainFormStrings.AirDown, Resources.AirDownIcon, (s, e) => noteView.AirDirection           = new AirDirection(VerticalAirDirection.Down, HorizontalAirDirection.Center)),
                new ToolStripMenuItem(MainFormStrings.AirLeftDown, Resources.AirLeftDownIcon, (s, e) => noteView.AirDirection   = new AirDirection(VerticalAirDirection.Down, HorizontalAirDirection.Left)),
                new ToolStripMenuItem(MainFormStrings.AirRightDown, Resources.AirRightDownIcon, (s, e) => noteView.AirDirection = new AirDirection(VerticalAirDirection.Down, HorizontalAirDirection.Right))
            });
            airKind.Image = Resources.AirUpIcon;

            var quantizeTicks = new int[]
            {
                4, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192
            };
            var quantizeComboBox = new ToolStripComboBox("クォンタイズ")
            {
                DropDownStyle = ComboBoxStyle.DropDownList,
                AutoSize      = false,
                Width         = 80
            };

            quantizeComboBox.Items.AddRange(quantizeTicks.Select(p => p + MainFormStrings.Division).ToArray());
            quantizeComboBox.Items.Add(MainFormStrings.Custom);
            quantizeComboBox.SelectedIndexChanged += (s, e) =>
            {
                if (quantizeComboBox.SelectedIndex == quantizeComboBox.Items.Count - 1)
                {
                    // ユーザー定義
                    var form = new CustomQuantizeSelectionForm(ScoreBook.Score.TicksPerBeat * 4);
                    if (form.ShowDialog(this) == DialogResult.OK)
                    {
                        noteView.QuantizeTick = form.QuantizeTick;
                    }
                }
                else
                {
                    noteView.QuantizeTick = noteView.UnitBeatTick * 4 / quantizeTicks[quantizeComboBox.SelectedIndex];
                }
                noteView.Focus();
            };
            quantizeComboBox.SelectedIndex = 1;

            noteView.NewNoteTypeChanged += (s, e) =>
            {
                tapButton.Checked       = noteView.NewNoteType.HasFlag(NoteType.Tap);
                exTapButton.Checked     = noteView.NewNoteType.HasFlag(NoteType.ExTap);
                holdButton.Checked      = noteView.NewNoteType.HasFlag(NoteType.Hold);
                slideButton.Checked     = noteView.NewNoteType.HasFlag(NoteType.Slide) && !noteView.IsNewSlideStepVisible;
                slideStepButton.Checked = noteView.NewNoteType.HasFlag(NoteType.Slide) && noteView.IsNewSlideStepVisible;
                airKind.Checked         = noteView.NewNoteType.HasFlag(NoteType.Air);
                airActionButton.Checked = noteView.NewNoteType.HasFlag(NoteType.AirAction);
                flickButton.Checked     = noteView.NewNoteType.HasFlag(NoteType.Flick);
                damageButton.Checked    = noteView.NewNoteType.HasFlag(NoteType.Damage);
            };

            noteView.AirDirectionChanged += (s, e) =>
            {
                switch (noteView.AirDirection.HorizontalDirection)
                {
                case HorizontalAirDirection.Center:
                    airKind.Image = noteView.AirDirection.VerticalDirection == VerticalAirDirection.Up ? Resources.AirUpIcon : Resources.AirDownIcon;
                    break;

                case HorizontalAirDirection.Left:
                    airKind.Image = noteView.AirDirection.VerticalDirection == VerticalAirDirection.Up ? Resources.AirLeftUpIcon : Resources.AirLeftDownIcon;
                    break;

                case HorizontalAirDirection.Right:
                    airKind.Image = noteView.AirDirection.VerticalDirection == VerticalAirDirection.Up ? Resources.AirRightUpIcon : Resources.AirRightDownIcon;
                    break;
                }
            };

            return(new ToolStrip(new ToolStripItem[]
            {
                tapButton, exTapButton, holdButton, slideButton, slideStepButton, airKind, airActionButton, flickButton, damageButton,
                quantizeComboBox
            }));
        }
Esempio n. 5
0
        public MainForm()
        {
            InitializeComponent();
            Size = new Size(420, 700);
            Icon = Resources.MainIcon;

            ToolStripManager.RenderMode = ToolStripManagerRenderMode.System;

            OperationManager = new OperationManager();
            OperationManager.OperationHistoryChanged += (s, e) =>
            {
                SetText(ScoreBook.Path);
                NoteView.Invalidate();
            };
            OperationManager.ChangesCommitted += (s, e) => SetText(ScoreBook.Path);

            NoteView = new NoteView(OperationManager)
            {
                Dock                   = DockStyle.Fill,
                UnitBeatHeight         = ApplicationSettings.Default.UnitBeatHeight,
                UnitLaneWidth          = ApplicationSettings.Default.UnitLaneWidth,
                InsertAirWithAirAction = ApplicationSettings.Default.InsertAirWithAirAction
            };

            PreviewManager = new SoundPreviewManager(this);
            PreviewManager.IsStopAtLastNote = ApplicationSettings.Default.IsPreviewAbortAtLastNote;
            PreviewManager.TickUpdated     += (s, e) => NoteView.CurrentTick = e.Tick;
            PreviewManager.ExceptionThrown += (s, e) => MessageBox.Show(this, ErrorStrings.PreviewException, Program.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Error);

            NoteViewScrollBar = new VScrollBar()
            {
                Dock        = DockStyle.Right,
                Minimum     = -NoteView.UnitBeatTick * 4 * 20,
                SmallChange = NoteView.UnitBeatTick
            };

            void processScrollBarRangeExtension(ScrollBar s)
            {
                if (NoteViewScrollBar.Value < NoteViewScrollBar.Minimum * 0.9f)
                {
                    NoteViewScrollBar.Minimum = (int)(NoteViewScrollBar.Minimum * 1.2);
                }
            }

            NoteView.Resize += (s, e) => UpdateThumbHeight();

            NoteView.MouseWheel += (s, e) =>
            {
                int value = NoteViewScrollBar.Value - e.Delta / 120 * NoteViewScrollBar.SmallChange;
                NoteViewScrollBar.Value = Math.Min(Math.Max(value, NoteViewScrollBar.Minimum), NoteViewScrollBar.GetMaximumValue());
                processScrollBarRangeExtension(NoteViewScrollBar);
            };

            NoteView.DragScroll += (s, e) =>
            {
                NoteViewScrollBar.Value = Math.Max(-NoteView.HeadTick, NoteViewScrollBar.Minimum);
                processScrollBarRangeExtension(NoteViewScrollBar);
            };

            NoteViewScrollBar.ValueChanged += (s, e) =>
            {
                NoteView.HeadTick = -NoteViewScrollBar.Value / 60 * 60; // 60の倍数できれいに表示されるので…
                NoteView.Invalidate();
            };

            NoteViewScrollBar.Scroll += (s, e) =>
            {
                if (e.Type == ScrollEventType.EndScroll)
                {
                    processScrollBarRangeExtension(NoteViewScrollBar);
                }
            };

            NoteView.NewNoteTypeChanged += (s, e) => NoteView.EditMode = EditMode.Edit;

            AllowDrop  = true;
            DragEnter += (s, e) =>
            {
                e.Effect = DragDropEffects.None;
                if (e.Data.GetDataPresent(DataFormats.FileDrop))
                {
                    var items = (string[])e.Data.GetData(DataFormats.FileDrop);
                    if (items.Length == 1 && items.All(p => Path.GetExtension(p) == FileExtension && File.Exists(p)))
                    {
                        e.Effect = DragDropEffects.Copy;
                    }
                }
            };
            DragDrop += (s, e) =>
            {
                string path = ((string[])e.Data.GetData(DataFormats.FileDrop)).Single();
                if (!ConfirmDiscardChanges())
                {
                    return;
                }
                LoadFile(path);
            };

            FormClosing += (s, e) =>
            {
                if (!ConfirmDiscardChanges())
                {
                    e.Cancel = true;
                    return;
                }

                ApplicationSettings.Default.Save();
            };

            using (var manager = this.WorkWithLayout())
            {
                this.Menu = CreateMainMenu(NoteView);
                this.Controls.Add(NoteView);
                this.Controls.Add(NoteViewScrollBar);
                this.Controls.Add(CreateNewNoteTypeToolStrip(NoteView));
                this.Controls.Add(CreateMainToolStrip(NoteView));
            }

            NoteView.NewNoteType = NoteType.Tap;
            NoteView.EditMode    = EditMode.Edit;

            LoadEmptyBook();
            SetText();

            if (!PreviewManager.IsSupported)
            {
                MessageBox.Show(this, ErrorStrings.PreviewNotSupported, Program.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Information);
            }

            if (PluginManager.FailedFiles.Count > 0)
            {
                MessageBox.Show(this, string.Join("\n", new[] { ErrorStrings.PluginLoadError }.Concat(PluginManager.FailedFiles)), Program.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            if (PluginManager.InvalidFiles.Count > 0)
            {
                MessageBox.Show(this, string.Join("\n", new[] { ErrorStrings.PluginNotSupported }.Concat(PluginManager.InvalidFiles)), Program.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
Esempio n. 6
0
        private ToolStrip CreateMainToolStrip(NoteView noteView)
        {
            var newFileButton = new ToolStripButton(MainFormStrings.NewFile, Resources.NewFileIcon, (s, e) => ClearFile())
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };
            var openFileButton = new ToolStripButton(MainFormStrings.OpenFile, Resources.OpenFileIcon, (s, e) => OpenFile())
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };
            var saveFileButton = new ToolStripButton(MainFormStrings.SaveFile, Resources.SaveFileIcon, (s, e) => SaveFile())
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };
            var exportButton = new ToolStripButton(MainFormStrings.Export, Resources.ExportIcon, (s, e) =>
            {
                if (!ExportManager.CanReExport)
                {
                    if (PluginManager.ScoreBookExportPlugins.Count() == 1)
                    {
                        ExportAs(PluginManager.ScoreBookExportPlugins.Single());
                        return;
                    }
                    MessageBox.Show(this, ErrorStrings.NotExported, Program.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }

                HandleExport(ScoreBook, ExportManager.PrepareReExport());
            })
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };

            var cutButton = new ToolStripButton(MainFormStrings.Cut, Resources.CutIcon, (s, e) => noteView.CutSelectedNotes())
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };
            var copyButton = new ToolStripButton(MainFormStrings.Copy, Resources.CopyIcon, (s, e) => noteView.CopySelectedNotes())
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };
            var pasteButton = new ToolStripButton(MainFormStrings.Paste, Resources.PasteIcon, (s, e) => noteView.PasteNotes())
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };

            var undoButton = new ToolStripButton(MainFormStrings.Undo, Resources.UndoIcon, (s, e) => OperationManager.Undo())
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image,
                Enabled      = false
            };
            var redoButton = new ToolStripButton(MainFormStrings.Redo, Resources.RedoIcon, (s, e) => OperationManager.Redo())
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image,
                Enabled      = false
            };

            var penButton = new ToolStripButton(MainFormStrings.Pen, Resources.EditIcon, (s, e) => noteView.EditMode = EditMode.Edit)
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };
            var selectionButton = new ToolStripButton(MainFormStrings.Selection, Resources.SelectionIcon, (s, e) => noteView.EditMode = EditMode.Select)
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };
            var eraserButton = new ToolStripButton(MainFormStrings.Eraser, Resources.EraserIcon, (s, e) => noteView.EditMode = EditMode.Erase)
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };

            var zoomInButton = new ToolStripButton(MainFormStrings.ZoomIn, Resources.ZoomInIcon)
            {
                Enabled      = noteView.UnitBeatHeight < 1920,
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };
            var zoomOutButton = new ToolStripButton(MainFormStrings.ZoomOut, Resources.ZoomOutIcon)
            {
                Enabled      = noteView.UnitBeatHeight > 30,
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };

            zoomInButton.Click += (s, e) =>
            {
                noteView.UnitBeatHeight *= 2;
                ApplicationSettings.Default.UnitBeatHeight = (int)noteView.UnitBeatHeight;
                zoomOutButton.Enabled = CanZoomOut;
                zoomInButton.Enabled  = CanZoomIn;
                UpdateThumbHeight();
            };

            zoomOutButton.Click += (s, e) =>
            {
                noteView.UnitBeatHeight /= 2;
                ApplicationSettings.Default.UnitBeatHeight = (int)noteView.UnitBeatHeight;
                zoomInButton.Enabled  = CanZoomIn;
                zoomOutButton.Enabled = CanZoomOut;
                UpdateThumbHeight();
            };

            ZoomInButton  = zoomInButton;
            ZoomOutButton = zoomOutButton;

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

            noteView.EditModeChanged += (s, e) =>
            {
                selectionButton.Checked = noteView.EditMode == EditMode.Select;
                penButton.Checked       = noteView.EditMode == EditMode.Edit;
                eraserButton.Checked    = noteView.EditMode == EditMode.Erase;
            };

            return(new ToolStrip(new ToolStripItem[]
            {
                newFileButton, openFileButton, saveFileButton, exportButton, new ToolStripSeparator(),
                cutButton, copyButton, pasteButton, new ToolStripSeparator(),
                undoButton, redoButton, new ToolStripSeparator(),
                penButton, selectionButton, eraserButton, new ToolStripSeparator(),
                zoomInButton, zoomOutButton
            }));
        }
Esempio n. 7
0
        private MainMenu CreateMainMenu(NoteView noteView)
        {
            var importPluginItems = PluginManager.ScoreBookImportPlugins.Select(p => new MenuItem(p.DisplayName, (s, e) =>
            {
                if (!ConfirmDiscardChanges())
                {
                    return;
                }
                if (!TrySelectOpeningFile(p.FileFilter, out string path))
                {
                    return;
                }

                using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read))
                {
                    var args = new ScoreBookImportPluginArgs(stream);
                    HandleImport(p, args);
                }
            })).ToArray();

            var exportPluginItems = PluginManager.ScoreBookExportPlugins.Select(p => new MenuItem(p.DisplayName, (s, e) =>
            {
                ExportAs(p);
            })).ToArray();

            var bookPropertiesMenuItem = new MenuItem(MainFormStrings.BookProperty, (s, e) =>
            {
                var vm     = new BookPropertiesWindowViewModel(ScoreBook, CurrentMusicSource);
                var window = new BookPropertiesWindow()
                {
                    DataContext = vm
                };
                window.ShowDialog(this);
            });

            var fileMenuItems = new MenuItem[]
            {
                new MenuItem(MainFormStrings.NewFile + "(&N)", (s, e) => ClearFile())
                {
                    Shortcut = Shortcut.CtrlN
                },
                new MenuItem(MainFormStrings.OpenFile + "(&O)", (s, e) => OpenFile())
                {
                    Shortcut = Shortcut.CtrlO
                },
                new MenuItem(MainFormStrings.SaveFile + "(&S)", (s, e) => SaveFile())
                {
                    Shortcut = Shortcut.CtrlS
                },
                new MenuItem(MainFormStrings.SaveAs + "(&A)", (s, e) => SaveAs())
                {
                    Shortcut = Shortcut.CtrlShiftS
                },
                new MenuItem("-"),
                new MenuItem(MainFormStrings.Import, importPluginItems)
                {
                    Enabled = importPluginItems.Length > 0
                },
                new MenuItem(MainFormStrings.Export, exportPluginItems)
                {
                    Enabled = exportPluginItems.Length > 0
                },
                new MenuItem("-"),
                bookPropertiesMenuItem,
                new MenuItem("-"),
                new MenuItem(MainFormStrings.Exit + "(&X)", (s, e) => this.Close())
            };

            var undoItem = new MenuItem(MainFormStrings.Undo, (s, e) => OperationManager.Undo())
            {
                Shortcut = Shortcut.CtrlZ,
                Enabled  = false
            };
            var redoItem = new MenuItem(MainFormStrings.Redo, (s, e) => OperationManager.Redo())
            {
                Shortcut = Shortcut.CtrlY,
                Enabled  = false
            };

            var cutItem          = new MenuItem(MainFormStrings.Cut, (s, e) => noteView.CutSelectedNotes(), Shortcut.CtrlX);
            var copyItem         = new MenuItem(MainFormStrings.Copy, (s, e) => noteView.CopySelectedNotes(), Shortcut.CtrlC);
            var pasteItem        = new MenuItem(MainFormStrings.Paste, (s, e) => noteView.PasteNotes(), Shortcut.CtrlV);
            var pasteFlippedItem = new MenuItem(MainFormStrings.PasteFlipped, (s, e) => noteView.PasteFlippedNotes(), Shortcut.CtrlShiftV);

            var selectAllItem          = new MenuItem(MainFormStrings.SelectAll, (s, e) => noteView.SelectAll(), Shortcut.CtrlA);
            var selectToEndItem        = new MenuItem(MainFormStrings.SelectToEnd, (s, e) => noteView.SelectToEnd());
            var selectoToBeginningItem = new MenuItem(MainFormStrings.SelectToBeginning, (s, e) => noteView.SelectToBeginning());

            var flipSelectedNotesItem   = new MenuItem(MainFormStrings.FlipSelectedNotes, (s, e) => noteView.FlipSelectedNotes());
            var removeSelectedNotesItem = new MenuItem(MainFormStrings.RemoveSelectedNotes, (s, e) => noteView.RemoveSelectedNotes(), Shortcut.Del);

            var removeEventsItem = new MenuItem(MainFormStrings.RemoveEvents, (s, e) =>
            {
                int minTick = noteView.SelectedRange.StartTick + (noteView.SelectedRange.Duration < 0 ? noteView.SelectedRange.Duration : 0);
                int maxTick = noteView.SelectedRange.StartTick + (noteView.SelectedRange.Duration < 0 ? 0 : noteView.SelectedRange.Duration);
                bool isContained(EventBase p) => p.Tick != 0 && minTick <= p.Tick && maxTick >= p.Tick;
                var events = ScoreBook.Score.Events;

                var bpmOp = events.BpmChangeEvents.Where(p => isContained(p)).ToList().Select(p =>
                {
                    ScoreBook.Score.Events.BpmChangeEvents.Remove(p);
                    return(new RemoveEventOperation <BpmChangeEvent>(events.BpmChangeEvents, p));
                }).ToList();

                var speedOp = events.HighSpeedChangeEvents.Where(p => isContained(p)).ToList().Select(p =>
                {
                    ScoreBook.Score.Events.HighSpeedChangeEvents.Remove(p);
                    return(new RemoveEventOperation <HighSpeedChangeEvent>(events.HighSpeedChangeEvents, p));
                }).ToList();

                var signatureOp = events.TimeSignatureChangeEvents.Where(p => isContained(p)).ToList().Select(p =>
                {
                    ScoreBook.Score.Events.TimeSignatureChangeEvents.Remove(p);
                    return(new RemoveEventOperation <TimeSignatureChangeEvent>(events.TimeSignatureChangeEvents, p));
                }).ToList();

                OperationManager.Push(new CompositeOperation("イベント削除", bpmOp.Cast <IOperation>().Concat(speedOp).Concat(signatureOp)));
                noteView.Invalidate();
            });

            var insertAirWithAirActionItem = new MenuItem(MainFormStrings.InsertAirWithAirAction, (s, e) =>
            {
                var item     = s as MenuItem;
                item.Checked = !item.Checked;
                NoteView.InsertAirWithAirAction = item.Checked;
                ApplicationSettings.Default.InsertAirWithAirAction = item.Checked;
            })
            {
                Checked = ApplicationSettings.Default.InsertAirWithAirAction
            };

            var pluginItems = PluginManager.ScorePlugins.Select(p => new MenuItem(p.DisplayName, (s, e) =>
            {
                CommitChanges();
                void updateScore(Score newScore)
                {
                    var op = new UpdateScoreOperation(ScoreBook.Score, newScore, score =>
                    {
                        ScoreBook.Score = score;
                        noteView.UpdateScore(score);
                    });
                    OperationManager.InvokeAndPush(op);
                }

                try
                {
                    p.Run(new ScorePluginArgs(() => ScoreBook.Score.Clone(), noteView.SelectedRange, updateScore));
                }
                catch (Exception ex)
                {
                    Program.DumpExceptionTo(ex, "plugin_exception.json");
                    MessageBox.Show(this, ErrorStrings.PluginException, Program.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            })).ToArray();
            var pluginItem = new MenuItem(MainFormStrings.Plugin, pluginItems)
            {
                Enabled = pluginItems.Length > 0
            };

            var editMenuItems = new MenuItem[]
            {
                undoItem, redoItem, new MenuItem("-"),
                cutItem, copyItem, pasteItem, pasteFlippedItem, new MenuItem("-"),
                selectAllItem, selectToEndItem, selectoToBeginningItem, new MenuItem("-"),
                flipSelectedNotesItem, removeSelectedNotesItem, removeEventsItem, new MenuItem("-"),
                insertAirWithAirActionItem, new MenuItem("-"),
                pluginItem
            };

            var viewModeItem = new MenuItem(MainFormStrings.ScorePreview, (s, e) =>
            {
                IsPreviewMode         = !IsPreviewMode;
                ((MenuItem)s).Checked = IsPreviewMode;
            }, Shortcut.CtrlP);

            WidenLaneWidthMenuItem  = new MenuItem(MainFormStrings.WidenLaneWidth);
            NarrowLaneWidthMenuItem = new MenuItem(MainFormStrings.NarrowLaneWidth);

            WidenLaneWidthMenuItem.Click += (s, e) =>
            {
                noteView.UnitLaneWidth += 4;
                ApplicationSettings.Default.UnitLaneWidth = noteView.UnitLaneWidth;
                WidenLaneWidthMenuItem.Enabled            = CanWidenLaneWidth;
                NarrowLaneWidthMenuItem.Enabled           = CanNarrowLaneWidth;
            };
            NarrowLaneWidthMenuItem.Click += (s, e) =>
            {
                noteView.UnitLaneWidth -= 4;
                ApplicationSettings.Default.UnitLaneWidth = noteView.UnitLaneWidth;
                WidenLaneWidthMenuItem.Enabled            = CanWidenLaneWidth;
                NarrowLaneWidthMenuItem.Enabled           = CanNarrowLaneWidth;
            };

            var viewMenuItems = new MenuItem[] {
                viewModeItem,
                new MenuItem("-"),
                WidenLaneWidthMenuItem, NarrowLaneWidthMenuItem
            };

            void UpdateEvent <T>(List <T> list, T item) where T : EventBase
            {
                var prev = list.SingleOrDefault(p => p.Tick == item.Tick);

                var insertOp = new InsertEventOperation <T>(list, item);

                if (prev == null)
                {
                    OperationManager.InvokeAndPush(insertOp);
                }
                else
                {
                    var removeOp = new RemoveEventOperation <T>(list, prev);
                    OperationManager.InvokeAndPush(new CompositeOperation(insertOp.Description, new IOperation[] { removeOp, insertOp }));
                }
                noteView.Invalidate();
            }

            var insertBpmItem = new MenuItem("BPM", (s, e) =>
            {
                var form = new BpmSelectionForm()
                {
                    Bpm = noteView.ScoreEvents.BpmChangeEvents.OrderBy(p => p.Tick).LastOrDefault(p => p.Tick <= noteView.CurrentTick)?.Bpm ?? 120
                };
                if (form.ShowDialog(this) != DialogResult.OK)
                {
                    return;
                }

                var item = new BpmChangeEvent()
                {
                    Tick = noteView.CurrentTick,
                    Bpm  = form.Bpm
                };
                UpdateEvent(noteView.ScoreEvents.BpmChangeEvents, item);
            });

            var insertHighSpeedItem = new MenuItem(MainFormStrings.HighSpeed, (s, e) =>
            {
                var form = new HighSpeedSelectionForm()
                {
                    SpeedRatio = noteView.ScoreEvents.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
                };
                UpdateEvent(noteView.ScoreEvents.HighSpeedChangeEvents, item);
            });

            var insertTimeSignatureItem = new MenuItem(MainFormStrings.TimeSignature, (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
                };
                UpdateEvent(noteView.ScoreEvents.TimeSignatureChangeEvents, item);
            });

            var insertMenuItems = new MenuItem[] { insertBpmItem, insertHighSpeedItem, insertTimeSignatureItem };

            var isAbortAtLastNoteItem = new MenuItem(MainFormStrings.AbortAtLastNote, (s, e) =>
            {
                var item     = s as MenuItem;
                item.Checked = !item.Checked;
                PreviewManager.IsStopAtLastNote = item.Checked;
                ApplicationSettings.Default.IsPreviewAbortAtLastNote = item.Checked;
            })
            {
                Checked = ApplicationSettings.Default.IsPreviewAbortAtLastNote
            };

            var playItem = new MenuItem(MainFormStrings.Play, (s, e) =>
            {
                if (string.IsNullOrEmpty(CurrentMusicSource?.FilePath))
                {
                    MessageBox.Show(this, ErrorStrings.MusicSourceNull, Program.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
                if (!File.Exists(CurrentMusicSource.FilePath))
                {
                    MessageBox.Show(this, ErrorStrings.SourceFileNotFound, Program.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                if (PreviewManager.Playing)
                {
                    PreviewManager.Stop();
                    return;
                }

                int startTick = noteView.CurrentTick;
                void lambda(object p, EventArgs q)
                {
                    isAbortAtLastNoteItem.Enabled = true;
                    PreviewManager.Finished      -= lambda;
                    noteView.CurrentTick          = startTick;
                    noteView.Editable             = CanEdit;
                }

                try
                {
                    CommitChanges();
                    var context = new SoundPreviewContext(ScoreBook.Score, CurrentMusicSource);
                    if (!PreviewManager.Start(context, startTick))
                    {
                        return;
                    }
                    isAbortAtLastNoteItem.Enabled = false;
                    PreviewManager.Finished      += lambda;
                    noteView.Editable             = CanEdit;
                }
                catch (Exception ex)
                {
                    Program.DumpExceptionTo(ex, "sound_exception.json");
                }
            }, (Shortcut)Keys.Space);

            var stopItem = new MenuItem(MainFormStrings.Stop, (s, e) =>
            {
                PreviewManager.Stop();
            });

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

            var helpMenuItems = new MenuItem[]
            {
                new MenuItem(MainFormStrings.Help, (s, e) => System.Diagnostics.Process.Start("https://github.com/paralleltree/Ched/wiki"), Shortcut.F1),
                new MenuItem(MainFormStrings.VersionInfo, (s, e) => new VersionInfoForm().ShowDialog(this))
            };

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

            return(new MainMenu(new MenuItem[]
            {
                new MenuItem(MainFormStrings.FileMenu, fileMenuItems),
                new MenuItem(MainFormStrings.EditMenu, editMenuItems),
                new MenuItem(MainFormStrings.ViewMenu, viewMenuItems),
                new MenuItem(MainFormStrings.InsertMenu, insertMenuItems),
                // PreviewManager初期化後じゃないといけないのダメ設計でしょ
                new MenuItem(MainFormStrings.PlayMenu, playMenuItems)
                {
                    Enabled = PreviewManager.IsSupported
                },
                new MenuItem(MainFormStrings.HelpMenu, helpMenuItems)
            }));
        }
Esempio n. 8
0
        private ToolStrip CreateMainToolStrip(NoteView noteView)
        {
            var newFileButton = new ToolStripButton(MainFormStrings.NewFile, Resources.NewFileIcon, (s, e) => ClearFile())
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };
            var openFileButton = new ToolStripButton(MainFormStrings.OpenFile, Resources.OpenFileIcon, (s, e) => OpenFile())
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };
            var saveFileButton = new ToolStripButton(MainFormStrings.SaveFile, Resources.SaveFileIcon, (s, e) => SaveFile())
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };
            var exportButton = new ToolStripButton(MainFormStrings.Export, Resources.ExportIcon, (s, e) =>
            {
                if (LastExportData == null)
                {
                    ExportFile();
                    return;
                }

                CommitChanges();
                try
                {
                    LastExportData.Exporter.Export(LastExportData.OutputPath, ScoreBook);
                    MessageBox.Show(this, ErrorStrings.ReExportComplete, Program.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(this, ErrorStrings.ExportFailed, Program.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    Program.DumpException(ex);
                }
            })
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };

            var cutButton = new ToolStripButton(MainFormStrings.Cut, Resources.CutIcon, (s, e) => noteView.CutSelectedNotes())
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };
            var copyButton = new ToolStripButton(MainFormStrings.Copy, Resources.CopyIcon, (s, e) => noteView.CopySelectedNotes())
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };
            var pasteButton = new ToolStripButton(MainFormStrings.Paste, Resources.PasteIcon, (s, e) => noteView.PasteNotes())
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };

            var undoButton = new ToolStripButton(MainFormStrings.Undo, Resources.UndoIcon, (s, e) => noteView.Undo())
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image,
                Enabled      = false
            };
            var redoButton = new ToolStripButton(MainFormStrings.Redo, Resources.RedoIcon, (s, e) => noteView.Redo())
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image,
                Enabled      = false
            };

            var penButton = new ToolStripButton(MainFormStrings.Pen, Resources.EditIcon, (s, e) => noteView.EditMode = EditMode.Edit)
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };
            var selectionButton = new ToolStripButton(MainFormStrings.Selection, Resources.SelectionIcon, (s, e) => noteView.EditMode = EditMode.Select)
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };
            var eraserButton = new ToolStripButton(MainFormStrings.Eraser, Resources.EraserIcon, (s, e) => noteView.EditMode = EditMode.Erase)
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };

            var zoomInButton = new ToolStripButton(MainFormStrings.ZoomIn, Resources.ZoomInIcon)
            {
                Enabled      = noteView.UnitBeatHeight < 1920,
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };
            var zoomOutButton = new ToolStripButton(MainFormStrings.ZoomOut, Resources.ZoomOutIcon)
            {
                Enabled      = noteView.UnitBeatHeight > 30,
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };

            zoomInButton.Click += (s, e) =>
            {
                noteView.UnitBeatHeight *= 2;
                ApplicationSettings.Default.UnitBeatHeight = (int)noteView.UnitBeatHeight;
                zoomOutButton.Enabled = CanZoomOut;
                zoomInButton.Enabled  = CanZoomIn;
                UpdateThumbHeight();
            };

            zoomOutButton.Click += (s, e) =>
            {
                noteView.UnitBeatHeight /= 2;
                ApplicationSettings.Default.UnitBeatHeight = (int)noteView.UnitBeatHeight;
                zoomInButton.Enabled  = CanZoomIn;
                zoomOutButton.Enabled = CanZoomOut;
                UpdateThumbHeight();
            };

            ZoomInButton  = zoomInButton;
            ZoomOutButton = zoomOutButton;

            OperationManager.OperationHistoryChanged += (s, e) =>
            {
                undoButton.Enabled = noteView.CanUndo;
                redoButton.Enabled = noteView.CanRedo;
            };

            noteView.EditModeChanged += (s, e) =>
            {
                selectionButton.Checked = noteView.EditMode == EditMode.Select;
                penButton.Checked       = noteView.EditMode == EditMode.Edit;
                eraserButton.Checked    = noteView.EditMode == EditMode.Erase;
            };

            return(new ToolStrip(new ToolStripItem[]
            {
                newFileButton, openFileButton, saveFileButton, exportButton, new ToolStripSeparator(),
                cutButton, copyButton, pasteButton, new ToolStripSeparator(),
                undoButton, redoButton, new ToolStripSeparator(),
                penButton, selectionButton, eraserButton, new ToolStripSeparator(),
                zoomInButton, zoomOutButton
            }));
        }
Esempio n. 9
0
        private MainMenu CreateMainMenu(NoteView noteView)
        {
            var importPluginItems = PluginManager.ScoreBookImportPlugins.Select(p => new MenuItem(p.DisplayName, (s, e) =>
            {
                OpenFile(p.FileFilter, q =>
                {
                    try
                    {
                        using (var reader = new StreamReader(q))
                            LoadBook(p.Import(reader));
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(this, ErrorStrings.ImportFailed, Program.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Error);
                        Program.DumpExceptionTo(ex, "import_exception.json");
                        LoadEmptyBook();
                    }
                });
            })).ToArray();

            var bookPropertiesMenuItem = new MenuItem(MainFormStrings.bookProperty, (s, e) =>
            {
                var form = new BookPropertiesForm(ScoreBook, CurrentMusicSource);
                if (form.ShowDialog(this) == DialogResult.OK)
                {
                    CurrentMusicSource = form.MusicSource;
                    if (string.IsNullOrEmpty(ScoreBook.Path))
                    {
                        return;
                    }
                    SoundSettings.Default.ScoreSound[ScoreBook.Path] = CurrentMusicSource;
                    SoundSettings.Default.Save();
                }
            });

            var fileMenuItems = new MenuItem[]
            {
                new MenuItem(MainFormStrings.NewFile + "(&N)", (s, e) => ClearFile())
                {
                    Shortcut = Shortcut.CtrlN
                },
                new MenuItem(MainFormStrings.OpenFile + "(&O)", (s, e) => OpenFile())
                {
                    Shortcut = Shortcut.CtrlO
                },
                new MenuItem(MainFormStrings.SaveFile + "(&S)", (s, e) => SaveFile())
                {
                    Shortcut = Shortcut.CtrlS
                },
                new MenuItem(MainFormStrings.SaveAs + "(&A)", (s, e) => SaveAs())
                {
                    Shortcut = Shortcut.CtrlShiftS
                },
                new MenuItem("-"),
                new MenuItem(MainFormStrings.Import, importPluginItems),
                new MenuItem(MainFormStrings.Export, (s, e) => ExportFile()),
                new MenuItem("-"),
                bookPropertiesMenuItem,
                new MenuItem("-"),
                new MenuItem(MainFormStrings.Exit + "(&X)", (s, e) => this.Close())
            };

            var undoItem = new MenuItem(MainFormStrings.Undo, (s, e) => noteView.Undo())
            {
                Shortcut = Shortcut.CtrlZ,
                Enabled  = false
            };
            var redoItem = new MenuItem(MainFormStrings.Redo, (s, e) => noteView.Redo())
            {
                Shortcut = Shortcut.CtrlY,
                Enabled  = false
            };

            var cutItem          = new MenuItem(MainFormStrings.Cut, (s, e) => noteView.CutSelectedNotes(), Shortcut.CtrlX);
            var copyItem         = new MenuItem(MainFormStrings.Copy, (s, e) => noteView.CopySelectedNotes(), Shortcut.CtrlC);
            var pasteItem        = new MenuItem(MainFormStrings.Paste, (s, e) => noteView.PasteNotes(), Shortcut.CtrlV);
            var pasteFlippedItem = new MenuItem(MainFormStrings.PasteFlipped, (s, e) => noteView.PasteFlippedNotes(), Shortcut.CtrlShiftV);

            var flipSelectedNotesItem   = new MenuItem(MainFormStrings.FlipSelectedNotes, (s, e) => noteView.FlipSelectedNotes());
            var removeSelectedNotesItem = new MenuItem(MainFormStrings.RemoveSelectedNotes, (s, e) => noteView.RemoveSelectedNotes(), Shortcut.Del);

            var removeEventsItem = new MenuItem(MainFormStrings.RemoveEvents, (s, e) =>
            {
                int minTick = noteView.SelectedRange.StartTick + (noteView.SelectedRange.Duration < 0 ? noteView.SelectedRange.Duration : 0);
                int maxTick = noteView.SelectedRange.StartTick + (noteView.SelectedRange.Duration < 0 ? 0 : noteView.SelectedRange.Duration);
                Func <EventBase, bool> isContained = p => p.Tick != 0 && minTick <= p.Tick && maxTick >= p.Tick;
                var events = ScoreBook.Score.Events;

                var bpmOp = events.BPMChangeEvents.Where(p => isContained(p)).ToList().Select(p =>
                {
                    ScoreBook.Score.Events.BPMChangeEvents.Remove(p);
                    return(new RemoveEventOperation <BPMChangeEvent>(events.BPMChangeEvents, p));
                }).ToList();

                var speedOp = events.HighSpeedChangeEvents.Where(p => isContained(p)).ToList().Select(p =>
                {
                    ScoreBook.Score.Events.HighSpeedChangeEvents.Remove(p);
                    return(new RemoveEventOperation <HighSpeedChangeEvent>(events.HighSpeedChangeEvents, p));
                }).ToList();

                var signatureOp = events.TimeSignatureChangeEvents.Where(p => isContained(p)).ToList().Select(p =>
                {
                    ScoreBook.Score.Events.TimeSignatureChangeEvents.Remove(p);
                    return(new RemoveEventOperation <TimeSignatureChangeEvent>(events.TimeSignatureChangeEvents, p));
                }).ToList();

                OperationManager.Push(new CompositeOperation("イベント削除", bpmOp.Cast <IOperation>().Concat(speedOp).Concat(signatureOp)));
                noteView.Invalidate();
            });

            var insertAirWithAirActionItem = new MenuItem(MainFormStrings.InsertAirWithAirAction, (s, e) =>
            {
                var item     = s as MenuItem;
                item.Checked = !item.Checked;
                NoteView.InsertAirWithAirAction = item.Checked;
                ApplicationSettings.Default.InsertAirWithAirAction = item.Checked;
            })
            {
                Checked = ApplicationSettings.Default.InsertAirWithAirAction
            };

            var pluginItems = PluginManager.ScorePlugins.Select(p => new MenuItem(p.DisplayName, (s, e) =>
            {
                CommitChanges();
                Action <Score> updateScore = newScore =>
                {
                    var op = new UpdateScoreOperation(ScoreBook.Score, newScore, score =>
                    {
                        ScoreBook.Score = score;
                        noteView.UpdateScore(score);
                    });
                    OperationManager.Push(op);
                    op.Redo();
                };

                try
                {
                    p.Run(new ScorePluginArgs(() => ScoreBook.Score.Clone(), noteView.SelectedRange, updateScore));
                }
                catch (Exception ex)
                {
                    Program.DumpExceptionTo(ex, "plugin_exception.json");
                    MessageBox.Show(this, ErrorStrings.PluginException, Program.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            })).ToArray();
            var pluginItem = new MenuItem(MainFormStrings.Plugin, pluginItems);

            var editMenuItems = new MenuItem[]
            {
                undoItem, redoItem, new MenuItem("-"),
                cutItem, copyItem, pasteItem, pasteFlippedItem, new MenuItem("-"),
                flipSelectedNotesItem, removeSelectedNotesItem, removeEventsItem, new MenuItem("-"),
                insertAirWithAirActionItem, new MenuItem("-"),
                pluginItem
            };

            var viewModeItem = new MenuItem(MainFormStrings.ScorePreview, (s, e) =>
            {
                IsPreviewMode         = !IsPreviewMode;
                ((MenuItem)s).Checked = IsPreviewMode;
            }, Shortcut.CtrlP);

            WidenLaneWidthMenuItem  = new MenuItem(MainFormStrings.WidenLaneWidth);
            NarrowLaneWidthMenuItem = new MenuItem(MainFormStrings.NarrowLaneWidth);

            WidenLaneWidthMenuItem.Click += (s, e) =>
            {
                noteView.UnitLaneWidth += 4;
                ApplicationSettings.Default.UnitLaneWidth = noteView.UnitLaneWidth;
                WidenLaneWidthMenuItem.Enabled            = CanWidenLaneWidth;
                NarrowLaneWidthMenuItem.Enabled           = CanNarrowLaneWidth;
            };
            NarrowLaneWidthMenuItem.Click += (s, e) =>
            {
                noteView.UnitLaneWidth -= 4;
                ApplicationSettings.Default.UnitLaneWidth = noteView.UnitLaneWidth;
                WidenLaneWidthMenuItem.Enabled            = CanWidenLaneWidth;
                NarrowLaneWidthMenuItem.Enabled           = CanNarrowLaneWidth;
            };

            var viewMenuItems = new MenuItem[] {
                viewModeItem,
                new MenuItem("-"),
                WidenLaneWidthMenuItem, NarrowLaneWidthMenuItem
            };

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

                var prev = noteView.ScoreEvents.BPMChangeEvents.SingleOrDefault(p => p.Tick == noteView.SelectedRange.StartTick);
                var item = new BPMChangeEvent()
                {
                    Tick = noteView.SelectedRange.StartTick,
                    BPM  = form.BPM
                };

                var insertOp = new InsertEventOperation <BPMChangeEvent>(noteView.ScoreEvents.BPMChangeEvents, item);
                if (prev == null)
                {
                    OperationManager.Push(insertOp);
                }
                else
                {
                    var removeOp = new RemoveEventOperation <BPMChangeEvent>(noteView.ScoreEvents.BPMChangeEvents, prev);
                    noteView.ScoreEvents.BPMChangeEvents.Remove(prev);
                    OperationManager.Push(new CompositeOperation(insertOp.Description, new IOperation[] { removeOp, insertOp }));
                }

                noteView.ScoreEvents.BPMChangeEvents.Add(item);
                noteView.Invalidate();
            });

            var insertHighSpeedItem = new MenuItem(MainFormStrings.HighSpeed, (s, e) =>
            {
                var form = new HighSpeedSelectionForm()
                {
                    SpeedRatio = noteView.ScoreEvents.HighSpeedChangeEvents.OrderBy(p => p.Tick).LastOrDefault(p => p.Tick <= noteView.CurrentTick)?.SpeedRatio ?? 1.0m
                };
                if (form.ShowDialog(this) != DialogResult.OK)
                {
                    return;
                }

                var prev = noteView.ScoreEvents.HighSpeedChangeEvents.SingleOrDefault(p => p.Tick == noteView.SelectedRange.StartTick);
                var item = new HighSpeedChangeEvent()
                {
                    Tick       = noteView.SelectedRange.StartTick,
                    SpeedRatio = form.SpeedRatio
                };

                var insertOp = new InsertEventOperation <HighSpeedChangeEvent>(noteView.ScoreEvents.HighSpeedChangeEvents, item);
                if (prev == null)
                {
                    OperationManager.Push(insertOp);
                }
                else
                {
                    var removeOp = new RemoveEventOperation <HighSpeedChangeEvent>(noteView.ScoreEvents.HighSpeedChangeEvents, prev);
                    noteView.ScoreEvents.HighSpeedChangeEvents.Remove(prev);
                    OperationManager.Push(new CompositeOperation(insertOp.Description, new IOperation[] { removeOp, insertOp }));
                }

                noteView.ScoreEvents.HighSpeedChangeEvents.Add(item);
                noteView.Invalidate();
            });

            var insertTimeSignatureItem = new MenuItem(MainFormStrings.TimeSignature, (s, e) =>
            {
                var form = new TimeSignatureSelectionForm();
                if (form.ShowDialog(this) != DialogResult.OK)
                {
                    return;
                }

                var prev = noteView.ScoreEvents.TimeSignatureChangeEvents.SingleOrDefault(p => p.Tick == noteView.SelectedRange.StartTick);
                var item = new TimeSignatureChangeEvent()
                {
                    Tick                = noteView.SelectedRange.StartTick,
                    Numerator           = form.Numerator,
                    DenominatorExponent = form.DenominatorExponent
                };

                var insertOp = new InsertEventOperation <TimeSignatureChangeEvent>(noteView.ScoreEvents.TimeSignatureChangeEvents, item);
                if (prev != null)
                {
                    noteView.ScoreEvents.TimeSignatureChangeEvents.Remove(prev);
                    var removeOp = new RemoveEventOperation <TimeSignatureChangeEvent>(noteView.ScoreEvents.TimeSignatureChangeEvents, prev);
                    OperationManager.Push(new CompositeOperation(insertOp.Description, new IOperation[] { removeOp, insertOp }));
                }
                else
                {
                    OperationManager.Push(insertOp);
                }

                noteView.ScoreEvents.TimeSignatureChangeEvents.Add(item);
                noteView.Invalidate();
            });

            var insertMenuItems = new MenuItem[] { insertBPMItem, insertHighSpeedItem, insertTimeSignatureItem };

            var isAbortAtLastNoteItem = new MenuItem(MainFormStrings.AbortAtLastNote, (s, e) =>
            {
                var item     = s as MenuItem;
                item.Checked = !item.Checked;
                PreviewManager.IsStopAtLastNote = item.Checked;
                ApplicationSettings.Default.IsPreviewAbortAtLastNote = item.Checked;
            })
            {
                Checked = ApplicationSettings.Default.IsPreviewAbortAtLastNote
            };

            var playItem = new MenuItem(MainFormStrings.Play, (s, e) =>
            {
                if (CurrentMusicSource == null)
                {
                    MessageBox.Show(this, ErrorStrings.MusicSourceNull, Program.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
                if (!File.Exists(CurrentMusicSource.FilePath))
                {
                    MessageBox.Show(this, ErrorStrings.SourceFileNotFound, Program.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                if (PreviewManager.Playing)
                {
                    PreviewManager.Stop();
                    return;
                }

                int startTick       = noteView.CurrentTick;
                EventHandler lambda = null;
                lambda = (p, q) =>
                {
                    isAbortAtLastNoteItem.Enabled = true;
                    PreviewManager.Finished      -= lambda;
                    noteView.CurrentTick          = startTick;
                };

                try
                {
                    if (!PreviewManager.Start(CurrentMusicSource, startTick))
                    {
                        return;
                    }
                    isAbortAtLastNoteItem.Enabled = false;
                    PreviewManager.Finished      += lambda;
                    noteView.Editable             = CanEdit;
                }
                catch (Exception ex)
                {
                    Program.DumpExceptionTo(ex, "sound_exception.json");
                }
            }, (Shortcut)Keys.Space);

            var stopItem = new MenuItem(MainFormStrings.Stop, (s, e) =>
            {
                PreviewManager.Stop();
            });

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

            var helpMenuItems = new MenuItem[]
            {
                new MenuItem(MainFormStrings.Help, (s, e) => System.Diagnostics.Process.Start("https://github.com/paralleltree/Ched/wiki"), Shortcut.F1),
                new MenuItem(MainFormStrings.VersionInfo, (s, e) => new VersionInfoForm().ShowDialog(this))
            };

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

            return(new MainMenu(new MenuItem[]
            {
                new MenuItem(MainFormStrings.FileMenu, fileMenuItems),
                new MenuItem(MainFormStrings.EditMenu, editMenuItems),
                new MenuItem(MainFormStrings.ViewMenu, viewMenuItems),
                new MenuItem(MainFormStrings.InsertMenu, insertMenuItems),
                // PreviewManager初期化後じゃないといけないのダメ設計でしょ
                new MenuItem(MainFormStrings.PlayMenu, playMenuItems)
                {
                    Enabled = PreviewManager.IsSupported
                },
                new MenuItem(MainFormStrings.HelpMenu, helpMenuItems)
            }));
        }
Esempio n. 10
0
        private ToolStrip CreateMainToolStrip(NoteView noteView)
        {
            var newFileButton = new ToolStripButton(MainFormStrings.NewFile, Resources.NewFileIcon, (s, e) => ClearFile())
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };
            var openFileButton = new ToolStripButton(MainFormStrings.OpenFile, Resources.OpenFileIcon, (s, e) => OpenFile())
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };
            var saveFileButton = new ToolStripButton(MainFormStrings.SaveFile, Resources.SaveFileIcon, (s, e) => SaveFile())
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };
            var exportButton = new ToolStripButton(MainFormStrings.Export, Resources.ExportIcon, (s, e) =>
            {
                if (LastExportData == null)
                {
                    ExportFile();
                    return;
                }

                HandleExport(LastExportData);
            })
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };

            var cutButton = new ToolStripButton(MainFormStrings.Cut, Resources.CutIcon, (s, e) => noteView.CutSelectedNotes())
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };
            var copyButton = new ToolStripButton(MainFormStrings.Copy, Resources.CopyIcon, (s, e) => noteView.CopySelectedNotes())
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };
            var pasteButton = new ToolStripButton(MainFormStrings.Paste, Resources.PasteIcon, (s, e) => noteView.PasteNotes())
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };

            var undoButton = new ToolStripButton(MainFormStrings.Undo, Resources.UndoIcon, (s, e) => noteView.Undo())
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image,
                Enabled      = false
            };
            var redoButton = new ToolStripButton(MainFormStrings.Redo, Resources.RedoIcon, (s, e) => noteView.Redo())
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image,
                Enabled      = false
            };

            var penButton = new ToolStripButton(MainFormStrings.Pen, Resources.EditIcon, (s, e) => noteView.EditMode = EditMode.Edit)
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };
            var selectionButton = new ToolStripButton(MainFormStrings.Selection, Resources.SelectionIcon, (s, e) => noteView.EditMode = EditMode.Select)
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };
            var eraserButton = new ToolStripButton(MainFormStrings.Eraser, Resources.EraserIcon, (s, e) => noteView.EditMode = EditMode.Erase)
            {
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };

            var zoomInButton = new ToolStripButton(MainFormStrings.ZoomIn, Resources.ZoomInIcon)
            {
                Enabled      = noteView.UnitBeatHeight < 1920,
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };
            var zoomOutButton = new ToolStripButton(MainFormStrings.ZoomOut, Resources.ZoomOutIcon)
            {
                Enabled      = noteView.UnitBeatHeight > 30,
                DisplayStyle = ToolStripItemDisplayStyle.Image
            };

            zoomInButton.Click += (s, e) =>
            {
                noteView.UnitBeatHeight *= 2;
                ApplicationSettings.Default.UnitBeatHeight = (int)noteView.UnitBeatHeight;
                zoomOutButton.Enabled = CanZoomOut;
                zoomInButton.Enabled  = CanZoomIn;
                UpdateThumbHeight();
            };

            zoomOutButton.Click += (s, e) =>
            {
                noteView.UnitBeatHeight /= 2;
                ApplicationSettings.Default.UnitBeatHeight = (int)noteView.UnitBeatHeight;
                zoomInButton.Enabled  = CanZoomIn;
                zoomOutButton.Enabled = CanZoomOut;
                UpdateThumbHeight();
            };

            ZoomInButton  = zoomInButton;
            ZoomOutButton = zoomOutButton;

            OperationManager.OperationHistoryChanged += (s, e) =>
            {
                undoButton.Enabled = noteView.CanUndo;
                redoButton.Enabled = noteView.CanRedo;
            };

            noteView.EditModeChanged += (s, e) =>
            {
                selectionButton.Checked = noteView.EditMode == EditMode.Select;
                penButton.Checked       = noteView.EditMode == EditMode.Edit;
                eraserButton.Checked    = noteView.EditMode == EditMode.Erase;
            };

            return(new ToolStrip(new ToolStripItem[]
            {
                newFileButton, openFileButton, saveFileButton, exportButton, new ToolStripSeparator(),
                cutButton, copyButton, pasteButton, new ToolStripSeparator(),
                undoButton, redoButton, new ToolStripSeparator(),
                penButton, selectionButton, eraserButton, new ToolStripSeparator(),
                zoomInButton, zoomOutButton
            }));
        }
Esempio n. 11
0
        private MainMenu CreateMainMenu(NoteView noteView)
        {
            var bookPropertiesMenuItem = new MenuItem("譜面プロパティ", (s, e) =>
            {
                var form = new BookPropertiesForm(ScoreBook, CurrentMusicSource);
                if (form.ShowDialog(this) == DialogResult.OK)
                {
                    CurrentMusicSource = form.MusicSource;
                    if (string.IsNullOrEmpty(ScoreBook.Path))
                    {
                        return;
                    }
                    SoundConfiguration.Default.ScoreSound[ScoreBook.Path] = CurrentMusicSource;
                    SoundConfiguration.Default.Save();
                }
            });

            var fileMenuItems = new MenuItem[]
            {
                new MenuItem("新規作成(&N)", (s, e) => ClearFile())
                {
                    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("エクスポート", (s, e) => ExportFile()),
                new MenuItem("-"),
                bookPropertiesMenuItem,
                new MenuItem("-"),
                new MenuItem("終了(&X)", (s, e) => this.Close())
            };

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

            var cutItem          = new MenuItem("切り取り", (s, e) => noteView.CutSelectedNotes(), Shortcut.CtrlX);
            var copyItem         = new MenuItem("コピー", (s, e) => noteView.CopySelectedNotes(), Shortcut.CtrlC);
            var pasteItem        = new MenuItem("貼り付け", (s, e) => noteView.PasteNotes(), Shortcut.CtrlV);
            var pasteFlippedItem = new MenuItem("反転貼り付け", (s, e) => noteView.PasteFlippedNotes(), Shortcut.CtrlShiftV);

            var flipSelectedNotesItem   = new MenuItem("選択範囲内ノーツを反転", (s, e) => noteView.FlipSelectedNotes());
            var removeSelectedNotesItem = new MenuItem("選択範囲内ノーツを削除", (s, e) => noteView.RemoveSelectedNotes(), Shortcut.Del);

            var removeEventsItem = new MenuItem("選択範囲内イベントを削除", (s, e) =>
            {
                int minTick = noteView.SelectedRange.StartTick + (noteView.SelectedRange.Duration < 0 ? noteView.SelectedRange.Duration : 0);
                int maxTick = noteView.SelectedRange.StartTick + (noteView.SelectedRange.Duration < 0 ? 0 : noteView.SelectedRange.Duration);
                Func <EventBase, bool> isContained = p => p.Tick != 0 && minTick <= p.Tick && maxTick >= p.Tick;
                var events = ScoreBook.Score.Events;

                var bpmOp = events.BPMChangeEvents.Where(p => isContained(p)).ToList().Select(p =>
                {
                    ScoreBook.Score.Events.BPMChangeEvents.Remove(p);
                    return(new RemoveEventOperation <BPMChangeEvent>(events.BPMChangeEvents, p));
                }).ToList();

                var speedOp = events.HighSpeedChangeEvents.Where(p => isContained(p)).ToList().Select(p =>
                {
                    ScoreBook.Score.Events.HighSpeedChangeEvents.Remove(p);
                    return(new RemoveEventOperation <HighSpeedChangeEvent>(events.HighSpeedChangeEvents, p));
                }).ToList();

                var signatureOp = events.TimeSignatureChangeEvents.Where(p => isContained(p)).ToList().Select(p =>
                {
                    ScoreBook.Score.Events.TimeSignatureChangeEvents.Remove(p);
                    return(new RemoveEventOperation <TimeSignatureChangeEvent>(events.TimeSignatureChangeEvents, p));
                }).ToList();

                OperationManager.Push(new CompositeOperation("イベント削除", bpmOp.Cast <IOperation>().Concat(speedOp).Concat(signatureOp)));
                noteView.Invalidate();
            });

            var pluginItems = PluginManager.ScorePlugins.Select(p => new MenuItem(p.DisplayName, (s, e) =>
            {
                CommitChanges();

                try
                {
                    p.Run(ScoreBook.Score);
                }
                catch (Exception ex)
                {
                    Program.DumpExceptionTo(ex, "plugin_exception.json");
                    MessageBox.Show(this, "プラグインの実行中にエラーが発生しました。", Program.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            })).ToArray();
            var pluginItem = new MenuItem("プラグイン", pluginItems);

            var editMenuItems = new MenuItem[]
            {
                undoItem, redoItem, new MenuItem("-"),
                cutItem, copyItem, pasteItem, pasteFlippedItem, new MenuItem("-"),
                flipSelectedNotesItem, removeSelectedNotesItem, removeEventsItem, new MenuItem("-"),
                pluginItem
            };

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

            var viewMenuItems = new MenuItem[] { viewModeItem };

            var insertBPMItem = new MenuItem("BPM", (s, e) =>
            {
                var form = new BPMSelectionForm();
                if (form.ShowDialog(this) != DialogResult.OK)
                {
                    return;
                }

                var prev = noteView.ScoreEvents.BPMChangeEvents.SingleOrDefault(p => p.Tick == noteView.SelectedRange.StartTick);
                var item = new Components.Events.BPMChangeEvent()
                {
                    Tick = noteView.SelectedRange.StartTick,
                    BPM  = form.BPM
                };

                var insertOp = new InsertEventOperation <Components.Events.BPMChangeEvent>(noteView.ScoreEvents.BPMChangeEvents, item);
                if (prev == null)
                {
                    OperationManager.Push(insertOp);
                }
                else
                {
                    var removeOp = new RemoveEventOperation <Components.Events.BPMChangeEvent>(noteView.ScoreEvents.BPMChangeEvents, prev);
                    noteView.ScoreEvents.BPMChangeEvents.Remove(prev);
                    OperationManager.Push(new CompositeOperation(insertOp.Description, new IOperation[] { removeOp, insertOp }));
                }

                noteView.ScoreEvents.BPMChangeEvents.Add(item);
                noteView.Invalidate();
            });

            var insertHighSpeedItem = new MenuItem("ハイスピード", (s, e) =>
            {
                var form = new HighSpeedSelectionForm();
                if (form.ShowDialog(this) != DialogResult.OK)
                {
                    return;
                }

                var prev = noteView.ScoreEvents.HighSpeedChangeEvents.SingleOrDefault(p => p.Tick == noteView.SelectedRange.StartTick);
                var item = new Components.Events.HighSpeedChangeEvent()
                {
                    Tick       = noteView.SelectedRange.StartTick,
                    SpeedRatio = form.SpeedRatio
                };

                var insertOp = new InsertEventOperation <Components.Events.HighSpeedChangeEvent>(noteView.ScoreEvents.HighSpeedChangeEvents, item);
                if (prev == null)
                {
                    OperationManager.Push(insertOp);
                }
                else
                {
                    var removeOp = new RemoveEventOperation <Components.Events.HighSpeedChangeEvent>(noteView.ScoreEvents.HighSpeedChangeEvents, prev);
                    noteView.ScoreEvents.HighSpeedChangeEvents.Remove(prev);
                    OperationManager.Push(new CompositeOperation(insertOp.Description, new IOperation[] { removeOp, insertOp }));
                }

                noteView.ScoreEvents.HighSpeedChangeEvents.Add(item);
                noteView.Invalidate();
            });

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

                var prev = noteView.ScoreEvents.TimeSignatureChangeEvents.SingleOrDefault(p => p.Tick == noteView.SelectedRange.StartTick);
                var item = new Components.Events.TimeSignatureChangeEvent()
                {
                    Tick                = noteView.SelectedRange.StartTick,
                    Numerator           = form.Numerator,
                    DenominatorExponent = form.DenominatorExponent
                };

                var insertOp = new InsertEventOperation <Components.Events.TimeSignatureChangeEvent>(noteView.ScoreEvents.TimeSignatureChangeEvents, item);
                if (prev != null)
                {
                    noteView.ScoreEvents.TimeSignatureChangeEvents.Remove(prev);
                    var removeOp = new RemoveEventOperation <Components.Events.TimeSignatureChangeEvent>(noteView.ScoreEvents.TimeSignatureChangeEvents, prev);
                    OperationManager.Push(new CompositeOperation(insertOp.Description, new IOperation[] { removeOp, insertOp }));
                }
                else
                {
                    OperationManager.Push(insertOp);
                }

                noteView.ScoreEvents.TimeSignatureChangeEvents.Add(item);
                noteView.Invalidate();
            });

            var insertMenuItems = new MenuItem[] { insertBPMItem, insertHighSpeedItem, insertTimeSignatureItem };

            var isAbortAtLastNoteItem = new MenuItem("最終ノートで停止", (s, e) =>
            {
                var item     = s as MenuItem;
                item.Checked = !item.Checked;
                PreviewManager.IsStopAtLastNote           = item.Checked;
                Settings.Default.IsPreviewAbortAtLastNote = item.Checked;
            })
            {
                Checked = Settings.Default.IsPreviewAbortAtLastNote
            };

            var playItem = new MenuItem("再生/停止", (s, e) =>
            {
                if (CurrentMusicSource == null)
                {
                    MessageBox.Show(this, "譜面プロパティから音源ファイルを指定してください。", Program.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
                if (!File.Exists(CurrentMusicSource.FilePath))
                {
                    MessageBox.Show(this, "音源ファイルが見つかりません。", Program.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                if (PreviewManager.Playing)
                {
                    PreviewManager.Stop();
                    return;
                }

                int startTick       = noteView.CurrentTick;
                EventHandler lambda = null;
                lambda = (p, q) =>
                {
                    isAbortAtLastNoteItem.Enabled = true;
                    PreviewManager.Finished      -= lambda;
                    noteView.CurrentTick          = startTick;
                };

                if (PreviewManager.Start(CurrentMusicSource, startTick))
                {
                    isAbortAtLastNoteItem.Enabled = false;
                    PreviewManager.Finished      += lambda;
                    noteView.Editable             = CanEdit;
                }
            }, (Shortcut)Keys.Space);

            var stopItem = new MenuItem("停止", (s, e) =>
            {
                PreviewManager.Stop();
            });

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

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

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

            return(new MainMenu(new MenuItem[]
            {
                new MenuItem("ファイル(&F)", fileMenuItems),
                new MenuItem("編集(&E)", editMenuItems),
                new MenuItem("表示(&V)", viewMenuItems),
                new MenuItem("挿入(&I)", insertMenuItems),
                // PreviewManager初期化後じゃないといけないのダメ設計でしょ
                new MenuItem("再生(&P)", playMenuItems)
                {
                    Enabled = PreviewManager.IsSupported
                },
                new MenuItem("ヘルプ(&H)", helpMenuItems)
            }));
        }
Esempio n. 12
0
        public bool Start(SoundSource music, int startTick)
        {
            if (Playing)
            {
                throw new InvalidOperationException();
            }
            if (music == null)
            {
                throw new ArgumentNullException("music");
            }
            SoundManager.Register(ClapSource.FilePath);
            SoundManager.Register(music.FilePath);
            EndTick = IsStopAtLastNote ? NoteView.Notes.GetLastTick() : GetTickFromTime(SoundManager.GetDuration(music.FilePath), NoteView.ScoreEvents.BPMChangeEvents);
            if (EndTick < startTick)
            {
                return(false);
            }

            var tickSet        = new HashSet <int>();
            var notes          = NoteView.Notes;
            var shortNotesTick = notes.Taps.Cast <TappableBase>().Concat(notes.ExTaps).Concat(notes.Flicks).Concat(notes.Damages).Select(p => p.Tick);
            var holdsTick      = notes.Holds.SelectMany(p => new int[] { p.StartTick, p.StartTick + p.Duration });
            var slidesTick     = notes.Slides.SelectMany(p => new int[] { p.StartTick }.Concat(p.StepNotes.Where(q => q.IsVisible).Select(q => q.Tick)));
            var airActionsTick = notes.AirActions.SelectMany(p => p.ActionNotes.Select(q => p.StartTick + q.Offset));

            foreach (int tick in shortNotesTick.Concat(holdsTick).Concat(slidesTick).Concat(airActionsTick))
            {
                tickSet.Add(tick);
            }
            TickElement = new LinkedList <int?>(tickSet.Where(p => p >= startTick).OrderBy(p => p).Select(p => new int?(p))).First;

            BPMElement = new LinkedList <BPMChangeEvent>(NoteView.ScoreEvents.BPMChangeEvents.OrderBy(p => p.Tick)).First;

            // スタート時まで進める
            while (TickElement != null && TickElement.Value < startTick)
            {
                TickElement = TickElement.Next;
            }
            while (BPMElement.Next != null && BPMElement.Next.Value.Tick <= startTick)
            {
                BPMElement = BPMElement.Next;
            }

            int clapLatencyTick = GetLatencyTick(ClapSource.Latency, (double)BPMElement.Value.BPM);

            InitialTick = startTick - clapLatencyTick;
            CurrentTick = InitialTick;
            StartTick   = startTick;

            TimeSpan startTime = GetTimeFromTick(startTick, NoteView.ScoreEvents.BPMChangeEvents);
            TimeSpan headGap   = TimeSpan.FromSeconds(-music.Latency) - startTime;

            elapsedTick = 0;
            Task.Run(() =>
            {
                LastSystemTick = Environment.TickCount;
                NoteView.Invoke((MethodInvoker)(() => Timer.Start()));

                System.Threading.Thread.Sleep(TimeSpan.FromSeconds(Math.Max(ClapSource.Latency, 0)));
                if (headGap.TotalSeconds > 0)
                {
                    System.Threading.Thread.Sleep(headGap);
                }
                if (!Playing)
                {
                    return;
                }
                SoundManager.Play(music.FilePath, startTime + TimeSpan.FromSeconds(music.Latency));
            })
            .ContinueWith(p =>
            {
                if (p.Exception != null)
                {
                    Program.DumpExceptionTo(p.Exception, "sound_exception.json");
                    ExceptionThrown?.Invoke(this, EventArgs.Empty);
                }
            });

            Playing = true;
            return(true);
        }
Esempio n. 13
0
 public SoundPreviewManager(NoteView noteView)
 {
     ClapSource  = new SoundSource("guide.mp3", 0.036);
     NoteView    = noteView;
     Timer.Tick += Tick;
 }
Esempio n. 14
0
        public MainForm()
        {
            InitializeComponent();
            Size = new Size(420, 700);
            Icon = Resources.MainIcon;

            ToolStripManager.RenderMode = ToolStripManagerRenderMode.System;

            OperationManager = new OperationManager();
            OperationManager.OperationHistoryChanged += (s, e) => SetText(ScoreBook.Path);
            OperationManager.ChangesCommited         += (s, e) => SetText(ScoreBook.Path);

            NoteView = new NoteView(OperationManager)
            {
                Dock           = DockStyle.Fill,
                UnitBeatHeight = Settings.Default.UnitBeatHeight
            };

            PreviewManager              = new SoundPreviewManager(NoteView);
            PreviewManager.Finished    += (s, e) => NoteView.Editable = CanEdit;
            PreviewManager.TickUpdated += (s, e) => NoteView.CurrentTick = e.Tick;

            NoteViewScrollBar = new VScrollBar()
            {
                Dock        = DockStyle.Right,
                Minimum     = -NoteView.UnitBeatTick * 4 * 20,
                SmallChange = NoteView.UnitBeatTick
            };

            Action <ScrollBar> processScrollBarRangeExtension = s =>
            {
                if (NoteViewScrollBar.Value < NoteViewScrollBar.Minimum * 0.9f)
                {
                    NoteViewScrollBar.Minimum = (int)(NoteViewScrollBar.Minimum * 1.2);
                }
            };

            NoteView.Resize += (s, e) => UpdateThumbHeight();

            NoteView.MouseWheel += (s, e) =>
            {
                int value = NoteViewScrollBar.Value - e.Delta / 120 * NoteViewScrollBar.SmallChange;
                NoteViewScrollBar.Value = Math.Min(Math.Max(value, NoteViewScrollBar.Minimum), NoteViewScrollBar.GetMaximumValue());
                processScrollBarRangeExtension(NoteViewScrollBar);
            };

            NoteView.DragScroll += (s, e) =>
            {
                NoteViewScrollBar.Value = Math.Max(-NoteView.HeadTick, NoteViewScrollBar.Minimum);
                processScrollBarRangeExtension(NoteViewScrollBar);
            };

            NoteViewScrollBar.ValueChanged += (s, e) =>
            {
                NoteView.HeadTick = -NoteViewScrollBar.Value / 60 * 60; // 60の倍数できれいに表示されるので…
                NoteView.Invalidate();
            };

            NoteViewScrollBar.Scroll += (s, e) =>
            {
                if (e.Type == ScrollEventType.EndScroll)
                {
                    processScrollBarRangeExtension(NoteViewScrollBar);
                }
            };

            AllowDrop  = true;
            DragEnter += (s, e) =>
            {
                e.Effect = DragDropEffects.None;
                if (e.Data.GetDataPresent(DataFormats.FileDrop))
                {
                    var items = (string[])e.Data.GetData(DataFormats.FileDrop);
                    if (items.Length == 1 && items.All(p => Path.GetExtension(p) == FileExtension && File.Exists(p)))
                    {
                        e.Effect = DragDropEffects.Copy;
                    }
                }
            };
            DragDrop += (s, e) =>
            {
                string path = ((string[])e.Data.GetData(DataFormats.FileDrop)).Single();
                if (OperationManager.IsChanged && !this.ConfirmDiscardChanges())
                {
                    return;
                }
                LoadFile(path);
            };

            FormClosing += (s, e) =>
            {
                if (OperationManager.IsChanged && !this.ConfirmDiscardChanges())
                {
                    e.Cancel = true;
                    return;
                }

                Settings.Default.Save();
            };

            using (var manager = this.WorkWithLayout())
            {
                this.Menu = CreateMainMenu(NoteView);
                this.Controls.Add(NoteView);
                this.Controls.Add(NoteViewScrollBar);
                this.Controls.Add(CreateNewNoteTypeToolStrip(NoteView));
                this.Controls.Add(CreateMainToolStrip(NoteView));
            }

            NoteView.NewNoteType = NoteType.Tap;
            NoteView.EditMode    = EditMode.Edit;

            LoadBook(new ScoreBook());
            SetText();

            if (!PreviewManager.IsSupported)
            {
                MessageBox.Show(this, "簡易プレビューが利用できない環境です。", Program.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }