aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CruUI/application.cpp4
-rw-r--r--CruUI/application.h11
-rw-r--r--CruUI/main.cpp25
-rw-r--r--CruUI/ui/control.cpp42
-rw-r--r--CruUI/ui/controls/linear_layout.cpp60
-rw-r--r--CruUI/ui/controls/text_block.cpp6
-rw-r--r--CruUI/ui/controls/toggle_button.cpp1
-rw-r--r--CruUI/ui/layout_base.cpp2
-rw-r--r--CruUI/ui/layout_base.h25
-rw-r--r--CruUI/ui/ui_base.cpp2
-rw-r--r--CruUI/ui/ui_base.h26
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, &current_anchor](Control* control)
+ float current_anchor_length = 0;
+ ForeachChild([this, &current_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)