]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/renderer.cpp
native apple event support for osx cocoa
[wxWidgets.git] / src / gtk / renderer.cpp
CommitLineData
9c7f49f5 1///////////////////////////////////////////////////////////////////////////////
90b903c2 2// Name: src/gtk/renderer.cpp
38c4cb6a 3// Purpose: implementation of wxRendererNative for wxGTK
9c7f49f5
VZ
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 20.07.2003
7// RCS-ID: $Id$
8// Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
65571936 9// License: wxWindows licence
9c7f49f5
VZ
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20// for compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
e1bf3ad3 27#include "wx/renderer.h"
cdccdfab
WS
28
29#ifndef WX_PRECOMP
30 #include "wx/window.h"
ed4b0fdc 31 #include "wx/dcclient.h"
9eddec69 32 #include "wx/settings.h"
f1c09bed 33 #include "wx/module.h"
cdccdfab
WS
34#endif
35
888dde65 36#include "wx/gtk/dc.h"
e8759560 37#include "wx/gtk/private.h"
888dde65 38
9c7f49f5 39#include <gtk/gtk.h>
9c7f49f5 40
9c7f49f5 41// ----------------------------------------------------------------------------
38c4cb6a 42// wxRendererGTK: our wxRendererNative implementation
9c7f49f5
VZ
43// ----------------------------------------------------------------------------
44
38c4cb6a 45class WXDLLEXPORT wxRendererGTK : public wxDelegateRendererNative
9c7f49f5
VZ
46{
47public:
48 // draw the header control button (used by wxListCtrl)
c97c9952 49 virtual int DrawHeaderButton(wxWindow *win,
9c7f49f5
VZ
50 wxDC& dc,
51 const wxRect& rect,
4b94ddc4 52 int flags = 0,
80752b57 53 wxHeaderSortIconType sortArrow = wxHDR_SORT_ICON_NONE,
4b94ddc4 54 wxHeaderButtonParams* params = NULL);
9c7f49f5 55
9c7f49f5
VZ
56 // draw the expanded/collapsed icon for a tree control item
57 virtual void DrawTreeItemButton(wxWindow *win,
58 wxDC& dc,
59 const wxRect& rect,
60 int flags = 0);
9c7f49f5 61
d16cf3cd
VZ
62 virtual void DrawSplitterBorder(wxWindow *win,
63 wxDC& dc,
af99040c
VZ
64 const wxRect& rect,
65 int flags = 0);
95155e75
VZ
66 virtual void DrawSplitterSash(wxWindow *win,
67 wxDC& dc,
68 const wxSize& size,
d16cf3cd 69 wxCoord position,
af99040c
VZ
70 wxOrientation orient,
71 int flags = 0);
d16cf3cd 72
38511687
VZ
73 virtual void DrawComboBoxDropButton(wxWindow *win,
74 wxDC& dc,
75 const wxRect& rect,
76 int flags = 0);
77
4c85ab75
VZ
78 virtual void DrawDropArrow(wxWindow *win,
79 wxDC& dc,
80 const wxRect& rect,
81 int flags = 0);
82
90b903c2
WS
83 virtual void DrawCheckBox(wxWindow *win,
84 wxDC& dc,
85 const wxRect& rect,
86 int flags = 0);
2209baae
RR
87
88 virtual void DrawPushButton(wxWindow *win,
89 wxDC& dc,
90 const wxRect& rect,
91 int flags = 0);
92
daebb44c
RR
93 virtual void DrawItemSelectionRect(wxWindow *win,
94 wxDC& dc,
95 const wxRect& rect,
96 int flags = 0);
90b903c2 97
e4131985
KO
98 virtual void DrawChoice(wxWindow* win,
99 wxDC& dc,
100 const wxRect& rect,
101 int flags=0);
102
103 virtual void DrawComboBox(wxWindow* win,
104 wxDC& dc,
105 const wxRect& rect,
106 int flags=0);
107
108 virtual void DrawTextCtrl(wxWindow* win,
109 wxDC& dc,
110 const wxRect& rect,
111 int flags=0);
112
113 virtual void DrawRadioButton(wxWindow* win,
114 wxDC& dc,
115 const wxRect& rect,
116 int flags=0);
117
6d789987
JS
118 virtual void DrawFocusRect(wxWindow* win, wxDC& dc, const wxRect& rect, int flags = 0);
119
e8759560 120 virtual wxSize GetCheckBoxSize(wxWindow *win);
f1c09bed 121
e8759560 122 virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win);
9c7f49f5
VZ
123};
124
125// ============================================================================
126// implementation
127// ============================================================================
128
129/* static */
f0244295 130wxRendererNative& wxRendererNative::GetDefault()
9c7f49f5
VZ
131{
132 static wxRendererGTK s_rendererGTK;
133
134 return s_rendererGTK;
135}
136
7e717730 137static GdkWindow* wxGetGdkWindowForDC(wxDC& dc)
e4131985
KO
138{
139 GdkWindow* gdk_window = NULL;
140#if wxUSE_NEW_DC
141 wxDCImpl *impl = dc.GetImpl();
142 wxGTKDCImpl *gtk_impl = wxDynamicCast( impl, wxGTKDCImpl );
143 if (gtk_impl)
144 gdk_window = gtk_impl->GetGDKWindow();
145#else
146 gdk_window = dc.GetGDKWindow();
147#endif
148 return gdk_window;
149}
150
d16cf3cd
VZ
151// ----------------------------------------------------------------------------
152// list/tree controls drawing
153// ----------------------------------------------------------------------------
154
c97c9952 155int
9c7f49f5
VZ
156wxRendererGTK::DrawHeaderButton(wxWindow *win,
157 wxDC& dc,
158 const wxRect& rect,
4b94ddc4 159 int flags,
80752b57 160 wxHeaderSortIconType sortArrow,
4b94ddc4 161 wxHeaderButtonParams* params)
9c7f49f5 162{
9b311923 163
e8759560 164 GtkWidget *button = wxGTKPrivate::GetHeaderButtonWidget();
f1c09bed 165
7e717730 166 GdkWindow* gdk_window = wxGetGdkWindowForDC(dc);
2e992e06
VZ
167 wxASSERT_MSG( gdk_window,
168 wxT("cannot use wxRendererNative on wxDC of this type") );
169
5eefe029
RR
170 int x_diff = 0;
171 if (win->GetLayoutDirection() == wxLayout_RightToLeft)
172 x_diff = rect.width;
f4322df6 173
1cfc4971
RR
174 GtkStateType state = GTK_STATE_NORMAL;
175 if (flags & wxCONTROL_DISABLED)
176 state = GTK_STATE_INSENSITIVE;
177 else
178 {
179 if (flags & wxCONTROL_CURRENT)
180 state = GTK_STATE_PRELIGHT;
181 }
182
9c7f49f5
VZ
183 gtk_paint_box
184 (
bc13e772 185 button->style,
2e992e06 186 gdk_window,
1cfc4971 187 state,
9c7f49f5 188 GTK_SHADOW_OUT,
38511687 189 NULL,
bc13e772 190 button,
9b311923 191 "button",
5eefe029 192 dc.LogicalToDeviceX(rect.x) - x_diff, rect.y, rect.width, rect.height
9c7f49f5 193 );
4b94ddc4 194
c97c9952 195 return DrawHeaderButtonContents(win, dc, rect, flags, sortArrow, params);
9c7f49f5
VZ
196}
197
9c7f49f5 198// draw a ">" or "v" button
9c7f49f5 199void
f8b043e7 200wxRendererGTK::DrawTreeItemButton(wxWindow* win,
9a0b7e33 201 wxDC& dc, const wxRect& rect, int flags)
9c7f49f5 202{
e8759560 203 GtkWidget *tree = wxGTKPrivate::GetTreeWidget();
f8b043e7 204
7e717730 205 GdkWindow* gdk_window = wxGetGdkWindowForDC(dc);
2e992e06
VZ
206 wxASSERT_MSG( gdk_window,
207 wxT("cannot use wxRendererNative on wxDC of this type") );
208
885dd597
RR
209 GtkStateType state;
210 if ( flags & wxCONTROL_CURRENT )
211 state = GTK_STATE_PRELIGHT;
212 else
213 state = GTK_STATE_NORMAL;
91af0895 214
428f4657
RR
215 int x_diff = 0;
216 if (win->GetLayoutDirection() == wxLayout_RightToLeft)
217 x_diff = rect.width;
2e992e06 218
bc13e772
VZ
219 // VZ: I don't know how to get the size of the expander so as to centre it
220 // in the given rectangle, +2/3 below is just what looks good here...
221 gtk_paint_expander
222 (
223 tree->style,
2e992e06 224 gdk_window,
885dd597 225 state,
bc13e772
VZ
226 NULL,
227 tree,
228 "treeview",
11012f47 229 dc.LogicalToDeviceX(rect.x) + 6 - x_diff,
bc13e772
VZ
230 dc.LogicalToDeviceY(rect.y) + 3,
231 flags & wxCONTROL_EXPANDED ? GTK_EXPANDER_EXPANDED
232 : GTK_EXPANDER_COLLAPSED
233 );
9c7f49f5
VZ
234}
235
9c7f49f5 236
d16cf3cd
VZ
237// ----------------------------------------------------------------------------
238// splitter sash drawing
239// ----------------------------------------------------------------------------
240
f1c09bed 241static int GetGtkSplitterFullSize(GtkWidget* widget)
38418827 242{
38418827 243 gint handle_size;
f1c09bed 244 gtk_widget_style_get(widget, "handle_size", &handle_size, NULL);
91af0895 245
38418827 246 return handle_size;
38418827
RR
247}
248
af99040c 249wxSplitterRenderParams
38418827 250wxRendererGTK::GetSplitterParams(const wxWindow *WXUNUSED(win))
d16cf3cd 251{
af99040c
VZ
252 // we don't draw any border, hence 0 for the second field
253 return wxSplitterRenderParams
254 (
e8759560 255 GetGtkSplitterFullSize(wxGTKPrivate::GetSplitterWidget()),
af99040c 256 0,
af99040c 257 true // hot sensitive
af99040c 258 );
d16cf3cd
VZ
259}
260
261void
262wxRendererGTK::DrawSplitterBorder(wxWindow * WXUNUSED(win),
263 wxDC& WXUNUSED(dc),
af99040c
VZ
264 const wxRect& WXUNUSED(rect),
265 int WXUNUSED(flags))
d16cf3cd
VZ
266{
267 // nothing to do
268}
95155e75 269
95155e75
VZ
270void
271wxRendererGTK::DrawSplitterSash(wxWindow *win,
272 wxDC& dc,
273 const wxSize& size,
d16cf3cd 274 wxCoord position,
af99040c 275 wxOrientation orient,
68567a96 276 int flags)
95155e75
VZ
277{
278 if ( !win->m_wxwindow->window )
279 {
0100b858 280 // window not realized yet
95155e75
VZ
281 return;
282 }
91af0895 283
7e717730 284 GdkWindow* gdk_window = wxGetGdkWindowForDC(dc);
2e992e06
VZ
285 wxASSERT_MSG( gdk_window,
286 wxT("cannot use wxRendererNative on wxDC of this type") );
287
e8759560 288 wxCoord full_size = GetGtkSplitterFullSize(wxGTKPrivate::GetSplitterWidget());
95155e75 289
d16cf3cd
VZ
290 // are we drawing vertical or horizontal splitter?
291 const bool isVert = orient == wxVERTICAL;
292
d16cf3cd 293 GdkRectangle rect;
91af0895 294
d16cf3cd
VZ
295 if ( isVert )
296 {
297 rect.x = position;
0100b858 298 rect.y = 0;
38418827 299 rect.width = full_size;
e4161a2a 300 rect.height = size.y;
d16cf3cd
VZ
301 }
302 else // horz
303 {
0100b858 304 rect.x = 0;
d16cf3cd 305 rect.y = position;
38418827 306 rect.height = full_size;
e4161a2a 307 rect.width = size.x;
d16cf3cd 308 }
f4322df6 309
847dfdb4
RR
310 int x_diff = 0;
311 if (win->GetLayoutDirection() == wxLayout_RightToLeft)
312 x_diff = rect.width;
35468934 313
af99040c
VZ
314 gtk_paint_handle
315 (
316 win->m_wxwindow->style,
2e992e06 317 gdk_window,
af99040c
VZ
318 flags & wxCONTROL_CURRENT ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL,
319 GTK_SHADOW_NONE,
320 NULL /* no clipping */,
321 win->m_wxwindow,
322 "paned",
847dfdb4
RR
323 dc.LogicalToDeviceX(rect.x) - x_diff,
324 dc.LogicalToDeviceY(rect.y),
af99040c
VZ
325 rect.width,
326 rect.height,
38418827 327 isVert ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL
af99040c 328 );
95155e75
VZ
329}
330
4c85ab75 331void
2e992e06 332wxRendererGTK::DrawDropArrow(wxWindow *WXUNUSED(win),
4c85ab75
VZ
333 wxDC& dc,
334 const wxRect& rect,
335 int flags)
38511687 336{
e8759560 337 GtkWidget *button = wxGTKPrivate::GetButtonWidget();
38511687 338
4c85ab75
VZ
339 // If we give GTK_PIZZA(win->m_wxwindow)->bin_window as
340 // a window for gtk_paint_xxx function, then it won't
341 // work for wxMemoryDC. So that is why we assume wxDC
342 // is wxWindowDC (wxClientDC, wxMemoryDC and wxPaintDC
343 // are derived from it) and use its m_window.
7e717730 344 GdkWindow* gdk_window = wxGetGdkWindowForDC(dc);
2e992e06
VZ
345 wxASSERT_MSG( gdk_window,
346 wxT("cannot use wxRendererNative on wxDC of this type") );
a4622f29 347
4c85ab75
VZ
348 // draw arrow so that there is even space horizontally
349 // on both sides
350 int arrowX = rect.width/4 + 1;
351 int arrowWidth = rect.width - (arrowX*2);
352
353 // scale arrow's height accoording to the width
354 int arrowHeight = rect.width/3;
355 int arrowY = (rect.height-arrowHeight)/2 +
356 ((rect.height-arrowHeight) & 1);
357
e1befae3 358 GtkStateType state;
a4622f29 359
3203621a
JS
360 if ( flags & wxCONTROL_PRESSED )
361 state = GTK_STATE_ACTIVE;
a4622f29
VZ
362 else if ( flags & wxCONTROL_DISABLED )
363 state = GTK_STATE_INSENSITIVE;
3203621a
JS
364 else if ( flags & wxCONTROL_CURRENT )
365 state = GTK_STATE_PRELIGHT;
e1befae3
VZ
366 else
367 state = GTK_STATE_NORMAL;
a4622f29 368
a4622f29 369 // draw arrow on button
a4622f29
VZ
370 gtk_paint_arrow
371 (
bc13e772 372 button->style,
2e992e06 373 gdk_window,
a4622f29 374 state,
e1befae3 375 flags & wxCONTROL_PRESSED ? GTK_SHADOW_IN : GTK_SHADOW_OUT,
a4622f29 376 NULL,
bc13e772 377 button,
a4622f29
VZ
378 "arrow",
379 GTK_ARROW_DOWN,
a8ac548e 380 FALSE,
4c85ab75
VZ
381 rect.x + arrowX,
382 rect.y + arrowY,
383 arrowWidth,
384 arrowHeight
a4622f29 385 );
38511687
VZ
386}
387
4c85ab75
VZ
388void
389wxRendererGTK::DrawComboBoxDropButton(wxWindow *win,
390 wxDC& dc,
391 const wxRect& rect,
392 int flags)
393{
2209baae
RR
394 DrawPushButton(win,dc,rect,flags);
395 DrawDropArrow(win,dc,rect);
396}
397
e8759560
VZ
398wxSize
399wxRendererGTK::GetCheckBoxSize(wxWindow *WXUNUSED(win))
400{
401 gint indicator_size, indicator_spacing;
402 gtk_widget_style_get(wxGTKPrivate::GetCheckButtonWidget(),
403 "indicator_size", &indicator_size,
404 "indicator_spacing", &indicator_spacing,
405 NULL);
406
407 int size = indicator_size + indicator_spacing * 2;
408 return wxSize(size, size);
409}
410
cdccdfab 411void
2e992e06 412wxRendererGTK::DrawCheckBox(wxWindow *WXUNUSED(win),
90b903c2
WS
413 wxDC& dc,
414 const wxRect& rect,
415 int flags )
2209baae 416{
e8759560 417 GtkWidget *button = wxGTKPrivate::GetCheckButtonWidget();
f1c09bed 418
7e717730 419 GdkWindow* gdk_window = wxGetGdkWindowForDC(dc);
2e992e06
VZ
420 wxASSERT_MSG( gdk_window,
421 wxT("cannot use wxRendererNative on wxDC of this type") );
90b903c2 422
e8759560
VZ
423 gint indicator_size, indicator_spacing;
424 gtk_widget_style_get(button,
425 "indicator_size", &indicator_size,
426 "indicator_spacing", &indicator_spacing,
427 NULL);
428
4c85ab75
VZ
429 GtkStateType state;
430
3203621a
JS
431 if ( flags & wxCONTROL_PRESSED )
432 state = GTK_STATE_ACTIVE;
4c85ab75
VZ
433 else if ( flags & wxCONTROL_DISABLED )
434 state = GTK_STATE_INSENSITIVE;
3203621a
JS
435 else if ( flags & wxCONTROL_CURRENT )
436 state = GTK_STATE_PRELIGHT;
4c85ab75
VZ
437 else
438 state = GTK_STATE_NORMAL;
90b903c2 439
2209baae 440 gtk_paint_check
4c85ab75
VZ
441 (
442 button->style,
2e992e06 443 gdk_window,
4c85ab75 444 state,
2209baae 445 flags & wxCONTROL_CHECKED ? GTK_SHADOW_IN : GTK_SHADOW_OUT,
4c85ab75
VZ
446 NULL,
447 button,
2209baae 448 "cellcheck",
e8759560
VZ
449 dc.LogicalToDeviceX(rect.x) + indicator_spacing,
450 dc.LogicalToDeviceY(rect.y) + indicator_spacing,
451 indicator_size, indicator_size
4c85ab75 452 );
4c85ab75
VZ
453}
454
2209baae 455void
2e992e06 456wxRendererGTK::DrawPushButton(wxWindow *WXUNUSED(win),
2209baae
RR
457 wxDC& dc,
458 const wxRect& rect,
459 int flags)
862d8041 460{
e8759560 461 GtkWidget *button = wxGTKPrivate::GetButtonWidget();
862d8041 462
7e717730 463 GdkWindow* gdk_window = wxGetGdkWindowForDC(dc);
2e992e06
VZ
464 wxASSERT_MSG( gdk_window,
465 wxT("cannot use wxRendererNative on wxDC of this type") );
2209baae
RR
466
467 // draw button
862d8041
RR
468 GtkStateType state;
469
470 if ( flags & wxCONTROL_PRESSED )
471 state = GTK_STATE_ACTIVE;
472 else if ( flags & wxCONTROL_DISABLED )
473 state = GTK_STATE_INSENSITIVE;
474 else if ( flags & wxCONTROL_CURRENT )
475 state = GTK_STATE_PRELIGHT;
476 else
477 state = GTK_STATE_NORMAL;
2209baae
RR
478
479 gtk_paint_box
862d8041
RR
480 (
481 button->style,
2e992e06 482 gdk_window,
862d8041 483 state,
2209baae 484 flags & wxCONTROL_PRESSED ? GTK_SHADOW_IN : GTK_SHADOW_OUT,
862d8041
RR
485 NULL,
486 button,
2209baae 487 "button",
e4131985
KO
488 dc.LogicalToDeviceX(rect.x),
489 dc.LogicalToDeviceY(rect.y),
490 rect.width,
491 rect.height
862d8041
RR
492 );
493}
daebb44c 494
cdccdfab 495void
daebb44c 496wxRendererGTK::DrawItemSelectionRect(wxWindow *win,
cdccdfab
WS
497 wxDC& dc,
498 const wxRect& rect,
499 int flags )
daebb44c 500{
7e717730 501 GdkWindow* gdk_window = wxGetGdkWindowForDC(dc);
2e992e06
VZ
502 wxASSERT_MSG( gdk_window,
503 wxT("cannot use wxRendererNative on wxDC of this type") );
504
08f57d21
RR
505 int x_diff = 0;
506 if (win->GetLayoutDirection() == wxLayout_RightToLeft)
507 x_diff = rect.width;
508
daebb44c 509 GtkStateType state;
90b903c2 510 if (flags & wxCONTROL_SELECTED)
daebb44c 511 {
05d97538
RR
512 // the wxCONTROL_FOCUSED state is deduced
513 // directly from the m_wxwindow by GTK+
514 state = GTK_STATE_SELECTED;
daebb44c 515
05d97538 516 gtk_paint_flat_box( win->m_widget->style,
2e992e06 517 gdk_window,
daebb44c
RR
518 state,
519 GTK_SHADOW_NONE,
cdccdfab 520 NULL,
daebb44c 521 win->m_wxwindow,
05d97538 522 "cell_even",
08f57d21 523 dc.LogicalToDeviceX(rect.x) - x_diff,
daebb44c
RR
524 dc.LogicalToDeviceY(rect.y),
525 rect.width,
526 rect.height );
527 }
72be9a3a
VZ
528 else // !wxCONTROL_SELECTED
529 {
530 state = GTK_STATE_NORMAL;
531 }
90b903c2 532
ce0cf2b8 533 if ((flags & wxCONTROL_CURRENT) && (flags & wxCONTROL_FOCUSED))
daebb44c 534 {
f4322df6 535 gtk_paint_focus( win->m_widget->style,
05d97538 536 gdk_window,
72be9a3a 537 state,
05d97538
RR
538 NULL,
539 win->m_wxwindow,
5a34b9b9
PC
540 // Detail "treeview" causes warning with GTK+ 2.12 Clearlooks theme:
541 // "... no property named `row-ending-details'"
542 // Using "treeview-middle" would fix the warning, but the right
543 // edge of the focus rect is not getting erased properly either.
544 // Better to not specify this detail unless the drawing is fixed.
545 NULL,
05d97538
RR
546 dc.LogicalToDeviceX(rect.x),
547 dc.LogicalToDeviceY(rect.y),
548 rect.width,
549 rect.height );
daebb44c
RR
550 }
551}
6d789987
JS
552
553void wxRendererGTK::DrawFocusRect(wxWindow* win, wxDC& dc, const wxRect& rect, int flags)
554{
7e717730 555 GdkWindow* gdk_window = wxGetGdkWindowForDC(dc);
6d789987
JS
556 wxASSERT_MSG( gdk_window,
557 wxT("cannot use wxRendererNative on wxDC of this type") );
558
559 GtkStateType state;
560 if (flags & wxCONTROL_SELECTED)
561 state = GTK_STATE_SELECTED;
562 else
563 state = GTK_STATE_NORMAL;
564
565 gtk_paint_focus( win->m_widget->style,
566 gdk_window,
567 state,
568 NULL,
569 win->m_wxwindow,
570 NULL,
571 dc.LogicalToDeviceX(rect.x),
572 dc.LogicalToDeviceY(rect.y),
573 rect.width,
574 rect.height );
575}
e4131985
KO
576
577// Uses the theme to draw the border and fill for something like a wxTextCtrl
7e717730 578void wxRendererGTK::DrawTextCtrl(wxWindow*, wxDC& dc, const wxRect& rect, int flags)
e4131985
KO
579{
580 GtkWidget *entry = wxGTKPrivate::GetTextEntryWidget();
581
7e717730 582 GdkWindow* gdk_window = wxGetGdkWindowForDC(dc);
e4131985
KO
583
584 GtkStateType state = GTK_STATE_NORMAL;
585 if ( flags & wxCONTROL_DISABLED )
586 state = GTK_STATE_INSENSITIVE;
587
588 if (flags & wxCONTROL_CURRENT )
589 GTK_WIDGET_SET_FLAGS( entry, GTK_HAS_FOCUS );
590 else
591 GTK_WIDGET_UNSET_FLAGS( entry, GTK_HAS_FOCUS );
592
593 gtk_paint_shadow
594 (
595 entry->style,
596 gdk_window,
597 state,
598 GTK_SHADOW_OUT,
599 NULL,
600 entry,
601 "entry",
602 dc.LogicalToDeviceX(rect.x),
603 dc.LogicalToDeviceY(rect.y),
604 rect.width,
605 rect.height
606 );
607}
608
609// Draw the equivallent of a wxComboBox
7e717730 610void wxRendererGTK::DrawComboBox(wxWindow*, wxDC& dc, const wxRect& rect, int flags)
e4131985
KO
611{
612 GtkWidget *combo = wxGTKPrivate::GetComboBoxWidget();
613
7e717730 614 GdkWindow* gdk_window = wxGetGdkWindowForDC(dc);
e4131985
KO
615
616 GtkStateType state = GTK_STATE_NORMAL;
617 if ( flags & wxCONTROL_DISABLED )
618 state = GTK_STATE_INSENSITIVE;
619
620 if (flags & wxCONTROL_CURRENT )
621 GTK_WIDGET_SET_FLAGS( combo, GTK_HAS_FOCUS );
622 else
623 GTK_WIDGET_UNSET_FLAGS( combo, GTK_HAS_FOCUS );
624
625 gtk_paint_shadow
626 (
627 combo->style,
628 gdk_window,
629 state,
630 GTK_SHADOW_OUT,
631 NULL,
632 combo,
633 "combobox",
634 dc.LogicalToDeviceX(rect.x),
635 dc.LogicalToDeviceY(rect.y),
636 rect.width,
637 rect.height
638 );
639
640 wxRect r = rect;
641 int extent = rect.height / 2;
642 r.x += rect.width - extent - extent/2;
643 r.y += extent/2;
644 r.width = extent;
645 r.height = extent;
646
647 gtk_paint_arrow
648 (
649 combo->style,
650 gdk_window,
651 state,
652 GTK_SHADOW_OUT,
653 NULL,
654 combo,
655 "arrow",
656 GTK_ARROW_DOWN,
657 TRUE,
658 dc.LogicalToDeviceX(r.x),
659 dc.LogicalToDeviceY(r.y),
660 r.width,
661 r.height
662 );
663
664 r = rect;
665 r.x += rect.width - 2*extent;
666 r.width = 2;
667
668 gtk_paint_box
669 (
670 combo->style,
671 gdk_window,
672 state,
673 GTK_SHADOW_ETCHED_OUT,
674 NULL,
675 combo,
676 "vseparator",
677 dc.LogicalToDeviceX(r.x),
678 dc.LogicalToDeviceY(r.y+1),
679 r.width,
680 r.height-2
681 );
682}
683
684
685void wxRendererGTK::DrawChoice(wxWindow* win, wxDC& dc,
686 const wxRect& rect, int flags)
687{
688 DrawComboBox( win, dc, rect, flags );
689}
690
691
692// Draw a themed radio button
7e717730 693void wxRendererGTK::DrawRadioButton(wxWindow*, wxDC& dc, const wxRect& rect, int flags)
e4131985
KO
694{
695 GtkWidget *button = wxGTKPrivate::GetRadioButtonWidget();
696
7e717730 697 GdkWindow* gdk_window = wxGetGdkWindowForDC(dc);
e4131985
KO
698
699 GtkShadowType shadow_type = GTK_SHADOW_OUT;
700 if ( flags & wxCONTROL_CHECKED )
701 shadow_type = GTK_SHADOW_IN;
702 else if ( flags & wxCONTROL_UNDETERMINED )
703 shadow_type = GTK_SHADOW_ETCHED_IN;
704
705 GtkStateType state = GTK_STATE_NORMAL;
706 if ( flags & wxCONTROL_DISABLED )
7e717730 707 state = GTK_STATE_INSENSITIVE;
e4131985 708 if ( flags & wxCONTROL_PRESSED )
7e717730 709 state = GTK_STATE_ACTIVE;
e4131985
KO
710/*
711 Don't know when to set this
712 state_type = GTK_STATE_PRELIGHT;
713*/
714
715 gtk_paint_option
716 (
717 button->style,
718 gdk_window,
719 state,
720 shadow_type,
721 NULL,
722 button,
723 "radiobutton",
724 dc.LogicalToDeviceX(rect.x),
725 dc.LogicalToDeviceY(rect.y),
726 rect.width, rect.height
727 );
728}