|
@@ -67,6 +67,7 @@ public:
|
|
|
|
|
|
const StyleProperties& style() const;
|
|
|
|
|
|
+ LayoutNodeWithStyle* parent();
|
|
|
const LayoutNodeWithStyle* parent() const;
|
|
|
|
|
|
void inserted_into(LayoutNode&) {}
|
|
@@ -97,6 +98,12 @@ public:
|
|
|
template<typename T>
|
|
|
T* first_child_of_type();
|
|
|
|
|
|
+ template<typename T>
|
|
|
+ const T* first_ancestor_of_type() const;
|
|
|
+
|
|
|
+ template<typename T>
|
|
|
+ T* first_ancestor_of_type();
|
|
|
+
|
|
|
protected:
|
|
|
explicit LayoutNode(const Node*);
|
|
|
|
|
@@ -157,6 +164,11 @@ inline const LayoutNodeWithStyle* LayoutNode::parent() const
|
|
|
return static_cast<const LayoutNodeWithStyle*>(TreeNode<LayoutNode>::parent());
|
|
|
}
|
|
|
|
|
|
+inline LayoutNodeWithStyle* LayoutNode::parent()
|
|
|
+{
|
|
|
+ return static_cast<LayoutNodeWithStyle*>(TreeNode<LayoutNode>::parent());
|
|
|
+}
|
|
|
+
|
|
|
template<typename T>
|
|
|
inline bool is(const LayoutNode&)
|
|
|
{
|
|
@@ -248,3 +260,23 @@ inline T* LayoutNode::first_child_of_type()
|
|
|
}
|
|
|
return nullptr;
|
|
|
}
|
|
|
+
|
|
|
+template<typename T>
|
|
|
+inline const T* LayoutNode::first_ancestor_of_type() const
|
|
|
+{
|
|
|
+ for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) {
|
|
|
+ if (is<T>(*ancestor))
|
|
|
+ return &to<T>(*ancestor);
|
|
|
+ }
|
|
|
+ return nullptr;
|
|
|
+}
|
|
|
+
|
|
|
+template<typename T>
|
|
|
+inline T* LayoutNode::first_ancestor_of_type()
|
|
|
+{
|
|
|
+ for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) {
|
|
|
+ if (is<T>(*ancestor))
|
|
|
+ return &to<T>(*ancestor);
|
|
|
+ }
|
|
|
+ return nullptr;
|
|
|
+}
|