diff --git a/src/editor/C4ConsoleQtDefinitionListViewer.cpp b/src/editor/C4ConsoleQtDefinitionListViewer.cpp new file mode 100644 index 000000000..105b33a2d --- /dev/null +++ b/src/editor/C4ConsoleQtDefinitionListViewer.cpp @@ -0,0 +1,200 @@ +/* +* OpenClonk, http://www.openclonk.org +* +* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ +* Copyright (c) 2013, The OpenClonk Team and contributors +* +* Distributed under the terms of the ISC license; see accompanying file +* "COPYING" for details. +* +* "Clonk" is a registered trademark of Matthes Bender, used with permission. +* See accompanying file "TRADEMARK" for details. +* +* To redistribute this file separately, substitute the full license texts +* for the above references. +*/ + +/* Proplist table view */ + +#include +#include +#include +#include +#include +#include +#include + + +/* Defintion tree */ + + +/* Defintion view model */ + +C4ConsoleQtDefinitionListModel::C4ConsoleQtDefinitionListModel() + : last_row_count(0) +{ + // initial model data + ReInit(); +} + +C4ConsoleQtDefinitionListModel::~C4ConsoleQtDefinitionListModel() +{ +} + +void C4ConsoleQtDefinitionListModel::ReInit() +{ + // Re-fill definition model with all loaded definitions matching condition + // (TODO: Add conditional lists) + root.reset(new DefListNode()); + int32_t index = 0; C4Def *def; + while (def = ::Definitions.GetDef(index++)) + { + // Build path leading to this definition + DefListNode *node_parent = root.get(); + StdCopyStrBuf fn(def->Filename), fn2; + fn.ReplaceChar(AltDirectorySeparator, DirectorySeparator); + for (;;) + { + bool is_parent_folder = fn.SplitAtChar(DirectorySeparator, &fn2); + if (!is_parent_folder || WildcardMatch(C4CFN_DefFiles, fn.getData())) // ignore non-.ocd-folders (except for final definition) + { + // Find if path is already there + RemoveExtension(&fn); + DefListNode *node_child = NULL; + for (auto &test_node_child : node_parent->items) + if (test_node_child->filename == fn) + { + node_child = &*test_node_child; + break; + } + // If not, create it + if (!node_child) + { + node_parent->items.emplace_back((node_child = new DefListNode())); + node_child->idx = node_parent->items.size() - 1; + node_child->parent = node_parent; + node_child->name.Copy(fn); + node_child->filename.Copy(fn); + } + // And fill in node if this is not a parent folder + if (!is_parent_folder) + { + node_child->def = def; + const char *def_name = def->GetName(); + if (def_name && *def_name) node_child->name.Copy(def_name); + break; + } + else + { + // Parent folder: Next path segment + node_parent = node_child; + } + } + fn = fn2; + } + } + // Descend into singleton root classes. I.e. if all elements are children of Objects/Items, move the root in there. + DefListNode *new_root = root.get(); + while (new_root->items.size() == 1 && !new_root->items[0]->def) + { + std::unique_ptr tmp(new_root->items[0].release()); + root.reset(tmp.release()); + } + // Model reset to invalidate all indexes + beginResetModel(); + endResetModel(); +} + +void C4ConsoleQtDefinitionListModel::OnItemRemoved(C4Def *p) +{ + for (auto idx : this->persistentIndexList()) + if (idx.internalPointer() == p) + this->changePersistentIndex(idx, QModelIndex()); + ReInit(); +} + +class C4Def *C4ConsoleQtDefinitionListModel::GetDefByModelIndex(const QModelIndex &idx) +{ + DefListNode *node = static_cast(idx.internalPointer()); + if (node) return node->def; else return NULL; +} + +int C4ConsoleQtDefinitionListModel::rowCount(const QModelIndex & parent) const +{ + int result = 0; + DefListNode *parent_node = parent.isValid() ? static_cast(parent.internalPointer()) : NULL; + if (!parent_node) parent_node = root.get(); + if (parent_node) result = parent_node->items.size(); + return result; +} + +int C4ConsoleQtDefinitionListModel::columnCount(const QModelIndex & parent) const +{ + return 1; // Name only +} + +QVariant C4ConsoleQtDefinitionListModel::data(const QModelIndex & index, int role) const +{ + // Object list lookup is done in index(). Here we just use the pointer. + DefListNode *node = static_cast(index.internalPointer()); + if (!node) return QVariant(); + if (role == Qt::DisplayRole) + { + return QString(node->name.getData()); + } + // Nothing to show + return QVariant(); +} + +QModelIndex C4ConsoleQtDefinitionListModel::index(int row, int column, const QModelIndex &parent) const +{ + // Current index out of range? + if (row < 0 || column != 0) return QModelIndex(); + DefListNode *parent_node = parent.isValid() ? static_cast(parent.internalPointer()) : NULL; + if (!parent_node) parent_node = root.get(); + if (parent_node->items.size() <= row) return QModelIndex(); + // Index into tree + DefListNode *node = parent_node->items[row].get(); + return createIndex(row, column, node); +} + +QModelIndex C4ConsoleQtDefinitionListModel::parent(const QModelIndex &index) const +{ + // Find parent through tree + DefListNode *node = static_cast(index.internalPointer()); + if (!node) return QModelIndex(); + DefListNode *parent_node = node->parent; + if (!parent_node || parent_node == root.get()) return QModelIndex(); + return createIndex(parent_node->idx, index.column(), parent_node); +} + + +QModelIndex C4ConsoleQtDefinitionListModel::GetModelIndexByItem(C4Def *def) const +{ + // Just search tree + DefListNode *node = root.get(); + while (node) + { + if (node->def == def) break; + if (!node->items.empty()) + node = node->items[0].get(); + else + { + int32_t idx = node->idx + 1; + while ((node = node->parent)) + { + if (node->items.size() > idx) + { + node = node->items[idx].get(); + break; + } + idx = node->idx + 1; + } + } + } + // Def found in tree? + if (node) + return createIndex(node->idx, 0, node); + else + return QModelIndex(); +} diff --git a/src/editor/C4ConsoleQtDefinitionListViewer.h b/src/editor/C4ConsoleQtDefinitionListViewer.h new file mode 100644 index 000000000..cdcfb8345 --- /dev/null +++ b/src/editor/C4ConsoleQtDefinitionListViewer.h @@ -0,0 +1,76 @@ +/* +* OpenClonk, http://www.openclonk.org +* +* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ +* Copyright (c) 2013, The OpenClonk Team and contributors +* +* Distributed under the terms of the ISC license; see accompanying file +* "COPYING" for details. +* +* "Clonk" is a registered trademark of Matthes Bender, used with permission. +* See accompanying file "TRADEMARK" for details. +* +* To redistribute this file separately, substitute the full license texts +* for the above references. +*/ + +/* List of loaded definitions */ + +#ifndef INC_C4ConsoleQtDefinitionListViewer +#define INC_C4ConsoleQtDefinitionListViewer +#ifdef WITH_QT_EDITOR + +#include // needed for automoc +#include // for glew.h +#include +#include + +// Prop list view implemented as a model view +class C4ConsoleQtDefinitionListModel : public QAbstractItemModel +{ + Q_OBJECT + + class QItemSelectionModel *selection_model; + QTreeView *view; + mutable int32_t last_row_count; + + // Tree structure of definition list + struct DefListNode + { + std::vector > items; + C4Def *def; + StdCopyStrBuf name, filename; + int32_t idx; + DefListNode *parent; + + DefListNode() : def(NULL), idx(0), parent(NULL) {} + }; + std::unique_ptr root; + +public: + C4ConsoleQtDefinitionListModel(); + ~C4ConsoleQtDefinitionListModel(); + + // Refresh definition list (on initialization or e.g. after ReloadDef) + void ReInit(); + void OnItemRemoved(class C4Def *def); + + // Callback from EditCursor when selection was changed e.g. from property window + void SetSelection(C4Def *new_selection); + + class C4Def *GetDefByModelIndex(const QModelIndex &idx); + QModelIndex GetModelIndexByItem(class C4Def *def) const; + +protected: + int rowCount(const QModelIndex & parent = QModelIndex()) const override; + int columnCount(const QModelIndex & parent = QModelIndex()) const override; + QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override; + QModelIndex index(int row, int column, const QModelIndex &parent) const override; + QModelIndex parent(const QModelIndex &index) const override; + + // signal callback when user changed selection in dialogue + void OnSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected); +}; + +#endif // WITH_QT_EDITOR +#endif // INC_C4ConsoleQtObjectListViewer diff --git a/src/res/CreateObj_Trans.png b/src/res/CreateObj_Trans.png new file mode 100644 index 000000000..6b677736d Binary files /dev/null and b/src/res/CreateObj_Trans.png differ