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