1- using System . Drawing ;
2- using System ;
1+ using System ;
2+ using System . Drawing ;
3+ using System . Linq ;
34using System . Windows . Forms ;
45
56namespace TinyCompiler
@@ -10,36 +11,21 @@ public WindowForm()
1011 {
1112 InitializeComponent ( ) ;
1213
13- // Subscribe to the necessary events
14+ // Subscribe to the necessary events for line number gutter
1415 tfSourceCode . TextChanged += ( object sender , EventArgs e ) => Invalidate ( ) ;
1516 tfSourceCode . VScroll += ( object sender , EventArgs e ) => Invalidate ( ) ;
16- tfSourceCode . KeyDown += RichTextBox1_KeyDown ;
17+ tfSourceCode . KeyDown += HandleRichTextBoxPaste ;
1718 }
1819
19- private void RichTextBox1_KeyDown ( object sender , KeyEventArgs e )
20+ protected override void OnPaint ( PaintEventArgs e )
2021 {
21- // Check if Ctrl+V is pressed (paste command)
22- if ( e . Control && e . KeyCode == Keys . V )
23- {
24- // Check if clipboard contains plain text
25- if ( Clipboard . ContainsText ( ) )
26- {
27- // Get plain text from clipboard
28- string plainText = Clipboard . GetText ( TextDataFormat . Text ) ;
29-
30- // Insert the plain text into the RichTextBox (at current cursor position)
31- tfSourceCode . SelectedText = plainText ;
32- }
33-
34- // Prevent default paste behavior (i.e., disabling rich text paste)
35- e . SuppressKeyPress = true ;
36- }
22+ base . OnPaint ( e ) ;
23+ DrawLineNumbers ( tfSourceCode , e . Graphics ) ;
3724 }
3825
39- private void btnCompile_Click ( object sender , System . EventArgs e )
26+ private void btnCompile_Click ( object sender , EventArgs e )
4027 {
41- string sourceCode = tfSourceCode . Text ;
42- Compiler . Compile ( sourceCode ) ;
28+ Compiler . Compile ( tfSourceCode . Text ) ;
4329
4430 PopulateTokensTable ( ) ;
4531 PopulateParseTree ( ) ;
@@ -64,23 +50,21 @@ private void PrintErrors()
6450 private void PopulateParseTree ( )
6551 {
6652 treePrase . Nodes . Clear ( ) ;
67- treePrase . Nodes . Add ( PrintParaseTree ( Compiler . treeRoot ) ) ;
53+ treePrase . Nodes . Add ( PrintParseTree ( Compiler . treeRoot ) ) ;
6854 }
6955
70- private void btnClear_Click ( object sender , System . EventArgs e )
56+ private void btnClear_Click ( object sender , EventArgs e )
7157 {
7258 // Resest UI Elements
7359 tfSourceCode . Clear ( ) ;
7460 tfErrors . Clear ( ) ;
7561 tblTokens . Rows . Clear ( ) ;
7662 treePrase . Nodes . Clear ( ) ;
7763
78- // Reset Global Data
79- Compiler . TokenStream . Clear ( ) ;
80- Errors . Clear ( ) ;
64+ Compiler . Clear ( ) ;
8165 }
8266
83- private static TreeNode PrintParaseTree ( Node root )
67+ private static TreeNode PrintParseTree ( Node root )
8468 {
8569 TreeNode tree = new TreeNode ( "Parse Tree" ) ;
8670 TreeNode treeRoot = PrintTree ( root ) ;
@@ -103,53 +87,63 @@ private static TreeNode PrintTree(Node root)
10387 TreeNode tree = new TreeNode ( root . Name ) ;
10488 foreach ( Node child in root . Children )
10589 {
106- if ( child = = null )
90+ if ( child ! = null )
10791 {
108- continue ;
92+ tree . Nodes . Add ( PrintTree ( child ) ) ;
10993 }
110-
111- tree . Nodes . Add ( PrintTree ( child ) ) ;
11294 }
11395
11496 return tree ;
11597 }
11698
117- protected override void OnPaint ( PaintEventArgs e )
99+ private void HandleRichTextBoxPaste ( object sender , KeyEventArgs e )
118100 {
119- base . OnPaint ( e ) ;
120- DrawLineNumbers ( e . Graphics ) ;
101+ if ( e . Control && ( e . KeyCode == Keys . V ) )
102+ {
103+ if ( Clipboard . ContainsText ( ) )
104+ {
105+ string plainText = Clipboard . GetText ( TextDataFormat . Text ) ;
106+ tfSourceCode . SelectedText = plainText ;
107+ }
108+
109+ // Prevent default paste behavior (i.e., disabling rich text paste)
110+ e . SuppressKeyPress = true ;
111+ }
121112 }
122113
123- private void DrawLineNumbers ( Graphics graphics )
114+ private void DrawLineNumbers ( RichTextBox richTextBox , Graphics graphics )
124115 {
125- // Set the font and brush for the line numbers
126- Font lineNumberFont = new Font ( "Consolas" , 10 ) ;
127- Brush lineNumberBrush = Brushes . Gray ;
128-
129- // Calculate the height of a single line based on the font
130- // Use GetLineFromCharIndex and GetPositionFromCharIndex to get the correct line height
131- int lineHeight = tfSourceCode . GetPositionFromCharIndex ( tfSourceCode . GetFirstCharIndexFromLine ( 1 ) ) . Y
132- - tfSourceCode . GetPositionFromCharIndex ( tfSourceCode . GetFirstCharIndexFromLine ( 0 ) ) . Y ;
133-
134- // Get the first and last visible lines
135- int firstVisibleLine = tfSourceCode . GetLineFromCharIndex ( tfSourceCode . GetCharIndexFromPosition ( new Point ( 0 , 4 ) ) ) ;
136- int lastVisibleLine = tfSourceCode . GetLineFromCharIndex ( tfSourceCode . GetCharIndexFromPosition ( new Point ( 0 , tfSourceCode . ClientRectangle . Bottom ) ) ) ;
137-
138- // Get the position of the RichTextBox control (Top is the distance from the top of the form)
139- int richTextBoxTop = tfSourceCode . Top ;
140- int richTextBoxLeft = tfSourceCode . Left ;
141-
142- // Set the initial position for drawing the line numbers
143- // Align with the left of the RichTextBox
144- int xPosition = richTextBoxLeft ;
145- int yPosition = richTextBoxTop + tfSourceCode . GetPositionFromCharIndex ( tfSourceCode . GetFirstCharIndexFromLine ( firstVisibleLine ) ) . Y ;
146-
147- // Draw the line numbers for all visible lines
148- for ( int i = firstVisibleLine ; i <= lastVisibleLine ; i ++ )
116+ Font font = richTextBox . Font ;
117+ Brush brush = Brushes . Gray ;
118+
119+ const float xPosMargin = 4.0f ;
120+ float yPos = richTextBox . Top ;
121+
122+ int firstIndex = richTextBox . GetCharIndexFromPosition ( Point . Empty ) ;
123+ int firstLine = richTextBox . GetLineFromCharIndex ( firstIndex ) ;
124+
125+ Point bottomLeft = new Point ( 0 , richTextBox . ClientRectangle . Height ) ;
126+ int lastIndex = richTextBox . GetCharIndexFromPosition ( bottomLeft ) ;
127+ int lastLine = richTextBox . GetLineFromCharIndex ( lastIndex ) ;
128+
129+ if ( richTextBox . Lines . Any ( ) && string . IsNullOrEmpty ( richTextBox . Lines . Last ( ) ) )
149130 {
150- SizeF size = graphics . MeasureString ( ( i + 1 ) . ToString ( ) , lineNumberFont ) ;
151- graphics . DrawString ( ( i + 1 ) . ToString ( ) , lineNumberFont , lineNumberBrush , xPosition - size . Width , yPosition ) ;
152- yPosition += lineHeight ; // Move to the next line position
131+ lastLine ++ ;
132+ }
133+
134+ int maxLines = richTextBox . ClientRectangle . Height / Font . Height ;
135+ for ( int i = firstLine ; ( i <= lastLine ) && ( i - firstLine <= maxLines ) ; i ++ )
136+ {
137+ string numStr = ( i + 1 ) . ToString ( ) ;
138+ PointF pos = new PointF ( richTextBox . Left - xPosMargin , yPos ) ;
139+ yPos += font . Height ;
140+
141+ using ( StringFormat sf = new StringFormat ( ) )
142+ {
143+ sf . Alignment = StringAlignment . Far ;
144+ sf . LineAlignment = StringAlignment . Near ;
145+ graphics . DrawString ( numStr , font , brush , pos , sf ) ;
146+ }
153147 }
154148 }
155149 }
0 commit comments