Textarea with line numbers and breakpoint setting

BlitzMax Forums/MaxGUI Module/Textarea with line numbers and breakpoint setting

JoshK(Posted 2012) [#1]
Well not really, but this code shows how it could be accomplished. The problem is the syncing the gutter with the scroll offset of the text area. Any ideas how this could be accomplished? I'll release the final versions with syntax highlighting and undo/redo if anyone can help:
' createtextarea.bmx

Import MaxGui.Drivers

Strict 

Const GUTTERWIDTH:Int=35

Global window:TGadget = CreateWindow( "My Window", 130, 20, 640, 480 )

Global textarea:TGadget = CreateTextArea( 0, 0, ClientWidth(window), ClientHeight(window), window )
SetMargins textarea,GUTTERWIDTH+2

'Gutter:
Local gutter2:TGadget=CreatePanel(0,0,GUTTERWIDTH+1, textarea.ClientHeight(),textarea)
SetGadgetLayout gutter2,1,0,1,1
SetGadgetColor gutter2,192,192,192
Local gutter:TGadget=CreatePanel(0,0,GUTTERWIDTH, gutter2.ClientHeight(),gutter2)
SetGadgetColor gutter,220,220,220
SetGadgetLayout gutter,1,1,1,1
Local label:TGadget
Local lineheight:Int=14
Local font:TGUIFont=LoadGuiFont("Arial",10)
For Local i:Int=1 To 1000
	label=CreateLabel(i,0,(i-1)* lineheight,gutter.ClientWidth(), 12,gutter,LABEL_RIGHT)
	label.SetLayout 1,0,1,0
	SetGadgetSensitivity(label,SENSITIZE_MOUSE)
	SetGadgetFont label,font
Next

SetGadgetLayout( textarea, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED, EDGE_ALIGNED )
SetGadgetText( textarea, "A TextArea gadget. :-)~n~nOne line...~n...and then another!")
ActivateGadget( textarea )
For Local n:Int=0 To 300
	AddTextAreaText textarea,"Hello, how are you today?~n"
Next

' Select the entire third (index: 2 [base-0]) line.
SelectTextAreaText( textarea, 2, 1, TEXTAREA_LINES )


' Output the properties of the current text selection (should be 1, 1 as set above).
Print "TextAreaCursor(): " + TextAreaCursor( textarea, TEXTAREA_LINES )
Print "TextAreaSelLen(): " + TextAreaSelLen( textarea, TEXTAREA_LINES )

While WaitEvent()
	Print CurrentEvent.ToString()
	Select EventID()
		Case EVENT_MOUSEDOWN
			SetGadgetColor TGadget(EventSource()),0,0,255,1
			SetGadgetColor TGadget(EventSource()),255,255,255,0
		Case EVENT_WINDOWCLOSE
			End
		Case EVENT_APPTERMINATE
			End
	End Select
Wend



col(Posted 2012) [#2]
Hey Josh,

I have some code for Win32 only, is that any good?

I setup a native Win32 hook and also a MaxGUI hook to catch window size changes and textarea changes, obviously it won't work as is for you, but I'm sure you can pull the info for what you may need :-

Type TCodeEditorMargin
	Field _TextArea:TGadget
	Field _Font:TGUIFont
	
	Field _ShowLineNumbers
	Field _ShowFoldings
	Field _LineNumbers:TGadget
	Field _Foldings:TGadget
	
	Field _Width
	
	Method Create:TCodeEditorMargin(TextArea:TGadget,Parent:TGadget)
		_Width = 16
		
		_LineNumbers = CreateCanvas(0,0,_Width,ClientHeight(TextArea),Parent)
		SetGadgetLayout  _LineNumbers,1,0,1,1
	
		_TextArea = TextArea

		Return Self
	EndMethod
	
	Method SetFont(Font:TGUIFont)
		_Font = Font
	EndMethod
	
	Method ShowLineNumbers(Show)
		_ShowLineNumbers = Show
		
		UpdateMarginWidth()
	EndMethod
	
	Method UpdateMarginWidth()
		_Width = 16
		
		If _ShowLineNumbers _Width :+ 3*16
		
		SetGadgetShape(_LineNumbers,0,0,_Width,GadgetHeight(_LineNumbers))
	EndMethod
	
	Method GetWidth()
		Return _Width
	EndMethod
	
	Method DrawLineNumbers(hDC,Canvas[])
		'Max2D cant do this bit very nicely so do it natively
		Local Char = CharAtPos(1,1)
		Local LineNo = TextAreaLine(_TextArea,Char)
		Local Pos[] = ScrPosOfChar(Char)
		Local MaxLines = LineCount()
		Local X = Canvas[0]+15
		Local Y = Pos[1]	
		Local MaxY = ClientHeight(_LineNumbers)
		
		Canvas[0] :+ 15
		FillRect(hDC,Canvas,GetStockObject(WHITE_BRUSH))
	
		SelectObject(hDC,_Font.handle)
		SetTextColor(hDC,$00AF912D)
		
		While Y < MaxY
			LineNo :+ 1
			Local Line$ = RSet(LineNo,6)
			TextOutW(hDC,15,Y,Line,Len(Line))
			Y :+ 16 'font height

			If LineNo = MaxLines Exit
		Wend
		
		For Y = 0 Until MaxY Step 2
			SetPixel(hDC,Canvas[2]-1,Y,$00AF912D)
		Next
	EndMethod
	
	Method CharAtPos(X,Y)
		Local Pos[] = [X,Y]
		
		Return SendMessageW(_TextArea.Query(QUERY_HWND_CLIENT),EM_CHARFROMPOS,0,Int Byte Ptr Pos)
	EndMethod
	
	Method ScrPosOfChar[](Char)
		Local Pos[2]
		
		SendMessageW(_TextArea.Query(QUERY_HWND_CLIENT),EM_POSFROMCHAR,Int Byte Ptr Pos,Char)
		Return Pos
	EndMethod
	
	Method LineCount()
		Return SendMessageW(_TextArea.Query(QUERY_HWND_CLIENT),EM_GETLINECOUNT,0,0)
	EndMethod
	
	Method Update()
		Local Canvas[4]
		Local hWnd,hDC
		
		hWnd = _LineNumbers.Query(QUERY_HWND_CLIENT)
		
		'Fill grey margin on the left
		GetClientRect(hWnd,Canvas)
		hDC = GetDC(hWnd)
		FillRect(hDC,Canvas,GetSysColorBrush(COLOR_3DLIGHT))
		
		'Line numbers?
		If _ShowLineNumbers DrawLineNumbers(hDC,Canvas)
		
		ReleaseDC(hWnd,hDC)
	EndMethod
EndType


Last edited 2012

Last edited 2012


JoshK(Posted 2012) [#3]
Interesting. I'm at home on my Mac but I'll take a look this afternoon.

Last edited 2012


col(Posted 2012) [#4]
These methods part of a Type that has the margin type as a field variable _Margin and are called by the hooks

Method Win32Msg(hWnd,Msg,Wp,Lp)		
		Select MSG
			Case WM_PAINT,WM_NCPAINT
				Update
				If _Margin _Margin.Update

		EndSelect
	EndMethod

	Method MaxGUIMsg:Object(ID,Data:TEvent,Context:Object)
		Select Data.Id
			Case EVENT_GADGETSELECT,EVENT_GADGETPAINT,EVENT_APPRESUME
				If _Margin _Margin.Update
				UpdateWindow _hWnd

		EndSelect

		Return Data
	EndMethod


Last edited 2012


JoshK(Posted 2012) [#5]
I haven;t tried your code yet, but I got this working on OSX with some custom gadget overdrawing:



MacSven(Posted 2012) [#6]
Can you post your code JoshK?


JoshK(Posted 2012) [#7]
1. Replace TextView::SetMargins with this:
-(void)setMargins:(int)leftmargin{
//	[self setTextContainerInset:NSMakeSize( leftmargin, 0) ];
	[style setFirstLineHeadIndent: leftmargin];
	[style setHeadIndent: leftmargin];
	[storage addAttribute:NSParagraphStyleAttributeName value:style range:NSMakeRange(0,[storage length])];}


2. Add this function in the TextView implementation block:
-(void)drawRect:(NSRect)rect
{
	[super drawRect:rect];	
	NSRect rect1=[scroll documentVisibleRect];
	float y=rect1.origin.y;
	
	NSColor *myColor;
	
	myColor = [NSColor colorWithCalibratedRed:1.0f green:1.0f blue:1.0f alpha:1.0f];
	[myColor set];
	NSRectFill(NSMakeRect(0, 0, 41, self.bounds.size.height));
	myColor = [NSColor colorWithCalibratedRed:0.9f green:0.9f blue:0.9f alpha:1.0f];
	[myColor set];
	NSRectFill(NSMakeRect(0, 0, 35, self.bounds.size.height));
	myColor = [NSColor colorWithCalibratedRed:0.5f green:0.5f blue:0.5f alpha:1.0f];
	[myColor set];	
	[myColor setFill];
	NSRectFill(NSMakeRect(35, 0, 1, self.bounds.size.height));
	
	int i;
	int linecount=[storage length];
	linecount=LinePos([storage string],linecount)+1;

	for (i=0; i<linecount; i++)
	{
		//NSString *string = [NSString stringWithString:@"test"];
		NSString *string = [NSString stringWithFormat:@"%d", i+1];
		NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:
		[NSColor grayColor], NSForegroundColorAttributeName,nil]; // you can add the font... here
		NSSize size = [string sizeWithAttributes:attributes];
		[string drawInRect:NSMakeRect(35-size.width-2, i*14-1, rect.size.width - 140, 500) withAttributes: attributes];	
	}
}


3. When you create a text area, set the margin to 37.

Last edited 2012


MacSven(Posted 2012) [#8]
Changed it but after rebuild iv got this error:

Compiling:cocoa.macos.m
/Applications/BlitzMax/mod/maxgui.mod/cocoamaxgui.mod/cocoa.macos.m: In function '-[PanelViewContent drawRect:]':
/Applications/BlitzMax/mod/maxgui.mod/cocoamaxgui.mod/cocoa.macos.m:834: error: 'scroll' undeclared (first use in this function)
/Applications/BlitzMax/mod/maxgui.mod/cocoamaxgui.mod/cocoa.macos.m:834: error: (Each undeclared identifier is reported only once
/Applications/BlitzMax/mod/maxgui.mod/cocoamaxgui.mod/cocoa.macos.m:834: error: for each function it appears in.)
/Applications/BlitzMax/mod/maxgui.mod/cocoamaxgui.mod/cocoa.macos.m:851: error: 'storage' undeclared (first use in this function)
/Applications/BlitzMax/mod/maxgui.mod/cocoamaxgui.mod/cocoa.macos.m: At top level:
/Applications/BlitzMax/mod/maxgui.mod/cocoamaxgui.mod/cocoa.macos.m:1592: error: expected identifier or '(' before '}' token
Build Error: failed to compile /Applications/BlitzMax/mod/maxgui.mod/cocoamaxgui.mod/cocoa.macos.m
Process complete


MacSven(Posted 2012) [#9]
Is this the right positions:

A rebuild is now ok. But the sample of the bmax have no effect



-(void)setTabs:(int)tabs{	
	[style setTabStops:[NSArray array]];	//Clear any TabStops
	[style setDefaultTabInterval: tabs];	//Set recurring TabStops remembering to convert from twips->pixels
	[storage addAttribute:NSParagraphStyleAttributeName value:style range:NSMakeRange(0,[storage length])];
}

-(void)setMargins:(int)leftmargin{
//	[self setTextContainerInset:NSMakeSize( leftmargin, 0) ];
	[style setFirstLineHeadIndent: leftmargin];
	[style setHeadIndent: leftmargin];
	[storage addAttribute:NSParagraphStyleAttributeName value:style range:NSMakeRange(0,[storage length])];


//	[self setTextContainerInset:NSMakeSize( leftmargin, 0) ];
//	[style setFirstLineHeadIndent: leftmargin*8];
//	[style setHeadIndent: leftmargin*8];
//	[storage addAttribute:NSParagraphStyleAttributeName value:style range:NSMakeRange(0,[storage length])];	
}

-(void)setText:(NSString*)text{



// TextView

@implementation TextView
-(void)drawRect:(NSRect)rect
{
	[super drawRect:rect];	
	NSRect rect1=[scroll documentVisibleRect];
	float y=rect1.origin.y;
	
	NSColor *myColor;
	
	myColor = [NSColor colorWithCalibratedRed:1.0f green:1.0f blue:1.0f alpha:1.0f];
	[myColor set];
	NSRectFill(NSMakeRect(0, 0, 41, self.bounds.size.height));
	myColor = [NSColor colorWithCalibratedRed:0.9f green:0.9f blue:0.9f alpha:1.0f];
	[myColor set];
	NSRectFill(NSMakeRect(0, 0, 35, self.bounds.size.height));
	myColor = [NSColor colorWithCalibratedRed:0.5f green:0.5f blue:0.5f alpha:1.0f];
	[myColor set];	
	[myColor setFill];
	NSRectFill(NSMakeRect(35, 0, 1, self.bounds.size.height));
	
	int i;
	int linecount=[storage length];
	linecount=LinePos([storage string],linecount)+1;

	for (i=0; i<linecount; i++)
	{
		//NSString *string = [NSString stringWithString:@"test"];
		NSString *string = [NSString stringWithFormat:@"%d", i+1];
		NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:
		[NSColor grayColor], NSForegroundColorAttributeName,nil]; // you can add the font... here
		NSSize size = [string sizeWithAttributes:attributes];
		[string drawInRect:NSMakeRect(35-size.width-2, i*14-1, rect.size.width - 140, 500) withAttributes: attributes];	
	}
}
-(id)initWithFrame:(NSRect)rect{
	
	scroll=[[NSScrollView alloc] initWithFrame:rect];
//	[scroll setVerticalScroller:[[Scroller alloc] init]];
//	[scroll setHorizontalScroller:[[Scroller alloc] init]];



JoshK(Posted 2012) [#10]
You might have to declare the function in the "interface" section.

You can download the whole file here:
http://www.leadwerks.com/post/cocoa.macos.m

Here's a compiled demo with source code:
http://www.leadwerks.com/post/maclinenumbers.zip

Last edited 2012


JoshK(Posted 2012) [#11]
I can override the mouse down event to ignore mouse clicks in the gutter, but can't change the cursor:
- (void)mouseDown:(NSEvent *)theEvent {
	NSPoint p=[self convertPoint:[theEvent locationInWindow] fromView:nil];
    if (p.x>35)
	{
		[super mouseDown:theEvent];
	}
}



col(Posted 2012) [#12]
Hey,

Like I say I've only worked on the win32 version, and to keep the mouse pointer I had chosen I needed to change a MaxGUI internal reference to the internal windows pointer handle for the changes to be retained. In the TWindowsGUIDriver there's a field called _cursor that also needs to be the cursor value as well as setting it in windows. Otherwise MaxGUI would change it back to the previous cursor.

I'm not sure on the MacOS equivalent though, maybe it has a similar code setup.

Last edited 2012


JoshK(Posted 2012) [#13]
col, your code has a lot of undeclared Windows functions.


col(Posted 2012) [#14]
Indeed there is. The code was quickly pulled from a Type that i'm making that includes edited line highlighting, folding, syntax highlighting and intellisense completion, almost a replica of the MSVC code editor blah blah.

Anyway, these should help out for that little extract...



MacSven(Posted 2012) [#15]
How can i now set the font and font size in the linecounter?


JoshK(Posted 2012) [#16]
No idea, I never got that far.


JoshK(Posted 2012) [#17]
Klepto has a new Scintilla module he's working on that is far better than this. I recommend you go with his solution when it becomes available.


col(Posted 2012) [#18]
In case anyone is still interested in this, I made a simpler version of a textarea with line numbers for Win32 ( tested on Win7 and Win8 ).
It uses 2 MaxGUI textarea and some low level window functions to keep them in sync.

The nice part is there is no modification to MaxGUI at all.

This could go along with a MacOs version that JoshK may still be playing around with... or use for anything you want to :)



ExampleApp.bmx :-
Strict

Import MaxGUI.Drivers
Import "CodeEdit.bmx"

AppFile = StripExt(AppFile.Replace(".debug",""))+".bmx"

Global Window:TGadget = CreateWindow("Line number example app",0,0,800,600,Null,WINDOW_DEFAULT|WINDOW_CENTER)
Global CodeEdit:TCodeEdit = CreateCodeEdit(Window)

' Retrieve the source area as a regular MaxGUI TextArea.
Global SourceArea:TGadget = CodeEdit.SourceArea()
SetTextAreaText(SourceArea,LoadText(AppFile))

Repeat
	WaitEvent()
	RunHooks(CodeEditHook,Null)

	Select EventID()
		Case EVENT_WINDOWCLOSE,EVENT_APPTERMINATE
			End
			
	EndSelect
Forever



And 'CodeEdit.bmx'
' CodeEdit

Strict

Import MaxGUI.Drivers

?Win32

Global CodeEditHook = AllocHookId()

Function CreateCodeEdit:TCodeEdit(Parent:TGadget)
	Return New TCodeEdit.Create(Parent)
EndFunction

Type TCodeEdit
	Global _NextWndProc	
	Field _Font:TGUIFont
	Field _CharWidth
	Field _MarginWidth
	Field _MainPanel:TGadget
	Field _SourceArea:TGadget
	Field _LineNos:TGadget
	
	Field _hWndLineNos
	Field _hWndSource
	
	Method Create:TCodeEdit(Parent:TGadget)		
		' This hook is solely used to detect when the textarea is scrolled so I can update the line numbers.
		_NextWndProc = SetWindowsHookExW(WH_CALLWNDPROC,CodeEditWndProc,GetModuleHandleW(Null),GetCurrentThreadID())

		_Font = LoadGuiFont("Consolas",10)
		_CharWidth = _Font.CharWidth(Asc("0"))
		
		_MarginWidth = _CharWidth*6 ' 5 really!

		_MainPanel = CreatePanel(0,0,ClientWidth(Parent),ClientHeight(Parent),Parent,PANEL_SUNKEN)
		SetGadgetLayout(_MainPanel,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED)
		_SourceArea = CreateTextArea(_MarginWidth,0,ClientWidth(_MainPanel)-_MarginWidth,ClientHeight(_MainPanel),_MainPanel)
		SetGadgetLayout(_SourceArea,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED)
		_LineNos = CreateTextArea(0,0,_MarginWidth,ClientHeight(_MainPanel),_MainPanel)
		SetGadgetLayout(_LineNos,EDGE_ALIGNED,0,EDGE_ALIGNED,EDGE_ALIGNED)
		SetGadgetColor(_LineNos,240,240,240)
		SetMargins(_SourceArea,10)
		SetTextAreaTabs(_SourceArea,_Font.CharWidth(Asc(" ")) * 3 )

		' Save some CPU cycles later
		_hWndLineNos = QueryGadget(_LineNos,QUERY_HWND)
		_hWndSource = QueryGadget(_SourceArea,QUERY_HWND)

		' Set no borders for the LineNos and SourceText areas
		SetWindowLongW(_hWndSource,GWL_EXSTYLE,GetWindowLongW(_hWndSource,GWL_EXSTYLE)~WS_EX_CLIENTEDGE)
		SetWindowLongW(_hWndLineNos,GWL_EXSTYLE,GetWindowLongW(_hWndLineNos,GWL_EXSTYLE)~WS_EX_CLIENTEDGE)

		' Set Linenos so that user cannot select/edit them
		SendMessageW(_hWndLineNos,EM_HIDESELECTION,True,0)

		' Set to plain text only and set the undo limit
		SendMessageW(_hWndSource,EM_SETTEXTMODE,TM_PLAINTEXT,0)
		'SendMessageW(_hWndSource,EM_SETUNDOLIMIT,1024*1024,0)
		
		' Set fonts
		SetGadgetFont(_SourceArea,_Font)
		SetGadgetFont(_LineNos,_Font)

		' Force a repaint to make sure the borders are visually removed
		SetGadgetShape(Parent,GadgetX(Parent),GadgetY(Parent),ClientWidth(Parent),ClientHeight(parent))
		
		' Equivalent of MaxGUIs SetGadgetExtra
		Local Handle = HandleFromObject(Self)
		SetWindowLongW(QueryGadget(_MainPanel,QUERY_HWND),-21,Handle)
		SetWindowLongW(_hWndSource,-21,Handle)
		SetWindowLongW(_hWndLineNos,-21,Handle)
		
		' Init
		UpdateLineCount()
		
		AddHook CodeEditHook,Hook,Self
		
		Return Self
	EndMethod
	
	Function Hook:Object(Id,Data:Object,context:Object)
		If ActiveGadget() = TCodeEdit(Context)._LineNos ActivateGadget(TCodeEdit(Context)._SourceArea)
		
		Return Data
	EndFunction
	
	' This os callback is used to detect the sourcearea has been changed under any circumstance and needs redrawing, 
	' I use that to adjust the LineNos accordingly.
	Function CodeEditWndProc(code,wp,lp)"Win32"
		If code >= 0 And wp = 0
			Local cwp:Int Ptr = Int Ptr lp

			Local _CodeEdit:TCodeEdit = TCodeEdit(HandleToObject(GetWindowLongW(cwp[3],-21)))
			
			If _CodeEdit
				Local Style
				
				' Turn OFF scrollbars for the LineNos - do it here because windows does insist on resetting the style at any given chance. lol.
				Style = GetWindowLongW(_CodeEdit._hWndLineNos,GWL_STYLE)
				If (Style & WS_VSCROLL) SetWindowLongW(_CodeEdit._hWndLineNos,GWL_STYLE,Style~WS_VSCROLL)
				If (Style & WS_HSCROLL) SetWindowLongW(_CodeEdit._hWndLineNos,GWL_STYLE,Style~WS_HSCROLL)

				Select cwp[2]
					Case WM_NOTIFY,WM_COMMAND
						' Update the LineNos
						_CodeEdit.UpdateLineCount()
					
					Case WM_PAINT
						' Keep linenos and the SourceText area in sync with each other
						Style = GetWindowLongW(_CodeEdit._hWndSource,GWL_STYLE)

						' Test if scrollbar is visible in the SourceText area, if so make the _LineNos is slightly smaller to match the same height
						Local Showing = (Style & WS_HSCROLL) = WS_HSCROLL
						SetGadgetShape(_CodeEdit._LineNos,0,0,GadgetWidth(_CodeEdit._LineNos),ClientHeight(_CodeEdit._MainPanel)-(GetSystemMetrics(SM_CYHSCROLL))*Showing)

						Local Pos[2]
						SendMessageW(cwp[3],EM_GETSCROLLPOS,0,Int Byte Ptr Pos)
						If cwp[3] = _CodeEdit._hWndSource
							SendMessageW(_CodeEdit._hWndLineNos,EM_SETSCROLLPOS,0,Int Byte Ptr [0,Pos[1]])
						ElseIf cwp[3] = _CodeEdit._hWndLineNos
							Local SPos[2]
							'Keep the original SourceText area horizontal scroll position but adjust the Y position to match the LineNos
							SendMessageW(_CodeEdit._hWndSource,EM_GETSCROLLPOS,0,Int Byte Ptr SPos)
							Pos[0] = SPos[0]
							SendMessageW(_CodeEdit._hWndSource,EM_SETSCROLLPOS,0,Int Byte Ptr Pos)
						EndIf
						
				EndSelect
				
			EndIf
		EndIf

		Return CallNextHookEx(_NextWndProc, code, wp, lp)
	EndFunction
	
	Method UpdateLineCount()
		' Naive approach
		Local SourceLineCount = SendMessageW(_hWndSource,EM_GETLINECOUNT,0,0)
		Local LineNosLineCount = SendMessageW(_hWndLineNos,EM_GETLINECOUNT,0,0)
		
		If (SourceLineCount = LineNosLineCount) And SourceLineCount <> 1 Return

		Local Nos$,i
		For i = 0 Until SourceLineCount - 1
			Nos :+ RSet((i+1) + "~n",6)
		Next
		Nos :+ RSet((i+1) ,5)

		SetTextAreaText(_LineNos,Nos)
		RedrawGadget(_LineNos)
	EndMethod
	
	Method SetFont(Font:TGUIFont)
		_Font = Font
		
		_CharWidth = _Font.CharWidth(Asc("0"))		
		_MarginWidth = _CharWidth*6 ' 5 really!

		SetGadgetShape(_LineNos,0,0,_MarginWidth,GadgetHeight(_LineNos))
		SetGadgetShape(_SourceArea,_MarginWidth,0,ClientWidth(_MainPanel)-_MarginWidth,GadgetHeight(_SourceArea))
		SetGadgetFont(_SourceArea,_Font)
		SetGadgetFont(_LineNos,_Font)
	EndMethod
	
	Method SourceArea:TGadget()
		Return _SourceArea
	EndMethod
	
	Method Margin:TGadget()
		Return _LineNos
	EndMethod
EndType

?


Last edited 2012


col(Posted 2012) [#19]
Oh, you can set the font for both the line numbers and source area by using

CodeEdit.SetFont(LoadGuiFont("Consolas",10))


Its set up for using fixed width fonts, but I suppose that could be changed.

Another pic with 2 textareas with line numbers, loaded with 2 different documents :-


Source:-
Strict

Import MaxGUI.Drivers
Import "CodeEdit.bmx"

AppFile = StripExt(AppFile.Replace(".debug",""))+".bmx"

Local Font:TGuiFont = LoadGuiFont("Consolas",10)

Global Window:TGadget = CreateWindow("Line number example app",0,0,900,600,Null,WINDOW_DEFAULT|WINDOW_CENTER)
Global Panel1:TGadget = CreatePanel(20,20,400,400,Window,PANEL_GROUP,"Window1")
Global Panel2:TGadget = CreatePanel(420,20,400,400,Window,PANEL_GROUP,"Window2")

SetGadgetFont(Window,Font)
SetGadgetFont(Panel1,Font)
SetGadgetFont(Panel2,Font)

Global CodeEdit1:TCodeEdit = CreateCodeEdit(Panel1)
CodeEdit1.SetFont(LoadGuiFont("DejaVu Sans Mono",7))

Global CodeEdit2:TCodeEdit = CreateCodeEdit(Panel2)
CodeEdit2.SetFont(LoadGuiFont("Consolas",11))

' Retrieve the source area as a regular MaxGUI TextArea.
Global SourceArea1:TGadget = CodeEdit1.SourceArea()
SetTextAreaText(SourceArea1,LoadText(AppFile))

' Get the LineNo textarea and change the color of the text
Global Lines1:TGadget = CodeEdit1.Margin()
SetGadgetTextColor(Lines1,60,120,240)

Global SourceArea2:TGadget = CodeEdit2.SourceArea()
SetTextAreaText(SourceArea2,"This is another~nsimple example~nof~n~nusing multiple documents that~nhave~nline numbers, and~ndifferent fonts")

Repeat
	WaitEvent()
	RunHooks(CodeEditHook,Null)

	Select EventID()
		Case EVENT_WINDOWCLOSE,EVENT_APPTERMINATE
			End
			
	EndSelect
Forever


Last edited 2012