2013-12-01 04:00:02 +00:00
using System ;
using System.Collections.Generic ;
using System.Drawing ;
using System.IO ;
2013-12-05 19:18:20 +00:00
using System.Linq ;
2013-12-01 04:00:02 +00:00
using System.Windows.Forms ;
2013-12-01 20:55:52 +00:00
2013-12-01 04:00:02 +00:00
using BizHawk.Client.Common ;
namespace BizHawk.Client.EmuHawk
{
public partial class TAStudio : Form , IToolForm
{
2013-12-14 14:40:33 +00:00
// TODO: UI flow that conveniently allows to start from savestate
2013-12-07 17:29:47 +00:00
private const string MarkerColumnName = "MarkerColumn" ;
private const string FrameColumnName = "FrameColumn" ;
2013-12-06 15:47:23 +00:00
2013-12-01 04:00:02 +00:00
private int _defaultWidth ;
private int _defaultHeight ;
2013-12-05 19:18:20 +00:00
private TasMovie _tas ;
2013-12-01 04:00:02 +00:00
2013-12-10 01:45:45 +00:00
// Input Painting
private string StartDrawColumn = String . Empty ;
private bool StartOn = false ;
2013-12-01 04:00:02 +00:00
#region API
public TAStudio ( )
{
InitializeComponent ( ) ;
TASView . QueryItemText + = TASView_QueryItemText ;
TASView . QueryItemBkColor + = TASView_QueryItemBkColor ;
TASView . VirtualMode = true ;
Closing + = ( o , e ) = >
{
if ( AskSave ( ) )
{
SaveConfigSettings ( ) ;
2013-12-01 22:29:38 +00:00
GlobalWin . OSD . AddMessage ( "TAStudio Disengaged" ) ;
if ( Global . MovieSession . Movie is TasMovie )
{
Global . MovieSession . Movie = new Movie ( ) ;
2013-12-14 14:40:33 +00:00
GlobalWin . MainForm . StopMovie ( saveChanges : false ) ;
2013-12-01 22:29:38 +00:00
}
2013-12-01 04:00:02 +00:00
}
else
{
e . Cancel = true ;
}
} ;
TopMost = Global . Config . TAStudioTopMost ;
2013-12-08 19:30:57 +00:00
TASView . InputPaintingMode = Global . Config . TAStudioDrawInput ;
TASView . PointedCellChanged + = TASView_PointedCellChanged ;
2013-12-01 04:00:02 +00:00
}
public bool AskSave ( )
{
2013-12-14 14:40:33 +00:00
if ( _tas . Changes )
{
GlobalWin . Sound . StopSound ( ) ;
var result = MessageBox . Show ( "Save Changes?" , "Tastudio" , MessageBoxButtons . YesNoCancel , MessageBoxIcon . Question , MessageBoxDefaultButton . Button3 ) ;
GlobalWin . Sound . StartSound ( ) ;
if ( result = = DialogResult . Yes )
{
SaveTASMenuItem_Click ( null , null ) ;
}
else if ( result = = DialogResult . No )
{
_tas . Changes = false ;
return true ;
}
else if ( result = = DialogResult . Cancel )
{
return false ;
}
}
2013-12-01 04:00:02 +00:00
return true ;
}
public bool UpdateBefore
{
get { return false ; }
}
public void UpdateValues ( )
{
2013-12-07 21:37:52 +00:00
if ( ! IsHandleCreated | | IsDisposed )
{
return ;
}
2013-12-05 19:18:20 +00:00
TASView . ItemCount = _tas . InputLogLength ;
2013-12-01 04:00:02 +00:00
}
public void Restart ( )
{
2013-12-07 21:37:52 +00:00
if ( ! IsHandleCreated | | IsDisposed )
{
return ;
}
2013-12-01 04:00:02 +00:00
}
#endregion
private void TASView_QueryItemBkColor ( int index , int column , ref Color color )
{
2013-12-06 15:47:23 +00:00
var record = _tas [ index ] ;
if ( ! record . HasState )
{
color = BackColor ;
}
else
{
2013-12-07 21:37:52 +00:00
color = record . Lagged ? Color . Pink : Color . LightGreen ;
2013-12-06 15:47:23 +00:00
}
2013-12-01 04:00:02 +00:00
}
private void TASView_QueryItemText ( int index , int column , out string text )
{
2013-12-07 01:50:52 +00:00
try
2013-12-06 15:47:23 +00:00
{
2013-12-07 01:50:52 +00:00
var columnName = TASView . Columns [ column ] . Name ;
2013-12-07 17:29:47 +00:00
var columnText = TASView . Columns [ column ] . Text ;
2013-12-07 01:50:52 +00:00
2013-12-07 17:29:47 +00:00
if ( columnName = = MarkerColumnName )
2013-12-07 01:50:52 +00:00
{
2013-12-07 21:37:52 +00:00
text = String . Empty ;
2013-12-07 01:50:52 +00:00
}
2013-12-07 17:29:47 +00:00
else if ( columnName = = FrameColumnName )
2013-12-07 01:50:52 +00:00
{
text = index . ToString ( ) . PadLeft ( 5 , '0' ) ;
}
else
{
2013-12-07 17:29:47 +00:00
text = _tas [ index ] . IsPressed ( columnName ) ? columnText : String . Empty ;
2013-12-07 01:50:52 +00:00
}
2013-12-06 15:47:23 +00:00
}
2013-12-07 01:50:52 +00:00
catch ( Exception ex )
2013-12-06 18:27:06 +00:00
{
2013-12-07 17:29:47 +00:00
text = String . Empty ;
2013-12-07 21:37:52 +00:00
MessageBox . Show ( "oops\n" + ex ) ;
2013-12-06 18:27:06 +00:00
}
2013-12-01 04:00:02 +00:00
}
private void TAStudio_Load ( object sender , EventArgs e )
{
2013-12-01 22:29:38 +00:00
if ( Global . MovieSession . Movie . IsActive )
{
var result = MessageBox . Show ( "Warning, Tastudio doesn't support .bkm movie files at this time, opening this will cause you to lose your work, proceed? If you have unsaved changes you should cancel this, and savebefore opening TAStudio" , "Unsupported movie" , MessageBoxButtons . OKCancel , MessageBoxIcon . Warning ) ;
if ( result ! = DialogResult . Yes )
{
Close ( ) ;
return ;
}
}
2013-12-14 19:51:07 +00:00
if ( Global . Config . AutoloadTAStudioProject )
{
Global . MovieSession . Movie = new TasMovie ( ) ;
_tas = Global . MovieSession . Movie as TasMovie ;
LoadFileFromRecent ( Global . Config . RecentTas [ 0 ] ) ;
}
else
{
EngageTasStudio ( ) ;
}
_tas . ActivePlayers = new List < string > { "Player 1" } ; // TODO
2013-12-05 19:18:20 +00:00
SetUpColumns ( ) ;
2013-12-14 19:51:07 +00:00
LoadConfigSettings ( ) ;
2013-12-05 19:18:20 +00:00
}
2013-12-10 16:37:41 +00:00
private void EngageTasStudio ( )
{
GlobalWin . OSD . AddMessage ( "TAStudio engaged" ) ;
Global . MovieSession . Movie = new TasMovie ( ) ;
2013-12-14 06:58:09 +00:00
2013-12-10 16:37:41 +00:00
_tas = Global . MovieSession . Movie as TasMovie ;
_tas . StartNewRecording ( ) ;
_tas . OnChanged + = OnMovieChanged ;
2013-12-14 14:40:33 +00:00
GlobalWin . MainForm . StartNewMovie ( _tas , true , true ) ;
2013-12-10 16:37:41 +00:00
}
private void StartNewSession ( )
{
if ( AskSave ( ) )
{
GlobalWin . OSD . AddMessage ( "new TAStudio session started" ) ;
_tas . StartNewRecording ( ) ;
2013-12-14 14:40:33 +00:00
GlobalWin . MainForm . StartNewMovie ( _tas , true , true ) ;
TASView . ItemCount = _tas . InputLogLength ;
2013-12-10 16:37:41 +00:00
}
}
2013-12-05 19:18:20 +00:00
private void SetUpColumns ( )
{
TASView . Columns . Clear ( ) ;
2013-12-07 21:37:52 +00:00
AddColumn ( MarkerColumnName , String . Empty , 18 ) ;
2013-12-07 17:29:47 +00:00
AddColumn ( FrameColumnName , "Frame#" , 68 ) ;
2013-12-05 19:18:20 +00:00
2013-12-07 21:37:52 +00:00
foreach ( var kvp in _tas . AvailableMnemonics )
2013-12-05 19:18:20 +00:00
{
2013-12-07 17:29:47 +00:00
AddColumn ( kvp . Key , kvp . Value . ToString ( ) , 20 ) ;
}
}
public void AddColumn ( string columnName , string columnText , int columnWidth )
{
if ( TASView . Columns [ columnName ] = = null )
{
var column = new ColumnHeader
{
Name = columnName ,
Text = columnText ,
Width = columnWidth ,
} ;
TASView . Columns . Add ( column ) ;
2013-12-05 19:18:20 +00:00
}
2013-12-01 04:00:02 +00:00
}
private void LoadConfigSettings ( )
{
_defaultWidth = Size . Width ;
_defaultHeight = Size . Height ;
if ( Global . Config . TAStudioSaveWindowPosition & & Global . Config . TASWndx > = 0 & & Global . Config . TASWndy > = 0 )
{
Location = new Point ( Global . Config . TASWndx , Global . Config . TASWndy ) ;
}
if ( Global . Config . TASWidth > = 0 & & Global . Config . TASHeight > = 0 )
{
Size = new Size ( Global . Config . TASWidth , Global . Config . TASHeight ) ;
}
}
private void SaveConfigSettings ( )
{
Global . Config . TASWndx = Location . X ;
Global . Config . TASWndy = Location . Y ;
Global . Config . TASWidth = Right - Left ;
Global . Config . TASHeight = Bottom - Top ;
}
2013-12-10 02:13:50 +00:00
public void LoadFileFromRecent ( string path )
{
2013-12-14 19:51:07 +00:00
if ( AskSave ( ) )
2013-12-10 02:13:50 +00:00
{
_tas . Filename = path ;
var loadResult = _tas . Load ( ) ;
if ( ! loadResult )
{
ToolHelpers . HandleLoadError ( Global . Config . RecentTas , path ) ;
}
else
{
Global . Config . RecentTas . Add ( path ) ;
TASView . ItemCount = _tas . InputLogLength ;
}
}
}
2013-12-01 04:00:02 +00:00
#region Events
#region File Menu
2013-12-10 01:45:45 +00:00
private void FileSubMenu_DropDownOpened ( object sender , EventArgs e )
{
SaveTASMenuItem . Enabled = ! String . IsNullOrWhiteSpace ( _tas . Filename ) ;
}
2013-12-10 02:13:50 +00:00
private void RecentSubMenu_DropDownOpened ( object sender , EventArgs e )
{
RecentSubMenu . DropDownItems . Clear ( ) ;
RecentSubMenu . DropDownItems . AddRange (
ToolHelpers . GenerateRecentMenu ( Global . Config . RecentTas , LoadFileFromRecent )
) ;
}
2013-12-10 16:37:41 +00:00
private void NewTASMenuItem_Click ( object sender , EventArgs e )
{
StartNewSession ( ) ;
}
2013-12-10 02:13:50 +00:00
private void OpenTASMenuItem_Click ( object sender , EventArgs e )
{
2013-12-14 19:51:07 +00:00
if ( AskSave ( ) )
2013-12-10 02:13:50 +00:00
{
2013-12-14 19:51:07 +00:00
var file = ToolHelpers . GetTasProjFileFromUser ( _tas . Filename ) ;
if ( file ! = null )
{
_tas . Filename = file . FullName ;
_tas . Load ( ) ;
Global . Config . RecentTas . Add ( _tas . Filename ) ;
TASView . ItemCount = _tas . InputLogLength ;
// TOOD: message to the user
}
2013-12-10 02:13:50 +00:00
}
}
2013-12-10 01:45:45 +00:00
private void SaveTASMenuItem_Click ( object sender , EventArgs e )
{
2013-12-14 14:40:33 +00:00
if ( String . IsNullOrEmpty ( _tas . Filename ) )
{
SaveAsTASMenuItem_Click ( sender , e ) ;
}
else
{
_tas . Save ( ) ;
}
2013-12-10 01:45:45 +00:00
// TODO: inform the user it happened somehow
}
private void SaveAsTASMenuItem_Click ( object sender , EventArgs e )
{
var file = ToolHelpers . GetTasProjSaveFileFromUser ( _tas . Filename ) ;
2013-12-10 16:37:41 +00:00
if ( file ! = null )
2013-12-10 01:45:45 +00:00
{
_tas . Filename = file . FullName ;
_tas . Save ( ) ;
2013-12-10 02:13:50 +00:00
Global . Config . RecentTas . Add ( _tas . Filename ) ;
2013-12-10 01:45:45 +00:00
// TODO: inform the user it happened somehow
}
}
2013-12-01 04:00:02 +00:00
private void ExitMenuItem_Click ( object sender , EventArgs e )
{
Close ( ) ;
}
#endregion
2013-12-08 19:30:57 +00:00
#region Config
private void ConfigSubMenu_DropDownOpened ( object sender , EventArgs e )
{
DrawInputByDraggingMenuItem . Checked = Global . Config . TAStudioDrawInput ;
}
private void DrawInputByDraggingMenuItem_Click ( object sender , EventArgs e )
{
TASView . InputPaintingMode = Global . Config . TAStudioDrawInput ^ = true ;
}
#endregion
2013-12-01 04:00:02 +00:00
#region Settings Menu
2013-12-08 19:30:57 +00:00
2013-12-01 04:00:02 +00:00
private void SettingsSubMenu_DropDownOpened ( object sender , EventArgs e )
{
SaveWindowPositionMenuItem . Checked = Global . Config . TAStudioSaveWindowPosition ;
AutoloadMenuItem . Checked = Global . Config . AutoloadTAStudio ;
2013-12-14 19:51:07 +00:00
AutoloadProjectMenuItem . Checked = Global . Config . AutoloadTAStudioProject ;
2013-12-01 04:00:02 +00:00
AlwaysOnTopMenuItem . Checked = Global . Config . TAStudioTopMost ;
}
private void AutoloadMenuItem_Click ( object sender , EventArgs e )
{
Global . Config . AutoloadTAStudio ^ = true ;
}
2013-12-07 21:37:52 +00:00
2013-12-14 19:51:07 +00:00
private void AutoloadProjectMenuItem_Click ( object sender , EventArgs e )
{
Global . Config . AutoloadTAStudioProject ^ = true ;
}
2013-12-01 04:00:02 +00:00
private void SaveWindowPositionMenuItem_Click ( object sender , EventArgs e )
{
Global . Config . TAStudioSaveWindowPosition ^ = true ;
}
private void AlwaysOnTopMenuItem_Click ( object sender , EventArgs e )
{
Global . Config . TAStudioTopMost ^ = true ;
}
2013-12-14 14:48:05 +00:00
private void RestoreDefaultSettingsMenuItem_Click ( object sender , EventArgs e )
{
Size = new Size ( _defaultWidth , _defaultHeight ) ;
Global . Config . TAStudioSaveWindowPosition = true ;
Global . Config . TAStudioTopMost = true ;
}
2013-12-01 04:00:02 +00:00
#endregion
2013-12-08 18:44:41 +00:00
#region TASView Events
2013-12-14 06:58:09 +00:00
private void OnMovieChanged ( object sender , MovieRecord . InputEventArgs e )
{
//TODO: move logic needs to go here
TASView . ItemCount = _tas . InputLogLength ;
}
2013-12-08 18:44:41 +00:00
private void TASView_MouseDown ( object sender , MouseEventArgs e )
{
2013-12-08 19:30:57 +00:00
if ( TASView . PointedCell . Row . HasValue & & ! String . IsNullOrEmpty ( TASView . PointedCell . Column ) )
{
_tas . ToggleButton ( TASView . PointedCell . Row . Value , TASView . PointedCell . Column ) ;
TASView . Refresh ( ) ;
2013-12-08 19:42:07 +00:00
StartDrawColumn = TASView . PointedCell . Column ;
StartOn = _tas . IsPressed ( TASView . PointedCell . Row . Value , TASView . PointedCell . Column ) ;
2013-12-08 19:30:57 +00:00
}
}
private void TASView_PointedCellChanged ( object sender , TasListView . CellEventArgs e )
{
2013-12-08 19:42:07 +00:00
if ( TASView . IsPaintDown & & e . NewCell . Row . HasValue & & ! String . IsNullOrEmpty ( StartDrawColumn ) )
2013-12-08 18:44:41 +00:00
{
2013-12-08 19:42:07 +00:00
_tas . SetButton ( e . NewCell . Row . Value , StartDrawColumn , StartOn ) ; //Notice it uses new row, old column, you can only paint across a single column
2013-12-08 18:44:41 +00:00
TASView . Refresh ( ) ;
}
}
#endregion
2013-12-10 01:45:45 +00:00
#endregion
2013-12-01 04:00:02 +00:00
}
}