|
/*
|
|
* Copyright (C) 2008 Emweb bvba, Kessel-Lo, Belgium.
|
|
*
|
|
* See the LICENSE file for terms of use.
|
|
*/
|
|
#include "TreeViewExample.h"
|
|
|
|
#include <iostream>
|
|
|
|
#include <Wt/WApplication.h>
|
|
#include <Wt/WContainerWidget.h>
|
|
#include <Wt/WEnvironment.h>
|
|
#include <Wt/WPanel.h>
|
|
#include <Wt/WPushButton.h>
|
|
#include <Wt/WStandardItem.h>
|
|
#include <Wt/WStandardItemModel.h>
|
|
#include <Wt/WText.h>
|
|
#include <Wt/WTreeView.h>
|
|
|
|
static const char *weatherIcons[] = {
|
|
"sun01.png",
|
|
"cloudy01.png",
|
|
"w_cloud.png",
|
|
"rain.png",
|
|
"storm.png",
|
|
"snow.png"
|
|
};
|
|
|
|
TreeViewExample::TreeViewExample(std::shared_ptr<WStandardItemModel> model,
|
|
const WString& titleText)
|
|
: model_(model)
|
|
{
|
|
belgium_ = model_->item(0, 0)->child(0, 0);
|
|
|
|
this->addWidget(cpp14::make_unique<WText>(titleText));
|
|
|
|
/*
|
|
* Now create the view
|
|
*/
|
|
WPanel *panel = this->addWidget(cpp14::make_unique<WPanel>());
|
|
panel->resize(600, 300);
|
|
|
|
// panel->hide();
|
|
|
|
auto treeView = cpp14::make_unique<WTreeView>();
|
|
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<WContainerWidget>());
|
|
WPushButton *b;
|
|
|
|
b = wc->addWidget(cpp14::make_unique<WPushButton>("Toggle row height"));
|
|
b->clicked().connect(this, &TreeViewExample::toggleRowHeight);
|
|
b->setToolTip("Toggles row height between 31px and 25px");
|
|
|
|
b = wc->addWidget(cpp14::make_unique<WPushButton>("Toggle stripes"));
|
|
b->clicked().connect(this, &TreeViewExample::toggleStripes);
|
|
b->setToolTip("Toggle alternating row colors");
|
|
|
|
b = wc->addWidget(cpp14::make_unique<WPushButton>("Toggle root"));
|
|
b->clicked().connect(this, &TreeViewExample::toggleRoot);
|
|
b->setToolTip("Toggles root item between all and the first continent.");
|
|
|
|
b = wc->addWidget(cpp14::make_unique<WPushButton>("Add rows"));
|
|
b->clicked().connect(this, &TreeViewExample::addRows);
|
|
b->setToolTip("Adds some cities to Belgium");
|
|
|
|
b = wc->addWidget(cpp14::make_unique<WPushButton>("Show"));
|
|
b->clicked().connect(panel, &WPanel::show);
|
|
}
|
|
|
|
std::shared_ptr<WStandardItemModel> TreeViewExample::createModel(bool useInternalPath)
|
|
{
|
|
/*
|
|
* Setup a model.
|
|
*
|
|
* We use the standard item model, which is a general model
|
|
* suitable for hierarchical (tree-like) data, but stores all data
|
|
* in memory.
|
|
*/
|
|
auto result = std::make_shared<WStandardItemModel>(0, 4);
|
|
|
|
/*
|
|
* Headers ...
|
|
*/
|
|
result->setHeaderData(0, Orientation::Horizontal, std::string("Places"));
|
|
result->setHeaderData(1, Orientation::Horizontal, std::string("Weather"));
|
|
result->setHeaderData(2, Orientation::Horizontal, std::string("Drink"));
|
|
result->setHeaderData(3, Orientation::Horizontal, std::string("Visited"));
|
|
|
|
/*
|
|
* ... and data
|
|
*/
|
|
std::unique_ptr<WStandardItem> continent, country;
|
|
WStandardItem *continentPtr, *countryPtr;
|
|
|
|
continent = continentItem("Europe");
|
|
continentPtr = continent.get();
|
|
result->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("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();
|
|
result->appendRow(std::move(continent));
|
|
|
|
country = countryItem("Morocco (المغرب)", "ma");
|
|
countryPtr = country.get();
|
|
continentPtr->appendRow(std::move(country));
|
|
countryPtr->appendRow(cityItems("Casablanca", Sun, "Tea",
|
|
useInternalPath, false));
|
|
|
|
return result;
|
|
}
|
|
|
|
std::unique_ptr<WStandardItem> TreeViewExample::continentItem(const std::string& continent)
|
|
{
|
|
std::unique_ptr<WStandardItem> result
|
|
= cpp14::make_unique<WStandardItem>(continent);
|
|
result->setColumnCount(4);
|
|
return result;
|
|
}
|
|
|
|
std::unique_ptr<WStandardItem> TreeViewExample::countryItem(const std::string& country,
|
|
const std::string& code)
|
|
{
|
|
std::unique_ptr<WStandardItem> result
|
|
= cpp14::make_unique<WStandardItem>(WString(country));
|
|
result->setIcon("icons/flag_" + code + ".png");
|
|
return result;
|
|
}
|
|
|
|
std::vector<std::unique_ptr<WStandardItem>>
|
|
TreeViewExample::cityItems(const std::string& city,
|
|
WeatherIcon weather,
|
|
const std::string& drink,
|
|
bool useInternalPath, bool visited)
|
|
{
|
|
std::vector<std::unique_ptr<WStandardItem>> result;
|
|
std::unique_ptr<WStandardItem> item;
|
|
|
|
// column 0: country
|
|
item = cpp14::make_unique<WStandardItem>(WString(city));
|
|
result.push_back(std::move(item));
|
|
|
|
// column 1: weather
|
|
item = cpp14::make_unique<WStandardItem>();
|
|
item->setIcon(std::string("icons/") + weatherIcons[weather]);
|
|
result.push_back(std::move(item));
|
|
|
|
// column 2: drink
|
|
item = cpp14::make_unique<WStandardItem>(drink);
|
|
if (useInternalPath)
|
|
item->setLink(WLink(LinkType::InternalPath, "/drinks/" + drink));
|
|
result.push_back(std::move(item));
|
|
|
|
// column 3: visited
|
|
item = cpp14::make_unique<WStandardItem>();
|
|
item->setCheckable(true);
|
|
item->setChecked(visited);
|
|
result.push_back(std::move(item));
|
|
|
|
return result;
|
|
}
|
|
|
|
void TreeViewExample::toggleRowHeight()
|
|
{
|
|
if (treeView_->rowHeight() == WLength(31))
|
|
treeView_->setRowHeight(25);
|
|
else
|
|
treeView_->setRowHeight(31);
|
|
}
|
|
|
|
void TreeViewExample::toggleStripes()
|
|
{
|
|
treeView_->setAlternatingRowColors(!treeView_->alternatingRowColors());
|
|
}
|
|
|
|
void TreeViewExample::toggleRoot()
|
|
{
|
|
if (treeView_->rootIndex() == WModelIndex())
|
|
treeView_->setRootIndex(model_->index(0, 0));
|
|
else
|
|
treeView_->setRootIndex(WModelIndex());
|
|
}
|
|
|
|
void TreeViewExample::addRows()
|
|
{
|
|
static 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);
|
|
}
|