2023-10-01 18:40:41 +02:00
using System ;
using System.Diagnostics ;
2023-10-01 21:40:27 +02:00
using System.IO ;
2023-10-01 18:40:41 +02:00
using System.Linq ;
using System.Windows.Forms ;
using TaikoSoundEditor.Commons.Controls ;
using TaikoSoundEditor.Commons.Utils ;
2023-07-17 10:20:00 +02:00
using TaikoSoundEditor.Data ;
namespace TaikoSoundEditor
{
public partial class MainForm : Form
{
public MainForm ( )
{
InitializeComponent ( ) ;
MusicAttributePathSelector . PathChanged + = MusicAttributePathSelector_PathChanged ;
MusicOrderPathSelector . PathChanged + = MusicOrderPathSelector_PathChanged ;
MusicInfoPathSelector . PathChanged + = MusicInfoPathSelector_PathChanged ;
WordListPathSelector . PathChanged + = WordListPathSelector_PathChanged ;
DirSelector . PathChanged + = DirSelector_PathChanged ;
2023-07-28 18:29:27 +02:00
2023-07-17 10:20:00 +02:00
AddedMusicBinding . DataSource = AddedMusic ;
NewSoundsBox . DataSource = AddedMusicBinding ;
2023-07-19 07:10:25 +02:00
TabControl . SelectedIndexChanged + = TabControl_SelectedIndexChanged ;
2023-07-28 18:29:27 +02:00
2023-08-16 18:40:36 +02:00
SimpleGenreBox . DataSource = Enum . GetValues ( typeof ( Genre ) ) ;
2023-09-18 17:53:43 +02:00
DatatableKeyBox . Text = Config . IniFile . Read ( "DatatableKey" ) ;
2023-10-01 18:40:41 +02:00
FumenKeyBox . Text = Config . IniFile . Read ( "FumenKey" ) ;
2023-09-18 17:53:43 +02:00
2023-10-01 21:40:27 +02:00
LoadPreferences ( ) ;
DatatableDef . Path = Config . DatatableDefPath ;
2023-08-16 18:40:36 +02:00
//SortByGenreToolStripMenuItem.RadioCheck = true;
2023-07-19 07:10:25 +02:00
}
private void TabControl_SelectedIndexChanged ( object sender , EventArgs e )
{
2023-07-30 07:32:58 +02:00
Logger . Info ( $"Commuted to tab {TabControl.SelectedIndex}.{TabControl.Name}" ) ;
2023-10-01 18:40:41 +02:00
}
2023-07-17 10:20:00 +02:00
#region Editor
2023-10-01 18:40:41 +02:00
private void LoadMusicInfo ( IMusicInfo item )
2023-07-19 12:07:56 +02:00
{
2023-07-19 07:10:25 +02:00
Logger . Info ( $"Showing properties for MusicInfo: {item}" ) ;
2023-07-19 12:07:56 +02:00
if ( item = = null )
{
MusicInfoGrid . SelectedObject = null ;
MusicAttributesGrid . SelectedObject = null ;
MusicOrderGrid . SelectedObject = null ;
WordsGrid . SelectedObject = null ;
WordSubGrid . SelectedObject = null ;
WordDetailGrid . SelectedObject = null ;
return ;
}
2023-07-17 10:20:00 +02:00
MusicInfoGrid . SelectedObject = item ;
MusicAttributesGrid . SelectedObject = MusicAttributes . GetByUniqueId ( item . UniqueId ) ;
MusicOrderGrid . SelectedObject = MusicOrders . GetByUniqueId ( item . UniqueId ) ;
WordsGrid . SelectedObject = WordList . GetBySong ( item . Id ) ;
WordSubGrid . SelectedObject = WordList . GetBySongSub ( item . Id ) ;
WordDetailGrid . SelectedObject = WordList . GetBySongDetail ( item . Id ) ;
2023-07-28 18:29:27 +02:00
simpleBoxLoading = true ;
SimpleIdBox . Text = item . Id ;
2023-07-30 07:18:54 +02:00
SimpleTitleBox . Text = WordList . GetBySong ( item . Id ) ? . JapaneseText ? ? throw new ArgumentNullException ( $"Title for '{item.Id}' not found in wordlist" ) ;
SimpleSubtitleBox . Text = WordList . GetBySongSub ( item . Id ) ? . JapaneseText ? ? throw new ArgumentNullException ( $"Subtitle for '{item.Id}' not found in wordlist" ) ;
SimpleDetailBox . Text = WordList . GetBySongDetail ( item . Id ) ? . JapaneseText ? ? throw new ArgumentNullException ( $"Detail for '{item.Id}' not found in wordlist" ) ;
SimpleGenreBox . SelectedItem = MusicOrders . GetByUniqueId ( item . UniqueId ) ? . Genre ? ? throw new ArgumentNullException ( $"Music order entry #{item.UniqueId} could not be found" ) ;
2023-07-28 18:29:27 +02:00
SimpleStarEasyBox . Value = item . StarEasy ;
SimpleStarNormalBox . Value = item . StarNormal ;
SimpleStarHardBox . Value = item . StarHard ;
SimpleStarManiaBox . Value = item . StarMania ;
SimpleStarUraBox . Value = item . StarUra ;
SimpleStarUraBox . Enabled = MusicAttributes . GetByUniqueId ( item . UniqueId ) . CanPlayUra ;
simpleBoxLoading = false ;
2023-07-17 10:20:00 +02:00
}
2023-07-19 12:07:56 +02:00
2023-07-28 18:02:47 +02:00
private void LoadNewSongData ( NewSongData item )
{
Logger . Info ( $"Selection Changed NewSongData: {item}" ) ;
Logger . Info ( $"Showing properties for NewSongData: {item}" ) ;
MusicInfoGrid . SelectedObject = item ? . MusicInfo ;
MusicAttributesGrid . SelectedObject = item ? . MusicAttribute ;
MusicOrderGrid . SelectedObject = item ? . MusicOrder ;
WordsGrid . SelectedObject = item ? . Word ;
WordSubGrid . SelectedObject = item ? . WordSub ;
WordDetailGrid . SelectedObject = item ? . WordDetail ;
indexChanging = false ;
2023-07-28 18:40:31 +02:00
if ( item = = null ) return ;
simpleBoxLoading = true ;
SimpleIdBox . Text = item . MusicInfo . Id ;
SimpleTitleBox . Text = item . Word . JapaneseText ;
SimpleSubtitleBox . Text = item . WordSub . JapaneseText ;
SimpleDetailBox . Text = item . WordDetail . JapaneseText ;
SimpleGenreBox . SelectedItem = item . MusicOrder . Genre ;
SimpleStarEasyBox . Value = item . MusicInfo . StarEasy ;
SimpleStarNormalBox . Value = item . MusicInfo . StarNormal ;
SimpleStarHardBox . Value = item . MusicInfo . StarHard ;
SimpleStarManiaBox . Value = item . MusicInfo . StarMania ;
SimpleStarUraBox . Value = item . MusicInfo . StarUra ;
SimpleStarUraBox . Enabled = item . MusicAttribute . CanPlayUra ;
simpleBoxLoading = false ;
2023-07-28 18:02:47 +02:00
}
2023-07-19 12:07:56 +02:00
private bool indexChanging = false ;
2023-07-17 10:20:00 +02:00
2023-07-30 07:32:58 +02:00
private void LoadedMusicBox_SelectedIndexChanged ( object sender , EventArgs e ) = > ExceptionGuard . Run ( ( ) = >
2023-07-17 10:20:00 +02:00
{
2023-07-19 12:07:56 +02:00
if ( indexChanging ) return ;
indexChanging = true ;
NewSoundsBox . SelectedItem = null ;
2023-10-01 18:40:41 +02:00
var item = LoadedMusicBox . SelectedItem as IMusicInfo ;
2023-07-19 07:10:25 +02:00
Logger . Info ( $"Selection Changed MusicItem: {item}" ) ;
2023-07-28 18:02:47 +02:00
LoadMusicInfo ( item ) ;
2023-07-19 12:07:56 +02:00
indexChanging = false ;
2023-07-30 08:51:24 +02:00
SoundViewTab . SelectedTab = SoundViewerSimple ;
2023-07-30 07:32:58 +02:00
} ) ;
2023-07-17 10:20:00 +02:00
2023-07-30 07:32:58 +02:00
private void EditorTable_Resize ( object sender , EventArgs e ) = > ExceptionGuard . Run ( ( ) = >
2023-07-17 10:20:00 +02:00
{
WordsGB . Height = WordSubGB . Height = WordDetailGB . Height = EditorTable . Height / 3 ;
2023-07-30 07:32:58 +02:00
} ) ;
2023-07-17 10:20:00 +02:00
2023-07-30 07:32:58 +02:00
private void NewSoundsBox_SelectedIndexChanged ( object sender , EventArgs e ) = > ExceptionGuard . Run ( ( ) = >
2023-07-17 10:20:00 +02:00
{
2023-07-19 12:07:56 +02:00
if ( indexChanging ) return ;
indexChanging = true ;
2023-07-30 07:32:58 +02:00
LoadedMusicBox . SelectedItem = null ;
2023-07-19 07:10:25 +02:00
var item = NewSoundsBox . SelectedItem as NewSongData ;
2023-07-28 18:02:47 +02:00
LoadNewSongData ( item ) ;
2023-07-30 08:51:24 +02:00
SoundViewTab . SelectedTab = SoundViewerSimple ;
2023-07-30 07:32:58 +02:00
} ) ;
2023-07-17 10:20:00 +02:00
2023-07-28 18:02:47 +02:00
#endregion
2023-07-19 12:07:56 +02:00
2023-07-29 08:53:20 +02:00
private void RemoveNewSong ( NewSongData ns )
{
AddedMusic . Remove ( ns ) ;
Logger . Info ( "Refreshing list" ) ;
AddedMusicBinding . ResetBindings ( false ) ;
2023-08-16 19:18:20 +02:00
MusicOrderViewer . RemoveAllSongs ( ns . MusicOrder . UniqueId ) ;
2023-07-29 08:53:20 +02:00
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 ) ;
}
2023-10-01 18:40:41 +02:00
private void RemoveExistingSong ( IMusicInfo mi )
2023-07-29 08:53:20 +02:00
{
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" ) ;
2023-07-31 19:17:21 +02:00
RefreshExistingSongsListView ( ) ;
2023-07-29 08:53:20 +02:00
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" ) ;
2023-08-16 19:18:20 +02:00
MusicOrderViewer . RemoveAllSongs ( mo . UniqueId ) ;
2023-07-29 08:53:20 +02:00
}
2023-07-28 18:02:47 +02:00
private void RemoveSongButton_Click ( object sender , EventArgs e ) = > ExceptionGuard . Run ( ( ) = >
2023-07-19 12:07:56 +02:00
{
Logger . Info ( "Clicked remove song" ) ;
if ( NewSoundsBox . SelectedItem ! = null )
{
Logger . Info ( "Removing newly added song" ) ;
2023-07-29 08:15:24 +02:00
var ns = NewSoundsBox . SelectedItem as NewSongData ;
2023-07-29 08:53:20 +02:00
RemoveNewSong ( ns ) ;
2023-07-19 12:07:56 +02:00
return ;
}
if ( LoadedMusicBox . SelectedItem ! = null )
{
Logger . Info ( "Removing existing song" ) ;
2023-10-01 18:40:41 +02:00
var mi = LoadedMusicBox . SelectedItem as IMusicInfo ;
2023-07-29 08:53:20 +02:00
RemoveExistingSong ( mi ) ;
2023-07-19 12:07:56 +02:00
return ;
}
2023-07-28 18:29:27 +02:00
} ) ;
2023-07-30 07:32:58 +02:00
private void SoundViewTab_SelectedIndexChanged ( object sender , EventArgs e ) = > ExceptionGuard . Run ( ( ) = >
2023-07-28 18:29:27 +02:00
{
2023-07-30 07:32:58 +02:00
if ( SoundViewTab . SelectedTab = = MusicOrderTab )
2023-07-29 07:58:11 +02:00
{
MusicOrderViewer . Invalidate ( ) ;
2023-07-28 21:28:05 +02:00
return ;
}
2023-07-28 18:29:27 +02:00
if ( ! ( SoundViewTab . SelectedTab = = SoundViewerExpert | | SoundViewTab . SelectedTab = = SoundViewerSimple ) )
2023-07-30 07:32:58 +02:00
return ;
2023-07-28 18:29:27 +02:00
if ( LoadedMusicBox . SelectedItem ! = null )
{
2023-10-01 18:40:41 +02:00
var item = LoadedMusicBox . SelectedItem as IMusicInfo ;
2023-07-28 18:29:27 +02:00
Logger . Info ( $"Tab switched, reloading MusicItem: {item}" ) ;
LoadMusicInfo ( item ) ;
return ;
}
2023-07-30 07:32:58 +02:00
if ( NewSoundsBox . SelectedItem ! = null )
2023-07-28 18:29:27 +02:00
{
var item = NewSoundsBox . SelectedItem as NewSongData ;
Logger . Info ( $"Tab switched, reloading NewSongData: {item}" ) ;
LoadNewSongData ( item ) ;
return ;
2023-07-30 07:32:58 +02:00
}
} ) ;
2023-07-28 18:29:27 +02:00
private bool simpleBoxLoading = false ;
private void SimpleBoxChanged ( object sender , EventArgs e ) = > ExceptionGuard . Run ( ( ) = >
{
if ( simpleBoxLoading ) return ;
if ( LoadedMusicBox . SelectedItem ! = null )
{
2023-10-01 18:40:41 +02:00
var item = LoadedMusicBox . SelectedItem as IMusicInfo ;
2023-07-28 18:29:27 +02:00
Logger . Info ( $"Simple Box changed : {(sender as Control).Name} to value {(sender as Control).Text}" ) ;
WordList . GetBySong ( item . Id ) . JapaneseText = SimpleTitleBox . Text ;
WordList . GetBySongSub ( item . Id ) . JapaneseText = SimpleSubtitleBox . Text ;
WordList . GetBySongDetail ( item . Id ) . JapaneseText = SimpleDetailBox . Text ;
2023-07-29 09:32:03 +02:00
MusicOrders . GetByUniqueId ( item . UniqueId ) . Genre = item . Genre = ( Genre ) ( SimpleGenreBox . SelectedItem ? ? Genre . Pop ) ;
2023-07-28 18:29:27 +02:00
item . StarEasy = ( int ) SimpleStarEasyBox . Value ;
item . StarNormal = ( int ) SimpleStarNormalBox . Value ;
item . StarHard = ( int ) SimpleStarHardBox . Value ;
item . StarMania = ( int ) SimpleStarManiaBox . Value ;
item . StarUra = ( int ) SimpleStarUraBox . Value ;
return ;
}
2023-07-28 18:40:31 +02:00
else if ( NewSoundsBox . SelectedItem ! = null )
{
var item = NewSoundsBox . SelectedItem as NewSongData ;
Logger . Info ( $"Simple Box changed : {(sender as Control).Name} to value {(sender as Control).Text}" ) ;
item . Word . JapaneseText = SimpleTitleBox . Text ;
item . WordSub . JapaneseText = SimpleSubtitleBox . Text ;
item . WordDetail . JapaneseText = SimpleDetailBox . Text ;
2023-07-29 10:06:11 +02:00
item . MusicOrder . Genre = item . MusicInfo . Genre = ( Genre ) ( SimpleGenreBox . SelectedItem ? ? Genre . Pop ) ;
2023-07-28 18:40:31 +02:00
item . MusicInfo . StarEasy = ( int ) SimpleStarEasyBox . Value ;
item . MusicInfo . StarNormal = ( int ) SimpleStarNormalBox . Value ;
item . MusicInfo . StarHard = ( int ) SimpleStarHardBox . Value ;
item . MusicInfo . StarMania = ( int ) SimpleStarManiaBox . Value ;
item . MusicInfo . StarUra = ( int ) SimpleStarUraBox . Value ;
return ;
}
2023-07-28 18:29:27 +02:00
} ) ;
2023-07-29 08:53:20 +02:00
2023-10-01 18:40:41 +02:00
private void MusicOrderViewer_SongRemoved ( MusicOrderViewer sender , IMusicOrder mo ) = > ExceptionGuard . Run ( ( ) = >
2023-07-29 08:53:20 +02:00
{
var uniqId = mo . UniqueId ;
2023-08-16 18:05:50 +02:00
if ( MusicOrderViewer . SongExists ( uniqId ) )
return ;
2023-07-29 08:53:20 +02:00
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." ) ;
} ) ;
2023-07-29 09:21:31 +02:00
2023-07-30 07:32:58 +02:00
private void LocateInMusicOrderButton_Click ( object sender , EventArgs e ) = > ExceptionGuard . Run ( ( ) = >
2023-07-29 09:21:31 +02:00
{
if ( LoadedMusicBox . SelectedItem ! = null )
{
2023-10-01 18:40:41 +02:00
var item = LoadedMusicBox . SelectedItem as IMusicInfo ;
2023-07-29 09:21:31 +02:00
var mo = MusicOrders . GetByUniqueId ( item . UniqueId ) ;
if ( MusicOrderViewer . Locate ( mo ) )
{
SoundViewTab . SelectedTab = MusicOrderTab ;
}
return ;
}
else if ( NewSoundsBox . SelectedItem ! = null )
{
var item = NewSoundsBox . SelectedItem as NewSongData ;
if ( MusicOrderViewer . Locate ( item . MusicOrder ) )
{
SoundViewTab . SelectedTab = MusicOrderTab ;
}
return ;
}
2023-07-30 07:32:58 +02:00
} ) ;
2023-07-31 18:45:26 +02:00
2023-10-01 18:40:41 +02:00
private void MusicOrderViewer_SongDoubleClick ( MusicOrderViewer sender , IMusicOrder mo )
2023-07-31 18:45:26 +02:00
{
var uid = mo . UniqueId ;
2023-10-01 18:40:41 +02:00
var mi = LoadedMusicBox . Items . Cast < IMusicInfo > ( ) . Where ( _ = > _ . UniqueId = = uid ) . FirstOrDefault ( ) ;
2023-07-31 18:45:26 +02:00
if ( mi ! = null )
{
LoadedMusicBox . SelectedItem = mi ;
return ;
}
var ns = AddedMusic . Where ( _ = > _ . UniqueId = = uid ) . FirstOrDefault ( ) ;
if ( ns ! = null )
{
NewSoundsBox . SelectedItem = ns ;
return ;
}
}
2023-07-31 19:17:21 +02:00
private void SearchBox_TextChanged ( object sender , EventArgs e )
{
RefreshExistingSongsListView ( ) ;
}
private void RefreshExistingSongsListView ( )
{
var list = MusicInfos . Items . Where ( mi = > mi . UniqueId ! = 0 )
. Where ( mi = >
{
if ( string . IsNullOrEmpty ( SearchBox . Text ) )
return true ;
if ( int . TryParse ( SearchBox . Text , out int uid ) & & mi . UniqueId = = uid )
{
return true ;
}
return mi . Id . Contains ( SearchBox . Text )
| | WordList . GetBySong ( mi . Id ) . JapaneseText . Contains ( SearchBox . Text )
| | WordList . GetBySongSub ( mi . Id ) . JapaneseText . Contains ( SearchBox . Text ) ;
} )
. ToList ( ) ;
LoadedMusicBox . DataSource = list ;
LoadedMusicBinding . ResetBindings ( false ) ;
}
2023-08-16 18:40:36 +02:00
private void MusicOrderSortToolStripMenuItem_Click ( object sender , EventArgs e )
{
SortByGenreToolStripMenuItem . Checked = SortByIdToolStripMenuItem . Checked = NoSortToolStripMenuItem . Checked = false ;
if ( sender = = SortByGenreToolStripMenuItem )
{
SortByGenreToolStripMenuItem . Checked = true ;
Config . SetMusicOrderSortByGenre ( ) ;
}
else if ( sender = = SortByIdToolStripMenuItem )
{
SortByIdToolStripMenuItem . Checked = true ;
Config . SetMusicOrderSortById ( ) ;
}
else //if (sender == NoSortToolStripMenuItem)
{
NoSortToolStripMenuItem . Checked = true ;
Config . SetMusicOrderNoSort ( ) ;
}
}
private void LoadPreferences ( )
{
var musicOrderSort = Config . IniFile . Read ( Config . MusicOrderSortProperty ) ;
if ( musicOrderSort = = Config . MusicOrderSortValueGenre )
{
SortByGenreToolStripMenuItem . PerformClick ( ) ;
}
else if ( musicOrderSort = = Config . MusicOrderSortValueId )
{
SortByIdToolStripMenuItem . PerformClick ( ) ;
}
else
{
NoSortToolStripMenuItem . PerformClick ( ) ;
}
}
2023-10-01 18:40:41 +02:00
private void checkForUpdatesToolStripMenuItem_Click ( object sender , EventArgs e ) = > ExceptionGuard . Run ( ( ) = >
2023-08-16 18:57:47 +02:00
{
//var rel = await Updates.GetLatestTja2Fumen();
} ) ;
2023-09-18 17:53:43 +02:00
private void DatatableKeyBox_TextChanged ( object sender , EventArgs e )
{
Config . IniFile . Write ( "DatatableKey" , DatatableKeyBox . Text ) ;
}
private void FumenKeyBox_TextChanged ( object sender , EventArgs e )
{
Config . IniFile . Write ( "FumenKey" , FumenKeyBox . Text ) ;
}
2023-10-01 18:40:41 +02:00
private void LoadedMusicBox_DrawItem ( object sender , DrawItemEventArgs e )
{
e . DrawBackground ( ) ;
if ( e . Index < 0 | | e . Index > = LoadedMusicBox . Items . Count )
return ;
var selItem = LoadedMusicBox . Items [ e . Index ] as IMusicInfo ;
TextRenderer . DrawText ( e . Graphics , $"{selItem.UniqueId}. {selItem.Id}" , Font , e . Bounds , e . ForeColor , e . BackColor , TextFormatFlags . Left | TextFormatFlags . VerticalCenter ) ;
e . DrawFocusRectangle ( ) ;
2023-10-01 21:40:27 +02:00
}
private void DatatableDef_PathChanged ( object sender , EventArgs args )
{
try
{
var json = File . ReadAllText ( DatatableDef . Path ) ;
DatatableTypes . LoadFromJson ( json ) ;
Config . DatatableDefPath = DatatableDef . Path ;
}
catch ( Exception e )
{
MessageBox . Show ( e . Message ) ;
}
2023-10-01 18:40:41 +02:00
}
2023-10-01 21:40:27 +02:00
2023-07-17 10:20:00 +02:00
}
}