aboutsummaryrefslogtreecommitdiff
path: root/include/cru/ui/controls
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2022-02-10 19:26:19 +0800
committercrupest <crupest@outlook.com>2022-02-10 19:26:19 +0800
commitb2622f654598f82a220a98daaa84fed9ce3b92b2 (patch)
tree544d5a9a52d7530bf54e888d3fabd79ff85bfdb7 /include/cru/ui/controls
parentb8863c403a44c1c7ac35f1a1da92bbf3c8858552 (diff)
downloadcru-b2622f654598f82a220a98daaa84fed9ce3b92b2.tar.gz
cru-b2622f654598f82a220a98daaa84fed9ce3b92b2.tar.bz2
cru-b2622f654598f82a220a98daaa84fed9ce3b92b2.zip
...
Diffstat (limited to 'include/cru/ui/controls')
-rw-r--r--include/cru/ui/controls/Control.h11
-rw-r--r--include/cru/ui/controls/LayoutControl.h32
-rw-r--r--include/cru/ui/controls/NoChildControl.h2
-rw-r--r--include/cru/ui/controls/SingleChildControl.h8
4 files changed, 49 insertions, 4 deletions
diff --git a/include/cru/ui/controls/Control.h b/include/cru/ui/controls/Control.h
index 9a237f8b..242db3f4 100644
--- a/include/cru/ui/controls/Control.h
+++ b/include/cru/ui/controls/Control.h
@@ -10,6 +10,7 @@ namespace cru::ui::controls {
* methods:
* - GetControlType()
* - ForEachChild(const std::function<void(Control*)>& predicate)
+ * - RemoveChild(Control* child)
* - GetRenderObject()
*/
class CRU_UI_API Control : public Object {
@@ -35,6 +36,14 @@ class CRU_UI_API Control : public Object {
virtual void ForEachChild(const std::function<void(Control*)>& predicate) = 0;
+ /**
+ * \remarks This method should be permissive, which means if the specified
+ * child control is not a real child of this then nothing will be done.
+ */
+ virtual void RemoveChild(Control* child) = 0;
+
+ void RemoveFromParent();
+
public:
virtual render::RenderObject* GetRenderObject() const = 0;
@@ -129,7 +138,7 @@ class CRU_UI_API Control : public Object {
//*************** region: tree ***************
protected:
- virtual void OnParentChanged(Control* old_parent, Control* new_parent);
+ virtual void OnParentChanged(Control* old_parent, Control* new_parent) {}
protected:
virtual void OnMouseHoverChange(bool newHover) { CRU_UNUSED(newHover) }
diff --git a/include/cru/ui/controls/LayoutControl.h b/include/cru/ui/controls/LayoutControl.h
index b42cfc9a..59ffaee2 100644
--- a/include/cru/ui/controls/LayoutControl.h
+++ b/include/cru/ui/controls/LayoutControl.h
@@ -17,12 +17,30 @@ class CRU_UI_API LayoutControl : public Control {
~LayoutControl() override = default;
public:
+ const std::vector<Control*>& GetChildren() const { return children_; }
+ Index GetChildCount() const { return children_.size(); }
+ Control* GetChild(Index index) const { return children_[index]; }
+ Index IndexOf(Control* control) const {
+ auto it = std::find(children_.begin(), children_.end(), control);
+ if (it == children_.end()) {
+ return -1;
+ }
+ return it - children_.begin();
+ }
+
void ForEachChild(const std::function<void(Control*)>& callback) override {
for (auto child : children_) {
callback(child);
}
}
+ void RemoveChild(Control* child) override {
+ auto index = IndexOf(child);
+ if (index != -1) {
+ RemoveChildAt(index);
+ }
+ }
+
render::RenderObject* GetRenderObject() const override {
return container_render_object_.get();
}
@@ -31,7 +49,7 @@ class CRU_UI_API LayoutControl : public Control {
return container_render_object_.get();
}
- void AddChild(Control* child, Index position) {
+ void AddChildAt(Control* child, Index position) {
Expects(child);
Expects(child->GetParent() == nullptr);
if (position < 0) position = 0;
@@ -43,7 +61,9 @@ class CRU_UI_API LayoutControl : public Control {
container_render_object_->AddChild(child->GetRenderObject(), position);
}
- void RemoveChild(Index position) {
+ void AddChild(Control* child) { AddChildAt(child, GetChildCount()); }
+
+ void RemoveChildAt(Index position) {
if (position < 0 || position >= children_.size()) return;
auto child = children_[position];
children_.erase(children_.begin() + position);
@@ -51,6 +71,14 @@ class CRU_UI_API LayoutControl : public Control {
container_render_object_->RemoveChild(position);
}
+ void ClearChildren() {
+ for (auto child : children_) {
+ child->SetParent(nullptr);
+ }
+ children_.clear();
+ container_render_object_->ClearChildren();
+ }
+
const typename TRenderObject::ChildLayoutData& GetChildLayoutData(
Index position) {
return container_render_object_->GetChildLayoutDataAt(position);
diff --git a/include/cru/ui/controls/NoChildControl.h b/include/cru/ui/controls/NoChildControl.h
index 1b864b20..f22fd85e 100644
--- a/include/cru/ui/controls/NoChildControl.h
+++ b/include/cru/ui/controls/NoChildControl.h
@@ -15,5 +15,7 @@ class CRU_UI_API NoChildControl : public Control {
public:
void ForEachChild(const std::function<void(Control*)>& callback) override;
+
+ void RemoveChild(Control* child) override;
};
} // namespace cru::ui::controls
diff --git a/include/cru/ui/controls/SingleChildControl.h b/include/cru/ui/controls/SingleChildControl.h
index 037d6dd3..d40d7a27 100644
--- a/include/cru/ui/controls/SingleChildControl.h
+++ b/include/cru/ui/controls/SingleChildControl.h
@@ -48,8 +48,14 @@ class CRU_UI_API SingleChildControl : public Control {
}
}
+ void RemoveChild(Control* child) override {
+ if (child_ == child) {
+ SetChild(nullptr);
+ }
+ }
+
private:
- Control* child_;
+ Control* child_ = nullptr;
std::unique_ptr<TRenderObject> container_render_object_;
};
} // namespace cru::ui::controls