CEGUI and WxMax

BlitzMax Modules Forums/Brucey's Modules/CEGUI and WxMax

Is there a work around for this as of yet?

Work around for what?

Using cegui in a wxmax control (canvas)?

i'm able to get it working ok using maxguiex, but with wxmax I get the opengl driver error, as it's not compatible it seems.

edit:

OpenGLRenderer failed to initialise the GLEW library. Missing GL version


Well, I've got it rendering no problem... but there appears to be a bug with the Eventhooks where EmitEventHook is returning 0 on the call to AddHook EmitEventHook,TCEEvent.Keyhook,Null,0 in CEGUI.
So, I'm working out a way to include a "different" event handler, which will work here.

I'll post code when it's done :-p

Drop this in the raknet examples folder to test (without having to change the CEGUI scheme/datafile stuff).
You'll also need to update CEGUI. I've added a second param to CEGUI_init() which disables the built-in event handling, since it wasn't working here with wxMax (Looks like a bug with AddHook tbh).

Seems to work on Mac. Not tested elsewhere yet.

SuperStrict

Framework wx.wxApp
Import wx.wxFrame
Import wx.wxglmax2D
Import wx.wxGLCanvas
Import wx.wxTimer
Import BaH.CEGUI
Import wx.wxMouseEvent

SetGraphicsDriver wxGLGraphicsDriver(),GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER

' Start the app !!!!!
New MyApp.run()

cegui_cleanup()

Type MyApp Extends wxApp

	Field frame:MyFrame

	Method OnInit:Int()

		frame = MyFrame(New MyFrame.Create(,,"wxMax + CEGUI", -1, -1, 800, 600))

		frame.Center()
		frame.show()
		
		Return True
	
	End Method

End Type


Type MyFrame Extends wxFrame

	Field canvas:MyCanvas

	Method OnInit()

		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
	Field ax#, ay#, tim#

	Field helperWindow:TCEWindow
	Field helperLabel:TCEWindow
	Field helperText:TCEEditbox
	Field helperSubmit:TCEPushButton
	
	Field initialized:Int

	Method OnInit()
	
		SetCursor(New wxCursor.StockCreate(wxCURSOR_BLANK))

		timer = New wxTimer.Create(Self)

		EnablePolledInput(Self)

		ConnectAny(wxEVT_TIMER, OnTimer)
