max2d + wxgadgets

BlitzMax Modules Forums/Brucey's Modules/max2d + wxgadgets

hi im trying to create a canvas for max2d and drawing some gadgets at the same time. I tried to merge the read-only text example and the max2d example:
SuperStrict

Framework wx.wxApp
Import wx.wxFrame
Import wx.wxPanel
Import wx.wxTextCtrl
Import wx.wxmax2D
Import wx.wxTimer

Type MyTextCtrl Extends wxTextCtrl
	
	EndType

Type mypanel Extends wxPanel
	Method oninit()
	
		SetAutoLayout( True )

	EndMethod
	EndType

New MyApp.run()


Type MyApp Extends wxApp

	Field frame:MyFrame
Field panel:MyPanel
	Method OnInit:Int()

		' Create the main application windowType MyFrame Extends wxFrame

		frame = MyFrame(New MyFrame.Create( , , "Kingdom" , , , 640 , 480) ) 
Local			panel:mypanel = MyPanel(New MyPanel.Create( frame, 0, 0, 640, 200 ))
Local	readonly:mytextctrl = MyTextCtrl(New MyTextCtrl.Create( panel, wxID_ANY, "Read only", 10,90, 140,100 , wxTE_READONLY|wxTE_MULTILINE | wxHSCROLL ))
		readonly.AppendText(" Appended.")
		' Show it and tell the application that it's our main window
		frame.show(True)
		SetTopWindow(frame)

		Return True
	End Method

End Type

Type MyFrame Extends wxFrame

	Field canvas:MyCanvas

	Method OnInit()
		
		canvas = MyCanvas(New MyCanvas.CreateWin(Self))
		
		ConnectAny(wxEVT_CLOSE, OnClose)
	End Method

	Function OnClose(event:wxEvent)
		MyFrame(event.parent).canvas.timer.Stop() ' stop the timer!
		wxWindow(event.parent).Destroy() ' remove the frame
	End Function
	
	Function OnQuit(event:wxEvent)
		wxWindow(event.parent).Close(True)
	End Function
End Type

Type MyCanvas Extends wxWindow

	Field timer:wxTimer

	Method OnInit()
		SetBackgroundStyle(wxBG_STYLE_CUSTOM)
	
		timer = New wxTimer.Create(Self)


		ConnectAny(wxEVT_PAINT, OnPaint)
		ConnectAny(wxEVT_TIMER, OnTick)

		timer.Start(30)
	End Method

	Function OnPaint(event:wxEvent)
		Local canvas:MyCanvas = MyCanvas(event.parent)

		SetGraphics wxGraphics(canvas)
		
		SetColor(0, 0, 0)
		
		Cls

		DrawLine 200,200,250,250
		
		Flip

	End Function

	Function OnTick(event:wxEvent)
		wxWindow(event.parent).Refresh()
	End Function
	
	


End Type



but i can just see a white square

has anyone done this sucessfully?

Me thinks something went wrong somewhere in your example :-)
Doesn't appear to do much here either.

could I have an example of max2d plus widgets please?

The glmax2d sample shows how to use the wxGLCanvas on a window.
You import wx.wxGLMax2D, which is a special version of BRL.GLMax2D that works better with wxWidgets.

If you want to use the DX max2d driver, I'm not very experienced with the Win32 side of things... but since you can get access to the HWND handle of a wxWindow, it should be relatively easy to connect the two together.

Has anyone tried it?

I did manage to demo the Blitz3DSDK running on a wxWindow instance at one point for someone.

SuperStrict

Framework wx.wxApp
Import wx.wxFrame
Import wx.wxglmax2D
Import wx.wxTimer
Import wx.wxPanel
Import wx.wxTextCtrl


SetGraphicsDriver GLMax2DDriver()

New MyApp.run()


Type MyTextCtrl Extends wxTextCtrl
	
	EndType

Type mypanel Extends wxPanel
	Method oninit()
	
		SetAutoLayout( True )

	EndMethod
	EndType


