How can I dynamically re-create a wxMenu (sub menu) with a variable number of items? - c++

I want to create a list of COM ports in a sub menu that is updated every time the sub menu is viewed.
My plan:
Create a list of objects with data about each detected port, up to 32 object pointers. Example: comDetected *COMsFound[MAX_COM_DETECT]; (working)
Delete() old menu entries (working)
Create a new menu upon EVT_MENU_OPEN() with AppendRadioItem() (working)
Use EVT_MENU() to run the same function for each COM port selection
How do I determine in the event handling function (from wxCommandEvent?) which menu option caused the event? Without this information, I will need 32 separate functions.
Is there a more dynamic way to create the objects and events to avoid the arbitrary limit of 32 I have created?
Edit - This is what I have now for menu re-creation, which seems to be working:
Re-edit - not so good, as explained by bogdan
void FiltgenFrame::OnMenuOpen(wxMenuEvent& event)
{
//fill in COM port menu when opened
if(event.GetMenu() == COMSubMenu)
{
int i;
wxString comhelp;
//re-scan ports
comport->getPorts();
if(comport->COMdetectChanged == 1)
{
comport->currentCOMselection = 0; //when menu is regenerated, selection returns to 0
//get rid of old menu entries
for(i = 0; i < comport->oldnumCOMsFound; i++)
{
COMSubMenu->Delete(FILTGEN_COM1 + i);
COMSubMenu->Unbind(wxEVT_MENU, [i](wxCommandEvent&)
{
logMsg(DBG_MENUS, ACT_NORMAL, "menu COM select index: %d\n", i);
}, FILTGEN_COM1 + i);
}
//add new menu entries
for(i = 0; i < comport->numCOMsFound; i++)
{
comhelp.Printf("Use %s", comport->COMsFound[i]->name);
COMSubMenu->AppendRadioItem(FILTGEN_COM1 + i, comport->COMsFound[i]->name, comhelp);
COMSubMenu->Bind(wxEVT_MENU, [i](wxCommandEvent&)
{
comport->currentCOMselection = i;
logMsg(DBG_MENUS, ACT_NORMAL, "menu COM select index: %d\n", i);
}, FILTGEN_COM1 + i);
}
}
}
}
Edit - re-worked code 1-29-15. Broke apart OnMenuOpen and recreateCOMmenu due to factors unrelated to this question. Added COMselectionHandler because of advice.
void FiltgenFrame::COMselectionHandler(wxCommandEvent& event)
{
comport->currentCOMselection = event.GetId() - FILTGEN_COM1;
logMsg(DBG_MENUS, ACT_NORMAL, "COM menu select index: %d\n", comport->currentCOMselection);
}
void FiltgenFrame::recreateCOMmenu()
{
logMsg(DBG_MENUS, ACT_NORMAL, "FiltgenFrame::recreateCOMmenu():\n");
int i;
wxString comhelp;
//re-scan ports
comport->getPorts();
if(comport->COMdetectChanged == 1)
{
comport->currentCOMselection = 0; //when menu is regenerated, selection returns to 0
//get rid of old menu entries
for(i = 0; i < comport->oldnumCOMsFound; i++)
{
COMSubMenu->Delete(FILTGEN_COM1 + i);
COMSubMenu->Unbind(wxEVT_MENU, &FiltgenFrame::COMselectionHandler, this, FILTGEN_COM1 + i);
}
//add new menu entries
for(i = 0; i < comport->numCOMsFound; i++)
{
comhelp.Printf("Use %s", comport->COMsFound[i]->name);
COMSubMenu->AppendRadioItem(FILTGEN_COM1 + i, comport->COMsFound[i]->name, comhelp);
COMSubMenu->Bind(wxEVT_MENU, &FiltgenFrame::COMselectionHandler, this, FILTGEN_COM1 + i);
}
}
}
void FiltgenFrame::OnMenuOpen(wxMenuEvent& event)
{
//fill in COM port menu when opened
if(event.GetMenu() == COMSubMenu)
{
recreateCOMmenu();
}
}