'		ConnectAny(wxEVT_TIMER, OnTick)
		ConnectAny(wxEVT_KEY_DOWN, OnKeyDown)
		ConnectAny(wxEVT_KEY_UP, OnKeyUp)
		ConnectAny(wxEVT_CHAR, OnKeyChar)
		ConnectAny(wxEVT_MOUSE_EVENTS, OnMouse)

		timer.Start(16)
	End Method

	Function OnTimer(event:wxEvent)
		MyCanvas(event.parent).Refresh()
	End Function
	
	Method OnPaint(event:wxPaintEvent)
		Render()
	End Method

	Method Render()

		SetGraphics CanvasGraphics2D( Self )
		
		cls

		DrawText MouseX() + ", " + MouseY(), 20, 60

		If Not initialized Then
		
			initialized = True

			Init_CEGUI(Null, True)
			
			TCESchemeManager.loadScheme("datafiles/schemes/WindowsLook.scheme")
			
			If Not TCEFontManager.isFontPresent( "DejaVuSans-10" ) Then
				TCEFontManager.createFont( "datafiles/fonts/DejaVuSans-10.font" )
			End If
	
			TCESystem.setDefaultMouseCursor("WindowsLook", "MouseArrow")
	
			Local root:TCEWindow = TCEWindowManager.loadWindowLayout("datafiles/layouts/helper.layout")
			TCESystem.setGUISheet(root)
			
			helperWindow = TCEWindowManager.getWindow("HelperWindow")
			helperWindow.Hide()
			
			helperLabel = TCEWindowManager.getWindow("Helper/label")
			helperText = TCEEditbox(TCEWindowManager.getWindow("Helper/Editbox"))
			helperSubmit = TCEPushButton(TCEWindowManager.getWindow("Helper/Submit"))
			
			helperSubmit.subscribeEvent(TCEPushButton.EventClicked, submitted) ' click
			helperText.subscribeEvent(TCEEditbox.EventTextAccepted, submitted) ' enter

			RequestValue("Hello", "Some stuff")
		End If

		TCESystem.renderGUI()
		
		Flip
	
	End Method

	Function submitted:Int(args:TCEEventArgs)
	End Function

	Method RequestValue(title:String, label:String)
		helperWindow.setText(title)
		helperLabel.setText(label)

		helperText.setText("")

		helperWindow.show()
		
		helperText.activate()
	End Method

	Function OnKeyDown(event:wxEvent)
		Local evt:wxKeyEvent = wxKeyEvent(event)
		Local key:Int = MapWxKeyCodeToBlitz(evt.GetKeyCode())
		EmitEvent(CreateEvent( EVENT_KEYDOWN, event.parent, key)) ' event for Max2D

		TCESystem.injectKeyDown(key)

		event.Skip()
	End Function

	Function OnKeyUp(event:wxEvent)
		Local evt:wxKeyEvent = wxKeyEvent(event)
		Local key:Int = MapWxKeyCodeToBlitz(evt.GetKeyCode())
		EmitEvent(CreateEvent( EVENT_KEYUP, event.parent, key)) ' event for Max2D
		
		TCESystem.injectKeyUp(key)
		
		event.Skip()
	End Function

	Function OnKeyChar(event:wxEvent)
		Local evt:wxKeyEvent = wxKeyEvent(event)
		'Local key:Int = MapWxKeyCodeToBlitz(evt.GetKeyCode())
		'EmitEvent(CreateEvent( EVENT_KEYDOWN, event.parent, key)) ' event for Max2D

		TCESystem.injectChar(Asc(evt.GetUnicodeKey()))

		event.Skip()
	End Function
	
	Function OnMouse(event:wxEvent)
		Local evt:wxMouseEvent = wxMouseEvent(event)
	
		Local elapsed:Float = (MilliSecs() - cegui_startTime)/1000.0

		Select evt.GetEventType()
			Case wxEVT_MOTION
				Local x:Int, y:Int
				evt.GetPosition(x, y)
				EmitEvent(CreateEvent( EVENT_MOUSEMOVE, event.parent, 0, 0, x, y)) ' event for Max2D

				TCESystem.injectTimePulse(elapsed)
				TCESystem.injectMousePosition(x, y)
				
			Case wxEVT_LEFT_DOWN
				EmitEvent(CreateEvent( EVENT_MOUSEDOWN, event.parent, 1)) ' event for Max2D

				TCESystem.injectTimePulse(elapsed)
				TCESystem.injectMouseButtonDown(1)
			Case wxEVT_LEFT_UP
				EmitEvent(CreateEvent( EVENT_MOUSEUP, event.parent, 1)) ' event for Max2D

				TCESystem.injectTimePulse(elapsed)
				TCESystem.injectMouseButtonUp(1)
			
			Case wxEVT_LEFT_DCLICK
			
				TCESystem.injectTimePulse(elapsed)
				TCESystem.injectMouseButtonDown(1)
				TCESystem.injectTimePulse(elapsed)
				TCESystem.injectMouseButtonUp(1)
			
			Case wxEVT_RIGHT_DOWN
				EmitEvent(CreateEvent( EVENT_MOUSEDOWN, event.parent, 2)) ' event for Max2D

				TCESystem.injectTimePulse(elapsed)
				TCESystem.injectMouseButtonDown(2)
			Case wxEVT_RIGHT_UP
				EmitEvent(CreateEvent( EVENT_MOUSEUP, event.parent, 2)) ' event for Max2D

				TCESystem.injectTimePulse(elapsed)
				TCESystem.injectMouseButtonUp(2)
			Case wxEVT_MIDDLE_DOWN
				EmitEvent(CreateEvent( EVENT_MOUSEDOWN, event.parent, 3)) ' event for Max2D

				TCESystem.injectTimePulse(elapsed)
				TCESystem.injectMouseButtonDown(3)
			Case wxEVT_MIDDLE_UP
				EmitEvent(CreateEvent( EVENT_MOUSEUP, event.parent, 3)) ' event for Max2D

				TCESystem.injectTimePulse(elapsed)
				TCESystem.injectMouseButtonUp(3)
			Case wxEVT_MOUSEWHEEL

			Case wxEVT_ENTER_WINDOW
				wxWindow(Event.parent).SetCursor(New wxCursor.StockCreate(wxCURSOR_BLANK))

			Case wxEVT_LEAVE_WINDOW
				wxWindow(Event.parent).SetCursor(New wxCursor.StockCreate(wxCURSOR_ARROW))

		End Select
		event.Skip()
	End Function

End Type


Yes, the event stuff is pretty hefty. It's always there (in Max2D etc), but that's usually hidden away from you - what you don't know about won't hurt you, eh?
Here I'm passing events to both Max2D and CEGUI. (except of course we're using my wx version of GLMax2D - because we need to use our own GL implementation - Had Mark used Factories, like he has with image loaders and the likes, we could have done this all a bit more tidier... oh well).

Obviously this is just a hacked together mess, but it shows the two running together. :-)

I'm understanding what's going on in the code, however i'm hitting an error:

TCESystem.injectTimePulse(elapsed)

>

Function injectTimePulse(time:Float)
	bmx_cegui_system_injectTimePulse(cegui_systemPtr ,time)
End Function


Commenting out the line just ends up giving me an error from mouse injection. I have the latest cegui from the svn built. And I altered the helper.layout to my own since I don't have it, although that shouldn't be the issue as before the error I can see the layout loading properly.

Here's a wee update :

SuperStrict

Framework wx.wxApp
Import wx.wxFrame
Import wx.wxglmax2D
Import wx.wxGLCanvas
Import wx.wxTimer
Import BaH.CEGUI
Import wx.wxMouseEvent

SetGraphicsDriver wxGLGraphicsDriver(),GRAPHICS_BACKBUFFER|GRAPHICS_DEPTHBUFFER

' Start the app !!!!!
New MyApp.run()

cegui_cleanup()

Type MyApp Extends wxApp

	Field frame:MyFrame

	Method OnInit:Int()

		frame = MyFrame(New MyFrame.Create(,,"wxMax + CEGUI", -1, -1, 800, 600))

		frame.Center()
		frame.show()
		
		Return True
	
	End Method

End Type


Type MyFrame Extends wxFrame

	Field canvas:MyCanvas

	Method OnInit()

		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
	Field ax#, ay#, tim#

	Field helperWindow:TCEWindow
	Field helperLabel:TCEWindow
	Field helperText:TCEEditbox
	Field helperSubmit:TCEPushButton
	
	Field initialized:Int

	Method OnInit()
	
		SetCursor(New wxCursor.StockCreate(wxCURSOR_BLANK))

		timer = New wxTimer.Create(Self)

		EnablePolledInput(Self)

		ConnectAny(wxEVT_TIMER, OnTimer)
