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