]> git.saurik.com Git - wxWidgets.git/commitdiff
support mnemonics for wxStatic/RadioBox and made it easier to add support for more...
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 12 Mar 2006 14:21:19 +0000 (14:21 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 12 Mar 2006 14:21:19 +0000 (14:21 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@38027 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/changes.txt
include/wx/gtk/control.h
include/wx/gtk/radiobox.h
include/wx/gtk/statbox.h
include/wx/gtk/stattext.h
include/wx/gtk/window.h
src/gtk/control.cpp
src/gtk/radiobox.cpp
src/gtk/statbox.cpp
src/gtk/stattext.cpp
src/gtk/window.cpp

index a89fa51c0086caf596ecbe8954c7362c5791f5cb..7e852f490f8ef500d17688c1248f67916a300b77 100644 (file)
@@ -151,6 +151,11 @@ wxGTK:
   --enable-gstreamer8 to force configure to check for GStreamer 0.8.\
 - Fixed problem with choice editor in wxGrid whereby the editor
   lost focus when the combobox menu was shown.
   --enable-gstreamer8 to force configure to check for GStreamer 0.8.\
 - Fixed problem with choice editor in wxGrid whereby the editor
   lost focus when the combobox menu was shown.
+- Fixed focusing with mnemonic accelerator keys on wxStaticText which
+  is now able to focus on wxComboBox and possibly other controls
+  previously unable to be focused upon before
+- Enabled mnemonics and the corresponding accelerator keys for 
+  wxStaticBox and wxRadioBox
 - Fixed problem trying to print from a preview, whereby wrong printer
   class was used.
 - Worked around pango crashes in strncmp on Solaris 10.
 - Fixed problem trying to print from a preview, whereby wrong printer
   class was used.
 - Worked around pango crashes in strncmp on Solaris 10.
index 42e48726bfd212cdc2ba7a3fc3811c036fd78b4d..f2e5c6dc045aa7b5c84e77aec6f2723f546d865d 100644 (file)
@@ -66,8 +66,11 @@ protected:
     // sets the label to the given string and also sets it for the given widget
     void GTKSetLabelForLabel(GtkLabel *w, const wxString& label);
 
     // sets the label to the given string and also sets it for the given widget
     void GTKSetLabelForLabel(GtkLabel *w, const wxString& label);
 
-    // as GTKSetLabelForLabel() but for a GtkFrame widget
+    // GtkFrame helpers
+    GtkWidget* GTKCreateFrame(const wxString& label);
     void GTKSetLabelForFrame(GtkFrame *w, const wxString& label);
     void GTKSetLabelForFrame(GtkFrame *w, const wxString& label);
+    void GTKFrameApplyWidgetStyle(GtkFrame* w, GtkRcStyle* rc);
+    void GTKFrameSetMnemonicWidget(GtkFrame* w, GtkWidget* widget);
 
     // remove mnemonics ("&"s) from the label
     static wxString GTKRemoveMnemonics(const wxString& label);
 
     // remove mnemonics ("&"s) from the label
     static wxString GTKRemoveMnemonics(const wxString& label);
index fedb790c06aceefa8bb02b67921945f057a4952b..244dbab904ec9ddb31c83d5d1dcb622fbede30e0 100644 (file)
@@ -127,6 +127,9 @@ public:
 protected:
     void DoApplyWidgetStyle(GtkRcStyle *style);
 
 protected:
     void DoApplyWidgetStyle(GtkRcStyle *style);
 
+    virtual bool GTKWidgetNeedsMnemonic() const;
+    virtual void GTKWidgetDoSetMnemonic(GtkWidget* w);
+
     // common part of all ctors
     void Init();
 
     // common part of all ctors
     void Init();
 
index 67e0a8e21de9069fa9a49b470311d6c96b2406ef..90c5abc8c3f7909e169779ac21921bff4b12d529 100644 (file)
@@ -43,6 +43,9 @@ public:
     virtual bool IsTransparentForMouse() const { return TRUE; }
 
 protected:
     virtual bool IsTransparentForMouse() const { return TRUE; }
 
 protected:
+    virtual bool GTKWidgetNeedsMnemonic() const;
+    virtual void GTKWidgetDoSetMnemonic(GtkWidget* w);
+
     void DoApplyWidgetStyle(GtkRcStyle *style);
     
 private:
     void DoApplyWidgetStyle(GtkRcStyle *style);
     
 private:
index c17c4105912d5cd4ace1559db88c74753b7bfbc6..dd123049847a6b7959318099cd7d7ae88b24bb00 100644 (file)
@@ -65,6 +65,9 @@ public:
     // --------------
 
 protected:
     // --------------
 
 protected:
+    virtual bool GTKWidgetNeedsMnemonic() const;
+    virtual void GTKWidgetDoSetMnemonic(GtkWidget* w);
+
     virtual void DoSetSize(int x, int y,
                            int width, int height,
                            int sizeFlags = wxSIZE_AUTO);
     virtual void DoSetSize(int x, int y,
                            int width, int height,
                            int sizeFlags = wxSIZE_AUTO);
index c14e0d836e9bb3a1abae0878c5c5e5d0aec58874..44b7940a8e7bdeceddca014a559137a755e5b28a 100644 (file)
@@ -156,6 +156,13 @@ public:
     virtual bool IsOwnGtkWindow( GdkWindow *window );
     void ConnectWidget( GtkWidget *widget );
 
     virtual bool IsOwnGtkWindow( GdkWindow *window );
     void ConnectWidget( GtkWidget *widget );
 
+    // Override GTKWidgetNeedsMnemonic and return true if your
+    // needs to set its mnemonic widget, such as for a 
+    // GtkLabel for wxStaticText, then do the actual
+    // setting of the widget inside GTKWidgetDoSetMnemonic
+    virtual bool GTKWidgetNeedsMnemonic() const;
+    virtual void GTKWidgetDoSetMnemonic(GtkWidget* w);
+
     // Returns the default context which usually is anti-aliased
     PangoContext   *GtkGetPangoDefaultContext();
 
     // Returns the default context which usually is anti-aliased
     PangoContext   *GtkGetPangoDefaultContext();
 
index 921820d4275eab3864061c3473d9279c16a66db0..4368959b6c8bf116e789e6d05bdddc9f3a472a91 100644 (file)
@@ -66,7 +66,6 @@ wxSize wxControl::DoGetBestSize() const
     return best;
 }
 
     return best;
 }
 
