~brian-sidebotham/wxwidgets-cmake/wxpython-2.9.4

« back to all changes in this revision

Viewing changes to src/msw/renderer.cpp

  • Committer: Brian Sidebotham
  • Date: 2013-08-03 14:30:08 UTC
  • Revision ID: brian.sidebotham@gmail.com-20130803143008-c7806tkych1tp6fc
Initial import into Bazaar

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
///////////////////////////////////////////////////////////////////////////////
 
2
// Name:        src/msw/renderer.cpp
 
3
// Purpose:     implementation of wxRendererNative for Windows
 
4
// Author:      Vadim Zeitlin
 
5
// Modified by:
 
6
// Created:     20.07.2003
 
7
// RCS-ID:      $Id: renderer.cpp 71569 2012-05-26 12:29:46Z VZ $
 
8
// Copyright:   (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
 
9
// Licence:     wxWindows licence
 
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
 
 
27
#ifndef WX_PRECOMP
 
28
    #include "wx/string.h"
 
29
    #include "wx/window.h"
 
30
    #include "wx/dc.h"
 
31
    #include "wx/settings.h"
 
32
#endif //WX_PRECOMP
 
33
 
 
34
#include "wx/dcgraph.h"
 
35
#include "wx/scopeguard.h"
 
36
#include "wx/splitter.h"
 
37
#include "wx/renderer.h"
 
38
#include "wx/msw/private.h"
 
39
#include "wx/msw/uxtheme.h"
 
40
 
 
41
// tmschema.h is in Win32 Platform SDK and might not be available with earlier
 
42
// compilers
 
43
#ifndef CP_DROPDOWNBUTTON
 
44
    #define BP_PUSHBUTTON      1
 
45
    #define BP_RADIOBUTTON     2
 
46
    #define BP_CHECKBOX        3
 
47
    #define RBS_UNCHECKEDNORMAL 1
 
48
    #define RBS_CHECKEDNORMAL   (RBS_UNCHECKEDNORMAL + 4)
 
49
    #define RBS_MIXEDNORMAL     (RBS_CHECKEDNORMAL + 4)
 
50
    #define CBS_UNCHECKEDNORMAL 1
 
51
    #define CBS_CHECKEDNORMAL   (CBS_UNCHECKEDNORMAL + 4)
 
52
    #define CBS_MIXEDNORMAL     (CBS_CHECKEDNORMAL + 4)
 
53
 
 
54
    #define PBS_NORMAL          1
 
55
    #define PBS_HOT             2
 
56
    #define PBS_PRESSED         3
 
57
    #define PBS_DISABLED        4
 
58
    #define PBS_DEFAULTED       5
 
59
 
 
60
    #define CP_DROPDOWNBUTTON  1
 
61
 
 
62
    #define CBXS_NORMAL        1
 
63
    #define CBXS_HOT           2
 
64
    #define CBXS_PRESSED       3
 
65
    #define CBXS_DISABLED      4
 
66
 
 
67
    #define TVP_GLYPH           2
 
68
 
 
69
    #define GLPS_CLOSED         1
 
70
    #define GLPS_OPENED         2
 
71
 
 
72
    #define HP_HEADERITEM       1
 
73
 
 
74
    #define HIS_NORMAL          1
 
75
    #define HIS_HOT             2
 
76
    #define HIS_PRESSED         3
 
77
 
 
78
    #define TMT_HEIGHT          2417
 
79
 
 
80
    #define HP_HEADERSORTARROW  4
 
81
    #define HSAS_SORTEDUP       1
 
82
    #define HSAS_SORTEDDOWN     2
 
83
 
 
84
    #define EP_EDITTEXT         1
 
85
    #define ETS_NORMAL          1
 
86
    #define ETS_HOT             2
 
87
    #define ETS_SELECTED        3
 
88
    #define ETS_DISABLED        4
 
89
    #define ETS_FOCUSED         5
 
90
    #define ETS_READONLY        6
 
91
    #define ETS_ASSIST          7
 
92
    #define TMT_FILLCOLOR       3802
 
93
    #define TMT_TEXTCOLOR       3803
 
94
    #define TMT_BORDERCOLOR     3801
 
95
    #define TMT_EDGEFILLCOLOR   3808
 
96
 
 
97
    #define WP_MINBUTTON 15
 
98
    #define WP_MAXBUTTON 17
 
99
    #define WP_CLOSEBUTTON 18
 
100
    #define WP_RESTOREBUTTON 21
 
101
    #define WP_HELPBUTTON 23
 
102
#endif
 
103
 
 
104
#if defined(__WXWINCE__)
 
105
    #ifndef DFCS_FLAT
 
106
        #define DFCS_FLAT 0
 
107
    #endif
 
108
    #ifndef DFCS_MONO
 
109
        #define DFCS_MONO 0
 
110
    #endif
 
111
#endif
 
112
 
 
113
#ifndef DFCS_HOT
 
114
    #define DFCS_HOT 0x1000
 
115
#endif
 
116
 
 
117
// ----------------------------------------------------------------------------
 
