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