Created
May 20, 2020 12:25
-
-
Save RockinRoel/27ec5be4a785888c465a5121e3216a58 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Wt/WAbstractItemModel.h> | |
#include <Wt/WApplication.h> | |
#include <Wt/WContainerWidget.h> | |
#include <Wt/WModelIndex.h> | |
#include <Wt/WStandardItem.h> | |
#include <Wt/WStandardItemModel.h> | |
#include <Wt/WTreeView.h> | |
#include <algorithm> | |
#include <iterator> | |
#include <memory> | |
namespace ModelIterators { | |
class ColumnIterator final { | |
public: | |
using difference_type = int; | |
using value_type = Wt::WModelIndex; | |
using reference = const value_type &; | |
using pointer = const value_type *; | |
using iterator_category = std::forward_iterator_tag; | |
// past the end iterator | |
ColumnIterator(); | |
// column iterator starting from index | |
ColumnIterator(const Wt::WModelIndex &index); | |
// copy ctor | |
ColumnIterator(const ColumnIterator &other); | |
// copy assignment | |
ColumnIterator& operator=(const ColumnIterator &other); | |
// move ctor deleted | |
ColumnIterator(ColumnIterator &&) = delete; | |
// move assignment deleted | |
ColumnIterator& operator=(ColumnIterator &&) = delete; | |
// equality | |
bool operator==(const ColumnIterator &other) const; | |
// inequality | |
bool operator!=(const ColumnIterator &other) const; | |
// deref | |
const Wt::WModelIndex &operator*() const; | |
// arrow | |
const Wt::WModelIndex *operator->() const; | |
// preincrement | |
ColumnIterator& operator++(); | |
// postincrement | |
ColumnIterator operator++(int); | |
private: | |
Wt::WModelIndex index_; | |
}; | |
void swap(ColumnIterator &it1, ColumnIterator &it2); | |
ColumnIterator::ColumnIterator() | |
{ } | |
ColumnIterator::ColumnIterator(const Wt::WModelIndex &index) | |
: index_(index) | |
{ } | |
ColumnIterator::ColumnIterator(const ColumnIterator &other) | |
: index_(other.index_) | |
{ } | |
ColumnIterator& ColumnIterator::operator=(const ColumnIterator &other) | |
{ | |
index_ = other.index_; | |
return *this; | |
} | |
bool ColumnIterator::operator==(const ColumnIterator &other) const | |
{ | |
return index_ == other.index_; | |
} | |
bool ColumnIterator::operator!=(const ColumnIterator &other) const | |
{ | |
return index_ != other.index_; | |
} | |
const Wt::WModelIndex &ColumnIterator::operator*() const | |
{ | |
return index_; | |
} | |
const Wt::WModelIndex *ColumnIterator::operator->() const | |
{ | |
return &index_; | |
} | |
ColumnIterator& ColumnIterator::operator++() | |
{ | |
if (!index_.isValid()) | |
return *this; | |
const Wt::WAbstractItemModel * const model = index_.model(); | |
// first: child? | |
const Wt::WModelIndex child = index_.child(0, index_.column()); | |
if (child.isValid()) { | |
index_ = child; | |
return *this; | |
} | |
// then: sibling? | |
const Wt::WModelIndex sibling = model->index(index_.row() + 1, index_.column(), index_.parent()); | |
if (sibling.isValid()) { | |
index_ = sibling; | |
return *this; | |
} | |
// finally: (great*)uncle? | |
for (Wt::WModelIndex ancestor = index_.parent(); | |
ancestor.isValid(); | |
ancestor = ancestor.parent()) { | |
const Wt::WModelIndex uncle = model->index(ancestor.row() + 1, ancestor.column(), ancestor.parent()); | |
if (uncle.isValid()) { | |
index_ = uncle; | |
return *this; | |
} | |
} | |
// if everything fails: past the end iterator | |
index_ = Wt::WModelIndex(); | |
return *this; | |
} | |
ColumnIterator ColumnIterator::operator++(int) | |
{ | |
ColumnIterator old = *this; | |
++*this; | |
return old; | |
} | |
void swap(ColumnIterator &it1, ColumnIterator &it2) | |
{ | |
ColumnIterator tmp = it1; | |
it1 = it2; | |
it2 = tmp; | |
} | |
} | |
void fillModel(Wt::WStandardItem *item, | |
int &index, | |
int count, | |
int maxDepth, | |
int currentDepth = 0) | |
{ | |
if (currentDepth == maxDepth) { | |
return; | |
} | |
for (int r = 0; r < count; ++r) { | |
auto subItem = std::make_unique<Wt::WStandardItem>(Wt::utf8("{1}").arg(index)); | |
++index; | |
fillModel(subItem.get(), index, count, maxDepth, currentDepth + 1); | |
item->appendRow(std::move(subItem)); | |
} | |
} | |
int main(int argc, char *argv[]) | |
{ | |
return Wt::WRun(argc, argv, [](const Wt::WEnvironment &env) { | |
auto app = std::make_unique<Wt::WApplication>(env); | |
auto root = app->root(); | |
auto model = std::make_shared<Wt::WStandardItemModel>(); | |
int index = 0; | |
fillModel(model->invisibleRootItem(), index, 10, 3); | |
auto tv = root->addNew<Wt::WTreeView>(); | |
tv->setModel(model); | |
tv->resize(500, 500); | |
std::for_each(ModelIterators::ColumnIterator(model->index(0, 0)), | |
ModelIterators::ColumnIterator(), | |
[](const Wt::WModelIndex &index) { | |
std::cout << "R: " << index.row() << ", C: " << index.column() << ", V: " << Wt::asString(index.data()).toUTF8() << '\n'; | |
}); | |
return app; | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment