Yet Another GUI Module - Part 2

BlitzMax Modules Forums/Brucey's Modules/Yet Another GUI Module - Part 2

This is a continuation of This Topic, which was getting big.

:-)


I've added a wxFlatNotebook widget, which is like a normal tabbed notebook except the tabs are very customizable. There are about 5 default "looks", as well as the ability to locate tabs at different positions, and even customize the colouring of them. Just finishing off the sample at the moment. A nice addition, that I've tested on Mac and Win32 so far.

Thx, Brucey! :D
wxMax rockz!


- FOODy

I have problems starting one wxapp, closing it (but not the programm) and starting the same wxapp again.
I've tried it with the propgrip example by adding a second "New MyApp.run()" line under the first. After closing the first window a second one appears, but it crashes upon resizing.

Or maybe is there a way to achieve similar behavior without starting the wxapp multiple times? I'm trying to combine a normal Graphics/Max2d-Window with additional Windows using WxWidgets. I'm doing an editor for my game, so the Max2d-Window shows the map and if you click e.g. on a NPC a second windows for editing it's properties pops up.

I have problems starting one wxapp, closing it (but not the programm) and starting the same wxapp again.

That's because you shouldn't be doing that :-)
Think of a wxApp instance as like a main() method of C. When you call run() you are starting the main event-loop for wxWidgets. Once the last window is closed, by default, that signals the end of your application. You can override this by telling the window that its closer doesn't mean you want to end the running of the App too.

At the moment, your main problem is that you are trying to run two separate main loops - one for wxWidgets and one for Max2D. My plan is to integrate proper Graphics support into wxMax so that it will work much like a Canvas gadget in MaxGUI - where you might set up a wxTimer and have it repaint the Max2D window every tick.
It should already be possible to attach a graphics context to a wxMax window on Win32 (if that's the platform you are using), but for Mac it's going to require a new glgraphics and max2d module - since glgraphics for Mac is tied to Cocoa controls... ho hum.

So for now, your mixing of application-specific wxMax code and Graphics code might not work so well.

When deriving a type from wxPanel, event handlers seem not to have valid event.parent? I can of course add my own “CreateMyPanel Method” and there store it for later use. But wanted to know if this is an error?

There are two interfaces for creating most controls : Function or Method.

I would expect that you should be able to do something like this:
Type MyPanel extends wxPanel

  Method OnInit()
    Connect(-1, some_event_type, OnTheEvent())
  End Method

  Function OnTheEvent(event:wxEvent)
    If not MyPanel(event.parent) Then
      Print "This event wasn't mine!?!"
    Else
      Print "Success! :-)"
    End if
  End Function

End Type

' in your frame code, somewhere...
Local panel:MyPanel = new MyPanel.Create(....)

I'd always expect to see Success printed.

Is there a pre-compiled version yet?

Would you like any assistance getting it insalled on your machine? Or is there another problem?

Yes, it takes FOREVER to compile!! lol :)

EDIT: i havn't downloaded it this time, but last time it did not have anything compiled, so i assumed it was the same this time.

I guess i could offer the usual forum advice get a faster machine... but I wont. Seriously it is well worth the build wait. Given a little more time Brucey will have made one of the most significant steps in MAX development.

I hope that this will get its own section sometime soon (not just made into a sticky).

Last time I never got it to work.

Anyhow, what link should i be using for SVN?

http://wxmax.googlecode.com/svn/trunk/wx.mod
I use tortoise svn on the PC and use "svn up" from the terminal under OSX.

this page is quite good but again if you have problems SHOUT!

http://code.google.com/p/wxmax/wiki/SetupAndInstallation

uhm... another problem.
The SelectItem() method works for a wxCheckListBox (as copied from the sample), but it doesn't for the wxBitmapComboBox I'm using in my code. I just get an unhandled memory exception error.
Could you try if SelectItem() works for you on wxBitmapComboBoxes or give any hints on how to debug this?

tortoise is asking me for a username and password...

EDIT: and, i dont need to get brucey's bmk, correct? because its in 1.28.. right?

@Plash

Tortoise is asking for username and password at which point? When you install it, or when you try and download "svn co" the source?

I guess you are getting it from here right?
http://tortoisesvn.net/downloads

EDIT2: nvm got it working.

EDIT3: @Nigel, yeah thats what i did this time.

using tortoise svn:

1. Create a folder inside Blitzmax/mod folder called wx.mod
2. Then right click on the wx.mod folder and select svn Checkout from the menu.
3. In the Repository window use:
http://wxmax.googlecode.com/svn/trunk/wx.mod as the URL of repository
4. Click ok

@Steffenk

Can you let me have some demo code to try?

Is there a pre-compiled version yet?

Not yet, as there is still much to do, and it's not at that point where I feel it's "releasable" yet. That's not to say you can't use it though. For many applications there is more than enough already implemented.

Steffenk, I've found out the problem. It seems wxBitmapComboBox sometimes doesn't subclass from wxControlWithItems, so the call in there to SelectItem() was causing a crash. I've not implemented much of wxControlWithItems' methods directly in wxBitmapComboBox, which seems to stop the crash you had.
If you have any problems with other methods, let me know. Thanks :-)
(update from SVN for the code)

As for the build speed. Not much we can do about that really (than have it pre-built, of course). It's just that there's a *lot* to compile. There's currently about 130 separate modules which make up wxMax. That's a little more than the rest of BlitzMax's own modules :-)
Once it's built, compiling an application is quick. And unless you are updating from SVN often, you won't need to spend much time waiting for a build.

And if you feel the wiki documentation can be improved anywhere, please let me know.

:o)

Here's a sneak look at some wxCodeGen generated code. It can process a wxFormBuilder project file and generate the required wxMax code.

the main app (which you hand-code yourself)
SuperStrict

Framework wx.wxApp
Import "test_controls.bmx"

Type MyApp Extends wxApp

	Field frame:MyFrame

	Method OnInit:Int()

		frame = MyFrame(New MyFrame.Create())
		
		SetTopWindow(frame)
		
		frame.show()
	
		Return True
	
	End Method

End Type

New MyApp.run()

Type MyFrame Extends MyFrame1Base

	Method OnLanguageDelete(event:wxCommandEvent)
		DebugLog wxControl(Event.parent).GetLabel()
	End Method

End Type


