aboutsummaryrefslogtreecommitdiff
path: root/src/ui/controls/popup_menu.cpp
blob: 88ea8f177a01eca8ff3ad7df4620b61e47dad33e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include "popup_menu.hpp"

#include "ui/window.hpp"
#include "text_block.hpp"
#include "list_item.hpp"
#include "linear_layout.hpp"
#include "ui/events/ui_event.hpp"

namespace cru::ui::controls
{
    Window* CreatePopupMenu(const Point& anchor, const std::vector<MenuItemInfo>& items, Window* parent)
    {
        const auto popup = Window::CreatePopup(parent);

        popup->lose_focus_event.AddHandler([popup](events::FocusChangeEventArgs& args)
        {
            if (args.IsWindow())
                popup->Close();
        });

        const auto create_menu_item = [popup](const String& text, const std::function<void()>& action) -> ListItem*
        {
            auto text_block = TextBlock::Create(text);
            text_block->GetLayoutParams()->width.alignment = Alignment::Start;

            auto list_item = CreateWithLayout<ListItem>(
                LayoutSideParams::Stretch(Alignment::Center),
                LayoutSideParams::Content(Alignment::Start),
                ControlList{ text_block }
            );

            list_item->mouse_click_event.AddHandler([popup, action](events::MouseButtonEventArgs& args)
            {
                if (args.GetMouseButton() == MouseButton::Left)
                {
                    action();
                    popup->Close();
                }
            });

            return list_item;
        };

        const auto menu = LinearLayout::Create(LinearLayout::Orientation::Vertical);

        menu->SetBordered(true);

        for (const auto& item : items)
            menu->AddChild(create_menu_item(item.first, item.second));

        popup->AddChild(menu);

        popup->SetSizeFitContent();
        popup->SetWindowPosition(anchor);

        return popup;
    }
}