diff options
author | crupest <crupest@outlook.com> | 2018-11-11 17:38:05 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2018-11-11 17:38:05 +0800 |
commit | 61b44c223df9c3d2a6daec85f693a2b9a406f5c9 (patch) | |
tree | 2594670863ef855222cb5af1798807f2c263ab66 /src/ui/controls | |
parent | 3cc588ade5ac08e53c406cea6bfcaaafac4346cf (diff) | |
download | cru-61b44c223df9c3d2a6daec85f693a2b9a406f5c9.tar.gz cru-61b44c223df9c3d2a6daec85f693a2b9a406f5c9.tar.bz2 cru-61b44c223df9c3d2a6daec85f693a2b9a406f5c9.zip |
Add popup menu. Fix a potential bug in window destroy.
Diffstat (limited to 'src/ui/controls')
-rw-r--r-- | src/ui/controls/popup_menu.cpp | 58 | ||||
-rw-r--r-- | src/ui/controls/popup_menu.hpp | 20 |
2 files changed, 78 insertions, 0 deletions
diff --git a/src/ui/controls/popup_menu.cpp b/src/ui/controls/popup_menu.cpp new file mode 100644 index 00000000..88ea8f17 --- /dev/null +++ b/src/ui/controls/popup_menu.cpp @@ -0,0 +1,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; + } +} diff --git a/src/ui/controls/popup_menu.hpp b/src/ui/controls/popup_menu.hpp new file mode 100644 index 00000000..d47e3eb6 --- /dev/null +++ b/src/ui/controls/popup_menu.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include <vector> +#include <utility> +#include <functional> + +#include "base.hpp" +#include "ui/ui_base.hpp" + +namespace cru::ui +{ + class Window; +} + +namespace cru::ui::controls +{ + using MenuItemInfo = std::pair<String, std::function<void()>>; + + Window* CreatePopupMenu(const Point& anchor, const std::vector<MenuItemInfo>& items, Window* parent = nullptr); +} |