and the code that gets generated (in this case text_controls.bmx
'
' BlitzMax code generated with wxCodeGen : 04 Jan 2008 13:29:56
' 
' 
' PLEASE DO "NOT" EDIT THIS FILE!
' 
SuperStrict

Import wx.wxButton
Import wx.wxComboBox
Import wx.wxFrame
Import wx.wxListCtrl
Import wx.wxMenu
Import wx.wxMenuBar
Import wx.wxPanel
Import wx.wxStaticBoxSizer
Import wx.wxStaticText
Import wx.wxTextCtrl
Import wx.wxWindow


Type MyFrame1Base Extends wxFrame

	Field m_panel1:wxPanel
	Field sbSizer1:wxStaticBoxSizer
	Field m_listCtrl1:wxListCtrl
	Field m_textCtrl1:wxTextCtrl
	Field m_button1:wxButton
	Field m_button2:wxButton
	Field m_staticText2:wxStaticText
	Field m_comboBox1:wxComboBox
	Field m_listCtrl2:wxListCtrl
	Field m_button3:wxButton
	Field m_button4:wxButton
	Field m_textCtrl3:wxTextCtrl
	Field m_staticText1:wxStaticText
	Field m_textCtrl2:wxTextCtrl
	Field m_menubar1:wxMenuBar
	Field m_menu1:wxMenu
	Field m_menu11:wxMenu
	Field m_menu2:wxMenu

	Const TAG_ADD:Int = 5000
	Const TAG_DELETE:Int = 5001
	Const LANG_ADD:Int = 5002
	Const wxID_EXIT:Int = 5003

	Method Create:MyFrame1Base(parent:wxWindow = Null,id:Int = wxID_ANY, title:String = "wxBLFBuilder Test", x:Int = -1, y:Int = -1, w:Int = -1, h:Int = -1, style:Int = wxCAPTION|wxCLOSE_BOX|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxSYSTEM_MENU|wxCLIP_CHILDREN|wxTAB_TRAVERSAL)
		Return MyFrame1Base(Super.Create(parent, id, title, x, y, w, h, style))
	End Method

	Method OnInit()

		Local bSizer1:wxBoxSizer
		bSizer1 = New wxBoxSizer.Create(wxHORIZONTAL)
		bSizer1.SetMinSize(500,400)
		m_panel1 = New wxPanel.Create(Self, wxID_ANY, wxTAB_TRAVERSAL)

		Local bSizer4:wxBoxSizer
		bSizer4 = New wxBoxSizer.Create(wxHORIZONTAL)

		sbSizer1 = New wxStaticBoxSizer.CreateSizerWithBox( New wxStaticBox.Create(m_panel1, wxID_ANY, "Tags"), wxVERTICAL)
		m_listCtrl1 = New wxListCtrl.Create(m_panel1, wxID_ANY,,,,, wxLC_LIST)
		sbSizer1.Add(m_listCtrl1, 1, wxALL|wxEXPAND, 5)

		m_textCtrl1 = New wxTextCtrl.Create(m_panel1, wxID_ANY, "")
		m_textCtrl1.SetMaxLength(1)
		sbSizer1.Add(m_textCtrl1, 0, wxALL|wxEXPAND, 5)


		Local bSizer3:wxBoxSizer
		bSizer3 = New wxBoxSizer.Create(wxHORIZONTAL)
		m_button1 = New wxButton.Create(m_panel1, TAG_ADD, "Add")
		bSizer3.Add(m_button1, 0, wxALL, 5)

		m_button2 = New wxButton.Create(m_panel1, TAG_DELETE, "Delete")
		bSizer3.Add(m_button2, 0, wxALL, 5)

		sbSizer1.AddSizer(bSizer3, 0, wxALIGN_CENTER_HORIZONTAL, 5)

		bSizer4.AddSizer(sbSizer1, 0, wxALL|wxEXPAND, 5)


		Local bSizer2:wxBoxSizer
		bSizer2 = New wxBoxSizer.Create(wxVERTICAL)

		Local sbSizer2:wxStaticBoxSizer
		sbSizer2 = New wxStaticBoxSizer.CreateSizerWithBox( New wxStaticBox.Create(m_panel1, wxID_ANY, "Language"), wxVERTICAL)

		Local bSizer6:wxBoxSizer
		bSizer6 = New wxBoxSizer.Create(wxHORIZONTAL)
		m_staticText2 = New wxStaticText.Create(m_panel1, wxID_ANY, "Default")
		m_staticText2.Wrap(-1)
		bSizer6.Add(m_staticText2, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5)

		m_comboBox1 = New wxComboBox.Create(m_panel1, wxID_ANY, "", Null,,,,, wxCB_READONLY)
		bSizer6.Add(m_comboBox1, 1, wxALL, 5)

		sbSizer2.AddSizer(bSizer6, 0, wxEXPAND, 5)


		Local bSizer7:wxBoxSizer
		bSizer7 = New wxBoxSizer.Create(wxHORIZONTAL)
		m_listCtrl2 = New wxListCtrl.Create(m_panel1, wxID_ANY,,,,, wxLC_LIST)
		bSizer7.Add(m_listCtrl2, 1, wxALL|wxEXPAND, 5)


		Local bSizer8:wxBoxSizer
		bSizer8 = New wxBoxSizer.Create(wxVERTICAL)
		m_button3 = New wxButton.Create(m_panel1, LANG_ADD, "Add")
		bSizer8.Add(m_button3, 0, wxALL, 5)

		m_button4 = New wxButton.Create(m_panel1, wxID_ANY, "Delete")
		bSizer8.Add(m_button4, 0, wxALL, 5)

		bSizer7.AddSizer(bSizer8, 0, wxALIGN_BOTTOM|wxALIGN_CENTER, 5)

		sbSizer2.AddSizer(bSizer7, 1, wxEXPAND, 5)

		bSizer2.AddSizer(sbSizer2, 2, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5)


		Local sbSizer3:wxStaticBoxSizer
		sbSizer3 = New wxStaticBoxSizer.CreateSizerWithBox( New wxStaticBox.Create(m_panel1, wxID_ANY, "Text"), wxVERTICAL)
		m_textCtrl3 = New wxTextCtrl.Create(m_panel1, wxID_ANY, "",,,,, wxTE_MULTILINE)
		m_textCtrl3.SetMaxLength(0)
		sbSizer3.Add(m_textCtrl3, 1, wxALL|wxEXPAND, 5)


		Local bSizer5:wxBoxSizer
		bSizer5 = New wxBoxSizer.Create(wxHORIZONTAL)
		m_staticText1 = New wxStaticText.Create(m_panel1, wxID_ANY, "Value")
		m_staticText1.Wrap(-1)
		bSizer5.Add(m_staticText1, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5)

		m_textCtrl2 = New wxTextCtrl.Create(m_panel1, wxID_ANY, "")
		m_textCtrl2.SetMaxLength(0)
		bSizer5.Add(m_textCtrl2, 1, wxALL, 5)

		sbSizer3.AddSizer(bSizer5, 0, wxALL|wxEXPAND, 0)

		bSizer2.AddSizer(sbSizer3, 1, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5)

		bSizer4.AddSizer(bSizer2, 1, wxALL|wxEXPAND, 5)

		m_panel1.SetSizer(bSizer4)
		m_panel1.Layout()
		bSizer1.Add(m_panel1, 1, wxEXPAND, 0)

		m_menubar1 = New wxMenuBar.Create()

		m_menu1 = New wxMenu.Create()

		Local m_menuItem1:wxMenuItem
		m_menuItem1 = New wxMenuItem.Create(m_menu1, wxID_ANY, "New", "", wxITEM_NORMAL)
		m_menu1.AppendItem(m_menuItem1)

		m_menu11 = New wxMenu.Create()

		Local m_menuItem6:wxMenuItem
		m_menuItem6 = New wxMenuItem.Create(m_menu11, wxID_ANY, "MyMenuItem", "", wxITEM_NORMAL)
		m_menu11.AppendItem(m_menuItem6)
		m_menu1.AppendMenu(-1, "MyMenu", m_menu11)

		Local m_menuItem2:wxMenuItem
		m_menuItem2 = New wxMenuItem.Create(m_menu1, wxID_ANY, "Open", "", wxITEM_CHECK)
		m_menu1.AppendItem(m_menuItem2)

		Local m_menuItem3:wxMenuItem
		m_menuItem3 = New wxMenuItem.Create(m_menu1, wxID_ANY, "Save", "", wxITEM_NORMAL)
		m_menu1.AppendItem(m_menuItem3)

		m_menu1.AppendSeparator()

		Local m_menuItem4:wxMenuItem
		m_menuItem4 = New wxMenuItem.Create(m_menu1, wxID_EXIT, "Quit" + "	CTRL+Q", "help", wxITEM_NORMAL)
		m_menu1.AppendItem(m_menuItem4)
		m_menubar1.Append(m_menu1, "File")

		m_menu2 = New wxMenu.Create()
		m_menubar1.Append(m_menu2, "Language")
		SetMenuBar(m_menubar1)

		SetSizer(bSizer1)
		Layout()
		bSizer1.Fit(Self)
		Center(wxBOTH)

		ConnectAny(wxEVT_CLOSE_WINDOW, _OnClose)
		ConnectAny(wxEVT_SIZE, _OnSize)
		Connect(TAG_ADD, wxEVT_COMMAND_BUTTON_CLICKED, _OnAddTag)
		Connect(TAG_DELETE, wxEVT_COMMAND_BUTTON_CLICKED, _OnDeleteTag)
		Connect(LANG_ADD, wxEVT_COMMAND_BUTTON_CLICKED, _OnButtonClick)
		m_button4.ConnectAny(wxEVT_COMMAND_BUTTON_CLICKED, _OnLanguageDelete, Null, Self)
		Connect(m_menuItem3.GetId(), wxEVT_COMMAND_MENU_SELECTED, _OnSave)
		Connect(m_menuItem4.GetId(), wxEVT_COMMAND_MENU_SELECTED, _OnQuit)
	End Method

	Function _OnClose(event:wxEvent)
		MyFrame1Base(event.parent).OnClose(wxCloseEvent(event))
	End Function

	Method OnClose(event:wxCloseEvent)
		DebugLog "Please override MyFrame1.OnClose()"
		event.Skip()
	End Method

	Function _OnSize(event:wxEvent)
		MyFrame1Base(event.parent).OnSize(wxSizeEvent(event))
	End Function

	Method OnSize(event:wxSizeEvent)
		DebugLog "Please override MyFrame1.OnSize()"
		event.Skip()
	End Method

	Function _OnAddTag(event:wxEvent)
		MyFrame1Base(event.parent).OnAddTag(wxCommandEvent(event))
	End Function

	Method OnAddTag(event:wxCommandEvent)
		DebugLog "Please override MyFrame1.OnAddTag()"
		event.Skip()
	End Method

	Function _OnDeleteTag(event:wxEvent)
		MyFrame1Base(event.parent).OnDeleteTag(wxCommandEvent(event))
	End Function

	Method OnDeleteTag(event:wxCommandEvent)
		DebugLog "Please override MyFrame1.OnDeleteTag()"
		event.Skip()
	End Method

	Function _OnButtonClick(event:wxEvent)
		MyFrame1Base(event.parent).OnButtonClick(wxCommandEvent(event))
	End Function

	Method OnButtonClick(event:wxCommandEvent)
		DebugLog "Please override MyFrame1.OnButtonClick()"
		event.Skip()
	End Method

	Function _OnLanguageDelete(event:wxEvent)
		MyFrame1Base(event.sink).OnLanguageDelete(wxCommandEvent(event))
	End Function

	Method OnLanguageDelete(event:wxCommandEvent)
		DebugLog "Please override MyFrame1.OnLanguageDelete()"
		event.Skip()
	End Method

	Function _OnSave(event:wxEvent)
		MyFrame1Base(event.sink).OnSave(wxCommandEvent(event))
	End Function

	Method OnSave(event:wxCommandEvent)
		DebugLog "Please override MyFrame1.OnSave()"
		event.Skip()
	End Method

	Function _OnQuit(event:wxEvent)
		MyFrame1Base(event.parent).OnQuit(wxCommandEvent(event))
	End Function

	Method OnQuit(event:wxCommandEvent)
		DebugLog "Please override MyFrame1.OnQuit()"
		event.Skip()
	End Method

End Type


It's a "run from the IDE" app at the moment, but I'm thinking perhaps we can have wxCodeGen as a small GUI app, which you can use to re-create the BlitzMax source for a form/panel as you go.
Or perhaps integration into an IDE or something...

For a stand-alone GUI app, if anyone has any ideas of what they might want from it (other than perhaps clicking on a button to create the code...), do speak up ;-)

Does wx already have a formbuilder?

PS. The flatnotebook sample is awesome.

My current project uses multiple wxFormBuilder files and the ability to process them all in one automated shot would be useful.

@Plash, google wxFormBuilder. The sizers took me a while to get my head around, but once understood you will quickly produce layouts.

Brucey,
Latest 'svn up' revision 195 was huge? What precedence are you giving to wx modules? There are a few I would like to see before others. I guess everyone will have there own preferences. Alpha versions of wxCodeGen would be useful :-)

What precedence are you giving to wx modules

None in particular. Feel free to vote for your preferred order.

I'll post a version of wxCodeGen once I've done some more of the controls. Currently it has most of the "common" controls, event generation, and menu stuff (bar/menu/item). It's just a case of adding a control to a project, changing properties and seeing what the generated C++ looks like - then coding all the equivalent wxMax code.

Brucey, my vote goes to:

modules:
wxgenericdirctrl
wxprocess
wxexecute
wxconfig
wxhelpcontroller
wxtipprovider

examples:
wxartprovider (hoping this will allow icons in wxgenericdirctrl to be altered?)

I will be looking into writing my own controls next week as one project I have on my list is uses only custom controls :-)

A little question.
I have installed and updated all the wxMod (via svn). I noticed that ALL the .exe (even the 'hallo world' from the code.google page) generate a file of about 3Mb.
Is it normal (due to fact that wx.dll are 'glued') or/and is it possibile to do something to have a smaller .exe? [of course I could use UPX]
Thanks!
[Some examples are impressive! MaxGUI seems a poor relative...]

The reason the file sizes seem big is that the supplied libs are statically linked into the application.
It is entirely possible to use DLLs instead, but obviously you then have a bunch of DLLs you need to ship with your app. (each to their own!)

Although the size of a very basic app appears large, as you grow your application it doesn't grow very quickly after that.

Think of it like how BlitzMax works if you don't use Framework... you get more than you need.
I've tried to split it up into as many parts as possible in an effort to include only the code that you are actually using, but wxWidgets as a lot of internal stuff that keeps everything together, which I expect is what makes up a lot of that basic size.

And remember that the wxWidgets framework is cross-platform, so there's an extra layer on top of direct OS API calls.

I'm happy to take a small hit on file size for a decent cross-platform GUI :-)

OK! Thanks for the replay...yes, the 'size cost' is acceptable due to the final quality of the application.

Brucey wrote:
Here's a sneak look at some wxCodeGen generated code. It can process a wxFormBuilder project file and generate the required wxMax code.

Am I missing something here!

wxFormBuilder can generate platform independant resource files called XRC files. You shouldn't need a Converter or a Generator; wxWidgets has all that built in. So why are you extracting data from the project files?

If we have a control defined in the XRC file we should be able to load it using wxXmlResource.Get(). Take a look Here .

The problem with XRC is that we'll need wxXmlResourceHandlers for all the widgets - extra ones on top of what is already there - because I've subclassed all the widgets to provide better integration between BlitzMax and wxWidgets.

For example, rather than creating a wxListCtrl it will need to create a MaxListCtrl, because that subclass adds event and other support.

It's a whole lot of other work on top of everything.

Once all the widgets are working, then there'll be time to look at adding resource support too. But I'm concentrating on getting the widgets functional first. wxCodeGen helps me with that :-)

I've put up a small download for Win32 users which includes an updated header/lib for GL support.
Seems you need to set TWO separate flags to enable GL support in wxWidgets...

You can unzip the file into your wxMax lib/win32 folder, and it should update libwxmsw28u_gl.a and the mswu folder.

There's now some experimental support for 'native' Max2D functionality in wxMax using wxGLCanvas.

Take a look at the glmax2d sample for an example of the code. There's also the glcube sample, ported to wxMax, highlighting OpenGL calls.

It should work much like the Canvas on MaxGUI, and you'll probably want to add key/mouse event handlers to your canvas instance.

Thanks to DavidDC for a bit of pre-coding brain-storming and encouragement ;-)

Hi Brucey, great work!
I love wxWidgets, been using them for quite a while with Python. So I'm very exited that you wrapping them up to use with BMax. I got the windows version to work without much hassle and all the samples run fine.
I'm trying to get it working in Ubuntu 7.10 (quite a new playfield for me!).
I get the error:
cannot find -lgdk_pixbuf-2.0

I'm not quite sure what's missing. I installed a few linux modules with 'gdk' in it, but nothing seems to fill the gap.
Any ideas?

thanx!

You should have the "normal" gdk libs installed, but the developer libs are required for compiling - which aren't normally part of a standard distribution.

In your package manager, look for things like gtk+2-dev or gdk2-dev or something similar.
Choosing one should get you all the related dev libs too.

Hi!I've just updated wxMax via SVN to v. 199

