Change {DECLARE,IMPLEMENT}_*CLASS and {DECLARE,BEGIN,END}_EVENT_TABLE
occurrences to use the wx-prefixed version of the macros.
1264 lines
37 KiB
C++
1264 lines
37 KiB
C++
///////////////////////////////////////////////////////////////////////////////
|
|
// Name: src/ribbon/buttonbar.cpp
|
|
// Purpose: Ribbon control similar to a tool bar
|
|
// Author: Peter Cawley
|
|
// Modified by:
|
|
// Created: 2009-07-01
|
|
// Copyright: (C) Peter Cawley
|
|
// Licence: wxWindows licence
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "wx/wxprec.h"
|
|
|
|
#ifdef __BORLANDC__
|
|
#pragma hdrstop
|
|
#endif
|
|
|
|
#if wxUSE_RIBBON
|
|
|
|
#include "wx/ribbon/panel.h"
|
|
#include "wx/ribbon/buttonbar.h"
|
|
#include "wx/ribbon/art.h"
|
|
#include "wx/dcbuffer.h"
|
|
|
|
#ifndef WX_PRECOMP
|
|
#endif
|
|
|
|
#ifdef __WXMSW__
|
|
#include "wx/msw/private.h"
|
|
#endif
|
|
|
|
wxDEFINE_EVENT(wxEVT_RIBBONBUTTONBAR_CLICKED, wxRibbonButtonBarEvent);
|
|
wxDEFINE_EVENT(wxEVT_RIBBONBUTTONBAR_DROPDOWN_CLICKED, wxRibbonButtonBarEvent);
|
|
|
|
wxIMPLEMENT_DYNAMIC_CLASS(wxRibbonButtonBarEvent, wxCommandEvent);
|
|
wxIMPLEMENT_CLASS(wxRibbonButtonBar, wxRibbonControl);
|
|
|
|
wxBEGIN_EVENT_TABLE(wxRibbonButtonBar, wxRibbonControl)
|
|
EVT_ERASE_BACKGROUND(wxRibbonButtonBar::OnEraseBackground)
|
|
EVT_ENTER_WINDOW(wxRibbonButtonBar::OnMouseEnter)
|
|
EVT_LEAVE_WINDOW(wxRibbonButtonBar::OnMouseLeave)
|
|
EVT_MOTION(wxRibbonButtonBar::OnMouseMove)
|
|
EVT_PAINT(wxRibbonButtonBar::OnPaint)
|
|
EVT_SIZE(wxRibbonButtonBar::OnSize)
|
|
EVT_LEFT_DOWN(wxRibbonButtonBar::OnMouseDown)
|
|
EVT_LEFT_DCLICK(wxRibbonButtonBar::OnMouseDown)
|
|
EVT_LEFT_UP(wxRibbonButtonBar::OnMouseUp)
|
|
wxEND_EVENT_TABLE()
|
|
|
|
class wxRibbonButtonBarButtonSizeInfo
|
|
{
|
|
public:
|
|
bool is_supported;
|
|
wxSize size;
|
|
wxRect normal_region;
|
|
wxRect dropdown_region;
|
|
};
|
|
|
|
class wxRibbonButtonBarButtonInstance
|
|
{
|
|
public:
|
|
wxPoint position;
|
|
wxRibbonButtonBarButtonBase* base;
|
|
wxRibbonButtonBarButtonState size;
|
|
};
|
|
|
|
class wxRibbonButtonBarButtonBase
|
|
{
|
|
public:
|
|
wxRibbonButtonBarButtonInstance NewInstance()
|
|
{
|
|
wxRibbonButtonBarButtonInstance i;
|
|
i.base = this;
|
|
return i;
|
|
}
|
|
|
|
wxRibbonButtonBarButtonState GetLargestSize()
|
|
{
|
|
if(sizes[wxRIBBON_BUTTONBAR_BUTTON_LARGE].is_supported)
|
|
return wxRIBBON_BUTTONBAR_BUTTON_LARGE;
|
|
if(sizes[wxRIBBON_BUTTONBAR_BUTTON_MEDIUM].is_supported)
|
|
return wxRIBBON_BUTTONBAR_BUTTON_MEDIUM;
|
|
wxASSERT(sizes[wxRIBBON_BUTTONBAR_BUTTON_SMALL].is_supported);
|
|
return wxRIBBON_BUTTONBAR_BUTTON_SMALL;
|
|
}
|
|
|
|
bool GetSmallerSize(
|
|
wxRibbonButtonBarButtonState* size, int n = 1)
|
|
{
|
|
for(; n > 0; --n)
|
|
{
|
|
switch(*size)
|
|
{
|
|
case wxRIBBON_BUTTONBAR_BUTTON_LARGE:
|
|
if(sizes[wxRIBBON_BUTTONBAR_BUTTON_MEDIUM].is_supported)
|
|
{
|
|
*size = wxRIBBON_BUTTONBAR_BUTTON_MEDIUM;
|
|
break;
|
|
}
|
|
wxFALLTHROUGH;
|
|
case wxRIBBON_BUTTONBAR_BUTTON_MEDIUM:
|
|
if(sizes[wxRIBBON_BUTTONBAR_BUTTON_SMALL].is_supported)
|
|
{
|
|
*size = wxRIBBON_BUTTONBAR_BUTTON_SMALL;
|
|
break;
|
|
}
|
|
wxFALLTHROUGH;
|
|
case wxRIBBON_BUTTONBAR_BUTTON_SMALL:
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
wxString label;
|
|
wxString help_string;
|
|
wxBitmap bitmap_large;
|
|
wxBitmap bitmap_large_disabled;
|
|
wxBitmap bitmap_small;
|
|
wxBitmap bitmap_small_disabled;
|
|
wxRibbonButtonBarButtonSizeInfo sizes[3];
|
|
wxClientDataContainer client_data;
|
|
int id;
|
|
wxRibbonButtonKind kind;
|
|
long state;
|
|
};
|
|
|
|
WX_DECLARE_OBJARRAY(wxRibbonButtonBarButtonInstance, wxArrayRibbonButtonBarButtonInstance);
|
|
#include "wx/arrimpl.cpp"
|
|
WX_DEFINE_OBJARRAY(wxArrayRibbonButtonBarButtonInstance)
|
|
|
|
class wxRibbonButtonBarLayout
|
|
{
|
|
public:
|
|
wxSize overall_size;
|
|
wxArrayRibbonButtonBarButtonInstance buttons;
|
|
|
|
void CalculateOverallSize()
|
|
{
|
|
overall_size = wxSize(0, 0);
|
|
size_t btn_count = buttons.Count();
|
|
size_t btn_i;
|
|
for(btn_i = 0; btn_i < btn_count; ++btn_i)
|
|
{
|
|
wxRibbonButtonBarButtonInstance& instance = buttons.Item(btn_i);
|
|
wxSize size = instance.base->sizes[instance.size].size;
|
|
int right = instance.position.x + size.GetWidth();
|
|
int bottom = instance.position.y + size.GetHeight();
|
|
if(right > overall_size.GetWidth())
|
|
{
|
|
overall_size.SetWidth(right);
|
|
}
|
|
if(bottom > overall_size.GetHeight())
|
|
{
|
|
overall_size.SetHeight(bottom);
|
|
}
|
|
}
|
|
}
|
|
|
|
wxRibbonButtonBarButtonInstance* FindSimilarInstance(
|
|
wxRibbonButtonBarButtonInstance* inst)
|
|
{
|
|
if(inst == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
size_t btn_count = buttons.Count();
|
|
size_t btn_i;
|
|
for(btn_i = 0; btn_i < btn_count; ++btn_i)
|
|
{
|
|
wxRibbonButtonBarButtonInstance& instance = buttons.Item(btn_i);
|
|
if(instance.base == inst->base)
|
|
{
|
|
return &instance;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
};
|
|
|
|
wxRibbonButtonBar::wxRibbonButtonBar()
|
|
{
|
|
m_layouts_valid = false;
|
|
CommonInit (0);
|
|
}
|
|
|
|
wxRibbonButtonBar::wxRibbonButtonBar(wxWindow* parent,
|
|
wxWindowID id,
|
|
const wxPoint& pos,
|
|
const wxSize& size,
|
|
long style)
|
|
: wxRibbonControl(parent, id, pos, size, wxBORDER_NONE)
|
|
{
|
|
m_layouts_valid = false;
|
|
|
|
CommonInit(style);
|
|
}
|
|
|
|
wxRibbonButtonBar::~wxRibbonButtonBar()
|
|
{
|
|
size_t count = m_buttons.GetCount();
|
|
size_t i;
|
|
for(i = 0; i < count; ++i)
|
|
{
|
|
wxRibbonButtonBarButtonBase* button = m_buttons.Item(i);
|
|
delete button;
|
|
}
|
|
m_buttons.Clear();
|
|
|
|
count = m_layouts.GetCount();
|
|
for(i = 0; i < count; ++i)
|
|
{
|
|
wxRibbonButtonBarLayout* layout = m_layouts.Item(i);
|
|
delete layout;
|
|
}
|
|
m_layouts.Clear();
|
|
}
|
|
|
|
bool wxRibbonButtonBar::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;
|
|
}
|
|
|
|
wxRibbonButtonBarButtonBase* wxRibbonButtonBar::AddButton(
|
|
int button_id,
|
|
const wxString& label,
|
|
const wxBitmap& bitmap,
|
|
const wxString& help_string,
|
|
wxRibbonButtonKind kind)
|
|
{
|
|
return AddButton(button_id, label, bitmap, wxNullBitmap, wxNullBitmap,
|
|
wxNullBitmap, kind, help_string);
|
|
}
|
|
|
|
wxRibbonButtonBarButtonBase* wxRibbonButtonBar::AddDropdownButton(
|
|
int button_id,
|
|
const wxString& label,
|
|
const wxBitmap& bitmap,
|
|
const wxString& help_string)
|
|
{
|
|
return AddButton(button_id, label, bitmap, help_string,
|
|
wxRIBBON_BUTTON_DROPDOWN);
|
|
}
|
|
|
|
wxRibbonButtonBarButtonBase* wxRibbonButtonBar::AddToggleButton(
|
|
int button_id,
|
|
const wxString& label,
|
|
const wxBitmap& bitmap,
|
|
const wxString& help_string)
|
|
{
|
|
return AddButton(button_id, label, bitmap, help_string,
|
|
wxRIBBON_BUTTON_TOGGLE);
|
|
}
|
|
|
|
wxRibbonButtonBarButtonBase* wxRibbonButtonBar::AddHybridButton(
|
|
int button_id,
|
|
const wxString& label,
|
|
const wxBitmap& bitmap,
|
|
const wxString& help_string)
|
|
{
|
|
return AddButton(button_id, label, bitmap, help_string,
|
|
wxRIBBON_BUTTON_HYBRID);
|
|
}
|
|
|
|
wxRibbonButtonBarButtonBase* wxRibbonButtonBar::AddButton(
|
|
int button_id,
|
|
const wxString& label,
|
|
const wxBitmap& bitmap,
|
|
const wxBitmap& bitmap_small,
|
|
const wxBitmap& bitmap_disabled,
|
|
const wxBitmap& bitmap_small_disabled,
|
|
wxRibbonButtonKind kind,
|
|
const wxString& help_string)
|
|
{
|
|
return InsertButton(GetButtonCount(), button_id, label, bitmap,
|
|
bitmap_small, bitmap_disabled,bitmap_small_disabled, kind, help_string);
|
|
}
|
|
|
|
wxRibbonButtonBarButtonBase* wxRibbonButtonBar::InsertButton(
|
|
size_t pos,
|
|
int button_id,
|
|
const wxString& label,
|
|
const wxBitmap& bitmap,
|
|
const wxBitmap& bitmap_small,
|
|
const wxBitmap& bitmap_disabled,
|
|
const wxBitmap& bitmap_small_disabled,
|
|
wxRibbonButtonKind kind,
|
|
const wxString& help_string)
|
|
{
|
|
wxASSERT(bitmap.IsOk() || bitmap_small.IsOk());
|
|
if(m_buttons.IsEmpty())
|
|
{
|
|
if(bitmap.IsOk())
|
|
{
|
|
m_bitmap_size_large = bitmap.GetSize();
|
|
if(!bitmap_small.IsOk())
|
|
{
|
|
m_bitmap_size_small = m_bitmap_size_large;
|
|
m_bitmap_size_small *= 0.5;
|
|
}
|
|
}
|
|
if(bitmap_small.IsOk())
|
|
{
|
|
m_bitmap_size_small = bitmap_small.GetSize();
|
|
if(!bitmap.IsOk())
|
|
{
|
|
m_bitmap_size_large = m_bitmap_size_small;
|
|
m_bitmap_size_large *= 2.0;
|
|
}
|
|
}
|
|
}
|
|
|
|
wxRibbonButtonBarButtonBase* base = new wxRibbonButtonBarButtonBase;
|
|
base->id = button_id;
|
|
base->label = label;
|
|
base->bitmap_large = bitmap;
|
|
if(!base->bitmap_large.IsOk())
|
|
{
|
|
base->bitmap_large = MakeResizedBitmap(base->bitmap_small,
|
|
m_bitmap_size_large);
|
|
}
|
|
else if(base->bitmap_large.GetSize() != m_bitmap_size_large)
|
|
{
|
|
base->bitmap_large = MakeResizedBitmap(base->bitmap_large,
|
|
m_bitmap_size_large);
|
|
}
|
|
base->bitmap_small = bitmap_small;
|
|
if(!base->bitmap_small.IsOk())
|
|
{
|
|
base->bitmap_small = MakeResizedBitmap(base->bitmap_large,
|
|
m_bitmap_size_small);
|
|
}
|
|
else if(base->bitmap_small.GetSize() != m_bitmap_size_small)
|
|
{
|
|
base->bitmap_small = MakeResizedBitmap(base->bitmap_small,
|
|
m_bitmap_size_small);
|
|
}
|
|
base->bitmap_large_disabled = bitmap_disabled;
|
|
if(!base->bitmap_large_disabled.IsOk())
|
|
{
|
|
base->bitmap_large_disabled = MakeDisabledBitmap(base->bitmap_large);
|
|
}
|
|
base->bitmap_small_disabled = bitmap_small_disabled;
|
|
if(!base->bitmap_small_disabled.IsOk())
|
|
{
|
|
base->bitmap_small_disabled = MakeDisabledBitmap(base->bitmap_small);
|
|
}
|
|
base->kind = kind;
|
|
base->help_string = help_string;
|
|
base->state = 0;
|
|
|
|
wxClientDC temp_dc(this);
|
|
FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_SMALL, temp_dc);
|
|
FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_MEDIUM, temp_dc);
|
|
FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_LARGE, temp_dc);
|
|
|
|
m_buttons.Insert(base, pos);
|
|
m_layouts_valid = false;
|
|
return base;
|
|
}
|
|
|
|
|
|
void
|
|
wxRibbonButtonBar::SetItemClientObject(wxRibbonButtonBarButtonBase* item,
|
|
wxClientData* data)
|
|
{
|
|
wxCHECK_RET( item, "Can't associate client object with an invalid item" );
|
|
|
|
item->client_data.SetClientObject(data);
|
|
}
|
|
|
|
wxClientData*
|
|
wxRibbonButtonBar::GetItemClientObject(const wxRibbonButtonBarButtonBase* item) const
|
|
{
|
|
wxCHECK_MSG( item, NULL, "Can't get client object for an invalid item" );
|
|
|
|
return item->client_data.GetClientObject();
|
|
}
|
|
|
|
void
|
|
wxRibbonButtonBar::SetItemClientData(wxRibbonButtonBarButtonBase* item,
|
|
void* data)
|
|
{
|
|
wxCHECK_RET( item, "Can't associate client data with an invalid item" );
|
|
|
|
item->client_data.SetClientData(data);
|
|
}
|
|
|
|
void*
|
|
wxRibbonButtonBar::GetItemClientData(const wxRibbonButtonBarButtonBase* item) const
|
|
{
|
|
wxCHECK_MSG( item, NULL, "Can't get client data for an invalid item" );
|
|
|
|
return item->client_data.GetClientData();
|
|
}
|
|
|
|
|
|
wxRibbonButtonBarButtonBase* wxRibbonButtonBar::InsertButton(
|
|
size_t pos,
|
|
int button_id,
|
|
const wxString& label,
|
|
const wxBitmap& bitmap,
|
|
const wxString& help_string,
|
|
wxRibbonButtonKind kind)
|
|
{
|
|
return InsertButton(pos, button_id, label, bitmap, wxNullBitmap,
|
|
wxNullBitmap, wxNullBitmap, kind, help_string);
|
|
}
|
|
|
|
wxRibbonButtonBarButtonBase* wxRibbonButtonBar::InsertDropdownButton(
|
|
size_t pos,
|
|
int button_id,
|
|
const wxString& label,
|
|
const wxBitmap& bitmap,
|
|
const wxString& help_string)
|
|
{
|
|
return InsertButton(pos, button_id, label, bitmap, help_string,
|
|
wxRIBBON_BUTTON_DROPDOWN);
|
|
}
|
|
|
|
wxRibbonButtonBarButtonBase* wxRibbonButtonBar::InsertToggleButton(
|
|
size_t pos,
|
|
int button_id,
|
|
const wxString& label,
|
|
const wxBitmap& bitmap,
|
|
const wxString& help_string)
|
|
{
|
|
return InsertButton(pos, button_id, label, bitmap, help_string,
|
|
wxRIBBON_BUTTON_TOGGLE);
|
|
}
|
|
|
|
wxRibbonButtonBarButtonBase* wxRibbonButtonBar::InsertHybridButton(
|
|
size_t pos,
|
|
int button_id,
|
|
const wxString& label,
|
|
const wxBitmap& bitmap,
|
|
const wxString& help_string)
|
|
{
|
|
return InsertButton(pos, button_id, label, bitmap, help_string,
|
|
wxRIBBON_BUTTON_HYBRID);
|
|
}
|
|
|
|
void wxRibbonButtonBar::FetchButtonSizeInfo(wxRibbonButtonBarButtonBase* button,
|
|
wxRibbonButtonBarButtonState size, wxDC& dc)
|
|
{
|
|
wxRibbonButtonBarButtonSizeInfo& info = button->sizes[size];
|
|
if(m_art)
|
|
{
|
|
info.is_supported = m_art->GetButtonBarButtonSize(dc, this,
|
|
button->kind, size, button->label, m_bitmap_size_large,
|
|
m_bitmap_size_small, &info.size, &info.normal_region,
|
|
&info.dropdown_region);
|
|
}
|
|
else
|
|
info.is_supported = false;
|
|
}
|
|
|
|
wxBitmap wxRibbonButtonBar::MakeResizedBitmap(const wxBitmap& original, wxSize size)
|
|
{
|
|
wxImage img(original.ConvertToImage());
|
|
img.Rescale(size.GetWidth(), size.GetHeight(), wxIMAGE_QUALITY_HIGH);
|
|
return wxBitmap(img);
|
|
}
|
|
|
|
wxBitmap wxRibbonButtonBar::MakeDisabledBitmap(const wxBitmap& original)
|
|
{
|
|
wxImage img(original.ConvertToImage());
|
|
return wxBitmap(img.ConvertToGreyscale());
|
|
}
|
|
|
|
size_t wxRibbonButtonBar::GetButtonCount() const
|
|
{
|
|
return m_buttons.GetCount();
|
|
}
|
|
|
|
bool wxRibbonButtonBar::Realize()
|
|
{
|
|
if(!m_layouts_valid)
|
|
{
|
|
MakeLayouts();
|
|
m_layouts_valid = true;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void wxRibbonButtonBar::ClearButtons()
|
|
{
|
|
m_layouts_valid = false;
|
|
size_t count = m_buttons.GetCount();
|
|
size_t i;
|
|
for(i = 0; i < count; ++i)
|
|
{
|
|
wxRibbonButtonBarButtonBase* button = m_buttons.Item(i);
|
|
delete button;
|
|
}
|
|
m_buttons.Clear();
|
|
Realize();
|
|
}
|
|
|
|
bool wxRibbonButtonBar::DeleteButton(int button_id)
|
|
{
|
|
size_t count = m_buttons.GetCount();
|
|
size_t i;
|
|
for(i = 0; i < count; ++i)
|
|
{
|
|
wxRibbonButtonBarButtonBase* button = m_buttons.Item(i);
|
|
if(button->id == button_id)
|
|
{
|
|
m_layouts_valid = false;
|
|
m_buttons.RemoveAt(i);
|
|
if (m_hovered_button && m_hovered_button->base == button)
|
|
m_hovered_button = NULL;
|
|
if (m_active_button && m_active_button->base == button)
|
|
m_active_button = NULL;
|
|
delete button;
|
|
Realize();
|
|
Refresh();
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void wxRibbonButtonBar::EnableButton(int button_id, bool enable)
|
|
{
|
|
size_t count = m_buttons.GetCount();
|
|
size_t i;
|
|
for(i = 0; i < count; ++i)
|
|
{
|
|
wxRibbonButtonBarButtonBase* button = m_buttons.Item(i);
|
|
if(button->id == button_id)
|
|
{
|
|
if(enable)
|
|
{
|
|
if(button->state & wxRIBBON_BUTTONBAR_BUTTON_DISABLED)
|
|
{
|
|
button->state &= ~wxRIBBON_BUTTONBAR_BUTTON_DISABLED;
|
|
Refresh();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if((button->state & wxRIBBON_BUTTONBAR_BUTTON_DISABLED) == 0)
|
|
{
|
|
button->state |= wxRIBBON_BUTTONBAR_BUTTON_DISABLED;
|
|
Refresh();
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void wxRibbonButtonBar::ToggleButton(int button_id, bool checked)
|
|
{
|
|
size_t count = m_buttons.GetCount();
|
|
size_t i;
|
|
for(i = 0; i < count; ++i)
|
|
{
|
|
wxRibbonButtonBarButtonBase* button = m_buttons.Item(i);
|
|
if(button->id == button_id)
|
|
{
|
|
if(checked)
|
|
{
|
|
if((button->state & wxRIBBON_BUTTONBAR_BUTTON_TOGGLED) == 0)
|
|
{
|
|
button->state |= wxRIBBON_BUTTONBAR_BUTTON_TOGGLED;
|
|
Refresh();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(button->state & wxRIBBON_BUTTONBAR_BUTTON_TOGGLED)
|
|
{
|
|
button->state &= ~wxRIBBON_BUTTONBAR_BUTTON_TOGGLED;
|
|
Refresh();
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void wxRibbonButtonBar::SetArtProvider(wxRibbonArtProvider* art)
|
|
{
|
|
if(art == m_art)
|
|
{
|
|
return;
|
|
}
|
|
|
|
wxRibbonControl::SetArtProvider(art);
|
|
|
|
wxClientDC temp_dc(this);
|
|
size_t btn_count = m_buttons.Count();
|
|
size_t btn_i;
|
|
for(btn_i = 0; btn_i < btn_count; ++btn_i)
|
|
{
|
|
wxRibbonButtonBarButtonBase* base = m_buttons.Item(btn_i);
|
|
|
|
FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_SMALL, temp_dc);
|
|
FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_MEDIUM, temp_dc);
|
|
FetchButtonSizeInfo(base, wxRIBBON_BUTTONBAR_BUTTON_LARGE, temp_dc);
|
|
}
|
|
|
|
m_layouts_valid = false;
|
|
Realize();
|
|
}
|
|
|
|
bool wxRibbonButtonBar::IsSizingContinuous() const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
wxSize wxRibbonButtonBar::DoGetNextSmallerSize(wxOrientation direction,
|
|
wxSize result) const
|
|
{
|
|
size_t nlayouts = m_layouts.GetCount();
|
|
size_t i;
|
|
for(i = 0; i < nlayouts; ++i)
|
|
{
|
|
wxRibbonButtonBarLayout* layout = m_layouts.Item(i);
|
|
wxSize size = layout->overall_size;
|
|
switch(direction)
|
|
{
|
|
case wxHORIZONTAL:
|
|
if(size.x < result.x && size.y <= result.y)
|
|
{
|
|
result.x = size.x;
|
|
break;
|
|
}
|
|
else
|
|
continue;
|
|
case wxVERTICAL:
|
|
if(size.x <= result.x && size.y < result.y)
|
|
{
|
|
result.y = size.y;
|
|
break;
|
|
}
|
|
else
|
|
continue;
|
|
case wxBOTH:
|
|
if(size.x < result.x && size.y < result.y)
|
|
{
|
|
result = size;
|
|
break;
|
|
}
|
|
else
|
|
continue;
|
|
}
|
|
break;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
wxSize wxRibbonButtonBar::DoGetNextLargerSize(wxOrientation direction,
|
|
wxSize result) const
|
|
{
|
|
size_t nlayouts = m_layouts.GetCount();
|
|
size_t i = nlayouts;
|
|
while(i > 0)
|
|
{
|
|
--i;
|
|
wxRibbonButtonBarLayout* layout = m_layouts.Item(i);
|
|
wxSize size = layout->overall_size;
|
|
switch(direction)
|
|
{
|
|
case wxHORIZONTAL:
|
|
if(size.x > result.x && size.y <= result.y)
|
|
{
|
|
result.x = size.x;
|
|
break;
|
|
}
|
|
else
|
|
continue;
|
|
case wxVERTICAL:
|
|
if(size.x <= result.x && size.y > result.y)
|
|
{
|
|
result.y = size.y;
|
|
break;
|
|
}
|
|
else
|
|
continue;
|
|
case wxBOTH:
|
|
if(size.x > result.x && size.y > result.y)
|
|
{
|
|
result = size;
|
|
break;
|
|
}
|
|
else
|
|
continue;
|
|
}
|
|
break;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void wxRibbonButtonBar::UpdateWindowUI(long flags)
|
|
{
|
|
wxWindowBase::UpdateWindowUI(flags);
|
|
|
|
// don't waste time updating state of tools in a hidden toolbar
|
|
if ( !IsShown() )
|
|
return;
|
|
|
|
size_t btn_count = m_buttons.size();
|
|
bool rerealize = false;
|
|
for ( size_t btn_i = 0; btn_i < btn_count; ++btn_i )
|
|
{
|
|
wxRibbonButtonBarButtonBase& btn = *m_buttons.Item(btn_i);
|
|
int id = btn.id;
|
|
|
|
wxUpdateUIEvent event(id);
|
|
event.SetEventObject(this);
|
|
|
|
if ( ProcessWindowEvent(event) )
|
|
{
|
|
if ( event.GetSetEnabled() )
|
|
EnableButton(id, event.GetEnabled());
|
|
if ( event.GetSetChecked() )
|
|
ToggleButton(id, event.GetChecked());
|
|
if ( event.GetSetText() )
|
|
{
|
|
btn.label = event.GetText();
|
|
rerealize = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( rerealize )
|
|
Realize();
|
|
}
|
|
|
|
void wxRibbonButtonBar::OnEraseBackground(wxEraseEvent& WXUNUSED(evt))
|
|
{
|
|
// All painting done in main paint handler to minimise flicker
|
|
}
|
|
|
|
void wxRibbonButtonBar::OnPaint(wxPaintEvent& WXUNUSED(evt))
|
|
{
|
|
wxAutoBufferedPaintDC dc(this);
|
|
m_art->DrawButtonBarBackground(dc, this, GetSize());
|
|
|
|
wxRibbonButtonBarLayout* layout = m_layouts.Item(m_current_layout);
|
|
|
|
size_t btn_count = layout->buttons.Count();
|
|
size_t btn_i;
|
|
for(btn_i = 0; btn_i < btn_count; ++btn_i)
|
|
{
|
|
wxRibbonButtonBarButtonInstance& button = layout->buttons.Item(btn_i);
|
|
wxRibbonButtonBarButtonBase* base = button.base;
|
|
|
|
wxBitmap* bitmap = &base->bitmap_large;
|
|
wxBitmap* bitmap_small = &base->bitmap_small;
|
|
if(base->state & wxRIBBON_BUTTONBAR_BUTTON_DISABLED)
|
|
{
|
|
bitmap = &base->bitmap_large_disabled;
|
|
bitmap_small = &base->bitmap_small_disabled;
|
|
}
|
|
wxRect rect(button.position + m_layout_offset, base->sizes[button.size].size);
|
|
|
|
m_art->DrawButtonBarButton(dc, this, rect, base->kind,
|
|
base->state | button.size, base->label, *bitmap, *bitmap_small);
|
|
}
|
|
}
|
|
|
|
void wxRibbonButtonBar::OnSize(wxSizeEvent& evt)
|
|
{
|
|
wxSize new_size = evt.GetSize();
|
|
size_t layout_count = m_layouts.GetCount();
|
|
size_t layout_i;
|
|
m_current_layout = layout_count - 1;
|
|
for(layout_i = 0; layout_i < layout_count; ++layout_i)
|
|
{
|
|
wxSize layout_size = m_layouts.Item(layout_i)->overall_size;
|
|
if(layout_size.x <= new_size.x && layout_size.y <= new_size.y)
|
|
{
|
|
m_layout_offset.x = (new_size.x - layout_size.x) / 2;
|
|
m_layout_offset.y = (new_size.y - layout_size.y) / 2;
|
|
m_current_layout = layout_i;
|
|
break;
|
|
}
|
|
}
|
|
m_hovered_button = m_layouts.Item(m_current_layout)->FindSimilarInstance(m_hovered_button);
|
|
Refresh();
|
|
}
|
|
|
|
void wxRibbonButtonBar::CommonInit(long WXUNUSED(style))
|
|
{
|
|
m_bitmap_size_large = wxSize(32, 32);
|
|
m_bitmap_size_small = wxSize(16, 16);
|
|
|
|
wxRibbonButtonBarLayout* placeholder_layout = new wxRibbonButtonBarLayout;
|
|
placeholder_layout->overall_size = wxSize(20, 20);
|
|
m_layouts.Add(placeholder_layout);
|
|
m_current_layout = 0;
|
|
m_layout_offset = wxPoint(0, 0);
|
|
m_hovered_button = NULL;
|
|
m_active_button = NULL;
|
|
m_lock_active_state = false;
|
|
m_show_tooltips_for_disabled = false;
|
|
|
|
SetBackgroundStyle(wxBG_STYLE_CUSTOM);
|
|
}
|
|
|
|
void wxRibbonButtonBar::SetShowToolTipsForDisabled(bool show)
|
|
{
|
|
m_show_tooltips_for_disabled = show;
|
|
}
|
|
|
|
bool wxRibbonButtonBar::GetShowToolTipsForDisabled() const
|
|
{
|
|
return m_show_tooltips_for_disabled;
|
|
}
|
|
|
|
wxSize wxRibbonButtonBar::GetMinSize() const
|
|
{
|
|
return m_layouts.Last()->overall_size;
|
|
}
|
|
|
|
wxSize wxRibbonButtonBar::DoGetBestSize() const
|
|
{
|
|
return m_layouts.Item(0)->overall_size;
|
|
}
|
|
|
|
void wxRibbonButtonBar::MakeLayouts()
|
|
{
|
|
if(m_layouts_valid || m_art == NULL)
|
|
{
|
|
return;
|
|
}
|
|
{
|
|
// Clear existing layouts
|
|
if(m_hovered_button)
|
|
{
|
|
m_hovered_button->base->state &= ~wxRIBBON_BUTTONBAR_BUTTON_HOVER_MASK;
|
|
m_hovered_button = NULL;
|
|
}
|
|
if(m_active_button)
|
|
{
|
|
m_active_button->base->state &= ~wxRIBBON_BUTTONBAR_BUTTON_ACTIVE_MASK;
|
|
m_active_button = NULL;
|
|
}
|
|
size_t count = m_layouts.GetCount();
|
|
size_t i;
|
|
for(i = 0; i < count; ++i)
|
|
{
|
|
wxRibbonButtonBarLayout* layout = m_layouts.Item(i);
|
|
delete layout;
|
|
}
|
|
m_layouts.Clear();
|
|
}
|
|
size_t btn_count = m_buttons.Count();
|
|
size_t btn_i;
|
|
{
|
|
// Best layout : all buttons large, stacking horizontally
|
|
wxRibbonButtonBarLayout* layout = new wxRibbonButtonBarLayout;
|
|
wxPoint cursor(0, 0);
|
|
layout->overall_size.SetHeight(0);
|
|
for(btn_i = 0; btn_i < btn_count; ++btn_i)
|
|
{
|
|
wxRibbonButtonBarButtonBase* button = m_buttons.Item(btn_i);
|
|
wxRibbonButtonBarButtonInstance instance = button->NewInstance();
|
|
instance.position = cursor;
|
|
instance.size = button->GetLargestSize();
|
|
wxSize& size = button->sizes[instance.size].size;
|
|
cursor.x += size.GetWidth();
|
|
layout->overall_size.SetHeight(wxMax(layout->overall_size.GetHeight(),
|
|
size.GetHeight()));
|
|
layout->buttons.Add(instance);
|
|
}
|
|
layout->overall_size.SetWidth(cursor.x);
|
|
m_layouts.Add(layout);
|
|
}
|
|
if(btn_count >= 2)
|
|
{
|
|
// Collapse the rightmost buttons and stack them vertically
|
|
size_t iLast = btn_count - 1;
|
|
while(TryCollapseLayout(m_layouts.Last(), iLast, &iLast) && iLast > 0)
|
|
{
|
|
--iLast;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool wxRibbonButtonBar::TryCollapseLayout(wxRibbonButtonBarLayout* original,
|
|
size_t first_btn, size_t* last_button)
|
|
{
|
|
size_t btn_count = m_buttons.Count();
|
|
size_t btn_i;
|
|
int used_height = 0;
|
|
int used_width = 0;
|
|
int available_width = 0;
|
|
int available_height = 0;
|
|
|
|
for(btn_i = first_btn + 1; btn_i > 0; /* decrement is inside loop */)
|
|
{
|
|
--btn_i;
|
|
wxRibbonButtonBarButtonBase* button = m_buttons.Item(btn_i);
|
|
wxRibbonButtonBarButtonState large_size_class = button->GetLargestSize();
|
|
wxSize large_size = button->sizes[large_size_class].size;
|
|
int t_available_height = wxMax(available_height,
|
|
large_size.GetHeight());
|
|
int t_available_width = available_width + large_size.GetWidth();
|
|
wxRibbonButtonBarButtonState small_size_class = large_size_class;
|
|
if(!button->GetSmallerSize(&small_size_class))
|
|
{
|
|
return false;
|
|
}
|
|
wxSize small_size = button->sizes[small_size_class].size;
|
|
int t_used_height = used_height + small_size.GetHeight();
|
|
int t_used_width = wxMax(used_width, small_size.GetWidth());
|
|
|
|
if(t_used_height > t_available_height)
|
|
{
|
|
++btn_i;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
used_height = t_used_height;
|
|
used_width = t_used_width;
|
|
available_width = t_available_width;
|
|
available_height = t_available_height;
|
|
}
|
|
}
|
|
|
|
if(btn_i >= first_btn || used_width >= available_width)
|
|
{
|
|
return false;
|
|
}
|
|
if(last_button != NULL)
|
|
{
|
|
*last_button = btn_i;
|
|
}
|
|
|
|
wxRibbonButtonBarLayout* layout = new wxRibbonButtonBarLayout;
|
|
WX_APPEND_ARRAY(layout->buttons, original->buttons);
|
|
wxPoint cursor(layout->buttons.Item(btn_i).position);
|
|
bool preserve_height = false;
|
|
if(btn_i == 0)
|
|
{
|
|
// If height isn't preserved (i.e. it is reduced), then the minimum
|
|
// size for the button bar will decrease, preventing the original
|
|
// layout from being used (in some cases).
|
|
// It may be a good idea to always preserve the height, but for now
|
|
// it is only done when the first button is involved in a collapse.
|
|
preserve_height = true;
|
|
}
|
|
|
|
for(; btn_i <= first_btn; ++btn_i)
|
|
{
|
|
wxRibbonButtonBarButtonInstance& instance = layout->buttons.Item(btn_i);
|
|
instance.base->GetSmallerSize(&instance.size);
|
|
instance.position = cursor;
|
|
cursor.y += instance.base->sizes[instance.size].size.GetHeight();
|
|
}
|
|
|
|
int x_adjust = available_width - used_width;
|
|
|
|
for(; btn_i < btn_count; ++btn_i)
|
|
{
|
|
wxRibbonButtonBarButtonInstance& instance = layout->buttons.Item(btn_i);
|
|
instance.position.x -= x_adjust;
|
|
}
|
|
|
|
layout->CalculateOverallSize();
|
|
|
|
// Sanity check
|
|
if(layout->overall_size.GetWidth() >= original->overall_size.GetWidth() ||
|
|
layout->overall_size.GetHeight() > original->overall_size.GetHeight())
|
|
{
|
|
delete layout;
|
|
wxFAIL_MSG("Layout collapse resulted in increased size");
|
|
return false;
|
|
}
|
|
|
|
if(preserve_height)
|
|
{
|
|
layout->overall_size.SetHeight(original->overall_size.GetHeight());
|
|
}
|
|
|
|
m_layouts.Add(layout);
|
|
return true;
|
|
}
|
|
|
|
void wxRibbonButtonBar::OnMouseMove(wxMouseEvent& evt)
|
|
{
|
|
wxPoint cursor(evt.GetPosition());
|
|
wxRibbonButtonBarButtonInstance* new_hovered = NULL;
|
|
wxRibbonButtonBarButtonInstance* tooltipButton = NULL;
|
|
long new_hovered_state = 0;
|
|
|
|
wxRibbonButtonBarLayout* layout = m_layouts.Item(m_current_layout);
|
|
size_t btn_count = layout->buttons.Count();
|
|
size_t btn_i;
|
|
for(btn_i = 0; btn_i < btn_count; ++btn_i)
|
|
{
|
|
wxRibbonButtonBarButtonInstance& instance = layout->buttons.Item(btn_i);
|
|
wxRibbonButtonBarButtonSizeInfo& size = instance.base->sizes[instance.size];
|
|
wxRect btn_rect;
|
|
btn_rect.SetTopLeft(m_layout_offset + instance.position);
|
|
btn_rect.SetSize(size.size);
|
|
if(btn_rect.Contains(cursor))
|
|
{
|
|
if((instance.base->state & wxRIBBON_BUTTONBAR_BUTTON_DISABLED) == 0)
|
|
{
|
|
tooltipButton = &instance;
|
|
new_hovered = &instance;
|
|
new_hovered_state = instance.base->state;
|
|
new_hovered_state &= ~wxRIBBON_BUTTONBAR_BUTTON_HOVER_MASK;
|
|
wxPoint offset(cursor);
|
|
offset -= btn_rect.GetTopLeft();
|
|
if(size.normal_region.Contains(offset))
|
|
{
|
|
new_hovered_state |= wxRIBBON_BUTTONBAR_BUTTON_NORMAL_HOVERED;
|
|
}
|
|
if(size.dropdown_region.Contains(offset))
|
|
{
|
|
new_hovered_state |= wxRIBBON_BUTTONBAR_BUTTON_DROPDOWN_HOVERED;
|
|
}
|
|
break;
|
|
}
|
|
else if (m_show_tooltips_for_disabled)
|
|
{
|
|
tooltipButton = &instance;
|
|
}
|
|
}
|
|
}
|
|
|
|
#if wxUSE_TOOLTIPS
|
|
if(tooltipButton == NULL && GetToolTip())
|
|
{
|
|
UnsetToolTip();
|
|
}
|
|
if(tooltipButton)
|
|
{
|
|
SetToolTip(tooltipButton->base->help_string);
|
|
}
|
|
#endif
|
|
|
|
if(new_hovered != m_hovered_button || (m_hovered_button != NULL &&
|
|
new_hovered_state != m_hovered_button->base->state))
|
|
{
|
|
if(m_hovered_button != NULL)
|
|
{
|
|
m_hovered_button->base->state &= ~wxRIBBON_BUTTONBAR_BUTTON_HOVER_MASK;
|
|
}
|
|
m_hovered_button = new_hovered;
|
|
if(m_hovered_button != NULL)
|
|
{
|
|
m_hovered_button->base->state = new_hovered_state;
|
|
}
|
|
Refresh(false);
|
|
}
|
|
|
|
if(m_active_button && !m_lock_active_state)
|
|
{
|
|
long new_active_state = m_active_button->base->state;
|
|
new_active_state &= ~wxRIBBON_BUTTONBAR_BUTTON_ACTIVE_MASK;
|
|
wxRibbonButtonBarButtonSizeInfo& size =
|
|
m_active_button->base->sizes[m_active_button->size];
|
|
wxRect btn_rect;
|
|
btn_rect.SetTopLeft(m_layout_offset + m_active_button->position);
|
|
btn_rect.SetSize(size.size);
|
|
if(btn_rect.Contains(cursor))
|
|
{
|
|
wxPoint offset(cursor);
|
|
offset -= btn_rect.GetTopLeft();
|
|
if(size.normal_region.Contains(offset))
|
|
{
|
|
new_active_state |= wxRIBBON_BUTTONBAR_BUTTON_NORMAL_ACTIVE;
|
|
}
|
|
if(size.dropdown_region.Contains(offset))
|
|
{
|
|
new_active_state |= wxRIBBON_BUTTONBAR_BUTTON_DROPDOWN_ACTIVE;
|
|
}
|
|
}
|
|
if(new_active_state != m_active_button->base->state)
|
|
{
|
|
m_active_button->base->state = new_active_state;
|
|
Refresh(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
void wxRibbonButtonBar::OnMouseDown(wxMouseEvent& evt)
|
|
{
|
|
wxPoint cursor(evt.GetPosition());
|
|
m_active_button = NULL;
|
|
|
|
wxRibbonButtonBarLayout* layout = m_layouts.Item(m_current_layout);
|
|
size_t btn_count = layout->buttons.Count();
|
|
size_t btn_i;
|
|
for(btn_i = 0; btn_i < btn_count; ++btn_i)
|
|
{
|
|
wxRibbonButtonBarButtonInstance& instance = layout->buttons.Item(btn_i);
|
|
wxRibbonButtonBarButtonSizeInfo& size = instance.base->sizes[instance.size];
|
|
wxRect btn_rect;
|
|
btn_rect.SetTopLeft(m_layout_offset + instance.position);
|
|
btn_rect.SetSize(size.size);
|
|
if(btn_rect.Contains(cursor))
|
|
{
|
|
if((instance.base->state & wxRIBBON_BUTTONBAR_BUTTON_DISABLED) == 0)
|
|
{
|
|
m_active_button = &instance;
|
|
cursor -= btn_rect.GetTopLeft();
|
|
long state = 0;
|
|
if(size.normal_region.Contains(cursor))
|
|
state = wxRIBBON_BUTTONBAR_BUTTON_NORMAL_ACTIVE;
|
|
else if(size.dropdown_region.Contains(cursor))
|
|
state = wxRIBBON_BUTTONBAR_BUTTON_DROPDOWN_ACTIVE;
|
|
instance.base->state |= state;
|
|
Refresh(false);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void wxRibbonButtonBar::OnMouseUp(wxMouseEvent& evt)
|
|
{
|
|
wxPoint cursor(evt.GetPosition());
|
|
|
|
if(m_active_button)
|
|
{
|
|
wxRibbonButtonBarButtonSizeInfo& size =
|
|
m_active_button->base->sizes[m_active_button->size];
|
|
wxRect btn_rect;
|
|
btn_rect.SetTopLeft(m_layout_offset + m_active_button->position);
|
|
btn_rect.SetSize(size.size);
|
|
if(btn_rect.Contains(cursor))
|
|
{
|
|
int id = m_active_button->base->id;
|
|
cursor -= btn_rect.GetTopLeft();
|
|
wxEventType event_type;
|
|
do
|
|
{
|
|
if(size.normal_region.Contains(cursor))
|
|
event_type = wxEVT_RIBBONBUTTONBAR_CLICKED;
|
|
else if(size.dropdown_region.Contains(cursor))
|
|
event_type = wxEVT_RIBBONBUTTONBAR_DROPDOWN_CLICKED;
|
|
else
|
|
break;
|
|
wxRibbonButtonBarEvent notification(event_type, id);
|
|
if(m_active_button->base->kind == wxRIBBON_BUTTON_TOGGLE)
|
|
{
|
|
m_active_button->base->state ^=
|
|
wxRIBBON_BUTTONBAR_BUTTON_TOGGLED;
|
|
notification.SetInt(m_active_button->base->state &
|
|
wxRIBBON_BUTTONBAR_BUTTON_TOGGLED);
|
|
}
|
|
notification.SetEventObject(this);
|
|
notification.SetBar(this);
|
|
notification.SetButton(m_active_button->base);
|
|
m_lock_active_state = true;
|
|
ProcessWindowEvent(notification);
|
|
m_lock_active_state = false;
|
|
|
|
wxStaticCast(m_parent, wxRibbonPanel)->HideIfExpanded();
|
|
} while(false);
|
|
if(m_active_button) // may have been NULLed by event handler
|
|
{
|
|
m_active_button->base->state &= ~wxRIBBON_BUTTONBAR_BUTTON_ACTIVE_MASK;
|
|
m_active_button = NULL;
|
|
}
|
|
Refresh(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
void wxRibbonButtonBar::OnMouseEnter(wxMouseEvent& evt)
|
|
{
|
|
if(m_active_button && !evt.LeftIsDown())
|
|
{
|
|
m_active_button = NULL;
|
|
}
|
|
}
|
|
|
|
void wxRibbonButtonBar::OnMouseLeave(wxMouseEvent& WXUNUSED(evt))
|
|
{
|
|
bool repaint = false;
|
|
if(m_hovered_button != NULL)
|
|
{
|
|
m_hovered_button->base->state &= ~wxRIBBON_BUTTONBAR_BUTTON_HOVER_MASK;
|
|
m_hovered_button = NULL;
|
|
repaint = true;
|
|
}
|
|
if(m_active_button != NULL && !m_lock_active_state)
|
|
{
|
|
m_active_button->base->state &= ~wxRIBBON_BUTTONBAR_BUTTON_ACTIVE_MASK;
|
|
repaint = true;
|
|
}
|
|
if(repaint)
|
|
Refresh(false);
|
|
}
|
|
|
|
wxRibbonButtonBarButtonBase *wxRibbonButtonBar::GetActiveItem() const
|
|
{
|
|
return m_active_button == NULL ? NULL : m_active_button->base;
|
|
}
|
|
|
|
|
|
wxRibbonButtonBarButtonBase *wxRibbonButtonBar::GetHoveredItem() const
|
|
{
|
|
return m_hovered_button == NULL ? NULL : m_hovered_button->base;
|
|
}
|
|
|
|
|
|
wxRibbonButtonBarButtonBase *wxRibbonButtonBar::GetItem(size_t n) const
|
|
{
|
|
wxCHECK_MSG(n < m_buttons.GetCount(), NULL, "wxRibbonButtonBar item's index is out of bound");
|
|
return m_buttons.Item(n);
|
|
}
|
|
|
|
wxRibbonButtonBarButtonBase *wxRibbonButtonBar::GetItemById(int button_id) const
|
|
{
|
|
size_t count = m_buttons.GetCount();
|
|
for ( size_t i = 0; i < count; ++i )
|
|
{
|
|
wxRibbonButtonBarButtonBase* button = m_buttons.Item(i);
|
|
if ( button->id == button_id )
|
|
return button;
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
int wxRibbonButtonBar::GetItemId(wxRibbonButtonBarButtonBase *item) const
|
|
{
|
|
wxCHECK_MSG(item != NULL, wxNOT_FOUND, "wxRibbonButtonBar item should not be NULL");
|
|
return item->id;
|
|
}
|
|
|
|
|
|
bool wxRibbonButtonBarEvent::PopupMenu(wxMenu* menu)
|
|
{
|
|
wxPoint pos = wxDefaultPosition;
|
|
if(m_bar->m_active_button)
|
|
{
|
|
wxRibbonButtonBarButtonSizeInfo& size =
|
|
m_bar->m_active_button->base->sizes[m_bar->m_active_button->size];
|
|
wxRect btn_rect;
|
|
btn_rect.SetTopLeft(m_bar->m_layout_offset +
|
|
m_bar->m_active_button->position);
|
|
btn_rect.SetSize(size.size);
|
|
pos = btn_rect.GetBottomLeft();
|
|
pos.y++;
|
|
}
|
|
return m_bar->PopupMenu(menu, pos);
|
|
}
|
|
|
|
#endif // wxUSE_RIBBON
|