OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
DropDown Class Reference

#include </home/runner/work/OrcaSlicer/OrcaSlicer/src/slic3r/GUI/Widgets/DropDown.hpp>

Inheritance diagram for DropDown:
Collaboration diagram for DropDown:

Classes

struct  Item

Public Member Functions

 DropDown (std::vector< Item > &items)
 DropDown (wxWindow *parent, std::vector< Item > &items, long style=0)
void Create (wxWindow *parent, long style=0)
void Invalidate (bool clear=false)
int GetSelection () const
void SetSelection (int n)
wxString GetValue () const
void SetValue (const wxString &value)
void SetCornerRadius (double radius)
void SetBorderColor (StateColor const &color)
void SetSelectorBorderColor (StateColor const &color)
void SetTextColor (StateColor const &color)
void SetSelectorBackgroundColor (StateColor const &color)
void SetUseContentWidth (bool use, bool limit_max_content_width=false)
void SetAlignIcon (bool align)
void Rescale ()
bool HasDismissLongTime ()
void Popup (wxWindow *focus=nullptr) override
bool Create (wxWindow *parent, int flags=wxBORDER_NONE)

Protected Member Functions

void Dismiss () override
void OnDismiss () override
bool ShouldDismissOnTopWindowDeactivate () override

Private Member Functions

void paintEvent (wxPaintEvent &evt)
void paintNow ()
void render (wxDC &dc)
int hoverIndex ()
int selectedItem ()
std::pair< int, int > actionColumn () const
void messureSize ()
void autoPosition ()
void mouseDown (wxMouseEvent &event)
void mouseReleased (wxMouseEvent &event)
void mouseCaptureLost (wxMouseCaptureLostEvent &event)
void mouseMove (wxMouseEvent &event)
void mouseWheelMoved (wxMouseEvent &event)
void sendDropDownEvent ()
void sendDropDownActionEvent (int index)

Private Attributes

std::vector< Item > & items
size_t count = 0
wxString group
bool need_sync = false
int selection = -1
int hover_item = -1
DropDown * subDropDown { nullptr }
DropDown * mainDropDown { nullptr }
double radius = 0
bool use_content_width = false
bool limit_max_content_width = false
bool align_icon = false
bool text_off = false
wxSize textSize
wxSize iconSize
int actionIconWidth = 0
wxSize rowSize
StateHandler state_handler
StateColor text_color
StateColor border_color
StateColor selector_border_color
StateColor selector_background_color
ScalableBitmap check_bitmap
ScalableBitmap arrow_bitmap
bool pressedDown = false
boost::posix_time::ptime dismissTime
wxPoint offset
wxPoint dragStart

Friends

class ComboBox

Detailed Description


Class Documentation

◆ DropDown::Item

struct DropDown::Item
Class Members
wxBitmap action_icon
wxString alias {}
void * data {nullptr}
int flag {0}
wxString group_key {}
wxString group_label {}
wxBitmap icon
wxBitmap icon_textctrl
int style { 0 }
wxString text
wxString text_static_tips
wxString tip {}

Constructor & Destructor Documentation

◆ DropDown() [1/2]

DropDown::DropDown ( std::vector< Item > & items)
56 : items(items)
57 , state_handler(this)
58 , border_color(0xDBDBDB)
59 , text_color(std::make_pair(0x909090, (int) StateColor::Disabled),
60 std::make_pair(0x363636, (int) StateColor::Normal))
61 , selector_border_color(std::make_pair(0x009688, (int) StateColor::Hovered),
62 std::make_pair(*wxWHITE, (int) StateColor::Normal))
63 , selector_background_color(std::make_pair(0xBFE1DE, (int) StateColor::Checked), // ORCA updated background color for checked item
64 std::make_pair(*wxWHITE, (int) StateColor::Normal))
65{
66}
StateColor selector_background_color
Definition DropDown.hpp:78
StateHandler state_handler
Definition DropDown.hpp:74
std::vector< Item > & items
Definition DropDown.hpp:53
StateColor selector_border_color
Definition DropDown.hpp:77
StateColor border_color
Definition DropDown.hpp:76
StateColor text_color
Definition DropDown.hpp:75
@ Hovered
Definition StateColor.hpp:20
@ Normal
Definition StateColor.hpp:16
@ Disabled
Definition StateColor.hpp:22
@ Checked
Definition StateColor.hpp:18

References DropDown(), border_color, items, selector_background_color, selector_border_color, state_handler, and text_color.

Referenced by DropDown(), DropDown(), and messureSize().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ DropDown() [2/2]

DropDown::DropDown ( wxWindow * parent,
std::vector< Item > & items,
long style = 0 )
70{
71 Create(parent, style);
72}
#define style
Definition WipeTowerDialog.cpp:101
void Create(wxWindow *parent, long style=0)
Definition DropDown.cpp:74
DropDown(std::vector< Item > &items)
Definition DropDown.cpp:55

References DropDown(), Create(), items, and style.

Here is the call graph for this function:

Member Function Documentation

◆ actionColumn()

std::pair< int, int > DropDown::actionColumn ( ) const
private
251{
252 if (actionIconWidth <= 0)
253 return {0, 0};
254 int right = rowSize.x;
255 if (rowSize.y * count > GetSize().y) // position bar
256 right -= 6;
257 return {right - actionIconWidth - FromDIP(16), right};
258}
size_t count
Definition DropDown.hpp:54
int actionIconWidth
Definition DropDown.hpp:71
wxSize rowSize
Definition DropDown.hpp:72
@ right
Definition MarchingSquares.hpp:190

References actionIconWidth, count, and rowSize.

Referenced by mouseReleased(), and render().

Here is the caller graph for this function:

◆ autoPosition()

