feat: added layer tree icons

This commit is contained in:
Sara Gerretsen 2025-12-08 13:41:15 +01:00
parent cf0086d128
commit 670cfa1779
5 changed files with 120 additions and 31 deletions

View file

@ -1,21 +1,32 @@
#include "primitive_layer_list.h"
#include "core/object/object.h"
#include "core/variant/callable.h"
#include "scene/gui/tree.h"
#include "scene/resources/texture.h"
#include "terrain_editor/edit_history.h"
#include "terrain_editor/macros.h"
#include "terrain_editor/terrain_primitive.h"
#include <cstdint>
void PrimitiveLayerList::_bind_methods() {
BIND_HPROPERTY(Variant::OBJECT, terrain, PROPERTY_HINT_NODE_TYPE, "TerrainMeshGenerator");
BIND_HPROPERTY(Variant::DICTIONARY, icons, PROPERTY_HINT_DICTIONARY_TYPE, "StringName;Texture2D");
}
void PrimitiveLayerList::generate_subtree(size_t idx, Ref<TerrainPrimitive> prim, TreeItem *parent) {
TreeItem *base{ create_item(get_root()) };
base->set_text(0, vformat("%d", idx));
base->set_expand_right(0, false);
base->set_editable(0, true);
base->set_text(1, prim->get_name().is_empty() ? prim->get_class() : prim->get_name());
base->set_editable(1, true);
base->set_expand_right(1, true);
base->set_icon(ICON_COLUMN, this->icons.has(prim->get_class()) ? this->icons.get(prim->get_class()) : Ref<Texture2D>());
base->set_icon_max_width(ICON_COLUMN, 24);
base->set_selectable(ICON_COLUMN, true);
base->set_expand_right(ICON_COLUMN, false);
base->set_text(IDX_COLUMN, vformat("%d", idx));
base->set_expand_right(IDX_COLUMN, false);
base->set_editable(IDX_COLUMN, true);
base->set_text(NAME_COLUMN, prim->get_name().is_empty() ? prim->get_class() : prim->get_name());
base->set_editable(NAME_COLUMN, true);
base->set_expand_right(NAME_COLUMN, true);
this->subtrees.insert(prim, base);
}
@ -48,18 +59,27 @@ void PrimitiveLayerList::switch_index(size_t from, size_t to) {
void PrimitiveLayerList::layer_renamed(TreeItem *item) {
Array primitives = this->terrain->get_primitives();
Ref<TerrainPrimitive> primitive{ primitives.get(item->get_index()) };
primitive->set_name(item->get_text(1));
String old{ primitive->get_name() };
Callable set_name_c{ callable_mp(cast_to<Resource>(primitive.ptr()), &Resource::set_name) };
EditHistory::get_singleton()->push_action(set_name_c.bind(item->get_text(1)), set_name_c.bind(old));
}
void PrimitiveLayerList::item_edited() {
TreeItem *edited{ get_edited() };
if (!edited) {
return;
}
switch (get_edited_column()) {
default:
return;
case 0: // index
switch_index(edited->get_index(), edited->get_text(0).to_int());
case IDX_COLUMN: { // index
Callable switch_index_c{ callable_mp(this, &self_type::switch_index) };
int64_t from{ edited->get_index() },
to{ edited->get_text(0).to_int() };
EditHistory::get_singleton()->push_action(switch_index_c.bind(from, to), switch_index_c.bind(to, from));
return;
case 1: // name
}
case NAME_COLUMN: // name
layer_renamed(edited);
return;
}
@ -75,7 +95,9 @@ void PrimitiveLayerList::_notification(int what) {
case NOTIFICATION_READY:
connect("item_edited", callable_mp(this, &self_type::item_edited));
create_item();
set_columns(COLUMN_MAX);
set_hide_root(true);
set_select_mode(SelectMode::SELECT_ROW);
if (this->terrain) {
this->terrain->connect(TerrainMeshGenerator::sig_primitive_list_changed, callable_mp(this, &self_type::regenerate_tree));
regenerate_tree(this->terrain->get_primitives());
@ -84,6 +106,23 @@ void PrimitiveLayerList::_notification(int what) {
}
}
void PrimitiveLayerList::set_icons(Dictionary dict) {
this->icons.clear();
for (KeyValue<Variant, Variant> elem : dict) {
StringName key{ elem.key };
Ref<Texture2D> value{ elem.value };
this->icons.insert(key, value);
}
}
Dictionary PrimitiveLayerList::get_icons() const {
Dictionary dict;
for (KeyValue<StringName, Ref<Texture2D>> icon : this->icons) {
dict[icon.key] = icon.value;
}
return dict;
}
void PrimitiveLayerList::set_terrain(TerrainMeshGenerator *terrain) {
this->terrain = terrain;
}

View file

@ -8,6 +8,12 @@
class PrimitiveLayerList : public Tree {
GDCLASS(PrimitiveLayerList, Tree);
static void _bind_methods();
enum ColumnTags {
ICON_COLUMN = 0,
IDX_COLUMN = 1,
NAME_COLUMN = 2,
COLUMN_MAX
};
void generate_subtree(size_t idx, Ref<TerrainPrimitive> prim, TreeItem *parent);
void regenerate_tree(Array array);
void switch_index(size_t from, size_t to);
@ -18,10 +24,14 @@ protected:
void _notification(int what);
public:
void set_icons(Dictionary dict);
Dictionary get_icons() const;
void set_terrain(TerrainMeshGenerator *generator);
TerrainMeshGenerator *get_terrain() const;
private:
HashMap<StringName, Ref<Texture2D>> icons{};
TerrainMeshGenerator *terrain{};
HashMap<Ref<TerrainPrimitive>, TreeItem *> subtrees{};
};