|
#include <string>
|
|
#include <vector>
|
|
#include <boost/any.hpp>
|
|
#include <boost/thread.hpp>
|
|
#include <Wt/WAbstractItemDelegate>
|
|
#include <Wt/WAbstractTableModel>
|
|
#include <Wt/WApplication>
|
|
#include <Wt/WPushButton>
|
|
#include <Wt/WTableView>
|
|
|
|
using namespace Wt;
|
|
|
|
class Model : public WAbstractTableModel
|
|
{
|
|
public:
|
|
Model(WObject *parent = 0);
|
|
|
|
virtual int columnCount(const WModelIndex &parent = WModelIndex()) const;
|
|
virtual int rowCount(const WModelIndex &parent = WModelIndex()) const;
|
|
virtual boost::any data(const WModelIndex &index, int role = DisplayRole) const;
|
|
|
|
void push_front(const std::string &text);
|
|
void pop_front();
|
|
|
|
private:
|
|
std::vector<std::string> data_;
|
|
};
|
|
|
|
Model::Model(WObject *parent) :
|
|
WAbstractTableModel(parent)
|
|
{
|
|
data_.push_back("1");
|
|
data_.push_back("2");
|
|
data_.push_back("3");
|
|
data_.push_back("4");
|
|
data_.push_back("5");
|
|
}
|
|
|
|
int Model::columnCount(const WModelIndex &parent) const
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
int Model::rowCount(const WModelIndex &parent) const
|
|
{
|
|
return data_.size();
|
|
}
|
|
|
|
boost::any Model::data(const WModelIndex &index, int role) const
|
|
{
|
|
if (role != DisplayRole) return boost::any();
|
|
if (index.row() >= data_.size()) return boost::any();
|
|
return boost::any(data_[index.row()]);
|
|
}
|
|
|
|
void Model::push_front(const std::string &text)
|
|
{
|
|
beginInsertRows(WModelIndex(), 0, 0);
|
|
data_.insert(data_.begin(), text);
|
|
endInsertRows();
|
|
}
|
|
|
|
void Model::pop_front()
|
|
{
|
|
if (data_.size()) {
|
|
beginRemoveRows(WModelIndex(), 0, 0);
|
|
data_.erase(data_.begin());
|
|
endRemoveRows();
|
|
}
|
|
}
|
|
|
|
class ItemWidget : public WPushButton
|
|
{
|
|
public:
|
|
ItemWidget(const WModelIndex &index, WContainerWidget *parent = 0) :
|
|
WPushButton(parent), index_(index), state_(0)
|
|
{
|
|
onClicked();
|
|
clicked().connect(this, &ItemWidget::onClicked);
|
|
}
|
|
|
|
void setIndex(const WModelIndex &index) { index_ = index; }
|
|
|
|
private:
|
|
void onClicked();
|
|
|
|
WModelIndex index_;
|
|
int state_;
|
|
};
|
|
|
|
void ItemWidget::onClicked()
|
|
{
|
|
if (state_) {
|
|
setText(boost::any_cast<const std::string &>(index_.data()));
|
|
state_ = 0;
|
|
} else {
|
|
setText("[" + boost::any_cast<const std::string &>(index_.data()) + "]");
|
|
state_ = 1;
|
|
}
|
|
}
|
|
|
|
class Delegate : public WAbstractItemDelegate
|
|
{
|
|
public:
|
|
Delegate(WObject *parent = 0) : WAbstractItemDelegate(parent) {}
|
|
|
|
virtual WWidget *update(WWidget *widget, const WModelIndex &index,
|
|
WFlags<ViewItemRenderFlag> flags);
|
|
|
|
virtual void updateModelIndex(WWidget *widget, const WModelIndex &index);
|
|
};
|
|
|
|
WWidget *Delegate::update(WWidget *widget, const WModelIndex &index,
|
|
WFlags<ViewItemRenderFlag> flags)
|
|
{
|
|
if (widget) {
|
|
updateModelIndex(widget, index);
|
|
return widget;
|
|
} else {
|
|
WContainerWidget *container = new WContainerWidget;
|
|
new ItemWidget(index, container);
|
|
return container;
|
|
}
|
|
}
|
|
|
|
void Delegate::updateModelIndex(WWidget *widget, const WModelIndex &index)
|
|
{
|
|
WContainerWidget *container = dynamic_cast<WContainerWidget *>(widget);
|
|
assert(container);
|
|
ItemWidget *item = dynamic_cast<ItemWidget *>(container->widget(0));
|
|
assert(item);
|
|
item->setIndex(index);
|
|
}
|
|
|
|
class App : public WApplication
|
|
{
|
|
public:
|
|
App(const WEnvironment &env);
|
|
|
|
private:
|
|
void addRow();
|
|
void removeRow();
|
|
|
|
Model *model_;
|
|
WTableView *table_;
|
|
};
|
|
|
|
App::App(const WEnvironment &env) :
|
|
WApplication(env)
|
|
{
|
|
model_ = new Model(this);
|
|
|
|
Delegate *delegate = new Delegate(this);
|
|
|
|
table_ = new WTableView(root());
|
|
table_->setHeaderHeight(0);
|
|
table_->setRowHeight(30);
|
|
table_->setModel(model_);
|
|
table_->setItemDelegate(delegate);
|
|
|
|
WPushButton *addButton = new WPushButton("Add", root());
|
|
WPushButton *removeButton = new WPushButton("Remove", root());
|
|
addButton->clicked().connect(this, &App::addRow);
|
|
removeButton->clicked().connect(this, &App::removeRow);
|
|
}
|
|
|
|
void App::addRow()
|
|
{
|
|
model_->push_front("x");
|
|
}
|
|
|
|
void App::removeRow()
|
|
{
|
|
model_->pop_front();
|
|
}
|
|
|
|
static WApplication *createApplication(const WEnvironment &env)
|
|
{
|
|
return new App(env);
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
return WRun(argc, argv, createApplication);
|
|
}
|