building module, after 10 or 20 submodules of wx compiling, MaxIDE give me that error:
Building Modules
Compiling:glue.cpp
In file included from C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/glue.cpp:23:
C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/glue.h:47: error: variable or field `bmx_wxglcanvas_swapbuffers' declared void
C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/glue.h:47: error: `wxGLCanvas' was not declared in this scope
C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/glue.h:47: error: `canvas' was not declared in this scope
C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/glue.h:57: error: expected class-name before '{' token
C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/glue.cpp: In constructor `MaxGLCanvas::MaxGLCanvas(BBObject*, wxWindow*, wxWindowID, int, int, int, int, long int, const wxString&, int*)':
C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/glue.cpp:32: error: class `MaxGLCanvas' does not have any field named `wxGLCanvas'
C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/glue.cpp:34: error: cannot convert `MaxGLCanvas* const' to `wxObject*' for argument `1' to `void wxbind(wxObject*, BBObject*)'
C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/glue.cpp: In destructor `MaxGLCanvas::~MaxGLCanvas()':
C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/glue.cpp:38: error: cannot convert `MaxGLCanvas* const' to `wxObject*' for argument `1' to `void wxunbind(wxObject*)'
C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/glue.cpp: In member function `void MaxGLCanvas::Render(BBObject*)':
C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/glue.cpp:43: error: `wxGLCanvas' has not been declared
C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/glue.cpp:43: error: `SetCurrent' undeclared (first use this function)
C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/glue.cpp:43: error: (Each undeclared identifier is reported only once for each function it appears in.)
C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/glue.cpp:44: error: no matching function for call to `wxPaintDC::wxPaintDC(MaxGLCanvas* const)'
C:/Programmi/BlitzMax/mod/wx.mod/include/wx/msw/dcclient.h:96: note: candidates are: wxPaintDC::wxPaintDC(const wxPaintDC&)
C:/Programmi/BlitzMax/mod/wx.mod/include/wx/msw/dcclient.h:82: note:                 wxPaintDC::wxPaintDC(wxWindow*)
C:/Programmi/BlitzMax/mod/wx.mod/include/wx/msw/dcclient.h:79: note:                 wxPaintDC::wxPaintDC()
C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/glue.cpp: At global scope:
C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/glue.cpp:50: error: `wxGLCanvas' has not been declared
C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/glue.cpp: In function `int _initAttrs(int*, int)':
C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/glue.cpp:55: error: `WX_GL_RGBA' undeclared (first use this function)
C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/glue.cpp:56: error: `WX_GL_DOUBLEBUFFER' undeclared (first use this function)
C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/glue.cpp:57: error: `WX_GL_MIN_ALPHA' undeclared (first use this function)
C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/glue.cpp:58: error: `WX_GL_DEPTH_SIZE' undeclared (first use this function)
C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/glue.cpp:59: error: `WX_GL_STENCIL_SIZE' undeclared (first use this function)
C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/glue.cpp:60: error: `WX_GL_MIN_ACCUM_RED' undeclared (first use this function)
C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/glue.cpp: At global scope:
C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/glue.cpp:86: error: variable or field `bmx_wxglcanvas_swapbuffers' declared void
C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/glue.cpp:86: error: redefinition of `int bmx_wxglcanvas_swapbuffers'
C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/glue.h:47: error: `int bmx_wxglcanvas_swapbuffers' previously defined here
C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/glue.cpp:86: error: `wxGLCanvas' was not declared in this scope
C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/glue.cpp:86: error: `canvas' was not declared in this scope
C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/glue.cpp:86: error: expected `,' or `;' before '{' token
Build Error: failed to compile C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/glue.cpp
Process complete

what's could be?

By running:
sudo apt-get install libgtk2.0-dev
I managed to get past the above mentioned error.

But now I get:
Building hello_world
Linking:hello_world.debug
/home/urs/blitzmax/mod/wx.mod/wx.mod/../lib/linux/libwx_gtk2u_core-2.8.a(corelib_textctrl.o):(.rodata._ZTV10wxTextCtrl[vtable for wxTextCtrl]+0x368): undefined reference to `std::basic_streambuf<char, std::char_traits<char> >::seekoff(long long, std::_Ios_Seekdir, std::_Ios_Openmode)'
/home/urs/blitzmax/mod/wx.mod/wx.mod/../lib/linux/libwx_gtk2u_core-2.8.a(corelib_textcmn.o):(.rodata._ZTV14wxTextCtrlBase[vtable for wxTextCtrlBase]+0x368): undefined reference to `std::basic_streambuf<char, std::char_traits<char> >::seekoff(long long, std::_Ios_Seekdir, std::_Ios_Openmode)'
/home/urs/blitzmax/mod/wx.mod/wx.mod/../lib/linux/libwx_gtk2u_core-2.8.a(corelib_treectlg.o):(.rodata._ZTV14wxTreeTextCtrl[vtable for wxTreeTextCtrl]+0x368): undefined reference to `std::basic_streambuf<char, std::char_traits<char> >::seekoff(long long, std::_Ios_Seekdir, std::_Ios_Openmode)'
collect2: ld returned 1 exit status
Build Error: Failed to link /home/urs/blitzmax/mod/wx.mod/samples/hello_world.debug
Process complete


@z4g0

Sorry... I had the wrong compiler directive in glue.h :-/
Should be fine now.

@nadia

I think that problem is related to "Compilation Issues" here : http://code.google.com/p/wxmax/wiki/FrequentlyAskedQuestions

Most likely you are compiling with a different version of gcc than the static libs were compiled with.

Two ways around this issue:

1) Compile with the same version ;-)

2) make a wxWidgets build yourself with the version of the compiler you have - it's not that difficult.

For 1), if you have installed gcc-3.3 for compiling BlitzMax stuff, then that's the fault, since gcc-4.x was used to compile the static libs.

I can help you with 2) if you need it :-)

I just want to second Nigel's comment:

I hope that this will get its own section sometime soon (not just made into a sticky).


wxMax is so large that a single thread is never going to cope with all the issues that people are going to stumble into.

Given that it's such a value-adding addition to Max, it more than warrants its own space in this forum.

yup, I found I got gcc3.3 and gcc4.1 installed but BMax is probably using gcc3.3.
Is there a way to force BMax to use gcc4.1 ?

If not, yes I would like some help to build wxWidgets with gcc3.3.

thanks Brucey for fast fix!

now i'm getting this new similar error:
http://rafb.net/p/JVe4B387.html

Brucey wrote:
Once all the widgets are working, then there'll be time to look at adding resource support too. But I'm concentrating on getting the widgets functional first. wxCodeGen helps me with that :-)


Ah, fair enough.
Thanks,

@nadia
Is there a way to force BMax to use gcc4.1 ?


You can modify BMK to compile for "gcc" instead of "gcc-3.3". Your default gcc should be 4.x.

Look for this in bmk_util.bmx :
?Linux
	cmd="gcc-3.3 -static"
	opts:+" -m32 -mfancy-math-387"
?

and change gcc-3.3 to just gcc.

Compile bmx.bmx as non-gui and non-debug, then replace the binary in BlitzMax/bin (remember to backup first!!!)

Now, since you are compiling with a different gcc, you need to rebuild *ALL* the modules to make sure you are linked against correct glibc.

Hope this helps.

@z4g0

ah... sorry... long day..

I needed to fix the cpp glue as well as the header... ho hum.

That should be it now. (fingers crossed, thumbs held etc)

A fix for the mainloop.bmx sample is in located this thread

YO! now works! compiled all wx's submodules without errors! Ty!

All samples seems work good, except from:
-glmax2d.bmx
-glcube.bmx

that giving me that errors:
Building glmax2d
Compiling:glmax2d.bmx
flat assembler  version 1.66
3 passes, 35712 bytes.
Linking:glmax2d.debug.exe
C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/wxglcanvas.debug.win32.x86.a(wxglcanvas.bmx.debug.win32.x86.o): undefined reference to `bmx_wxglcanvas_create'
C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/wxglcanvas.debug.win32.x86.a(wxglcanvas.bmx.debug.win32.x86.o): undefined reference to `bmx_wxglcanvas_swapbuffers'
C:/Programmi/BlitzMax/mod/wx.mod/wxglcanvas.mod/wxglcanvas.debug.win32.x86.a(wxglcanvas.bmx.debug.win32.x86.o): undefined reference to `bmx_wxglcanvas_onpainthook'
Build Error: Failed to link C:/Programmi/BlitzMax/mod/wx.mod/samples/glmax2d.debug.exe
Process complete


@z4g0

perhaps you need:

wxwidgets_2.8.7_static_GL_win32.zip Updated win32 static lib and header for wxGLCanvas support (drop into lib/win32)

http://code.google.com/p/wxmax/downloads/list

Thank DavidDC:

I've putted the files of the wxwidgets_2.8.7_static_GL_win32.zip into the lib/win32 wxmod's folder,
and RE-buildied all mods (to e sure ... but that's wasted me 30 minutes and more..):
No compile errors now, but in theese two sample files I get
"Unhandled exception: Unhandled Memory Exception Error"

in
		frame.show(True)


@z4g0 Sorry no clue on that one.

Brucey:

Can I put in a vote for an OnInit for RadioButtons? For all gadgets actually :-)

i.e.
Method Create:wxRadioButton(parent:wxWindow, id:Int, label:String, x:Int = -1, y:Int = -1, ..
			w:Int = -1, h:Int = -1, style:Int = 0)
			
		wxObjectPtr = bmx_wxradiobutton_create(Self, parent.wxObjectPtr, id, label, x, y, w, h, style)
		

		OnInit()  ' Pretty please with sugar on top?
		
		Return Self
End Method


All of them? :-p

sure :-)

Okay... spent some quality time on Win32 to try and resolve the GLCanvas problems.

In the end I've found it was easier to simply release a new build of the libraries, compiled with the correct settings. (Yes, had I done this in the first place... :-p )

http://code.google.com/p/wxmax/downloads/detail?name=wxwidgets_2.8.7_static_win32b.zip

If you aren't interested in GL/GLMax2D integration on Windows, you can stick with the libs you already have.

There's also a fix to wxGLCanvas in SVN to stop the flicker on Win32.

Anyways... if you have any problems... :-)

Hi Brucey,
I followed your instruction above to get BMax to compile with gcc-4.1 and rebuilding all the BMax mods went fine.

But when I run a simple test:
Graphics 800,600
DrawText ("Hello, World!",50,50)
Flip
WaitKey

I get this:
Building untitled1
Compiling:untitled1.bmx
flat assembler  version 1.64
3 passes, 2665 bytes.
Linking:untitled1
Executing:untitled1
/usr/bin/ld: warning: libstdc++.so.6, needed by /usr/lib/libGLU.so, may conflict with libstdc++.so.5
Segmentation fault (core dumped)

Process complete

