Modal/Modeless windows Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
raananb
Super wx Problem Solver
Super wx Problem Solver
Posts: 488
Joined: Fri Oct 27, 2006 4:35 pm
Location: Paris, France
Contact:

Modal/Modeless windows

Post by raananb »

I have been using Powersoft (later Sybase) Power++ RAD to develop Windows applications.

I would like to rewrite my applications using wxWidgets, but before I start, I would like to be sure that 1) it is possible to create a window (frame?) from an existing window and 2) that there is a way to create Modal and Modeless windows.

I would appreciate some hints as to how this can be achieved.
Belgabor
I live to help wx-kind
I live to help wx-kind
Posts: 173
Joined: Mon Sep 25, 2006 1:12 pm

Post by Belgabor »

There are two basic top-level window classes, wxFrame and wxDialog. You can always open new top-level windows from others.
wxFrame is always modeless, but can have a menu bar and a window associated toolbar.
wxDialog can be both modeless and modal, but (unfortunately) doesn't support a menu bar. A toolbar can be implemented as a control.

There are also base classes for MDI windows, but I never used those.
raananb
Super wx Problem Solver
Super wx Problem Solver
Posts: 488
Joined: Fri Oct 27, 2006 4:35 pm
Location: Paris, France
Contact:

Post by raananb »

Thanks. I will start with this.
User avatar
tierra
Site Admin
Site Admin
Posts: 1355
Joined: Sun Aug 29, 2004 7:14 pm
Location: Salt Lake City, Utah, USA
Contact:

Post by tierra »

Belgabor wrote:wxDialog can be both modeless and modal, but (unfortunately) doesn't support a menu bar.
I love how so many people think this is some drawback to wxWidgets. Dialogs aren't supposed to have menus. Not only is it not allowed on Mac OS X, it's highly discouraged in any platform user interface design. The main window menubar is supposed to act as a central location to access all functionality of a program. Users expect that they can browse that menu to find and access any feature of a program. It's just confuses the user when there's more than one menubar with different menu items. You won't find many major applications that use a menubar anywhere other than the main window.

People also love to point out that the GIMP does that. In my opinion it's a mistake, but the GIMP devs are also going for a design that isn't MDI, but isn't SDI either, and they don't have a whole lot of choice with the multiple windows.

I recommend reading GUI Bloopers, it covers this topic along with many others.
Belgabor
I live to help wx-kind
I live to help wx-kind
Posts: 173
Joined: Mon Sep 25, 2006 1:12 pm

Post by Belgabor »

While I generally agree with you, I still feel it's a drawback. As the developer it's my choice to make how to present an UI. As you say, in many (even most) cases a menu is not apropriate in a dialog, but in some it might be (probably easier to understand if you think modal window rather than dialog).
I understand the decision not to support it generally as a major target platform doesn't, still I'd prefer to have it available if the need arises :D

PS: Personally I'm not very fond of The Gimp's UI, but as I lack the time to work out something better I don't complain :)
raananb
Super wx Problem Solver
Super wx Problem Solver
Posts: 488
Joined: Fri Oct 27, 2006 4:35 pm
Location: Paris, France
Contact:

Post by raananb »

The discussion about menus in a second-level window is certainly interesting, but probably not relevant to my issue. The modal/modeless is a design issue for an application developer, and I guess that wxDialogue can be considered as a modal window capable of using all the pertinent widgets.

However, having looked further, I did not find any widget corresponding to a new window.

I consequently do not see how to design a new window (with its own widgets) which can be called from a higher-level window.

Any clues?
Belgabor
I live to help wx-kind
I live to help wx-kind
Posts: 173
Joined: Mon Sep 25, 2006 1:12 pm

Post by Belgabor »

I'm not sure I fully understand the problem. You should subclass wxFrame/wxDialog for every kind of window you need and set up its contents in its constructor.
In the parent window you then simply create a new instance of your window class and call its Show or ShowModal method.
raananb
Super wx Problem Solver
Super wx Problem Solver
Posts: 488
Joined: Fri Oct 27, 2006 4:35 pm
Location: Paris, France
Contact:

