aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main.cpp13
-rw-r--r--src/ui/controls/border_delegate.cpp14
-rw-r--r--src/ui/controls/border_delegate.h6
-rw-r--r--src/ui/controls/margin_container.cpp63
-rw-r--r--src/ui/controls/text_box.cpp28
-rw-r--r--src/ui/controls/text_box.h5
-rw-r--r--src/ui/controls/text_control.cpp70
-rw-r--r--src/ui/controls/text_control.h4
8 files changed, 125 insertions, 78 deletions
diff --git a/src/main.cpp b/src/main.cpp
index e11fbbe0..7a105d79 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -153,9 +153,16 @@ int APIENTRY wWinMain(
*/
window.AddChild(
- Button::Create(
- {TextBlock::Create(L"Button")}
- )
+ Border::Create({
+ MarginContainer::Create(Thickness(50, 50), {
+ LinearLayout::Create(LinearLayout::Orientation::Vertical, {
+ Button::Create({
+ TextBlock::Create(L"Button")
+ }),
+ TextBox::Create()
+ })
+ })
+ })
);
window.Show();
diff --git a/src/ui/controls/border_delegate.cpp b/src/ui/controls/border_delegate.cpp
index 0b460997..c8855e0f 100644
--- a/src/ui/controls/border_delegate.cpp
+++ b/src/ui/controls/border_delegate.cpp
@@ -1,7 +1,19 @@
#include "border_delegate.h"
+#include "graph/graph.h"
namespace cru::ui::controls
{
+ BorderProperty::Ptr BorderProperty::Create()
+ {
+ return std::make_shared<BorderProperty>(graph::CreateSolidBrush(D2D1::ColorF(D2D1::ColorF::Black)));
+ }
+
+ BorderProperty::BorderProperty(Microsoft::WRL::ComPtr<ID2D1Brush> brush)
+ : brush_(std::move(brush))
+ {
+
+ }
+
void BorderProperty::SetBrush(Microsoft::WRL::ComPtr<ID2D1Brush> brush)
{
brush_ = std::move(brush);
@@ -33,7 +45,7 @@ namespace cru::ui::controls
}
BorderDelegate::BorderDelegate(Control* control)
- : BorderDelegate(control, std::make_shared<BorderProperty>())
+ : BorderDelegate(control, BorderProperty::Create())
{
}
diff --git a/src/ui/controls/border_delegate.h b/src/ui/controls/border_delegate.h
index 6d3b31db..6d8663e9 100644
--- a/src/ui/controls/border_delegate.h
+++ b/src/ui/controls/border_delegate.h
@@ -8,10 +8,7 @@ namespace cru::ui::controls
{
public:
using Ptr = std::shared_ptr<BorderProperty>;
- static Ptr Create()
- {
- return std::make_shared<BorderProperty>();
- }
+ static Ptr Create();
constexpr static auto brush_property_name = L"Brush";
constexpr static auto width_property_name = L"Width";
@@ -20,6 +17,7 @@ namespace cru::ui::controls
constexpr static auto radius_y_property_name = L"RadiusY";
BorderProperty() = default;
+ explicit BorderProperty(Microsoft::WRL::ComPtr<ID2D1Brush> brush);
BorderProperty(const BorderProperty& other) = delete;
BorderProperty(BorderProperty&& other) = delete;
BorderProperty& operator=(const BorderProperty& other) = delete;
diff --git a/src/ui/controls/margin_container.cpp b/src/ui/controls/margin_container.cpp
index 26acb172..12dde025 100644
--- a/src/ui/controls/margin_container.cpp
+++ b/src/ui/controls/margin_container.cpp
@@ -25,70 +25,11 @@ namespace cru::ui::controls
Size MarginContainer::OnMeasure(const Size& available_size)
{
- const auto layout_params = GetLayoutParams();
-
- if (!layout_params->Validate())
- throw std::runtime_error("LayoutParams is not valid. Please check it.");
-
- auto&& get_available_length_for_child = [](const LayoutSideParams& layout_length, const float available_length) -> float
- {
- switch (layout_length.mode)
- {
- case MeasureMode::Exactly:
- {
- return std::min(layout_length.length, available_length);
- }
- case MeasureMode::Stretch:
- case MeasureMode::Content:
- {
- return available_length;
- }
- default:
- UnreachableCode();
- }
- };
-
- 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));
-
- const auto margin_size = Size(margin_.left + margin_.right, margin_.top + margin_.bottom);
- const auto coerced_size_for_children = AtLeast0(size_for_children - margin_size);
-
- auto max_child_size = Size::Zero();
- ForeachChild([coerced_size_for_children, &max_child_size](Control* control)
- {
- control->Measure(coerced_size_for_children);
- const auto&& size = control->GetDesiredSize();
- if (max_child_size.width < size.width)
- max_child_size.width = size.width;
- if (max_child_size.height < size.height)
- max_child_size.height = size.height;
- });
-
- auto&& calculate_final_length = [](const LayoutSideParams& layout_length, const float length_for_children, const float max_child_length) -> float
- {
- switch (layout_length.mode)
- {
- case MeasureMode::Exactly:
- case MeasureMode::Stretch:
- return length_for_children;
- case MeasureMode::Content:
- return max_child_length;
- default:
- UnreachableCode();
- }
- };
-
- return Size(
- calculate_final_length(layout_params->width, coerced_size_for_children.width, max_child_size.width),
- calculate_final_length(layout_params->height, coerced_size_for_children.height, max_child_size.height)
- );
+ return DefaultMeasureWithPadding(available_size, margin_);
}
void MarginContainer::OnLayout(const Rect& rect)
{
- const auto anchor = Point(margin_.left, margin_.top);
- const auto margin_size = Size(margin_.left + margin_.right, margin_.top + margin_.bottom);
- Control::OnLayout(Rect(anchor, AtLeast0(rect.GetSize() - margin_size)));
+ DefaultLayoutWithPadding(rect, margin_);
}
}
diff --git a/src/ui/controls/text_box.cpp b/src/ui/controls/text_box.cpp
index 4a4114ab..0d65f1ad 100644
--- a/src/ui/controls/text_box.cpp
+++ b/src/ui/controls/text_box.cpp
@@ -26,21 +26,28 @@ namespace cru::ui::controls
is_caret_show_ = !is_caret_show_;
Repaint();
});
+
+ border_delegate_ = std::make_unique<BorderDelegate>(this);
}
TextBox::~TextBox() = default;
void TextBox::OnDraw(ID2D1DeviceContext* device_context)
{
- TextControl::OnDraw(device_context);
- if (is_caret_show_)
+ border_delegate_->Draw(device_context, GetSize());
+ const auto border_thickness = border_delegate_->GetBorderThickness();
+ graph::WithTransform(device_context, D2D1::Matrix3x2F::Translation(border_thickness.left, border_thickness.top), [this](ID2D1DeviceContext* device_context)
{
- const auto caret_half_width = Application::GetInstance()->GetCaretInfo().half_caret_width;
- FLOAT x, y;
- DWRITE_HIT_TEST_METRICS metrics{};
- ThrowIfFailed(text_layout_->HitTestTextPosition(caret_position_, FALSE, &x, &y, &metrics));
- device_context->FillRectangle(D2D1::RectF(metrics.left - caret_half_width, metrics.top, metrics.left + caret_half_width, metrics.top + metrics.height), caret_brush_.Get());
- }
+ TextControl::OnDraw(device_context);
+ if (is_caret_show_)
+ {
+ const auto caret_half_width = Application::GetInstance()->GetCaretInfo().half_caret_width;
+ FLOAT x, y;
+ DWRITE_HIT_TEST_METRICS metrics{};
+ ThrowIfFailed(text_layout_->HitTestTextPosition(caret_position_, FALSE, &x, &y, &metrics));
+ device_context->FillRectangle(D2D1::RectF(metrics.left - caret_half_width, metrics.top, metrics.left + caret_half_width, metrics.top + metrics.height), caret_brush_.Get());
+ }
+ });
}
void TextBox::OnGetFocusCore(events::FocusChangeEventArgs& args)
@@ -131,6 +138,11 @@ namespace cru::ui::controls
}
}
+ Size TextBox::OnMeasure(const Size& available_size)
+ {
+ return TextMeasureWithPadding(available_size, border_delegate_->GetBorderThickness());
+ }
+
void TextBox::RequestChangeCaretPosition(const unsigned position)
{
caret_position_ = position;
diff --git a/src/ui/controls/text_box.h b/src/ui/controls/text_box.h
index 07c4abe4..a6e4566d 100644
--- a/src/ui/controls/text_box.h
+++ b/src/ui/controls/text_box.h
@@ -2,6 +2,7 @@
#include "text_control.h"
#include "timer.h"
+#include "border_delegate.h"
namespace cru::ui::controls
{
@@ -36,6 +37,8 @@ namespace cru::ui::controls
void OnKeyDownCore(events::KeyEventArgs& args) override final;
void OnCharCore(events::CharEventArgs& args) override final;
+ Size OnMeasure(const Size& available_size) override;
+
void RequestChangeCaretPosition(unsigned position) override;
private:
@@ -44,5 +47,7 @@ namespace cru::ui::controls
ActionPtr caret_action_;
Microsoft::WRL::ComPtr<ID2D1Brush> caret_brush_;
bool is_caret_show_ = false;
+
+ std::unique_ptr<BorderDelegate> border_delegate_;
};
}
diff --git a/src/ui/controls/text_control.cpp b/src/ui/controls/text_control.cpp
index 692c4451..0b730500 100644
--- a/src/ui/controls/text_control.cpp
+++ b/src/ui/controls/text_control.cpp
@@ -259,6 +259,76 @@ namespace cru::ui::controls
return result_size;
}
+ inline Size ThicknessToSize(const Thickness& thickness)
+ {
+ return Size(thickness.left + thickness.right, thickness.top + thickness.bottom);
+ }
+
+ inline float AtLeast0(const float value)
+ {
+ return value < 0 ? 0 : value;
+ }
+
+ inline Size AtLeast0(const Size& size)
+ {
+ return Size(AtLeast0(size.width), AtLeast0(size.height));
+ }
+
+ Size TextControl::TextMeasureWithPadding(const Size& available_size, const Thickness& padding)
+ {
+ const auto layout_params = GetLayoutParams();
+ const auto padding_size = ThicknessToSize(padding);
+
+ auto&& get_measure_length = [](const LayoutSideParams& layout_length, const float available_length) -> float
+ {
+ switch (layout_length.mode)
+ {
+ case MeasureMode::Exactly:
+ {
+ return std::min(layout_length.length, available_length);
+ }
+ case MeasureMode::Stretch:
+ case MeasureMode::Content:
+ {
+ return available_length;
+ }
+ default:
+ UnreachableCode();
+ }
+ };
+
+ Size measure_size(get_measure_length(layout_params->width, available_size.width),
+ get_measure_length(layout_params->height, available_size.height));
+
+ measure_size = AtLeast0(measure_size - padding_size);
+
+ ThrowIfFailed(text_layout_->SetMaxWidth(measure_size.width));
+ ThrowIfFailed(text_layout_->SetMaxHeight(measure_size.height));
+
+ DWRITE_TEXT_METRICS metrics{};
+
+ ThrowIfFailed(text_layout_->GetMetrics(&metrics));
+
+ const Size measure_result(metrics.width, metrics.height);
+
+ auto&& calculate_final_length = [](const LayoutSideParams& layout_length, const float measure_length, const float measure_result_length) -> float
+ {
+ if ((layout_length.mode == MeasureMode::Stretch ||
+ layout_length.mode == MeasureMode::Exactly)
+ && measure_result_length < measure_length)
+ return measure_length;
+ else
+ return measure_result_length;
+ };
+
+ const Size result_size(
+ calculate_final_length(layout_params->width, measure_size.width, measure_result.width),
+ calculate_final_length(layout_params->height, measure_size.height, measure_result.height)
+ );
+
+ return result_size + padding_size;
+ }
+
void TextControl::RequestChangeCaretPosition(unsigned position)
{
diff --git a/src/ui/controls/text_control.h b/src/ui/controls/text_control.h
index a24766dc..2ead7c54 100644
--- a/src/ui/controls/text_control.h
+++ b/src/ui/controls/text_control.h
@@ -76,7 +76,9 @@ namespace cru::ui::controls
void OnLoseFocusCore(events::FocusChangeEventArgs& args) override;
- Size OnMeasure(const Size& available_size) override final;
+ Size OnMeasure(const Size& available_size) override;
+
+ Size TextMeasureWithPadding(const Size& available_size, const Thickness& padding);
virtual void RequestChangeCaretPosition(unsigned position);