Project

General

Profile

Bug #5889 » TreeViewExample.C

Daniel Lier, 08/23/2017 12:56 PM

 
1
/*
2
 * Copyright (C) 2008 Emweb bvba, Kessel-Lo, Belgium.
3
 *
4
 * See the LICENSE file for terms of use.
5
 */
6
#include "TreeViewExample.h"
7

    
8
#include <iostream>
9

    
10
#include <Wt/WApplication.h>
11
#include <Wt/WContainerWidget.h>
12
#include <Wt/WEnvironment.h>
13
#include <Wt/WPanel.h>
14
#include <Wt/WPushButton.h>
15
#include <Wt/WStandardItem.h>
16
#include <Wt/WStandardItemModel.h>
17
#include <Wt/WText.h>
18
#include <Wt/WTreeView.h>
19

    
20
static const char *weatherIcons[] = {
21
  "sun01.png",
22
  "cloudy01.png",
23
  "w_cloud.png",
24
  "rain.png",
25
  "storm.png",
26
  "snow.png"
27
};
28

    
29
TreeViewModel::TreeViewModel()
30
  : belgium_(nullptr)
31
{
32
  update();
33
}
34

    
35
bool TreeViewModel::update()
36
{
37
  clear();
38
  belgium_ = nullptr;
39

    
40
  bool useInternalPath = true;
41
  insertColumns(0, 4);
42

    
43
  setHeaderData(0, Orientation::Horizontal, std::string("Places"));
44
  setHeaderData(1, Orientation::Horizontal, std::string("Weather"));
45
  setHeaderData(2, Orientation::Horizontal, std::string("Drink"));
46
  setHeaderData(3, Orientation::Horizontal, std::string("Visited"));
47

    
48
  /*
49
  * ... and data
50
  */
51
  std::unique_ptr<WStandardItem> continent, country;
52
  WStandardItem *continentPtr, *countryPtr;
53

    
54
  continent = continentItem("Europe");
55
  continentPtr = continent.get();
56
  this->appendRow(std::move(continent));
57

    
58
  country = countryItem("Belgium", "be");
59
  countryPtr = country.get();
60
  continentPtr->appendRow(std::move(country));
61
  countryPtr->appendRow(cityItems("Brussels", Rain, "Beer", useInternalPath, true));
62

    
63
  countryPtr->appendRow(cityItems("Brussels", Rain, "Beer", useInternalPath, true));
64
  countryPtr->appendRow(cityItems("Brussels", Rain, "Beer", useInternalPath, true));
65
  countryPtr->appendRow(cityItems("Brussels", Rain, "Beer", useInternalPath, true));
66
  countryPtr->appendRow(cityItems("Brussels", Rain, "Beer", useInternalPath, true));
67
  countryPtr->appendRow(cityItems("Brussels", Rain, "Beer", useInternalPath, true));
68
  countryPtr->appendRow(cityItems("Brussels", Rain, "Beer", useInternalPath, true));
69
  countryPtr->appendRow(cityItems("Brussels", Rain, "Beer", useInternalPath, true));
70
  countryPtr->appendRow(cityItems("Leuven", Rain, "Beer", useInternalPath, true));
71

    
72
  country = countryItem("France", "fr");
73
  countryPtr = country.get();
74
  continentPtr->appendRow(std::move(country));
75
  countryPtr->appendRow(cityItems("Paris", Cloud, "Wine", useInternalPath, true));
76
  countryPtr->appendRow(cityItems("Bordeaux", SunCloud, "Bordeaux wine", useInternalPath, false));
77

    
78
  country = countryItem("Spain", "sp");
79
  countryPtr = country.get();
80
  continentPtr->appendRow(std::move(country));
81
  countryPtr->appendRow(cityItems("Barcelona", Sun, "Cava", useInternalPath, true));
82
  countryPtr->appendRow(cityItems("Madrid", Sun, "San Miguel", useInternalPath, false));
83

    
84
  continent = continentItem("Africa");
85
  continentPtr = continent.get();
86
  appendRow(std::move(continent));
87

    
88
  country = countryItem("Morocco (المغرب)", "ma");
89
  countryPtr = country.get();
90
  continentPtr->appendRow(std::move(country));
91
  countryPtr->appendRow(cityItems("Casablanca", Sun, "Tea", useInternalPath, false));
92

    
93
  belgium_ = item(0, 0)->child(0, 0);
94

    
95
  return true;
96
}
97

    
98
std::unique_ptr<WStandardItem> TreeViewModel::continentItem(const std::string& continent)
99
{
100
  std::unique_ptr<WStandardItem> result
101
    = cpp14::make_unique<WStandardItem>(continent);
102
  result->setColumnCount(4);
103
  return result;
104
}
105

    
106
std::unique_ptr<WStandardItem> TreeViewModel::countryItem(const std::string& country, const std::string& code)
107
{
108
  std::unique_ptr<WStandardItem> result
109
    = cpp14::make_unique<WStandardItem>(WString(country));
110
  result->setIcon("icons/flag_" + code + ".png");
111
  return result;
112
}
113

    
114
std::vector<std::unique_ptr<WStandardItem>> TreeViewModel::cityItems(const std::string& city, WeatherIcon weather, const std::string& drink, bool useInternalPath, bool visited)
115
{
116
  std::vector<std::unique_ptr<WStandardItem>> result;
117
  std::unique_ptr<WStandardItem> item;
118

    
119
  // column 0: country
120
  item = cpp14::make_unique<WStandardItem>(WString(city));
121
  result.push_back(std::move(item));
122

    
123
  // column 1: weather
124
  item = cpp14::make_unique<WStandardItem>();
125
  item->setIcon(std::string("icons/") + weatherIcons[weather]);
126
  result.push_back(std::move(item));
127

    
128
  // column 2: drink
129
  item = cpp14::make_unique<WStandardItem>(drink);
130
  if (useInternalPath)
131
    item->setLink(WLink(LinkType::InternalPath, "/drinks/" + drink));
132
  result.push_back(std::move(item));
133

    
134
  // column 3: visited
135
  item = cpp14::make_unique<WStandardItem>();
136
  item->setCheckable(true);
137
  item->setChecked(visited);
138
  result.push_back(std::move(item));
139

    
140
  return result;
141
}
142

    
143
void TreeViewModel::toggleRowHeight(WTreeView *treeView_)
144
{
145
  if (treeView_->rowHeight() == WLength(31))
146
    treeView_->setRowHeight(25);
147
  else
148
    treeView_->setRowHeight(31);
149
}
150

    
151
void TreeViewModel::toggleStripes(WTreeView *treeView_)
152
{
153
  treeView_->setAlternatingRowColors(!treeView_->alternatingRowColors());
154
}
155

    
156
void TreeViewModel::toggleRoot(WTreeView *treeView_)
157
{
158
  if (treeView_->rootIndex() == WModelIndex())
159
    treeView_->setRootIndex(this->index(0, 0));
160
  else
161
    treeView_->setRootIndex(WModelIndex());
162
}
163

    
164
void TreeViewModel::addRows(WTreeView *treeView_)
165
{
166
  if (nullptr != belgium_)
167
  {
168
    int COUNT = 10;
169

    
170
    for (int i = 0; i < COUNT; ++i)
171
    {
172
      std::string cityName = "City " + asString(belgium_->rowCount() + 1).toUTF8();
173
      bool useInternalPath = false;
174
      belgium_->appendRow(cityItems(cityName, Storm, "Juice", useInternalPath, false));
175
    }
176

    
177
    treeView_->scrollTo(belgium_->child(belgium_->rowCount() - COUNT)->index(), ScrollHint::PositionAtTop);
178
  }
179
}
180

    
181

    
182

    
183
TreeViewExample::TreeViewExample(const WString& titleText)
184
{
185
  model_ = std::make_unique<TreeViewModel>();
186
  TreeViewModel *pTreeViewModel = dynamic_cast<TreeViewModel*>(model_.get());
187

    
188
  this->addWidget(cpp14::make_unique<WText>(titleText));
189

    
190
  /*
191
   * Now create the view
192
   */
193
  WPanel *panel = this->addWidget(cpp14::make_unique<WPanel>());
194
  panel->resize(600, 300);
195

    
196
  auto treeView = cpp14::make_unique<WTreeView>();
197
  treeView_ = treeView.get();
198
  panel->setCentralWidget(std::move(treeView));
199
  
200
  if (!WApplication::instance()->environment().ajax())
201
    treeView_->resize(WLength::Auto, 290);
202

    
203
  treeView_->setAlternatingRowColors(true);
204
  treeView_->setRowHeight(25);
205
  treeView_->setModel(model_);
206

    
207
  treeView_->setColumnWidth(1, WLength(100));
208
  treeView_->setColumnAlignment(1, AlignmentFlag::Center);
209
  treeView_->setColumnWidth(3, WLength(100));
210
  treeView_->setColumnAlignment(3, AlignmentFlag::Center);
211

    
212
  treeView_->setRowHeaderCount(1);
213
  treeView_->setColumnWidth(0, 300);
214

    
215
  /*
216
   * Expand the first (and single) top level node
217
   */
218
  treeView_->setExpanded(model_->index(0, 0), true);
219
  treeView_->setExpanded(model_->index(0, 0, model_->index(0, 0)), true);
220

    
221
  treeView_->setSortingEnabled(false);
222
  treeView_->setSortingEnabled(0, true);
223
  treeView_->setSortingEnabled(2, true);
224

    
225
  /*
226
   * Setup some buttons to manipulate the view and the model.
227
   */
228
  WContainerWidget *wc = this->addWidget(cpp14::make_unique<WContainerWidget>());
229
  WPushButton *b;
230

    
231
  b = wc->addWidget(cpp14::make_unique<WPushButton>("Toggle row height"));
232
  b->clicked().connect([=] { pTreeViewModel->toggleRowHeight(treeView_); });
233
  b->setToolTip("Toggles row height between 31px and 25px");
234
  
235
  b = wc->addWidget(cpp14::make_unique<WPushButton>("Toggle stripes"));
236
  b->clicked().connect([=] { pTreeViewModel->toggleStripes(treeView_); });
237
  b->setToolTip("Toggle alternating row colors");
238
  
239
  b = wc->addWidget(cpp14::make_unique<WPushButton>("Toggle root"));
240
  b->clicked().connect([=] { pTreeViewModel->toggleRoot(treeView_); });
241
  b->setToolTip("Toggles root item between all and the first continent.");
242

    
243
  b = wc->addWidget(cpp14::make_unique<WPushButton>("Add rows"));
244
  b->clicked().connect([=]{ pTreeViewModel->addRows(treeView_); });
245
  b->setToolTip("Adds some cities to Belgium");
246
}
247

    
248
bool TreeViewExample::update()
249
{
250
  bool bReturn = false;
251

    
252
  if (nullptr != treeView_)
253
  {
254
    TreeViewModel *pModel = dynamic_cast<TreeViewModel*>(treeView_->model().get());
255
    if (nullptr != pModel) bReturn = pModel->update();
256
  }
257

    
258
  return bReturn;
259
}
260

    
(2-2/3)