-
 void wxControl::PostCreation(const wxSize& size)
 {
     wxWindow::PostCreation();
 void wxControl::PostCreation(const wxSize& size)
 {
     wxWindow::PostCreation();
@@ -110,22 +109,54 @@ void wxControl::GTKSetLabelForLabel(GtkLabel *w, const wxString& label)
     gtk_label_set_text_with_mnemonic(w, wxGTK_CONV(labelGTK));
 }
 
     gtk_label_set_text_with_mnemonic(w, wxGTK_CONV(labelGTK));
 }
 
+// ----------------------------------------------------------------------------
+// GtkFrame helpers
+//
+// GtkFrames do in fact support mnemonics in GTK2+ but not through
+// gtk_frame_set_label, rather you need to use a custom label widget
+// instead (idea gleaned from the native gtk font dialog code in GTK)
+// ----------------------------------------------------------------------------
+
+GtkWidget* wxControl::GTKCreateFrame(const wxString& label)
+{
+    const wxString labelGTK = GTKConvertMnemonics(label);
+    GtkWidget* labelwidget = gtk_label_new_with_mnemonic(wxGTK_CONV(labelGTK));
+    gtk_widget_show(labelwidget); // without this it won't show...
+
+    GtkWidget* framewidget = gtk_frame_new(NULL);
+    gtk_frame_set_label_widget(GTK_FRAME(framewidget), labelwidget);
+
+    return framewidget; //note that the label is already set so you'll 
+                        //only need to call wxControl::SetLabel afterwards
+}
+
 void wxControl::GTKSetLabelForFrame(GtkFrame *w, const wxString& label)
 {
 void wxControl::GTKSetLabelForFrame(GtkFrame *w, const wxString& label)
 {
-    wxControl::SetLabel(label);
+    GtkLabel* labelwidget = GTK_LABEL(gtk_frame_get_label_widget(w));
+    GTKSetLabelForLabel(labelwidget, label);
+}
+
+void wxControl::GTKFrameApplyWidgetStyle(GtkFrame* w, GtkRcStyle* style)
+{
+    gtk_widget_modify_style(GTK_WIDGET(w), style);
+    gtk_widget_modify_style(gtk_frame_get_label_widget (w), style);
+}
 
 
-    // frames don't support mnemonics even under GTK+ 2
-    const wxString labelGTK = GTKRemoveMnemonics(label);
+void wxControl::GTKFrameSetMnemonicWidget(GtkFrame* w, GtkWidget* widget)
+{
+    GtkLabel* labelwidget = GTK_LABEL(gtk_frame_get_label_widget(w));
 
 
-    gtk_frame_set_label(w, labelGTK.empty() ? (char *)NULL
-                                            : wxGTK_CONV(labelGTK));
+    gtk_label_set_mnemonic_widget(labelwidget, widget);
 }
 
 }
 
