Project

General

Profile

Bug #7396 » TreeViewExample.C

Geert Verbruggen, 01/10/2020 02:33 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
TreeViewExample::TreeViewExample(std::shared_ptr<WStandardItemModel> model,
30
                                 const WString& titleText)
31
  : model_(model)
32
{
33
  belgium_ = model_->item(0, 0)->child(0, 0);
34

    
35
  this->addWidget(cpp14::make_unique<WText>(titleText));
36

    
37
  /*
38
   * Now create the view
39
   */
40
  WPanel *panel = this->addWidget(cpp14::make_unique<WPanel>());
41
  panel->resize(600, 300);
42

    
43
//  panel->hide();
44

    
45
  auto treeView = cpp14::make_unique<WTreeView>();
46
  treeView_ = treeView.get();
47
  panel->setCentralWidget(std::move(treeView));
48
  
49
  if (!WApplication::instance()->environment().ajax())
50
    treeView_->resize(WLength::Auto, 290);
51

    
52
  treeView_->setAlternatingRowColors(true);
53
  treeView_->setRowHeight(25);
54
  treeView_->setModel(model_);
55

    
56
  treeView_->setColumnWidth(1, WLength(100));
57
  treeView_->setColumnAlignment(1, AlignmentFlag::Center);
58
  treeView_->setColumnWidth(3, WLength(100));
59
  treeView_->setColumnAlignment(3, AlignmentFlag::Center);
60

    
61
  treeView_->setRowHeaderCount(1);
62
  treeView_->setColumnWidth(0, 300);
63

    
64
  /*
65
   * Expand the first (and single) top level node
66
   */
67
  treeView_->setExpanded(model->index(0, 0), true);
68
  treeView_->setExpanded(model->index(0, 0, model->index(0, 0)), true);
69

    
70
  treeView_->setSortingEnabled(false);
71
  treeView_->setSortingEnabled(0, true);
72
  treeView_->setSortingEnabled(2, true);
73

    
74
  /*
75
   * Setup some buttons to manipulate the view and the model.
76
   */
77
  WContainerWidget *wc =
78
      this->addWidget(cpp14::make_unique<WContainerWidget>());
79
  WPushButton *b;
80
  
81
  b = wc->addWidget(cpp14::make_unique<WPushButton>("Toggle row height"));
82
  b->clicked().connect(this, &TreeViewExample::toggleRowHeight);
83
  b->setToolTip("Toggles row height between 31px and 25px");
84
  
85
  b = wc->addWidget(cpp14::make_unique<WPushButton>("Toggle stripes"));
86
  b->clicked().connect(this, &TreeViewExample::toggleStripes);
87
  b->setToolTip("Toggle alternating row colors");
88
  
89
  b = wc->addWidget(cpp14::make_unique<WPushButton>("Toggle root"));
90
  b->clicked().connect(this, &TreeViewExample::toggleRoot);
91
  b->setToolTip("Toggles root item between all and the first continent.");
92

    
93
  b = wc->addWidget(cpp14::make_unique<WPushButton>("Add rows"));
94
  b->clicked().connect(this, &TreeViewExample::addRows);
95
  b->setToolTip("Adds some cities to Belgium");
96

    
97
  b = wc->addWidget(cpp14::make_unique<WPushButton>("Show"));
98
  b->clicked().connect(panel, &WPanel::show);
99
}
100

    
101
std::shared_ptr<WStandardItemModel> TreeViewExample::createModel(bool useInternalPath)
102
{
103
  /*
104
   * Setup a model.
105
   *
106
   * We use the standard item model, which is a general model
107
   * suitable for hierarchical (tree-like) data, but stores all data
108
   * in memory.
109
   */
110
  auto result = std::make_shared<WStandardItemModel>(0, 4);
111

    
112
  /*
113
   * Headers ...
114
   */
115
  result->setHeaderData(0, Orientation::Horizontal, std::string("Places"));
116
  result->setHeaderData(1, Orientation::Horizontal, std::string("Weather"));
117
  result->setHeaderData(2, Orientation::Horizontal, std::string("Drink"));
118
  result->setHeaderData(3, Orientation::Horizontal, std::string("Visited"));
119
  
120
  /*
121
   * ... and data
122
   */
123
  std::unique_ptr<WStandardItem> continent, country;
124
  WStandardItem *continentPtr, *countryPtr;
125

    
126
  continent = continentItem("Europe");
127
  continentPtr = continent.get();
128
  result->appendRow(std::move(continent));
129

    
130
  country = countryItem("Belgium", "be");
131
  countryPtr = country.get();
132
  continentPtr->appendRow(std::move(country));
133
  countryPtr->appendRow(cityItems("Brussels", Rain, "Beer",
134
                                  useInternalPath, true));
135
  countryPtr->appendRow(cityItems("Leuven", Rain, "Beer",
136
                                  useInternalPath, true));
137
  
138
  country = countryItem("France", "fr");
139
  countryPtr = country.get();
140
  continentPtr->appendRow(std::move(country));
141
  countryPtr->appendRow(cityItems("Paris", Cloud, "Wine",
142
                                  useInternalPath, true));
143
  countryPtr->appendRow(cityItems("Bordeaux", SunCloud, "Bordeaux wine",
144
                                  useInternalPath, false));
145
  
146
  country = countryItem("Spain", "sp");
147
  countryPtr = country.get();
148
  continentPtr->appendRow(std::move(country));
149
  countryPtr->appendRow(cityItems("Barcelona", Sun, "Cava",
150
                                  useInternalPath, true));
151
  countryPtr->appendRow(cityItems("Madrid", Sun, "San Miguel",
152
                                  useInternalPath, false));
153
  
154
  continent = continentItem("Africa");
155
  continentPtr = continent.get();
156
  result->appendRow(std::move(continent));
157
  
158
  country = countryItem("Morocco (المغرب)", "ma");
159
  countryPtr = country.get();
160
  continentPtr->appendRow(std::move(country));
161
  countryPtr->appendRow(cityItems("Casablanca", Sun, "Tea",
162
                                  useInternalPath, false));
163

    
164
  return result;
165
}
166

    
167
std::unique_ptr<WStandardItem> TreeViewExample::continentItem(const std::string& continent)
168
{
169
  std::unique_ptr<WStandardItem> result
170
      = cpp14::make_unique<WStandardItem>(continent);
171
  result->setColumnCount(4);
172
  return result;
173
}
174

    
175
std::unique_ptr<WStandardItem> TreeViewExample::countryItem(const std::string& country,
176
					    const std::string& code)
