1. changed wxControl::GetLabel() to return the originally provided label and

not the one stripped from mnemonics (this was inconsistent with the other
   ports and resulted in problems when using wxUpdateUIEvent::SetText())
2. added wxControl::GTKConvertMnemonics(), GTKRemoveMnemonics() and also
   helper GTKSetLabelForLabel() and GTKSetLabelForFrame() wrappers
3. use them instead of duplicating their code in different derived controls


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@36435 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2005-12-18 16:37:56 +00:00
parent d1d40c2176
commit b2ff89d648
14 changed files with 398 additions and 330 deletions

View File

@ -21,6 +21,9 @@
class WXDLLIMPEXP_CORE wxControl;
typedef struct _GtkLabel GtkLabel;
typedef struct _GtkFrame GtkFrame;
//-----------------------------------------------------------------------------
// wxControl
//-----------------------------------------------------------------------------
@ -51,20 +54,29 @@ public:
const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxControlNameStr);
// this function will filter out '&' characters and will put the accelerator
// char (the one immediately after '&') into m_chAccel (TODO not yet)
virtual void SetLabel( const wxString &label );
virtual wxString GetLabel() const;
virtual wxVisualAttributes GetDefaultAttributes() const;
protected:
virtual wxSize DoGetBestSize() const;
void PostCreation(const wxSize& size);
#ifdef __WXGTK20__
wxString PrepareLabelMnemonics( const wxString &label ) const;
#endif
// 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
void GTKSetLabelForFrame(GtkFrame *w, const wxString& label);
// remove mnemonics ("&"s) from the label
static wxString GTKRemoveMnemonics(const wxString& label);
// converts wx label to GTK+ label, i.e. basically replace "&"s with "_"s
//
// for GTK+ 1 (which doesn't support mnemonics) this is the same as
// GTKRemoveMnemonics()
static wxString GTKConvertMnemonics(const wxString &label);
// These are used by GetDefaultAttributes
static wxVisualAttributes
@ -89,8 +101,8 @@ protected:
// override this and return true.
virtual bool UseGTKStyleBase() const { return false; }
wxString m_label;
char m_chAccel; // enabled to avoid breaking binary compatibility later on
// this field contains the label in wx format, i.e. with "&" mnemonics
wxString m_label;
private:
DECLARE_DYNAMIC_CLASS(wxControl)

View File

@ -21,6 +21,9 @@
class WXDLLIMPEXP_CORE wxControl;
typedef struct _GtkLabel GtkLabel;
typedef struct _GtkFrame GtkFrame;
//-----------------------------------------------------------------------------
// wxControl
//-----------------------------------------------------------------------------
@ -51,20 +54,29 @@ public:
const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxControlNameStr);
// this function will filter out '&' characters and will put the accelerator
// char (the one immediately after '&') into m_chAccel (TODO not yet)
virtual void SetLabel( const wxString &label );
virtual wxString GetLabel() const;
virtual wxVisualAttributes GetDefaultAttributes() const;
protected:
virtual wxSize DoGetBestSize() const;
void PostCreation(const wxSize& size);
#ifdef __WXGTK20__
wxString PrepareLabelMnemonics( const wxString &label ) const;
#endif
// 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
void GTKSetLabelForFrame(GtkFrame *w, const wxString& label);
// remove mnemonics ("&"s) from the label
static wxString GTKRemoveMnemonics(const wxString& label);
// converts wx label to GTK+ label, i.e. basically replace "&"s with "_"s
//
// for GTK+ 1 (which doesn't support mnemonics) this is the same as
// GTKRemoveMnemonics()
static wxString GTKConvertMnemonics(const wxString &label);
// These are used by GetDefaultAttributes
static wxVisualAttributes
@ -89,8 +101,8 @@ protected:
// override this and return true.
virtual bool UseGTKStyleBase() const { return false; }
wxString m_label;
char m_chAccel; // enabled to avoid breaking binary compatibility later on
// this field contains the label in wx format, i.e. with "&" mnemonics
wxString m_label;
private:
DECLARE_DYNAMIC_CLASS(wxControl)

View File

