diff --git a/src/strategies/role.cpp b/src/strategies/role.cpp index fe073a5..ef7de74 100644 --- a/src/strategies/role.cpp +++ b/src/strategies/role.cpp @@ -1,82 +1,176 @@ /*************************************************************************** * Copyright (C) 2018 by Emmanuel Lepage Vallee * * Author : Emmanuel Lepage Vallee * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * **************************************************************************/ #include "role.h" +#include +#include +#include + +// KQuickItemViews +#include +#include + class RoleStrategiesPrivate { public: - int m_Role { Qt::SizeHintRole }; - QString m_RoleName { "sizeHint" }; + bool m_Reload { true }; + int m_SizeRole { Qt::SizeHintRole }; + int m_PositionRole { -1 }; + QString m_SizeRoleName { "sizeHint" }; + QString m_PositionRoleName { }; void updateName(); + + GeometryStrategies::Role *q_ptr; }; GeometryStrategies::Role::Role(Viewport *parent) : GeometryAdapter(parent), d_ptr(new RoleStrategiesPrivate()) { + d_ptr->q_ptr = this; setCapabilities(Capabilities::HAS_AHEAD_OF_TIME); } GeometryStrategies::Role::~Role() { delete d_ptr; } QSizeF GeometryStrategies::Role::sizeHint(const QModelIndex &index, AbstractItemAdapter *adapter) const { - Q_UNUSED(index) Q_UNUSED(adapter) - Q_ASSERT(false); //TODO - return {}; + + if (d_ptr->m_Reload) + d_ptr->updateName(); + + const auto val = index.data(d_ptr->m_SizeRole); + Q_ASSERT(val.isValid()); + + if (val.type() == QMetaType::QRectF) { + const QRectF rect = val.toRectF(); + + return rect.size(); + } + + Q_ASSERT(val.toSizeF().isValid()); + + return val.toSizeF(); +} + +QPointF GeometryStrategies::Role::positionHint(const QModelIndex &index, AbstractItemAdapter *adapter) const +{ + Q_UNUSED(adapter) + if (d_ptr->m_Reload) + d_ptr->updateName(); + + const auto val = index.data(d_ptr->m_SizeRole); + Q_ASSERT(val.isValid()); + + if (val.type() == QMetaType::QRectF) { + const QRectF rect = val.toRectF(); + + return rect.topLeft(); + } + + return val.toPointF(); +} + +int GeometryStrategies::Role::sizeRole() const +{ + return d_ptr->m_SizeRole; } -int GeometryStrategies::Role::role() const +void GeometryStrategies::Role::setSizeRole(int role) { - return d_ptr->m_Role; + d_ptr->m_SizeRole = role; + d_ptr->updateName(); + emit roleChanged(); +} + +QString GeometryStrategies::Role::sizeRoleName() const +{ + return d_ptr->m_SizeRoleName; +} + +void GeometryStrategies::Role::setSizeRoleName(const QString& roleName) +{ + if (d_ptr->m_SizeRoleName == roleName) + return; + + d_ptr->m_SizeRoleName = roleName; + d_ptr->updateName(); + emit roleChanged(); } -void GeometryStrategies::Role::setRole(int role) +int GeometryStrategies::Role::positionRole() const { - d_ptr->m_Role = role; + return d_ptr->m_PositionRole; +} + +void GeometryStrategies::Role::setPositionRole(int role) +{ + setCapabilities( + Capabilities::HAS_AHEAD_OF_TIME | Capabilities::HAS_POSITION_HINTS + ); + + d_ptr->m_PositionRole = role; d_ptr->updateName(); emit roleChanged(); } -QString GeometryStrategies::Role::roleName() const +QString GeometryStrategies::Role::positionRoleName() const { - return d_ptr->m_RoleName; + return d_ptr->m_PositionRoleName; } -void GeometryStrategies::Role::setRoleName(const QString& roleName) +void GeometryStrategies::Role::setPositionRoleName(const QString& roleName) { - d_ptr->m_RoleName = roleName; + if (d_ptr->m_PositionRoleName == roleName) + return; + + d_ptr->m_PositionRoleName = roleName; d_ptr->updateName(); emit roleChanged(); } void RoleStrategiesPrivate::updateName() { - /*d_ptr->m_SizeHintRole = s.toLatin1(); + //TODO set the role name from the role index + const auto ma = q_ptr->viewport()->modelAdapter(); + + if (!ma->rawModel()) { + m_Reload = true; + return; + } + + const auto rn = ma->rawModel()->roleNames(); + const auto rnv = rn.values(); + + const QByteArray srn = m_SizeRoleName.toLatin1(); + const QByteArray prn = m_PositionRoleName.toLatin1(); + + if ((!srn.isEmpty()) && ma->rawModel() && rnv.contains(srn)) { + q_ptr->setSizeRole(rn.key(srn)); + } - if (!d_ptr->m_SizeHintRole.isEmpty() && d_ptr->m_pModelAdapter->rawModel()) - d_ptr->m_SizeHintRoleIndex = d_ptr->m_pModelAdapter->rawModel()->roleNames().key( - d_ptr->m_SizeHintRole - );*/ + if ((!prn.isEmpty()) && ma->rawModel() && rnv.contains(prn)) { + q_ptr->setPositionRole(rn.key(prn)); + } - Q_ASSERT(false); //TODO + m_Reload = false; } diff --git a/src/strategies/role.h b/src/strategies/role.h index 713b457..80287ad 100644 --- a/src/strategies/role.h +++ b/src/strategies/role.h @@ -1,59 +1,68 @@ /*************************************************************************** * Copyright (C) 2018 by Emmanuel Lepage Vallee * * Author : Emmanuel Lepage Vallee * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * **************************************************************************/ #ifndef KQUICKITEMVIEWS_ROLE_H #define KQUICKITEMVIEWS_ROLE_H #include class Viewport; class RoleStrategiesPrivate; namespace GeometryStrategies { /** * A GeometryAdapter to use size hints provided by the model as a role. */ class Q_DECL_EXPORT Role : public GeometryAdapter { Q_OBJECT public: explicit Role(Viewport *parent = nullptr); virtual ~Role(); - Q_PROPERTY(int role READ role WRITE setRole NOTIFY roleChanged) - Q_PROPERTY(QString roleName READ roleName WRITE setRoleName NOTIFY roleChanged) + Q_PROPERTY(int sizeRole READ sizeRole WRITE setSizeRole NOTIFY roleChanged) + Q_PROPERTY(int positionRole READ positionRole WRITE setPositionRole NOTIFY roleChanged) + Q_PROPERTY(QString sizeRoleName READ sizeRoleName WRITE setSizeRoleName NOTIFY roleChanged) + Q_PROPERTY(QString positionRoleName READ positionRoleName WRITE setPositionRoleName NOTIFY roleChanged) - int role() const; - void setRole(int role); + int sizeRole() const; + void setSizeRole(int role); - QString roleName() const; - void setRoleName(const QString& roleName); + int positionRole() const; + void setPositionRole(int role); + + QString positionRoleName() const; + void setPositionRoleName(const QString& roleName); + + QString sizeRoleName() const; + void setSizeRoleName(const QString& roleName); Q_INVOKABLE virtual QSizeF sizeHint(const QModelIndex &index, AbstractItemAdapter *adapter) const override; + Q_INVOKABLE virtual QPointF positionHint(const QModelIndex &index, AbstractItemAdapter *adapter) const override; Q_SIGNALS: void roleChanged(); private: RoleStrategiesPrivate *d_ptr; }; } #endif