diff options
author | crupest <crupest@outlook.com> | 2022-02-15 21:34:21 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2022-02-15 21:34:21 +0800 |
commit | 24aaa8fbc5da8370506402facdb8ccaf563454e5 (patch) | |
tree | 0075bfbee729b1ccc57966bef97bda4be09cbde9 | |
parent | fa6e9a419f688df12a57199aa3b4dce10cc6fd49 (diff) | |
download | cru-24aaa8fbc5da8370506402facdb8ccaf563454e5.tar.gz cru-24aaa8fbc5da8370506402facdb8ccaf563454e5.tar.bz2 cru-24aaa8fbc5da8370506402facdb8ccaf563454e5.zip |
...
-rw-r--r-- | demos/main/main.cpp | 20 | ||||
-rw-r--r-- | include/cru/ui/components/PopupButton.h | 3 | ||||
-rw-r--r-- | include/cru/ui/components/Select.h | 34 | ||||
-rw-r--r-- | include/cru/ui/helper/ClickDetector.h | 3 | ||||
-rw-r--r-- | include/cru/ui/render/LayoutRenderObject.h | 2 | ||||
-rw-r--r-- | src/osx/gui/Window.mm | 16 | ||||
-rw-r--r-- | src/ui/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/ui/components/Menu.cpp | 6 | ||||
-rw-r--r-- | src/ui/components/PopupButton.cpp | 2 | ||||
-rw-r--r-- | src/ui/components/Select.cpp | 31 | ||||
-rw-r--r-- | src/ui/helper/ClickDetector.cpp | 11 |
11 files changed, 105 insertions, 25 deletions
diff --git a/demos/main/main.cpp b/demos/main/main.cpp index 2e8188a1..67d3ddad 100644 --- a/demos/main/main.cpp +++ b/demos/main/main.cpp @@ -4,6 +4,7 @@ #include "cru/platform/gui/Window.h" #include "cru/ui/Base.h" #include "cru/ui/components/Menu.h" +#include "cru/ui/components/PopupButton.h" #include "cru/ui/controls/Button.h" #include "cru/ui/controls/FlexLayout.h" #include "cru/ui/controls/TextBlock.h" @@ -14,6 +15,7 @@ using cru::platform::gui::IUiApplication; using namespace cru::ui::controls; +using namespace cru::ui::components; int main() { std::unique_ptr<IUiApplication> application( @@ -54,20 +56,10 @@ int main() { text_box.SetMultiLine(true); flex_layout.AddChild(&text_box); - auto popup_menu = std::make_unique<cru::ui::components::PopupMenu>(&window); - popup_menu->GetMenu()->AddTextItem(u"Item 1", [] {}); - popup_menu->GetMenu()->AddTextItem(u"Item 2000", [] {}); - - window.MouseDownEvent()->Bubble()->AddHandler( - [&window, &popup_menu](cru::ui::events::MouseButtonEventArgs& e) { - if (e.GetButton() == cru::ui::mouse_buttons::right) { - popup_menu->SetPosition(e.GetPoint() + window.GetWindowHost() - ->GetNativeWindow() - ->GetClientRect() - .GetLeftTop()); - popup_menu->Show(); - } - }); + PopupMenuTextButton popup_menu_text_button; + popup_menu_text_button.SetButtonText(u"Popup Menu Button"); + popup_menu_text_button.SetMenuItems({u"Item 1", u"Item 2", u"Item 3"}); + flex_layout.AddChild(popup_menu_text_button.GetRootControl()); window.GetWindowHost()->GetNativeWindow()->SetVisibility( cru::platform::gui::WindowVisibilityType::Show); diff --git a/include/cru/ui/components/PopupButton.h b/include/cru/ui/components/PopupButton.h index f8c545bf..38109fbe 100644 --- a/include/cru/ui/components/PopupButton.h +++ b/include/cru/ui/components/PopupButton.h @@ -1,12 +1,13 @@ #pragma once #include "Component.h" +#include "cru/ui/Base.h" #include "cru/ui/components/Menu.h" #include "cru/ui/controls/Button.h" #include "cru/ui/controls/Popup.h" #include "cru/ui/controls/TextBlock.h" namespace cru::ui::components { -class PopupMenuTextButton : public Component { +class CRU_UI_API PopupMenuTextButton : public Component { public: PopupMenuTextButton(); ~PopupMenuTextButton() override; diff --git a/include/cru/ui/components/Select.h b/include/cru/ui/components/Select.h new file mode 100644 index 00000000..cc658092 --- /dev/null +++ b/include/cru/ui/components/Select.h @@ -0,0 +1,34 @@ +#pragma once +#include "Component.h" +#include "Menu.h" +#include "cru/ui/controls/Button.h" +#include "cru/ui/controls/TextBlock.h" + +namespace cru::ui::components { +class CRU_UI_API Select : public Component { + public: + Select(); + ~Select() override; + + public: + ui::controls::Control* GetRootControl() override { return &button_; } + + std::vector<String> GetItems() { return items_; } + void SetItems(std::vector<String> items); + + Index GetSelectedIndex() { return selected_index_; } + void SetSelectedIndex(Index index); + + IEvent<Index>* ItemSelectedEvent() { return &item_selected_event_; } + + private: + Index selected_index_; + std::vector<String> items_; + + ui::controls::Button button_; + ui::controls::TextBlock button_text_; + PopupMenu popup_menu_; + + Event<Index> item_selected_event_; +}; +} // namespace cru::ui::components diff --git a/include/cru/ui/helper/ClickDetector.h b/include/cru/ui/helper/ClickDetector.h index 1cfb26bc..0d74b9c0 100644 --- a/include/cru/ui/helper/ClickDetector.h +++ b/include/cru/ui/helper/ClickDetector.h @@ -4,6 +4,8 @@ #include "cru/common/Event.h" namespace cru::ui::helper { +class ClickDetector; + class CRU_UI_API ClickEventArgs : Object { public: ClickEventArgs(controls::Control* sender, const Point& down_point, @@ -20,6 +22,7 @@ class CRU_UI_API ClickEventArgs : Object { controls::Control* GetSender() const { return sender_; } Point GetDownPoint() const { return down_point_; } + Point GetDownPointOfScreen() const; Point GetUpPoint() const { return up_point_; } MouseButton GetButton() const { return button_; } diff --git a/include/cru/ui/render/LayoutRenderObject.h b/include/cru/ui/render/LayoutRenderObject.h index 8fec3ada..11df0449 100644 --- a/include/cru/ui/render/LayoutRenderObject.h +++ b/include/cru/ui/render/LayoutRenderObject.h @@ -39,7 +39,7 @@ class LayoutRenderObject : public RenderObject { } void RemoveChild(Index position) { - Expects(position > 0 && position < GetChildCount()); + Expects(position >= 0 && position < GetChildCount()); children_[position].render_object->SetParent(nullptr); children_.erase(children_.begin() + position); InvalidateLayout(); diff --git a/src/osx/gui/Window.mm b/src/osx/gui/Window.mm index 4f2937a3..e9de3ac7 100644 --- a/src/osx/gui/Window.mm +++ b/src/osx/gui/Window.mm @@ -168,14 +168,14 @@ Point OsxWindowPrivate::TransformMousePoint(const Point& point) { void OsxWindowPrivate::CreateWindow() { Expects(!window_); - NSRect content_rect = Convert(content_rect_); NSWindowStyleMask style_mask = CalcWindowStyleMask(style_flag_); - - auto cr = content_rect; - cr.origin.y = GetScreenSize().height - content_rect.origin.y - content_rect.size.height; - window_ = [[CruWindow alloc] init:this contentRect:cr style:style_mask]; + window_ = [[CruWindow alloc] init:this + contentRect:{0, 0, content_rect_.width, content_rect_.height} + style:style_mask]; Ensures(window_); + osx_window_->SetClientRect(content_rect_); + [window_ setDelegate:window_delegate_]; if (parent_) { @@ -193,7 +193,7 @@ void OsxWindowPrivate::CreateWindow() { [window_ setTitle:(NSString*)title_str]; CFRelease(title_str); - draw_layer_ = CreateLayer(content_rect.size); + draw_layer_ = CreateLayer(Convert(content_rect_.GetSize())); create_event_.Raise(nullptr); @@ -438,6 +438,10 @@ cru::platform::gui::KeyModifier GetKeyModifier(NSEvent* event) { return self; } +- (BOOL)canBecomeMainWindow { + return YES; +} + - (BOOL)canBecomeKeyWindow { return YES; } diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index 9ad0df08..56205db0 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -3,6 +3,8 @@ add_library(cru_ui SHARED ThemeManager.cpp components/Component.cpp components/Menu.cpp + components/PopupButton.cpp + components/Select.cpp controls/Button.cpp controls/CheckBox.cpp controls/Container.cpp diff --git a/src/ui/components/Menu.cpp b/src/ui/components/Menu.cpp index 74909c85..ae00a2b2 100644 --- a/src/ui/components/Menu.cpp +++ b/src/ui/components/Menu.cpp @@ -92,8 +92,10 @@ void PopupMenu::SetPosition(const Point& position) { void PopupMenu::Show() { popup_.GetWindowHost()->RelayoutWithSize(Size::Infinate(), true); - popup_.GetWindowHost()->GetNativeWindow()->SetVisibility( - platform::gui::WindowVisibilityType::Show); + auto native_window = popup_.GetWindowHost()->GetNativeWindow(); + native_window->SetVisibility(platform::gui::WindowVisibilityType::Show); + native_window->RequestFocus(); + native_window->SetToForeground(); } void PopupMenu::Close() { popup_.GetWindowHost()->GetNativeWindow()->Close(); } diff --git a/src/ui/components/PopupButton.cpp b/src/ui/components/PopupButton.cpp index 606d5fd8..8eed7c09 100644 --- a/src/ui/components/PopupButton.cpp +++ b/src/ui/components/PopupButton.cpp @@ -7,7 +7,7 @@ namespace cru::ui::components { PopupMenuTextButton::PopupMenuTextButton() : popup_menu_(&button_) { button_.SetChild(&button_text_); button_.ClickEvent()->AddHandler([this](const helper::ClickEventArgs& args) { - popup_menu_.SetPosition(args.GetDownPoint()); + popup_menu_.SetPosition(args.GetDownPointOfScreen()); popup_menu_.Show(); }); } diff --git a/src/ui/components/Select.cpp b/src/ui/components/Select.cpp new file mode 100644 index 00000000..9f9fbfae --- /dev/null +++ b/src/ui/components/Select.cpp @@ -0,0 +1,31 @@ +#include "cru/ui/components/Select.h" + +namespace cru::ui::components { +Select::Select() { + button_.SetChild(&button_text_); + button_.ClickEvent()->AddHandler([this](const helper::ClickEventArgs& args) { + popup_menu_.SetPosition(args.GetDownPoint()); + popup_menu_.Show(); + }); +} + +Select::~Select() { button_.RemoveFromParent(); } + +void Select::SetItems(std::vector<String> items) { + popup_menu_.GetMenu()->ClearItems(); + for (Index i = 0; i < items.size(); i++) { + popup_menu_.GetMenu()->AddTextItem(std::move(items[i]), + [this, i] { SetSelectedIndex(i); }); + } +} + +void Select::SetSelectedIndex(Index index) { + selected_index_ = index; + if (index >= 0 && index < items_.size()) { + button_text_.SetText(items_[index]); + } else { + button_text_.SetText({}); + } + item_selected_event_.Raise(index); +} +} // namespace cru::ui::components diff --git a/src/ui/helper/ClickDetector.cpp b/src/ui/helper/ClickDetector.cpp index 981e9e04..a10133e9 100644 --- a/src/ui/helper/ClickDetector.cpp +++ b/src/ui/helper/ClickDetector.cpp @@ -3,10 +3,21 @@ #include "cru/common/Logger.h" #include "cru/ui/DebugFlags.h" #include "cru/ui/controls/Control.h" +#include "cru/ui/host/WindowHost.h" #include <optional> namespace cru::ui::helper { +Point ClickEventArgs::GetDownPointOfScreen() const { + auto window_host = sender_->GetWindowHost(); + if (window_host != nullptr) { + auto window = window_host->GetNativeWindow(); + return down_point_ + window->GetClientRect().GetLeftTop(); + } else { + return down_point_; + } +} + ClickDetector::ClickDetector(controls::Control* control) { Expects(control); control_ = control; |