From 4ebf8002a52ecffa84bd4fbda2571c4df5333b2b Mon Sep 17 00:00:00 2001 From: maelstrom Date: Sat, 18 Jan 2025 18:50:56 +0100 Subject: [PATCH] feat: Added icons to instances in the explorer --- assets/icons/Silk-Icons.LICENSE | 22 ++++++++++++++++++++++ assets/icons/instance.png | Bin 0 -> 353 bytes assets/icons/part.png | Bin 0 -> 452 bytes assets/icons/script.png | Bin 0 -> 748 bytes assets/icons/workspace.png | Bin 0 -> 923 bytes editor/explorermodel.cpp | 30 +++++++++++++++++++++++++++--- editor/explorermodel.h | 1 + editor/mainwindow.cpp | 1 + src/objects/base/instance.cpp | 1 + src/objects/base/instance.h | 1 + src/objects/part.cpp | 1 + 11 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 assets/icons/Silk-Icons.LICENSE create mode 100644 assets/icons/instance.png create mode 100644 assets/icons/part.png create mode 100644 assets/icons/script.png create mode 100644 assets/icons/workspace.png diff --git a/assets/icons/Silk-Icons.LICENSE b/assets/icons/Silk-Icons.LICENSE new file mode 100644 index 0000000..2cf67dc --- /dev/null +++ b/assets/icons/Silk-Icons.LICENSE @@ -0,0 +1,22 @@ +Silk icon set 1.3 + +_________________________________________ +Mark James +http://www.famfamfam.com/lab/icons/silk/ +_________________________________________ + +This work is licensed under a +Creative Commons Attribution 2.5 License. +[ http://creativecommons.org/licenses/by/2.5/ ] + +This means you may use it for any purpose, +and make any changes you like. +All I ask is that you include a link back +to this page in your credits. + +Are you using this icon set? Send me an email +(including a link or picture if available) to +mjames@gmail.com + +Any other questions about this icon set please +contact mjames@gmail.com \ No newline at end of file diff --git a/assets/icons/instance.png b/assets/icons/instance.png new file mode 100644 index 0000000000000000000000000000000000000000..33af046098e0c48e5dce566fd6c134b066a496e2 GIT binary patch literal 353 zcmV-n0iOPeP)@H!pQI5+Ti_L0YJ|=5)wx zkF=1qGlSNkDr^3|$ws8mau%VAs!N}G7ur`j3{a)&lwiJCaRceu$939gbwXgD!G7W+ z`tnW&{YVf#zprcNBv=w4wLNbW#_u=%`)~XMSM_D9ZJ#Vp00000NkvXXu0mjfl(La4 literal 0 HcmV?d00001 diff --git a/assets/icons/part.png b/assets/icons/part.png new file mode 100644 index 0000000000000000000000000000000000000000..7851cf34c946e5667221e3478668503eb1cd733f GIT binary patch literal 452 zcmV;#0XzPQP)Pdwe5?6tW?r-ok|b$oDQj8FV%kZPq;(MWOV8?8;<)(iP}>hNMU> z7fbz%jjlr7h8uuoQ~J6}n}@Y@PdTk=)PxO{%7zmL?dchpZX*~n;I{!C>*(8cU;q(~ zAS%Po_@naEU!xidrBXD?;hN|x^%W|Ij)0y*r5vi|?W&Fub(NqJ@z0o=OrG{ z$cl-P=->hx6#}NAmbP5myY~I>{qOhtLMa7Y{qE64eE#g}(xpY)TeQ8l?;Upi4EuP3 zj9qNwYy4OP^j-JLi)W5q`snr30AQZ_=_2*h-J^Uqwd^<9gC_@m_YruehOwSPa9@O%#PST ztn>RnbQXoQ3&2p_*N2(YI zkrMO}==(rnxsJAW59QQs0L07JZk*~;x_q%%{cN7dr3j%I4jC^oS!R20 zp-X8Kpw211iFbazd*AM1?Vu^zTr_Qvx?Y!ieJR$aQy;v2#^ddUoYEFRo!j>1ci(tn z{K@;T0)Sj-bCEg}zP!0%dBFa`LT=k_fI7GB{l`yczPWYR>anra$&%HTk?G3F@#Ue> zFdEg-dzaUZYPNRv<+lA7pzgcw+uL{UoxOeM-g%tFNu0n5OqYg(!P3&eWMyo1vh4Ri e9{q`*0R9JiiaRV3rbYDt0000A9)b<7tX~vT z$e)FfZ+`X4_uKyq#wJHC;J3lH{lhQkUc~Wid;*pnjhM12xe-bPByd^xuQ9zgeM^Mm z*tc)|P}LtTnHXr@Gkmmbkg^O2bqyhO>LP|qjIwW2@Di+4EuKm~&tOO2!N3o{128Hl z9v%fgerM0C#)7P|PMvxr*!Gf?eGA8f{OT6fS`9l>LQCg)p=~c$Zr|AT_0+_?F*JJk zlapOT2Q(wWx-LMq(TxXxLn+U;!LV)MhNp~ommdh+fo8T*&g-yQbbG&ze&=>tC(Ar=&^1xlA;Jc(6 zcCi_xs8k}-S&#ONOHm%e@#nGC7F++8C~r29Or!_{(QGQEG)+O^J1BCPmgM4JAzC8I z`jS9bO>|}Jq_#$IRzp0d34>)&3L%7MN)eTv!0B!^nn}f4z2*vFE@jv3dn zG>H)u>FR7_d2JcsjvfZ$vkP~xik@T^(_N)nx=tqJV+tQjQ`owJ83bf`zX6Ear*=Mhzn5QUuXE|v zR33Qyi8G!0{H2r##d#6R6YmYbZz4NTssT;cXiGb6lxO+k@{ba@2D~*hKDY6N;Bkh> xhhCRLejsJkAIT{5sICHcfU`5>bKmUb{{y)0nR3PMMxX!y002ovPDHLkV1nl+t-}BS literal 0 HcmV?d00001 diff --git a/editor/explorermodel.cpp b/editor/explorermodel.cpp index d39742b..00ca0fc 100644 --- a/editor/explorermodel.cpp +++ b/editor/explorermodel.cpp @@ -1,14 +1,20 @@ #include "explorermodel.h" #include "objects/base/instance.h" #include "qcontainerfwd.h" +#include "qicon.h" +#include "qimage.h" +#include "qnamespace.h" #include "qobject.h" #include "qwidget.h" #include "common.h" #include #include +#include "objects/base/instance.h" // https://doc.qt.io/qt-6/qtwidgets-itemviews-simpletreemodel-example.html#testing-the-model +std::map instanceIconCache; + ExplorerModel::ExplorerModel(InstanceRef dataRoot, QWidget *parent) : QAbstractItemModel(parent) , rootItem(dataRoot) { @@ -96,11 +102,18 @@ int ExplorerModel::columnCount(const QModelIndex &parent) const { } QVariant ExplorerModel::data(const QModelIndex &index, int role) const { - if (!index.isValid() || role != Qt::DisplayRole) + if (!index.isValid()) return {}; - const Instance *item = static_cast(index.internalPointer()); - return QString::fromStdString(item->name); + Instance *item = static_cast(index.internalPointer()); + + switch (role) { + case Qt::DisplayRole: + return QString::fromStdString(item->name); + case Qt::DecorationRole: + return iconOf(item->GetClass()); + } + return {}; } QVariant ExplorerModel::headerData(int section, Qt::Orientation orientation, @@ -113,4 +126,15 @@ Qt::ItemFlags ExplorerModel::flags(const QModelIndex &index) const { return index.isValid() ? QAbstractItemModel::flags(index) : Qt::ItemFlags(Qt::NoItemFlags); +} + +QImage ExplorerModel::iconOf(InstanceType* type) const { + if (instanceIconCache.count(type->className)) return instanceIconCache[type->className]; + + InstanceType* currentClass = type; + while (currentClass->explorerIcon.empty()) currentClass = currentClass->super; + + QImage icon("assets/icons/" + QString::fromStdString(currentClass->explorerIcon)); + instanceIconCache[type->className] = icon; + return icon; } \ No newline at end of file diff --git a/editor/explorermodel.h b/editor/explorermodel.h index 80cc004..6317625 100644 --- a/editor/explorermodel.h +++ b/editor/explorermodel.h @@ -30,6 +30,7 @@ public: private: InstanceRef rootItem; QModelIndex toIndex(InstanceRef item); + QImage iconOf(InstanceType* type) const; }; #endif // EXPLORERMODEL_H diff --git a/editor/mainwindow.cpp b/editor/mainwindow.cpp index aff9e84..22f2cee 100644 --- a/editor/mainwindow.cpp +++ b/editor/mainwindow.cpp @@ -28,6 +28,7 @@ MainWindow::MainWindow(QWidget *parent) setMouseTracking(true); ui->explorerView->setModel(new ExplorerModel(std::dynamic_pointer_cast(workspace))); + ui->explorerView->setRootIsDecorated(false); simulationInit(); diff --git a/src/objects/base/instance.cpp b/src/objects/base/instance.cpp index e9c84f5..6cbd305 100644 --- a/src/objects/base/instance.cpp +++ b/src/objects/base/instance.cpp @@ -9,6 +9,7 @@ static InstanceType TYPE_ { .super = NULL, .className = "Instance", .constructor = NULL, // Instance is abstract and therefore not creatable + .explorerIcon = "instance", }; InstanceType* Instance::TYPE = &TYPE_; diff --git a/src/objects/base/instance.h b/src/objects/base/instance.h index 865ccb5..bb7baa6 100644 --- a/src/objects/base/instance.h +++ b/src/objects/base/instance.h @@ -9,6 +9,7 @@ struct InstanceType { InstanceType* super; // May be null std::string className; InstanceConstructor constructor; + std::string explorerIcon = ""; }; // Base class for all instances in the data model diff --git a/src/objects/part.cpp b/src/objects/part.cpp index 3459581..d91fbae 100644 --- a/src/objects/part.cpp +++ b/src/objects/part.cpp @@ -5,6 +5,7 @@ static InstanceType TYPE_ { .super = Instance::TYPE, .className = "Part", .constructor = &Part::CreateGeneric, + .explorerIcon = "part", }; InstanceType* Part::TYPE = &TYPE_;