Compiling wxWidgets for 10.4?

wadesworld

Mac Developer
OK, so you do have the libraries linking. Good. Now that we know that, we need to determine:

1) Is wxWindowBase::RegisterHotKey(int, int, int) just in a library that you're not linking? This seems unlikely, because it looks like you're linking to all of them.

2) Is wxWindowBase::RegisterHotKey(int, int, int) not being compiled into the library for some reason? This is the tough part - you have to figure out if the wrong header is being included, if the library maintainer perhaps accidentally left it #ifdef'ed out, etc.

Go to /usr/local/lib and run the following command:

nm libwx* | grep RegisterHotKey

and post the output here. That will show us if it is defined in any libraries.

Wade
 

Kinniken

Registered
All your command returned was:

cdejacqu-rob-0:/usr/local/lib cedricdj$ nm libwx* | grep RegisterHotKey
nm: no name list
nm: no name list
nm: no name list
nm: no name list
nm: no name list
nm: no name list

However, it gave me the idea to try and search the wxMac directory for RegisterHotKey. It turned out that while it was implemented, the definition was simply "return false", with a comment stating that this function still had to be written. Since it was apparently useless (on mac at least) and since I don't need it, I commented it out in both the .cpp and the .h files and recompiled and reinstalled the libraries... and it works :D

All my thanks to you and Viro, I would never have managed it without your help.
 

Viro

Registered
It's very strange that you had to do that. What version of wxWidgets are you using, and what were your _entire_ configure flags? I didn't have to do any of that when I compiled my version of wxWidgets.
 

Kinniken

Registered
I agree that it makes little senses, especially since command-line compilation worked fine without it...

I'm using 2.6.0, and my configure command was : ../configure --disable-webkit --disable-shared
 

Kinniken

Registered
Quick question, now that I have started using it: how do I convert an int to wxString, in order to display it? All my (windows-based) teacher could suggest was itoa(), but it's a non ANSI-function which apparently does not exist in the stdlib Xcode uses...
 

Viro

Registered
You've got quite a few options there. The C++ way would be to use a stringstream.

Code:
#include <sstream>
using namespace std;

//.... somewhere in your code
stringstream s;
s<< myInt;

wxString myString;
myString = s.str().c_str();
You might be able to make the code shorter, but this is just me coding when I've just woken up :).

The C way of doing it would be to use sprintf(or the safer snprintf). I dislike this method since it is possible to cause buffer overruns. They are used just like the normal printf except the string isnt printed to stdout, rather it's put in an array of characters of your choice.
 

Kinniken

Registered
Thanks, that worked :)

Next question ;) :

How do I get a method to trigger when the window is resized? (preferably "live")

I tried overloading the OnSize() method of my frame, but it never triggers...
 

Viro

Registered
I don't know what you have, but did you declare an event table? This is very similar to MFC's DECLARE_MESSAGE_MAP macro.

At the start of your .cpp implementing the methods of you class you need the following
Code:
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_SIZE(MyFrame::OnSize)
END_EVENT_TABLE()
wxWidgets suffers from the same kludges that MFC suffers from. The functions are implemented using message maps, instead of the traditional inheritance hierarchy that most Object Oriented libraries use. This was done on the pretext of efficiency back in the days when C++ compilers were inefficient and every single byte counted.

Hence, overriding wxFrame::OnSize() isn't enough. You need to declare that you have overriden it, and map the resize event to MyFrame::OnSize(). Horribly contorted if you ask me.
 

Kinniken

Registered
Well guessed Viro, that was my problem. Fixed! :D

Now I can simulate anchor-based resizing behaviour instead of that sizer-based abomination. And I agree with you that this message map is ugly and unnecessary.

As much as I appreciate being able to code the GUI on OS X and port it to Windows with only a recompile (well, in theory at least...), I do find wxWidgets rather clumsy. It reminds me of AWT or NetBeans.
 

Viro