Since dynamic seems to be the key word here, I would go for dynamic event handling (actually, I always go for dynamic event handling using Bind, it's so much nicer than the alternatives):
auto pm = new wxMenu(); //I suppose you're adding this to an existing menu.
std::wstring port_str = L"COM";
int id_base = 77; //However you want to set up the IDs of the menu entries.
for(int port_num = 1; port_num <= 32; ++port_num)
{
int id = id_base + port_num;
pm->AppendRadioItem(id, port_str + std::to_wstring(port_num));
pm->Bind(wxEVT_MENU, [port_num](wxCommandEvent&)
{
//Do something with the current port_num; for example:
wxMessageBox(std::to_wstring(port_num));
//You can also capture id if you prefer, of course.
}, id);
}
In the lambda expression, we capture the port number by value, so, for each iteration, the current port_num will be captured. This achieves exactly what you asked for: the same function (the operator() of the lambda's closure type) associated with each menu entry. The function knows the entry for which it was called because it has access to the captured port_num value, stored in the lambda's closure object - a small object, most likely the size of one int in this case.
To avoid a fixed limit on the number of objects, you can simply store them in a std::vector. If you want the vector to own the objects (have them destroyed automatically when the vector is destroyed), then you can store them directly in a std::vector<comDetected>. If something else owns the objects and takes care of destroying them separately, you could use std::vector<comDetected*>.
UPDATE: When writing my first solution, I didn't realize you'll want to Unbind and re-bind those event handlers; pretty obvious in hindsight, really, but... anyway, my mistake, sorry.
Here's the problem: as far as I can tell, there's no straightforward way to Unbind a lambda function object that was passed directly to Bind as I did in my example. Simply calling Unbind as you're doing in your updated code isn't going to work, because that Unbind will try to find an event handler that was installed by a corresponding call to Bind with the exact same arguments. That won't happen for the reasons explained in the next section (there's also an explanation for why it seems to work), but you might be more interested in solutions, so I'll start with those.
Solution 1 (the best one in your case): Forgo using lambdas; just use either a free function or a member function pointer. In this case, you'll need to get the menu entry ID from evt.GetId() and get the port index from it; something like this:
void handler_func(wxCommandEvent& evt)
{
int i = evt.GetId() - FILTGEN_COM1;
comport->currentCOMselection = i;
logMsg(DBG_MENUS, ACT_NORMAL, "menu COM select index: %d\n", i);
}
Then, your code would look like this:
void FiltgenFrame::OnMenuOpen(wxMenuEvent& event)
{
/* ... */
COMSubMenu->Unbind(wxEVT_MENU, handler_func, FILTGEN_COM1 + i);
/* ... */
COMSubMenu->Bind(wxEVT_MENU, handler_func, FILTGEN_COM1 + i);
/* ... */
}
The example above is using a free function. You can also use a member function - more info here.
Solution 2: In case you can rebuild that menu at some other time than EVT_MENU_OPEN(), you could go for destroying the whole wxMenu and rebuilding and inserting it into its parent menu in the right place. Destroying the old menu object will take care of all the dynamic event handlers bound to it, so you don't need to Unbind them. However, destroying the menu just before it's displayed doesn't sound like a good idea - I haven't tried it, but as far as I can tell it won't work, or behave in highly platform-dependent ways.
Here are the reasons for which Unbind won't work directly with lambdas:
The object generated by a lambda expression has a unique type. Even if you copy-paste the exact same lambda expression to another place in your code, that second lambda will generate a closure object of a type different from the one generated by the original lambda. Since Unbind checks the type of the functor argument against the types of the installed handlers, it will never find a match.
Even if we got around the problem above, there's another one: the function object passed to Unbind also needs to have the same address as the one passed to the corresponding Bind. The object generated when the lambda expression is passed directly to Bind is a temporary (it will typically be allocated on the stack), so making any assumptions about its address across function calls is just incorrect.
We can get around the two problems above (store the closure objects separately somewhere and so on), but I think any such solution is far too cumbersome to be worth considering - it will negate all the advantages of the lambda-based solution.
Here's why it seems to work in your code:
If Unbind doesn't find an event handler to remove, it just returns false; all existing handlers remain in there. Later on, Bind adds a new handler for the same event type and same entry ID at the front of the event handler list, so newer handlers are called first. Unless a handler calls evt.Skip() before returning, the event is considered handled after the handler returns and no other handlers are called.
Even though it sort of works as you expect, letting all those old unused handlers accumulate in the list every time the menu is rebuilt isn't a good idea, obviously.

Related

I want return type pointer but i want my function to return pointer of derive class

Dragon* Dragon::spawn() {
int x = rand() % 5;
int y;
if (!if_locked(x)) //is a function to see if that id is unlocked because i want some dragon to be generated only if you have certain xp so it will call func again until unlocked id is generated
spawn();
else
y = unlocking(m); // Y is generated form 1-5, I have assigned Id to each derive class whosoever id matches Y that pointer will be returned
if (y == 1) {
GroundDragon* pt;
return pt;
}
if (y == 2) {
WaterDragon* st;
return st;
}
if (y == 3) {
IceDragon*bt;
return bt;
}
if (y == 4) {
FireDragon* ct;
return ct;
}
if (y == 5) {
DarkDragon* dark;
return dark;
}
}
As you can see im making syntax mistakes i hope someone can guide me
The return type of function is base class and all the classes in if statement are derive class
so i can later use this function
template<class T>
void spawner(T*) {// I will spawn() fucntion as perimeter at time of call
T = new T;
}
Forgive me if im repaeting question the last time i post it didnt get attention i was expecting so i modifed my code a bit hopeful it is clear now`
int Dragon::unlocking(Mage m) {
if (m.getxp() <= 50 and m.getxp() <= 100) {
unlock[0] = 1;
cout << "Congratulation GroundDragon unlocked " << endl;
return 1;
}
if (m.getxp() > 100 and m.getxp() < 150) {
unlock[1] = 1;
cout << "Congratulation WaterDragon unlocked " << endl;
return 2;
}
if (m.getxp() > 150 and m.getxp() < 175) {
unlock[2] = 1;
cout << "Congratulation IceDragon unlocked " << endl;
return 3;
}
if (m.getxp() > 175 and m.getxp() < 500) {
unlock[3] = 1;
cout << "Congratulation FireDragon unlocked " << endl;
return 4;
}
if (m.getxp() > 500) {
unlock[4] = 1;
cout << "Congratulation DarkDragon unlocked " << endl;
return 5;
}
}
bool Dragon::if_locked(int x) {
if (unlock[x] == 1) {
return true;
}
else
return false;
}
*Im not comfortable with smartpointer(i have never used them before but i would love to use them if you show me how to call it main *
I used raw pointer but it is still showing me errors please help mw
The idea is sound, it's just the execution that failed.
If you want to have a factory function that will return different objects that will then behave polymorphically, this is perfectly fine, with one important thing - you need to return actual objects.
Your factory function has a return type of Dragon*. This means that whatever value you return, it will be a pointer pointing to (some sort of a) Dragon. However, the value of that pointer can point to an object that is actually an instace of FireDragon, IceDragon etc. When you create an instance of such an object, the pointer to such instance can then get converted to the appropriate return type and returned.
In your case though, while you're creating temporary objects of type pointer-to-some-sort-of-dragon, you're not actually filling them with instances. They all are created with an unspecified value, and that value is then converted to an unspecified value of type Dragon*, with no way to extract the information which type it was converted from.
So, in order to make it work in a usual fashion, we just need to create a new instance of appropriate type and return it. We don't ever want to return raw pointers from functions when transferring ownership, so std::unique_ptr is a much better alternative:
std::unique_ptr<Dragon> Dragon::spawn() {
int x = rand() % 5;
/* note - this bit of code doesn't make any sense whatsoever
int y;
if (!if_locked(x)) //is a different function
spawn();
else
y = unlocking(m); //is also a different function
*/
// note that `rand() % 5` will produce values 0 through 4.
switch(x) {
case 0: return std::make_unique<GroundDragon>();
case 1: return std::make_unique<WaterDragon>();
case 2: return std::make_unique<IceDragon>();
case 3: return std::make_unique<FireDragon>();
case 4: return std::make_unique<DarkDragon>();
}
}
Now you don't need the spawner function at all; you can directly use the returned value.
I think the first important lesson to give is about initializing pointers.
The line
GroundDragon* pt;
declares that there is a pointer to a GroundDragon object, so far so good. However, this does not create an object.
As an analogy: you created a direction sign that is able to point into the direction of a village, but you do not build an actual village for it to point towards. And right now, it just points into some random direction.
Being uninitialized, pt contains a random value, not the address of an existing object of type GroundDragon. Doing anything with it will most likely result in bad things (it is undefined behaviour in particular).
In order to initialize it, you would write it like
GroundDragon* pt = new GroundDragon;
This creates an objects of type GroundDragon on the heap and assigns it's address to pt.
Also note that every new needs a delete to keep the memory clean, just to mention this preemptively.
This is very essential knowledge - make sure to understand this.
I wanted to write this in order to show you how to work with raw pointers, as an addition to the answer of Bartek Banachewicz, who did not show the way to initialize raw pointers. What he then does, using smart pointers, is clearly a way better approach than using raw pointers, though. However, I'd say that it is quite important that you are also able to work with raw pointers. Make sure to be able to do both in the long run, and use smart pointers whenever you can.
Edit: Now for the other part of your code,
int x = rand() % 5;
int y;
if (!if_locked(x)) //is a function to see if that id is unlocked because i want some dragon to be generated only if you have certain xp so it will call func again until unlocked id is generated
spawn();
else
y = unlocking(m);
First of all, please be aware that calling spawn(); ignores the return value. Which means, it has no effect at all. What you probably wanted to write is return spawn();.
Second, if(!if_locked(x)) seems to me to be the contrary of what it should be. "if not locked" means "if unlocked", and in that case, it should not try it again but instead proceed, right?
And, is the Mage m that you give to unlocking a member of Dragon? Sounds like it rather should be a pointer, if you don't especially want a relationship like Dragon owns Mage.
In any case, I would keep unlocking out of spawn. A method like spawn says that it is good for spawning. Especially printing that something is unlocked is not something I would intuitively understand a part of the spawning process. Also, I would name it differently, as "unlocking" is a status rather than a command. Go like check_for_new_unlocks or something like that, which sounds like a command. And do it separately from spawn.
Also, note that you check for narrow experience intervals - are you sure that it can't happen that an interval is never triggered, as the character might advance over the interval with never calling the method in between?
Furthermore, I'd call the array that says if something is unlocked differently. "unlock" sounds like a command. How about "available"?
Also, I find the recursive call of spawn to be less readable as trying out other values for x, but that is opinion. I'd go like
int x = rand() % 5;
while(not available[x])
{
x = rand() % 5;
}
Maybe this can be done more clever, though, based on the actual mechanics. You could create the random variable like int x = rand() % total_available(); for instance.
Note that a lot of this is somewhat opinion based. In this regard, I want to point you towards CodeReview - as soon as your code works correctly, you might want to post it there for people to help you improve it in several different regards.

When creating threads using lambda expressions, how to give each thread its own copy of the lambda expression?

I have been working on a program that basically used brute force to work backward to find a method using a given set of operations to reach the given number. So, for example, if I gave in a set of operations +5,-7,*10,/3, and a given number say 100(*this example probably won't come up with a solution), and also a given max amount of moves to solve (let's say 8), it will attempt to come up with a use of these operations to get to 100. This part works using a single thread which I have tested in an application.
However, I wanted it to be faster and I came to multithreading. I have worked a long time to even get the lambda function to work, and after some serious debugging have realized that the solution "combo" is technically found. However, before it is tested, it is changed. I wasn't sure how this was possible considering the fact that I had thought that each thread was given its own copy of the lambda function and its variables to use.
In summary, the program starts off by parsing the information, then passes the information which is divided by the parser as paramaters into the array of an operation object(somewhat of a functor). It then uses an algorithm which generated combinations which are then executed by the operation objects. The algorithm, in simplicity, takes in the amount of operations, assigns it to a char value(each char value corresponds to an operation), then outputs a char value. It generates all possible combinations.
That is a summary of how my program works. Everything seems to be working fine and in order other than two things. There is another error which I have not added to the title because there is a way to fix it, but I am curious about alternatives. This way is also probably not good for my computer.
So, going back to the problem with the lambda expression inputted with the thread as seen is with what I saw using breakpoints in the debugger. It appeared that both threads were not generating individual combos, but more rather properly switching between the first number, but alternating combos. So, it would go 1111, 2211, rather than generating 1111, 2111.(these are generated as the previous paragraph showed, but they are done a char at a time, combined using a stringstream), but once they got out of the loop that filled the combo up, combos would get lost. It would randomly switch between the two and never test the correct combo because combinations seemed to get scrambled randomly. This I realized must have something to do with race conditions and mutual exclusion. I had thought I had avoided it all by not changing any variables changed from outside the lambda expression, but it appears like both threads are using the same lambda expression.
I want to know why this occurs, and how to make it so that I can say create an array of these expressions and assign each thread its own, or something similar to that which avoids having to deal with mutual exclusion as a whole.
Now, the other problem happens when I at the end delete my array of operation objects. The code which assigns them and the deleting code is shown below.
operation *operations[get<0>(functions)];
for (int i = 0; i < get<0>(functions); i++)
{
//creates a new object for each operation in the array and sets it to the corresponding parameter
operations[i] = new operation(parameterStrings[i]);
}
delete[] operations;
The get<0>(functions) is where the amount of functions is stored in a tuple and is the number of objects to be stored in an array. The paramterStrings is a vector in which the strings used as parameters for the constructor of the class are stored. This code results in an "Exception trace/breakpoint trap." If I use "*operations" instead I get a segmentation fault in the file where the class is defined, the first line where it says "class operation." The alternative is just to comment out the delete part, but I am pretty sure that it would be a bad idea to do so, considering the fact that it is created using the "new" operator and might cause memory leaks.
Below is the code for the lambda expression and where the corresponding code for the creation of threads. I readded code inside the lambda expression so it could be looked into to find possible causes for race conditions.
auto threadLambda = [&](int thread, char *letters, operation **operations, int beginNumber) {
int i, entry[len];
bool successfulComboFound = false;
stringstream output;
int outputNum;
for (i = 0; i < len; i++)
{
entry[i] = 0;
}
do
{
for (i = 0; i < len; i++)
{
if (i == 0)
{
output << beginNumber;
}
char numSelect = *letters + (entry[i]);
output << numSelect;
}
outputNum = stoll(output.str());
if (outputNum == 23513511)
{
cout << "strange";
}
if (outputNum != 0)
{
tuple<int, bool> outputTuple;
int previousValue = initValue;
for (int g = 0; g <= (output.str()).length(); g++)
{
operation *copyOfOperation = (operations[((int)(output.str()[g])) - 49]);
//cout << copyOfOperation->inputtedValue;
outputTuple = (*operations)->doOperation(previousValue);
previousValue = get<0>(outputTuple);
if (get<1>(outputTuple) == false)
{
break;
}
debugCheck[thread - 1] = debugCheck[thread - 1] + 1;
if (previousValue == goalValue)
{
movesToSolve = g + 1;
winCombo = outputNum;
successfulComboFound = true;
break;
}
}
//cout << output.str() << ' ';
}
if (successfulComboFound == true)
{
break;
}
output.str("0");
for (i = 0; i < len && ++entry[i] == nbletters; i++)
entry[i] = 0;
} while (i < len);
if (successfulComboFound == true)
{
comboFoundGlobal = true;
finishedThreads.push_back(true);
}
else
{
finishedThreads.push_back(true);
}
};
Threads created here :
thread *threadArray[numberOfThreads];
for (int f = 0; f < numberOfThreads; f++)
{
threadArray[f] = new thread(threadLambda, f + 1, lettersPointer, operationsPointer, ((int)(workingBeginOperations[f])) - 48);
}
If any more of the code is needed to help solve the problem, please let me know and I will edit the post to add the code. Thanks in advance for all of your help.
Your lambda object captures its arguments by reference [&], so each copy of the lambda used by a thread references the same shared objects, and so various threads race and clobber each other.
This is assuming things like movesToSolve and winCombo come from captures (it is not clear from the code, but it seems like it). winCombo is updated when a successful result is found, but another thread might immediately overwrite it right after.
So every thread is using the same data, data races abound.
You want to ensure that your lambda works only on two three types of data:
Private data
Shared, constant data
Properly synchronized mutable shared data
Generally you want to have almost everything in category 1 and 2, with as little as possible in category 3.
Category 1 is the easiest, since you can use e.g., local variables within the lambda function, or captured-by-value variables if you ensure a different lambda instance is passed to each thread.
For category 2, you can use const to ensure the relevant data isn't modified.
Finally you may need some shared global state, e.g., to indicate that a value is found. One option would be something like a single std::atomic<Result *> where when any thread finds a result, they create a new Result object and atomically compare-and-swap it into the globally visible result pointer. Other threads check this pointer for null in their run loop to see if they should bail out early (I assume that's what you want: for all threads to finish if any thread finds a result).
A more idiomatic way would be to use std::promise.

How to prevent user from entering invalid values in wxGrid cell?

I'd like to create wxGrid where user can edit some cells, but prohibit entering incorrect valued. For example, only strings of length 4 could be entered there. So, if user enter string of another length, I'd like to show a error message and return to cell editor. How to do it?
If I handle a cell change event EVT_GRID_CELL_CHANGE, for example
void Frame::OnGridCellChange(wxGridEvent& event)
{
int r = event.GetRow(); // get changed cell
int c = event.GetCol(); // get changed cell
if (Grid->GetCellValue(r, c).length() != 4)
{Error E (this);
/* Create the Error message */
E.ShowModal();
// The error message shown, uses clicks OK
// So, what to do here?
}
Grid->ShowCellEditControl(); is not a solution because cell change won't be generated if user edit nothing, but just click another cell - incorrect value would appear in Grid.
Handling EVT_GRID_EDITOR_HIDDEN seems not suitable since it appears before new value actually saved to cell.
You need to use your own specialization of the cell editor.
http://docs.wxwidgets.org/trunk/classwx_grid_cell_editor.html
Perhaps using an event of type wxEVT_GRID_CELL_CHANGING would work for you? If the string that is returned by calling GetString() on the event is not four characters long then you can veto the event, something like:
void Frame::OnGridCellChanging(wxGridEvent& event)
{
if (event.GetString().length() != 4)
{
//Veto the event so the change is not stored
event.Veto();
Error E (this);
E.ShowModal();
}
This does seem to require a wxWidgets 2.9.x release however.

Using glutTimerFunc with glutMouseFunc

I am trying to do a little game, and in my game I have some squares and when the user click on these squares, they got highlighted. To achieve this effect I am using glutMouseFunc with glutTimerFunc.
When the user clicks on the screen I pick the pixel and identify the square I need to highlight. Once the square is identified I call glutTimerFunc. The function registred with glutTimerFunc increase the value of each component of color by 0.01 until they reach one max value defined by me, then this value goes back to a minimum value.
glutTimerFunc execute in 60 milliseconds and I get a almost smooth shine effect.
My problem is, if I click on two squares very fast, the effect starts on the first square, but don't finish, so the square remains highlighted and the second squares do the entire effect. If I click like a crazy man on every square, all of them got highlighted.
How can I make this effect of shining terminate even if I click on other square?
Here is a snippet of code
void Memoria::shineEffect(GLint value) {
if(value == 1) {
for(GLint i = 0; i < 3; i++) {
if(colors[selectedSquare][i] > 0) {
colors[selectedSquare][i] += COLOR_INCREASE;
if(colors[selectedSquare][i] >= MAX) {
colors[selectedSquare][i] = MAX;
value = -1;
}
}
}
glutTimerFunc(FPS, timeWrapper, value);
}
else {
if(value == -1) {
for(GLint i = 0; i < 3; i++) {
if(colors[selectedSquare][i] > 0) {
colors[selectedSquare][i] -= COLOR_INCREASE;
if(colors[selectedSquare][i] <= MIN) {
value = 0;
colors[selectedSquare][i] = MIN;
}
}
}
glutTimerFunc(FPS, timeWrapper, value);
}
}
}
timeWrapper calls shineEffect if the value passed in the parameter is 1 or -1.
You want the shineEffect function to go through one highlight loop at least, and then stop if the highlighted item has changed. It's more a UI code design issue rather than an OpenGL or GLUT one.
The mechanic you need to implement is pretty straightforward:
install once for all an updateHighlights function with glutTimerFunc: this function will be responsible of updating the highlights of all the clicked elements,
create a queue of elements: each time an element has been clicked, add it to the queue,
The task performed by the updateHighLights function should be as follow:
if the queue contains one element, keep cycling its highlight as you already do in your program
if the queue contain more than one element, for each element in the queue,
step the highlight cycle
if the cycle is over, and the element is not the last one, remove the element from the queue
Here's another perhaps more flexible take on your problem.
The Glut event loop machinery is very simple design: there's only one hook to put your "idle work" code, so it's probably more flexible to install a function there which calls a list of others functions. That list could be then modified with a set primitive, to install or remove specific tasks to perform during idle time. This could be much more flexible than the "one function" approach of GLUT.
For instance, you could isolate your current highlight code in one function with a struct containing the element to highlight, and have the function remove itself from the list when its element is done through a highlight cycle and isn't active anymore.
Since you are using C++, it should be easy to bundle all these functionalities in classes:
one class for the list of idle tasks
one base class for idle tasks
one derived idle task class for the purpose of highlighting a square (with fields for the square and for the active status)
one class to keep track of the active square, so that it may be easily deactivated and replaced by the new active one. This one would be accessed by the glutMouseFunc function.

How to move an item up and down in a wxListCtrl (wxwidgets)

This should be pretty easy but I'm having a heck of a time doing it. Basically I want to move a row in my wxListCtrl up or down. I posted this to wxwidgets forum and got the following code.
m_list->Freeze();
wxListItem item;
item.SetId(item_id); // the one which is selected
m_list->GetItem(item); // Retrieve the item
m_list->DeleteItem(item_id); // Remove it
item.SetId(item_id - 1); // Move it up
m_list->SetItem(item); // Apply it's new pos in the list
m_list->Thaw();
which doesn't work. The element is deleted but not moved up (I guess the setitem line is not working). Then I thought to just switch the text and the image but I can't even get the text from the row reliably. I have
int index = m_right->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
wxString label = m_right->GetItemText(index);
if(index == 0)
return;
wxListItem item;
item.SetId(index);
bool success = m_right->GetItem(item);
wxString text = item.GetText();
but text is blank even though there is text and the index is correct. So, I'm stuck not even being able to do the most basic task. Anybody know how to do this? The code runs in a button callback (the user presses a little up arrow and my code executes to try to move it). I'm using 2.9.1 on windows.
I made it work like this with wxWidgets 2.9.3 :
void FileSelectionPanel::OnMoveUp( wxCommandEvent& WXUNUSED(evt) )
{
int idx = _listCtrl->GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
if( idx == 0) idx = _listCtrl->GetNextItem( 0, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
_listCtrl->Freeze();
while( idx > -1 ) {
wxListItem item;
item.SetId(idx); _listCtrl->GetItem(item);
item.SetId(idx-1); _listCtrl->InsertItem(item);
_listCtrl->SetItemData( idx-1, _listCtrl->GetItemData( idx+1 ));
for( int i = 0; i < _listCtrl->GetColumnCount(); i++ ) {
_listCtrl->SetItem( idx-1, i, _listCtrl->GetItemText( idx+1, i ));
}
_listCtrl->DeleteItem( idx + 1 );
idx = _listCtrl->GetNextItem( idx-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );
}
_listCtrl->Thaw();
}
The thing I noticed it that wxListItem is more of a convenience struct, for storing state of the view and help pass values into the wxListCtrl "nicely". It is in no way bound to what is actually inside of the wxListCtrl.
Hope this still helps anyone !
Even there is already an answer that is checked. I have the same problem here, but my list is unordered. By looking into wxWidgets' code I found out there is another important information inside the wxListItem object - the mask. I got my reordering to work correctly by setting the mask value to -1, which means that all data shall be copied. This includes the item text as well as other information, like the item data (which was important in my case).
wxListItem item;
item.SetId(item_id); // set needed id
item.SetMask(-1); // set needed data
m_list->GetItem(item); // actually retrieve the item
m_list->DeleteItem(item_id); // remove old copy
item.SetId(item_id - 1); // move item up
m_list->InsertItem(item); // insert copy of item
I also had to use "InsertItem" instead of "SetItem". Otherwise, there was no new item inserted, but an existing one overwritten (see also tomcat31's answer).
Is the list ordered? if it is auto ordering it may be ignoring the order you are trying to apply.
From recollection the internal order was not necessarily sequential, you might have to get the index of the previous item and go one before it.