]> git.saurik.com Git - wxWidgets.git/blob - src/ribbon/gallery.cpp
Fix item selection/focus drawing in generic wxListCtrl.
[wxWidgets.git] / src / ribbon / gallery.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/ribbon/gallery.cpp
3 // Purpose: Ribbon control which displays a gallery of items to choose from
4 // Author: Peter Cawley
5 // Modified by:
6 // Created: 2009-07-22
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/gallery.h"
21 #include "wx/ribbon/art.h"
22 #include "wx/ribbon/bar.h"
23 #include "wx/dcbuffer.h"
24 #include "wx/clntdata.h"
25
26 #ifndef WX_PRECOMP
27 #endif
28
29 #ifdef __WXMSW__
30 #include "wx/msw/private.h"
31 #endif
32
33 wxDEFINE_EVENT(wxEVT_COMMAND_RIBBONGALLERY_HOVER_CHANGED, wxRibbonGalleryEvent);
34 wxDEFINE_EVENT(wxEVT_COMMAND_RIBBONGALLERY_SELECTED, wxRibbonGalleryEvent);
35
36 IMPLEMENT_DYNAMIC_CLASS(wxRibbonGalleryEvent, wxCommandEvent)
37 IMPLEMENT_CLASS(wxRibbonGallery, wxRibbonControl)
38
39 class wxRibbonGalleryItem
40 {
41 public:
42 wxRibbonGalleryItem()
43 {
44 m_id = 0;
45 m_is_visible = false;
46 }
47
48 void SetId(int id) {m_id = id;}
49 void SetBitmap(const wxBitmap& bitmap) {m_bitmap = bitmap;}
50 const wxBitmap& GetBitmap() const {return m_bitmap;}
51 void SetIsVisible(bool visible) {m_is_visible = visible;}
52 void SetPosition(int x, int y, const wxSize& size)
53 {
54 m_position = wxRect(wxPoint(x, y), size);
55 }
56 bool IsVisible() const {return m_is_visible;}
57 const wxRect& GetPosition() const {return m_position;}
58
59 void SetClientObject(wxClientData *data) {m_client_data.SetClientObject(data);}
60 wxClientData *GetClientObject() const {return m_client_data.GetClientObject();}
61 void SetClientData(void *data) {m_client_data.SetClientData(data);}
62 void *GetClientData() const {return m_client_data.GetClientData();}
63
64 protected:
65 wxBitmap m_bitmap;
66 wxClientDataContainer m_client_data;
67 wxRect m_position;
68 int m_id;
69 bool m_is_visible;
70 };
71
72 BEGIN_EVENT_TABLE(wxRibbonGallery, wxRibbonControl)
73 EVT_ENTER_WINDOW(wxRibbonGallery::OnMouseEnter)
74 EVT_ERASE_BACKGROUND(wxRibbonGallery::OnEraseBackground)
75 EVT_LEAVE_WINDOW(wxRibbonGallery::OnMouseLeave)
76 EVT_LEFT_DOWN(wxRibbonGallery::OnMouseDown)
77 EVT_LEFT_UP(wxRibbonGallery::OnMouseUp)
78 EVT_MOTION(wxRibbonGallery::OnMouseMove)
79 EVT_PAINT(wxRibbonGallery::OnPaint)
80 EVT_SIZE(wxRibbonGallery::OnSize)
81 END_EVENT_TABLE()
82
83 wxRibbonGallery::wxRibbonGallery()
84 {
85 }
86
87 wxRibbonGallery::wxRibbonGallery(wxWindow* parent,
88 wxWindowID id,
89 const wxPoint& pos,
90 const wxSize& size,
91 long style)
92 : wxRibbonControl(parent, id, pos, size, wxBORDER_NONE)
93 {
94 CommonInit(style);
95 }
96
97 wxRibbonGallery::~wxRibbonGallery()
98 {
99 Clear();
100 }
101
102 bool wxRibbonGallery::Create(wxWindow* parent,
103 wxWindowID id,
104 const wxPoint& pos,
105 const wxSize& size,
106 long style)
107 {
108 if(!wxRibbonControl::Create(parent, id, pos, size, wxBORDER_NONE))
109 {
110 return false;
111 }
112
113 CommonInit(style);
114 return true;
115 }
116
117 void wxRibbonGallery::CommonInit(long WXUNUSED(style))
118 {
119 m_selected_item = NULL;
120 m_hovered_item = NULL;
121 m_active_item = NULL;
122 m_scroll_up_button_rect = wxRect(0, 0, 0, 0);
123 m_scroll_down_button_rect = wxRect(0, 0, 0, 0);
124 m_extension_button_rect = wxRect(0, 0, 0, 0);
125 m_mouse_active_rect = NULL;
126 m_bitmap_size = wxSize(64, 32);
127 m_bitmap_padded_size = m_bitmap_size;
128 m_item_separation_x = 0;
129 m_item_separation_y = 0;
130 m_scroll_amount = 0;
131 m_scroll_limit = 0;
132 m_up_button_state = wxRIBBON_GALLERY_BUTTON_DISABLED;
133 m_down_button_state = wxRIBBON_GALLERY_BUTTON_NORMAL;
134 m_extension_button_state = wxRIBBON_GALLERY_BUTTON_NORMAL;
135 m_hovered = false;
136
137 SetBackgroundStyle(wxBG_STYLE_CUSTOM);
138 }
139
140 void wxRibbonGallery::OnMouseEnter(wxMouseEvent& evt)
141 {
142 m_hovered = true;
143 if(m_mouse_active_rect != NULL && !evt.LeftIsDown())
144 {
145 m_mouse_active_rect = NULL;
146 m_active_item = NULL;
147 }
148 Refresh(false);
149 }
150
151 void wxRibbonGallery::OnMouseMove(wxMouseEvent& evt)
152 {
153 bool refresh = false;
154 wxPoint pos = evt.GetPosition();
155
156 if(TestButtonHover(m_scroll_up_button_rect, pos, &m_up_button_state))
157 refresh = true;
158 if(TestButtonHover(m_scroll_down_button_rect, pos, &m_down_button_state))
159 refresh = true;
160 if(TestButtonHover(m_extension_button_rect, pos, &m_extension_button_state))
161 refresh = true;
162
163 wxRibbonGalleryItem *hovered_item = NULL;
164 wxRibbonGalleryItem *active_item = NULL;
165 if(m_client_rect.Contains(pos))
166 {
167 if(m_art && m_art->GetFlags() & wxRIBBON_BAR_FLOW_VERTICAL)
168 pos.x += m_scroll_amount;
169 else
170 pos.y += m_scroll_amount;
171
172 size_t item_count = m_items.Count();
173 size_t item_i;
174 for(item_i = 0; item_i < item_count; ++item_i)
175 {
176 wxRibbonGalleryItem *item = m_items.Item(item_i);
177 if(!item->IsVisible())
178 continue;
179
180 if(item->GetPosition().Contains(pos))
181 {
182 if(m_mouse_active_rect == &item->GetPosition())
183 active_item = item;
184 hovered_item = item;
185 break;
186 }
187 }
188 }
189 if(active_item != m_active_item)
190 {
191 m_active_item = active_item;
192 refresh = true;
193 }
194 if(hovered_item != m_hovered_item)
195 {
196 m_hovered_item = hovered_item;
197 wxRibbonGalleryEvent notification(
198 wxEVT_COMMAND_RIBBONGALLERY_HOVER_CHANGED, GetId());
199 notification.SetEventObject(this);
200 notification.SetGallery(this);
201 notification.SetGalleryItem(hovered_item);
202 ProcessWindowEvent(notification);
203 refresh = true;
204 }
205
206 if(refresh)
207 Refresh(false);
208 }
209
210 bool wxRibbonGallery::TestButtonHover(const wxRect& rect, wxPoint pos,
211 wxRibbonGalleryButtonState* state)
212 {
213 if(*state == wxRIBBON_GALLERY_BUTTON_DISABLED)
214 return false;
215
216 wxRibbonGalleryButtonState new_state;
217 if(rect.Contains(pos))
218 {
219 if(m_mouse_active_rect == &rect)
220 new_state = wxRIBBON_GALLERY_BUTTON_ACTIVE;
221 else
222 new_state = wxRIBBON_GALLERY_BUTTON_HOVERED;
223 }
224 else
225 new_state = wxRIBBON_GALLERY_BUTTON_NORMAL;
226
227 if(new_state != *state)
228 {
229 *state = new_state;
230 return true;
231 }
232 else
233 {
234 return false;
235 }
236 }
237
238 void wxRibbonGallery::OnMouseLeave(wxMouseEvent& WXUNUSED(evt))
239 {
240 m_hovered = false;
241 m_active_item = NULL;
242 if(m_up_button_state != wxRIBBON_GALLERY_BUTTON_DISABLED)
243 m_up_button_state = wxRIBBON_GALLERY_BUTTON_NORMAL;
244 if(m_down_button_state != wxRIBBON_GALLERY_BUTTON_DISABLED)
245 m_down_button_state = wxRIBBON_GALLERY_BUTTON_NORMAL;
246 if(m_extension_button_state != wxRIBBON_GALLERY_BUTTON_DISABLED)
247 m_extension_button_state = wxRIBBON_GALLERY_BUTTON_NORMAL;
248 if(m_hovered_item != NULL)
249 {
250 m_hovered_item = NULL;
251 wxRibbonGalleryEvent notification(
252 wxEVT_COMMAND_RIBBONGALLERY_HOVER_CHANGED, GetId());
253 notification.SetEventObject(this);
254 notification.SetGallery(this);
255 ProcessWindowEvent(notification);
256 }
257 Refresh(false);
258 }
259
260 void wxRibbonGallery::OnMouseDown(wxMouseEvent& evt)
261 {
262 wxPoint pos = evt.GetPosition();
263 m_mouse_active_rect = NULL;
264 if(m_client_rect.Contains(pos))
265 {
266 if(m_art && m_art->GetFlags() & wxRIBBON_BAR_FLOW_VERTICAL)
267 pos.x += m_scroll_amount;
268 else
269 pos.y += m_scroll_amount;
270 size_t item_count = m_items.Count();
271 size_t item_i;
272 for(item_i = 0; item_i < item_count; ++item_i)
273 {
274 wxRibbonGalleryItem *item = m_items.Item(item_i);
275 if(!item->IsVisible())
276 continue;
277
278 const wxRect& rect = item->GetPosition();
279 if(rect.Contains(pos))
280 {
281 m_active_item = item;
282 m_mouse_active_rect = &rect;
283 break;
284 }
285 }
286 }
287 else if(m_scroll_up_button_rect.Contains(pos))
288 {
289 if(m_up_button_state != wxRIBBON_GALLERY_BUTTON_DISABLED)
290 {
291 m_mouse_active_rect = &m_scroll_up_button_rect;
292 m_up_button_state = wxRIBBON_GALLERY_BUTTON_ACTIVE;
293 }
294 }
295 else if(m_scroll_down_button_rect.Contains(pos))
296 {
297 if(m_down_button_state != wxRIBBON_GALLERY_BUTTON_DISABLED)
298 {
299 m_mouse_active_rect = &m_scroll_down_button_rect;
300 m_down_button_state = wxRIBBON_GALLERY_BUTTON_ACTIVE;
301 }
302 }
303 else if(m_extension_button_rect.Contains(pos))
304 {
305 if(m_extension_button_state != wxRIBBON_GALLERY_BUTTON_DISABLED)
306 {
307 m_mouse_active_rect = &m_extension_button_rect;
308 m_extension_button_state = wxRIBBON_GALLERY_BUTTON_ACTIVE;
309 }
310 }
311 if(m_mouse_active_rect != NULL)
312 Refresh(false);
313 }
314
315 void wxRibbonGallery::OnMouseUp(wxMouseEvent& evt)
316 {
317 if(m_mouse_active_rect != NULL)
318 {
319 wxPoint pos = evt.GetPosition();
320 if(m_active_item)
321 {
322 if(m_art && m_art->GetFlags() & wxRIBBON_BAR_FLOW_VERTICAL)
323 pos.x += m_scroll_amount;
324 else
325 pos.y += m_scroll_amount;
326 }
327 if(m_mouse_active_rect->Contains(pos))
328 {
329 if(m_mouse_active_rect == &m_scroll_up_button_rect)
330 {
331 m_up_button_state = wxRIBBON_GALLERY_BUTTON_HOVERED;
332 ScrollLines(-1);
333 }
334 else if(m_mouse_active_rect == &m_scroll_down_button_rect)
335 {
336 m_down_button_state = wxRIBBON_GALLERY_BUTTON_HOVERED;
337 ScrollLines(1);
338 }
339 else if(m_mouse_active_rect == &m_extension_button_rect)
340 {
341 m_extension_button_state = wxRIBBON_GALLERY_BUTTON_HOVERED;
342 wxCommandEvent notification(wxEVT_COMMAND_BUTTON_CLICKED,
343 GetId());
344 notification.SetEventObject(this);
345 ProcessWindowEvent(notification);
346 }
347 else if(m_active_item != NULL)
348 {
349 if(m_selected_item != m_active_item)
350 {
351 m_selected_item = m_active_item;
352 wxRibbonGalleryEvent notification(
353 wxEVT_COMMAND_RIBBONGALLERY_SELECTED, GetId());
354 notification.SetEventObject(this);
355 notification.SetGallery(this);
356 notification.SetGalleryItem(m_selected_item);
357 ProcessWindowEvent(notification);
358 }
359 }
360 }
361 m_mouse_active_rect = NULL;
362 m_active_item = NULL;
363 Refresh(false);
364 }
365 }
366
367 void wxRibbonGallery::SetItemClientObject(wxRibbonGalleryItem* itm,
368 wxClientData* data)
369 {
370 itm->SetClientObject(data);
371 }
372
373 wxClientData* wxRibbonGallery::GetItemClientObject(const wxRibbonGalleryItem* itm) const
374 {
375 return itm->GetClientObject();
376 }
377
378 void wxRibbonGallery::SetItemClientData(wxRibbonGalleryItem* itm, void* data)
379 {
380 itm->SetClientData(data);
381 }
382
383 void* wxRibbonGallery::GetItemClientData(const wxRibbonGalleryItem* itm) const
384 {
385 return itm->GetClientData();
386 }
387
388 bool wxRibbonGallery::ScrollLines(int lines)
389 {
390 if(m_scroll_limit == 0 || m_art == NULL)
391 return false;
392
393 int line_size = m_bitmap_padded_size.GetHeight();
394 if(m_art->GetFlags() & wxRIBBON_BAR_FLOW_VERTICAL)
395 line_size = m_bitmap_padded_size.GetWidth();
396 if(lines < 0)
397 {
398 if(m_scroll_amount > 0)
399 {
400 m_scroll_amount += lines * line_size;
401 if(m_scroll_amount <= 0)
402 {
403 m_scroll_amount = 0;
404 m_up_button_state = wxRIBBON_GALLERY_BUTTON_DISABLED;
405 }
406 else if(m_up_button_state == wxRIBBON_GALLERY_BUTTON_DISABLED)
407 m_up_button_state = wxRIBBON_GALLERY_BUTTON_NORMAL;
408 if(m_down_button_state == wxRIBBON_GALLERY_BUTTON_DISABLED)
409 m_down_button_state = wxRIBBON_GALLERY_BUTTON_NORMAL;
410 return true;
411 }
412 }
413 else if(lines > 0)
414 {
415 if(m_scroll_amount < m_scroll_limit)
416 {
417 m_scroll_amount += lines * line_size;
418 if(m_scroll_amount >= m_scroll_limit)
419 {
420 m_scroll_amount = m_scroll_limit;
421 m_down_button_state = wxRIBBON_GALLERY_BUTTON_DISABLED;
422 }
423 else if(m_down_button_state == wxRIBBON_GALLERY_BUTTON_DISABLED)
424 m_down_button_state = wxRIBBON_GALLERY_BUTTON_NORMAL;
425 if(m_up_button_state == wxRIBBON_GALLERY_BUTTON_DISABLED)
426 m_up_button_state = wxRIBBON_GALLERY_BUTTON_NORMAL;
427 return true;
428 }
429 }
430 return false;
431 }
432
433 void wxRibbonGallery::EnsureVisible(const wxRibbonGalleryItem* item)
434 {
435 if(item == NULL || !item->IsVisible() || IsEmpty())
436 return;
437
438 int y = item->GetPosition().GetTop();
439 int base_y = m_items.Item(0)->GetPosition().GetTop();
440 int delta = y - base_y - m_scroll_amount;
441 ScrollLines(delta / m_bitmap_padded_size.GetHeight());
442 }
443
444 bool wxRibbonGallery::IsHovered() const
445 {
446 return m_hovered;
447 }
448
449 void wxRibbonGallery::OnEraseBackground(wxEraseEvent& WXUNUSED(evt))
450 {
451 // All painting done in main paint handler to minimise flicker
452 }
453
454 void wxRibbonGallery::OnPaint(wxPaintEvent& WXUNUSED(evt))
455 {
456 wxAutoBufferedPaintDC dc(this);
457 if(m_art == NULL)
458 return;
459
460 m_art->DrawGalleryBackground(dc, this, GetSize());
461
462 int padding_top = m_art->GetMetric(wxRIBBON_ART_GALLERY_BITMAP_PADDING_TOP_SIZE);
463 int padding_left = m_art->GetMetric(wxRIBBON_ART_GALLERY_BITMAP_PADDING_LEFT_SIZE);
464
465 dc.SetClippingRegion(m_client_rect);
466
467 bool offset_vertical = true;
468 if(m_art->GetFlags() & wxRIBBON_BAR_FLOW_VERTICAL)
469 offset_vertical = false;
470 size_t item_count = m_items.Count();
471 size_t item_i;
472 for(item_i = 0; item_i < item_count; ++item_i)
473 {
474 wxRibbonGalleryItem *item = m_items.Item(item_i);
475 if(!item->IsVisible())
476 continue;
477
478 const wxRect& pos = item->GetPosition();
479 wxRect offset_pos(pos);
480 if(offset_vertical)
481 offset_pos.SetTop(offset_pos.GetTop() - m_scroll_amount);
482 else
483 offset_pos.SetLeft(offset_pos.GetLeft() - m_scroll_amount);
484 m_art->DrawGalleryItemBackground(dc, this, offset_pos, item);
485 dc.DrawBitmap(item->GetBitmap(), offset_pos.GetLeft() + padding_left,
486 offset_pos.GetTop() + padding_top);
487 }
488 }
489
490 void wxRibbonGallery::OnSize(wxSizeEvent& WXUNUSED(evt))
491 {
492 Layout();
493 }
494
495 wxRibbonGalleryItem* wxRibbonGallery::Append(const wxBitmap& bitmap, int id)
496 {
497 wxASSERT(bitmap.IsOk());
498 if(m_items.IsEmpty())
499 {
500 m_bitmap_size = bitmap.GetSize();
501 CalculateMinSize();
502 }
503 else
504 {
505 wxASSERT(bitmap.GetSize() == m_bitmap_size);
506 }
507
508 wxRibbonGalleryItem *item = new wxRibbonGalleryItem;
509 item->SetId(id);
510 item->SetBitmap(bitmap);
511 m_items.Add(item);
512 return item;
513 }
514
515 wxRibbonGalleryItem* wxRibbonGallery::Append(const wxBitmap& bitmap, int id,
516 void* clientData)
517 {
518 wxRibbonGalleryItem *item = Append(bitmap, id);
519 item->SetClientData(clientData);
520 return item;
521 }
522
523 wxRibbonGalleryItem* wxRibbonGallery::Append(const wxBitmap& bitmap, int id,
524 wxClientData* clientData)
525 {
526 wxRibbonGalleryItem *item = Append(bitmap, id);
527 item->SetClientObject(clientData);
528 return item;
529 }
530
531 void wxRibbonGallery::Clear()
532 {
533 size_t item_count = m_items.Count();
534 size_t item_i;
535 for(item_i = 0; item_i < item_count; ++item_i)
536 {
537 wxRibbonGalleryItem *item = m_items.Item(item_i);
538 delete item;
539 }
540 m_items.Clear();
541 }
542
543 bool wxRibbonGallery::IsSizingContinuous() const
544 {
545 return false;
546 }
547
548 void wxRibbonGallery::CalculateMinSize()
549 {
550 if(m_art == NULL || !m_bitmap_size.IsFullySpecified())
551 {
552 SetMinSize(wxSize(20, 20));
553 }
554 else
555 {
556 m_bitmap_padded_size = m_bitmap_size;
557 m_bitmap_padded_size.IncBy(
558 m_art->GetMetric(wxRIBBON_ART_GALLERY_BITMAP_PADDING_LEFT_SIZE) +
559 m_art->GetMetric(wxRIBBON_ART_GALLERY_BITMAP_PADDING_RIGHT_SIZE),
560 m_art->GetMetric(wxRIBBON_ART_GALLERY_BITMAP_PADDING_TOP_SIZE) +
561 m_art->GetMetric(wxRIBBON_ART_GALLERY_BITMAP_PADDING_BOTTOM_SIZE));
562
563 wxMemoryDC dc;
564 SetMinSize(m_art->GetGallerySize(dc, this, m_bitmap_padded_size));
565
566 // The best size is displaying several items
567 m_best_size = m_bitmap_padded_size;
568 m_best_size.x *= 3;
569 m_best_size = m_art->GetGallerySize(dc, this, m_best_size);
570 }
571 }
572
573 bool wxRibbonGallery::Realize()
574 {
575 CalculateMinSize();
576 return Layout();
577 }
578
579 bool wxRibbonGallery::Layout()
580 {
581 if(m_art == NULL)
582 return false;
583
584 wxMemoryDC dc;
585 wxPoint origin;
586 wxSize client_size = m_art->GetGalleryClientSize(dc, this, GetSize(),
587 &origin, &m_scroll_up_button_rect, &m_scroll_down_button_rect,
588 &m_extension_button_rect);
589 m_client_rect = wxRect(origin, client_size);
590
591 int x_cursor = 0;
592 int y_cursor = 0;
593
594 size_t item_count = m_items.Count();
595 size_t item_i;
596 long art_flags = m_art->GetFlags();
597 for(item_i = 0; item_i < item_count; ++item_i)
598 {
599 wxRibbonGalleryItem *item = m_items.Item(item_i);
600 item->SetIsVisible(true);
601 if(art_flags & wxRIBBON_BAR_FLOW_VERTICAL)
602 {
603 if(y_cursor + m_bitmap_padded_size.y > client_size.GetHeight())
604 {
605 if(y_cursor == 0)
606 break;
607 y_cursor = 0;
608 x_cursor += m_bitmap_padded_size.x;
609 }
610 item->SetPosition(origin.x + x_cursor, origin.y + y_cursor,
611 m_bitmap_padded_size);
612 y_cursor += m_bitmap_padded_size.y;
613 }
614 else
615 {
616 if(x_cursor + m_bitmap_padded_size.x > client_size.GetWidth())
617 {
618 if(x_cursor == 0)
619 break;
620 x_cursor = 0;
621 y_cursor += m_bitmap_padded_size.y;
622 }
623 item->SetPosition(origin.x + x_cursor, origin.y + y_cursor,
624 m_bitmap_padded_size);
625 x_cursor += m_bitmap_padded_size.x;
626 }
627 }
628 for(; item_i < item_count; ++item_i)
629 {
630 wxRibbonGalleryItem *item = m_items.Item(item_i);
631 item->SetIsVisible(false);
632 }
633 if(art_flags & wxRIBBON_BAR_FLOW_VERTICAL)
634 m_scroll_limit = x_cursor;
635 else
636 m_scroll_limit = y_cursor;
637 if(m_scroll_amount >= m_scroll_limit)
638 {
639 m_scroll_amount = m_scroll_limit;
640 m_down_button_state = wxRIBBON_GALLERY_BUTTON_DISABLED;
641 }
642 else if(m_down_button_state == wxRIBBON_GALLERY_BUTTON_DISABLED)
643 m_down_button_state = wxRIBBON_GALLERY_BUTTON_NORMAL;
644
645 if(m_scroll_amount <= 0)
646 {
647 m_scroll_amount = 0;
648 m_up_button_state = wxRIBBON_GALLERY_BUTTON_DISABLED;
649 }
650 else if(m_up_button_state == wxRIBBON_GALLERY_BUTTON_DISABLED)
651 m_up_button_state = wxRIBBON_GALLERY_BUTTON_NORMAL;
652
653 return true;
654 }
655
656 wxSize wxRibbonGallery::DoGetBestSize() const
657 {
658 return m_best_size;
659 }
660
661 wxSize wxRibbonGallery::DoGetNextSmallerSize(wxOrientation direction,
662 wxSize relative_to) const
663 {
664 if(m_art == NULL)
665 return relative_to;
666
667 wxMemoryDC dc;
668
669 wxSize client = m_art->GetGalleryClientSize(dc, this, relative_to, NULL,
670 NULL, NULL, NULL);
671 switch(direction)
672 {
673 case wxHORIZONTAL:
674 client.DecBy(1, 0);
675 break;
676 case wxVERTICAL:
677 client.DecBy(0, 1);
678 break;
679 case wxBOTH:
680 client.DecBy(1, 1);
681 break;
682 }
683 if(client.GetWidth() < 0 || client.GetHeight() < 0)
684 return relative_to;
685
686 client.x = (client.x / m_bitmap_padded_size.x) * m_bitmap_padded_size.x;
687 client.y = (client.y / m_bitmap_padded_size.y) * m_bitmap_padded_size.y;
688
689 wxSize size = m_art->GetGallerySize(dc, this, client);
690 wxSize minimum = GetMinSize();
691
692 if(size.GetWidth() < minimum.GetWidth() ||
693 size.GetHeight() < minimum.GetHeight())
694 {
695 return relative_to;
696 }
697
698 switch(direction)
699 {
700 case wxHORIZONTAL:
701 size.SetHeight(relative_to.GetHeight());
702 break;
703 case wxVERTICAL:
704 size.SetWidth(relative_to.GetWidth());
705 break;
706 default:
707 break;
708 }
709
710 return size;
711 }
712
713 wxSize wxRibbonGallery::DoGetNextLargerSize(wxOrientation direction,
714 wxSize relative_to) const
715 {
716 if(m_art == NULL)
717 return relative_to;
718
719 wxMemoryDC dc;
720
721 wxSize client = m_art->GetGalleryClientSize(dc, this, relative_to, NULL,
722 NULL, NULL, NULL);
723
724 // No need to grow if the given size can already display every item
725 int nitems = (client.GetWidth() / m_bitmap_padded_size.x) *
726 (client.GetHeight() / m_bitmap_padded_size.y);
727 if(nitems >= (int)m_items.GetCount())
728 return relative_to;
729
730 switch(direction)
731 {
732 case wxHORIZONTAL:
733 client.IncBy(m_bitmap_padded_size.x, 0);
734 break;
735 case wxVERTICAL:
736 client.IncBy(0, m_bitmap_padded_size.y);
737 break;
738 case wxBOTH:
739 client.IncBy(m_bitmap_padded_size);
740 break;
741 }
742
743 client.x = (client.x / m_bitmap_padded_size.x) * m_bitmap_padded_size.x;
744 client.y = (client.y / m_bitmap_padded_size.y) * m_bitmap_padded_size.y;
745
746 wxSize size = m_art->GetGallerySize(dc, this, client);
747 wxSize minimum = GetMinSize();
748
749 if(size.GetWidth() < minimum.GetWidth() ||
750 size.GetHeight() < minimum.GetHeight())
751 {
752 return relative_to;
753 }
754
755 switch(direction)
756 {
757 case wxHORIZONTAL:
758 size.SetHeight(relative_to.GetHeight());
759 break;
760 case wxVERTICAL:
761 size.SetWidth(relative_to.GetWidth());
762 break;
763 default:
764 break;
765 }
766
767 return size;
768 }
769
770 bool wxRibbonGallery::IsEmpty() const
771 {
772 return m_items.IsEmpty();
773 }
774
775 unsigned int wxRibbonGallery::GetCount() const
776 {
777 return (unsigned int)m_items.GetCount();
778 }
779
780 wxRibbonGalleryItem* wxRibbonGallery::GetItem(unsigned int n)
781 {
782 if(n >= GetCount())
783 return NULL;
784 return m_items.Item(n);
785 }
786
787 void wxRibbonGallery::SetSelection(wxRibbonGalleryItem* item)
788 {
789 if(item != m_selected_item)
790 {
791 m_selected_item = item;
792 Refresh(false);
793 }
794 }
795
796 wxRibbonGalleryItem* wxRibbonGallery::GetSelection() const
797 {
798 return m_selected_item;
799 }
800
801 wxRibbonGalleryItem* wxRibbonGallery::GetHoveredItem() const
802 {
803 return m_hovered_item;
804 }
805
806 wxRibbonGalleryItem* wxRibbonGallery::GetActiveItem() const
807 {
808 return m_active_item;
809 }
810
811 wxRibbonGalleryButtonState wxRibbonGallery::GetUpButtonState() const
812 {
813 return m_up_button_state;
814 }
815
816 wxRibbonGalleryButtonState wxRibbonGallery::GetDownButtonState() const
817 {
818 return m_down_button_state;
819 }
820
821 wxRibbonGalleryButtonState wxRibbonGallery::GetExtensionButtonState() const
822 {
823 return m_extension_button_state;
824 }
825
826 #endif // wxUSE_RIBBON