aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2018-11-25 17:50:12 +0800
committercrupest <crupest@outlook.com>2018-11-25 17:50:12 +0800
commit5391e781e4682731721c841462904809bc618870 (patch)
treee1315ff02ebdf63b80f2eb9e6a1f43a44a313249
parentabc776a9ea02a564dfe44141e51e4cbc87a7a3a1 (diff)
downloadcru-5391e781e4682731721c841462904809bc618870.tar.gz
cru-5391e781e4682731721c841462904809bc618870.tar.bz2
cru-5391e781e4682731721c841462904809bc618870.zip
Change clip to padding into clip content.
-rw-r--r--src/ui/control.cpp92
-rw-r--r--src/ui/control.hpp24
-rw-r--r--src/ui/controls/scroll_control.cpp2
-rw-r--r--src/ui/controls/text_control.cpp2
4 files changed, 80 insertions, 40 deletions
diff --git a/src/ui/control.cpp b/src/ui/control.cpp
index 22b7164f..66f22c58 100644
--- a/src/ui/control.cpp
+++ b/src/ui/control.cpp
@@ -191,20 +191,21 @@ namespace cru::ui
bool Control::IsPointInside(const Point & point)
{
- if (border_geometry_ != nullptr)
+ const auto border_geometry = geometry_info_.border_geometry;
+ if (border_geometry != nullptr)
{
if (IsBordered())
{
BOOL contains;
- border_geometry_->FillContainsPoint(Convert(point), D2D1::Matrix3x2F::Identity(), &contains);
+ border_geometry->FillContainsPoint(Convert(point), D2D1::Matrix3x2F::Identity(), &contains);
if (!contains)
- border_geometry_->StrokeContainsPoint(Convert(point), GetBorderProperty().GetStrokeWidth(), nullptr, D2D1::Matrix3x2F::Identity(), &contains);
+ border_geometry->StrokeContainsPoint(Convert(point), GetBorderProperty().GetStrokeWidth(), nullptr, D2D1::Matrix3x2F::Identity(), &contains);
return contains != 0;
}
else
{
BOOL contains;
- border_geometry_->FillContainsPoint(Convert(point), D2D1::Matrix3x2F::Identity(), &contains);
+ border_geometry->FillContainsPoint(Convert(point), D2D1::Matrix3x2F::Identity(), &contains);
return contains != 0;
}
}
@@ -215,8 +216,18 @@ namespace cru::ui
{
const auto point_inside = IsPointInside(point);
- if (!point_inside && IsClipToPadding())
- return nullptr; // if clip then don't test children.
+ if (IsClipContent())
+ {
+ if (!point_inside)
+ return nullptr;
+ if (geometry_info_.content_geometry != nullptr)
+ {
+ BOOL contains;
+ ThrowIfFailed(geometry_info_.content_geometry->FillContainsPoint(Convert(point), D2D1::Matrix3x2F::Identity(), &contains));
+ if (contains == 0)
+ return this;
+ }
+ }
const auto& children = GetChildren();
@@ -229,18 +240,15 @@ namespace cru::ui
return child_hit_test_result;
}
- if (!point_inside)
- return nullptr;
-
- return this;
+ return point_inside ? this : nullptr;
}
- void Control::SetClipToPadding(const bool clip)
+ void Control::SetClipContent(const bool clip)
{
- if (clip_to_padding_ == clip)
+ if (clip_content_ == clip)
return;
- clip_to_padding_ = clip;
+ clip_content_ = clip;
InvalidateDraw();
}
@@ -254,9 +262,9 @@ namespace cru::ui
OnDrawDecoration(device_context);
- const auto set_layer = in_border_geometry_ != nullptr && IsClipToPadding();
+ const auto set_layer = geometry_info_.content_geometry != nullptr && IsClipContent();
if (set_layer)
- device_context->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(), in_border_geometry_.Get()), nullptr);
+ device_context->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(), geometry_info_.content_geometry.Get()), nullptr);
OnDrawCore(device_context);
@@ -377,7 +385,7 @@ namespace cru::ui
void Control::UpdateBorder()
{
- RegenerateBorderGeometry();
+ RegenerateGeometries();
InvalidateLayout();
InvalidateDraw();
}
@@ -447,9 +455,9 @@ namespace cru::ui
}
#endif
- if (is_bordered_ && border_geometry_ != nullptr)
+ if (is_bordered_ && geometry_info_.border_geometry != nullptr)
device_context->DrawGeometry(
- border_geometry_.Get(),
+ geometry_info_.border_geometry.Get(),
GetBorderProperty().GetBrush().Get(),
GetBorderProperty().GetStrokeWidth(),
GetBorderProperty().GetStrokeStyle().Get()
@@ -458,9 +466,10 @@ namespace cru::ui
void Control::OnDrawCore(ID2D1DeviceContext* device_context)
{
+ const auto ground_geometry = geometry_info_.padding_content_geometry;
//draw background.
- if (in_border_geometry_ != nullptr && background_brush_ != nullptr)
- device_context->FillGeometry(in_border_geometry_.Get(), background_brush_.Get());
+ if (ground_geometry != nullptr && background_brush_ != nullptr)
+ device_context->FillGeometry(ground_geometry.Get(), background_brush_.Get());
const auto padding_rect = GetRect(RectRange::Padding);
graph::WithTransform(device_context, D2D1::Matrix3x2F::Translation(padding_rect.left, padding_rect.top),
[this](ID2D1DeviceContext* device_context)
@@ -482,8 +491,8 @@ namespace cru::ui
//draw foreground.
- if (in_border_geometry_ != nullptr && foreground_brush_ != nullptr)
- device_context->FillGeometry(in_border_geometry_.Get(), foreground_brush_.Get());
+ if (ground_geometry != nullptr && foreground_brush_ != nullptr)
+ device_context->FillGeometry(ground_geometry.Get(), foreground_brush_.Get());
graph::WithTransform(device_context, D2D1::Matrix3x2F::Translation(padding_rect.left, padding_rect.top),
[this](ID2D1DeviceContext* device_context)
{
@@ -545,7 +554,7 @@ namespace cru::ui
void Control::OnSizeChangedCore(SizeChangedEventArgs & args)
{
- RegenerateBorderGeometry();
+ RegenerateGeometries();
#ifdef CRU_DEBUG_LAYOUT
margin_geometry_ = CalculateSquareRingGeometry(GetRect(RectRange::Margin), GetRect(RectRange::FullBorder));
padding_geometry_ = CalculateSquareRingGeometry(GetRect(RectRange::Padding), GetRect(RectRange::Content));
@@ -566,7 +575,7 @@ namespace cru::ui
size_changed_event.Raise(args);
}
- void Control::RegenerateBorderGeometry()
+ void Control::RegenerateGeometries()
{
if (IsBordered())
{
@@ -579,10 +588,10 @@ namespace cru::ui
ThrowIfFailed(
graph::GraphManager::GetInstance()->GetD2D1Factory()->CreateRoundedRectangleGeometry(bound_rounded_rect, &geometry)
);
- border_geometry_ = std::move(geometry);
+ geometry_info_.border_geometry = std::move(geometry);
- const auto in_border_rect = GetRect(RectRange::Padding);
- const auto in_border_rounded_rect = D2D1::RoundedRect(Convert(in_border_rect),
+ const auto padding_rect = GetRect(RectRange::Padding);
+ const auto in_border_rounded_rect = D2D1::RoundedRect(Convert(padding_rect),
GetBorderProperty().GetRadiusX() - GetBorderProperty().GetStrokeWidth() / 2.0f,
GetBorderProperty().GetRadiusY() - GetBorderProperty().GetStrokeWidth() / 2.0f);
@@ -590,7 +599,24 @@ namespace cru::ui
ThrowIfFailed(
graph::GraphManager::GetInstance()->GetD2D1Factory()->CreateRoundedRectangleGeometry(in_border_rounded_rect, &geometry2)
);
- in_border_geometry_ = std::move(geometry2);
+ geometry_info_.padding_content_geometry = geometry2;
+
+
+ Microsoft::WRL::ComPtr<ID2D1RectangleGeometry> geometry3;
+ ThrowIfFailed(
+ graph::GraphManager::GetInstance()->GetD2D1Factory()->CreateRectangleGeometry(Convert(GetRect(RectRange::Content)), &geometry3)
+ );
+ Microsoft::WRL::ComPtr<ID2D1PathGeometry> geometry4;
+ ThrowIfFailed(
+ graph::GraphManager::GetInstance()->GetD2D1Factory()->CreatePathGeometry(&geometry4)
+ );
+ Microsoft::WRL::ComPtr<ID2D1GeometrySink> sink;
+ geometry4->Open(&sink);
+ ThrowIfFailed(
+ geometry3->CombineWithGeometry(geometry2.Get(), D2D1_COMBINE_MODE_INTERSECT, D2D1::Matrix3x2F::Identity(), sink.Get())
+ );
+ sink->Close();
+ geometry_info_.content_geometry = std::move(geometry4);
}
else
{
@@ -599,8 +625,14 @@ namespace cru::ui
ThrowIfFailed(
graph::GraphManager::GetInstance()->GetD2D1Factory()->CreateRectangleGeometry(Convert(bound_rect), &geometry)
);
- border_geometry_ = geometry;
- in_border_geometry_ = std::move(geometry);
+ geometry_info_.border_geometry = geometry;
+ geometry_info_.padding_content_geometry = std::move(geometry);
+
+ Microsoft::WRL::ComPtr<ID2D1RectangleGeometry> geometry2;
+ ThrowIfFailed(
+ graph::GraphManager::GetInstance()->GetD2D1Factory()->CreateRectangleGeometry(Convert(GetRect(RectRange::Content)), &geometry2)
+ );
+ geometry_info_.content_geometry = std::move(geometry2);
}
}
diff --git a/src/ui/control.hpp b/src/ui/control.hpp
index 44c98728..6c5b0ea5 100644
--- a/src/ui/control.hpp
+++ b/src/ui/control.hpp
@@ -26,11 +26,21 @@ namespace cru::ui
Point lefttop_position_absolute;
};
+
class Control : public Object
{
friend class Window;
friend class LayoutManager;
+ private:
+ struct GeometryInfo
+ {
+ Microsoft::WRL::ComPtr<ID2D1Geometry> border_geometry = nullptr;
+ Microsoft::WRL::ComPtr<ID2D1Geometry> padding_content_geometry = nullptr;
+ Microsoft::WRL::ComPtr<ID2D1Geometry> content_geometry = nullptr;
+ };
+
+
protected:
struct WindowConstructorTag {}; //Used for constructor for class Window.
@@ -126,12 +136,12 @@ namespace cru::ui
//*************** region: graphic ***************
- bool IsClipToPadding() const
+ bool IsClipContent() const
{
- return clip_to_padding_;
+ return clip_content_;
}
- void SetClipToPadding(bool clip);
+ void SetClipContent(bool clip);
//Draw this control and its child controls.
void Draw(ID2D1DeviceContext* device_context);
@@ -299,7 +309,7 @@ namespace cru::ui
void RaisePositionChangedEvent(events::PositionChangedEventArgs& args);
void RaiseSizeChangedEvent(events::SizeChangedEventArgs& args);
- void RegenerateBorderGeometry();
+ void RegenerateGeometries();
//*************** region: mouse event ***************
virtual void OnMouseEnter(events::MouseEventArgs& args);
@@ -403,11 +413,9 @@ namespace cru::ui
bool is_bordered_ = false;
BorderProperty border_property_;
- bool clip_to_padding_ = false;
+ GeometryInfo geometry_info_{};
- Microsoft::WRL::ComPtr<ID2D1Geometry> border_geometry_ = nullptr;
- // used for foreground and background brush and clip.
- Microsoft::WRL::ComPtr<ID2D1Geometry> in_border_geometry_ = nullptr;
+ bool clip_content_ = false;
Microsoft::WRL::ComPtr<ID2D1Brush> foreground_brush_ = nullptr;
Microsoft::WRL::ComPtr<ID2D1Brush> background_brush_ = nullptr;
diff --git a/src/ui/controls/scroll_control.cpp b/src/ui/controls/scroll_control.cpp
index 00969ab7..6b6d899c 100644
--- a/src/ui/controls/scroll_control.cpp
+++ b/src/ui/controls/scroll_control.cpp
@@ -9,7 +9,7 @@ namespace cru::ui::controls
{
ScrollControl::ScrollControl(const bool container) : Control(container)
{
- SetClipToPadding(true);
+ SetClipContent(true);
}
ScrollControl::~ScrollControl()
diff --git a/src/ui/controls/text_control.cpp b/src/ui/controls/text_control.cpp
index c37441b3..d7d6b810 100644
--- a/src/ui/controls/text_control.cpp
+++ b/src/ui/controls/text_control.cpp
@@ -20,7 +20,7 @@ namespace cru::ui::controls
selection_brush_ = UiManager::GetInstance()->GetPredefineResources()->text_control_selection_brush;
- SetClipToPadding(true);
+ SetClipContent(true);
}