Merge pull request #51039 from nekomatata/layer-grid-32

Refactor layer property editor grid
This commit is contained in:
Rémi Verschelde 2021-08-02 21:14:16 +02:00 committed by GitHub
commit c17a541650
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 379 additions and 74 deletions

View File

@ -786,9 +786,45 @@
<member name="layer_names/2d_navigation/layer_2" type="String" setter="" getter="" default="&quot;&quot;"> <member name="layer_names/2d_navigation/layer_2" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 2D navigation layer 2. If left empty, the layer will display as "Layer 2". Optional name for the 2D navigation layer 2. If left empty, the layer will display as "Layer 2".
</member> </member>
<member name="layer_names/2d_navigation/layer_20" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 2D navigation layer 20. If left empty, the layer will display as "Layer 20".
</member>
<member name="layer_names/2d_navigation/layer_21" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 2D navigation layer 21. If left empty, the layer will display as "Layer 21".
</member>
<member name="layer_names/2d_navigation/layer_22" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 2D navigation layer 22. If left empty, the layer will display as "Layer 22".
</member>
<member name="layer_names/2d_navigation/layer_23" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 2D navigation layer 23. If left empty, the layer will display as "Layer 23".
</member>
<member name="layer_names/2d_navigation/layer_24" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 2D navigation layer 24. If left empty, the layer will display as "Layer 24".
</member>
<member name="layer_names/2d_navigation/layer_25" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 2D navigation layer 25. If left empty, the layer will display as "Layer 25".
</member>
<member name="layer_names/2d_navigation/layer_26" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 2D navigation layer 26. If left empty, the layer will display as "Layer 26".
</member>
<member name="layer_names/2d_navigation/layer_27" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 2D navigation layer 27. If left empty, the layer will display as "Layer 27".
</member>
<member name="layer_names/2d_navigation/layer_28" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 2D navigation layer 28. If left empty, the layer will display as "Layer 28".
</member>
<member name="layer_names/2d_navigation/layer_29" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 2D navigation layer 29. If left empty, the layer will display as "Layer 29".
</member>
<member name="layer_names/2d_navigation/layer_3" type="String" setter="" getter="" default="&quot;&quot;"> <member name="layer_names/2d_navigation/layer_3" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 2D navigation layer 3. If left empty, the layer will display as "Layer 3". Optional name for the 2D navigation layer 3. If left empty, the layer will display as "Layer 3".
</member> </member>
<member name="layer_names/2d_navigation/layer_30" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 2D navigation layer 30. If left empty, the layer will display as "Layer 30".
</member>
<member name="layer_names/2d_navigation/layer_31" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 2D navigation layer 31. If left empty, the layer will display as "Layer 31".
</member>
<member name="layer_names/2d_navigation/layer_4" type="String" setter="" getter="" default="&quot;&quot;"> <member name="layer_names/2d_navigation/layer_4" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 2D navigation layer 4. If left empty, the layer will display as "Layer 4". Optional name for the 2D navigation layer 4. If left empty, the layer will display as "Layer 4".
</member> </member>
@ -846,9 +882,45 @@
<member name="layer_names/2d_physics/layer_2" type="String" setter="" getter="" default="&quot;&quot;"> <member name="layer_names/2d_physics/layer_2" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 2D physics layer 2. If left empty, the layer will display as "Layer 2". Optional name for the 2D physics layer 2. If left empty, the layer will display as "Layer 2".
</member> </member>
<member name="layer_names/2d_physics/layer_20" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 2D physics layer 20. If left empty, the layer will display as "Layer 20".
</member>
<member name="layer_names/2d_physics/layer_21" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 2D physics layer 21. If left empty, the layer will display as "Layer 21".
</member>
<member name="layer_names/2d_physics/layer_22" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 2D physics layer 22. If left empty, the layer will display as "Layer 22".
</member>
<member name="layer_names/2d_physics/layer_23" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 2D physics layer 23. If left empty, the layer will display as "Layer 23".
</member>
<member name="layer_names/2d_physics/layer_24" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 2D physics layer 24. If left empty, the layer will display as "Layer 24".
</member>
<member name="layer_names/2d_physics/layer_25" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 2D physics layer 25. If left empty, the layer will display as "Layer 25".
</member>
<member name="layer_names/2d_physics/layer_26" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 2D physics layer 26. If left empty, the layer will display as "Layer 26".
</member>
<member name="layer_names/2d_physics/layer_27" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 2D physics layer 27. If left empty, the layer will display as "Layer 27".
</member>
<member name="layer_names/2d_physics/layer_28" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 2D physics layer 28. If left empty, the layer will display as "Layer 28".
</member>
<member name="layer_names/2d_physics/layer_29" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 2D physics layer 29. If left empty, the layer will display as "Layer 29".
</member>
<member name="layer_names/2d_physics/layer_3" type="String" setter="" getter="" default="&quot;&quot;"> <member name="layer_names/2d_physics/layer_3" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 2D physics layer 3. If left empty, the layer will display as "Layer 3". Optional name for the 2D physics layer 3. If left empty, the layer will display as "Layer 3".
</member> </member>
<member name="layer_names/2d_physics/layer_30" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 2D physics layer 30. If left empty, the layer will display as "Layer 30".
</member>
<member name="layer_names/2d_physics/layer_31" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 2D physics layer 31. If left empty, the layer will display as "Layer 31".
</member>
<member name="layer_names/2d_physics/layer_4" type="String" setter="" getter="" default="&quot;&quot;"> <member name="layer_names/2d_physics/layer_4" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 2D physics layer 4. If left empty, the layer will display as "Layer 4". Optional name for the 2D physics layer 4. If left empty, the layer will display as "Layer 4".
</member> </member>
@ -966,9 +1038,45 @@
<member name="layer_names/3d_navigation/layer_2" type="String" setter="" getter="" default="&quot;&quot;"> <member name="layer_names/3d_navigation/layer_2" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 3D navigation layer 2. If left empty, the layer will display as "Layer 2". Optional name for the 3D navigation layer 2. If left empty, the layer will display as "Layer 2".
</member> </member>
<member name="layer_names/3d_navigation/layer_20" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 3D navigation layer 20. If left empty, the layer will display as "Layer 20".
</member>
<member name="layer_names/3d_navigation/layer_21" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 3D navigation layer 21. If left empty, the layer will display as "Layer 21".
</member>
<member name="layer_names/3d_navigation/layer_22" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 3D navigation layer 22. If left empty, the layer will display as "Layer 22".
</member>
<member name="layer_names/3d_navigation/layer_23" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 3D navigation layer 23. If left empty, the layer will display as "Layer 23".
</member>
<member name="layer_names/3d_navigation/layer_24" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 3D navigation layer 24. If left empty, the layer will display as "Layer 24".
</member>
<member name="layer_names/3d_navigation/layer_25" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 3D navigation layer 25. If left empty, the layer will display as "Layer 25".
</member>
<member name="layer_names/3d_navigation/layer_26" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 3D navigation layer 26. If left empty, the layer will display as "Layer 26".
</member>
<member name="layer_names/3d_navigation/layer_27" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 3D navigation layer 27. If left empty, the layer will display as "Layer 27".
</member>
<member name="layer_names/3d_navigation/layer_28" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 3D navigation layer 28. If left empty, the layer will display as "Layer 28".
</member>
<member name="layer_names/3d_navigation/layer_29" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 3D navigation layer 29. If left empty, the layer will display as "Layer 29".
</member>
<member name="layer_names/3d_navigation/layer_3" type="String" setter="" getter="" default="&quot;&quot;"> <member name="layer_names/3d_navigation/layer_3" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 3D navigation layer 3. If left empty, the layer will display as "Layer 3". Optional name for the 3D navigation layer 3. If left empty, the layer will display as "Layer 3".
</member> </member>
<member name="layer_names/3d_navigation/layer_30" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 3D navigation layer 30. If left empty, the layer will display as "Layer 30".
</member>
<member name="layer_names/3d_navigation/layer_31" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 3D navigation layer 31. If left empty, the layer will display as "Layer 31".
</member>
<member name="layer_names/3d_navigation/layer_4" type="String" setter="" getter="" default="&quot;&quot;"> <member name="layer_names/3d_navigation/layer_4" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 3D navigation layer 4. If left empty, the layer will display as "Layer 4". Optional name for the 3D navigation layer 4. If left empty, the layer will display as "Layer 4".
</member> </member>
@ -1026,9 +1134,45 @@
<member name="layer_names/3d_physics/layer_2" type="String" setter="" getter="" default="&quot;&quot;"> <member name="layer_names/3d_physics/layer_2" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 3D physics layer 2. If left empty, the layer will display as "Layer 2". Optional name for the 3D physics layer 2. If left empty, the layer will display as "Layer 2".
</member> </member>
<member name="layer_names/3d_physics/layer_20" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 3D physics layer 20. If left empty, the layer will display as "Layer 20".
</member>
<member name="layer_names/3d_physics/layer_21" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 3D physics layer 21. If left empty, the layer will display as "Layer 21".
</member>
<member name="layer_names/3d_physics/layer_22" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 3D physics layer 22. If left empty, the layer will display as "Layer 22".
</member>
<member name="layer_names/3d_physics/layer_23" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 3D physics layer 23. If left empty, the layer will display as "Layer 23".
</member>
<member name="layer_names/3d_physics/layer_24" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 3D physics layer 24. If left empty, the layer will display as "Layer 24".
</member>
<member name="layer_names/3d_physics/layer_25" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 3D physics layer 25. If left empty, the layer will display as "Layer 25".
</member>
<member name="layer_names/3d_physics/layer_26" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 3D physics layer 26. If left empty, the layer will display as "Layer 26".
</member>
<member name="layer_names/3d_physics/layer_27" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 3D physics layer 27. If left empty, the layer will display as "Layer 27".
</member>
<member name="layer_names/3d_physics/layer_28" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 3D physics layer 28. If left empty, the layer will display as "Layer 28".
</member>
<member name="layer_names/3d_physics/layer_29" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 3D physics layer 29. If left empty, the layer will display as "Layer 29".
</member>
<member name="layer_names/3d_physics/layer_3" type="String" setter="" getter="" default="&quot;&quot;"> <member name="layer_names/3d_physics/layer_3" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 3D physics layer 3. If left empty, the layer will display as "Layer 3". Optional name for the 3D physics layer 3. If left empty, the layer will display as "Layer 3".
</member> </member>
<member name="layer_names/3d_physics/layer_30" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 3D physics layer 30. If left empty, the layer will display as "Layer 30".
</member>
<member name="layer_names/3d_physics/layer_31" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 3D physics layer 31. If left empty, the layer will display as "Layer 31".
</member>
<member name="layer_names/3d_physics/layer_4" type="String" setter="" getter="" default="&quot;&quot;"> <member name="layer_names/3d_physics/layer_4" type="String" setter="" getter="" default="&quot;&quot;">
Optional name for the 3D physics layer 4. If left empty, the layer will display as "Layer 4". Optional name for the 3D physics layer 4. If left empty, the layer will display as "Layer 4".
</member> </member>

