Discussion:
En/Dis(able) wxDialog/wxFrame children of a wxDialog/wxFrame
(too old to reply)
Damien.Garrido
2009-05-15 14:02:38 UTC
Permalink
I looking for a way to enable/disable all children of a wxWindow. This is
working for most children (wxButton, wxCheckBox, etc...), but not for
wxDialog and wxFrame...


Is there any option (like wxENABLE_ALL_CHILDREN) to set somewhere in order
to also enable/disable children which are wxDialog/wxFrame windows ?

Or is there any event for enabling/disabling children ? Something like
wxENABLE that I could manage myself in the wxDialog/wxFrame children classes
with the appropriate event handler...


I've been advised to use a panel as the parent of all children:


"The easy way is to give each frame/dialog a wxPanel as its only child
control (apart from *bars). This is a good idea anyway, especially for
frames.

All the other controls get parented by that panel, and go inside its sizer.
Disabling the panel then automatically disables all its children."



Here is my answer:



"I've tried but it doesn't work for me...

Here is what I did:


I created a parent_frame (wxFrame) without parent.
I added a main_panel (wxPanel which holds a button) and attached it to
parent_frame.
I created a child_frame (wxFrame) and attached it to parent_panel.
I created a child_panel (same wxPanel) and attached it to child_frame.
I connected the parent_panel button to a method which enable/disable the
parent_panel.


When I click the button of the parent frame, then the parent_panel is
disabled as well as some of its children (actually the single button).

But some of the parent_panel children are not disabled (that is to say the
child_frame and child_panel)
It seems that wxDialog and wxFrame are not considered as normal wxWindow
children objects and adding a wxPanel does not change anything...


PS: I'm using wxGTK on Linux.


Here is some code about it:



class parent_frame : public wxFrame
{
public:
parent_frame( wxWindow* parent, wxWindowID id = wxID_ANY, const
wxString& title = wxT("Parent Frame"), const wxPoint& pos =
wxDefaultPosition, const wxSize& size = wxSize( 230,70 ), long style =
wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL ) : wxFrame( parent, id, title, pos,
size, style )
{
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
}
~parent_frame()
{}
};

class child_frame : public wxFrame
{
public:
child_frame( wxWindow* parent, wxWindowID id = wxID_ANY, const
wxString& title = wxT("Child Frame"), const wxPoint& pos =
wxDefaultPosition, const wxSize& size = wxSize( 230,70 ), long style =
wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL ) : wxFrame( parent, id, title, pos,
size, style )
{
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
}
~child_frame()
{}
};

class main_panel : public wxPanel
{
public:
wxButton* btn_enable_disable;
main_panel( wxWindow* parent, wxWindowID id = wxID_ANY, const
wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 225,50 ),
long style = wxTAB_TRAVERSAL ) : wxPanel( parent, id, pos, size, style )
{
wxBoxSizer* szr_main = new wxBoxSizer( wxVERTICAL );
btn_enable_disable = new wxButton( this, wxID_ANY,
wxT("Enable/Disable"), wxDefaultPosition, wxDefaultSize, 0 );
szr_main->Add( btn_enable_disable, 0,
wxALIGN_CENTER|wxALL|wxEXPAND, 5 );
this->SetSizer( szr_main );
this->Layout();
}
~main_panel()
{}
};

parent_frame* parent_frame;
main_panel* parent_panel;
child_frame* child_frame;
main_panel* child_panel;

void my_app::enable_disable( wxCommandEvent & )
{
parent_panel->Enable( parent_panel->IsEnabled() );
}

bool my_app::OnInit()
{
parent_frame* parent_frame = new parent_frame( nullptr );
main_panel* parent_panel = new main_panel( parent_frame );
child_frame* child_frame = new child_frame( parent_panel );
main_panel* child_panel = new main_panel( child_frame );
parent_panel->btn_enable_disable->Connect(
wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( my_app::enable_disable
), NULL, this );
parent_frame->Show();
child_frame->Show();
}"



Then finally I noticed the following :



"I found this in src/gtk/windows.cpp :


