diff --git a/Controls/MusicOrderViewer.Designer.cs b/Controls/MusicOrderViewer.Designer.cs index e198698..f457361 100644 --- a/Controls/MusicOrderViewer.Designer.cs +++ b/Controls/MusicOrderViewer.Designer.cs @@ -35,6 +35,7 @@ this.CutButton = new System.Windows.Forms.Button(); this.PageLabel = new System.Windows.Forms.Label(); this.LeftButton = new System.Windows.Forms.Button(); + this.RemoveButton = new System.Windows.Forms.Button(); this.ControlsPanel.SuspendLayout(); this.SuspendLayout(); // @@ -64,6 +65,7 @@ // // ControlsPanel // + this.ControlsPanel.Controls.Add(this.RemoveButton); this.ControlsPanel.Controls.Add(this.PasteButton); this.ControlsPanel.Controls.Add(this.CutButton); this.ControlsPanel.Controls.Add(this.PageLabel); @@ -120,6 +122,19 @@ this.LeftButton.UseVisualStyleBackColor = true; this.LeftButton.Click += new System.EventHandler(this.LeftButton_Click); // + // RemoveButton + // + this.RemoveButton.BackgroundImage = global::TaikoSoundEditor.Properties.Resources.ic_remove_gs; + this.RemoveButton.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom; + this.RemoveButton.FlatAppearance.BorderSize = 0; + this.RemoveButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.RemoveButton.Location = new System.Drawing.Point(63, 3); + this.RemoveButton.Name = "RemoveButton"; + this.RemoveButton.Size = new System.Drawing.Size(24, 24); + this.RemoveButton.TabIndex = 3; + this.RemoveButton.UseVisualStyleBackColor = true; + this.RemoveButton.Click += new System.EventHandler(this.RemoveButton_Click); + // // MusicOrderViewer // this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); @@ -145,5 +160,6 @@ private Label PageLabel; private Button CutButton; private Button PasteButton; + private Button RemoveButton; } } diff --git a/Controls/MusicOrderViewer.cs b/Controls/MusicOrderViewer.cs index 05cd241..32c64bb 100644 --- a/Controls/MusicOrderViewer.cs +++ b/Controls/MusicOrderViewer.cs @@ -1,6 +1,7 @@ using System.Diagnostics; using System.Drawing.Drawing2D; using TaikoSoundEditor.Data; +using TaikoSoundEditor.Extensions; using TaikoSoundEditor.Properties; namespace TaikoSoundEditor.Controls @@ -33,8 +34,9 @@ namespace TaikoSoundEditor.Controls CutSelection.RemoveWhere(c => c.MusicOrder == mo); PasteActive = CutSelection.Count > 0; - CutActive = Selection.Count > 0; + CutActive = RemoveActive = Selection.Count > 0; if (!PasteActive) PasteMode = false; + CurrentPage = CurrentPage; Invalidate(); } @@ -44,7 +46,7 @@ namespace TaikoSoundEditor.Controls get => _CurrentPage; set { - _CurrentPage = value; + _CurrentPage = value.Clamp(0, PagesCount - 1); PageLabel.Text = $"Page {_CurrentPage + 1} of {PagesCount}"; MusicOrdersPanel.Invalidate(); @@ -247,7 +249,7 @@ namespace TaikoSoundEditor.Controls CutSelection.Clear(); PasteMode = false; PasteActive = false; - CutActive = false; + CutActive = RemoveActive = false; MusicOrdersPanel.Invalidate(); return; @@ -284,7 +286,7 @@ namespace TaikoSoundEditor.Controls MusicOrdersPanel.Invalidate(); } - CutActive = Selection.Count > 0; + CutActive = RemoveActive = Selection.Count > 0; } private bool _CutActive = false; @@ -311,6 +313,19 @@ namespace TaikoSoundEditor.Controls } } + private bool _RemoveActive=false; + + public bool RemoveActive + { + get => _RemoveActive; + set + { + _RemoveActive = value; + RemoveButton.BackgroundImage = RemoveActive ? Resources.ic_remove : Resources.ic_remove_gs; + RemoveButton.Enabled = RemoveActive; + } + } + private void CutButton_Click(object sender, EventArgs e) { PasteMode = false; @@ -329,7 +344,7 @@ namespace TaikoSoundEditor.Controls Selection.Clear(); PasteActive = CutSelection.Count > 0; - CutActive= Selection.Count > 0; + CutActive = RemoveActive = Selection.Count > 0; MusicOrdersPanel.Invalidate(); } @@ -344,7 +359,8 @@ namespace TaikoSoundEditor.Controls _PasteMode = value; PasteButton.FlatAppearance.BorderSize = _PasteMode ? 1 : 0; } - } + } + private void PasteButton_Click(object sender, EventArgs e) { @@ -353,7 +369,37 @@ namespace TaikoSoundEditor.Controls foreach (var card in Selection) card.IsSelected = false; Selection.Clear(); + CutActive = RemoveActive = false; MusicOrdersPanel.Invalidate(); } + + private void RemoveButton_Click(object sender, EventArgs e) + { + var toRemove = Selection.ToList(); + if (Selection.Count == 0) + return; + + var message = $"Are you sure you want to remove {toRemove.Count} song{(toRemove.Count>0?"s":"")}?"; + + if (MessageBox.Show(message, "Remove?", MessageBoxButtons.YesNo) != DialogResult.Yes) + return; + + foreach(var card in Selection) + { + SongCards.Remove(card); + CutSelection.Remove(card); + SongRemoved?.Invoke(this, card.MusicOrder); + } + Selection.Clear(); + + CutActive = RemoveActive = false; + PasteActive = CutSelection.Count > 0; + if (!PasteActive) PasteMode = false; + CurrentPage = CurrentPage; + MusicOrdersPanel.Invalidate(); + } + + public delegate void OnSongRemoved(MusicOrderViewer sender, MusicOrder mo); + public event OnSongRemoved SongRemoved; } } diff --git a/MainForm.Designer.cs b/MainForm.Designer.cs index 96cdbd9..800af6a 100644 --- a/MainForm.Designer.cs +++ b/MainForm.Designer.cs @@ -803,13 +803,18 @@ // MusicOrderViewer // this.MusicOrderViewer.CurrentPage = 0; + this.MusicOrderViewer.CutActive = false; this.MusicOrderViewer.Dock = System.Windows.Forms.DockStyle.Fill; this.MusicOrderViewer.ItemsPerCol = 5; this.MusicOrderViewer.ItemsPerRow = 4; this.MusicOrderViewer.Location = new System.Drawing.Point(3, 3); this.MusicOrderViewer.Name = "MusicOrderViewer"; + this.MusicOrderViewer.PasteActive = false; + this.MusicOrderViewer.PasteMode = false; + this.MusicOrderViewer.RemoveActive = false; this.MusicOrderViewer.Size = new System.Drawing.Size(515, 290); this.MusicOrderViewer.TabIndex = 0; + this.MusicOrderViewer.SongRemoved += new TaikoSoundEditor.Controls.MusicOrderViewer.OnSongRemoved(this.MusicOrderViewer_SongRemoved); // // RemoveSongButton // diff --git a/MainForm.cs b/MainForm.cs index e3eb86e..23e20fd 100644 --- a/MainForm.cs +++ b/MainForm.cs @@ -123,6 +123,57 @@ namespace TaikoSoundEditor #endregion + private void RemoveNewSong(NewSongData ns) + { + AddedMusic.Remove(ns); + Logger.Info("Refreshing list"); + AddedMusicBinding.ResetBindings(false); + MusicOrderViewer.RemoveSong(ns.MusicOrder); + + Logger.Info("Removing from wordlist & music_attributes"); + WordList.Items.Remove(ns.Word); + WordList.Items.Remove(ns.WordDetail); + WordList.Items.Remove(ns.WordSub); + MusicAttributes.Items.Remove(ns.MusicAttribute); + } + + private void RemoveExistingSong(MusicInfo mi) + { + var ma = MusicAttributes.GetByUniqueId(mi.UniqueId); + var mo = MusicOrders.GetByUniqueId(mi.UniqueId); + var w = WordList.GetBySong(mi.Id); + var ws = WordList.GetBySongSub(mi.Id); + var wd = WordList.GetBySongDetail(mi.Id); + + Logger.Info("Removing music info"); + MusicInfos.Items.RemoveAll(x => x.UniqueId == mi.UniqueId); + Logger.Info("Removing music attribute"); + MusicAttributes.Items.Remove(ma); + Logger.Info("Removing music order"); + MusicOrders.Items.Remove(mo); + Logger.Info("Removing word"); + WordList.Items.Remove(w); + Logger.Info("Removing word sub"); + WordList.Items.Remove(ws); + Logger.Info("Removing word detail"); + WordList.Items.Remove(wd); + + Logger.Info("Refreshing list"); + LoadedMusicBinding.DataSource = MusicInfos.Items.Where(mi => mi.UniqueId != 0).ToList(); + LoadedMusicBinding.ResetBindings(false); + + var sel = LoadedMusicBox.SelectedIndex; + + if (sel >= MusicInfos.Items.Count) + sel = MusicInfos.Items.Count - 1; + + LoadedMusicBox.SelectedItem = null; + LoadedMusicBox.SelectedIndex = sel; + + Logger.Info("Removing from music orders"); + MusicOrderViewer.RemoveSong(mo); + } + private void RemoveSongButton_Click(object sender, EventArgs e) => ExceptionGuard.Run(() => { Logger.Info("Clicked remove song"); @@ -130,17 +181,7 @@ namespace TaikoSoundEditor { Logger.Info("Removing newly added song"); var ns = NewSoundsBox.SelectedItem as NewSongData; - AddedMusic.Remove(ns); - Logger.Info("Refreshing list"); - AddedMusicBinding.ResetBindings(false); - MusicOrderViewer.RemoveSong(ns.MusicOrder); - - Logger.Info("Removing from wordlist & music_attributes"); - WordList.Items.Remove(ns.Word); - WordList.Items.Remove(ns.WordDetail); - WordList.Items.Remove(ns.WordSub); - MusicAttributes.Items.Remove(ns.MusicAttribute); - + RemoveNewSong(ns); return; } @@ -148,40 +189,7 @@ namespace TaikoSoundEditor { Logger.Info("Removing existing song"); var mi = LoadedMusicBox.SelectedItem as MusicInfo; - var ma = MusicAttributes.GetByUniqueId(mi.UniqueId); - var mo = MusicOrders.GetByUniqueId(mi.UniqueId); - var w = WordList.GetBySong(mi.Id); - var ws = WordList.GetBySongSub(mi.Id); - var wd = WordList.GetBySongDetail(mi.Id); - - Logger.Info("Removing music info"); - MusicInfos.Items.RemoveAll(x => x.UniqueId == mi.UniqueId); - Logger.Info("Removing music attribute"); - MusicAttributes.Items.Remove(ma); - Logger.Info("Removing music order"); - MusicOrders.Items.Remove(mo); - Logger.Info("Removing word"); - WordList.Items.Remove(w); - Logger.Info("Removing word sub"); - WordList.Items.Remove(ws); - Logger.Info("Removing word detail"); - WordList.Items.Remove(wd); - - Logger.Info("Refreshing list"); - LoadedMusicBinding.DataSource = MusicInfos.Items.Where(mi => mi.UniqueId != 0).ToList(); - LoadedMusicBinding.ResetBindings(false); - - var sel = LoadedMusicBox.SelectedIndex; - - if (sel >= MusicInfos.Items.Count) - sel = MusicInfos.Items.Count - 1; - - LoadedMusicBox.SelectedItem = null; - LoadedMusicBox.SelectedIndex = sel; - - Logger.Info("Removing from music orders"); - MusicOrderViewer.RemoveSong(mo); - + RemoveExistingSong(mi); return; } }); @@ -255,5 +263,25 @@ namespace TaikoSoundEditor return; } }); + + private void MusicOrderViewer_SongRemoved(Controls.MusicOrderViewer sender, MusicOrder mo) => ExceptionGuard.Run(() => + { + var uniqId = mo.UniqueId; + var mi = MusicInfos.Items.Where(x => x.UniqueId == uniqId).FirstOrDefault(); + + if (mi != null) + { + RemoveExistingSong(mi); + return; + } + + var ns = AddedMusic.Where(x => x.UniqueId == uniqId).FirstOrDefault(); + if (ns != null) + { + RemoveNewSong(ns); + return; + } + throw new InvalidOperationException("Nothing to remove."); + }); } } \ No newline at end of file diff --git a/Properties/Resources.Designer.cs b/Properties/Resources.Designer.cs index 83502aa..33f3730 100644 --- a/Properties/Resources.Designer.cs +++ b/Properties/Resources.Designer.cs @@ -100,6 +100,26 @@ namespace TaikoSoundEditor.Properties { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap ic_remove { + get { + object obj = ResourceManager.GetObject("ic_remove", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap ic_remove_gs { + get { + object obj = ResourceManager.GetObject("ic_remove_gs", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Byte[]. /// diff --git a/Properties/Resources.resx b/Properties/Resources.resx index 22cdd7a..c06419e 100644 --- a/Properties/Resources.resx +++ b/Properties/Resources.resx @@ -130,6 +130,12 @@ ..\Resources\ic_paste_gs.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\ic_remove.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\ic_remove_gs.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\song_ABCDEF_nus3bank.bin;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 diff --git a/Resources/ic_remove.png b/Resources/ic_remove.png new file mode 100644 index 0000000..22babd5 Binary files /dev/null and b/Resources/ic_remove.png differ diff --git a/Resources/ic_remove_gs.png b/Resources/ic_remove_gs.png new file mode 100644 index 0000000..556c464 Binary files /dev/null and b/Resources/ic_remove_gs.png differ