]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/renderer.cpp
Change wxNotebook selection before sending page changed event in wxMSW.
[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
bc13e772
VZ
259 // VZ: I don't know how to get the size of the expander so as to centre it
260 // in the given rectangle, +2/3 below is just what looks good here...
261 gtk_paint_expander
262 (
385e8575 263 gtk_widget_get_style(tree),
2e992e06 264 gdk_window,
885dd597 265 state,
bc13e772
VZ
266 NULL,
267 tree,
268 "treeview",
11012f47 269 dc.LogicalToDeviceX(rect.x) + 6 - x_diff,
bc13e772
VZ
270 dc.LogicalToDeviceY(rect.y) + 3,
271 flags & wxCONTROL_EXPANDED ? GTK_EXPANDER_EXPANDED
272 : GTK_EXPANDER_COLLAPSED
273 );
9c7f49f5
VZ
274}
275
9c7f49f5 276
d16cf3cd
VZ
277// ----------------------------------------------------------------------------
278// splitter sash drawing
279// ----------------------------------------------------------------------------
280
f1c09bed 281static int GetGtkSplitterFullSize(GtkWidget* widget)
38418827 282{
38418827 283 gint handle_size;
f1c09bed 284 gtk_widget_style_get(widget, "handle_size", &handle_size, NULL);
91af0895 285
38418827 286 return handle_size;
38418827
RR
287}
288
af99040c 289wxSplitterRenderParams
38418827 290wxRendererGTK::GetSplitterParams(const wxWindow *WXUNUSED(win))
d16cf3cd 291{
af99040c
VZ
292 // we don't draw any border, hence 0 for the second field
293 return wxSplitterRenderParams
294 (
e8759560 295 GetGtkSplitterFullSize(wxGTKPrivate::GetSplitterWidget()),
af99040c 296 0,
af99040c 297 true // hot sensitive
af99040c 298 );
d16cf3cd
VZ
299}
300
301void
302wxRendererGTK::DrawSplitterBorder(wxWindow * WXUNUSED(win),
303 wxDC& WXUNUSED(dc),
af99040c
VZ
304 const wxRect& WXUNUSED(rect),
305 int WXUNUSED(flags))
d16cf3cd
VZ
306{
307 // nothing to do
308}
95155e75 309
95155e75 310void
02f07b19 311wxRendererGTK::DrawSplitterSash(wxWindow* win,
95155e75
VZ
312 wxDC& dc,
313 const wxSize& size,
d16cf3cd 314 wxCoord position,
af99040c 315 wxOrientation orient,
68567a96 316 int flags)
95155e75 317{
385e8575 318 if (gtk_widget_get_window(win->m_wxwindow) == NULL)
95155e75 319 {
0100b858 320 // window not realized yet
95155e75
VZ
321 return;
322 }
91af0895 323
02f07b19 324 GdkWindow* gdk_window = wxGetGdkWindowForDC(win, dc);
2e992e06
VZ
325 wxASSERT_MSG( gdk_window,
326 wxT("cannot use wxRendererNative on wxDC of this type") );
327
e8759560 328 wxCoord full_size = GetGtkSplitterFullSize(wxGTKPrivate::GetSplitterWidget());
95155e75 329
d16cf3cd
VZ
330 // are we drawing vertical or horizontal splitter?
331 const bool isVert = orient == wxVERTICAL;
332
d16cf3cd 333 GdkRectangle rect;
91af0895 334
d16cf3cd
VZ
335 if ( isVert )
336 {
337 rect.x = position;
0100b858 338 rect.y = 0;
38418827 339 rect.width = full_size;
e4161a2a 340 rect.height = size.y;
d16cf3cd
VZ
341 }
342 else // horz
343 {
0100b858 344 rect.x = 0;
d16cf3cd 345 rect.y = position;
38418827 346 rect.height = full_size;
e4161a2a 347 rect.width = size.x;
d16cf3cd 348 }
f4322df6 349
847dfdb4
RR
350 int x_diff = 0;
351 if (win->GetLayoutDirection() == wxLayout_RightToLeft)
352 x_diff = rect.width;
35468934 353
af99040c
VZ
354 gtk_paint_handle
355 (
385e8575 356 gtk_widget_get_style(win->m_wxwindow),
2e992e06 357 gdk_window,
af99040c
VZ
358 flags & wxCONTROL_CURRENT ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL,
359 GTK_SHADOW_NONE,
360 NULL /* no clipping */,
361 win->m_wxwindow,
362 "paned",
847dfdb4
RR
363 dc.LogicalToDeviceX(rect.x) - x_diff,
364 dc.LogicalToDeviceY(rect.y),
af99040c
VZ
365 rect.width,
366 rect.height,
38418827 367 isVert ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL
af99040c 368 );
95155e75
VZ
369}
370
4c85ab75 371void
02f07b19 372wxRendererGTK::DrawDropArrow(wxWindow* win,
4c85ab75
VZ
373 wxDC& dc,
374 const wxRect& rect,
375 int flags)
38511687 376{
e8759560 377 GtkWidget *button = wxGTKPrivate::GetButtonWidget();
38511687 378
02f07b19 379 // If we give WX_PIZZA(win->m_wxwindow)->bin_window as
4c85ab75
VZ
380 // a window for gtk_paint_xxx function, then it won't
381 // work for wxMemoryDC. So that is why we assume wxDC
382 // is wxWindowDC (wxClientDC, wxMemoryDC and wxPaintDC
383 // are derived from it) and use its m_window.
02f07b19 384 GdkWindow* gdk_window = wxGetGdkWindowForDC(win, dc);
2e992e06
VZ
385 wxASSERT_MSG( gdk_window,
386 wxT("cannot use wxRendererNative on wxDC of this type") );
a4622f29 387
4c85ab75
VZ
388 // draw arrow so that there is even space horizontally
389 // on both sides
390 int arrowX = rect.width/4 + 1;
391 int arrowWidth = rect.width - (arrowX*2);
392
393 // scale arrow's height accoording to the width
394 int arrowHeight = rect.width/3;
395 int arrowY = (rect.height-arrowHeight)/2 +
396 ((rect.height-arrowHeight) & 1);
397
e1befae3 398 GtkStateType state;
a4622f29 399
3203621a
JS
400 if ( flags & wxCONTROL_PRESSED )
401 state = GTK_STATE_ACTIVE;
a4622f29
VZ
402 else if ( flags & wxCONTROL_DISABLED )
403 state = GTK_STATE_INSENSITIVE;
3203621a
JS
404 else if ( flags & wxCONTROL_CURRENT )
405 state = GTK_STATE_PRELIGHT;
e1befae3
VZ
406 else
407 state = GTK_STATE_NORMAL;
a4622f29 408
a4622f29 409 // draw arrow on button
a4622f29
VZ
410 gtk_paint_arrow
411 (
385e8575 412 gtk_widget_get_style(button),
2e992e06 413 gdk_window,
a4622f29 414 state,
e1befae3 415 flags & wxCONTROL_PRESSED ? GTK_SHADOW_IN : GTK_SHADOW_OUT,
a4622f29 416 NULL,
bc13e772 417 button,
a4622f29
VZ
418 "arrow",
419 GTK_ARROW_DOWN,
a8ac548e 420 FALSE,
4c85ab75
VZ
421 rect.x + arrowX,
422 rect.y + arrowY,
423 arrowWidth,
424 arrowHeight
a4622f29 425 );
38511687
VZ
426}
427
4c85ab75
VZ
428void
429wxRendererGTK::DrawComboBoxDropButton(wxWindow *win,
430 wxDC& dc,
431 const wxRect& rect,
432 int flags)
433{
2209baae
RR
434 DrawPushButton(win,dc,rect,flags);
435 DrawDropArrow(win,dc,rect);
436}
437
e8759560 438wxSize
191e43fd 439wxRendererGTK::GetCheckBoxSize(wxWindow *WXUNUSED(win))
e8759560
VZ
440{
441 gint indicator_size, indicator_spacing;
442 gtk_widget_style_get(wxGTKPrivate::GetCheckButtonWidget(),
443 "indicator_size", &indicator_size,
444 "indicator_spacing", &indicator_spacing,
445 NULL);
446
447 int size = indicator_size + indicator_spacing * 2;
448 return wxSize(size, size);
449}
450
cdccdfab 451void
02f07b19 452wxRendererGTK::DrawCheckBox(wxWindow* win,
90b903c2
WS
453 wxDC& dc,
454 const wxRect& rect,
455 int flags )
2209baae 456{
e8759560 457 GtkWidget *button = wxGTKPrivate::GetCheckButtonWidget();
f1c09bed 458
02f07b19 459 GdkWindow* gdk_window = wxGetGdkWindowForDC(win, dc);
2e992e06
VZ
460 wxASSERT_MSG( gdk_window,
461 wxT("cannot use wxRendererNative on wxDC of this type") );
90b903c2 462
e8759560
VZ
463 gint indicator_size, indicator_spacing;
464 gtk_widget_style_get(button,
465 "indicator_size", &indicator_size,
466 "indicator_spacing", &indicator_spacing,
467 NULL);
468
4c85ab75
VZ
469 GtkStateType state;
470
3203621a
JS
471 if ( flags & wxCONTROL_PRESSED )
472 state = GTK_STATE_ACTIVE;
4c85ab75
VZ
473 else if ( flags & wxCONTROL_DISABLED )
474 state = GTK_STATE_INSENSITIVE;
3203621a
JS
475 else if ( flags & wxCONTROL_CURRENT )
476 state = GTK_STATE_PRELIGHT;
4c85ab75
VZ
477 else
478 state = GTK_STATE_NORMAL;
90b903c2 479
e78778c8
RR
480 GtkShadowType shadow_type;
481
482 if ( flags & wxCONTROL_UNDETERMINED )
483 shadow_type = GTK_SHADOW_ETCHED_IN;
484 else if ( flags & wxCONTROL_CHECKED )
485 shadow_type = GTK_SHADOW_IN;
486 else
487 shadow_type = GTK_SHADOW_OUT;
488
2209baae 489 gtk_paint_check
4c85ab75 490 (
385e8575 491 gtk_widget_get_style(button),
2e992e06 492 gdk_window,
4c85ab75 493 state,
e78778c8 494 shadow_type,
4c85ab75
VZ
495 NULL,
496 button,
2209baae 497 "cellcheck",
e8759560
VZ
498 dc.LogicalToDeviceX(rect.x) + indicator_spacing,
499 dc.LogicalToDeviceY(rect.y) + indicator_spacing,
500 indicator_size, indicator_size
4c85ab75 501 );
4c85ab75
VZ
502}
503
2209baae 504void
02f07b19 505wxRendererGTK::DrawPushButton(wxWindow* win,
2209baae
RR
506 wxDC& dc,
507 const wxRect& rect,
508 int flags)
862d8041 509{
e8759560 510 GtkWidget *button = wxGTKPrivate::GetButtonWidget();
862d8041 511
02f07b19 512 GdkWindow* gdk_window = wxGetGdkWindowForDC(win, dc);
2e992e06
VZ
513 wxASSERT_MSG( gdk_window,
514 wxT("cannot use wxRendererNative on wxDC of this type") );
2209baae
RR
515
516 // draw button
862d8041
RR
517 GtkStateType state;
518
519 if ( flags & wxCONTROL_PRESSED )
520 state = GTK_STATE_ACTIVE;
521 else if ( flags & wxCONTROL_DISABLED )
522 state = GTK_STATE_INSENSITIVE;
523 else if ( flags & wxCONTROL_CURRENT )
524 state = GTK_STATE_PRELIGHT;
525 else
526 state = GTK_STATE_NORMAL;
2209baae
RR
527
528 gtk_paint_box
862d8041 529 (
385e8575 530 gtk_widget_get_style(button),
2e992e06 531 gdk_window,
862d8041 532 state,
2209baae 533 flags & wxCONTROL_PRESSED ? GTK_SHADOW_IN : GTK_SHADOW_OUT,
862d8041
RR
534 NULL,
535 button,
2209baae 536 "button",
99c4be68
VZ
537 dc.LogicalToDeviceX(rect.x),
538 dc.LogicalToDeviceY(rect.y),
539 rect.width,
e4131985 540 rect.height
862d8041
RR
541 );
542}
daebb44c 543
cdccdfab 544void
02f07b19 545wxRendererGTK::DrawItemSelectionRect(wxWindow* win,
cdccdfab
WS
546 wxDC& dc,
547 const wxRect& rect,
548 int flags )
daebb44c 549{
02f07b19 550 GdkWindow* gdk_window = wxGetGdkWindowForDC(win, dc);
2e992e06
VZ
551 wxASSERT_MSG( gdk_window,
552 wxT("cannot use wxRendererNative on wxDC of this type") );
553
90b903c2 554 if (flags & wxCONTROL_SELECTED)
daebb44c 555 {
c70ad287
VZ
556 int x_diff = 0;
557 if (win->GetLayoutDirection() == wxLayout_RightToLeft)
558 x_diff = rect.width;
559
05d97538
RR
560 // the wxCONTROL_FOCUSED state is deduced
561 // directly from the m_wxwindow by GTK+
385e8575 562 gtk_paint_flat_box(gtk_widget_get_style(wxGTKPrivate::GetTreeWidget()),
2e992e06 563 gdk_window,
c70ad287 564 GTK_STATE_SELECTED,
daebb44c 565 GTK_SHADOW_NONE,
cdccdfab 566 NULL,
daebb44c 567 win->m_wxwindow,
05d97538 568 "cell_even",
08f57d21 569 dc.LogicalToDeviceX(rect.x) - x_diff,
daebb44c
RR
570 dc.LogicalToDeviceY(rect.y),
571 rect.width,
572 rect.height );
573 }
90b903c2 574
ce0cf2b8 575 if ((flags & wxCONTROL_CURRENT) && (flags & wxCONTROL_FOCUSED))
c70ad287 576 DrawFocusRect(win, dc, rect, flags);
daebb44c 577}
6d789987
JS
578
579void wxRendererGTK::DrawFocusRect(wxWindow* win, wxDC& dc, const wxRect& rect, int flags)
580{
02f07b19 581 GdkWindow* gdk_window = wxGetGdkWindowForDC(win, dc);
6d789987
JS
582 wxASSERT_MSG( gdk_window,
583 wxT("cannot use wxRendererNative on wxDC of this type") );
584
585 GtkStateType state;
586 if (flags & wxCONTROL_SELECTED)
587 state = GTK_STATE_SELECTED;
588 else
589 state = GTK_STATE_NORMAL;
590
385e8575 591 gtk_paint_focus( gtk_widget_get_style(win->m_widget),
6d789987
JS
592 gdk_window,
593 state,
594 NULL,
595 win->m_wxwindow,
596 NULL,
597 dc.LogicalToDeviceX(rect.x),
598 dc.LogicalToDeviceY(rect.y),
599 rect.width,
600 rect.height );
601}
e4131985
KO
602
603// Uses the theme to draw the border and fill for something like a wxTextCtrl
02f07b19 604void wxRendererGTK::DrawTextCtrl(wxWindow* win, wxDC& dc, const wxRect& rect, int flags)
e4131985
KO
605{
606 GtkWidget *entry = wxGTKPrivate::GetTextEntryWidget();
607
02f07b19 608 GdkWindow* gdk_window = wxGetGdkWindowForDC(win, dc);
e4131985
KO
609
610 GtkStateType state = GTK_STATE_NORMAL;
611 if ( flags & wxCONTROL_DISABLED )
612 state = GTK_STATE_INSENSITIVE;
99c4be68 613
385e8575 614 gtk_widget_set_can_focus(entry, (flags & wxCONTROL_CURRENT) != 0);
e4131985
KO
615
616 gtk_paint_shadow
617 (
385e8575 618 gtk_widget_get_style(entry),
e4131985
KO
619 gdk_window,
620 state,
621 GTK_SHADOW_OUT,
622 NULL,
623 entry,
624 "entry",
625 dc.LogicalToDeviceX(rect.x),
626 dc.LogicalToDeviceY(rect.y),
627 rect.width,
99c4be68 628 rect.height
e4131985
KO
629 );
630}
631
4c51a665 632// Draw the equivalent of a wxComboBox
02f07b19 633void wxRendererGTK::DrawComboBox(wxWindow* win, wxDC& dc, const wxRect& rect, int flags)
e4131985
KO
634{
635 GtkWidget *combo = wxGTKPrivate::GetComboBoxWidget();
636
02f07b19 637 GdkWindow* gdk_window = wxGetGdkWindowForDC(win, dc);
e4131985
KO
638
639 GtkStateType state = GTK_STATE_NORMAL;
640 if ( flags & wxCONTROL_DISABLED )
641 state = GTK_STATE_INSENSITIVE;
99c4be68 642
385e8575 643 gtk_widget_set_can_focus(combo, (flags & wxCONTROL_CURRENT) != 0);
e4131985
KO
644
645 gtk_paint_shadow
646 (
385e8575 647 gtk_widget_get_style(combo),
e4131985
KO
648 gdk_window,
649 state,
650 GTK_SHADOW_OUT,
651 NULL,
652 combo,
653 "combobox",
654 dc.LogicalToDeviceX(rect.x),
655 dc.LogicalToDeviceY(rect.y),
656 rect.width,
99c4be68 657 rect.height
e4131985
KO
658 );
659
660 wxRect r = rect;
661 int extent = rect.height / 2;
662 r.x += rect.width - extent - extent/2;
663 r.y += extent/2;
664 r.width = extent;
665 r.height = extent;
666
667 gtk_paint_arrow
668 (
385e8575 669 gtk_widget_get_style(combo),
e4131985
KO
670 gdk_window,
671 state,
672 GTK_SHADOW_OUT,
673 NULL,
674 combo,
675 "arrow",
676 GTK_ARROW_DOWN,
677 TRUE,
678 dc.LogicalToDeviceX(r.x),
679 dc.LogicalToDeviceY(r.y),
680 r.width,
681 r.height
682 );
683
684 r = rect;
685 r.x += rect.width - 2*extent;
686 r.width = 2;
687
688 gtk_paint_box
689 (
385e8575 690 gtk_widget_get_style(combo),
e4131985
KO
691 gdk_window,
692 state,
693 GTK_SHADOW_ETCHED_OUT,
694 NULL,
695 combo,
696 "vseparator",
697 dc.LogicalToDeviceX(r.x),
698 dc.LogicalToDeviceY(r.y+1),
699 r.width,
700 r.height-2
701 );
702}
703
704
705void wxRendererGTK::DrawChoice(wxWindow* win, wxDC& dc,
706 const wxRect& rect, int flags)
707{
708 DrawComboBox( win, dc, rect, flags );
709}
710
99c4be68 711
e4131985 712// Draw a themed radio button
6e6b532c 713void wxRendererGTK::DrawRadioBitmap(wxWindow* win, wxDC& dc, const wxRect& rect, int flags)
e4131985
KO
714{
715 GtkWidget *button = wxGTKPrivate::GetRadioButtonWidget();
716
02f07b19 717 GdkWindow* gdk_window = wxGetGdkWindowForDC(win, dc);
99c4be68 718
e4131985
KO
719 GtkShadowType shadow_type = GTK_SHADOW_OUT;
720 if ( flags & wxCONTROL_CHECKED )
721 shadow_type = GTK_SHADOW_IN;
722 else if ( flags & wxCONTROL_UNDETERMINED )
723 shadow_type = GTK_SHADOW_ETCHED_IN;
99c4be68 724
e4131985
KO
725 GtkStateType state = GTK_STATE_NORMAL;
726 if ( flags & wxCONTROL_DISABLED )
7e717730 727 state = GTK_STATE_INSENSITIVE;
e4131985 728 if ( flags & wxCONTROL_PRESSED )
7e717730 729 state = GTK_STATE_ACTIVE;
e4131985
KO
730/*
731 Don't know when to set this
732 state_type = GTK_STATE_PRELIGHT;
733*/
734
735 gtk_paint_option
736 (
385e8575 737 gtk_widget_get_style(button),
e4131985
KO
738 gdk_window,
739 state,
740 shadow_type,
741 NULL,
742 button,
743 "radiobutton",
99c4be68
VZ
744 dc.LogicalToDeviceX(rect.x),
745 dc.LogicalToDeviceY(rect.y),
e4131985
KO
746 rect.width, rect.height
747 );
748}