+// ----------------------------------------------------------------------------
 // worker function implementing both GTKConvert/RemoveMnemonics()
 //
 // notice that under GTK+ 1 we only really need to support MNEMONICS_REMOVE as
 // it doesn't support mnemonics anyhow but this would make the code so ugly
 // that we do the same thing for GKT+ 1 and 2
 // worker function implementing both GTKConvert/RemoveMnemonics()
 //
 // notice that under GTK+ 1 we only really need to support MNEMONICS_REMOVE as
 // it doesn't support mnemonics anyhow but this would make the code so ugly
 // that we do the same thing for GKT+ 1 and 2
+// ----------------------------------------------------------------------------
+
 enum MnemonicsFlag
 {
     MNEMONICS_REMOVE,
 enum MnemonicsFlag
 {
     MNEMONICS_REMOVE,
index 686e8979ae169cc7fd2ccc7c608abcbdc3679d55..283027982e95e708102db8fcc4d2902036cf452e 100644 (file)
@@ -205,8 +205,8 @@ bool wxRadioBox::Create( wxWindow *parent, wxWindowID id, const wxString& title,
         return false;
     }
 
         return false;
     }
 
-    m_widget = gtk_frame_new(NULL);
-    SetLabel(title);
+    m_widget = GTKCreateFrame(title);
+    wxControl::SetLabel(title);
 
     // majorDim may be 0 if all trailing parameters were omitted, so don't
     // assert here but just use the correct value for it
 
     // majorDim may be 0 if all trailing parameters were omitted, so don't
     // assert here but just use the correct value for it
@@ -530,8 +530,7 @@ void wxRadioBox::GtkEnableEvents()
 
 void wxRadioBox::DoApplyWidgetStyle(GtkRcStyle *style)
 {
 
 void wxRadioBox::DoApplyWidgetStyle(GtkRcStyle *style)
 {
-    gtk_widget_modify_style( m_widget, style );
-    gtk_widget_modify_style(GTK_FRAME(m_widget)->label_widget, style);
+    GTKFrameApplyWidgetStyle(GTK_FRAME(m_widget), style);
 
     wxList::compatibility_iterator node = m_boxes.GetFirst();
     while (node)
 
     wxList::compatibility_iterator node = m_boxes.GetFirst();
     while (node)
@@ -545,6 +544,16 @@ void wxRadioBox::DoApplyWidgetStyle(GtkRcStyle *style)
     }
 }
 
     }
 }
 
+bool wxRadioBox::GTKWidgetNeedsMnemonic() const
+{
+    return true;
+}
+
+void wxRadioBox::GTKWidgetDoSetMnemonic(GtkWidget* w)
+{
+    GTKFrameSetMnemonicWidget(GTK_FRAME(m_widget), w);
+}
+
 #if wxUSE_TOOLTIPS
 void wxRadioBox::ApplyToolTip( GtkTooltips *tips, const wxChar *tip )
 {
 #if wxUSE_TOOLTIPS
 void wxRadioBox::ApplyToolTip( GtkTooltips *tips, const wxChar *tip )
 {
index 89c9c8adc3cf9c3e9409c271bc0aaa8d3049b73d..4d3feeb72b0fa7675a13af950b2bfe45c6140b27 100644 (file)
@@ -56,8 +56,8 @@ bool wxStaticBox::Create( wxWindow *parent,
         return FALSE;
     }
 
         return FALSE;
     }
 
-    m_widget = gtk_frame_new(NULL);
-    SetLabel(label);
+    m_widget = GTKCreateFrame(label);
+    wxControl::SetLabel(label);
 
     m_parent->DoAddChild( this );
 
 
     m_parent->DoAddChild( this );
 
@@ -87,8 +87,17 @@ void wxStaticBox::SetLabel( const wxString& label )
 
 void wxStaticBox::DoApplyWidgetStyle(GtkRcStyle *style)
 {
 
 void wxStaticBox::DoApplyWidgetStyle(GtkRcStyle *style)
 {
-    gtk_widget_modify_style(m_widget, style);
-    gtk_widget_modify_style(GTK_FRAME(m_widget)->label_widget, style);
+    GTKFrameApplyWidgetStyle(GTK_FRAME(m_widget), style);
+}
+
+bool wxStaticBox::GTKWidgetNeedsMnemonic() const
+{
+    return true;
+}
+
+void wxStaticBox::GTKWidgetDoSetMnemonic(GtkWidget* w)
+{
+    GTKFrameSetMnemonicWidget(GTK_FRAME(m_widget), w);
 }
 
 // static
 }
 
 // static
index 1befdd1c898c6d659d13befb5a75f7febfb80db6..2641ea02f33db4b7a9c41169d89db99d8dc0c86d 100644 (file)
@@ -166,6 +166,16 @@ bool wxStaticText::SetForegroundColour(const wxColour& colour)
     return true;
 }
 
     return true;
 }
 
+bool wxStaticText::GTKWidgetNeedsMnemonic() const
+{
+    return true;
+}
+
+void wxStaticText::GTKWidgetDoSetMnemonic(GtkWidget* w)
+{
+    gtk_label_set_mnemonic_widget(GTK_LABEL(m_widget), w);
+}
+
 // static
 wxVisualAttributes
 wxStaticText::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
 // static
 wxVisualAttributes
 wxStaticText::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
index b54d7239f1a1cd4c24ee710fa63defe3dc0be0ac..95dd20fbcba7221589349b8ba4b5b4f8c5e669ba 100644 (file)
@@ -50,7 +50,6 @@
 #include "wx/settings.h"
 #include "wx/log.h"
 #include "wx/fontutil.h"
 #include "wx/settings.h"
 #include "wx/log.h"
 #include "wx/fontutil.h"
-#include "wx/stattext.h"
 
 #ifdef __WXDEBUG__
     #include "wx/thread.h"
 
 #ifdef __WXDEBUG__
     #include "wx/thread.h"
@@ -1755,7 +1754,7 @@ gtk_window_motion_notify_callback( GtkWidget *widget,
             // Rewrite cursor handling here (away from idle).
         }
     }
             // Rewrite cursor handling here (away from idle).
         }
     }
-    
+
     if (win->GetEventHandler()->ProcessEvent( event ))
     {
         g_signal_stop_emission_by_name (widget, "motion_notify_event");
     if (win->GetEventHandler()->ProcessEvent( event ))
     {
         g_signal_stop_emission_by_name (widget, "motion_notify_event");
@@ -2024,7 +2023,7 @@ gtk_window_enter_callback( GtkWidget *widget,
             // Rewrite cursor handling here (away from idle).
         }
     }
             // Rewrite cursor handling here (away from idle).
         }
     }
