From b292e2f512fa9b25e2d2928604ab884b00e6c6bf Mon Sep 17 00:00:00 2001 From: Robert Roebling Date: Thu, 17 Dec 1998 08:40:34 +0000 Subject: [PATCH] I've put live into Vadim's wxNavigationKeyEvent idea git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1212 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/generic/listctrl.h | 2 + include/wx/generic/panelg.h | 9 +- include/wx/gtk/control.h | 4 +- include/wx/gtk/notebook.h | 2 +- include/wx/gtk/radiobox.h | 1 + include/wx/gtk/window.h | 15 +- include/wx/gtk1/control.h | 4 +- include/wx/gtk1/notebook.h | 2 +- include/wx/gtk1/radiobox.h | 1 + include/wx/gtk1/window.h | 15 +- samples/checklst/checklst.cpp | 14 +- src/generic/listctrl.cpp | 4 +- src/generic/panelg.cpp | 169 ++++++++------------ src/generic/statusbr.cpp | 2 +- src/gtk/bmpbuttn.cpp | 1 + src/gtk/button.cpp | 57 +++---- src/gtk/checkbox.cpp | 91 +++++------ src/gtk/combobox.cpp | 1 + src/gtk/control.cpp | 23 ++- src/gtk/frame.cpp | 8 + src/gtk/listbox.cpp | 26 ++- src/gtk/notebook.cpp | 289 +++++++++++++++++++--------------- src/gtk/radiobox.cpp | 22 +++ src/gtk/radiobut.cpp | 1 + src/gtk/scrolbar.cpp | 1 + src/gtk/slider.cpp | 1 + src/gtk/textctrl.cpp | 23 ++- src/gtk/window.cpp | 165 +++++++++++++++---- src/gtk1/bmpbuttn.cpp | 1 + src/gtk1/button.cpp | 57 +++---- src/gtk1/checkbox.cpp | 91 +++++------ src/gtk1/combobox.cpp | 1 + src/gtk1/control.cpp | 23 ++- src/gtk1/frame.cpp | 8 + src/gtk1/listbox.cpp | 26 ++- src/gtk1/notebook.cpp | 289 +++++++++++++++++++--------------- src/gtk1/radiobox.cpp | 22 +++ src/gtk1/radiobut.cpp | 1 + src/gtk1/scrolbar.cpp | 1 + src/gtk1/slider.cpp | 1 + src/gtk1/textctrl.cpp | 23 ++- src/gtk1/window.cpp | 165 +++++++++++++++---- 42 files changed, 1038 insertions(+), 624 deletions(-) diff --git a/include/wx/generic/listctrl.h b/include/wx/generic/listctrl.h index b0fd434549..0fd0373086 100644 --- a/include/wx/generic/listctrl.h +++ b/include/wx/generic/listctrl.h @@ -624,6 +624,8 @@ class wxListCtrl: public wxControl else return wxColour(); } bool PopupMenu( wxMenu *menu, int x, int y ) { return m_mainWin->PopupMenu( menu, x, y ); } + void SetFocus() + { m_mainWin->SetFocus(); } // implementation diff --git a/include/wx/generic/panelg.h b/include/wx/generic/panelg.h index 701a0ca000..cf47375852 100644 --- a/include/wx/generic/panelg.h +++ b/include/wx/generic/panelg.h @@ -20,7 +20,7 @@ WXDLLEXPORT_DATA(extern const char*) wxPanelNameStr; -// Dialog boxes + class WXDLLEXPORT wxPanel: public wxWindow { public: @@ -56,17 +56,12 @@ public: // to the dialog via validators. virtual void InitDialog(); - // overriden base class virtuals - virtual void SetFocus(); - - // callbacks // Responds to colour changes void OnSysColourChanged(wxSysColourChangedEvent& event); + // Process a keyboard navigation message (Tab traversal) void OnNavigationKey(wxNavigationKeyEvent& event); -protected: - bool SetFocusToNextChild(wxNode *nodeCurrent = (wxNode *) NULL, bool bForward = TRUE); DECLARE_DYNAMIC_CLASS(wxPanel) DECLARE_EVENT_TABLE() diff --git a/include/wx/gtk/control.h b/include/wx/gtk/control.h index 80cc74b331..d3a164d275 100644 --- a/include/wx/gtk/control.h +++ b/include/wx/gtk/control.h @@ -7,7 +7,6 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// - #ifndef __GTKCONTROLH__ #define __GTKCONTROLH__ @@ -46,10 +45,11 @@ public: // char (the one immediately after '&') into m_chAccel (@@ not yet) virtual void SetLabel( const wxString &label ); virtual wxString GetLabel() const; - + protected: wxString m_label; char m_chAccel; // enabled to avoid breaking binary compatibility later on + }; #endif // __GTKCONTROLH__ diff --git a/include/wx/gtk/notebook.h b/include/wx/gtk/notebook.h index 086aed0175..1c2aa872b9 100644 --- a/include/wx/gtk/notebook.h +++ b/include/wx/gtk/notebook.h @@ -146,7 +146,7 @@ public: // don't delete it yourself). If bSelect, this page becomes active. bool AddPage(wxWindow *pPage, const wxString& strText, - bool bSelect = FALSE, + bool select = FALSE, int imageId = -1); // @@@@ VZ: I don't know how to implement InsertPage() diff --git a/include/wx/gtk/radiobox.h b/include/wx/gtk/radiobox.h index e3984613ee..cfd3a0242a 100644 --- a/include/wx/gtk/radiobox.h +++ b/include/wx/gtk/radiobox.h @@ -80,6 +80,7 @@ class wxRadioBox: public wxControl void SetNumberOfRowsOrCols( int n ); void OnSize( wxSizeEvent &event ); + void SetFocus(); // implementation diff --git a/include/wx/gtk/window.h b/include/wx/gtk/window.h index 339a9d6106..82a4de7e78 100644 --- a/include/wx/gtk/window.h +++ b/include/wx/gtk/window.h @@ -88,6 +88,16 @@ private: wxString m_data; }; +//----------------------------------------------------------------------------- +// (debug) +//----------------------------------------------------------------------------- + +#ifdef __WXDEBUG__ + +void debug_focus_in( GtkWidget* widget, const char* name, const char* window ); + +#endif + //----------------------------------------------------------------------------- // wxWindow //----------------------------------------------------------------------------- @@ -151,9 +161,11 @@ public: virtual void MakeModal( bool modal ); virtual bool IsEnabled() const { return m_isEnabled; } inline bool Enabled() const { return IsEnabled(); } - virtual void SetFocus(); virtual bool OnClose(); + virtual void SetFocus(); + static wxWindow *FindFocus(); + virtual void AddChild( wxWindow *child ); wxList& GetChildren() { return m_children; } @@ -331,6 +343,7 @@ public: GdkGC *m_scrollGC; GtkStyle *m_widgetStyle; bool m_isStaticBox; + bool m_acceptsFocus; wxInsertChildFunction m_insertCallback; diff --git a/include/wx/gtk1/control.h b/include/wx/gtk1/control.h index 80cc74b331..d3a164d275 100644 --- a/include/wx/gtk1/control.h +++ b/include/wx/gtk1/control.h @@ -7,7 +7,6 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// - #ifndef __GTKCONTROLH__ #define __GTKCONTROLH__ @@ -46,10 +45,11 @@ public: // char (the one immediately after '&') into m_chAccel (@@ not yet) virtual void SetLabel( const wxString &label ); virtual wxString GetLabel() const; - + protected: wxString m_label; char m_chAccel; // enabled to avoid breaking binary compatibility later on + }; #endif // __GTKCONTROLH__ diff --git a/include/wx/gtk1/notebook.h b/include/wx/gtk1/notebook.h index 086aed0175..1c2aa872b9 100644 --- a/include/wx/gtk1/notebook.h +++ b/include/wx/gtk1/notebook.h @@ -146,7 +146,7 @@ public: // don't delete it yourself). If bSelect, this page becomes active. bool AddPage(wxWindow *pPage, const wxString& strText, - bool bSelect = FALSE, + bool select = FALSE, int imageId = -1); // @@@@ VZ: I don't know how to implement InsertPage() diff --git a/include/wx/gtk1/radiobox.h b/include/wx/gtk1/radiobox.h index e3984613ee..cfd3a0242a 100644 --- a/include/wx/gtk1/radiobox.h +++ b/include/wx/gtk1/radiobox.h @@ -80,6 +80,7 @@ class wxRadioBox: public wxControl void SetNumberOfRowsOrCols( int n ); void OnSize( wxSizeEvent &event ); + void SetFocus(); // implementation diff --git a/include/wx/gtk1/window.h b/include/wx/gtk1/window.h index 339a9d6106..82a4de7e78 100644 --- a/include/wx/gtk1/window.h +++ b/include/wx/gtk1/window.h @@ -88,6 +88,16 @@ private: wxString m_data; }; +//----------------------------------------------------------------------------- +// (debug) +//----------------------------------------------------------------------------- + +#ifdef __WXDEBUG__ + +void debug_focus_in( GtkWidget* widget, const char* name, const char* window ); + +#endif + //----------------------------------------------------------------------------- // wxWindow //----------------------------------------------------------------------------- @@ -151,9 +161,11 @@ public: virtual void MakeModal( bool modal ); virtual bool IsEnabled() const { return m_isEnabled; } inline bool Enabled() const { return IsEnabled(); } - virtual void SetFocus(); virtual bool OnClose(); + virtual void SetFocus(); + static wxWindow *FindFocus(); + virtual void AddChild( wxWindow *child ); wxList& GetChildren() { return m_children; } @@ -331,6 +343,7 @@ public: GdkGC *m_scrollGC; GtkStyle *m_widgetStyle; bool m_isStaticBox; + bool m_acceptsFocus; wxInsertChildFunction m_insertCallback; diff --git a/samples/checklst/checklst.cpp b/samples/checklst/checklst.cpp index 5cd439384c..8310a8aa91 100644 --- a/samples/checklst/checklst.cpp +++ b/samples/checklst/checklst.cpp @@ -24,9 +24,15 @@ #include "wx/wx.h" #endif +#ifdef __WXMSW__ #include "wx/ownerdrw.h" +#endif #include "wx/menuitem.h" -#include "wx/msw/checklst.h" +#include "wx/checklst.h" + +#ifdef __WXGTK__ +#include "mondrian.xpm" +#endif // Define a new application type class CheckListBoxApp: public wxApp @@ -89,7 +95,7 @@ CheckListBoxFrame::CheckListBoxFrame(wxFrame *frame, char *title, int x, int y, : wxFrame(frame, -1, title, wxPoint(x, y), wxSize(w, h)) { // set the icon - SetIcon(wxIcon("mondrian")); + SetIcon(wxICON(mondrian)); // Make a menubar wxMenu *file_menu = new wxMenu; @@ -127,9 +133,11 @@ CheckListBoxFrame::CheckListBoxFrame(wxFrame *frame, char *title, int x, int y, delete [] astrChoices; +#ifdef __WXMSW__ for ( ui = 0; ui < WXSIZEOF(aszChoices); ui += 2 ) { m_pListBox->GetItem(ui)->SetBackgroundColour(wxColor(200, 200, 200)); } +#endif m_pListBox->Check(2); @@ -163,7 +171,7 @@ void CheckListBoxFrame::OnListboxSelect(wxCommandEvent& event) wxString strSelection; unsigned int nSel = event.GetSelection(); strSelection.sprintf("item %d selected (%schecked)", nSel, - m_pListBox->IsChecked(nSel) ? "" : "not "); + m_pListBox->IsChecked((int)nSel) ? "" : "not "); SetStatusText(strSelection); } diff --git a/src/generic/listctrl.cpp b/src/generic/listctrl.cpp index 7e2bbc8391..47febe9e3e 100644 --- a/src/generic/listctrl.cpp +++ b/src/generic/listctrl.cpp @@ -2301,7 +2301,7 @@ bool wxListCtrl::Create( wxWindow *parent, wxWindowID id, m_mainWin = new wxListMainWindow( this, -1, wxPoint(0,0), size, s ); if (GetWindowStyleFlag() & wxLC_REPORT) - m_headerWin = new wxListHeaderWindow( this, -1, m_mainWin, wxPoint(0,0), wxSize(size.x,23) ); + m_headerWin = new wxListHeaderWindow( this, -1, m_mainWin, wxPoint(0,0), wxSize(size.x,23), wxTAB_TRAVERSAL ); else m_headerWin = (wxListHeaderWindow *) NULL; @@ -2355,7 +2355,7 @@ void wxListCtrl::SetWindowStyleFlag( long flag ) // m_mainWin->SetSize( 0, 24, width, height-24 ); if (!m_headerWin) { - m_headerWin = new wxListHeaderWindow( this, -1, m_mainWin, wxPoint(0,0), wxSize(width,23) ); + m_headerWin = new wxListHeaderWindow( this, -1, m_mainWin, wxPoint(0,0), wxSize(width,23), wxTAB_TRAVERSAL ); } else { diff --git a/src/generic/panelg.cpp b/src/generic/panelg.cpp index 70006c5ea0..8f3f3daab9 100644 --- a/src/generic/panelg.cpp +++ b/src/generic/panelg.cpp @@ -46,28 +46,24 @@ bool wxPanel::Create(wxWindow *parent, wxWindowID id, long style, const wxString& name) { - bool ret = wxWindow::Create(parent, id, pos, size, style, name); + bool ret = wxWindow::Create(parent, id, pos, size, style, name); - if ( ret ) { + if ( ret ) + { #ifndef __WXGTK__ - SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE)); - SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT)); + SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE)); + SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT)); #endif - } + } - return ret; + return ret; } void wxPanel::InitDialog(void) { - wxInitDialogEvent event(GetId()); - event.SetEventObject(this); - GetEventHandler()->ProcessEvent(event); -} - -void wxPanel::SetFocus() -{ - SetFocusToNextChild(); + wxInitDialogEvent event(GetId()); + event.SetEventObject(this); + GetEventHandler()->ProcessEvent(event); } // Responds to colour changes, and passes event on to children. @@ -80,97 +76,68 @@ void wxPanel::OnSysColourChanged(wxSysColourChangedEvent& event) wxWindow::OnSysColourChanged(event); } -void wxPanel::OnNavigationKey(wxNavigationKeyEvent& event) -{ - // don't process these ones here - if ( event.IsWindowChange() ) { - event.Skip(); - return; - } - - // first of all, find the window which currently has the focus - wxNode *node = GetChildren().First(); - wxWindow *winFocus = event.GetCurrentFocus(); - - // @@@ no FindFocus() in wxGTK - #ifndef __WXGTK__ - if ( winFocus == NULL ) - winFocus = wxWindow::FindFocus(); - #endif - - while ( node != NULL ) { - if ( node->Data() == winFocus ) - break; - - node = node->Next(); - } - - if ( !SetFocusToNextChild(node, event.GetDirection()) ) - event.Skip(); -} - -// set focus to the next child which accepts it (or first/last if node == NULL) -bool wxPanel::SetFocusToNextChild(wxNode *node, bool bForward) +void wxPanel::OnNavigationKey( wxNavigationKeyEvent& event ) { - // @@ using typed list would be better... - #define WIN(node) ((wxWindow *)(node->Data())) - - bool bFound = FALSE; // have we found a window we will set focus to? - - wxList *children = & GetChildren(); - if ( node == NULL ) { - // we've never had focus before - node = bForward ? children->First() : children->Last(); - if ( node == NULL ) { - // no children - return FALSE; + if (m_children.GetCount() < 2) + { + event.Skip(); + return; } - bFound = WIN(node)->AcceptsFocus(); - } -#if 0 // to restore when it will really work (now it's triggered all the time) - else { - // just to be sure it's the right one - wxASSERT( WIN(node)->AcceptsFocus() ); - } -#endif // 0 - - // find the next child which accepts focus - bool bParentWantsIt = TRUE; - while ( !bFound ) { - node = bForward ? node->Next() : node->Previous(); - if ( node == NULL ) { - if ( !bParentWantsIt ) { - // we've already been here which means that we've done a whole - // cycle without success - get out from the infinite loop - return FALSE; - } - - // ask parent if he doesn't want to advance focus to the next panel - if ( GetParent() != NULL ) { - wxNavigationKeyEvent event; - event.SetDirection(bForward); - event.SetWindowChange(FALSE); - event.SetCurrentFocus(this); - - if ( GetParent()->ProcessEvent(event) ) - return TRUE; - } - - // a sentinel to avoid infinite loops - bParentWantsIt = FALSE; - - // wrap around - node = bForward ? children->First() : children->Last(); + // don't process these ones here + if (event.IsWindowChange()) + { + event.Skip(); + return; } - bFound = WIN(node)->AcceptsFocus(); - } - - WIN(node)->SetFocus(); - - #undef WIN - - return TRUE; + wxWindow *winFocus = event.GetCurrentFocus(); + if (!winFocus) winFocus = wxWindow::FindFocus(); + + if (!winFocus) + { + event.Skip(); + return; + } + + wxNode *start_node = m_children.Find( winFocus ); + if (!start_node) start_node = m_children.First(); + + wxNode *node = event.GetDirection() ? start_node->Next() : start_node->Previous(); + + while (node != start_node) + { + if (!node) + { +/* + if (GetParent() != NULL) + { + wxNavigationKeyEvent new_event; + new_event.SetDirection( event.GetDirection() ); + new_event.SetWindowChange(FALSE); + new_event.SetCurrentFocus( this ); + + if (GetParent()->GetEventHandler()->ProcessEvent(new_event)) + { + return; + } + } +*/ + + node = event.GetDirection() ? m_children.First() : m_children.Last(); + } + + wxWindow *child = (wxWindow*) node->Data(); + + if (child->AcceptsFocus()) + { + child->SetFocus(); + return; + } + + node = node->Next(); + } + + event.Skip(); } diff --git a/src/generic/statusbr.cpp b/src/generic/statusbr.cpp index 01321e734a..683752e0b1 100644 --- a/src/generic/statusbr.cpp +++ b/src/generic/statusbr.cpp @@ -84,7 +84,7 @@ bool wxStatusBar::Create(wxWindow *parent, wxWindowID id, m_borderX = wxTHICK_LINE_BORDER; m_borderY = wxTHICK_LINE_BORDER; - bool success = wxWindow::Create(parent, id, pos, size, style, name); + bool success = wxWindow::Create(parent, id, pos, size, style | wxTAB_TRAVERSAL, name); // Don't wish this to be found as a child parent->GetChildren().DeleteObject(this); diff --git a/src/gtk/bmpbuttn.cpp b/src/gtk/bmpbuttn.cpp index bf155fb4fc..cd10cf260c 100644 --- a/src/gtk/bmpbuttn.cpp +++ b/src/gtk/bmpbuttn.cpp @@ -102,6 +102,7 @@ bool wxBitmapButton::Create( wxWindow *parent, wxWindowID id, const wxBitmap &bi long style, const wxValidator& validator, const wxString &name ) { m_needParent = TRUE; + m_acceptsFocus = TRUE; wxSize newSize = size; diff --git a/src/gtk/button.cpp b/src/gtk/button.cpp index 8338f5bcff..8980bb0301 100644 --- a/src/gtk/button.cpp +++ b/src/gtk/button.cpp @@ -58,37 +58,38 @@ bool wxButton::Create( wxWindow *parent, wxWindowID id, const wxString &label, const wxPoint &pos, const wxSize &size, long style, const wxValidator& validator, const wxString &name ) { - m_clientData = (wxClientData*) NULL; - m_needParent = TRUE; + m_clientData = (wxClientData*) NULL; + m_needParent = TRUE; + m_acceptsFocus = TRUE; - wxSize newSize = size; + wxSize newSize = size; - PreCreation( parent, id, pos, newSize, style, name ); + PreCreation( parent, id, pos, newSize, style, name ); - SetValidator( validator ); + SetValidator( validator ); - m_widget = gtk_button_new_with_label( m_label ); - SetLabel(label); + m_widget = gtk_button_new_with_label( m_label ); + SetLabel(label); - if (newSize.x == -1) newSize.x = 15+gdk_string_measure( m_widget->style->font, label ); - if (newSize.y == -1) newSize.y = 26; - SetSize( newSize.x, newSize.y ); + if (newSize.x == -1) newSize.x = 15+gdk_string_measure( m_widget->style->font, label ); + if (newSize.y == -1) newSize.y = 26; + SetSize( newSize.x, newSize.y ); - gtk_signal_connect( GTK_OBJECT(m_widget), "clicked", - GTK_SIGNAL_FUNC(gtk_button_clicked_callback), (gpointer*)this ); + gtk_signal_connect( GTK_OBJECT(m_widget), "clicked", + GTK_SIGNAL_FUNC(gtk_button_clicked_callback), (gpointer*)this ); - m_parent->AddChild( this ); + m_parent->AddChild( this ); - (m_parent->m_insertCallback)( m_parent, this ); + (m_parent->m_insertCallback)( m_parent, this ); - PostCreation(); + PostCreation(); - SetBackgroundColour( parent->GetBackgroundColour() ); - SetForegroundColour( parent->GetForegroundColour() ); + SetBackgroundColour( parent->GetBackgroundColour() ); + SetForegroundColour( parent->GetForegroundColour() ); - Show( TRUE ); + Show( TRUE ); - return TRUE; + return TRUE; } void wxButton::SetDefault(void) @@ -101,27 +102,27 @@ void wxButton::SetDefault(void) void wxButton::SetLabel( const wxString &label ) { - wxCHECK_RET( m_widget != NULL, "invalid button" ); + wxCHECK_RET( m_widget != NULL, "invalid button" ); - wxControl::SetLabel( label ); + wxControl::SetLabel( label ); - gtk_label_set( GTK_LABEL( GTK_BUTTON(m_widget)->child ), GetLabel() ); + gtk_label_set( GTK_LABEL( GTK_BUTTON(m_widget)->child ), GetLabel() ); } void wxButton::Enable( bool enable ) { - wxCHECK_RET( m_widget != NULL, "invalid button" ); + wxCHECK_RET( m_widget != NULL, "invalid button" ); - wxControl::Enable( enable ); + wxControl::Enable( enable ); - gtk_widget_set_sensitive( GTK_BUTTON(m_widget)->child, enable ); + gtk_widget_set_sensitive( GTK_BUTTON(m_widget)->child, enable ); } void wxButton::ApplyWidgetStyle() { - SetWidgetStyle(); - gtk_widget_set_style( m_widget, m_widgetStyle ); - gtk_widget_set_style( GTK_BUTTON(m_widget)->child, m_widgetStyle ); + SetWidgetStyle(); + gtk_widget_set_style( m_widget, m_widgetStyle ); + gtk_widget_set_style( GTK_BUTTON(m_widget)->child, m_widgetStyle ); } diff --git a/src/gtk/checkbox.cpp b/src/gtk/checkbox.cpp index 6e94fdfceb..daafd5f43f 100644 --- a/src/gtk/checkbox.cpp +++ b/src/gtk/checkbox.cpp @@ -26,20 +26,20 @@ extern bool g_blockEventsOnDrag; static void gtk_checkbox_clicked_callback( GtkWidget *WXUNUSED(widget), wxCheckBox *cb ) { - if (!cb->HasVMT()) return; + if (!cb->HasVMT()) return; - if (cb->m_blockFirstEvent) - { - cb->m_blockFirstEvent = FALSE; - return; - } + if (cb->m_blockFirstEvent) + { + cb->m_blockFirstEvent = FALSE; + return; + } - if (g_blockEventsOnDrag) return; + if (g_blockEventsOnDrag) return; - wxCommandEvent event(wxEVT_COMMAND_CHECKBOX_CLICKED, cb->GetId()); - event.SetInt( cb->GetValue() ); - event.SetEventObject(cb); - cb->GetEventHandler()->ProcessEvent(event); + wxCommandEvent event(wxEVT_COMMAND_CHECKBOX_CLICKED, cb->GetId()); + event.SetInt( cb->GetValue() ); + event.SetEventObject(cb); + cb->GetEventHandler()->ProcessEvent(event); } //----------------------------------------------------------------------------- @@ -56,81 +56,82 @@ bool wxCheckBox::Create( wxWindow *parent, wxWindowID id, const wxString &label const wxPoint &pos, const wxSize &size, long style, const wxValidator& validator, const wxString &name ) { - m_needParent = TRUE; + m_needParent = TRUE; + m_acceptsFocus = TRUE; - PreCreation( parent, id, pos, size, style, name ); + PreCreation( parent, id, pos, size, style, name ); - SetValidator( validator ); + SetValidator( validator ); - m_widget = gtk_check_button_new_with_label( m_label ); + m_widget = gtk_check_button_new_with_label( m_label ); - m_blockFirstEvent = FALSE; + m_blockFirstEvent = FALSE; - wxSize newSize = size; - if (newSize.x == -1) newSize.x = 25+gdk_string_measure( m_widget->style->font, label ); - if (newSize.y == -1) newSize.y = 26; - SetSize( newSize.x, newSize.y ); + wxSize newSize = size; + if (newSize.x == -1) newSize.x = 25+gdk_string_measure( m_widget->style->font, label ); + if (newSize.y == -1) newSize.y = 26; + SetSize( newSize.x, newSize.y ); - gtk_signal_connect( GTK_OBJECT(m_widget), "clicked", - GTK_SIGNAL_FUNC(gtk_checkbox_clicked_callback), (gpointer*)this ); + gtk_signal_connect( GTK_OBJECT(m_widget), "clicked", + GTK_SIGNAL_FUNC(gtk_checkbox_clicked_callback), (gpointer*)this ); - m_parent->AddChild( this ); + m_parent->AddChild( this ); - (m_parent->m_insertCallback)( m_parent, this ); + (m_parent->m_insertCallback)( m_parent, this ); - PostCreation(); + PostCreation(); - gtk_widget_realize( GTK_BUTTON( m_widget )->child ); + gtk_widget_realize( GTK_BUTTON( m_widget )->child ); - SetLabel( label ); + SetLabel( label ); - SetBackgroundColour( parent->GetBackgroundColour() ); - SetForegroundColour( parent->GetForegroundColour() ); + SetBackgroundColour( parent->GetBackgroundColour() ); + SetForegroundColour( parent->GetForegroundColour() ); - Show( TRUE ); + Show( TRUE ); - return TRUE; + return TRUE; } void wxCheckBox::SetValue( bool state ) { - wxCHECK_RET( m_widget != NULL, "invalid checkbox" ); + wxCHECK_RET( m_widget != NULL, "invalid checkbox" ); - m_blockFirstEvent = TRUE; + m_blockFirstEvent = TRUE; - gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(m_widget), state ); + gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(m_widget), state ); } bool wxCheckBox::GetValue() const { - wxCHECK_MSG( m_widget != NULL, FALSE, "invalid checkbox" ); + wxCHECK_MSG( m_widget != NULL, FALSE, "invalid checkbox" ); - return GTK_TOGGLE_BUTTON(m_widget)->active; + return GTK_TOGGLE_BUTTON(m_widget)->active; } void wxCheckBox::SetLabel( const wxString& label ) { - wxCHECK_RET( m_widget != NULL, "invalid checkbox" ); + wxCHECK_RET( m_widget != NULL, "invalid checkbox" ); - wxControl::SetLabel( label ); + wxControl::SetLabel( label ); - gtk_label_set( GTK_LABEL( GTK_BUTTON(m_widget)->child ), GetLabel() ); + gtk_label_set( GTK_LABEL( GTK_BUTTON(m_widget)->child ), GetLabel() ); } void wxCheckBox::Enable( bool enable ) { - wxCHECK_RET( m_widget != NULL, "invalid checkbox" ); + wxCHECK_RET( m_widget != NULL, "invalid checkbox" ); - wxControl::Enable( enable ); + wxControl::Enable( enable ); - gtk_widget_set_sensitive( GTK_BUTTON(m_widget)->child, enable ); + gtk_widget_set_sensitive( GTK_BUTTON(m_widget)->child, enable ); } void wxCheckBox::ApplyWidgetStyle() { - SetWidgetStyle(); - gtk_widget_set_style( m_widget, m_widgetStyle ); - gtk_widget_set_style( GTK_BUTTON(m_widget)->child, m_widgetStyle ); + SetWidgetStyle(); + gtk_widget_set_style( m_widget, m_widgetStyle ); + gtk_widget_set_style( GTK_BUTTON(m_widget)->child, m_widgetStyle ); } diff --git a/src/gtk/combobox.cpp b/src/gtk/combobox.cpp index 7a1e8412b9..ae8b352156 100644 --- a/src/gtk/combobox.cpp +++ b/src/gtk/combobox.cpp @@ -63,6 +63,7 @@ bool wxComboBox::Create( wxWindow *parent, wxWindowID id, const wxString& value, { m_alreadySent = FALSE; m_needParent = TRUE; + m_acceptsFocus = TRUE; PreCreation( parent, id, pos, size, style, name ); diff --git a/src/gtk/control.cpp b/src/gtk/control.cpp index c9064a3413..4b04d0bb37 100644 --- a/src/gtk/control.cpp +++ b/src/gtk/control.cpp @@ -21,7 +21,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxControl,wxWindow) wxControl::wxControl(void) { - m_needParent = TRUE; + m_needParent = TRUE; } wxControl::wxControl( wxWindow *parent, wxWindowID id, @@ -37,24 +37,23 @@ void wxControl::Command( wxCommandEvent &WXUNUSED(event) ) void wxControl::SetLabel( const wxString &label ) { - m_label = ""; - for ( const char *pc = label; *pc != '\0'; pc++ ) { - if ( *pc == '&' ) { - pc++; // skip it + m_label = ""; + for ( const char *pc = label; *pc != '\0'; pc++ ) + { + if ( *pc == '&' ) + { + pc++; // skip it #if 0 // it would be unused anyhow for now - kbd interface not done yet - if ( *pc != '&' ) - m_chAccel = *pc; + if ( *pc != '&' ) m_chAccel = *pc; #endif + } + m_label << *pc; } - - m_label << *pc; - } } wxString wxControl::GetLabel(void) const { - return m_label; + return m_label; } - diff --git a/src/gtk/frame.cpp b/src/gtk/frame.cpp index 8d0d64c9ca..ae11c5097e 100644 --- a/src/gtk/frame.cpp +++ b/src/gtk/frame.cpp @@ -142,6 +142,10 @@ bool wxFrame::Create( wxWindow *parent, wxWindowID id, const wxString &title, m_widget = gtk_window_new( win_type ); +#ifdef __WXDEBUG__ + debug_focus_in( m_widget, "wxFrame::m_widget", name ); +#endif + if ((size.x != -1) && (size.y != -1)) gtk_widget_set_usize( m_widget, m_width, m_height ); if ((pos.x != -1) && (pos.y != -1)) @@ -159,6 +163,10 @@ bool wxFrame::Create( wxWindow *parent, wxWindowID id, const wxString &title, gtk_widget_show( m_wxwindow ); GTK_WIDGET_UNSET_FLAGS( m_wxwindow, GTK_CAN_FOCUS ); +#ifdef __WXDEBUG__ + debug_focus_in( m_wxwindow, "wxFrame::m_wxwindow", name ); +#endif + gtk_container_add( GTK_CONTAINER(m_widget), m_wxwindow ); gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate", diff --git a/src/gtk/listbox.cpp b/src/gtk/listbox.cpp index 22d401bd8a..a9ef5ae287 100644 --- a/src/gtk/listbox.cpp +++ b/src/gtk/listbox.cpp @@ -130,6 +130,7 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id, long style, const wxValidator& validator, const wxString &name ) { m_needParent = TRUE; + m_acceptsFocus = TRUE; PreCreation( parent, id, pos, size, style, name ); @@ -138,7 +139,7 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id, m_widget = gtk_scrolled_window_new( (GtkAdjustment*) NULL, (GtkAdjustment*) NULL ); gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(m_widget), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC ); - + m_list = GTK_LIST( gtk_list_new() ); GtkSelectionMode mode = GTK_SELECTION_BROWSE; @@ -155,6 +156,25 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id, gtk_container_add( GTK_CONTAINER(m_widget), GTK_WIDGET(m_list) ); #endif +#ifdef __WXDEBUG__ + debug_focus_in( m_widget, "wxListBox::m_widget", name ); + + debug_focus_in( GTK_WIDGET(m_list), "wxListBox::m_list", name ); + + GtkScrolledWindow *s_window = GTK_SCROLLED_WINDOW(m_widget); + + debug_focus_in( s_window->hscrollbar, "wxWindow::hsrcollbar", name ); + debug_focus_in( s_window->vscrollbar, "wxWindow::vsrcollbar", name ); + +#ifdef NEW_GTK_SCROLL_CODE + GtkViewport *viewport = GTK_VIEWPORT(s_window->child); +#else + GtkViewport *viewport = GTK_VIEWPORT(s_window->viewport); +#endif + + debug_focus_in( GTK_WIDGET(viewport), "wxWindow::viewport", name ); +#endif + gtk_widget_show( GTK_WIDGET(m_list) ); wxSize newSize = size; @@ -180,6 +200,10 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id, list_item = gtk_list_item_new_with_label( choices[i] ); } +#ifdef __WXDEBUG__ + debug_focus_in( list_item, "wxListBox::list_item", name ); +#endif + gtk_container_add( GTK_CONTAINER(m_list), list_item ); gtk_signal_connect( GTK_OBJECT(list_item), "select", diff --git a/src/gtk/notebook.cpp b/src/gtk/notebook.cpp index ca9146b045..b74e19d4de 100644 --- a/src/gtk/notebook.cpp +++ b/src/gtk/notebook.cpp @@ -17,6 +17,13 @@ #include "wx/imaglist.h" #include "wx/intl.h" #include "wx/log.h" +#include "gdk/gdkkeysyms.h" + +//----------------------------------------------------------------------------- +// data +//----------------------------------------------------------------------------- + +extern bool g_blockEventsOnDrag; //----------------------------------------------------------------------------- // wxNotebookPage @@ -72,16 +79,16 @@ static void gtk_notebook_page_change_callback(GtkNotebook *WXUNUSED(widget), gint nPage, gpointer data) { - wxNotebook *notebook = (wxNotebook *)data; + wxNotebook *notebook = (wxNotebook *)data; - int old = notebook->GetSelection(); + int old = notebook->GetSelection(); - // TODO: emulate PAGE_CHANGING event + // TODO: emulate PAGE_CHANGING event - wxNotebookEvent event( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, - notebook->GetId(), nPage, old ); - event.SetEventObject( notebook ); - notebook->GetEventHandler()->ProcessEvent( event ); + wxNotebookEvent event( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, + notebook->GetId(), nPage, old ); + event.SetEventObject( notebook ); + notebook->GetEventHandler()->ProcessEvent( event ); } //----------------------------------------------------------------------------- @@ -90,17 +97,48 @@ static void gtk_notebook_page_change_callback(GtkNotebook *WXUNUSED(widget), static void gtk_page_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxWindow *win ) { - if ((win->m_x == alloc->x) && - (win->m_y == alloc->y) && - (win->m_width == alloc->width) && - (win->m_height == alloc->height)) - { - return; - } + if ((win->m_x == alloc->x) && + (win->m_y == alloc->y) && + (win->m_width == alloc->width) && + (win->m_height == alloc->height)) + { + return; + } - win->SetSize( alloc->x, alloc->y, alloc->width, alloc->height ); + win->SetSize( alloc->x, alloc->y, alloc->width, alloc->height ); - if (win->GetAutoLayout()) win->Layout(); + if (win->GetAutoLayout()) win->Layout(); +} + +//----------------------------------------------------------------------------- +// "key_press_event" +//----------------------------------------------------------------------------- + +static gint +gtk_notebook_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_event, wxNotebook *notebook ) +{ + if (g_blockEventsOnDrag) return FALSE; + + if (!notebook->HasVMT()) return FALSE; + + if (gdk_event->keyval != GDK_Down) return FALSE; + + if (notebook != notebook->FindFocus()) return FALSE; + + if (notebook->m_pages.GetCount() == 0) return FALSE; + + wxNode *node = notebook->m_pages.Nth( notebook->GetSelection() ); + + if (!node) return FALSE; + + wxNotebookPage *page = (wxNotebookPage*) node->Data(); + + // don't let others the key event + gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "key_press_event" ); + + page->m_client->SetFocus(); + + return TRUE; } //----------------------------------------------------------------------------- @@ -109,32 +147,28 @@ static void gtk_page_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* static void wxInsertChildInNotebook( wxNotebook* parent, wxWindow* child ) { - wxNotebookPage *page = new wxNotebookPage(); + wxNotebookPage *page = new wxNotebookPage(); - page->m_id = parent->GetPageCount(); + page->m_id = parent->GetPageCount(); - page->m_box = gtk_hbox_new (FALSE, 0); - gtk_container_border_width(GTK_CONTAINER(page->m_box), 2); + page->m_box = gtk_hbox_new (FALSE, 0); + gtk_container_border_width(GTK_CONTAINER(page->m_box), 2); - GtkNotebook *notebook = GTK_NOTEBOOK(parent->m_widget); + GtkNotebook *notebook = GTK_NOTEBOOK(parent->m_widget); - page->m_client = child; - gtk_notebook_append_page( notebook, child->m_widget, page->m_box ); + page->m_client = child; + gtk_notebook_append_page( notebook, child->m_widget, page->m_box ); - page->m_page = (GtkNotebookPage*) (g_list_last(notebook->children)->data); + page->m_page = (GtkNotebookPage*) (g_list_last(notebook->children)->data); - page->m_parent = notebook; + page->m_parent = notebook; - gtk_signal_connect( GTK_OBJECT(child->m_widget), "size_allocate", - GTK_SIGNAL_FUNC(gtk_page_size_callback), (gpointer)child ); + gtk_signal_connect( GTK_OBJECT(child->m_widget), "size_allocate", + GTK_SIGNAL_FUNC(gtk_page_size_callback), (gpointer)child ); - if (!page->m_page) - { - wxLogFatalError( "Notebook page creation error" ); - return; - } + wxASSERT_MSG( page->m_page, "Notebook page creation error" ); - parent->m_pages.Append( page ); + parent->m_pages.Append( page ); } //----------------------------------------------------------------------------- @@ -145,155 +179,164 @@ IMPLEMENT_DYNAMIC_CLASS(wxNotebook,wxControl) void wxNotebook::Init() { - m_imageList = (wxImageList *) NULL; - m_pages.DeleteContents( TRUE ); - m_idHandler = 0; + m_imageList = (wxImageList *) NULL; + m_pages.DeleteContents( TRUE ); + m_idHandler = 0; } wxNotebook::wxNotebook() { - Init(); + Init(); } wxNotebook::wxNotebook( wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) { - Init(); - Create( parent, id, pos, size, style, name ); + Init(); + Create( parent, id, pos, size, style, name ); } wxNotebook::~wxNotebook() { - // don't generate change page events any more - if (m_idHandler != 0) - gtk_signal_disconnect(GTK_OBJECT(m_widget), m_idHandler); + // don't generate change page events any more + if (m_idHandler != 0) + gtk_signal_disconnect(GTK_OBJECT(m_widget), m_idHandler); - DeleteAllPages(); + DeleteAllPages(); } bool wxNotebook::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) { - m_needParent = TRUE; - m_insertCallback = (wxInsertChildFunction)wxInsertChildInNotebook; + m_needParent = TRUE; + m_acceptsFocus = TRUE; + m_insertCallback = (wxInsertChildFunction)wxInsertChildInNotebook; + + PreCreation( parent, id, pos, size, style, name ); - PreCreation( parent, id, pos, size, style, name ); + m_widget = gtk_notebook_new(); - m_widget = gtk_notebook_new(); +#ifdef __WXDEBUG__ + debug_focus_in( m_widget, "wxNotebook::m_widget", name ); +#endif - gtk_notebook_set_scrollable( GTK_NOTEBOOK(m_widget), 1 ); + gtk_notebook_set_scrollable( GTK_NOTEBOOK(m_widget), 1 ); - m_idHandler = gtk_signal_connect ( + m_idHandler = gtk_signal_connect ( GTK_OBJECT(m_widget), "switch_page", GTK_SIGNAL_FUNC(gtk_notebook_page_change_callback), (gpointer)this ); - m_parent->AddChild( this ); + m_parent->AddChild( this ); - (m_parent->m_insertCallback)( m_parent, this ); + (m_parent->m_insertCallback)( m_parent, this ); - PostCreation(); + gtk_signal_connect( GTK_OBJECT(m_widget), "key_press_event", + GTK_SIGNAL_FUNC(gtk_notebook_key_press_callback), (gpointer)this ); - Show( TRUE ); + PostCreation(); - return TRUE; + Show( TRUE ); + + return TRUE; } int wxNotebook::GetSelection() const { - wxCHECK_MSG( m_widget != NULL, -1, "invalid notebook" ); - - if (m_pages.Number() == 0) return -1; + wxCHECK_MSG( m_widget != NULL, -1, "invalid notebook" ); - GtkNotebookPage *g_page = GTK_NOTEBOOK(m_widget)->cur_page; - if (!g_page) return -1; + if (m_pages.Number() == 0) return -1; - wxNotebookPage *page = (wxNotebookPage *) NULL; + GtkNotebookPage *g_page = GTK_NOTEBOOK(m_widget)->cur_page; + if (!g_page) return -1; - wxNode *node = m_pages.First(); - while (node) - { - page = (wxNotebookPage*)node->Data(); + wxNotebookPage *page = (wxNotebookPage *) NULL; - if ((page->m_page == g_page) || (page->m_page == (GtkNotebookPage*)NULL)) + wxNode *node = m_pages.First(); + while (node) { - // page->m_page is NULL directly after gtk_notebook_append. gtk emits - // "switch_page" then and we ask for GetSelection() in the handler for - // "switch_page". otherwise m_page should never be NULL. all this - // might also be wrong. - break; + page = (wxNotebookPage*)node->Data(); + + if ((page->m_page == g_page) || (page->m_page == (GtkNotebookPage*)NULL)) + { + // page->m_page is NULL directly after gtk_notebook_append. gtk emits + // "switch_page" then and we ask for GetSelection() in the handler for + // "switch_page". otherwise m_page should never be NULL. all this + // might also be wrong. + break; + } + node = node->Next(); } - node = node->Next(); - } - wxCHECK_MSG( node != NULL, -1, "wxNotebook: no selection?" ); + wxCHECK_MSG( node != NULL, -1, "wxNotebook: no selection?" ); - return page->m_id; + return page->m_id; } int wxNotebook::GetPageCount() const { - // count only the pages which were already added to the notebook for MSW - // compatibility (and, in fact, this behaviour makes more sense anyhow - // because only the added pages are shown) - int n = 0; - for ( wxNode *node = m_pages.First(); node; node = node->Next() ) - { - wxNotebookPage *page = (wxNotebookPage*)node->Data(); - if ( page->WasAdded() ) - n++; - } + // count only the pages which were already added to the notebook for MSW + // compatibility (and, in fact, this behaviour makes more sense anyhow + // because only the added pages are shown) + + int n = 0; + for ( wxNode *node = m_pages.First(); node; node = node->Next() ) + { + wxNotebookPage *page = (wxNotebookPage*)node->Data(); + + if (page->WasAdded()) n++; + } - return n; + return n; } int wxNotebook::GetRowCount() const { - return 1; + return 1; } wxString wxNotebook::GetPageText( int page ) const { - wxCHECK_MSG( m_widget != NULL, "", "invalid notebook" ); + wxCHECK_MSG( m_widget != NULL, "", "invalid notebook" ); - wxNotebookPage* nb_page = GetNotebookPage(page); - if (nb_page) - return nb_page->m_text; - else - return ""; + wxNotebookPage* nb_page = GetNotebookPage(page); + if (nb_page) + return nb_page->m_text; + else + return ""; } int wxNotebook::GetPageImage( int page ) const { - wxCHECK_MSG( m_widget != NULL, 0, "invalid notebook" ); + wxCHECK_MSG( m_widget != NULL, 0, "invalid notebook" ); - wxNotebookPage* nb_page = GetNotebookPage(page); - if (nb_page) - return nb_page->m_image; - else - return 0; + wxNotebookPage* nb_page = GetNotebookPage(page); + if (nb_page) + return nb_page->m_image; + else + return 0; } wxNotebookPage* wxNotebook::GetNotebookPage(int page) const { - wxCHECK_MSG( m_widget != NULL, (wxNotebookPage*)NULL, "invalid notebook" ); + wxCHECK_MSG( m_widget != NULL, (wxNotebookPage*)NULL, "invalid notebook" ); - wxNotebookPage *nb_page = (wxNotebookPage *) NULL; + wxNotebookPage *nb_page = (wxNotebookPage *) NULL; - wxNode *node = m_pages.First(); - while (node) - { - nb_page = (wxNotebookPage*)node->Data(); - if (nb_page->m_id == page) - return nb_page; - node = node->Next(); - } + wxNode *node = m_pages.First(); + while (node) + { + nb_page = (wxNotebookPage*)node->Data(); + if (nb_page->m_id == page) + return nb_page; + node = node->Next(); + } - wxLogDebug( "Notebook page %d not found!", page ); + wxFAIL_MSG( "Notebook page not found!" ); - return (wxNotebookPage *) NULL; + return (wxNotebookPage *) NULL; } int wxNotebook::SetSelection( int page ) @@ -437,7 +480,7 @@ bool wxNotebook::RemovePage( int page ) } bool wxNotebook::AddPage(wxWindow* win, const wxString& text, - bool bSelect, int imageId) + bool select, int imageId) { wxCHECK_MSG( m_widget != NULL, FALSE, "invalid notebook" ); @@ -491,38 +534,38 @@ bool wxNotebook::AddPage(wxWindow* win, const wxString& text, gtk_widget_show((GtkWidget *)page->m_label); - if (bSelect) SetSelection(GetPageCount()); + if (select) SetSelection( GetPageCount()-1 ); return TRUE; } wxWindow *wxNotebook::GetPage( int page ) const { - wxCHECK_MSG( m_widget != NULL, (wxWindow*) NULL, "invalid notebook" ); + wxCHECK_MSG( m_widget != NULL, (wxWindow*) NULL, "invalid notebook" ); - wxNotebookPage* nb_page = GetNotebookPage(page); - if (!nb_page) - return (wxWindow *) NULL; - else - return nb_page->m_client; + wxNotebookPage* nb_page = GetNotebookPage(page); + if (!nb_page) + return (wxWindow *) NULL; + else + return nb_page->m_client; } // override these 2 functions to do nothing: everything is done in OnSize void wxNotebook::SetConstraintSizes( bool WXUNUSED(recurse) ) { - // don't set the sizes of the pages - their correct size is not yet known - wxControl::SetConstraintSizes(FALSE); + // don't set the sizes of the pages - their correct size is not yet known + wxControl::SetConstraintSizes(FALSE); } bool wxNotebook::DoPhase( int WXUNUSED(nPhase) ) { - return TRUE; + return TRUE; } void wxNotebook::ApplyWidgetStyle() { - SetWidgetStyle(); - gtk_widget_set_style( m_widget, m_widgetStyle ); + SetWidgetStyle(); + gtk_widget_set_style( m_widget, m_widgetStyle ); } //----------------------------------------------------------------------------- diff --git a/src/gtk/radiobox.cpp b/src/gtk/radiobox.cpp index 38e1be21dc..255d17c125 100644 --- a/src/gtk/radiobox.cpp +++ b/src/gtk/radiobox.cpp @@ -71,6 +71,7 @@ bool wxRadioBox::Create( wxWindow *parent, wxWindowID id, const wxString& title, { m_alreadySent = FALSE; m_needParent = TRUE; + m_acceptsFocus = TRUE; PreCreation( parent, id, pos, size, style, name ); @@ -282,6 +283,27 @@ int wxRadioBox::FindString( const wxString &s ) const return -1; } +void wxRadioBox::SetFocus() +{ + wxCHECK_RET( m_widget != NULL, "invalid radiobox" ); + + if (m_boxes.GetCount() == 0) return; + + wxNode *node = m_boxes.First(); + while (node) + { + GtkToggleButton *button = GTK_TOGGLE_BUTTON( node->Data() ); + if (button->active) + { + gtk_widget_grab_focus( GTK_WIDGET(button) ); + + return; + } + node = node->Next(); + } + +} + void wxRadioBox::SetSelection( int n ) { wxCHECK_RET( m_widget != NULL, "invalid radiobox" ); diff --git a/src/gtk/radiobut.cpp b/src/gtk/radiobut.cpp index aab86976cd..bc2156d094 100644 --- a/src/gtk/radiobut.cpp +++ b/src/gtk/radiobut.cpp @@ -53,6 +53,7 @@ bool wxRadioButton::Create( wxWindow *parent, wxWindowID id, const wxString& lab const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator, const wxString& name ) { + m_acceptsFocus = TRUE; m_needParent = TRUE; wxSize newSize = size; diff --git a/src/gtk/scrolbar.cpp b/src/gtk/scrolbar.cpp index 54cde192ec..c0d729487d 100644 --- a/src/gtk/scrolbar.cpp +++ b/src/gtk/scrolbar.cpp @@ -116,6 +116,7 @@ bool wxScrollBar::Create(wxWindow *parent, wxWindowID id, long style, const wxValidator& validator, const wxString& name ) { m_needParent = TRUE; + m_acceptsFocus = TRUE; PreCreation( parent, id, pos, size, style, name ); diff --git a/src/gtk/slider.cpp b/src/gtk/slider.cpp index d94ac244de..d45eda3add 100644 --- a/src/gtk/slider.cpp +++ b/src/gtk/slider.cpp @@ -79,6 +79,7 @@ bool wxSlider::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator, const wxString& name ) { + m_acceptsFocus = TRUE; m_needParent = TRUE; PreCreation( parent, id, pos, size, style, name ); diff --git a/src/gtk/textctrl.cpp b/src/gtk/textctrl.cpp index 549f3488f3..7a3cf2f76f 100644 --- a/src/gtk/textctrl.cpp +++ b/src/gtk/textctrl.cpp @@ -20,6 +20,14 @@ #include #include +#include "gdk/gdkkeysyms.h" + +//----------------------------------------------------------------------------- +// data +//----------------------------------------------------------------------------- + +extern bool g_blockEventsOnDrag; + //----------------------------------------------------------------------------- // "changed" //----------------------------------------------------------------------------- @@ -48,7 +56,6 @@ gtk_text_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* WXUNUSED(all win->CalculateScrollbar(); } - //----------------------------------------------------------------------------- // wxTextCtrl //----------------------------------------------------------------------------- @@ -81,6 +88,7 @@ bool wxTextCtrl::Create( wxWindow *parent, wxWindowID id, const wxString &value, int style, const wxValidator& validator, const wxString &name ) { m_needParent = TRUE; + m_acceptsFocus = TRUE; PreCreation( parent, id, pos, size, style, name ); @@ -152,9 +160,8 @@ bool wxTextCtrl::Create( wxWindow *parent, wxWindowID id, const wxString &value, } // we want to be notified about text changes - gtk_signal_connect(GTK_OBJECT(m_text), "changed", - GTK_SIGNAL_FUNC(gtk_text_changed_callback), - (gpointer)this); + gtk_signal_connect( GTK_OBJECT(m_text), "changed", + GTK_SIGNAL_FUNC(gtk_text_changed_callback), (gpointer)this); if (!value.IsNull()) { @@ -608,15 +615,7 @@ void wxTextCtrl::OnChar( wxKeyEvent &key_event ) event.SetEventObject(this); if (GetEventHandler()->ProcessEvent(event)) return; } - else if (key_event.KeyCode() == WXK_TAB) - { - wxNavigationKeyEvent event; - event.SetDirection( key_event.m_shiftDown ); - event.SetWindowChange(FALSE); - event.SetEventObject(this); - if (GetEventHandler()->ProcessEvent(event)) return; - } key_event.Skip(); } diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 3a1c153c6e..4d375355ff 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -120,15 +120,51 @@ #endif #endif +//----------------------------------------------------------------------------- +// (debug) +//----------------------------------------------------------------------------- + +#ifdef __WXDEBUG__ + +static gint gtk_debug_focus_in_callback( GtkWidget *WXUNUSED(widget), + GdkEvent *WXUNUSED(event), + const char *name ) +{ + printf( "FOCUS NOW AT: " ); + printf( name ); + printf( "\n" ); + + return FALSE; +} + +void debug_focus_in( GtkWidget* widget, const char* name, const char *window ) +{ + return; + + wxString tmp = name; + tmp += " FROM "; + tmp += window; + + char *s = new char[tmp.Length()+1]; + + strcpy( s, WXSTRINGCAST tmp ); + + gtk_signal_connect( GTK_OBJECT(widget), "focus_in_event", + GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback), (gpointer)s ); +} + +#endif + //----------------------------------------------------------------------------- // data //----------------------------------------------------------------------------- -extern wxList wxPendingDelete; -extern wxList wxTopLevelWindows; -extern bool g_blockEventsOnDrag; -extern bool g_blockEventsOnScroll; -static bool g_capturing = FALSE; +extern wxList wxPendingDelete; +extern wxList wxTopLevelWindows; +extern bool g_blockEventsOnDrag; +extern bool g_blockEventsOnScroll; +static bool g_capturing = FALSE; +static wxWindow *g_focusWindow = (wxWindow*) NULL; // hack: we need something to pass to gtk_menu_popup, so we store the time of // the last click here @@ -181,7 +217,7 @@ static void gtk_window_draw_callback( GtkWidget *WXUNUSED(widget), GdkRectangle } //----------------------------------------------------------------------------- -// "key_press_event" +// "key_press_event" from any window //----------------------------------------------------------------------------- static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_event, wxWindow *win ) @@ -303,11 +339,41 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_e ancestor = ancestor->GetParent(); } } - + + // win is a control: tab can be propagated up + if ((!ret) && (gdk_event->keyval == GDK_Tab)) + { + wxNavigationKeyEvent new_event; + new_event.SetDirection( !(gdk_event->state & GDK_SHIFT_MASK) ); + new_event.SetWindowChange( FALSE ); + new_event.SetCurrentFocus( win ); + ret = win->GetEventHandler()->ProcessEvent( new_event ); + } + +/* + // win is a panel: up can be propagated to the panel + if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) && + (gdk_event->keyval == GDK_Up)) + { + win->m_parent->SetFocus(); + ret = TRUE; + } + + // win is a panel: left/right can be propagated to the panel + if ((!ret) && (win->m_wxwindow) && + ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) || + (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down))) + { + wxNavigationKeyEvent new_event; + new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) ); + new_event.SetCurrentFocus( win ); + ret = win->GetEventHandler()->ProcessEvent( new_event ); + } +*/ + if (ret) { - if ((gdk_event->keyval >= 0x20) && (gdk_event->keyval <= 0xFF)) - gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "key_press_event" ); + gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "key_press_event" ); } return ret; @@ -658,6 +724,9 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion static gint gtk_window_focus_in_callback( GtkWidget *widget, GdkEvent *WXUNUSED(event), wxWindow *win ) { if (g_blockEventsOnDrag) return TRUE; + + g_focusWindow = win; + if (win->m_wxwindow) { if (GTK_WIDGET_CAN_FOCUS(win->m_wxwindow)) @@ -729,10 +798,13 @@ static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEvent *WXUNUSED static gint gtk_window_enter_callback( GtkWidget *widget, GdkEventCrossing *gdk_event, wxWindow *win ) { - if (widget->window != gdk_event->window) return TRUE; - if (g_blockEventsOnDrag) return TRUE; + if ((widget->window) && (win->m_cursor)) + gdk_window_set_cursor( widget->window, win->m_cursor->GetCursor() ); + + if (widget->window != gdk_event->window) return TRUE; + if (!win->HasVMT()) return TRUE; /* @@ -742,9 +814,6 @@ static gint gtk_window_enter_callback( GtkWidget *widget, GdkEventCrossing *gdk_ printf( ".\n" ); */ - if ((widget->window) && (win->m_cursor)) - gdk_window_set_cursor( widget->window, win->m_cursor->GetCursor() ); - wxMouseEvent event( wxEVT_ENTER_WINDOW ); event.SetEventObject( win ); @@ -777,10 +846,13 @@ static gint gtk_window_enter_callback( GtkWidget *widget, GdkEventCrossing *gdk_ static gint gtk_window_leave_callback( GtkWidget *widget, GdkEventCrossing *gdk_event, wxWindow *win ) { - if (widget->window != gdk_event->window) return TRUE; - if (g_blockEventsOnDrag) return TRUE; + if ((widget->window) && (win->m_cursor)) + gdk_window_set_cursor( widget->window, wxSTANDARD_CURSOR->GetCursor() ); + + if (widget->window != gdk_event->window) return TRUE; + if (!win->HasVMT()) return TRUE; /* @@ -790,9 +862,6 @@ static gint gtk_window_leave_callback( GtkWidget *widget, GdkEventCrossing *gdk_ printf( ".\n" ); */ - if ((widget->window) && (win->m_cursor)) - gdk_window_set_cursor( widget->window, wxSTANDARD_CURSOR->GetCursor() ); - wxMouseEvent event( wxEVT_LEAVE_WINDOW ); event.SetEventObject( win ); @@ -1104,6 +1173,7 @@ wxWindow::wxWindow() m_clientData = NULL; m_isStaticBox = FALSE; + m_acceptsFocus = FALSE; } wxWindow::wxWindow( wxWindow *parent, wxWindowID id, @@ -1126,9 +1196,18 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id, m_widget = gtk_scrolled_window_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL ); GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS ); + +#ifdef __WXDEBUG__ + debug_focus_in( m_widget, "wxWindow::m_widget", name ); +#endif GtkScrolledWindow *s_window = GTK_SCROLLED_WINDOW(m_widget); +#ifdef __WXDEBUG__ + debug_focus_in( s_window->hscrollbar, "wxWindow::hsrcollbar", name ); + debug_focus_in( s_window->vscrollbar, "wxWindow::vsrcollbar", name ); +#endif + GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass ); scroll_class->scrollbar_spacing = 0; @@ -1142,6 +1221,10 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id, m_wxwindow = gtk_myfixed_new(); +#ifdef __WXDEBUG__ + debug_focus_in( m_wxwindow, "wxWindow::m_wxwindow", name ); +#endif + #ifdef NEW_GTK_SCROLL_CODE gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(m_widget), m_wxwindow ); GtkViewport *viewport = GTK_VIEWPORT(s_window->child); @@ -1150,6 +1233,10 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id, GtkViewport *viewport = GTK_VIEWPORT(s_window->viewport); #endif +#ifdef __WXDEBUG__ + debug_focus_in( GTK_WIDGET(viewport), "wxWindow::viewport", name ); +#endif + if (m_windowStyle & wxRAISED_BORDER) { gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_OUT ); @@ -1163,10 +1250,16 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id, gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_NONE ); } - if (m_windowStyle & wxTAB_TRAVERSAL == wxTAB_TRAVERSAL) + if ((m_windowStyle & wxTAB_TRAVERSAL) != 0) + { GTK_WIDGET_UNSET_FLAGS( m_wxwindow, GTK_CAN_FOCUS ); + m_acceptsFocus = FALSE; + } else + { GTK_WIDGET_SET_FLAGS( m_wxwindow, GTK_CAN_FOCUS ); + m_acceptsFocus = TRUE; + } // shut the viewport up gtk_viewport_set_hadjustment( viewport, (GtkAdjustment*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) ); @@ -1902,17 +1995,34 @@ void wxWindow::MakeModal( bool modal ) void wxWindow::SetFocus() { wxCHECK_RET( (m_widget != NULL), "invalid window" ); - + GtkWidget *connect_widget = GetConnectWidget(); if (connect_widget) { - if (GTK_WIDGET_CAN_FOCUS(connect_widget) && !GTK_WIDGET_HAS_FOCUS (connect_widget) ) + if (GTK_WIDGET_CAN_FOCUS(connect_widget) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ ) { gtk_widget_grab_focus (connect_widget); } + else if (GTK_IS_CONTAINER(connect_widget)) + { + gtk_container_focus( GTK_CONTAINER(connect_widget), GTK_DIR_TAB_FORWARD ); + } + else + { + } } } +wxWindow *wxWindow::FindFocus() +{ + return g_focusWindow; +} + +bool wxWindow::AcceptsFocus() const +{ + return IsEnabled() && IsShown() && m_acceptsFocus; +} + bool wxWindow::OnClose() { return TRUE; @@ -3154,8 +3264,8 @@ void wxWindow::GetClientSizeConstraint(int *w, int *h) const void wxWindow::GetPositionConstraint(int *x, int *y) const { - wxLayoutConstraints *constr = GetConstraints(); - if (constr) + wxLayoutConstraints *constr = GetConstraints(); + if (constr) { *x = constr->left.GetValue(); *y = constr->top.GetValue(); @@ -3164,12 +3274,7 @@ void wxWindow::GetPositionConstraint(int *x, int *y) const GetPosition(x, y); } -bool wxWindow::AcceptsFocus() const -{ - return IsEnabled() && IsShown(); -} - void wxWindow::OnIdle(wxIdleEvent& WXUNUSED(event) ) { - UpdateWindowUI(); + UpdateWindowUI(); } diff --git a/src/gtk1/bmpbuttn.cpp b/src/gtk1/bmpbuttn.cpp index bf155fb4fc..cd10cf260c 100644 --- a/src/gtk1/bmpbuttn.cpp +++ b/src/gtk1/bmpbuttn.cpp @@ -102,6 +102,7 @@ bool wxBitmapButton::Create( wxWindow *parent, wxWindowID id, const wxBitmap &bi long style, const wxValidator& validator, const wxString &name ) { m_needParent = TRUE; + m_acceptsFocus = TRUE; wxSize newSize = size; diff --git a/src/gtk1/button.cpp b/src/gtk1/button.cpp index 8338f5bcff..8980bb0301 100644 --- a/src/gtk1/button.cpp +++ b/src/gtk1/button.cpp @@ -58,37 +58,38 @@ bool wxButton::Create( wxWindow *parent, wxWindowID id, const wxString &label, const wxPoint &pos, const wxSize &size, long style, const wxValidator& validator, const wxString &name ) { - m_clientData = (wxClientData*) NULL; - m_needParent = TRUE; + m_clientData = (wxClientData*) NULL; + m_needParent = TRUE; + m_acceptsFocus = TRUE; - wxSize newSize = size; + wxSize newSize = size; - PreCreation( parent, id, pos, newSize, style, name ); + PreCreation( parent, id, pos, newSize, style, name ); - SetValidator( validator ); + SetValidator( validator ); - m_widget = gtk_button_new_with_label( m_label ); - SetLabel(label); + m_widget = gtk_button_new_with_label( m_label ); + SetLabel(label); - if (newSize.x == -1) newSize.x = 15+gdk_string_measure( m_widget->style->font, label ); - if (newSize.y == -1) newSize.y = 26; - SetSize( newSize.x, newSize.y ); + if (newSize.x == -1) newSize.x = 15+gdk_string_measure( m_widget->style->font, label ); + if (newSize.y == -1) newSize.y = 26; + SetSize( newSize.x, newSize.y ); - gtk_signal_connect( GTK_OBJECT(m_widget), "clicked", - GTK_SIGNAL_FUNC(gtk_button_clicked_callback), (gpointer*)this ); + gtk_signal_connect( GTK_OBJECT(m_widget), "clicked", + GTK_SIGNAL_FUNC(gtk_button_clicked_callback), (gpointer*)this ); - m_parent->AddChild( this ); + m_parent->AddChild( this ); - (m_parent->m_insertCallback)( m_parent, this ); + (m_parent->m_insertCallback)( m_parent, this ); - PostCreation(); + PostCreation(); - SetBackgroundColour( parent->GetBackgroundColour() ); - SetForegroundColour( parent->GetForegroundColour() ); + SetBackgroundColour( parent->GetBackgroundColour() ); + SetForegroundColour( parent->GetForegroundColour() ); - Show( TRUE ); + Show( TRUE ); - return TRUE; + return TRUE; } void wxButton::SetDefault(void) @@ -101,27 +102,27 @@ void wxButton::SetDefault(void) void wxButton::SetLabel( const wxString &label ) { - wxCHECK_RET( m_widget != NULL, "invalid button" ); + wxCHECK_RET( m_widget != NULL, "invalid button" ); - wxControl::SetLabel( label ); + wxControl::SetLabel( label ); - gtk_label_set( GTK_LABEL( GTK_BUTTON(m_widget)->child ), GetLabel() ); + gtk_label_set( GTK_LABEL( GTK_BUTTON(m_widget)->child ), GetLabel() ); } void wxButton::Enable( bool enable ) { - wxCHECK_RET( m_widget != NULL, "invalid button" ); + wxCHECK_RET( m_widget != NULL, "invalid button" ); - wxControl::Enable( enable ); + wxControl::Enable( enable ); - gtk_widget_set_sensitive( GTK_BUTTON(m_widget)->child, enable ); + gtk_widget_set_sensitive( GTK_BUTTON(m_widget)->child, enable ); } void wxButton::ApplyWidgetStyle() { - SetWidgetStyle(); - gtk_widget_set_style( m_widget, m_widgetStyle ); - gtk_widget_set_style( GTK_BUTTON(m_widget)->child, m_widgetStyle ); + SetWidgetStyle(); + gtk_widget_set_style( m_widget, m_widgetStyle ); + gtk_widget_set_style( GTK_BUTTON(m_widget)->child, m_widgetStyle ); } diff --git a/src/gtk1/checkbox.cpp b/src/gtk1/checkbox.cpp index 6e94fdfceb..daafd5f43f 100644 --- a/src/gtk1/checkbox.cpp +++ b/src/gtk1/checkbox.cpp @@ -26,20 +26,20 @@ extern bool g_blockEventsOnDrag; static void gtk_checkbox_clicked_callback( GtkWidget *WXUNUSED(widget), wxCheckBox *cb ) { - if (!cb->HasVMT()) return; + if (!cb->HasVMT()) return; - if (cb->m_blockFirstEvent) - { - cb->m_blockFirstEvent = FALSE; - return; - } + if (cb->m_blockFirstEvent) + { + cb->m_blockFirstEvent = FALSE; + return; + } - if (g_blockEventsOnDrag) return; + if (g_blockEventsOnDrag) return; - wxCommandEvent event(wxEVT_COMMAND_CHECKBOX_CLICKED, cb->GetId()); - event.SetInt( cb->GetValue() ); - event.SetEventObject(cb); - cb->GetEventHandler()->ProcessEvent(event); + wxCommandEvent event(wxEVT_COMMAND_CHECKBOX_CLICKED, cb->GetId()); + event.SetInt( cb->GetValue() ); + event.SetEventObject(cb); + cb->GetEventHandler()->ProcessEvent(event); } //----------------------------------------------------------------------------- @@ -56,81 +56,82 @@ bool wxCheckBox::Create( wxWindow *parent, wxWindowID id, const wxString &label const wxPoint &pos, const wxSize &size, long style, const wxValidator& validator, const wxString &name ) { - m_needParent = TRUE; + m_needParent = TRUE; + m_acceptsFocus = TRUE; - PreCreation( parent, id, pos, size, style, name ); + PreCreation( parent, id, pos, size, style, name ); - SetValidator( validator ); + SetValidator( validator ); - m_widget = gtk_check_button_new_with_label( m_label ); + m_widget = gtk_check_button_new_with_label( m_label ); - m_blockFirstEvent = FALSE; + m_blockFirstEvent = FALSE; - wxSize newSize = size; - if (newSize.x == -1) newSize.x = 25+gdk_string_measure( m_widget->style->font, label ); - if (newSize.y == -1) newSize.y = 26; - SetSize( newSize.x, newSize.y ); + wxSize newSize = size; + if (newSize.x == -1) newSize.x = 25+gdk_string_measure( m_widget->style->font, label ); + if (newSize.y == -1) newSize.y = 26; + SetSize( newSize.x, newSize.y ); - gtk_signal_connect( GTK_OBJECT(m_widget), "clicked", - GTK_SIGNAL_FUNC(gtk_checkbox_clicked_callback), (gpointer*)this ); + gtk_signal_connect( GTK_OBJECT(m_widget), "clicked", + GTK_SIGNAL_FUNC(gtk_checkbox_clicked_callback), (gpointer*)this ); - m_parent->AddChild( this ); + m_parent->AddChild( this ); - (m_parent->m_insertCallback)( m_parent, this ); + (m_parent->m_insertCallback)( m_parent, this ); - PostCreation(); + PostCreation(); - gtk_widget_realize( GTK_BUTTON( m_widget )->child ); + gtk_widget_realize( GTK_BUTTON( m_widget )->child ); - SetLabel( label ); + SetLabel( label ); - SetBackgroundColour( parent->GetBackgroundColour() ); - SetForegroundColour( parent->GetForegroundColour() ); + SetBackgroundColour( parent->GetBackgroundColour() ); + SetForegroundColour( parent->GetForegroundColour() ); - Show( TRUE ); + Show( TRUE ); - return TRUE; + return TRUE; } void wxCheckBox::SetValue( bool state ) { - wxCHECK_RET( m_widget != NULL, "invalid checkbox" ); + wxCHECK_RET( m_widget != NULL, "invalid checkbox" ); - m_blockFirstEvent = TRUE; + m_blockFirstEvent = TRUE; - gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(m_widget), state ); + gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(m_widget), state ); } bool wxCheckBox::GetValue() const { - wxCHECK_MSG( m_widget != NULL, FALSE, "invalid checkbox" ); + wxCHECK_MSG( m_widget != NULL, FALSE, "invalid checkbox" ); - return GTK_TOGGLE_BUTTON(m_widget)->active; + return GTK_TOGGLE_BUTTON(m_widget)->active; } void wxCheckBox::SetLabel( const wxString& label ) { - wxCHECK_RET( m_widget != NULL, "invalid checkbox" ); + wxCHECK_RET( m_widget != NULL, "invalid checkbox" ); - wxControl::SetLabel( label ); + wxControl::SetLabel( label ); - gtk_label_set( GTK_LABEL( GTK_BUTTON(m_widget)->child ), GetLabel() ); + gtk_label_set( GTK_LABEL( GTK_BUTTON(m_widget)->child ), GetLabel() ); } void wxCheckBox::Enable( bool enable ) { - wxCHECK_RET( m_widget != NULL, "invalid checkbox" ); + wxCHECK_RET( m_widget != NULL, "invalid checkbox" ); - wxControl::Enable( enable ); + wxControl::Enable( enable ); - gtk_widget_set_sensitive( GTK_BUTTON(m_widget)->child, enable ); + gtk_widget_set_sensitive( GTK_BUTTON(m_widget)->child, enable ); } void wxCheckBox::ApplyWidgetStyle() { - SetWidgetStyle(); - gtk_widget_set_style( m_widget, m_widgetStyle ); - gtk_widget_set_style( GTK_BUTTON(m_widget)->child, m_widgetStyle ); + SetWidgetStyle(); + gtk_widget_set_style( m_widget, m_widgetStyle ); + gtk_widget_set_style( GTK_BUTTON(m_widget)->child, m_widgetStyle ); } diff --git a/src/gtk1/combobox.cpp b/src/gtk1/combobox.cpp index 7a1e8412b9..ae8b352156 100644 --- a/src/gtk1/combobox.cpp +++ b/src/gtk1/combobox.cpp @@ -63,6 +63,7 @@ bool wxComboBox::Create( wxWindow *parent, wxWindowID id, const wxString& value, { m_alreadySent = FALSE; m_needParent = TRUE; + m_acceptsFocus = TRUE; PreCreation( parent, id, pos, size, style, name ); diff --git a/src/gtk1/control.cpp b/src/gtk1/control.cpp index c9064a3413..4b04d0bb37 100644 --- a/src/gtk1/control.cpp +++ b/src/gtk1/control.cpp @@ -21,7 +21,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxControl,wxWindow) wxControl::wxControl(void) { - m_needParent = TRUE; + m_needParent = TRUE; } wxControl::wxControl( wxWindow *parent, wxWindowID id, @@ -37,24 +37,23 @@ void wxControl::Command( wxCommandEvent &WXUNUSED(event) ) void wxControl::SetLabel( const wxString &label ) { - m_label = ""; - for ( const char *pc = label; *pc != '\0'; pc++ ) { - if ( *pc == '&' ) { - pc++; // skip it + m_label = ""; + for ( const char *pc = label; *pc != '\0'; pc++ ) + { + if ( *pc == '&' ) + { + pc++; // skip it #if 0 // it would be unused anyhow for now - kbd interface not done yet - if ( *pc != '&' ) - m_chAccel = *pc; + if ( *pc != '&' ) m_chAccel = *pc; #endif + } + m_label << *pc; } - - m_label << *pc; - } } wxString wxControl::GetLabel(void) const { - return m_label; + return m_label; } - diff --git a/src/gtk1/frame.cpp b/src/gtk1/frame.cpp index 8d0d64c9ca..ae11c5097e 100644 --- a/src/gtk1/frame.cpp +++ b/src/gtk1/frame.cpp @@ -142,6 +142,10 @@ bool wxFrame::Create( wxWindow *parent, wxWindowID id, const wxString &title, m_widget = gtk_window_new( win_type ); +#ifdef __WXDEBUG__ + debug_focus_in( m_widget, "wxFrame::m_widget", name ); +#endif + if ((size.x != -1) && (size.y != -1)) gtk_widget_set_usize( m_widget, m_width, m_height ); if ((pos.x != -1) && (pos.y != -1)) @@ -159,6 +163,10 @@ bool wxFrame::Create( wxWindow *parent, wxWindowID id, const wxString &title, gtk_widget_show( m_wxwindow ); GTK_WIDGET_UNSET_FLAGS( m_wxwindow, GTK_CAN_FOCUS ); +#ifdef __WXDEBUG__ + debug_focus_in( m_wxwindow, "wxFrame::m_wxwindow", name ); +#endif + gtk_container_add( GTK_CONTAINER(m_widget), m_wxwindow ); gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate", diff --git a/src/gtk1/listbox.cpp b/src/gtk1/listbox.cpp index 22d401bd8a..a9ef5ae287 100644 --- a/src/gtk1/listbox.cpp +++ b/src/gtk1/listbox.cpp @@ -130,6 +130,7 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id, long style, const wxValidator& validator, const wxString &name ) { m_needParent = TRUE; + m_acceptsFocus = TRUE; PreCreation( parent, id, pos, size, style, name ); @@ -138,7 +139,7 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id, m_widget = gtk_scrolled_window_new( (GtkAdjustment*) NULL, (GtkAdjustment*) NULL ); gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(m_widget), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC ); - + m_list = GTK_LIST( gtk_list_new() ); GtkSelectionMode mode = GTK_SELECTION_BROWSE; @@ -155,6 +156,25 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id, gtk_container_add( GTK_CONTAINER(m_widget), GTK_WIDGET(m_list) ); #endif +#ifdef __WXDEBUG__ + debug_focus_in( m_widget, "wxListBox::m_widget", name ); + + debug_focus_in( GTK_WIDGET(m_list), "wxListBox::m_list", name ); + + GtkScrolledWindow *s_window = GTK_SCROLLED_WINDOW(m_widget); + + debug_focus_in( s_window->hscrollbar, "wxWindow::hsrcollbar", name ); + debug_focus_in( s_window->vscrollbar, "wxWindow::vsrcollbar", name ); + +#ifdef NEW_GTK_SCROLL_CODE + GtkViewport *viewport = GTK_VIEWPORT(s_window->child); +#else + GtkViewport *viewport = GTK_VIEWPORT(s_window->viewport); +#endif + + debug_focus_in( GTK_WIDGET(viewport), "wxWindow::viewport", name ); +#endif + gtk_widget_show( GTK_WIDGET(m_list) ); wxSize newSize = size; @@ -180,6 +200,10 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id, list_item = gtk_list_item_new_with_label( choices[i] ); } +#ifdef __WXDEBUG__ + debug_focus_in( list_item, "wxListBox::list_item", name ); +#endif + gtk_container_add( GTK_CONTAINER(m_list), list_item ); gtk_signal_connect( GTK_OBJECT(list_item), "select", diff --git a/src/gtk1/notebook.cpp b/src/gtk1/notebook.cpp index ca9146b045..b74e19d4de 100644 --- a/src/gtk1/notebook.cpp +++ b/src/gtk1/notebook.cpp @@ -17,6 +17,13 @@ #include "wx/imaglist.h" #include "wx/intl.h" #include "wx/log.h" +#include "gdk/gdkkeysyms.h" + +//----------------------------------------------------------------------------- +// data +//----------------------------------------------------------------------------- + +extern bool g_blockEventsOnDrag; //----------------------------------------------------------------------------- // wxNotebookPage @@ -72,16 +79,16 @@ static void gtk_notebook_page_change_callback(GtkNotebook *WXUNUSED(widget), gint nPage, gpointer data) { - wxNotebook *notebook = (wxNotebook *)data; + wxNotebook *notebook = (wxNotebook *)data; - int old = notebook->GetSelection(); + int old = notebook->GetSelection(); - // TODO: emulate PAGE_CHANGING event + // TODO: emulate PAGE_CHANGING event - wxNotebookEvent event( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, - notebook->GetId(), nPage, old ); - event.SetEventObject( notebook ); - notebook->GetEventHandler()->ProcessEvent( event ); + wxNotebookEvent event( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, + notebook->GetId(), nPage, old ); + event.SetEventObject( notebook ); + notebook->GetEventHandler()->ProcessEvent( event ); } //----------------------------------------------------------------------------- @@ -90,17 +97,48 @@ static void gtk_notebook_page_change_callback(GtkNotebook *WXUNUSED(widget), static void gtk_page_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxWindow *win ) { - if ((win->m_x == alloc->x) && - (win->m_y == alloc->y) && - (win->m_width == alloc->width) && - (win->m_height == alloc->height)) - { - return; - } + if ((win->m_x == alloc->x) && + (win->m_y == alloc->y) && + (win->m_width == alloc->width) && + (win->m_height == alloc->height)) + { + return; + } - win->SetSize( alloc->x, alloc->y, alloc->width, alloc->height ); + win->SetSize( alloc->x, alloc->y, alloc->width, alloc->height ); - if (win->GetAutoLayout()) win->Layout(); + if (win->GetAutoLayout()) win->Layout(); +} + +//----------------------------------------------------------------------------- +// "key_press_event" +//----------------------------------------------------------------------------- + +static gint +gtk_notebook_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_event, wxNotebook *notebook ) +{ + if (g_blockEventsOnDrag) return FALSE; + + if (!notebook->HasVMT()) return FALSE; + + if (gdk_event->keyval != GDK_Down) return FALSE; + + if (notebook != notebook->FindFocus()) return FALSE; + + if (notebook->m_pages.GetCount() == 0) return FALSE; + + wxNode *node = notebook->m_pages.Nth( notebook->GetSelection() ); + + if (!node) return FALSE; + + wxNotebookPage *page = (wxNotebookPage*) node->Data(); + + // don't let others the key event + gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "key_press_event" ); + + page->m_client->SetFocus(); + + return TRUE; } //----------------------------------------------------------------------------- @@ -109,32 +147,28 @@ static void gtk_page_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* static void wxInsertChildInNotebook( wxNotebook* parent, wxWindow* child ) { - wxNotebookPage *page = new wxNotebookPage(); + wxNotebookPage *page = new wxNotebookPage(); - page->m_id = parent->GetPageCount(); + page->m_id = parent->GetPageCount(); - page->m_box = gtk_hbox_new (FALSE, 0); - gtk_container_border_width(GTK_CONTAINER(page->m_box), 2); + page->m_box = gtk_hbox_new (FALSE, 0); + gtk_container_border_width(GTK_CONTAINER(page->m_box), 2); - GtkNotebook *notebook = GTK_NOTEBOOK(parent->m_widget); + GtkNotebook *notebook = GTK_NOTEBOOK(parent->m_widget); - page->m_client = child; - gtk_notebook_append_page( notebook, child->m_widget, page->m_box ); + page->m_client = child; + gtk_notebook_append_page( notebook, child->m_widget, page->m_box ); - page->m_page = (GtkNotebookPage*) (g_list_last(notebook->children)->data); + page->m_page = (GtkNotebookPage*) (g_list_last(notebook->children)->data); - page->m_parent = notebook; + page->m_parent = notebook; - gtk_signal_connect( GTK_OBJECT(child->m_widget), "size_allocate", - GTK_SIGNAL_FUNC(gtk_page_size_callback), (gpointer)child ); + gtk_signal_connect( GTK_OBJECT(child->m_widget), "size_allocate", + GTK_SIGNAL_FUNC(gtk_page_size_callback), (gpointer)child ); - if (!page->m_page) - { - wxLogFatalError( "Notebook page creation error" ); - return; - } + wxASSERT_MSG( page->m_page, "Notebook page creation error" ); - parent->m_pages.Append( page ); + parent->m_pages.Append( page ); } //----------------------------------------------------------------------------- @@ -145,155 +179,164 @@ IMPLEMENT_DYNAMIC_CLASS(wxNotebook,wxControl) void wxNotebook::Init() { - m_imageList = (wxImageList *) NULL; - m_pages.DeleteContents( TRUE ); - m_idHandler = 0; + m_imageList = (wxImageList *) NULL; + m_pages.DeleteContents( TRUE ); + m_idHandler = 0; } wxNotebook::wxNotebook() { - Init(); + Init(); } wxNotebook::wxNotebook( wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) { - Init(); - Create( parent, id, pos, size, style, name ); + Init(); + Create( parent, id, pos, size, style, name ); } wxNotebook::~wxNotebook() { - // don't generate change page events any more - if (m_idHandler != 0) - gtk_signal_disconnect(GTK_OBJECT(m_widget), m_idHandler); + // don't generate change page events any more + if (m_idHandler != 0) + gtk_signal_disconnect(GTK_OBJECT(m_widget), m_idHandler); - DeleteAllPages(); + DeleteAllPages(); } bool wxNotebook::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) { - m_needParent = TRUE; - m_insertCallback = (wxInsertChildFunction)wxInsertChildInNotebook; + m_needParent = TRUE; + m_acceptsFocus = TRUE; + m_insertCallback = (wxInsertChildFunction)wxInsertChildInNotebook; + + PreCreation( parent, id, pos, size, style, name ); - PreCreation( parent, id, pos, size, style, name ); + m_widget = gtk_notebook_new(); - m_widget = gtk_notebook_new(); +#ifdef __WXDEBUG__ + debug_focus_in( m_widget, "wxNotebook::m_widget", name ); +#endif - gtk_notebook_set_scrollable( GTK_NOTEBOOK(m_widget), 1 ); + gtk_notebook_set_scrollable( GTK_NOTEBOOK(m_widget), 1 ); - m_idHandler = gtk_signal_connect ( + m_idHandler = gtk_signal_connect ( GTK_OBJECT(m_widget), "switch_page", GTK_SIGNAL_FUNC(gtk_notebook_page_change_callback), (gpointer)this ); - m_parent->AddChild( this ); + m_parent->AddChild( this ); - (m_parent->m_insertCallback)( m_parent, this ); + (m_parent->m_insertCallback)( m_parent, this ); - PostCreation(); + gtk_signal_connect( GTK_OBJECT(m_widget), "key_press_event", + GTK_SIGNAL_FUNC(gtk_notebook_key_press_callback), (gpointer)this ); - Show( TRUE ); + PostCreation(); - return TRUE; + Show( TRUE ); + + return TRUE; } int wxNotebook::GetSelection() const { - wxCHECK_MSG( m_widget != NULL, -1, "invalid notebook" ); - - if (m_pages.Number() == 0) return -1; + wxCHECK_MSG( m_widget != NULL, -1, "invalid notebook" ); - GtkNotebookPage *g_page = GTK_NOTEBOOK(m_widget)->cur_page; - if (!g_page) return -1; + if (m_pages.Number() == 0) return -1; - wxNotebookPage *page = (wxNotebookPage *) NULL; + GtkNotebookPage *g_page = GTK_NOTEBOOK(m_widget)->cur_page; + if (!g_page) return -1; - wxNode *node = m_pages.First(); - while (node) - { - page = (wxNotebookPage*)node->Data(); + wxNotebookPage *page = (wxNotebookPage *) NULL; - if ((page->m_page == g_page) || (page->m_page == (GtkNotebookPage*)NULL)) + wxNode *node = m_pages.First(); + while (node) { - // page->m_page is NULL directly after gtk_notebook_append. gtk emits - // "switch_page" then and we ask for GetSelection() in the handler for - // "switch_page". otherwise m_page should never be NULL. all this - // might also be wrong. - break; + page = (wxNotebookPage*)node->Data(); + + if ((page->m_page == g_page) || (page->m_page == (GtkNotebookPage*)NULL)) + { + // page->m_page is NULL directly after gtk_notebook_append. gtk emits + // "switch_page" then and we ask for GetSelection() in the handler for + // "switch_page". otherwise m_page should never be NULL. all this + // might also be wrong. + break; + } + node = node->Next(); } - node = node->Next(); - } - wxCHECK_MSG( node != NULL, -1, "wxNotebook: no selection?" ); + wxCHECK_MSG( node != NULL, -1, "wxNotebook: no selection?" ); - return page->m_id; + return page->m_id; } int wxNotebook::GetPageCount() const { - // count only the pages which were already added to the notebook for MSW - // compatibility (and, in fact, this behaviour makes more sense anyhow - // because only the added pages are shown) - int n = 0; - for ( wxNode *node = m_pages.First(); node; node = node->Next() ) - { - wxNotebookPage *page = (wxNotebookPage*)node->Data(); - if ( page->WasAdded() ) - n++; - } + // count only the pages which were already added to the notebook for MSW + // compatibility (and, in fact, this behaviour makes more sense anyhow + // because only the added pages are shown) + + int n = 0; + for ( wxNode *node = m_pages.First(); node; node = node->Next() ) + { + wxNotebookPage *page = (wxNotebookPage*)node->Data(); + + if (page->WasAdded()) n++; + } - return n; + return n; } int wxNotebook::GetRowCount() const { - return 1; + return 1; } wxString wxNotebook::GetPageText( int page ) const { - wxCHECK_MSG( m_widget != NULL, "", "invalid notebook" ); + wxCHECK_MSG( m_widget != NULL, "", "invalid notebook" ); - wxNotebookPage* nb_page = GetNotebookPage(page); - if (nb_page) - return nb_page->m_text; - else - return ""; + wxNotebookPage* nb_page = GetNotebookPage(page); + if (nb_page) + return nb_page->m_text; + else + return ""; } int wxNotebook::GetPageImage( int page ) const { - wxCHECK_MSG( m_widget != NULL, 0, "invalid notebook" ); + wxCHECK_MSG( m_widget != NULL, 0, "invalid notebook" ); - wxNotebookPage* nb_page = GetNotebookPage(page); - if (nb_page) - return nb_page->m_image; - else - return 0; + wxNotebookPage* nb_page = GetNotebookPage(page); + if (nb_page) + return nb_page->m_image; + else + return 0; } wxNotebookPage* wxNotebook::GetNotebookPage(int page) const { - wxCHECK_MSG( m_widget != NULL, (wxNotebookPage*)NULL, "invalid notebook" ); + wxCHECK_MSG( m_widget != NULL, (wxNotebookPage*)NULL, "invalid notebook" ); - wxNotebookPage *nb_page = (wxNotebookPage *) NULL; + wxNotebookPage *nb_page = (wxNotebookPage *) NULL; - wxNode *node = m_pages.First(); - while (node) - { - nb_page = (wxNotebookPage*)node->Data(); - if (nb_page->m_id == page) - return nb_page; - node = node->Next(); - } + wxNode *node = m_pages.First(); + while (node) + { + nb_page = (wxNotebookPage*)node->Data(); + if (nb_page->m_id == page) + return nb_page; + node = node->Next(); + } - wxLogDebug( "Notebook page %d not found!", page ); + wxFAIL_MSG( "Notebook page not found!" ); - return (wxNotebookPage *) NULL; + return (wxNotebookPage *) NULL; } int wxNotebook::SetSelection( int page ) @@ -437,7 +480,7 @@ bool wxNotebook::RemovePage( int page ) } bool wxNotebook::AddPage(wxWindow* win, const wxString& text, - bool bSelect, int imageId) + bool select, int imageId) { wxCHECK_MSG( m_widget != NULL, FALSE, "invalid notebook" ); @@ -491,38 +534,38 @@ bool wxNotebook::AddPage(wxWindow* win, const wxString& text, gtk_widget_show((GtkWidget *)page->m_label); - if (bSelect) SetSelection(GetPageCount()); + if (select) SetSelection( GetPageCount()-1 ); return TRUE; } wxWindow *wxNotebook::GetPage( int page ) const { - wxCHECK_MSG( m_widget != NULL, (wxWindow*) NULL, "invalid notebook" ); + wxCHECK_MSG( m_widget != NULL, (wxWindow*) NULL, "invalid notebook" ); - wxNotebookPage* nb_page = GetNotebookPage(page); - if (!nb_page) - return (wxWindow *) NULL; - else - return nb_page->m_client; + wxNotebookPage* nb_page = GetNotebookPage(page); + if (!nb_page) + return (wxWindow *) NULL; + else + return nb_page->m_client; } // override these 2 functions to do nothing: everything is done in OnSize void wxNotebook::SetConstraintSizes( bool WXUNUSED(recurse) ) { - // don't set the sizes of the pages - their correct size is not yet known - wxControl::SetConstraintSizes(FALSE); + // don't set the sizes of the pages - their correct size is not yet known + wxControl::SetConstraintSizes(FALSE); } bool wxNotebook::DoPhase( int WXUNUSED(nPhase) ) { - return TRUE; + return TRUE; } void wxNotebook::ApplyWidgetStyle() { - SetWidgetStyle(); - gtk_widget_set_style( m_widget, m_widgetStyle ); + SetWidgetStyle(); + gtk_widget_set_style( m_widget, m_widgetStyle ); } //----------------------------------------------------------------------------- diff --git a/src/gtk1/radiobox.cpp b/src/gtk1/radiobox.cpp index 38e1be21dc..255d17c125 100644 --- a/src/gtk1/radiobox.cpp +++ b/src/gtk1/radiobox.cpp @@ -71,6 +71,7 @@ bool wxRadioBox::Create( wxWindow *parent, wxWindowID id, const wxString& title, { m_alreadySent = FALSE; m_needParent = TRUE; + m_acceptsFocus = TRUE; PreCreation( parent, id, pos, size, style, name ); @@ -282,6 +283,27 @@ int wxRadioBox::FindString( const wxString &s ) const return -1; } +void wxRadioBox::SetFocus() +{ + wxCHECK_RET( m_widget != NULL, "invalid radiobox" ); + + if (m_boxes.GetCount() == 0) return; + + wxNode *node = m_boxes.First(); + while (node) + { + GtkToggleButton *button = GTK_TOGGLE_BUTTON( node->Data() ); + if (button->active) + { + gtk_widget_grab_focus( GTK_WIDGET(button) ); + + return; + } + node = node->Next(); + } + +} + void wxRadioBox::SetSelection( int n ) { wxCHECK_RET( m_widget != NULL, "invalid radiobox" ); diff --git a/src/gtk1/radiobut.cpp b/src/gtk1/radiobut.cpp index aab86976cd..bc2156d094 100644 --- a/src/gtk1/radiobut.cpp +++ b/src/gtk1/radiobut.cpp @@ -53,6 +53,7 @@ bool wxRadioButton::Create( wxWindow *parent, wxWindowID id, const wxString& lab const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator, const wxString& name ) { + m_acceptsFocus = TRUE; m_needParent = TRUE; wxSize newSize = size; diff --git a/src/gtk1/scrolbar.cpp b/src/gtk1/scrolbar.cpp index 54cde192ec..c0d729487d 100644 --- a/src/gtk1/scrolbar.cpp +++ b/src/gtk1/scrolbar.cpp @@ -116,6 +116,7 @@ bool wxScrollBar::Create(wxWindow *parent, wxWindowID id, long style, const wxValidator& validator, const wxString& name ) { m_needParent = TRUE; + m_acceptsFocus = TRUE; PreCreation( parent, id, pos, size, style, name ); diff --git a/src/gtk1/slider.cpp b/src/gtk1/slider.cpp index d94ac244de..d45eda3add 100644 --- a/src/gtk1/slider.cpp +++ b/src/gtk1/slider.cpp @@ -79,6 +79,7 @@ bool wxSlider::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator, const wxString& name ) { + m_acceptsFocus = TRUE; m_needParent = TRUE; PreCreation( parent, id, pos, size, style, name ); diff --git a/src/gtk1/textctrl.cpp b/src/gtk1/textctrl.cpp index 549f3488f3..7a3cf2f76f 100644 --- a/src/gtk1/textctrl.cpp +++ b/src/gtk1/textctrl.cpp @@ -20,6 +20,14 @@ #include #include +#include "gdk/gdkkeysyms.h" + +//----------------------------------------------------------------------------- +// data +//----------------------------------------------------------------------------- + +extern bool g_blockEventsOnDrag; + //----------------------------------------------------------------------------- // "changed" //----------------------------------------------------------------------------- @@ -48,7 +56,6 @@ gtk_text_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* WXUNUSED(all win->CalculateScrollbar(); } - //----------------------------------------------------------------------------- // wxTextCtrl //----------------------------------------------------------------------------- @@ -81,6 +88,7 @@ bool wxTextCtrl::Create( wxWindow *parent, wxWindowID id, const wxString &value, int style, const wxValidator& validator, const wxString &name ) { m_needParent = TRUE; + m_acceptsFocus = TRUE; PreCreation( parent, id, pos, size, style, name ); @@ -152,9 +160,8 @@ bool wxTextCtrl::Create( wxWindow *parent, wxWindowID id, const wxString &value, } // we want to be notified about text changes - gtk_signal_connect(GTK_OBJECT(m_text), "changed", - GTK_SIGNAL_FUNC(gtk_text_changed_callback), - (gpointer)this); + gtk_signal_connect( GTK_OBJECT(m_text), "changed", + GTK_SIGNAL_FUNC(gtk_text_changed_callback), (gpointer)this); if (!value.IsNull()) { @@ -608,15 +615,7 @@ void wxTextCtrl::OnChar( wxKeyEvent &key_event ) event.SetEventObject(this); if (GetEventHandler()->ProcessEvent(event)) return; } - else if (key_event.KeyCode() == WXK_TAB) - { - wxNavigationKeyEvent event; - event.SetDirection( key_event.m_shiftDown ); - event.SetWindowChange(FALSE); - event.SetEventObject(this); - if (GetEventHandler()->ProcessEvent(event)) return; - } key_event.Skip(); } diff --git a/src/gtk1/window.cpp b/src/gtk1/window.cpp index 3a1c153c6e..4d375355ff 100644 --- a/src/gtk1/window.cpp +++ b/src/gtk1/window.cpp @@ -120,15 +120,51 @@ #endif #endif +//----------------------------------------------------------------------------- +// (debug) +//----------------------------------------------------------------------------- + +#ifdef __WXDEBUG__ + +static gint gtk_debug_focus_in_callback( GtkWidget *WXUNUSED(widget), + GdkEvent *WXUNUSED(event), + const char *name ) +{ + printf( "FOCUS NOW AT: " ); + printf( name ); + printf( "\n" ); + + return FALSE; +} + +void debug_focus_in( GtkWidget* widget, const char* name, const char *window ) +{ + return; + + wxString tmp = name; + tmp += " FROM "; + tmp += window; + + char *s = new char[tmp.Length()+1]; + + strcpy( s, WXSTRINGCAST tmp ); + + gtk_signal_connect( GTK_OBJECT(widget), "focus_in_event", + GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback), (gpointer)s ); +} + +#endif + //----------------------------------------------------------------------------- // data //----------------------------------------------------------------------------- -extern wxList wxPendingDelete; -extern wxList wxTopLevelWindows; -extern bool g_blockEventsOnDrag; -extern bool g_blockEventsOnScroll; -static bool g_capturing = FALSE; +extern wxList wxPendingDelete; +extern wxList wxTopLevelWindows; +extern bool g_blockEventsOnDrag; +extern bool g_blockEventsOnScroll; +static bool g_capturing = FALSE; +static wxWindow *g_focusWindow = (wxWindow*) NULL; // hack: we need something to pass to gtk_menu_popup, so we store the time of // the last click here @@ -181,7 +217,7 @@ static void gtk_window_draw_callback( GtkWidget *WXUNUSED(widget), GdkRectangle } //----------------------------------------------------------------------------- -// "key_press_event" +// "key_press_event" from any window //----------------------------------------------------------------------------- static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_event, wxWindow *win ) @@ -303,11 +339,41 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_e ancestor = ancestor->GetParent(); } } - + + // win is a control: tab can be propagated up + if ((!ret) && (gdk_event->keyval == GDK_Tab)) + { + wxNavigationKeyEvent new_event; + new_event.SetDirection( !(gdk_event->state & GDK_SHIFT_MASK) ); + new_event.SetWindowChange( FALSE ); + new_event.SetCurrentFocus( win ); + ret = win->GetEventHandler()->ProcessEvent( new_event ); + } + +/* + // win is a panel: up can be propagated to the panel + if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) && + (gdk_event->keyval == GDK_Up)) + { + win->m_parent->SetFocus(); + ret = TRUE; + } + + // win is a panel: left/right can be propagated to the panel + if ((!ret) && (win->m_wxwindow) && + ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) || + (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down))) + { + wxNavigationKeyEvent new_event; + new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) ); + new_event.SetCurrentFocus( win ); + ret = win->GetEventHandler()->ProcessEvent( new_event ); + } +*/ + if (ret) { - if ((gdk_event->keyval >= 0x20) && (gdk_event->keyval <= 0xFF)) - gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "key_press_event" ); + gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "key_press_event" ); } return ret; @@ -658,6 +724,9 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion static gint gtk_window_focus_in_callback( GtkWidget *widget, GdkEvent *WXUNUSED(event), wxWindow *win ) { if (g_blockEventsOnDrag) return TRUE; + + g_focusWindow = win; + if (win->m_wxwindow) { if (GTK_WIDGET_CAN_FOCUS(win->m_wxwindow)) @@ -729,10 +798,13 @@ static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEvent *WXUNUSED static gint gtk_window_enter_callback( GtkWidget *widget, GdkEventCrossing *gdk_event, wxWindow *win ) { - if (widget->window != gdk_event->window) return TRUE; - if (g_blockEventsOnDrag) return TRUE; + if ((widget->window) && (win->m_cursor)) + gdk_window_set_cursor( widget->window, win->m_cursor->GetCursor() ); + + if (widget->window != gdk_event->window) return TRUE; + if (!win->HasVMT()) return TRUE; /* @@ -742,9 +814,6 @@ static gint gtk_window_enter_callback( GtkWidget *widget, GdkEventCrossing *gdk_ printf( ".\n" ); */ - if ((widget->window) && (win->m_cursor)) - gdk_window_set_cursor( widget->window, win->m_cursor->GetCursor() ); - wxMouseEvent event( wxEVT_ENTER_WINDOW ); event.SetEventObject( win ); @@ -777,10 +846,13 @@ static gint gtk_window_enter_callback( GtkWidget *widget, GdkEventCrossing *gdk_ static gint gtk_window_leave_callback( GtkWidget *widget, GdkEventCrossing *gdk_event, wxWindow *win ) { - if (widget->window != gdk_event->window) return TRUE; - if (g_blockEventsOnDrag) return TRUE; + if ((widget->window) && (win->m_cursor)) + gdk_window_set_cursor( widget->window, wxSTANDARD_CURSOR->GetCursor() ); + + if (widget->window != gdk_event->window) return TRUE; + if (!win->HasVMT()) return TRUE; /* @@ -790,9 +862,6 @@ static gint gtk_window_leave_callback( GtkWidget *widget, GdkEventCrossing *gdk_ printf( ".\n" ); */ - if ((widget->window) && (win->m_cursor)) - gdk_window_set_cursor( widget->window, wxSTANDARD_CURSOR->GetCursor() ); - wxMouseEvent event( wxEVT_LEAVE_WINDOW ); event.SetEventObject( win ); @@ -1104,6 +1173,7 @@ wxWindow::wxWindow() m_clientData = NULL; m_isStaticBox = FALSE; + m_acceptsFocus = FALSE; } wxWindow::wxWindow( wxWindow *parent, wxWindowID id, @@ -1126,9 +1196,18 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id, m_widget = gtk_scrolled_window_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL ); GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS ); + +#ifdef __WXDEBUG__ + debug_focus_in( m_widget, "wxWindow::m_widget", name ); +#endif GtkScrolledWindow *s_window = GTK_SCROLLED_WINDOW(m_widget); +#ifdef __WXDEBUG__ + debug_focus_in( s_window->hscrollbar, "wxWindow::hsrcollbar", name ); + debug_focus_in( s_window->vscrollbar, "wxWindow::vsrcollbar", name ); +#endif + GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass ); scroll_class->scrollbar_spacing = 0; @@ -1142,6 +1221,10 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id, m_wxwindow = gtk_myfixed_new(); +#ifdef __WXDEBUG__ + debug_focus_in( m_wxwindow, "wxWindow::m_wxwindow", name ); +#endif + #ifdef NEW_GTK_SCROLL_CODE gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(m_widget), m_wxwindow ); GtkViewport *viewport = GTK_VIEWPORT(s_window->child); @@ -1150,6 +1233,10 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id, GtkViewport *viewport = GTK_VIEWPORT(s_window->viewport); #endif +#ifdef __WXDEBUG__ + debug_focus_in( GTK_WIDGET(viewport), "wxWindow::viewport", name ); +#endif + if (m_windowStyle & wxRAISED_BORDER) { gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_OUT ); @@ -1163,10 +1250,16 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id, gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_NONE ); } - if (m_windowStyle & wxTAB_TRAVERSAL == wxTAB_TRAVERSAL) + if ((m_windowStyle & wxTAB_TRAVERSAL) != 0) + { GTK_WIDGET_UNSET_FLAGS( m_wxwindow, GTK_CAN_FOCUS ); + m_acceptsFocus = FALSE; + } else + { GTK_WIDGET_SET_FLAGS( m_wxwindow, GTK_CAN_FOCUS ); + m_acceptsFocus = TRUE; + } // shut the viewport up gtk_viewport_set_hadjustment( viewport, (GtkAdjustment*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) ); @@ -1902,17 +1995,34 @@ void wxWindow::MakeModal( bool modal ) void wxWindow::SetFocus() { wxCHECK_RET( (m_widget != NULL), "invalid window" ); - + GtkWidget *connect_widget = GetConnectWidget(); if (connect_widget) { - if (GTK_WIDGET_CAN_FOCUS(connect_widget) && !GTK_WIDGET_HAS_FOCUS (connect_widget) ) + if (GTK_WIDGET_CAN_FOCUS(connect_widget) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ ) { gtk_widget_grab_focus (connect_widget); } + else if (GTK_IS_CONTAINER(connect_widget)) + { + gtk_container_focus( GTK_CONTAINER(connect_widget), GTK_DIR_TAB_FORWARD ); + } + else + { + } } } +wxWindow *wxWindow::FindFocus() +{ + return g_focusWindow; +} + +bool wxWindow::AcceptsFocus() const +{ + return IsEnabled() && IsShown() && m_acceptsFocus; +} + bool wxWindow::OnClose() { return TRUE; @@ -3154,8 +3264,8 @@ void wxWindow::GetClientSizeConstraint(int *w, int *h) const void wxWindow::GetPositionConstraint(int *x, int *y) const { - wxLayoutConstraints *constr = GetConstraints(); - if (constr) + wxLayoutConstraints *constr = GetConstraints(); + if (constr) { *x = constr->left.GetValue(); *y = constr->top.GetValue(); @@ -3164,12 +3274,7 @@ void wxWindow::GetPositionConstraint(int *x, int *y) const GetPosition(x, y); } -bool wxWindow::AcceptsFocus() const -{ - return IsEnabled() && IsShown(); -} - void wxWindow::OnIdle(wxIdleEvent& WXUNUSED(event) ) { - UpdateWindowUI(); + UpdateWindowUI(); } -- 2.45.2