void DropDown::autoPosition ( )
private
714{
715 messureSize();
716 wxPoint pos;
717 wxSize off;
718 if (mainDropDown) {
719 pos = mainDropDown->ClientToScreen(wxPoint(0, 0));
720 off = mainDropDown->GetSize();
721 pos.x += 6;
722 pos.y += mainDropDown->hover_item * rowSize.y + rowSize.y + mainDropDown->offset.y;
723 off.x -= 12;
724 off.y = -rowSize.y;
725 } else {
726 pos = GetParent()->ClientToScreen(wxPoint(0, 0));
727 off = GetParent()->GetSize();
728 pos.y -= 6;
729 off.x = 0;
730 off.y += 12;
731 }
732 wxPoint old = GetPosition();
733 wxSize size = GetSize();
734 Position(pos, off);
735 if (old != GetPosition()) {
736 size = rowSize;
737 size.y *= std::min((size_t) 15, count);
738 size.y += count > 15 ? rowSize.y / 2 : 0;
739 if (size != GetSize()) {
740 wxWindow::SetSize(size);
741 offset = wxPoint();
742 Position(pos, off);
743 }
744 }
745 if (GetPosition().y > pos.y) {
746 // may exceed
747 auto drect = wxDisplay(GetParent()).GetGeometry();
748 if (GetPosition().y + size.y + 10 > drect.GetBottom()) {
749 int available_height = drect.GetBottom() - GetPosition().y - 10;
750 if (available_height < rowSize.y * 2)
751 return;
752 if (use_content_width && count <= 15) size.x += 6;
753 size.y = available_height;
754 wxWindow::SetSize(size);
755 if (selection >= 0) {
756 if (offset.y + rowSize.y * (selection + 1) > size.y)
757 offset.y = size.y - rowSize.y * (selection + 1);
758 else if (offset.y + rowSize.y * selection < 0)
759 offset.y = -rowSize.y * selection;
760 }
761 }
762 }
763}
void messureSize()
Definition DropDown.cpp:557
int selection
Definition DropDown.hpp:57
DropDown * mainDropDown
Definition DropDown.hpp:61
wxPoint offset
Definition DropDown.hpp:84
bool use_content_width
Definition DropDown.hpp:64
Vec3d pos(const Pt &p)
Definition ReprojectPointsOnMesh.hpp:16

References count, mainDropDown, messureSize(), offset, rowSize, selection, and use_content_width.

Here is the call graph for this function:

◆ Create() [1/2]

void DropDown::Create ( wxWindow * parent,
long style = 0 )
75{
76 PopupWindow::Create(parent, wxPU_CONTAINS_CONTROLS);
77 SetBackgroundStyle(wxBG_STYLE_PAINT);
78 SetBackgroundColour(*wxWHITE);
80 state_handler.update_binds();
81 if ((style & DD_NO_CHECK_ICON) == 0)
82 check_bitmap = ScalableBitmap(this, "checked", 16);
83 arrow_bitmap = ScalableBitmap(this, "hms_arrow", 16);
85
86 // BBS set default font
87 SetFont(Label::Body_14);
88#ifdef __WXOSX__
89 // PopupWindow releases mouse on idle, which may cause various problems,
90 // such as losting mouse move, and dismissing soon on first LEFT_DOWN event.
91 Bind(wxEVT_IDLE, [] (wxIdleEvent & evt) {});
92#endif
93}
#define DD_NO_TEXT
Definition DropDown.hpp:23
#define DD_NO_CHECK_ICON
Definition DropDown.hpp:22
ScalableBitmap arrow_bitmap
Definition DropDown.hpp:80
ScalableBitmap check_bitmap
Definition DropDown.hpp:79
bool text_off
Definition DropDown.hpp:67
static wxFont Body_14
Definition Label.hpp:53
bool Create(wxWindow *parent, int flags=wxBORDER_NONE)
Definition PopupWindow.cpp:21

References arrow_bitmap, Label::Body_14, border_color, check_bitmap, PopupWindow::Create(), DD_NO_CHECK_ICON, DD_NO_TEXT, selector_background_color, selector_border_color, state_handler, style, text_color, and text_off.

Referenced by DropDown().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Create() [2/2]

bool PopupWindow::Create ( wxWindow * parent,
int flags = wxBORDER_NONE )
inherited
22{
23 if (!wxPopupTransientWindow::Create(parent, style))
24 return false;
25#ifdef __WXGTK__
26 GetTopParent(parent)->Bind(wxEVT_ACTIVATE, &PopupWindow::topWindowActiavate, this);
27#endif
28#ifdef __WXOSX__
29 if (style & wxPU_CONTAINS_CONTROLS)
30 for (auto evt : {wxEVT_LEFT_DOWN, wxEVT_LEFT_UP, wxEVT_LEFT_DCLICK, wxEVT_MOTION, wxEVT_MOUSEWHEEL})
31 Bind(evt, &PopupWindow::OnMouseEvent2, this);
32#endif
33 return true;
34}
static wxWindow * GetTopParent(wxWindow *pWindow)
Definition PopupWindow.cpp:10

References GetTopParent(), and style.

Referenced by PopupWindow(), and DropDown::Create().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Dismiss()

void DropDown::Dismiss ( )
overrideprotected
924{
925 if (subDropDown && subDropDown->IsShown())
926 return;
927 PopupWindow::Dismiss();
928}
DropDown * subDropDown
Definition DropDown.hpp:60

References subDropDown.

◆ GetSelection()

int DropDown::GetSelection ( ) const
inline
97{ return selection; }

References selection.

◆ GetValue()

wxString DropDown::GetValue ( ) const
121{
122 return selection >= 0 ? items[selection].text : wxString();
123}

References items, and selection.

◆ HasDismissLongTime()

bool DropDown::HasDismissLongTime ( )
183{
184 auto now = boost::posix_time::microsec_clock::universal_time();
185 return !IsShown() &&
186 (now - dismissTime).total_milliseconds() >= 20;
187}
boost::posix_time::ptime dismissTime
Definition DropDown.hpp:83

References dismissTime.

◆ hoverIndex()