and if I try to run the wxMax sample hello_world.bmx, I get:
Building hello_world
Compiling:hello_world.bmx
flat assembler  version 1.64
3 passes, 2206 bytes.
Linking:hello_world
/home/urs/blitzmax/mod/wx.mod/wx.mod/wx.release.linux.x86.a(wxglue.cpp.release.linux.x86.o): In function `std::_Rb_tree_iterator<std::pair<wxObject* const, BBObject*> >::operator++()':
wxglue.cpp:(.text._ZNSt17_Rb_tree_iteratorISt4pairIKP8wxObjectP8BBObjectEEppEv[std::_Rb_tree_iterator<std::pair<wxObject* const, BBObject*> >::operator++()]+0xd): undefined reference to `std::_Rb_tree_increment(std::_Rb_tree_node_base*)'
/home/urs/blitzmax/mod/wx.mod/wx.mod/wx.release.linux.x86.a(wxglue.cpp.release.linux.x86.o): In function `std::_Rb_tree_iterator<std::pair<wxObject* const, BBObject*> >::operator++(int)':
wxglue.cpp:(.text._ZNSt17_Rb_tree_iteratorISt4pairIKP8wxObjectP8BBObjectEEppEi[std::_Rb_tree_iterator<std::pair<wxObject* const, BBObject*> >::operator++(int)]+0x14): undefined reference to `std::_Rb_tree_increment(std::_Rb_tree_node_base*)'
/home/urs/blitzmax/mod/wx.mod/wx.mod/wx.release.linux.x86.a(wxglue.cpp.release.linux.x86.o): In function `std::_Rb_tree<wxObject*, std::pair<wxObject* const, BBObject*>, std::_Select1st<std::pair<wxObject* const, BBObject*> >, std::less<wxObject*>, std::allocator<std::pair<wxObject* const, BBObject*> > >::erase(std::_Rb_tree_iterator<std::pair<wxObject* const, BBObject*> >)':
wxglue.cpp:(.text._ZNSt8_Rb_treeIP8wxObjectSt4pairIKS1_P8BBObjectESt10_Select1stIS6_ESt4lessIS1_ESaIS6_EE5eraseESt17_Rb_tree_iteratorIS6_E[std::_Rb_tree<wxObject*, std::pair<wxObject* const, BBObject*>, std::_Select1st<std::pair<wxObject* const, BBObject*> >, std::less<wxObject*>, std::allocator<std::pair<wxObject* const, BBObject*> > >::erase(std::_Rb_tree_iterator<std::pair<wxObject* const, BBObject*> >)]+0x12): undefined reference to `std::_Rb_tree_rebalance_for_erase(std::_Rb_tree_node_base*, std::_Rb_tree_node_base&)'
/home/urs/blitzmax/mod/wx.mod/wx.mod/wx.release.linux.x86.a(wxglue.cpp.release.linux.x86.o): In function `std::_Rb_tree_iterator<std::pair<wxObject* const, BBObject*> >::operator--()':
wxglue.cpp:(.text._ZNSt17_Rb_tree_iteratorISt4pairIKP8wxObjectP8BBObjectEEmmEv[std::_Rb_tree_iterator<std::pair<wxObject* const, BBObject*> >::operator--()]+0xd): undefined reference to `std::_Rb_tree_decrement(std::_Rb_tree_node_base*)'
/home/urs/blitzmax/mod/wx.mod/wx.mod/wx.release.linux.x86.a(wxglue.cpp.release.linux.x86.o): In function `std::_Rb_tree<wxObject*, std::pair<wxObject* const, BBObject*>, std::_Select1st<std::pair<wxObject* const, BBObject*> >, std::less<wxObject*>, std::allocator<std::pair<wxObject* const, BBObject*> > >::_M_insert(std::_Rb_tree_node_base*, std::_Rb_tree_node_base*, std::pair<wxObject* const, BBObject*> const&)':
wxglue.cpp:(.text._ZNSt8_Rb_treeIP8wxObjectSt4pairIKS1_P8BBObjectESt10_Select1stIS6_ESt4lessIS1_ESaIS6_EE9_M_insertEPSt18_Rb_tree_node_baseSE_RKS6_[std::_Rb_tree<wxObject*, std::pair<wxObject* const, BBObject*>, std::_Select1st<std::pair<wxObject* const, BBObject*> >, std::less<wxObject*>, std::allocator<std::pair<wxObject* const, BBObject*> > >::_M_insert(std::_Rb_tree_node_base*, std::_Rb_tree_node_base*, std::pair<wxObject* const, BBObject*> const&)]+0x4b): undefined reference to `std::_Rb_tree_insert_and_rebalance(bool, std::_Rb_tree_node_base*, std::_Rb_tree_node_base*, std::_Rb_tree_node_base&)'
/home/urs/blitzmax/mod/wx.mod/wx.mod/../lib/linux/libwx_gtk2u_core-2.8.a(corelib_textctrl.o):(.rodata._ZTV10wxTextCtrl[vtable for wxTextCtrl]+0x368): undefined reference to `std::basic_streambuf<char, std::char_traits<char> >::seekoff(long long, std::_Ios_Seekdir, std::_Ios_Openmode)'
/home/urs/blitzmax/mod/wx.mod/wx.mod/../lib/linux/libwx_gtk2u_core-2.8.a(corelib_textcmn.o):(.rodata._ZTV14wxTextCtrlBase[vtable for wxTextCtrlBase]+0x368): undefined reference to `std::basic_streambuf<char, std::char_traits<char> >::seekoff(long long, std::_Ios_Seekdir, std::_Ios_Openmode)'
/home/urs/blitzmax/mod/wx.mod/wx.mod/../lib/linux/libwx_gtk2u_core-2.8.a(corelib_treectlg.o):(.rodata._ZTV14wxTreeTextCtrl[vtable for wxTreeTextCtrl]+0x368): undefined reference to `std::basic_streambuf<char, std::char_traits<char> >::seekoff(long long, std::_Ios_Seekdir, std::_Ios_Openmode)'
collect2: ld returned 1 exit status
Build Error: Failed to link /home/urs/blitzmax/mod/wx.mod/samples/hello_world
Process complete


Maybe it would be easier to compile wxWidgets for gcc-3.3?

Apologies nadia...

It seems there's also a reference to 3.3 in the LinkApp function in bmk_util :
?Linux
	cmd$="g++-3.3 -m32 -s -Os --eh-frame-hdr -pthread -static-libgcc"

Which makes sense when you see that warning message "...may conflict with libstdc++.so.5...", which one wouldn't expect having linked the binaries to the latest gcc.

Before you give up completely, you might like to try changing that reference to 3.3 also :-)

Brucey,

Am trying to create my own rotary control deriving a type from wxControl. I am unable to find the definition of wxControl to find out how to do the following:

wxObjectPtr = wxObject.Create( Self, parent.wxObjectPtr, id )


here is a little more of the source:

'-------------------------------------------
Type Rotary Extends wxControl
'-------------------------------------------

	Field m_parent:wxWindow


	Function CreateRotary:Rotary(parent:wxWindow, id:Int, value:Int, minValue:Int, maxValue:Int,..
			x:Int = -1, y:Int = -1 )
		'
		Return New Rotary.Create(parent, id, value, minValue, maxValue, x, y)
		
	End Function

	Method Create:Rotary( parent:wxWindow, id:Int, value:Int, minValue:Int, maxValue:Int, x:Int, y:Int )
		'
		m_parent = parent

		wxObjectPtr = wxObject.Create( Self, parent.wxObjectPtr, id )
			
		OnInit()
		
		Return wxObjectPtr
		
	End Method

	Method OnInit()
		'		

		' Connect the functions to the events
		ConnectAny(wxEVT_LEFT_DOWN,OnMouseLeftDown)
		ConnectAny(wxEVT_LEFT_UP,OnMouseLeftUp)
		ConnectAny(wxEVT_MOTION,OnMouseMotion)
		ConnectAny(wxEVT_PAINT,OnPaint)

	End Method

EndType


Hey Brucey, this is fantastic! After fixing the g++-3.3 stuff, I can run now most of the wxMax samples!

When I try to run sheet.bmx I get the following error:
Building sheet
Compiling:sheet.bmx
flat assembler  version 1.64
4 passes, 79007 bytes.
Linking:sheet
Executing:sheet
appstub.linux signal handler 11
Process complete

and when I try to run this:
Graphics 800,600
DrawText ("Hello, World!",50,50)
Flip
WaitKey

I get error:
Building untitled1
Compiling:untitled1.bmx
flat assembler  version 1.64
3 passes, 2665 bytes.
Linking:untitled1
Executing:untitled1
Segmentation fault (core dumped)

Process complete


maybe another of you magic tips?

@nadia
It's such a shame you are having so many problems with the newer gcc.
As a test I've just finished a BlitzMax build on a Fedora-based Linux (that Russian Linux distro whose name escapes me currently), which came with gcc 4.1.1.
And just to make things more likely not to work, the Linux was running in Parallels in its own VM.

Amazingly, your small seg-faulting example worked first time.
In fact, after building wxWidgets 2.8.7, I got all the samples to run too... including the sheet sample. And, surprisingly, the glcube sample worked better first time than the win32 attempt ! (I at least expected some flicker/slowdown running through the vm).

Am uploading the Linux static libs for 2.8.7 for those that are interested. It fixes a few bugs.

btw nadia, if you run your small example in debug mode, does it give you any errors before it dies?

Nigel,

would a Create() for wxControl help you at all? ...
If you then subclassed wxControl, you could perhaps use that as a base for your custom controls?

unless you want to create your custom control in the C++ :-)

btw, it's best to have a Create() return Self.

Lemme know if you need more than that.

oh thanks brucey!! now GL samples works!!


...Trying to put a minib3D scene in a wx window, but seems more difficult than I thinked...
I saw that the minib3D's Graphics3 simply call 'Graphics' functions: How I must move to insert a Max2D+minib3D scene in wx? there's no-way to simply attach the handle of max2D 'Graphics' Window to a wx window?

It should work in a similar way to getting miniB3D in a MaxGUI window using a Canvas - probably :-)

So if there are any examples of doing it that way, that might be the best place to start from.

Brucey,

Perhaps a more general question first. If you had a working C++ additional control (a rotary widget) and you wanted to implement the same in Blitz. What steps would you follow to achieve this?

Pick an example from wx.mod...

Say, wxButton as it's quite basic :

glue.h - defines the Max subclass of the original widget, as well as the exposed API calls.
glue.cpp - implements what is defined in glue.h
common.bmx - is the Extern list, as well as any widget specific consts.
wxbutton.bmx - is the BlitzMax code which wraps up the API.

The all use the same basic structure, which seems to work ;-)

I saw a nice rotary thingme in the industrial widgets pack. On my list of potential additions at some point. There's also a cool KeyBinder and ledpanel I want to add too.

Although the subclasses mostly appear not to actually do much, they will probably become more important when resources are implemented - oh joys, that'll be fun :-p

Oh, and you'll of course need to include the source for your widget... see any of wxScintilla, wxSheet, wxPropGrid for clues there...

:-)

Brucey,
Do you have a link to the rotary widget you mention above?

http://www.koansoftware.com/kwic/index.htm

It also appears to be avaliable at the wxCode repository, but I dunno what the current state is.

revision 204 causes a few problems with:

Building Modules
Compiling:glue.cpp
C:/Program Files/BlitzMax/mod/wx.mod/wxconfig.mod/glue.cpp:84: error: `uint' does not name a type
C:/Program Files/BlitzMax/mod/wx.mod/wxconfig.mod/glue.cpp:88: error: `uint' does not name a type
Build Error: failed to compile C:/Program Files/BlitzMax/mod/wx.mod/wxconfig.mod/glue.cpp
Process complete

change from uint to unsigned int fixes problem (on windows).

I've been thinking of using wxMax/wxWidgets to write my next GUI app, but I'm concerned about file size (the library alone is quite large). I haven't downloaded anything wx yet, so I'd like to ask those who have been testing this:

Are your final exe's of a reasonable size or would you say they are bloated?

How's GUI<->User interaction speed?

Should I wait until the port is more mature, or is it pretty much ready to go now?

Thanks in advance,
Russell

Are your final exe's of a reasonable size or would you say they are bloated?

Well most of my little gadget test apps are 4-6 Mb - so yes there is a decent filesize hit I'd say. But I think it's worth it.

Speed is fine by me. Feels pretty sharp and responsive (testing in Leopard).

Should you wait? I think it's fine to dive in now. There's a lot that hasn't been properly tested yet but Brucey seems to possess an uncanny knack for fixing a bug almost as soon as it's posted. Because it's still in very active development you do need to be comfortable with a lot of SVN updates and possess a wee bit of gumption to get you through any initial install hiccups.

All the main gadgets are in place and as it stands now I don't think there's anything in MaxGui that isn't in wxMax.

If you are considering writing a relatively complex GUI app in Max then wxMax is definitely the way to go and now is a good time to start :-)

@Russel

The biggest example aui.bmx, which implements a IDE-like GUI (not like the BlitzMax-Gui rather like a real IDE), is 3,7 MB big in release mode. Compressed with upx it's 1 MB. So if you are planning to create just a little window with some buttons wxMax is maybe a little oversized and brings too much overhead. But if you are planning to use it for a more complex interface you can't get a better module.

edit:
And big thanks to brucey for his great work.

ps: how do i f*** post a link here?

Forum codes

For comparison, aui in release mode is 4.9Mb on the mac.

Hi again, I'm giving the Ubuntu iinstallation a bit of a rest, haven't quite got it to work properly yet. I'll give it another shot later.

In the meantime I've been playing with he windows version of wxMax a bit. So far I'm very impressed with it and think it's quite a bit faster then wxPython!

I've run into a few problems with the event handling stuff. Here is some testing code. Why are the focus and mouse event handlers not firing?

SuperStrict

Framework wx.wxApp
Import wx.wxFrame
Import wx.wxStaticText
Import wx.wxTextCtrl
Import wx.wxButton

Type MyApp Extends wxApp

	Field frame:MyFrame

	Method OnInit:Int()

		frame = MyFrame(New MyFrame.Create(,, "wxMax tests...", 0, 0, 400, 250)) 
		frame.Center(wxBOTH) 
		frame.SetBackgroundColour(wxColour.CreateColour(210, 200, 200)) 

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

End Type

Type MyFrame Extends wxFrame
	Const TXT01_ID:Int = wxID_HIGHEST + 1
	Const TXT02_ID:Int = wxID_HIGHEST + 2
	
	Field txtTest01:wxTextCtrl
	Field lblInput:wxStaticText
	Field cmdClose:wxButton
	Field txtTest02:wxTextCtrl
	
	Method OnInit() 
		' some reusable font settings and colour
		Local lFont:wxFont = wxFont.CreateFontWithAttributes(10, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, False, "Arial") 
		Local lFontCol:wxColour = wxColour.CreateColour(0, 0, 200, 0) 
	
		' creating a label with coloured text etc
		Local lbl:wxStaticText = New wxStaticText.Create(Self, wxID_ANY, "Enter some text", 20, 20, 100, 20) 
		lbl.SetFont(lFont) 
		lbl.SetForegroundColour(lFontCol) 
		
		' a text input box
		txtTest01 = New wxTextCtrl.Create(Self, TXT01_ID, "copy to label..", 20, 40, 140, 20) 
		
		' create another label to receive the input from the text box
		lblInput = New wxStaticText.Create(Self, wxID_ANY, "", 20, 90, 140, 25, wxST_NO_AUTORESIZE | wxSUNKEN_BORDER | wxALIGN_CENTER) 
		lblInput.SetFont(lFont) 
		lblInput.SetForegroundColour(lFontCol) 
		
		' create a close button
		cmdClose = New wxButton.Create(Self, wxID_CLOSE, "Close", 10, 170, 40, 20) 
		cmdClose.Center(wxHORIZONTAL) 
		
		
		' create a status bar just for fun
		CreateStatusBar(2)
		SetStatusText("Testing text boxes...") 
		
		connect(TXT01_ID, wxEVT_COMMAND_TEXT_UPDATED, OnText) 
		connect(wxID_CLOSE, wxEVT_COMMAND_BUTTON_CLICKED, OnQuit) 
		
		ConnectRange(TXT01_ID, TXT02_ID, wxEVT_SET_FOCUS, OnSetFocus) 
		ConnectRange(TXT01_ID, TXT02_ID, wxEVT_KILL_FOCUS, OnKillFocus) 
		
		ConnectRange(TXT01_ID, TXT02_ID, wxEVT_MOUSE_EVENTS, OnMouseEvent) 
		'Connect(TXT01_ID, wxEVT_MOUSE_EVENTS, OnMouseEvent) 
		'ConnectAny(wxEVT_MOUSE_EVENTS, OnMouseEvent) 
		
		' #### second set of label/input box ###########################################
		' creating a label with coloured text etc
		lbl = New wxStaticText.Create(Self, wxID_ANY, "Second text box", 220, 20, 100, 20) 
		lbl.SetFont(lFont) 
		lbl.SetForegroundColour(lFontCol) 
		
		' another text input box
		txtTest02 = New wxTextCtrl.Create(Self, TXT02_ID, "testing 01", 220, 40, 140, 20) 
		
	End Method

	Function OnText(event:wxEvent) 
		MyFrame(event.parent).lblInput.SetLabel(MyFrame(event.parent).txtTest01.GetValue().ToUpper()) 
		'DebugLog MyFrame(event.parent).txtTest01.GetValue() 
	End Function
	
	Function OnQuit(event:wxEvent)
		' true is to force the frame to close
		wxWindow(event.parent).Close(True)
	End Function
	
	Function OnSetFocus(event:wxEvent) 
		DebugLog "got focus..."
	End Function

	Function OnKillFocus(event:wxEvent) 
		DebugLog "lost focus..."
	End Function
	
	Function OnMouseEvent(event:wxEvent) 
		Local ev:wxMouseEvent = wxMouseEvent(event) 
		If Not ev.Moving() Then
			If ev.Entering() Then
				DebugLog "Mouse entered text box"
			Else If ev.Leaving() Then
				DebugLog "Mouse left text box"
			End If
		End If
		
	End Function
	
	
End Type

New MyApp.run()


I am trying to intercept the close request to provide an ARE YOU SURE message and I think i'm intercepting the wrong event.

What is the event raised when you press the [x] close button on a form?

Type myTest Extends wxFrame
  Method OnInit()
    connect( ,wxEVT_CLOSE, onCloseWindow )
  End Method

  Function OnCloseWindow(event:wxEvent)
    If wxMessageBox("Are you sure?" , "Exit" , wxICON_QUESTION | wxYES_NO ) = wxYES Then
      wxWindow(event.parent).Close(True) 
    End If
  End Function
End Type


@Scaremonger

try something like

For the menu quit entry use:
Connect(wxID_EXIT, wxEVT_COMMAND_MENU_SELECTED, OnQuit)

For the [x]
Connect( , wxEVT_CLOSE_WINDOW, OnCloseWindow )


	Function OnCloseWindow(event:wxEvent)
		'
    		If wxMessageBox("Are you sure?" , "Exit" , wxICON_QUESTION | wxYES_NO ) = wxYES Then
			event.skip()
		EndIf

	End Function

	'
	Function OnQuit(event:wxEvent)
		'
		Frame(event.parent).Close(True)
		
	End Function


@Nigel Brown -> Thanks very much.

@nadia

After having a rummage in the headers, it seems mouse events are not defined for use with ConnectRange.

You might either do this :
ConnectAny( wxEVT_MOUSE_EVENTS, OnMouseEvent)

which connects mouse events to everything in the window, or perhaps
txtTest01.ConnectAny( wxEVT_MOUSE_EVENTS, OnMouseEvent, Null, Self) 

to connect mouseevents specifically to the textfield.


Does wxPython allow you to connect mouse events to a range of ids?

@Nigel

examples:
wxartprovider (hoping this will allow icons in wxgenericdirctrl to be altered?)


I'll have a look at artprovider.
Also, wxGenericDirCtrl (just in!) exposes its wxTreeCtrl, which might allow you to inject your own imagelist.
Of course, artprovider would be a preferred option.

Have added an "artprovider" sample which demonstrates using your own images to replace those in a wxGenericDirCtrl.

A surprisingly powerful tool, is wxArtProvider. Very cool :-)
(hmm? Haven't I used it before? No. I am mostly just implementing the controls. Don't get much time to try them out yet :-p )

Brucey,

Just changed my wxTreetCtrl to wxGenericDirCtrl and its looking good, need to spend some time looking at how to interact with it. Thanks guess thats one of my three wishes used up. Anyone want to trade one of theirs?

Looks like you have made progress with wxConfigBase is there much more to do with this? wxSetAppName() - wxSetVendorName() etc...

is there much more to do with this

Try as I might, I couldn't (at least on Mac) manage to create a wxFileConfig and have it save out anything.

So I suggest you set appname and vendorname, and just do
config = wxConfigBase.Get()

It'll create you an instance of a wxConfig and will save it wherever (on Win32, I think that defaults to the registry. On Mac it creates a file in ~/Library/Preferences).

You can keep calling Get() to get the same config, as it is global.

Other than my issues with not being able to create my *own* wxFileConfig instance, it seems to work pretty well.

oh.. SetAppName and SetVendorName are part of wxApp :-)

Thanks for the replies, everyone about the size and efficiency of wxMax/wxWidgets.

I like the fact that I can import only the actual controls that are needed/used to keep file size down, too. (Does Framework Assistant work with it? Probably not, but would be really cool!)

I think I will end up using wx et al after all.

Thanks!
Russell

Brucey,

The following seems to work correctly on Leopard. However if you then call m_pConfig.Free() You get an error after exiting the app?

		SetVendorName(_("Company"))
		SetAppName(_("ApplicationName"))
		m_pConfig:wxConfigBase = New wxConfigBase.Get()

		m_useSplash = m_pConfig.ReadBool(AppDir+res+"resources/splash", True )
		m_pConfig.WriteBool(AppDir+res+"resources/splash", m_useSplash )


Thanks guess thats one of my three wishes used up.

Speaking of wish lists Brucey, wxTextValidator would be nice! :-)

revision 213 compiles text.bmx from samples but produces the following link error:

Building text
Compiling:text.bmx
flat assembler version 1.66
4 passes, 153575 bytes.
Linking:text.debug.exe
C:/Program Files/BlitzMax/mod/wx.mod/wxtextctrl.mod/wxtextctrl.debug.win32.x86.a(glue.cpp.debug.win32.x86.o):glue.cpp:(.text+0x2db): undefined reference to `MaxTextValidator::Validator()'
Build Error: Failed to link C:/Program Files/BlitzMax/mod/wx.mod/samples/text.debug.exe
Process complete