118
// methods common to wxRendererMSW and wxRendererXP
 
119
// ----------------------------------------------------------------------------
 
120
 
 
121
class wxRendererMSWBase : public wxDelegateRendererNative
 
122
{
 
123
public:
 
124
    wxRendererMSWBase() { }
 
125
    wxRendererMSWBase(wxRendererNative& rendererNative)
 
126
        : wxDelegateRendererNative(rendererNative) { }
 
127
 
 
128
    void DrawFocusRect(wxWindow * win,
 
129
                        wxDC& dc,
 
130
                        const wxRect& rect,
 
131
                        int flags = 0);
 
132
 
 
133
    void DrawItemSelectionRect(wxWindow *win,
 
134
                                wxDC& dc,
 
135
                                const wxRect& rect,
 
136
                                int flags = 0);
 
137
 
 
138
    void DrawChoice(wxWindow* win,
 
139
                     wxDC& dc,
 
140
                     const wxRect& rect,
 
141
                     int flags = 0);
 
142
 
 
143
    void DrawComboBox(wxWindow* win,
 
144
                       wxDC& dc,
 
145
                       const wxRect& rect,
 
146
                       int flags = 0);
 
147
 
 
148
    virtual void DrawComboBoxDropButton(wxWindow *win,
 
149
                                         wxDC& dc,
 
150
                                         const wxRect& rect,
 
151
                                         int flags = 0) = 0;
 
152
 
 
153
    virtual void DrawTextCtrl(wxWindow* win,
 
154
                               wxDC& dc,
 
155
                               const wxRect& rect,
 
156
                               int flags = 0) = 0;
 
157
};
 
158
 
 
159
// ----------------------------------------------------------------------------
 
160
// wxRendererMSW: wxRendererNative implementation for "old" Win32 systems
 
161
// ----------------------------------------------------------------------------
 
162
 
 
163
class wxRendererMSW : public wxRendererMSWBase
 
164
{
 
165
public:
 
166
    wxRendererMSW() { }
 
167
 
 
168
    static wxRendererNative& Get();
 
169
 
 
170
    virtual void DrawComboBoxDropButton(wxWindow *win,
 
171
                                        wxDC& dc,
 
172
                                        const wxRect& rect,
 
173
                                        int flags = 0);
 
174
 
 
175
    virtual void DrawCheckBox(wxWindow *win,
 
176
                              wxDC& dc,
 
177
                              const wxRect& rect,
 
178
                              int flags = 0)
 
179
    {
 
180
        DoDrawButton(DFCS_BUTTONCHECK, win, dc, rect, flags);
 
181
    }
 
182
 
 
183
    virtual void DrawPushButton(wxWindow *win,
 
184
                                wxDC& dc,
 
185
                                const wxRect& rect,
 
186
                                int flags = 0);
 
187
 
 
188
    virtual void DrawTextCtrl(wxWindow* win,
 
189
                              wxDC& dc,
 
190
                              const wxRect& rect,
 
191
                              int flags = 0);
 
192
 
 
193
    virtual void DrawRadioBitmap(wxWindow* win,
 
194
                                 wxDC& dc,
 
195
                                 const wxRect& rect,
 
196
                                 int flags = 0)
 
197
    {
 
198
        DoDrawButton(DFCS_BUTTONRADIO, win, dc, rect, flags);
 
199
    }
 
200
 
 
201
    virtual void DrawTitleBarBitmap(wxWindow *win,
 
202
                                    wxDC& dc,
 
203
                                    const wxRect& rect,
 
204
                                    wxTitleBarButton button,
 
205
                                    int flags = 0);
 
206
 
 
207
    virtual wxSize GetCheckBoxSize(wxWindow *win);
 
208
 
 
209
    virtual int GetHeaderButtonHeight(wxWindow *win);
 
210
 
 
211
    virtual int GetHeaderButtonMargin(wxWindow *win);
 
212
 
 
213
private:
 
214
    // wrapper of DrawFrameControl()
 
215
    void DoDrawFrameControl(UINT type,
 
216
                            UINT kind,
 
217
                            wxWindow *win,
 
218
                            wxDC& dc,
 
219
                            const wxRect& rect,
 
220
                            int flags);
 
221
 
 
222
    // common part of Draw{PushButton,CheckBox,RadioBitmap}(): wraps
 
223
    // DrawFrameControl(DFC_BUTTON)
 
224
    void DoDrawButton(UINT kind,
 
225
                      wxWindow *win,
 
226
                      wxDC& dc,
 
227
                      const wxRect& rect,
 
228
                      int flags)
 
229
    {
 
230
        DoDrawFrameControl(DFC_BUTTON, kind, win, dc, rect, flags);
 
231
    }
 
232
 
 
233
    wxDECLARE_NO_COPY_CLASS(wxRendererMSW);
 
234
};
 
235
 
 
236
// ----------------------------------------------------------------------------
 
237
// wxRendererXP: wxRendererNative implementation for Windows XP and later
 
238
// ----------------------------------------------------------------------------
 
239
 
 
240
#if wxUSE_UXTHEME
 
