1
|
#include <string>
|
2
|
#include <vector>
|
3
|
#include <boost/any.hpp>
|
4
|
#include <boost/thread.hpp>
|
5
|
#include <Wt/WAbstractItemDelegate>
|
6
|
#include <Wt/WAbstractTableModel>
|
7
|
#include <Wt/WApplication>
|
8
|
#include <Wt/WPushButton>
|
9
|
#include <Wt/WTableView>
|
10
|
|
11
|
using namespace Wt;
|
12
|
|
13
|
class Model : public WAbstractTableModel
|
14
|
{
|
15
|
public:
|
16
|
Model(WObject *parent = 0);
|
17
|
|
18
|
virtual int columnCount(const WModelIndex &parent = WModelIndex()) const;
|
19
|
virtual int rowCount(const WModelIndex &parent = WModelIndex()) const;
|
20
|
virtual boost::any data(const WModelIndex &index, int role = DisplayRole) const;
|
21
|
|
22
|
void push_front(const std::string &text);
|
23
|
void pop_front();
|
24
|
|
25
|
private:
|
26
|
std::vector<std::string> data_;
|
27
|
};
|
28
|
|
29
|
Model::Model(WObject *parent) :
|
30
|
WAbstractTableModel(parent)
|
31
|
{
|
32
|
data_.push_back("1");
|
33
|
data_.push_back("2");
|
34
|
data_.push_back("3");
|
35
|
data_.push_back("4");
|
36
|
data_.push_back("5");
|
37
|
}
|
38
|
|
39
|
int Model::columnCount(const WModelIndex &parent) const
|
40
|
{
|
41
|
return 1;
|
42
|
}
|
43
|
|
44
|
int Model::rowCount(const WModelIndex &parent) const
|
45
|
{
|
46
|
return data_.size();
|
47
|
}
|
48
|
|
49
|
boost::any Model::data(const WModelIndex &index, int role) const
|
50
|
{
|
51
|
if (role != DisplayRole) return boost::any();
|
52
|
if (index.row() >= data_.size()) return boost::any();
|
53
|
return boost::any(data_[index.row()]);
|
54
|
}
|
55
|
|
56
|
void Model::push_front(const std::string &text)
|
57
|
{
|
58
|
beginInsertRows(WModelIndex(), 0, 0);
|
59
|
data_.insert(data_.begin(), text);
|
60
|
endInsertRows();
|
61
|
}
|
62
|
|
63
|
void Model::pop_front()
|
64
|
{
|
65
|
if (data_.size()) {
|
66
|
beginRemoveRows(WModelIndex(), 0, 0);
|
67
|
data_.erase(data_.begin());
|
68
|
endRemoveRows();
|
69
|
}
|
70
|
}
|
71
|
|
72
|
class ItemWidget : public WPushButton
|
73
|
{
|
74
|
public:
|
75
|
ItemWidget(const WModelIndex &index, WContainerWidget *parent = 0) :
|
76
|
WPushButton(parent), index_(index), state_(0)
|
77
|
{
|
78
|
onClicked();
|
79
|
clicked().connect(this, &ItemWidget::onClicked);
|
80
|
}
|
81
|
|
82
|
void setIndex(const WModelIndex &index) { index_ = index; }
|
83
|
|
84
|
private:
|
85
|
void onClicked();
|
86
|
|
87
|
WModelIndex index_;
|
88
|
int state_;
|
89
|
};
|
90
|
|
91
|
void ItemWidget::onClicked()
|
92
|
{
|
93
|
if (state_) {
|
94
|
setText(boost::any_cast<const std::string &>(index_.data()));
|
95
|
state_ = 0;
|
96
|
} else {
|
97
|
setText("[" + boost::any_cast<const std::string &>(index_.data()) + "]");
|
98
|
state_ = 1;
|
99
|
}
|
100
|
}
|
101
|
|
102
|
class Delegate : public WAbstractItemDelegate
|
103
|
{
|
104
|
public:
|
105
|
Delegate(WObject *parent = 0) : WAbstractItemDelegate(parent) {}
|
106
|
|
107
|
virtual WWidget *update(WWidget *widget, const WModelIndex &index,
|
108
|
WFlags<ViewItemRenderFlag> flags);
|
109
|
|
110
|
virtual void updateModelIndex(WWidget *widget, const WModelIndex &index);
|
111
|
};
|
112
|
|
113
|
WWidget *Delegate::update(WWidget *widget, const WModelIndex &index,
|
114
|
WFlags<ViewItemRenderFlag> flags)
|
115
|
{
|
116
|
if (widget) {
|
117
|
updateModelIndex(widget, index);
|
118
|
return widget;
|
119
|
} else {
|
120
|
WContainerWidget *container = new WContainerWidget;
|
121
|
new ItemWidget(index, container);
|
122
|
return container;
|
123
|
}
|
124
|
}
|
125
|
|
126
|
void Delegate::updateModelIndex(WWidget *widget, const WModelIndex &index)
|
127
|
{
|
128
|
WContainerWidget *container = dynamic_cast<WContainerWidget *>(widget);
|
129
|
assert(container);
|
130
|
ItemWidget *item = dynamic_cast<ItemWidget *>(container->widget(0));
|
131
|
assert(item);
|
132
|
item->setIndex(index);
|
133
|
}
|
134
|
|
135
|
class App : public WApplication
|
136
|
{
|
137
|
public:
|
138
|
App(const WEnvironment &env);
|
139
|
|
140
|
private:
|
141
|
void addRow();
|
142
|
void removeRow();
|
143
|
|
144
|
Model *model_;
|
145
|
WTableView *table_;
|
146
|
};
|
147
|
|
148
|
App::App(const WEnvironment &env) :
|
149
|
WApplication(env)
|
150
|
{
|
151
|
model_ = new Model(this);
|
152
|
|
153
|
Delegate *delegate = new Delegate(this);
|
154
|
|
155
|
table_ = new WTableView(root());
|
156
|
table_->setHeaderHeight(0);
|
157
|
table_->setRowHeight(30);
|
158
|
table_->setModel(model_);
|
159
|
table_->setItemDelegate(delegate);
|
160
|
|
161
|
WPushButton *addButton = new WPushButton("Add", root());
|
162
|
WPushButton *removeButton = new WPushButton("Remove", root());
|
163
|
addButton->clicked().connect(this, &App::addRow);
|
164
|
removeButton->clicked().connect(this, &App::removeRow);
|
165
|
}
|
166
|
|
167
|
void App::addRow()
|
168
|
{
|
169
|
model_->push_front("x");
|
170
|
}
|
171
|
|
172
|
void App::removeRow()
|
173
|
{
|
174
|
model_->pop_front();
|
175
|
}
|
176
|
|
177
|
static WApplication *createApplication(const WEnvironment &env)
|
178
|
{
|
179
|
return new App(env);
|
180
|
}
|
181
|
|
182
|
int main(int argc, char **argv)
|
183
|
{
|
184
|
return WRun(argc, argv, createApplication);
|
185
|
}
|