View File

@ -691,17 +691,39 @@ EditorPropertyFlags::EditorPropertyFlags() {
class EditorPropertyLayersGrid : public Control { class EditorPropertyLayersGrid : public Control {
GDCLASS(EditorPropertyLayersGrid, Control); GDCLASS(EditorPropertyLayersGrid, Control);
public: private:
uint32_t value;
Vector<Rect2> flag_rects; Vector<Rect2> flag_rects;
Vector<String> names; Rect2 expand_rect;
Vector<String> tooltips; bool expand_hovered = false;
int hovered_index; bool expanded = false;
int expansion_rows = 0;
int hovered_index = -1;
virtual Size2 get_minimum_size() const override { Size2 get_grid_size() const {
Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label")); Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label"));
int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label"));
return Vector2(0, font->get_height(font_size) * 2); return Vector2(0, font->get_height(font_size) * 3);
}
public:
uint32_t value = 0;
int layer_group_size = 0;
int layer_count = 0;
Vector<String> names;
Vector<String> tooltips;
virtual Size2 get_minimum_size() const override {
Size2 min_size = get_grid_size();
// Add extra rows when expanded.
if (expanded) {
const int bsize = (min_size.height * 80 / 100) / 2;
for (int i = 0; i < expansion_rows; ++i) {
min_size.y += 2 * (bsize + 1) + 3;
}
}
return min_size;
} }
virtual String get_tooltip(const Point2 &p_pos) const override { virtual String get_tooltip(const Point2 &p_pos) const override {
@ -712,80 +734,192 @@ public:
} }
return String(); return String();
} }
void _gui_input(const Ref<InputEvent> &p_ev) { void _gui_input(const Ref<InputEvent> &p_ev) {
const Ref<InputEventMouseMotion> mm = p_ev; const Ref<InputEventMouseMotion> mm = p_ev;
if (mm.is_valid()) { if (mm.is_valid()) {
for (int i = 0; i < flag_rects.size(); i++) { bool expand_was_hovered = expand_hovered;
if (flag_rects[i].has_point(mm->get_position())) { expand_hovered = expand_rect.has_point(mm->get_position());
// Used to highlight the hovered flag in the layers grid. if (expand_hovered != expand_was_hovered) {
hovered_index = i; update();
update(); }
break;
if (!expand_hovered) {
for (int i = 0; i < flag_rects.size(); i++) {
if (flag_rects[i].has_point(mm->get_position())) {
// Used to highlight the hovered flag in the layers grid.
hovered_index = i;
update();
return;
}
} }
} }
// Remove highlight when no square is hovered.
if (hovered_index != -1) {
hovered_index = -1;
update();
}
return;
} }
const Ref<InputEventMouseButton> mb = p_ev; const Ref<InputEventMouseButton> mb = p_ev;
if (mb.is_valid() && mb->get_button_index() == MOUSE_BUTTON_LEFT && mb->is_pressed()) {
if (hovered_index >= 0) {
// Toggle the flag.
// We base our choice on the hovered flag, so that it always matches the hovered flag.
if (value & (1 << hovered_index)) {
value &= ~(1 << hovered_index);
} else {
value |= (1 << hovered_index);
}
if (mb.is_valid() && mb->get_button_index() == MOUSE_BUTTON_LEFT && mb->is_pressed() && hovered_index >= 0) { emit_signal(SNAME("flag_changed"), value);
// Toggle the flag. update();
// We base our choice on the hovered flag, so that it always matches the hovered flag. } else if (expand_hovered) {
if (value & (1 << hovered_index)) { expanded = !expanded;
value &= ~(1 << hovered_index); minimum_size_changed();
} else { update();
value |= (1 << hovered_index);
} }
emit_signal(SNAME("flag_changed"), value);
update();
} }
} }
void _notification(int p_what) { void _notification(int p_what) {
switch (p_what) { switch (p_what) {
case NOTIFICATION_DRAW: { case NOTIFICATION_DRAW: {
Rect2 rect; Size2 grid_size = get_grid_size();
rect.size = get_size(); grid_size.x = get_size().x;
flag_rects.clear(); flag_rects.clear();
const int bsize = (rect.size.height * 80 / 100) / 2; int prev_expansion_rows = expansion_rows;
expansion_rows = 0;
const int bsize = (grid_size.height * 80 / 100) / 2;
const int h = bsize * 2 + 1; const int h = bsize * 2 + 1;
const int vofs = (rect.size.height - h) / 2;
Color color = get_theme_color(SNAME("highlight_color"), SNAME("Editor")); Color color = get_theme_color(SNAME("highlight_color"), SNAME("Editor"));
for (int i = 0; i < 2; i++) {
Point2 ofs(4, vofs); Color text_color = get_theme_color(SNAME("font_color"), SNAME("Editor"));
if (i == 1) { text_color.a *= 0.5;
Color text_color_on = get_theme_color(SNAME("font_hover_color"), SNAME("Editor"));
text_color_on.a *= 0.7;
const int vofs = (grid_size.height - h) / 2;
int layer_index = 0;
int block_index = 0;
Point2 arrow_pos;
Point2 block_ofs(4, vofs);
while (true) {
Point2 ofs = block_ofs;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < layer_group_size; j++) {
const bool on = value & (1 << layer_index);
Rect2 rect2 = Rect2(ofs, Size2(bsize, bsize));
color.a = on ? 0.6 : 0.2;
if (layer_index == hovered_index) {
// Add visual feedback when hovering a flag.
color.a += 0.15;
}
draw_rect(rect2, color);
flag_rects.push_back(rect2);
Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label"));
Vector2 offset;
offset.y = rect2.size.y * 0.75;
draw_string(font, rect2.position + offset, itos(layer_index), HALIGN_CENTER, rect2.size.x, -1, on ? text_color_on : text_color);
ofs.x += bsize + 1;
++layer_index;
}
ofs.x = block_ofs.x;
ofs.y += bsize + 1; ofs.y += bsize + 1;
} }
ofs += rect.position; if (layer_index >= layer_count) {
for (int j = 0; j < 10; j++) { if (!flag_rects.is_empty() && (expansion_rows == 0)) {
Point2 o = ofs + Point2(j * (bsize + 1), 0); const Rect2 &last_rect = flag_rects[flag_rects.size() - 1];
if (j >= 5) { arrow_pos = last_rect.position + last_rect.size;
o.x += 1;
} }
break;
const int idx = i * 10 + j;
const bool on = value & (1 << idx);
Rect2 rect2 = Rect2(o, Size2(bsize, bsize));
color.a = on ? 0.6 : 0.2;
if (idx == hovered_index) {
// Add visual feedback when hovering a flag.
color.a += 0.15;
}
draw_rect(rect2, color);
flag_rects.push_back(rect2);
} }
int block_size_x = layer_group_size * (bsize + 1);
block_ofs.x += block_size_x + 3;
if (block_ofs.x + block_size_x + 12 > grid_size.width) {
// Keep last valid cell position for the expansion icon.
if (!flag_rects.is_empty() && (expansion_rows == 0)) {
const Rect2 &last_rect = flag_rects[flag_rects.size() - 1];
arrow_pos = last_rect.position + last_rect.size;
}
++expansion_rows;
if (expanded) {
// Expand grid to next line.
block_ofs.x = 4;
block_ofs.y += 2 * (bsize + 1) + 3;
} else {
// Skip remaining blocks.
break;
}
}
++block_index;
}
if ((expansion_rows != prev_expansion_rows) && expanded) {
minimum_size_changed();
}
if ((expansion_rows == 0) && (layer_index == layer_count)) {
// Whole grid was drawn, no need for expansion icon.
break;
}
Ref<Texture2D> arrow = get_theme_icon(SNAME("arrow"), SNAME("Tree"));
ERR_FAIL_COND(arrow.is_null());
Color arrow_color = get_theme_color(SNAME("highlight_color"), SNAME("Editor"));
arrow_color.a = expand_hovered ? 1.0 : 0.6;
arrow_pos.x += 2.0;
arrow_pos.y -= arrow->get_height();
Rect2 arrow_draw_rect(arrow_pos, arrow->get_size());
expand_rect = arrow_draw_rect;
if (expanded) {
arrow_draw_rect.size.y *= -1.0; // Flip arrow vertically when expanded.
}
RID ci = get_canvas_item();
arrow->draw_rect(ci, arrow_draw_rect, false, arrow_color);
} break;
case NOTIFICATION_MOUSE_EXIT: {
if (expand_hovered) {
expand_hovered = false;
update();
}
if (hovered_index != -1) {
hovered_index = -1;
update();
} }
} break; } break;
case NOTIFICATION_MOUSE_EXIT: {
hovered_index = -1;
update();
} break;
default: default:
break; break;
} }
@ -800,12 +934,8 @@ public:
ClassDB::bind_method(D_METHOD("_gui_input"), &EditorPropertyLayersGrid::_gui_input); ClassDB::bind_method(D_METHOD("_gui_input"), &EditorPropertyLayersGrid::_gui_input);
ADD_SIGNAL(MethodInfo("flag_changed", PropertyInfo(Variant::INT, "flag"))); ADD_SIGNAL(MethodInfo("flag_changed", PropertyInfo(Variant::INT, "flag")));
} }
EditorPropertyLayersGrid() {
value = 0;
hovered_index = -1; // Nothing is hovered.
}
}; };
void EditorPropertyLayers::_grid_changed(uint32_t p_grid) { void EditorPropertyLayers::_grid_changed(uint32_t p_grid) {
emit_changed(get_edited_property(), p_grid); emit_changed(get_edited_property(), p_grid);
} }
@ -818,30 +948,49 @@ void EditorPropertyLayers::update_property() {
void EditorPropertyLayers::setup(LayerType p_layer_type) { void EditorPropertyLayers::setup(LayerType p_layer_type) {
String basename; String basename;
int layer_group_size = 0;
int layer_count = 0;
switch (p_layer_type) { switch (p_layer_type) {
case LAYER_RENDER_2D: case LAYER_RENDER_2D: {
basename = "layer_names/2d_render"; basename = "layer_names/2d_render";
break; layer_group_size = 5;
case LAYER_PHYSICS_2D: layer_count = 20;
} break;
case LAYER_PHYSICS_2D: {
basename = "layer_names/2d_physics"; basename = "layer_names/2d_physics";
break; layer_group_size = 4;
case LAYER_NAVIGATION_2D: layer_count = 32;
} break;
case LAYER_NAVIGATION_2D: {
basename = "layer_names/2d_navigation"; basename = "layer_names/2d_navigation";
break; layer_group_size = 4;
case LAYER_RENDER_3D: layer_count = 32;
} break;
case LAYER_RENDER_3D: {
basename = "layer_names/3d_render"; basename = "layer_names/3d_render";
break; layer_group_size = 5;
case LAYER_PHYSICS_3D: layer_count = 20;
} break;
case LAYER_PHYSICS_3D: {
basename = "layer_names/3d_physics"; basename = "layer_names/3d_physics";
break; layer_group_size = 4;
case LAYER_NAVIGATION_3D: layer_count = 32;
} break;
case LAYER_NAVIGATION_3D: {
basename = "layer_names/3d_navigation"; basename = "layer_names/3d_navigation";
break; layer_group_size = 4;
layer_count = 32;
} break;
} }
Vector<String> names; Vector<String> names;
Vector<String> tooltips; Vector<String> tooltips;
for (int i = 0; i < 20; i++) { for (int i = 0; i < layer_count; i++) {
String name; String name;
if (ProjectSettings::get_singleton()->has_setting(basename + vformat("/layer_%d", i))) { if (ProjectSettings::get_singleton()->has_setting(basename + vformat("/layer_%d", i))) {
@ -858,12 +1007,17 @@ void EditorPropertyLayers::setup(LayerType p_layer_type) {
grid->names = names; grid->names = names;
grid->tooltips = tooltips; grid->tooltips = tooltips;
grid->layer_group_size = layer_group_size;
grid->layer_count = layer_count;
} }
void EditorPropertyLayers::_button_pressed() { void EditorPropertyLayers::_button_pressed() {
int layer_count = grid->layer_count;
int layer_group_size = grid->layer_group_size;
layers->clear(); layers->clear();
for (int i = 0; i < 20; i++) { for (int i = 0; i < layer_count; i++) {
if (i == 5 || i == 10 || i == 15) { if ((i != 0) && ((i % layer_group_size) == 0)) {
layers->add_separator(); layers->add_separator();
} }
layers->add_check_item(grid->names[i], i); layers->add_check_item(grid->names[i], i);
@ -894,17 +1048,21 @@ void EditorPropertyLayers::_bind_methods() {
EditorPropertyLayers::EditorPropertyLayers() { EditorPropertyLayers::EditorPropertyLayers() {
HBoxContainer *hb = memnew(HBoxContainer); HBoxContainer *hb = memnew(HBoxContainer);
hb->set_clip_contents(true);
add_child(hb); add_child(hb);
grid = memnew(EditorPropertyLayersGrid); grid = memnew(EditorPropertyLayersGrid);
grid->connect("flag_changed", callable_mp(this, &EditorPropertyLayers::_grid_changed)); grid->connect("flag_changed", callable_mp(this, &EditorPropertyLayers::_grid_changed));
grid->set_h_size_flags(SIZE_EXPAND_FILL); grid->set_h_size_flags(SIZE_EXPAND_FILL);
hb->add_child(grid); hb->add_child(grid);
button = memnew(Button); button = memnew(Button);
button->set_toggle_mode(true); button->set_toggle_mode(true);
button->set_text("..."); button->set_text("...");
button->connect("pressed", callable_mp(this, &EditorPropertyLayers::_button_pressed)); button->connect("pressed", callable_mp(this, &EditorPropertyLayers::_button_pressed));
hb->add_child(button); hb->add_child(button);
set_bottom_editor(hb); set_bottom_editor(hb);
layers = memnew(PopupMenu); layers = memnew(PopupMenu);
add_child(layers); add_child(layers);
layers->set_hide_on_checkable_item_selection(false); layers->set_hide_on_checkable_item_selection(false);

View File

@ -1000,9 +1000,12 @@ void register_scene_types() {
for (int i = 0; i < 20; i++) { for (int i = 0; i < 20; i++) {
GLOBAL_DEF_BASIC(vformat("layer_names/2d_render/layer_%d", i), ""); GLOBAL_DEF_BASIC(vformat("layer_names/2d_render/layer_%d", i), "");
GLOBAL_DEF_BASIC(vformat("layer_names/3d_render/layer_%d", i), "");
}
for (int i = 0; i < 32; i++) {
GLOBAL_DEF_BASIC(vformat("layer_names/2d_physics/layer_%d", i), ""); GLOBAL_DEF_BASIC(vformat("layer_names/2d_physics/layer_%d", i), "");
GLOBAL_DEF_BASIC(vformat("layer_names/2d_navigation/layer_%d", i), ""); GLOBAL_DEF_BASIC(vformat("layer_names/2d_navigation/layer_%d", i), "");
GLOBAL_DEF_BASIC(vformat("layer_names/3d_render/layer_%d", i), "");
GLOBAL_DEF_BASIC(vformat("layer_names/3d_physics/layer_%d", i), ""); GLOBAL_DEF_BASIC(vformat("layer_names/3d_physics/layer_%d", i), "");
GLOBAL_DEF_BASIC(vformat("layer_names/3d_navigation/layer_%d", i), ""); GLOBAL_DEF_BASIC(vformat("layer_names/3d_navigation/layer_%d", i), "");
} }