From 6693339bc0832c5c79c0f422166c36659b7c7496 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20B=C3=BCrgmann?= Date: Sat, 4 Apr 2020 12:58:51 +0200 Subject: [PATCH] Now you can insert form elements add a position --- cppcms/form.h | 38 +++++++++++++++++++++++++++++++++++ src/form.cpp | 55 +++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 83 insertions(+), 10 deletions(-) diff --git a/cppcms/form.h b/cppcms/form.h index 33e5a6b9..b183458d 100644 --- a/cppcms/form.h +++ b/cppcms/form.h @@ -242,12 +242,31 @@ namespace cppcms { /// virtual void clear(); + /// + /// Add \a subform at specific position to form. The ownership is not + /// transferred to the parent. + /// When \a index is negative it is interpreted from the back, if index + /// is greater than the number of already added elemenets, the element + /// will simply add at the end (or beginning if negative). + /// + void add(int index, form &subform); + /// /// Add \a subform to form. The ownership is not transferred to /// the parent. /// void add(form &subform); + /// + /// Add \a subform at specific position to form. The ownership is + /// transferred to the parent and the subform will be destroyed together + /// with the parent. + /// When \a index is negative it is interpreted from the back, if index + /// is greater than the number of already added elemenets, the element + /// will simply add at the end (or beginning if negative). + /// + void attach(int index, form *subform); + /// /// Add \a subform to form. The ownership is transferred to /// the parent and the subform will be destroyed together with @@ -255,12 +274,31 @@ namespace cppcms { /// void attach(form *subform); + /// + /// Add \a widget at specific position to form. The ownership is not + /// transferred to to the parent. + /// When \a index is negative it is interpreted from the back, if index + /// is greater than the number of already added elemenets, the element + /// will simply add at the end (or beginning if negative). + /// + void add(int index, widgets::base_widget &widget); + /// /// Add \a widget to form. The ownership is not transferred to /// to the parent. /// void add(widgets::base_widget &widget); + /// + /// Add \a widget at specific position to form. The ownership is + /// transferred to the parent and the widget will be destroyed together + /// with the parent. + /// When \a index is negative it is interpreted from the back, if index + /// is greater than the number of already added elemenets, the element + /// will simply add at the end (or beginning if negative). + /// + void attach(int index, widgets::base_widget *widget); + /// /// Add \a widget to form. The ownership is transferred to /// the parent and the widget will be destroyed together with diff --git a/src/form.cpp b/src/form.cpp index 2ccc0be7..508fb889 100644 --- a/src/form.cpp +++ b/src/form.cpp @@ -150,27 +150,62 @@ void form::clear() } } +namespace { + +// std::advance is not applicable because UB when n > size +template +Iter advance(Iter it, const Iter& end, int n) { + while (n--) + if (it == end) + break; + else + ++it; + return it; +} +template +void add_impl(form* self, V& elements_, T* form, bool owning, int position) { + if (position < 0) { + auto it = advance(elements_.rend(), elements_.rbegin(), position * -1); + elements_.emplace(it.base() -1, form, owning); + } else { + auto it = advance(elements_.begin(), elements_.end(), position); + elements_.emplace(it, form, owning); + } + form->parent(self); +} +} +void form::add(int index, widgets::base_widget &form) +{ + add_impl(this, elements_, &form, false, index); +} +void form::add(int index, form &subform) +{ + add_impl(this, elements_, &subform, false, index); +} void form::add(widgets::base_widget &form) { - elements_.push_back(widget_type(&form,false)); - form.parent(this); + add_impl(this, elements_, &form, false, elements_.size()); } void form::add(form &subform) { - elements_.push_back(widget_type(&subform,false)); - subform.parent(this); + add_impl(this, elements_, &subform, false, elements_.size()); } +void form::attach(int index, form *subform) +{ + add_impl(this, elements_, subform, true, index); +} +void form::attach(int index, widgets::base_widget *form) +{ + add_impl(this, elements_, form, true, index); +} void form::attach(form *subform) { - elements_.push_back(widget_type(subform,true)); - subform->parent(this); + add_impl(this, elements_, subform, true, elements_.size()); } - -void form::attach(widgets::base_widget *subform) +void form::attach(widgets::base_widget *form) { - elements_.push_back(widget_type(subform,true)); - subform->parent(this); + add_impl(this, elements_, form, true, elements_.size()); } struct form::iterator::_data {};