241
 
 
242
class wxRendererXP : public wxRendererMSWBase
 
243
{
 
244
public:
 
245
    wxRendererXP() : wxRendererMSWBase(wxRendererMSW::Get()) { }
 
246
 
 
247
    static wxRendererNative& Get();
 
248
 
 
249
    virtual int DrawHeaderButton(wxWindow *win,
 
250
                                  wxDC& dc,
 
251
                                  const wxRect& rect,
 
252
                                  int flags = 0,
 
253
                                  wxHeaderSortIconType sortArrow = wxHDR_SORT_ICON_NONE,
 
254
                                  wxHeaderButtonParams* params = NULL);
 
255
 
 
256
    virtual void DrawTreeItemButton(wxWindow *win,
 
257
                                    wxDC& dc,
 
258
                                    const wxRect& rect,
 
259
                                    int flags = 0);
 
260
    virtual void DrawSplitterBorder(wxWindow *win,
 
261
                                    wxDC& dc,
 
262
                                    const wxRect& rect,
 
263
                                    int flags = 0);
 
264
    virtual void DrawSplitterSash(wxWindow *win,
 
265
                                  wxDC& dc,
 
266
                                  const wxSize& size,
 
267
                                  wxCoord position,
 
268
                                  wxOrientation orient,
 
269
                                  int flags = 0);
 
270
    virtual void DrawComboBoxDropButton(wxWindow *win,
 
271
                                        wxDC& dc,
 
272
                                        const wxRect& rect,
 
273
                                        int flags = 0);
 
274
    virtual void DrawCheckBox(wxWindow *win,
 
275
                              wxDC& dc,
 
276
                              const wxRect& rect,
 
277
                              int flags = 0)
 
278
    {
 
279
        if ( !DoDrawXPButton(BP_CHECKBOX, win, dc, rect, flags) )
 
280
            m_rendererNative.DrawCheckBox(win, dc, rect, flags);
 
281
    }
 
282
 
 
283
    virtual void DrawPushButton(wxWindow *win,
 
284
                                wxDC& dc,
 
285
                                const wxRect& rect,
 
286
                                int flags = 0)
 
287
    {
 
288
        if ( !DoDrawXPButton(BP_PUSHBUTTON, win, dc, rect, flags) )
 
289
            m_rendererNative.DrawPushButton(win, dc, rect, flags);
 
290
    }
 
291
 
 
292
    virtual void DrawTextCtrl(wxWindow* win,
 
293
                              wxDC& dc,
 
294
                              const wxRect& rect,
 
295
                              int flags = 0);
 
296
 
 
297
    virtual void DrawRadioBitmap(wxWindow *win,
 
298
                                 wxDC& dc,
 
299
                                 const wxRect& rect,
 
300
                                 int flags = 0)
 
301
    {
 
302
        if ( !DoDrawXPButton(BP_RADIOBUTTON, win, dc, rect, flags) )
 
303
            m_rendererNative.DrawRadioBitmap(win, dc, rect, flags);
 
304
    }
 
305
 
 
306
    virtual void DrawTitleBarBitmap(wxWindow *win,
 
307
                                    wxDC& dc,
 
308
                                    const wxRect& rect,
 
309
                                    wxTitleBarButton button,
 
310
                                    int flags = 0);
 
311
 
 
312
    virtual wxSplitterRenderParams GetSplitterParams(const wxWindow *win);
 
313
 
 
314
private:
 
315
    // wrapper around DrawThemeBackground() translating flags to NORMAL/HOT/
 
316
    // PUSHED/DISABLED states (and so suitable for drawing anything
 
317
    // button-like)
 
318
    void DoDrawButtonLike(HTHEME htheme,
 
319
                          int part,
 
320
                          wxDC& dc,
 
321
                          const wxRect& rect,
 
322
                          int flags);
 
323
 
 
324
    // common part of DrawCheckBox(), DrawPushButton() and DrawRadioBitmap()
 
325
    bool DoDrawXPButton(int kind,
 
326
                        wxWindow *win,
 
327
                        wxDC& dc,
 
328
                        const wxRect& rect,
 
329
                        int flags);
 
330
 
 
331
    wxDECLARE_NO_COPY_CLASS(wxRendererXP);
 
332
};
 
333
 
 
334
#endif // wxUSE_UXTHEME
 
335
 
 
336
 
 
337
// ============================================================================
 
338
// wxRendererMSWBase implementation
 
339
// ============================================================================
 
340
 
 
341
void wxRendererMSWBase::DrawFocusRect(wxWindow * WXUNUSED(win),
 
342
                                      wxDC& dc,
 
343
                                      const wxRect& rect,
 
344
                                      int WXUNUSED(flags))
 
345
{
 
346
    RECT rc;
 
347
    wxCopyRectToRECT(rect, rc);
 
348
 
 
349
    ::DrawFocusRect(GetHdcOf(dc.GetTempHDC()), &rc);
 
350
}
 
