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