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.\
|
||||
- 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.
|
||||
|
@@ -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);
|
||||
|
||||
// as GTKSetLabelForLabel() but for a GtkFrame widget
|
||||
// GtkFrame helpers
|
||||
GtkWidget* GTKCreateFrame(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);
|
||||
|
@@ -127,6 +127,9 @@ public:
|
||||
protected:
|
||||
void DoApplyWidgetStyle(GtkRcStyle *style);
|
||||
|
||||
virtual bool GTKWidgetNeedsMnemonic() const;
|
||||
virtual void GTKWidgetDoSetMnemonic(GtkWidget* w);
|
||||
|
||||
// common part of all ctors
|
||||
void Init();
|
||||
|
||||
|
@@ -43,6 +43,9 @@ public:
|
||||
virtual bool IsTransparentForMouse() const { return TRUE; }
|
||||
|
||||
protected:
|
||||
virtual bool GTKWidgetNeedsMnemonic() const;
|
||||
virtual void GTKWidgetDoSetMnemonic(GtkWidget* w);
|
||||
|
||||
void DoApplyWidgetStyle(GtkRcStyle *style);
|
||||
|
||||
private:
|
||||
|
@@ -65,6 +65,9 @@ public:
|
||||
// --------------
|
||||
|
||||
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);
|
||||
|
@@ -156,6 +156,13 @@ public:
|
||||
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();
|
||||
|
||||
|
@@ -66,7 +66,6 @@ wxSize wxControl::DoGetBestSize() const
|
||||
return best;
|
||||
}
|
||||
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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
|
||||
const wxString labelGTK = GTKRemoveMnemonics(label);
|
||||
GtkWidget* framewidget = gtk_frame_new(NULL);
|
||||
gtk_frame_set_label_widget(GTK_FRAME(framewidget), labelwidget);
|
||||
|
||||
gtk_frame_set_label(w, labelGTK.empty() ? (char *)NULL
|
||||
: wxGTK_CONV(labelGTK));
|
||||
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)
|
||||
{
|
||||
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()
|
||||
//
|
||||
// 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,
|
||||
|
@@ -205,8 +205,8 @@ bool wxRadioBox::Create( wxWindow *parent, wxWindowID id, const wxString& title,
|
||||
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
|
||||
@@ -530,8 +530,7 @@ void wxRadioBox::GtkEnableEvents()
|
||||
|
||||
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)
|
||||
@@ -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 )
|
||||
{
|
||||
|
@@ -56,8 +56,8 @@ bool wxStaticBox::Create( wxWindow *parent,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
m_widget = gtk_frame_new(NULL);
|
||||
SetLabel(label);
|
||||
m_widget = GTKCreateFrame(label);
|
||||
wxControl::SetLabel(label);
|
||||
|
||||
m_parent->DoAddChild( this );
|
||||
|
||||
@@ -87,8 +87,17 @@ void wxStaticBox::SetLabel( const wxString& label )
|
||||
|
||||
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
|
||||
|
@@ -166,6 +166,16 @@ bool wxStaticText::SetForegroundColour(const wxColour& colour)
|
||||
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))
|
||||
|
@@ -50,7 +50,6 @@
|
||||
#include "wx/settings.h"
|
||||
#include "wx/log.h"
|
||||
#include "wx/fontutil.h"
|
||||
#include "wx/stattext.h"
|
||||
|
||||
#ifdef __WXDEBUG__
|
||||
#include "wx/thread.h"
|
||||
@@ -3606,44 +3605,62 @@ void wxWindowGTK::DoMoveInTabOrder(wxWindow *win, MoveKind move)
|
||||
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() )
|
||||
{
|
||||
#if wxUSE_STATTEXT
|
||||
// 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;
|
||||
wxWindowGTK* mnemonicWindow = NULL;
|
||||
|
||||
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() )
|
||||
{
|
||||
GtkLabel *l = GTK_LABEL(lastLabel->m_widget);
|
||||
gtk_label_set_mnemonic_widget(l, win->m_widget);
|
||||
lastLabel = NULL;
|
||||
}
|
||||
}
|
||||
else // check if this one is a label
|
||||
// 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) )
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user