diff options
author | Petr Mrázek <peterix@gmail.com> | 2019-08-20 02:58:27 +0200 |
---|---|---|
committer | Petr Mrázek <peterix@gmail.com> | 2019-08-20 02:58:27 +0200 |
commit | 1747f413b9d9a515d8ba6f583bba5985bad5636d (patch) | |
tree | 3b964f253d0f476fe89c1ff35e6f093cedf270b5 | |
parent | 6d975748c0dd9ac89815fe5043c0d89b8e684bc7 (diff) | |
download | MultiMC-1747f413b9d9a515d8ba6f583bba5985bad5636d.tar MultiMC-1747f413b9d9a515d8ba6f583bba5985bad5636d.tar.gz MultiMC-1747f413b9d9a515d8ba6f583bba5985bad5636d.tar.lz MultiMC-1747f413b9d9a515d8ba6f583bba5985bad5636d.tar.xz MultiMC-1747f413b9d9a515d8ba6f583bba5985bad5636d.zip |
GH-851 save, load and use group expansion status
-rw-r--r-- | api/logic/InstanceList.cpp | 66 | ||||
-rw-r--r-- | api/logic/InstanceList.h | 9 | ||||
-rw-r--r-- | application/MainWindow.cpp | 4 | ||||
-rw-r--r-- | application/groupview/GroupView.cpp | 10 | ||||
-rw-r--r-- | application/groupview/GroupView.h | 12 |
5 files changed, 69 insertions, 32 deletions
diff --git a/api/logic/InstanceList.cpp b/api/logic/InstanceList.cpp index 58e2ee0c..a6dd734b 100644 --- a/api/logic/InstanceList.cpp +++ b/api/logic/InstanceList.cpp @@ -160,8 +160,8 @@ GroupId InstanceList::getInstanceGroup(const InstanceId& id) const { return GroupId(); } - auto iter = m_groupMap.find(inst->id()); - if(iter != m_groupMap.end()) + auto iter = m_instanceGroupIndex.find(inst->id()); + if(iter != m_instanceGroupIndex.end()) { return *iter; } @@ -178,8 +178,8 @@ void InstanceList::setInstanceGroup(const InstanceId& id, const GroupId& name) } bool changed = false; - auto iter = m_groupMap.find(inst->id()); - if(iter != m_groupMap.end()) + auto iter = m_instanceGroupIndex.find(inst->id()); + if(iter != m_instanceGroupIndex.end()) { if(*iter != name) { @@ -190,12 +190,12 @@ void InstanceList::setInstanceGroup(const InstanceId& id, const GroupId& name) else { changed = true; - m_groupMap[id] = name; + m_instanceGroupIndex[id] = name; } if(changed) { - m_groups.insert(name); + m_groupNameCache.insert(name); auto idx = getInstIndex(inst.get()); emit dataChanged(index(idx), index(idx), {GroupRole}); saveGroupList(); @@ -204,7 +204,7 @@ void InstanceList::setInstanceGroup(const InstanceId& id, const GroupId& name) QStringList InstanceList::getGroups() { - return m_groups.toList(); + return m_groupNameCache.toList(); } void InstanceList::deleteGroup(const QString& name) @@ -217,7 +217,7 @@ void InstanceList::deleteGroup(const QString& name) auto instGroupName = getInstanceGroup(instID); if(instGroupName == name) { - m_groupMap.remove(instID); + m_instanceGroupIndex.remove(instID); qDebug() << "Remove" << instID << "from group" << name; removed = true; auto idx = getInstIndex(instance.get()); @@ -233,6 +233,11 @@ void InstanceList::deleteGroup(const QString& name) } } +bool InstanceList::isGroupCollapsed(const QString& group) +{ + return m_collapsedGroups.contains(group); +} + void InstanceList::deleteInstance(const InstanceId& id) { auto inst = getInstanceById(id); @@ -242,7 +247,7 @@ void InstanceList::deleteInstance(const InstanceId& id) return; } - if(m_groupMap.remove(id)) + if(m_instanceGroupIndex.remove(id)) { saveGroupList(); } @@ -515,7 +520,7 @@ void InstanceList::saveGroupList() WatchLock foo(m_watcher, m_instDir); QString groupFileName = m_instDir + "/instgroups.json"; QMap<QString, QSet<QString>> reverseGroupMap; - for (auto iter = m_groupMap.begin(); iter != m_groupMap.end(); iter++) + for (auto iter = m_instanceGroupIndex.begin(); iter != m_instanceGroupIndex.end(); iter++) { QString id = iter.key(); QString group = iter.value(); @@ -548,7 +553,7 @@ void InstanceList::saveGroupList() auto name = iter.key(); QJsonObject groupObj; QJsonArray instanceArr; - groupObj.insert("hidden", QJsonValue(QString("false"))); + groupObj.insert("hidden", QJsonValue(m_collapsedGroups.contains(name))); for (auto item : list) { instanceArr.append(QJsonValue(item)); @@ -572,7 +577,6 @@ void InstanceList::saveGroupList() void InstanceList::loadGroupList() { qDebug() << "Will load group list now."; - QSet<QString> groupSet; QString groupFileName = m_instDir + "/instgroups.json"; @@ -623,7 +627,8 @@ void InstanceList::loadGroupList() return; } - m_groupMap.clear(); + QSet<QString> groupSet; + m_instanceGroupIndex.clear(); // Iterate through all the groups. QJsonObject groupMapping = rootObj.value("groups").toObject(); @@ -634,37 +639,35 @@ void InstanceList::loadGroupList() // If not an object, complain and skip to the next one. if (!iter.value().isObject()) { - qWarning() << QString("Group '%1' in the group list should " - "be an object.") - .arg(groupName) - .toUtf8(); + qWarning() << QString("Group '%1' in the group list should be an object.").arg(groupName).toUtf8(); continue; } QJsonObject groupObj = iter.value().toObject(); if (!groupObj.value("instances").isArray()) { - qWarning() << QString("Group '%1' in the group list is invalid. " - "It should contain an array " - "called 'instances'.") - .arg(groupName) - .toUtf8(); + qWarning() << QString("Group '%1' in the group list is invalid. It should contain an array called 'instances'.").arg(groupName).toUtf8(); continue; } // keep a list/set of groups for choosing groupSet.insert(groupName); + auto hidden = groupObj.value("hidden").toBool(false); + if(hidden) { + m_collapsedGroups.insert(groupName); + } + // Iterate through the list of instances in the group. QJsonArray instancesArray = groupObj.value("instances").toArray(); for (QJsonArray::iterator iter2 = instancesArray.begin(); iter2 != instancesArray.end(); iter2++) { - m_groupMap[(*iter2).toString()] = groupName; + m_instanceGroupIndex[(*iter2).toString()] = groupName; } } m_groupsLoaded = true; - m_groups.unite(groupSet); + m_groupNameCache.unite(groupSet); qDebug() << "Group list loaded."; } @@ -689,6 +692,17 @@ void InstanceList::on_InstFolderChanged(const Setting &setting, QVariant value) } } +void InstanceList::on_GroupStateChanged(const QString& group, bool collapsed) +{ + qDebug() << "Group" << group << (collapsed ? "collapsed" : "expanded"); + if(collapsed) { + m_collapsedGroups.insert(group); + } else { + m_collapsedGroups.remove(group); + } + saveGroupList(); +} + class InstanceStaging : public Task { Q_OBJECT @@ -819,9 +833,9 @@ bool InstanceList::commitStagedInstance(const QString& path, const QString& inst qWarning() << "Failed to move" << path << "to" << destination; return false; } - m_groupMap[instID] = groupName; + m_instanceGroupIndex[instID] = groupName; instanceSet.insert(instID); - m_groups.insert(groupName); + m_groupNameCache.insert(groupName); emit instancesChanged(); emit instanceSelectRequest(instID); } diff --git a/api/logic/InstanceList.h b/api/logic/InstanceList.h index e0abd890..005a24cd 100644 --- a/api/logic/InstanceList.h +++ b/api/logic/InstanceList.h @@ -99,6 +99,8 @@ public: InstancePtr getInstanceById(QString id) const; QModelIndex getInstanceIndexById(const QString &id) const; QStringList getGroups(); + bool isGroupCollapsed(const QString &groupName); + GroupId getInstanceGroup(const InstanceId & id) const; void setInstanceGroup(const InstanceId & id, const GroupId& name); @@ -134,6 +136,7 @@ signals: public slots: void on_InstFolderChanged(const Setting &setting, QVariant value); + void on_GroupStateChanged(const QString &group, bool collapsed); private slots: void propertiesChanged(BaseInstance *inst); @@ -154,12 +157,14 @@ private: int m_watchLevel = 0; bool m_dirty = false; QList<InstancePtr> m_instances; - QSet<QString> m_groups; + QSet<QString> m_groupNameCache; SettingsObjectPtr m_globalSettings; QString m_instDir; QFileSystemWatcher * m_watcher; - QMap<InstanceId, GroupId> m_groupMap; + // FIXME: this is so inefficient that looking at it is almost painful. + QSet<QString> m_collapsedGroups; + QMap<InstanceId, GroupId> m_instanceGroupIndex; QSet<InstanceId> instanceSet; bool m_groupsLoaded = false; bool m_instancesProbed = false; diff --git a/application/MainWindow.cpp b/application/MainWindow.cpp index 1db09c6c..8457cd41 100644 --- a/application/MainWindow.cpp +++ b/application/MainWindow.cpp @@ -682,6 +682,10 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow connect(proxymodel, &InstanceProxyModel::dataChanged, this, &MainWindow::instanceDataChanged); view->setModel(proxymodel); + view->setSourceOfGroupCollapseStatus([](const QString & groupName)->bool { + return MMC->instances()->isGroupCollapsed(groupName); + }); + connect(view, &GroupView::groupStateChanged, MMC->instances().get(), &InstanceList::on_GroupStateChanged); ui->horizontalLayout->addWidget(view); } // The cat background diff --git a/application/groupview/GroupView.cpp b/application/groupview/GroupView.cpp index bc7ef6c0..ff0daee4 100644 --- a/application/groupview/GroupView.cpp +++ b/application/groupview/GroupView.cpp @@ -175,6 +175,9 @@ void GroupView::updateGeometries() else { auto cat = new VisualGroup(groupName, this); + if(fVisibility) { + cat->collapsed = fVisibility(groupName); + } cats.insert(groupName, cat); cat->update(); } @@ -384,6 +387,8 @@ void GroupView::mouseReleaseEvent(QMouseEvent *event) if (state() == ExpandingState) { m_pressedCategory->collapsed = false; + emit groupStateChanged(m_pressedCategory->text, false); + updateGeometries(); viewport()->update(); event->accept(); @@ -392,6 +397,8 @@ void GroupView::mouseReleaseEvent(QMouseEvent *event) else if (state() == CollapsingState) { m_pressedCategory->collapsed = true; + emit groupStateChanged(m_pressedCategory->text, true); + updateGeometries(); viewport()->update(); event->accept(); @@ -607,8 +614,7 @@ void GroupView::dropEvent(QDropEvent *event) const QString categoryText = category->text; if (model()->dropMimeData(event->mimeData(), Qt::MoveAction, row, 0, QModelIndex())) { - model()->setData(model()->index(row, 0), categoryText, - GroupViewRoles::GroupRole); + model()->setData(model()->index(row, 0), categoryText, GroupViewRoles::GroupRole); event->setDropAction(Qt::MoveAction); event->accept(); } diff --git a/application/groupview/GroupView.h b/application/groupview/GroupView.h index db29a0d4..13bfd234 100644 --- a/application/groupview/GroupView.h +++ b/application/groupview/GroupView.h @@ -20,6 +20,7 @@ #include <QScrollBar> #include <QCache> #include "VisualGroup.h" +#include <functional> struct GroupViewRoles { @@ -41,6 +42,11 @@ public: void setModel(QAbstractItemModel *model) override; + using visibilityFunction = std::function<bool(const QString &)>; + void setSourceOfGroupCollapseStatus(visibilityFunction f) { + fVisibility = f; + } + /// return geometry rectangle occupied by the specified model item QRect geometryRect(const QModelIndex &index) const; /// return visual rectangle occupied by the specified model item @@ -48,8 +54,7 @@ public: /// get the model index at the specified visual point virtual QModelIndex indexAt(const QPoint &point) const override; QString groupNameAt(const QPoint &point); - void setSelection(const QRect &rect, - const QItemSelectionModel::SelectionFlags commands) override; + void setSelection(const QRect &rect, const QItemSelectionModel::SelectionFlags commands) override; virtual int horizontalOffset() const override; virtual int verticalOffset() const override; @@ -80,6 +85,7 @@ protected slots: signals: void droppedURLs(QList<QUrl> urls); + void groupStateChanged(QString group, bool collapsed); protected: virtual bool isIndexHidden(const QModelIndex &index) const override; @@ -103,6 +109,8 @@ private: friend struct VisualGroup; QList<VisualGroup *> m_groups; + visibilityFunction fVisibility; + // geometry int m_leftMargin = 5; int m_rightMargin = 5; |