The title of this article says it all. I’m currently working on the next ‘iteration’ of Gunstyle with a fellow developer and over the past weekend we were in need of a GUI library to help develop our map editor. In the past maxGUI ‘worked’ more or _less…._emphasis on the _less_. The design of maxGUI left me with a bad taste in my mouth. It’s a procedural library that is cobbled together with some weak OO on top that didn’t provide much flexibility (not to mention it wasn’t exactly ‘native’ UI on different platforms). Either way, it was a good library for small projects and prototypes.
Now we’re working on something of a little bit bigger in scale, and needing a more heavy duty gui library to go with it. So we chose Brucey’s wxMax GUI Module for Blitzmax. Just picking it up over the weekend has been a joy to work with. It’s object-oriented from the get go so it’s a bit easier to integrate into already established OO code. It also boasts being cross-platform (Win/Linux/Mac), but I’ve yet to test or need this functionality yet. It’s also wrapping a rather solid and established library, wxWidgets.
One of the main requirements was for us to develop a GUI around a game framework that would allow us to switch in and out of an editor on the fly. To test this type of functionality I whipped up a basic test file that switches from the standard Blitzmax graphics window to a wxMax GUI with a GLCanvas and back again several times. Below is the actual source for doing that type of switching, in case anyone wants to do something similar:
SuperStrict Framework wx.wxApp Import brl.glmax2d Import brl.standardio Import wx.wxFrame Import wx.wxPanel Import wx.wxGLCanvas Import wx.wxglmax2d Import brl.max2d Import wx.wxTimer Import brl.pngloader Global app:TestApp = New TestApp Global imgTest:TImage Global imgPath:String = “myTestImage.png” SetGraphicsDriver(brl.GLMax2D.GLMax2DDriver()) ‘ needed in order for the normal gfx driver to run SetGraphics(Graphics(800, 600)) ‘ set context back to main window ‘ test switching between max2D and wxMax ‘ while loading an image that is shared between the two modes If FileType(imgPath) = 0 Then Notify “invalid path for image. file does not exist” EndGraphics() End End If imgTest = LoadImage(imgPath) SetBlend(ALPHABLEND) RunBmaxGraphics() app.Run() RunBmaxGraphics() app.Run() Function RunBmaxGraphics() SetGraphicsDriver(brl.GLMax2D.GLMax2DDriver()) ‘ needed in order for the normal gfx driver to run SetGraphics(Graphics(800, 600)) ‘ set context back to main window While Not(KeyHit(KEY_ESCAPE)) Cls If KeyHit(KEY_D) Then Exit End If DrawImage(imgTest, 100, 100) Flip WEnd EndGraphics() End Function Type TestApp Extends wxApp Field frame:wxFrame Field panel:wxPanel Field canvas:TMax2DCanvas Method OnInit:Int() frame = New wxFrame.Create(,, “Test”, 0, 0, 1024, 768) frame.Center() panel = New wxPanel.Create(frame, wxID_ANY, 160, 0, 1024, 768) canvas = TMax2DCanvas(New TMax2DCanvas.Create(panel, wxID_ANY, GRAPHICS_BACKBUFFER | GRAPHICS_DEPTHBUFFER, 0, 0, 1024, 768)) frame.Show() Return True End Method End Type Type GLFrame Extends wxFrame Field canvas:TMax2DCanvas Method OnInit() canvas = TMax2DCanvas(New TMax2DCanvas.Create(Self, -1, GRAPHICS_BACKBUFFER | GRAPHICS_DEPTHBUFFER)) ConnectAny(wxEVT_CLOSE, OnClose) End Method Function OnClose(event:wxEvent) GLFrame(event.parent).canvas.timer.Stop() event.Skip() End Function End Type Type TMax2DCanvas Extends wxGLCanvas Field timer:wxTimer Method OnInit() SetBackgroundStyle(wxBG_STYLE_CUSTOM) timer = New wxTimer.Create(Self) wx.wxglmax2d.GLMax2DDriver().SetBlend(ALPHABLEND) timer.Start(100) ConnectAny(wxEVT_TIMER, OnTick) End Method Method OnPaint(event:wxPaintEvent) Render() End Method Method Render() SetGraphics CanvasGraphics2D(Self) Cls DrawImage(imgTest, 100, 100) Flip End Method Function OnTick(event:wxEvent) wxWindow(event.parent).Refresh() End Function End Type
The main benefit of the above setup is seen in the switching between ‘RunBmaxGraphics()‘ and ‘app.run()‘. I can switch from my normal game logic, to an editor logic, but still use the same rendering routines! Now I’m not 100% positive that resources such as TImage will persist after a graphics change (in my case they do, but I don’t think that’s universal) so you may be required to reload textures.