// returns whether we should accept focus ourselves or not
bool AcceptsFocus() const { return m_acceptsFocus; }
+ // returns whether we or one of our children accepts focus: we always do
+ // because if we don't have any focusable children it probably means that
+ // we're not being used as a container at all (think of wxGrid or generic
+ // wxListCtrl) and so should get focus for ourselves
+ bool AcceptsFocusRecursively() const { return true; }
+
// call this when the number of children of the window changes
- void UpdateCanFocus() { SetCanFocus(ShouldAcceptFocus()); }
+ //
+ // note that we have any children, this panel (used just as container for
+ // them) shouldn't get focus for itself
+ void UpdateCanFocus() { SetCanFocus(!HasAnyFocusableChildren()); }
protected:
- // return true if we should be focusable
- bool ShouldAcceptFocus() const;
+ // return true if we have any children accepting focus
+ bool HasAnyFocusableChildren() const;
// the parent window we manage the children for
wxWindow *m_winParent;
#define WX_DECLARE_CONTROL_CONTAINER_BASE() \
public: \
virtual bool AcceptsFocus() const; \
+ virtual bool AcceptsFocusRecursively() const; \
virtual void AddChild(wxWindowBase *child); \
virtual void RemoveChild(wxWindowBase *child); \
void SetFocusIgnoringChildren(); \
m_container.UpdateCanFocus(); \
} \
\
+ bool classname::AcceptsFocusRecursively() const \
+ { \
+ return m_container.AcceptsFocusRecursively(); \
+ } \
+ \
bool classname::AcceptsFocus() const \
{ \
return m_container.AcceptsFocus(); \
// this class clients and take into account the current window state
virtual bool AcceptsFocus() const { return true; }
- // can this window have focus right now?
- bool CanAcceptFocus() const { return AcceptsFocus() && IsShown() && IsEnabled(); }
+ // can this window or one of its children accept focus?
+ //
+ // usually it's the same as AcceptsFocus() but is overridden for
+ // container windows
+ virtual bool AcceptsFocusRecursively() const { return AcceptsFocus(); }
// can this window be given focus by keyboard navigation? if not, the
// only way to give it focus (provided it accepts it at all) is to
// click it
virtual bool AcceptsFocusFromKeyboard() const { return AcceptsFocus(); }
+
+ // this is mostly a helper for the various functions using it below
+ bool CanBeFocused() const { return IsShown() && IsEnabled(); }
+
+ // can this window itself have focus?
+ bool IsFocusable() const { return AcceptsFocus() && CanBeFocused(); }
+
+ // can this window have focus right now?
+ //
+ // if this method returns true, it means that calling SetFocus() will
+ // put focus either to this window or one of its children, if you need
+ // to know whether this window accepts focus itself, use IsFocusable()
+ bool CanAcceptFocus() const
+ { return AcceptsFocusRecursively() && CanBeFocused(); }
+
// can this window be assigned focus from keyboard right now?
bool CanAcceptFocusFromKeyboard() const
- { return AcceptsFocusFromKeyboard() && CanAcceptFocus(); }
+ { return AcceptsFocusFromKeyboard() && CanBeFocused(); }
// call this when the return value of AcceptsFocus() changes
virtual void SetCanFocus(bool WXUNUSED(canFocus)) { }
m_winParent->SetCanFocus(m_acceptsFocus);
}
-// if the window has a focusable child, it shouldn't be focusable itself (think
-// of wxPanel used for grouping different controls) but if it doesn't have any
-// (focusable) children, then it should be possible to give it focus (think of
-// wxGrid or generic wxListCtrl)
-bool wxControlContainerBase::ShouldAcceptFocus() const
+bool wxControlContainerBase::HasAnyFocusableChildren() const
{
- // we can accept focus either if we have no children at all (in this case
- // we're probably not used as a container) or only when at least one child
- // accepts focus
- wxWindowList::compatibility_iterator node = m_winParent->GetChildren().GetFirst();
- if ( !node )
- return true;
-
- while ( node )
+ const wxWindowList& children = m_winParent->GetChildren();
+ for ( wxWindowList::const_iterator i = children.begin(),
+ end = children.end();
+ i != end;
+ ++i )
{
- wxWindow *child = node->GetData();
- node = node->GetNext();
+ const wxWindow * const child = *i;
if ( !m_winParent->IsClientAreaChild(child) )
continue;
if ( child->CanAcceptFocus() )
- return false;
+ return true;
}
- return true;
+ return false;
}
#ifndef wxHAS_NATIVE_TAB_TRAVERSAL
g_lastButtonNumber = gdk_event->button;
- if (win->m_wxwindow && (g_focusWindow != win) && win->CanAcceptFocus())
+ if (win->m_wxwindow && (g_focusWindow != win) && win->IsFocusable())
{
gtk_widget_grab_focus( win->m_wxwindow );
}
return TRUE;
if ((event_type == wxEVT_LEFT_DOWN) && !win->IsOfStandardClass() &&
- (g_focusWindow != win) && win->CanAcceptFocus())
+ (g_focusWindow != win) && win->IsFocusable())
{
gtk_widget_grab_focus( win->m_wxwindow );
}
g_lastButtonNumber = gdk_event->button;
- if (win->m_wxwindow && (g_focusWindow != win) && win->CanAcceptFocus())
+ if (win->m_wxwindow && (g_focusWindow != win) && win->IsFocusable())
{
gtk_widget_grab_focus( win->m_wxwindow );
/*
// problems, so don't do it for them (unnecessary anyhow)
if ( !win->IsOfStandardClass() )
{
- if ( message == WM_LBUTTONDOWN && win->CanAcceptFocus() )
+ if ( message == WM_LBUTTONDOWN && win->IsFocusable() )
win->SetFocus();
}
}