'		ConnectAny(wxEVT_TIMER, OnTick)
		ConnectAny(wxEVT_KEY_DOWN, OnKeyDown)
		ConnectAny(wxEVT_KEY_UP, OnKeyUp)
		ConnectAny(wxEVT_CHAR, OnKeyChar)
		ConnectAny(wxEVT_MOUSE_EVENTS, OnMouse)

		timer.Start(16)
	End Method

	Function OnTimer(event:wxEvent)
		MyCanvas(event.parent).Refresh()
	End Function
	
	Method OnPaint(event:wxPaintEvent)
		Render()
	End Method

	Method Render()

		SetGraphics CanvasGraphics2D( Self )
		
		Cls

		DrawText MouseX() + ", " + MouseY(), 20, 60

		If Not initialized Then
		
			Flip
			Flip
		
			initialized = True

			Init_CEGUI(Null, True)
			
			TCESchemeManager.loadScheme("datafiles/schemes/WindowsLook.scheme")
			
			If Not TCEFontManager.isFontPresent( "DejaVuSans-10" ) Then
				TCEFontManager.createFont( "datafiles/fonts/DejaVuSans-10.font" )
			End If
	
			TCESystem.setDefaultMouseCursor("WindowsLook", "MouseArrow")
	
			Local root:TCEWindow = TCEWindowManager.loadWindowLayout("datafiles/layouts/helper.layout")
			TCESystem.setGUISheet(root)
			
			helperWindow = TCEWindowManager.getWindow("HelperWindow")
			helperWindow.Hide()
			
			helperLabel = TCEWindowManager.getWindow("Helper/label")
			helperText = TCEEditbox(TCEWindowManager.getWindow("Helper/Editbox"))
			helperSubmit = TCEPushButton(TCEWindowManager.getWindow("Helper/Submit"))
			
			helperSubmit.subscribeEvent(TCEPushButton.EventClicked, submitted) ' click
			helperText.subscribeEvent(TCEEditbox.EventTextAccepted, submitted) ' enter

			RequestValue("Hello", "Some stuff")
		End If

		TCESystem.renderGUI()
		
		Flip
	
	End Method

	Function submitted:Int(args:TCEEventArgs)
	End Function

	Method RequestValue(title:String, label:String)
		helperWindow.setText(title)
		helperLabel.setText(label)

		helperText.setText("")

		helperWindow.show()
		
		helperText.activate()
	End Method

	Function OnKeyDown(event:wxEvent)
		Local evt:wxKeyEvent = wxKeyEvent(event)
		Local key:Int = MapWxKeyCodeToBlitz(evt.GetKeyCode())
		EmitEvent(CreateEvent( EVENT_KEYDOWN, event.parent, key)) ' event for Max2D

		TCESystem.injectKeyDown(key)

		event.Skip()
	End Function

	Function OnKeyUp(event:wxEvent)
		Local evt:wxKeyEvent = wxKeyEvent(event)
		Local key:Int = MapWxKeyCodeToBlitz(evt.GetKeyCode())
		EmitEvent(CreateEvent( EVENT_KEYUP, event.parent, key)) ' event for Max2D
		
		TCESystem.injectKeyUp(key)
		
		event.Skip()
	End Function

	Function OnKeyChar(event:wxEvent)
		Local evt:wxKeyEvent = wxKeyEvent(event)
		'Local key:Int = MapWxKeyCodeToBlitz(evt.GetKeyCode())
		'EmitEvent(CreateEvent( EVENT_KEYDOWN, event.parent, key)) ' event for Max2D

		TCESystem.injectChar(Asc(evt.GetUnicodeKey()))

		event.Skip()
	End Function
	
	Function OnMouse(event:wxEvent)
		If MyCanvas(event.parent).initialized Then
			Local evt:wxMouseEvent = wxMouseEvent(event)
		
			Local elapsed:Float = (MilliSecs() - cegui_startTime)/1000.0
	
			Select evt.GetEventType()
				Case wxEVT_MOTION
					Local x:Int, y:Int
					evt.GetPosition(x, y)
					EmitEvent(CreateEvent( EVENT_MOUSEMOVE, event.parent, 0, 0, x, y)) ' event for Max2D

					TCESystem.injectTimePulse(elapsed)
					TCESystem.injectMousePosition(x, y)
					
				Case wxEVT_LEFT_DOWN
					EmitEvent(CreateEvent( EVENT_MOUSEDOWN, event.parent, 1)) ' event for Max2D
	
					TCESystem.injectTimePulse(elapsed)
					TCESystem.injectMouseButtonDown(1)
				Case wxEVT_LEFT_UP
					EmitEvent(CreateEvent( EVENT_MOUSEUP, event.parent, 1)) ' event for Max2D
	
					TCESystem.injectTimePulse(elapsed)
					TCESystem.injectMouseButtonUp(1)
				
				Case wxEVT_LEFT_DCLICK
				
					TCESystem.injectTimePulse(elapsed)
					TCESystem.injectMouseButtonDown(1)
					TCESystem.injectTimePulse(elapsed)
					TCESystem.injectMouseButtonUp(1)
				
				Case wxEVT_RIGHT_DOWN
					EmitEvent(CreateEvent( EVENT_MOUSEDOWN, event.parent, 2)) ' event for Max2D
	
					TCESystem.injectTimePulse(elapsed)
					TCESystem.injectMouseButtonDown(2)
				Case wxEVT_RIGHT_UP
					EmitEvent(CreateEvent( EVENT_MOUSEUP, event.parent, 2)) ' event for Max2D
	
					TCESystem.injectTimePulse(elapsed)
					TCESystem.injectMouseButtonUp(2)
				Case wxEVT_MIDDLE_DOWN
					EmitEvent(CreateEvent( EVENT_MOUSEDOWN, event.parent, 3)) ' event for Max2D
	
					TCESystem.injectTimePulse(elapsed)
					TCESystem.injectMouseButtonDown(3)
				Case wxEVT_MIDDLE_UP
					EmitEvent(CreateEvent( EVENT_MOUSEUP, event.parent, 3)) ' event for Max2D
	
					TCESystem.injectTimePulse(elapsed)
					TCESystem.injectMouseButtonUp(3)
				Case wxEVT_MOUSEWHEEL
	
				Case wxEVT_ENTER_WINDOW
					wxWindow(Event.parent).SetCursor(New wxCursor.StockCreate(wxCURSOR_BLANK))
	
				Case wxEVT_LEAVE_WINDOW
					wxWindow(Event.parent).SetCursor(New wxCursor.StockCreate(wxCURSOR_ARROW))
	
			End Select

		End If
		event.Skip()
	End Function

