Project

General

Profile

Bug #3371 ยป modelview2.cpp

Alexander Morozov, 06/23/2014 04:28 PM

 
#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);
}
    (1-1/1)