|
|
Home » U++ Library support » TopWindow&PopUp, TrayIcon » Modal vs non-modal window
|
Re: Modal vs non-modal window [message #11958 is a reply to message #11950] |
Thu, 04 October 2007 13:08 |
mrjt
Messages: 705 Registered: March 2007 Location: London
|
Contributor |
|
|
Hello and welcome!
I assume you've already decided against a seperate class for the window, so what I would do is something like this:
One<AWindow> wnd;
void OpenAWindow() {
if (!wnd) {
wnd = new AWindow();
CtrlLayout(*wnd, "A Window");
wnd->ok <<= THISBACK(AWindowOK);
wnd->WhenClose = wnd->cancel <<= THISBACK(AWindowClose);
//wnd->Open(this);
wnd->OpenMain();
}
else
wnd->TopMost(false, false);
}
void AWindowOK() {
if (wnd->Accept()) {
// Do Something with data
AWindowClose();
}
}
void AWindowClose() { wnd.Clear(); }
(all members of another class)
This allows the window to be displayed non-modally. By changing OpenMain to Open(this) you will get a child window (always above parent). It's possible that Mirek might come along and tell me I've got this wrong though
Also, if you didn't care about memory release after closing (if it's a small app I wouldn't bother), you could just add the line:AWindow &wnd = Single<AWindow>() to all the functions you need to access the window, and remove the member variable.
Hope that helps.
James
edit: Forgot AWindowClose
[Updated on: Thu, 04 October 2007 14:59] Report message to a moderator
|
|
|
|
|
|
Re: Modal vs non-modal window [message #11968 is a reply to message #11964] |
Fri, 05 October 2007 12:09 |
mrjt
Messages: 705 Registered: March 2007 Location: London
|
Contributor |
|
|
There are no stupid questions
There are lots of different ways of handling windows in Upp, and choosing which method to use is dependent on the complexity and type of the window and application as well as personal preference.
Generally I would use seperate classes if the window has more complex behaviour, such as values in one field changing allowable values in others, or Option controls that disbale/enable fields etc. You could do all this from the parent window but it would become untidy and complex, especially if you have lots of them.
If you can make your window a modal dialog (one that blocks other windows) it becomes easier to do more complex windows without a seperate class because it can all be handled in one function. A good example of this that I often use as a reference is void Ide::SetupFormat() in the ide package (ide/Setup.cpp) because it handles quite complex data (look at CtrlRetriever in particular, this might be useful to you) and you can easily compare it to the running version in TheIde.
Once you have non-modal windows it is more difficult becuase you have to seperate the OK button handling, but it really depends on the types of windows you are using. If for instance you have many windows that are just data entry you may be able to simplify the process so that seperate classes are unnecessary by creating a single class that inherits from TopWindow and behaves in a general way. For example, this:
class DataEntryWindow : public TopWindow
{
public:
typedef DataEntryWindow CLASSNAME;
// Sets the table name to update
DataEntryWindow &SetTableRecord(String table, int recordid);
// Links a DB field with a Ctrl
DataEntryWindow &SetDataSource(Ctrl &source, String field, Value intial_value, int datatype);
OnOK() { if (Accept()) { Commit(); OnCancelClose();} }
OnCancelClose() { delete this; }
private:
Commit(); // Builds SQL string using datasources and commits it to DB
};
could form the basis of a data enrty window that can be launched from a single function and then forgotten about:
void NewEmployee()
{
WithEmployeeLayout<DataEntryWindow> *wnd = new WithEmployeeLayout<DataEntryWindow>();
//Set tablename, datasources etc
wnd->Open(this);
}
Note that I've never used Upp for SQL, so I'm not sure how well this would work, but something similar should be possible. You may also be able to do something with Serialize().
Other than all that (I got a bit carried away I think, I really should be doing some work ) you just need to play around, Upp is very versatile once you know what your doing. Reading the source code (both CtrlLib and ide) helps as it was written by very good programmers.
Feel free to ask anything else, answering questions is always good to get the brain working in the morning
James
[Updated on: Fri, 05 October 2007 12:20] Report message to a moderator
|
|
|
|
|
|
Re: Modal vs non-modal window [message #11985 is a reply to message #11968] |
Sat, 06 October 2007 18:07 |
|
mirek
Messages: 13984 Registered: November 2005
|
Ultimate Member |
|
|
mrjt wrote on Fri, 05 October 2007 06:09 |
class DataEntryWindow : public TopWindow
{
public:
typedef DataEntryWindow CLASSNAME;
// Sets the table name to update
DataEntryWindow &SetTableRecord(String table, int recordid);
// Links a DB field with a Ctrl
DataEntryWindow &SetDataSource(Ctrl &source, String field, Value intial_value, int datatype);
OnOK() { if (Accept()) { Commit(); OnCancelClose();} }
OnCancelClose() { delete this; }
private:
Commit(); // Builds SQL string using datasources and commits it to DB
};
could form the basis of a data enrty window that can be launched from a single function and then forgotten about:
void NewEmployee()
{
WithEmployeeLayout<DataEntryWindow> *wnd = new WithEmployeeLayout<DataEntryWindow>();
//Set tablename, datasources etc
wnd->Open(this);
}
|
Not that this is only a good idea if you have unlimited number of peer windows (like in UWord), preferably even main peer windows.
For modeless things, usually it is better to just make those subdialogs a member variables (no pointers); to open and close them as needed, no news and deletes involved. This also has the advantage that the content of dialog is accessible in the containing class, so there is often no need to transfer widget data to variables and back...
Mirek
|
|
|
Re: Modal vs non-modal window [message #12003 is a reply to message #11985] |
Sun, 07 October 2007 18:33 |
NeonN
Messages: 8 Registered: September 2007 Location: Czech Republic
|
Promising Member |
|
|
luzr wrote on Sat, 06 October 2007 17:59 |
Also, Open() picks "last active window" of application as its owner (which usuallly is the right window to use..). That is why there has to be OpenMain (which does not pick anything, makes it the "main" window).
|
Thx, a lot. I was wondering what is the difference between Open() and Open(this) ... now I get it.
luzr wrote on Sat, 06 October 2007 18:07 |
For modeless things, usually it is better to just make those subdialogs a member variables (no pointers); to open and close them as needed, no news and deletes involved. This also has the advantage that the content of dialog is accessible in the containing class, so there is often no need to transfer widget data to variables and back...
|
I read it once before somewhere on this forum... is there any other reason to don't use 'new' for dialogs? If I use 'new', the window doesn't disappear after it's init class-member function is done and the widgets are cleared after closing the window. But I don't know if it's OK to use Ultimate++ this way ...
|
|
|
|
Re: Modal vs non-modal window [message #12009 is a reply to message #12008] |
Sun, 07 October 2007 20:32 |
NeonN
Messages: 8 Registered: September 2007 Location: Czech Republic
|
Promising Member |
|
|
For example:
I have one window with button. The button has assigned callback to function that creates another window...
If I just do this:
void ClassName::InitDialog()
{
WithLayout<TopWindow> laySomething;
CtrlLayoutOKCancel(laySomething, "Something");
laySomething.OpenMain();
}
... the window disappear after the function is over. I'd have to Execute() the window or ... (I don't know... I'm new in C++ and Ultimate++. I'm trying to understand how to work with the window - what is the best method...)
But when I do this:
void ClassName::InitDialog()
{
laySomething = new WithSomethingLayout<TopWindow>;
CtrlLayoutOKCancel(*laySomething, "Something");
laySomething->OpenMain();
}
... the window is still opened. I can do anything with the window because the pointer to it is declared in the private part of class but the memmory is allocated only when I need it. And when I close the window, the widgets are automatically cleared (destroyed).
So that's why i don't understand why is using new/delete less alegant or less easier... and why I shouldn't do this...
[Updated on: Sun, 07 October 2007 20:56] Report message to a moderator
|
|
|
Re: Modal vs non-modal window [message #12010 is a reply to message #12009] |
Sun, 07 October 2007 23:46 |
|
mirek
Messages: 13984 Registered: November 2005
|
Ultimate Member |
|
|
class ClassName {
...
WithLayout<TopWindow> laySomething;
...
};
NeonN wrote on Sun, 07 October 2007 14:32 | and why I shouldn't do this...
|
Well, e.g., when you close the main window, what happens to owned ones? Making owned windows proper class members solves this problem implicitly.
Mirek
[Updated on: Sun, 07 October 2007 23:48] Report message to a moderator
|
|
|
Re: Modal vs non-modal window [message #12015 is a reply to message #12010] |
Mon, 08 October 2007 09:14 |
NeonN
Messages: 8 Registered: September 2007 Location: Czech Republic
|
Promising Member |
|
|
Thx, i get it now... i wasn't thinking about that (making the dialow window class member). But I'm not very exited opening the window this way because it's IMHO wasting free memmory... the dialog window is allocated all the time when main window is running...
Maybe it's not so important for me because the app i am porting will be using at most 5-10 small dialogs... but anyway, i don't like it at all ....
[Updated on: Mon, 08 October 2007 09:15] Report message to a moderator
|
|
|
Re: Modal vs non-modal window [message #12016 is a reply to message #12015] |
Mon, 08 October 2007 10:52 |
|
mirek
Messages: 13984 Registered: November 2005
|
Ultimate Member |
|
|
NeonN wrote on Mon, 08 October 2007 03:14 | Thx, i get it now... i wasn't thinking about that (making the dialow window class member). But I'm not very exited opening the window this way because it's IMHO wasting free memmory... the dialog window is allocated all the time when main window is running...
Maybe it's not so important for me because the app i am porting will be using at most 5-10 small dialogs... but anyway, i don't like it at all ....
|
Yep, that is, in theory, a valid concern.
Anyway, how big is subdialog? Single widget occupies 100-200 bytes, so it is usually less than 5KB. People tend to waste much more in other parts of code without even knowing
Another important issue is that you will get access to the dialog, all its settings and values, for free. With new, you would in most cases needed to store a pointer to subdialog anyway.
OTOH, if the memory really is concern, you can use something like
class ClassName {
...
One< WithLayout<TopWindow> > laySomething;
...
};
void ClassName::InitDlg()
{
...
laySomething.Create();
...
}
In this case, data will be allocated on demand, while still keeping the advantage of deterministic cleanup.
|
|
|
Re: Modal vs non-modal window [message #12022 is a reply to message #12016] |
Mon, 08 October 2007 14:58 |
NeonN
Messages: 8 Registered: September 2007 Location: Czech Republic
|
Promising Member |
|
|
Thx for the One<> tip... it seams really useful.
luzr wrote on Mon, 08 October 2007 10:52 |
Another important issue is that you will get access to the dialog, all its settings and values, for free. With new, you would in most cases needed to store a pointer to subdialog anyway.
|
Yes, the pointer to the dialog would be a member of main class (and the dialog window would be new'ed in the window-init function)... so I could access to the widgets and values of them in the whole class. But now, the One<> seems as a better option. Thx again...
The app will contain approximately 5-10 dialogs... some of them are just few edits put together but few will be more complex (2-4 ArrayCtrl with data selected from DB, edits, droplists, buttons - all in 2-3 tabs)... so I guess it's more than few kB .
[Updated on: Mon, 08 October 2007 15:52] Report message to a moderator
|
|
|
Goto Forum:
Current Time: Sat Jun 08 08:55:53 CEST 2024
Total time taken to generate the page: 0.02137 seconds
|
|
|