177
{
178
  std::unique_ptr<WStandardItem> result
179
      = cpp14::make_unique<WStandardItem>(WString(country));
180
  result->setIcon("icons/flag_" + code + ".png");
181
  return result;
182
}
183

    
184
std::vector<std::unique_ptr<WStandardItem>>
185
TreeViewExample::cityItems(const std::string& city,
186
			   WeatherIcon weather,
187
			   const std::string& drink,
188
			   bool useInternalPath, bool visited)
189
{
190
  std::vector<std::unique_ptr<WStandardItem>> result;
191
  std::unique_ptr<WStandardItem> item;
192
  
193
  // column 0: country
194
  item = cpp14::make_unique<WStandardItem>(WString(city));
195
  result.push_back(std::move(item));
196
  
197
  // column 1: weather
198
  item = cpp14::make_unique<WStandardItem>();
199
  item->setIcon(std::string("icons/") + weatherIcons[weather]);
200
  result.push_back(std::move(item));
201
  
202
  // column 2: drink
203
  item = cpp14::make_unique<WStandardItem>(drink);
204
  if (useInternalPath)
205
    item->setLink(WLink(LinkType::InternalPath, "/drinks/" + drink));
206
  result.push_back(std::move(item));
207
  
208
  // column 3: visited
209
  item = cpp14::make_unique<WStandardItem>();
210
  item->setCheckable(true);
211
  item->setChecked(visited);
212
  result.push_back(std::move(item));
213
  
214
  return result;
215
}
216

    
217
void TreeViewExample::toggleRowHeight()
218
{
219
  if (treeView_->rowHeight() == WLength(31))
220
    treeView_->setRowHeight(25);
221
  else
222
    treeView_->setRowHeight(31);
223
}
224

    
225
void TreeViewExample::toggleStripes()
226
{
227
  treeView_->setAlternatingRowColors(!treeView_->alternatingRowColors());
228
}
229

    
230
void TreeViewExample::toggleRoot()
231
{
232
  if (treeView_->rootIndex() == WModelIndex())
233
    treeView_->setRootIndex(model_->index(0, 0));
234
  else
235
    treeView_->setRootIndex(WModelIndex());
236
}
237

    
238
void TreeViewExample::addRows()
239
{
240
  static int COUNT = 10;
241

    
242
  for (int i = 0; i < COUNT; ++i) {
243
    std::string cityName = "City "
244
      + asString(belgium_->rowCount() + 1).toUTF8();
245
    
246
    bool useInternalPath = false;
247
    belgium_->appendRow(cityItems(cityName, Storm, "Juice",
248
                                  useInternalPath, false));
249
  }
250

    
251
  treeView_->scrollTo(belgium_->child(belgium_->rowCount() -COUNT )->index(),
252
                      ScrollHint::PositionAtTop);
253
}
(1-1/4)