]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/gtk1/control.cpp
Merge in from trunk r64802 - r68625
[wxWidgets.git] / src / gtk1 / control.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/gtk1/control.cpp
3// Purpose: wxControl implementation for wxGTK
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#if wxUSE_CONTROLS
14
15#include "wx/control.h"
16
17#ifndef WX_PRECOMP
18 #include "wx/log.h"
19 #include "wx/settings.h"
20#endif
21
22#include "wx/fontutil.h"
23#include "wx/gtk1/private.h"
24
25// ============================================================================
26// wxControl implementation
27// ============================================================================
28
29// ----------------------------------------------------------------------------
30// wxControl creation
31// ----------------------------------------------------------------------------
32
33IMPLEMENT_DYNAMIC_CLASS(wxControl, wxWindow)
34
35wxControl::wxControl()
36{
37 m_needParent = true;
38}
39
40bool wxControl::Create( wxWindow *parent,
41 wxWindowID id,
42 const wxPoint &pos,
43 const wxSize &size,
44 long style,
45 const wxValidator& validator,
46 const wxString &name )
47{
48 bool ret = wxWindow::Create(parent, id, pos, size, style, name);
49
50#if wxUSE_VALIDATORS
51 SetValidator(validator);
52#endif
53
54 return ret;
55}
56
57wxSize wxControl::DoGetBestSize() const
58{
59 // Do not return any arbitrary default value...
60 wxASSERT_MSG( m_widget, wxT("DoGetBestSize called before creation") );
61
62 GtkRequisition req;
63 req.width = 2;
64 req.height = 2;
65 (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(m_widget) )->size_request )
66 (m_widget, &req );
67
68 wxSize best(req.width, req.height);
69 CacheBestSize(best);
70 return best;
71}
72
73
74void wxControl::PostCreation(const wxSize& size)
75{
76 wxWindow::PostCreation();
77
78 // NB: GetBestSize needs to know the style, otherwise it will assume
79 // default font and if the user uses a different font, determined
80 // best size will be different (typically, smaller) than the desired
81 // size. This call ensure that a style is available at the time
82 // GetBestSize is called.
83 gtk_widget_ensure_style(m_widget);
84
85 ApplyWidgetStyle();
86 SetInitialSize(size);
87}
88
89// ----------------------------------------------------------------------------
90// wxControl dealing with labels
91// ----------------------------------------------------------------------------
92
93void wxControl::SetLabel( const wxString &label )
94{
95 // keep the original string internally to be able to return it later (for
96 // consistency with the other ports)
97 m_label = label;
98
99 InvalidateBestSize();
100}
101
102wxString wxControl::GetLabel() const
103{
104 return m_label;
105}
106
107void wxControl::GTKSetLabelForLabel(GtkLabel *w, const wxString& label)
108{
109 // don't call the virtual function which might call this one back again
110 wxControl::SetLabel(label);
111
112 const wxString labelGTK = GTKRemoveMnemonics(label);
113
114 gtk_label_set(w, wxGTK_CONV(labelGTK));
115}
116
117void wxControl::GTKSetLabelForFrame(GtkFrame *w, const wxString& label)
118{
119 wxControl::SetLabel(label);
120
121 const wxString labelGTK = GTKRemoveMnemonics(label);
122
123 gtk_frame_set_label(w, labelGTK.empty() ? (const char *)NULL
124 : wxGTK_CONV(labelGTK));
125}
126
127/* static */
128wxString wxControl::GTKRemoveMnemonics(const wxString& label)
129{
130 const size_t len = label.length();
131 wxString labelGTK;
132 labelGTK.reserve(len);
133 for ( size_t i = 0; i < len; i++ )
134 {
135 wxChar ch = label[i];
136
137 if ( ch == wxT('&') )
138 {
139 if ( i == len - 1 )
140 {
141 // "&" at the end of string is an error
142 wxLogDebug(wxT("Invalid label \"%s\"."), label.c_str());
143 break;
144 }
145
146 ch = label[++i]; // skip '&' itself
147 if ( ch == wxT('&') )
148 {
149 // special case: "&&" is not a mnemonic at all but just an
150 // escaped "&"
151 labelGTK += wxT('&');
152 continue;
153 }
154 }
155
156 labelGTK += ch;
157 }
158
159 return labelGTK;
160}
161
162// ----------------------------------------------------------------------------
163// wxControl styles (a.k.a. attributes)
164// ----------------------------------------------------------------------------
165
166wxVisualAttributes wxControl::GetDefaultAttributes() const
167{
168 return GetDefaultAttributesFromGTKWidget(m_widget,
169 UseGTKStyleBase());
170}
171
172
173#define SHIFT (8*(sizeof(short int)-sizeof(char)))
174
175// static
176wxVisualAttributes
177wxControl::GetDefaultAttributesFromGTKWidget(GtkWidget* widget,
178 bool useBase,
179 int state)
180{
181 GtkStyle* style;
182 wxVisualAttributes attr;
183
184 style = gtk_rc_get_style(widget);
185 if (!style)
186 style = gtk_widget_get_default_style();
187
188 if (!style)
189 {
190 return wxWindow::GetClassDefaultAttributes(wxWINDOW_VARIANT_NORMAL);
191 }
192
193 if (state == -1)
194 state = GTK_STATE_NORMAL;
195
196 // get the style's colours
197 attr.colFg = wxColour(style->fg[state].red >> SHIFT,
198 style->fg[state].green >> SHIFT,
199 style->fg[state].blue >> SHIFT);
200 if (useBase)
201 attr.colBg = wxColour(style->base[state].red >> SHIFT,
202 style->base[state].green >> SHIFT,
203 style->base[state].blue >> SHIFT);
204 else
205 attr.colBg = wxColour(style->bg[state].red >> SHIFT,
206 style->bg[state].green >> SHIFT,
207 style->bg[state].blue >> SHIFT);
208
209 // get the style's font
210 // TODO: isn't there a way to get a standard gtk 1.2 font?
211 attr.font = wxFont( 12, wxSWISS, wxNORMAL, wxNORMAL );
212
213 return attr;
214}
215
216
217//static
218wxVisualAttributes
219wxControl::GetDefaultAttributesFromGTKWidget(wxGtkWidgetNew_t widget_new,
220 bool useBase,
221 int state)
222{
223 wxVisualAttributes attr;
224 // NB: we need toplevel window so that GTK+ can find the right style
225 GtkWidget *wnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
226 GtkWidget* widget = widget_new();
227 gtk_container_add(GTK_CONTAINER(wnd), widget);
228 attr = GetDefaultAttributesFromGTKWidget(widget, useBase, state);
229 gtk_widget_destroy(wnd);
230 return attr;
231}
232
233//static
234wxVisualAttributes
235wxControl::GetDefaultAttributesFromGTKWidget(wxGtkWidgetNewFromStr_t widget_new,
236 bool useBase,
237 int state)
238{
239 wxVisualAttributes attr;
240 // NB: we need toplevel window so that GTK+ can find the right style
241 GtkWidget *wnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
242 GtkWidget* widget = widget_new("");
243 gtk_container_add(GTK_CONTAINER(wnd), widget);
244 attr = GetDefaultAttributesFromGTKWidget(widget, useBase, state);
245 gtk_widget_destroy(wnd);
246 return attr;
247}
248
249
250//static
251wxVisualAttributes
252wxControl::GetDefaultAttributesFromGTKWidget(wxGtkWidgetNewFromAdj_t widget_new,
253 bool useBase,
254 int state)
255{
256 wxVisualAttributes attr;
257 // NB: we need toplevel window so that GTK+ can find the right style
258 GtkWidget *wnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
259 GtkWidget* widget = widget_new(NULL);
260 gtk_container_add(GTK_CONTAINER(wnd), widget);
261 attr = GetDefaultAttributesFromGTKWidget(widget, useBase, state);
262 gtk_widget_destroy(wnd);
263 return attr;
264}
265
266#endif // wxUSE_CONTROLS