mirror of
https://github.com/wxWidgets/wxWidgets.git
synced 2026-08-18 01:19:45 +08:00
Add new wxRibbonArtProvider::UpdateColoursFromSystem() and implement it in wxRibbonMSWArtProvider. Closes #26644.
1293 lines
38 KiB
C++
1293 lines
38 KiB
C++
///////////////////////////////////////////////////////////////////////////////
|
|
// Name: src/ribbon/toolbar.cpp
|
|
// Purpose: Ribbon-style tool bar
|
|
// Author: Peter Cawley
|
|
// Created: 2009-07-06
|
|
// Copyright: (C) Peter Cawley
|
|
// Licence: wxWindows licence
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "wx/wxprec.h"
|
|
|
|
|
|
#if wxUSE_RIBBON
|
|
|
|
#include "wx/ribbon/toolbar.h"
|
|
#include "wx/ribbon/art.h"
|
|
#include "wx/ribbon/bar.h"
|
|
#include "wx/dcbuffer.h"
|
|
|
|
#ifndef WX_PRECOMP
|
|
#endif
|
|
|
|
#ifdef __WXMSW__
|
|
#include "wx/msw/private.h"
|
|
#endif
|
|
|
|
#include <memory>
|
|
|
|
class wxRibbonToolBarToolBase
|
|
{
|
|
public:
|
|
wxString help_string;
|
|
wxBitmapBundle bitmap;
|
|
wxBitmapBundle bitmap_disabled;
|
|
wxRect dropdown;
|
|
wxPoint position;
|
|
wxSize size;
|
|
wxObject* client_data = nullptr;
|
|
int id;
|
|
wxRibbonButtonKind kind;
|
|
long state;
|
|
};
|
|
|
|
WX_DEFINE_ARRAY_PTR(wxRibbonToolBarToolBase*, wxArrayRibbonToolBarToolBase);
|
|
|
|
class wxRibbonToolBarToolGroup
|
|
{
|
|
public:
|
|
// To identify the group as a wxRibbonToolBarToolBase*
|
|
wxRibbonToolBarToolBase dummy_tool;
|
|
|
|
wxArrayRibbonToolBarToolBase tools;
|
|
wxPoint position;
|
|
wxSize size;
|
|
};
|
|
|
|
wxDEFINE_EVENT(wxEVT_RIBBONTOOLBAR_CLICKED, wxRibbonToolBarEvent);
|
|
wxDEFINE_EVENT(wxEVT_RIBBONTOOLBAR_DROPDOWN_CLICKED, wxRibbonToolBarEvent);
|
|
|
|
wxIMPLEMENT_DYNAMIC_CLASS(wxRibbonToolBarEvent, wxCommandEvent);
|
|
wxIMPLEMENT_CLASS(wxRibbonToolBar, wxRibbonControl);
|
|
|
|
wxBEGIN_EVENT_TABLE(wxRibbonToolBar, wxRibbonControl)
|
|
EVT_ENTER_WINDOW(wxRibbonToolBar::OnMouseEnter)
|
|
EVT_ERASE_BACKGROUND(wxRibbonToolBar::OnEraseBackground)
|
|
EVT_LEAVE_WINDOW(wxRibbonToolBar::OnMouseLeave)
|
|
EVT_LEFT_DOWN(wxRibbonToolBar::OnMouseDown)
|
|
EVT_LEFT_DCLICK(wxRibbonToolBar::OnMouseDown)
|
|
EVT_LEFT_UP(wxRibbonToolBar::OnMouseUp)
|
|
EVT_MOTION(wxRibbonToolBar::OnMouseMove)
|
|
EVT_PAINT(wxRibbonToolBar::OnPaint)
|
|
EVT_SIZE(wxRibbonToolBar::OnSize)
|
|
EVT_DPI_CHANGED(wxRibbonToolBar::OnDPIChanged)
|
|
EVT_SYS_COLOUR_CHANGED(wxRibbonToolBar::OnSysColourChanged)
|
|
wxEND_EVENT_TABLE()
|
|
|
|
wxRibbonToolBar::wxRibbonToolBar()
|
|
{
|
|
}
|
|
|
|
wxRibbonToolBar::wxRibbonToolBar(wxWindow* parent,
|
|
wxWindowID id,
|
|
const wxPoint& pos,
|
|
const wxSize& size,
|
|
long style)
|
|
: wxRibbonControl(parent, id, pos, size, wxBORDER_NONE)
|
|
{
|
|
CommonInit(style);
|
|
}
|
|
|
|
bool wxRibbonToolBar::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 wxRibbonToolBar::CommonInit(long WXUNUSED(style))
|
|
{
|
|
AppendGroup();
|
|
m_hover_tool = nullptr;
|
|
m_active_tool = nullptr;
|
|
m_nrows_min = 1;
|
|
m_nrows_max = 1;
|
|
m_sizes = new wxSize[1];
|
|
SetBackgroundStyle(wxBG_STYLE_PAINT);
|
|
}
|
|
|
|
wxRibbonToolBar::~wxRibbonToolBar()
|
|
{
|
|
size_t count = m_groups.GetCount();
|
|
size_t i, t;
|
|
for(i = 0; i < count; ++i)
|
|
{
|
|
wxRibbonToolBarToolGroup* group = m_groups.Item(i);
|
|
size_t tool_count = group->tools.GetCount();
|
|
for(t = 0; t < tool_count; ++t)
|
|
{
|
|
wxRibbonToolBarToolBase* tool = group->tools.Item(t);
|
|
delete tool;
|
|
}
|
|
delete group;
|
|
}
|
|
m_groups.Clear();
|
|
delete[] m_sizes;
|
|
}
|
|
|
|
wxRibbonToolBarToolBase* wxRibbonToolBar::AddTool(
|
|
int tool_id,
|
|
const wxBitmapBundle& bitmap,
|
|
const wxString& help_string,
|
|
wxRibbonButtonKind kind)
|
|
{
|
|
return AddTool(tool_id, bitmap, wxBitmapBundle(), help_string, kind, nullptr);
|
|
}
|
|
|
|
wxRibbonToolBarToolBase* wxRibbonToolBar::AddDropdownTool(
|
|
int tool_id,
|
|
const wxBitmapBundle& bitmap,
|
|
const wxString& help_string)
|
|
{
|
|
return AddTool(tool_id, bitmap, wxBitmapBundle(), help_string,
|
|
wxRIBBON_BUTTON_DROPDOWN, nullptr);
|
|
}
|
|
|
|
wxRibbonToolBarToolBase* wxRibbonToolBar::AddHybridTool(
|
|
int tool_id,
|
|
const wxBitmapBundle& bitmap,
|
|
const wxString& help_string)
|
|
{
|
|
return AddTool(tool_id, bitmap, wxBitmapBundle(), help_string,
|
|
wxRIBBON_BUTTON_HYBRID, nullptr);
|
|
}
|
|
|
|
wxRibbonToolBarToolBase* wxRibbonToolBar::AddToggleTool(
|
|
int tool_id,
|
|
const wxBitmapBundle& bitmap,
|
|
const wxString& help_string)
|
|
{
|
|
return AddTool(tool_id, bitmap, wxBitmapBundle(), help_string,
|
|
wxRIBBON_BUTTON_TOGGLE, nullptr);
|
|
}
|
|
|
|
wxRibbonToolBarToolBase* wxRibbonToolBar::AddTool(
|
|
int tool_id,
|
|
const wxBitmapBundle& bitmap,
|
|
const wxBitmapBundle& bitmap_disabled,
|
|
const wxString& help_string,
|
|
wxRibbonButtonKind kind,
|
|
wxObject* client_data)
|
|
{
|
|
return InsertTool(GetToolCount(), tool_id, bitmap, bitmap_disabled,
|
|
help_string, kind, client_data);
|
|
}
|
|
|
|
wxRibbonToolBarToolBase* wxRibbonToolBar::AddSeparator()
|
|
{
|
|
if(m_groups.Last()->tools.IsEmpty())
|
|
return nullptr;
|
|
|
|
AppendGroup();
|
|
return &m_groups.Last()->dummy_tool;
|
|
}
|
|
|
|
|
|
wxRibbonToolBarToolBase* wxRibbonToolBar::InsertTool(
|
|
size_t pos,
|
|
int tool_id,
|
|
const wxBitmapBundle& bitmap,
|
|
const wxString& help_string,
|
|
wxRibbonButtonKind kind)
|
|
{
|
|
return InsertTool(pos, tool_id, bitmap, wxBitmapBundle(), help_string, kind,
|
|
nullptr);
|
|
}
|
|
|
|
wxRibbonToolBarToolBase* wxRibbonToolBar::InsertDropdownTool(
|
|
size_t pos,
|
|
int tool_id,
|
|
const wxBitmapBundle& bitmap,
|
|
const wxString& help_string)
|
|
{
|
|
return InsertTool(pos, tool_id, bitmap, wxBitmapBundle(), help_string,
|
|
wxRIBBON_BUTTON_DROPDOWN, nullptr);
|
|
}
|
|
|
|
wxRibbonToolBarToolBase* wxRibbonToolBar::InsertHybridTool(
|
|
size_t pos,
|
|
int tool_id,
|
|
const wxBitmapBundle& bitmap,
|
|
const wxString& help_string)
|
|
{
|
|
return InsertTool(pos, tool_id, bitmap, wxBitmapBundle(), help_string,
|
|
wxRIBBON_BUTTON_HYBRID, nullptr);
|
|
}
|
|
|
|
wxRibbonToolBarToolBase* wxRibbonToolBar::InsertToggleTool(
|
|
size_t pos,
|
|
int tool_id,
|
|
const wxBitmapBundle& bitmap,
|
|
const wxString& help_string)
|
|
{
|
|
return InsertTool(pos, tool_id, bitmap, wxBitmapBundle(), help_string,
|
|
wxRIBBON_BUTTON_TOGGLE, nullptr);
|
|
}
|
|
|
|
wxRibbonToolBarToolBase* wxRibbonToolBar::InsertTool(
|
|
size_t pos,
|
|
int tool_id,
|
|
const wxBitmapBundle& bitmap,
|
|
const wxBitmapBundle& bitmap_disabled,
|
|
const wxString& help_string,
|
|
wxRibbonButtonKind kind,
|
|
wxObject* client_data)
|
|
{
|
|
wxASSERT(bitmap.IsOk());
|
|
|
|
// Create the wxRibbonToolBarToolBase with parameters
|
|
std::unique_ptr<wxRibbonToolBarToolBase> tool(new wxRibbonToolBarToolBase);
|
|
tool->id = tool_id;
|
|
tool->bitmap = bitmap;
|
|
if(bitmap_disabled.IsOk())
|
|
{
|
|
wxASSERT(bitmap.GetDefaultSize() == bitmap_disabled.GetDefaultSize());
|
|
tool->bitmap_disabled = bitmap_disabled;
|
|
}
|
|
else
|
|
{
|
|
// Generate disabled bitmap from normal bitmap
|
|
wxBitmap bmp = bitmap.GetBitmap(bitmap.GetDefaultSize());
|
|
tool->bitmap_disabled = wxBitmapBundle::FromBitmap(MakeDisabledBitmap(bmp));
|
|
}
|
|
tool->help_string = help_string;
|
|
tool->kind = kind;
|
|
tool->client_data = client_data;
|
|
tool->state = 0;
|
|
|
|
// Find the position where insert tool
|
|
size_t group_count = m_groups.GetCount();
|
|
size_t g;
|
|
for(g = 0; g < group_count; ++g)
|
|
{
|
|
wxRibbonToolBarToolGroup* group = m_groups.Item(g);
|
|
size_t tool_count = group->tools.GetCount();
|
|
if(pos <= tool_count)
|
|
{
|
|
// Give the ownership of the tool to group->tools
|
|
wxRibbonToolBarToolBase* const p = tool.release();
|
|
group->tools.Insert(p, pos);
|
|
return p;
|
|
}
|
|
pos -= tool_count + 1;
|
|
}
|
|
wxFAIL_MSG("Tool position out of toolbar bounds.");
|
|
return nullptr;
|
|
}
|
|
|
|
wxRibbonToolBarToolBase* wxRibbonToolBar::InsertSeparator(size_t pos)
|
|
{
|
|
size_t group_count = m_groups.GetCount();
|
|
size_t g;
|
|
for(g = 0; g < group_count; ++g)
|
|
{
|
|
if(pos==0) // Prepend group
|
|
return &InsertGroup(g)->dummy_tool;
|
|
if(pos==group_count) // Append group
|
|
return &InsertGroup(g+1)->dummy_tool;
|
|
|
|
wxRibbonToolBarToolGroup* group = m_groups.Item(g);
|
|
size_t tool_count = group->tools.GetCount();
|
|
if(pos < tool_count)
|
|
{
|
|
wxRibbonToolBarToolGroup* new_group = InsertGroup(g+1);
|
|
|
|
for(size_t t = pos; t < tool_count; t++)
|
|
new_group->tools.Add(group->tools[t]);
|
|
group->tools.RemoveAt(pos, tool_count-pos);
|
|
|
|
return &group->dummy_tool;
|
|
}
|
|
pos -= tool_count + 1;
|
|
}
|
|
// Add an empty group at the end of the bar.
|
|
if(m_groups.Last()->tools.IsEmpty())
|
|
return nullptr;
|
|
AppendGroup();
|
|
return &m_groups.Last()->dummy_tool;
|
|
}
|
|
|
|
wxRibbonToolBarToolGroup* wxRibbonToolBar::InsertGroup(size_t pos)
|
|
{
|
|
wxRibbonToolBarToolGroup* group = new wxRibbonToolBarToolGroup;
|
|
m_groups.Insert(group, pos);
|
|
return group;
|
|
}
|
|
|
|
void wxRibbonToolBar::ClearTools()
|
|
{
|
|
size_t count = m_groups.GetCount();
|
|
size_t i, t;
|
|
for(i = 0; i < count; ++i)
|
|
{
|
|
wxRibbonToolBarToolGroup* group = m_groups.Item(i);
|
|
size_t tool_count = group->tools.GetCount();
|
|
for(t = 0; t < tool_count; ++t)
|
|
{
|
|
wxRibbonToolBarToolBase* tool = group->tools.Item(t);
|
|
delete tool;
|
|
}
|
|
delete group;
|
|
}
|
|
m_groups.Clear();
|
|
}
|
|
|
|
bool wxRibbonToolBar::DeleteTool(int tool_id)
|
|
{
|
|
size_t group_count = m_groups.GetCount();
|
|
size_t g, t;
|
|
for(g = 0; g < group_count; ++g)
|
|
{
|
|
wxRibbonToolBarToolGroup* group = m_groups.Item(g);
|
|
size_t tool_count = group->tools.GetCount();
|
|
for(t = 0; t < tool_count; ++t)
|
|
{
|
|
wxRibbonToolBarToolBase* tool = group->tools.Item(t);
|
|
if(tool->id == tool_id)
|
|
{
|
|
group->tools.RemoveAt(t);
|
|
delete tool;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool wxRibbonToolBar::DeleteToolByPos(size_t pos)
|
|
{
|
|
size_t group_count = m_groups.GetCount();
|
|
size_t g, t;
|
|
for(g = 0; g < group_count; ++g)
|
|
{
|
|
wxRibbonToolBarToolGroup* group = m_groups.Item(g);
|
|
size_t tool_count = group->tools.GetCount();
|
|
if(pos<tool_count)
|
|
{
|
|
// Remove tool
|
|
wxRibbonToolBarToolBase* tool = group->tools.Item(pos);
|
|
group->tools.RemoveAt(pos);
|
|
delete tool;
|
|
return true;
|
|
}
|
|
else if(pos==tool_count)
|
|
{
|
|
// Remove separator
|
|
if(g < group_count - 1)
|
|
{
|
|
wxRibbonToolBarToolGroup* next_group = m_groups.Item(g+1);
|
|
for(t = 0; t < next_group->tools.GetCount(); ++t)
|
|
group->tools.Add(next_group->tools[t]);
|
|
m_groups.RemoveAt(g+1);
|
|
delete next_group;
|
|
}
|
|
return true;
|
|
}
|
|
pos -= tool_count+1;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
wxRibbonToolBarToolBase* wxRibbonToolBar::FindById(int tool_id)const
|
|
{
|
|
size_t group_count = m_groups.GetCount();
|
|
size_t g, t;
|
|
for(g = 0; g < group_count; ++g)
|
|
{
|
|
wxRibbonToolBarToolGroup* group = m_groups.Item(g);
|
|
size_t tool_count = group->tools.GetCount();
|
|
for(t = 0; t < tool_count; ++t)
|
|
{
|
|
wxRibbonToolBarToolBase* tool = group->tools.Item(t);
|
|
if(tool->id == tool_id)
|
|
{
|
|
return tool;
|
|
}
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
wxRibbonToolBarToolBase* wxRibbonToolBar::GetToolByPos(size_t pos)const
|
|
{
|
|
size_t group_count = m_groups.GetCount();
|
|
size_t g;
|
|
for(g = 0; g < group_count; ++g)
|
|
{
|
|
wxRibbonToolBarToolGroup* group = m_groups.Item(g);
|
|
size_t tool_count = group->tools.GetCount();
|
|
if(pos<tool_count)
|
|
{
|
|
return group->tools[pos];
|
|
}
|
|
else if(pos==tool_count)
|
|
{
|
|
return nullptr;
|
|
}
|
|
pos -= tool_count+1;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
wxRibbonToolBarToolBase* wxRibbonToolBar::GetToolByPos(wxCoord x, wxCoord y)const
|
|
{
|
|
size_t group_count = m_groups.GetCount();
|
|
for ( size_t g = 0; g < group_count; ++g )
|
|
{
|
|
wxRibbonToolBarToolGroup* group = m_groups.Item(g);
|
|
size_t tool_count = group->tools.GetCount();
|
|
for ( size_t t = 0; t < tool_count; ++t )
|
|
{
|
|
wxRibbonToolBarToolBase* tool = group->tools.Item(t);
|
|
wxRect rect(group->position + tool->position, tool->size);
|
|
if(rect.Contains(x, y))
|
|
{
|
|
return tool;
|
|
}
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
size_t wxRibbonToolBar::GetToolCount() const
|
|
{
|
|
size_t count = 0;
|
|
for(size_t g = 0; g < m_groups.GetCount(); ++g)
|
|
{
|
|
wxRibbonToolBarToolGroup* group = m_groups.Item(g);
|
|
count += group->tools.GetCount();
|
|
}
|
|
// There is a splitter in front of every group except for the first
|
|
// If only one group, no separator.
|
|
if(m_groups.GetCount()>1)
|
|
count += m_groups.GetCount() - 1;
|
|
return count;
|
|
}
|
|
|
|
int wxRibbonToolBar::GetToolId(const wxRibbonToolBarToolBase* tool)const
|
|
{
|
|
wxCHECK_MSG(tool != nullptr , wxNOT_FOUND, "The tool pointer must not be null");
|
|
return tool->id;
|
|
}
|
|
|
|
wxRibbonToolBarToolBase* wxRibbonToolBar::GetActiveTool() const
|
|
{
|
|
return m_active_tool == nullptr ? nullptr : m_active_tool;
|
|
}
|
|
|
|
wxObject* wxRibbonToolBar::GetToolClientData(int tool_id)const
|
|
{
|
|
wxRibbonToolBarToolBase* tool = FindById(tool_id);
|
|
wxCHECK_MSG(tool != nullptr , nullptr, "Invalid tool id");
|
|
return tool->client_data;
|
|
}
|
|
|
|
bool wxRibbonToolBar::GetToolEnabled(int tool_id)const
|
|
{
|
|
wxRibbonToolBarToolBase* tool = FindById(tool_id);
|
|
wxCHECK_MSG(tool != nullptr , false, "Invalid tool id");
|
|
return (tool->state & wxRIBBON_TOOLBAR_TOOL_DISABLED) == 0;
|
|
}
|
|
|
|
wxString wxRibbonToolBar::GetToolHelpString(int tool_id)const
|
|
{
|
|
wxRibbonToolBarToolBase* tool = FindById(tool_id);
|
|
wxCHECK_MSG(tool != nullptr , wxEmptyString, "Invalid tool id");
|
|
return tool->help_string;
|
|
}
|
|
|
|
wxRibbonButtonKind wxRibbonToolBar::GetToolKind(int tool_id)const
|
|
{
|
|
wxRibbonToolBarToolBase* tool = FindById(tool_id);
|
|
wxCHECK_MSG(tool != nullptr , wxRIBBON_BUTTON_NORMAL, "Invalid tool id");
|
|
return tool->kind;
|
|
}
|
|
|
|
int wxRibbonToolBar::GetToolPos(int tool_id)const
|
|
{
|
|
size_t group_count = m_groups.GetCount();
|
|
size_t g, t;
|
|
int pos = 0;
|
|
for(g = 0; g < group_count; ++g)
|
|
{
|
|
wxRibbonToolBarToolGroup* group = m_groups.Item(g);
|
|
size_t tool_count = group->tools.GetCount();
|
|
for(t = 0; t < tool_count; ++t)
|
|
{
|
|
wxRibbonToolBarToolBase* tool = group->tools.Item(t);
|
|
if(tool->id == tool_id)
|
|
{
|
|
return pos;
|
|
}
|
|
++pos;
|
|
}
|
|
++pos; // Increment pos for group separator.
|
|
}
|
|
return wxNOT_FOUND;
|
|
}
|
|
|
|
wxRect wxRibbonToolBar::GetToolRect(int tool_id)const
|
|
{
|
|
size_t group_count = m_groups.GetCount();
|
|
size_t g, t;
|
|
|
|
for(g = 0; g < group_count; ++g)
|
|
{
|
|
wxRibbonToolBarToolGroup* group = m_groups.Item(g);
|
|
size_t tool_count = group->tools.GetCount();
|
|
for(t = 0; t < tool_count; ++t)
|
|
{
|
|
wxRibbonToolBarToolBase* tool = group->tools.Item(t);
|
|
if (tool->id == tool_id)
|
|
{
|
|
return wxRect(group->position + tool->position, tool->size);
|
|
}
|
|
}
|
|
}
|
|
return wxRect();
|
|
}
|
|
|
|
bool wxRibbonToolBar::GetToolState(int tool_id)const
|
|
{
|
|
wxRibbonToolBarToolBase* tool = FindById(tool_id);
|
|
wxCHECK_MSG(tool != nullptr , false, "Invalid tool id");
|
|
return (tool->state & wxRIBBON_TOOLBAR_TOOL_TOGGLED) != 0;
|
|
}
|
|
|
|
wxBitmap wxRibbonToolBar::MakeDisabledBitmap(const wxBitmap& original)
|
|
{
|
|
wxImage img(original.ConvertToImage());
|
|
return wxBitmap(img.ConvertToGreyscale(), -1, original.GetScaleFactor());
|
|
}
|
|
|
|
void wxRibbonToolBar::AppendGroup()
|
|
{
|
|
wxRibbonToolBarToolGroup* group = new wxRibbonToolBarToolGroup;
|
|
m_groups.Add(group);
|
|
}
|
|
|
|
bool wxRibbonToolBar::IsSizingContinuous() const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
void wxRibbonToolBar::SetToolClientData(int tool_id, wxObject* clientData)
|
|
{
|
|
wxRibbonToolBarToolBase* tool = FindById(tool_id);
|
|
wxCHECK_RET(tool != nullptr , "Invalid tool id");
|
|
tool->client_data = clientData;
|
|
}
|
|
|
|
void wxRibbonToolBar::SetToolDisabledBitmap(int tool_id, const wxBitmapBundle &bitmap)
|
|
{
|
|
wxRibbonToolBarToolBase* tool = FindById(tool_id);
|
|
wxCHECK_RET(tool != nullptr , "Invalid tool id");
|
|
tool->bitmap_disabled = bitmap;
|
|
}
|
|
|
|
void wxRibbonToolBar::SetToolHelpString(int tool_id, const wxString& helpString)
|
|
{
|
|
wxRibbonToolBarToolBase* tool = FindById(tool_id);
|
|
wxCHECK_RET(tool != nullptr , "Invalid tool id");
|
|
tool->help_string = helpString;
|
|
}
|
|
|
|
void wxRibbonToolBar::SetToolNormalBitmap(int tool_id, const wxBitmapBundle &bitmap)
|
|
{
|
|
wxRibbonToolBarToolBase* tool = FindById(tool_id);
|
|
wxCHECK_RET(tool != nullptr , "Invalid tool id");
|
|
tool->bitmap = bitmap;
|
|
}
|
|
|
|
void wxRibbonToolBar::EnableTool(int tool_id, bool enable)
|
|
{
|
|
wxRibbonToolBarToolBase* tool = FindById(tool_id);
|
|
wxCHECK_RET(tool != nullptr , "Invalid tool id");
|
|
if(enable)
|
|
{
|
|
if(tool->state & wxRIBBON_TOOLBAR_TOOL_DISABLED)
|
|
{
|
|
tool->state &= ~wxRIBBON_TOOLBAR_TOOL_DISABLED;
|
|
Refresh();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if((tool->state & wxRIBBON_TOOLBAR_TOOL_DISABLED)==0)
|
|
{
|
|
tool->state |= wxRIBBON_TOOLBAR_TOOL_DISABLED;
|
|
Refresh();
|
|
}
|
|
}
|
|
}
|
|
|
|
void wxRibbonToolBar::ToggleTool(int tool_id, bool checked)
|
|
{
|
|
wxRibbonToolBarToolBase* tool = FindById(tool_id);
|
|
wxCHECK_RET(tool != nullptr , "Invalid tool id");
|
|
if(checked)
|
|
{
|
|
if((tool->state & wxRIBBON_TOOLBAR_TOOL_TOGGLED) == 0)
|
|
{
|
|
tool->state |= wxRIBBON_TOOLBAR_TOOL_TOGGLED;
|
|
Refresh();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(tool->state & wxRIBBON_TOOLBAR_TOOL_TOGGLED)
|
|
{
|
|
tool->state &= ~wxRIBBON_TOOLBAR_TOOL_TOGGLED;
|
|
Refresh();
|
|
}
|
|
}
|
|
}
|
|
|
|
static int GetSizeInOrientation(wxSize size, wxOrientation orientation)
|
|
{
|
|
switch(orientation)
|
|
{
|
|
case wxHORIZONTAL: return size.GetWidth();
|
|
case wxVERTICAL: return size.GetHeight();
|
|
case wxBOTH: return size.GetWidth() * size.GetHeight();
|
|
default: return 0;
|
|
}
|
|
}
|
|
|
|
wxSize wxRibbonToolBar::DoGetNextSmallerSize(wxOrientation direction,
|
|
wxSize relative_to) const
|
|
{
|
|
wxSize result(relative_to);
|
|
int area = 0;
|
|
int nrows;
|
|
for(nrows = m_nrows_min; nrows <= m_nrows_max; ++nrows)
|
|
{
|
|
wxSize size(m_sizes[nrows - m_nrows_min]);
|
|
wxSize original(size);
|
|
switch(direction)
|
|
{
|
|
case wxHORIZONTAL:
|
|
if(size.GetWidth() < relative_to.GetWidth()
|
|
&& size.GetHeight() <= relative_to.GetHeight())
|
|
{
|
|
size.SetHeight(relative_to.GetHeight());
|
|
break;
|
|
}
|
|
continue;
|
|
case wxVERTICAL:
|
|
if(size.GetWidth() <= relative_to.GetWidth()
|
|
&& size.GetHeight() < relative_to.GetHeight())
|
|
{
|
|
size.SetWidth(relative_to.GetWidth());
|
|
break;
|
|
}
|
|
continue;
|
|
case wxBOTH:
|
|
if(size.GetWidth() < relative_to.GetWidth()
|
|
&& size.GetHeight() < relative_to.GetHeight())
|
|
{
|
|
break;
|
|
}
|
|
continue;
|
|
}
|
|
if(GetSizeInOrientation(original, direction) > area)
|
|
{
|
|
result = size;
|
|
area = GetSizeInOrientation(original, direction);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
wxSize wxRibbonToolBar::DoGetNextLargerSize(wxOrientation direction,
|
|
wxSize relative_to) const
|
|
{
|
|
// Pick the smallest of our sizes which are larger than the given size
|
|
wxSize result(relative_to);
|
|
int area = INT_MAX;
|
|
int nrows;
|
|
for(nrows = m_nrows_min; nrows <= m_nrows_max; ++nrows)
|
|
{
|
|
wxSize size(m_sizes[nrows - m_nrows_min]);
|
|
wxSize original(size);
|
|
switch(direction)
|
|
{
|
|
case wxHORIZONTAL:
|
|
if(size.GetWidth() > relative_to.GetWidth()
|
|
&& size.GetHeight() <= relative_to.GetHeight())
|
|
{
|
|
size.SetHeight(relative_to.GetHeight());
|
|
break;
|
|
}
|
|
continue;
|
|
case wxVERTICAL:
|
|
if(size.GetWidth() <= relative_to.GetWidth()
|
|
&& size.GetHeight() > relative_to.GetHeight())
|
|
{
|
|
size.SetWidth(relative_to.GetWidth());
|
|
break;
|
|
}
|
|
continue;
|
|
case wxBOTH:
|
|
if(size.GetWidth() > relative_to.GetWidth()
|
|
&& size.GetHeight() > relative_to.GetHeight())
|
|
{
|
|
break;
|
|
}
|
|
continue;
|
|
}
|
|
if(GetSizeInOrientation(original, direction) < area)
|
|
{
|
|
result = size;
|
|
area = GetSizeInOrientation(original, direction);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
void wxRibbonToolBar::SetRows(int nMin, int nMax)
|
|
{
|
|
if(nMax == -1)
|
|
nMax = nMin;
|
|
|
|
wxASSERT(1 <= nMin);
|
|
wxASSERT(nMin <= nMax);
|
|
|
|
m_nrows_min = nMin;
|
|
m_nrows_max = nMax;
|
|
|
|
delete[] m_sizes;
|
|
m_sizes = new wxSize[m_nrows_max - m_nrows_min + 1];
|
|
|
|
Realize();
|
|
}
|
|
|
|
bool wxRibbonToolBar::Realize()
|
|
{
|
|
if(m_art == nullptr)
|
|
return false;
|
|
|
|
// Calculate the size of each group and the position/size of each tool
|
|
wxMemoryDC temp_dc;
|
|
size_t group_count = m_groups.GetCount();
|
|
size_t g, t;
|
|
for(g = 0; g < group_count; ++g)
|
|
{
|
|
wxRibbonToolBarToolBase* prev = nullptr;
|
|
wxRibbonToolBarToolGroup* group = m_groups.Item(g);
|
|
size_t tool_count = group->tools.GetCount();
|
|
int tallest = 0;
|
|
for(t = 0; t < tool_count; ++t)
|
|
{
|
|
wxRibbonToolBarToolBase* tool = group->tools.Item(t);
|
|
tool->size = m_art->GetToolSize(temp_dc, this,
|
|
tool->bitmap.GetPreferredLogicalSizeFor(this), tool->kind, t == 0,
|
|
t == (tool_count - 1), &tool->dropdown);
|
|
if(t == 0)
|
|
tool->state |= wxRIBBON_TOOLBAR_TOOL_FIRST;
|
|
if(t == tool_count - 1)
|
|
tool->state |= wxRIBBON_TOOLBAR_TOOL_LAST;
|
|
if(tool->size.GetHeight() > tallest)
|
|
tallest = tool->size.GetHeight();
|
|
if(prev)
|
|
{
|
|
tool->position = prev->position;
|
|
tool->position.x += prev->size.x;
|
|
}
|
|
else
|
|
{
|
|
tool->position = wxPoint(0, 0);
|
|
}
|
|
prev = tool;
|
|
}
|
|
if(tool_count == 0)
|
|
group->size = wxSize(0, 0);
|
|
else
|
|
{
|
|
group->size = wxSize(prev->position.x + prev->size.x, tallest);
|
|
for(t = 0; t < tool_count; ++t)
|
|
group->tools.Item(t)->size.SetHeight(tallest);
|
|
}
|
|
}
|
|
|
|
// Calculate the minimum size for each possible number of rows
|
|
int nrows, r;
|
|
int sep = m_art->GetMetric(wxRIBBON_ART_TOOL_GROUP_SEPARATION_SIZE);
|
|
int smallest_area = INT_MAX;
|
|
wxSize* row_sizes = new wxSize[m_nrows_max];
|
|
wxOrientation major_axis = m_art->GetFlags() & wxRIBBON_BAR_FLOW_VERTICAL ?
|
|
wxVERTICAL : wxHORIZONTAL;
|
|
|
|
SetMinSize(wxSize(0, 0));
|
|
wxSize minSize(INT_MAX, INT_MAX);
|
|
|
|
// See if we're sizing flexibly (i.e. wrapping), and set min size differently
|
|
bool sizingFlexibly = false;
|
|
wxRibbonPanel* panel = wxDynamicCast(GetParent(), wxRibbonPanel);
|
|
if (panel && (panel->GetFlags() & wxRIBBON_PANEL_FLEXIBLE))
|
|
sizingFlexibly = true;
|
|
|
|
// Without this, there will be redundant horizontal space because SetMinSize will
|
|
// use the smallest possible height (and therefore largest width).
|
|
if (sizingFlexibly)
|
|
major_axis = wxHORIZONTAL;
|
|
|
|
for(nrows = m_nrows_min; nrows <= m_nrows_max; ++nrows)
|
|
{
|
|
for(r = 0; r < nrows; ++r)
|
|
row_sizes[r] = wxSize(0, 0);
|
|
for(g = 0; g < group_count; ++g)
|
|
{
|
|
wxRibbonToolBarToolGroup* group = m_groups.Item(g);
|
|
int shortest_row = 0;
|
|
for(r = 1; r < nrows; ++r)
|
|
{
|
|
if(row_sizes[r].GetWidth() < row_sizes[shortest_row].GetWidth())
|
|
shortest_row = r;
|
|
}
|
|
row_sizes[shortest_row].x += group->size.x + sep;
|
|
if(group->size.y > row_sizes[shortest_row].y)
|
|
row_sizes[shortest_row].y = group->size.y;
|
|
}
|
|
wxSize size(0, 0);
|
|
for(r = 0; r < nrows; ++r)
|
|
{
|
|
if(row_sizes[r].GetWidth() != 0)
|
|
row_sizes[r].DecBy(sep, 0);
|
|
if(row_sizes[r].GetWidth() > size.GetWidth())
|
|
size.SetWidth(row_sizes[r].GetWidth());
|
|
size.IncBy(0, row_sizes[r].y);
|
|
}
|
|
m_sizes[nrows - m_nrows_min] = size;
|
|
|
|
if(GetSizeInOrientation(size, major_axis) < smallest_area)
|
|
{
|
|
smallest_area = GetSizeInOrientation(size, major_axis);
|
|
SetMinSize(size);
|
|
}
|
|
|
|
if (sizingFlexibly)
|
|
{
|
|
if (size.x < minSize.x)
|
|
minSize.x = size.x;
|
|
if (size.y < minSize.y)
|
|
minSize.y = size.y;
|
|
}
|
|
}
|
|
|
|
if (sizingFlexibly)
|
|
{
|
|
// Give it the min size in either direction regardless of row,
|
|
// so that we're able to vary the size of the panel according to
|
|
// the space the toolbar takes up.
|
|
SetMinSize(minSize);
|
|
}
|
|
delete[] row_sizes;
|
|
|
|
// Position the groups
|
|
wxSizeEvent dummy_event(GetSize());
|
|
OnSize(dummy_event);
|
|
|
|
return true;
|
|
}
|
|
|
|
void wxRibbonToolBar::OnSize(wxSizeEvent& evt)
|
|
{
|
|
if(m_art == nullptr)
|
|
return;
|
|
|
|
// Choose row count with largest possible area
|
|
wxSize size = evt.GetSize();
|
|
int row_count = m_nrows_max;
|
|
wxOrientation major_axis = m_art->GetFlags() & wxRIBBON_BAR_FLOW_VERTICAL ?
|
|
wxVERTICAL : wxHORIZONTAL;
|
|
|
|
// See if we're sizing flexibly, and set min size differently
|
|
bool sizingFlexibly = false;
|
|
wxRibbonPanel* panel = wxDynamicCast(GetParent(), wxRibbonPanel);
|
|
if (panel && (panel->GetFlags() & wxRIBBON_PANEL_FLEXIBLE))
|
|
sizingFlexibly = true;
|
|
|
|
// Without this, there will be redundant horizontal space because SetMinSize will
|
|
// use the smallest possible height (and therefore largest width).
|
|
if (sizingFlexibly)
|
|
major_axis = wxHORIZONTAL;
|
|
|
|
if(m_nrows_max != m_nrows_min)
|
|
{
|
|
int area = 0;
|
|
for(int i = 0; i <= m_nrows_max - m_nrows_min; ++i)
|
|
{
|
|
if(m_sizes[i].x <= size.x && m_sizes[i].y <= size.y &&
|
|
GetSizeInOrientation(m_sizes[i], major_axis) > area)
|
|
{
|
|
area = GetSizeInOrientation(m_sizes[i], major_axis);
|
|
row_count = m_nrows_min + i;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Assign groups to rows and calculate row widths
|
|
wxSize* row_sizes = new wxSize[row_count];
|
|
int sep = m_art->GetMetric(wxRIBBON_ART_TOOL_GROUP_SEPARATION_SIZE);
|
|
|
|
int r;
|
|
size_t g;
|
|
size_t group_count = m_groups.GetCount();
|
|
for(g = 0; g < group_count; ++g)
|
|
{
|
|
wxRibbonToolBarToolGroup* group = m_groups.Item(g);
|
|
int shortest_row = 0;
|
|
for(r = 1; r < row_count; ++r)
|
|
{
|
|
if(row_sizes[r].GetWidth() < row_sizes[shortest_row].GetWidth())
|
|
shortest_row = r;
|
|
}
|
|
group->position = wxPoint(row_sizes[shortest_row].x, shortest_row);
|
|
row_sizes[shortest_row].x += group->size.x + sep;
|
|
if(group->size.y > row_sizes[shortest_row].y)
|
|
row_sizes[shortest_row].y = group->size.y;
|
|
}
|
|
|
|
// Calculate row positions
|
|
int total_height = 0;
|
|
for(r = 0; r < row_count; ++r)
|
|
total_height += row_sizes[r].GetHeight();
|
|
int rowsep = (size.GetHeight() - total_height) / (row_count + 1);
|
|
int* rowypos = new int[row_count];
|
|
rowypos[0] = rowsep;
|
|
for(r = 1; r < row_count; ++r)
|
|
{
|
|
rowypos[r] = rowypos[r - 1] + row_sizes[r - 1].GetHeight() + rowsep;
|
|
}
|
|
|
|
// Set group y positions
|
|
for(g = 0; g < group_count; ++g)
|
|
{
|
|
wxRibbonToolBarToolGroup* group = m_groups.Item(g);
|
|
group->position.y = rowypos[group->position.y];
|
|
}
|
|
|
|
delete[] rowypos;
|
|
delete[] row_sizes;
|
|
}
|
|
|
|
void wxRibbonToolBar::OnDPIChanged(wxDPIChangedEvent& event)
|
|
{
|
|
Realize();
|
|
event.Skip();
|
|
}
|
|
|
|
void wxRibbonToolBar::OnSysColourChanged(wxSysColourChangedEvent& event)
|
|
{
|
|
event.Skip();
|
|
m_art->UpdateColoursFromSystem();
|
|
}
|
|
|
|
// Finds the best width and height given the parents' width and height
|
|
wxSize wxRibbonToolBar::GetBestSizeForParentSize(const wxSize& parentSize) const
|
|
{
|
|
if (!m_sizes)
|
|
return GetMinSize();
|
|
|
|
// Choose row count with largest possible area
|
|
wxSize size = parentSize;
|
|
|
|
// A toolbar should maximize its width whether vertical or horizontal, so
|
|
// force the major axis to be horizontal. Without this, there will be
|
|
// redundant horizontal space.
|
|
wxOrientation major_axis = wxHORIZONTAL;
|
|
wxSize bestSize = m_sizes[0];
|
|
|
|
if(m_nrows_max != m_nrows_min)
|
|
{
|
|
int area = 0;
|
|
for(int i = 0; i <= m_nrows_max - m_nrows_min; ++i)
|
|
{
|
|
if(m_sizes[i].x <= size.x && m_sizes[i].y <= size.y &&
|
|
GetSizeInOrientation(m_sizes[i], major_axis) > area)
|
|
{
|
|
area = GetSizeInOrientation(m_sizes[i], major_axis);
|
|
bestSize = m_sizes[i];
|
|
}
|
|
}
|
|
}
|
|
return bestSize;
|
|
}
|
|
|
|
wxSize wxRibbonToolBar::DoGetBestSize() const
|
|
{
|
|
return GetMinSize();
|
|
}
|
|
|
|
void wxRibbonToolBar::OnEraseBackground(wxEraseEvent& WXUNUSED(evt))
|
|
{
|
|
// All painting done in main paint handler to minimise flicker
|
|
}
|
|
|
|
void wxRibbonToolBar::OnPaint(wxPaintEvent& WXUNUSED(evt))
|
|
{
|
|
wxAutoBufferedPaintDC dc(this);
|
|
if(m_art == nullptr)
|
|
return;
|
|
|
|
m_art->DrawToolBarBackground(dc, this, GetSize());
|
|
|
|
size_t group_count = m_groups.GetCount();
|
|
size_t g, t;
|
|
for(g = 0; g < group_count; ++g)
|
|
{
|
|
wxRibbonToolBarToolGroup* group = m_groups.Item(g);
|
|
size_t tool_count = group->tools.GetCount();
|
|
if(tool_count != 0)
|
|
{
|
|
m_art->DrawToolGroupBackground(dc, this,
|
|
wxRect(group->position, group->size));
|
|
for(t = 0; t < tool_count; ++t)
|
|
{
|
|
wxRibbonToolBarToolBase* tool = group->tools.Item(t);
|
|
wxRect rect(group->position + tool->position, tool->size);
|
|
// Resolve bitmap bundle to actual bitmap for current DPI
|
|
wxBitmap bmp;
|
|
if(tool->state & wxRIBBON_TOOLBAR_TOOL_DISABLED)
|
|
bmp = tool->bitmap_disabled.GetBitmapFor(this);
|
|
else
|
|
bmp = tool->bitmap.GetBitmapFor(this);
|
|
m_art->DrawTool(dc, this, rect, bmp, tool->kind, tool->state);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void wxRibbonToolBar::OnMouseMove(wxMouseEvent& evt)
|
|
{
|
|
wxPoint pos(evt.GetPosition());
|
|
wxRibbonToolBarToolBase *new_hover = nullptr;
|
|
|
|
size_t group_count = m_groups.GetCount();
|
|
size_t g, t;
|
|
for(g = 0; g < group_count; ++g)
|
|
{
|
|
wxRibbonToolBarToolGroup* group = m_groups.Item(g);
|
|
if(group->position.x <= pos.x && pos.x < group->position.x + group->size.x
|
|
&& group->position.y <= pos.y && pos.y < group->position.y + group->size.y)
|
|
{
|
|
size_t tool_count = group->tools.GetCount();
|
|
pos -= group->position;
|
|
for(t = 0; t < tool_count; ++t)
|
|
{
|
|
wxRibbonToolBarToolBase* tool = group->tools.Item(t);
|
|
if(tool->position.x <= pos.x && pos.x < tool->position.x + tool->size.x
|
|
&& tool->position.y <= pos.y && pos.y < tool->position.y + tool->size.y)
|
|
{
|
|
pos -= tool->position;
|
|
new_hover = tool;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
#if wxUSE_TOOLTIPS
|
|
if(new_hover)
|
|
{
|
|
if (new_hover != m_hover_tool &&
|
|
!(new_hover->state & wxRIBBON_TOOLBAR_TOOL_DROPDOWN_ACTIVE))
|
|
SetToolTip(new_hover->help_string);
|
|
}
|
|
else if(GetToolTip())
|
|
{
|
|
UnsetToolTip();
|
|
}
|
|
#endif
|
|
|
|
if(new_hover != m_hover_tool)
|
|
{
|
|
if(m_hover_tool)
|
|
{
|
|
m_hover_tool->state &= ~(wxRIBBON_TOOLBAR_TOOL_HOVER_MASK
|
|
| wxRIBBON_TOOLBAR_TOOL_ACTIVE_MASK);
|
|
}
|
|
m_hover_tool = new_hover;
|
|
|
|
if(new_hover && new_hover->state & wxRIBBON_TOOLBAR_TOOL_DISABLED)
|
|
new_hover = nullptr; // A disabled tool can not be highlighted
|
|
|
|
if(new_hover)
|
|
{
|
|
long what = wxRIBBON_TOOLBAR_TOOL_NORMAL_HOVERED;
|
|
if(new_hover->dropdown.Contains(pos))
|
|
what = wxRIBBON_TOOLBAR_TOOL_DROPDOWN_HOVERED;
|
|
|
|
new_hover->state |= what;
|
|
|
|
if(new_hover == m_active_tool)
|
|
{
|
|
new_hover->state &= ~wxRIBBON_TOOLBAR_TOOL_ACTIVE_MASK;
|
|
new_hover->state |= (what << 2);
|
|
}
|
|
}
|
|
Refresh(false);
|
|
}
|
|
else if(m_hover_tool && m_hover_tool->kind == wxRIBBON_BUTTON_HYBRID)
|
|
{
|
|
long newstate = m_hover_tool->state &~wxRIBBON_TOOLBAR_TOOL_HOVER_MASK;
|
|
long what = wxRIBBON_TOOLBAR_TOOL_NORMAL_HOVERED;
|
|
if(m_hover_tool->dropdown.Contains(pos))
|
|
what = wxRIBBON_TOOLBAR_TOOL_DROPDOWN_HOVERED;
|
|
newstate |= what;
|
|
if(newstate != m_hover_tool->state)
|
|
{
|
|
m_hover_tool->state = newstate;
|
|
if(m_hover_tool == m_active_tool)
|
|
{
|
|
m_hover_tool->state &= ~wxRIBBON_TOOLBAR_TOOL_ACTIVE_MASK;
|
|
m_hover_tool->state |= (what << 2);
|
|
}
|
|
Refresh(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
void wxRibbonToolBar::OnMouseDown(wxMouseEvent& evt)
|
|
{
|
|
OnMouseMove(evt);
|
|
if(m_hover_tool)
|
|
{
|
|
m_active_tool = m_hover_tool;
|
|
m_active_tool->state |=
|
|
(m_active_tool->state & wxRIBBON_TOOLBAR_TOOL_HOVER_MASK) << 2;
|
|
UnsetToolTip();
|
|
Refresh(false);
|
|
}
|
|
}
|
|
|
|
void wxRibbonToolBar::OnMouseLeave(wxMouseEvent& WXUNUSED(evt))
|
|
{
|
|
if(m_hover_tool)
|
|
{
|
|
m_hover_tool->state &= ~wxRIBBON_TOOLBAR_TOOL_HOVER_MASK;
|
|
m_hover_tool = nullptr;
|
|
Refresh(false);
|
|
}
|
|
}
|
|
|
|
void wxRibbonToolBar::OnMouseUp(wxMouseEvent& WXUNUSED(evt))
|
|
{
|
|
if(m_active_tool)
|
|
{
|
|
if(m_active_tool->state & wxRIBBON_TOOLBAR_TOOL_ACTIVE_MASK)
|
|
{
|
|
wxEventType evt_type = wxEVT_RIBBONTOOLBAR_CLICKED;
|
|
if(m_active_tool->state & wxRIBBON_TOOLBAR_TOOL_DROPDOWN_ACTIVE)
|
|
evt_type = wxEVT_RIBBONTOOLBAR_DROPDOWN_CLICKED;
|
|
wxRibbonToolBarEvent notification(evt_type, m_active_tool->id);
|
|
if(m_active_tool->kind == wxRIBBON_BUTTON_TOGGLE)
|
|
{
|
|
m_active_tool->state ^=
|
|
wxRIBBON_TOOLBAR_TOOL_TOGGLED;
|
|
notification.SetInt(m_active_tool->state &
|
|
wxRIBBON_TOOLBAR_TOOL_TOGGLED);
|
|
}
|
|
notification.SetEventObject(this);
|
|
notification.SetBar(this);
|
|
ProcessEvent(notification);
|
|
|
|
if (auto* const panel = wxCheckedStaticCast<wxRibbonPanel>(GetParent()))
|
|
panel->HideIfExpanded();
|
|
}
|
|
|
|
// Notice that m_active_tool could have been reset by the event handler
|
|
// above so we need to test it again.
|
|
if (m_active_tool)
|
|
{
|
|
m_active_tool->state &= ~wxRIBBON_TOOLBAR_TOOL_ACTIVE_MASK;
|
|
m_active_tool = nullptr;
|
|
Refresh(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
void wxRibbonToolBar::OnMouseEnter(wxMouseEvent& evt)
|
|
{
|
|
if(m_active_tool && !evt.LeftIsDown())
|
|
{
|
|
m_active_tool->state &= ~wxRIBBON_TOOLBAR_TOOL_ACTIVE_MASK;
|
|
m_active_tool = nullptr;
|
|
}
|
|
}
|
|
|
|
void wxRibbonToolBar::UpdateWindowUI(long flags)
|
|
{
|
|
wxWindowBase::UpdateWindowUI(flags);
|
|
|
|
// don't waste time updating state of tools in a hidden toolbar
|
|
if ( !IsShown() )
|
|
return;
|
|
|
|
size_t group_count = m_groups.GetCount();
|
|
size_t g, t;
|
|
for(g = 0; g < group_count; ++g)
|
|
{
|
|
wxRibbonToolBarToolGroup* group = m_groups.Item(g);
|
|
size_t tool_count = group->tools.GetCount();
|
|
for(t = 0; t < tool_count; ++t)
|
|
{
|
|
wxRibbonToolBarToolBase* tool = group->tools.Item(t);
|
|
int id = tool->id;
|
|
|
|
wxUpdateUIEvent event(id);
|
|
event.SetEventObject(this);
|
|
|
|
if ( ProcessWindowEvent(event) )
|
|
{
|
|
if ( event.GetSetEnabled() )
|
|
EnableTool(id, event.GetEnabled());
|
|
if ( event.GetSetChecked() )
|
|
ToggleTool(id, event.GetChecked());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool wxRibbonToolBarEvent::PopupMenu(wxMenu* menu)
|
|
{
|
|
wxPoint pos = wxDefaultPosition;
|
|
if(m_bar->m_active_tool)
|
|
{
|
|
// Find the group which contains the tool
|
|
size_t group_count = m_bar->m_groups.GetCount();
|
|
size_t g, t;
|
|
for(g = 0; g < group_count; ++g)
|
|
{
|
|
wxRibbonToolBarToolGroup* group = m_bar->m_groups.Item(g);
|
|
size_t tool_count = group->tools.GetCount();
|
|
for(t = 0; t < tool_count; ++t)
|
|
{
|
|
wxRibbonToolBarToolBase* tool = group->tools.Item(t);
|
|
if(tool == m_bar->m_active_tool)
|
|
{
|
|
pos = group->position;
|
|
pos += tool->position;
|
|
pos.y += tool->size.GetHeight();
|
|
g = group_count;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return m_bar->PopupMenu(menu, pos);
|
|
}
|
|
|
|
#endif // wxUSE_RIBBON
|