351
 
 
352
void wxRendererMSWBase::DrawItemSelectionRect(wxWindow *win,
 
353
                                              wxDC& dc,
 
354
                                              const wxRect& rect,
 
355
                                              int flags)
 
356
{
 
357
    wxBrush brush;
 
358
    if ( flags & wxCONTROL_SELECTED )
 
359
    {
 
360
        if ( flags & wxCONTROL_FOCUSED )
 
361
        {
 
362
            brush = wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT));
 
363
        }
 
364
        else // !focused
 
365
        {
 
366
            brush = wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
 
367
        }
 
368
    }
 
369
    else // !selected
 
370
    {
 
371
        brush = *wxTRANSPARENT_BRUSH;
 
372
    }
 
373
 
 
374
    dc.SetBrush(brush);
 
375
    dc.SetPen(*wxTRANSPARENT_PEN);
 
376
    dc.DrawRectangle( rect );
 
377
 
 
378
    if ((flags & wxCONTROL_FOCUSED) && (flags & wxCONTROL_CURRENT))
 
379
        DrawFocusRect( win, dc, rect, flags );
 
380
}
 
381
 
 
382
void wxRendererMSWBase::DrawChoice(wxWindow* win,
 
383
                                   wxDC& dc,
 
384
                                   const wxRect& rect,
 
385
                                   int flags)
 
386
{
 
387
    DrawComboBox(win, dc, rect, flags);
 
388
}
 
389
 
 
390
void wxRendererMSWBase::DrawComboBox(wxWindow* win,
 
391
                                     wxDC& dc,
 
392
                                     const wxRect& rect,
 
393
                                     int flags)
 
394
{
 
395
    // Draw the main part of the control same as TextCtrl
 
396
    DrawTextCtrl(win, dc, rect, flags);
 
397
 
 
398
    // Draw the button inside the border, on the right side
 
399
    wxRect br(rect);
 
400
    br.height -= 2;
 
401
    br.x += br.width - br.height - 1;
 
402
    br.width = br.height;
 
403
    br.y += 1;
 
404
 
 
405
    DrawComboBoxDropButton(win, dc, br, flags);
 
406
}
 
407
 
 
408
// ============================================================================
 
409
// wxRendererNative and wxRendererMSW implementation
 
410
// ============================================================================
 
411
 
 
412
/* static */
 
413
wxRendererNative& wxRendererNative::GetDefault()
 
414
{
 
415
#if wxUSE_UXTHEME
 
416
    wxUxThemeEngine *themeEngine = wxUxThemeEngine::Get();
 
417
    if ( themeEngine && themeEngine->IsAppThemed() )
 
418
        return wxRendererXP::Get();
 
419
#endif // wxUSE_UXTHEME
 
420
 
 
421
    return wxRendererMSW::Get();
 
422
}
 
423
 
 
424
/* static */
 
425
wxRendererNative& wxRendererMSW::Get()
 
426
{
 
427
    static wxRendererMSW s_rendererMSW;
 
428
 
 
429
    return s_rendererMSW;
 
430
}
 
431
 
 
432
void
 
433
wxRendererMSW::DrawComboBoxDropButton(wxWindow * WXUNUSED(win),
 
434
                                      wxDC& dc,
 
435
                                      const wxRect& rect,
 
436
                                      int flags)
 
437
{
 
438
    wxCHECK_RET( dc.GetImpl(), wxT("Invalid wxDC") );
 
439
 
 
440
    wxRect adjustedRect = dc.GetImpl()->MSWApplyGDIPlusTransform(rect);
 
441
    
 
442
    RECT r;
 
443
    wxCopyRectToRECT(adjustedRect, r);
 
444
 
 
445
    int style = DFCS_SCROLLCOMBOBOX;
 
446
    if ( flags & wxCONTROL_DISABLED )
 
447
        style |= DFCS_INACTIVE;
 
448
    if ( flags & wxCONTROL_PRESSED )
 
449
        style |= DFCS_PUSHED | DFCS_FLAT;
 
450
 
 
451
    ::DrawFrameControl(GetHdcOf(dc.GetTempHDC()), &r, DFC_SCROLL, style);
 
452
}
 
453
 
 
454
void
 
455
wxRendererMSW::DoDrawFrameControl(UINT type,
 
456
                                  UINT kind,
 
457
                                  wxWindow * WXUNUSED(win),
 
458
                                  wxDC& dc,
 
459
                                  const wxRect& rect,
 
460
                                  int flags)
 