static void wxWindowNotifyEnable(wxWindowGTK* win, bool enable)
{
win->OnParentEnable(enable);

// Recurse, so that children have the opportunity to Do The Right Thing
// and reset colours that have been messed up by a parent's (really
ancestor's)
// Enable call
for ( wxWindowList::compatibility_iterator node =
win->GetChildren().GetFirst();
node;
node = node->GetNext() )
{
wxWindow *child = node->GetData();
if ( !child->IsKindOf(CLASSINFO(wxDialog)) &&
!child->IsKindOf(CLASSINFO(wxFrame)))
wxWindowNotifyEnable(child, enable);
}
}


So if child is not a kind of wxDialog or wxFrame then go on notifying
children...

It seems I'm locked here ...


I could remove this test & recompile, but ... it's not really clean, isn't
it ?"




Any hint would be appreciated !
--
View this message in context: http://www.nabble.com/En-Dis%28able%29-wxDialog-wxFrame-children-of-a-wxDialog-wxFrame-tp23560456p23560456.html
Sent from the wxWidgets - Users mailing list archive at Nabble.com.
Vadim Zeitlin
2009-05-15 17:16:09 UTC
Permalink
On Fri, 15 May 2009 07:02:38 -0700 (PDT) "Damien.Garrido" <***@gmail.com> wrote:

D> I looking for a way to enable/disable all children of a wxWindow. This is
D> working for most children (wxButton, wxCheckBox, etc...), but not for
D> wxDialog and wxFrame...

Sorry but it's not clear at all from the rest of your message what this
problem is, exactly. Explaining it would dramatically increase chances of
getting helpful responses.

Regards,
VZ
--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/
Damien.Garrido
2009-05-15 18:08:56 UTC
Permalink
Ok sorry, I'll try to be clearer...


What I intend to do is to be able to enable or disable wxDialog and wxFrame
windows in chain.


For example I have a main wxFrame which have an enable_disable check box and
two wxFrame children :


child_one <- main -> child_two

Then the child_two have two other wxFrame children: child_two_child_one and
child_two_child_two

child_one <- main -> child_two -> child_two_child_one
|-> child_two_child_two


Ok, now I want to be able to disable child_two and its children by clicking
on the enable_disable check box.

The result must be child_two, child_two_child_one and child_two_child_two
are disabled and as well as their respective content (button, text controls,
etc).

The problem is that I'm only able to disable content of child_two, because
the enabling/disabling is not pass through children which are of type
wxFrame or wxDialog, as I've been able to see in the src/gtk/windows.cpp
file (wxWidgets version 2.8.10).


I might be able to use the wxWindowDisabler class if I need at most one top
level window staying enabled. It won't work if I need to use two or more
windows while disabling the others. I'll give it a try anyway, (and a look
to see how it is implemented, may be I could let more than one window
enabled...).


Regards,

Damien
Post by Vadim Zeitlin
D> I looking for a way to enable/disable all children of a wxWindow. This
is
D> working for most children (wxButton, wxCheckBox, etc...), but not for
D> wxDialog and wxFrame...
Sorry but it's not clear at all from the rest of your message what this
problem is, exactly. Explaining it would dramatically increase chances of
getting helpful responses.
Regards,
VZ
--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/
_______________________________________________
wx-users mailing list
http://lists.wxwidgets.org/mailman/listinfo/wx-users
--
View this message in context: http://www.nabble.com/En-Dis%28able%29-wxDialog-wxFrame-children-of-a-wxDialog-wxFrame-tp23560456p23564791.html
Sent from the wxWidgets - Users mailing list archive at Nabble.com.
Vadim Zeitlin
2009-05-16 12:02:13 UTC
Permalink
On Fri, 15 May 2009 11:08:56 -0700 (PDT) "Damien.Garrido" <***@gmail.com> wrote:

D> The problem is that I'm only able to disable content of child_two, because
D> the enabling/disabling is not pass through children which are of type
D> wxFrame or wxDialog, as I've been able to see in the src/gtk/windows.cpp
D> file (wxWidgets version 2.8.10).

Yes, this is correct and intentional.

To explicitly disable all top level children of a wxFrame you can either
iterate over its GetChildren() and check for IsTopLevel() (or maybe even
just disable everything as you want to disable normal children too) or
iterate over wxTopLevelWindows list and disable its elements whose
GetParent() returns your frame.

Regards,
VZ
--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/
Damien.Garrido
2009-05-19 09:43:47 UTC
Permalink
OK, I finally did it using recursion.

I added the following enable_all_children method to the window in charge of
enabling/disabling its children.

I iterate through its children windows and if a child is a top level window
I call the enable_all_children method recursively on this child.

