]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/gtk/control.cpp
patch 1352744
[wxWidgets.git] / src / gtk / control.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: control.cpp
3// Purpose:
4// Author: Robert Roebling
5// Id: $Id$
6// Copyright: (c) 1998 Robert Roebling, Julian Smart and Vadim Zeitlin
7// Licence: wxWindows licence
8/////////////////////////////////////////////////////////////////////////////
9
10// For compilers that support precompilation, includes "wx.h".
11#include "wx/wxprec.h"
12
13#include "wx/defs.h"
14
15#if wxUSE_CONTROLS
16
17#include "wx/control.h"
18#include "wx/fontutil.h"
19#include "wx/settings.h"
20
21#include <gtk/gtk.h>
22
23//-----------------------------------------------------------------------------
24// wxControl
25//-----------------------------------------------------------------------------
26
27IMPLEMENT_DYNAMIC_CLASS(wxControl, wxWindow)
28
29wxControl::wxControl()
30{
31 m_needParent = TRUE;
32}
33
34bool wxControl::Create( wxWindow *parent,
35 wxWindowID id,
36 const wxPoint &pos,
37 const wxSize &size,
38 long style,
39 const wxValidator& validator,
40 const wxString &name )
41{
42 bool ret = wxWindow::Create(parent, id, pos, size, style, name);
43
44#if wxUSE_VALIDATORS
45 SetValidator(validator);
46#endif
47
48 return ret;
49}
50
51void wxControl::SetLabel( const wxString &label )
52{
53 m_label.Empty();
54 for ( const wxChar *pc = label; *pc != wxT('\0'); pc++ )
55 {
56 if ( *pc == wxT('&') )
57 {
58 pc++; // skip it
59#if 0 // it would be unused anyhow for now - kbd interface not done yet
60 if ( *pc != wxT('&') ) m_chAccel = *pc;
61#endif
62 }
63 m_label << *pc;
64 }
65 InvalidateBestSize();
66}
67
68wxString wxControl::GetLabel() const
69{
70 return m_label;
71}
72
73
74wxSize wxControl::DoGetBestSize() const
75{
76 // Do not return any arbitrary default value...
77 wxASSERT_MSG( m_widget, wxT("DoGetBestSize called before creation") );
78
79 GtkRequisition req;
80 req.width = 2;
81 req.height = 2;
82 (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(m_widget) )->size_request )
83 (m_widget, &req );
84
85 wxSize best(req.width, req.height);
86 CacheBestSize(best);
87 return best;
88}
89
90
91void wxControl::PostCreation(const wxSize& size)
92{
93 wxWindow::PostCreation();
94
95 // NB: GetBestSize needs to know the style, otherwise it will assume
96 // default font and if the user uses a different font, determined
97 // best size will be different (typically, smaller) than the desired
98 // size. This call ensure that a style is available at the time
99 // GetBestSize is called.
100 gtk_widget_ensure_style(m_widget);
101
102 ApplyWidgetStyle();
103 SetInitialBestSize(size);
104}
105
106
107#ifdef __WXGTK20__
108wxString wxControl::PrepareLabelMnemonics( const wxString &label ) const
109{
110 //Format mnemonics properly for GTK2. This can be called from GTK1.x, but
111 //it's not very useful because mnemonics don't exist prior to GTK2.
112 wxString label2;
113 for (size_t i = 0; i < label.Len(); i++)
114 {
115 if (label.GetChar(i) == wxT('&'))
116 {
117 //Mnemonic escape sequence "&&" is a literal "&" in the output.
118 if (label.GetChar(i + 1) == wxT('&'))
119 {
120 label2 << wxT('&');
121 i++;
122 }
123 //Handle special case of "&_" (i.e. "_" is the mnemonic).
124 //FIXME - Is it possible to use "_" as a GTK mnemonic? Just use a
125 //dash for now.
126 else if (label.GetChar(i + 1) == wxT('_'))
127 {
128 label2 << wxT("_-");
129 i++;
130 }
131 //Replace WX mnemonic indicator "&" with GTK indicator "_".
132 else
133 {
134 label2 << wxT('_');
135 }
136 }
137 else if (label.GetChar(i) == wxT('_'))
138 {
139 //Escape any underlines in the string so GTK doesn't use them.
140 label2 << wxT("__");
141 }
142 else
143 {
144 label2 << label.GetChar(i);
145 }
146 }
147 return label2;
148}
149#endif
150
151
152wxVisualAttributes wxControl::GetDefaultAttributes() const
153{
154 return GetDefaultAttributesFromGTKWidget(m_widget,
155 UseGTKStyleBase());
156}
157
158
159#define SHIFT (8*(sizeof(short int)-sizeof(char)))
160
161// static
162wxVisualAttributes
163wxControl::GetDefaultAttributesFromGTKWidget(GtkWidget* widget,
164 bool useBase,
165 int state)
166{
167 GtkStyle* style;
168 wxVisualAttributes attr;
169
170 style = gtk_rc_get_style(widget);
171 if (!style)
172 style = gtk_widget_get_default_style();
173
174 if (!style)
175 {
176 return wxWindow::GetClassDefaultAttributes(wxWINDOW_VARIANT_NORMAL);
177 }
178
179 if (state == -1)
180 state = GTK_STATE_NORMAL;
181
182 // get the style's colours
183 attr.colFg = wxColour(style->fg[state].red >> SHIFT,
184 style->fg[state].green >> SHIFT,
185 style->fg[state].blue >> SHIFT);
186 if (useBase)
187 attr.colBg = wxColour(style->base[state].red >> SHIFT,
188 style->base[state].green >> SHIFT,
189 style->base[state].blue >> SHIFT);
190 else
191 attr.colBg = wxColour(style->bg[state].red >> SHIFT,
192 style->bg[state].green >> SHIFT,
193 style->bg[state].blue >> SHIFT);
194
195 // get the style's font
196#ifdef __WXGTK20__
197 if ( !style->font_desc )
198 style = gtk_widget_get_default_style();
199 if ( style && style->font_desc )
200 {
201 wxNativeFontInfo info;
202 info.description = pango_font_description_copy(style->font_desc);
203 attr.font = wxFont(info);
204 }
205 else
206 {
207 GtkSettings *settings = gtk_settings_get_default();
208 gchar *font_name = NULL;
209 g_object_get ( settings,
210 "gtk-font-name",
211 &font_name,
212 NULL);
213 if (!font_name)
214 attr.font = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
215 else
216 attr.font = wxFont(wxString::FromAscii(font_name));
217 g_free (font_name);
218 }
219#else
220 // TODO: isn't there a way to get a standard gtk 1.2 font?
221 attr.font = wxFont( 12, wxSWISS, wxNORMAL, wxNORMAL );
222#endif
223
224 return attr;
225}
226
227
228//static
229wxVisualAttributes
230wxControl::GetDefaultAttributesFromGTKWidget(wxGtkWidgetNew_t widget_new,
231 bool useBase,
232 int state)
233{
234 wxVisualAttributes attr;
235 // NB: we need toplevel window so that GTK+ can find the right style
236 GtkWidget *wnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
237 GtkWidget* widget = widget_new();
238 gtk_container_add(GTK_CONTAINER(wnd), widget);
239 attr = GetDefaultAttributesFromGTKWidget(widget, useBase, state);
240 gtk_widget_destroy(wnd);
241 return attr;
242}
243
244//static
245wxVisualAttributes
246wxControl::GetDefaultAttributesFromGTKWidget(wxGtkWidgetNewFromStr_t widget_new,
247 bool useBase,
248 int state)
249{
250 wxVisualAttributes attr;
251 // NB: we need toplevel window so that GTK+ can find the right style
252 GtkWidget *wnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
253 GtkWidget* widget = widget_new("");
254 gtk_container_add(GTK_CONTAINER(wnd), widget);
255 attr = GetDefaultAttributesFromGTKWidget(widget, useBase, state);
256 gtk_widget_destroy(wnd);
257 return attr;
258}
259
260
261//static
262wxVisualAttributes
263wxControl::GetDefaultAttributesFromGTKWidget(wxGtkWidgetNewFromAdj_t widget_new,
264 bool useBase,
265 int state)
266{
267 wxVisualAttributes attr;
268 // NB: we need toplevel window so that GTK+ can find the right style
269 GtkWidget *wnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
270 GtkWidget* widget = widget_new(NULL);
271 gtk_container_add(GTK_CONTAINER(wnd), widget);
272 attr = GetDefaultAttributesFromGTKWidget(widget, useBase, state);
273 gtk_widget_destroy(wnd);
274 return attr;
275}
276
277#endif // wxUSE_CONTROLS
278