diff --git a/ext/native/ui/view.h b/ext/native/ui/view.h index 62926338d0..952e3d9c29 100644 --- a/ext/native/ui/view.h +++ b/ext/native/ui/view.h @@ -292,6 +292,26 @@ public: // Fake RTTI bool Is(LayoutParamsType type) const { return type_ == type; } + template + T *As() { + if (Is(T::StaticType())) { + return static_cast(this); + } + return nullptr; + } + + template + const T *As() const { + if (Is(T::StaticType())) { + return static_cast(this); + } + return nullptr; + } + + static LayoutParamsType StaticType() { + return LP_PLAIN; + } + private: LayoutParamsType type_; }; diff --git a/ext/native/ui/viewgroup.cpp b/ext/native/ui/viewgroup.cpp index 5d5a2e7f4c..21f37cb8c9 100644 --- a/ext/native/ui/viewgroup.cpp +++ b/ext/native/ui/viewgroup.cpp @@ -395,9 +395,7 @@ void LinearLayout::Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec v continue; numVisible++; - const LayoutParams *layoutParams = views_[i]->GetLayoutParams(); - const LinearLayoutParams *linLayoutParams = static_cast(layoutParams); - if (!linLayoutParams->Is(LP_LINEAR)) linLayoutParams = 0; + const LinearLayoutParams *linLayoutParams = views_[i]->GetLayoutParams()->As(); Margins margins = defaultMargins_; @@ -459,9 +457,7 @@ void LinearLayout::Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec v for (size_t i = 0; i < views_.size(); i++) { if (views_[i]->GetVisibility() == V_GONE) continue; - const LayoutParams *layoutParams = views_[i]->GetLayoutParams(); - const LinearLayoutParams *linLayoutParams = static_cast(layoutParams); - if (!linLayoutParams->Is(LP_LINEAR)) linLayoutParams = 0; + const LinearLayoutParams *linLayoutParams = views_[i]->GetLayoutParams()->As(); if (linLayoutParams && linLayoutParams->weight > 0.0f) { Margins margins = defaultMargins_; @@ -500,9 +496,7 @@ void LinearLayout::Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec v for (size_t i = 0; i < views_.size(); i++) { if (views_[i]->GetVisibility() == V_GONE) continue; - const LayoutParams *layoutParams = views_[i]->GetLayoutParams(); - const LinearLayoutParams *linLayoutParams = static_cast(layoutParams); - if (!linLayoutParams->Is(LP_LINEAR)) linLayoutParams = 0; + const LinearLayoutParams *linLayoutParams = views_[i]->GetLayoutParams()->As(); if (linLayoutParams && linLayoutParams->weight > 0.0f) { Margins margins = defaultMargins_; @@ -548,9 +542,7 @@ void LinearLayout::Layout() { if (views_[i]->GetVisibility() == V_GONE) continue; - const LayoutParams *layoutParams = views_[i]->GetLayoutParams(); - const LinearLayoutParams *linLayoutParams = static_cast(layoutParams); - if (!linLayoutParams->Is(LP_LINEAR)) linLayoutParams = 0; + const LinearLayoutParams *linLayoutParams = views_[i]->GetLayoutParams()->As(); Gravity gravity = G_TOPLEFT; Margins margins = defaultMargins_; @@ -615,10 +607,7 @@ void ScrollView::Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec ver // Respect margins Margins margins; if (views_.size()) { - const LinearLayoutParams *linLayoutParams = static_cast(views_[0]->GetLayoutParams()); - if (!linLayoutParams->Is(LP_LINEAR)) { - linLayoutParams = 0; - } + const LinearLayoutParams *linLayoutParams = views_[0]->GetLayoutParams()->As(); if (linLayoutParams) { margins = linLayoutParams->margins; } @@ -657,8 +646,7 @@ void ScrollView::Layout() { // Respect margins Margins margins; - const LinearLayoutParams *linLayoutParams = static_cast(views_[0]->GetLayoutParams()); - if (!linLayoutParams->Is(LP_LINEAR)) linLayoutParams = 0; + const LinearLayoutParams *linLayoutParams = views_[0]->GetLayoutParams()->As(); if (linLayoutParams) { margins = linLayoutParams->margins; } @@ -909,8 +897,7 @@ void AnchorLayout::Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec v } } - const AnchorLayoutParams *params = static_cast(views_[i]->GetLayoutParams()); - if (!params->Is(LP_ANCHOR)) params = 0; + const AnchorLayoutParams *params = views_[i]->GetLayoutParams()->As(); if (params) { width = params->width; height = params->height; @@ -937,8 +924,7 @@ void AnchorLayout::Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec v void AnchorLayout::Layout() { for (size_t i = 0; i < views_.size(); i++) { - const AnchorLayoutParams *params = static_cast(views_[i]->GetLayoutParams()); - if (!params->Is(LP_ANCHOR)) params = 0; + const AnchorLayoutParams *params = views_[i]->GetLayoutParams()->As(); Bounds vBounds; vBounds.w = views_[i]->GetMeasuredWidth(); diff --git a/ext/native/ui/viewgroup.h b/ext/native/ui/viewgroup.h index 69c91862b6..833c937ef4 100644 --- a/ext/native/ui/viewgroup.h +++ b/ext/native/ui/viewgroup.h @@ -111,6 +111,10 @@ public: // Set to NONE to not attach this edge to the container. float left, top, right, bottom; bool center; // If set, only two "sides" can be set, and they refer to the center, not the edge, of the view being layouted. + + static LayoutParamsType StaticType() { + return LP_ANCHOR; + } }; class AnchorLayout : public ViewGroup { @@ -152,6 +156,10 @@ public: bool HasMargins() const { return hasMargins_; } + static LayoutParamsType StaticType() { + return LP_LINEAR; + } + private: bool hasMargins_; };