Type MyApp Extends wxApp

	Field frame:MyFrame

	Method OnInit:Int()

		' Create the main application windowType MyFrame Extends wxFrame
		' Create the main application windowType MyFrame Extends wxFrame
frame = MyFrame(New MyFrame.Create(Null, -1, "max2d AND gadgets", 0, 0, 640, 480))
	'	frame = MyFrame(New MyFrame.Create( , , "Kingdom" , , , 640 , 480) ) 
'Local			panel:mypanel = MyPanel(New MyPanel.Create( frame, 10, 10, 300, 100 ))

		' Show it and tell the application that it's our main window
	
		' Show it and tell the application that it's our main window
		frame.show(True)
		SetTopWindow(frame)

		Return True
	End Method

End Type



Type MyFrame Extends wxFrame

	Field canvas:MyCanvas

	Method OnInit()
Local panel:mypanel = MyPanel(New MyPanel.Create( Self, 10, 10, 300, 300 ))
Local	readonly:mytextctrl = MyTextCtrl(New MyTextCtrl.Create( panel, wxID_ANY, "Read only", 0,0, 140,100 , wxTE_READONLY|wxTE_MULTILINE | wxHSCROLL ))
		readonly.AppendText(" Appended.")

		canvas = MyCanvas(New MyCanvas.Create(Self, -1, GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER))
	
		ConnectAny(wxEVT_CLOSE, OnClose)
	End Method
	
	Function OnClose(event:wxEvent)
		MyFrame(event.parent).canvas.timer.Stop() ' we really need to stop the timer on Mac...
		event.Skip()
	End Function

End Type


Type MyCanvas Extends wxGLCanvas

	Field timer:wxTimer

	Method OnInit()
		SetBackgroundStyle(wxBG_STYLE_CUSTOM)
	
		timer = New wxTimer.Create(Self)


		ConnectAny(wxEVT_TIMER, OnTick)

		timer.Start(100)
	End Method

	Method OnPaint(event:wxPaintEvent)
		Render()
	End Method

	Method Render()


		SetGraphics CanvasGraphics2D( Self )

		SetClsColor(255, 255, 255)
		SetColor(0, 0, 0)
		
		Cls

		drawClock()
		
		Flip

	End Method

	Function OnTick(event:wxEvent)
		wxWindow(event.parent).Refresh()
	End Function
	
	
	Method drawClock()
	
		SetLineWidth(2)

		Local x:Int = 200, y:Int = 200
		Local radius:Int = 100
		' clock ticks
		For Local i:Int = 0 Until 12
			Local inset:Double = 0
		
			If i Mod 3 = 0 Then
				SetLineWidth(2)
				inset = 0.2 * radius
			Else
				inset = 0.1 * radius
				SetLineWidth(1)
			End If
			
			DrawLine x + (radius - inset) * Cos(i * 30), y + (radius - inset) * Sin(i * 30), ..
				x + radius * Cos(i * 30), y + radius * Sin (i * 30)
			
			' draw numbers
			inset = 0.3 * radius
			
			Local t:Int = (i + 2) Mod 12 + 1
			DrawText romanNumerals(t), x + (radius - inset) * Cos(i * 30) - 7, y + (radius - inset) * Sin(i * 30) - 6
		Next


		' clock hands
		Local hours:Int = CurrentTime()[0..2].toInt() Mod 12
		Local minutes:Int = CurrentTime()[3..5].toInt()
		Local seconds:Int = CurrentTime()[6..8].toInt()
		
		' hour hand:
		' the hour hand is rotated 30 degrees  per hour + 1/2 a degree per minute
		'
		SetLineWidth(4)

		DrawLine x, y, x + radius / 2 * Sin(30 * hours + minutes / 2.0), ..
				   y + radius / 2 * -Cos(30 * hours + minutes / 2.0)
		
		
		' minute hand:
		' the minute hand is rotated 6 degrees per minute + 1/10 a degree per second
		'
		SetLineWidth(2)
		DrawLine x, y, x + radius * 0.75 * Sin(6 * minutes + seconds / 10.0), ..
				   y + radius * 0.75 * -Cos(6 * minutes + seconds / 10.0)
		
		' seconds hand:
		' the second hand is rotated 6 degrees per second
		'
		SetColor(255, 0, 0)

		DrawLine x, y, x + radius * 0.7 * Sin(6 * seconds), ..
				   y + radius * 0.7 * -Cos(6 * seconds)


	End Method

	Method romanNumerals:String(value:Int)
		Local rn:String = ""
		
		While value > 9
			rn:+ "X"
			value:- 10
		Wend
	
		If value > 8 Then
			rn:+ "IX"
			value:- 9
		End If
		
		If value > 4 Then
			rn:+ "V"
			value:- 5
		End If
		
		If value > 3 Then
			rn:+ "IV"
			value:- 4
		End If
		
		While value > 0
			rn:+ "I"
			value:- 1
		Wend
		
		Return rn
	End Method

