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