int DropDown::hoverIndex ( )
private
494{
495 if (hover_item < 0)
496 return -1;
497 // BUG FIX: Can't take the shortcut if subDropDown exists (which means there are groups)
498 // because we need to detect group headers which return negative indices
499 if (count == items.size() && subDropDown == nullptr)
500 return hover_item;
501 int index = -1;
502 std::set<wxString> groups;
503 for (int i = 0; i < items.size(); ++i) {
504 auto &item = items[i];
505 // Skip by group
506 if (group.IsEmpty()) {
507 if (!item.group_key.IsEmpty()) {
508 if (groups.find(item.group_key) == groups.end())
509 groups.insert(item.group_key);
510 else
511 continue;
512 }
513 } else {
514 if (item.group_key != group)
515 continue;
516 }
517 if (++index == hover_item)
518 return (item.group_key.IsEmpty() || !group.IsEmpty()) ? i : -i - 2;
519 }
520 return -1;
521}
int hover_item
Definition DropDown.hpp:58
wxString group
Definition DropDown.hpp:55

References count, group, hover_item, items, and subDropDown.

Referenced by mouseMove(), mouseReleased(), mouseWheelMoved(), render(), and sendDropDownEvent().

Here is the caller graph for this function:

◆ Invalidate()

void DropDown::Invalidate ( bool clear = false)
96{
97 if (clear) {
98 selection = hover_item = -1;
99 offset = wxPoint();
100 }
101 assert(selection < (int) items.size());
102 need_sync = true;
103}
bool need_sync
Definition DropDown.hpp:56

References hover_item, items, need_sync, offset, and selection.

◆ messureSize()

void DropDown::messureSize ( )
private
558{
559 if (!need_sync) return;
560 textSize = wxSize();
561 iconSize = wxSize();
562 actionIconWidth = 0;
563 count = 0;
564 wxClientDC dc(GetParent() ? GetParent() : this);
565 dc.SetFont(GetFont());
566 std::set<wxString> groups;
567 for (size_t i = 0; i < items.size(); ++i) {
568 auto &item = items[i];
569 // Skip by group
570 if (group.IsEmpty()) {
571 if (!item.group_key.IsEmpty()) {
572 if (groups.find(item.group_key) == groups.end())
573 groups.insert(item.group_key);
574 else
575 continue;
576 }
577 } else {
578 if (item.group_key != group)
579 continue;
580 }
581 ++count;
582 wxSize size1;
583 if (!text_off) {
584 auto text = group.IsEmpty()
585 ? (item.group_key.IsEmpty() ? item.text : item.group_label)
586 : item.text;
587 size1 = dc.GetMultiLineTextExtent(text);
588 if (group.IsEmpty() && !item.group_key.IsEmpty())
589 size1.x += 5 + arrow_bitmap.GetBmpWidth();
590 }
591 if (item.icon.IsOk()) {
592 wxSize size2 = GetBmpSize(item.icon);
593 if (size2.x > iconSize.x)
594 iconSize = size2;
595 if (!align_icon) {
596 size1.x += size2.x + (text_off ? 0 : 5);
597 }
598 }
599 if (item.action_icon.IsOk())
600 actionIconWidth = std::max(actionIconWidth, GetBmpSize(item.action_icon).x);
601 if (size1.x > textSize.x) textSize = size1;
602 }
603 // Every row leaves room for the action column, as render() and actionColumn() lay it out.
604 if (actionIconWidth > 0)
605 textSize.x += actionIconWidth + FromDIP(16);
606 if (!align_icon) iconSize.x = 0;
607 wxSize szContent = textSize;
608 if (szContent.x < FromDIP(120) && !use_content_width)
609 szContent.x = FromDIP(120);
610 szContent.x += 10;
611 if (check_bitmap.bmp().IsOk()) {
612 auto szBmp = check_bitmap.GetBmpSize();
613 szContent.x += szBmp.x + 5;
614 }
615 if (iconSize.x > 0) szContent.x += iconSize.x + (text_off ? 0 : 5);
616 if (iconSize.y > szContent.y) szContent.y = iconSize.y;
617 szContent.y += 10;
618 if (count > 15) szContent.x += 6;
619 if (GetParent() && group.IsEmpty()) {
620 auto x = GetParent()->GetSize().x;
621 if (x > 0 && (!use_content_width || x > szContent.x))
622 szContent.x = x;
623 }
624 rowSize = szContent;
626 wxSize parent_size = GetParent()->GetSize();
627 if (rowSize.x > parent_size.x * 2) {
628 rowSize.x = 2 * parent_size.x;
629 szContent = rowSize;
630 }
631 }
632 szContent.y *= std::min((size_t) 15, std::max(count, (size_t) 1));
633 szContent.y += items.size() > 15 ? rowSize.y / 2 : 0;
634 wxWindow::SetSize(szContent);
635#ifdef __WXGTK__
636 // Gtk has a wrapper window for popup widget
637 if (szContent.x > 0 && szContent.y > 0)
638 gtk_window_resize (GTK_WINDOW (m_widget), szContent.x, szContent.y);
639#endif
640 if (!groups.empty() && subDropDown == nullptr) {
642 subDropDown->mainDropDown = this;
643 subDropDown->check_bitmap = check_bitmap;
644 subDropDown->text_off = text_off;
645 subDropDown->use_content_width = true;
646 subDropDown->Create(GetParent());
647#ifdef __WXGTK__
648 // Orca: On Wayland, while the sub holds an xdg_popup grab, motion events for
649 // the cursor over main may not be delivered (Mutter drops motion
650 // outside the grabbing surface). Poll on idle and synthesize a
651 // mouseMove on main so its hover highlight tracks and it can dismiss
652 // the sub when the cursor leaves the parent (group) item.
653 DropDown* sub = subDropDown;
654 sub->Bind(wxEVT_IDLE, [sub](wxIdleEvent& e) {
655 e.Skip();
656 if (!sub->IsShown() || !sub->mainDropDown->IsShown())
657 return;
658 wxPoint screen_pt = wxGetMousePosition();
659 if (sub->GetScreenRect().Contains(screen_pt) || !sub->mainDropDown->GetScreenRect().Contains(screen_pt))
660 return;
661 wxPoint main_pt = sub->mainDropDown->ScreenToClient(screen_pt);
662 wxMouseEvent ev(wxEVT_MOTION);
663 ev.SetEventObject(sub->mainDropDown);
664 ev.m_x = main_pt.x;
665 ev.m_y = main_pt.y;
666 sub->mainDropDown->mouseMove(ev);
667 e.RequestMore();
668 });
669 // Orca: the submenu holds the GTK grab, so GTK gives it the wheel events of the whole
670 // chain. GDK names the window under the cursor, so re-emit main's events on main.
671 g_signal_connect(sub->m_widget, "event", G_CALLBACK(+[](GtkWidget *, GdkEvent *event, gpointer data) -> gboolean {
672 auto *sub = static_cast<DropDown *>(data);
673 DropDown *main = sub->mainDropDown;
674 if (event->type != GDK_SCROLL || !main || !main->IsShown() || !sub->IsShown())
675 return FALSE;
676 gpointer owner = nullptr;
677 if (event->any.window)
678 gdk_window_get_user_data(event->any.window, &owner);
679 GtkWidget *widget = (owner && GTK_IS_WIDGET(owner)) ? GTK_WIDGET(owner) : nullptr;
680 bool for_main = widget && (widget == main->m_widget || gtk_widget_is_ancestor(widget, main->m_widget));
681 bool for_sub = widget && (widget == sub->m_widget || gtk_widget_is_ancestor(widget, sub->m_widget));
682 if (!for_main && for_sub) {
683 // The compositor may keep the pointer focus on the submenu while the cursor is over main.
684 wxPoint pt((int) event->scroll.x, (int) event->scroll.y);
685 if (sub->GetClientRect().Contains(pt))
686 return FALSE;
687 wxPoint off = sub->GetScreenRect().GetTopLeft() - main->GetScreenRect().GetTopLeft();
688 event->scroll.x += off.x;
689 event->scroll.y += off.y;
690 for_main = true;
691 }
692 if (!for_main)
693 return FALSE;
694 // wx connects its mouse handlers to GetConnectWidget(), the inner widget of the popup.
695 gtk_propagate_event(main->GetConnectWidget(), event);
696 return TRUE;
697 }), sub);
698#endif
699 subDropDown->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent &e) {
700 e.SetEventObject(this);
701 e.SetId(GetId());
702 GetEventHandler()->ProcessEvent(e);
703 });
704 subDropDown->Bind(EVT_DROPDOWN_ITEM_ACTION, [this](wxCommandEvent &e) {
705 e.SetEventObject(this);
706 e.SetId(GetId());
707 GetEventHandler()->ProcessEvent(e);
708 });
709 }
710 need_sync = false;
711}
static wxSize GetBmpSize(wxBitmap &bmp)
Definition DropDown.cpp:236
void mouseMove(wxMouseEvent &event)
Definition DropDown.cpp:811
bool align_icon
Definition DropDown.hpp:66
wxSize textSize
Definition DropDown.hpp:69
wxSize iconSize
Definition DropDown.hpp:70
bool limit_max_content_width
Definition DropDown.hpp:65
int main(int argc, char const *argv[])
Definition encoding-check.cpp:129
wxMouseEvent
Definition CameraPopup.cpp:47