-    
+
     if (win->GetEventHandler()->ProcessEvent( event ))
     {
        g_signal_stop_emission_by_name (widget, "enter_notify_event");
     if (win->GetEventHandler()->ProcessEvent( event ))
     {
        g_signal_stop_emission_by_name (widget, "enter_notify_event");
@@ -2943,7 +2942,7 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags
        if (GTK_WIDGET_VISIBLE (widget))
             gtk_widget_queue_resize (widget);
     }
        if (GTK_WIDGET_VISIBLE (widget))
             gtk_widget_queue_resize (widget);
     }
-    else 
+    else
 #endif
     if (m_parent->m_wxwindow == NULL) // i.e. wxNotebook
     {
 #endif
     if (m_parent->m_wxwindow == NULL) // i.e. wxNotebook
     {
@@ -3606,44 +3605,62 @@ void wxWindowGTK::DoMoveInTabOrder(wxWindow *win, MoveKind move)
         wxapp_install_idle_handler();
 }
 
         wxapp_install_idle_handler();
 }
 
+bool wxWindowGTK::GTKWidgetNeedsMnemonic() const
+{
+    // none needed by default
+    return false;
+}
+
+void wxWindowGTK::GTKWidgetDoSetMnemonic(GtkWidget* WXUNUSED(w))
+{
+    // nothing to do by default since none is needed
+}
+
 void wxWindowGTK::RealizeTabOrder()
 {
     if (m_wxwindow)
     {
         if ( !m_children.empty() )
         {
 void wxWindowGTK::RealizeTabOrder()
 {
     if (m_wxwindow)
     {
         if ( !m_children.empty() )
         {
-#if wxUSE_STATTEXT
             // we don't only construct the correct focus chain but also use
             // we don't only construct the correct focus chain but also use
-            // this opportunity to update the mnemonic widgets for all labels
-            //
-            // it would be nice to extract this code from here and put it in
-            // stattext.cpp to reduce dependencies but there is no really easy
-            // way to do it unfortunately
-            wxStaticText *lastLabel = NULL;
-#endif // wxUSE_STATTEXT
+            // this opportunity to update the mnemonic widgets for the widgets
+            // that need them
 
             GList *chain = NULL;
 
             GList *chain = NULL;
+            wxWindowGTK* mnemonicWindow = NULL;
 
             for ( wxWindowList::const_iterator i = m_children.begin();
                   i != m_children.end();
                   ++i )
             {
                 wxWindowGTK *win = *i;
 
             for ( wxWindowList::const_iterator i = m_children.begin();
                   i != m_children.end();
                   ++i )
             {
                 wxWindowGTK *win = *i;
-#if wxUSE_STATTEXT
-                if ( lastLabel )
+
+                if ( mnemonicWindow )
                 {
                     if ( win->AcceptsFocusFromKeyboard() )
                     {
                 {
                     if ( win->AcceptsFocusFromKeyboard() )
                     {
-                        GtkLabel *l = GTK_LABEL(lastLabel->m_widget);
-                        gtk_label_set_mnemonic_widget(l, win->m_widget);
-                        lastLabel = NULL;
+                        // wxComboBox et al. needs to focus on on a different
+                        // widget than m_widget, so if the main widget isn't
+                        // focusable try the connect widget
+                        GtkWidget* w = win->m_widget;
+                        if ( !GTK_WIDGET_CAN_FOCUS(w) )
+                        {
+                            w = win->GetConnectWidget();
+                            if ( !GTK_WIDGET_CAN_FOCUS(w) )
+                                w = NULL;
+                        }
+
+                        if ( w )
+                        {
+                            mnemonicWindow->GTKWidgetDoSetMnemonic(w);
+                            mnemonicWindow = NULL;
+                        }
                     }
                 }
                     }
                 }
-                else // check if this one is a label
+                else if ( win->GTKWidgetNeedsMnemonic() )
                 {
                 {
-                    lastLabel = wxDynamicCast(win, wxStaticText);
+                    mnemonicWindow = win;
                 }
                 }
-#endif // wxUSE_STATTEXT
 
                 chain = g_list_prepend(chain, win->m_widget);
             }
 
                 chain = g_list_prepend(chain, win->m_widget);
             }