461
{
 
462
    wxCHECK_RET( dc.GetImpl(), wxT("Invalid wxDC") );
 
463
 
 
464
    wxRect adjustedRect = dc.GetImpl()->MSWApplyGDIPlusTransform(rect);
 
465
 
 
466
    RECT r;
 
467
    wxCopyRectToRECT(adjustedRect, r);
 
468
 
 
469
    int style = kind;
 
470
    if ( flags & wxCONTROL_CHECKED )
 
471
        style |= DFCS_CHECKED;
 
472
    if ( flags & wxCONTROL_DISABLED )
 
473
        style |= DFCS_INACTIVE;
 
474
    if ( flags & wxCONTROL_FLAT )
 
475
        style |= DFCS_MONO;
 
476
    if ( flags & wxCONTROL_PRESSED )
 
477
        style |= DFCS_PUSHED;
 
478
    if ( flags & wxCONTROL_CURRENT )
 
479
        style |= DFCS_HOT;
 
480
    if ( flags & wxCONTROL_UNDETERMINED )
 
481
        // Using DFCS_BUTTON3STATE here doesn't work (as might be expected),
 
482
        // use the following two styles to get the same look of a check box
 
483
        // in the undetermined state.
 
484
        style |= DFCS_INACTIVE | DFCS_CHECKED;
 
485
 
 
486
    ::DrawFrameControl(GetHdcOf(dc.GetTempHDC()), &r, type, style);
 
487
}
 
488
 
 
489
void
 
490
wxRendererMSW::DrawPushButton(wxWindow *win,
 
491
                              wxDC& dc,
 
492
                              const wxRect& rectOrig,
 
493
                              int flags)
 
494
{
 
495
    wxRect rect(rectOrig);
 
496
    if ( flags & wxCONTROL_ISDEFAULT )
 
497
    {
 
498
        // DrawFrameControl() doesn't seem to support default buttons so we
 
499
        // have to draw the border ourselves
 
500
        wxDCPenChanger pen(dc, *wxBLACK_PEN);
 
501
        wxDCBrushChanger brush(dc, *wxTRANSPARENT_BRUSH);
 
502
        dc.DrawRectangle(rect);
 
503
        rect.Deflate(1);
 
504
    }
 
505
 
 
506
    DoDrawButton(DFCS_BUTTONPUSH, win, dc, rect, flags);
 
507
}
 
508
 
 
509
void
 
510
wxRendererMSW::DrawTitleBarBitmap(wxWindow *win,
 
511
                                  wxDC& dc,
 
512
                                  const wxRect& rect,
 
513
                                  wxTitleBarButton button,
 
514
                                  int flags)
 
515
{
 
516
    UINT kind;
 
517
    switch ( button )
 
518
    {
 
519
        case wxTITLEBAR_BUTTON_CLOSE:
 
520
            kind = DFCS_CAPTIONCLOSE;
 
521
            break;
 
522
 
 
523
        case wxTITLEBAR_BUTTON_MAXIMIZE:
 
524
            kind = DFCS_CAPTIONMAX;
 
525
            break;
 
526
 
 
527
        case wxTITLEBAR_BUTTON_ICONIZE:
 
528
            kind = DFCS_CAPTIONMIN;
 
529
            break;
 
530
 
 
531
        case wxTITLEBAR_BUTTON_RESTORE:
 
532
            kind = DFCS_CAPTIONRESTORE;
 
533
            break;
 
534
 
 
535
        case wxTITLEBAR_BUTTON_HELP:
 
536
            kind = DFCS_CAPTIONHELP;
 
537
            break;
 
538
 
 
539
        default:
 
540
            wxFAIL_MSG( "unsupported title bar button" );
 
541
            return;
 
542
    }
 
543
 
 
544
    DoDrawFrameControl(DFC_CAPTION, kind, win, dc, rect, flags);
 
545
}
 
546
 
 
547
wxSize wxRendererMSW::GetCheckBoxSize(wxWindow * WXUNUSED(win))
 
548
{
 
549
    return wxSize(::GetSystemMetrics(SM_CXMENUCHECK),
 
550
                  ::GetSystemMetrics(SM_CYMENUCHECK));
 
551
}
 
552
 
 
553
int wxRendererMSW::GetHeaderButtonHeight(wxWindow * WXUNUSED(win))
 
554
{
 
555
    // some "reasonable" value returned in case of error, it doesn't really
 
556
    // correspond to anything but it's better than returning 0
 
557
    static const int DEFAULT_HEIGHT = 20;
 
558
 
 
559
 
 
560
    // create a temporary header window just to get its geometry
 
561
    HWND hwndHeader = ::CreateWindow(WC_HEADER, NULL, 0,
 
562
                                     0, 0, 0, 0, NULL, NULL, NULL, NULL);
 
563
    if ( !hwndHeader )
 
564
        return DEFAULT_HEIGHT;
 
565
 
 
566
    wxON_BLOCK_EXIT1( ::DestroyWindow, hwndHeader );
 
567
 
 
568
    // initialize the struct filled with the values by Header_Layout()
 
569
    RECT parentRect = { 0, 0, 100, 100 };
 
570
    WINDOWPOS wp = { 0, 0, 0, 0, 0, 0, 0 };
 
571
    HDLAYOUT hdl = { &parentRect, &wp };
 
572
 
 
573
    return Header_Layout(hwndHeader, &hdl) ? wp.cy : DEFAULT_HEIGHT;
 
574
}
 
575
 
 
576
int wxRendererMSW::GetHeaderButtonMargin(wxWindow *WXUNUSED(win))
 
577
{
 
578
    return 10;
 
579
}
 
580
 
 
581
// Uses the theme to draw the border and fill for something like a wxTextCtrl
 
