accordion.cpp 2.61 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
#include "accordion.hpp"

#include <QScrollArea>

namespace cvv
{
namespace qtutil
{

Accordion::Accordion(QWidget *parent)
    : QWidget{ parent }, elements_{}, layout_{ nullptr }
{
	auto lay = util::make_unique<QVBoxLayout>();
	layout_ = *lay;
	layout_->setAlignment(Qt::AlignTop);

	// needed because scrollArea->setLayout(layout_); does not work
	auto resizehelper = util::make_unique<QWidget>();
	resizehelper->setLayout(lay.release());

	auto scrollArea = util::make_unique<QScrollArea>();
	scrollArea->setWidget(resizehelper.release());
	// needed because no contained widget demands a size
	scrollArea->setWidgetResizable(true);

	auto mainLayout = util::make_unique<QVBoxLayout>();
	mainLayout->addWidget(scrollArea.release());
	setLayout(mainLayout.release());
}

void Accordion::collapseAll(bool b)
{
	for (auto &elem : elements_)
	{
		elem.second->collapse(b);
	}
}

void Accordion::hideAll(bool b)
{
	for (auto &elem : elements_)
	{
		elem.second->setVisible(!b);
	}
}

Accordion::Handle Accordion::insert(const QString &title,
                                    std::unique_ptr<QWidget> widget,
                                    bool isCollapsed, std::size_t position)
{
	// create element
	auto widgetPtr = widget.get();
	elements_.emplace(
	    widgetPtr, util::make_unique<Collapsable>(title, std::move(widget),
	                                              isCollapsed).release());
	// insert element
	layout_->insertWidget(position, &element(widgetPtr));
	return widgetPtr;
}

void Accordion::remove(Handle handle)
{
	Collapsable *elem = &element(handle);
	layout_->removeWidget(elem);
	elements_.erase(handle);
	elem->setParent(0);
	elem->deleteLater();
}

void Accordion::clear()
{
	// clear layout
	for (auto &elem : elements_)
	{
		layout_->removeWidget(elem.second);
		elem.second->setParent(nullptr);
		elem.second->deleteLater();
	}
	elements_.clear();
}

std::pair<QString, Collapsable *> Accordion::pop(Handle handle)
{
	Collapsable *elem = &element(handle);
	// remove from layout
	layout_->removeWidget(elem);
	std::pair<QString, Collapsable *> result{ element(handle).title(),
		                                  elem };
	// remove from map
	elements_.erase(handle);
	return result;
}

std::vector<std::pair<QString, Collapsable *>> Accordion::popAll()
{
	std::vector<std::pair<QString, Collapsable *>> result{};
	for (auto &elem : elements_)
	{
		// remove from layout
		layout_->removeWidget(elem.second);
		result.push_back(
		    std::pair<QString, Collapsable *>{ elem.second->title(),
			                               elem.second });
	}
	// remove from map
	elements_.clear();
	return result;
}
}
} // end namespaces qtutil, cvv