End Type

SuperStrict

Framework wx.wxApp
Import wx.wxFrame
Import wx.wxglmax2D
Import wx.wxTimer
Import wx.wxPanel
Import wx.wxTextCtrl


SetGraphicsDriver GLMax2DDriver()

New MyApp.run()


Type MyTextCtrl Extends wxTextCtrl
	
	EndType

Type mypanel Extends wxPanel
	Method oninit()
	
		SetAutoLayout( True )

	EndMethod
	EndType


Type MyApp Extends wxApp

	Field frame:MyFrame

	Method OnInit:Int()

		' Create the main application windowType MyFrame Extends wxFrame
		' Create the main application windowType MyFrame Extends wxFrame
frame = MyFrame(New MyFrame.Create(Null, -1, "max2d AND gadgets", 0, 0, 640, 480))
	'	frame = MyFrame(New MyFrame.Create( , , "Kingdom" , , , 640 , 480) ) 
'Local			panel:mypanel = MyPanel(New MyPanel.Create( frame, 10, 10, 300, 100 ))

		' Show it and tell the application that it's our main window
	
		' Show it and tell the application that it's our main window
		frame.show(True)
		SetTopWindow(frame)

		Return True
	End Method

End Type



Type MyFrame Extends wxFrame

	Field canvas:MyCanvas

	Method OnInit()
Local panel:mypanel = MyPanel(New MyPanel.Create( Self, 10, 10, 300, 300 ))
Local	readonly:mytextctrl = MyTextCtrl(New MyTextCtrl.Create( panel, wxID_ANY, "Read only", 0,0, 140,100 , wxTE_READONLY|wxTE_MULTILINE | wxHSCROLL ))
		readonly.AppendText(" Appended.")

		canvas = MyCanvas(New MyCanvas.Create(Self, -1, GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER))
	
		ConnectAny(wxEVT_CLOSE, OnClose)
	End Method
	
	Function OnClose(event:wxEvent)
		MyFrame(event.parent).canvas.timer.Stop() ' we really need to stop the timer on Mac...
		event.Skip()
	End Function

End Type


