Damien.Garrido
2009-05-15 14:02:38 UTC
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 !
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.
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.