aboutsummaryrefslogtreecommitdiff
path: root/CruUI/ui/controls
diff options
context:
space:
mode:
Diffstat (limited to 'CruUI/ui/controls')
-rw-r--r--CruUI/ui/controls/linear_layout.h9
-rw-r--r--CruUI/ui/controls/text_block.cpp10
-rw-r--r--CruUI/ui/controls/text_block.h2
-rw-r--r--CruUI/ui/controls/toggle_button.cpp123
-rw-r--r--CruUI/ui/controls/toggle_button.h59
5 files changed, 193 insertions, 10 deletions
diff --git a/CruUI/ui/controls/linear_layout.h b/CruUI/ui/controls/linear_layout.h
index 74c504cb..ead56081 100644
--- a/CruUI/ui/controls/linear_layout.h
+++ b/CruUI/ui/controls/linear_layout.h
@@ -18,9 +18,16 @@ namespace cru::ui::controls
return new LinearLayout(orientation);
}
- private:
+ protected:
explicit LinearLayout(Orientation orientation = Orientation::Vertical);
+ public:
+ LinearLayout(const LinearLayout& other) = delete;
+ LinearLayout(LinearLayout&& other) = delete;
+ LinearLayout& operator=(const LinearLayout& other) = delete;
+ LinearLayout& operator=(LinearLayout&& other) = delete;
+ ~LinearLayout() override = default;
+
protected:
Size OnMeasure(const Size& available_size) override;
void OnLayout(const Rect& rect) override;
diff --git a/CruUI/ui/controls/text_block.cpp b/CruUI/ui/controls/text_block.cpp
index a3dc23c5..beb799d3 100644
--- a/CruUI/ui/controls/text_block.cpp
+++ b/CruUI/ui/controls/text_block.cpp
@@ -11,19 +11,13 @@ namespace cru
{
namespace controls
{
+ using graph::CreateSolidBrush;
+
inline Microsoft::WRL::ComPtr<IDWriteFactory> GetDWriteFactory()
{
return graph::GraphManager::GetInstance()->GetDWriteFactory();
}
- Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> CreateSolidBrush(const D2D1_COLOR_F& color)
- {
- const auto device_context = graph::GraphManager::GetInstance()->GetD2D1DeviceContext();
- Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> solid_color_brush;
- device_context->CreateSolidColorBrush(color, &solid_color_brush);
- return solid_color_brush;
- }
-
TextBlock::TextBlock(const Microsoft::WRL::ComPtr<IDWriteTextFormat>& init_text_format,
const Microsoft::WRL::ComPtr<ID2D1Brush>& init_brush) : Control(false)
{
diff --git a/CruUI/ui/controls/text_block.h b/CruUI/ui/controls/text_block.h
index be2a1da2..db22e3c7 100644
--- a/CruUI/ui/controls/text_block.h
+++ b/CruUI/ui/controls/text_block.h
@@ -51,7 +51,7 @@ namespace cru
return text_block;
}
- private:
+ protected:
explicit TextBlock(
const Microsoft::WRL::ComPtr<IDWriteTextFormat>& init_text_format = nullptr,
const Microsoft::WRL::ComPtr<ID2D1Brush>& init_brush = nullptr
diff --git a/CruUI/ui/controls/toggle_button.cpp b/CruUI/ui/controls/toggle_button.cpp
new file mode 100644
index 00000000..ea2329ea
--- /dev/null
+++ b/CruUI/ui/controls/toggle_button.cpp
@@ -0,0 +1,123 @@
+#include "toggle_button.h"
+
+#include "graph/graph.h"
+
+namespace cru::ui::controls
+{
+ using graph::CreateSolidBrush;
+
+ // ui length parameters of toggle button.
+ constexpr float half_height = 15;
+ constexpr float half_width = half_height * 2;
+ constexpr float stroke_width = 3;
+ constexpr float inner_circle_radius = half_height - stroke_width;
+ constexpr float inner_circle_x = half_width - half_height;
+
+ ToggleButton::ToggleButton()
+ {
+ graph::GraphManager::GetInstance()->GetD2D1Factory()->CreateRoundedRectangleGeometry(D2D1::RoundedRect(D2D1::RectF(-half_width, -half_height, half_width, half_height), half_height, half_height), &frame_path_);
+
+ on_brush_ = CreateSolidBrush(D2D1::ColorF(D2D1::ColorF::LightBlue));
+ off_brush_ = CreateSolidBrush(D2D1::ColorF(D2D1::ColorF::LightGray));
+ }
+
+ inline D2D1_POINT_2F ConvertPoint(const Point& point)
+ {
+ return D2D1::Point2F(point.x, point.y);
+ }
+
+ bool ToggleButton::IsPointInside(const Point& point)
+ {
+ const auto size = GetSize();
+ const auto transform = D2D1::Matrix3x2F::Translation(size.width / 2, size.height / 2);
+ BOOL contains;
+ frame_path_->FillContainsPoint(ConvertPoint(point), transform, &contains);
+ if (!contains)
+ frame_path_->StrokeContainsPoint(ConvertPoint(point), stroke_width, nullptr, transform, &contains);
+ return contains != 0;
+ }
+
+ void ToggleButton::SetState(const bool state)
+ {
+ if (state != state_)
+ {
+ state_ = state;
+ OnToggleInternal(state);
+ Repaint();
+ }
+ }
+
+ void ToggleButton::Toggle()
+ {
+ SetState(!GetState());
+ }
+
+ void ToggleButton::OnToggle(events::ToggleEventArgs& args)
+ {
+
+ }
+
+ void ToggleButton::OnDraw(ID2D1DeviceContext* device_context)
+ {
+ const auto size = GetSize();
+ graph::WithTransform(device_context, D2D1::Matrix3x2F::Translation(size.width / 2, size.height / 2), [this](ID2D1DeviceContext* device_context)
+ {
+ if (state_)
+ {
+ device_context->DrawGeometry(frame_path_.Get(), on_brush_.Get(), stroke_width);
+ device_context->FillEllipse(D2D1::Ellipse(D2D1::Point2F(inner_circle_x, 0), inner_circle_radius, inner_circle_radius), on_brush_.Get());
+ }
+ else
+ {
+ device_context->DrawGeometry(frame_path_.Get(), off_brush_.Get(), stroke_width);
+ device_context->FillEllipse(D2D1::Ellipse(D2D1::Point2F(-inner_circle_x, 0), inner_circle_radius, inner_circle_radius), off_brush_.Get());
+ }
+ });
+ }
+
+ void ToggleButton::OnMouseClickCore(events::MouseButtonEventArgs& args)
+ {
+ Control::OnMouseClickCore(args);
+ Toggle();
+ }
+
+ Size ToggleButton::OnMeasure(const Size& available_size)
+ {
+ const auto layout_params = GetLayoutParams();
+
+ auto&& get_measure_length = [](const MeasureLength& layout_length, const float available_length, const float fix_length) -> float
+ {
+ switch (layout_length.mode)
+ {
+ case MeasureMode::Exactly:
+ {
+ return std::max(std::min(layout_length.length, available_length), fix_length);
+ }
+ case MeasureMode::Stretch:
+ {
+ return std::max(available_length, fix_length);
+ }
+ case MeasureMode::Content:
+ {
+ return fix_length;
+ }
+ default:
+ UnreachableCode();
+ }
+ };
+
+ const Size result_size(
+ get_measure_length(layout_params->width, available_size.width, half_width * 2 + stroke_width),
+ get_measure_length(layout_params->height, available_size.height, half_height * 2 + stroke_width)
+ );
+
+ return result_size;
+ }
+
+ void ToggleButton::OnToggleInternal(bool new_state)
+ {
+ events::ToggleEventArgs args(this, this, new_state);
+ OnToggle(args);
+ toggle_event.Raise(args);
+ }
+}
diff --git a/CruUI/ui/controls/toggle_button.h b/CruUI/ui/controls/toggle_button.h
new file mode 100644
index 00000000..d2e49473
--- /dev/null
+++ b/CruUI/ui/controls/toggle_button.h
@@ -0,0 +1,59 @@
+#pragma once
+
+#include "ui/control.h"
+
+namespace cru::ui::controls
+{
+ class ToggleButton : public Control
+ {
+ public:
+ static ToggleButton* Create()
+ {
+ return new ToggleButton();
+ }
+
+ protected:
+ ToggleButton();
+
+ public:
+ ToggleButton(const ToggleButton& other) = delete;
+ ToggleButton(ToggleButton&& other) = delete;
+ ToggleButton& operator=(const ToggleButton& other) = delete;
+ ToggleButton& operator=(ToggleButton&& other) = delete;
+ ~ToggleButton() override = default;
+
+ bool IsPointInside(const Point& point) override;
+
+ bool GetState() const
+ {
+ return state_;
+ }
+
+ void SetState(bool state);
+
+ void Toggle();
+
+ public:
+ events::ToggleEvent toggle_event;
+
+ protected:
+ virtual void OnToggle(events::ToggleEventArgs& args);
+
+ protected:
+ void OnDraw(ID2D1DeviceContext* device_context) override;
+
+ void OnMouseClickCore(events::MouseButtonEventArgs& args) override;
+
+ Size OnMeasure(const Size& available_size) override;
+
+ private:
+ void OnToggleInternal(bool new_state);
+
+ private:
+ bool state_ = false;
+
+ Microsoft::WRL::ComPtr<ID2D1RoundedRectangleGeometry> frame_path_;
+ Microsoft::WRL::ComPtr<ID2D1Brush> on_brush_;
+ Microsoft::WRL::ComPtr<ID2D1Brush> off_brush_;
+ };
+}