]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/control.cpp
backported changes from gtk/window.cpp rev 1.678 (bug 1531348)
[wxWidgets.git] / src / gtk1 / control.cpp
CommitLineData
c801d85f 1/////////////////////////////////////////////////////////////////////////////
3cbab641 2// Name: src/gtk1/control.cpp
634fb750 3// Purpose: wxControl implementation for wxGTK
c801d85f 4// Author: Robert Roebling
dbf858b5 5// Id: $Id$
01111366 6// Copyright: (c) 1998 Robert Roebling, Julian Smart and Vadim Zeitlin
65571936 7// Licence: wxWindows licence
c801d85f
KB
8/////////////////////////////////////////////////////////////////////////////
9
14f355c2
VS
10// For compilers that support precompilation, includes "wx.h".
11#include "wx/wxprec.h"
12
1e6feb95
VZ
13#if wxUSE_CONTROLS
14
c801d85f 15#include "wx/control.h"
e4db172a
WS
16
17#ifndef WX_PRECOMP
18 #include "wx/log.h"
9eddec69 19 #include "wx/settings.h"
e4db172a
WS
20#endif
21
9d522606 22#include "wx/fontutil.h"
3cbab641 23#include "wx/gtk1/private.h"
034be888 24
634fb750
VZ
25// ============================================================================
26// wxControl implementation
27// ============================================================================
28
29// ----------------------------------------------------------------------------
30// wxControl creation
31// ----------------------------------------------------------------------------
c801d85f 32
9abe166a 33IMPLEMENT_DYNAMIC_CLASS(wxControl, wxWindow)
c801d85f 34
31528cd3 35wxControl::wxControl()
c801d85f 36{
9eddec69 37 m_needParent = true;
6de97a3b 38}
c801d85f 39
04165bec 40bool wxControl::Create( wxWindow *parent,
31528cd3
VZ
41 wxWindowID id,
42 const wxPoint &pos,
43 const wxSize &size,
44 long style,
8d772832 45 const wxValidator& validator,
04165bec 46 const wxString &name )
8d772832 47{
04165bec 48 bool ret = wxWindow::Create(parent, id, pos, size, style, name);
b2ff89d6 49
04165bec 50#if wxUSE_VALIDATORS
8d772832 51 SetValidator(validator);
8d772832
RD
52#endif
53
04165bec
RR
54 return ret;
55}
56
f68586e5
VZ
57wxSize wxControl::DoGetBestSize() const
58{
0279e844
RR
59 // Do not return any arbitrary default value...
60 wxASSERT_MSG( m_widget, wxT("DoGetBestSize called before creation") );
61
f68586e5 62 GtkRequisition req;
33720b2d
RR
63 req.width = 2;
64 req.height = 2;
2afa14f2 65 (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(m_widget) )->size_request )
f68586e5
VZ
66 (m_widget, &req );
67
9f884528
RD
68 wxSize best(req.width, req.height);
69 CacheBestSize(best);
70 return best;
f68586e5
VZ
71}
72
abdeb9e7
RD
73
74void wxControl::PostCreation(const wxSize& size)
75{
76 wxWindow::PostCreation();
f40fdaa3
VS
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);
b2ff89d6 84
abdeb9e7 85 ApplyWidgetStyle();
170acdc9 86 SetInitialSize(size);
abdeb9e7
RD
87}
88
b2ff89d6
VZ
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
ee6dd41a 112 const wxString labelGTK = GTKRemoveMnemonics(label);
abdeb9e7 113
b2ff89d6 114 gtk_label_set(w, wxGTK_CONV(labelGTK));
b2ff89d6
VZ
115}
116
117void wxControl::GTKSetLabelForFrame(GtkFrame *w, const wxString& label)
118{
119 wxControl::SetLabel(label);
120
b2ff89d6
VZ
121 const wxString labelGTK = GTKRemoveMnemonics(label);
122
123 gtk_frame_set_label(w, labelGTK.empty() ? (char *)NULL
124 : wxGTK_CONV(labelGTK));
125}
126
ee6dd41a
VZ
127/* static */
128wxString wxControl::GTKRemoveMnemonics(const wxString& label)
b2ff89d6
VZ
129{
130 const size_t len = label.length();
131 wxString labelGTK;
132 labelGTK.reserve(len);
133 for ( size_t i = 0; i < len; i++ )
eaafd2f8 134 {
b2ff89d6
VZ
135 wxChar ch = label[i];
136
ee6dd41a 137 if ( ch == _T('&') )
eaafd2f8 138 {
ee6dd41a
VZ
139 if ( i == len - 1 )
140 {
141 // "&" at the end of string is an error
142 wxLogDebug(wxT("Invalid label \"%s\"."), label.c_str());
b2ff89d6 143 break;
ee6dd41a
VZ
144 }
145
146 ch = label[++i]; // skip '&' itself
147 if ( ch == _T('&') )
148 {
149 // special case: "&&" is not a mnemonic at all but just an
150 // escaped "&"
151 labelGTK += wxT('&');
152 continue;
153 }
eaafd2f8 154 }
ee6dd41a
VZ
155
156 labelGTK += ch;
eaafd2f8 157 }
b2ff89d6
VZ
158
159 return labelGTK;
160}
161
b2ff89d6
VZ
162// ----------------------------------------------------------------------------
163// wxControl styles (a.k.a. attributes)
164// ----------------------------------------------------------------------------
9d522606
RD
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;
b2ff89d6 195
9d522606
RD
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
9d522606
RD
210 // TODO: isn't there a way to get a standard gtk 1.2 font?
211 attr.font = wxFont( 12, wxSWISS, wxNORMAL, wxNORMAL );
b2ff89d6 212
9d522606
RD
213 return attr;
214}
215
216
217//static
218wxVisualAttributes
865bb325 219wxControl::GetDefaultAttributesFromGTKWidget(wxGtkWidgetNew_t widget_new,
9d522606
RD
220 bool useBase,
221 int state)
222{
223 wxVisualAttributes attr;
66d8fe77
VS
224 // NB: we need toplevel window so that GTK+ can find the right style
225 GtkWidget *wnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
9d522606 226 GtkWidget* widget = widget_new();
66d8fe77 227 gtk_container_add(GTK_CONTAINER(wnd), widget);
9d522606 228 attr = GetDefaultAttributesFromGTKWidget(widget, useBase, state);
66d8fe77 229 gtk_widget_destroy(wnd);
9d522606
RD
230 return attr;
231}
232
233//static
234wxVisualAttributes
865bb325 235wxControl::GetDefaultAttributesFromGTKWidget(wxGtkWidgetNewFromStr_t widget_new,
9d522606
RD
236 bool useBase,
237 int state)
238{
239 wxVisualAttributes attr;
66d8fe77
VS
240 // NB: we need toplevel window so that GTK+ can find the right style
241 GtkWidget *wnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
9d522606 242 GtkWidget* widget = widget_new("");
66d8fe77 243 gtk_container_add(GTK_CONTAINER(wnd), widget);
9d522606 244 attr = GetDefaultAttributesFromGTKWidget(widget, useBase, state);
66d8fe77 245 gtk_widget_destroy(wnd);
9d522606
RD
246 return attr;
247}
248
249
250//static
251wxVisualAttributes
865bb325 252wxControl::GetDefaultAttributesFromGTKWidget(wxGtkWidgetNewFromAdj_t widget_new,
9d522606
RD
253 bool useBase,
254 int state)
255{
256 wxVisualAttributes attr;
66d8fe77
VS
257 // NB: we need toplevel window so that GTK+ can find the right style
258 GtkWidget *wnd = gtk_window_new(GTK_WINDOW_TOPLEVEL);
9d522606 259 GtkWidget* widget = widget_new(NULL);
66d8fe77 260 gtk_container_add(GTK_CONTAINER(wnd), widget);
9d522606 261 attr = GetDefaultAttributesFromGTKWidget(widget, useBase, state);
66d8fe77 262 gtk_widget_destroy(wnd);
9d522606
RD
263 return attr;
264}
265
1e6feb95 266#endif // wxUSE_CONTROLS