diff options
Diffstat (limited to 'CruUI')
-rw-r--r-- | CruUI/application.cpp | 4 | ||||
-rw-r--r-- | CruUI/application.h | 11 | ||||
-rw-r--r-- | CruUI/main.cpp | 25 | ||||
-rw-r--r-- | CruUI/ui/control.cpp | 42 | ||||
-rw-r--r-- | CruUI/ui/controls/linear_layout.cpp | 60 | ||||
-rw-r--r-- | CruUI/ui/controls/text_block.cpp | 6 | ||||
-rw-r--r-- | CruUI/ui/controls/toggle_button.cpp | 1 | ||||
-rw-r--r-- | CruUI/ui/layout_base.cpp | 2 | ||||
-rw-r--r-- | CruUI/ui/layout_base.h | 25 | ||||
-rw-r--r-- | CruUI/ui/ui_base.cpp | 2 | ||||
-rw-r--r-- | CruUI/ui/ui_base.h | 26 |
11 files changed, 152 insertions, 52 deletions
diff --git a/CruUI/application.cpp b/CruUI/application.cpp index 78b44d7e..120fffa6 100644 --- a/CruUI/application.cpp +++ b/CruUI/application.cpp @@ -100,6 +100,10 @@ namespace cru { animation_manager_ = std::make_unique<ui::animations::details::AnimationManager>(); god_window_ = std::make_unique<GodWindow>(this); + +#ifdef CRU_DEBUG + debug_border_brush_ = graph::CreateSolidBrush(D2D1::ColorF(D2D1::ColorF::Crimson)); +#endif } Application::~Application() diff --git a/CruUI/application.h b/CruUI/application.h index fe7422d3..1c98b906 100644 --- a/CruUI/application.h +++ b/CruUI/application.h @@ -101,6 +101,13 @@ namespace cru return god_window_.get(); } +#ifdef CRU_DEBUG + Microsoft::WRL::ComPtr<ID2D1Brush> GetDebugBorderBrush() const + { + return debug_border_brush_; + } +#endif + private: HINSTANCE h_instance_; @@ -110,6 +117,10 @@ namespace cru std::unique_ptr<ui::animations::details::AnimationManager> animation_manager_; std::unique_ptr<GodWindow> god_window_; + +#ifdef CRU_DEBUG + Microsoft::WRL::ComPtr<ID2D1Brush> debug_border_brush_; +#endif }; diff --git a/CruUI/main.cpp b/CruUI/main.cpp index 8e7a8672..e8dc60d6 100644 --- a/CruUI/main.cpp +++ b/CruUI/main.cpp @@ -5,8 +5,11 @@ #include "ui/controls/toggle_button.h" +using cru::String; using cru::Application; using cru::ui::Window; +using cru::ui::MeasureMode; +using cru::ui::MeasureLength; using cru::ui::controls::LinearLayout; using cru::ui::controls::TextBlock; using cru::ui::controls::ToggleButton; @@ -70,16 +73,25 @@ int APIENTRY wWinMain( const auto layout = LinearLayout::Create(); - layout->GetLayoutParams()->width.mode = cru::ui::MeasureMode::Stretch; + layout->GetLayoutParams()->width.mode = MeasureMode::Stretch; layout->mouse_click_event.AddHandler([layout](cru::ui::events::MouseButtonEventArgs& args) { - layout->AddChild(TextBlock::Create(L"Layout is clicked!")); + if (args.GetSender() == args.GetOriginalSender()) + layout->AddChild(TextBlock::Create(L"Layout is clicked!")); }); layout->AddChild(ToggleButton::Create()); - const auto text_block = TextBlock::Create(L"Hello World!!!"); + auto&& create_text_block = [](const String& text, const MeasureLength& width = MeasureLength::Content(), const MeasureLength& height = MeasureLength::Content()) + { + const auto text_block = TextBlock::Create(text); + text_block->GetLayoutParams()->width = width; + text_block->GetLayoutParams()->height = height; + return text_block; + }; + + const auto text_block = create_text_block(L"Hello World!!!", MeasureLength::Exactly(200), MeasureLength::Exactly(50)); text_block->mouse_click_event.AddHandler([layout](cru::ui::events::MouseButtonEventArgs& args) { @@ -87,10 +99,11 @@ int APIENTRY wWinMain( }); layout->AddChild(text_block); - layout->AddChild(TextBlock::Create(L"This is a very very very very very long sentence!!!")); - layout->AddChild(TextBlock::Create(L"By crupest!!!")); + layout->AddChild(create_text_block(L"This is a very very very very very long sentence!!!", MeasureLength::Stretch(), MeasureLength::Stretch())); + layout->AddChild(TextBlock::Create(L"This is a little short sentence!!!")); + layout->AddChild(create_text_block(L"By crupest!!!", MeasureLength::Stretch(), MeasureLength::Stretch())); + - window.AddChild(layout); window.Show(); diff --git a/CruUI/ui/control.cpp b/CruUI/ui/control.cpp index adf429b1..e2f63d02 100644 --- a/CruUI/ui/control.cpp +++ b/CruUI/ui/control.cpp @@ -17,18 +17,18 @@ namespace cru { window_(nullptr), parent_(nullptr), children_(), - old_position_(Point::zero), - position_(Point::zero), - size_(Size::zero), + old_position_(), + position_(), + size_(), position_cache_(), is_mouse_inside_(false), is_mouse_leave_{ { MouseButton::Left, true }, { MouseButton::Middle, true }, { MouseButton::Right, true } - }, + }, layout_params_(new BasicLayoutParams()), - desired_size_(Size::zero) + desired_size_() { } @@ -187,7 +187,7 @@ namespace cru { const auto old_size = size_; size_ = size; SizeChangedEventArgs args(this, this, old_size, size); - OnSizeChangedInternal(args); + RaiseSizeChangedEvent(args); if (auto window = GetWindow()) window->Repaint(); } @@ -321,7 +321,11 @@ namespace cru { void Control::OnDraw(ID2D1DeviceContext * device_context) { - +#ifdef CRU_DEBUG + auto brush = Application::GetInstance()->GetDebugBorderBrush(); + const auto size = GetSize(); + device_context->DrawRectangle(D2D1::RectF(0, 0, size.width, size.height), brush.Get()); +#endif } void Control::OnPositionChanged(PositionChangedEventArgs & args) @@ -350,7 +354,7 @@ namespace cru { position_changed_event.Raise(args); } - void Control::OnSizeChangedInternal(SizeChangedEventArgs& args) + void Control::RaiseSizeChangedEvent(SizeChangedEventArgs& args) { OnSizeChangedCore(args); OnSizeChanged(args); @@ -407,7 +411,7 @@ namespace cru { void Control::OnMouseUpCore(MouseButtonEventArgs & args) { if (!is_mouse_leave_[args.GetMouseButton()]) - OnMouseClickInternal(args); + RaiseMouseClickEvent(args); } void Control::OnMouseClickCore(MouseButtonEventArgs& args) @@ -415,42 +419,42 @@ namespace cru { } - void Control::OnMouseEnterInternal(MouseEventArgs& args) + void Control::RaiseMouseEnterEvent(MouseEventArgs& args) { OnMouseEnterCore(args); OnMouseEnter(args); mouse_enter_event.Raise(args); } - void Control::OnMouseLeaveInternal(MouseEventArgs& args) + void Control::RaiseMouseLeaveEvent(MouseEventArgs& args) { OnMouseLeaveCore(args); OnMouseLeave(args); mouse_leave_event.Raise(args); } - void Control::OnMouseMoveInternal(MouseEventArgs& args) + void Control::RaiseMouseMoveEvent(MouseEventArgs& args) { OnMouseMoveCore(args); OnMouseMove(args); mouse_move_event.Raise(args); } - void Control::OnMouseDownInternal(MouseButtonEventArgs& args) + void Control::RaiseMouseDownEvent(MouseButtonEventArgs& args) { OnMouseDownCore(args); OnMouseDown(args); mouse_down_event.Raise(args); } - void Control::OnMouseUpInternal(MouseButtonEventArgs& args) + void Control::RaiseMouseUpEvent(MouseButtonEventArgs& args) { OnMouseUpCore(args); OnMouseUp(args); mouse_up_event.Raise(args); } - void Control::OnMouseClickInternal(MouseButtonEventArgs& args) + void Control::RaiseMouseClickEvent(MouseButtonEventArgs& args) { OnMouseClickCore(args); OnMouseClick(args); @@ -477,14 +481,14 @@ namespace cru { } - void Control::OnGetFocusInternal(FocusChangeEventArgs& args) + void Control::RaiseGetFocusEvent(FocusChangeEventArgs& args) { OnGetFocusCore(args); OnGetFocus(args); get_focus_event.Raise(args); } - void Control::OnLoseFocusInternal(FocusChangeEventArgs& args) + void Control::RaiseLoseFocusEvent(FocusChangeEventArgs& args) { OnLoseFocusCore(args); OnLoseFocus(args); @@ -519,7 +523,7 @@ namespace cru { const Size size_for_children(get_available_length_for_child(layout_params->width, available_size.width), get_available_length_for_child(layout_params->height, available_size.height)); - auto max_child_size = Size::zero; + auto max_child_size = Size::Zero(); ForeachChild([&](Control* control) { control->Measure(size_for_children); @@ -554,7 +558,7 @@ namespace cru { { ForeachChild([](Control* control) { - control->Layout(Rect(Point::zero, control->GetDesiredSize())); + control->Layout(Rect(Point::Zero(), control->GetDesiredSize())); }); } diff --git a/CruUI/ui/controls/linear_layout.cpp b/CruUI/ui/controls/linear_layout.cpp index 33a7855f..5f55ba0a 100644 --- a/CruUI/ui/controls/linear_layout.cpp +++ b/CruUI/ui/controls/linear_layout.cpp @@ -40,23 +40,61 @@ namespace cru::ui::controls auto rest_available_size_for_children = total_available_size_for_children; - ForeachChild([this, &rest_available_size_for_children](Control* const control) + std::list<Control*> stretch_control_list; + + // First measure Content and Exactly and count Stretch. + if (orientation_ == Orientation::Horizontal) + ForeachChild([&rest_available_size_for_children, &stretch_control_list](Control* const control) { - control->Measure(rest_available_size_for_children); - if (orientation_ == Orientation::Horizontal) + const auto mode = control->GetLayoutParams()->width.mode; + if (mode == MeasureMode::Content || mode == MeasureMode::Exactly) { + control->Measure(rest_available_size_for_children); rest_available_size_for_children.width -= control->GetDesiredSize().width; if (rest_available_size_for_children.width < 0) rest_available_size_for_children.width = 0; } else + stretch_control_list.push_back(control); + }); + else + ForeachChild([&rest_available_size_for_children, &stretch_control_list](Control* const control) + { + const auto mode = control->GetLayoutParams()->height.mode; + if (mode == MeasureMode::Content || mode == MeasureMode::Exactly) { + control->Measure(rest_available_size_for_children); rest_available_size_for_children.height -= control->GetDesiredSize().height; if (rest_available_size_for_children.height < 0) rest_available_size_for_children.height = 0; } + else + stretch_control_list.push_back(control); }); + if (orientation_ == Orientation::Horizontal) + { + const auto available_width = rest_available_size_for_children.width / stretch_control_list.size(); + for (const auto control : stretch_control_list) + { + control->Measure(Size(available_width, rest_available_size_for_children.height)); + rest_available_size_for_children.width -= control->GetDesiredSize().width; + if (rest_available_size_for_children.width < 0) + rest_available_size_for_children.width = 0; + } + } + else + { + const auto available_height = rest_available_size_for_children.height / stretch_control_list.size(); + for (const auto control : stretch_control_list) + { + control->Measure(Size(rest_available_size_for_children.width, available_height)); + rest_available_size_for_children.height -= control->GetDesiredSize().height; + if (rest_available_size_for_children.height < 0) + rest_available_size_for_children.height = 0; + } + } + auto actual_size_for_children = total_available_size_for_children; if (orientation_ == Orientation::Horizontal) actual_size_for_children.width -= rest_available_size_for_children.width; @@ -85,16 +123,20 @@ namespace cru::ui::controls void LinearLayout::OnLayout(const Rect& rect) { - auto current_anchor = Point::zero; - ForeachChild([this, ¤t_anchor](Control* control) + float current_anchor_length = 0; + ForeachChild([this, ¤t_anchor_length, rect](Control* control) { const auto size = control->GetDesiredSize(); - control->Layout(Rect(current_anchor, size)); - if (orientation_ == Orientation::Horizontal) - current_anchor.x += size.width; + { + control->Layout(Rect(Point(current_anchor_length, (rect.height - size.height) / 2), size)); + current_anchor_length += size.width; + } else - current_anchor.y += size.height; + { + control->Layout(Rect(Point((rect.width - size.width) / 2, current_anchor_length), size)); + current_anchor_length += size.height; + } }); } } diff --git a/CruUI/ui/controls/text_block.cpp b/CruUI/ui/controls/text_block.cpp index 294c456b..8921198b 100644 --- a/CruUI/ui/controls/text_block.cpp +++ b/CruUI/ui/controls/text_block.cpp @@ -76,6 +76,7 @@ namespace cru void TextBlock::OnDraw(ID2D1DeviceContext* device_context) { + Control::OnDraw(device_context); if (text_layout_ != nullptr) { if (selected_range_.has_value()) @@ -179,7 +180,7 @@ namespace cru Size TextBlock::OnMeasure(const Size& available_size) { if (text_.empty()) - return Size::zero; + return Size::Zero(); const auto layout_params = GetLayoutParams(); @@ -252,6 +253,9 @@ namespace cru 24.0, L"zh-cn", &text_format_ )); + + ThrowIfFailed(text_format_->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER)); + ThrowIfFailed(text_format_->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER)); } void TextBlock::RecreateTextLayout() diff --git a/CruUI/ui/controls/toggle_button.cpp b/CruUI/ui/controls/toggle_button.cpp index 001f46eb..94685b6e 100644 --- a/CruUI/ui/controls/toggle_button.cpp +++ b/CruUI/ui/controls/toggle_button.cpp @@ -85,6 +85,7 @@ namespace cru::ui::controls void ToggleButton::OnDraw(ID2D1DeviceContext* device_context) { + Control::OnDraw(device_context); const auto size = GetSize(); graph::WithTransform(device_context, D2D1::Matrix3x2F::Translation(size.width / 2, size.height / 2), [this](ID2D1DeviceContext* device_context) { diff --git a/CruUI/ui/layout_base.cpp b/CruUI/ui/layout_base.cpp index f04d1fe8..a589d2ea 100644 --- a/CruUI/ui/layout_base.cpp +++ b/CruUI/ui/layout_base.cpp @@ -52,7 +52,7 @@ namespace cru::ui void LayoutManager::RefreshControlPositionCache(Control * control) { - auto point = Point::zero; + auto point = Point::Zero(); auto parent = control; while ((parent = parent->GetParent())) { const auto p = parent->GetPositionRelative(); diff --git a/CruUI/ui/layout_base.h b/CruUI/ui/layout_base.h index 08f36769..25a6774c 100644 --- a/CruUI/ui/layout_base.h +++ b/CruUI/ui/layout_base.h @@ -22,13 +22,30 @@ namespace cru struct MeasureLength final { - explicit MeasureLength(const float length = 0.0, const MeasureMode mode = MeasureMode::Content) + constexpr static MeasureLength Exactly(const float length) + { + return MeasureLength(MeasureMode::Exactly, length); + } + + constexpr static MeasureLength Content() + { + return MeasureLength(MeasureMode::Content, 0); + } + + constexpr static MeasureLength Stretch() + { + return MeasureLength(MeasureMode::Stretch, 0); + } + + constexpr MeasureLength() = default; + + constexpr explicit MeasureLength(const MeasureMode mode, const float length) : length(length), mode(mode) { } - bool Validate() const + constexpr bool Validate() const { if (mode == MeasureMode::Exactly && length < 0.0) { @@ -40,8 +57,8 @@ namespace cru return true; } - float length; - MeasureMode mode; + float length = 0.0; + MeasureMode mode = MeasureMode::Content; }; struct BasicLayoutParams diff --git a/CruUI/ui/ui_base.cpp b/CruUI/ui/ui_base.cpp index b30f65ab..550432e4 100644 --- a/CruUI/ui/ui_base.cpp +++ b/CruUI/ui/ui_base.cpp @@ -2,7 +2,5 @@ namespace cru { namespace ui { - const Point Point::zero(0, 0); - const Size Size::zero(0, 0); } } diff --git a/CruUI/ui/ui_base.h b/CruUI/ui/ui_base.h index 8ce82cdf..21d41c6a 100644 --- a/CruUI/ui/ui_base.h +++ b/CruUI/ui/ui_base.h @@ -7,13 +7,16 @@ namespace cru { struct Point { - static const Point zero; + constexpr static Point Zero() + { + return Point(0, 0); + } - Point() = default; - Point(const float x, const float y) : x(x), y(y) { } + constexpr Point() = default; + constexpr Point(const float x, const float y) : x(x), y(y) { } - float x; - float y; + float x = 0; + float y = 0; }; inline bool operator==(const Point& left, const Point& right) @@ -28,13 +31,16 @@ namespace cru struct Size { - static const Size zero; + constexpr static Size Zero() + { + return Size(0, 0); + } - Size() = default; - Size(const float width, const float height) : width(width), height(height) { } + constexpr Size() = default; + constexpr Size(const float width, const float height) : width(width), height(height) { } - float width; - float height; + float width = 0; + float height = 0; }; inline Size operator - (const Size& left, const Size& right) |