support mnemonics for wxStatic/RadioBox and made it easier to add support for more controls by virtualizing the mnemonics support logic (patch 1448178)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@38027 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -151,6 +151,11 @@ wxGTK:
|
|||||||
--enable-gstreamer8 to force configure to check for GStreamer 0.8.\
|
--enable-gstreamer8 to force configure to check for GStreamer 0.8.\
|
||||||
- Fixed problem with choice editor in wxGrid whereby the editor
|
- Fixed problem with choice editor in wxGrid whereby the editor
|
||||||
lost focus when the combobox menu was shown.
|
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
|
- Fixed problem trying to print from a preview, whereby wrong printer
|
||||||
class was used.
|
class was used.
|
||||||
- Worked around pango crashes in strncmp on Solaris 10.
|
- Worked around pango crashes in strncmp on Solaris 10.
|
||||||
|
@@ -66,8 +66,11 @@ protected:
|
|||||||
// sets the label to the given string and also sets it for the given widget
|
// sets the label to the given string and also sets it for the given widget
|
||||||
void GTKSetLabelForLabel(GtkLabel *w, const wxString& label);
|
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
|
// remove mnemonics ("&"s) from the label
|
||||||
static wxString GTKRemoveMnemonics(const wxString& label);
|
static wxString GTKRemoveMnemonics(const wxString& label);
|
||||||
|
@@ -127,6 +127,9 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
void DoApplyWidgetStyle(GtkRcStyle *style);
|
void DoApplyWidgetStyle(GtkRcStyle *style);
|
||||||
|
|
||||||
|
virtual bool GTKWidgetNeedsMnemonic() const;
|
||||||
|
virtual void GTKWidgetDoSetMnemonic(GtkWidget* w);
|
||||||
|
|
||||||
// common part of all ctors
|
// common part of all ctors
|
||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
|
@@ -43,6 +43,9 @@ public:
|
|||||||
virtual bool IsTransparentForMouse() const { return TRUE; }
|
virtual bool IsTransparentForMouse() const { return TRUE; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
virtual bool GTKWidgetNeedsMnemonic() const;
|
||||||
|
virtual void GTKWidgetDoSetMnemonic(GtkWidget* w);
|
||||||
|
|
||||||
void DoApplyWidgetStyle(GtkRcStyle *style);
|
void DoApplyWidgetStyle(GtkRcStyle *style);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@@ -65,6 +65,9 @@ public:
|
|||||||
// --------------
|
// --------------
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
virtual bool GTKWidgetNeedsMnemonic() const;
|
||||||
|
virtual void GTKWidgetDoSetMnemonic(GtkWidget* w);
|
||||||
|
|
||||||
virtual void DoSetSize(int x, int y,
|
virtual void DoSetSize(int x, int y,
|
||||||
int width, int height,
|
int width, int height,
|
||||||
int sizeFlags = wxSIZE_AUTO);
|
int sizeFlags = wxSIZE_AUTO);
|
||||||
|
@@ -156,6 +156,13 @@ public:
|
|||||||
virtual bool IsOwnGtkWindow( GdkWindow *window );
|
virtual bool IsOwnGtkWindow( GdkWindow *window );
|
||||||
void ConnectWidget( GtkWidget *widget );
|
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
|
// Returns the default context which usually is anti-aliased
|
||||||
PangoContext *GtkGetPangoDefaultContext();
|
PangoContext *GtkGetPangoDefaultContext();
|
||||||
|
|
||||||
|
@@ -66,7 +66,6 @@ wxSize wxControl::DoGetBestSize() const
|
|||||||
return best;
|
return best;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void wxControl::PostCreation(const wxSize& size)
|
void wxControl::PostCreation(const wxSize& size)
|
||||||
{
|
{
|
||||||
wxWindow::PostCreation();
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxControl::GTKSetLabelForFrame(GtkFrame *w, const wxString& label)
|
// ----------------------------------------------------------------------------
|
||||||
|
// 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)
|
||||||
{
|
{
|
||||||
wxControl::SetLabel(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...
|
||||||
|
|
||||||
// frames don't support mnemonics even under GTK+ 2
|
GtkWidget* framewidget = gtk_frame_new(NULL);
|
||||||
const wxString labelGTK = GTKRemoveMnemonics(label);
|
gtk_frame_set_label_widget(GTK_FRAME(framewidget), labelwidget);
|
||||||
|
|
||||||
gtk_frame_set_label(w, labelGTK.empty() ? (char *)NULL
|
return framewidget; //note that the label is already set so you'll
|
||||||
: wxGTK_CONV(labelGTK));
|
//only need to call wxControl::SetLabel afterwards
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxControl::GTKSetLabelForFrame(GtkFrame *w, const wxString& 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxControl::GTKFrameSetMnemonicWidget(GtkFrame* w, GtkWidget* widget)
|
||||||
|
{
|
||||||
|
GtkLabel* labelwidget = GTK_LABEL(gtk_frame_get_label_widget(w));
|
||||||
|
|
||||||
|
gtk_label_set_mnemonic_widget(labelwidget, widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
// worker function implementing both GTKConvert/RemoveMnemonics()
|
// worker function implementing both GTKConvert/RemoveMnemonics()
|
||||||
//
|
//
|
||||||
// notice that under GTK+ 1 we only really need to support MNEMONICS_REMOVE as
|
// 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
|
// 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
|
// that we do the same thing for GKT+ 1 and 2
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
enum MnemonicsFlag
|
enum MnemonicsFlag
|
||||||
{
|
{
|
||||||
MNEMONICS_REMOVE,
|
MNEMONICS_REMOVE,
|
||||||
|
@@ -205,8 +205,8 @@ bool wxRadioBox::Create( wxWindow *parent, wxWindowID id, const wxString& title,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_widget = gtk_frame_new(NULL);
|
m_widget = GTKCreateFrame(title);
|
||||||
SetLabel(title);
|
wxControl::SetLabel(title);
|
||||||
|
|
||||||
// majorDim may be 0 if all trailing parameters were omitted, so don't
|
// majorDim may be 0 if all trailing parameters were omitted, so don't
|
||||||
// assert here but just use the correct value for it
|
// 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 );
|
GTKFrameApplyWidgetStyle(GTK_FRAME(m_widget), style);
|
||||||
gtk_widget_modify_style(GTK_FRAME(m_widget)->label_widget, style);
|
|
||||||
|
|
||||||
wxList::compatibility_iterator node = m_boxes.GetFirst();
|
wxList::compatibility_iterator node = m_boxes.GetFirst();
|
||||||
while (node)
|
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
|
#if wxUSE_TOOLTIPS
|
||||||
void wxRadioBox::ApplyToolTip( GtkTooltips *tips, const wxChar *tip )
|
void wxRadioBox::ApplyToolTip( GtkTooltips *tips, const wxChar *tip )
|
||||||
{
|
{
|
||||||
|
@@ -56,8 +56,8 @@ bool wxStaticBox::Create( wxWindow *parent,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_widget = gtk_frame_new(NULL);
|
m_widget = GTKCreateFrame(label);
|
||||||
SetLabel(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);
|
GTKFrameApplyWidgetStyle(GTK_FRAME(m_widget), style);
|
||||||
gtk_widget_modify_style(GTK_FRAME(m_widget)->label_widget, style);
|
}
|
||||||
|
|
||||||
|
bool wxStaticBox::GTKWidgetNeedsMnemonic() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxStaticBox::GTKWidgetDoSetMnemonic(GtkWidget* w)
|
||||||
|
{
|
||||||
|
GTKFrameSetMnemonicWidget(GTK_FRAME(m_widget), w);
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
@@ -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
|
// static
|
||||||
wxVisualAttributes
|
wxVisualAttributes
|
||||||
wxStaticText::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
|
wxStaticText::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
|
||||||
|
@@ -50,7 +50,6 @@
|
|||||||
#include "wx/settings.h"
|
#include "wx/settings.h"
|
||||||
#include "wx/log.h"
|
#include "wx/log.h"
|
||||||
#include "wx/fontutil.h"
|
#include "wx/fontutil.h"
|
||||||
#include "wx/stattext.h"
|
|
||||||
|
|
||||||
#ifdef __WXDEBUG__
|
#ifdef __WXDEBUG__
|
||||||
#include "wx/thread.h"
|
#include "wx/thread.h"
|
||||||
@@ -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()
|
void wxWindowGTK::RealizeTabOrder()
|
||||||
{
|
{
|
||||||
if (m_wxwindow)
|
if (m_wxwindow)
|
||||||
{
|
{
|
||||||
if ( !m_children.empty() )
|
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
|
// this opportunity to update the mnemonic widgets for the widgets
|
||||||
//
|
// that need them
|
||||||
// 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
|
|
||||||
|
|
||||||
GList *chain = NULL;
|
GList *chain = NULL;
|
||||||
|
wxWindowGTK* mnemonicWindow = NULL;
|
||||||
|
|
||||||
for ( wxWindowList::const_iterator i = m_children.begin();
|
for ( wxWindowList::const_iterator i = m_children.begin();
|
||||||
i != m_children.end();
|
i != m_children.end();
|
||||||
++i )
|
++i )
|
||||||
{
|
{
|
||||||
wxWindowGTK *win = *i;
|
wxWindowGTK *win = *i;
|
||||||
#if wxUSE_STATTEXT
|
|
||||||
if ( lastLabel )
|
if ( mnemonicWindow )
|
||||||
{
|
{
|
||||||
if ( win->AcceptsFocusFromKeyboard() )
|
if ( win->AcceptsFocusFromKeyboard() )
|
||||||
{
|
{
|
||||||
GtkLabel *l = GTK_LABEL(lastLabel->m_widget);
|
// wxComboBox et al. needs to focus on on a different
|
||||||
gtk_label_set_mnemonic_widget(l, win->m_widget);
|
// widget than m_widget, so if the main widget isn't
|
||||||
lastLabel = NULL;
|
// focusable try the connect widget
|
||||||
}
|
GtkWidget* w = win->m_widget;
|
||||||
}
|
if ( !GTK_WIDGET_CAN_FOCUS(w) )
|
||||||
else // check if this one is a label
|
|
||||||
{
|
{
|
||||||
lastLabel = wxDynamicCast(win, wxStaticText);
|
w = win->GetConnectWidget();
|
||||||
|
if ( !GTK_WIDGET_CAN_FOCUS(w) )
|
||||||
|
w = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( w )
|
||||||
|
{
|
||||||
|
mnemonicWindow->GTKWidgetDoSetMnemonic(w);
|
||||||
|
mnemonicWindow = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( win->GTKWidgetNeedsMnemonic() )
|
||||||
|
{
|
||||||
|
mnemonicWindow = win;
|
||||||
}
|
}
|
||||||
#endif // wxUSE_STATTEXT
|
|
||||||
|
|
||||||
chain = g_list_prepend(chain, win->m_widget);
|
chain = g_list_prepend(chain, win->m_widget);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user