aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--demos/main/main.cpp20
-rw-r--r--include/cru/ui/components/PopupButton.h3
-rw-r--r--include/cru/ui/components/Select.h34
-rw-r--r--include/cru/ui/helper/ClickDetector.h3
-rw-r--r--include/cru/ui/render/LayoutRenderObject.h2
-rw-r--r--src/osx/gui/Window.mm16
-rw-r--r--src/ui/CMakeLists.txt2
-rw-r--r--src/ui/components/Menu.cpp6
-rw-r--r--src/ui/components/PopupButton.cpp2
-rw-r--r--src/ui/components/Select.cpp31
-rw-r--r--src/ui/helper/ClickDetector.cpp11
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;