582
void wxRendererMSW::DrawTextCtrl(wxWindow* WXUNUSED(win),
 
583
                                 wxDC& dc,
 
584
                                 const wxRect& rect,
 
585
                                 int WXUNUSED(flags))
 
586
{
 
587
    wxColour fill;
 
588
    wxColour bdr;
 
589
    {
 
590
        fill = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
 
591
        bdr = *wxBLACK;
 
592
    }
 
593
 
 
594
    dc.SetPen(bdr);
 
595
    dc.SetBrush(fill);
 
596
    dc.DrawRectangle(rect);
 
597
}
 
598
 
 
599
 
 
600
// ============================================================================
 
601
// wxRendererXP implementation
 
602
// ============================================================================
 
603
 
 
604
#if wxUSE_UXTHEME
 
605
 
 
606
/* static */
 
607
wxRendererNative& wxRendererXP::Get()
 
608
{
 
609
    static wxRendererXP s_rendererXP;
 
610
 
 
611
    return s_rendererXP;
 
612
}
 
613
 
 
614
// NOTE: There is no guarantee that the button drawn fills the entire rect (XP
 
615
// default theme, for example), so the caller should have cleared button's
 
616
// background before this call. This is quite likely a wxMSW-specific thing.
 
617
void
 
618
wxRendererXP::DrawComboBoxDropButton(wxWindow * win,
 
619
                                      wxDC& dc,
 
620
                                      const wxRect& rect,
 
621
                                      int flags)
 
622
{
 
623
    wxUxThemeHandle hTheme(win, L"COMBOBOX");
 
624
    if ( !hTheme )
 
625
    {
 
626
        m_rendererNative.DrawComboBoxDropButton(win, dc, rect, flags);
 
627
        return;
 
628
    }
 
629
 
 
630
    wxCHECK_RET( dc.GetImpl(), wxT("Invalid wxDC") );
 
631
 
 
632
    wxRect adjustedRect = dc.GetImpl()->MSWApplyGDIPlusTransform(rect);
 
633
 
 
634
    RECT r;
 
635
    wxCopyRectToRECT(adjustedRect, r);
 
636
 
 
637
    int state;
 
638
    if ( flags & wxCONTROL_PRESSED )
 
639
        state = CBXS_PRESSED;
 
640
    else if ( flags & wxCONTROL_CURRENT )
 
641
        state = CBXS_HOT;
 
642
    else if ( flags & wxCONTROL_DISABLED )
 
643
        state = CBXS_DISABLED;
 
644
    else
 
645
        state = CBXS_NORMAL;
 
646
 
 
647
    wxUxThemeEngine::Get()->DrawThemeBackground
 
648
                            (
 
649
                                hTheme,
 
650
                                GetHdcOf(dc.GetTempHDC()),
 
651
                                CP_DROPDOWNBUTTON,
 
652
                                state,
 
653
                                &r,
 
654
                                NULL
 
655
                            );
 
656
 
 
657
}
 
658
 
 
659
int
 
660
wxRendererXP::DrawHeaderButton(wxWindow *win,
 
661
                               wxDC& dc,
 
662
                               const wxRect& rect,
 
663
                               int flags,
 
664
                               wxHeaderSortIconType sortArrow,
 
665
                               wxHeaderButtonParams* params)
 
666
{
 
667
    wxUxThemeHandle hTheme(win, L"HEADER");
 
668
    if ( !hTheme )
 
669
    {
 
670
        return m_rendererNative.DrawHeaderButton(win, dc, rect, flags, sortArrow, params);
 
671
    }
 
672
 
 
673
    wxCHECK_MSG( dc.GetImpl(), -1, wxT("Invalid wxDC") );
 
674
 
 
675
    wxRect adjustedRect = dc.GetImpl()->MSWApplyGDIPlusTransform(rect);
 
676
 
 
677
    RECT r;
 
678
    wxCopyRectToRECT(adjustedRect, r);
 
679
 
 
680
    int state;
 
681
    if ( flags & wxCONTROL_PRESSED )
 
682
        state = HIS_PRESSED;
 
683
    else if ( flags & wxCONTROL_CURRENT )
 
684
        state = HIS_HOT;
 
685
    else
 
686
        state = HIS_NORMAL;
 
687
    wxUxThemeEngine::Get()->DrawThemeBackground
 
688
                            (
 
689
                                hTheme,
 
690
                                GetHdcOf(dc.GetTempHDC()),
 
691
                                HP_HEADERITEM,
 
692
                                state,
 
693
                                &r,
 
694
                                NULL
 
695
                            );
 
696
 
 
697
    // NOTE: Using the theme to draw HP_HEADERSORTARROW doesn't do anything.
 
698
    // Why?  If this can be fixed then draw the sort arrows using the theme
 
699
    // and then clear those flags before calling DrawHeaderButtonContents.
 
700
 
 
701
    // Add any extras that are specified in flags and params
 
702
    return DrawHeaderButtonContents(win, dc, rect, flags, sortArrow, params);
 
703
}
 