References DropDown(), actionIconWidth, align_icon, arrow_bitmap, check_bitmap, count, GetBmpSize(), group, iconSize, items, limit_max_content_width, main(), mainDropDown, mouseMove(), need_sync, rowSize, subDropDown, text_off, textSize, and use_content_width.

Referenced by autoPosition(), SetSelection(), and SetUseContentWidth().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mouseCaptureLost()

void DropDown::mouseCaptureLost ( wxMouseCaptureLostEvent & event)
private
806{
807 wxMouseEvent evt;
808 mouseReleased(evt);
809}
void mouseReleased(wxMouseEvent &event)
Definition DropDown.cpp:777

References mouseReleased().

Referenced by wxDEFINE_EVENT().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mouseDown()

void DropDown::mouseDown ( wxMouseEvent & event)
private
766{
767 // Receivce unexcepted LEFT_DOWN on Mac after OnDismiss
768 if (!IsShown())
769 return;
770 // force calc hover item again
771 mouseMove(event);
772 pressedDown = true;
773 CaptureMouse();
774 dragStart = event.GetPosition();
775}
bool pressedDown
Definition DropDown.hpp:82
wxPoint dragStart
Definition DropDown.hpp:85

References dragStart, mouseMove(), and pressedDown.

Referenced by wxDEFINE_EVENT().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mouseMove()

void DropDown::mouseMove ( wxMouseEvent & event)
private
812{
813 wxPoint pt = event.GetPosition();
814#ifdef __WXOSX__
815 if (mainDropDown) {
816 auto size = GetSize();
817 if (pt.x < 0 || pt.y < 0 || pt.x >= size.x || pt.y >= size.y) {
818 auto diff = GetPosition() - mainDropDown->GetPosition();
819 event.SetX(pt.x + diff.x);
820 event.SetY(pt.y + diff.y);
821 mainDropDown->mouseMove(event);
822 return;
823 }
824 }
825#endif
826 if (pressedDown) {
827 wxPoint pt2 = offset + pt - dragStart;
828 wxSize size = GetSize();
829 dragStart = pt;
830 if (pt2.y > 0)
831 pt2.y = 0;
832 else if (pt2.y + rowSize.y * int(count) < size.y)
833 pt2.y = size.y - rowSize.y * int(count);
834 if (pt2.y != offset.y) {
835 offset = pt2;
836 hover_item = -1; // moved
837 } else {
838 return;
839 }
840 }
841 if (!pressedDown || hover_item >= 0) {
842 int hover = (pt.y - offset.y) / rowSize.y;
843 if (hover >= (int) count) hover = -1;
844 if (hover == hover_item) return;
845 hover_item = hover;
846 int index = hoverIndex();
847 if (index < -1) {
848 auto & drop = *subDropDown;
849 drop.group = items[-index - 2].group_key;
850 drop.need_sync = true;
851 drop.messureSize();
852#ifdef __WXGTK__
853 // wxGTK wraps popup contents in a native GtkWindow. Make the submenu
854 // transient for the currently mapped parent popup window before
855 // positioning/showing it, so wlroots/Hyprland sees the topmost parent.
856 if (m_widget && drop.m_widget)
857 gtk_window_set_transient_for(GTK_WINDOW(drop.m_widget), GTK_WINDOW(m_widget));
858#endif
859 drop.autoPosition();
860 drop.paintNow();
861 if (!drop.IsShown())
862 drop.Popup(&drop);
863 } else if (index >= 0) {
864 if (subDropDown) {
865 subDropDown->group.clear();
866 if (subDropDown->IsShown())
867 subDropDown->Dismiss();
868 }
869 SetToolTip(items[index].tip);
870 }
871 }
872 paintNow();
873}
void paintNow()
Definition DropDown.cpp:228
int hoverIndex()
Definition DropDown.cpp:493
Slic3r::Polygons diff(const Slic3r::Polygon &subject, const Slic3r::Polygon &clip, ApplySafetyOffset do_safety_offset)
Definition ClipperUtils.cpp:731

