* Build a nested widget tree by recursively filling containers with nested widgets read from their parts. * @param nwid_begin Iterator to beginning of nested widget parts. * @param nwid_end Iterator to ending of nested widget parts. * @param parent Pointer or container to use for storing the child widgets (*parent == nullptr or *parent == container or background widget). * @return Iterator to
| 3364 | * @return Iterator to remaining nested widget parts. |
| 3365 | */ |
| 3366 | static std::span<const NWidgetPart>::iterator MakeWidgetTree(std::span<const NWidgetPart>::iterator nwid_begin, std::span<const NWidgetPart>::iterator nwid_end, std::unique_ptr<NWidgetBase> &parent) |
| 3367 | { |
| 3368 | /* If *parent == nullptr, only the first widget is read and returned. Otherwise, *parent must point to either |
| 3369 | * a #NWidgetContainer or a #NWidgetBackground object, and parts are added as much as possible. */ |
| 3370 | NWidgetContainer *nwid_cont = dynamic_cast<NWidgetContainer *>(parent.get()); |
| 3371 | NWidgetBackground *nwid_parent = dynamic_cast<NWidgetBackground *>(parent.get()); |
| 3372 | assert(parent == nullptr || (nwid_cont != nullptr && nwid_parent == nullptr) || (nwid_cont == nullptr && nwid_parent != nullptr)); |
| 3373 | |
| 3374 | while (nwid_begin != nwid_end) { |
| 3375 | std::unique_ptr<NWidgetBase> sub_widget = nullptr; |
| 3376 | bool fill_sub = false; |
| 3377 | nwid_begin = MakeNWidget(nwid_begin, nwid_end, sub_widget, fill_sub); |
| 3378 | |
| 3379 | /* Break out of loop when end reached */ |
| 3380 | if (sub_widget == nullptr) break; |
| 3381 | |
| 3382 | /* If sub-widget is a container, recursively fill that container. */ |
| 3383 | if (fill_sub && IsContainerWidgetType(sub_widget->type)) { |
| 3384 | nwid_begin = MakeWidgetTree(nwid_begin, nwid_end, sub_widget); |
| 3385 | } |
| 3386 | |
| 3387 | /* Add sub_widget to parent container if available, otherwise return the widget to the caller. */ |
| 3388 | if (nwid_cont != nullptr) nwid_cont->Add(std::move(sub_widget)); |
| 3389 | if (nwid_parent != nullptr) nwid_parent->Add(std::move(sub_widget)); |
| 3390 | if (nwid_cont == nullptr && nwid_parent == nullptr) { |
| 3391 | parent = std::move(sub_widget); |
| 3392 | return nwid_begin; |
| 3393 | } |
| 3394 | } |
| 3395 | |
| 3396 | if (nwid_begin == nwid_end) return nwid_begin; // Reached the end of the array of parts? |
| 3397 | |
| 3398 | assert(nwid_begin < nwid_end); |
| 3399 | assert(nwid_begin->type == WPT_ENDCONTAINER); |
| 3400 | return std::next(nwid_begin); // *nwid_begin is also 'used' |
| 3401 | } |
| 3402 | |
| 3403 | /** |
| 3404 | * Construct a nested widget tree from an array of parts. |
no test coverage detected