Can be fixed by Importing wx.wxTextValidator

Fixed wxTextCtrl instead, to import wxTextValidator.
Like I should have done originally :-)

First: Thank you for wxMax :-)

I hope I write in the correct Thread.
I want to create a Window/Frame like Windows in MaxGUI with the Style "WINDOW_CLIENTCOORDS". Because I maybe could get errors, if I create (for example) a Button on the left buttom of a Window, and an other User has an other Windows/Linux-Style than myself. So it could be, that the Button is outside of the Window. I hope that you understood what I mean ^^
Sorry for my baaad english :(

Greetings
#Reaper

Reaper. If you add a wxSizer to the frame, you can SetMinSize(), which, as the docs explain:

"Normally, the sizer will calculate its minimal size based purely on how much space its children need. After calling this method GetMinSize will return either the minimal size as requested by its children or the minimal size set here, depending on which is bigger."

wxSizers allow you to lay-out your controls without having specify exact coords or width/height.

When you load your app on a PC with a different theme, the sizers should arrange themselves so that your layout remains the same, even though the controls might be different sizes.

Hope that helps?

:o)

Thank you for your answer.
Hmm... I don't know realy how to use the Sizer, or which Sizer I should/could use. I found an example in the Docs, but it is a little bit complicate:

' we want to get a dialog that is stretchable because it
' has a text ctrl at the top and two buttons at the bottom
Type MyDialog Extends wxDialog

Function CreateMyDialog:MyDialog(parent:wxFrame, id:Int, title:String)
Return New MyDialog.Create(parent, id, title, -1, -1, -1, -1, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
End Function

Method OnInit:Int()

Local topsizer:wxBoxSizer = New wxBoxSizer.Create( wxVERTICAL )
' create text ctrl with minimal size 100x60
topsizer.Add( ..
New wxTextCtrl.Create( Self, -1, "My text.", -1, -1, 100, 60, wxTE_MULTILINE), ..
1,           .. ' make vertically stretchable
wxEXPAND |   .. ' make horizontally stretchable
wxALL,       .. '   and make border all around
10 )            ' set border width to 10
Local button_sizer:wxBoxSizer = New wxBoxSizer.Create( wxHORIZONTAL )
button_sizer.Add( ..
New wxButton.Create( Self, wxID_OK, "OK" ), ..
0,          .. ' make horizontally unstretchable
wxALL,      .. ' make border all around (implicit top alignment)
10 )           ' set border width to 10
button_sizer.Add(  ..
New wxButton.Create( Self, wxID_CANCEL, "Cancel" ), ..
0,          .. ' make horizontally unstretchable
wxALL,      .. ' make border all around (implicit top alignment)
10 )           ' set border width to 10
topsizer.AddSizer( ..
button_sizer,  ..
0,             .. ' make vertically unstretchable
wxALIGN_CENTER ) ' no border and centre horizontally
SetSizer( topsizer )      ' use the sizer for layout
topsizer.SetSizeHints( Self )   ' set size hints to honour minimum size

Return True
End Method

End Type


I think/hope that this is more than I nead. ^^
I will continue with my tests ;-)
Thank you! :-)

Greetings
#Reaper

Newcomers to wxMax could do a lot worse than to Google "Cross-Platform GUI ebook Programming with wxWidgets" and grab the free .pdf ebook.

Combine this with the included sample code and compiled wxMax docs and you have yourself an excellent document base for your projects.

Reaper. You might want to try out wxFormBuilder which is a GUI-designer.
It should give you an idea of how sizers work, and how to use them to lay stuff out.

At the moment you are stuck with the generated C++ code, but I'm working on a little app that will generate BlitzMax code from the wxFormBuilder project file.

Just some advise please.

I used to use vb6 and had GUIs for Databases. Fairly simple as each control can link to a table or recordset.

In BlitzMax i tend to be opening recordsets, manipulating the data, and either writing back to the database or to a file.

Now that i am learning wxWidgets what would be a simple way to link data to a control? Just open the recordset and attach data to a control, or put the data in a list/array which is then linked to the control, or some other option?

