aboutsummaryrefslogtreecommitdiff
path: root/src/ui
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2018-11-10 21:53:33 +0800
committercrupest <crupest@outlook.com>2018-11-10 21:53:33 +0800
commite5513daa53cb958b0c83d575c440f40aaf40f562 (patch)
treec6782f0cbfe4eca466f13ef571338e6b55342860 /src/ui
parentcfcd03f564e82419345a7a6900fdc17c5b8c2631 (diff)
downloadcru-e5513daa53cb958b0c83d575c440f40aaf40f562.tar.gz
cru-e5513daa53cb958b0c83d575c440f40aaf40f562.tar.bz2
cru-e5513daa53cb958b0c83d575c440f40aaf40f562.zip
...
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/control.cpp7
-rw-r--r--src/ui/controls/list_item.cpp58
-rw-r--r--src/ui/controls/list_item.hpp46
-rw-r--r--src/ui/convert_util.hpp13
-rw-r--r--src/ui/layout_base.hpp39
-rw-r--r--src/ui/ui_base.cpp5
-rw-r--r--src/ui/ui_base.hpp45
-rw-r--r--src/ui/ui_manager.cpp37
-rw-r--r--src/ui/ui_manager.hpp9
9 files changed, 197 insertions, 62 deletions
diff --git a/src/ui/control.cpp b/src/ui/control.cpp
index 5d15e287..ed904de1 100644
--- a/src/ui/control.cpp
+++ b/src/ui/control.cpp
@@ -7,6 +7,7 @@
#include "graph/graph.hpp"
#include "exception.hpp"
#include "cru_debug.hpp"
+#include "convert_util.hpp"
#ifdef CRU_DEBUG_LAYOUT
#include "ui_manager.hpp"
@@ -376,12 +377,6 @@ namespace cru::ui
window_ = nullptr;
}
-
- inline D2D1_RECT_F Convert(const Rect& rect)
- {
- return D2D1::RectF(rect.left, rect.top, rect.left + rect.width, rect.top + rect.height);
- }
-
void Control::OnDrawCore(ID2D1DeviceContext* device_context)
{
#ifdef CRU_DEBUG_LAYOUT
diff --git a/src/ui/controls/list_item.cpp b/src/ui/controls/list_item.cpp
index 25dd49a8..bdd44273 100644
--- a/src/ui/controls/list_item.cpp
+++ b/src/ui/controls/list_item.cpp
@@ -1,6 +1,62 @@
#include "list_item.hpp"
+#include "ui/ui_manager.hpp"
+#include "ui/convert_util.hpp"
+
namespace cru::ui::controls
{
-
+ ListItem::ListItem() : Control(true)
+ {
+ const auto predefine_resources = UiManager::GetInstance()->GetPredefineResources();
+
+ brushes_[State::Normal].border_brush = predefine_resources->list_item_normal_border_brush;
+ brushes_[State::Normal].fill_brush = predefine_resources->list_item_normal_fill_brush;
+ brushes_[State::Hover] .border_brush = predefine_resources->list_item_hover_border_brush;
+ brushes_[State::Hover] .fill_brush = predefine_resources->list_item_hover_fill_brush;
+ brushes_[State::Select].border_brush = predefine_resources->list_item_select_border_brush;
+ brushes_[State::Select].fill_brush = predefine_resources->list_item_select_fill_brush;
+ }
+
+ StringView ListItem::GetControlType() const
+ {
+ return control_type;
+ }
+
+ void ListItem::SetState(const State state)
+ {
+ state_ = state;
+ Repaint();
+ }
+
+ void ListItem::OnDrawForeground(ID2D1DeviceContext* device_context)
+ {
+ const auto rect = Rect(Point::Zero(), GetRect(RectRange::Padding).GetSize());
+ device_context->FillRectangle(Convert(rect), brushes_[state_].fill_brush.Get());
+ device_context->DrawRectangle(Convert(rect.Shrink(Thickness(0.5))), brushes_[state_].border_brush.Get(), 1);
+ }
+
+ void ListItem::OnMouseEnterCore(events::MouseEventArgs& args)
+ {
+ if (GetState() == State::Select)
+ return;
+
+ if (IsAnyMouseButtonDown())
+ return;
+
+ SetState(State::Hover);
+ }
+
+ void ListItem::OnMouseLeaveCore(events::MouseEventArgs& args)
+ {
+ if (GetState() == State::Select)
+ return;
+
+ SetState(State::Normal);
+ }
+
+ void ListItem::OnMouseClickCore(events::MouseButtonEventArgs& args)
+ {
+ if (args.GetMouseButton() == MouseButton::Left)
+ SetState(State::Select);
+ }
}
diff --git a/src/ui/controls/list_item.hpp b/src/ui/controls/list_item.hpp
index 8525e0e8..1de89b5f 100644
--- a/src/ui/controls/list_item.hpp
+++ b/src/ui/controls/list_item.hpp
@@ -1,5 +1,8 @@
#pragma once
+#include <map>
+#include <initializer_list>
+
#include "ui/control.hpp"
namespace cru::ui::controls
@@ -9,8 +12,29 @@ namespace cru::ui::controls
public:
static constexpr auto control_type = L"ListItem";
+ enum class State
+ {
+ Normal,
+ Hover,
+ Select
+ };
+
+ private:
+ struct StateBrush
+ {
+ Microsoft::WRL::ComPtr<ID2D1Brush> border_brush;
+ Microsoft::WRL::ComPtr<ID2D1Brush> fill_brush;
+ };
+
public:
- static ListItem* Create();
+ static ListItem* Create(const std::initializer_list<Control*>& children)
+ {
+ const auto list_item = new ListItem();
+ for (auto control : children)
+ list_item->AddChild(control);
+ return list_item;
+ }
+
private:
ListItem();
public:
@@ -19,5 +43,25 @@ namespace cru::ui::controls
ListItem& operator=(const ListItem& other) = delete;
ListItem& operator=(ListItem&& other) = delete;
~ListItem() override = default;
+
+ StringView GetControlType() const override;
+
+ State GetState() const
+ {
+ return state_;
+ }
+
+ void SetState(State state);
+
+ protected:
+ void OnDrawForeground(ID2D1DeviceContext* device_context) override;
+
+ void OnMouseEnterCore(events::MouseEventArgs& args) override final;
+ void OnMouseLeaveCore(events::MouseEventArgs& args) override final;
+ void OnMouseClickCore(events::MouseButtonEventArgs& args) override final;
+
+ private:
+ State state_ = State::Normal;
+ std::map<State, StateBrush> brushes_{};
};
}
diff --git a/src/ui/convert_util.hpp b/src/ui/convert_util.hpp
new file mode 100644
index 00000000..1c18f59b
--- /dev/null
+++ b/src/ui/convert_util.hpp
@@ -0,0 +1,13 @@
+#pragma once
+
+#include "system_headers.hpp"
+
+#include "ui_base.hpp"
+
+namespace cru::ui
+{
+ inline D2D1_RECT_F Convert(const Rect& rect)
+ {
+ return D2D1::RectF(rect.left, rect.top, rect.left + rect.width, rect.top + rect.height);
+ }
+}
diff --git a/src/ui/layout_base.hpp b/src/ui/layout_base.hpp
index 512301b7..d8e4e2d1 100644
--- a/src/ui/layout_base.hpp
+++ b/src/ui/layout_base.hpp
@@ -33,45 +33,6 @@ namespace cru::ui
Margin // including content, padding, border and margin
};
- struct Thickness
- {
- constexpr static Thickness Zero()
- {
- return Thickness(0);
- }
-
- constexpr Thickness() : Thickness(0) { }
-
- constexpr explicit Thickness(const float width)
- : left(width), top(width), right(width), bottom(width) { }
-
- constexpr explicit Thickness(const float horizontal, const float vertical)
- : left(horizontal), top(vertical), right(horizontal), bottom(vertical) { }
-
- constexpr Thickness(const float left, const float top, const float right, const float bottom)
- : left(left), top(top), right(right), bottom(bottom) { }
-
- float GetHorizontalTotal() const
- {
- return left + right;
- }
-
- float GetVerticalTotal() const
- {
- return top + bottom;
- }
-
- float Validate() const
- {
- return left >= 0.0 && top >= 0.0 && right >= 0.0 && bottom >= 0.0;
- }
-
- float left;
- float top;
- float right;
- float bottom;
- };
-
struct LayoutSideParams final
{
constexpr static LayoutSideParams Exactly(const float length, const Alignment alignment = Alignment::Center)
diff --git a/src/ui/ui_base.cpp b/src/ui/ui_base.cpp
index b52694e7..c91fcd7b 100644
--- a/src/ui/ui_base.cpp
+++ b/src/ui/ui_base.cpp
@@ -15,4 +15,9 @@ namespace cru::ui
const auto result = ::GetKeyState(virtual_code);
return (static_cast<unsigned short>(result) & 1) != 0;
}
+
+ bool IsAnyMouseButtonDown()
+ {
+ return IsKeyDown(VK_LBUTTON) || IsKeyDown(VK_RBUTTON) || IsKeyDown(VK_MBUTTON);
+ }
}
diff --git a/src/ui/ui_base.hpp b/src/ui/ui_base.hpp
index 8daa43d7..c20d44b6 100644
--- a/src/ui/ui_base.hpp
+++ b/src/ui/ui_base.hpp
@@ -63,6 +63,45 @@ namespace cru::ui
return !(left == right);
}
+ struct Thickness
+ {
+ constexpr static Thickness Zero()
+ {
+ return Thickness(0);
+ }
+
+ constexpr Thickness() : Thickness(0) { }
+
+ constexpr explicit Thickness(const float width)
+ : left(width), top(width), right(width), bottom(width) { }
+
+ constexpr explicit Thickness(const float horizontal, const float vertical)
+ : left(horizontal), top(vertical), right(horizontal), bottom(vertical) { }
+
+ constexpr Thickness(const float left, const float top, const float right, const float bottom)
+ : left(left), top(top), right(right), bottom(bottom) { }
+
+ float GetHorizontalTotal() const
+ {
+ return left + right;
+ }
+
+ float GetVerticalTotal() const
+ {
+ return top + bottom;
+ }
+
+ float Validate() const
+ {
+ return left >= 0.0 && top >= 0.0 && right >= 0.0 && bottom >= 0.0;
+ }
+
+ float left;
+ float top;
+ float right;
+ float bottom;
+ };
+
struct Rect
{
constexpr Rect() = default;
@@ -101,6 +140,11 @@ namespace cru::ui
return Size(width, height);
}
+ constexpr Rect Shrink(const Thickness& thickness) const
+ {
+ return Rect(left + thickness.left, top + thickness.top, width - thickness.GetHorizontalTotal(), height - thickness.GetVerticalTotal());
+ }
+
constexpr bool IsPointInside(const Point& point) const
{
return
@@ -154,4 +198,5 @@ namespace cru::ui
bool IsKeyDown(int virtual_code);
bool IsKeyToggled(int virtual_code);
+ bool IsAnyMouseButtonDown();
}
diff --git a/src/ui/ui_manager.cpp b/src/ui/ui_manager.cpp
index 3918b2d5..d803e0cb 100644
--- a/src/ui/ui_manager.cpp
+++ b/src/ui/ui_manager.cpp
@@ -52,29 +52,36 @@ namespace cru::ui
//!!! never use default constructor of border at here, because it will recursively call this method!
PredefineResources::PredefineResources(graph::GraphManager* graph_manager) :
- border_property_brush{CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::Black))},
+ border_property_brush {CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::Black))},
- button_normal_border{CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::RoyalBlue)), 2, 6, 6},
- button_press_border{CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::Blue)), 2, 6, 6},
+ button_normal_border {CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::RoyalBlue)), 2, 6, 6},
+ button_press_border {CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::Blue)), 2, 6, 6},
- text_control_selection_brush{CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::LightSkyBlue))},
+ text_control_selection_brush {CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::LightSkyBlue))},
- text_box_border{CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::Black))},
- text_box_text_brush{CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::Black))},
- text_box_text_format{CreateDefaultTextFormat(graph_manager)},
- text_box_caret_brush{CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::Black))},
+ text_box_border {CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::Black))},
+ text_box_text_brush {CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::Black))},
+ text_box_text_format {CreateDefaultTextFormat(graph_manager)},
+ text_box_caret_brush {CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::Black))},
- text_block_text_brush{CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::Black))},
- text_block_text_format{CreateDefaultTextFormat(graph_manager)},
+ text_block_text_brush {CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::Black))},
+ text_block_text_format {CreateDefaultTextFormat(graph_manager)},
- toggle_button_on_brush{CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::DeepSkyBlue))},
- toggle_button_off_brush{CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::LightGray))}
+ toggle_button_on_brush {CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::DeepSkyBlue))},
+ toggle_button_off_brush {CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::LightGray))},
+
+ list_item_normal_border_brush {CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::White, 0))},
+ list_item_normal_fill_brush {CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::White, 0))},
+ list_item_hover_border_brush {CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::SkyBlue))},
+ list_item_hover_fill_brush {CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::SkyBlue, 0.3))},
+ list_item_select_border_brush {CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::MediumBlue))},
+ list_item_select_fill_brush {CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::SkyBlue, 0.3))}
#ifdef CRU_DEBUG_LAYOUT
,
- debug_layout_out_border_brush{CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::Crimson))},
- debug_layout_margin_brush{CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::LightCoral, 0.25f))},
- debug_layout_padding_brush{CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::SkyBlue, 0.25f))}
+ debug_layout_out_border_brush {CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::Crimson))},
+ debug_layout_margin_brush {CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::LightCoral, 0.25f))},
+ debug_layout_padding_brush {CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::SkyBlue, 0.25f))}
#endif
{
diff --git a/src/ui/ui_manager.hpp b/src/ui/ui_manager.hpp
index 753da907..6b368e12 100644
--- a/src/ui/ui_manager.hpp
+++ b/src/ui/ui_manager.hpp
@@ -53,6 +53,15 @@ namespace cru::ui
Microsoft::WRL::ComPtr<ID2D1Brush> toggle_button_on_brush;
Microsoft::WRL::ComPtr<ID2D1Brush> toggle_button_off_brush;
+ //region ListItem
+ Microsoft::WRL::ComPtr<ID2D1Brush> list_item_normal_border_brush;
+ Microsoft::WRL::ComPtr<ID2D1Brush> list_item_normal_fill_brush;
+ Microsoft::WRL::ComPtr<ID2D1Brush> list_item_hover_border_brush;
+ Microsoft::WRL::ComPtr<ID2D1Brush> list_item_hover_fill_brush;
+ Microsoft::WRL::ComPtr<ID2D1Brush> list_item_select_border_brush;
+ Microsoft::WRL::ComPtr<ID2D1Brush> list_item_select_fill_brush;
+
+
#ifdef CRU_DEBUG_LAYOUT
//region debug
Microsoft::WRL::ComPtr<ID2D1Brush> debug_layout_out_border_brush;