Type MyCanvas Extends wxGLCanvas

	Field timer:wxTimer

	Method OnInit()
		SetBackgroundStyle(wxBG_STYLE_CUSTOM)
	
		timer = New wxTimer.Create(Self)


		ConnectAny(wxEVT_TIMER, OnTick)

		timer.Start(100)
	End Method

	Method OnPaint(event:wxPaintEvent)
		Render()
	End Method

	Method Render()


		SetGraphics CanvasGraphics2D( Self )

		SetClsColor(255, 255, 255)
		SetColor(0, 0, 0)
		
		Cls

		drawClock()
		
		Flip

	End Method

	Function OnTick(event:wxEvent)
		wxWindow(event.parent).Refresh()
	End Function
	
	
	Method drawClock()
	
		SetLineWidth(2)

		Local x:Int = 200, y:Int = 200
		Local radius:Int = 100
		' clock ticks
		For Local i:Int = 0 Until 12
			Local inset:Double = 0
		
			If i Mod 3 = 0 Then
				SetLineWidth(2)
				inset = 0.2 * radius
			Else
				inset = 0.1 * radius
				SetLineWidth(1)
			End If
			
			DrawLine x + (radius - inset) * Cos(i * 30), y + (radius - inset) * Sin(i * 30), ..
				x + radius * Cos(i * 30), y + radius * Sin (i * 30)
			
			' draw numbers
			inset = 0.3 * radius
			
			Local t:Int = (i + 2) Mod 12 + 1
			DrawText romanNumerals(t), x + (radius - inset) * Cos(i * 30) - 7, y + (radius - inset) * Sin(i * 30) - 6
		Next


		' clock hands
		Local hours:Int = CurrentTime()[0..2].toInt() Mod 12
		Local minutes:Int = CurrentTime()[3..5].toInt()
		Local seconds:Int = CurrentTime()[6..8].toInt()
		
		' hour hand:
		' the hour hand is rotated 30 degrees  per hour + 1/2 a degree per minute
		'
		SetLineWidth(4)

		DrawLine x, y, x + radius / 2 * Sin(30 * hours + minutes / 2.0), ..
				   y + radius / 2 * -Cos(30 * hours + minutes / 2.0)
		
		
		' minute hand:
		' the minute hand is rotated 6 degrees per minute + 1/10 a degree per second
		'
		SetLineWidth(2)
		DrawLine x, y, x + radius * 0.75 * Sin(6 * minutes + seconds / 10.0), ..
				   y + radius * 0.75 * -Cos(6 * minutes + seconds / 10.0)
		
		' seconds hand:
		' the second hand is rotated 6 degrees per second
		'
		SetColor(255, 0, 0)

		DrawLine x, y, x + radius * 0.7 * Sin(6 * seconds), ..
				   y + radius * 0.7 * -Cos(6 * seconds)


	End Method

	Method romanNumerals:String(value:Int)
		Local rn:String = ""
		
		While value > 9
			rn:+ "X"
			value:- 10
		Wend
	
		If value > 8 Then
			rn:+ "IX"
			value:- 9
		End If
		
		If value > 4 Then
			rn:+ "V"
			value:- 5
		End If
		
		If value > 3 Then
			rn:+ "IV"
			value:- 4
		End If
		
		While value > 0
			rn:+ "I"
			value:- 1
		Wend
		
		Return rn
	End Method

End Type



I managed to get a textcontrol to appear but I dont why it appears at that place, or why the rest of the screen is covered in gray so that I cant see the clock

Here's a slightly tweaked version of your example :

SuperStrict

Framework wx.wxApp
Import wx.wxFrame
Import wx.wxglmax2D
Import wx.wxTimer
Import wx.wxPanel
Import wx.wxTextCtrl


SetGraphicsDriver GLMax2DDriver()

New MyApp.run()


Type MyTextCtrl Extends wxTextCtrl
	
EndType


Type MyApp Extends wxApp

	Field frame:MyFrame

	Method OnInit:Int()

		' Create the main application windowType MyFrame Extends wxFrame
		' Create the main application windowType MyFrame Extends wxFrame
frame = MyFrame(New MyFrame.Create(Null, -1, "max2d AND gadgets", , , 640, 480))
	'	frame = MyFrame(New MyFrame.Create( , , "Kingdom" , , , 640 , 480) ) 
'Local			panel:mypanel = MyPanel(New MyPanel.Create( frame, 10, 10, 300, 100 ))

		' Show it and tell the application that it's our main window
	
		' Show it and tell the application that it's our main window
		frame.show(True)
		SetTopWindow(frame)

		Return True
	End Method

End Type



Type MyFrame Extends wxFrame

	Field canvas:MyCanvas

	Method OnInit()
		Local p:wxPanel = New wxPanel.Create( Self )

Local	readonly:mytextctrl = MyTextCtrl(New MyTextCtrl.Create( p, wxID_ANY, "Read only", 10,10, 140,100 , wxTE_READONLY|wxTE_MULTILINE | wxHSCROLL ))
		readonly.AppendText(" Appended.")

		canvas = MyCanvas(New MyCanvas.Create(p, -1, GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER, 10, 115, 350, 320))
	
		ConnectAny(wxEVT_CLOSE, OnClose)
	End Method
	
	Function OnClose(event:wxEvent)
		MyFrame(event.parent).canvas.timer.Stop() ' we really need to stop the timer on Mac...
		event.Skip()
	End Function

