--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// Name: src/ribbon/gallery.cpp
+// Purpose: Ribbon control which displays a gallery of items to choose from
+// Author: Peter Cawley
+// Modified by:
+// Created: 2009-07-22
+// RCS-ID: $Id$
+// Copyright: (C) Peter Cawley
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif
+
+#include "wx/ribbon/gallery.h"
+
+#if wxUSE_RIBBON
+
+#include "wx/ribbon/art.h"
+#include "wx/ribbon/bar.h"
+#include "wx/dcbuffer.h"
+#include "wx/clntdata.h"
+
+#ifndef WX_PRECOMP
+#endif
+
+#ifdef __WXMSW__
+#include "wx/msw/private.h"
+#endif
+
+wxDEFINE_EVENT(wxEVT_COMMAND_RIBBONGALLERY_HOVER_CHANGED, wxRibbonGalleryEvent);
+wxDEFINE_EVENT(wxEVT_COMMAND_RIBBONGALLERY_SELECTED, wxRibbonGalleryEvent);
+
+IMPLEMENT_DYNAMIC_CLASS(wxRibbonGalleryEvent, wxCommandEvent)
+IMPLEMENT_CLASS(wxRibbonGallery, wxRibbonControl)
+
+class wxRibbonGalleryItem
+{
+public:
+ wxRibbonGalleryItem()
+ {
+ m_id = 0;
+ m_is_visible = false;
+ }
+
+ void SetId(int id) {m_id = id;}
+ void SetBitmap(const wxBitmap& bitmap) {m_bitmap = bitmap;}
+ const wxBitmap& GetBitmap() const {return m_bitmap;}
+ void SetIsVisible(bool visible) {m_is_visible = visible;}
+ void SetPosition(int x, int y, const wxSize& size)
+ {
+ m_position = wxRect(wxPoint(x, y), size);
+ }
+ bool IsVisible() const {return m_is_visible;}
+ const wxRect& GetPosition() const {return m_position;}
+
+ void SetClientObject(wxClientData *data) {m_client_data.SetClientObject(data);}
+ wxClientData *GetClientObject() const {return m_client_data.GetClientObject();}
+ void SetClientData(void *data) {m_client_data.SetClientData(data);}
+ void *GetClientData() const {return m_client_data.GetClientData();}
+
+protected:
+ wxBitmap m_bitmap;
+ wxClientDataContainer m_client_data;
+ wxRect m_position;
+ int m_id;
+ bool m_is_visible;
+};
+
+BEGIN_EVENT_TABLE(wxRibbonGallery, wxRibbonControl)
+ EVT_ENTER_WINDOW(wxRibbonGallery::OnMouseEnter)
+ EVT_ERASE_BACKGROUND(wxRibbonGallery::OnEraseBackground)
+ EVT_LEAVE_WINDOW(wxRibbonGallery::OnMouseLeave)
+ EVT_LEFT_DOWN(wxRibbonGallery::OnMouseDown)
+ EVT_LEFT_UP(wxRibbonGallery::OnMouseUp)
+ EVT_MOTION(wxRibbonGallery::OnMouseMove)
+ EVT_PAINT(wxRibbonGallery::OnPaint)
+ EVT_SIZE(wxRibbonGallery::OnSize)
+END_EVENT_TABLE()
+
+wxRibbonGallery::wxRibbonGallery()
+{
+}
+
+wxRibbonGallery::wxRibbonGallery(wxWindow* parent,
+ wxWindowID id,
+ const wxPoint& pos,
+ const wxSize& size,
+ long style)
+ : wxRibbonControl(parent, id, pos, size, wxBORDER_NONE)
+{
+ CommonInit(style);
+}
+
+wxRibbonGallery::~wxRibbonGallery()
+{
+ Clear();
+}
+
+bool wxRibbonGallery::Create(wxWindow* parent,
+ wxWindowID id,
+ const wxPoint& pos,
+ const wxSize& size,
+ long style)
+{
+ if(!wxRibbonControl::Create(parent, id, pos, size, wxBORDER_NONE))
+ {
+ return false;
+ }
+
+ CommonInit(style);
+ return true;
+}
+
+void wxRibbonGallery::CommonInit(long WXUNUSED(style))
+{
+ m_selected_item = NULL;
+ m_hovered_item = NULL;
+ m_active_item = NULL;
+ m_scroll_up_button_rect = wxRect(0, 0, 0, 0);
+ m_scroll_down_button_rect = wxRect(0, 0, 0, 0);
+ m_extension_button_rect = wxRect(0, 0, 0, 0);
+ m_mouse_active_rect = NULL;
+ m_bitmap_size = wxSize(64, 32);
+ m_bitmap_padded_size = m_bitmap_size;
+ m_item_separation_x = 0;
+ m_item_separation_y = 0;
+ m_scroll_amount = 0;
+ m_scroll_limit = 0;
+ m_up_button_state = wxRIBBON_GALLERY_BUTTON_DISABLED;
+ m_down_button_state = wxRIBBON_GALLERY_BUTTON_NORMAL;
+ m_extension_button_state = wxRIBBON_GALLERY_BUTTON_NORMAL;
+ m_hovered = false;
+
+ SetBackgroundStyle(wxBG_STYLE_CUSTOM);
+}
+
+void wxRibbonGallery::OnMouseEnter(wxMouseEvent& evt)
+{
+ m_hovered = true;
+ if(m_mouse_active_rect != NULL && !evt.LeftIsDown())
+ {
+ m_mouse_active_rect = NULL;
+ m_active_item = NULL;
+ }
+ Refresh(false);
+}
+
+void wxRibbonGallery::OnMouseMove(wxMouseEvent& evt)
+{
+ bool refresh = false;
+ wxPoint pos = evt.GetPosition();
+
+ if(TestButtonHover(m_scroll_up_button_rect, pos, &m_up_button_state))
+ refresh = true;
+ if(TestButtonHover(m_scroll_down_button_rect, pos, &m_down_button_state))
+ refresh = true;
+ if(TestButtonHover(m_extension_button_rect, pos, &m_extension_button_state))
+ refresh = true;
+
+ wxRibbonGalleryItem *hovered_item = NULL;
+ wxRibbonGalleryItem *active_item = NULL;
+ if(m_client_rect.Contains(pos))
+ {
+ if(m_art && m_art->GetFlags() & wxRIBBON_BAR_FLOW_VERTICAL)
+ pos.x += m_scroll_amount;
+ else
+ pos.y += m_scroll_amount;
+
+ size_t item_count = m_items.Count();
+ size_t item_i;
+ for(item_i = 0; item_i < item_count; ++item_i)
+ {
+ wxRibbonGalleryItem *item = m_items.Item(item_i);
+ if(!item->IsVisible())
+ continue;
+
+ if(item->GetPosition().Contains(pos))
+ {
+ if(m_mouse_active_rect == &item->GetPosition())
+ active_item = item;
+ hovered_item = item;
+ break;
+ }
+ }
+ }
+ if(active_item != m_active_item)
+ {
+ m_active_item = active_item;
+ refresh = true;
+ }
+ if(hovered_item != m_hovered_item)
+ {
+ m_hovered_item = hovered_item;
+ wxRibbonGalleryEvent notification(
+ wxEVT_COMMAND_RIBBONGALLERY_HOVER_CHANGED, GetId());
+ notification.SetEventObject(this);
+ notification.SetGallery(this);
+ notification.SetGalleryItem(hovered_item);
+ ProcessWindowEvent(notification);
+ refresh = true;
+ }
+
+ if(refresh)
+ Refresh(false);
+}
+
+bool wxRibbonGallery::TestButtonHover(const wxRect& rect, wxPoint pos,
+ wxRibbonGalleryButtonState* state)
+{
+ if(*state == wxRIBBON_GALLERY_BUTTON_DISABLED)
+ return false;
+
+ wxRibbonGalleryButtonState new_state;
+ if(rect.Contains(pos))
+ {
+ if(m_mouse_active_rect == &rect)
+ new_state = wxRIBBON_GALLERY_BUTTON_ACTIVE;
+ else
+ new_state = wxRIBBON_GALLERY_BUTTON_HOVERED;
+ }
+ else
+ new_state = wxRIBBON_GALLERY_BUTTON_NORMAL;
+
+ if(new_state != *state)
+ {
+ *state = new_state;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+void wxRibbonGallery::OnMouseLeave(wxMouseEvent& WXUNUSED(evt))
+{
+ m_hovered = false;
+ m_active_item = NULL;
+ if(m_up_button_state != wxRIBBON_GALLERY_BUTTON_DISABLED)
+ m_up_button_state = wxRIBBON_GALLERY_BUTTON_NORMAL;
+ if(m_down_button_state != wxRIBBON_GALLERY_BUTTON_DISABLED)
+ m_down_button_state = wxRIBBON_GALLERY_BUTTON_NORMAL;
+ if(m_extension_button_state != wxRIBBON_GALLERY_BUTTON_DISABLED)
+ m_extension_button_state = wxRIBBON_GALLERY_BUTTON_NORMAL;
+ if(m_hovered_item != NULL)
+ {
+ m_hovered_item = NULL;
+ wxRibbonGalleryEvent notification(
+ wxEVT_COMMAND_RIBBONGALLERY_HOVER_CHANGED, GetId());
+ notification.SetEventObject(this);
+ notification.SetGallery(this);
+ ProcessWindowEvent(notification);
+ }
+ Refresh(false);
+}
+
+void wxRibbonGallery::OnMouseDown(wxMouseEvent& evt)
+{
+ wxPoint pos = evt.GetPosition();
+ m_mouse_active_rect = NULL;
+ if(m_client_rect.Contains(pos))
+ {
+ if(m_art && m_art->GetFlags() & wxRIBBON_BAR_FLOW_VERTICAL)
+ pos.x += m_scroll_amount;
+ else
+ pos.y += m_scroll_amount;
+ size_t item_count = m_items.Count();
+ size_t item_i;
+ for(item_i = 0; item_i < item_count; ++item_i)
+ {
+ wxRibbonGalleryItem *item = m_items.Item(item_i);
+ if(!item->IsVisible())
+ continue;
+
+ const wxRect& rect = item->GetPosition();
+ if(rect.Contains(pos))
+ {
+ m_active_item = item;
+ m_mouse_active_rect = ▭
+ break;
+ }
+ }
+ }
+ else if(m_scroll_up_button_rect.Contains(pos))
+ {
+ if(m_up_button_state != wxRIBBON_GALLERY_BUTTON_DISABLED)
+ {
+ m_mouse_active_rect = &m_scroll_up_button_rect;
+ m_up_button_state = wxRIBBON_GALLERY_BUTTON_ACTIVE;
+ }
+ }
+ else if(m_scroll_down_button_rect.Contains(pos))
+ {
+ if(m_down_button_state != wxRIBBON_GALLERY_BUTTON_DISABLED)
+ {
+ m_mouse_active_rect = &m_scroll_down_button_rect;
+ m_down_button_state = wxRIBBON_GALLERY_BUTTON_ACTIVE;
+ }
+ }
+ else if(m_extension_button_rect.Contains(pos))
+ {
+ if(m_extension_button_state != wxRIBBON_GALLERY_BUTTON_DISABLED)
+ {
+ m_mouse_active_rect = &m_extension_button_rect;
+ m_extension_button_state = wxRIBBON_GALLERY_BUTTON_ACTIVE;
+ }
+ }
+ if(m_mouse_active_rect != NULL)
+ Refresh(false);
+}
+
+void wxRibbonGallery::OnMouseUp(wxMouseEvent& evt)
+{
+ if(m_mouse_active_rect != NULL)
+ {
+ wxPoint pos = evt.GetPosition();
+ if(m_active_item)
+ {
+ if(m_art && m_art->GetFlags() & wxRIBBON_BAR_FLOW_VERTICAL)
+ pos.x += m_scroll_amount;
+ else
+ pos.y += m_scroll_amount;
+ }
+ if(m_mouse_active_rect->Contains(pos))
+ {
+ if(m_mouse_active_rect == &m_scroll_up_button_rect)
+ {
+ m_up_button_state = wxRIBBON_GALLERY_BUTTON_HOVERED;
+ ScrollLines(-1);
+ }
+ else if(m_mouse_active_rect == &m_scroll_down_button_rect)
+ {
+ m_down_button_state = wxRIBBON_GALLERY_BUTTON_HOVERED;
+ ScrollLines(1);
+ }
+ else if(m_mouse_active_rect == &m_extension_button_rect)
+ {
+ m_extension_button_state = wxRIBBON_GALLERY_BUTTON_HOVERED;
+ wxCommandEvent notification(wxEVT_COMMAND_BUTTON_CLICKED,
+ GetId());
+ notification.SetEventObject(this);
+ ProcessWindowEvent(notification);
+ }
+ else if(m_active_item != NULL)
+ {
+ if(m_selected_item != m_active_item)
+ {
+ m_selected_item = m_active_item;
+ wxRibbonGalleryEvent notification(
+ wxEVT_COMMAND_RIBBONGALLERY_SELECTED, GetId());
+ notification.SetEventObject(this);
+ notification.SetGallery(this);
+ notification.SetGalleryItem(m_selected_item);
+ ProcessWindowEvent(notification);
+ }
+ }
+ }
+ m_mouse_active_rect = NULL;
+ m_active_item = NULL;
+ Refresh(false);
+ }
+}
+
+void wxRibbonGallery::SetItemClientObject(wxRibbonGalleryItem* itm,
+ wxClientData* data)
+{
+ itm->SetClientObject(data);
+}
+
+wxClientData* wxRibbonGallery::GetItemClientObject(const wxRibbonGalleryItem* itm) const
+{
+ return itm->GetClientObject();
+}
+
+void wxRibbonGallery::SetItemClientData(wxRibbonGalleryItem* itm, void* data)
+{
+ itm->SetClientData(data);
+}
+
+void* wxRibbonGallery::GetItemClientData(const wxRibbonGalleryItem* itm) const
+{
+ return itm->GetClientData();
+}
+
+bool wxRibbonGallery::ScrollLines(int lines)
+{
+ if(m_scroll_limit == 0 || m_art == NULL)
+ return false;
+
+ int line_size = m_bitmap_padded_size.GetHeight();
+ if(m_art->GetFlags() & wxRIBBON_BAR_FLOW_VERTICAL)
+ line_size = m_bitmap_padded_size.GetWidth();
+ if(lines < 0)
+ {
+ if(m_scroll_amount > 0)
+ {
+ m_scroll_amount += lines * line_size;
+ if(m_scroll_amount <= 0)
+ {
+ m_scroll_amount = 0;
+ m_up_button_state = wxRIBBON_GALLERY_BUTTON_DISABLED;
+ }
+ else if(m_up_button_state == wxRIBBON_GALLERY_BUTTON_DISABLED)
+ m_up_button_state = wxRIBBON_GALLERY_BUTTON_NORMAL;
+ if(m_down_button_state == wxRIBBON_GALLERY_BUTTON_DISABLED)
+ m_down_button_state = wxRIBBON_GALLERY_BUTTON_NORMAL;
+ return true;
+ }
+ }
+ else if(lines > 0)
+ {
+ if(m_scroll_amount < m_scroll_limit)
+ {
+ m_scroll_amount += lines * line_size;
+ if(m_scroll_amount >= m_scroll_limit)
+ {
+ m_scroll_amount = m_scroll_limit;
+ m_down_button_state = wxRIBBON_GALLERY_BUTTON_DISABLED;
+ }
+ else if(m_down_button_state == wxRIBBON_GALLERY_BUTTON_DISABLED)
+ m_down_button_state = wxRIBBON_GALLERY_BUTTON_NORMAL;
+ if(m_up_button_state == wxRIBBON_GALLERY_BUTTON_DISABLED)
+ m_up_button_state = wxRIBBON_GALLERY_BUTTON_NORMAL;
+ return true;
+ }
+ }
+ return false;
+}
+
+void wxRibbonGallery::EnsureVisible(const wxRibbonGalleryItem* item)
+{
+ if(item == NULL || !item->IsVisible() || IsEmpty())
+ return;
+
+ int y = item->GetPosition().GetTop();
+ int base_y = m_items.Item(0)->GetPosition().GetTop();
+ int delta = y - base_y - m_scroll_amount;
+ ScrollLines(delta / m_bitmap_padded_size.GetHeight());
+}
+
+bool wxRibbonGallery::IsHovered() const
+{
+ return m_hovered;
+}
+
+void wxRibbonGallery::OnEraseBackground(wxEraseEvent& WXUNUSED(evt))
+{
+ // All painting done in main paint handler to minimise flicker
+}
+
+void wxRibbonGallery::OnPaint(wxPaintEvent& WXUNUSED(evt))
+{
+ wxAutoBufferedPaintDC dc(this);
+ if(m_art == NULL)
+ return;
+
+ wxSize cur_size = GetSize();
+ wxSize min_size = GetMinSize();
+
+ m_art->DrawGalleryBackground(dc, this, GetSize());
+
+ int padding_top = m_art->GetMetric(wxRIBBON_ART_GALLERY_BITMAP_PADDING_TOP_SIZE);
+ int padding_left = m_art->GetMetric(wxRIBBON_ART_GALLERY_BITMAP_PADDING_LEFT_SIZE);
+
+ dc.SetClippingRegion(m_client_rect);
+
+ bool offset_vertical = true;
+ if(m_art->GetFlags() & wxRIBBON_BAR_FLOW_VERTICAL)
+ offset_vertical = false;
+ size_t item_count = m_items.Count();
+ size_t item_i;
+ for(item_i = 0; item_i < item_count; ++item_i)
+ {
+ wxRibbonGalleryItem *item = m_items.Item(item_i);
+ if(!item->IsVisible())
+ continue;
+
+ const wxRect& pos = item->GetPosition();
+ wxRect offset_pos(pos);
+ if(offset_vertical)
+ offset_pos.SetTop(offset_pos.GetTop() - m_scroll_amount);
+ else
+ offset_pos.SetLeft(offset_pos.GetLeft() - m_scroll_amount);
+ m_art->DrawGalleryItemBackground(dc, this, offset_pos, item);
+ dc.DrawBitmap(item->GetBitmap(), offset_pos.GetLeft() + padding_left,
+ offset_pos.GetTop() + padding_top);
+ }
+}
+
+void wxRibbonGallery::OnSize(wxSizeEvent& WXUNUSED(evt))
+{
+ Layout();
+}
+
+wxRibbonGalleryItem* wxRibbonGallery::Append(const wxBitmap& bitmap, int id)
+{
+ wxASSERT(bitmap.IsOk());
+ if(m_items.IsEmpty())
+ {
+ m_bitmap_size = bitmap.GetSize();
+ CalculateMinSize();
+ }
+ else
+ {
+ wxASSERT(bitmap.GetSize() == m_bitmap_size);
+ }
+
+ wxRibbonGalleryItem *item = new wxRibbonGalleryItem;
+ item->SetId(id);
+ item->SetBitmap(bitmap);
+ m_items.Add(item);
+ return item;
+}
+
+wxRibbonGalleryItem* wxRibbonGallery::Append(const wxBitmap& bitmap, int id,
+ void* clientData)
+{
+ wxRibbonGalleryItem *item = Append(bitmap, id);
+ item->SetClientData(clientData);
+ return item;
+}
+
+wxRibbonGalleryItem* wxRibbonGallery::Append(const wxBitmap& bitmap, int id,
+ wxClientData* clientData)
+{
+ wxRibbonGalleryItem *item = Append(bitmap, id);
+ item->SetClientObject(clientData);
+ return item;
+}
+
+void wxRibbonGallery::Clear()
+{
+ size_t item_count = m_items.Count();
+ size_t item_i;
+ for(item_i = 0; item_i < item_count; ++item_i)
+ {
+ wxRibbonGalleryItem *item = m_items.Item(item_i);
+ delete item;
+ }
+ m_items.Clear();
+}
+
+bool wxRibbonGallery::IsSizingContinuous() const
+{
+ return false;
+}
+
+void wxRibbonGallery::CalculateMinSize()
+{
+ if(m_art == NULL || !m_bitmap_size.IsFullySpecified())
+ {
+ SetMinSize(wxSize(20, 20));
+ }
+ else
+ {
+ m_bitmap_padded_size = m_bitmap_size;
+ m_bitmap_padded_size.IncBy(
+ m_art->GetMetric(wxRIBBON_ART_GALLERY_BITMAP_PADDING_LEFT_SIZE) +
+ m_art->GetMetric(wxRIBBON_ART_GALLERY_BITMAP_PADDING_RIGHT_SIZE),
+ m_art->GetMetric(wxRIBBON_ART_GALLERY_BITMAP_PADDING_TOP_SIZE) +
+ m_art->GetMetric(wxRIBBON_ART_GALLERY_BITMAP_PADDING_BOTTOM_SIZE));
+
+ wxMemoryDC dc;
+ SetMinSize(m_art->GetGallerySize(dc, this, m_bitmap_padded_size));
+
+ // The best size is displaying several items
+ m_best_size = m_bitmap_padded_size;
+ m_best_size.x *= 3;
+ m_best_size = m_art->GetGallerySize(dc, this, m_best_size);
+ }
+}
+
+bool wxRibbonGallery::Realize()
+{
+ CalculateMinSize();
+ return Layout();
+}
+
+bool wxRibbonGallery::Layout()
+{
+ if(m_art == NULL)
+ return false;
+
+ wxMemoryDC dc;
+ wxPoint origin;
+ wxSize client_size = m_art->GetGalleryClientSize(dc, this, GetSize(),
+ &origin, &m_scroll_up_button_rect, &m_scroll_down_button_rect,
+ &m_extension_button_rect);
+ m_client_rect = wxRect(origin, client_size);
+
+ int x_cursor = 0;
+ int y_cursor = 0;
+
+ size_t item_count = m_items.Count();
+ size_t item_i;
+ long art_flags = m_art->GetFlags();
+ for(item_i = 0; item_i < item_count; ++item_i)
+ {
+ wxRibbonGalleryItem *item = m_items.Item(item_i);
+ item->SetIsVisible(true);
+ if(art_flags & wxRIBBON_BAR_FLOW_VERTICAL)
+ {
+ if(y_cursor + m_bitmap_padded_size.y > client_size.GetHeight())
+ {
+ if(y_cursor == 0)
+ break;
+ y_cursor = 0;
+ x_cursor += m_bitmap_padded_size.x;
+ }
+ item->SetPosition(origin.x + x_cursor, origin.y + y_cursor,
+ m_bitmap_padded_size);
+ y_cursor += m_bitmap_padded_size.y;
+ }
+ else
+ {
+ if(x_cursor + m_bitmap_padded_size.x > client_size.GetWidth())
+ {
+ if(x_cursor == 0)
+ break;
+ x_cursor = 0;
+ y_cursor += m_bitmap_padded_size.y;
+ }
+ item->SetPosition(origin.x + x_cursor, origin.y + y_cursor,
+ m_bitmap_padded_size);
+ x_cursor += m_bitmap_padded_size.x;
+ }
+ }
+ for(; item_i < item_count; ++item_i)
+ {
+ wxRibbonGalleryItem *item = m_items.Item(item_i);
+ item->SetIsVisible(false);
+ }
+ if(art_flags & wxRIBBON_BAR_FLOW_VERTICAL)
+ m_scroll_limit = x_cursor;
+ else
+ m_scroll_limit = y_cursor;
+ if(m_scroll_amount >= m_scroll_limit)
+ {
+ m_scroll_amount = m_scroll_limit;
+ m_down_button_state = wxRIBBON_GALLERY_BUTTON_DISABLED;
+ }
+ else if(m_down_button_state == wxRIBBON_GALLERY_BUTTON_DISABLED)
+ m_down_button_state = wxRIBBON_GALLERY_BUTTON_NORMAL;
+
+ if(m_scroll_amount <= 0)
+ {
+ m_scroll_amount = 0;
+ m_up_button_state = wxRIBBON_GALLERY_BUTTON_DISABLED;
+ }
+ else if(m_up_button_state == wxRIBBON_GALLERY_BUTTON_DISABLED)
+ m_up_button_state = wxRIBBON_GALLERY_BUTTON_NORMAL;
+
+ return true;
+}
+
+wxSize wxRibbonGallery::DoGetBestSize() const
+{
+ return m_best_size;
+}
+
+wxSize wxRibbonGallery::DoGetNextSmallerSize(wxOrientation direction,
+ wxSize relative_to) const
+{
+ if(m_art == NULL)
+ return relative_to;
+
+ wxMemoryDC dc;
+
+ wxSize client = m_art->GetGalleryClientSize(dc, this, relative_to, NULL,
+ NULL, NULL, NULL);
+ switch(direction)
+ {
+ case wxHORIZONTAL:
+ client.DecBy(1, 0);
+ break;
+ case wxVERTICAL:
+ client.DecBy(0, 1);
+ break;
+ case wxBOTH:
+ client.DecBy(1, 1);
+ break;
+ }
+ if(client.GetWidth() < 0 || client.GetHeight() < 0)
+ return relative_to;
+
+ client.x = (client.x / m_bitmap_padded_size.x) * m_bitmap_padded_size.x;
+ client.y = (client.y / m_bitmap_padded_size.y) * m_bitmap_padded_size.y;
+
+ wxSize size = m_art->GetGallerySize(dc, this, client);
+ wxSize minimum = GetMinSize();
+
+ if(size.GetWidth() < minimum.GetWidth() ||
+ size.GetHeight() < minimum.GetHeight())
+ {
+ return relative_to;
+ }
+
+ switch(direction)
+ {
+ case wxHORIZONTAL:
+ size.SetHeight(relative_to.GetHeight());
+ break;
+ case wxVERTICAL:
+ size.SetWidth(relative_to.GetWidth());
+ break;
+ default:
+ break;
+ }
+
+ return size;
+}
+
+wxSize wxRibbonGallery::DoGetNextLargerSize(wxOrientation direction,
+ wxSize relative_to) const
+{
+ if(m_art == NULL)
+ return relative_to;
+
+ wxMemoryDC dc;
+
+ wxSize client = m_art->GetGalleryClientSize(dc, this, relative_to, NULL,
+ NULL, NULL, NULL);
+
+ // No need to grow if the given size can already display every item
+ int nitems = (client.GetWidth() / m_bitmap_padded_size.x) *
+ (client.GetHeight() / m_bitmap_padded_size.y);
+ if(nitems >= (int)m_items.GetCount())
+ return relative_to;
+
+ switch(direction)
+ {
+ case wxHORIZONTAL:
+ client.IncBy(m_bitmap_padded_size.x, 0);
+ break;
+ case wxVERTICAL:
+ client.IncBy(0, m_bitmap_padded_size.y);
+ break;
+ case wxBOTH:
+ client.IncBy(m_bitmap_padded_size);
+ break;
+ }
+
+ client.x = (client.x / m_bitmap_padded_size.x) * m_bitmap_padded_size.x;
+ client.y = (client.y / m_bitmap_padded_size.y) * m_bitmap_padded_size.y;
+
+ wxSize size = m_art->GetGallerySize(dc, this, client);
+ wxSize minimum = GetMinSize();
+
+ if(size.GetWidth() < minimum.GetWidth() ||
+ size.GetHeight() < minimum.GetHeight())
+ {
+ return relative_to;
+ }
+
+ switch(direction)
+ {
+ case wxHORIZONTAL:
+ size.SetHeight(relative_to.GetHeight());
+ break;
+ case wxVERTICAL:
+ size.SetWidth(relative_to.GetWidth());
+ break;
+ default:
+ break;
+ }
+
+ return size;
+}
+
+bool wxRibbonGallery::IsEmpty() const
+{
+ return m_items.IsEmpty();
+}
+
+unsigned int wxRibbonGallery::GetCount() const
+{
+ return (unsigned int)m_items.GetCount();
+}
+
+wxRibbonGalleryItem* wxRibbonGallery::GetItem(unsigned int n)
+{
+ if(n >= GetCount())
+ return NULL;
+ return m_items.Item(n);
+}
+
+void wxRibbonGallery::SetSelection(wxRibbonGalleryItem* item)
+{
+ if(item != m_selected_item)
+ {
+ m_selected_item = item;
+ Refresh(false);
+ }
+}
+
+wxRibbonGalleryItem* wxRibbonGallery::GetSelection() const
+{
+ return m_selected_item;
+}
+
+wxRibbonGalleryItem* wxRibbonGallery::GetHoveredItem() const
+{
+ return m_hovered_item;
+}
+
+wxRibbonGalleryItem* wxRibbonGallery::GetActiveItem() const
+{
+ return m_active_item;
+}
+
+wxRibbonGalleryButtonState wxRibbonGallery::GetUpButtonState() const
+{
+ return m_up_button_state;
+}
+
+wxRibbonGalleryButtonState wxRibbonGallery::GetDownButtonState() const
+{
+ return m_down_button_state;
+}
+
+wxRibbonGalleryButtonState wxRibbonGallery::GetExtensionButtonState() const
+{
+ return m_extension_button_state;
+}
+
+#endif // wxUSE_RIBBON