Registered
It's a real pity that wxWidgets is so contorted. I like the fact that it uses native widgets and the licensing isn't GPL (rather it's LGPL). This is an advantage compared to Qt.

But these days, I seem to like Qt better just because the API is cleaner. But then you have got moc. And the license is GPL unless you pay $1500 for a commercial license.

Can't beat them all I guess :D.
 

Kinniken

Registered
Yeah, Qt would be useless for me for those license reasons - I can't afford $1500 for a commercial one... Anyway, for the moment it's not like I have a choice: my assignment requires using wxWidgets. For that matter, technically it requires using MS Visual Studio, but since I can port it back when I'm done that's no biggy.

Anyway, I have an other small problem... I can't seem to get the ids of selected rows in a wxGrid component... consider:

void MyFrame::GridSelChange() {

cout<<"1"<<endl;

wxArrayInt ai;
int id;
ai=grEtudiants->GetSelectedRows();

if (!ai.IsEmpty()) {
cout<<"2"<<endl;
}
}
The cout<<2 never triggers, even when I have several rows selected (the cout<<1 triggers fine) (I have selection mode set to rows only).

Any idea what I could be doing wrong? :confused:
 

Viro

Registered
No idea :D. That looks like it should work. Did you try it out on Windows to see if the problem is only with the Mac port (quite possible)?
 

Kinniken

Registered
No, I would have to go to university for that. I might this afternoon.

Hmm, looking more closely, it seems there are two "selection" levels - one when rows get an aqua background and one when a cell gets a thick black border.
Possibly because I have cell editing disabled, all I can do is the "aqua" select, when I click on a row. Cell 0,0 has the black border when the grid is created, and I can't move it anywhere else.
Could this be the problem? Is a "selection" for wxWidgets the aqua background or the black border?
 

Kinniken

Registered
I'm totally at a loss on this problem... Here is what it looks like:



Notice the odd black outline on cell (0,0), which is there when the grid is created and is impossible to move or make disappear. The selected row is never taken into account, nowhere - IsInSelection() called on one of its cell always return false, for exemple.
The oddest part is that if I select a row from the code, using SelectRow(), the row appears selected in the window exactly as if the user has clicked on it, but this time it is recognised as being selected by wxWidgets!
I haven't had time to try it on PC, but I will. I badly need to get it to work though, handling data displayed in lists is central to my project...

Oh, and an other anomaly: when live cell editing is enabled, it works - but only for cell(0,0), the one in the black outline. Double-clicking on anyone of the others fail.

If it turns out that wxGrid is broken on mac, I'm in trouble. Sight.
 

Viro

Registered
Try running your wxGrid sample that comes with wxWidgets to see if you have the same problem. I don't use the grid widget, and am not familiar with it.

Also, 2.6.1 was released recently, but there is no mention of any bugs with wxGrid.
 

Kinniken

Registered
And as usual, the insight comes ten minutes after acknowledging defeat: my override of the SelChange() event is preventing the triggering of parts of the wx code devoted to sel change... I switch my event to an other trigger and the first "miracle" happens: the black outline now moves to the cell clicked (on top of the row being highlighted), and a call to IsInSelection() on the cell returns true.

However and a few more tests later, I have to say wxGrid's way of handling selection is one of the most warped things I've ever seen. First, there's this thing of having two "selections", à la Excel: the black outline which is only present on a cell at a time and the aqua background which can be present on any number of cells. When the selection mode is set to "rows only", the black outline does not disappear as it should, but clicking on a cell colours the row in aqua on top of moving the outline to the cell in question. Weird.

Far weirder than that though is the fact that a row highlighted in aqua like that does not count as "selected"... The only way I've found to mark a row as selected from the UI is to click on its header.

Anyway, I can sort my way out of this mess now... all I need to do is:
- trigger the wxGrid SelChange() event inside my overloaded one
- write a custom selectedRow() function using the black outline and not the aqua background, via the IsInSelection() method

Speak of kludges...

Oh, concerning step one, I have to admit I forgot how you call a parent's function when overloading it in a child class (apart from constructors)... Do you remember?
 

Kinniken

Registered
Viro said:
Try running your wxGrid sample that comes with wxWidgets to see if you have the same problem. I don't use the grid widget, and am not familiar with it.
Which one would that be?
 

Kinniken

Registered
erratum: all the cells highlighted in aqua return true to IsInSelection(). It's just that they are not in SelectedRows().
 

Kinniken

Registered
This thing is even weirder than I thought. Even when using .Skip(), the method supposed to ensure that the normal event behaviour is executed, every wxGrid methods to detect selections fails.

However, someone pointed out an obvious workaround to me: the event passed in parameter has a GetRow() method which surprisingly enough works fine. Problem solved, at last.

Next question ;) :

Is there a way to tie events to controls without defining subclasses? IE, to have different methods execute when the user click on different buttons without having to declare a new class for every single one of them? It would be very useful...
 
Top