]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/renderer.cpp
don't access inexistent column in wxDataViewTreeCtrl::OnSize() (this bug also probabl...
[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
6d789987
JS
98 virtual void DrawFocusRect(wxWindow* win, wxDC& dc, const wxRect& rect, int flags = 0);
99
e8759560 100 virtual wxSize GetCheckBoxSize(wxWindow *win);
f1c09bed 101
e8759560 102 virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win);
9c7f49f5
VZ
103};
104
105// ============================================================================
106// implementation
107// ============================================================================
108
109/* static */
f0244295 110wxRendererNative& wxRendererNative::GetDefault()
9c7f49f5
VZ
111{
112 static wxRendererGTK s_rendererGTK;
113
114 return s_rendererGTK;
115}
116
d16cf3cd
VZ
117// ----------------------------------------------------------------------------
118// list/tree controls drawing
119// ----------------------------------------------------------------------------
120
c97c9952 121int
9c7f49f5
VZ
122wxRendererGTK::DrawHeaderButton(wxWindow *win,
123 wxDC& dc,
124 const wxRect& rect,
4b94ddc4 125 int flags,
80752b57 126 wxHeaderSortIconType sortArrow,
4b94ddc4 127 wxHeaderButtonParams* params)
9c7f49f5 128{
9b311923 129
e8759560 130 GtkWidget *button = wxGTKPrivate::GetHeaderButtonWidget();
f1c09bed 131
ab171e95
RR
132 GdkWindow* gdk_window = NULL;
133#if wxUSE_NEW_DC
888dde65
RR
134 wxDCImpl *impl = dc.GetImpl();
135 wxGTKDCImpl *gtk_impl = wxDynamicCast( impl, wxGTKDCImpl );
ab171e95
RR
136 if (gtk_impl)
137 gdk_window = gtk_impl->GetGDKWindow();
138#else
139 gdk_window = dc.GetGDKWindow();
140#endif
2e992e06
VZ
141 wxASSERT_MSG( gdk_window,
142 wxT("cannot use wxRendererNative on wxDC of this type") );
143
5eefe029
RR
144 int x_diff = 0;
145 if (win->GetLayoutDirection() == wxLayout_RightToLeft)
146 x_diff = rect.width;
f4322df6 147
1cfc4971
RR
148 GtkStateType state = GTK_STATE_NORMAL;
149 if (flags & wxCONTROL_DISABLED)
150 state = GTK_STATE_INSENSITIVE;
151 else
152 {
153 if (flags & wxCONTROL_CURRENT)
154 state = GTK_STATE_PRELIGHT;
155 }
156
9c7f49f5
VZ
157 gtk_paint_box
158 (
bc13e772 159 button->style,
2e992e06 160 gdk_window,
1cfc4971 161 state,
9c7f49f5 162 GTK_SHADOW_OUT,
38511687 163 NULL,
bc13e772 164 button,
9b311923 165 "button",
5eefe029 166 dc.LogicalToDeviceX(rect.x) - x_diff, rect.y, rect.width, rect.height
9c7f49f5 167 );
4b94ddc4 168
c97c9952 169 return DrawHeaderButtonContents(win, dc, rect, flags, sortArrow, params);
9c7f49f5
VZ
170}
171
9c7f49f5 172// draw a ">" or "v" button
9c7f49f5 173void
f8b043e7 174wxRendererGTK::DrawTreeItemButton(wxWindow* win,
9a0b7e33 175 wxDC& dc, const wxRect& rect, int flags)
9c7f49f5 176{
e8759560 177 GtkWidget *tree = wxGTKPrivate::GetTreeWidget();
f8b043e7 178
ab171e95
RR
179 GdkWindow* gdk_window = NULL;
180#if wxUSE_NEW_DC
888dde65
RR
181 wxDCImpl *impl = dc.GetImpl();
182 wxGTKDCImpl *gtk_impl = wxDynamicCast( impl, wxGTKDCImpl );
ab171e95
RR
183 if (gtk_impl)
184 gdk_window = gtk_impl->GetGDKWindow();
185#else
186 gdk_window = dc.GetGDKWindow();
187#endif
2e992e06
VZ
188 wxASSERT_MSG( gdk_window,
189 wxT("cannot use wxRendererNative on wxDC of this type") );
190
885dd597
RR
191 GtkStateType state;
192 if ( flags & wxCONTROL_CURRENT )
193 state = GTK_STATE_PRELIGHT;
194 else
195 state = GTK_STATE_NORMAL;
91af0895 196
428f4657
RR
197 int x_diff = 0;
198 if (win->GetLayoutDirection() == wxLayout_RightToLeft)
199 x_diff = rect.width;
2e992e06 200
bc13e772
VZ
201 // VZ: I don't know how to get the size of the expander so as to centre it
202 // in the given rectangle, +2/3 below is just what looks good here...
203 gtk_paint_expander
204 (
205 tree->style,
2e992e06 206 gdk_window,
885dd597 207 state,
bc13e772
VZ
208 NULL,
209 tree,
210 "treeview",
11012f47 211 dc.LogicalToDeviceX(rect.x) + 6 - x_diff,
bc13e772
VZ
212 dc.LogicalToDeviceY(rect.y) + 3,
213 flags & wxCONTROL_EXPANDED ? GTK_EXPANDER_EXPANDED
214 : GTK_EXPANDER_COLLAPSED
215 );
9c7f49f5
VZ
216}
217
9c7f49f5 218
d16cf3cd
VZ
219// ----------------------------------------------------------------------------
220// splitter sash drawing
221// ----------------------------------------------------------------------------
222
f1c09bed 223static int GetGtkSplitterFullSize(GtkWidget* widget)
38418827 224{
38418827 225 gint handle_size;
f1c09bed 226 gtk_widget_style_get(widget, "handle_size", &handle_size, NULL);
91af0895 227
38418827 228 return handle_size;
38418827
RR
229}
230
af99040c 231wxSplitterRenderParams
38418827 232wxRendererGTK::GetSplitterParams(const wxWindow *WXUNUSED(win))
d16cf3cd 233{
af99040c
VZ
234 // we don't draw any border, hence 0 for the second field
235 return wxSplitterRenderParams
236 (
e8759560 237 GetGtkSplitterFullSize(wxGTKPrivate::GetSplitterWidget()),
af99040c 238 0,
af99040c 239 true // hot sensitive
af99040c 240 );
d16cf3cd
VZ
241}
242
243void
244wxRendererGTK::DrawSplitterBorder(wxWindow * WXUNUSED(win),
245 wxDC& WXUNUSED(dc),
af99040c
VZ
246 const wxRect& WXUNUSED(rect),
247 int WXUNUSED(flags))
d16cf3cd
VZ
248{
249 // nothing to do
250}
95155e75 251
95155e75
VZ
252void
253wxRendererGTK::DrawSplitterSash(wxWindow *win,
254 wxDC& dc,
255 const wxSize& size,
d16cf3cd 256 wxCoord position,
af99040c 257 wxOrientation orient,
68567a96 258 int flags)
95155e75
VZ
259{
260 if ( !win->m_wxwindow->window )
261 {
0100b858 262 // window not realized yet
95155e75
VZ
263 return;
264 }
91af0895 265
ab171e95
RR
266 GdkWindow* gdk_window = NULL;
267#if wxUSE_NEW_DC
888dde65
RR
268 wxDCImpl *impl = dc.GetImpl();
269 wxGTKDCImpl *gtk_impl = wxDynamicCast( impl, wxGTKDCImpl );
ab171e95
RR
270 if (gtk_impl)
271 gdk_window = gtk_impl->GetGDKWindow();
272#else
273 gdk_window = dc.GetGDKWindow();
274#endif
2e992e06
VZ
275 wxASSERT_MSG( gdk_window,
276 wxT("cannot use wxRendererNative on wxDC of this type") );
277
e8759560 278 wxCoord full_size = GetGtkSplitterFullSize(wxGTKPrivate::GetSplitterWidget());
95155e75 279
d16cf3cd
VZ
280 // are we drawing vertical or horizontal splitter?
281 const bool isVert = orient == wxVERTICAL;
282
d16cf3cd 283 GdkRectangle rect;
91af0895 284
d16cf3cd
VZ
285 if ( isVert )
286 {
287 rect.x = position;
0100b858 288 rect.y = 0;
38418827 289 rect.width = full_size;
e4161a2a 290 rect.height = size.y;
d16cf3cd
VZ
291 }
292 else // horz
293 {
0100b858 294 rect.x = 0;
d16cf3cd 295 rect.y = position;
38418827 296 rect.height = full_size;
e4161a2a 297 rect.width = size.x;
d16cf3cd 298 }
f4322df6 299
847dfdb4
RR
300 int x_diff = 0;
301 if (win->GetLayoutDirection() == wxLayout_RightToLeft)
302 x_diff = rect.width;
35468934 303
af99040c
VZ
304 gtk_paint_handle
305 (
306 win->m_wxwindow->style,
2e992e06 307 gdk_window,
af99040c
VZ
308 flags & wxCONTROL_CURRENT ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL,
309 GTK_SHADOW_NONE,
310 NULL /* no clipping */,
311 win->m_wxwindow,
312 "paned",
847dfdb4
RR
313 dc.LogicalToDeviceX(rect.x) - x_diff,
314 dc.LogicalToDeviceY(rect.y),
af99040c
VZ
315 rect.width,
316 rect.height,
38418827 317 isVert ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL
af99040c 318 );
95155e75
VZ
319}
320
4c85ab75 321void
2e992e06 322wxRendererGTK::DrawDropArrow(wxWindow *WXUNUSED(win),
4c85ab75
VZ
323 wxDC& dc,
324 const wxRect& rect,
325 int flags)
38511687 326{
e8759560 327 GtkWidget *button = wxGTKPrivate::GetButtonWidget();
38511687 328
4c85ab75
VZ
329 // If we give GTK_PIZZA(win->m_wxwindow)->bin_window as
330 // a window for gtk_paint_xxx function, then it won't
331 // work for wxMemoryDC. So that is why we assume wxDC
332 // is wxWindowDC (wxClientDC, wxMemoryDC and wxPaintDC
333 // are derived from it) and use its m_window.
ab171e95
RR
334 GdkWindow* gdk_window = NULL;
335#if wxUSE_NEW_DC
888dde65
RR
336 wxDCImpl *impl = dc.GetImpl();
337 wxGTKDCImpl *gtk_impl = wxDynamicCast( impl, wxGTKDCImpl );
ab171e95
RR
338 if (gtk_impl)
339 gdk_window = gtk_impl->GetGDKWindow();
340#else
341 gdk_window = dc.GetGDKWindow();
342#endif
2e992e06
VZ
343 wxASSERT_MSG( gdk_window,
344 wxT("cannot use wxRendererNative on wxDC of this type") );
a4622f29 345
4c85ab75
VZ
346 // draw arrow so that there is even space horizontally
347 // on both sides
348 int arrowX = rect.width/4 + 1;
349 int arrowWidth = rect.width - (arrowX*2);
350
351 // scale arrow's height accoording to the width
352 int arrowHeight = rect.width/3;
353 int arrowY = (rect.height-arrowHeight)/2 +
354 ((rect.height-arrowHeight) & 1);
355
e1befae3 356 GtkStateType state;
a4622f29 357
3203621a
JS
358 if ( flags & wxCONTROL_PRESSED )
359 state = GTK_STATE_ACTIVE;
a4622f29
VZ
360 else if ( flags & wxCONTROL_DISABLED )
361 state = GTK_STATE_INSENSITIVE;
3203621a
JS
362 else if ( flags & wxCONTROL_CURRENT )
363 state = GTK_STATE_PRELIGHT;
e1befae3
VZ
364 else
365 state = GTK_STATE_NORMAL;
a4622f29 366
a4622f29 367 // draw arrow on button
a4622f29
VZ
368 gtk_paint_arrow
369 (
bc13e772 370 button->style,
2e992e06 371 gdk_window,
a4622f29 372 state,
e1befae3 373 flags & wxCONTROL_PRESSED ? GTK_SHADOW_IN : GTK_SHADOW_OUT,
a4622f29 374 NULL,
bc13e772 375 button,
a4622f29
VZ
376 "arrow",
377 GTK_ARROW_DOWN,
a8ac548e 378 FALSE,
4c85ab75
VZ
379 rect.x + arrowX,
380 rect.y + arrowY,
381 arrowWidth,
382 arrowHeight
a4622f29 383 );
38511687
VZ
384}
385
4c85ab75
VZ
386void
387wxRendererGTK::DrawComboBoxDropButton(wxWindow *win,
388 wxDC& dc,
389 const wxRect& rect,
390 int flags)
391{
2209baae
RR
392 DrawPushButton(win,dc,rect,flags);
393 DrawDropArrow(win,dc,rect);
394}
395
e8759560
VZ
396wxSize
397wxRendererGTK::GetCheckBoxSize(wxWindow *WXUNUSED(win))
398{
399 gint indicator_size, indicator_spacing;
400 gtk_widget_style_get(wxGTKPrivate::GetCheckButtonWidget(),
401 "indicator_size", &indicator_size,
402 "indicator_spacing", &indicator_spacing,
403 NULL);
404
405 int size = indicator_size + indicator_spacing * 2;
406 return wxSize(size, size);
407}
408
cdccdfab 409void
2e992e06 410wxRendererGTK::DrawCheckBox(wxWindow *WXUNUSED(win),
90b903c2
WS
411 wxDC& dc,
412 const wxRect& rect,
413 int flags )
2209baae 414{
e8759560 415 GtkWidget *button = wxGTKPrivate::GetCheckButtonWidget();
f1c09bed 416
ab171e95
RR
417 GdkWindow* gdk_window = NULL;
418#if wxUSE_NEW_DC
888dde65
RR
419 wxDCImpl *impl = dc.GetImpl();
420 wxGTKDCImpl *gtk_impl = wxDynamicCast( impl, wxGTKDCImpl );
ab171e95
RR
421 if (gtk_impl)
422 gdk_window = gtk_impl->GetGDKWindow();
423#else
424 gdk_window = dc.GetGDKWindow();
425#endif
2e992e06
VZ
426 wxASSERT_MSG( gdk_window,
427 wxT("cannot use wxRendererNative on wxDC of this type") );
90b903c2 428
e8759560
VZ
429 gint indicator_size, indicator_spacing;
430 gtk_widget_style_get(button,
431 "indicator_size", &indicator_size,
432 "indicator_spacing", &indicator_spacing,
433 NULL);
434
4c85ab75
VZ
435 GtkStateType state;
436
3203621a
JS
437 if ( flags & wxCONTROL_PRESSED )
438 state = GTK_STATE_ACTIVE;
4c85ab75
VZ
439 else if ( flags & wxCONTROL_DISABLED )
440 state = GTK_STATE_INSENSITIVE;
3203621a
JS
441 else if ( flags & wxCONTROL_CURRENT )
442 state = GTK_STATE_PRELIGHT;
4c85ab75
VZ
443 else
444 state = GTK_STATE_NORMAL;
90b903c2 445
2209baae 446 gtk_paint_check
4c85ab75
VZ
447 (
448 button->style,
2e992e06 449 gdk_window,
4c85ab75 450 state,
2209baae 451 flags & wxCONTROL_CHECKED ? GTK_SHADOW_IN : GTK_SHADOW_OUT,
4c85ab75
VZ
452 NULL,
453 button,
2209baae 454 "cellcheck",
e8759560
VZ
455 dc.LogicalToDeviceX(rect.x) + indicator_spacing,
456 dc.LogicalToDeviceY(rect.y) + indicator_spacing,
457 indicator_size, indicator_size
4c85ab75 458 );
4c85ab75
VZ
459}
460
2209baae 461void
2e992e06 462wxRendererGTK::DrawPushButton(wxWindow *WXUNUSED(win),
2209baae
RR
463 wxDC& dc,
464 const wxRect& rect,
465 int flags)
862d8041 466{
e8759560 467 GtkWidget *button = wxGTKPrivate::GetButtonWidget();
862d8041 468
ab171e95
RR
469 GdkWindow* gdk_window = NULL;
470#if wxUSE_NEW_DC
888dde65
RR
471 wxDCImpl *impl = dc.GetImpl();
472 wxGTKDCImpl *gtk_impl = wxDynamicCast( impl, wxGTKDCImpl );
ab171e95
RR
473 if (gtk_impl)
474 gdk_window = gtk_impl->GetGDKWindow();
475#else
476 gdk_window = dc.GetGDKWindow();
477#endif
2e992e06
VZ
478 wxASSERT_MSG( gdk_window,
479 wxT("cannot use wxRendererNative on wxDC of this type") );
2209baae
RR
480
481 // draw button
862d8041
RR
482 GtkStateType state;
483
484 if ( flags & wxCONTROL_PRESSED )
485 state = GTK_STATE_ACTIVE;
486 else if ( flags & wxCONTROL_DISABLED )
487 state = GTK_STATE_INSENSITIVE;
488 else if ( flags & wxCONTROL_CURRENT )
489 state = GTK_STATE_PRELIGHT;
490 else
491 state = GTK_STATE_NORMAL;
2209baae
RR
492
493 gtk_paint_box
862d8041
RR
494 (
495 button->style,
2e992e06 496 gdk_window,
862d8041 497 state,
2209baae 498 flags & wxCONTROL_PRESSED ? GTK_SHADOW_IN : GTK_SHADOW_OUT,
862d8041
RR
499 NULL,
500 button,
2209baae
RR
501 "button",
502 rect.x, rect.y, rect.width, rect.height
862d8041
RR
503 );
504}
daebb44c 505
cdccdfab 506void
daebb44c 507wxRendererGTK::DrawItemSelectionRect(wxWindow *win,
cdccdfab
WS
508 wxDC& dc,
509 const wxRect& rect,
510 int flags )
daebb44c 511{
ab171e95
RR
512 GdkWindow* gdk_window = NULL;
513#if wxUSE_NEW_DC
888dde65
RR
514 wxDCImpl *impl = dc.GetImpl();
515 wxGTKDCImpl *gtk_impl = wxDynamicCast( impl, wxGTKDCImpl );
ab171e95
RR
516 if (gtk_impl)
517 gdk_window = gtk_impl->GetGDKWindow();
518#else
519 gdk_window = dc.GetGDKWindow();
520#endif
2e992e06
VZ
521 wxASSERT_MSG( gdk_window,
522 wxT("cannot use wxRendererNative on wxDC of this type") );
523
08f57d21
RR
524 int x_diff = 0;
525 if (win->GetLayoutDirection() == wxLayout_RightToLeft)
526 x_diff = rect.width;
527
daebb44c 528 GtkStateType state;
90b903c2 529 if (flags & wxCONTROL_SELECTED)
daebb44c 530 {
05d97538
RR
531 // the wxCONTROL_FOCUSED state is deduced
532 // directly from the m_wxwindow by GTK+
533 state = GTK_STATE_SELECTED;
daebb44c 534
05d97538 535 gtk_paint_flat_box( win->m_widget->style,
2e992e06 536 gdk_window,
daebb44c
RR
537 state,
538 GTK_SHADOW_NONE,
cdccdfab 539 NULL,
daebb44c 540 win->m_wxwindow,
05d97538 541 "cell_even",
08f57d21 542 dc.LogicalToDeviceX(rect.x) - x_diff,
daebb44c
RR
543 dc.LogicalToDeviceY(rect.y),
544 rect.width,
545 rect.height );
546 }
72be9a3a
VZ
547 else // !wxCONTROL_SELECTED
548 {
549 state = GTK_STATE_NORMAL;
550 }
90b903c2 551
ce0cf2b8 552 if ((flags & wxCONTROL_CURRENT) && (flags & wxCONTROL_FOCUSED))
daebb44c 553 {
f4322df6 554 gtk_paint_focus( win->m_widget->style,
05d97538 555 gdk_window,
72be9a3a 556 state,
05d97538
RR
557 NULL,
558 win->m_wxwindow,
5a34b9b9
PC
559 // Detail "treeview" causes warning with GTK+ 2.12 Clearlooks theme:
560 // "... no property named `row-ending-details'"
561 // Using "treeview-middle" would fix the warning, but the right
562 // edge of the focus rect is not getting erased properly either.
563 // Better to not specify this detail unless the drawing is fixed.
564 NULL,
05d97538
RR
565 dc.LogicalToDeviceX(rect.x),
566 dc.LogicalToDeviceY(rect.y),
567 rect.width,
568 rect.height );
daebb44c
RR
569 }
570}
6d789987
JS
571
572void wxRendererGTK::DrawFocusRect(wxWindow* win, wxDC& dc, const wxRect& rect, int flags)
573{
ab171e95
RR
574 GdkWindow* gdk_window = NULL;
575#if wxUSE_NEW_DC
888dde65
RR
576 wxDCImpl *impl = dc.GetImpl();
577 wxGTKDCImpl *gtk_impl = wxDynamicCast( impl, wxGTKDCImpl );
ab171e95
RR
578 if (gtk_impl)
579 gdk_window = gtk_impl->GetGDKWindow();
580#else
581 gdk_window = dc.GetGDKWindow();
582#endif
6d789987
JS
583 wxASSERT_MSG( gdk_window,
584 wxT("cannot use wxRendererNative on wxDC of this type") );
585
586 GtkStateType state;
587 if (flags & wxCONTROL_SELECTED)
588 state = GTK_STATE_SELECTED;
589 else
590 state = GTK_STATE_NORMAL;
591
592 gtk_paint_focus( win->m_widget->style,
593 gdk_window,
594 state,
595 NULL,
596 win->m_wxwindow,
597 NULL,
598 dc.LogicalToDeviceX(rect.x),
599 dc.LogicalToDeviceY(rect.y),
600 rect.width,
601 rect.height );
602}