Post by raananb »

My remarks originate in my experience with Power++, where you can create a form (modal or modeless) with a form widget, and you can then graphically implement all the elements you need on that form. You have a 'system' tool to link one form to another so that you can reference one form from the other and pass data through a structure you define in the called form. This obviates the need to subclass things - the package does it for you. You can link a form to more than one form and call it from each when needed.

Obviously, there are a few things which I will need to learn... (and some I will have to forget)
User avatar
tierra
Site Admin
Site Admin
Posts: 1355
Joined: Sun Aug 29, 2004 7:14 pm
Location: Salt Lake City, Utah, USA
Contact:

Post by tierra »

I'm about 95% positive I can assure you that everything you've done with Power++ is possible with wxWidgets, though it will be significantly different as there are different tools for the job and a different API altogether. I'm also confused as to exactly what you're asking, but if you're just looking to see if equivalent RAD tools exist for wxWidgets, you should look over the wxWiki tools page for a full list of RAD tools and look at the features yourself.
Belgabor
I live to help wx-kind
I live to help wx-kind
Posts: 173
Joined: Mon Sep 25, 2006 1:12 pm

Post by Belgabor »

If you need more specific help, just ask. My current project requires a lot of data transfer between parent and child dialogs, so I learnd a lot I can pass on.
One thing I'd recommend you is to take a look at the wxValidator classes. For simple (and with a bit of creativity complex) dialogs they can make your life a LOT easier.
raananb
Super wx Problem Solver
Super wx Problem Solver
Posts: 488
Joined: Fri Oct 27, 2006 4:35 pm
Location: Paris, France
Contact:

Post by raananb »

Thanks both Tierra and Belgabor - I have been away for a week, and am now back with Dev++, trying to find out how to do what I would like to achieve.

Some code snippets showing how to subclass a window and pass data back and forth between parent and child will be very helpful.
Belgabor
I live to help wx-kind
I live to help wx-kind
Posts: 173
Joined: Mon Sep 25, 2006 1:12 pm

Post by Belgabor »

Ok, here is how I usually transfer data between my windows. I only used wxDialogs in modal mode so far, so you may need to adjust a bit.

First I have a structure that holds the data I want to transfer. In this example I use a struct:

Code: Select all

struct MyStruct{
	wxString a;
	int b;
	int c;
};
In the declaration I add a private instance of this struct and two public functions to transfer the data:

Code: Select all

class MyDialog : public wxDialog {
    // Declaration of controls and constructor skipped
private:
    MyStruct m_mystruct;
public:
    void SetMyStruct(const MyStruct& mystruct) {
        m_mystruct = mystruct;
    };
    MyStruct GetMyStruct() const {return m_mystruct;};
};
If the transfer is simple as in this example I leave the implementation in the class declaration as shown here. Note that a pointer to the transfer structure will not work (I mean MyStruct *m_mystruct; will not work).

In the constructor of the dialog I set up validators:

Code: Select all

    // Creation of controls skipped
    m_textA->SetValidator(wxGenericValidator(&m_mystruct.a);
    m_textB->SetValidator(wxGenericValidator(&m_mystruct.b);
    m_textC->SetValidator(wxGenericValidator(&m_mystruct.c);
Note: I do it this way because I use xrc resources. If you create the controls yourself you can assign the validators in the controls' constructors.

In the parent window I then create and show the dialog like this:

Code: Select all

    MyDialog *dialog = new MyDialog(this);
    dialog->SetMyStruct(currentmystruct);
    if (dialog->ShowModal() == wxID_OK) {
        currentmystruct = dialog->GetMyStruct();
    }
    dialog->Destroy();
That's basically it. The transfer of the values to the controls and back is handeled by the validators and the default wxDialog methods.
raananb
Super wx Problem Solver
Super wx Problem Solver
Posts: 488
Joined: Fri Oct 27, 2006 4:35 pm
Location: Paris, France
Contact:

Post by raananb »

Thanks Belgabor, that point is now clear.
Post Reply