diff options
author | crupest <crupest@outlook.com> | 2018-11-25 23:19:48 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2018-11-25 23:19:48 +0800 |
commit | 7e00386fc0895f8b08cd64ef737cb6c618955635 (patch) | |
tree | adc302dc67e4a1e520d9a78080200e5df1ed69b7 /CruUI-Generate/cru_ui.cpp | |
parent | b88992fd00df7b8c243bc0e7d577ef2aa9437c3f (diff) | |
download | cru-7e00386fc0895f8b08cd64ef737cb6c618955635.tar.gz cru-7e00386fc0895f8b08cd64ef737cb6c618955635.tar.bz2 cru-7e00386fc0895f8b08cd64ef737cb6c618955635.zip |
Generate merged code.
Diffstat (limited to 'CruUI-Generate/cru_ui.cpp')
-rw-r--r-- | CruUI-Generate/cru_ui.cpp | 512 |
1 files changed, 466 insertions, 46 deletions
diff --git a/CruUI-Generate/cru_ui.cpp b/CruUI-Generate/cru_ui.cpp index ecfeec7d..043eef5d 100644 --- a/CruUI-Generate/cru_ui.cpp +++ b/CruUI-Generate/cru_ui.cpp @@ -260,6 +260,7 @@ namespace cru //-------begin of file: src\main.cpp //-------------------------------------------------------- + using cru::String; using cru::StringView; using cru::Application; @@ -277,6 +278,7 @@ using cru::ui::controls::Button; using cru::ui::controls::TextBox; using cru::ui::controls::ListItem; using cru::ui::controls::FrameLayout; +using cru::ui::controls::ScrollControl; int APIENTRY wWinMain( HINSTANCE hInstance, @@ -284,6 +286,10 @@ int APIENTRY wWinMain( LPWSTR lpCmdLine, int nCmdShow) { +#ifdef CRU_DEBUG + _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); +#endif + Application application(hInstance); const auto window = Window::CreateOverlapped(); @@ -433,9 +439,16 @@ int APIENTRY wWinMain( } { - const auto text_block = CreateWithLayout<TextBlock>(LayoutSideParams::Stretch(), LayoutSideParams::Stretch(), L"This is a very very very very very long sentence!!!"); + const auto scroll_view = CreateWithLayout<ScrollControl>(LayoutSideParams::Stretch(), LayoutSideParams::Stretch()); + + scroll_view->SetVerticalScrollBarVisibility(ScrollControl::ScrollBarVisibility::Always); + + const auto text_block = TextBlock::Create( + L"Love myself I do. Not everything, but I love the good as well as the bad. I love my crazy lifestyle, and I love my hard discipline. I love my freedom of speech and the way my eyes get dark when I'm tired. I love that I have learned to trust people with my heart, even if it will get broken. I am proud of everything that I am and will become."); text_block->SetSelectable(true); - layout->AddChild(text_block); + + scroll_view->AddChild(text_block); + layout->AddChild(scroll_view); } layout->AddChild(CreateWithLayout<TextBlock>(LayoutSideParams::Content(Alignment::Start), LayoutSideParams::Content(), L"This is a little short sentence!!!")); @@ -466,7 +479,6 @@ int APIENTRY wWinMain( window.AddChild(linear_layout); */ - window->Show(); return application.Run(); @@ -985,20 +997,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; } } @@ -1009,8 +1022,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(); @@ -1023,18 +1046,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(); } @@ -1048,9 +1068,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); @@ -1102,6 +1122,7 @@ namespace cru::ui { SetPositionRelative(rect.GetLeftTop()); SetSize(rect.GetSize()); + AfterLayoutSelf(); OnLayoutCore(Rect(Point::Zero(), rect.GetSize())); } @@ -1171,7 +1192,7 @@ namespace cru::ui void Control::UpdateBorder() { - RegenerateBorderGeometry(); + RegenerateGeometryInfo(); InvalidateLayout(); InvalidateDraw(); } @@ -1241,9 +1262,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() @@ -1252,9 +1273,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) @@ -1276,8 +1298,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) { @@ -1339,7 +1361,7 @@ namespace cru::ui void Control::OnSizeChangedCore(SizeChangedEventArgs & args) { - RegenerateBorderGeometry(); + RegenerateGeometryInfo(); #ifdef CRU_DEBUG_LAYOUT margin_geometry_ = CalculateSquareRingGeometry(GetRect(RectRange::Margin), GetRect(RectRange::FullBorder)); padding_geometry_ = CalculateSquareRingGeometry(GetRect(RectRange::Padding), GetRect(RectRange::Content)); @@ -1360,7 +1382,7 @@ namespace cru::ui size_changed_event.Raise(args); } - void Control::RegenerateBorderGeometry() + void Control::RegenerateGeometryInfo() { if (IsBordered()) { @@ -1373,10 +1395,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); @@ -1384,7 +1406,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 { @@ -1393,8 +1432,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); } } @@ -1671,7 +1716,7 @@ namespace cru::ui auto parent = GetParent(); while (parent != nullptr) { - auto lp = parent->GetLayoutParams(); + const auto lp = parent->GetLayoutParams(); if (!stretch_width_determined) { @@ -1806,6 +1851,11 @@ namespace cru::ui } } + void Control::AfterLayoutSelf() + { + + } + void Control::CheckAndNotifyPositionChanged() { if (this->old_position_ != this->position_) @@ -2103,7 +2153,11 @@ namespace cru::ui 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.3f))}, 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.3f))} + list_item_select_fill_brush {CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::SkyBlue, 0.3f))}, + + scroll_bar_background_brush {CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::Gainsboro, 0.3f))}, + scroll_bar_border_brush {CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::DimGray))}, + scroll_bar_brush {CreateSolidBrush(graph_manager, D2D1::ColorF(D2D1::ColorF::DimGray))} #ifdef CRU_DEBUG_LAYOUT , @@ -3139,6 +3193,7 @@ namespace cru::ui::controls #include <algorithm> + namespace cru::ui::controls { LinearLayout::LinearLayout(const Orientation orientation) @@ -3147,16 +3202,6 @@ namespace cru::ui::controls } - 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)); - } - StringView LinearLayout::GetControlType() const { return control_type; @@ -3421,6 +3466,381 @@ namespace cru::ui::controls //-------end of file: src\ui\controls\popup_menu.cpp //-------------------------------------------------------- //-------------------------------------------------------- +//-------begin of file: src\ui\controls\scroll_control.cpp +//-------------------------------------------------------- + +#include <limits> + + +namespace cru::ui::controls +{ + constexpr auto scroll_bar_width = 15.0f; + + ScrollControl::ScrollControl(const bool container) : Control(container) + { + SetClipContent(true); + } + + ScrollControl::~ScrollControl() + { + + } + + StringView ScrollControl::GetControlType() const + { + return control_type; + } + + void ScrollControl::SetHorizontalScrollEnabled(const bool enable) + { + horizontal_scroll_enabled_ = enable; + InvalidateLayout(); + InvalidateDraw(); + } + + void ScrollControl::SetVerticalScrollEnabled(const bool enable) + { + vertical_scroll_enabled_ = enable; + InvalidateLayout(); + InvalidateDraw(); + } + + void ScrollControl::SetHorizontalScrollBarVisibility(const ScrollBarVisibility visibility) + { + if (visibility != horizontal_scroll_bar_visibility_) + { + horizontal_scroll_bar_visibility_ = visibility; + switch (visibility) + { + case ScrollBarVisibility::Always: + is_horizontal_scroll_bar_visible_ = true; + break; + case ScrollBarVisibility::None: + is_horizontal_scroll_bar_visible_ = false; + break; + case ScrollBarVisibility::Auto: + UpdateScrollBarVisibility(); + } + InvalidateDraw(); + } + } + + void ScrollControl::SetVerticalScrollBarVisibility(const ScrollBarVisibility visibility) + { + if (visibility != vertical_scroll_bar_visibility_) + { + vertical_scroll_bar_visibility_ = visibility; + switch (visibility) + { + case ScrollBarVisibility::Always: + is_vertical_scroll_bar_visible_ = true; + break; + case ScrollBarVisibility::None: + is_vertical_scroll_bar_visible_ = false; + break; + case ScrollBarVisibility::Auto: + UpdateScrollBarVisibility(); + } + InvalidateDraw(); + } + + } + + void ScrollControl::SetScrollOffset(std::optional<float> x, std::optional<float> y) + { + CoerceAndSetOffsets(x.value_or(GetScrollOffsetX()), y.value_or(GetScrollOffsetY())); + } + + void ScrollControl::SetViewWidth(const float length) + { + view_width_ = length; + } + + void ScrollControl::SetViewHeight(const float length) + { + view_height_ = length; + } + + Size ScrollControl::OnMeasureContent(const Size& available_size) + { + const auto layout_params = GetLayoutParams(); + + auto available_size_for_children = available_size; + if (IsHorizontalScrollEnabled()) + { + 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(); + } + + if (IsVerticalScrollEnabled()) + { + 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); + 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; + } + + // coerce size fro stretch. + for (auto control: GetChildren()) + { + auto size = control->GetDesiredSize(); + const auto child_layout_params = control->GetLayoutParams(); + if (child_layout_params->width.mode == MeasureMode::Stretch) + size.width = max_child_size.width; + if (child_layout_params->height.mode == MeasureMode::Stretch) + size.height = max_child_size.height; + control->SetDesiredSize(size); + } + + auto result = max_child_size; + if (IsHorizontalScrollEnabled()) + { + SetViewWidth(max_child_size.width); + result.width = available_size.width; + } + if (IsVerticalScrollEnabled()) + { + SetViewHeight(max_child_size.height); + result.height = available_size.height; + } + + return result; + } + + void ScrollControl::OnLayoutContent(const Rect& rect) + { + auto layout_rect = rect; + + if (IsHorizontalScrollEnabled()) + layout_rect.width = GetViewWidth(); + if (IsVerticalScrollEnabled()) + layout_rect.height = GetViewHeight(); + + for (auto control: GetChildren()) + { + const auto size = control->GetDesiredSize(); + // Ignore alignment, always center aligned. + auto&& calculate_anchor = [](const float anchor, const float layout_length, const float control_length, const float offset) -> float + { + return anchor + (layout_length - control_length) / 2 - offset; + }; + + 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)); + } + } + + void ScrollControl::AfterLayoutSelf() + { + UpdateScrollBarBorderInfo(); + CoerceAndSetOffsets(offset_x_, offset_y_, false); + UpdateScrollBarVisibility(); + } + + void ScrollControl::OnDrawForeground(ID2D1DeviceContext* device_context) + { + Control::OnDrawForeground(device_context); + + const auto predefined = UiManager::GetInstance()->GetPredefineResources(); + + if (is_horizontal_scroll_bar_visible_) + { + device_context->FillRectangle( + Convert(horizontal_bar_info_.border), + predefined->scroll_bar_background_brush.Get() + ); + + device_context->FillRectangle( + Convert(horizontal_bar_info_.bar), + predefined->scroll_bar_brush.Get() + ); + + device_context->DrawLine( + Convert(horizontal_bar_info_.border.GetLeftTop()), + Convert(horizontal_bar_info_.border.GetRightTop()), + predefined->scroll_bar_border_brush.Get() + ); + } + + if (is_vertical_scroll_bar_visible_) + { + device_context->FillRectangle( + Convert(vertical_bar_info_.border), + predefined->scroll_bar_background_brush.Get() + ); + + device_context->FillRectangle( + Convert(vertical_bar_info_.bar), + predefined->scroll_bar_brush.Get() + ); + + device_context->DrawLine( + Convert(vertical_bar_info_.border.GetLeftTop()), + Convert(vertical_bar_info_.border.GetLeftBottom()), + predefined->scroll_bar_border_brush.Get() + ); + } + } + + void ScrollControl::OnMouseDownCore(events::MouseButtonEventArgs& args) + { + Control::OnMouseDownCore(args); + + if (args.GetMouseButton() == MouseButton::Left) + { + const auto point = args.GetPoint(this); + if (is_vertical_scroll_bar_visible_ && vertical_bar_info_.bar.IsPointInside(point)) + { + GetWindow()->CaptureMouseFor(this); + is_pressing_scroll_bar_ = Orientation::Vertical; + pressing_delta_ = point.y - vertical_bar_info_.bar.top; + return; + } + + if (is_horizontal_scroll_bar_visible_ && horizontal_bar_info_.bar.IsPointInside(point)) + { + GetWindow()->CaptureMouseFor(this); + pressing_delta_ = point.x - horizontal_bar_info_.bar.left; + is_pressing_scroll_bar_ = Orientation::Horizontal; + return; + } + } + } + + void ScrollControl::OnMouseMoveCore(events::MouseEventArgs& args) + { + Control::OnMouseMoveCore(args); + + const auto mouse_point = args.GetPoint(this); + + if (is_pressing_scroll_bar_ == Orientation::Horizontal) + { + const auto new_head_position = mouse_point.x - pressing_delta_; + const auto new_offset = new_head_position / horizontal_bar_info_.border.width * view_width_; + SetScrollOffset(new_offset, std::nullopt); + return; + } + + if (is_pressing_scroll_bar_ == Orientation::Vertical) + { + const auto new_head_position = mouse_point.y - pressing_delta_; + const auto new_offset = new_head_position / vertical_bar_info_.border.height * view_height_; + SetScrollOffset(std::nullopt, new_offset); + return; + } + } + + void ScrollControl::OnMouseUpCore(events::MouseButtonEventArgs& args) + { + Control::OnMouseUpCore(args); + + if (args.GetMouseButton() == MouseButton::Left && is_pressing_scroll_bar_.has_value()) + { + GetWindow()->ReleaseCurrentMouseCapture(); + is_pressing_scroll_bar_ = std::nullopt; + } + } + + void ScrollControl::CoerceAndSetOffsets(const float offset_x, const float offset_y, const bool update_children) + { + const auto old_offset_x = offset_x_; + const auto old_offset_y = offset_y_; + + const auto content_rect = GetRect(RectRange::Content); + offset_x_ = Coerce(offset_x, 0.0f, AtLeast0(view_width_ - content_rect.width)); + offset_y_ = Coerce(offset_y, 0.0f, AtLeast0(view_height_ - content_rect.height)); + UpdateScrollBarBarInfo(); + + if (update_children) + { + for (auto child : GetChildren()) + { + const auto old_position = child->GetPositionRelative(); + child->SetPositionRelative(Point( + old_position.x + old_offset_x - offset_x_, + old_position.y + old_offset_y - offset_y_ + )); + } + } + InvalidateDraw(); + } + + void ScrollControl::UpdateScrollBarVisibility() + { + const auto content_rect = GetRect(RectRange::Content); + if (GetHorizontalScrollBarVisibility() == ScrollBarVisibility::Auto) + is_horizontal_scroll_bar_visible_ = view_width_ > content_rect.width; + if (GetVerticalScrollBarVisibility() == ScrollBarVisibility::Auto) + is_vertical_scroll_bar_visible_ = view_height_ > content_rect.height; + } + + void ScrollControl::UpdateScrollBarBorderInfo() + { + const auto content_rect = GetRect(RectRange::Content); + horizontal_bar_info_.border = Rect(content_rect.left, content_rect.GetBottom() - scroll_bar_width, content_rect.width, scroll_bar_width); + vertical_bar_info_.border = Rect(content_rect.GetRight() - scroll_bar_width , content_rect.top, scroll_bar_width, content_rect.height); + } + + void ScrollControl::UpdateScrollBarBarInfo() + { + const auto content_rect = GetRect(RectRange::Content); + { + const auto& border = horizontal_bar_info_.border; + if (view_width_ <= content_rect.width) + horizontal_bar_info_.bar = border; + else + { + const auto bar_length = border.width * content_rect.width / view_width_; + const auto offset = border.width * offset_x_ / view_width_; + horizontal_bar_info_.bar = Rect(border.left + offset, border.top, bar_length, border.height); + } + } + { + const auto& border = vertical_bar_info_.border; + if (view_height_ <= content_rect.height) + vertical_bar_info_.bar = border; + else + { + const auto bar_length = border.height * content_rect.height / view_height_; + const auto offset = border.height * offset_y_ / view_height_; + vertical_bar_info_.bar = Rect(border.left, border.top + offset, border.width, bar_length); + } + } + } +} +//-------------------------------------------------------- +//-------end of file: src\ui\controls\scroll_control.cpp +//-------------------------------------------------------- +//-------------------------------------------------------- //-------begin of file: src\ui\controls\text_block.cpp //-------------------------------------------------------- @@ -3667,7 +4087,7 @@ namespace cru::ui::controls selection_brush_ = UiManager::GetInstance()->GetPredefineResources()->text_control_selection_brush; - SetClipToPadding(true); + SetClipContent(true); } |