704
 
 
705
 
 
706
void
 
707
wxRendererXP::DrawTreeItemButton(wxWindow *win,
 
708
                                 wxDC& dc,
 
709
                                 const wxRect& rect,
 
710
                                 int flags)
 
711
{
 
712
    wxUxThemeHandle hTheme(win, L"TREEVIEW");
 
713
    if ( !hTheme )
 
714
    {
 
715
        m_rendererNative.DrawTreeItemButton(win, dc, rect, flags);
 
716
        return;
 
717
    }
 
718
 
 
719
    wxCHECK_RET( dc.GetImpl(), wxT("Invalid wxDC") );
 
720
 
 
721
    wxRect adjustedRect = dc.GetImpl()->MSWApplyGDIPlusTransform(rect);
 
722
 
 
723
    RECT r;
 
724
    wxCopyRectToRECT(adjustedRect, r);
 
725
 
 
726
    int state = flags & wxCONTROL_EXPANDED ? GLPS_OPENED : GLPS_CLOSED;
 
727
    wxUxThemeEngine::Get()->DrawThemeBackground
 
728
                            (
 
729
                                hTheme,
 
730
                                GetHdcOf(dc.GetTempHDC()),
 
731
                                TVP_GLYPH,
 
732
                                state,
 
733
                                &r,
 
734
                                NULL
 
735
                            );
 
736
}
 
737
 
 
738
bool
 
739
wxRendererXP::DoDrawXPButton(int kind,
 
740
                             wxWindow *win,
 
741
                             wxDC& dc,
 
742
                             const wxRect& rect,
 
743
                             int flags)
 
744
{
 
745
    wxUxThemeHandle hTheme(win, L"BUTTON");
 
746
    if ( !hTheme )
 
747
        return false;
 
748
 
 
749
    DoDrawButtonLike(hTheme, kind, dc, rect, flags);
 
750
 
 
751
    return true;
 
752
}
 
753
 
 
754
void
 
755
wxRendererXP::DoDrawButtonLike(HTHEME htheme,
 
756
                               int part,
 
757
                               wxDC& dc,
 
758
                               const wxRect& rect,
 
759
                               int flags)
 
760
{
 
761
    wxCHECK_RET( dc.GetImpl(), wxT("Invalid wxDC") );
 
762
 
 
763
    wxRect adjustedRect = dc.GetImpl()->MSWApplyGDIPlusTransform(rect);
 
764
 
 
765
    RECT r;
 
766
    wxCopyRectToRECT(adjustedRect, r);
 
767
 
 
768
    // the base state is always 1, whether it is PBS_NORMAL,
 
769
    // {CBS,RBS}_UNCHECKEDNORMAL or CBS_NORMAL
 
770
    int state = 1;
 
771
 
 
772
    // XBS_XXX is followed by XBX_XXXHOT, then XBS_XXXPRESSED and DISABLED
 
773
    enum
 
774
    {
 
775
        NORMAL_OFFSET,
 
776
        HOT_OFFSET,
 
777
        PRESSED_OFFSET,
 
778
        DISABLED_OFFSET,
 
779
        STATES_COUNT
 
780
    };
 
781
 
 
782
    // in both RBS_ and CBS_ enums CHECKED elements are offset by 4 from base
 
783
    // (UNCHECKED) ones and MIXED are offset by 4 again as there are all states
 
784
    // from the above enum in between them
 
785
    if ( flags & wxCONTROL_CHECKED )
 
786
        state += STATES_COUNT;
 
787
    else if ( flags & wxCONTROL_UNDETERMINED )
 
788
        state += 2*STATES_COUNT;
 
789
 
 
790
    if ( flags & wxCONTROL_DISABLED )
 
791
        state += DISABLED_OFFSET;
 
792
    else if ( flags & wxCONTROL_PRESSED )
 
793
        state += PRESSED_OFFSET;
 
794
    else if ( flags & wxCONTROL_CURRENT )
 
795
        state += HOT_OFFSET;
 
796
    // wxCONTROL_ISDEFAULT flag is only valid for push buttons
 
797
    else if ( part == BP_PUSHBUTTON && (flags & wxCONTROL_ISDEFAULT) )
 
798
        state = PBS_DEFAULTED;
 
799
 
 
800
    wxUxThemeEngine::Get()->DrawThemeBackground
 
801
                            (
 
802
                                htheme,
 
803
                                GetHdcOf(dc.GetTempHDC()),
 
804
                                part,
 
805
                                state,
 
806
                                &r,
 
807
                                NULL
 
808
                            );
 
809
}
 
810
 
 
811
void
 
812
wxRendererXP::DrawTitleBarBitmap(wxWindow *win,
 
813
                                 wxDC& dc,
 
814
                                 const wxRect& rect,
 
815
                                 wxTitleBarButton button,
 
816
                                 int flags)
 
