I’m displaying an AlertWindow in my plugin to allow the user to name a preset and I’d like the text in the TextEditor to be highlighted/selected when the AlertWindow opens to make it easier for the user.
I’m doing this:
AlertWindow w ("Save preset as...", "", AlertWindow::NoIcon, this);
w.addTextEditor ("presetName", "Untitled", "Preset Name");
w.addButton ("Cancel", 0, KeyPress (KeyPress::escapeKey, 0, 0));
w.addButton ("OK", 1, KeyPress (KeyPress::returnKey, 0, 0));
// this does nothing...
TextEditor* te = w.getTextEditor("presetName");
Range<int>r(0, 8);
te->setHighlightedRegion(r);
if (w.runModalLoop() != 0) // is they picked 'ok'
{
const int index = w.getComboBoxComponent ("list")->getSelectedItemIndex();
String newName = w.getTextEditorContents ("presetName");
printf("saveAs: %d - %s\n", index, newName.toRawUTF8());
// do the actual save
}
Nothing I do highlights the text. What am I missing?
Looks like this is a timing issue where the AlertWindow is running before it is repainted with the highlighted text. I’ll take a look at this but a way around it for the time being is to set up your AlertWindow and its TextEditor somewhere else like the constructor of the parent class before the code to run the modal loop is called. Alternatively, you could delay the runModalLoop() call by a small amount using a timer.
Then follow Ed’s advice and make the AlertWindow a class object and initialize it in your class constructor so it’s ready to go when you call runModalLoop(). The only thing you’ll have to adjust is the persistence of the TextEditor text between uses.
BTW - You shouldn’t use any modal windows in a plug-in. Rather create a new Component which covers your complete plugin UI then put a custom Component on that.
Whoa… I made the somewhat horrible assumption that because it’s in Juce, using an AlertWindow would be ok. It would be nice if the documentation explained this.
And why wouldn’t there be a plugin safe AlertWindow class?
/** Runs a component modally, waiting until the loop terminates.
This method first makes the component visible, brings it to the front and
gives it the keyboard focus.
It then runs a loop, dispatching messages from the system message queue, but
blocking all mouse or keyboard messages from reaching any components other
than this one and its children.
This loop continues until the component's exitModalState() method is called (or
the component is deleted), and then this method returns, returning the value
passed into exitModalState().
Note that you SHOULD NEVER USE THIS METHOD! Modal loops are a dangerous construct
because things that happen during the events that they dispatch could affect the
state of objects which are currently in use somewhere on the stack, so when the
loop finishes and the stack unwinds, horrible problems can occur. This is especially
bad in plugins, where the host may choose to delete the plugin during runModalLoop(),
so that when it returns, the entire DLL could have been unloaded from memory!
Also, some OSes deliberately make it impossible to run modal loops (e.g. Android),
so this method won't even exist on some platforms.
@see enterModalState, exitModalState, isCurrentlyModal, getCurrentlyModalComponent,
isCurrentlyBlockedByAnotherModalComponent, ModalComponentManager
*/
int runModalLoop();