Enhance wxRibbonToolBar functionality to wxRibbonButtonBar level.
[wxWidgets.git] / src / ribbon / art_msw.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/ribbon/art_msw.cpp
3 // Purpose: MSW style art provider for ribbon interface
4 // Author: Peter Cawley
5 // Modified by:
6 // Created: 2009-05-25
7 // RCS-ID: $Id$
8 // Copyright: (C) Peter Cawley
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 #include "wx/wxprec.h"
13
14 #ifdef __BORLANDC__
15 #pragma hdrstop
16 #endif
17
18 #if wxUSE_RIBBON
19
20 #include "wx/ribbon/art.h"
21 #include "wx/ribbon/art_internal.h"
22 #include "wx/ribbon/bar.h"
23 #include "wx/ribbon/buttonbar.h"
24 #include "wx/ribbon/gallery.h"
25 #include "wx/ribbon/toolbar.h"
26
27 #ifndef WX_PRECOMP
28 #include "wx/dcmemory.h"
29 #endif
30
31 #ifdef __WXMSW__
32 #include "wx/msw/private.h"
33 #endif
34
35 static const char* const gallery_up_xpm[] = {
36 "5 5 2 1",
37 " c None",
38 "x c #FF00FF",
39 " ",
40 " x ",
41 " xxx ",
42 "xxxxx",
43 " "};
44
45 static const char* const gallery_down_xpm[] = {
46 "5 5 2 1",
47 " c None",
48 "x c #FF00FF",
49 " ",
50 "xxxxx",
51 " xxx ",
52 " x ",
53 " "};
54
55 static const char* const gallery_left_xpm[] = {
56 "5 5 2 1",
57 " c None",
58 "x c #FF00FF",
59 " x ",
60 " xx ",
61 " xxx ",
62 " xx ",
63 " x "};
64
65 static const char* const gallery_right_xpm[] = {
66 "5 5 2 1",
67 " c None",
68 "x c #FF00FF",
69 " x ",
70 " xx ",
71 " xxx ",
72 " xx ",
73 " x "};
74
75 static const char* const gallery_extension_xpm[] = {
76 "5 5 2 1",
77 " c None",
78 "x c #FF00FF",
79 "xxxxx",
80 " ",
81 "xxxxx",
82 " xxx ",
83 " x "};
84
85 wxRibbonMSWArtProvider::wxRibbonMSWArtProvider(bool set_colour_scheme)
86 {
87 m_flags = 0;
88 m_tab_label_font = *wxNORMAL_FONT;
89 m_button_bar_label_font = m_tab_label_font;
90 m_panel_label_font = m_tab_label_font;
91
92 if(set_colour_scheme)
93 {
94 SetColourScheme(
95 wxColour(194, 216, 241),
96 wxColour(255, 223, 114),
97 wxColour( 0, 0, 0));
98 }
99
100 m_cached_tab_separator_visibility = -10.0; // valid visibilities are in range [0, 1]
101 m_tab_separation_size = 3;
102 m_page_border_left = 2;
103 m_page_border_top = 1;
104 m_page_border_right = 2;
105 m_page_border_bottom = 3;
106 m_panel_x_separation_size = 1;
107 m_panel_y_separation_size = 1;
108 m_tool_group_separation_size = 3;
109 m_gallery_bitmap_padding_left_size = 4;
110 m_gallery_bitmap_padding_right_size = 4;
111 m_gallery_bitmap_padding_top_size = 4;
112 m_gallery_bitmap_padding_bottom_size = 4;
113 }
114
115 wxRibbonMSWArtProvider::~wxRibbonMSWArtProvider()
116 {
117 }
118
119 void wxRibbonMSWArtProvider::GetColourScheme(
120 wxColour* primary,
121 wxColour* secondary,
122 wxColour* tertiary) const
123 {
124 if(primary != NULL)
125 *primary = m_primary_scheme_colour;
126 if(secondary != NULL)
127 *secondary = m_secondary_scheme_colour;
128 if(tertiary != NULL)
129 *tertiary = m_tertiary_scheme_colour;
130 }
131
132 void wxRibbonMSWArtProvider::SetColourScheme(
133 const wxColour& primary,
134 const wxColour& secondary,
135 const wxColour& tertiary)
136 {
137 m_primary_scheme_colour = primary;
138 m_secondary_scheme_colour = secondary;
139 m_tertiary_scheme_colour = tertiary;
140
141 wxRibbonHSLColour primary_hsl(primary);
142 wxRibbonHSLColour secondary_hsl(secondary);
143 // tertiary not used for anything
144
145 // Map primary saturation from [0, 1] to [.25, .75]
146 bool primary_is_gray = false;
147 static const double gray_saturation_threshold = 0.01;
148 if(primary_hsl.saturation <= gray_saturation_threshold)
149 primary_is_gray = true;
150 else
151 {
152 primary_hsl.saturation = cos(primary_hsl.saturation * M_PI)
153 * -0.25 + 0.5;
154 }
155
156 // Map primary luminance from [0, 1] to [.23, .83]
157 primary_hsl.luminance = cos(primary_hsl.luminance * M_PI) * -0.3 + 0.53;
158
159 // Map secondary saturation from [0, 1] to [0.16, 0.84]
160 bool secondary_is_gray = false;
161 if(secondary_hsl.saturation <= gray_saturation_threshold)
162 secondary_is_gray = true;
163 else
164 {
165 secondary_hsl.saturation = cos(secondary_hsl.saturation * M_PI)
166 * -0.34 + 0.5;
167 }
168
169 // Map secondary luminance from [0, 1] to [0.1, 0.9]
170 secondary_hsl.luminance = cos(secondary_hsl.luminance * M_PI) * -0.4 + 0.5;
171
172 #define LikePrimary(h, s, l) \
173 primary_hsl.ShiftHue(h ## f).Saturated(primary_is_gray ? 0 : s ## f) \
174 .Lighter(l ## f).ToRGB()
175 #define LikeSecondary(h, s, l) \
176 secondary_hsl.ShiftHue(h ## f).Saturated(secondary_is_gray ? 0 : s ## f) \
177 .Lighter(l ## f).ToRGB()
178
179 m_page_border_pen = LikePrimary(1.4, 0.00, -0.08);
180
181 m_page_background_top_colour = LikePrimary(-0.1, -0.03, 0.12);
182 m_page_hover_background_top_colour = LikePrimary(-2.8, 0.27, 0.17);
183 m_page_background_top_gradient_colour = LikePrimary(0.1, -0.10, 0.08);
184 m_page_hover_background_top_gradient_colour = LikePrimary(3.2, 0.16, 0.13);
185 m_page_background_colour = LikePrimary(0.4, -0.09, 0.05);
186 m_page_hover_background_colour = LikePrimary(0.1, 0.19, 0.10);
187 m_page_background_gradient_colour = LikePrimary(-3.2, 0.27, 0.10);
188 m_page_hover_background_gradient_colour = LikePrimary(1.8, 0.01, 0.15);
189
190 m_tab_active_background_colour = LikePrimary(-0.1, -0.31, 0.16);
191 m_tab_active_background_gradient_colour = LikePrimary(-0.1, -0.03, 0.12);
192 m_tab_separator_colour = LikePrimary(0.9, 0.24, 0.05);
193 m_tab_ctrl_background_brush = LikePrimary(1.0, 0.39, 0.07);
194 m_tab_hover_background_colour = LikePrimary(1.3, 0.15, 0.10);
195 m_tab_hover_background_top_colour = LikePrimary(1.4, 0.36, 0.08);
196 m_tab_border_pen = LikePrimary(1.4, 0.03, -0.05);
197 m_tab_separator_gradient_colour = LikePrimary(1.7, -0.15, -0.18);
198 m_tab_hover_background_top_gradient_colour = LikePrimary(1.8, 0.34, 0.13);
199 m_tab_label_colour = LikePrimary(4.3, 0.13, -0.49);
200 m_tab_hover_background_gradient_colour = LikeSecondary(-1.5, -0.34, 0.01);
201
202 m_panel_minimised_border_gradient_pen = LikePrimary(-6.9, -0.17, -0.09);
203 m_panel_minimised_border_pen = LikePrimary(-5.3, -0.24, -0.06);
204 m_panel_border_gradient_pen = LikePrimary(-5.2, -0.15, -0.06);
205 m_panel_border_pen = LikePrimary(-2.8, -0.32, 0.02);
206 m_panel_label_background_brush = LikePrimary(-1.5, 0.03, 0.05);
207 m_panel_active_background_gradient_colour = LikePrimary(0.5, 0.34, 0.05);
208 m_panel_hover_label_background_brush = LikePrimary(1.0, 0.30, 0.09);
209 m_panel_active_background_top_gradient_colour = LikePrimary(1.4, -0.17, -0.13);
210 m_panel_active_background_colour = LikePrimary(1.6, -0.18, -0.18);
211 m_panel_active_background_top_colour = LikePrimary(1.7, -0.20, -0.03);
212 m_panel_label_colour = LikePrimary(2.8, -0.14, -0.35);
213 m_panel_hover_label_colour = m_panel_label_colour;
214 m_panel_minimised_label_colour = m_tab_label_colour;
215
216 m_gallery_button_disabled_background_colour = LikePrimary(-2.8, -0.46, 0.09);
217 m_gallery_button_disabled_background_top_brush = LikePrimary(-2.8, -0.36, 0.15);
218 m_gallery_hover_background_brush = LikePrimary(-0.8, 0.05, 0.15);
219 m_gallery_border_pen = LikePrimary(0.7, -0.02, 0.03);
220 m_gallery_button_background_top_brush = LikePrimary(0.8, 0.34, 0.13);
221 m_gallery_button_background_colour = LikePrimary(1.3, 0.10, 0.08);
222 // SetColour used so that the relevant bitmaps are generated
223 SetColour(wxRIBBON_ART_GALLERY_BUTTON_FACE_COLOUR, LikePrimary(1.4, -0.21, -0.23));
224 SetColour(wxRIBBON_ART_GALLERY_BUTTON_HOVER_FACE_COLOUR, LikePrimary(1.5, -0.24, -0.29));
225 SetColour(wxRIBBON_ART_GALLERY_BUTTON_ACTIVE_FACE_COLOUR, LikePrimary(1.5, -0.24, -0.29));
226 SetColour(wxRIBBON_ART_GALLERY_BUTTON_DISABLED_FACE_COLOUR, LikePrimary(0.0, -1.0, 0.0));
227 m_gallery_button_disabled_background_gradient_colour = LikePrimary(1.5, -0.43, 0.12);
228 m_gallery_button_background_gradient_colour = LikePrimary(1.7, 0.11, 0.09);
229 m_gallery_item_border_pen = LikeSecondary(-3.9, -0.16, -0.14);
230 m_gallery_button_hover_background_colour = LikeSecondary(-0.9, 0.16, -0.07);
231 m_gallery_button_hover_background_gradient_colour = LikeSecondary(0.1, 0.12, 0.03);
232 m_gallery_button_hover_background_top_brush = LikeSecondary(4.3, 0.16, 0.17);
233
234 m_gallery_button_active_background_colour = LikeSecondary(-9.9, 0.03, -0.22);
235 m_gallery_button_active_background_gradient_colour = LikeSecondary(-9.5, 0.14, -0.11);
236 m_gallery_button_active_background_top_brush = LikeSecondary(-9.0, 0.15, -0.08);
237
238 m_button_bar_label_colour = m_tab_label_colour;
239 m_button_bar_hover_border_pen = LikeSecondary(-6.2, -0.47, -0.14);
240 m_button_bar_hover_background_gradient_colour = LikeSecondary(-0.6, 0.16, 0.04);
241 m_button_bar_hover_background_colour = LikeSecondary(-0.2, 0.16, -0.10);
242 m_button_bar_hover_background_top_gradient_colour = LikeSecondary(0.2, 0.16, 0.03);
243 m_button_bar_hover_background_top_colour = LikeSecondary(8.8, 0.16, 0.17);
244 m_button_bar_active_border_pen = LikeSecondary(-6.2, -0.47, -0.25);
245 m_button_bar_active_background_top_colour = LikeSecondary(-8.4, 0.08, 0.06);
246 m_button_bar_active_background_top_gradient_colour = LikeSecondary(-9.7, 0.13, -0.07);
247 m_button_bar_active_background_colour = LikeSecondary(-9.9, 0.14, -0.14);
248 m_button_bar_active_background_gradient_colour = LikeSecondary(-8.7, 0.17, -0.03);
249
250 m_toolbar_border_pen = LikePrimary(1.4, -0.21, -0.16);
251 SetColour(wxRIBBON_ART_TOOLBAR_FACE_COLOUR, LikePrimary(1.4, -0.17, -0.22));
252 m_tool_background_top_colour = LikePrimary(-1.9, -0.07, 0.06);
253 m_tool_background_top_gradient_colour = LikePrimary(1.4, 0.12, 0.08);
254 m_tool_background_colour = LikePrimary(1.4, -0.09, 0.03);
255 m_tool_background_gradient_colour = LikePrimary(1.9, 0.11, 0.09);
256 m_tool_hover_background_top_colour = LikeSecondary(3.4, 0.11, 0.16);
257 m_tool_hover_background_top_gradient_colour = LikeSecondary(-1.4, 0.04, 0.08);
258 m_tool_hover_background_colour = LikeSecondary(-1.8, 0.16, -0.12);
259 m_tool_hover_background_gradient_colour = LikeSecondary(-2.6, 0.16, 0.05);
260 m_tool_active_background_top_colour = LikeSecondary(-9.9, -0.12, -0.09);
261 m_tool_active_background_top_gradient_colour = LikeSecondary(-8.5, 0.16, -0.12);
262 m_tool_active_background_colour = LikeSecondary(-7.9, 0.16, -0.20);
263 m_tool_active_background_gradient_colour = LikeSecondary(-6.6, 0.16, -0.10);
264
265 #undef LikePrimary
266 #undef LikeSecondary
267
268 // Invalidate cached tab separator
269 m_cached_tab_separator_visibility = -1.0;
270 }
271
272 wxRibbonArtProvider* wxRibbonMSWArtProvider::Clone() const
273 {
274 wxRibbonMSWArtProvider *copy = new wxRibbonMSWArtProvider;
275 CloneTo(copy);
276 return copy;
277 }
278
279 void wxRibbonMSWArtProvider::CloneTo(wxRibbonMSWArtProvider* copy) const
280 {
281 for(int i = 0; i < 4; ++i)
282 {
283 copy->m_gallery_up_bitmap[i] = m_gallery_up_bitmap[i];
284 copy->m_gallery_down_bitmap[i] = m_gallery_down_bitmap[i];
285 copy->m_gallery_extension_bitmap[i] = m_gallery_extension_bitmap[i];
286 }
287 copy->m_toolbar_drop_bitmap = m_toolbar_drop_bitmap;
288
289 copy->m_primary_scheme_colour = m_primary_scheme_colour;
290 copy->m_secondary_scheme_colour = m_secondary_scheme_colour;
291 copy->m_tertiary_scheme_colour = m_tertiary_scheme_colour;
292
293 copy->m_button_bar_label_colour = m_button_bar_label_colour;
294 copy->m_tab_label_colour = m_tab_label_colour;
295 copy->m_tab_separator_colour = m_tab_separator_colour;
296 copy->m_tab_separator_gradient_colour = m_tab_separator_gradient_colour;
297 copy->m_tab_active_background_colour = m_tab_hover_background_colour;
298 copy->m_tab_active_background_gradient_colour = m_tab_hover_background_gradient_colour;
299 copy->m_tab_hover_background_colour = m_tab_hover_background_colour;
300 copy->m_tab_hover_background_gradient_colour = m_tab_hover_background_gradient_colour;
301 copy->m_tab_hover_background_top_colour = m_tab_hover_background_top_colour;
302 copy->m_tab_hover_background_top_gradient_colour = m_tab_hover_background_top_gradient_colour;
303 copy->m_panel_label_colour = m_panel_label_colour;
304 copy->m_panel_hover_label_colour = m_panel_hover_label_colour;
305 copy->m_panel_minimised_label_colour = m_panel_minimised_label_colour;
306 copy->m_panel_active_background_colour = m_panel_active_background_colour;
307 copy->m_panel_active_background_gradient_colour = m_panel_active_background_gradient_colour;
308 copy->m_panel_active_background_top_colour = m_panel_active_background_top_colour;
309 copy->m_panel_active_background_top_gradient_colour = m_panel_active_background_top_gradient_colour;
310 copy->m_page_background_colour = m_page_background_colour;
311 copy->m_page_background_gradient_colour = m_page_background_gradient_colour;
312 copy->m_page_background_top_colour = m_page_background_top_colour;
313 copy->m_page_background_top_gradient_colour = m_page_background_top_gradient_colour;
314 copy->m_page_hover_background_colour = m_page_hover_background_colour;
315 copy->m_page_hover_background_gradient_colour = m_page_hover_background_gradient_colour;
316 copy->m_page_hover_background_top_colour = m_page_hover_background_top_colour;
317 copy->m_page_hover_background_top_gradient_colour = m_page_hover_background_top_gradient_colour;
318 copy->m_button_bar_hover_background_colour = m_button_bar_hover_background_colour;
319 copy->m_button_bar_hover_background_gradient_colour = m_button_bar_hover_background_gradient_colour;
320 copy->m_button_bar_hover_background_top_colour = m_button_bar_hover_background_top_colour;
321 copy->m_button_bar_hover_background_top_gradient_colour = m_button_bar_hover_background_top_gradient_colour;
322 copy->m_button_bar_active_background_colour = m_button_bar_active_background_colour;
323 copy->m_button_bar_active_background_gradient_colour = m_button_bar_active_background_gradient_colour;
324 copy->m_button_bar_active_background_top_colour = m_button_bar_active_background_top_colour;
325 copy->m_button_bar_active_background_top_gradient_colour = m_button_bar_active_background_top_gradient_colour;
326 copy->m_gallery_button_background_colour = m_gallery_button_background_colour;
327 copy->m_gallery_button_background_gradient_colour = m_gallery_button_background_gradient_colour;
328 copy->m_gallery_button_hover_background_colour = m_gallery_button_hover_background_colour;
329 copy->m_gallery_button_hover_background_gradient_colour = m_gallery_button_hover_background_gradient_colour;
330 copy->m_gallery_button_active_background_colour = m_gallery_button_active_background_colour;
331 copy->m_gallery_button_active_background_gradient_colour = m_gallery_button_active_background_gradient_colour;
332 copy->m_gallery_button_disabled_background_colour = m_gallery_button_disabled_background_colour;
333 copy->m_gallery_button_disabled_background_gradient_colour = m_gallery_button_disabled_background_gradient_colour;
334 copy->m_gallery_button_face_colour = m_gallery_button_face_colour;
335 copy->m_gallery_button_hover_face_colour = m_gallery_button_hover_face_colour;
336 copy->m_gallery_button_active_face_colour = m_gallery_button_active_face_colour;
337 copy->m_gallery_button_disabled_face_colour = m_gallery_button_disabled_face_colour;
338
339 copy->m_tab_ctrl_background_brush = m_tab_ctrl_background_brush;
340 copy->m_panel_label_background_brush = m_panel_label_background_brush;
341 copy->m_panel_hover_label_background_brush = m_panel_hover_label_background_brush;
342 copy->m_gallery_hover_background_brush = m_gallery_hover_background_brush;
343 copy->m_gallery_button_background_top_brush = m_gallery_button_background_top_brush;
344 copy->m_gallery_button_hover_background_top_brush = m_gallery_button_hover_background_top_brush;
345 copy->m_gallery_button_active_background_top_brush = m_gallery_button_active_background_top_brush;
346 copy->m_gallery_button_disabled_background_top_brush = m_gallery_button_disabled_background_top_brush;
347
348 copy->m_tab_label_font = m_tab_label_font;
349 copy->m_button_bar_label_font = m_button_bar_label_font;
350 copy->m_panel_label_font = m_panel_label_font;
351
352 copy->m_page_border_pen = m_page_border_pen;
353 copy->m_panel_border_pen = m_panel_border_pen;
354 copy->m_panel_border_gradient_pen = m_panel_border_gradient_pen;
355 copy->m_panel_minimised_border_pen = m_panel_minimised_border_pen;
356 copy->m_panel_minimised_border_gradient_pen = m_panel_minimised_border_gradient_pen;
357 copy->m_tab_border_pen = m_tab_border_pen;
358 copy->m_gallery_border_pen = m_gallery_border_pen;
359 copy->m_button_bar_hover_border_pen = m_button_bar_hover_border_pen;
360 copy->m_button_bar_active_border_pen = m_button_bar_active_border_pen;
361 copy->m_gallery_item_border_pen = m_gallery_item_border_pen;
362 copy->m_toolbar_border_pen = m_toolbar_border_pen;
363
364 copy->m_flags = m_flags;
365 copy->m_tab_separation_size = m_tab_separation_size;
366 copy->m_page_border_left = m_page_border_left;
367 copy->m_page_border_top = m_page_border_top;
368 copy->m_page_border_right = m_page_border_right;
369 copy->m_page_border_bottom = m_page_border_bottom;
370 copy->m_panel_x_separation_size = m_panel_x_separation_size;
371 copy->m_panel_y_separation_size = m_panel_y_separation_size;
372 copy->m_gallery_bitmap_padding_left_size = m_gallery_bitmap_padding_left_size;
373 copy->m_gallery_bitmap_padding_right_size = m_gallery_bitmap_padding_right_size;
374 copy->m_gallery_bitmap_padding_top_size = m_gallery_bitmap_padding_top_size;
375 copy->m_gallery_bitmap_padding_bottom_size = m_gallery_bitmap_padding_bottom_size;
376 }
377
378 long wxRibbonMSWArtProvider::GetFlags() const
379 {
380 return m_flags;
381 }
382
383 void wxRibbonMSWArtProvider::SetFlags(long flags)
384 {
385 if((flags ^ m_flags) & wxRIBBON_BAR_FLOW_VERTICAL)
386 {
387 if(flags & wxRIBBON_BAR_FLOW_VERTICAL)
388 {
389 m_page_border_left++;
390 m_page_border_right++;
391 m_page_border_top--;
392 m_page_border_bottom--;
393 }
394 else
395 {
396 m_page_border_left--;
397 m_page_border_right--;
398 m_page_border_top++;
399 m_page_border_bottom++;
400 }
401 }
402 m_flags = flags;
403
404 // Need to reload some bitmaps when flags change
405 #define Reload(setting) SetColour(setting, GetColour(setting))
406 Reload(wxRIBBON_ART_GALLERY_BUTTON_FACE_COLOUR);
407 Reload(wxRIBBON_ART_GALLERY_BUTTON_HOVER_FACE_COLOUR);
408 Reload(wxRIBBON_ART_GALLERY_BUTTON_ACTIVE_FACE_COLOUR);
409 Reload(wxRIBBON_ART_GALLERY_BUTTON_DISABLED_FACE_COLOUR);
410 #undef Reload
411 }
412
413 int wxRibbonMSWArtProvider::GetMetric(int id) const
414 {
415 switch(id)
416 {
417 case wxRIBBON_ART_TAB_SEPARATION_SIZE:
418 return m_tab_separation_size;
419 case wxRIBBON_ART_PAGE_BORDER_LEFT_SIZE:
420 return m_page_border_left;
421 case wxRIBBON_ART_PAGE_BORDER_TOP_SIZE:
422 return m_page_border_top;
423 case wxRIBBON_ART_PAGE_BORDER_RIGHT_SIZE:
424 return m_page_border_right;
425 case wxRIBBON_ART_PAGE_BORDER_BOTTOM_SIZE:
426 return m_page_border_bottom;
427 case wxRIBBON_ART_PANEL_X_SEPARATION_SIZE:
428 return m_panel_x_separation_size;
429 case wxRIBBON_ART_PANEL_Y_SEPARATION_SIZE:
430 return m_panel_y_separation_size;
431 case wxRIBBON_ART_TOOL_GROUP_SEPARATION_SIZE:
432 return m_tool_group_separation_size;
433 case wxRIBBON_ART_GALLERY_BITMAP_PADDING_LEFT_SIZE:
434 return m_gallery_bitmap_padding_left_size;
435 case wxRIBBON_ART_GALLERY_BITMAP_PADDING_RIGHT_SIZE:
436 return m_gallery_bitmap_padding_right_size;
437 case wxRIBBON_ART_GALLERY_BITMAP_PADDING_TOP_SIZE:
438 return m_gallery_bitmap_padding_top_size;
439 case wxRIBBON_ART_GALLERY_BITMAP_PADDING_BOTTOM_SIZE:
440 return m_gallery_bitmap_padding_bottom_size;
441 default:
442 wxFAIL_MSG(wxT("Invalid Metric Ordinal"));
443 break;
444 }
445
446 return 0;
447 }
448
449 void wxRibbonMSWArtProvider::SetMetric(int id, int new_val)
450 {
451 switch(id)
452 {
453 case wxRIBBON_ART_TAB_SEPARATION_SIZE:
454 m_tab_separation_size = new_val;
455 break;
456 case wxRIBBON_ART_PAGE_BORDER_LEFT_SIZE:
457 m_page_border_left = new_val;
458 break;
459 case wxRIBBON_ART_PAGE_BORDER_TOP_SIZE:
460 m_page_border_top = new_val;
461 break;
462 case wxRIBBON_ART_PAGE_BORDER_RIGHT_SIZE:
463 m_page_border_right = new_val;
464 break;
465 case wxRIBBON_ART_PAGE_BORDER_BOTTOM_SIZE:
466 m_page_border_bottom = new_val;
467 break;
468 case wxRIBBON_ART_PANEL_X_SEPARATION_SIZE:
469 m_panel_x_separation_size = new_val;
470 break;
471 case wxRIBBON_ART_PANEL_Y_SEPARATION_SIZE:
472 m_panel_y_separation_size = new_val;
473 break;
474 case wxRIBBON_ART_TOOL_GROUP_SEPARATION_SIZE:
475 m_tool_group_separation_size = new_val;
476 break;
477 case wxRIBBON_ART_GALLERY_BITMAP_PADDING_LEFT_SIZE:
478 m_gallery_bitmap_padding_left_size = new_val;
479 break;
480 case wxRIBBON_ART_GALLERY_BITMAP_PADDING_RIGHT_SIZE:
481 m_gallery_bitmap_padding_right_size = new_val;
482 break;
483 case wxRIBBON_ART_GALLERY_BITMAP_PADDING_TOP_SIZE:
484 m_gallery_bitmap_padding_top_size = new_val;
485 break;
486 case wxRIBBON_ART_GALLERY_BITMAP_PADDING_BOTTOM_SIZE:
487 m_gallery_bitmap_padding_bottom_size = new_val;
488 break;
489 default:
490 wxFAIL_MSG(wxT("Invalid Metric Ordinal"));
491 break;
492 }
493 }
494
495 void wxRibbonMSWArtProvider::SetFont(int id, const wxFont& font)
496 {
497 switch(id)
498 {
499 case wxRIBBON_ART_TAB_LABEL_FONT:
500 m_tab_label_font = font;
501 break;
502 case wxRIBBON_ART_BUTTON_BAR_LABEL_FONT:
503 m_button_bar_label_font = font;
504 break;
505 case wxRIBBON_ART_PANEL_LABEL_FONT:
506 m_panel_label_font = font;
507 break;
508 default:
509 wxFAIL_MSG(wxT("Invalid Metric Ordinal"));
510 break;
511 }
512 }
513
514 wxFont wxRibbonMSWArtProvider::GetFont(int id) const
515 {
516 switch(id)
517 {
518 case wxRIBBON_ART_TAB_LABEL_FONT:
519 return m_tab_label_font;
520 case wxRIBBON_ART_BUTTON_BAR_LABEL_FONT:
521 return m_button_bar_label_font;
522 case wxRIBBON_ART_PANEL_LABEL_FONT:
523 return m_panel_label_font;
524 default:
525 wxFAIL_MSG(wxT("Invalid Metric Ordinal"));
526 break;
527 }
528
529 return wxNullFont;
530 }
531
532 wxColour wxRibbonMSWArtProvider::GetColour(int id) const
533 {
534 switch(id)
535 {
536 case wxRIBBON_ART_BUTTON_BAR_LABEL_COLOUR:
537 return m_button_bar_label_colour;
538 case wxRIBBON_ART_BUTTON_BAR_HOVER_BORDER_COLOUR:
539 return m_button_bar_hover_border_pen.GetColour();
540 case wxRIBBON_ART_BUTTON_BAR_HOVER_BACKGROUND_TOP_COLOUR:
541 return m_button_bar_hover_background_top_colour;
542 case wxRIBBON_ART_BUTTON_BAR_HOVER_BACKGROUND_TOP_GRADIENT_COLOUR:
543 return m_button_bar_hover_background_top_gradient_colour;
544 case wxRIBBON_ART_BUTTON_BAR_HOVER_BACKGROUND_COLOUR:
545 return m_button_bar_hover_background_colour;
546 case wxRIBBON_ART_BUTTON_BAR_HOVER_BACKGROUND_GRADIENT_COLOUR:
547 return m_button_bar_hover_background_gradient_colour;
548 case wxRIBBON_ART_BUTTON_BAR_ACTIVE_BORDER_COLOUR:
549 return m_button_bar_active_border_pen.GetColour();
550 case wxRIBBON_ART_BUTTON_BAR_ACTIVE_BACKGROUND_TOP_COLOUR:
551 return m_button_bar_active_background_top_colour;
552 case wxRIBBON_ART_BUTTON_BAR_ACTIVE_BACKGROUND_TOP_GRADIENT_COLOUR:
553 return m_button_bar_active_background_top_gradient_colour;
554 case wxRIBBON_ART_BUTTON_BAR_ACTIVE_BACKGROUND_COLOUR:
555 return m_button_bar_active_background_colour;
556 case wxRIBBON_ART_BUTTON_BAR_ACTIVE_BACKGROUND_GRADIENT_COLOUR:
557 return m_button_bar_active_background_gradient_colour;
558 case wxRIBBON_ART_GALLERY_BORDER_COLOUR:
559 return m_gallery_border_pen.GetColour();
560 case wxRIBBON_ART_GALLERY_HOVER_BACKGROUND_COLOUR:
561 return m_gallery_hover_background_brush.GetColour();
562 case wxRIBBON_ART_GALLERY_BUTTON_BACKGROUND_COLOUR:
563 return m_gallery_button_background_colour;
564 case wxRIBBON_ART_GALLERY_BUTTON_BACKGROUND_GRADIENT_COLOUR:
565 return m_gallery_button_background_gradient_colour;
566 case wxRIBBON_ART_GALLERY_BUTTON_BACKGROUND_TOP_COLOUR:
567 return m_gallery_button_background_top_brush.GetColour();
568 case wxRIBBON_ART_GALLERY_BUTTON_FACE_COLOUR:
569 return m_gallery_button_face_colour;
570 case wxRIBBON_ART_GALLERY_BUTTON_HOVER_BACKGROUND_COLOUR:
571 return m_gallery_button_hover_background_colour;
572 case wxRIBBON_ART_GALLERY_BUTTON_HOVER_BACKGROUND_GRADIENT_COLOUR:
573 return m_gallery_button_hover_background_gradient_colour;
574 case wxRIBBON_ART_GALLERY_BUTTON_HOVER_BACKGROUND_TOP_COLOUR:
575 return m_gallery_button_hover_background_top_brush.GetColour();
576 case wxRIBBON_ART_GALLERY_BUTTON_HOVER_FACE_COLOUR:
577 return m_gallery_button_face_colour;
578 case wxRIBBON_ART_GALLERY_BUTTON_ACTIVE_BACKGROUND_COLOUR:
579 return m_gallery_button_active_background_colour;
580 case wxRIBBON_ART_GALLERY_BUTTON_ACTIVE_BACKGROUND_GRADIENT_COLOUR:
581 return m_gallery_button_active_background_gradient_colour;
582 case wxRIBBON_ART_GALLERY_BUTTON_ACTIVE_BACKGROUND_TOP_COLOUR:
583 return m_gallery_button_background_top_brush.GetColour();
584 case wxRIBBON_ART_GALLERY_BUTTON_ACTIVE_FACE_COLOUR:
585 return m_gallery_button_active_face_colour;
586 case wxRIBBON_ART_GALLERY_BUTTON_DISABLED_BACKGROUND_COLOUR:
587 return m_gallery_button_disabled_background_colour;
588 case wxRIBBON_ART_GALLERY_BUTTON_DISABLED_BACKGROUND_GRADIENT_COLOUR:
589 return m_gallery_button_disabled_background_gradient_colour;
590 case wxRIBBON_ART_GALLERY_BUTTON_DISABLED_BACKGROUND_TOP_COLOUR:
591 return m_gallery_button_disabled_background_top_brush.GetColour();
592 case wxRIBBON_ART_GALLERY_BUTTON_DISABLED_FACE_COLOUR:
593 return m_gallery_button_disabled_face_colour;
594 case wxRIBBON_ART_GALLERY_ITEM_BORDER_COLOUR:
595 return m_gallery_item_border_pen.GetColour();
596 case wxRIBBON_ART_TAB_CTRL_BACKGROUND_COLOUR:
597 case wxRIBBON_ART_TAB_CTRL_BACKGROUND_GRADIENT_COLOUR:
598 return m_tab_ctrl_background_brush.GetColour();
599 case wxRIBBON_ART_TAB_LABEL_COLOUR:
600 return m_tab_label_colour;
601 case wxRIBBON_ART_TAB_SEPARATOR_COLOUR:
602 return m_tab_separator_colour;
603 case wxRIBBON_ART_TAB_SEPARATOR_GRADIENT_COLOUR:
604 return m_tab_separator_gradient_colour;
605 case wxRIBBON_ART_TAB_ACTIVE_BACKGROUND_TOP_COLOUR:
606 case wxRIBBON_ART_TAB_ACTIVE_BACKGROUND_TOP_GRADIENT_COLOUR:
607 return wxColour(0, 0, 0);
608 case wxRIBBON_ART_TAB_ACTIVE_BACKGROUND_COLOUR:
609 return m_tab_active_background_colour;
610 case wxRIBBON_ART_TAB_ACTIVE_BACKGROUND_GRADIENT_COLOUR:
611 return m_tab_active_background_gradient_colour;
612 case wxRIBBON_ART_TAB_HOVER_BACKGROUND_TOP_COLOUR:
613 return m_tab_hover_background_top_colour;
614 case wxRIBBON_ART_TAB_HOVER_BACKGROUND_TOP_GRADIENT_COLOUR:
615 return m_tab_hover_background_top_gradient_colour;
616 case wxRIBBON_ART_TAB_HOVER_BACKGROUND_COLOUR:
617 return m_tab_hover_background_colour;
618 case wxRIBBON_ART_TAB_HOVER_BACKGROUND_GRADIENT_COLOUR:
619 return m_tab_hover_background_gradient_colour;
620 case wxRIBBON_ART_TAB_BORDER_COLOUR:
621 return m_tab_border_pen.GetColour();
622 case wxRIBBON_ART_PANEL_BORDER_COLOUR:
623 return m_panel_border_pen.GetColour();
624 case wxRIBBON_ART_PANEL_BORDER_GRADIENT_COLOUR:
625 return m_panel_border_gradient_pen.GetColour();
626 case wxRIBBON_ART_PANEL_MINIMISED_BORDER_COLOUR:
627 return m_panel_minimised_border_pen.GetColour();
628 case wxRIBBON_ART_PANEL_MINIMISED_BORDER_GRADIENT_COLOUR:
629 return m_panel_minimised_border_gradient_pen.GetColour();
630 case wxRIBBON_ART_PANEL_LABEL_BACKGROUND_COLOUR:
631 case wxRIBBON_ART_PANEL_LABEL_BACKGROUND_GRADIENT_COLOUR:
632 return m_panel_label_background_brush.GetColour();
633 case wxRIBBON_ART_PANEL_LABEL_COLOUR:
634 return m_panel_label_colour;
635 case wxRIBBON_ART_PANEL_MINIMISED_LABEL_COLOUR:
636 return m_panel_minimised_label_colour;
637 case wxRIBBON_ART_PANEL_HOVER_LABEL_BACKGROUND_COLOUR:
638 case wxRIBBON_ART_PANEL_HOVER_LABEL_BACKGROUND_GRADIENT_COLOUR:
639 return m_panel_hover_label_background_brush.GetColour();
640 case wxRIBBON_ART_PANEL_HOVER_LABEL_COLOUR:
641 return m_panel_hover_label_colour;
642 case wxRIBBON_ART_PANEL_ACTIVE_BACKGROUND_TOP_COLOUR:
643 return m_panel_active_background_top_colour;
644 case wxRIBBON_ART_PANEL_ACTIVE_BACKGROUND_TOP_GRADIENT_COLOUR:
645 return m_panel_active_background_top_gradient_colour;
646 case wxRIBBON_ART_PANEL_ACTIVE_BACKGROUND_COLOUR:
647 return m_panel_active_background_colour;
648 case wxRIBBON_ART_PANEL_ACTIVE_BACKGROUND_GRADIENT_COLOUR:
649 return m_panel_active_background_gradient_colour;
650 case wxRIBBON_ART_PAGE_BORDER_COLOUR:
651 return m_page_border_pen.GetColour();
652 case wxRIBBON_ART_PAGE_BACKGROUND_TOP_COLOUR:
653 return m_page_background_top_colour;
654 case wxRIBBON_ART_PAGE_BACKGROUND_TOP_GRADIENT_COLOUR:
655 return m_page_background_top_gradient_colour;
656 case wxRIBBON_ART_PAGE_BACKGROUND_COLOUR:
657 return m_page_background_colour;
658 case wxRIBBON_ART_PAGE_BACKGROUND_GRADIENT_COLOUR:
659 return m_page_background_gradient_colour;
660 case wxRIBBON_ART_PAGE_HOVER_BACKGROUND_TOP_COLOUR:
661 return m_page_hover_background_top_colour;
662 case wxRIBBON_ART_PAGE_HOVER_BACKGROUND_TOP_GRADIENT_COLOUR:
663 return m_page_hover_background_top_gradient_colour;
664 case wxRIBBON_ART_PAGE_HOVER_BACKGROUND_COLOUR:
665 return m_page_hover_background_colour;
666 case wxRIBBON_ART_PAGE_HOVER_BACKGROUND_GRADIENT_COLOUR:
667 return m_page_hover_background_gradient_colour;
668 case wxRIBBON_ART_TOOLBAR_BORDER_COLOUR:
669 case wxRIBBON_ART_TOOLBAR_HOVER_BORDER_COLOUR:
670 return m_toolbar_border_pen.GetColour();
671 case wxRIBBON_ART_TOOLBAR_FACE_COLOUR:
672 return m_tool_face_colour;
673 default:
674 wxFAIL_MSG(wxT("Invalid Metric Ordinal"));
675 break;
676 }
677
678 return wxColour();
679 }
680
681 void wxRibbonMSWArtProvider::SetColour(int id, const wxColor& colour)
682 {
683 switch(id)
684 {
685 case wxRIBBON_ART_BUTTON_BAR_LABEL_COLOUR:
686 m_button_bar_label_colour = colour;
687 break;
688 case wxRIBBON_ART_BUTTON_BAR_HOVER_BORDER_COLOUR:
689 m_button_bar_hover_border_pen.SetColour(colour);
690 break;
691 case wxRIBBON_ART_BUTTON_BAR_HOVER_BACKGROUND_TOP_COLOUR:
692 m_button_bar_hover_background_top_colour = colour;
693 break;
694 case wxRIBBON_ART_BUTTON_BAR_HOVER_BACKGROUND_TOP_GRADIENT_COLOUR:
695 m_button_bar_hover_background_top_gradient_colour = colour;
696 break;
697 case wxRIBBON_ART_BUTTON_BAR_HOVER_BACKGROUND_COLOUR:
698 m_button_bar_hover_background_colour = colour;
699 break;
700 case wxRIBBON_ART_BUTTON_BAR_HOVER_BACKGROUND_GRADIENT_COLOUR:
701 m_button_bar_hover_background_gradient_colour = colour;
702 break;
703 case wxRIBBON_ART_BUTTON_BAR_ACTIVE_BORDER_COLOUR:
704 m_button_bar_active_border_pen.SetColour(colour);
705 break;
706 case wxRIBBON_ART_BUTTON_BAR_ACTIVE_BACKGROUND_TOP_COLOUR:
707 m_button_bar_active_background_top_colour = colour;
708 break;
709 case wxRIBBON_ART_BUTTON_BAR_ACTIVE_BACKGROUND_TOP_GRADIENT_COLOUR:
710 m_button_bar_active_background_top_gradient_colour = colour;
711 break;
712 case wxRIBBON_ART_BUTTON_BAR_ACTIVE_BACKGROUND_COLOUR:
713 m_button_bar_active_background_colour = colour;
714 break;
715 case wxRIBBON_ART_BUTTON_BAR_ACTIVE_BACKGROUND_GRADIENT_COLOUR:
716 m_button_bar_active_background_gradient_colour = colour;
717 break;
718 case wxRIBBON_ART_GALLERY_BORDER_COLOUR:
719 m_gallery_border_pen.SetColour(colour);
720 break;
721 case wxRIBBON_ART_GALLERY_HOVER_BACKGROUND_COLOUR:
722 m_gallery_hover_background_brush.SetColour(colour);
723 break;
724 case wxRIBBON_ART_GALLERY_BUTTON_BACKGROUND_COLOUR:
725 m_gallery_button_background_colour = colour;
726 break;
727 case wxRIBBON_ART_GALLERY_BUTTON_BACKGROUND_GRADIENT_COLOUR:
728 m_gallery_button_background_gradient_colour = colour;
729 break;
730 case wxRIBBON_ART_GALLERY_BUTTON_BACKGROUND_TOP_COLOUR:
731 m_gallery_button_background_top_brush.SetColour(colour);
732 break;
733 case wxRIBBON_ART_GALLERY_BUTTON_FACE_COLOUR:
734 m_gallery_button_face_colour = colour;
735 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
736 {
737 m_gallery_up_bitmap[0] = wxRibbonLoadPixmap(gallery_left_xpm, colour);
738 m_gallery_down_bitmap[0] = wxRibbonLoadPixmap(gallery_right_xpm, colour);
739 }
740 else
741 {
742 m_gallery_up_bitmap[0] = wxRibbonLoadPixmap(gallery_up_xpm, colour);
743 m_gallery_down_bitmap[0] = wxRibbonLoadPixmap(gallery_down_xpm, colour);
744 }
745 m_gallery_extension_bitmap[0] = wxRibbonLoadPixmap(gallery_extension_xpm, colour);
746 break;
747 case wxRIBBON_ART_GALLERY_BUTTON_HOVER_BACKGROUND_COLOUR:
748 m_gallery_button_hover_background_colour = colour;
749 break;
750 case wxRIBBON_ART_GALLERY_BUTTON_HOVER_BACKGROUND_GRADIENT_COLOUR:
751 m_gallery_button_hover_background_gradient_colour = colour;
752 break;
753 case wxRIBBON_ART_GALLERY_BUTTON_HOVER_BACKGROUND_TOP_COLOUR:
754 m_gallery_button_hover_background_top_brush.SetColour(colour);
755 break;
756 case wxRIBBON_ART_GALLERY_BUTTON_HOVER_FACE_COLOUR:
757 m_gallery_button_hover_face_colour = colour;
758 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
759 {
760 m_gallery_up_bitmap[1] = wxRibbonLoadPixmap(gallery_left_xpm, colour);
761 m_gallery_down_bitmap[1] = wxRibbonLoadPixmap(gallery_right_xpm, colour);
762 }
763 else
764 {
765 m_gallery_up_bitmap[1] = wxRibbonLoadPixmap(gallery_up_xpm, colour);
766 m_gallery_down_bitmap[1] = wxRibbonLoadPixmap(gallery_down_xpm, colour);
767 }
768 m_gallery_extension_bitmap[1] = wxRibbonLoadPixmap(gallery_extension_xpm, colour);
769 break;
770 case wxRIBBON_ART_GALLERY_BUTTON_ACTIVE_BACKGROUND_COLOUR:
771 m_gallery_button_active_background_colour = colour;
772 break;
773 case wxRIBBON_ART_GALLERY_BUTTON_ACTIVE_BACKGROUND_GRADIENT_COLOUR:
774 m_gallery_button_active_background_gradient_colour = colour;
775 break;
776 case wxRIBBON_ART_GALLERY_BUTTON_ACTIVE_BACKGROUND_TOP_COLOUR:
777 m_gallery_button_background_top_brush.SetColour(colour);
778 break;
779 case wxRIBBON_ART_GALLERY_BUTTON_ACTIVE_FACE_COLOUR:
780 m_gallery_button_active_face_colour = colour;
781 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
782 {
783 m_gallery_up_bitmap[2] = wxRibbonLoadPixmap(gallery_left_xpm, colour);
784 m_gallery_down_bitmap[2] = wxRibbonLoadPixmap(gallery_right_xpm, colour);
785 }
786 else
787 {
788 m_gallery_up_bitmap[2] = wxRibbonLoadPixmap(gallery_up_xpm, colour);
789 m_gallery_down_bitmap[2] = wxRibbonLoadPixmap(gallery_down_xpm, colour);
790 }
791 m_gallery_extension_bitmap[2] = wxRibbonLoadPixmap(gallery_extension_xpm, colour);
792 break;
793 case wxRIBBON_ART_GALLERY_BUTTON_DISABLED_BACKGROUND_COLOUR:
794 m_gallery_button_disabled_background_colour = colour;
795 break;
796 case wxRIBBON_ART_GALLERY_BUTTON_DISABLED_BACKGROUND_GRADIENT_COLOUR:
797 m_gallery_button_disabled_background_gradient_colour = colour;
798 break;
799 case wxRIBBON_ART_GALLERY_BUTTON_DISABLED_BACKGROUND_TOP_COLOUR:
800 m_gallery_button_disabled_background_top_brush.SetColour(colour);
801 break;
802 case wxRIBBON_ART_GALLERY_BUTTON_DISABLED_FACE_COLOUR:
803 m_gallery_button_disabled_face_colour = colour;
804 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
805 {
806 m_gallery_up_bitmap[3] = wxRibbonLoadPixmap(gallery_left_xpm, colour);
807 m_gallery_down_bitmap[3] = wxRibbonLoadPixmap(gallery_right_xpm, colour);
808 }
809 else
810 {
811 m_gallery_up_bitmap[3] = wxRibbonLoadPixmap(gallery_up_xpm, colour);
812 m_gallery_down_bitmap[3] = wxRibbonLoadPixmap(gallery_down_xpm, colour);
813 }
814 m_gallery_extension_bitmap[3] = wxRibbonLoadPixmap(gallery_extension_xpm, colour);
815 break;
816 case wxRIBBON_ART_GALLERY_ITEM_BORDER_COLOUR:
817 m_gallery_item_border_pen.SetColour(colour);
818 break;
819 case wxRIBBON_ART_TAB_CTRL_BACKGROUND_COLOUR:
820 case wxRIBBON_ART_TAB_CTRL_BACKGROUND_GRADIENT_COLOUR:
821 m_tab_ctrl_background_brush.SetColour(colour);
822 m_cached_tab_separator_visibility = -1.0;
823 break;
824 case wxRIBBON_ART_TAB_LABEL_COLOUR:
825 m_tab_label_colour = colour;
826 break;
827 case wxRIBBON_ART_TAB_SEPARATOR_COLOUR:
828 m_tab_separator_colour = colour;
829 m_cached_tab_separator_visibility = -1.0;
830 break;
831 case wxRIBBON_ART_TAB_SEPARATOR_GRADIENT_COLOUR:
832 m_tab_separator_gradient_colour = colour;
833 m_cached_tab_separator_visibility = -1.0;
834 break;
835 case wxRIBBON_ART_TAB_ACTIVE_BACKGROUND_TOP_COLOUR:
836 case wxRIBBON_ART_TAB_ACTIVE_BACKGROUND_TOP_GRADIENT_COLOUR:
837 break;
838 case wxRIBBON_ART_TAB_ACTIVE_BACKGROUND_COLOUR:
839 m_tab_active_background_colour = colour;
840 break;
841 case wxRIBBON_ART_TAB_ACTIVE_BACKGROUND_GRADIENT_COLOUR:
842 m_tab_active_background_gradient_colour = colour;
843 break;
844 case wxRIBBON_ART_TAB_HOVER_BACKGROUND_TOP_COLOUR:
845 m_tab_hover_background_top_colour = colour;
846 break;
847 case wxRIBBON_ART_TAB_HOVER_BACKGROUND_TOP_GRADIENT_COLOUR:
848 m_tab_hover_background_top_gradient_colour = colour;
849 break;
850 case wxRIBBON_ART_TAB_HOVER_BACKGROUND_COLOUR:
851 m_tab_hover_background_colour = colour;
852 break;
853 case wxRIBBON_ART_TAB_HOVER_BACKGROUND_GRADIENT_COLOUR:
854 m_tab_hover_background_gradient_colour = colour;
855 break;
856 case wxRIBBON_ART_TAB_BORDER_COLOUR:
857 m_tab_border_pen.SetColour(colour);
858 break;
859 case wxRIBBON_ART_PANEL_BORDER_COLOUR:
860 m_panel_border_pen.SetColour(colour);
861 break;
862 case wxRIBBON_ART_PANEL_BORDER_GRADIENT_COLOUR:
863 m_panel_border_gradient_pen.SetColour(colour);
864 break;
865 case wxRIBBON_ART_PANEL_MINIMISED_BORDER_COLOUR:
866 m_panel_minimised_border_pen.SetColour(colour);
867 break;
868 case wxRIBBON_ART_PANEL_MINIMISED_BORDER_GRADIENT_COLOUR:
869 m_panel_minimised_border_gradient_pen.SetColour(colour);
870 break;
871 case wxRIBBON_ART_PANEL_LABEL_BACKGROUND_COLOUR:
872 case wxRIBBON_ART_PANEL_LABEL_BACKGROUND_GRADIENT_COLOUR:
873 m_panel_label_background_brush.SetColour(colour);
874 break;
875 case wxRIBBON_ART_PANEL_LABEL_COLOUR:
876 m_panel_label_colour = colour;
877 break;
878 case wxRIBBON_ART_PANEL_HOVER_LABEL_BACKGROUND_COLOUR:
879 case wxRIBBON_ART_PANEL_HOVER_LABEL_BACKGROUND_GRADIENT_COLOUR:
880 m_panel_hover_label_background_brush.SetColour(colour);
881 break;
882 case wxRIBBON_ART_PANEL_HOVER_LABEL_COLOUR:
883 m_panel_hover_label_colour = colour;
884 break;
885 case wxRIBBON_ART_PANEL_MINIMISED_LABEL_COLOUR:
886 m_panel_minimised_label_colour = colour;
887 break;
888 case wxRIBBON_ART_PANEL_ACTIVE_BACKGROUND_TOP_COLOUR:
889 m_panel_active_background_top_colour = colour;
890 break;
891 case wxRIBBON_ART_PANEL_ACTIVE_BACKGROUND_TOP_GRADIENT_COLOUR:
892 m_panel_active_background_top_gradient_colour = colour;
893 break;
894 case wxRIBBON_ART_PANEL_ACTIVE_BACKGROUND_COLOUR:
895 m_panel_active_background_colour = colour;
896 break;
897 case wxRIBBON_ART_PANEL_ACTIVE_BACKGROUND_GRADIENT_COLOUR:
898 m_panel_active_background_gradient_colour = colour;
899 break;
900 case wxRIBBON_ART_PAGE_BORDER_COLOUR:
901 m_page_border_pen.SetColour(colour);
902 break;
903 case wxRIBBON_ART_PAGE_BACKGROUND_TOP_COLOUR:
904 m_page_background_top_colour = colour;
905 break;
906 case wxRIBBON_ART_PAGE_BACKGROUND_TOP_GRADIENT_COLOUR:
907 m_page_background_top_gradient_colour = colour;
908 break;
909 case wxRIBBON_ART_PAGE_BACKGROUND_COLOUR:
910 m_page_background_colour = colour;
911 break;
912 case wxRIBBON_ART_PAGE_BACKGROUND_GRADIENT_COLOUR:
913 m_page_background_gradient_colour = colour;
914 break;
915 case wxRIBBON_ART_PAGE_HOVER_BACKGROUND_TOP_COLOUR:
916 m_page_hover_background_top_colour = colour;
917 break;
918 case wxRIBBON_ART_PAGE_HOVER_BACKGROUND_TOP_GRADIENT_COLOUR:
919 m_page_hover_background_top_gradient_colour = colour;
920 break;
921 case wxRIBBON_ART_PAGE_HOVER_BACKGROUND_COLOUR:
922 m_page_hover_background_colour = colour;
923 break;
924 case wxRIBBON_ART_PAGE_HOVER_BACKGROUND_GRADIENT_COLOUR:
925 m_page_hover_background_gradient_colour = colour;
926 break;
927 case wxRIBBON_ART_TOOLBAR_BORDER_COLOUR:
928 case wxRIBBON_ART_TOOLBAR_HOVER_BORDER_COLOUR:
929 m_toolbar_border_pen.SetColour(colour);
930 break;
931 case wxRIBBON_ART_TOOLBAR_FACE_COLOUR:
932 m_tool_face_colour = colour;
933 m_toolbar_drop_bitmap = wxRibbonLoadPixmap(gallery_down_xpm, colour);
934 break;
935 default:
936 wxFAIL_MSG(wxT("Invalid Metric Ordinal"));
937 break;
938 }
939 }
940
941 void wxRibbonMSWArtProvider::DrawTabCtrlBackground(
942 wxDC& dc,
943 wxWindow* WXUNUSED(wnd),
944 const wxRect& rect)
945 {
946 dc.SetPen(*wxTRANSPARENT_PEN);
947 dc.SetBrush(m_tab_ctrl_background_brush);
948 dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height);
949
950 dc.SetPen(m_page_border_pen);
951 if(rect.width > 6)
952 {
953 dc.DrawLine(rect.x + 3, rect.y + rect.height - 1, rect.x + rect.width - 3, rect.y + rect.height - 1);
954 }
955 else
956 {
957 dc.DrawLine(rect.x, rect.y + rect.height - 1, rect.x + rect.width, rect.y + rect.height - 1);
958 }
959 }
960
961 void wxRibbonMSWArtProvider::DrawTab(
962 wxDC& dc,
963 wxWindow* WXUNUSED(wnd),
964 const wxRibbonPageTabInfo& tab)
965 {
966 if(tab.rect.height <= 2)
967 return;
968
969 if(tab.active || tab.hovered)
970 {
971 if(tab.active)
972 {
973 wxRect background(tab.rect);
974
975 background.x += 2;
976 background.y += 2;
977 background.width -= 4;
978 background.height -= 2;
979
980 dc.GradientFillLinear(background, m_tab_active_background_colour,
981 m_tab_active_background_gradient_colour, wxSOUTH);
982
983 // TODO: active and hovered
984 }
985 else if(tab.hovered)
986 {
987 wxRect background(tab.rect);
988
989 background.x += 2;
990 background.y += 2;
991 background.width -= 4;
992 background.height -= 3;
993 int h = background.height;
994 background.height /= 2;
995 dc.GradientFillLinear(background,
996 m_tab_hover_background_top_colour,
997 m_tab_hover_background_top_gradient_colour, wxSOUTH);
998
999 background.y += background.height;
1000 background.height = h - background.height;
1001 dc.GradientFillLinear(background, m_tab_hover_background_colour,
1002 m_tab_hover_background_gradient_colour, wxSOUTH);
1003 }
1004
1005 wxPoint border_points[6];
1006 border_points[0] = wxPoint(1, tab.rect.height - 2);
1007 border_points[1] = wxPoint(1, 3);
1008 border_points[2] = wxPoint(3, 1);
1009 border_points[3] = wxPoint(tab.rect.width - 4, 1);
1010 border_points[4] = wxPoint(tab.rect.width - 2, 3);
1011 border_points[5] = wxPoint(tab.rect.width - 2, tab.rect.height - 1);
1012
1013 dc.SetPen(m_tab_border_pen);
1014 dc.DrawLines(sizeof(border_points)/sizeof(wxPoint), border_points, tab.rect.x, tab.rect.y);
1015
1016 if(tab.active)
1017 {
1018 // Give the tab a curved outward border at the bottom
1019 dc.DrawPoint(tab.rect.x, tab.rect.y + tab.rect.height - 2);
1020 dc.DrawPoint(tab.rect.x + tab.rect.width - 1, tab.rect.y + tab.rect.height - 2);
1021
1022 wxPen p(m_tab_active_background_gradient_colour);
1023 dc.SetPen(p);
1024
1025 // Technically the first two points are the wrong colour, but they're near enough
1026 dc.DrawPoint(tab.rect.x + 1, tab.rect.y + tab.rect.height - 2);
1027 dc.DrawPoint(tab.rect.x + tab.rect.width - 2, tab.rect.y + tab.rect.height - 2);
1028 dc.DrawPoint(tab.rect.x + 1, tab.rect.y + tab.rect.height - 1);
1029 dc.DrawPoint(tab.rect.x, tab.rect.y + tab.rect.height - 1);
1030 dc.DrawPoint(tab.rect.x + tab.rect.width - 2, tab.rect.y + tab.rect.height - 1);
1031 dc.DrawPoint(tab.rect.x + tab.rect.width - 1, tab.rect.y + tab.rect.height - 1);
1032 }
1033 }
1034
1035 if(m_flags & wxRIBBON_BAR_SHOW_PAGE_ICONS)
1036 {
1037 wxBitmap icon = tab.page->GetIcon();
1038 if(icon.IsOk())
1039 {
1040 int x = tab.rect.x + 4;
1041 if((m_flags & wxRIBBON_BAR_SHOW_PAGE_LABELS) == 0)
1042 x = tab.rect.x + (tab.rect.width - icon.GetWidth()) / 2;
1043 dc.DrawBitmap(icon, x, tab.rect.y + 1 + (tab.rect.height - 1 -
1044 icon.GetHeight()) / 2, true);
1045 }
1046 }
1047 if(m_flags & wxRIBBON_BAR_SHOW_PAGE_LABELS)
1048 {
1049 wxString label = tab.page->GetLabel();
1050 if(!label.IsEmpty())
1051 {
1052 dc.SetFont(m_tab_label_font);
1053 dc.SetTextForeground(m_tab_label_colour);
1054 dc.SetBackgroundMode(wxTRANSPARENT);
1055
1056 int text_height;
1057 int text_width;
1058 dc.GetTextExtent(label, &text_width, &text_height);
1059 int width = tab.rect.width - 5;
1060 int x = tab.rect.x + 3;
1061 if(m_flags & wxRIBBON_BAR_SHOW_PAGE_ICONS)
1062 {
1063 x += 3 + tab.page->GetIcon().GetWidth();
1064 width -= 3 + tab.page->GetIcon().GetWidth();
1065 }
1066 int y = tab.rect.y + (tab.rect.height - text_height) / 2;
1067
1068 if(width <= text_width)
1069 {
1070 dc.SetClippingRegion(x, tab.rect.y, width, tab.rect.height);
1071 dc.DrawText(label, x, y);
1072 }
1073 else
1074 {
1075 dc.DrawText(label, x + (width - text_width) / 2 + 1, y);
1076 }
1077 }
1078 }
1079 }
1080
1081 void wxRibbonMSWArtProvider::DrawTabSeparator(
1082 wxDC& dc,
1083 wxWindow* wnd,
1084 const wxRect& rect,
1085 double visibility)
1086 {
1087 if(visibility <= 0.0)
1088 {
1089 return;
1090 }
1091 if(visibility > 1.0)
1092 {
1093 visibility = 1.0;
1094 }
1095
1096 // The tab separator is relatively expensive to draw (for its size), and is
1097 // usually drawn multiple times sequentially (in different positions), so it
1098 // makes sense to draw it once and cache it.
1099 if(!m_cached_tab_separator.IsOk() || m_cached_tab_separator.GetSize() != rect.GetSize() || visibility != m_cached_tab_separator_visibility)
1100 {
1101 wxRect size(rect.GetSize());
1102 ReallyDrawTabSeparator(wnd, size, visibility);
1103 }
1104 dc.DrawBitmap(m_cached_tab_separator, rect.x, rect.y, false);
1105 }
1106
1107 void wxRibbonMSWArtProvider::ReallyDrawTabSeparator(wxWindow* wnd, const wxRect& rect, double visibility)
1108 {
1109 if(!m_cached_tab_separator.IsOk() || m_cached_tab_separator.GetSize() != rect.GetSize())
1110 {
1111 m_cached_tab_separator = wxBitmap(rect.GetSize());
1112 }
1113
1114 wxMemoryDC dc(m_cached_tab_separator);
1115 DrawTabCtrlBackground(dc, wnd, rect);
1116
1117 wxCoord x = rect.x + rect.width / 2;
1118 double h = (double)(rect.height - 1);
1119
1120 double r1 = m_tab_ctrl_background_brush.GetColour().Red() * (1.0 - visibility) + 0.5;
1121 double g1 = m_tab_ctrl_background_brush.GetColour().Green() * (1.0 - visibility) + 0.5;
1122 double b1 = m_tab_ctrl_background_brush.GetColour().Blue() * (1.0 - visibility) + 0.5;
1123 double r2 = m_tab_separator_colour.Red();
1124 double g2 = m_tab_separator_colour.Green();
1125 double b2 = m_tab_separator_colour.Blue();
1126 double r3 = m_tab_separator_gradient_colour.Red();
1127 double g3 = m_tab_separator_gradient_colour.Green();
1128 double b3 = m_tab_separator_gradient_colour.Blue();
1129
1130 for(int i = 0; i < rect.height - 1; ++i)
1131 {
1132 double p = ((double)i)/h;
1133
1134 double r = (p * r3 + (1.0 - p) * r2) * visibility + r1;
1135 double g = (p * g3 + (1.0 - p) * g2) * visibility + g1;
1136 double b = (p * b3 + (1.0 - p) * b2) * visibility + b1;
1137
1138 wxPen P(wxColour((unsigned char)r, (unsigned char)g, (unsigned char)b));
1139 dc.SetPen(P);
1140 dc.DrawPoint(x, rect.y + i);
1141 }
1142
1143 m_cached_tab_separator_visibility = visibility;
1144 }
1145
1146 void wxRibbonMSWArtProvider::DrawPartialPageBackground(wxDC& dc,
1147 wxWindow* wnd, const wxRect& rect, wxRibbonPage* page,
1148 wxPoint offset, bool hovered)
1149 {
1150 wxRect background;
1151 // Expanded panels need a background - the expanded panel at
1152 // best size may have a greater Y dimension higher than when
1153 // on the bar if it has a sizer. AUI art provider does not need this
1154 // because it paints the panel without reference to its parent's size.
1155 // Expanded panels use a wxFrame as parent (not a wxRibbonPage).
1156
1157 if(wnd->GetSizer() && wnd->GetParent() != page)
1158 {
1159 background = wnd->GetParent()->GetSize();
1160 offset = wxPoint(0,0);
1161 }
1162 else
1163 {
1164 background = page->GetSize();
1165 page->AdjustRectToIncludeScrollButtons(&background);
1166 background.height -= 2;
1167 }
1168 // Page background isn't dependant upon the width of the page
1169 // (at least not the part of it intended to be painted by this
1170 // function). Set to wider than the page itself for when externally
1171 // expanded panels need a background - the expanded panel can be wider
1172 // than the bar.
1173 background.x = 0;
1174 background.width = INT_MAX;
1175
1176 // upper_rect, lower_rect, paint_rect are all in page co-ordinates
1177 wxRect upper_rect(background);
1178 upper_rect.height /= 5;
1179
1180 wxRect lower_rect(background);
1181 lower_rect.y += upper_rect.height;
1182 lower_rect.height -= upper_rect.height;
1183
1184 wxRect paint_rect(rect);
1185 paint_rect.x += offset.x;
1186 paint_rect.y += offset.y;
1187
1188 wxColour bg_top, bg_top_grad, bg_btm, bg_btm_grad;
1189 if(hovered)
1190 {
1191 bg_top = m_page_hover_background_top_colour;
1192 bg_top_grad = m_page_hover_background_top_gradient_colour;
1193 bg_btm = m_page_hover_background_colour;
1194 bg_btm_grad = m_page_hover_background_gradient_colour;
1195 }
1196 else
1197 {
1198 bg_top = m_page_background_top_colour;
1199 bg_top_grad = m_page_background_top_gradient_colour;
1200 bg_btm = m_page_background_colour;
1201 bg_btm_grad = m_page_background_gradient_colour;
1202 }
1203
1204 if(paint_rect.Intersects(upper_rect))
1205 {
1206 wxRect rect(upper_rect);
1207 rect.Intersect(paint_rect);
1208 rect.x -= offset.x;
1209 rect.y -= offset.y;
1210 wxColour starting_colour(wxRibbonInterpolateColour(bg_top, bg_top_grad,
1211 paint_rect.y, upper_rect.y, upper_rect.y + upper_rect.height));
1212 wxColour ending_colour(wxRibbonInterpolateColour(bg_top, bg_top_grad,
1213 paint_rect.y + paint_rect.height, upper_rect.y,
1214 upper_rect.y + upper_rect.height));
1215 dc.GradientFillLinear(rect, starting_colour, ending_colour, wxSOUTH);
1216 }
1217
1218 if(paint_rect.Intersects(lower_rect))
1219 {
1220 wxRect rect(lower_rect);
1221 rect.Intersect(paint_rect);
1222 rect.x -= offset.x;
1223 rect.y -= offset.y;
1224 wxColour starting_colour(wxRibbonInterpolateColour(bg_btm, bg_btm_grad,
1225 paint_rect.y, lower_rect.y, lower_rect.y + lower_rect.height));
1226 wxColour ending_colour(wxRibbonInterpolateColour(bg_btm, bg_btm_grad,
1227 paint_rect.y + paint_rect.height,
1228 lower_rect.y, lower_rect.y + lower_rect.height));
1229 dc.GradientFillLinear(rect, starting_colour, ending_colour, wxSOUTH);
1230 }
1231 }
1232
1233 void wxRibbonMSWArtProvider::DrawPageBackground(
1234 wxDC& dc,
1235 wxWindow* WXUNUSED(wnd),
1236 const wxRect& rect)
1237 {
1238 dc.SetPen(*wxTRANSPARENT_PEN);
1239 dc.SetBrush(m_tab_ctrl_background_brush);
1240
1241 {
1242 wxRect edge(rect);
1243
1244 edge.width = 2;
1245 dc.DrawRectangle(edge.x, edge.y, edge.width, edge.height);
1246
1247 edge.x += rect.width - 2;
1248 dc.DrawRectangle(edge.x, edge.y, edge.width, edge.height);
1249
1250 edge = rect;
1251 edge.height = 2;
1252 edge.y += (rect.height - edge.height);
1253 dc.DrawRectangle(edge.x, edge.y, edge.width, edge.height);
1254 }
1255
1256 {
1257 wxRect background(rect);
1258 background.x += 2;
1259 background.width -= 4;
1260 background.height -= 2;
1261
1262 background.height /= 5;
1263 dc.GradientFillLinear(background, m_page_background_top_colour,
1264 m_page_background_top_gradient_colour, wxSOUTH);
1265
1266 background.y += background.height;
1267 background.height = rect.height - 2 - background.height;
1268 dc.GradientFillLinear(background, m_page_background_colour,
1269 m_page_background_gradient_colour, wxSOUTH);
1270 }
1271
1272 {
1273 wxPoint border_points[8];
1274 border_points[0] = wxPoint(2, 0);
1275 border_points[1] = wxPoint(1, 1);
1276 border_points[2] = wxPoint(1, rect.height - 4);
1277 border_points[3] = wxPoint(3, rect.height - 2);
1278 border_points[4] = wxPoint(rect.width - 4, rect.height - 2);
1279 border_points[5] = wxPoint(rect.width - 2, rect.height - 4);
1280 border_points[6] = wxPoint(rect.width - 2, 1);
1281 border_points[7] = wxPoint(rect.width - 4, -1);
1282
1283 dc.SetPen(m_page_border_pen);
1284 dc.DrawLines(sizeof(border_points)/sizeof(wxPoint), border_points, rect.x, rect.y);
1285 }
1286 }
1287
1288 void wxRibbonMSWArtProvider::DrawScrollButton(
1289 wxDC& dc,
1290 wxWindow* WXUNUSED(wnd),
1291 const wxRect& rect_,
1292 long style)
1293 {
1294 wxRect rect(rect_);
1295
1296 if((style & wxRIBBON_SCROLL_BTN_FOR_MASK) == wxRIBBON_SCROLL_BTN_FOR_PAGE)
1297 {
1298 // Page scroll buttons do not have the luxury of rendering on top of anything
1299 // else, and their size includes some padding, hence the background painting
1300 // and size adjustment.
1301 dc.SetPen(*wxTRANSPARENT_PEN);
1302 dc.SetBrush(m_tab_ctrl_background_brush);
1303 dc.DrawRectangle(rect);
1304 dc.SetClippingRegion(rect);
1305 switch(style & wxRIBBON_SCROLL_BTN_DIRECTION_MASK)
1306 {
1307 case wxRIBBON_SCROLL_BTN_LEFT:
1308 rect.x++;
1309 case wxRIBBON_SCROLL_BTN_RIGHT:
1310 rect.y--;
1311 rect.width--;
1312 break;
1313 case wxRIBBON_SCROLL_BTN_UP:
1314 rect.x++;
1315 rect.y--;
1316 rect.width -= 2;
1317 rect.height++;
1318 break;
1319 case wxRIBBON_SCROLL_BTN_DOWN:
1320 rect.x++;
1321 rect.width -= 2;
1322 rect.height--;
1323 break;
1324 }
1325 }
1326
1327 {
1328 wxRect background(rect);
1329 background.x++;
1330 background.y++;
1331 background.width -= 2;
1332 background.height -= 2;
1333
1334 if(style & wxRIBBON_SCROLL_BTN_UP)
1335 background.height /= 2;
1336 else
1337 background.height /= 5;
1338 dc.GradientFillLinear(background, m_page_background_top_colour,
1339 m_page_background_top_gradient_colour, wxSOUTH);
1340
1341 background.y += background.height;
1342 background.height = rect.height - 2 - background.height;
1343 dc.GradientFillLinear(background, m_page_background_colour,
1344 m_page_background_gradient_colour, wxSOUTH);
1345 }
1346
1347 {
1348 wxPoint border_points[7];
1349 switch(style & wxRIBBON_SCROLL_BTN_DIRECTION_MASK)
1350 {
1351 case wxRIBBON_SCROLL_BTN_LEFT:
1352 border_points[0] = wxPoint(2, 0);
1353 border_points[1] = wxPoint(rect.width - 1, 0);
1354 border_points[2] = wxPoint(rect.width - 1, rect.height - 1);
1355 border_points[3] = wxPoint(2, rect.height - 1);
1356 border_points[4] = wxPoint(0, rect.height - 3);
1357 border_points[5] = wxPoint(0, 2);
1358 break;
1359 case wxRIBBON_SCROLL_BTN_RIGHT:
1360 border_points[0] = wxPoint(0, 0);
1361 border_points[1] = wxPoint(rect.width - 3, 0);
1362 border_points[2] = wxPoint(rect.width - 1, 2);
1363 border_points[3] = wxPoint(rect.width - 1, rect.height - 3);
1364 border_points[4] = wxPoint(rect.width - 3, rect.height - 1);
1365 border_points[5] = wxPoint(0, rect.height - 1);
1366 break;
1367 case wxRIBBON_SCROLL_BTN_UP:
1368 border_points[0] = wxPoint(2, 0);
1369 border_points[1] = wxPoint(rect.width - 3, 0);
1370 border_points[2] = wxPoint(rect.width - 1, 2);
1371 border_points[3] = wxPoint(rect.width - 1, rect.height - 1);
1372 border_points[4] = wxPoint(0, rect.height - 1);
1373 border_points[5] = wxPoint(0, 2);
1374 break;
1375 case wxRIBBON_SCROLL_BTN_DOWN:
1376 border_points[0] = wxPoint(0, 0);
1377 border_points[1] = wxPoint(rect.width - 1, 0);
1378 border_points[2] = wxPoint(rect.width - 1, rect.height - 3);
1379 border_points[3] = wxPoint(rect.width - 3, rect.height - 1);
1380 border_points[4] = wxPoint(2, rect.height - 1);
1381 border_points[5] = wxPoint(0, rect.height - 3);
1382 break;
1383 }
1384 border_points[6] = border_points[0];
1385
1386 dc.SetPen(m_page_border_pen);
1387 dc.DrawLines(sizeof(border_points)/sizeof(wxPoint), border_points, rect.x, rect.y);
1388 }
1389
1390 {
1391 // NB: Code for handling hovered/active state is temporary
1392 wxPoint arrow_points[3];
1393 switch(style & wxRIBBON_SCROLL_BTN_DIRECTION_MASK)
1394 {
1395 case wxRIBBON_SCROLL_BTN_LEFT:
1396 arrow_points[0] = wxPoint(rect.width / 2 - 2, rect.height / 2);
1397 if(style & wxRIBBON_SCROLL_BTN_ACTIVE)
1398 arrow_points[0].y += 1;
1399 arrow_points[1] = arrow_points[0] + wxPoint(3, -3);
1400 arrow_points[2] = arrow_points[0] + wxPoint(3, 3);
1401 break;
1402 case wxRIBBON_SCROLL_BTN_RIGHT:
1403 arrow_points[0] = wxPoint(rect.width / 2 + 2, rect.height / 2);
1404 if(style & wxRIBBON_SCROLL_BTN_ACTIVE)
1405 arrow_points[0].y += 1;
1406 arrow_points[1] = arrow_points[0] - wxPoint(3, 3);
1407 arrow_points[2] = arrow_points[0] - wxPoint(3, -3);
1408 break;
1409 case wxRIBBON_SCROLL_BTN_UP:
1410 arrow_points[0] = wxPoint(rect.width / 2, rect.height / 2 - 2);
1411 if(style & wxRIBBON_SCROLL_BTN_ACTIVE)
1412 arrow_points[0].y += 1;
1413 arrow_points[1] = arrow_points[0] + wxPoint( 3, 3);
1414 arrow_points[2] = arrow_points[0] + wxPoint(-3, 3);
1415 break;
1416 case wxRIBBON_SCROLL_BTN_DOWN:
1417 arrow_points[0] = wxPoint(rect.width / 2, rect.height / 2 + 2);
1418 if(style & wxRIBBON_SCROLL_BTN_ACTIVE)
1419 arrow_points[0].y += 1;
1420 arrow_points[1] = arrow_points[0] - wxPoint( 3, 3);
1421 arrow_points[2] = arrow_points[0] - wxPoint(-3, 3);
1422 break;
1423 }
1424
1425 dc.SetPen(*wxTRANSPARENT_PEN);
1426 wxBrush B(style & wxRIBBON_SCROLL_BTN_HOVERED ? m_tab_active_background_colour : m_tab_label_colour);
1427 dc.SetBrush(B);
1428 dc.DrawPolygon(sizeof(arrow_points)/sizeof(wxPoint), arrow_points, rect.x, rect.y);
1429 }
1430 }
1431
1432 void wxRibbonMSWArtProvider::DrawDropdownArrow(wxDC& dc, int x, int y, const wxColour& colour)
1433 {
1434 wxPoint arrow_points[3];
1435 wxBrush brush(colour);
1436 arrow_points[0] = wxPoint(1, 2);
1437 arrow_points[1] = arrow_points[0] + wxPoint(-3, -3);
1438 arrow_points[2] = arrow_points[0] + wxPoint( 3, -3);
1439 dc.SetPen(*wxTRANSPARENT_PEN);
1440 dc.SetBrush(brush);
1441 dc.DrawPolygon(sizeof(arrow_points)/sizeof(wxPoint), arrow_points, x, y);
1442 }
1443
1444 void wxRibbonMSWArtProvider::RemovePanelPadding(wxRect* rect)
1445 {
1446 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
1447 {
1448 rect->y += 1;
1449 rect->height -= 2;
1450 }
1451 else
1452 {
1453 rect->x += 1;
1454 rect->width -= 2;
1455 }
1456 }
1457
1458 void wxRibbonMSWArtProvider::DrawPanelBackground(
1459 wxDC& dc,
1460 wxRibbonPanel* wnd,
1461 const wxRect& rect)
1462 {
1463 DrawPartialPageBackground(dc, wnd, rect, false);
1464
1465 wxRect true_rect(rect);
1466 RemovePanelPadding(&true_rect);
1467
1468 int label_height;
1469 {
1470 dc.SetFont(m_panel_label_font);
1471 dc.SetPen(*wxTRANSPARENT_PEN);
1472 if(wnd->IsHovered())
1473 {
1474 dc.SetBrush(m_panel_hover_label_background_brush);
1475 dc.SetTextForeground(m_panel_hover_label_colour);
1476 }
1477 else
1478 {
1479 dc.SetBrush(m_panel_label_background_brush);
1480 dc.SetTextForeground(m_panel_label_colour);
1481 }
1482
1483 wxRect label_rect(true_rect);
1484 wxString label = wnd->GetLabel();
1485 bool clip_label = false;
1486 wxSize label_size(dc.GetTextExtent(label));
1487
1488 label_rect.SetX(label_rect.GetX() + 1);
1489 label_rect.SetWidth(label_rect.GetWidth() - 2);
1490 label_rect.SetHeight(label_size.GetHeight() + 2);
1491 label_rect.SetY(true_rect.GetBottom() - label_rect.GetHeight());
1492 label_height = label_rect.GetHeight();
1493
1494 if(label_size.GetWidth() > label_rect.GetWidth())
1495 {
1496 // Test if there is enough length for 3 letters and ...
1497 wxString new_label = label.Mid(0, 3) + wxT("...");
1498 label_size = dc.GetTextExtent(new_label);
1499 if(label_size.GetWidth() > label_rect.GetWidth())
1500 {
1501 // Not enough room for three characters and ...
1502 // Display the entire label and just crop it
1503 clip_label = true;
1504 }
1505 else
1506 {
1507 // Room for some characters and ...
1508 // Display as many characters as possible and append ...
1509 for(size_t len = label.Len() - 1; len >= 3; --len)
1510 {
1511 new_label = label.Mid(0, len) + wxT("...");
1512 label_size = dc.GetTextExtent(new_label);
1513 if(label_size.GetWidth() <= label_rect.GetWidth())
1514 {
1515 label = new_label;
1516 break;
1517 }
1518 }
1519 }
1520 }
1521
1522 dc.DrawRectangle(label_rect.GetX(), label_rect.GetY(), label_rect.GetWidth(), label_rect.GetHeight());
1523 if(clip_label)
1524 {
1525 wxDCClipper clip(dc, label_rect);
1526 dc.DrawText(label, label_rect.x, label_rect.y +
1527 (label_rect.GetHeight() - label_size.GetHeight()) / 2);
1528 }
1529 else
1530 {
1531 dc.DrawText(label, label_rect.x +
1532 (label_rect.GetWidth() - label_size.GetWidth()) / 2,
1533 label_rect.y +
1534 (label_rect.GetHeight() - label_size.GetHeight()) / 2);
1535 }
1536 }
1537
1538 if(wnd->IsHovered())
1539 {
1540 wxRect client_rect(true_rect);
1541 client_rect.x++;
1542 client_rect.width -= 2;
1543 client_rect.y++;
1544 client_rect.height -= 2 + label_height;
1545 DrawPartialPageBackground(dc, wnd, client_rect, true);
1546 }
1547
1548 DrawPanelBorder(dc, true_rect, m_panel_border_pen, m_panel_border_gradient_pen);
1549 }
1550
1551 void wxRibbonMSWArtProvider::DrawGalleryBackground(
1552 wxDC& dc,
1553 wxRibbonGallery* wnd,
1554 const wxRect& rect)
1555 {
1556 DrawPartialPageBackground(dc, wnd, rect);
1557
1558 if(wnd->IsHovered())
1559 {
1560 dc.SetPen(*wxTRANSPARENT_PEN);
1561 dc.SetBrush(m_gallery_hover_background_brush);
1562 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
1563 {
1564 dc.DrawRectangle(rect.x + 1, rect.y + 1, rect.width - 2,
1565 rect.height - 16);
1566 }
1567 else
1568 {
1569 dc.DrawRectangle(rect.x + 1, rect.y + 1, rect.width - 16,
1570 rect.height - 2);
1571 }
1572 }
1573
1574 dc.SetPen(m_gallery_border_pen);
1575 // Outline
1576 dc.DrawLine(rect.x + 1, rect.y, rect.x + rect.width - 1, rect.y);
1577 dc.DrawLine(rect.x, rect.y + 1, rect.x, rect.y + rect.height - 1);
1578 dc.DrawLine(rect.x + 1, rect.y + rect.height - 1, rect.x + rect.width - 1,
1579 rect.y + rect.height - 1);
1580 dc.DrawLine(rect.x + rect.width - 1, rect.y + 1, rect.x + rect.width - 1,
1581 rect.y + rect.height - 1);
1582
1583 DrawGalleryBackgroundCommon(dc, wnd, rect);
1584 }
1585
1586 void wxRibbonMSWArtProvider::DrawGalleryBackgroundCommon(wxDC& dc,
1587 wxRibbonGallery* wnd,
1588 const wxRect& rect)
1589 {
1590 wxRect up_btn, down_btn, ext_btn;
1591
1592 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
1593 {
1594 // Divider between items and buttons
1595 dc.DrawLine(rect.x, rect.y + rect.height - 15, rect.x + rect.width,
1596 rect.y + rect.height - 15);
1597
1598 up_btn = wxRect(rect.x, rect.y + rect.height - 15, rect.width / 3, 15);
1599
1600 down_btn = wxRect(up_btn.GetRight() + 1, up_btn.GetTop(),
1601 up_btn.GetWidth(), up_btn.GetHeight());
1602 dc.DrawLine(down_btn.GetLeft(), down_btn.GetTop(), down_btn.GetLeft(),
1603 down_btn.GetBottom());
1604
1605 ext_btn = wxRect(down_btn.GetRight() + 1, up_btn.GetTop(), rect.width -
1606 up_btn.GetWidth() - down_btn.GetWidth() - 1, up_btn.GetHeight());
1607 dc.DrawLine(ext_btn.GetLeft(), ext_btn.GetTop(), ext_btn.GetLeft(),
1608 ext_btn.GetBottom());
1609 }
1610 else
1611 {
1612 // Divider between items and buttons
1613 dc.DrawLine(rect.x + rect.width - 15, rect.y, rect.x + rect.width - 15,
1614 rect.y + rect.height);
1615
1616 up_btn = wxRect(rect.x + rect.width - 15, rect.y, 15, rect.height / 3);
1617
1618 down_btn = wxRect(up_btn.GetLeft(), up_btn.GetBottom() + 1,
1619 up_btn.GetWidth(), up_btn.GetHeight());
1620 dc.DrawLine(down_btn.GetLeft(), down_btn.GetTop(), down_btn.GetRight(),
1621 down_btn.GetTop());
1622
1623 ext_btn = wxRect(up_btn.GetLeft(), down_btn.GetBottom() + 1, up_btn.GetWidth(),
1624 rect.height - up_btn.GetHeight() - down_btn.GetHeight() - 1);
1625 dc.DrawLine(ext_btn.GetLeft(), ext_btn.GetTop(), ext_btn.GetRight(),
1626 ext_btn.GetTop());
1627 }
1628
1629 DrawGalleryButton(dc, up_btn, wnd->GetUpButtonState(),
1630 m_gallery_up_bitmap);
1631 DrawGalleryButton(dc, down_btn, wnd->GetDownButtonState(),
1632 m_gallery_down_bitmap);
1633 DrawGalleryButton(dc, ext_btn, wnd->GetExtensionButtonState(),
1634 m_gallery_extension_bitmap);
1635 }
1636
1637 void wxRibbonMSWArtProvider::DrawGalleryButton(wxDC& dc,
1638 wxRect rect,
1639 wxRibbonGalleryButtonState state,
1640 wxBitmap* bitmaps)
1641 {
1642 wxBitmap btn_bitmap;
1643 wxBrush btn_top_brush;
1644 wxColour btn_colour;
1645 wxColour btn_grad_colour;
1646 switch(state)
1647 {
1648 case wxRIBBON_GALLERY_BUTTON_NORMAL:
1649 btn_top_brush = m_gallery_button_background_top_brush;
1650 btn_colour = m_gallery_button_background_colour;
1651 btn_grad_colour = m_gallery_button_background_gradient_colour;
1652 btn_bitmap = bitmaps[0];
1653 break;
1654 case wxRIBBON_GALLERY_BUTTON_HOVERED:
1655 btn_top_brush = m_gallery_button_hover_background_top_brush;
1656 btn_colour = m_gallery_button_hover_background_colour;
1657 btn_grad_colour = m_gallery_button_hover_background_gradient_colour;
1658 btn_bitmap = bitmaps[1];
1659 break;
1660 case wxRIBBON_GALLERY_BUTTON_ACTIVE:
1661 btn_top_brush = m_gallery_button_active_background_top_brush;
1662 btn_colour = m_gallery_button_active_background_colour;
1663 btn_grad_colour = m_gallery_button_active_background_gradient_colour;
1664 btn_bitmap = bitmaps[2];
1665 break;
1666 case wxRIBBON_GALLERY_BUTTON_DISABLED:
1667 btn_top_brush = m_gallery_button_disabled_background_top_brush;
1668 btn_colour = m_gallery_button_disabled_background_colour;
1669 btn_grad_colour = m_gallery_button_disabled_background_gradient_colour;
1670 btn_bitmap = bitmaps[3];
1671 break;
1672 }
1673
1674 rect.x++;
1675 rect.y++;
1676 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
1677 {
1678 rect.width--;;
1679 rect.height -= 2;
1680 }
1681 else
1682 {
1683 rect.width -= 2;
1684 rect.height--;
1685 }
1686
1687 dc.SetPen(*wxTRANSPARENT_PEN);
1688 dc.SetBrush(btn_top_brush);
1689 dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height / 2);
1690
1691 wxRect lower(rect);
1692 lower.height = (lower.height + 1) / 2;
1693 lower.y += rect.height - lower.height;
1694 dc.GradientFillLinear(lower, btn_colour, btn_grad_colour, wxSOUTH);
1695
1696 dc.DrawBitmap(btn_bitmap, rect.x + rect.width / 2 - 2, lower.y - 2, true);
1697 }
1698
1699 void wxRibbonMSWArtProvider::DrawGalleryItemBackground(
1700 wxDC& dc,
1701 wxRibbonGallery* wnd,
1702 const wxRect& rect,
1703 wxRibbonGalleryItem* item)
1704 {
1705 if(wnd->GetHoveredItem() != item && wnd->GetActiveItem() != item &&
1706 wnd->GetSelection() != item)
1707 return;
1708
1709 dc.SetPen(m_gallery_item_border_pen);
1710 dc.DrawLine(rect.x + 1, rect.y, rect.x + rect.width - 1, rect.y);
1711 dc.DrawLine(rect.x, rect.y + 1, rect.x, rect.y + rect.height - 1);
1712 dc.DrawLine(rect.x + 1, rect.y + rect.height - 1, rect.x + rect.width - 1,
1713 rect.y + rect.height - 1);
1714 dc.DrawLine(rect.x + rect.width - 1, rect.y + 1, rect.x + rect.width - 1,
1715 rect.y + rect.height - 1);
1716
1717 wxBrush top_brush;
1718 wxColour bg_colour;
1719 wxColour bg_gradient_colour;
1720
1721 if(wnd->GetActiveItem() == item || wnd->GetSelection() == item)
1722 {
1723 top_brush = m_gallery_button_active_background_top_brush;
1724 bg_colour = m_gallery_button_active_background_colour;
1725 bg_gradient_colour = m_gallery_button_active_background_gradient_colour;
1726 }
1727 else
1728 {
1729 top_brush = m_gallery_button_hover_background_top_brush;
1730 bg_colour = m_gallery_button_hover_background_colour;
1731 bg_gradient_colour = m_gallery_button_hover_background_gradient_colour;
1732 }
1733
1734 wxRect upper(rect);
1735 upper.x += 1;
1736 upper.width -= 2;
1737 upper.y += 1;
1738 upper.height /= 3;
1739 dc.SetPen(*wxTRANSPARENT_PEN);
1740 dc.SetBrush(top_brush);
1741 dc.DrawRectangle(upper.x, upper.y, upper.width, upper.height);
1742
1743 wxRect lower(upper);
1744 lower.y += lower.height;
1745 lower.height = rect.height - 2 - lower.height;
1746 dc.GradientFillLinear(lower, bg_colour, bg_gradient_colour, wxSOUTH);
1747 }
1748
1749 void wxRibbonMSWArtProvider::DrawPanelBorder(wxDC& dc, const wxRect& rect,
1750 wxPen& primary_colour,
1751 wxPen& secondary_colour)
1752 {
1753 wxPoint border_points[9];
1754 border_points[0] = wxPoint(2, 0);
1755 border_points[1] = wxPoint(rect.width - 3, 0);
1756 border_points[2] = wxPoint(rect.width - 1, 2);
1757 border_points[3] = wxPoint(rect.width - 1, rect.height - 3);
1758 border_points[4] = wxPoint(rect.width - 3, rect.height - 1);
1759 border_points[5] = wxPoint(2, rect.height - 1);
1760 border_points[6] = wxPoint(0, rect.height - 3);
1761 border_points[7] = wxPoint(0, 2);
1762
1763 if(primary_colour.GetColour() == secondary_colour.GetColour())
1764 {
1765 border_points[8] = border_points[0];
1766 dc.SetPen(primary_colour);
1767 dc.DrawLines(sizeof(border_points)/sizeof(wxPoint), border_points, rect.x, rect.y);
1768 }
1769 else
1770 {
1771 dc.SetPen(primary_colour);
1772 dc.DrawLines(3, border_points, rect.x, rect.y);
1773
1774 #define SingleLine(start, finish) \
1775 dc.DrawLine(start.x + rect.x, start.y + rect.y, finish.x + rect.x, finish.y + rect.y)
1776
1777 SingleLine(border_points[0], border_points[7]);
1778 dc.SetPen(secondary_colour);
1779 dc.DrawLines(3, border_points + 4, rect.x, rect.y);
1780 SingleLine(border_points[4], border_points[3]);
1781
1782 #undef SingleLine
1783
1784 border_points[6] = border_points[2];
1785 wxRibbonDrawParallelGradientLines(dc, 2, border_points + 6, 0, 1,
1786 border_points[3].y - border_points[2].y + 1, rect.x, rect.y,
1787 primary_colour.GetColour(), secondary_colour.GetColour());
1788 }
1789 }
1790
1791 void wxRibbonMSWArtProvider::DrawMinimisedPanel(
1792 wxDC& dc,
1793 wxRibbonPanel* wnd,
1794 const wxRect& rect,
1795 wxBitmap& bitmap)
1796 {
1797 DrawPartialPageBackground(dc, wnd, rect, false);
1798
1799 wxRect true_rect(rect);
1800 RemovePanelPadding(&true_rect);
1801
1802 if(wnd->GetExpandedPanel() != NULL)
1803 {
1804 wxRect client_rect(true_rect);
1805 client_rect.x++;
1806 client_rect.width -= 2;
1807 client_rect.y++;
1808 client_rect.height = (rect.y + rect.height / 5) - client_rect.x;
1809 dc.GradientFillLinear(client_rect,
1810 m_panel_active_background_top_colour,
1811 m_panel_active_background_top_gradient_colour, wxSOUTH);
1812
1813 client_rect.y += client_rect.height;
1814 client_rect.height = (true_rect.y + true_rect.height) - client_rect.y;
1815 dc.GradientFillLinear(client_rect,
1816 m_panel_active_background_colour,
1817 m_panel_active_background_gradient_colour, wxSOUTH);
1818 }
1819 else if(wnd->IsHovered())
1820 {
1821 wxRect client_rect(true_rect);
1822 client_rect.x++;
1823 client_rect.width -= 2;
1824 client_rect.y++;
1825 client_rect.height -= 2;
1826 DrawPartialPageBackground(dc, wnd, client_rect, true);
1827 }
1828
1829 wxRect preview;
1830 DrawMinimisedPanelCommon(dc, wnd, true_rect, &preview);
1831
1832 dc.SetBrush(m_panel_hover_label_background_brush);
1833 dc.SetPen(*wxTRANSPARENT_PEN);
1834 dc.DrawRectangle(preview.x + 1, preview.y + preview.height - 8,
1835 preview.width - 2, 7);
1836
1837 int mid_pos = rect.y + rect.height / 5 - preview.y;
1838 if(mid_pos < 0 || mid_pos >= preview.height)
1839 {
1840 wxRect full_rect(preview);
1841 full_rect.x += 1;
1842 full_rect.y += 1;
1843 full_rect.width -= 2;
1844 full_rect.height -= 9;
1845 if(mid_pos < 0)
1846 {
1847 dc.GradientFillLinear(full_rect,
1848 m_page_hover_background_colour,
1849 m_page_hover_background_gradient_colour, wxSOUTH);
1850 }
1851 else
1852 {
1853 dc.GradientFillLinear(full_rect,
1854 m_page_hover_background_top_colour,
1855 m_page_hover_background_top_gradient_colour, wxSOUTH);
1856 }
1857 }
1858 else
1859 {
1860 wxRect top_rect(preview);
1861 top_rect.x += 1;
1862 top_rect.y += 1;
1863 top_rect.width -= 2;
1864 top_rect.height = mid_pos;
1865 dc.GradientFillLinear(top_rect,
1866 m_page_hover_background_top_colour,
1867 m_page_hover_background_top_gradient_colour, wxSOUTH);
1868
1869 wxRect btm_rect(top_rect);
1870 btm_rect.y = preview.y + mid_pos;
1871 btm_rect.height = preview.y + preview.height - 7 - btm_rect.y;
1872 dc.GradientFillLinear(btm_rect,
1873 m_page_hover_background_colour,
1874 m_page_hover_background_gradient_colour, wxSOUTH);
1875 }
1876
1877 if(bitmap.IsOk())
1878 {
1879 dc.DrawBitmap(bitmap, preview.x + (preview.width - bitmap.GetWidth()) / 2,
1880 preview.y + (preview.height - 7 - bitmap.GetHeight()) / 2, true);
1881 }
1882
1883 DrawPanelBorder(dc, preview, m_panel_border_pen, m_panel_border_gradient_pen);
1884
1885 DrawPanelBorder(dc, true_rect, m_panel_minimised_border_pen,
1886 m_panel_minimised_border_gradient_pen);
1887 }
1888
1889 void wxRibbonMSWArtProvider::DrawMinimisedPanelCommon(
1890 wxDC& dc,
1891 wxRibbonPanel* wnd,
1892 const wxRect& true_rect,
1893 wxRect* preview_rect)
1894 {
1895 wxRect preview(0, 0, 32, 32);
1896 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
1897 {
1898 preview.x = true_rect.x + 4;
1899 preview.y = true_rect.y + (true_rect.height - preview.height) / 2;
1900 }
1901 else
1902 {
1903 preview.x = true_rect.x + (true_rect.width - preview.width) / 2;
1904 preview.y = true_rect.y + 4;
1905 }
1906 if(preview_rect)
1907 *preview_rect = preview;
1908
1909 wxCoord label_width, label_height;
1910 dc.SetFont(m_panel_label_font);
1911 dc.GetTextExtent(wnd->GetLabel(), &label_width, &label_height);
1912
1913 int xpos = true_rect.x + (true_rect.width - label_width + 1) / 2;
1914 int ypos = preview.y + preview.height + 5;
1915
1916 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
1917 {
1918 xpos = preview.x + preview.width + 5;
1919 ypos = true_rect.y + (true_rect.height - label_height) / 2;
1920 }
1921
1922 dc.SetTextForeground(m_panel_minimised_label_colour);
1923 dc.DrawText(wnd->GetLabel(), xpos, ypos);
1924
1925
1926 wxPoint arrow_points[3];
1927 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
1928 {
1929 xpos += label_width;
1930 arrow_points[0] = wxPoint(xpos + 5, ypos + label_height / 2);
1931 arrow_points[1] = arrow_points[0] + wxPoint(-3, 3);
1932 arrow_points[2] = arrow_points[0] + wxPoint(-3, -3);
1933 }
1934 else
1935 {
1936 ypos += label_height;
1937 arrow_points[0] = wxPoint(true_rect.width / 2, ypos + 5);
1938 arrow_points[1] = arrow_points[0] + wxPoint(-3, -3);
1939 arrow_points[2] = arrow_points[0] + wxPoint( 3, -3);
1940 }
1941
1942 dc.SetPen(*wxTRANSPARENT_PEN);
1943 wxBrush B(m_panel_minimised_label_colour);
1944 dc.SetBrush(B);
1945 dc.DrawPolygon(sizeof(arrow_points)/sizeof(wxPoint), arrow_points,
1946 true_rect.x, true_rect.y);
1947 }
1948
1949 void wxRibbonMSWArtProvider::DrawButtonBarBackground(
1950 wxDC& dc,
1951 wxWindow* wnd,
1952 const wxRect& rect)
1953 {
1954 DrawPartialPageBackground(dc, wnd, rect, true);
1955 }
1956
1957 void wxRibbonMSWArtProvider::DrawPartialPageBackground(
1958 wxDC& dc,
1959 wxWindow* wnd,
1960 const wxRect& rect,
1961 bool allow_hovered)
1962 {
1963 // Assume the window is a child of a ribbon page, and also check for a
1964 // hovered panel somewhere between the window and the page, as it causes
1965 // the background to change.
1966 wxPoint offset(wnd->GetPosition());
1967 wxRibbonPage* page = NULL;
1968 wxWindow* parent = wnd->GetParent();
1969 wxRibbonPanel* panel = wxDynamicCast(wnd, wxRibbonPanel);
1970 bool hovered = false;
1971
1972 if(panel != NULL)
1973 {
1974 hovered = allow_hovered && panel->IsHovered();
1975 if(panel->GetExpandedDummy() != NULL)
1976 {
1977 offset = panel->GetExpandedDummy()->GetPosition();
1978 parent = panel->GetExpandedDummy()->GetParent();
1979 }
1980 }
1981 for(; parent; parent = parent->GetParent())
1982 {
1983 if(panel == NULL)
1984 {
1985 panel = wxDynamicCast(parent, wxRibbonPanel);
1986 if(panel != NULL)
1987 {
1988 hovered = allow_hovered && panel->IsHovered();
1989 if(panel->GetExpandedDummy() != NULL)
1990 {
1991 parent = panel->GetExpandedDummy();
1992 }
1993 }
1994 }
1995 page = wxDynamicCast(parent, wxRibbonPage);
1996 if(page != NULL)
1997 {
1998 break;
1999 }
2000 offset += parent->GetPosition();
2001 }
2002 if(page != NULL)
2003 {
2004 DrawPartialPageBackground(dc, wnd, rect, page, offset, hovered);
2005 return;
2006 }
2007
2008 // No page found - fallback to painting with a stock brush
2009 dc.SetBrush(*wxWHITE_BRUSH);
2010 dc.SetPen(*wxTRANSPARENT_PEN);
2011 dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height);
2012 }
2013
2014 void wxRibbonMSWArtProvider::DrawButtonBarButton(
2015 wxDC& dc,
2016 wxWindow* WXUNUSED(wnd),
2017 const wxRect& rect,
2018 wxRibbonButtonKind kind,
2019 long state,
2020 const wxString& label,
2021 const wxBitmap& bitmap_large,
2022 const wxBitmap& bitmap_small)
2023 {
2024 if(kind == wxRIBBON_BUTTON_TOGGLE)
2025 {
2026 kind = wxRIBBON_BUTTON_NORMAL;
2027 if(state & wxRIBBON_BUTTONBAR_BUTTON_TOGGLED)
2028 state ^= wxRIBBON_BUTTONBAR_BUTTON_ACTIVE_MASK;
2029 }
2030
2031 if(state & (wxRIBBON_BUTTONBAR_BUTTON_HOVER_MASK |
2032 wxRIBBON_BUTTONBAR_BUTTON_ACTIVE_MASK))
2033 {
2034 if(state & wxRIBBON_BUTTONBAR_BUTTON_ACTIVE_MASK)
2035 dc.SetPen(m_button_bar_active_border_pen);
2036 else
2037 dc.SetPen(m_button_bar_hover_border_pen);
2038
2039 wxRect bg_rect(rect);
2040 bg_rect.x++;
2041 bg_rect.y++;
2042 bg_rect.width -= 2;
2043 bg_rect.height -= 2;
2044
2045 wxRect bg_rect_top(bg_rect);
2046 bg_rect_top.height /= 3;
2047 bg_rect.y += bg_rect_top.height;
2048 bg_rect.height -= bg_rect_top.height;
2049
2050 if(kind == wxRIBBON_BUTTON_HYBRID)
2051 {
2052 switch(state & wxRIBBON_BUTTONBAR_BUTTON_SIZE_MASK)
2053 {
2054 case wxRIBBON_BUTTONBAR_BUTTON_LARGE:
2055 {
2056 int iYBorder = rect.y + bitmap_large.GetHeight() + 4;
2057 wxRect partial_bg(rect);
2058 if(state & wxRIBBON_BUTTONBAR_BUTTON_NORMAL_HOVERED)
2059 {
2060 partial_bg.SetBottom(iYBorder - 1);
2061 }
2062 else
2063 {
2064 partial_bg.height -= (iYBorder - partial_bg.y + 1);
2065 partial_bg.y = iYBorder + 1;
2066 }
2067 dc.DrawLine(rect.x, iYBorder, rect.x + rect.width, iYBorder);
2068 bg_rect.Intersect(partial_bg);
2069 bg_rect_top.Intersect(partial_bg);
2070 }
2071 break;
2072 case wxRIBBON_BUTTONBAR_BUTTON_MEDIUM:
2073 {
2074 int iArrowWidth = 9;
2075 if(state & wxRIBBON_BUTTONBAR_BUTTON_NORMAL_HOVERED)
2076 {
2077 bg_rect.width -= iArrowWidth;
2078 bg_rect_top.width -= iArrowWidth;
2079 dc.DrawLine(bg_rect_top.x + bg_rect_top.width,
2080 rect.y, bg_rect_top.x + bg_rect_top.width,
2081 rect.y + rect.height);
2082 }
2083 else
2084 {
2085 --iArrowWidth;
2086 bg_rect.x += bg_rect.width - iArrowWidth;
2087 bg_rect_top.x += bg_rect_top.width - iArrowWidth;
2088 bg_rect.width = iArrowWidth;
2089 bg_rect_top.width = iArrowWidth;
2090 dc.DrawLine(bg_rect_top.x - 1, rect.y,
2091 bg_rect_top.x - 1, rect.y + rect.height);
2092 }
2093 }
2094 break;
2095 case wxRIBBON_BUTTONBAR_BUTTON_SMALL:
2096 break;
2097 }
2098 }
2099
2100 if(state & wxRIBBON_BUTTONBAR_BUTTON_ACTIVE_MASK)
2101 {
2102 dc.GradientFillLinear(bg_rect_top,
2103 m_button_bar_active_background_top_colour,
2104 m_button_bar_active_background_top_gradient_colour, wxSOUTH);
2105 dc.GradientFillLinear(bg_rect,
2106 m_button_bar_active_background_colour,
2107 m_button_bar_active_background_gradient_colour, wxSOUTH);
2108 }
2109 else
2110 {
2111 dc.GradientFillLinear(bg_rect_top,
2112 m_button_bar_hover_background_top_colour,
2113 m_button_bar_hover_background_top_gradient_colour, wxSOUTH);
2114 dc.GradientFillLinear(bg_rect,
2115 m_button_bar_hover_background_colour,
2116 m_button_bar_hover_background_gradient_colour, wxSOUTH);
2117 }
2118
2119 wxPoint border_points[9];
2120 border_points[0] = wxPoint(2, 0);
2121 border_points[1] = wxPoint(rect.width - 3, 0);
2122 border_points[2] = wxPoint(rect.width - 1, 2);
2123 border_points[3] = wxPoint(rect.width - 1, rect.height - 3);
2124 border_points[4] = wxPoint(rect.width - 3, rect.height - 1);
2125 border_points[5] = wxPoint(2, rect.height - 1);
2126 border_points[6] = wxPoint(0, rect.height - 3);
2127 border_points[7] = wxPoint(0, 2);
2128 border_points[8] = border_points[0];
2129
2130 dc.DrawLines(sizeof(border_points)/sizeof(wxPoint), border_points,
2131 rect.x, rect.y);
2132 }
2133
2134 dc.SetFont(m_button_bar_label_font);
2135 dc.SetTextForeground(m_button_bar_label_colour);
2136 DrawButtonBarButtonForeground(dc, rect, kind, state, label, bitmap_large,
2137 bitmap_small);
2138 }
2139
2140 void wxRibbonMSWArtProvider::DrawButtonBarButtonForeground(
2141 wxDC& dc,
2142 const wxRect& rect,
2143 wxRibbonButtonKind kind,
2144 long state,
2145 const wxString& label,
2146 const wxBitmap& bitmap_large,
2147 const wxBitmap& bitmap_small)
2148 {
2149 switch(state & wxRIBBON_BUTTONBAR_BUTTON_SIZE_MASK)
2150 {
2151 case wxRIBBON_BUTTONBAR_BUTTON_LARGE:
2152 {
2153 const int padding = 2;
2154 dc.DrawBitmap(bitmap_large,
2155 rect.x + (rect.width - bitmap_large.GetWidth()) / 2,
2156 rect.y + padding, true);
2157 int ypos = rect.y + padding + bitmap_large.GetHeight() + padding;
2158 int arrow_width = kind == wxRIBBON_BUTTON_NORMAL ? 0 : 8;
2159 wxCoord label_w, label_h;
2160 dc.GetTextExtent(label, &label_w, &label_h);
2161 if(label_w + 2 * padding <= rect.width)
2162 {
2163 dc.DrawText(label, rect.x + (rect.width - label_w) / 2, ypos);
2164 if(arrow_width != 0)
2165 {
2166 DrawDropdownArrow(dc, rect.x + rect.width / 2,
2167 ypos + (label_h * 3) / 2,
2168 m_button_bar_label_colour);
2169 }
2170 }
2171 else
2172 {
2173 size_t breaki = label.Len();
2174 do
2175 {
2176 --breaki;
2177 if(wxRibbonCanLabelBreakAtPosition(label, breaki))
2178 {
2179 wxString label_top = label.Mid(0, breaki);
2180 dc.GetTextExtent(label_top, &label_w, &label_h);
2181 if(label_w + 2 * padding <= rect.width)
2182 {
2183 dc.DrawText(label_top,
2184 rect.x + (rect.width - label_w) / 2, ypos);
2185 ypos += label_h;
2186 wxString label_bottom = label.Mid(breaki + 1);
2187 dc.GetTextExtent(label_bottom, &label_w, &label_h);
2188 label_w += arrow_width;
2189 int iX = rect.x + (rect.width - label_w) / 2;
2190 dc.DrawText(label_bottom, iX, ypos);
2191 if(arrow_width != 0)
2192 {
2193 DrawDropdownArrow(dc,
2194 iX + 2 +label_w - arrow_width,
2195 ypos + label_h / 2 + 1,
2196 m_button_bar_label_colour);
2197 }
2198 break;
2199 }
2200 }
2201 } while(breaki > 0);
2202 }
2203 }
2204 break;
2205 case wxRIBBON_BUTTONBAR_BUTTON_MEDIUM:
2206 {
2207 int x_cursor = rect.x + 2;
2208 dc.DrawBitmap(bitmap_small, x_cursor,
2209 rect.y + (rect.height - bitmap_small.GetHeight())/2, true);
2210 x_cursor += bitmap_small.GetWidth() + 2;
2211 wxCoord label_w, label_h;
2212 dc.GetTextExtent(label, &label_w, &label_h);
2213 dc.DrawText(label, x_cursor,
2214 rect.y + (rect.height - label_h) / 2);
2215 x_cursor += label_w + 3;
2216 if(kind != wxRIBBON_BUTTON_NORMAL)
2217 {
2218 DrawDropdownArrow(dc, x_cursor, rect.y + rect.height / 2,
2219 m_button_bar_label_colour);
2220 }
2221 break;
2222 }
2223 default:
2224 // TODO
2225 break;
2226 }
2227 }
2228
2229 void wxRibbonMSWArtProvider::DrawToolBarBackground(
2230 wxDC& dc,
2231 wxWindow* wnd,
2232 const wxRect& rect)
2233 {
2234 DrawPartialPageBackground(dc, wnd, rect);
2235 }
2236
2237 void wxRibbonMSWArtProvider::DrawToolGroupBackground(
2238 wxDC& dc,
2239 wxWindow* WXUNUSED(wnd),
2240 const wxRect& rect)
2241 {
2242 dc.SetPen(m_toolbar_border_pen);
2243 wxPoint outline[9];
2244 outline[0] = wxPoint(2, 0);
2245 outline[1] = wxPoint(rect.width - 3, 0);
2246 outline[2] = wxPoint(rect.width - 1, 2);
2247 outline[3] = wxPoint(rect.width - 1, rect.height - 3);
2248 outline[4] = wxPoint(rect.width - 3, rect.height - 1);
2249 outline[5] = wxPoint(2, rect.height - 1);
2250 outline[6] = wxPoint(0, rect.height - 3);
2251 outline[7] = wxPoint(0, 2);
2252 outline[8] = outline[0];
2253
2254 dc.DrawLines(sizeof(outline)/sizeof(wxPoint), outline, rect.x, rect.y);
2255 }
2256
2257 void wxRibbonMSWArtProvider::DrawTool(
2258 wxDC& dc,
2259 wxWindow* WXUNUSED(wnd),
2260 const wxRect& rect,
2261 const wxBitmap& bitmap,
2262 wxRibbonButtonKind kind,
2263 long state)
2264 {
2265 if(kind == wxRIBBON_BUTTON_TOGGLE)
2266 {
2267 if(state & wxRIBBON_TOOLBAR_TOOL_TOGGLED)
2268 state ^= wxRIBBON_TOOLBAR_TOOL_ACTIVE_MASK;
2269 }
2270
2271 wxRect bg_rect(rect);
2272 bg_rect.Deflate(1);
2273 if((state & wxRIBBON_TOOLBAR_TOOL_LAST) == 0)
2274 bg_rect.width++;
2275 bool is_split_hybrid = (kind == wxRIBBON_BUTTON_HYBRID && (state &
2276 (wxRIBBON_TOOLBAR_TOOL_HOVER_MASK | wxRIBBON_TOOLBAR_TOOL_ACTIVE_MASK)));
2277
2278 // Background
2279 wxRect bg_rect_top(bg_rect);
2280 bg_rect_top.height = (bg_rect_top.height * 2) / 5;
2281 wxRect bg_rect_btm(bg_rect);
2282 bg_rect_btm.y += bg_rect_top.height;
2283 bg_rect_btm.height -= bg_rect_top.height;
2284 wxColour bg_top_colour = m_tool_background_top_colour;
2285 wxColour bg_top_grad_colour = m_tool_background_top_gradient_colour;
2286 wxColour bg_colour = m_tool_background_colour;
2287 wxColour bg_grad_colour = m_tool_background_gradient_colour;
2288 if(state & wxRIBBON_TOOLBAR_TOOL_ACTIVE_MASK)
2289 {
2290 bg_top_colour = m_tool_active_background_top_colour;
2291 bg_top_grad_colour = m_tool_active_background_top_gradient_colour;
2292 bg_colour = m_tool_active_background_colour;
2293 bg_grad_colour = m_tool_active_background_gradient_colour;
2294 }
2295 else if(state & wxRIBBON_TOOLBAR_TOOL_HOVER_MASK)
2296 {
2297 bg_top_colour = m_tool_hover_background_top_colour;
2298 bg_top_grad_colour = m_tool_hover_background_top_gradient_colour;
2299 bg_colour = m_tool_hover_background_colour;
2300 bg_grad_colour = m_tool_hover_background_gradient_colour;
2301 }
2302 dc.GradientFillLinear(bg_rect_top, bg_top_colour, bg_top_grad_colour, wxSOUTH);
2303 dc.GradientFillLinear(bg_rect_btm, bg_colour, bg_grad_colour, wxSOUTH);
2304 if(is_split_hybrid)
2305 {
2306 wxRect nonrect(bg_rect);
2307 if(state & (wxRIBBON_TOOLBAR_TOOL_DROPDOWN_HOVERED |
2308 wxRIBBON_TOOLBAR_TOOL_DROPDOWN_ACTIVE))
2309 {
2310 nonrect.width -= 8;
2311 }
2312 else
2313 {
2314 nonrect.x += nonrect.width - 8;
2315 nonrect.width = 8;
2316 }
2317 wxBrush B(m_tool_hover_background_top_colour);
2318 dc.SetPen(*wxTRANSPARENT_PEN);
2319 dc.SetBrush(B);
2320 dc.DrawRectangle(nonrect.x, nonrect.y, nonrect.width, nonrect.height);
2321 }
2322
2323 // Border
2324 dc.SetPen(m_toolbar_border_pen);
2325 if(state & wxRIBBON_TOOLBAR_TOOL_FIRST)
2326 {
2327 dc.DrawPoint(rect.x + 1, rect.y + 1);
2328 dc.DrawPoint(rect.x + 1, rect.y + rect.height - 2);
2329 }
2330 else
2331 dc.DrawLine(rect.x, rect.y + 1, rect.x, rect.y + rect.height - 1);
2332
2333 if(state & wxRIBBON_TOOLBAR_TOOL_LAST)
2334 {
2335 dc.DrawPoint(rect.x + rect.width - 2, rect.y + 1);
2336 dc.DrawPoint(rect.x + rect.width - 2, rect.y + rect.height - 2);
2337 }
2338
2339 // Foreground
2340 int avail_width = bg_rect.GetWidth();
2341 if(kind & wxRIBBON_BUTTON_DROPDOWN)
2342 {
2343 avail_width -= 8;
2344 if(is_split_hybrid)
2345 {
2346 dc.DrawLine(rect.x + avail_width + 1, rect.y,
2347 rect.x + avail_width + 1, rect.y + rect.height);
2348 }
2349 dc.DrawBitmap(m_toolbar_drop_bitmap, bg_rect.x + avail_width + 2,
2350 bg_rect.y + (bg_rect.height / 2) - 2, true);
2351 }
2352 dc.DrawBitmap(bitmap, bg_rect.x + (avail_width - bitmap.GetWidth()) / 2,
2353 bg_rect.y + (bg_rect.height - bitmap.GetHeight()) / 2, true);
2354 }
2355
2356 void wxRibbonMSWArtProvider::GetBarTabWidth(
2357 wxDC& dc,
2358 wxWindow* WXUNUSED(wnd),
2359 const wxString& label,
2360 const wxBitmap& bitmap,
2361 int* ideal,
2362 int* small_begin_need_separator,
2363 int* small_must_have_separator,
2364 int* minimum)
2365 {
2366 int width = 0;
2367 int min = 0;
2368 if((m_flags & wxRIBBON_BAR_SHOW_PAGE_LABELS) && !label.IsEmpty())
2369 {
2370 dc.SetFont(m_tab_label_font);
2371 width += dc.GetTextExtent(label).GetWidth();
2372 min += wxMin(25, width); // enough for a few chars
2373 if(bitmap.IsOk())
2374 {
2375 // gap between label and bitmap
2376 width += 4;
2377 min += 2;
2378 }
2379 }
2380 if((m_flags & wxRIBBON_BAR_SHOW_PAGE_ICONS) && bitmap.IsOk())
2381 {
2382 width += bitmap.GetWidth();
2383 min += bitmap.GetWidth();
2384 }
2385
2386 if(ideal != NULL)
2387 {
2388 *ideal = width + 30;
2389 }
2390 if(small_begin_need_separator != NULL)
2391 {
2392 *small_begin_need_separator = width + 20;
2393 }
2394 if(small_must_have_separator != NULL)
2395 {
2396 *small_must_have_separator = width + 10;
2397 }
2398 if(minimum != NULL)
2399 {
2400 *minimum = min;
2401 }
2402 }
2403
2404 int wxRibbonMSWArtProvider::GetTabCtrlHeight(
2405 wxDC& dc,
2406 wxWindow* WXUNUSED(wnd),
2407 const wxRibbonPageTabInfoArray& pages)
2408 {
2409 int text_height = 0;
2410 int icon_height = 0;
2411
2412 if(pages.GetCount() <= 1 && (m_flags & wxRIBBON_BAR_ALWAYS_SHOW_TABS) == 0)
2413 {
2414 // To preserve space, a single tab need not be displayed. We still need
2415 // two pixels of border / padding though.
2416 return 2;
2417 }
2418
2419 if(m_flags & wxRIBBON_BAR_SHOW_PAGE_LABELS)
2420 {
2421 dc.SetFont(m_tab_label_font);
2422 text_height = dc.GetTextExtent(wxT("ABCDEFXj")).GetHeight() + 10;
2423 }
2424 if(m_flags & wxRIBBON_BAR_SHOW_PAGE_ICONS)
2425 {
2426 size_t numpages = pages.GetCount();
2427 for(size_t i = 0; i < numpages; ++i)
2428 {
2429 const wxRibbonPageTabInfo& info = pages.Item(i);
2430 if(info.page->GetIcon().IsOk())
2431 {
2432 icon_height = wxMax(icon_height, info.page->GetIcon().GetHeight() + 4);
2433 }
2434 }
2435 }
2436
2437 return wxMax(text_height, icon_height);
2438 }
2439
2440 wxSize wxRibbonMSWArtProvider::GetScrollButtonMinimumSize(
2441 wxDC& WXUNUSED(dc),
2442 wxWindow* WXUNUSED(wnd),
2443 long WXUNUSED(style))
2444 {
2445 return wxSize(12, 12);
2446 }
2447
2448 wxSize wxRibbonMSWArtProvider::GetPanelSize(
2449 wxDC& dc,
2450 const wxRibbonPanel* wnd,
2451 wxSize client_size,
2452 wxPoint* client_offset)
2453 {
2454 dc.SetFont(m_panel_label_font);
2455 wxSize label_size = dc.GetTextExtent(wnd->GetLabel());
2456
2457 client_size.IncBy(0, label_size.GetHeight());
2458 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
2459 client_size.IncBy(4, 8);
2460 else
2461 client_size.IncBy(6, 6);
2462
2463 if(client_offset != NULL)
2464 {
2465 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
2466 *client_offset = wxPoint(2, 3);
2467 else
2468 *client_offset = wxPoint(3, 2);
2469 }
2470
2471 return client_size;
2472 }
2473
2474 wxSize wxRibbonMSWArtProvider::GetPanelClientSize(
2475 wxDC& dc,
2476 const wxRibbonPanel* wnd,
2477 wxSize size,
2478 wxPoint* client_offset)
2479 {
2480 dc.SetFont(m_panel_label_font);
2481 wxSize label_size = dc.GetTextExtent(wnd->GetLabel());
2482
2483 size.DecBy(0, label_size.GetHeight());
2484 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
2485 size.DecBy(4, 8);
2486 else
2487 size.DecBy(6, 6);
2488
2489 if(client_offset != NULL)
2490 {
2491 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
2492 *client_offset = wxPoint(2, 3);
2493 else
2494 *client_offset = wxPoint(3, 2);
2495 }
2496 if (size.x < 0) size.x = 0;
2497 if (size.y < 0) size.y = 0;
2498
2499 return size;
2500 }
2501
2502 wxSize wxRibbonMSWArtProvider::GetGallerySize(
2503 wxDC& WXUNUSED(dc),
2504 const wxRibbonGallery* WXUNUSED(wnd),
2505 wxSize client_size)
2506 {
2507 client_size.IncBy( 2, 1); // Left / top padding
2508 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
2509 client_size.IncBy(1, 16); // Right / bottom padding
2510 else
2511 client_size.IncBy(16, 1); // Right / bottom padding
2512 return client_size;
2513 }
2514
2515 wxSize wxRibbonMSWArtProvider::GetGalleryClientSize(
2516 wxDC& WXUNUSED(dc),
2517 const wxRibbonGallery* WXUNUSED(wnd),
2518 wxSize size,
2519 wxPoint* client_offset,
2520 wxRect* scroll_up_button,
2521 wxRect* scroll_down_button,
2522 wxRect* extension_button)
2523 {
2524 wxRect scroll_up;
2525 wxRect scroll_down;
2526 wxRect extension;
2527 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
2528 {
2529 // Flow is vertical - put buttons on bottom
2530 scroll_up.y = size.GetHeight() - 15;
2531 scroll_up.height = 15;
2532 scroll_up.x = 0;
2533 scroll_up.width = (size.GetWidth() + 2) / 3;
2534 scroll_down.y = scroll_up.y;
2535 scroll_down.height = scroll_up.height;
2536 scroll_down.x = scroll_up.x + scroll_up.width;
2537 scroll_down.width = scroll_up.width;
2538 extension.y = scroll_down.y;
2539 extension.height = scroll_down.height;
2540 extension.x = scroll_down.x + scroll_down.width;
2541 extension.width = size.GetWidth() - scroll_up.width - scroll_down.width;
2542 size.DecBy(1, 16);
2543 size.DecBy( 2, 1);
2544 }
2545 else
2546 {
2547 // Flow is horizontal - put buttons on right
2548 scroll_up.x = size.GetWidth() - 15;
2549 scroll_up.width = 15;
2550 scroll_up.y = 0;
2551 scroll_up.height = (size.GetHeight() + 2) / 3;
2552 scroll_down.x = scroll_up.x;
2553 scroll_down.width = scroll_up.width;
2554 scroll_down.y = scroll_up.y + scroll_up.height;
2555 scroll_down.height = scroll_up.height;
2556 extension.x = scroll_down.x;
2557 extension.width = scroll_down.width;
2558 extension.y = scroll_down.y + scroll_down.height;
2559 extension.height = size.GetHeight() - scroll_up.height - scroll_down.height;
2560 size.DecBy(16, 1);
2561 size.DecBy( 2, 1);
2562 }
2563
2564 if(client_offset != NULL)
2565 *client_offset = wxPoint(2, 1);
2566 if(scroll_up_button != NULL)
2567 *scroll_up_button = scroll_up;
2568 if(scroll_down_button != NULL)
2569 *scroll_down_button = scroll_down;
2570 if(extension_button != NULL)
2571 *extension_button = extension;
2572
2573 return size;
2574 }
2575
2576 wxRect wxRibbonMSWArtProvider::GetPageBackgroundRedrawArea(
2577 wxDC& WXUNUSED(dc),
2578 const wxRibbonPage* WXUNUSED(wnd),
2579 wxSize page_old_size,
2580 wxSize page_new_size)
2581 {
2582 wxRect new_rect, old_rect;
2583
2584 if(page_new_size.GetWidth() != page_old_size.GetWidth())
2585 {
2586 if(page_new_size.GetHeight() != page_old_size.GetHeight())
2587 {
2588 // Width and height both changed - redraw everything
2589 return wxRect(page_new_size);
2590 }
2591 else
2592 {
2593 // Only width changed - redraw right hand side
2594 const int right_edge_width = 4;
2595
2596 new_rect = wxRect(page_new_size.GetWidth() - right_edge_width, 0, right_edge_width, page_new_size.GetHeight());
2597 old_rect = wxRect(page_old_size.GetWidth() - right_edge_width, 0, right_edge_width, page_old_size.GetHeight());
2598 }
2599 }
2600 else
2601 {
2602 if(page_new_size.GetHeight() == page_old_size.GetHeight())
2603 {
2604 // Nothing changed (should never happen) - redraw nothing
2605 return wxRect(0, 0, 0, 0);
2606 }
2607 else
2608 {
2609 // Height changed - need to redraw everything (as the background
2610 // gradient is done vertically).
2611 return page_new_size;
2612 }
2613 }
2614
2615 new_rect.Union(old_rect);
2616 new_rect.Intersect(wxRect(page_new_size));
2617 return new_rect;
2618 }
2619
2620 bool wxRibbonMSWArtProvider::GetButtonBarButtonSize(
2621 wxDC& dc,
2622 wxWindow* wnd,
2623 wxRibbonButtonKind kind,
2624 wxRibbonButtonBarButtonState size,
2625 const wxString& label,
2626 wxSize bitmap_size_large,
2627 wxSize bitmap_size_small,
2628 wxSize* button_size,
2629 wxRect* normal_region,
2630 wxRect* dropdown_region)
2631 {
2632 const int drop_button_width = 8;
2633
2634 dc.SetFont(m_button_bar_label_font);
2635 switch(size & wxRIBBON_BUTTONBAR_BUTTON_SIZE_MASK)
2636 {
2637 case wxRIBBON_BUTTONBAR_BUTTON_SMALL:
2638 // Small bitmap, no label
2639 *button_size = bitmap_size_small + wxSize(6, 4);
2640 switch(kind)
2641 {
2642 case wxRIBBON_BUTTON_NORMAL:
2643 case wxRIBBON_BUTTON_TOGGLE:
2644 *normal_region = wxRect(*button_size);
2645 *dropdown_region = wxRect(0, 0, 0, 0);
2646 break;
2647 case wxRIBBON_BUTTON_DROPDOWN:
2648 *button_size += wxSize(drop_button_width, 0);
2649 *dropdown_region = wxRect(*button_size);
2650 *normal_region = wxRect(0, 0, 0, 0);
2651 break;
2652 case wxRIBBON_BUTTON_HYBRID:
2653 *normal_region = wxRect(*button_size);
2654 *dropdown_region = wxRect(button_size->GetWidth(), 0,
2655 drop_button_width, button_size->GetHeight());
2656 *button_size += wxSize(drop_button_width, 0);
2657 break;
2658 }
2659 break;
2660 case wxRIBBON_BUTTONBAR_BUTTON_MEDIUM:
2661 // Small bitmap, with label to the right
2662 {
2663 GetButtonBarButtonSize(dc, wnd, kind, wxRIBBON_BUTTONBAR_BUTTON_SMALL,
2664 label, bitmap_size_large, bitmap_size_small, button_size,
2665 normal_region, dropdown_region);
2666 int text_size = dc.GetTextExtent(label).GetWidth();
2667 button_size->SetWidth(button_size->GetWidth() + text_size);
2668 switch(kind)
2669 {
2670 case wxRIBBON_BUTTON_DROPDOWN:
2671 dropdown_region->SetWidth(dropdown_region->GetWidth() + text_size);
2672 break;
2673 case wxRIBBON_BUTTON_HYBRID:
2674 dropdown_region->SetX(dropdown_region->GetX() + text_size);
2675 // no break
2676 case wxRIBBON_BUTTON_NORMAL:
2677 case wxRIBBON_BUTTON_TOGGLE:
2678 normal_region->SetWidth(normal_region->GetWidth() + text_size);
2679 break;
2680 }
2681 break;
2682 }
2683 case wxRIBBON_BUTTONBAR_BUTTON_LARGE:
2684 // Large bitmap, with label below (possibly split over 2 lines)
2685 {
2686 wxSize icon_size(bitmap_size_large);
2687 icon_size += wxSize(4, 4);
2688 wxCoord label_height;
2689 wxCoord best_width;
2690 dc.GetTextExtent(label, &best_width, &label_height);
2691 int last_line_extra_width = 0;
2692 if(kind != wxRIBBON_BUTTON_NORMAL && kind != wxRIBBON_BUTTON_TOGGLE)
2693 {
2694 last_line_extra_width += 8;
2695 }
2696 size_t i;
2697 for(i = 0; i < label.Len(); ++i)
2698 {
2699 if(wxRibbonCanLabelBreakAtPosition(label, i))
2700 {
2701 int width = wxMax(
2702 dc.GetTextExtent(label.Mid(0, i - 1)).GetWidth(),
2703 dc.GetTextExtent(label.Mid(i + 1)).GetWidth() + last_line_extra_width);
2704 if(width < best_width)
2705 {
2706 best_width = width;
2707 }
2708 }
2709 }
2710 label_height *= 2; // Assume two lines even when only one is used
2711 // (to give all buttons a consistent height)
2712 icon_size.SetWidth(wxMax(icon_size.GetWidth(), best_width) + 6);
2713 icon_size.SetHeight(icon_size.GetHeight() + label_height);
2714 *button_size = icon_size;
2715 switch(kind)
2716 {
2717 case wxRIBBON_BUTTON_DROPDOWN:
2718 *dropdown_region = wxRect(icon_size);
2719 break;
2720 case wxRIBBON_BUTTON_HYBRID:
2721 *normal_region = wxRect(icon_size);
2722 normal_region->height -= 2 + label_height;
2723 dropdown_region->x = 0;
2724 dropdown_region->y = normal_region->height;
2725 dropdown_region->width = icon_size.GetWidth();
2726 dropdown_region->height = icon_size.GetHeight() - normal_region->height;
2727 break;
2728 case wxRIBBON_BUTTON_NORMAL:
2729 case wxRIBBON_BUTTON_TOGGLE:
2730 *normal_region = wxRect(icon_size);
2731 break;
2732 }
2733 break;
2734 }
2735 };
2736 return true;
2737 }
2738
2739 wxSize wxRibbonMSWArtProvider::GetMinimisedPanelMinimumSize(
2740 wxDC& dc,
2741 const wxRibbonPanel* wnd,
2742 wxSize* desired_bitmap_size,
2743 wxDirection* expanded_panel_direction)
2744 {
2745 if(desired_bitmap_size != NULL)
2746 {
2747 *desired_bitmap_size = wxSize(16, 16);
2748 }
2749 if(expanded_panel_direction != NULL)
2750 {
2751 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
2752 *expanded_panel_direction = wxEAST;
2753 else
2754 *expanded_panel_direction = wxSOUTH;
2755 }
2756 wxSize base_size(42, 42);
2757
2758 dc.SetFont(m_panel_label_font);
2759 wxSize label_size(dc.GetTextExtent(wnd->GetLabel()));
2760 label_size.IncBy(2, 2); // Allow for differences between this DC and a paint DC
2761 label_size.IncBy(6, 0); // Padding
2762 label_size.y *= 2; // Second line for dropdown button
2763
2764 if(m_flags & wxRIBBON_BAR_FLOW_VERTICAL)
2765 {
2766 // Label alongside icon
2767 return wxSize(base_size.x + label_size.x,
2768 wxMax(base_size.y, label_size.y));
2769 }
2770 else
2771 {
2772 // Label beneath icon
2773 return wxSize(wxMax(base_size.x, label_size.x),
2774 base_size.y + label_size.y);
2775 }
2776 }
2777
2778 wxSize wxRibbonMSWArtProvider::GetToolSize(
2779 wxDC& WXUNUSED(dc),
2780 wxWindow* WXUNUSED(wnd),
2781 wxSize bitmap_size,
2782 wxRibbonButtonKind kind,
2783 bool WXUNUSED(is_first),
2784 bool is_last,
2785 wxRect* dropdown_region)
2786 {
2787 wxSize size(bitmap_size);
2788 size.IncBy(7, 6);
2789 if(is_last)
2790 size.IncBy(1, 0);
2791 if(kind & wxRIBBON_BUTTON_DROPDOWN)
2792 {
2793 size.IncBy(8, 0);
2794 if(dropdown_region)
2795 {
2796 if(kind == wxRIBBON_BUTTON_DROPDOWN)
2797 *dropdown_region = size;
2798 else
2799 *dropdown_region = wxRect(size.GetWidth() - 8, 0, 8, size.GetHeight());
2800 }
2801 }
2802 else
2803 {
2804 if(dropdown_region)
2805 *dropdown_region = wxRect(0, 0, 0, 0);
2806 }
2807 return size;
2808 }
2809
2810 #endif // wxUSE_RIBBON