References count, dragStart, hover_item, hoverIndex(), items, mainDropDown, offset, paintNow(), pressedDown, rowSize, and subDropDown.

Referenced by messureSize(), mouseDown(), and wxDEFINE_EVENT().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mouseReleased()

void DropDown::mouseReleased ( wxMouseEvent & event)
private
778{
779 if (pressedDown) {
780 dragStart = wxPoint();
781 pressedDown = false;
782 if (HasCapture())
783 ReleaseMouse();
784 if (hover_item < 0)
785 return;
786 if (hover_item >= 0 && (subDropDown == nullptr || subDropDown->group.empty())) { // not moved
787 int index = hoverIndex();
788 if (index >= 0 && items[index].action_icon.IsOk()) {
789 const auto action_column = actionColumn();
790 if (event.GetX() >= action_column.first && event.GetX() < action_column.second) {
792 paintNow();
793 return;
794 }
795 }
797 if (mainDropDown)
798 mainDropDown->hover_item = -1; // To Dismiss mainDropDown
799 DismissAndNotify();
800 } else if (subDropDown)
801 subDropDown->Popup(subDropDown);
802 }
803}
std::pair< int, int > actionColumn() const
Definition DropDown.cpp:250
void sendDropDownEvent()
Definition DropDown.cpp:900
void sendDropDownActionEvent(int index)
Definition DropDown.cpp:912

References actionColumn(), dragStart, hover_item, hoverIndex(), items, mainDropDown, paintNow(), pressedDown, sendDropDownActionEvent(), sendDropDownEvent(), and subDropDown.

Referenced by mouseCaptureLost(), and wxDEFINE_EVENT().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mouseWheelMoved()

void DropDown::mouseWheelMoved ( wxMouseEvent & event)
private
876{
877 auto delta = event.GetWheelRotation();
878 wxSize size = GetSize();
879 wxPoint pt2 = offset + wxPoint{0, delta};
880 if (pt2.y > 0)
881 pt2.y = 0;
882 else if (pt2.y + rowSize.y * int(count) < size.y)
883 pt2.y = size.y - rowSize.y * int(count);
884 if (pt2.y != offset.y) {
885 offset = pt2;
886 } else {
887 return;
888 }
889 int hover = (event.GetPosition().y - offset.y) / rowSize.y;
890 if (hover >= (int) count) hover = -1;
891 if (hover != hover_item) {
892 hover_item = hover;
893 if (auto index = hoverIndex(); index >= 0)
894 SetToolTip(items[index].tip);
895 }
896 paintNow();
897}

References count, hover_item, hoverIndex(), items, offset, paintNow(), and rowSize.

Referenced by wxDEFINE_EVENT().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OnDismiss()

void DropDown::OnDismiss ( )
overrideprotected
940{
941 if (mainDropDown) {
942
943 const wxPoint& mouse_pos = wxGetMousePosition();
944 if (!mainDropDown->GetScreenRect().Contains(mouse_pos))
945 mainDropDown->DismissAndNotify();
946 else
947#ifdef __WIN32__
948 SetActiveWindow(mainDropDown->GetHandle());
949#else
950 ;
951#endif
952 return;
953 }
954 if (subDropDown && subDropDown->IsShown())
955 return;
956 dismissTime = boost::posix_time::microsec_clock::universal_time();
957 hover_item = -1;
958 wxCommandEvent e(EVT_DISMISS);
959 GetEventHandler()->ProcessEvent(e);
960}

References dismissTime, hover_item, mainDropDown, and subDropDown.

◆ paintEvent()

void DropDown::paintEvent ( wxPaintEvent & evt)
private
214{
215 // depending on your system you may need to look at double-buffered dcs
216 wxBufferedPaintDC dc(this);
217 render(dc);
218}
void render(wxDC &dc)
Definition DropDown.cpp:309

References render().

Referenced by wxDEFINE_EVENT().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ paintNow()

void DropDown::paintNow ( )
private
229{
230 // depending on your system you may need to look at double-buffered dcs
231 //wxClientDC dc(this);
232 //render(dc);
233 Refresh();
234}

Referenced by mouseMove(), mouseReleased(), mouseWheelMoved(), SetBorderColor(), SetCornerRadius(), SetSelection(), SetSelectorBackgroundColor(), SetSelectorBorderColor(), and SetTextColor().

Here is the caller graph for this function:

◆ Popup()

void DropDown::Popup ( wxWindow * focus = nullptr)
override
190{
191#ifdef __WXGTK__
192 if (!mainDropDown && m_widget) {
193 // Data-view cell editors can receive focus before wxGTK infers a
194 // native popup parent, so provide the current toplevel explicitly.
195 GtkWindow *transient_parent = nullptr;
196 for (wxWindow *win = GetParent(); win; win = win->GetParent()) {
197 GtkWidget *widget = static_cast<GtkWidget *>(win->GetHandle());
198 if (!widget)
199 continue;
200 GtkWidget *top = gtk_widget_get_toplevel(widget);
201 if (GTK_IS_WINDOW(top)) {
202 transient_parent = GTK_WINDOW(top);
203 break;
204 }
205 }
206 if (transient_parent)
207 gtk_window_set_transient_for(GTK_WINDOW(m_widget), transient_parent);
208 }
209#endif
210 PopupWindow::Popup(focus);
211}

