1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/gtk/control.cpp 
   3 // Purpose:     wxControl implementation for wxGTK 
   4 // Author:      Robert Roebling 
   6 // Copyright:   (c) 1998 Robert Roebling, Julian Smart and Vadim Zeitlin 
   7 // Licence:     wxWindows licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  10 // For compilers that support precompilation, includes "wx.h". 
  11 #include "wx/wxprec.h" 
  15 #include "wx/control.h" 
  19     #include "wx/settings.h" 
  22 #include "wx/fontutil.h" 
  23 #include "wx/gtk/private.h" 
  25 #include "wx/sysopt.h" 
  27 #include "wx/gtk/private/mnemonics.h" 
  29 // ============================================================================ 
  30 // wxControl implementation 
  31 // ============================================================================ 
  33 // ---------------------------------------------------------------------------- 
  35 // ---------------------------------------------------------------------------- 
  37 IMPLEMENT_DYNAMIC_CLASS(wxControl
, wxWindow
) 
  39 wxControl::wxControl() 
  43 bool wxControl::Create( wxWindow 
*parent
, 
  48                       const wxValidator
& validator
, 
  49                       const wxString 
&name 
) 
  51     bool ret 
= wxWindow::Create(parent
, id
, pos
, size
, style
, name
); 
  54     SetValidator(validator
); 
  60 wxSize 
wxControl::DoGetBestSize() const 
  62     // Do not return any arbitrary default value... 
  63     wxASSERT_MSG( m_widget
, wxT("DoGetBestSize called before creation") ); 
  68         // this is not a native control, size_request is likely to be (0,0) 
  69         best 
= wxControlBase::DoGetBestSize(); 
  74         GTK_WIDGET_GET_CLASS(m_widget
)->size_request(m_widget
, &req
); 
  75         best
