From 3da17724b6a873579628356a92ade9c41f07d5a3 Mon Sep 17 00:00:00 2001 From: Robert Roebling Date: Sun, 31 Oct 1999 10:22:26 +0000 Subject: [PATCH] More tab code corrections. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4273 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/generic/panelg.h | 4 ++ samples/scroll/scroll.cpp | 6 +-- src/generic/panelg.cpp | 91 +++++++++++++++++++++++++++++-------- src/gtk/window.cpp | 65 +++++--------------------- src/gtk1/window.cpp | 65 +++++--------------------- 5 files changed, 104 insertions(+), 127 deletions(-) diff --git a/include/wx/generic/panelg.h b/include/wx/generic/panelg.h index b6c550a860..308be49ecb 100644 --- a/include/wx/generic/panelg.h +++ b/include/wx/generic/panelg.h @@ -78,8 +78,12 @@ public: // set the focus to the first child if we get it void OnFocus(wxFocusEvent& event); + // calls layout for layout constraints and sizers void OnSize(wxSizeEvent& event); + // overridden to tab move focus into first focusable child + virtual void SetFocus(); + // called by wxWindow whenever it gets focus void SetLastFocus(wxWindow *win) { m_winLastFocused = win; } wxWindow *GetLastFocus() const { return m_winLastFocused; } diff --git a/samples/scroll/scroll.cpp b/samples/scroll/scroll.cpp index d1a03c1ab6..8f5cba310c 100644 --- a/samples/scroll/scroll.cpp +++ b/samples/scroll/scroll.cpp @@ -151,17 +151,17 @@ MyCanvas::MyCanvas( wxWindow *parent, wxWindowID id, (void) new wxListBox( this, -1, wxPoint(260,280), wxSize(120,120), 5, choices, wxLB_ALWAYS_SB ); - wxWindow *test = new wxWindow( this, -1, wxPoint(10, 530), wxSize(130,120), wxSIMPLE_BORDER | wxTAB_TRAVERSAL ); + wxPanel *test = new wxPanel( this, -1, wxPoint(10, 530), wxSize(130,120), wxSIMPLE_BORDER | wxTAB_TRAVERSAL ); test->SetBackgroundColour( "WHEAT" ); wxButton *test2 = new wxButton( test, -1, "Hallo", wxPoint(10,10) ); - test = new wxWindow( this, -1, wxPoint(160, 530), wxSize(130,120), wxSUNKEN_BORDER | wxTAB_TRAVERSAL ); + test = new wxPanel( this, -1, wxPoint(160, 530), wxSize(130,120), wxSUNKEN_BORDER | wxTAB_TRAVERSAL ); test->SetBackgroundColour( "WHEAT" ); test->SetCursor( wxCursor( wxCURSOR_NO_ENTRY ) ); test2 = new wxButton( test, -1, "Hallo", wxPoint(10,10) ); test2->SetCursor( wxCursor( wxCURSOR_PENCIL ) ); - test = new wxWindow( this, -1, wxPoint(310, 530), wxSize(130,120), wxRAISED_BORDER | wxTAB_TRAVERSAL ); + test = new wxPanel( this, -1, wxPoint(310, 530), wxSize(130,120), wxRAISED_BORDER | wxTAB_TRAVERSAL ); test->SetBackgroundColour( "WHEAT" ); test->SetCursor( wxCursor( wxCURSOR_PENCIL ) ); test2 = new wxButton( test, -1, "Hallo", wxPoint(10,10) ); diff --git a/src/generic/panelg.cpp b/src/generic/panelg.cpp index e9339b481a..1536036da2 100644 --- a/src/generic/panelg.cpp +++ b/src/generic/panelg.cpp @@ -99,7 +99,15 @@ void wxPanel::OnNavigationKey( wxNavigationKeyEvent& event ) return; } - wxWindow *winFocus = event.GetCurrentFocus(); + // Did the event emitter tell us where the last focus was? + // wxGTK does this in wxWindow, but wxMSW does not. It is + // also done in wxPanel if the event is propagated up. + wxWindow *winFocus = event.GetCurrentFocus(); + + // Do we know where the focus was ourselves, then? + if (!winFocus) + winFocus = m_winLastFocused; + if (!winFocus) winFocus = wxWindow::FindFocus(); @@ -120,27 +128,31 @@ void wxPanel::OnNavigationKey( wxNavigationKeyEvent& event ) while ( node != start_node ) { + // Have we come to the last or first item on the panel? if ( !node ) { - // check if our (may be grand) parent is another panel: if this is + // Check if our (may be grand) parent is another panel: if this is // the case, they will know what to do with this navigation key and // so give them the chance to process it instead of looping inside // this panel (normally, the focus will go to the next/previous - // item after this panel in the parent panel) - wxWindow *focussed_child_of_p = this; - for ( wxWindow *p = GetParent(); p; p = p->GetParent() ) + // item after this panel in the parent panel). + wxWindow *focussed_child_of_parent = this; + for ( wxWindow *parent = GetParent(); parent; parent = parent->GetParent() ) { // we don't want to tab into a different dialog or frame - if ( focussed_child_of_p->IsTopLevel() ) + if ( focussed_child_of_parent->IsTopLevel() ) break; - - if ( wxDynamicCast(p, wxPanel) ) + + // is the parent a panel? + wxPanel *panel = wxDynamicCast(parent, wxPanel); + if (panel) { - event.SetCurrentFocus( focussed_child_of_p ); - if (p->GetEventHandler()->ProcessEvent( event )) + event.SetCurrentFocus( focussed_child_of_parent ); + if (parent->GetEventHandler()->ProcessEvent( event )) return; } - focussed_child_of_p = p; + + focussed_child_of_parent = parent; } // no, we are not inside another panel so process this ourself @@ -154,7 +166,7 @@ void wxPanel::OnNavigationKey( wxNavigationKeyEvent& event ) if ( child->AcceptsFocus() ) { - // ok, event processed + m_winLastFocused = child; // should be redundant, but it is not child->SetFocus(); return; } @@ -175,16 +187,59 @@ void wxPanel::OnSize(wxSizeEvent& WXUNUSED(event)) #endif } +void wxPanel::SetFocus() +{ + // If the panel gets the focus *by way of getting it set directly* + // we move it to the first window that can get it. + + wxNode *node = GetChildren().First(); + while (node) + { + wxWindow *child = (wxWindow*) node->Data(); + if (child->AcceptsFocus()) + { + m_winLastFocused = child; // should be redundant, but it is not + child->SetFocus(); + return; + } + node = node->Next(); + } + + m_winLastFocused = (wxWindow*) NULL; + + wxWindow::SetFocus(); +} + void wxPanel::OnFocus(wxFocusEvent& event) { - if ( m_winLastFocused ) + // If the panel gets the focus *by way of getting clicked on* + // we move it to either the last window that had the focus or + // the first one that can get it. + + if (m_winLastFocused) { // it might happen that the window got reparented... - if ( m_winLastFocused->GetParent() != this ) - m_winLastFocused = (wxWindow *)NULL; - else + if ( m_winLastFocused->GetParent() == this ) + { m_winLastFocused->SetFocus(); + return; + } } - else - event.Skip(); + + wxNode *node = GetChildren().First(); + while (node) + { + wxWindow *child = (wxWindow*) node->Data(); + if (child->AcceptsFocus()) + { + m_winLastFocused = child; // should be redundant, but it is not + child->SetFocus(); + return; + } + node = node->Next(); + } + + m_winLastFocused = (wxWindow*) NULL; + + event.Skip(); } diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 1b7eca62e5..5cc4b89019 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -739,9 +739,12 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_e /* win is a control: tab can be propagated up */ if ( (!ret) && ((gdk_event->keyval == GDK_Tab) || (gdk_event->keyval == GDK_ISO_Left_Tab)) && - (win->HasFlag(wxTE_PROCESS_TAB) == 0)) + (!win->HasFlag(wxTE_PROCESS_TAB)) && + (win->GetParent()) && + (win->GetParent()->HasFlag( wxTAB_TRAVERSAL)) ) { wxNavigationKeyEvent new_event; + new_event.SetEventObject( win ); /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */ new_event.SetDirection( (gdk_event->keyval == GDK_Tab) ); /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */ @@ -1295,21 +1298,6 @@ static gint gtk_window_focus_in_callback( GtkWidget *widget, GdkEvent *WXUNUSED( g_focusWindow = win; - if (win->m_wxwindow) - { - if (GTK_WIDGET_CAN_FOCUS(win->m_wxwindow)) - { - GTK_WIDGET_SET_FLAGS (win->m_wxwindow, GTK_HAS_FOCUS); -/* - printf( "SetFocus flag from " ); - if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) - printf( win->GetClassInfo()->GetClassName() ); - printf( ".\n" ); -*/ - } - } - - /* printf( "OnSetFocus from " ); if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) @@ -1319,6 +1307,12 @@ static gint gtk_window_focus_in_callback( GtkWidget *widget, GdkEvent *WXUNUSED( printf( ".\n" ); */ + wxPanel *panel = wxDynamicCast(win->GetParent(), wxPanel); + if (panel) + { + panel->SetLastFocus(win); + } + wxFocusEvent event( wxEVT_SET_FOCUS, win->GetId() ); event.SetEventObject( win ); @@ -1343,12 +1337,6 @@ static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEvent *WXUNUSED if (!win->m_hasVMT) return FALSE; if (g_blockEventsOnDrag) return FALSE; - if (win->m_wxwindow) - { - if (GTK_WIDGET_CAN_FOCUS(win->m_wxwindow)) - GTK_WIDGET_UNSET_FLAGS (win->m_wxwindow, GTK_HAS_FOCUS); - } - /* printf( "OnKillFocus from " ); if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) @@ -1671,13 +1659,6 @@ static void wxInsertChildInWindow( wxWindow* parent, wxWindow* child ) child->m_y, child->m_width, child->m_height ); - - if (parent->HasFlag(wxTAB_TRAVERSAL)) - { - /* we now allow a window to get the focus as long as it - doesn't have any children. */ - GTK_WIDGET_UNSET_FLAGS( parent->m_wxwindow, GTK_CAN_FOCUS ); - } } //----------------------------------------------------------------------------- @@ -1832,18 +1813,8 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id, } #endif // GTK_MINOR_VERSION - if (HasFlag(wxTAB_TRAVERSAL)) - { - /* we now allow a window to get the focus as long as it - doesn't have any children. */ - GTK_WIDGET_SET_FLAGS( m_wxwindow, GTK_CAN_FOCUS ); - m_acceptsFocus = FALSE; - } - else - { - GTK_WIDGET_SET_FLAGS( m_wxwindow, GTK_CAN_FOCUS ); - m_acceptsFocus = TRUE; - } + GTK_WIDGET_SET_FLAGS( m_wxwindow, GTK_CAN_FOCUS ); + m_acceptsFocus = TRUE; #if (GTK_MINOR_VERSION == 0) // shut the viewport up @@ -2486,18 +2457,6 @@ void wxWindow::SetFocus() { wxCHECK_RET( (m_widget != NULL), wxT("invalid window") ); - wxNode *node = m_children.First(); - while (node) - { - wxWindow *child = (wxWindow*) node->Data(); - if (child->AcceptsFocus()) - { - child->SetFocus(); - return; - } - node = node->Next(); - } - if (m_wxwindow) { gtk_widget_grab_focus (m_wxwindow); diff --git a/src/gtk1/window.cpp b/src/gtk1/window.cpp index 1b7eca62e5..5cc4b89019 100644 --- a/src/gtk1/window.cpp +++ b/src/gtk1/window.cpp @@ -739,9 +739,12 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_e /* win is a control: tab can be propagated up */ if ( (!ret) && ((gdk_event->keyval == GDK_Tab) || (gdk_event->keyval == GDK_ISO_Left_Tab)) && - (win->HasFlag(wxTE_PROCESS_TAB) == 0)) + (!win->HasFlag(wxTE_PROCESS_TAB)) && + (win->GetParent()) && + (win->GetParent()->HasFlag( wxTAB_TRAVERSAL)) ) { wxNavigationKeyEvent new_event; + new_event.SetEventObject( win ); /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */ new_event.SetDirection( (gdk_event->keyval == GDK_Tab) ); /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */ @@ -1295,21 +1298,6 @@ static gint gtk_window_focus_in_callback( GtkWidget *widget, GdkEvent *WXUNUSED( g_focusWindow = win; - if (win->m_wxwindow) - { - if (GTK_WIDGET_CAN_FOCUS(win->m_wxwindow)) - { - GTK_WIDGET_SET_FLAGS (win->m_wxwindow, GTK_HAS_FOCUS); -/* - printf( "SetFocus flag from " ); - if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) - printf( win->GetClassInfo()->GetClassName() ); - printf( ".\n" ); -*/ - } - } - - /* printf( "OnSetFocus from " ); if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) @@ -1319,6 +1307,12 @@ static gint gtk_window_focus_in_callback( GtkWidget *widget, GdkEvent *WXUNUSED( printf( ".\n" ); */ + wxPanel *panel = wxDynamicCast(win->GetParent(), wxPanel); + if (panel) + { + panel->SetLastFocus(win); + } + wxFocusEvent event( wxEVT_SET_FOCUS, win->GetId() ); event.SetEventObject( win ); @@ -1343,12 +1337,6 @@ static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEvent *WXUNUSED if (!win->m_hasVMT) return FALSE; if (g_blockEventsOnDrag) return FALSE; - if (win->m_wxwindow) - { - if (GTK_WIDGET_CAN_FOCUS(win->m_wxwindow)) - GTK_WIDGET_UNSET_FLAGS (win->m_wxwindow, GTK_HAS_FOCUS); - } - /* printf( "OnKillFocus from " ); if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) @@ -1671,13 +1659,6 @@ static void wxInsertChildInWindow( wxWindow* parent, wxWindow* child ) child->m_y, child->m_width, child->m_height ); - - if (parent->HasFlag(wxTAB_TRAVERSAL)) - { - /* we now allow a window to get the focus as long as it - doesn't have any children. */ - GTK_WIDGET_UNSET_FLAGS( parent->m_wxwindow, GTK_CAN_FOCUS ); - } } //----------------------------------------------------------------------------- @@ -1832,18 +1813,8 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id, } #endif // GTK_MINOR_VERSION - if (HasFlag(wxTAB_TRAVERSAL)) - { - /* we now allow a window to get the focus as long as it - doesn't have any children. */ - GTK_WIDGET_SET_FLAGS( m_wxwindow, GTK_CAN_FOCUS ); - m_acceptsFocus = FALSE; - } - else - { - GTK_WIDGET_SET_FLAGS( m_wxwindow, GTK_CAN_FOCUS ); - m_acceptsFocus = TRUE; - } + GTK_WIDGET_SET_FLAGS( m_wxwindow, GTK_CAN_FOCUS ); + m_acceptsFocus = TRUE; #if (GTK_MINOR_VERSION == 0) // shut the viewport up @@ -2486,18 +2457,6 @@ void wxWindow::SetFocus() { wxCHECK_RET( (m_widget != NULL), wxT("invalid window") ); - wxNode *node = m_children.First(); - while (node) - { - wxWindow *child = (wxWindow*) node->Data(); - if (child->AcceptsFocus()) - { - child->SetFocus(); - return; - } - node = node->Next(); - } - if (m_wxwindow) { gtk_widget_grab_focus (m_wxwindow); -- 2.45.2