End Type


Type MyCanvas Extends wxGLCanvas

	Field timer:wxTimer

	Method OnInit()
		SetBackgroundStyle(wxBG_STYLE_CUSTOM)
	
		timer = New wxTimer.Create(Self)


		ConnectAny(wxEVT_TIMER, OnTick)

		timer.Start(100)
	End Method

	Method OnPaint(event:wxPaintEvent)
		Render()
	End Method

	Method Render()


		SetGraphics CanvasGraphics2D( Self )

		SetClsColor(255, 255, 255)
		SetColor(0, 0, 0)
		
		Cls

		drawClock()
		
		Flip

	End Method

	Function OnTick(event:wxEvent)
		wxWindow(event.parent).Refresh()
	End Function
	
	
	Method drawClock()
	
		SetLineWidth(2)

		Local x:Int = 200, y:Int = 200
		Local radius:Int = 100
		' clock ticks
		For Local i:Int = 0 Until 12
			Local inset:Double = 0
		
			If i Mod 3 = 0 Then
				SetLineWidth(2)
				inset = 0.2 * radius
			Else
				inset = 0.1 * radius
				SetLineWidth(1)
			End If
			
			DrawLine x + (radius - inset) * Cos(i * 30), y + (radius - inset) * Sin(i * 30), ..
				x + radius * Cos(i * 30), y + radius * Sin (i * 30)
			
			' draw numbers
			inset = 0.3 * radius
			
			Local t:Int = (i + 2) Mod 12 + 1
			DrawText romanNumerals(t), x + (radius - inset) * Cos(i * 30) - 7, y + (radius - inset) * Sin(i * 30) - 6
		Next


		' clock hands
		Local hours:Int = CurrentTime()[0..2].toInt() Mod 12
		Local minutes:Int = CurrentTime()[3..5].toInt()
		Local seconds:Int = CurrentTime()[6..8].toInt()
		
		' hour hand:
		' the hour hand is rotated 30 degrees  per hour + 1/2 a degree per minute
		'
		SetLineWidth(4)

		DrawLine x, y, x + radius / 2 * Sin(30 * hours + minutes / 2.0), ..
				   y + radius / 2 * -Cos(30 * hours + minutes / 2.0)
		
		
		' minute hand:
		' the minute hand is rotated 6 degrees per minute + 1/10 a degree per second
		'
		SetLineWidth(2)
		DrawLine x, y, x + radius * 0.75 * Sin(6 * minutes + seconds / 10.0), ..
				   y + radius * 0.75 * -Cos(6 * minutes + seconds / 10.0)
		
		' seconds hand:
		' the second hand is rotated 6 degrees per second
		'
		SetColor(255, 0, 0)

		DrawLine x, y, x + radius * 0.7 * Sin(6 * seconds), ..
				   y + radius * 0.7 * -Cos(6 * seconds)


	End Method

	Method romanNumerals:String(value:Int)
		Local rn:String = ""
		
		While value > 9
			rn:+ "X"
			value:- 10
		Wend
	
		If value > 8 Then
			rn:+ "IX"
			value:- 9
		End If
		
		If value > 4 Then
			rn:+ "V"
			value:- 5
		End If
		
		If value > 3 Then
			rn:+ "IV"
			value:- 4
		End If
		
		While value > 0
			rn:+ "I"
			value:- 1
		Wend
		
		Return rn
	End Method

End Type

I've added coords/sizing to the canvas, and changed the main panel - The control added to a frame should be either a sizer or a container type, and by default (only) fills the whole child area of the frame.
Tested on Mac (PPC)... but expect it to work on Win32 also... :-)

aha!
so you put the canvas on the panel instead of the frame
AND
you specified the size and position of the canvas
thanks!