.Set(req
.width
, req
.height
); 
  81 void wxControl::PostCreation(const wxSize
& size
) 
  83     wxWindow::PostCreation(); 
  85     // NB: GetBestSize needs to know the style, otherwise it will assume 
  86     //     default font and if the user uses a different font, determined 
  87     //     best size will be different (typically, smaller) than the desired 
  88     //     size. This call ensure that a style is available at the time 
  89     //     GetBestSize is called. 
  90     gtk_widget_ensure_style(m_widget
); 
  92     GTKApplyWidgetStyle(); 
  96 // ---------------------------------------------------------------------------- 
  97 // Work around a GTK+ bug whereby button is insensitive after being 
  99 // ---------------------------------------------------------------------------- 
 101 // Fix sensitivity due to bug in GTK+ < 2.14 
 102 void wxControl::GTKFixSensitivity(bool onlyIfUnderMouse
) 
 104     if (gtk_check_version(2,14,0) 
 105 #if wxUSE_SYSTEM_OPTIONS 
 106         && (wxSystemOptions::GetOptionInt(wxT("gtk.control.disable-sensitivity-fix")) != 1) 
 110         wxPoint pt 
= wxGetMousePosition(); 
 111         wxRect 
rect(ClientToScreen(wxPoint(0, 0)), GetSize()); 
 112         if (!onlyIfUnderMouse 
|| rect
.Contains(pt
)) 
 120 // ---------------------------------------------------------------------------- 
 121 // wxControl dealing with labels 
 122 // ---------------------------------------------------------------------------- 
 124 void wxControl::GTKSetLabelForLabel(GtkLabel 
*w
, const wxString
& label
) 
 126     // save the original label 
 127     wxControlBase::SetLabel(label
); 
 129     const wxString labelGTK 
= GTKConvertMnemonics(label
); 
 130     gtk_label_set_text_with_mnemonic(w
, wxGTK_CONV(labelGTK
)); 
 133 void wxControl::GTKSetLabelWithMarkupForLabel(GtkLabel 
*w
, const wxString
& label
) 
 135     const wxString labelGTK 
= GTKConvertMnemonicsWithMarkup(label
); 
 136     gtk_label_set_markup_with_mnemonic(w
, wxGTK_CONV(labelGTK
)); 
 140 // ---------------------------------------------------------------------------- 
 143 // GtkFrames do in fact support mnemonics in GTK2+ but not through 
 144 // gtk_frame_set_label, rather you need to use a custom label widget 
 145 // instead (idea gleaned from the native gtk font dialog code in GTK) 
 146 // ---------------------------------------------------------------------------- 
 148 GtkWidget
* wxControl::GTKCreateFrame(const wxString
& label
) 
 150     const wxString labelGTK 
= GTKConvertMnemonics(label
); 
 151     GtkWidget
* labelwidget 
= gtk_label_new_with_mnemonic(wxGTK_CONV(labelGTK
)); 
 152     gtk_widget_show(labelwidget
); // without this it won't show... 
 154     GtkWidget
* framewidget 
= gtk_frame_new(NULL
); 
 155     gtk_frame_set_label_widget(GTK_FRAME(framewidget
), labelwidget
); 
 157     return framewidget
; // note that the label is already set so you'll 
 158                         // only need to call wxControl::SetLabel afterwards 
 161 void wxControl::GTKSetLabelForFrame(GtkFrame 
*w
, const wxString
& label
) 
 163     GtkLabel
* labelwidget 
= GTK_LABEL(gtk_frame_get_label_widget(w
)); 
 164     GTKSetLabelForLabel(labelwidget
, label
); 
 167 void wxControl::GTKFrameApplyWidgetStyle(GtkFrame
* w
, GtkRcStyle
* style
) 
 169     gtk_widget_modify_style(GTK_WIDGET(w
), style
); 
 170     gtk_widget_modify_style(gtk_frame_get_label_widget (w
), style
); 
 173 void wxControl::GTKFrameSetMnemonicWidget(GtkFrame
* w
, GtkWidget
* widget
) 
 175     GtkLabel
* labelwidget 
= GTK_LABEL(gtk_frame_get_label_widget(w
)); 
 177     gtk_label_set_mnemonic_widget(labelwidget
, widget
); 
 180 // ---------------------------------------------------------------------------- 
 181 // worker function implementing GTK*Mnemonics() functions 
 182 // ---------------------------------------------------------------------------- 
 185 wxString 
wxControl::GTKRemoveMnemonics(const wxString
& label
) 
 187     return wxGTKRemoveMnemonics(label
); 
 191 wxString 
wxControl::GTKConvertMnemonics(const wxString
& label
) 
 193     return wxConvertMnemonicsToGTK(label
); 
 197 wxString 
wxControl::GTKConvertMnemonicsWithMarkup(const wxString
& label
) 
 199     return wxConvertMnemonicsToGTKMarkup(label
); 
 202 // ---------------------------------------------------------------------------- 
 203 // wxControl styles (a.k.a. attributes) 
 204 // ---------------------------------------------------------------------------- 
 206 wxVisualAttributes 
wxControl::GetDefaultAttributes() const 
 208     return GetDefaultAttributesFromGTKWidget(m_widget
, 
 214 wxControl::GetDefaultAttributesFromGTKWidget(GtkWidget
* widget
, 
 219     wxVisualAttributes attr
; 
 221     style 
= gtk_rc_get_style(widget
); 
 223         style 
= gtk_widget_get_default_style(); 
 227         return wxWindow::GetClassDefaultAttributes(wxWINDOW_VARIANT_NORMAL
); 
 231         state 
= GTK_STATE_NORMAL
; 
 233     // get the style's colours 
 234     attr
.colFg 
= wxColour(style
->fg
[state
]); 
 236         attr
.colBg 
= wxColour(style
->base
[state
]); 
 238         attr
.colBg 
= wxColour(style
->bg
[state
]); 
 240     // get the style's font 
 241     if ( !style
->font_desc 
) 
 242         style 
= gtk_widget_get_default_style(); 
 243     if ( style 
&& style
->font_desc 
) 
 245         wxNativeFontInfo info
; 
 246         info
.description 
= pango_font_description_copy(style
->font_desc
); 
 247         attr
.font 
= wxFont(info
); 
 251         GtkSettings 
*settings 
= gtk_settings_get_default(); 
 252         gchar 
*font_name 
= NULL
; 
 253         g_object_get ( settings
, 
 258             attr
.font 
= wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT 
); 
 260             attr
.font 
= wxFont(wxString::FromAscii(font_name
)); 
 270 wxControl::GetDefaultAttributesFromGTKWidget(wxGtkWidgetNew_t widget_new
, 
 274     wxVisualAttributes attr
; 
 275     // NB: we need toplevel window so that GTK+ can find the right style 
 276     GtkWidget 
*wnd 
= gtk_window_new(GTK_WINDOW_TOPLEVEL
); 
 277     GtkWidget
* widget 
= widget_new(); 
 278     gtk_container_add(GTK_CONTAINER(wnd
), widget
); 
 279     attr 
= GetDefaultAttributesFromGTKWidget(widget
, useBase
, state
); 
 280     gtk_widget_destroy(wnd
); 
 286 wxControl::GetDefaultAttributesFromGTKWidget(wxGtkWidgetNewFromStr_t widget_new
, 
 290     wxVisualAttributes attr
; 
 291     // NB: we need toplevel window so that GTK+ can find the right style 
 292     GtkWidget 
*wnd 
= gtk_window_new(GTK_WINDOW_TOPLEVEL
); 
 293     GtkWidget
* widget 
= widget_new(""); 
 294     gtk_container_add(GTK_CONTAINER(wnd
), widget
); 
 295     attr 
= GetDefaultAttributesFromGTKWidget(widget
, useBase
, state
); 
 296     gtk_widget_destroy(wnd
); 
 303 wxControl::GetDefaultAttributesFromGTKWidget(wxGtkWidgetNewFromAdj_t widget_new
, 
 307     wxVisualAttributes attr
; 
 308     // NB: we need toplevel window so that GTK+ can find the right style 
 309     GtkWidget 
*wnd 
= gtk_window_new(GTK_WINDOW_TOPLEVEL
); 
 310     GtkWidget
* widget 
= widget_new(NULL
); 
 311     gtk_container_add(GTK_CONTAINER(wnd
), widget
); 
 312     attr 
= GetDefaultAttributesFromGTKWidget(widget
, useBase
, state
); 
 313     gtk_widget_destroy(wnd
); 
 317 // ---------------------------------------------------------------------------- 
 319 // ---------------------------------------------------------------------------- 
 321 void wxControl::OnInternalIdle() 
 323     if ( GTKShowFromOnIdle() ) 
 326     if ( wxUpdateUIEvent::CanUpdate(this) && IsShownOnScreen() ) 
 327         UpdateWindowUI(wxUPDATE_UI_FROMIDLE
); 
 330 #endif // wxUSE_CONTROLS