I paste the code in case someone else has the same goal:

wxwidgets:

//!
//! @brief Enable or disable all top level children windows
//!
void main_frame::enable_all_children&#40;
http://www.wxwidgets.org/manuals/stable/wx_wxwindow.html#wxwindow wxWindow *
window, bool enabled &#41;
&#123;
&nbsp; &nbsp; &nbsp; &nbsp; //! Enable or disable itself
&nbsp; &nbsp; &nbsp; &nbsp; window-&gt;Enable&#40; enabled &#41;;
&nbsp; &nbsp; &nbsp; &nbsp; if &#40; window-&gt;IsTopLevel&#40;&#41; &#41;
&nbsp; &nbsp; &nbsp; &nbsp; &#123;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
http://www.wxwidgets.org/manuals/stable/wx_wxtoplevelwindow.html#wxtoplevelwindow
wxTopLevelWindow * top_level_window = dynamic_cast&lt;
http://www.wxwidgets.org/manuals/stable/wx_wxtoplevelwindow.html#wxtoplevelwindow
wxTopLevelWindow * &gt;&#40; window &#41;;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LOG&#40; debug &#41;
&lt;&lt; &quot;Top level window [title=&quot; &lt;&lt;
top_level_window-&gt;GetTitle&#40;&#41;.mb_str&#40;&#41;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &lt;&lt; &quot;] [label=&quot; &lt;&lt;
window-&gt;GetLabel&#40;&#41;.mb_str&#40;&#41;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &lt;&lt; &quot;] [name=&quot; &lt;&lt;
window-&gt;GetName&#40;&#41;.mb_str&#40;&#41;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &lt;&lt; &quot;] has been &quot; &lt;&lt; &#40; enabled ?
&quot;enabled&quot; : &quot;disabled&quot; &#41;;
&nbsp; &nbsp; &nbsp; &nbsp; &#125;
&nbsp; &nbsp; &nbsp; &nbsp; //! Enable or disable all top level children
windows
&nbsp; &nbsp; &nbsp; &nbsp; wxWindowList window_list =
window-&gt;GetChildren&#40;&#41;;
&nbsp; &nbsp; &nbsp; &nbsp; for &#40; wxWindowList::iterator child =
window_list.begin&#40;&#41;; child != window_list.end&#40;&#41;; ++child
&#41;
&nbsp; &nbsp; &nbsp; &nbsp; &#123;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if &#40; &#40;
*child &#41;-&gt;IsTopLevel&#40;&#41; &#41;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#123;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; enable_all_children&#40; *child, enabled &#41;;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &#125;
&nbsp; &nbsp; &nbsp; &nbsp; &#125;
&#125;
//!
//! @brief Enable or disable all needed children windows
//!
void main_frame::enable_all&#40; bool enabled &#41;
&#123;
&nbsp; &nbsp; &nbsp; &nbsp; // Enable/disable some immediate children
&nbsp; &nbsp; &nbsp; &nbsp; m_button-&gt;Enable&#40; enabled &#41;;
&nbsp; &nbsp; &nbsp; &nbsp; m_check_box-&gt;Enable&#40; enabled &#41;;
&nbsp; &nbsp; &nbsp; &nbsp; m_radio_button-&gt;Enable&#40; enabled &#41;;
&nbsp; &nbsp; &nbsp; &nbsp; // Enable/disable top level children windows
&nbsp; &nbsp; &nbsp; &nbsp; if &#40; m_frame_1 != nullptr &#41;
&nbsp; &nbsp; &nbsp; &nbsp; &#123;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
enable_all_children&#40; m_frame_1, enabled &#41;;
&nbsp; &nbsp; &nbsp; &nbsp; &#125;
&nbsp; &nbsp; &nbsp; &nbsp; if &#40; m_frame_3 != nullptr &#41;
&nbsp; &nbsp; &nbsp; &nbsp; &#123;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
enable_all_children&#40; m_frame_3, enabled &#41;;
&nbsp; &nbsp; &nbsp; &nbsp; &#125;
&#125;
&nbsp;



Thanks for your help.
--
View this message in context: http://www.nabble.com/En-Dis%28able%29-wxDialog-wxFrame-children-of-a-wxDialog-wxFrame-tp23560456p23612951.html
Sent from the wxWidgets - Users mailing list archive at Nabble.com.
Loading...