As per Davids post above i have just downloaded the pdf but i haven't had a chance to read it yet.

Regards
Glenn

There is a Get/SetClientData() on wxEvtHandler which most of the controls inherit.
It takes an Object.

But this is just a straight, "please hold onto this object for me" link. Nothing specific with the data is done.

wxListCtrl's and other list-based controls also have the facility to store user data on each item.

If you need to manage data for controls, you can always subclass the control override the methods to do whatever extra work you need.

Thank you Brucey for this module! I look forward to a wxFormBuilder with BMax support :)

Btw: http://code.google.com/p/wxmax/wiki/SetupAndInstallation
Can you add a Notice for Windows that libodbc32.a, librpcrt4.a and libwinspool.a have to copy from MinGW\lib to wx.mod\lib\win32 ?

cu olli

I've been playing around a bit wit the wxListBox and found the following problem:
If you add some ItemClientData into a ListBox item, lets say an ID number. It loads fine if converted to a string. Initially the retrieving of the ID number from the selected list item works fine too, but after scrolling up and down the list box wit the arrow keys, the ItemClientData suddenly disappears! What is happening???

Here is a little testing app:
Thanx very much for any help!
SuperStrict

Framework wx.wxApp
Import wx.wxFrame
Import wx.wxStaticText
Import wx.wxListBox
Import wx.wxButton
'Import wx.wxMessageDialog

Import brl.random

Type MyApp Extends wxApp

	Field frame:MyFrame
	

	Method OnInit:Int()
		frame = MyFrame(New MyFrame.Create(,, "wxMax tests...", 0, 0, 200, 250)) 
		frame.Center(wxBOTH) 
		frame.SetBackgroundColour(wxColour.CreateColour(210, 200, 200)) 

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

End Type

Type MyFrame Extends wxFrame
	Const LST01_ID:Int = wxID_HIGHEST + 1
	
	Field cmdClose:wxButton
	Field label:wxStaticText
	Field lstTest:wxListBox
	
	Method OnInit() 
	
		' label to display list box selection 
		label = New wxStaticText.Create(Self, wxID_ANY, "display id of selected list item..", 20, 10, 140, 20, wxST_NO_AUTORESIZE | wxSUNKEN_BORDER) 
		label.SetForegroundColour(wxColour.CreateColour(200, 0, 0)) 
		label.Center(wxHORIZONTAL) 
		
		
		' create a list box
		lstTest = New wxListBox.Create(Self, LST01_ID, Null, 20, 30, 140, 150) 
		lstTest.Center(wxHORIZONTAL) 
		lstTest.ConnectAny(wxEVT_COMMAND_LISTBOX_SELECTED, OnLstDocSelect, Self) 
				
		' create a close button
		cmdClose = New wxButton.Create(Self, wxID_CLOSE, "Close", 10, 190, 40, 20) 
		cmdClose.Center(wxHORIZONTAL) 
		
		
		' create a status bar
		'CreateStatusBar(2) 
		'SetStatusText("Testing List Box...") 
				
		connect(wxID_CLOSE, wxEVT_COMMAND_BUTTON_CLICKED, OnQuit) 
		
		'load ListBox with some testing data
		lstTest.clear() 
		Local i:Int
		For i = 1 To 50
			' load a string with a random number into the itemClientData object
			lstTest.Append("item " + i, String(Rand(1, 1000))) 
		Next
	End Method
	
	Function OnLstDocSelect(event:wxEvent) 
		Local mf:MyFrame = MyFrame(event.userData) 
		' read the itemClientData
		
		' !!!!!!!!!!!  PLEASE NOTE !!!!!!!!!!!!!!!                  <<<< ----------------!!!
		' Initially this works fine. But if you scroll up and down about four to fife times 
		' with the up and down arrow keys, the ItemClientData suddenly disappears ?????
		
		Local n:Int = mf.lstTest.GetSelection() 
		Local id:String = String(mf.lstTest.GetItemClientData(n)) 
		' clear the label 
		 
		If Not id
			' itemClientData disappeared!
			'DebugStop
			mf.label.SetLabel(" ID is EMPTY!!!!") 
		Else
			mf.label.SetLabel(" Id = " + id) 
		End If
		event.Skip() 
	End Function
	
	Function OnQuit(event:wxEvent) 
		' true is to force the frame to close
		wxWindow(event.parent).Close(True)
	End Function
	
End Type

New MyApp.run()


@nadia, the problem is that the listctrl is not holding its own reference to the clientdata object, so after a while it is being GC'd by BlitzMax.

This issue also notes the problem : http://code.google.com/p/wxmax/issues/detail?id=13

The reason it's not reference counting it properly yet is because it's going to take a while to get that working, and I thought it best to have controls wrapped first and worry about more complicated things later.

I hope that's not too much of a problem at the moment.

It's on my list of things to do :-)

Thanks very much Brucey, I had a suspicion i was something todo with the GC. I'll find a way to fix it for now ;-)

@Brucey,

I have some Problems according to dialogs and sizers. I thought this code snippet would work.

SuperStrict

Framework wx.wxApp
Import wx.wxDialog
Import wx.wxStaticText
Import wx.wxTextCtrl

Type App Extends wxApp
	
	Field login:LoginDialog
	
	Method OnInit:Int()
		
		login = LoginDialog(New LoginDialog.Create_(Null, -1, "Login"))
		
		SetTopWindow(login)
		
		login.Show(True)
		
		Return True
		
	EndMethod
	
EndType

Type LoginDialog Extends wxDialog
	
	Const ID_PASSWORD:Int = 1000
	Const ID_OK:Int = 1001
	Const ID_ABORT:Int = 1002
	
	Field elementSizer:wxBoxSizer
	
	Field label:wxStaticText
	Field password:wxTextCtrl

	Field buttonSizer:wxBoxSizer
	
	Field okButton:wxButton
	Field abortButton:wxButton
		
	Method OnInit:Int()
		
		elementSizer = New wxBoxSizer.Create(wxVERTICAL)
		
		label = New wxStaticText.Create(Self, wxID_ANY, "Gib das Passwort ein:")
		password = New wxTextCtrl.Create(Self, ID_PASSWORD, "", -1, -1, -1, -1, wxTE_PASSWORD)
		
		elementSizer.Add(label, 0, wxALL|wxEXPAND, 5)
		elementSizer.Add(password, 1, wxALL|wxEXPAND, 5)
		
		buttonSizer = New wxBoxSizer.Create(wxHORIZONTAL)
		
		okButton = New wxButton.Create(Self, ID_OK, "Login")
		abortButton = New wxButton.Create(Self, ID_ABORT, "Abbrechen")
		
		buttonSizer.Add(okButton, 1, wxALL|wxEXPAND, 5)
		buttonSizer.Add(abortButton, 1, wxALL|wxEXPAND, 5)
		
		elementSizer.Add(buttonSizer, 1, wxEXPAND, 5)
		
		SetSizer(elementSizer)
		Layout()
		elementSizer.Fit(Self)
		
	EndMethod
	
EndType


It shows an error at the line where I want to add buttonSizer as child to elementSizer: Unable to convert from 'wx.wxwindow.wxBoxSizer' to 'wxWindow'.

If I comment this out the example compiles but doesn't do anything - it's not showing a Dialog.

Thanks for your reply,
Artemis

PS: For this code I've designed it in wxFormBuilder and referred to the generated C++-Code.

PSS: What's your wxCodeGen doing? It would make my life much easier.

@ArtemisX

first try adding
New App.run()


Oh, no, what a shame. Yeah, that works.

But the problem with the sizers is still there.

try this as well:

SuperStrict

Framework wx.wxApp
Import wx.wxDialog
Import wx.wxStaticText
Import wx.wxTextCtrl
Import wx.wxStdDialogButtonSizer
Import wx.wxlocale

Type App Extends wxApp
	
	Field login:LoginDialog
	
	Method OnInit:Int()
		
		login = LoginDialog(New LoginDialog.Create_(Null, -1, "Login"))
		
		SetTopWindow(login)
		
		login.Show(True)
		
		Return True
		
	EndMethod
	
EndType

Type LoginDialog Extends wxDialog
	
	Const ID_PASSWORD:Int = 1000
	Const ID_OK:Int = 1001
	Const ID_ABORT:Int = 1002
	
	Field elementSizer:wxBoxSizer
	
	Field label:wxStaticText
	Field password:wxTextCtrl

	Field buttonSizer:wxBoxSizer
	
	Field okButton:wxButton
	Field abortButton:wxButton
		
	Method OnInit:Int()
		
		setsizehints(-1,-1)
		
		elementSizer = New wxBoxSizer.Create(wxVERTICAL)
		
		label = New wxStaticText.Create(Self, wxID_ANY, _("Gib das Passwort ein:"),-1,-1, -1,-1, 0)
		label.wrap(-1)
		elementSizer.Add(label, 0, wxALL, 5)

		password = New wxTextCtrl.Create(Self, ID_PASSWORD, "", -1, -1, -1, -1, wxTE_PASSWORD)
		elementSizer.Add(password, 0, wxALL, 5)

		buttonSizer = New wxStdDialogButtonSizer.Create(wxHORIZONTAL)
				
		okButton = New wxButton.Create(Self, ID_OK, _("Login"))
		buttonSizer.Add(okButton, 1, wxALL|wxEXPAND, 5)

		abortButton = New wxButton.Create(Self, ID_ABORT, _("Abbrechen"))
		buttonSizer.Add(abortButton, 1, wxALL|wxEXPAND, 5)
		
		elementSizer.AddSizer( buttonSizer, 1, wxEXPAND, 5)
		
		SetSizer(elementSizer)
		Layout()
		
	EndMethod
	
EndType

New app.run()


@Nigel Brown,

yeah, that works, but there are still some problems/questions:
- if I close the dialog the application does not end
- the button are very big, it's like this:
Password:
#Textfield########
+------------++------------+
|            ||            |
|            ||            |
|     Ok     ||   Abort    |
|            ||            |
|            ||            |
+------------++------------+

- was does the funktion _ do?

@Brucey
here is a bug-report:
when i call wxDialog.Create_ with the first parameter Null the programm runs normal in release mode but crashes in debugmode at line 73 in wxdialog.mod/wxdialog.bmx because there is no switch whether parent is null or not. But the official documentation says that parent can be Null.

Artemis

if I close the dialog the application does not end

The dialog is still "live", even though you cannot see it. It needs to be Free()'d. Try connecting an wxEVT_CLOSE to the dialog and either Free() or Destroy() the the dialog.
By default, a wxWidgets app will wait until all frames are closed before ending.

the button are very big

What happens if you use :
elementSizer.AddSizer( buttonSizer, 0, wxEXPAND, 5)

Second param is "proportion", which changes the way it stretches.

I've also fixed the dialog parent problem.

What's your wxCodeGen doing? It would make my life much easier.

It's generating max-code from the .fbp file, in the same way that wxFormBuilder generates the C++.
Not quite finished yet though.

Yeah, I have to change it to 0 and remove wxEXPAND and then call elementSizer.fit(Self) and it works.

One question: I thought that Stnadard-Dialogs like Yes-No-Dialogs and StandardDialogButtonSizers would use the language of the system the app is running on but they don't. I'm running a German system but the button-labels are still 'Cancel' and so on.
Is there any possibility to change the labels of the standars-buttons or do I have to create my own dialog?

I've seen that the function _ has something to do with localization - how does it work? Do I have to create .po or .mo file like localization under linux with gettext?

Here is some test code not sure if this is all you need have no time to test, just of to Footbal :-) just wrap the text file you require with _("") and produce some .po files in a folder named langauges for transaltion.

include "wx.wxLocale"

local locale:wxLocale = New wxLocale.Create()

Local lng:Int = wxGetSingleChoiceIndex("Please choose language:", "Language", langNames)
		
	    If lng <> -1 Then
	        ' don't use wxLOCALE_LOAD_DEFAULT flag so that Init() doesn't return
	        ' false just because it failed to load wxstd catalog
	        If Not locale.Init(langIds[lng], wxLOCALE_CONV_ENCODING) Then
	            wxLogError(_("This language is not supported by the system."))
	            Return False
	        End If
	    End If

	    ' normally this wouldn't be necessary as the catalog files would be found
	    ' in the default locations, but when the program is not installed the
	    ' catalogs are in the build directory where we wouldn't find them by
	    ' default
	    wxLocale.AddCatalogLookupPathPrefix("languages/.")
	
	    ' Initialize the catalogs we'll be using
	    locale.AddCatalog("internat")


