summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fusion_model.hpp71
-rw-r--r--fusion_static_dispatch.hpp2
-rw-r--r--main.cpp75
-rw-r--r--qt_adapter.hpp62
4 files changed, 164 insertions, 46 deletions
diff --git a/fusion_model.hpp b/fusion_model.hpp
index ace8f51..f40ac33 100644
--- a/fusion_model.hpp
+++ b/fusion_model.hpp
@@ -9,44 +9,95 @@
#include <vector>
#include <map>
+#include <iostream>
template <typename T>
struct fusion_model {
-
+private:
+ fusion_model(T);
+};
+
+struct FusionModelInterface {
+ virtual size_t row_count() const {throw std::runtime_error("\"row_count()\" not implemented for this model");}
+ virtual size_t column_count() const {throw std::runtime_error("\"column_count()\" not implemented for this model");}
+ virtual std::string field_name(size_t section) const {throw std::runtime_error("\"field_name(size_t)\" not implemented for this model");}
+ virtual std::string key(size_t section) const {throw std::runtime_error("\"key(size_t)\" not implemented for this model");}
+ virtual boost::any get_cell(size_t row, size_t column) const {throw std::runtime_error("\"get_cell(size_t, size_t)\" not implemented for this model");}
};
template <typename T>
-struct fusion_model<std::vector<T>>
+struct fusion_model<std::vector<T>> : public FusionModelInterface
{
- static_assert(boost::fusion::traits::is_sequence<T>::type::value, "T is not a boost fusion sequence");
+ static_assert(friendly_fusion::traits::is_sequence<T>::type::value, "T is not a boost fusion sequence");
typedef std::vector<T> data_type;
+ typedef T row_type;
+
+ static constexpr bool has_header_h = true;
+ static constexpr bool has_header_v = false;
std::vector<T> data;
- size_t row_count() const
+ virtual size_t row_count() const override final
{
return data.size();
}
- size_t column_count() const
+ virtual size_t column_count() const override final
{
return boost::fusion::result_of::size<T>::type::value;
}
- std::string horizontal_header_data(size_t section) const
+ virtual std::string field_name(size_t section) const override final
{
return get_nth_name<T>(section);
}
- boost::any get_cell(size_t row, size_t column) const
+ virtual boost::any get_cell(size_t row, size_t column) const override final
{
return get_nth(data[row], column);
}
};
-template <typename T, typename U>
-struct fusion_model<std::map<T, U>>
+template <typename T>
+struct fusion_model<std::map<std::string, T>> : public FusionModelInterface
{
- std::map<T, U> data;
+ static_assert(boost::fusion::traits::is_sequence<T>::type::value, "T is not a boost fusion sequence");
+
+ typedef std::map<std::string, T> data_type;
+ typedef T row_type;
+
+ static constexpr bool has_header_h = true;
+ static constexpr bool has_header_v = true;
+
+ std::map<std::string, T> data;
+
+ virtual size_t row_count() const override final
+ {
+ return data.size();
+ }
+
+ virtual size_t column_count() const override final
+ {
+ return boost::fusion::result_of::size<T>::type::value;
+ }
+
+ virtual std::string field_name(size_t section) const override final
+ {
+ return get_nth_name<T>(section);
+ }
+
+ virtual std::string key(size_t section) const override final
+ {
+ auto cit = data.cbegin();
+ std::advance(cit, section);
+ return cit->first;
+ }
+
+ virtual boost::any get_cell(size_t row, size_t column) const override final
+ {
+ auto cit = data.cbegin();
+ std::advance(cit, row);
+ return get_nth(cit->second, column);
+ }
}; \ No newline at end of file
diff --git a/fusion_static_dispatch.hpp b/fusion_static_dispatch.hpp
index 17b6ff4..8b68ba0 100644
--- a/fusion_static_dispatch.hpp
+++ b/fusion_static_dispatch.hpp
@@ -5,6 +5,8 @@
#include <boost/any.hpp>
+#include <functional>
+
template <typename T, int index>
struct TypeAt {
typedef friendly_fusion::result_of::begin<T> begin;
diff --git a/main.cpp b/main.cpp
index 1ca2350..3e9307d 100644
--- a/main.cpp
+++ b/main.cpp
@@ -2,19 +2,23 @@
#include "fusion_model.hpp"
#include "qt_adapter.hpp"
#include "gui_item_delegate.hpp"
+#include "meta_types.hpp"
#include <boost/fusion/adapted.hpp>
#include <iostream>
#include <QMainWindow>
+#include <QHeaderView>
+#include <QVBoxLayout>
#include <QApplication>
+#include <QMdiArea>
struct Data {
std::string name;
uint32_t number;
float ratio;
- bool lolwut;
+ bool boolean;
};
BOOST_FUSION_ADAPT_STRUCT(
@@ -22,7 +26,7 @@ BOOST_FUSION_ADAPT_STRUCT(
(std::string, name)
(uint32_t, number)
(float, ratio)
- (bool, lolwut)
+ (bool, boolean)
)
struct DataModel : public fusion_model<std::vector<Data>> {
@@ -32,49 +36,62 @@ struct DataModel : public fusion_model<std::vector<Data>> {
}
};
+struct DataMapping :public fusion_model<std::map<std::string, Data>> {
+ void add_data(std::string key, Data value)
+ {
+ data.emplace(key, value);
+ }
+};
+
int main()
{
+ Data d1{"Pietje", 2, 3.333f, true};
+ Data d2{"Jantje", 3, 1.5f, false};
+ Data d3{"Sjaakje", 1, 0.1337f, false};
+
DataModel model;
- model.add_data({"Pietje", 2, 3.333f, true});
- model.add_data({"Jantje", 3, 1.5f, false});
- model.add_data({"Sjaakje", 1, 0.1337f, false});
+ model.add_data(d1);
+ model.add_data(d2);
+ model.add_data(d3);
auto adapter = make_qt_adapter(model);
+ DataMapping mapping;
+
+ mapping.add_data("nummer1", d1);
+ mapping.add_data("nummer2", d2);
+ mapping.add_data("nummer3", d3);
+
+ auto&& adapter2 = make_qt_adapter(mapping);
+
int argc = 0;
QApplication qapp(argc, nullptr);
QMainWindow w;
-
- decltype(adapter)::element_type::view view;
- view.setModel(adapter.get());
+ widget_type<decltype(adapter)>::type widget;
+ widget.setFixedSize(640, 480);
+ widget.setModel(adapter.get());
+ //widget.show();
- GuiItemDelegate delegate;
- view.setItemDelegate(&delegate);
+ widget_type<decltype(adapter)>::type widget2;
+ widget2.setFixedSize(640, 480);
+ widget2.verticalHeader()->setEnabled(true);
+ widget2.setModel(adapter2.get());
+ //widget2.show();
- view.show();
+ QMdiArea area;
- qapp.exec();
+ QVBoxLayout layout;
+
+ layout.addWidget(&widget);
+ layout.addWidget(&widget2);
- for(int column = 0; column < model.column_count(); ++column)
- {
- std::cout << model.horizontal_header_data(column) << "\t";
- }
- std::cout << std::endl;
+ area.setLayout(&layout);
- for(int row = 0; row < model.row_count(); ++row)
- {
- for(int column = 0; column < model.column_count(); ++column) {
- if(column == 0) {
- std::cout << boost::any_cast<std::string>(model.get_cell(row, column)) << "\t";
- } else {
- std::cout << boost::any_cast<uint32_t>(model.get_cell(row, column)) << "\t";
- }
- }
- std::cout << std::endl;
- }
+ w.setCentralWidget(&area);
+ w.show();
- return 0;
+ return qapp.exec();
}
diff --git a/qt_adapter.hpp b/qt_adapter.hpp
index 2843667..6e0de17 100644
--- a/qt_adapter.hpp
+++ b/qt_adapter.hpp
@@ -3,14 +3,16 @@
#include "fusion_model.hpp"
#include "boost_any_to_qvariant.hpp"
#include "meta_types.hpp"
+#include "gui_item_delegate.hpp"
#include <QAbstractTableModel>
#include <QTableView>
+#include <QVariant>
#include <QMetaType>
#include <memory>
-
-
+#include <string>
+#include <iostream>
template <typename T>
struct QtModelType
@@ -24,6 +26,34 @@ struct QtModelType<std::vector<V>>
typedef QAbstractTableModel type;
};
+template <typename V>
+struct QtModelType<std::map<std::string, V>>
+{
+ typedef QAbstractTableModel type;
+};
+
+template <typename T>
+struct widget_type {
+ typedef void type;
+};
+
+template <typename T>
+struct widget_type<std::unique_ptr<T>> {
+ typedef typename T::widget type;
+};
+
+template <typename T>
+struct QtWidget : public T {
+
+ GuiItemDelegate delegate;
+
+ QtWidget(QWidget* parent = nullptr)
+ : T(parent)
+ {
+ T::setItemDelegate(&delegate);
+ }
+};
+
template <typename T, typename Q>
struct QtAdapter : public Q {
@@ -37,6 +67,7 @@ template <typename T>
struct QtAdapter<T, QAbstractTableModel> : public QAbstractTableModel
{
typedef QTableView view;
+ typedef QtWidget<view> widget;
T model;
@@ -54,16 +85,33 @@ struct QtAdapter<T, QAbstractTableModel> : public QAbstractTableModel
return model.column_count();
}
- virtual QVariant data(QModelIndex const& index, int role) const
+ virtual QVariant data(QModelIndex const& index, int role) const override
{
if(role != Qt::DisplayRole) return QVariant();
- return to_qvariant<typename T::data_type::value_type>(model.get_cell(index.row(), index.column()), index.column());
+ return to_qvariant<typename T::row_type>(model.get_cell(index.row(), index.column()), index.column());
+ }
+
+ virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const override
+ {
+ if(role != Qt::DisplayRole) {
+ return QVariant();
+ }
+
+ if(orientation == Qt::Horizontal && T::has_header_h) {
+ return QVariant(QString::fromStdString(model.field_name(section)));
+ }
+
+ if(orientation == Qt::Vertical && T::has_header_v) {
+ return QVariant(QString::fromStdString(model.key(section)));
+ }
+
+ return QVariant();
}
};
-
template <typename T>
-std::shared_ptr<QtAdapter<T, typename QtModelType<typename T::data_type>::type>> make_qt_adapter(T value) {
- return std::make_shared<QtAdapter<T, typename QtModelType<typename T::data_type>::type>>(value);
+std::unique_ptr<QtAdapter<T, typename QtModelType<typename T::data_type>::type>> make_qt_adapter(T value) {
+ typedef QtAdapter<T, typename QtModelType<typename T::data_type>::type> type;
+ return std::unique_ptr<type>(new type(value));
}