2012-07-19 00:19:47 +00:00
using System ;
using System.Collections.Generic ;
using System.Drawing ;
using System.Linq ;
using System.Text ;
using System.Windows.Forms ;
2012-07-19 04:19:24 +00:00
using System.Text.RegularExpressions ;
2012-07-22 20:25:53 +00:00
using System.IO ;
2013-10-25 00:57:23 +00:00
2013-11-04 01:39:19 +00:00
using BizHawk.Emulation.Common ;
2013-10-25 00:57:23 +00:00
using BizHawk.Client.Common ;
2012-07-19 00:19:47 +00:00
2013-11-03 03:54:37 +00:00
namespace BizHawk.Client.EmuHawk
2012-07-19 00:19:47 +00:00
{
2012-07-22 19:54:40 +00:00
public partial class LuaWriter : Form
{
2012-07-23 01:02:04 +00:00
//TODO:
2012-07-27 00:15:02 +00:00
//ability to save new script (currently causes an exception)
//New scripts should be added to lua console automatically
2012-08-11 01:50:27 +00:00
//make functions is string part of string or comment since the actual way of validating it isn't correct
2012-07-27 00:15:02 +00:00
//Save fontstyle to config
2012-07-23 01:02:04 +00:00
//Line numbers
//Option to toggle line numbers
//Auto-complete drop down on functions in libraries
//intellisense on library functions
//Option to turn off basic lua script
//Tool strip
//function toolstrip button (inserts a function end block and puts cursor on blank line between them
//error checking logic on library functions (check parameters, etc)
//fix so drag & drop text file on edit box works (not just the edges around it
//listview object with lua functions, double click inserts them into the script
2012-07-22 20:25:53 +00:00
public string CurrentFile = "" ;
2012-07-22 22:24:02 +00:00
public Regex keyWords = new Regex ( "and|break|do|else|if|end|false|for|function|in|local|nil|not|or|repeat|return|then|true|until|while|elseif" ) ;
2012-07-23 01:02:04 +00:00
public Regex libraryWords ;
2012-07-22 22:24:02 +00:00
2013-04-14 23:56:45 +00:00
private bool changes ;
private bool redo ;
private bool hasChanged ;
private bool ProcessingText ;
private readonly char [ ] Symbols = { '+' , '-' , '*' , '/' , '%' , '^' , '#' , '=' , '<' , '>' , '(' , ')' , '{' , '}' , '[' , ']' , ';' , ':' , ',' , '.' } ;
private List < int [ ] > pos = new List < int [ ] > ( ) ;
2012-08-06 07:12:25 +00:00
2012-07-22 19:54:40 +00:00
public LuaWriter ( )
{
InitializeComponent ( ) ;
2013-04-14 23:56:45 +00:00
LuaText . MouseWheel + = LuaText_MouseWheel ;
2012-07-27 23:33:05 +00:00
}
void LuaText_MouseWheel ( object sender , MouseEventArgs e )
{
2012-08-01 02:56:38 +00:00
if ( KeyInput . IsPressed ( SlimDX . DirectInput . Key . LeftControl ) )
{
Double Zoom ;
if ( ( LuaText . ZoomFactor = = 0.1F & & e . Delta < 0 ) | | ( LuaText . ZoomFactor = = 5.0F & & e . Delta > 0 ) )
2013-04-14 23:56:45 +00:00
{
Zoom = ( LuaText . ZoomFactor * 100 ) ;
}
2012-08-01 02:56:38 +00:00
else
2013-04-14 23:56:45 +00:00
{
Zoom = ( LuaText . ZoomFactor * 100 ) + e . Delta / 12 ;
}
2012-08-01 02:56:38 +00:00
ZoomLabel . Text = string . Format ( "Zoom: {0:0}%" , Zoom ) ;
}
2012-07-22 19:54:40 +00:00
}
private void timer_Tick ( object sender , EventArgs e )
2012-07-22 22:24:02 +00:00
{
if ( ! hasChanged )
{
return ;
}
2012-10-09 00:17:48 +00:00
// ProcessText(); // Commenting out until it's fixed to not scroll everything all the time
2012-07-22 22:24:02 +00:00
hasChanged = false ;
}
2012-08-11 01:50:27 +00:00
private void ProcessText ( )
2012-07-22 19:54:40 +00:00
{
2012-08-11 01:50:27 +00:00
LuaText . InhibitPaint = true ;
ProcessingText = true ;
int selPos = LuaText . SelectionStart ;
int selChars = LuaText . SelectedText . Length ;
LuaText . SelectAll ( ) ;
LuaText . SelectionColor = Color . FromArgb ( Global . Config . LuaDefaultTextColor ) ;
if ( Global . Config . LuaDefaultTextBold )
LuaText . SelectionFont = new Font ( LuaText . SelectionFont , FontStyle . Bold ) ;
else
LuaText . SelectionFont = new Font ( LuaText . SelectionFont , FontStyle . Regular ) ;
2012-08-06 23:19:05 +00:00
2012-08-11 05:15:56 +00:00
AddCommentsAndStrings ( ) ;
2012-08-12 07:06:38 +00:00
AddNumbers ( ) ;
2012-08-11 01:50:27 +00:00
AddKeyWords ( ) ;
AddLibraries ( ) ;
AddSymbols ( ) ;
2012-08-08 21:33:24 +00:00
2012-08-11 01:50:27 +00:00
ColorText ( ) ;
2012-08-08 21:33:24 +00:00
2012-08-11 01:50:27 +00:00
LuaText . Select ( selPos , selChars ) ;
ProcessingText = false ;
LuaText . InhibitPaint = false ;
LuaText . Refresh ( ) ;
2012-07-22 19:54:40 +00:00
}
2012-08-12 07:06:38 +00:00
private void AddNumbers ( )
{
string temp = LuaText . Text ;
foreach ( Match match in new Regex ( @"(\d+\.?\d+|\.\d+|\d+)" ) . Matches ( temp ) )
{
if ( ! IsThisPartOfStringOrComment ( match . Index ) )
{
char before = ' ' , after = ' ' ;
if ( match . Index > 0 )
before = LuaText . Text [ match . Index - 1 ] ;
if ( match . Index + match . Length ! = LuaText . Text . Length )
after = LuaText . Text [ match . Index + match . Length ] ;
if ( ! char . IsLetter ( before ) & & ! char . IsLetter ( after ) )
{
AddPosition ( match . Index , match . Length , Global . Config . LuaDecimalColor , Global . Config . LuaDecimalBold , 0 ) ;
}
}
}
}
2012-08-11 05:15:56 +00:00
private void AddCommentsAndStrings ( )
2012-08-03 06:17:21 +00:00
{
2012-08-06 08:18:50 +00:00
string temp = LuaText . Text ;
2013-04-14 23:56:45 +00:00
int position = 0 ;
2012-08-11 05:15:56 +00:00
while ( position < = temp . Length )
2012-08-03 06:17:21 +00:00
{
2013-04-14 23:56:45 +00:00
int comment = temp . IndexOf ( "--" , position , StringComparison . Ordinal ) ;
int longcomment = temp . IndexOf ( "--[[" , position ) ;
int quote = temp . IndexOf ( '"' , position ) ;
int apos = temp . IndexOf ( '\'' , position ) ;
int longstring = temp . IndexOf ( "[" , position ) ;
2012-08-11 05:15:56 +00:00
int secondBracket = temp . IndexOf ( '[' , longstring + 1 ) ;
if ( secondBracket > = 0 )
while ( longstring > = 0 & & secondBracket > = 0 & & longstring ! = longcomment - 2 & & ! IsLongString ( temp . Substring ( longstring , secondBracket - longstring ) ) )
2012-08-06 08:18:50 +00:00
{
2012-08-11 05:15:56 +00:00
longstring = temp . IndexOf ( '[' , longstring + 1 ) ;
if ( longstring > = 0 )
secondBracket = temp . IndexOf ( '[' , longstring + 1 ) ;
if ( secondBracket = = - 1 )
longstring = - 1 ;
}
else
longstring = - 1 ;
2012-08-11 01:50:27 +00:00
2012-08-11 05:15:56 +00:00
if ( comment > = 0 & & ( comment < quote | | quote = = - 1 ) & & ( comment < apos | | apos = = - 1 ) & & ( comment < longstring | | longstring = = - 1 ) )
{
if ( comment < longcomment | | longcomment = = - 1 )
{
position = AddComment ( comment ) ;
2012-08-06 08:18:50 +00:00
}
2012-08-11 05:15:56 +00:00
else if ( comment > = longcomment & & longcomment > = 0 )
2012-08-06 08:18:50 +00:00
{
2012-08-11 05:15:56 +00:00
position = AddMultiLineComment ( longcomment ) ;
2012-08-06 08:18:50 +00:00
}
2012-08-03 06:17:21 +00:00
}
2012-08-11 05:15:56 +00:00
else if ( quote > = 0 & & ( quote < apos | | apos = = - 1 ) & & ( quote < longstring | | longstring = = - 1 ) )
{
position = AddString ( quote , '"' ) ;
}
else if ( apos > = 0 & & ( apos < longstring | | longstring = = - 1 ) )
{
position = AddString ( apos , '\'' ) ;
}
else if ( longstring > = 0 )
{
position = AddLongString ( longstring , secondBracket ) ;
}
position + + ;
}
}
private int AddLongString ( int startPos , int secondBracket )
{
int ending = 0 ;
if ( startPos ! = LuaText . Text . Length - 1 )
{
string tempBracket = GetLongStringClosingBracket ( LuaText . Text . Substring ( startPos , secondBracket - startPos + 1 ) ) ;
ending = LuaText . Text . IndexOf ( tempBracket , secondBracket + 1 ) ;
if ( ending < 0 )
ending = LuaText . Text . Length ;
2012-08-03 06:17:21 +00:00
else
2012-08-11 05:15:56 +00:00
ending + = tempBracket . Length - 1 ;
2012-08-03 06:17:21 +00:00
}
2012-08-11 05:15:56 +00:00
AddPosition ( startPos , ending - startPos + 1 , Global . Config . LuaStringColor , Global . Config . LuaStringBold , 1 ) ;
return ending ;
2012-08-03 06:17:21 +00:00
}
private string GetLongStringClosingBracket ( string openingBracket )
{
string closingBrackets = "]" ;
2013-04-14 23:56:45 +00:00
int level = openingBracket . Count ( c = > c = = '=' ) ;
2012-08-03 06:17:21 +00:00
for ( int x = 0 ; x < level ; x + + )
2013-04-14 23:56:45 +00:00
{
2012-08-03 06:17:21 +00:00
closingBrackets + = '=' ;
2013-04-14 23:56:45 +00:00
}
2012-08-03 06:17:21 +00:00
return closingBrackets + ']' ;
}
2013-04-14 23:56:45 +00:00
private static bool IsLongString ( string longstring )
2012-08-03 06:17:21 +00:00
{
2013-04-14 23:56:45 +00:00
return longstring . All ( c = > c = = '[' | | c = = '=' ) ;
2012-08-03 06:17:21 +00:00
}
2012-08-06 07:12:25 +00:00
private void AddSymbols ( )
2012-07-23 01:02:04 +00:00
{
2012-08-06 07:12:25 +00:00
string temp = LuaText . Text ;
2012-07-23 01:02:04 +00:00
foreach ( char mark in Symbols )
{
int currPos = 0 ;
2013-04-14 23:56:45 +00:00
int selection = temp . IndexOf ( mark , currPos ) ;
2012-08-06 07:12:25 +00:00
while ( selection > = 0 )
2012-07-23 01:02:04 +00:00
{
2012-08-11 05:15:56 +00:00
if ( ! IsThisPartOfStringOrComment ( selection ) )
AddPosition ( selection , 1 , Global . Config . LuaSymbolColor , Global . Config . LuaSymbolBold , 0 ) ;
2012-08-04 03:35:17 +00:00
2012-08-06 07:12:25 +00:00
currPos = selection + 1 ;
selection = temp . IndexOf ( mark , currPos ) ;
2012-07-23 01:02:04 +00:00
2012-08-06 07:12:25 +00:00
if ( currPos = = temp . Length )
2012-07-23 01:02:04 +00:00
break ;
}
}
}
2012-07-22 22:16:44 +00:00
2012-08-11 05:15:56 +00:00
private int AddString ( int startPos , char mark )
2012-07-22 19:54:40 +00:00
{
2013-04-14 23:56:45 +00:00
int endLine ;
2012-07-22 19:54:40 +00:00
2012-08-11 05:15:56 +00:00
if ( LuaText . GetLineFromCharIndex ( startPos ) + 1 = = LuaText . Lines . Count ( ) )
2013-04-14 23:56:45 +00:00
{
2012-08-11 05:15:56 +00:00
endLine = LuaText . Text . Length - 1 ;
2013-04-14 23:56:45 +00:00
}
2012-08-11 05:15:56 +00:00
else
2013-04-14 23:56:45 +00:00
{
2012-08-11 05:15:56 +00:00
endLine = LuaText . GetFirstCharIndexFromLine ( LuaText . GetLineFromCharIndex ( startPos ) + 1 ) - 1 ;
2013-04-14 23:56:45 +00:00
}
2012-08-11 05:15:56 +00:00
2013-04-14 23:56:45 +00:00
int ending ;
2012-08-11 05:15:56 +00:00
if ( startPos ! = LuaText . Text . Length - 1 )
2012-07-22 19:54:40 +00:00
{
2012-08-11 05:15:56 +00:00
if ( startPos + 1 ! = endLine )
2012-07-23 01:02:04 +00:00
{
2012-08-11 05:15:56 +00:00
ending = LuaText . Text . IndexOf ( mark , startPos + 1 , endLine - startPos + 1 ) ;
if ( ending > 0 )
2012-07-23 01:02:04 +00:00
{
2012-08-11 05:15:56 +00:00
while ( ending > 0 )
2012-07-23 01:02:04 +00:00
{
2012-08-11 05:15:56 +00:00
if ( ! IsThisPartOfTheString ( LuaText . Text . Substring ( startPos , ending - startPos + 1 ) ) )
break ;
2012-07-23 01:02:04 +00:00
else
ending + + ;
2012-08-11 05:15:56 +00:00
ending = LuaText . Text . IndexOf ( mark , ending , endLine - startPos + 1 ) ;
2012-07-23 01:02:04 +00:00
}
}
else
2012-08-11 05:15:56 +00:00
ending = endLine ;
2012-07-23 01:02:04 +00:00
}
2012-08-11 05:15:56 +00:00
else
ending = endLine ;
2012-07-22 19:54:40 +00:00
}
2012-08-11 05:15:56 +00:00
else
ending = endLine ;
if ( startPos ! = LuaText . Text . Length )
{
AddPosition ( startPos , ending - startPos + 1 , Global . Config . LuaStringColor , Global . Config . LuaStringBold , 1 ) ;
}
return ending ;
2012-07-22 19:54:40 +00:00
}
private bool IsThisPartOfTheString ( string wholestring )
{
int ammount = 0 ;
for ( int x = wholestring . Length - 2 ; x > - 1 ; x - - )
{
if ( wholestring [ x ] = = '\\' )
2013-04-14 23:56:45 +00:00
{
2012-07-22 19:54:40 +00:00
ammount + + ;
2013-04-14 23:56:45 +00:00
}
2012-07-22 19:54:40 +00:00
else
2013-04-14 23:56:45 +00:00
{
2012-07-22 19:54:40 +00:00
break ;
2013-04-14 23:56:45 +00:00
}
2012-07-22 19:54:40 +00:00
}
2013-04-14 23:56:45 +00:00
return ammount % 2 ! = 0 ;
2012-07-22 19:54:40 +00:00
}
2012-08-11 05:15:56 +00:00
private int AddComment ( int startPos )
2012-07-22 19:54:40 +00:00
{
2012-08-11 05:15:56 +00:00
int endComment ;
2012-07-22 19:54:40 +00:00
2012-08-11 05:15:56 +00:00
if ( LuaText . GetLineFromCharIndex ( startPos ) + 1 = = LuaText . Lines . Count ( ) )
endComment = LuaText . Text . Length - startPos ;
else
endComment = LuaText . GetFirstCharIndexFromLine ( LuaText . GetLineFromCharIndex ( startPos ) + 1 ) - 1 ;
2012-07-22 19:54:40 +00:00
2012-08-11 05:15:56 +00:00
AddPosition ( startPos , endComment - startPos , Global . Config . LuaCommentColor , Global . Config . LuaCommentBold , 1 ) ;
2012-07-22 19:54:40 +00:00
2012-08-11 05:15:56 +00:00
return endComment ;
}
private int AddMultiLineComment ( int startPos )
{
2013-04-14 23:56:45 +00:00
int endComment ;
2012-08-11 05:15:56 +00:00
2013-04-14 23:56:45 +00:00
int selection = LuaText . Text . IndexOf ( "]]" , StringComparison . Ordinal ) ;
2012-08-11 05:15:56 +00:00
if ( selection > 0 )
2013-04-14 23:56:45 +00:00
{
2012-08-11 05:15:56 +00:00
endComment = selection - startPos + 2 ;
2013-04-14 23:56:45 +00:00
}
2012-08-11 05:15:56 +00:00
else
2013-04-14 23:56:45 +00:00
{
2012-08-11 05:15:56 +00:00
endComment = LuaText . Text . Length ;
2013-04-14 23:56:45 +00:00
}
2012-08-11 05:15:56 +00:00
AddPosition ( startPos , endComment , Global . Config . LuaCommentColor , Global . Config . LuaCommentBold , 1 ) ;
return endComment ;
2012-07-22 19:54:40 +00:00
}
2012-07-23 01:02:04 +00:00
2012-08-06 07:12:25 +00:00
private void AddKeyWords ( )
2012-07-22 19:54:40 +00:00
{
2012-08-06 07:12:25 +00:00
foreach ( Match match in keyWords . Matches ( LuaText . Text ) )
2012-07-22 19:54:40 +00:00
{
2012-08-11 05:15:56 +00:00
if ( ! IsThisPartOfStringOrComment ( match . Index ) )
{
char before = ' ' , after = ' ' ;
2012-07-22 19:54:40 +00:00
2012-08-11 05:15:56 +00:00
if ( match . Index > 0 )
if ( match . Index > 5 & & match . Value ! = "if" & & LuaText . Text . Substring ( match . Index - 4 , 4 ) ! = "else" )
before = LuaText . Text [ match . Index - 1 ] ;
2012-07-22 19:54:40 +00:00
2012-08-11 05:15:56 +00:00
if ( match . Index + match . Length ! = LuaText . Text . Length )
if ( match . Value ! = "else" & & LuaText . Text . Substring ( match . Index , 2 ) ! = "if" )
after = LuaText . Text [ match . Index + match . Length ] ;
2012-07-22 19:54:40 +00:00
2012-08-11 05:15:56 +00:00
if ( ! char . IsLetterOrDigit ( before ) & & ! char . IsLetterOrDigit ( after ) )
{
AddPosition ( match . Index , match . Length , Global . Config . LuaKeyWordColor , Global . Config . LuaKeyWordBold , 1 ) ;
}
2012-07-22 19:54:40 +00:00
}
}
}
2012-07-19 00:19:47 +00:00
2012-08-11 05:15:56 +00:00
private bool IsThisPartOfStringOrComment ( int startPos )
{
2013-04-14 23:56:45 +00:00
return pos . Where ( position = > position [ 4 ] = = 1 ) . Any ( position = > position [ 0 ] < = startPos & & position [ 0 ] + position [ 1 ] > startPos ) ;
2012-08-11 05:15:56 +00:00
}
private void AddPosition ( int start , int lenght , int color , bool bold , int iscommentorstring )
2012-07-23 01:02:04 +00:00
{
2012-08-06 07:12:25 +00:00
int IsBold = 0 , IndexToAdd = 0 ;
if ( bold )
IsBold = 1 ;
2012-08-11 01:50:27 +00:00
for ( int x = 0 ; x < pos . Count ; x + + )
2012-07-23 01:02:04 +00:00
{
2012-08-06 07:12:25 +00:00
if ( start < pos [ x ] [ 0 ] )
{
IndexToAdd = x ;
break ;
}
if ( x = = pos . Count - 1 )
IndexToAdd = x + 1 ;
}
2012-08-11 01:50:27 +00:00
2013-04-14 23:56:45 +00:00
pos . Insert ( IndexToAdd , new [ ] { start , lenght , color , IsBold , iscommentorstring } ) ;
2012-08-06 07:12:25 +00:00
}
private void ColorText ( )
{
foreach ( int [ ] positions in pos )
{
2012-08-11 01:50:27 +00:00
LuaText . Select ( positions [ 0 ] , positions [ 1 ] ) ;
LuaText . SelectionColor = Color . FromArgb ( positions [ 2 ] ) ;
if ( positions [ 3 ] = = 1 )
LuaText . SelectionFont = new Font ( LuaText . SelectionFont , FontStyle . Bold ) ;
else
LuaText . SelectionFont = new Font ( LuaText . SelectionFont , FontStyle . Regular ) ;
2012-08-06 07:12:25 +00:00
}
pos = new List < int [ ] > ( ) ;
}
private void AddLibraries ( )
{
foreach ( Match match in libraryWords . Matches ( LuaText . Text ) )
{
2012-08-11 05:15:56 +00:00
if ( ! IsThisPartOfStringOrComment ( match . Index ) )
2012-07-23 01:02:04 +00:00
{
2012-08-11 05:15:56 +00:00
if ( match . Index > = 0 )
{
char before = ' ' , after = ' ' ;
2012-07-23 12:28:03 +00:00
2012-08-11 05:15:56 +00:00
if ( match . Index > 0 )
before = LuaText . Text [ match . Index - 1 ] ;
2012-07-23 12:28:03 +00:00
2012-08-11 05:15:56 +00:00
if ( match . Index + match . Length ! = LuaText . Text . Length )
after = LuaText . Text [ match . Index + match . Length ] ;
2012-07-23 12:28:03 +00:00
2012-08-11 05:15:56 +00:00
if ( ! char . IsLetterOrDigit ( before ) )
2012-07-23 01:02:04 +00:00
{
2012-08-11 05:15:56 +00:00
if ( after = = '.' )
{
AddPosition ( match . Index , match . Length , Global . Config . LuaLibraryColor , Global . Config . LuaLibraryBold , 0 ) ;
}
2012-07-23 01:02:04 +00:00
}
}
}
}
}
private void GenerateLibraryRegex ( )
{
StringBuilder list = new StringBuilder ( ) ;
2013-11-03 16:07:58 +00:00
List < string > Libs = GlobalWin . Tools . LuaConsole . LuaImp . Docs . GetLibraryList ( ) ;
2012-07-23 01:02:04 +00:00
for ( int i = 0 ; i < Libs . Count ; i + + )
{
list . Append ( Libs [ i ] ) ;
if ( i < Libs . Count - 1 )
{
list . Append ( '|' ) ;
}
}
2012-08-11 01:50:27 +00:00
list . Append ( "|coroutine|package|debug|file|io|math|os|package|string|table" ) ;
2012-07-23 01:02:04 +00:00
libraryWords = new Regex ( list . ToString ( ) ) ;
}
2012-07-27 00:15:02 +00:00
private void LoadFont ( )
{
LuaText . Font = new Font ( Global . Config . LuaWriterFont , Global . Config . LuaWriterFontSize ) ;
}
2012-07-22 19:54:40 +00:00
private void LuaWriter_Load ( object sender , EventArgs e )
2012-07-23 01:02:04 +00:00
{
2012-07-26 01:22:12 +00:00
//LuaTextFont;
2012-08-04 03:35:17 +00:00
ProcessingText = true ;
2013-04-14 23:56:45 +00:00
LuaText . SelectionTabs = new [ ] { 20 , 40 , 60 , 80 , 100 , 120 , 140 , 160 , 180 , 200 , 220 , 240 , 260 , 280 , 300 , 320 , 340 , 360 , 380 , 400 , 420 , 480 , 500 , 520 , 540 , 560 , 580 , 600 } ; //adelikat: What a goofy way to have to do this
2012-07-27 00:15:02 +00:00
LoadFont ( ) ;
2012-08-04 03:35:17 +00:00
LuaText . BackColor = Color . FromArgb ( Global . Config . LuaWriterBackColor ) ;
2012-08-01 02:56:38 +00:00
LuaText . ZoomFactor = Global . Config . LuaWriterZoom ;
ZoomLabel . Text = string . Format ( "Zoom: {0}%" , LuaText . ZoomFactor * 100 ) ;
2012-07-23 01:02:04 +00:00
GenerateLibraryRegex ( ) ;
2012-09-13 23:07:34 +00:00
2012-07-22 20:25:53 +00:00
if ( ! String . IsNullOrWhiteSpace ( CurrentFile ) )
{
LoadCurrentFile ( ) ;
2012-09-13 23:07:34 +00:00
NoChanges ( ) ;
2012-07-22 20:25:53 +00:00
}
2012-08-03 02:59:36 +00:00
else if ( ! Global . Config . LuaWriterStartEmpty )
2012-07-25 17:36:26 +00:00
{
2012-07-26 02:51:25 +00:00
LuaText . Text = "while true do\n\t\n\temu.frameadvance()\nend" ;
LuaText . SelectionStart = 15 ;
2012-09-13 23:07:34 +00:00
Changes ( ) ;
2012-07-25 17:36:26 +00:00
}
2012-08-03 02:59:36 +00:00
else
startWithEmptyScriptToolStripMenuItem . Checked = true ;
2012-07-25 17:36:26 +00:00
UpdateLineNumber ( ) ;
ProcessText ( ) ;
2012-07-22 20:25:53 +00:00
}
2012-07-22 22:24:02 +00:00
private void NoChanges ( )
{
changes = false ;
MessageLabel . Text = CurrentFile ;
}
2012-07-22 20:25:53 +00:00
private void LoadCurrentFile ( )
{
var file = new FileInfo ( CurrentFile ) ;
if ( file . Exists = = false )
{
return ;
}
2012-08-11 01:50:27 +00:00
StreamReader sr = new StreamReader ( file . FullName ) ;
LuaText . Text = sr . ReadToEnd ( ) ;
sr . Close ( ) ;
2012-07-22 20:25:53 +00:00
}
private void LuaWriter_DragEnter ( object sender , DragEventArgs e )
{
2013-04-14 23:56:45 +00:00
e . Effect = e . Data . GetDataPresent ( DataFormats . FileDrop ) ? DragDropEffects . Copy : DragDropEffects . None ;
2012-07-22 20:25:53 +00:00
}
private void LuaWriter_DragDrop ( object sender , DragEventArgs e )
{
string [ ] filePaths = ( string [ ] ) e . Data . GetData ( DataFormats . FileDrop ) ;
if ( Path . GetExtension ( filePaths [ 0 ] ) = = ( ".lua" ) | | Path . GetExtension ( filePaths [ 0 ] ) = = ( ".txt" ) )
{
//TODO: save changes
CurrentFile = filePaths [ 0 ] ;
LoadCurrentFile ( ) ;
}
2012-07-22 19:54:40 +00:00
}
2012-07-22 22:24:02 +00:00
private void saveToolStripMenuItem_Click ( object sender , EventArgs e )
{
2012-09-13 23:07:34 +00:00
SaveScript ( ) ;
2012-08-11 01:50:27 +00:00
MessageLabel . Text = Path . GetFileName ( CurrentFile ) + " saved." ;
2012-07-22 22:24:02 +00:00
}
private void SaveScript ( )
{
2012-09-13 23:07:34 +00:00
if ( String . IsNullOrWhiteSpace ( CurrentFile ) )
2012-07-22 22:24:02 +00:00
{
2012-09-13 23:07:34 +00:00
SaveScriptAs ( ) ;
}
else
{
var file = new FileInfo ( CurrentFile ) ;
2013-05-07 01:17:52 +00:00
/ * if ( ! file . Exists )
2012-09-13 23:07:34 +00:00
{
SaveScriptAs ( ) ;
2013-05-07 01:17:52 +00:00
} * /
2012-09-13 23:07:34 +00:00
using ( StreamWriter sw = new StreamWriter ( CurrentFile ) )
{
sw . Write ( LuaText . Text ) ;
}
MessageLabel . Text = Path . GetFileName ( CurrentFile ) + " saved." ;
NoChanges ( ) ;
2012-07-22 22:24:02 +00:00
}
}
private void SaveScriptAs ( )
{
var file = GetSaveFileFromUser ( CurrentFile ) ;
if ( file ! = null )
{
CurrentFile = file . FullName ;
SaveScript ( ) ;
MessageLabel . Text = Path . GetFileName ( CurrentFile ) + " saved." ;
2012-09-14 01:26:38 +00:00
Global . Config . RecentLua . Add ( file . FullName ) ;
2012-07-22 22:24:02 +00:00
}
}
public static FileInfo GetSaveFileFromUser ( string currentFile )
{
var sfd = new SaveFileDialog ( ) ;
2012-09-13 23:07:34 +00:00
if ( ! String . IsNullOrWhiteSpace ( currentFile ) )
2012-07-22 22:24:02 +00:00
{
sfd . FileName = Path . GetFileNameWithoutExtension ( currentFile ) ;
sfd . InitialDirectory = Path . GetDirectoryName ( currentFile ) ;
}
2013-10-20 18:02:43 +00:00
else if ( ! ( Global . Emulator is NullEmulator ) )
2012-07-22 22:24:02 +00:00
{
sfd . FileName = PathManager . FilesystemSafeName ( Global . Game ) ;
2012-11-29 18:42:13 +00:00
sfd . InitialDirectory = PathManager . GetLuaPath ( ) ;
2012-07-22 22:24:02 +00:00
}
else
{
sfd . FileName = "NULL" ;
2012-11-29 18:42:13 +00:00
sfd . InitialDirectory = PathManager . GetLuaPath ( ) ;
2012-07-22 22:24:02 +00:00
}
sfd . Filter = "Watch Files (*.lua)|*.lua|All Files|*.*" ;
sfd . RestoreDirectory = true ;
2013-11-28 22:39:00 +00:00
var result = sfd . ShowHawkDialog ( ) ;
2012-07-22 22:24:02 +00:00
if ( result ! = DialogResult . OK )
2013-11-28 22:39:00 +00:00
{
2012-07-22 22:24:02 +00:00
return null ;
2013-11-28 22:39:00 +00:00
}
return new FileInfo ( sfd . FileName ) ;
2012-07-22 22:24:02 +00:00
}
private void LuaText_KeyUp ( object sender , KeyEventArgs e )
{
2012-07-23 02:24:48 +00:00
2012-07-22 22:24:02 +00:00
}
2012-08-11 01:50:27 +00:00
private int CountTabsAtBeginningOfLine ( string line )
{
int tabs = 0 ;
foreach ( Char c in line )
{
if ( c = = '\t' )
tabs + + ;
else
break ;
}
return tabs ;
}
InputPrompt. I made the UserOK variable to change to false if the user clicks the Cancel button.
LuaWriter. Adding "end" after pressing Enter if the current line has "if", "for", etc. is now fixed. Also added some more edit menu items, like Undo, Redo, Cut, Copy, Paste, Select All, Search, Replace and Go To...
Search and Replace still need to be implemente. Implemente Go To, if the user inserts an invalid text (letters, symbols, etc) it will not close and prompt an error. Otherwise, it will go to the specified line.
2012-08-02 21:45:06 +00:00
2012-07-22 22:24:02 +00:00
private void Changes ( )
{
changes = true ;
MessageLabel . Text = CurrentFile + " *" ;
}
private void LuaText_TextChanged ( object sender , EventArgs e )
{
2012-08-11 01:50:27 +00:00
if ( ! ProcessingText )
{
hasChanged = true ;
Changes ( ) ;
}
2012-07-22 22:24:02 +00:00
}
private void saveAsToolStripMenuItem_Click ( object sender , EventArgs e )
{
SaveScriptAs ( ) ;
}
2012-07-23 01:32:41 +00:00
private void syntaxHighlightingToolStripMenuItem_Click ( object sender , EventArgs e )
{
LuaWriterColorConfig l = new LuaWriterColorConfig ( ) ;
2012-08-11 01:50:27 +00:00
if ( l . ShowDialog ( ) = = DialogResult . OK )
{
ProcessText ( ) ; //Update display with new settings
}
2012-07-23 01:32:41 +00:00
}
private void fontToolStripMenuItem_Click ( object sender , EventArgs e )
{
FontDialog f = new FontDialog ( ) ;
DialogResult result = f . ShowDialog ( ) ;
if ( result = = DialogResult . OK )
{
2012-07-27 00:15:02 +00:00
LuaText . Font = f . Font ;
Global . Config . LuaWriterFont = f . Font . Name ;
Global . Config . LuaWriterFontSize = f . Font . Size ;
ProcessText ( ) ; //Re-update coloring and such when font changes
2012-07-23 01:32:41 +00:00
}
}
2012-07-23 02:24:48 +00:00
private void LuaText_KeyDown ( object sender , KeyEventArgs e )
{
if ( e . KeyCode = = Keys . Escape )
{
AutoCompleteView . Visible = false ;
}
if ( e . KeyCode = = Keys . OemPeriod )
{
string currentword = CurrentWord ( ) ;
if ( IsLibraryWord ( currentword ) )
{
2013-11-03 16:07:58 +00:00
List < string > libfunctions = GlobalWin . Tools . LuaConsole . LuaImp . Docs . GetFunctionsByLibrary ( currentword ) ;
2012-08-11 01:50:27 +00:00
2012-10-09 00:17:48 +00:00
// Position autocomplete box near the cursor's current position
int x = LuaText . GetPositionFromCharIndex ( LuaText . SelectionStart ) . X + LuaText . Location . X + 5 ;
int y = LuaText . GetPositionFromCharIndex ( LuaText . SelectionStart ) . Y + LuaText . Location . Y + ( int ) LuaText . Font . GetHeight ( ) + 5 ; // One row down
AutoCompleteView . Location = new Point ( x , y ) ;
2012-08-02 17:48:17 +00:00
2012-10-09 00:17:48 +00:00
// Populate list with available options
AutoCompleteView . Items . Clear ( ) ;
2012-08-11 01:50:27 +00:00
foreach ( string function in libfunctions )
2012-07-23 02:24:48 +00:00
{
ListViewItem item = new ListViewItem ( function ) ;
AutoCompleteView . Items . Add ( item ) ;
}
2012-10-09 00:17:48 +00:00
// Show window after it has been positioned and set up
AutoCompleteView . Visible = true ;
2012-08-11 01:50:27 +00:00
}
}
if ( e . KeyCode = = Keys . Enter )
{
string [ ] Words = { "if" , "for" , "while" , "function" } ;
string tabsStr = "" ;
int linenumber = LuaText . GetLineFromCharIndex ( LuaText . GetFirstCharIndexOfCurrentLine ( ) ) ;
int tabs = CountTabsAtBeginningOfLine ( LuaText . Lines [ linenumber ] ) ;
for ( int a = 1 ; a < = tabs ; a + + )
tabsStr + = "\t" ;
foreach ( string Word in Words )
{
try
{
if ( LuaText . Lines [ linenumber ] . Substring ( 0 + tabs , Word . Length ) = = Word )
{
string str = LuaText . Text . Insert ( LuaText . SelectionStart , "\n" + tabsStr + "\t\n" + tabsStr + "end" ) ;
LuaText . Text = str ;
LuaText . Select ( LuaText . GetFirstCharIndexFromLine ( linenumber + 1 ) + 1 + tabs , 0 ) ;
e . SuppressKeyPress = true ;
return ;
}
}
catch { }
}
string tempStr = LuaText . Text . Insert ( LuaText . SelectionStart , "\n" + tabsStr ) ;
LuaText . Text = tempStr ;
LuaText . Select ( LuaText . GetFirstCharIndexFromLine ( linenumber + 1 ) + tabs , 0 ) ;
e . SuppressKeyPress = true ;
}
if ( e . KeyCode = = Keys . Up | | e . KeyCode = = Keys . Down )
{
if ( AutoCompleteView . Visible )
{
e . SuppressKeyPress = true ;
SelectNextItem ( e . KeyCode = = Keys . Down ) ;
}
}
}
private void SelectNextItem ( bool Next )
{
if ( AutoCompleteView . SelectedItems . Count > 0 )
{
if ( Next )
{
if ( AutoCompleteView . FocusedItem = = AutoCompleteView . Items [ AutoCompleteView . Items . Count - 1 ] )
return ;
AutoCompleteView . FocusedItem = AutoCompleteView . Items [ AutoCompleteView . Items . IndexOf ( AutoCompleteView . SelectedItems [ 0 ] ) + 1 ] ;
}
else
{
if ( AutoCompleteView . FocusedItem = = AutoCompleteView . Items [ 0 ] )
return ;
AutoCompleteView . FocusedItem = AutoCompleteView . Items [ AutoCompleteView . Items . IndexOf ( AutoCompleteView . SelectedItems [ 0 ] ) - 1 ] ;
}
}
else
{
if ( Next )
AutoCompleteView . FocusedItem = AutoCompleteView . Items [ 0 ] ;
}
}
2012-08-09 21:53:49 +00:00
2012-07-23 02:24:48 +00:00
private string CurrentWord ( )
{
int last = LuaText . SelectionStart ;
int lastSpace = LuaText . Text . Substring ( 0 , last ) . LastIndexOf ( ' ' ) ;
2012-08-11 01:50:27 +00:00
int lastTab = LuaText . Text . Substring ( 0 , last ) . LastIndexOf ( '\t' ) ;
2012-07-23 02:24:48 +00:00
int lastLine = LuaText . Text . Substring ( 0 , last ) . LastIndexOf ( '\n' ) ;
2013-04-14 23:56:45 +00:00
int start ;
2012-08-09 21:53:49 +00:00
if ( lastSpace > lastLine | | lastTab > lastLine )
2012-07-23 02:24:48 +00:00
{
2012-08-11 01:50:27 +00:00
if ( lastSpace > lastTab )
start = lastSpace ;
else
start = lastTab ;
2012-07-23 02:24:48 +00:00
}
else
{
start = lastLine ;
}
if ( start = = - 1 )
{
start = 0 ;
}
int length = last - start - 1 ;
string word = LuaText . Text . Substring ( start + 1 , length ) ;
return word ;
}
private bool IsLibraryWord ( string word )
{
2013-11-03 16:07:58 +00:00
List < string > Libs = GlobalWin . Tools . LuaConsole . LuaImp . Docs . GetLibraryList ( ) ;
2012-07-23 02:24:48 +00:00
if ( Libs . Contains ( word ) )
{
return true ;
}
return false ;
}
private void AutoCompleteView_MouseDoubleClick ( object sender , MouseEventArgs e )
{
ListView . SelectedIndexCollection indexes = AutoCompleteView . SelectedIndices ;
if ( indexes . Count > 0 )
{
string str = AutoCompleteView . Items [ indexes [ 0 ] ] . Text ;
int start = LuaText . SelectionStart ;
LuaText . Text = LuaText . Text . Insert ( start , str ) ;
AutoCompleteView . Visible = false ;
2012-08-11 01:50:27 +00:00
LuaText . Select ( start + str . Length , 0 ) ;
2012-07-23 02:24:48 +00:00
}
}
2012-07-24 03:35:28 +00:00
private void LuaText_SelectionChanged ( object sender , EventArgs e )
2012-07-25 17:36:26 +00:00
{
UpdateLineNumber ( ) ;
}
private void UpdateLineNumber ( )
2012-07-24 03:35:28 +00:00
{
if ( ! hasChanged )
{
int currentLineIndex = LuaText . GetLineFromCharIndex ( LuaText . SelectionStart ) ;
int lastLineIndex = LuaText . GetLineFromCharIndex ( LuaText . TextLength ) ;
int currentColumnIndex = LuaText . SelectionStart - LuaText . GetFirstCharIndexFromLine ( currentLineIndex ) ;
PositionLabel . Text = string . Format ( "Line {0}/{1}, Column {2}" , currentLineIndex + 1 , lastLineIndex + 1 , currentColumnIndex + 1 ) ;
}
}
2012-07-25 22:53:11 +00:00
2012-08-11 01:50:27 +00:00
private void LuaText_PreviewKeyDown ( object sender , PreviewKeyDownEventArgs e )
{
}
2012-07-27 00:15:02 +00:00
private void exitToolStripMenuItem_Click ( object sender , EventArgs e )
{
//TODO: check for changes and ask save
2013-04-14 23:56:45 +00:00
Close ( ) ;
2012-07-27 00:15:02 +00:00
}
2012-08-01 02:56:38 +00:00
private void LuaWriter_FormClosing ( object sender , FormClosingEventArgs e )
{
Global . Config . LuaWriterZoom = LuaText . ZoomFactor ;
2012-08-03 02:59:36 +00:00
Global . Config . LuaWriterStartEmpty = startWithEmptyScriptToolStripMenuItem . Checked ;
2012-08-04 03:35:17 +00:00
Global . Config . LuaWriterBackColor = LuaText . BackColor . ToArgb ( ) ;
2012-08-01 02:56:38 +00:00
}
private void restoreSettingsToolStripMenuItem_Click ( object sender , EventArgs e )
{
Global . Config . LuaDefaultTextColor = - 16777216 ;
Global . Config . LuaKeyWordColor = - 16776961 ;
Global . Config . LuaCommentColor = - 16744448 ;
Global . Config . LuaStringColor = - 8355712 ;
Global . Config . LuaSymbolColor = - 16777216 ;
Global . Config . LuaLibraryColor = - 16711681 ;
2012-08-02 17:48:17 +00:00
2012-08-04 03:35:17 +00:00
Global . Config . LuaDefaultTextBold = false ;
2012-08-11 01:50:27 +00:00
Global . Config . LuaKeyWordBold = false ;
Global . Config . LuaCommentBold = false ;
Global . Config . LuaStringBold = false ;
Global . Config . LuaSymbolBold = false ;
Global . Config . LuaLibraryBold = false ;
2012-08-02 17:48:17 +00:00
2012-08-04 03:35:17 +00:00
Global . Config . LuaWriterBackColor = - 1 ;
LuaText . BackColor = Color . FromArgb ( - 1 ) ;
2012-08-03 02:59:36 +00:00
Global . Config . LuaWriterStartEmpty = false ;
startWithEmptyScriptToolStripMenuItem . Checked = false ;
2012-08-01 02:56:38 +00:00
ProcessText ( ) ;
Global . Config . LuaWriterFontSize = 11 ;
Global . Config . LuaWriterFont = "Courier New" ;
LuaText . Font = new Font ( "Courier New" , 11 ) ;
Global . Config . LuaWriterZoom = 1 ;
LuaText . ZoomFactor = 1 ;
ZoomLabel . Text = "Zoom: 100%" ;
}
InputPrompt. I made the UserOK variable to change to false if the user clicks the Cancel button.
LuaWriter. Adding "end" after pressing Enter if the current line has "if", "for", etc. is now fixed. Also added some more edit menu items, like Undo, Redo, Cut, Copy, Paste, Select All, Search, Replace and Go To...
Search and Replace still need to be implemente. Implemente Go To, if the user inserts an invalid text (letters, symbols, etc) it will not close and prompt an error. Otherwise, it will go to the specified line.
2012-08-02 21:45:06 +00:00
2012-08-11 01:50:27 +00:00
private void goToToolStripMenuItem_Click ( object sender , EventArgs e )
{
InputPrompt gotodialog = new InputPrompt ( ) ;
gotodialog . FormClosing + = ( s , a ) = >
{
if ( gotodialog . UserOK )
{
int x ;
if ( ! int . TryParse ( gotodialog . UserText , out x ) )
{
a . Cancel = true ;
MessageBox . Show ( "You must enter only numbers." , "Invalid text" , MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
}
else if ( Convert . ToInt32 ( gotodialog . UserText ) > LuaText . Lines . Length )
{
a . Cancel = true ;
MessageBox . Show ( "You must enter a number between 1 and " + LuaText . Lines . Length . ToString ( ) + '.' , "Invalid Line number" , MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
}
}
} ;
gotodialog . Text = "Go To Line" ;
gotodialog . SetMessage ( "Line Number (1 - " + LuaText . Lines . Length . ToString ( ) + ')' ) ;
gotodialog . ShowDialog ( ) ;
int linepos = Convert . ToInt32 ( gotodialog . UserText ) - 1 ;
LuaText . Select ( LuaText . GetFirstCharIndexFromLine ( linepos ) + CountTabsAtBeginningOfLine ( LuaText . Lines [ linepos ] ) , 0 ) ;
}
private void selectAllToolStripMenuItem_Click ( object sender , EventArgs e )
{
LuaText . SelectAll ( ) ;
}
private void cutToolStripMenuItem_Click ( object sender , EventArgs e )
{
LuaText . Cut ( ) ;
}
private void copyToolStripMenuItem_Click ( object sender , EventArgs e )
{
LuaText . Copy ( ) ;
}
private void pasteToolStripMenuItem_Click ( object sender , EventArgs e )
{
LuaText . Paste ( ) ;
}
private void undoToolStripMenuItem_Click ( object sender , EventArgs e )
{
LuaText . Undo ( ) ;
2013-02-24 20:17:12 +00:00
redo = true ;
2012-08-11 01:50:27 +00:00
}
private void redoToolStripMenuItem_Click ( object sender , EventArgs e )
{
LuaText . Redo ( ) ;
}
2012-08-03 02:59:36 +00:00
private void startWithEmptyScriptToolStripMenuItem_Click ( object sender , EventArgs e )
{
startWithEmptyScriptToolStripMenuItem . Checked ^ = true ;
}
2012-08-04 03:35:17 +00:00
private void backgroundColorToolStripMenuItem_Click ( object sender , EventArgs e )
{
ColorDialog col = new ColorDialog ( ) ;
if ( col . ShowDialog ( ) = = DialogResult . OK )
{
LuaText . BackColor = col . Color ;
}
}
2013-02-24 20:17:12 +00:00
private void editToolStripMenuItem_DropDownOpened ( object sender , EventArgs e )
{
if ( changes )
{
undoToolStripMenuItem . Enabled = true ;
}
else
{
undoToolStripMenuItem . Enabled = false ;
}
if ( redo )
{
redoToolStripMenuItem . Enabled = true ;
}
else
{
redoToolStripMenuItem . Enabled = false ;
}
}
2012-07-22 19:54:40 +00:00
}
2012-07-20 22:02:14 +00:00
}