817
{
 
818
    wxUxThemeHandle hTheme(win, L"WINDOW");
 
819
    if ( !hTheme )
 
820
    {
 
821
        m_rendererNative.DrawTitleBarBitmap(win, dc, rect, button, flags);
 
822
        return;
 
823
    }
 
824
 
 
825
    int part;
 
826
    switch ( button )
 
827
    {
 
828
        case wxTITLEBAR_BUTTON_CLOSE:
 
829
            part = WP_CLOSEBUTTON;
 
830
            break;
 
831
 
 
832
        case wxTITLEBAR_BUTTON_MAXIMIZE:
 
833
            part = WP_MAXBUTTON;
 
834
            break;
 
835
 
 
836
        case wxTITLEBAR_BUTTON_ICONIZE:
 
837
            part = WP_MINBUTTON;
 
838
            break;
 
839
 
 
840
        case wxTITLEBAR_BUTTON_RESTORE:
 
841
            part = WP_RESTOREBUTTON;
 
842
            break;
 
843
 
 
844
        case wxTITLEBAR_BUTTON_HELP:
 
845
            part = WP_HELPBUTTON;
 
846
            break;
 
847
 
 
848
        default:
 
849
            wxFAIL_MSG( "unsupported title bar button" );
 
850
            return;
 
851
    }
 
852
 
 
853
    DoDrawButtonLike(hTheme, part, dc, rect, flags);
 
854
}
 
855
 
 
856
// Uses the theme to draw the border and fill for something like a wxTextCtrl
 
857
void wxRendererXP::DrawTextCtrl(wxWindow* win,
 
858
                                wxDC& dc,
 
859
                                const wxRect& rect,
 
860
                                int flags)
 
861
{
 
862
    wxUxThemeHandle hTheme(win, L"EDIT");
 
863
    if ( !hTheme )
 
864
    {
 
865
        m_rendererNative.DrawTextCtrl(win,dc,rect,flags);
 
866
        return;
 
867
    }
 
868
 
 
869
    wxColour fill;
 
870
    wxColour bdr;
 
871
    COLORREF cref;
 
872
 
 
873
    wxUxThemeEngine::Get()->GetThemeColor(hTheme, EP_EDITTEXT,
 
874
                                          ETS_NORMAL, TMT_FILLCOLOR, &cref);
 
875
    fill = wxRGBToColour(cref);
 
876
 
 
877
    int etsState;
 
878
    if ( flags & wxCONTROL_DISABLED )
 
879
        etsState = ETS_DISABLED;
 
880
    else
 
881
        etsState = ETS_NORMAL;
 
882
 
 
883
    wxUxThemeEngine::Get()->GetThemeColor(hTheme, EP_EDITTEXT,
 
884
                                              etsState, TMT_BORDERCOLOR, &cref);
 
885
    bdr = wxRGBToColour(cref);
 
886
 
 
887
    dc.SetPen( bdr );
 
888
    dc.SetBrush( fill );
 
889
    dc.DrawRectangle(rect);
 
890
}
 
891
 
 
892
// ----------------------------------------------------------------------------
 
893
// splitter drawing
 
894
// ----------------------------------------------------------------------------
 
895
 
 
896
// the width of the sash: this is the same as used by Explorer...
 
897
static const wxCoord SASH_WIDTH = 4;
 
898
 
 
899
wxSplitterRenderParams
 
900
wxRendererXP::GetSplitterParams(const wxWindow * win)
 
901
{
 
902
    if ( win->HasFlag(wxSP_NO_XP_THEME) )
 
903
        return m_rendererNative.GetSplitterParams(win);
 
904
    else
 
905
        return wxSplitterRenderParams(SASH_WIDTH, 0, false);
 
906
}
 
907
 
 
908
void
 
909
wxRendererXP::DrawSplitterBorder(wxWindow * win,
 
910
                                 wxDC& dc,
 
911
                                 const wxRect& rect,
 
912
                                 int flags)
 
913
{
 
914
    if ( win->HasFlag(wxSP_NO_XP_THEME) )
 
915
    {
 
916
        m_rendererNative.DrawSplitterBorder(win, dc, rect, flags);
 
917
    }
 
918
}
 
919
 
 
920
void
 
921
wxRendererXP::DrawSplitterSash(wxWindow *win,
 
922
                               wxDC& dc,
 
923
                               const wxSize& size,
 
924
                               wxCoord position,
 
925
                               wxOrientation orient,
 
926
                               int flags)
 
927
{
 
928
    if ( !win->HasFlag(wxSP_NO_XP_THEME) )
 
929
    {
 
930
        dc.SetPen(*wxTRANSPARENT_PEN);
 
931
        dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)));
 
932
        if ( orient == wxVERTICAL )
 
933
        {
 
934
            dc.DrawRectangle(position, 0, SASH_WIDTH, size.y);
 
935
        }
 
936
        else // wxHORIZONTAL
 
937
        {
 
938
            dc.DrawRectangle(0, position, size.x, SASH_WIDTH);
 
939
        }
 
940
 
 
941
        return;
 
942
    }
 
943
 
 
944
    m_rendererNative.DrawSplitterSash(win, dc, size, position, orient, flags);
 
945
}
 
946
 
 
947
#endif // wxUSE_UXTHEME