I've seen that the function _ has something to do with localization - how does it work?

gettext parses files looking for a function called _() by default. It generates a .po file which can then be copied and translated into other languages.
Have a look at the internat sample for ideas.

I believe you can also get a version of gettext for win32.

As for standard dialogs only showing english, I think you need to also include wxWidgets' .po files with your distro (unless they are already installed on your system in the standard location).
I've uploaded the 2.8.7 locale files. I'm not sure where you would need to put it in order to work, but they are there now for you to experiment with if you like :-)

There's now a "tools" folder in the main wx.mod folder.

This has the first release source for wxCodeGen. It is stable enough to generate itself, which is kinda useful ;-)

However, there's still a lot of stuff missing -
* No live checking/generation yet.
* Not all controls are catered for so far.
* Not all events are covered.
* The example App code page needs doing too.

Note : You will need BaH.libxml - which is used to process the fbp (xml) file.

Otherwise, it appears to be working really well. For an idea of what you get from it, the file codegenbase.bmx is generated from the provided wxcodegen.fbp.

Have a play. All feedback welcome.

:o)

Thanks for your help Brucey! :)
wxFormBuilder is not very easy, but I learn ;)
I will try your wxCodeGen also. Thanks!

Greetings
#Reaper :)

Using a tool like wxFormBuilder should involve much less work than attempting to hand-code a window.

Yes, the sizers will take some time to get used to, but in the long term you should find you can quickly create new windows without much effort.

If anyone comes across an OS X Leopard distributable of wxFormBuilder I would love to have a link to it. :-)

I have a shaky (reasonably stable) Leopard build for Intel. It's a static build rather than with the shared libs as recommended by the wxFormBuilder folks - since I'm having trouble running a shared build of it.

I haven't decided if the instability is Intel or Leopard based, yet. I would probably tend to the latter tho.

I'll put it up, somewhere, on Monday.

Brucey thanks, wxCodeGen working a treat. just wxRichTextCtrl failed but I know the reason for that. :-)

Leopard build is available from here :

http://code.google.com/p/wxmax/downloads/list

It's a bit... flakey... I'm afraid, but it works better than the PPC version offered on the main site (which won't run at all on my Intel 10.5).
Save often :-p

@ArtemisX

I found this link on internationalization you might find it helpful:

http://wxwidgets.info/wxTranslation

Using the following code I am able to add a panel to a sizer and this is then displayed by the frame:
		Local bSizer1:wxBoxSizer
		bSizer1 = New wxBoxSizer.Create(wxVERTICAL)
		m_panel1 = New wxPanel.Create(Self, wxID_ANY,,,,, wxTAB_TRAVERSAL)
		m_panel1.Layout()
		bSizer1.Add(m_panel1, 1, wxEXPAND | wxALL, 0)

		SetSizer(bSizer1)
		Layout()


How can I then dynamically remove this sizer containing a panel and replace it with another?

@Nigel Brown
The sizer is a container for the components within it. Why do you need to remove the sizer and replace it?

duplicate

@Scaremonger

I have a requirement to have 5 panels that will each be displayed exclusivley inside the main frame. If you show(true) and show(false) on each sizer enclosed panel it displays them correctly but each panel has to be added to the sizer attached to the main frame or it fails to size properly.

@Nigel Brown

I think I see what you mean. What you need to do is leave the page sizer alone, and update the component sizers within it.
Take a look at this code, The panels all start visible (I've commented out the show(false) line). Now select the appropriate panel from the File menu, and it hides everything except the one shown.


SuperStrict

Framework wx.wxApp
Import wx.wxFrame
Import wx.wxPanel

Type MyApp Extends wxApp

	Field frame:MyFrame

	Method OnInit:Int()

		frame = MyFrame(New MyFrame.Create(,,"Panel test", 100, 100))

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

End Type

Type MyFrame Extends wxFrame
	Global panels:wxPanel[5]

	Method OnInit()
	Local sz:wxSizer 		
	Local sizer:wxBoxSizer
	Local col:wxColour[] = [wxRed(), wxGreen(), wxBlue(), wxBlack(), wxWhite()]

		'# Create the top-level sizer and assign to parent dialog box.
		sz = New wxBoxSizer.Create(wxVERTICAL)
		setsizer(sz)

		'# Create the panels / componets
		sizer = New wxBoxSizer.Create(wxVERTICAL) 
		For Local panel% = 0 To 4
			panels[panel] = New wxPanel.Create(Self , wxID_ANY , ,,,, wxTAB_TRAVERSAL)
			panels[panel].setbackgroundcolour( col[panel] ) 
'			panels[panel].show( False )
			sizer.add( panels[panel] , 1 , wxALL | wxGROW , 5) 
		Next

		'# Add the component sizer to the page sizer.
		sz.addSizer( sizer, 1, wxALL | wxGROW, 5 )

		' create a menu bar
		Local fileMenu:wxMenu = wxMenu.CreateMenu()
		fileMenu.AppendCheckItem(101, "&Panel1" )
		fileMenu.AppendCheckItem(102, "&Panel2" )
		fileMenu.AppendCheckItem(103, "&Panel3" )
		fileMenu.AppendCheckItem(104, "&Panel4" )
		fileMenu.AppendCheckItem(105, "&Panel5" )

		' now append the freshly created menu to the menu bar...
		Local menuBar:wxMenuBar = wxMenuBar.CreateMenuBar()
		menuBar.Append(fileMenu, "&File")
		SetMenuBar(menuBar)
		
		'# Connect up the events
		Connect(101, wxEVT_COMMAND_MENU_SELECTED, showPanel)
		Connect(102, wxEVT_COMMAND_MENU_SELECTED, showPanel)
		Connect(103, wxEVT_COMMAND_MENU_SELECTED, showPanel)
		Connect(104, wxEVT_COMMAND_MENU_SELECTED, showPanel)
		Connect(105, wxEVT_COMMAND_MENU_SELECTED, showPanel)
		
	End Method

	Function showPanel(	event:wxEvent )
	Local frame:Myframe = MyFrame(event.parent)
	Local menubar:wxMenuBar	 = frame.GetMenuBar()
	Local id% = event.getId()
		For Local item% = 101 To 105
			menubar.Check(item , (id = item) ) 
			frame.panels[item-101].show( (id = item) )
		Next
		frame.layout()
	End Function

End Type

New MyApp.run()



Scaremonger, you understood exactly what was required, and after some messing with my derived type and your excellent example it is now working, thank you.

@ArtemisX

I've worked out how to get the default labels to change.
The locale zip that I've put on the Downloads section has each language inside with their specific translations.

You take the language file you need, and create a .mo from the .po (you can use PoEdit to do this). This .mo is placed in a folder, for example, the german language mo would go into "de".

Have a look at wxCodeGen, it now has support for different languages. It should help you understand how to implement it in your own apps.

I figured it was about time I took a look at this and thought about porting my level editor from MaxGUI but when I tried to grab it with Tortoise SVN, I get an error :

'WXMax\wx.mod\wxlocale.mod\.svn\lock': Access is Denied.

I saw something about readonly in the command line, and I'm not sure if this is related, but TortoiseSVN doesn't give me any command line options when I check out a repository, as far as I can see anyway.

EDIT: On second glance, I'm pretty sure it hasn't downloaded all files necessary to compile the mod.

Thanks Brucey,

I'll have a look at it.

I've translated the German po-File so you can include it in the next revision.

msgid ""
msgstr ""
"Project-Id-Version: wxCodeGen\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-01-14 18:04+0200\n"
"PO-Revision-Date: 2008-01-14 19:32+0100\n"
"Last-Translator: Jonas Cleve <jonas _ cleve @ yahoo . de>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Poedit-Language: English\n"
"X-Poedit-Basepath: .\n"
"X-Poedit-SearchPath-0: ../..\n"

#: ../../cgmain.bmx:78
msgid "New Project"
msgstr "Neues Projekt"

#: ../../codegenbase.bmx:78
msgid "Projects"
msgstr "Projekte"

#: ../../codegenbase.bmx:90
msgid "Add"
msgstr "Hinzufügen"

#: ../../codegenbase.bmx:93
msgid "Delete"
msgstr "Löschen"

#: ../../codegenbase.bmx:116
msgid "Project Name"
msgstr "Projektname"

#: ../../codegenbase.bmx:125
msgid "wxFormBuilder Project File"
msgstr "wxFormBuilder-Datei"

#: ../../codegenbase.bmx:129
msgid "Select a wxFormbuilder Project File"
msgstr "Wähle eine wxFormBuilder-Datei aus"

#: ../../codegenbase.bmx:129
msgid "*.*"
msgstr "*.*"

#: ../../codegenbase.bmx:134
msgid "BMX Project Folder"
msgstr "Projektordner"

#: ../../codegenbase.bmx:138
msgid "Select the BlitzMax Project folder"
msgstr "Wähle den Projektordner aus"

#: ../../codegenbase.bmx:143
msgid "Generated Filename"
msgstr "Dateiname"

#: ../../codegenbase.bmx:155
msgid ".bmx"
msgstr ".bmx"

#: ../../codegenbase.bmx:165
msgid "App Structure"
msgstr "Programmstruktur"

#: ../../codegenbase.bmx:166
msgid "Create SuperStrict"
msgstr "SuperStrict-Modus benutzen"

#: ../../codegenbase.bmx:169
msgid "Create Import statements"
msgstr "Import-Deklarationen erstellen"

#: ../../codegenbase.bmx:174
msgid "Auto-Generate Code on Update"
msgstr "Bei einer Änderung Code automatisch neu generieren"

#: ../../codegenbase.bmx:179
msgid "Project Config"
msgstr "Projektkonfiguration"

#: ../../codegenbase.bmx:193
msgid "Application Code"
msgstr "Programmcode"

#: ../../codegenbase.bmx:199
msgid "Check for Project File Updates"
msgstr "Projektdateien auf Änderungen prüfen."

#: ../../codegenbase.bmx:200
msgid "Monitors the project files for changes."
msgstr "Überprüft die Projektdateien auf Änderungen."

#: ../../codegenbase.bmx:204
msgid "String Localization"
msgstr "String-Lokalisierung"

#: ../../codegenbase.bmx:207
msgid "wxCodeGen Language"
msgstr "wxCodeGen-Sprache"

#: ../../codegenbase.bmx:212
msgid "Global Preferences"
msgstr "Globale Einstellungen"

#: ../../codegenbase.bmx:220
msgid "Generate"
msgstr "Generieren"

#: ../../codegenbase.bmx:239
msgid "&New Project"
msgstr "&Neues Projekt"

#: ../../codegenbase.bmx:245
msgid "&Quit"
msgstr "S&chließen"

#: ../../codegenbase.bmx:247
msgid "File"
msgstr "Datei"

#: ../../codegenbase.bmx:252
msgid "&About"
msgstr "Über"

#: ../../codegenbase.bmx:254
msgid "&Help"
msgstr "Hilfe"

#: ../../wxCodeGen.bmx:258
msgid "Are you sure you want to delete? : "
msgstr "Bist du sicher, dass du das löschen willst? :"

#: ../../wxCodeGen.bmx:260
msgid "Delete Project?"
msgstr "Projekt löschen?"

#: ../../wxCodeGen.bmx:297
msgid "You will need to restart wxCodeGen to see the new language."
msgstr "Du musst wxCodeGen neustarten um die neue Sprache zu sehen."

#: ../../wxCodeGen.bmx:298
msgid "Language Changed"
msgstr "Sprache würde geändert"


Just tried it again and it was ok this time, so I guess the previous error meant the repository was being updated while I was checking it out?

EDIT: Actually, can someone recommend a decent SVN client? Tortoise has screwed up my system to the point where renaming a folder takes 5 minutes, so that's going to be uninstalled.

Thanks for the translation, ArtemisX :-)

I've also just added support for drag-and-drop. Drag a .fbp file onto the Listbox of wxCodeGen and it will either add it as a new project, or show the project that matches the dropped file.
The latest commit adds wxFileDropTarget support to wxMax - have a look at wxCodeGen for example usage ;-)

