2013-08-09 02:54:59 +00:00
using System ;
using System.Collections.Generic ;
using System.Drawing ;
using System.Linq ;
using System.Windows.Forms ;
2013-10-25 00:57:23 +00:00
using BizHawk.Client.Common ;
2013-11-03 03:54:37 +00:00
namespace BizHawk.Client.EmuHawk
2013-08-09 02:54:59 +00:00
{
2013-10-06 20:45:04 +00:00
public partial class PathConfig : Form
2013-08-09 02:54:59 +00:00
{
2013-12-22 18:36:27 +00:00
// All path text boxes should do some kind of error checking
// Config path under base, config will default to %exe%
private bool _preventSelectedChangeEvent ; // Selected Index Changed events are a pain
2013-08-23 16:03:57 +00:00
private void LockDownCores ( )
{
2013-12-22 18:36:27 +00:00
if ( VersionInfo . INTERIM )
{
return ;
}
2013-11-28 01:33:38 +00:00
string [ ] coresToHide = { "PSX" , "GBA" , "INTV" , "C64" , "GEN" } ;
2013-08-23 16:03:57 +00:00
2013-11-28 01:33:38 +00:00
foreach ( var core in coresToHide )
{
PathTabControl . TabPages . Remove (
AllTabPages . FirstOrDefault ( x = > x . Name = = core ) ? ? new TabPage ( )
2013-11-15 22:27:20 +00:00
) ;
2013-08-23 16:03:57 +00:00
}
}
2013-11-28 01:33:38 +00:00
private static AutoCompleteStringCollection AutoCompleteOptions
2013-08-23 16:03:57 +00:00
{
get
{
2013-11-15 22:27:20 +00:00
return new AutoCompleteStringCollection
2013-09-22 16:13:28 +00:00
{
"%recent%" ,
"%exe%" ,
".\\" ,
"..\\" ,
} ;
2013-08-23 16:03:57 +00:00
}
}
2013-08-12 19:30:05 +00:00
2013-10-06 20:45:04 +00:00
public PathConfig ( )
2013-08-09 02:54:59 +00:00
{
InitializeComponent ( ) ;
}
private void LoadSettings ( )
2013-08-11 14:28:14 +00:00
{
RecentForROMs . Checked = Global . Config . UseRecentForROMs ;
2013-12-13 05:20:50 +00:00
BasePathBox . Text = Global . Config . PathEntries . GlobalBaseFragment ;
2013-11-15 23:32:06 +00:00
StartTabPages ( ) ;
2013-08-11 14:28:14 +00:00
SetDefaultFocusedTab ( ) ;
2013-11-15 22:27:20 +00:00
DoRomToggle ( ) ;
2013-08-11 14:28:14 +00:00
}
private void SetDefaultFocusedTab ( )
{
2013-08-23 16:03:57 +00:00
PathTabControl . SelectTab ( FindTabByName ( Global . Game . System ) ) ;
2013-08-11 14:28:14 +00:00
}
private TabPage FindTabByName ( string name )
{
2013-11-28 01:33:38 +00:00
return PathTabControl . TabPages
. OfType < TabPage > ( )
. FirstOrDefault ( x = > x . Name . ToUpper ( ) . Contains ( name . ToUpper ( ) ) )
? ? new TabPage ( ) ;
2013-08-11 14:28:14 +00:00
}
2013-11-15 23:32:06 +00:00
private void StartTabPages ( )
{
PathTabControl . TabPages . Clear ( ) ;
2013-11-28 01:33:38 +00:00
var systems = Global . Config . PathEntries . Select ( x = > x . SystemDisplayName ) . Distinct ( ) . ToList ( ) ;
2013-11-15 23:32:06 +00:00
systems . Sort ( ) ;
2013-11-28 01:33:38 +00:00
foreach ( var systemDisplayName in systems )
2013-11-15 23:32:06 +00:00
{
PathTabControl . TabPages . Add ( new TabPage
{
Text = systemDisplayName ,
Name = Global . Config . PathEntries . FirstOrDefault ( x = > x . SystemDisplayName = = systemDisplayName ) . System
} ) ;
}
}
private void DoTabPage ( TabPage tabPage )
{
const int xpos = 6 ;
int textboxWidth = tabPage . Width - 150 ;
const int padding = 5 ;
const int buttonWidth = 26 ;
int widgetOffset = textboxWidth + 15 ;
const int rowHeight = 30 ;
2013-11-28 01:33:38 +00:00
var paths = Global . Config . PathEntries . Where ( x = > x . System = = tabPage . Name ) . OrderBy ( x = > x . Ordinal ) . ThenBy ( x = > x . Type ) . ToList ( ) ;
2013-11-15 23:32:06 +00:00
int ypos = 14 ;
foreach ( var path in paths )
{
2013-11-28 01:33:38 +00:00
var box = new TextBox
2013-11-15 23:32:06 +00:00
{
Text = path . Path ,
Location = new Point ( xpos , ypos ) ,
Width = textboxWidth ,
Name = path . Type ,
Anchor = AnchorStyles . Top | AnchorStyles . Left | AnchorStyles . Right ,
MinimumSize = new Size ( 26 , 23 ) ,
AutoCompleteMode = AutoCompleteMode . SuggestAppend ,
AutoCompleteCustomSource = AutoCompleteOptions ,
AutoCompleteSource = AutoCompleteSource . CustomSource ,
} ;
2013-11-28 01:33:38 +00:00
var btn = new Button
2013-11-15 23:32:06 +00:00
{
Text = String . Empty ,
Image = Properties . Resources . OpenFile ,
Location = new Point ( widgetOffset , ypos - 1 ) ,
Width = buttonWidth ,
Name = path . Type ,
Anchor = AnchorStyles . Top | AnchorStyles . Right ,
} ;
2013-11-28 01:33:38 +00:00
var tempBox = box ;
var tempPath = path . Type ;
var tempSystem = path . System ;
2013-11-15 23:32:06 +00:00
btn . Click + = delegate
{
BrowseFolder ( tempBox , tempPath , tempSystem ) ;
} ;
2013-12-19 18:18:40 +00:00
int infoPadding = 0 ;
if ( tabPage . Name . Contains ( "Global" ) & & path . Type = = "Firmware" )
{
infoPadding = 26 ;
}
2013-11-28 01:33:38 +00:00
var label = new Label
2013-11-15 23:32:06 +00:00
{
Text = path . Type ,
2013-12-19 18:18:40 +00:00
Location = new Point ( widgetOffset + buttonWidth + padding + infoPadding , ypos + 4 ) ,
2013-11-15 23:32:06 +00:00
Width = 100 ,
Name = path . Type ,
Anchor = AnchorStyles . Top | AnchorStyles . Right ,
} ;
tabPage . Controls . Add ( label ) ;
tabPage . Controls . Add ( btn ) ;
tabPage . Controls . Add ( box ) ;
ypos + = rowHeight ;
}
2013-11-28 01:33:38 +00:00
var sys = tabPage . Name ;
2013-12-22 18:36:27 +00:00
if ( tabPage . Name = = "PCE" ) // Hack
2013-11-15 23:32:06 +00:00
{
sys = "PCECD" ;
}
2013-12-19 18:18:40 +00:00
if ( tabPage . Name . Contains ( "Global" ) )
2013-11-15 23:32:06 +00:00
{
2013-11-28 01:33:38 +00:00
var firmwareButton = new Button
2013-11-15 23:32:06 +00:00
{
Name = sys ,
2013-12-19 18:18:40 +00:00
Text = String . Empty ,
Image = Properties . Resources . Help ,
Location = new Point ( 499 , 253 ) ,
Width = 26 ,
Anchor = AnchorStyles . Top | AnchorStyles . Right
2013-11-15 23:32:06 +00:00
} ;
2013-12-19 18:18:40 +00:00
2013-11-15 23:32:06 +00:00
firmwareButton . Click + = delegate
{
2013-12-19 22:53:06 +00:00
if ( Owner is FirmwaresConfig )
{
MessageBox . Show ( "C-C-C-Combo Breaker!" , "Nice try, but" ) ;
return ;
}
2013-12-22 18:36:27 +00:00
2013-11-28 01:33:38 +00:00
var f = new FirmwaresConfig { TargetSystem = sys } ;
2013-12-19 22:53:06 +00:00
f . ShowDialog ( this ) ;
2013-11-15 23:32:06 +00:00
} ;
tabPage . Controls . Add ( firmwareButton ) ;
}
}
2013-12-22 18:36:27 +00:00
// TODO: this is only used by the defaults button, refactor since it is now redundant code (will have to force the rebuilding of all tabpages, currently they only build as necessar
2013-11-15 22:27:20 +00:00
private void DoTabs ( List < PathEntry > pathCollection )
2013-08-09 02:54:59 +00:00
{
2013-12-22 18:36:27 +00:00
_preventSelectedChangeEvent = true ;
PathTabControl . Visible = false ;
2013-08-11 20:06:27 +00:00
PathTabControl . TabPages . Clear ( ) ;
2013-12-22 18:36:27 +00:00
// Separate by system
2013-11-28 01:33:38 +00:00
var systems = Global . Config . PathEntries . Select ( x = > x . SystemDisplayName ) . Distinct ( ) . ToList ( ) ;
2013-08-09 02:54:59 +00:00
systems . Sort ( ) ;
2013-08-11 15:05:23 +00:00
2013-12-22 18:36:27 +00:00
// Hacky way to put global first
2013-11-28 01:33:38 +00:00
var global = systems . FirstOrDefault ( x = > x = = "Global" ) ;
2013-08-11 15:05:23 +00:00
systems . Remove ( global ) ;
systems . Insert ( 0 , global ) ;
2013-08-09 02:54:59 +00:00
2013-11-28 01:33:38 +00:00
var tabPages = new List < TabPage > ( systems . Count ) ;
2013-11-15 22:27:20 +00:00
const int _x = 6 ;
const int textboxWidth = 70 ;
const int padding = 5 ;
const int buttonWidth = 26 ;
const int widgetOffset = 85 ;
const int rowHeight = 30 ;
2013-11-28 01:33:38 +00:00
foreach ( var systemDisplayName in systems )
2013-08-09 02:54:59 +00:00
{
2013-11-28 01:33:38 +00:00
var systemId = Global . Config . PathEntries . FirstOrDefault ( x = > x . SystemDisplayName = = systemDisplayName ) . System ;
var t = new TabPage
2013-08-09 02:54:59 +00:00
{
2013-08-23 16:03:57 +00:00
Text = systemDisplayName ,
2013-08-11 19:05:05 +00:00
Name = systemId ,
2013-08-09 02:54:59 +00:00
} ;
2013-11-28 01:33:38 +00:00
var paths = pathCollection . Where ( x = > x . System = = systemId ) . OrderBy ( x = > x . Ordinal ) . ThenBy ( x = > x . Type ) . ToList ( ) ;
2013-08-09 02:54:59 +00:00
2013-11-28 01:33:38 +00:00
var _y = 14 ;
2013-08-11 14:28:14 +00:00
foreach ( var path in paths )
2013-08-09 02:54:59 +00:00
{
2013-11-28 01:33:38 +00:00
var box = new TextBox
2013-08-09 02:54:59 +00:00
{
Text = path . Path ,
Location = new Point ( _x , _y ) ,
2013-11-15 22:27:20 +00:00
Width = textboxWidth ,
2013-08-11 16:20:35 +00:00
Name = path . Type ,
Anchor = AnchorStyles . Top | AnchorStyles . Left | AnchorStyles . Right ,
MinimumSize = new Size ( 26 , 23 ) ,
2013-08-23 16:03:57 +00:00
AutoCompleteMode = AutoCompleteMode . SuggestAppend ,
AutoCompleteCustomSource = AutoCompleteOptions ,
AutoCompleteSource = AutoCompleteSource . CustomSource ,
2013-08-09 02:54:59 +00:00
} ;
2013-11-28 01:33:38 +00:00
var btn = new Button
2013-08-09 02:54:59 +00:00
{
2013-11-03 03:54:37 +00:00
Text = String . Empty ,
2013-11-15 22:27:20 +00:00
Image = Properties . Resources . OpenFile ,
Location = new Point ( widgetOffset , _y - 1 ) ,
Width = buttonWidth ,
2013-08-11 15:05:23 +00:00
Name = path . Type ,
2013-08-11 16:20:35 +00:00
Anchor = AnchorStyles . Top | AnchorStyles . Right ,
2013-08-09 02:54:59 +00:00
} ;
2013-08-13 00:03:50 +00:00
2013-11-28 01:33:38 +00:00
var tempBox = box ;
var tempPath = path . Type ;
var tempSystem = path . System ;
2013-11-15 22:27:20 +00:00
btn . Click + = delegate
2013-08-11 14:28:14 +00:00
{
2013-08-13 00:03:50 +00:00
BrowseFolder ( tempBox , tempPath , tempSystem ) ;
2013-11-15 22:27:20 +00:00
} ;
2013-08-09 02:54:59 +00:00
2013-11-28 01:33:38 +00:00
var label = new Label
2013-11-15 22:27:20 +00:00
{
2013-08-09 02:54:59 +00:00
Text = path . Type ,
2013-11-15 22:27:20 +00:00
Location = new Point ( widgetOffset + buttonWidth + padding , _y + 4 ) ,
2013-08-11 16:20:35 +00:00
Width = 100 ,
Name = path . Type ,
Anchor = AnchorStyles . Top | AnchorStyles . Right ,
2013-08-09 02:54:59 +00:00
} ;
t . Controls . Add ( label ) ;
2013-08-11 16:20:35 +00:00
t . Controls . Add ( btn ) ;
t . Controls . Add ( box ) ;
2013-08-09 02:54:59 +00:00
2013-11-15 22:27:20 +00:00
_y + = rowHeight ;
2013-08-11 19:05:05 +00:00
}
2013-11-28 01:33:38 +00:00
var sys = systemDisplayName ;
2013-12-22 18:36:27 +00:00
if ( systemDisplayName = = "PCE" ) // Hack
2013-08-11 19:05:05 +00:00
{
sys = "PCECD" ;
}
2013-11-28 01:33:38 +00:00
var hasFirmwares = FirmwaresConfig . SystemGroupNames . Any ( x = > x . Key = = sys ) ;
2013-08-11 19:05:05 +00:00
if ( hasFirmwares )
{
2013-11-28 01:33:38 +00:00
var firmwareButton = new Button
2013-08-11 19:05:05 +00:00
{
Name = sys ,
Text = "&Firmware" ,
Location = new Point ( _x , _y ) ,
Width = 75 ,
} ;
2013-11-15 22:27:20 +00:00
firmwareButton . Click + = delegate
2013-08-11 19:05:05 +00:00
{
2013-12-22 18:36:27 +00:00
var f = new FirmwaresConfig { TargetSystem = sys } ;
2013-08-11 19:05:05 +00:00
f . ShowDialog ( ) ;
2013-11-15 22:27:20 +00:00
} ;
2013-08-11 19:05:05 +00:00
t . Controls . Add ( firmwareButton ) ;
2013-08-09 02:54:59 +00:00
}
2013-12-19 18:18:40 +00:00
2013-11-15 22:27:20 +00:00
tabPages . Add ( t ) ;
2013-08-09 02:54:59 +00:00
}
2013-12-22 18:36:27 +00:00
2013-11-15 22:27:20 +00:00
PathTabControl . TabPages . AddRange ( tabPages . ToArray ( ) ) ;
2013-12-22 18:36:27 +00:00
PathTabControl . Visible = true ;
_preventSelectedChangeEvent = false ;
2013-08-09 02:54:59 +00:00
}
2013-12-22 18:36:27 +00:00
private static void BrowseFolder ( TextBox box , string name , string system )
2013-08-09 02:54:59 +00:00
{
2013-12-22 18:36:27 +00:00
// Ugly hack, we don't want to pass in the system in for system base and global paths
2013-11-16 22:42:07 +00:00
if ( name = = "Base" | | system = = "Global" | | system = = "Global_NULL" )
2013-08-11 15:05:23 +00:00
{
2013-11-15 22:27:20 +00:00
system = null ;
2013-08-11 15:05:23 +00:00
}
2013-09-22 16:13:28 +00:00
var f = new FolderBrowserDialog
2013-08-09 02:54:59 +00:00
{
2013-11-15 22:27:20 +00:00
Description = "Set the directory for " + name ,
SelectedPath = PathManager . MakeAbsolutePath ( box . Text , system )
2013-08-09 02:54:59 +00:00
} ;
2013-11-28 01:33:38 +00:00
var result = f . ShowDialog ( ) ;
2013-08-09 02:54:59 +00:00
if ( result = = DialogResult . OK )
{
2013-11-15 22:27:20 +00:00
box . Text = PathManager . TryMakeRelative ( f . SelectedPath , system ) ;
2013-08-09 02:54:59 +00:00
}
}
private void SaveSettings ( )
{
2013-08-11 14:28:14 +00:00
Global . Config . UseRecentForROMs = RecentForROMs . Checked ;
2013-08-11 21:48:17 +00:00
Global . Config . PathEntries [ "Global" , "Base" ] . Path = BasePathBox . Text ;
2013-08-11 15:05:23 +00:00
2013-11-28 01:33:38 +00:00
foreach ( var t in AllPathBoxes )
2013-08-11 15:05:23 +00:00
{
2013-12-22 18:36:27 +00:00
var pathEntry = Global . Config . PathEntries . FirstOrDefault ( x = > x . System = = t . Parent . Name & & x . Type = = t . Name ) ;
pathEntry . Path = t . Text ;
2013-08-11 14:28:14 +00:00
}
}
2013-11-15 22:27:20 +00:00
private void DoRomToggle ( )
2013-08-11 15:05:23 +00:00
{
2013-11-28 01:33:38 +00:00
var pcontrols = AllPathControls . Where ( x = > x . Name = = "ROM" ) . ToList ( ) ;
foreach ( var c in pcontrols )
2013-08-11 15:05:23 +00:00
{
c . Enabled = ! RecentForROMs . Checked ;
}
}
2013-11-15 22:27:20 +00:00
private IEnumerable < TextBox > AllPathBoxes
2013-08-11 15:05:23 +00:00
{
get
{
2013-12-22 18:36:27 +00:00
var allPathBoxes = new List < TextBox > ( ) ;
2013-08-11 15:05:23 +00:00
foreach ( TabPage tp in PathTabControl . TabPages )
{
2013-12-22 18:36:27 +00:00
allPathBoxes . AddRange ( tp . Controls . OfType < TextBox > ( ) ) ;
2013-08-11 15:05:23 +00:00
}
2013-12-22 18:36:27 +00:00
return allPathBoxes ;
2013-08-11 15:05:23 +00:00
}
}
2013-11-15 22:27:20 +00:00
private IEnumerable < Control > AllPathControls
2013-08-11 15:05:23 +00:00
{
get
{
2013-12-22 18:36:27 +00:00
var allPathControls = new List < Control > ( ) ;
2013-08-11 15:05:23 +00:00
foreach ( TabPage tp in PathTabControl . TabPages )
{
2013-12-22 18:36:27 +00:00
allPathControls . AddRange ( tp . Controls . OfType < Control > ( ) ) ;
2013-08-11 15:05:23 +00:00
}
2013-12-22 18:36:27 +00:00
return allPathControls ;
2013-08-11 15:05:23 +00:00
}
2013-08-09 02:54:59 +00:00
}
2013-08-11 20:06:27 +00:00
2013-11-15 22:27:20 +00:00
private IEnumerable < TabPage > AllTabPages
2013-08-23 16:03:57 +00:00
{
2013-11-28 01:33:38 +00:00
get { return PathTabControl . TabPages . Cast < TabPage > ( ) ; }
2013-08-23 16:03:57 +00:00
}
2013-08-12 22:31:48 +00:00
2013-12-22 18:36:27 +00:00
#region Events
private void NewPathConfig_Load ( object sender , EventArgs e )
2013-08-11 20:06:27 +00:00
{
2013-12-22 18:36:27 +00:00
LoadSettings ( ) ;
LockDownCores ( ) ;
}
private void RecentForROMs_CheckedChanged ( object sender , EventArgs e )
{
DoRomToggle ( ) ;
2013-08-11 20:06:27 +00:00
}
2013-11-15 23:32:06 +00:00
private void PathTabControl_SelectedIndexChanged ( object sender , EventArgs e )
{
2013-12-22 18:36:27 +00:00
if ( ! _preventSelectedChangeEvent & & PathTabControl . TabPages . Count > 0 )
{
var tabPage = ( sender as TabControl ) . SelectedTab ;
if ( tabPage . Controls . Count = = 0 )
{
DoTabPage ( ( sender as TabControl ) . SelectedTab ) ;
}
}
}
private void BrowseBase_Click ( object sender , EventArgs e )
{
var f = new FolderBrowserDialog
2013-11-15 23:32:06 +00:00
{
2013-12-22 18:36:27 +00:00
Description = "Set the directory for the base global path" ,
SelectedPath = PathManager . MakeAbsolutePath ( BasePathBox . Text , null )
} ;
var result = f . ShowDialog ( ) ;
if ( result = = DialogResult . OK )
{
BasePathBox . Text = f . SelectedPath ;
2013-11-15 23:32:06 +00:00
}
}
2013-12-22 18:36:27 +00:00
private void SpecialCommandsBtn_Click ( object sender , EventArgs e )
{
new PathInfo ( ) . Show ( ) ;
}
private void SaveBtn_Click ( object sender , EventArgs e )
{
SaveSettings ( ) ;
}
private void DefaultsBtn_Click ( object sender , EventArgs e )
{
DoTabs ( PathEntryCollection . DefaultValues ) ;
}
private void Ok_Click ( object sender , EventArgs e )
{
SaveSettings ( ) ;
GlobalWin . OSD . AddMessage ( "Path settings saved" ) ;
Close ( ) ;
}
private void Cancel_Click ( object sender , EventArgs e )
{
GlobalWin . OSD . AddMessage ( "Path config aborted" ) ;
Close ( ) ;
}
#endregion
2013-08-09 02:54:59 +00:00
}
}