2013-10-25 00:57:23 +00:00
using System ;
using System.Globalization ;
using System.Windows.Forms ;
2014-07-03 16:00:57 +00:00
using BizHawk.Common.StringExtensions ;
2014-07-03 15:16:47 +00:00
using BizHawk.Common.NumberExtensions ;
2013-10-25 00:57:23 +00:00
2013-11-03 03:54:37 +00:00
namespace BizHawk.Client.EmuHawk
2013-10-25 00:57:23 +00:00
{
2014-03-23 16:02:29 +00:00
// TODO: add a MaxValue property, nullable int, that will show up in Designer, change events will check that value and fix entries that exceed that value
2013-10-25 00:57:23 +00:00
public interface INumberBox
{
2014-02-24 02:50:56 +00:00
bool Nullable { get ; }
2013-11-08 23:55:45 +00:00
int? ToRawInt ( ) ;
void SetFromRawInt ( int? rawint ) ;
2013-10-25 00:57:23 +00:00
}
public class HexTextBox : TextBox , INumberBox
{
2014-02-24 02:50:56 +00:00
private string _addressFormatStr = string . Empty ;
private int? _maxSize ;
2013-10-25 00:57:23 +00:00
private bool _nullable = true ;
2014-02-24 02:50:56 +00:00
public HexTextBox ( )
{
CharacterCasing = CharacterCasing . Upper ;
}
2013-10-25 00:57:23 +00:00
public bool Nullable { get { return _nullable ; } set { _nullable = value ; } }
public void SetHexProperties ( int domainSize )
{
_maxSize = domainSize - 1 ;
2014-07-03 15:16:47 +00:00
MaxLength = _maxSize . Value . NumHexDigits ( ) ;
2014-02-24 02:50:56 +00:00
_addressFormatStr = "{0:X" + MaxLength + "}" ;
2013-10-25 00:57:23 +00:00
ResetText ( ) ;
}
private uint GetMax ( )
{
if ( _maxSize . HasValue )
{
return ( uint ) _maxSize . Value ;
}
2014-05-15 15:12:30 +00:00
return ( uint ) ( ( ( long ) 1 < < ( 4 * MaxLength ) ) - 1 ) ;
2013-10-25 00:57:23 +00:00
}
public override void ResetText ( )
{
2014-02-24 02:50:56 +00:00
Text = _nullable ? string . Empty : string . Format ( _addressFormatStr , 0 ) ;
2013-10-25 00:57:23 +00:00
}
protected override void OnKeyPress ( KeyPressEventArgs e )
{
if ( e . KeyChar = = '\b' | | e . KeyChar = = 22 | | e . KeyChar = = 1 | | e . KeyChar = = 3 )
{
return ;
}
2014-02-24 02:50:56 +00:00
2014-07-03 16:00:57 +00:00
if ( ! e . KeyChar . IsHex ( ) )
2013-10-25 00:57:23 +00:00
{
e . Handled = true ;
}
}
protected override void OnKeyDown ( KeyEventArgs e )
{
if ( e . KeyCode = = Keys . Up )
{
2014-07-03 16:00:57 +00:00
if ( Text . IsHex ( ) & & ! string . IsNullOrEmpty ( _addressFormatStr ) )
2013-10-25 00:57:23 +00:00
{
2014-02-24 02:50:56 +00:00
var val = ( uint ) ToRawInt ( ) ;
2013-10-25 00:57:23 +00:00
if ( val = = GetMax ( ) )
{
val = 0 ;
}
else
{
val + + ;
}
2014-02-24 02:50:56 +00:00
Text = string . Format ( _addressFormatStr , val ) ;
2013-10-25 00:57:23 +00:00
}
}
else if ( e . KeyCode = = Keys . Down )
{
2014-07-03 16:00:57 +00:00
if ( Text . IsHex ( ) & & ! string . IsNullOrEmpty ( _addressFormatStr ) )
2013-10-25 00:57:23 +00:00
{
2014-02-24 02:50:56 +00:00
var val = ( uint ) ToRawInt ( ) ;
2013-10-25 00:57:23 +00:00
if ( val = = 0 )
{
val = GetMax ( ) ;
}
else
{
val - - ;
}
2014-02-24 02:50:56 +00:00
Text = string . Format ( _addressFormatStr , val ) ;
2013-10-25 00:57:23 +00:00
}
}
else
{
base . OnKeyDown ( e ) ;
}
}
protected override void OnTextChanged ( EventArgs e )
{
2014-02-24 02:50:56 +00:00
if ( string . IsNullOrWhiteSpace ( Text ) )
2013-10-25 00:57:23 +00:00
{
ResetText ( ) ;
}
2013-11-02 00:44:55 +00:00
base . OnTextChanged ( e ) ;
2013-10-25 00:57:23 +00:00
}
2013-11-08 23:55:45 +00:00
public int? ToRawInt ( )
2013-10-25 00:57:23 +00:00
{
2014-02-24 02:50:56 +00:00
if ( string . IsNullOrWhiteSpace ( Text ) )
2013-10-25 00:57:23 +00:00
{
2013-11-08 23:55:45 +00:00
if ( Nullable )
{
return null ;
}
2014-02-24 02:50:56 +00:00
return 0 ;
2013-10-25 00:57:23 +00:00
}
2014-02-24 02:50:56 +00:00
return int . Parse ( Text , NumberStyles . HexNumber ) ;
2013-10-25 00:57:23 +00:00
}
2013-11-08 23:55:45 +00:00
public void SetFromRawInt ( int? val )
2013-10-25 00:57:23 +00:00
{
2014-02-24 02:50:56 +00:00
Text = val . HasValue ? string . Format ( _addressFormatStr , val ) : string . Empty ;
2013-10-25 00:57:23 +00:00
}
}
public class UnsignedIntegerBox : TextBox , INumberBox
{
2014-02-24 02:50:56 +00:00
private bool _nullable = true ;
2013-10-25 00:57:23 +00:00
public UnsignedIntegerBox ( )
{
CharacterCasing = CharacterCasing . Upper ;
}
public bool Nullable { get { return _nullable ; } set { _nullable = value ; } }
protected override void OnKeyPress ( KeyPressEventArgs e )
{
if ( e . KeyChar = = '\b' | | e . KeyChar = = 22 | | e . KeyChar = = 1 | | e . KeyChar = = 3 )
{
return ;
}
2014-02-24 02:50:56 +00:00
2014-07-03 16:00:57 +00:00
if ( ! e . KeyChar . IsUnsigned ( ) )
2013-10-25 00:57:23 +00:00
{
e . Handled = true ;
}
}
public override void ResetText ( )
{
2014-02-24 02:50:56 +00:00
Text = _nullable ? string . Empty : "0" ;
2013-10-25 00:57:23 +00:00
}
protected override void OnKeyDown ( KeyEventArgs e )
{
if ( e . KeyCode = = Keys . Up )
{
2014-07-03 16:00:57 +00:00
if ( Text . IsHex ( ) )
2013-10-25 00:57:23 +00:00
{
2014-02-24 02:50:56 +00:00
var val = ( uint ) ToRawInt ( ) ;
2013-10-25 00:57:23 +00:00
if ( val = = uint . MaxValue )
{
val = 0 ;
}
else
{
val + + ;
}
2014-02-24 02:50:56 +00:00
2013-10-25 00:57:23 +00:00
Text = val . ToString ( ) ;
}
}
else if ( e . KeyCode = = Keys . Down )
{
2014-07-03 16:00:57 +00:00
if ( Text . IsHex ( ) )
2013-10-25 00:57:23 +00:00
{
2014-02-24 02:50:56 +00:00
var val = ( uint ) ToRawInt ( ) ;
2013-10-25 00:57:23 +00:00
if ( val = = 0 )
{
val = uint . MaxValue ;
}
else
{
val - - ;
}
Text = val . ToString ( ) ;
}
}
else
{
base . OnKeyDown ( e ) ;
}
}
protected override void OnTextChanged ( EventArgs e )
{
2014-07-03 16:43:39 +00:00
if ( string . IsNullOrWhiteSpace ( Text ) | | ! Text . IsHex ( ) )
2013-10-25 00:57:23 +00:00
{
ResetText ( ) ;
}
2013-11-23 21:19:52 +00:00
base . OnTextChanged ( e ) ;
2013-10-25 00:57:23 +00:00
}
2013-11-08 23:55:45 +00:00
public int? ToRawInt ( )
2013-10-25 00:57:23 +00:00
{
2014-07-03 16:43:39 +00:00
if ( string . IsNullOrWhiteSpace ( Text ) | | ! Text . IsHex ( ) )
2013-10-25 00:57:23 +00:00
{
2013-11-08 23:55:45 +00:00
if ( Nullable )
{
return null ;
}
2014-02-24 02:50:56 +00:00
return 0 ;
2013-10-25 00:57:23 +00:00
}
2014-02-24 02:50:56 +00:00
return ( int ) uint . Parse ( Text ) ;
2013-10-25 00:57:23 +00:00
}
2013-11-08 23:55:45 +00:00
public void SetFromRawInt ( int? val )
2013-10-25 00:57:23 +00:00
{
2014-02-24 02:50:56 +00:00
Text = val . HasValue ? val . ToString ( ) : string . Empty ;
2013-10-25 00:57:23 +00:00
}
}
}