mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-13 02:41:16 +00:00
Add dropdown item action icons
This commit is contained in:
@@ -69,6 +69,11 @@ ComboBox::ComboBox(wxWindow *parent,
|
||||
e.SetId(GetId());
|
||||
GetEventHandler()->ProcessEvent(e);
|
||||
});
|
||||
drop.Bind(EVT_DROPDOWN_ITEM_ACTION, [this](wxCommandEvent &e) {
|
||||
e.SetEventObject(this);
|
||||
e.SetId(GetId());
|
||||
GetEventHandler()->ProcessEvent(e);
|
||||
});
|
||||
drop.Bind(EVT_DISMISS, [this](auto &) {
|
||||
drop_down = false;
|
||||
wxCommandEvent e(wxEVT_COMBOBOX_CLOSEUP);
|
||||
@@ -222,7 +227,7 @@ int ComboBox::Append(const wxString &text,
|
||||
int style)
|
||||
{
|
||||
auto valid_bit_map = (&bitmap && bitmap.IsOk()) ? bitmap : wxNullBitmap;
|
||||
Item item{text, wxEmptyString, valid_bit_map, valid_bit_map, clientData, group_key, group_label};
|
||||
Item item{text, wxEmptyString, valid_bit_map, valid_bit_map, wxNullBitmap, clientData, group_key, group_label};
|
||||
item.style = style;
|
||||
items.push_back(item);
|
||||
SetClientDataType(wxClientData_Void);
|
||||
@@ -268,6 +273,27 @@ void ComboBox::ForceDropdownOpen()
|
||||
}
|
||||
}
|
||||
|
||||
void ComboBox::RefreshDropdownIfOpen()
|
||||
{
|
||||
if (!drop_down)
|
||||
return;
|
||||
|
||||
drop.hover_item = -1;
|
||||
drop.offset = wxPoint();
|
||||
if (drop.subDropDown) {
|
||||
drop.subDropDown->group.clear();
|
||||
drop.subDropDown->hover_item = -1;
|
||||
drop.subDropDown->offset = wxPoint();
|
||||
if (drop.subDropDown->IsShown())
|
||||
drop.subDropDown->Dismiss();
|
||||
}
|
||||
|
||||
drop.need_sync = true;
|
||||
drop.messureSize();
|
||||
drop.autoPosition();
|
||||
drop.paintNow();
|
||||
}
|
||||
|
||||
unsigned int ComboBox::GetCount() const { return items.size(); }
|
||||
|
||||
void ComboBox::set_replace_text(wxString text, wxString image_name)
|
||||
@@ -321,6 +347,13 @@ void ComboBox::SetItemBitmap(unsigned int n, wxBitmap const &bitmap)
|
||||
drop.Invalidate();
|
||||
}
|
||||
|
||||
void ComboBox::SetItemActionBitmap(unsigned int n, wxBitmap const &bitmap)
|
||||
{
|
||||
if (n >= items.size()) return;
|
||||
items[n].action_icon = (&bitmap && bitmap.IsOk()) ? bitmap : wxNullBitmap;
|
||||
drop.Invalidate();
|
||||
}
|
||||
|
||||
int ComboBox::DoInsertItems(const wxArrayStringsAdapter &items,
|
||||
unsigned int pos,
|
||||
void ** clientData,
|
||||
@@ -328,7 +361,7 @@ int ComboBox::DoInsertItems(const wxArrayStringsAdapter &items,
|
||||
{
|
||||
if (pos > this->items.size()) return -1;
|
||||
for (int i = 0; i < items.GetCount(); ++i) {
|
||||
Item item { items[i], wxEmptyString, wxNullBitmap, wxNullBitmap, clientData ? clientData[i] : NULL };
|
||||
Item item { items[i], wxEmptyString, wxNullBitmap, wxNullBitmap, wxNullBitmap, clientData ? clientData[i] : NULL };
|
||||
this->items.insert(this->items.begin() + pos, item);
|
||||
++pos;
|
||||
}
|
||||
|
||||
@@ -80,10 +80,12 @@ public:
|
||||
|
||||
wxBitmap GetItemBitmap(unsigned int n);
|
||||
void SetItemBitmap(unsigned int n, wxBitmap const &bitmap);
|
||||
void SetItemActionBitmap(unsigned int n, wxBitmap const &bitmap);
|
||||
bool is_drop_down(){return drop_down;}
|
||||
void DeleteOneItem(unsigned int pos) { DoDeleteOneItem(pos); }
|
||||
|
||||
void ForceDropdownOpen();
|
||||
void RefreshDropdownIfOpen();
|
||||
|
||||
protected:
|
||||
virtual int DoInsertItems(const wxArrayStringsAdapter &items,
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <set>
|
||||
|
||||
wxDEFINE_EVENT(EVT_DISMISS, wxCommandEvent);
|
||||
wxDEFINE_EVENT(EVT_DROPDOWN_ITEM_ACTION, wxCommandEvent);
|
||||
|
||||
BEGIN_EVENT_TABLE(DropDown, PopupWindow)
|
||||
|
||||
@@ -225,6 +226,29 @@ static wxSize GetBmpSize(wxBitmap & bmp)
|
||||
#endif
|
||||
}
|
||||
|
||||
wxSize DropDown::actionIconSize() const
|
||||
{
|
||||
wxSize size;
|
||||
std::set<wxString> groups;
|
||||
for (const Item& item : items) {
|
||||
if (group.IsEmpty()) {
|
||||
if (!item.group_key.IsEmpty()) {
|
||||
if (groups.find(item.group_key) != groups.end())
|
||||
continue;
|
||||
groups.insert(item.group_key);
|
||||
}
|
||||
} else if (item.group_key != group) {
|
||||
continue;
|
||||
}
|
||||
|
||||
wxBitmap icon = item.action_icon;
|
||||
wxSize icon_size = GetBmpSize(icon);
|
||||
size.x = std::max(size.x, icon_size.x);
|
||||
size.y = std::max(size.y, icon_size.y);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
static void _DrawSplitItem(const wxWindow* w, wxDC& dc, wxString split_text, wxPoint start_pt, int item_width, int item_height)
|
||||
{
|
||||
// save dc
|
||||
@@ -354,6 +378,9 @@ void DropDown::render(wxDC &dc)
|
||||
rcContent.width -= szBmp.x + 5;
|
||||
}
|
||||
|
||||
const wxSize action_icon_size = actionIconSize();
|
||||
const int action_column_width = action_icon_size.x > 0 ? action_icon_size.x + FromDIP(16) : 0;
|
||||
|
||||
std::set<wxString> groups;
|
||||
// draw texts & icons
|
||||
int index = 0;
|
||||
@@ -392,6 +419,7 @@ void DropDown::render(wxDC &dc)
|
||||
}
|
||||
if (rcContent.y > size.y) break;
|
||||
wxPoint pt = rcContent.GetLeftTop();
|
||||
int rcContent_width = rcContent.width;
|
||||
|
||||
if (item.style & DD_ITEM_STYLE_SPLIT_ITEM) {
|
||||
_DrawSplitItem(this, dc, item.text, pt, rowSize.GetWidth(), rowSize.GetHeight());
|
||||
@@ -417,13 +445,27 @@ void DropDown::render(wxDC &dc)
|
||||
auto text = group.IsEmpty()
|
||||
? (item.group_key.IsEmpty() ? item.text : item.group_label)
|
||||
: item.text;
|
||||
if (action_column_width > 0)
|
||||
rcContent.width -= action_column_width;
|
||||
|
||||
if (item.action_icon.IsOk()) {
|
||||
auto action_size = GetBmpSize(item.action_icon);
|
||||
wxPoint action_pt(rcContent.x + rcContent_width - action_size.x - FromDIP(8),
|
||||
rcContent.y + (rcContent.height - action_size.y) / 2);
|
||||
dc.DrawBitmap(item.action_icon, action_pt);
|
||||
}
|
||||
|
||||
if (!text_off && !text.IsEmpty()) {
|
||||
wxSize tSize = dc.GetMultiLineTextExtent(text);
|
||||
if (pt.x + tSize.x > rcContent.GetRight()) {
|
||||
if (is_hover && item.tip.IsEmpty())
|
||||
SetToolTip(text);
|
||||
text = wxControl::Ellipsize(text, dc, wxELLIPSIZE_END,
|
||||
rcContent.GetRight() - pt.x);
|
||||
int max_text_width = rcContent.GetRight() - pt.x;
|
||||
if (max_text_width <= 0) {
|
||||
text.clear();
|
||||
} else {
|
||||
if (is_hover && item.tip.IsEmpty())
|
||||
SetToolTip(text);
|
||||
text = wxControl::Ellipsize(text, dc, wxELLIPSIZE_END, max_text_width);
|
||||
}
|
||||
}
|
||||
pt.y += (rcContent.height - textSize.y) / 2;
|
||||
dc.SetFont(GetFont());
|
||||
@@ -436,6 +478,7 @@ void DropDown::render(wxDC &dc)
|
||||
dc.DrawBitmap(arrow_bitmap.bmp(), pt);
|
||||
}
|
||||
}
|
||||
rcContent.width = rcContent_width;
|
||||
rcContent.y += rowSize.y;
|
||||
}
|
||||
}
|
||||
@@ -545,6 +588,8 @@ void DropDown::messureSize()
|
||||
size1.x += size2.x + (text_off ? 0 : 5);
|
||||
}
|
||||
}
|
||||
if (item.action_icon.IsOk())
|
||||
size1.x += GetBmpSize(item.action_icon).x + FromDIP(16);
|
||||
if (size1.x > textSize.x) textSize = size1;
|
||||
}
|
||||
if (!align_icon) iconSize.x = 0;
|
||||
@@ -616,6 +661,11 @@ void DropDown::messureSize()
|
||||
e.SetId(GetId());
|
||||
GetEventHandler()->ProcessEvent(e);
|
||||
});
|
||||
subDropDown->Bind(EVT_DROPDOWN_ITEM_ACTION, [this](wxCommandEvent &e) {
|
||||
e.SetEventObject(this);
|
||||
e.SetId(GetId());
|
||||
GetEventHandler()->ProcessEvent(e);
|
||||
});
|
||||
}
|
||||
need_sync = false;
|
||||
}
|
||||
@@ -694,6 +744,19 @@ void DropDown::mouseReleased(wxMouseEvent& event)
|
||||
if (hover_item < 0)
|
||||
return;
|
||||
if (hover_item >= 0 && (subDropDown == nullptr || subDropDown->group.empty())) { // not moved
|
||||
int index = hoverIndex();
|
||||
if (index >= 0 && items[index].action_icon.IsOk()) {
|
||||
wxSize action_size = actionIconSize();
|
||||
int action_right = GetSize().x;
|
||||
if (rowSize.y * count > GetSize().y)
|
||||
action_right -= 6;
|
||||
int action_left = action_right - action_size.x - FromDIP(16);
|
||||
if (event.GetX() >= action_left && event.GetX() <= action_right) {
|
||||
sendDropDownActionEvent(index);
|
||||
paintNow();
|
||||
return;
|
||||
}
|
||||
}
|
||||
sendDropDownEvent();
|
||||
if (mainDropDown)
|
||||
mainDropDown->hover_item = -1; // To Dismiss mainDropDown
|
||||
@@ -810,6 +873,17 @@ void DropDown::sendDropDownEvent()
|
||||
GetEventHandler()->ProcessEvent(event);
|
||||
}
|
||||
|
||||
void DropDown::sendDropDownActionEvent(int index)
|
||||
{
|
||||
if (index < 0 || index >= int(items.size()) || (items[index].style & DD_ITEM_STYLE_DISABLED))
|
||||
return;
|
||||
wxCommandEvent event(EVT_DROPDOWN_ITEM_ACTION, GetId());
|
||||
event.SetEventObject(this);
|
||||
event.SetInt(index);
|
||||
event.SetString(items[index].text);
|
||||
GetEventHandler()->ProcessEvent(event);
|
||||
}
|
||||
|
||||
void DropDown::Dismiss()
|
||||
{
|
||||
if (subDropDown && subDropDown->IsShown())
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#define DD_ITEM_STYLE_DISABLED 0x0002 // ----text----, text with horizontal line arounds
|
||||
|
||||
wxDECLARE_EVENT(EVT_DISMISS, wxCommandEvent);
|
||||
wxDECLARE_EVENT(EVT_DROPDOWN_ITEM_ACTION, wxCommandEvent);
|
||||
|
||||
class DropDown : public PopupWindow
|
||||
{
|
||||
@@ -25,6 +26,7 @@ public:
|
||||
wxString text_static_tips;// display static tips for TextInput.eg.PrinterInfoBox
|
||||
wxBitmap icon;
|
||||
wxBitmap icon_textctrl;// display icon for TextInput.eg.PrinterInfoBox
|
||||
wxBitmap action_icon;
|
||||
void * data{nullptr};
|
||||
wxString group_key{};
|
||||
wxString group_label{};
|
||||
@@ -123,6 +125,7 @@ private:
|
||||
int hoverIndex();
|
||||
|
||||
int selectedItem();
|
||||
wxSize actionIconSize() const;
|
||||
|
||||
friend class ComboBox;
|
||||
void messureSize();
|
||||
@@ -136,6 +139,7 @@ private:
|
||||
void mouseWheelMoved(wxMouseEvent &event);
|
||||
|
||||
void sendDropDownEvent();
|
||||
void sendDropDownActionEvent(int index);
|
||||
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
|
||||
Reference in New Issue
Block a user