/* * Copyright (C) 2008 Emweb bvba, Kessel-Lo, Belgium. * * See the LICENSE file for terms of use. */ #include "TreeViewExample.h" #include #include #include #include #include #include #include #include #include #include static const char *weatherIcons[] = { "sun01.png", "cloudy01.png", "w_cloud.png", "rain.png", "storm.png", "snow.png" }; TreeViewModel::TreeViewModel() : belgium_(nullptr) { update(); } bool TreeViewModel::update() { clear(); belgium_ = nullptr; bool useInternalPath = true; insertColumns(0, 4); setHeaderData(0, Orientation::Horizontal, std::string("Places")); setHeaderData(1, Orientation::Horizontal, std::string("Weather")); setHeaderData(2, Orientation::Horizontal, std::string("Drink")); setHeaderData(3, Orientation::Horizontal, std::string("Visited")); /* * ... and data */ std::unique_ptr continent, country; WStandardItem *continentPtr, *countryPtr; continent = continentItem("Europe"); continentPtr = continent.get(); this->appendRow(std::move(continent)); country = countryItem("Belgium", "be"); countryPtr = country.get(); continentPtr->appendRow(std::move(country)); countryPtr->appendRow(cityItems("Brussels", Rain, "Beer", useInternalPath, true)); countryPtr->appendRow(cityItems("Brussels", Rain, "Beer", useInternalPath, true)); countryPtr->appendRow(cityItems("Brussels", Rain, "Beer", useInternalPath, true)); countryPtr->appendRow(cityItems("Brussels", Rain, "Beer", useInternalPath, true)); countryPtr->appendRow(cityItems("Brussels", Rain, "Beer", useInternalPath, true)); countryPtr->appendRow(cityItems("Brussels", Rain, "Beer", useInternalPath, true)); countryPtr->appendRow(cityItems("Brussels", Rain, "Beer", useInternalPath, true)); countryPtr->appendRow(cityItems("Brussels", Rain, "Beer", useInternalPath, true)); countryPtr->appendRow(cityItems("Leuven", Rain, "Beer", useInternalPath, true)); country = countryItem("France", "fr"); countryPtr = country.get(); continentPtr->appendRow(std::move(country)); countryPtr->appendRow(cityItems("Paris", Cloud, "Wine", useInternalPath, true)); countryPtr->appendRow(cityItems("Bordeaux", SunCloud, "Bordeaux wine", useInternalPath, false)); country = countryItem("Spain", "sp"); countryPtr = country.get(); continentPtr->appendRow(std::move(country)); countryPtr->appendRow(cityItems("Barcelona", Sun, "Cava", useInternalPath, true)); countryPtr->appendRow(cityItems("Madrid", Sun, "San Miguel", useInternalPath, false)); continent = continentItem("Africa"); continentPtr = continent.get(); appendRow(std::move(continent)); country = countryItem("Morocco (المغرب)", "ma"); countryPtr = country.get(); continentPtr->appendRow(std::move(country)); countryPtr->appendRow(cityItems("Casablanca", Sun, "Tea", useInternalPath, false)); belgium_ = item(0, 0)->child(0, 0); return true; } std::unique_ptr TreeViewModel::continentItem(const std::string& continent) { std::unique_ptr result = cpp14::make_unique(continent); result->setColumnCount(4); return result; } std::unique_ptr TreeViewModel::countryItem(const std::string& country, const std::string& code) { std::unique_ptr result = cpp14::make_unique(WString(country)); result->setIcon("icons/flag_" + code + ".png"); return result; } std::vector> TreeViewModel::cityItems(const std::string& city, WeatherIcon weather, const std::string& drink, bool useInternalPath, bool visited) { std::vector> result; std::unique_ptr item; // column 0: country item = cpp14::make_unique(WString(city)); result.push_back(std::move(item)); // column 1: weather item = cpp14::make_unique(); item->setIcon(std::string("icons/") + weatherIcons[weather]); result.push_back(std::move(item)); // column 2: drink item = cpp14::make_unique(drink); if (useInternalPath) item->setLink(WLink(LinkType::InternalPath, "/drinks/" + drink)); result.push_back(std::move(item)); // column 3: visited item = cpp14::make_unique(); item->setCheckable(true); item->setChecked(visited); result.push_back(std::move(item)); return result; } void TreeViewModel::toggleRowHeight(WTreeView *treeView_) { if (treeView_->rowHeight() == WLength(31)) treeView_->setRowHeight(25); else treeView_->setRowHeight(31); } void TreeViewModel::toggleStripes(WTreeView *treeView_) { treeView_->setAlternatingRowColors(!treeView_->alternatingRowColors()); } void TreeViewModel::toggleRoot(WTreeView *treeView_) { if (treeView_->rootIndex() == WModelIndex()) treeView_->setRootIndex(this->index(0, 0)); else treeView_->setRootIndex(WModelIndex()); } void TreeViewModel::addRows(WTreeView *treeView_) { if (nullptr != belgium_) { int COUNT = 10; for (int i = 0; i < COUNT; ++i) { std::string cityName = "City " + asString(belgium_->rowCount() + 1).toUTF8(); bool useInternalPath = false; belgium_->appendRow(cityItems(cityName, Storm, "Juice", useInternalPath, false)); } treeView_->scrollTo(belgium_->child(belgium_->rowCount() - COUNT)->index(), ScrollHint::PositionAtTop); } } TreeViewExample::TreeViewExample(const WString& titleText) { model_ = std::make_unique(); TreeViewModel *pTreeViewModel = dynamic_cast(model_.get()); this->addWidget(cpp14::make_unique(titleText)); /* * Now create the view */ WPanel *panel = this->addWidget(cpp14::make_unique()); panel->resize(600, 300); auto treeView = cpp14::make_unique(); treeView_ = treeView.get(); panel->setCentralWidget(std::move(treeView)); if (!WApplication::instance()->environment().ajax()) treeView_->resize(WLength::Auto, 290); treeView_->setAlternatingRowColors(true); treeView_->setRowHeight(25); treeView_->setModel(model_); treeView_->setColumnWidth(1, WLength(100)); treeView_->setColumnAlignment(1, AlignmentFlag::Center); treeView_->setColumnWidth(3, WLength(100)); treeView_->setColumnAlignment(3, AlignmentFlag::Center); treeView_->setRowHeaderCount(1); treeView_->setColumnWidth(0, 300); /* * Expand the first (and single) top level node */ treeView_->setExpanded(model_->index(0, 0), true); treeView_->setExpanded(model_->index(0, 0, model_->index(0, 0)), true); treeView_->setSortingEnabled(false); treeView_->setSortingEnabled(0, true); treeView_->setSortingEnabled(2, true); /* * Setup some buttons to manipulate the view and the model. */ WContainerWidget *wc = this->addWidget(cpp14::make_unique()); WPushButton *b; b = wc->addWidget(cpp14::make_unique("Toggle row height")); b->clicked().connect([=] { pTreeViewModel->toggleRowHeight(treeView_); }); b->setToolTip("Toggles row height between 31px and 25px"); b = wc->addWidget(cpp14::make_unique("Toggle stripes")); b->clicked().connect([=] { pTreeViewModel->toggleStripes(treeView_); }); b->setToolTip("Toggle alternating row colors"); b = wc->addWidget(cpp14::make_unique("Toggle root")); b->clicked().connect([=] { pTreeViewModel->toggleRoot(treeView_); }); b->setToolTip("Toggles root item between all and the first continent."); b = wc->addWidget(cpp14::make_unique("Add rows")); b->clicked().connect([=]{ pTreeViewModel->addRows(treeView_); }); b->setToolTip("Adds some cities to Belgium"); } bool TreeViewExample::update() { bool bReturn = false; if (nullptr != treeView_) { TreeViewModel *pModel = dynamic_cast(treeView_->model().get()); if (nullptr != pModel) bReturn = pModel->update(); } return bReturn; }