References mainDropDown.

◆ render()

void DropDown::render ( wxDC & dc)
private
310{
311 if (items.size() == 0) return;
312 int states = state_handler.states();
313 if (subDropDown)
314 states |= subDropDown->state_handler.states();
315 dc.SetPen(wxPen(border_color.colorForStates(states)));
316 dc.SetBrush(wxBrush(StateColor::darkModeColorFor(GetBackgroundColour())));
317 // if (GetWindowStyle() & wxBORDER_NONE)
318 // dc.SetPen(wxNullPen);
319
320 // draw background
321 wxSize size = GetSize();
322 if (radius == 0)
323 dc.DrawRectangle(0, 0, size.x, size.y);
324 else
325 dc.DrawRoundedRectangle(0, 0, size.x, size.y, radius);
326
327 int selected_item = selectedItem();
328 int hover_index = hoverIndex();
329
330 // draw hover rectangle
331 wxRect rcContent = {{0, offset.y}, rowSize};
332 if (hover_item >= 0 && (states & StateColor::Hovered) && (hover_index < 0 || !(items[hover_index].style & DD_ITEM_STYLE_SPLIT_ITEM))) {
333 rcContent.y += rowSize.y * hover_item;
334 if (rcContent.GetBottom() > 0 && rcContent.y < size.y) {
335 if (selected_item == hover_item)
336 dc.SetBrush(wxBrush(selector_background_color.colorForStates(states | StateColor::Checked)));
337 dc.SetPen(wxPen(selector_border_color.colorForStates(states)));
338 rcContent.Deflate(4, 1);
339 dc.DrawRectangle(rcContent);
340 rcContent.Inflate(4, 1);
341 }
342 rcContent.y = offset.y;
343 }
344 // draw checked rectangle
345 if (selected_item >= 0 && (selected_item != hover_item || (states & StateColor::Hovered) == 0)) {
346 rcContent.y += rowSize.y * selected_item;
347 if (rcContent.GetBottom() > 0 && rcContent.y < size.y) {
348 dc.SetBrush(wxBrush(selector_background_color.colorForStates(states | StateColor::Checked)));
349 dc.SetPen(wxPen(selector_background_color.colorForStates(states)));
350 rcContent.Deflate(4, 1);
351 dc.DrawRectangle(rcContent);
352 rcContent.Inflate(4, 1);
353 }
354 rcContent.y = offset.y;
355 }
356 dc.SetBrush(*wxTRANSPARENT_BRUSH);
357 {
358 wxSize offset = (rowSize - textSize) / 2;
359 rcContent.Deflate(0, offset.y);
360 }
361
362 // draw position bar
363 if (rowSize.y * count > size.y) {
364 int height = rowSize.y * count;
365 wxRect rect = {size.x - 6, -offset.y * size.y / height, 4,
366 size.y * size.y / height};
367 dc.SetPen(wxPen(border_color.defaultColor()));
368 dc.SetBrush(wxBrush(*wxLIGHT_GREY));
369 dc.DrawRoundedRectangle(rect, 2);
370 rcContent.width -= 6;
371 }
372
373 // draw check icon
374 rcContent.x += 5;
375 rcContent.width -= 5;
376 if (check_bitmap.bmp().IsOk()) {
377 auto szBmp = check_bitmap.GetBmpSize();
378 if (selected_item >= 0) {
379 wxPoint pt = rcContent.GetLeftTop();
380 pt.y += (rcContent.height - szBmp.y) / 2;
381 pt.y += rowSize.y * selected_item;
382 if (pt.y + szBmp.y > 0 && pt.y < size.y)
383 dc.DrawBitmap(check_bitmap.bmp(), pt);
384 }
385 rcContent.x += szBmp.x + 5;
386 rcContent.width -= szBmp.x + 5;
387 }
388
389 const auto action_column = actionColumn();
390 if (action_column.second > action_column.first)
391 rcContent.width = action_column.first - rcContent.x;
392
393 std::set<wxString> groups;
394 // draw texts & icons
395 int index = 0;
396 for (int i = 0; i < items.size(); ++i) {
397 auto &item = items[i];
398 int states2 = states;
399 if ((item.style & DD_ITEM_STYLE_DISABLED) != 0)
400 states2 &= ~StateColor::Enabled;
401 // Skip by group
402 if (group.IsEmpty()) {
403 if (!item.group_key.IsEmpty()) {
404 if (groups.find(item.group_key) != groups.end())
405 continue;
406 groups.insert(item.group_key);
407 if (!item.group_key.IsEmpty()) {
408 bool disabled = true;
409 for (int j = i + 1; j < items.size(); ++j) {
410 if (items[j].group_key == item.group_key && (items[j].style & DD_ITEM_STYLE_DISABLED) == 0) {
411 disabled = false;
412 break;
413 }
414 }
415 if (!disabled)
416 states2 |= StateColor::Enabled;
417 }
418 }
419 } else {
420 if (item.group_key != group)
421 continue;
422 }
423 bool is_hover = index == hover_item;
424 ++index;
425 if (rcContent.GetBottom() < 0) {
426 rcContent.y += rowSize.y;
427 continue;
428 }
429 if (rcContent.y > size.y) break;
430 wxPoint pt = rcContent.GetLeftTop();
431
432 if (item.style & DD_ITEM_STYLE_SPLIT_ITEM) {
433 _DrawSplitItem(this, dc, item.text, pt, rowSize.GetWidth(), rowSize.GetHeight());
434 rcContent.y += rowSize.GetHeight();
435 continue;
436 }
437
438 auto & icon = item.icon;
439 auto size2 = GetBmpSize(icon);
440 if (iconSize.x > 0) {
441 if (icon.IsOk()) {
442 pt.y += (rcContent.height - size2.y) / 2;
443 dc.DrawBitmap(icon, pt);
444 }
445 pt.x += iconSize.x + 5;
446 pt.y = rcContent.y;
447 } else if (icon.IsOk()) {
448 pt.y += (rcContent.height - size2.y) / 2;
449 dc.DrawBitmap(icon, pt);
450 pt.x += size2.x + 5;
451 pt.y = rcContent.y;
452 }
453 auto text = group.IsEmpty()
454 ? (item.group_key.IsEmpty() ? item.text : item.group_label)
455 : item.text;
456 if (item.action_icon.IsOk()) {
457 auto action_size = GetBmpSize(item.action_icon);
458 wxPoint action_pt(action_column.second - action_size.x - FromDIP(8),
459 rcContent.y + (rcContent.height - action_size.y) / 2);
460 dc.DrawBitmap(item.action_icon, action_pt);
461 }
462
463 if (!text_off && !text.IsEmpty()) {
464 wxSize tSize = dc.GetMultiLineTextExtent(text);
465 if (pt.x + tSize.x > rcContent.GetRight()) {
466 int max_text_width = rcContent.GetRight() - pt.x;
467 if (max_text_width <= 0) {
468 text.clear();
469 } else {
470 if (is_hover && item.tip.IsEmpty())
471 SetToolTip(text);
472 text = wxControl::Ellipsize(text, dc, wxELLIPSIZE_END, max_text_width);
473 }
474 }
475 pt.y += (rcContent.height - textSize.y) / 2;
476 dc.SetFont(GetFont());
477 // Dimmed items stay selectable, so they only borrow the disabled text tone rather
478 // than taking the disabled state itself.
479 const int text_states = (item.style & DD_ITEM_STYLE_DIMMED) ? (states2 & ~StateColor::Enabled) : states2;
480 dc.SetTextForeground(text_color.colorForStates(text_states));
481 dc.DrawText(text, pt);
482 if (group.IsEmpty() && !item.group_key.IsEmpty()) {
483 auto szBmp = arrow_bitmap.GetBmpSize();
484 pt.x = rcContent.GetRight() - szBmp.x - 5;
485 pt.y = rcContent.y + (rcContent.height - szBmp.y) / 2;
486 dc.DrawBitmap(arrow_bitmap.bmp(), pt);
487 }
488 }
489 rcContent.y += rowSize.y;
490 }
491}
static void _DrawSplitItem(const wxWindow *w, wxDC &dc, wxString split_text, wxPoint start_pt, int item_width, int item_height)
Definition DropDown.cpp:260
#define DD_ITEM_STYLE_SPLIT_ITEM
Definition DropDown.hpp:26
#define DD_ITEM_STYLE_DIMMED
Definition DropDown.hpp:28
#define DD_ITEM_STYLE_DISABLED
Definition DropDown.hpp:27
int selectedItem()
Definition DropDown.cpp:523
double radius
Definition DropDown.hpp:63
static wxColour darkModeColorFor(wxColour const &color)
Definition StateColor.cpp:219
@ Enabled
Definition StateColor.hpp:17
coord_t height(const BoundingBox &box)
Definition Arrange.cpp:1185
@ disabled
Definition GLGizmoEmboss.cpp:223

References _DrawSplitItem(), actionColumn(), arrow_bitmap, border_color, check_bitmap, StateColor::Checked, count, StateColor::darkModeColorFor(), DD_ITEM_STYLE_DIMMED, DD_ITEM_STYLE_DISABLED, DD_ITEM_STYLE_SPLIT_ITEM, StateColor::Enabled, GetBmpSize(), group, hover_item, StateColor::Hovered, hoverIndex(), iconSize, items, offset, radius, rowSize, selectedItem(), selector_background_color, selector_border_color, state_handler, style, subDropDown, text_color, text_off, and textSize.

Referenced by paintEvent().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Rescale()

void DropDown::Rescale ( )
178{
179 need_sync = true;
180}

References need_sync.

◆ selectedItem()

int DropDown::selectedItem ( )
private
524{
525 if (selection < 0)
526 return -1;
527 // BUG FIX: Can't take the shortcut if subDropDown exists (which means there are groups)
528 // because the visual position differs from the actual item index when groups are shown
529 if (count == items.size() && subDropDown == nullptr)
530 return selection;
531 auto & sel = items[selection];
532 if (group.IsEmpty() ? !sel.group_key.IsEmpty() : sel.group_key != group)
533 return -1;
534 if (selection == 0)
535 return 0;
536 int index = 0;
537 std::set<wxString> groups;
538 for (size_t i = 0; i < selection; ++i) {
539 auto &item = items[i];
540 // Skip by group
541 if (group.IsEmpty()) {
542 if (!item.group_key.IsEmpty()) {
543 if (groups.find(item.group_key) == groups.end())
544 groups.insert(item.group_key);
545 else
546 continue;
547 }
548 } else {
549 if (item.group_key != group)
550 continue;
551 }
552 ++index;
553 }
554 return index;
555}

References count, group, items, selection, and subDropDown.

Referenced by render().

Here is the caller graph for this function:

◆ sendDropDownActionEvent()

void DropDown::sendDropDownActionEvent ( int index)
private
913{
914 if (index < 0 || index >= int(items.size()) || (items[index].style & DD_ITEM_STYLE_DISABLED))
915 return;
916 wxCommandEvent event(EVT_DROPDOWN_ITEM_ACTION, GetId());
917 event.SetEventObject(this);
918 event.SetInt(index);
919 event.SetString(items[index].text);
920 GetEventHandler()->ProcessEvent(event);
921}

References DD_ITEM_STYLE_DISABLED, and items.

Referenced by mouseReleased().

Here is the caller graph for this function:

◆ sendDropDownEvent()

void DropDown::sendDropDownEvent ( )
private
901{
902 int index = hoverIndex();
903 if (index < 0 || (items[index].style & DD_ITEM_STYLE_DISABLED))
904 return;
905 wxCommandEvent event(wxEVT_COMBOBOX, GetId());
906 event.SetEventObject(this);
907 event.SetInt(index);
908 event.SetString(items[index].text);
909 GetEventHandler()->ProcessEvent(event);
910}

References DD_ITEM_STYLE_DISABLED, hoverIndex(), items, and style.

Referenced by mouseReleased().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetAlignIcon()

void DropDown::SetAlignIcon ( bool align)
175{ align_icon = align; }

References align_icon.

◆ SetBorderColor()