End Type


It seems on Windows, OnMouse can be called before the window has finished initialising - don't ask... I don't know!
So in effect, we were trying to inject mouse movement into non initialised CEGUI...
The actual change is this, in the OnMouse function :
	If MyCanvas(event.parent).initialized Then


And yes, the mouse isn't hiding on Windows... I believe I know why, but am not too concerned about it for now. :-p

Thanks brucey! Exactly what I was looking for.

And yes, the mouse isn't hiding on Windows... I believe I know why, but am not too concerned about it for now. :-p


Yeah, I wasn't aware of a similar function in wxmax, but this did what I needed:

Local Cursor:wxCursor = New wxCursor.CreateWithImage(New wxImage.CreateEmptyImage(1, 1))
Self.SetCursor(Cursor)


I'm not sure if this is related to wxGLGraphicsDriver() or not, but the gui's font looks all chopped and gargled when initially loaded, but even worse after minimizing and bring it back up.

As far as I can tell it doesn't seem to affect the gui itself, just the fonts. I think I ran into a similar problem using maxgui as well.

I would ask in the cegui forum but I haven't a clue whether the issue is with blitzmax or cegui.

An image of what is happening here.

First image is fine, not on maxgui or wxmax windows.
Second image is loading with wxmax.
Third image is loaded, then minimized, then restored.

What about SetBlend ALPHABLEND ?

Another longshot..
Can be gfxcard driver settings?

Atleast here, when I set anti-aliasing to gfx driver controlled,
(ATI catalyst ctrl center), I get the same thing in Blender.
Menutext isn't readable at all.

By setting it to application controlled it's fine..

Might add that menus in Blender aren't "ordinary" windows menus,
but drawn/created by Blender itself..

Thanks guys. Using alpha fixed the majority of the issue. It only appears a slight bit blurry after minimizing, but a lot better than before.

I'm willing to bet that the tiny blur is caused by ole's suggestion with my gfx settings somewhere, although anti-alias doesn't appear to be it..i'll keep tinkering with it.

when I set anti-aliasing to gfx driver controlled


Yeah I ran into strange problems with that before as well, along with physx causing some of the weirdest physics jumping where anything moved by input would just disapear.

Isn't it possible that the window is not the same size as before, and the canvas is scaling slightly?

Doesn't seem to be the case.

However, I have another (hopefully last) question on this...

ConnectAny(wxEVT_CHAR, OnKeyChar)


creates an event on arrow keys and other system keys, injecting invalid characters. Should wxEVT_CHAR be registering on such keys?