@Gabriel.
TortoiseSVN is usually okay. I tend to use Eclipse for most of my repository control, as that's what I prefer as a cross-platform solution - but it's a tad overkill for SVN-only usage :-)
I think Tortoise, being an explorer service thingme, does watch the filesystem. It especially notes folders under source-control, so if you were to copy an SVN folder, it might be *really* slow...

Well OK, you caught me, I did copy an SVN folder, but it was affecting unrelated folders too. For instance, when I unzipped the lib and include archives ( in a separate downloads folder, off the HD root ) it was taking forever to complete the operation. Anyway, I removed Tortoise and the problem appears to have gone away, so I'll leave it at that for now.

I've looked at the samples, and the prospects for me converting my level editor don't look good. Unfortunately, I use a system almost identical to how WXWidgets uses WXApp for my game engine. That is, my game engine assumes it has full control and uses callbacks for anything else you want to do. So it's not even like I can set up a timer, the game engine isn't made that way.

I saw you had a sample called MainLoop which I guess is a sort of hack to allow people to have a procedural main loop. I don't quite understand how it works though. MainLoop isn't actually passed or referenced anywhere in the code, yet you still call WXApp's run method. So I guess the key here is that you're extending WXAppMain instead of WXApp. Am I right in assuming that MainLoop is called once and once only and that this happens after the init method is finished? Does this sound as though it would be a suitable way to setup my level editor as I've described it? I could call the Run() method of my game engine in this main loop function and then set a gameengine callback to do the other stuff you have in your mainloop method?

@Vertex re: extra static libs requirement.

Can you add a Notice for Windows that libodbc32.a, librpcrt4.a and libwinspool.a have to copy from MinGW\lib to wx.mod\lib\win32 ?


I'm not sure why you needed these? ODBC support is not built into the static libs I've released - unless you are building your own - so there shouldn't be any requirement for it. At least, not on the two Windows versions where I've been testing wxMax :-)

@Gabriel,

I'm using the official command line subversion client from http://subversion.tigris.org/ . Actually it's easy to use, you just have to go down into the command line.

@Brucey,
no problem - I'm glad I can help a little bit with your great work.

Edit: my mistake.

Latest wishes :-)

wxRichTextCtrl
wxProcess
wxExecute
wxHelpcontroller

wxRichTextCtrl is a big job, so don't expect that one too soon, at least not with full functionality.

wxProcess and wxExecute are a pair, so I guess they'll be done together, and aren't too heavy - although it might take a while to get them "just right".

I should probably give wxScintilla some more attention before I leap into wxRichTextCtrl (and wxSheet for that matter!).

After wxRichTextCtrl there can't be many more controls left to do... ?

Hmm, looks interesting, i'll try it out.

Though i'm not sure how to get all those .mod files into the directory, without downloading each one seperately.

another question, would we put all those .mod files into wx.mod? or keep them seperate?

Is there a zip file somewhere?

No, there is no zip because Brucey is working on it all day long and creating a zip would take too much time I think.

But if you want it I can write a little tutorial on how to get wx-mod running on windows (I thinks it's not different on linux or mac).

EDIT:
@Brucey,
yeah I'd appreciate it if you would take a closer look to wxScintilla.

@ ArtemisX: Would be much appriciated.

Since I updated wx.mod on monday, I can´t compile
wxcodegen.bmx

Compile Error: Unable to convert from 'wxGridSizer' to 'wx.wxwindow.wxFlexGridSizer'
Build Error: failed to compile C:/Programme/BlitzMax/mod/wx.mod/tools/wxcodegen/codegenbase.bmx

This is the line in codegenbase.bmx
fgSizer1 = new wxFlexGridSizer.CreateRC(4, 2, 0, 0)

@Volker, The latest code is okay. You should update again and Build Modules - there have been a lot of commits lately. I've just tried a "clean" build, and there were no problems here.

I do try to ensure that the code is build-able at all times, but I miss things occasionally... :-p


The latest wxCodeGen enables automatic generation of code when you save the wxFormBuilder project (essentially, it is simply checking the cached modified-time against the current timestamp). This means you don't need to press Generate as often.
Enable it by checking "Check for Project File Updates" on the Preferences page, and then "Auto-Generate Code on Update" for each project you want to auto-generate.

Oh, I didn´t rebuild modules. Works fine now.

But for what is the Application Code - Window in wxCodeGen?
Is it under construction or did you just use a white font :-) ?

But for what is the Application Code

It is intended to provide a base wxApp-style code that you might use as a framework to implement the generated code. Not started, as yet.
Perhaps it is not even required....

Getting wxMax running on Windows XP

1. Get the latest BlitzMax-Version
If you don't have 1.28 then get it.

2. Getting MinGW to build wxMax
For this please use Marks little tutorial which can be found here.

3. Getting Subversion to get wxMax
Download the Subversion commandline client from here - it's svn-1.4.5-setup.exe - and install it.

4. Getting wxMax via Subversion
Open the command line interpreter (cmd.exe) and got to your BlitzMax-Installation folder an then into the folder mod. Then type svn checkout http://wxmax.googlecode.com/svn/trunk/wx.mod/ and wait until Subversion is finished.

5. Getting the required libs and headers
Go to http://code.google.com/p/wxmax/downloads/list and download wxwidgets_2.8.7_headers.zip and wxwidgets_2.8.7_static_win32b.zip.
Unzip the headers in wx.mod/include/ and the libraries (static_win32b) in wx.mod/lib/.

6. Building wxMax
Open the command line interpreter again and switch to your BlitzMax folder and then to bin. Then type bmk makemods wx. This will take very long - depending on you machine - maybe a half hour or more.

That's it. Try some sample codes in wx.mod/samples/.

7. Updating wxMax
Open the command line interpreter and got to your BlitzMax-Installation folder an then into the folder mod/wx.mod. Then type svn update and wait until Subversion is finished.

That's great, ArtemisX :-)
Mind if I put that up on the wiki?

No, I think it would help some people.

I've added 7. because I forgot it.

EDIT:
@Brucey:
The code generated by wxCodeGen is not correct everywhere.
The "constructor" of a dialog ist created this way:
Method Create_:LoginDialogBase(parent:wxWindow = Null,id:Int = wxID_ANY, , title:String = "Login", x:Int = -1, y:Int = -1, w:Int = -1, h:Int = -1, style:Int = 0)

First there is a comma too much after wxID_ANY and the style is not correctly taken from the wxFB-Projekt.

When a notebook ist created with the style wxNB_TOP blitzmax says that the const does not exist. Unfortunately wxNB_BOTTOM, wxNB_LEFT and wxNB_RIGHT are missing also.

Otherwise the program works quite well, apart from the fact that some gadgets like wxScintilla are not (yet) supported.

Thanks ArtemisX. Using a code generator does show up gaps in wxMax - which there are still a few outstanding.

I'll look into sorting these out shortly.

:o)

I am passing the styles wxCAPTION|wxCLOSE_BOX|wxMINSIZE_BOX to a create wxFrame, under Leopard all works as expected but using windows I get a window with CAPTION but no close or minimize buttons?

@Nigel, you need to pass wxSYSTEM_MENU as well under windows!

Using wxCodeBuilder the following code is generated:

m_staticText181.SetFont(New wxFont.CreateWithAttribs(8, 74, 90, 90, False, Helvetica))

it should read:
m_staticText181.SetFont(New wxFont.CreateWithAttribs(8, 74, 90, 90, False, "Helvetica"))


can someone please help me figure out why I get this errors?

C:\Program Files\BlitzMax\bin>bmk makemods wx
Compiling:wxglue.cpp
C:/Program Files/BlitzMax/mod/wx.mod/wx.mod/wxglue.cpp: In function `BBString* bbStringFromWxString(const wxString&)':
C:/Program Files/BlitzMax/mod/wx.mod/wx.mod/wxglue.cpp:54: error: invalid conversion from `const wchar_t*' to `const BBChar*'
C:/Program Files/BlitzMax/mod/wx.mod/wx.mod/wxglue.cpp: In function `BBString* bmx_wxkeyevent_getunicodekey(wxKeyEvent&)':
C:/Program Files/BlitzMax/mod/wx.mod/wx.mod/wxglue.cpp:1069: error: 'class wxKeyEvent' has no member named 'GetUnicodeKey'
Build Error: failed to compile C:/Program Files/BlitzMax/mod/wx.mod/wx.mod/wxglue.cpp

I just started messing with it but I can get it to build modules. I thought I followed artemisX instructions correctly but I get this errors.

It looks like you don't have UNICODE? What version of Windows are you on?

windows xp sp2

Just to answer my own question, yes, MainLoop is called once and only once and it does appear that I can use the aforementioned callback system to work with WXWidgets, so long as I can insert the relevant message queue stuff into the callback. Still not sure if everything will work, but it is looking as though there is a chance.

I managed to fix the problem I just change wxUSE_UNICODE from 0 to 1
in the file setup.h
#ifndef wxUSE_UNICODE
    #define wxUSE_UNICODE 1
#endif


but now I get this error:
C:/Program Files/BlitzMax/mod/wx.mod/wxscintilla.mod/src/PlatWX.cpp: In member f
unction `virtual void SurfaceImpl::DrawTextNoClip(PRectangle, Font&, int, const
char*, int, ColourAllocated, ColourAllocated)':
C:/Program Files/BlitzMax/mod/wx.mod/wxscintilla.mod/src/PlatWX.cpp:437: error:
'class Font' has no member named 'ascent'
C:/Program Files/BlitzMax/mod/wx.mod/wxscintilla.mod/src/PlatWX.cpp: In member f
unction `virtual void SurfaceImpl::DrawTextClipped(PRectangle, Font&, int, const
 char*, int, ColourAllocated, ColourAllocated)':
C:/Program Files/BlitzMax/mod/wx.mod/wxscintilla.mod/src/PlatWX.cpp:450: error:
'class Font' has no member named 'ascent'
C:/Program Files/BlitzMax/mod/wx.mod/wxscintilla.mod/src/PlatWX.cpp: In member f
unction `virtual void SurfaceImpl::DrawTextTransparent(PRectangle, Font&, int, c
onst char*, int, ColourAllocated)':
C:/Program Files/BlitzMax/mod/wx.mod/wxscintilla.mod/src/PlatWX.cpp:465: error:
'class Font' has no member named 'ascent'
C:/Program Files/BlitzMax/mod/wx.mod/wxscintilla.mod/src/PlatWX.cpp: In member f
unction `virtual int SurfaceImpl::Ascent(Font&)':
C:/Program Files/BlitzMax/mod/wx.mod/wxscintilla.mod/src/PlatWX.cpp:574: error:
'class Font' has no member named 'ascent'
C:/Program Files/BlitzMax/mod/wx.mod/wxscintilla.mod/src/PlatWX.cpp:575: error:
'class Font' has no member named 'ascent'
Build Error: failed to compile C:/Program Files/BlitzMax/mod/wx.mod/wxscintilla.
mod/src/PlatWX.cpp

any help appreciated.

How would I go about recreating a MaxGUI window within a window for third party 3D engines to use? In MaxGUI, I create a canvas parented to the main window and pass the HWND. In WXWidgets, I create a WXWindow, parented to the main frame, but the 3D window fills up the entire frame, not just the window. So either I'm getting back the wrong Hwnd or my window is being resized or something.

EDIT: I can confirm that the window is definitely being resized and moved when TV uses it. Now a MaxGUI Canvas does not get resized or moved, so clearly this is a GUI thing, not a TV thing. How can I get a WXWindow to behave like a canvas in respect of not moving and not being resized?

Hi!

I program on a configuration tool. There is a main window and a I click on Menu -> Trial -> Test audio settings should open a new window with a textbox provide as a log.

The problem is, the entries of this log need many seconds like:
"Open audio output driver: OK"
"Make context current: OK"
"Load Test1.wav: OK"
"Play Test1.wav: OK"
"Load Test2.ogg: OK"
"Play Test2.ogg: OK"

And the test audio files need some seconds to play. But in this time I dont know, how I can update the GUI. Today I must wait until all audio files played and than I can show the log.

Is there an alternative to multithreading?

cu olli