void DropDown::SetBorderColor ( StateColor const & color)
138{
139 border_color = color;
140 state_handler.update_binds();
141 paintNow();
142}

References border_color, paintNow(), and state_handler.

Here is the call graph for this function:

◆ SetCornerRadius()

void DropDown::SetCornerRadius ( double radius)
132{
133 this->radius = radius;
134 paintNow();
135}

References paintNow(), and radius.

Here is the call graph for this function:

◆ SetSelection()

void DropDown::SetSelection ( int n)
106{
107 if (n >= (int) items.size())
108 n = -1;
109 if (selection == n) return;
110 selection = n;
111 if (need_sync) { // for icon Size
112 messureSize();
113 need_sync = true;
114 }
115 if (subDropDown)
116 subDropDown->SetSelection(n);
117 paintNow();
118}

References items, messureSize(), need_sync, paintNow(), selection, and subDropDown.

Here is the call graph for this function:

◆ SetSelectorBackgroundColor()

void DropDown::SetSelectorBackgroundColor ( StateColor const & color)
159{
161 state_handler.update_binds();
162 paintNow();
163}

References paintNow(), selector_background_color, and state_handler.

Here is the call graph for this function:

◆ SetSelectorBorderColor()

void DropDown::SetSelectorBorderColor ( StateColor const & color)
145{
146 selector_border_color = color;
147 state_handler.update_binds();
148 paintNow();
149}

References paintNow(), selector_border_color, and state_handler.

Here is the call graph for this function:

◆ SetTextColor()

void DropDown::SetTextColor ( StateColor const & color)
152{
153 text_color = color;
154 state_handler.update_binds();
155 paintNow();
156}

References paintNow(), state_handler, and text_color.

Here is the call graph for this function:

◆ SetUseContentWidth()

void DropDown::SetUseContentWidth ( bool use,
bool limit_max_content_width = false )
166{
167 if (use_content_width == use)
168 return;
169 use_content_width = use;
171 need_sync = true;
172 messureSize();
173}

References limit_max_content_width, messureSize(), need_sync, and use_content_width.

Referenced by Slic3r::GUI::PlaterPresetComboBox::PlaterPresetComboBox(), Slic3r::GUI::TabPresetComboBox::TabPresetComboBox(), Slic3r::GUI::Choice::BUILD(), Slic3r::GUI::PrinterAgentChoice::BUILD(), and BitmapChoiceRenderer::CreateEditorCtrl().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetValue()

void DropDown::SetValue ( const wxString & value)
126{
127 auto i = std::find_if(items.begin(), items.end(), [&value](Item & item) { return item.text == value; });
128 selection = i == items.end() ? -1 : std::distance(items.begin(), i);
129}
Definition DropDown.hpp:37

References items, and selection.

◆ ShouldDismissOnTopWindowDeactivate()

bool DropDown::ShouldDismissOnTopWindowDeactivate ( )
overrideprotectedvirtual

Reimplemented from PopupWindow.

931{
932 // On Wayland, mapping a chained xdg_popup with grab makes the parent
933 // toplevel inactive, which would otherwise cascade-dismiss the whole
934 // chain. Skip when our chain peer is shown.
935 return !((mainDropDown && mainDropDown->IsShown()) ||
936 (subDropDown && subDropDown->IsShown()));
937}

References mainDropDown, and subDropDown.

◆ ComboBox

friend class ComboBox
friend

References ComboBox.

Referenced by ComboBox.

Member Data Documentation

◆ actionIconWidth

int DropDown::actionIconWidth = 0
private

Referenced by actionColumn(), and messureSize().

◆ align_icon

bool DropDown::align_icon = false
private

Referenced by messureSize(), and SetAlignIcon().

◆ arrow_bitmap

ScalableBitmap DropDown::arrow_bitmap
private

Referenced by Create(), messureSize(), and render().

◆ border_color

StateColor DropDown::border_color
private

◆ check_bitmap

ScalableBitmap DropDown::check_bitmap
private

Referenced by Create(), messureSize(), and render().

◆ count

size_t DropDown::count = 0
private

◆ dismissTime

boost::posix_time::ptime DropDown::dismissTime
private

Referenced by HasDismissLongTime(), and OnDismiss().

◆ dragStart

wxPoint DropDown::dragStart
private

Referenced by mouseDown(), mouseMove(), and mouseReleased().

◆ group

wxString DropDown::group
private

◆ hover_item

int DropDown::hover_item = -1
private

◆ iconSize

wxSize DropDown::iconSize
private

Referenced by messureSize(), and render().

◆ items

◆ limit_max_content_width

bool DropDown::limit_max_content_width = false
private

Referenced by messureSize(), and SetUseContentWidth().

◆ mainDropDown

DropDown* DropDown::mainDropDown { nullptr }
private

◆ need_sync

bool DropDown::need_sync = false
private

◆ offset

wxPoint DropDown::offset
private

◆ pressedDown

bool DropDown::pressedDown = false
private

Referenced by mouseDown(), mouseMove(), and mouseReleased().

◆ radius

double DropDown::radius = 0
private

Referenced by render(), and SetCornerRadius().

◆ rowSize

wxSize DropDown::rowSize
private

◆ selection

int DropDown::selection = -1
private

◆ selector_background_color

StateColor DropDown::selector_background_color
private

◆ selector_border_color

StateColor DropDown::selector_border_color
private

◆ state_handler

◆ subDropDown

◆ text_color

StateColor DropDown::text_color
private

Referenced by DropDown(), Create(), render(), and SetTextColor().

◆ text_off

bool DropDown::text_off = false
private

Referenced by Create(), messureSize(), and render().

◆ textSize

wxSize DropDown::textSize
private

Referenced by messureSize(), and render().

◆ use_content_width

bool DropDown::use_content_width = false
private

The documentation for this class was generated from the following files:
  • /home/runner/work/OrcaSlicer/OrcaSlicer/src/slic3r/GUI/Widgets/DropDown.hpp
  • /home/runner/work/OrcaSlicer/OrcaSlicer/src/slic3r/GUI/Widgets/DropDown.cpp