@ -67,12 +67,12 @@ gtk_button_style_set_callback( GtkWidget *m_widget, GtkStyle *WXUNUSED(style), w
{
if (g_isIdle)
wxapp_install_idle_handler();
int left_border = 0;
int right_border = 0;
int top_border = 0;
int bottom_border = 0;
/* the default button has a border around it */
if (GTK_WIDGET_CAN_DEFAULT(m_widget))
{
@ -97,7 +97,7 @@ gtk_button_style_set_callback( GtkWidget *m_widget, GtkStyle *WXUNUSED(style), w
win->m_y-left_border,
win->m_width+left_border+right_border,
win->m_height+top_border+bottom_border );
}
}
return FALSE;
}
@ -130,28 +130,6 @@ bool wxButton::Create( wxWindow *parent, wxWindowID id, const wxString &label,
return FALSE;
}
/*
wxString label2( label );
for (size_t i = 0; i < label2.Len(); i++)
{
if (label2.GetChar(i) == wxT('&'))
label2.SetChar(i,wxT('_'));
}
GtkWidget *accel_label = gtk_accel_label_new( label2.mb_str() );
gtk_widget_show( accel_label );
m_widget = gtk_button_new();
gtk_container_add( GTK_CONTAINER(m_widget), accel_label );
gtk_accel_label_set_accel_widget( GTK_ACCEL_LABEL(accel_label), m_widget );
guint accel_key = gtk_label_parse_uline (GTK_LABEL(accel_label), label2.mb_str() );
gtk_accel_label_refetch( GTK_ACCEL_LABEL(accel_label) );
wxControl::SetLabel( label );
*/
#ifdef __WXGTK20__
m_widget = gtk_button_new_with_mnemonic("");
#else
@ -193,14 +171,14 @@ bool wxButton::Create( wxWindow *parent, wxWindowID id, const wxString &label,
gtk_signal_connect_after( GTK_OBJECT(m_widget), "style_set",
GTK_SIGNAL_FUNC(gtk_button_style_set_callback), (gpointer*) this );
m_parent->DoAddChild( this );
PostCreation(size);
return true;
}
void wxButton::SetDefault()
{
@ -208,10 +186,10 @@ void wxButton::SetDefault()
wxCHECK_RET( parent, _T("button without parent?") );
parent->SetDefaultItem(this);
GTK_WIDGET_SET_FLAGS( m_widget, GTK_CAN_DEFAULT );
gtk_widget_grab_default( m_widget );
// resize for default border
gtk_button_style_set_callback( m_widget, NULL, this );
}
@ -246,7 +224,7 @@ wxSize wxButtonBase::GetDefaultSize()
size.x = wxMax(minwidth, req.width);
size.y = wxMax(minheight, req.height);
gtk_widget_destroy(wnd);
}
return size;
@ -266,6 +244,8 @@ void wxButton::SetLabel( const wxString &lbl )
wxControl::SetLabel(label);
const wxString labelGTK = GTKConvertMnemonics(label);
#ifdef __WXGTK20__
if (wxIsStockID(m_windowId) && wxIsStockLabel(m_windowId, label))
{
@ -278,15 +258,13 @@ void wxButton::SetLabel( const wxString &lbl )
}
}
wxString label2 = PrepareLabelMnemonics(label);
gtk_button_set_label(GTK_BUTTON(m_widget), wxGTK_CONV(label2));
gtk_button_set_label(GTK_BUTTON(m_widget), wxGTK_CONV(labelGTK));
gtk_button_set_use_stock(GTK_BUTTON(m_widget), FALSE);
ApplyWidgetStyle( false );
#else
gtk_label_set(GTK_LABEL(BUTTON_CHILD(m_widget)), wxGTK_CONV(GetLabel()));
#endif
#else // GTK+ 1
gtk_label_set(GTK_LABEL(BUTTON_CHILD(m_widget)), wxGTK_CONV(labelGTK));
#endif // GTK+ 2/1
}
bool wxButton::Enable( bool enable )
@ -338,7 +316,7 @@ wxSize wxButton::DoGetBestSize() const
#ifndef __WXGTK20__
ret.x += 10; // add a few pixels for sloppy (but common) themes
#endif
if (!HasFlag(wxBU_EXACTFIT))
{
wxSize defaultSize = GetDefaultSize();

View File

@ -229,14 +229,7 @@ void wxCheckBox::SetLabel( const wxString& label )
{
wxCHECK_RET( m_widgetLabel != NULL, wxT("invalid checkbox") );
wxControl::SetLabel( label );
#ifdef __WXGTK20__
wxString label2 = PrepareLabelMnemonics( label );
gtk_label_set_text_with_mnemonic( GTK_LABEL(m_widgetLabel), wxGTK_CONV( label2 ) );
#else
gtk_label_set( GTK_LABEL(m_widgetLabel), wxGTK_CONV( GetLabel() ) );
#endif
GTKSetLabelForLabel(GTK_LABEL(m_widgetLabel), label);
}
bool wxCheckBox::Enable( bool enable )

View File

@ -17,8 +17,7 @@
#include "wx/control.h"
#include "wx/fontutil.h"
#include "wx/settings.h"
#include <gtk/gtk.h>
#include "wx/gtk/private.h"
//-----------------------------------------------------------------------------
// wxControl
@ -40,7 +39,7 @@ bool wxControl::Create( wxWindow *parent,
const wxString &name )
{
bool ret = wxWindow::Create(parent, id, pos, size, style, name);
#if wxUSE_VALIDATORS
SetValidator(validator);
#endif
@ -48,29 +47,6 @@ bool wxControl::Create( wxWindow *parent,
return ret;
}
void wxControl::SetLabel( const wxString &label )
{
m_label.Empty();
for ( const wxChar *pc = label; *pc != wxT('\0'); pc++ )
{
if ( *pc == wxT('&') )
{
pc++; // skip it
#if 0 // it would be unused anyhow for now - kbd interface not done yet
if ( *pc != wxT('&') ) m_chAccel = *pc;
#endif
}
m_label << *pc;
}
InvalidateBestSize();
}
wxString wxControl::GetLabel() const
{
return m_label;
}
wxSize wxControl::DoGetBestSize() const
{
// Do not return any arbitrary default value...
@ -98,56 +74,143 @@ void wxControl::PostCreation(const wxSize& size)
// size. This call ensure that a style is available at the time
// GetBestSize is called.
gtk_widget_ensure_style(m_widget);
ApplyWidgetStyle();
SetInitialBestSize(size);
}
// ----------------------------------------------------------------------------
// wxControl dealing with labels
// ----------------------------------------------------------------------------
void wxControl::SetLabel( const wxString &label )
{
// keep the original string internally to be able to return it later (for
// consistency with the other ports)
m_label = label;
InvalidateBestSize();
}
wxString wxControl::GetLabel() const
{
return m_label;
}
void wxControl::GTKSetLabelForLabel(GtkLabel *w, const wxString& label)
{
// don't call the virtual function which might call this one back again
wxControl::SetLabel(label);
const wxString labelGTK = GTKConvertMnemonics(label);
#ifdef __WXGTK20__
wxString wxControl::PrepareLabelMnemonics( const wxString &label ) const
gtk_label_set_text_with_mnemonic(w, wxGTK_CONV(labelGTK));
#else
gtk_label_set(w, wxGTK_CONV(labelGTK));
#endif
}
void wxControl::GTKSetLabelForFrame(GtkFrame *w, const wxString& label)
{
//Format mnemonics properly for GTK2. This can be called from GTK1.x, but
//it's not very useful because mnemonics don't exist prior to GTK2.
wxString label2;
for (size_t i = 0; i < label.Len(); i++)
wxControl::SetLabel(label);
// frames don't support mnemonics even under GTK+ 2
const wxString labelGTK = GTKRemoveMnemonics(label);
gtk_frame_set_label(w, labelGTK.empty() ? (char *)NULL
: wxGTK_CONV(labelGTK));
}
// 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,
MNEMONICS_CONVERT
};
static wxString GTKProcessMnemonics(const wxString& label, MnemonicsFlag flag)
{
const size_t len = label.length();
wxString labelGTK;
labelGTK.reserve(len);
for ( size_t i = 0; i < len; i++ )
{
if (label.GetChar(i) == wxT('&'))
wxChar ch = label[i];
switch ( ch )
{
//Mnemonic escape sequence "&&" is a literal "&" in the output.
if (label.GetChar(i + 1) == wxT('&'))
{
label2 << wxT('&');
i++;
}
//Handle special case of "&_" (i.e. "_" is the mnemonic).
//FIXME - Is it possible to use "_" as a GTK mnemonic? Just use a
//dash for now.
else if (label.GetChar(i + 1) == wxT('_'))
{
label2 << wxT("_-");
i++;
}
//Replace WX mnemonic indicator "&" with GTK indicator "_".
else
{
label2 << wxT('_');
}
}
else if (label.GetChar(i) == wxT('_'))
{
//Escape any underlines in the string so GTK doesn't use them.
label2 << wxT("__");
}
else
{
label2 << label.GetChar(i);
case wxT('&'):
if ( i == len - 1 )
{
// "&" at the end of string is an error
wxLogDebug(wxT("Invalid label \"%s\"."), label.c_str());
break;
}
ch = label[++i]; // skip '&' itself
switch ( ch )
{
case wxT('&'):
// special case: "&&" is not a mnemonic at all but just
// an escaped "&"
labelGTK += wxT('&');
break;
case wxT('_'):
if ( flag == MNEMONICS_CONVERT )
{
// '_' can't be a GTK mnemonic apparently so
// replace it with something similar
labelGTK += wxT("_-");
break;
}
//else: fall through
default:
if ( flag == MNEMONICS_CONVERT )
labelGTK += wxT('_');
labelGTK += ch;
}
break;
case wxT('_'):
if ( flag == MNEMONICS_CONVERT )
{
// escape any existing underlines in the string so that
// they don't become mnemonics accidentally
labelGTK += wxT("__");
break;
}
//else: fall through
default:
labelGTK += ch;
}
}
return label2;
}
#endif
return labelGTK;
}
/* static */
wxString wxControl::GTKRemoveMnemonics(const wxString& label)
{
return GTKProcessMnemonics(label, MNEMONICS_REMOVE);
}
/* static */
wxString wxControl::GTKConvertMnemonics(const wxString& label)
{
return GTKProcessMnemonics(label, MNEMONICS_CONVERT);
}
// ----------------------------------------------------------------------------
// wxControl styles (a.k.a. attributes)
// ----------------------------------------------------------------------------
wxVisualAttributes wxControl::GetDefaultAttributes() const
{
@ -178,7 +241,7 @@ wxControl::GetDefaultAttributesFromGTKWidget(GtkWidget* widget,
if (state == -1)
state = GTK_STATE_NORMAL;
// get the style's colours
attr.colFg = wxColour(style->fg[state].red >> SHIFT,
style->fg[state].green >> SHIFT,
@ -195,19 +258,19 @@ wxControl::GetDefaultAttributesFromGTKWidget(GtkWidget* widget,
// get the style's font
#ifdef __WXGTK20__
if ( !style->font_desc )
style = gtk_widget_get_default_style();
style = gtk_widget_get_default_style();
if ( style && style->font_desc )
{
wxNativeFontInfo info;
{
wxNativeFontInfo info;
info.description = pango_font_description_copy(style->font_desc);
attr.font = wxFont(info);
}
else
{
attr.font = wxFont(info);
}
else
{
GtkSettings *settings = gtk_settings_get_default();
gchar *font_name = NULL;
g_object_get ( settings,
"gtk-font-name",
"gtk-font-name",
&font_name,
NULL);
if (!font_name)
@ -215,12 +278,12 @@ wxControl::GetDefaultAttributesFromGTKWidget(GtkWidget* widget,
else
attr.font = wxFont(wxString::FromAscii(font_name));
g_free (font_name);
}
}
#else
// TODO: isn't there a way to get a standard gtk 1.2 font?
attr.font = wxFont( 12, wxSWISS, wxNORMAL, wxNORMAL );
#endif
return attr;
}

View File

@ -198,7 +198,8 @@ bool wxRadioBox::Create( wxWindow *parent, wxWindowID id, const wxString& title,
return false;
}
m_widget = gtk_frame_new( wxGTK_CONV( title ) );
m_widget = gtk_frame_new(NULL);
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
@ -273,8 +274,6 @@ bool wxRadioBox::Create( wxWindow *parent, wxWindowID id, const wxString& title,
m_parent->DoAddChild( this );
SetLabel( title );
PostCreation(size);
return true;
@ -399,9 +398,7 @@ void wxRadioBox::SetLabel( const wxString& label )
{
wxCHECK_RET( m_widget != NULL, wxT("invalid radiobox") );
wxControl::SetLabel( label );
gtk_frame_set_label( GTK_FRAME(m_widget), wxGTK_CONV( wxControl::GetLabel() ) );
GTKSetLabelForFrame(GTK_FRAME(m_widget), label);
}
void wxRadioBox::SetString( int item, const wxString& label )

View File

@ -36,19 +36,19 @@ extern wxWindowGTK *g_delayedFocus;
//-----------------------------------------------------------------------------
extern "C" {
static
static
void gtk_radiobutton_clicked_callback( GtkToggleButton *button, wxRadioButton *rb )
{
if (g_isIdle) wxapp_install_idle_handler();
if (!rb->m_hasVMT) return;
if (g_blockEventsOnDrag) return;
if (!button->active) return;
if (rb->m_blockEvent) return;
wxCommandEvent event( wxEVT_COMMAND_RADIOBUTTON_SELECTED, rb->GetId());
event.SetInt( rb->GetValue() );
event.SetEventObject( rb );
@ -61,7 +61,7 @@ void gtk_radiobutton_clicked_callback( GtkToggleButton *button, wxRadioButton *r
//-----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxRadioButton,wxControl)
bool wxRadioButton::Create( wxWindow *parent,
wxWindowID id,
const wxString& label,
@ -73,7 +73,7 @@ bool wxRadioButton::Create( wxWindow *parent,
{
m_acceptsFocus = TRUE;
m_needParent = TRUE;
m_blockEvent = FALSE;
if (!PreCreation( parent, pos, size ) ||
@ -108,14 +108,14 @@ bool wxRadioButton::Create( wxWindow *parent,
}
m_widget = gtk_radio_button_new_with_label( radioButtonGroup, wxGTK_CONV( label ) );
SetLabel(label);
gtk_signal_connect( GTK_OBJECT(m_widget), "clicked",
gtk_signal_connect( GTK_OBJECT(m_widget), "clicked",
GTK_SIGNAL_FUNC(gtk_radiobutton_clicked_callback), (gpointer*)this );
m_parent->DoAddChild( this );
PostCreation(size);
return TRUE;
@ -124,15 +124,8 @@ bool wxRadioButton::Create( wxWindow *parent,
void wxRadioButton::SetLabel( const wxString& label )
{
wxCHECK_RET( m_widget != NULL, wxT("invalid radiobutton") );
wxControl::SetLabel( label );
GtkLabel *g_label = GTK_LABEL( BUTTON_CHILD(m_widget) );
#ifdef __WXGTK20__
wxString label2 = PrepareLabelMnemonics( label );
gtk_label_set_text_with_mnemonic( g_label, wxGTK_CONV( label2 ) );
#else
gtk_label_set( g_label, wxGTK_CONV( GetLabel() ) );
#endif
GTKSetLabelForLabel(GTK_LABEL(BUTTON_CHILD(m_widget)), label);
}
void wxRadioButton::SetValue( bool val )
@ -161,7 +154,7 @@ void wxRadioButton::SetValue( bool val )
bool wxRadioButton::GetValue() const
{
wxCHECK_MSG( m_widget != NULL, FALSE, wxT("invalid radiobutton") );
return GTK_TOGGLE_BUTTON(m_widget)->active;
}
@ -169,7 +162,7 @@ bool wxRadioButton::Enable( bool enable )
{
if ( !wxControl::Enable( enable ) )
return FALSE;
gtk_widget_set_sensitive( BUTTON_CHILD(m_widget), enable );
return TRUE;
@ -198,7 +191,7 @@ void wxRadioButton::OnInternalIdle()
as setting the cursor in a parent window also effects the
windows above so that checking for the current cursor is
not possible. */
gdk_window_set_cursor( win, cursor.GetCursor() );
}

View File

@ -56,9 +56,8 @@ bool wxStaticBox::Create( wxWindow *parent,
return FALSE;
}
wxControl::SetLabel(label);
m_widget = gtk_frame_new(m_label.empty() ? (char *)NULL : (const char*) wxGTK_CONV( m_label ) );
m_widget = gtk_frame_new(NULL);
SetLabel(label);
m_parent->DoAddChild( this );
@ -79,12 +78,11 @@ bool wxStaticBox::Create( wxWindow *parent,
return TRUE;
}
void wxStaticBox::SetLabel( const wxString &label )
void wxStaticBox::SetLabel( const wxString& label )
{
wxControl::SetLabel( label );
wxCHECK_RET( m_widget != NULL, wxT("invalid staticbox") );
gtk_frame_set_label( GTK_FRAME( m_widget ),
m_label.empty() ? (char *)NULL : (const char*) wxGTK_CONV( m_label ) );
GTKSetLabelForFrame(GTK_FRAME(m_widget), label);
}
void wxStaticBox::DoApplyWidgetStyle(GtkRcStyle *style)

View File

@ -67,12 +67,12 @@ gtk_button_style_set_callback( GtkWidget *m_widget, GtkStyle *WXUNUSED(style), w
{
if (g_isIdle)
wxapp_install_idle_handler();
int left_border = 0;
int right_border = 0;
int top_border = 0;
int bottom_border = 0;
/* the default button has a border around it */
if (GTK_WIDGET_CAN_DEFAULT(m_widget))
{
@ -97,7 +97,7 @@ gtk_button_style_set_callback( GtkWidget *m_widget, GtkStyle *WXUNUSED(style), w
win->m_y-left_border,
win->m_width+left_border+right_border,
win->m_height+top_border+bottom_border );
}
}
return FALSE;
}
@ -130,28 +130,6 @@ bool wxButton::Create( wxWindow *parent, wxWindowID id, const wxString &label,
return FALSE;
}
/*
wxString label2( label );
for (size_t i = 0; i < label2.Len(); i++)
{
if (label2.GetChar(i) == wxT('&'))
label2.SetChar(i,wxT('_'));
}
GtkWidget *accel_label = gtk_accel_label_new( label2.mb_str() );
gtk_widget_show( accel_label );
m_widget = gtk_button_new();
gtk_container_add( GTK_CONTAINER(m_widget), accel_label );
gtk_accel_label_set_accel_widget( GTK_ACCEL_LABEL(accel_label), m_widget );
guint accel_key = gtk_label_parse_uline (GTK_LABEL(accel_label), label2.mb_str() );
gtk_accel_label_refetch( GTK_ACCEL_LABEL(accel_label) );
wxControl::SetLabel( label );
*/
#ifdef __WXGTK20__
m_widget = gtk_button_new_with_mnemonic("");
#else
@ -193,14 +171,14 @@ bool wxButton::Create( wxWindow *parent, wxWindowID id, const wxString &label,
gtk_signal_connect_after( GTK_OBJECT(m_widget), "style_set",
GTK_SIGNAL_FUNC(gtk_button_style_set_callback), (gpointer*) this );
m_parent->DoAddChild( this );
PostCreation(size);
return true;
}
void wxButton::SetDefault()
{
@ -208,10 +186,10 @@ void wxButton::SetDefault()
wxCHECK_RET( parent, _T("button without parent?") );
parent->SetDefaultItem(this);
GTK_WIDGET_SET_FLAGS( m_widget, GTK_CAN_DEFAULT );
gtk_widget_grab_default( m_widget );
// resize for default border
gtk_button_style_set_callback( m_widget, NULL, this );
}
@ -246,7 +224,7 @@ wxSize wxButtonBase::GetDefaultSize()
size.x = wxMax(minwidth, req.width);
size.y = wxMax(minheight, req.height);
gtk_widget_destroy(wnd);
}
return size;
@ -266,6 +244,8 @@ void wxButton::SetLabel( const wxString &lbl )
wxControl::SetLabel(label);
const wxString labelGTK = GTKConvertMnemonics(label);
#ifdef __WXGTK20__
if (wxIsStockID(m_windowId) && wxIsStockLabel(m_windowId, label))
{
@ -278,15 +258,13 @@ void wxButton::SetLabel( const wxString &lbl )
}
}
wxString label2 = PrepareLabelMnemonics(label);
gtk_button_set_label(GTK_BUTTON(m_widget), wxGTK_CONV(label2));
gtk_button_set_label(GTK_BUTTON(m_widget), wxGTK_CONV(labelGTK));
gtk_button_set_use_stock(GTK_BUTTON(m_widget), FALSE);
ApplyWidgetStyle( false );
#else
gtk_label_set(GTK_LABEL(BUTTON_CHILD(m_widget)), wxGTK_CONV(GetLabel()));
#endif
#else // GTK+ 1
gtk_label_set(GTK_LABEL(BUTTON_CHILD(m_widget)), wxGTK_CONV(labelGTK));
#endif // GTK+ 2/1
}
bool wxButton::Enable( bool enable )
@ -338,7 +316,7 @@ wxSize wxButton::DoGetBestSize() const
#ifndef __WXGTK20__
ret.x += 10; // add a few pixels for sloppy (but common) themes
#endif
if (!HasFlag(wxBU_EXACTFIT))
{
wxSize defaultSize = GetDefaultSize();

View File

@ -229,14 +229,7 @@ void wxCheckBox::SetLabel( const wxString& label )
{
wxCHECK_RET( m_widgetLabel != NULL, wxT("invalid checkbox") );
wxControl::SetLabel( label );
#ifdef __WXGTK20__
wxString label2 = PrepareLabelMnemonics( label );
gtk_label_set_text_with_mnemonic( GTK_LABEL(m_widgetLabel), wxGTK_CONV( label2 ) );
#else
gtk_label_set( GTK_LABEL(m_widgetLabel), wxGTK_CONV( GetLabel() ) );
#endif
GTKSetLabelForLabel(GTK_LABEL(m_widgetLabel), label);
}
bool wxCheckBox::Enable( bool enable )

View File

@ -17,8 +17,7 @@
#include "wx/control.h"
#include "wx/fontutil.h"
#include "wx/settings.h"
#include <gtk/gtk.h>
#include "wx/gtk/private.h"
//-----------------------------------------------------------------------------
// wxControl
@ -40,7 +39,7 @@ bool wxControl::Create( wxWindow *parent,
const wxString &name )
{
bool ret = wxWindow::Create(parent, id, pos, size, style, name);
#if wxUSE_VALIDATORS
SetValidator(validator);
#endif
@ -48,29 +47,6 @@ bool wxControl::Create( wxWindow *parent,
return ret;
}
void wxControl::SetLabel( const wxString &label )
{
m_label.Empty();
for ( const wxChar *pc = label; *pc != wxT('\0'); pc++ )
{
if ( *pc == wxT('&') )
{
pc++; // skip it
#if 0 // it would be unused anyhow for now - kbd interface not done yet
if ( *pc != wxT('&') ) m_chAccel = *pc;
#endif
}
m_label << *pc;
}
InvalidateBestSize();
}
wxString wxControl::GetLabel() const
{
return m_label;
}
wxSize wxControl::DoGetBestSize() const
{
// Do not return any arbitrary default value...
@ -98,56 +74,143 @@ void wxControl::PostCreation(const wxSize& size)
// size. This call ensure that a style is available at the time
// GetBestSize is called.
gtk_widget_ensure_style(m_widget);
ApplyWidgetStyle();
SetInitialBestSize(size);
}
// ----------------------------------------------------------------------------
// wxControl dealing with labels
// ----------------------------------------------------------------------------
void wxControl::SetLabel( const wxString &label )
{
// keep the original string internally to be able to return it later (for
// consistency with the other ports)
m_label = label;
InvalidateBestSize();
}
wxString wxControl::GetLabel() const
{
return m_label;
}
void wxControl::GTKSetLabelForLabel(GtkLabel *w, const wxString& label)
{
// don't call the virtual function which might call this one back again
wxControl::SetLabel(label);
const wxString labelGTK = GTKConvertMnemonics(label);
#ifdef __WXGTK20__
wxString wxControl::PrepareLabelMnemonics( const wxString &label ) const
gtk_label_set_text_with_mnemonic(w, wxGTK_CONV(labelGTK));
#else
gtk_label_set(w, wxGTK_CONV(labelGTK));
#endif
}
void wxControl::GTKSetLabelForFrame(GtkFrame *w, const wxString& label)
{
//Format mnemonics properly for GTK2. This can be called from GTK1.x, but
//it's not very useful because mnemonics don't exist prior to GTK2.
wxString label2;
for (size_t i = 0; i < label.Len(); i++)
wxControl::SetLabel(label);
// frames don't support mnemonics even under GTK+ 2
const wxString labelGTK = GTKRemoveMnemonics(label);
gtk_frame_set_label(w, labelGTK.empty() ? (char *)NULL
: wxGTK_CONV(labelGTK));
}
// 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,
MNEMONICS_CONVERT
};
static wxString GTKProcessMnemonics(const wxString& label, MnemonicsFlag flag)
{
const size_t len = label.length();
wxString labelGTK;
labelGTK.reserve(len);
for ( size_t i = 0; i < len; i++ )
{
if (label.GetChar(i) == wxT('&'))
wxChar ch = label[i];
switch ( ch )
{
//Mnemonic escape sequence "&&" is a literal "&" in the output.
if (label.GetChar(i + 1) == wxT('&'))
{
label2 << wxT('&');
i++;
}
//Handle special case of "&_" (i.e. "_" is the mnemonic).
//FIXME - Is it possible to use "_" as a GTK mnemonic? Just use a
//dash for now.
else if (label.GetChar(i + 1) == wxT('_'))
{
label2 << wxT("_-");
i++;
}
//Replace WX mnemonic indicator "&" with GTK indicator "_".
else
{
label2 << wxT('_');
}
}
else if (label.GetChar(i) == wxT('_'))
{
//Escape any underlines in the string so GTK doesn't use them.
label2 << wxT("__");
}
else
{
label2 << label.GetChar(i);
case wxT('&'):
if ( i == len - 1 )
{
// "&" at the end of string is an error
wxLogDebug(wxT("Invalid label \"%s\"."), label.c_str());
break;
}
ch = label[++i]; // skip '&' itself
switch ( ch )
{
case wxT('&'):
// special case: "&&" is not a mnemonic at all but just
// an escaped "&"
labelGTK += wxT('&');
break;
case wxT('_'):
if ( flag == MNEMONICS_CONVERT )
{
// '_' can't be a GTK mnemonic apparently so
// replace it with something similar
labelGTK += wxT("_-");
break;
}
//else: fall through
default:
if ( flag == MNEMONICS_CONVERT )
labelGTK += wxT('_');
labelGTK += ch;
}
break;
case wxT('_'):
if ( flag == MNEMONICS_CONVERT )
{
// escape any existing underlines in the string so that
// they don't become mnemonics accidentally
labelGTK += wxT("__");
break;
}
//else: fall through
default:
labelGTK += ch;
}
}
return label2;
}
#endif
return labelGTK;
}
/* static */
wxString wxControl::GTKRemoveMnemonics(const wxString& label)
{
return GTKProcessMnemonics(label, MNEMONICS_REMOVE);
}
/* static */
wxString wxControl::GTKConvertMnemonics(const wxString& label)
{
return GTKProcessMnemonics(label, MNEMONICS_CONVERT);
}
// ----------------------------------------------------------------------------
// wxControl styles (a.k.a. attributes)
// ----------------------------------------------------------------------------
wxVisualAttributes wxControl::GetDefaultAttributes() const
{
@ -178,7 +241,7 @@ wxControl::GetDefaultAttributesFromGTKWidget(GtkWidget* widget,
if (state == -1)
state = GTK_STATE_NORMAL;
// get the style's colours
attr.colFg = wxColour(style->fg[state].red >> SHIFT,
style->fg[state].green >> SHIFT,
@ -195,19 +258,19 @@ wxControl::GetDefaultAttributesFromGTKWidget(GtkWidget* widget,
// get the style's font
#ifdef __WXGTK20__
if ( !style->font_desc )
style = gtk_widget_get_default_style();
style = gtk_widget_get_default_style();
if ( style && style->font_desc )
{
wxNativeFontInfo info;
{
wxNativeFontInfo info;
info.description = pango_font_description_copy(style->font_desc);
attr.font = wxFont(info);
}
else
{
attr.font = wxFont(info);
}
else
{
GtkSettings *settings = gtk_settings_get_default();
gchar *font_name = NULL;
g_object_get ( settings,
"gtk-font-name",
"gtk-font-name",
&font_name,
NULL);
if (!font_name)
@ -215,12 +278,12 @@ wxControl::GetDefaultAttributesFromGTKWidget(GtkWidget* widget,
else
attr.font = wxFont(wxString::FromAscii(font_name));
g_free (font_name);
}
}
#else
// TODO: isn't there a way to get a standard gtk 1.2 font?
attr.font = wxFont( 12, wxSWISS, wxNORMAL, wxNORMAL );
#endif
return attr;
}

View File

@ -198,7 +198,8 @@ bool wxRadioBox::Create( wxWindow *parent, wxWindowID id, const wxString& title,
return false;
}
m_widget = gtk_frame_new( wxGTK_CONV( title ) );
m_widget = gtk_frame_new(NULL);
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
@ -273,8 +274,6 @@ bool wxRadioBox::Create( wxWindow *parent, wxWindowID id, const wxString& title,
m_parent->DoAddChild( this );
SetLabel( title );
PostCreation(size);
return true;
@ -399,9 +398,7 @@ void wxRadioBox::SetLabel( const wxString& label )
{
wxCHECK_RET( m_widget != NULL, wxT("invalid radiobox") );
wxControl::SetLabel( label );
gtk_frame_set_label( GTK_FRAME(m_widget), wxGTK_CONV( wxControl::GetLabel() ) );
GTKSetLabelForFrame(GTK_FRAME(m_widget), label);
}
void wxRadioBox::SetString( int item, const wxString& label )

View File

@ -36,19 +36,19 @@ extern wxWindowGTK *g_delayedFocus;
//-----------------------------------------------------------------------------
extern "C" {
static
static
void gtk_radiobutton_clicked_callback( GtkToggleButton *button, wxRadioButton *rb )
{
if (g_isIdle) wxapp_install_idle_handler();
if (!rb->m_hasVMT) return;
if (g_blockEventsOnDrag) return;
if (!button->active) return;
if (rb->m_blockEvent) return;
wxCommandEvent event( wxEVT_COMMAND_RADIOBUTTON_SELECTED, rb->GetId());
event.SetInt( rb->GetValue() );
event.SetEventObject( rb );
@ -61,7 +61,7 @@ void gtk_radiobutton_clicked_callback( GtkToggleButton *button, wxRadioButton *r
//-----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxRadioButton,wxControl)
bool wxRadioButton::Create( wxWindow *parent,
wxWindowID id,
const wxString& label,
@ -73,7 +73,7 @@ bool wxRadioButton::Create( wxWindow *parent,
{
m_acceptsFocus = TRUE;
m_needParent = TRUE;
m_blockEvent = FALSE;
if (!PreCreation( parent, pos, size ) ||
@ -108,14 +108,14 @@ bool wxRadioButton::Create( wxWindow *parent,
}
m_widget = gtk_radio_button_new_with_label( radioButtonGroup, wxGTK_CONV( label ) );
SetLabel(label);
gtk_signal_connect( GTK_OBJECT(m_widget), "clicked",
gtk_signal_connect( GTK_OBJECT(m_widget), "clicked",
GTK_SIGNAL_FUNC(gtk_radiobutton_clicked_callback), (gpointer*)this );
m_parent->DoAddChild( this );
PostCreation(size);
return TRUE;
@ -124,15 +124,8 @@ bool wxRadioButton::Create( wxWindow *parent,
void wxRadioButton::SetLabel( const wxString& label )
{
wxCHECK_RET( m_widget != NULL, wxT("invalid radiobutton") );
wxControl::SetLabel( label );
GtkLabel *g_label = GTK_LABEL( BUTTON_CHILD(m_widget) );
#ifdef __WXGTK20__
wxString label2 = PrepareLabelMnemonics( label );
gtk_label_set_text_with_mnemonic( g_label, wxGTK_CONV( label2 ) );
#else
gtk_label_set( g_label, wxGTK_CONV( GetLabel() ) );
#endif
GTKSetLabelForLabel(GTK_LABEL(BUTTON_CHILD(m_widget)), label);
}
void wxRadioButton::SetValue( bool val )
@ -161,7 +154,7 @@ void wxRadioButton::SetValue( bool val )
bool wxRadioButton::GetValue() const
{
wxCHECK_MSG( m_widget != NULL, FALSE, wxT("invalid radiobutton") );
return GTK_TOGGLE_BUTTON(m_widget)->active;
}
@ -169,7 +162,7 @@ bool wxRadioButton::Enable( bool enable )
{
if ( !wxControl::Enable( enable ) )
return FALSE;
gtk_widget_set_sensitive( BUTTON_CHILD(m_widget), enable );
return TRUE;
@ -198,7 +191,7 @@ void wxRadioButton::OnInternalIdle()
as setting the cursor in a parent window also effects the
windows above so that checking for the current cursor is
not possible. */
gdk_window_set_cursor( win, cursor.GetCursor() );
}

View File

@ -56,9 +56,8 @@ bool wxStaticBox::Create( wxWindow *parent,
return FALSE;
}
wxControl::SetLabel(label);
m_widget = gtk_frame_new(m_label.empty() ? (char *)NULL : (const char*) wxGTK_CONV( m_label ) );
m_widget = gtk_frame_new(NULL);
SetLabel(label);
m_parent->DoAddChild( this );
@ -79,12 +78,11 @@ bool wxStaticBox::Create( wxWindow *parent,
return TRUE;
}
void wxStaticBox::SetLabel( const wxString &label )
void wxStaticBox::SetLabel( const wxString& label )
{
wxControl::SetLabel( label );
wxCHECK_RET( m_widget != NULL, wxT("invalid staticbox") );
gtk_frame_set_label( GTK_FRAME( m_widget ),
m_label.empty() ? (char *)NULL : (const char*) wxGTK_CONV( m_label ) );
GTKSetLabelForFrame(GTK_FRAME(m_widget), label);
}
void wxStaticBox::DoApplyWidgetStyle(GtkRcStyle *style)