Commit a50ef8d4 authored by Yuya Nishihara's avatar Yuya Nishihara
Browse files

calculate content rectangle by C++ TileListModel for future extension

parent 8cfb48f9
......@@ -13,12 +13,14 @@ Control {
property real handleWidth: 5
property real handleHeight: 5
property var _majorPositions: _makeDefaultPositionsArray(majorCount)
property var _minorPositions: _makeDefaultPositionsArray(Math.max(...minorCounts))
// TODO: property var _majorPositions: _makeDefaultPositionsArray(majorCount)
// TODO: property var _minorPositions: _makeDefaultPositionsArray(Math.max(...minorCounts))
property TileListModel model
property Component delegate
// TODO
/*
function _makeDefaultPositionsArray(count) {
let positions = [];
for (let i = 0; i < count; ++i) {
......@@ -40,6 +42,7 @@ Control {
onMinorCountsChanged: {
_minorPositions = _makeDefaultPositionsArray(Math.max(...minorCounts));
}
*/
contentItem: Item {
Item {
......@@ -61,36 +64,13 @@ Control {
required property int index
required property string name
required property int tileIndex
required property rect contentRect
readonly property int majorIndex: {
let count = 0;
for (let i = 0; i < root.minorCounts.length; ++i) {
count += root.minorCounts[i];
if (tileIndex < count)
return i;
}
return root.minorCounts.length;
}
readonly property int minorIndex: {
tileIndex - root.minorCounts.slice(0, majorIndex).reduce((a, b) => a + b, 0)
}
// TODO: handle out-of-range index
readonly property real _majorPosition: root._majorPositions[majorIndex]
readonly property real _minorPosition: root._minorPositions[minorIndex]
readonly property real _majorSize: {
(majorIndex + 1 < root.majorCount ? root._majorPositions[majorIndex + 1] : 1) - _majorPosition
}
readonly property real _minorSize: {
let n = minorIndex < root.minorCounts.length ? root.minorCounts[minorIndex] : 0;
return (minorIndex + 1 < n ? root._minorPositions[minorIndex + 1] : 1) - _minorPosition;
}
x: contentArea.width * (root.majorOrientation === Qt.Horizontal ? _majorPosition : _minorPosition)
y: contentArea.height * (root.majorOrientation === Qt.Horizontal ? _minorPosition : _majorPosition)
width: contentArea.width * (root.majorOrientation === Qt.Horizontal ? _majorSize : _minorSize)
height: contentArea.height * (root.majorOrientation === Qt.Horizontal ? _minorSize : _majorSize)
visible: tileIndex >= 0 && majorIndex < root.majorCount && minorIndex < root.minorCounts[majorIndex]
x: parent.width * contentRect.x
y: parent.height * contentRect.y
width: parent.width * contentRect.width
height: parent.height * contentRect.height
visible: tileIndex >= 0
Component.onCompleted: {
root.delegate.createObject(tileContentArea, {
......@@ -115,6 +95,8 @@ Control {
}
}
// TODO
/*
Item {
anchors.fill: contentArea
......@@ -322,5 +304,6 @@ Control {
}
}
}
*/
}
}
......@@ -7,6 +7,7 @@ namespace {
enum Role : int {
NameRole = Qt::UserRole + 1,
TileIndexRole,
ContentRectRole,
};
}
......@@ -20,6 +21,7 @@ QHash<int, QByteArray> TileListModel::roleNames() const
static const QHash<int, QByteArray> roles = {
{ NameRole, QByteArrayLiteral("name") },
{ TileIndexRole, QByteArrayLiteral("tileIndex") },
{ ContentRectRole, QByteArrayLiteral("contentRect") },
};
return roles;
}
......@@ -44,6 +46,8 @@ QVariant TileListModel::data(const QModelIndex &index, int role) const
return tile.name;
case TileIndexRole:
return tile.tileIndex;
case ContentRectRole:
return tile.contentRect;
}
return {};
......@@ -79,7 +83,9 @@ void TileListModel::resetLayout(Qt::Orientation majorOrientation, const QVector<
continue;
if (t.tileIndex >= newTileCount) {
t.tileIndex = -1;
t.contentRect = {};
} else {
t.contentRect = defaultContentRectForTileAt(t.tileIndex);
Q_ASSERT(!knownTileSet.at(static_cast<size_t>(t.tileIndex)));
knownTileSet.at(static_cast<size_t>(t.tileIndex)) = true;
++knownTileCount;
......@@ -95,13 +101,13 @@ void TileListModel::resetLayout(Qt::Orientation majorOrientation, const QVector<
for (int i = 0; i < newTileCount; ++i) {
if (knownTileSet.at(static_cast<size_t>(i)))
continue;
m_tiles.push_back({ {}, i });
m_tiles.push_back({ {}, i, defaultContentRectForTileAt(i) });
}
endInsertRows();
Q_ASSERT(m_tiles.size() == static_cast<size_t>(newCount));
}
emitAllDataChanged({ TileIndexRole });
emitAllDataChanged({ TileIndexRole, ContentRectRole });
emit layoutReset();
}
......@@ -117,7 +123,7 @@ void TileListModel::assignTileItem(const QString &name)
// no vacant tile
const int row = static_cast<int>(m_tiles.size());
beginInsertRows(QModelIndex(), row, row);
m_tiles.push_back({ name, -1 });
m_tiles.push_back({ name, -1, {} });
endInsertRows();
}
}
......@@ -130,15 +136,46 @@ void TileListModel::setTileIndex(int row, int tileIndex)
auto &tile = m_tiles.at(static_cast<size_t>(row));
if (tile.tileIndex == tileIndex)
return;
auto contentRect = defaultContentRectForTileAt(tileIndex);
const auto p = std::find_if(m_tiles.begin(), m_tiles.end(),
[tileIndex](const auto &t) { return t.tileIndex == tileIndex; });
if (p != m_tiles.end()) {
contentRect = p->contentRect;
p->tileIndex = -1;
p->contentRect = {};
const int r = static_cast<int>(p - m_tiles.begin());
emit dataChanged(index(r), index(r), { TileIndexRole });
emit dataChanged(index(r), index(r), { TileIndexRole, ContentRectRole });
}
tile.tileIndex = tileIndex;
emit dataChanged(index(row), index(row), { TileIndexRole });
tile.contentRect = contentRect;
emit dataChanged(index(row), index(row), { TileIndexRole, ContentRectRole });
}
QRectF TileListModel::defaultContentRectForTileAt(int tileIndex) const
{
if (tileIndex < 0)
return {};
int majorIndex = 0, minorIndex = tileIndex;
for (; majorIndex < m_minorCounts.size(); ++majorIndex) {
const int n = m_minorCounts.at(majorIndex);
if (minorIndex < n)
break;
minorIndex -= n;
}
if (majorIndex >= m_minorCounts.size()) {
qWarning() << "tile index out of range:" << tileIndex;
return {};
}
const qreal majorPos = static_cast<qreal>(majorIndex) / m_minorCounts.size();
const qreal minorPos = static_cast<qreal>(minorIndex) / m_minorCounts.at(majorIndex);
const qreal majorSize = 1.0 / m_minorCounts.size();
const qreal minorSize = 1.0 / m_minorCounts.at(majorIndex);
return (m_majorOrientation == Qt::Horizontal)
? QRectF { majorPos, minorPos, majorSize, minorSize }
: QRectF { minorPos, majorPos, minorSize, majorSize };
}
void TileListModel::emitAllDataChanged(const QVector<int> &roles)
......
......@@ -2,6 +2,7 @@
#define TILELISTMODEL_H
#include <QAbstractListModel>
#include <QRectF>
#include <QVector>
#include <vector>
......@@ -36,8 +37,10 @@ private:
{
QString name;
int tileIndex;
QRectF contentRect;
};
QRectF defaultContentRectForTileAt(int tileIndex) const;
void emitAllDataChanged(const QVector<int> &roles);
Qt::Orientation m_majorOrientation;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment