aboutsummaryrefslogtreecommitdiff
path: root/CruUI-Generate/cru_ui.cpp
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2018-12-05 16:38:24 +0800
committercrupest <crupest@outlook.com>2018-12-05 16:38:24 +0800
commit8314c0217521c5835a33aa98a18250873d8f7131 (patch)
tree3701c8b8ed8c64651456bbb926b66a65c75f737c /CruUI-Generate/cru_ui.cpp
parent8898aee6c70bde922ee5de2a6213a44798525a16 (diff)
downloadcru-8314c0217521c5835a33aa98a18250873d8f7131.tar.gz
cru-8314c0217521c5835a33aa98a18250873d8f7131.tar.bz2
cru-8314c0217521c5835a33aa98a18250873d8f7131.zip
Update merged source.
Diffstat (limited to 'CruUI-Generate/cru_ui.cpp')
-rw-r--r--CruUI-Generate/cru_ui.cpp337
1 files changed, 90 insertions, 247 deletions
diff --git a/CruUI-Generate/cru_ui.cpp b/CruUI-Generate/cru_ui.cpp
index 6db99a0e..8f64a791 100644
--- a/CruUI-Generate/cru_ui.cpp
+++ b/CruUI-Generate/cru_ui.cpp
@@ -990,27 +990,25 @@ namespace cru::ui
Point Control::GetPositionRelative()
{
- return position_;
+ return rect_.GetLeftTop();
}
- void Control::SetPositionRelative(const Point & position)
+ Size Control::GetSize()
{
- if (position != position_)
- {
- if (old_position_ == position) // if cache has been refreshed and no pending notify
- old_position_ = position_;
- position_ = position;
- LayoutManager::GetInstance()->InvalidateControlPositionCache(this);
- if (auto window = GetWindow())
- {
- window->InvalidateDraw();
- }
- }
+ return rect_.GetSize();
}
- Size Control::GetSize()
+ void Control::SetRect(const Rect& rect)
{
- return size_;
+ const auto old_rect = rect_;
+ rect_ = rect;
+
+ RegenerateGeometryInfo();
+
+ OnRectChange(old_rect, rect);
+
+ if (auto window = GetWindow())
+ window->InvalidateDraw();
}
namespace
@@ -1034,24 +1032,6 @@ namespace cru::ui
#endif
}
- void Control::SetSize(const Size & size)
- {
- const auto old_size = size_;
- size_ = size;
- events::SizeChangedEventArgs args(this, this, old_size, size);
- size_changed_event.Raise(args);
-
- RegenerateGeometryInfo();
-
-#ifdef CRU_DEBUG_LAYOUT
- margin_geometry_ = CalculateSquareRingGeometry(GetRect(RectRange::Margin), GetRect(RectRange::FullBorder));
- padding_geometry_ = CalculateSquareRingGeometry(GetRect(RectRange::Padding), GetRect(RectRange::Content));
-#endif
-
- if (auto window = GetWindow())
- window->InvalidateDraw();
- }
-
Point Control::GetPositionAbsolute() const
{
return position_cache_.lefttop_position_absolute;
@@ -1187,17 +1167,21 @@ namespace cru::ui
window->WindowInvalidateLayout();
}
- void Control::Measure(const Size& available_size)
+ void Control::Measure(const Size& available_size, const AdditionalMeasureInfo& additional_info)
{
- SetDesiredSize(OnMeasureCore(available_size));
+ SetDesiredSize(OnMeasureCore(available_size, additional_info));
}
- void Control::Layout(const Rect& rect)
+ void Control::Layout(const Rect& rect, const AdditionalLayoutInfo& additional_info)
{
- SetPositionRelative(rect.GetLeftTop());
- SetSize(rect.GetSize());
- AfterLayoutSelf();
- OnLayoutCore(Rect(Point::Zero(), rect.GetSize()));
+ auto my_additional_info = additional_info;
+ my_additional_info.total_offset.x += rect.left;
+ my_additional_info.total_offset.y += rect.top;
+ position_cache_.lefttop_position_absolute.x = my_additional_info.total_offset.x;
+ position_cache_.lefttop_position_absolute.y = my_additional_info.total_offset.y;
+
+ SetRect(rect);
+ OnLayoutCore(Rect(Point::Zero(), rect.GetSize()), my_additional_info);
}
Size Control::GetDesiredSize() const
@@ -1380,6 +1364,11 @@ namespace cru::ui
});
}
+ void Control::OnRectChange(const Rect& old_rect, const Rect& new_rect)
+ {
+
+ }
+
void Control::RegenerateGeometryInfo()
{
if (IsBordered())
@@ -1439,6 +1428,12 @@ namespace cru::ui
);
geometry_info_.content_geometry = std::move(geometry2);
}
+
+ //TODO: generate debug geometry
+#ifdef CRU_DEBUG_LAYOUT
+ margin_geometry_ = CalculateSquareRingGeometry(GetRect(RectRange::Margin), GetRect(RectRange::FullBorder));
+ padding_geometry_ = CalculateSquareRingGeometry(GetRect(RectRange::Padding), GetRect(RectRange::Content));
+#endif
}
void Control::OnMouseClickBegin(MouseButton button)
@@ -1454,13 +1449,28 @@ namespace cru::ui
return Size(thickness.left + thickness.right, thickness.top + thickness.bottom);
}
- Size Control::OnMeasureCore(const Size& available_size)
+ Size Control::OnMeasureCore(const Size& available_size, const AdditionalMeasureInfo& additional_info)
{
const auto layout_params = GetLayoutParams();
if (!layout_params->Validate())
throw std::runtime_error("LayoutParams is not valid. Please check it.");
+ auto my_additional_info = additional_info;
+
+ if (layout_params->width.mode == MeasureMode::Content)
+ my_additional_info.horizontal_stretchable = false;
+ else if (layout_params->width.mode == MeasureMode::Exactly)
+ my_additional_info.horizontal_stretchable = true;
+ // if stretch, then inherent parent's value
+
+ if (layout_params->height.mode == MeasureMode::Content)
+ my_additional_info.vertical_stretchable = false;
+ else if (layout_params->height.mode == MeasureMode::Exactly)
+ my_additional_info.vertical_stretchable = true;
+ // if stretch, then inherent parent's value
+
+
auto border_size = Size::Zero();
if (is_bordered_)
{
@@ -1491,66 +1501,9 @@ namespace cru::ui
get_content_measure_length(layout_params->height, available_size.height, outer_size.height)
);
- const auto content_actual_size = OnMeasureContent(content_measure_size);
-
- auto stretch_width = false;
- auto stretch_width_determined = true;
- auto stretch_height = false;
- auto stretch_height_determined = true;
+ const auto content_actual_size = OnMeasureContent(content_measure_size, my_additional_info);
- // if it is stretch, init is stretch, and undetermined.
- if (layout_params->width.mode == MeasureMode::Stretch)
- {
- stretch_width = true;
- stretch_width_determined = false;
- }
- if (layout_params->height.mode == MeasureMode::Stretch)
- {
- stretch_height = true;
- stretch_width_determined = false;
- }
- if (!stretch_width_determined || !stretch_height_determined)
- {
- auto parent = GetParent();
- while (parent != nullptr)
- {
- const auto lp = parent->GetLayoutParams();
-
- if (!stretch_width_determined)
- {
- if (lp->width.mode == MeasureMode::Content) // if the first ancestor that is not stretch is content, then it can't stretch.
- {
- stretch_width = false;
- stretch_width_determined = true;
- }
- if (lp->width.mode == MeasureMode::Exactly) // if the first ancestor that is not stretch is content, then it must be stretch.
- {
- stretch_width = true;
- stretch_width_determined = true;
- }
- }
-
- if (!stretch_height_determined) // the same as width
- {
- if (lp->height.mode == MeasureMode::Content) // if the first ancestor that is not stretch is content, then it can't stretch.
- {
- stretch_height = false;
- stretch_height_determined = true;
- }
- if (lp->height.mode == MeasureMode::Exactly) // if the first ancestor that is not stretch is content, then it must be stretch.
- {
- stretch_height = true;
- stretch_height_determined = true;
- }
- }
-
- if (stretch_width_determined && stretch_height_determined) // if both are determined.
- break;
-
- parent = GetParent();
- }
- }
auto&& calculate_final_length = [](const bool stretch, const std::optional<float> min_length, const float measure_length, const float actual_length) -> float
{
@@ -1561,14 +1514,14 @@ namespace cru::ui
};
const auto final_size = Size(
- calculate_final_length(stretch_width, layout_params->width.min, content_measure_size.width, content_actual_size.width),
- calculate_final_length(stretch_height, layout_params->height.min, content_measure_size.height, content_actual_size.height)
+ calculate_final_length(my_additional_info.horizontal_stretchable, layout_params->width.min, content_measure_size.width, content_actual_size.width),
+ calculate_final_length(my_additional_info.vertical_stretchable, layout_params->height.min, content_measure_size.height, content_actual_size.height)
) + outer_size;
return final_size;
}
- void Control::OnLayoutCore(const Rect& rect)
+ void Control::OnLayoutCore(const Rect& rect, const AdditionalLayoutInfo& additional_info)
{
const auto layout_params = GetLayoutParams();
@@ -1590,15 +1543,15 @@ namespace cru::ui
if (content_rect.height < 0.0)
throw std::runtime_error(Format("Height to layout must sufficient. But in {}, height for content is {}.", ToUtf8String(GetControlType()), content_rect.height));
- OnLayoutContent(content_rect);
+ OnLayoutContent(content_rect, additional_info);
}
- Size Control::OnMeasureContent(const Size& available_size)
+ Size Control::OnMeasureContent(const Size& available_size, const AdditionalMeasureInfo& additional_info)
{
auto max_child_size = Size::Zero();
for (auto control: GetChildren())
{
- control->Measure(available_size);
+ control->Measure(available_size, additional_info);
const auto&& size = control->GetDesiredSize();
if (max_child_size.width < size.width)
max_child_size.width = size.width;
@@ -1621,7 +1574,7 @@ namespace cru::ui
return max_child_size;
}
- void Control::OnLayoutContent(const Rect& rect)
+ void Control::OnLayoutContent(const Rect& rect, const AdditionalLayoutInfo& additional_info)
{
for (auto control: GetChildren())
{
@@ -1646,22 +1599,7 @@ namespace cru::ui
control->Layout(Rect(Point(
calculate_anchor(rect.left, layout_params->width.alignment, rect.width, size.width),
calculate_anchor(rect.top, layout_params->height.alignment, rect.height, size.height)
- ), size));
- }
- }
-
- void Control::AfterLayoutSelf()
- {
-
- }
-
- void Control::CheckAndNotifyPositionChanged()
- {
- if (this->old_position_ != this->position_)
- {
- events::PositionChangedEventArgs args(this, this, this->old_position_, this->position_);
- position_changed_event.Raise(args);
- this->old_position_ = this->position_;
+ ), size), additional_info);
}
}
@@ -1768,84 +1706,9 @@ namespace cru::ui
//-------begin of file: src\ui\layout_base.cpp
//--------------------------------------------------------
-
namespace cru::ui
{
- LayoutManager* LayoutManager::GetInstance()
- {
- return Application::GetInstance()->ResolveSingleton<LayoutManager>([](auto)
- {
- return new LayoutManager{};
- });
- }
-
- void LayoutManager::InvalidateControlPositionCache(Control * control)
- {
- if (cache_invalid_controls_.count(control) == 1)
- return;
-
- // find descendant then erase it; find ancestor then just return.
- auto i = cache_invalid_controls_.cbegin();
- while (i != cache_invalid_controls_.cend())
- {
- auto current_i = i++;
- const auto result = IsAncestorOrDescendant(*current_i, control);
- if (result == control)
- cache_invalid_controls_.erase(current_i);
- else if (result != nullptr)
- return; // find a ancestor of "control", just return
- }
-
- cache_invalid_controls_.insert(control);
-
- if (cache_invalid_controls_.size() == 1) // when insert just now and not repeat to "InvokeLater".
- {
- InvokeLater([this] {
- for (const auto i : cache_invalid_controls_)
- RefreshControlPositionCache(i);
- for (const auto i : cache_invalid_controls_) // traverse all descendants of position-invalid controls and notify position change event
- i->TraverseDescendants([](Control* control)
- {
- control->CheckAndNotifyPositionChanged();
- });
- cache_invalid_controls_.clear(); // after update and notify, clear the set.
-
- });
- }
- }
- void LayoutManager::RefreshInvalidControlPositionCache()
- {
- for (const auto i : cache_invalid_controls_)
- RefreshControlPositionCache(i);
- cache_invalid_controls_.clear();
- }
-
- void LayoutManager::RefreshControlPositionCache(Control * control)
- {
- auto point = Point::Zero();
- auto parent = control;
- while ((parent = parent->GetParent())) {
- const auto p = parent->GetPositionRelative();
- point.x += p.x;
- point.y += p.y;
- }
- RefreshControlPositionCacheInternal(control, point);
- }
-
- void LayoutManager::RefreshControlPositionCacheInternal(Control * control, const Point & parent_lefttop_absolute)
- {
- const auto position = control->GetPositionRelative();
- const Point lefttop(
- parent_lefttop_absolute.x + position.x,
- parent_lefttop_absolute.y + position.y
- );
- control->position_cache_.lefttop_position_absolute = lefttop;
- for(auto c : control->GetChildren())
- {
- RefreshControlPositionCacheInternal(c, lefttop);
- }
- }
}
//--------------------------------------------------------
//-------end of file: src\ui\layout_base.cpp
@@ -2449,17 +2312,12 @@ namespace cru::ui
return Point();
}
- void Window::SetPositionRelative(const Point & position)
- {
-
- }
-
Size Window::GetSize()
{
return GetClientSize();
}
- void Window::SetSize(const Size & size)
+ void Window::SetRect(const Rect& size)
{
}
@@ -2484,16 +2342,16 @@ namespace cru::ui
void Window::Relayout()
{
- Measure(GetSize());
- OnLayoutCore(Rect(Point::Zero(), GetSize()));
+ Measure(GetSize(), AdditionalMeasureInfo{});
+ OnLayoutCore(Rect(Point::Zero(), GetSize()), AdditionalLayoutInfo{});
is_layout_invalid_ = false;
}
void Window::SetSizeFitContent(const Size& max_size)
{
- Measure(max_size);
+ Measure(max_size, AdditionalMeasureInfo{});
SetClientSize(GetDesiredSize());
- OnLayoutCore(Rect(Point::Zero(), GetSize()));
+ OnLayoutCore(Rect(Point::Zero(), GetSize()), AdditionalLayoutInfo{});
is_layout_invalid_ = false;
}
@@ -3025,7 +2883,7 @@ namespace cru::ui::controls
return control_type;
}
- Size LinearLayout::OnMeasureContent(const Size& available_size)
+ Size LinearLayout::OnMeasureContent(const Size& available_size, const AdditionalMeasureInfo& additional_info)
{
auto actual_size_for_children = Size::Zero();
@@ -3041,7 +2899,7 @@ namespace cru::ui::controls
if (mode == MeasureMode::Content || mode == MeasureMode::Exactly)
{
Size current_available_size(AtLeast0(available_size.width - actual_size_for_children.width), available_size.height);
- control->Measure(current_available_size);
+ control->Measure(current_available_size, additional_info);
const auto size = control->GetDesiredSize();
actual_size_for_children.width += size.width;
secondary_side_child_max_length = std::max(size.height, secondary_side_child_max_length);
@@ -3056,7 +2914,7 @@ namespace cru::ui::controls
if (mode == MeasureMode::Content || mode == MeasureMode::Exactly)
{
Size current_available_size(available_size.width, AtLeast0(available_size.height - actual_size_for_children.height));
- control->Measure(current_available_size);
+ control->Measure(current_available_size, additional_info);
const auto size = control->GetDesiredSize();
actual_size_for_children.height += size.height;
secondary_side_child_max_length = std::max(size.width, secondary_side_child_max_length);
@@ -3070,7 +2928,7 @@ namespace cru::ui::controls
const auto available_width = AtLeast0(available_size.width - actual_size_for_children.width) / stretch_control_list.size();
for (const auto control : stretch_control_list)
{
- control->Measure(Size(available_width, available_size.height));
+ control->Measure(Size(available_width, available_size.height), additional_info);
const auto size = control->GetDesiredSize();
actual_size_for_children.width += size.width;
secondary_side_child_max_length = std::max(size.height, secondary_side_child_max_length);
@@ -3081,7 +2939,7 @@ namespace cru::ui::controls
const auto available_height = AtLeast0(available_size.height - actual_size_for_children.height) / stretch_control_list.size();
for (const auto control : stretch_control_list)
{
- control->Measure(Size(available_size.width, available_height));
+ control->Measure(Size(available_size.width, available_height), additional_info);
const auto size = control->GetDesiredSize();
actual_size_for_children.height += size.height;
secondary_side_child_max_length = std::max(size.width, secondary_side_child_max_length);
@@ -3115,7 +2973,7 @@ namespace cru::ui::controls
return actual_size_for_children;
}
- void LinearLayout::OnLayoutContent(const Rect& rect)
+ void LinearLayout::OnLayoutContent(const Rect& rect, const AdditionalLayoutInfo& additional_info)
{
float current_main_side_anchor = 0;
for(auto control: GetChildren())
@@ -3146,12 +3004,12 @@ namespace cru::ui::controls
if (orientation_ == Orientation::Horizontal)
{
- control->Layout(calculate_rect(current_main_side_anchor, calculate_secondary_side_anchor(rect.height, size.height)));
+ control->Layout(calculate_rect(current_main_side_anchor, calculate_secondary_side_anchor(rect.height, size.height)), additional_info);
current_main_side_anchor += size.width;
}
else
{
- control->Layout(calculate_rect(calculate_secondary_side_anchor(rect.width, size.width), current_main_side_anchor));
+ control->Layout(calculate_rect(calculate_secondary_side_anchor(rect.width, size.width), current_main_side_anchor), additional_info);
current_main_side_anchor += size.height;
}
}
@@ -3505,7 +3363,7 @@ namespace cru::ui::controls
view_height_ = length;
}
- Size ScrollControl::OnMeasureContent(const Size& available_size)
+ Size ScrollControl::OnMeasureContent(const Size& available_size, const AdditionalMeasureInfo& additional_info)
{
const auto layout_params = GetLayoutParams();
@@ -3515,13 +3373,6 @@ namespace cru::ui::controls
if (layout_params->width.mode == MeasureMode::Content)
debug::DebugMessage(L"ScrollControl: Width measure mode is Content and horizontal scroll is enabled. So Stretch is used instead.");
- for (auto child : GetChildren())
- {
- const auto child_layout_params = child->GetLayoutParams();
- if (child_layout_params->width.mode == MeasureMode::Stretch)
- throw std::runtime_error(Format("ScrollControl: Horizontal scroll is enabled but a child {} 's width measure mode is Stretch which may cause infinite length.", ToUtf8String(child->GetControlType())));
- }
-
available_size_for_children.width = std::numeric_limits<float>::max();
}
@@ -3530,20 +3381,13 @@ namespace cru::ui::controls
if (layout_params->height.mode == MeasureMode::Content)
debug::DebugMessage(L"ScrollControl: Height measure mode is Content and vertical scroll is enabled. So Stretch is used instead.");
- for (auto child : GetChildren())
- {
- const auto child_layout_params = child->GetLayoutParams();
- if (child_layout_params->height.mode == MeasureMode::Stretch)
- throw std::runtime_error(Format("ScrollControl: Vertical scroll is enabled but a child {} 's height measure mode is Stretch which may cause infinite length.", ToUtf8String(child->GetControlType())));
- }
-
available_size_for_children.height = std::numeric_limits<float>::max();
}
auto max_child_size = Size::Zero();
for (auto control: GetChildren())
{
- control->Measure(available_size_for_children);
+ control->Measure(available_size_for_children, AdditionalMeasureInfo{false, false});
const auto&& size = control->GetDesiredSize();
if (max_child_size.width < size.width)
max_child_size.width = size.width;
@@ -3551,7 +3395,7 @@ namespace cru::ui::controls
max_child_size.height = size.height;
}
- // coerce size fro stretch.
+ // coerce size for stretch.
for (auto control: GetChildren())
{
auto size = control->GetDesiredSize();
@@ -3578,7 +3422,7 @@ namespace cru::ui::controls
return result;
}
- void ScrollControl::OnLayoutContent(const Rect& rect)
+ void ScrollControl::OnLayoutContent(const Rect& rect, const AdditionalLayoutInfo& additional_info)
{
auto layout_rect = rect;
@@ -3599,11 +3443,11 @@ namespace cru::ui::controls
control->Layout(Rect(Point(
calculate_anchor(rect.left, layout_rect.width, size.width, offset_x_),
calculate_anchor(rect.top, layout_rect.height, size.height, offset_y_)
- ), size));
+ ), size), additional_info);
}
}
- void ScrollControl::AfterLayoutSelf()
+ void ScrollControl::OnRectChange(const Rect& old_rect, const Rect& new_rect)
{
UpdateScrollBarBorderInfo();
CoerceAndSetOffsets(offset_x_, offset_y_, false);
@@ -3625,10 +3469,10 @@ namespace cru::ui::controls
for (auto child : GetChildren())
{
const auto old_position = child->GetPositionRelative();
- child->SetPositionRelative(Point(
+ child->SetRect(Rect(Point(
old_position.x + old_offset_x - offset_x_,
old_position.y + old_offset_y - offset_y_
- ));
+ ), child->GetSize()));
}
}
InvalidateDraw();
@@ -3959,14 +3803,6 @@ namespace cru::ui::controls
SetClipContent(true);
- size_changed_event.AddHandler([this](events::SizeChangedEventArgs& args)
- {
- const auto content = GetRect(RectRange::Content);
- ThrowIfFailed(text_layout_->SetMaxWidth(content.width));
- ThrowIfFailed(text_layout_->SetMaxHeight(content.height));
- InvalidateDraw();
- });
-
draw_content_event.AddHandler([this](events::DrawEventArgs& args)
{
const auto device_context = args.GetDeviceContext();
@@ -4080,7 +3916,7 @@ namespace cru::ui::controls
}
}
- Size TextControl::OnMeasureContent(const Size& available_size)
+ Size TextControl::OnMeasureContent(const Size& available_size, const AdditionalMeasureInfo&)
{
ThrowIfFailed(text_layout_->SetMaxWidth(available_size.width));
ThrowIfFailed(text_layout_->SetMaxHeight(available_size.height));
@@ -4099,6 +3935,13 @@ namespace cru::ui::controls
}
+ void TextControl::OnRectChange(const Rect& old_rect, const Rect& new_rect)
+ {
+ const auto content = GetRect(RectRange::Content);
+ ThrowIfFailed(text_layout_->SetMaxWidth(content.width));
+ ThrowIfFailed(text_layout_->SetMaxHeight(content.height));
+ }
+
void TextControl::OnTextChangedCore(const String& old_text, const String& new_text)
{
RecreateTextLayout();
@@ -4260,7 +4103,7 @@ namespace cru::ui::controls
SetState(!GetState());
}
- Size ToggleButton::OnMeasureContent(const Size& available_size)
+ Size ToggleButton::OnMeasureContent(const Size& available_size, const AdditionalMeasureInfo&)
{
const Size result_size(
half_width * 2 + stroke_width,