diff --git a/editor/scene/2d/tiles/tile_map_layer_editor.cpp b/editor/scene/2d/tiles/tile_map_layer_editor.cpp index 5f606c3dc16..0678bf7762c 100644 --- a/editor/scene/2d/tiles/tile_map_layer_editor.cpp +++ b/editor/scene/2d/tiles/tile_map_layer_editor.cpp @@ -42,6 +42,7 @@ #include "editor/themes/editor_scale.h" #include "scene/2d/tile_map.h" #include "scene/2d/tile_map_layer.h" +#include "scene/gui/grid_container.h" #include "scene/gui/split_container.h" #include "core/input/input.h" @@ -49,6 +50,20 @@ #include "core/math/random_pcg.h" #include "core/os/keyboard.h" +void SwitchSeparator::set_vertical(bool p_vertical) { + h_separator->set_visible(p_vertical); + v_separator->set_visible(!p_vertical); +} + +SwitchSeparator::SwitchSeparator() { + h_separator = memnew(HSeparator); + h_separator->hide(); + add_child(h_separator); + + v_separator = memnew(VSeparator); + add_child(v_separator); +} + TileMapLayer *TileMapLayerSubEditorPlugin::_get_edited_layer() const { return ObjectDB::get_instance(edited_tile_map_layer_id); } @@ -95,32 +110,14 @@ void TileMapLayerEditorTilesPlugin::_update_toolbar() { // Stop dragging if needed. _stop_dragging(); - // Hide all settings. - for (int i = 0; i < tools_settings->get_child_count(); i++) { - Object::cast_to(tools_settings->get_child(i))->hide(); - } - // Show only the correct settings. - if (tool_buttons_group->get_pressed_button() == select_tool_button) { - transform_toolbar->show(); - } else if (tool_buttons_group->get_pressed_button() != bucket_tool_button) { - tools_settings_vsep->show(); - picker_button->show(); - erase_button->show(); - transform_toolbar->show(); - tools_settings_vsep_2->show(); - random_tile_toggle->show(); - scatter_controls_container->set_visible(random_tile_toggle->is_pressed()); - } else { - tools_settings_vsep->show(); - picker_button->show(); - erase_button->show(); - transform_toolbar->show(); - tools_settings_vsep_2->show(); - bucket_contiguous_checkbox->show(); - random_tile_toggle->show(); - scatter_controls_container->set_visible(random_tile_toggle->is_pressed()); - } + bool using_select = (tool_buttons_group->get_pressed_button() == select_tool_button); + tools_settings_vsep->set_visible(!using_select); + picker_button->set_visible(!using_select); + erase_button->set_visible(!using_select); + random_tile_toggle->set_visible(!using_select); + bucket_contiguous_checkbox->set_visible(!using_select && tool_buttons_group->get_pressed_button() == bucket_tool_button); + scatter_controls_container->set_visible(!using_select && random_tile_toggle->is_pressed()); CanvasItemEditor::get_singleton()->set_current_tool(CanvasItemEditor::TOOL_SELECT); } @@ -156,8 +153,12 @@ void TileMapLayerEditorTilesPlugin::_set_transform_buttons_state(const Vector TileMapLayerEditorTilesPlugin::get_tabs() const { Vector tabs; - tabs.push_back({ toolbar, tiles_bottom_panel }); - tabs.push_back({ toolbar, patterns_bottom_panel }); + Vector toolbar_controls; + toolbar_controls.push_back(tilemap_tiles_tools_buttons); + toolbar_controls.push_back(tools_settings); + toolbar_controls.push_back(tools_settings_vsep); + tabs.push_back({ toolbar_controls, wide_toolbar, tiles_bottom_panel }); + tabs.push_back({ toolbar_controls, wide_toolbar, patterns_bottom_panel }); return tabs; } @@ -2141,6 +2142,19 @@ void TileMapLayerEditorTilesPlugin::edit(ObjectID p_tile_map_layer_id) { edited_tile_map_layer_id = p_tile_map_layer_id; } +void TileMapLayerEditorTilesPlugin::update_layout(EditorDock::DockLayout p_layout) { + bool is_vertical = (p_layout == EditorDock::DockLayout::DOCK_LAYOUT_VERTICAL); + atlas_sources_split_container->set_vertical(is_vertical); + atlas_sources_split_container->move_child(split_container_left_side, is_vertical ? -1 : 0); + split_container_left_side->set_vertical(!is_vertical); + + tilemap_tiles_tools_buttons->set_vertical(is_vertical); + transform_toolbar->set_vertical(is_vertical); + tools_settings->set_vertical(is_vertical); + tools_settings_vsep->set_vertical(is_vertical); + transform_separator->set_vertical(is_vertical); +} + TileMapLayerEditorTilesPlugin::TileMapLayerEditorTilesPlugin() { CanvasItemEditor::get_singleton() ->get_viewport_control() @@ -2154,9 +2168,9 @@ TileMapLayerEditorTilesPlugin::TileMapLayerEditorTilesPlugin() { erase_pattern->set_cell(Vector2i(0, 0), TileSet::INVALID_SOURCE, TileSetSource::INVALID_ATLAS_COORDS, TileSetSource::INVALID_TILE_ALTERNATIVE); // --- Toolbar --- - toolbar = memnew(HBoxContainer); + wide_toolbar = memnew(HBoxContainer); - HBoxContainer *tilemap_tiles_tools_buttons = memnew(HBoxContainer); + tilemap_tiles_tools_buttons = memnew(BoxContainer); tool_buttons_group.instantiate(); @@ -2210,15 +2224,12 @@ TileMapLayerEditorTilesPlugin::TileMapLayerEditorTilesPlugin() { bucket_tool_button->connect(SceneStringName(pressed), callable_mp(this, &TileMapLayerEditorTilesPlugin::_update_toolbar)); bucket_tool_button->set_accessibility_name(TTRC("Bucket Tool")); tilemap_tiles_tools_buttons->add_child(bucket_tool_button); - toolbar->add_child(tilemap_tiles_tools_buttons); viewport_shortcut_buttons.push_back(bucket_tool_button); // -- TileMap tool settings -- - tools_settings = memnew(HBoxContainer); - toolbar->add_child(tools_settings); - - tools_settings_vsep = memnew(VSeparator); - tools_settings->add_child(tools_settings_vsep); + tools_settings = memnew(BoxContainer); + tools_settings_vsep = memnew(SwitchSeparator); + tools_settings_vsep->set_vertical(false); // Picker picker_button = memnew(Button); @@ -2244,9 +2255,11 @@ TileMapLayerEditorTilesPlugin::TileMapLayerEditorTilesPlugin() { viewport_shortcut_buttons.push_back(erase_button); // Transform toolbar. - transform_toolbar = memnew(HBoxContainer); + transform_toolbar = memnew(BoxContainer); tools_settings->add_child(transform_toolbar); - transform_toolbar->add_child(memnew(VSeparator)); + transform_separator = memnew(SwitchSeparator); + transform_separator->set_vertical(false); + transform_toolbar->add_child(transform_separator); transform_button_rotate_left = memnew(Button); transform_button_rotate_left->set_theme_type_variation(SceneStringName(FlatButton)); @@ -2280,16 +2293,13 @@ TileMapLayerEditorTilesPlugin::TileMapLayerEditorTilesPlugin() { transform_button_flip_v->set_accessibility_name(TTRC("Flip Tile Vertically")); viewport_shortcut_buttons.push_back(transform_button_flip_v); - // Separator 2. - tools_settings_vsep_2 = memnew(VSeparator); - tools_settings->add_child(tools_settings_vsep_2); - // Continuous checkbox. bucket_contiguous_checkbox = memnew(CheckBox); bucket_contiguous_checkbox->set_flat(true); bucket_contiguous_checkbox->set_text(TTR("Contiguous")); bucket_contiguous_checkbox->set_pressed(true); - tools_settings->add_child(bucket_contiguous_checkbox); + bucket_contiguous_checkbox->hide(); + wide_toolbar->add_child(bucket_contiguous_checkbox); // Random tile checkbox. random_tile_toggle = memnew(Button); @@ -2300,7 +2310,8 @@ TileMapLayerEditorTilesPlugin::TileMapLayerEditorTilesPlugin() { tools_settings->add_child(random_tile_toggle); // Random tile scattering. - scatter_controls_container = memnew(HBoxContainer); + scatter_controls_container = memnew(BoxContainer); + scatter_controls_container->set_vertical(false); scatter_label = memnew(Label); scatter_label->set_tooltip_text(TTR("Modifies the chance of painting nothing instead of a randomly selected tile.")); @@ -2316,7 +2327,7 @@ TileMapLayerEditorTilesPlugin::TileMapLayerEditorTilesPlugin() { scatter_spinbox->connect(SceneStringName(value_changed), callable_mp(this, &TileMapLayerEditorTilesPlugin::_on_scattering_spinbox_changed)); scatter_spinbox->set_accessibility_name(TTRC("Scattering:")); scatter_controls_container->add_child(scatter_spinbox); - tools_settings->add_child(scatter_controls_container); + wide_toolbar->add_child(scatter_controls_container); _on_random_tile_checkbox_toggled(false); @@ -2345,25 +2356,26 @@ TileMapLayerEditorTilesPlugin::TileMapLayerEditorTilesPlugin() { missing_source_label->hide(); tiles_bottom_panel->add_child(missing_source_label); - atlas_sources_split_container = memnew(HSplitContainer); + atlas_sources_split_container = memnew(SplitContainer); + atlas_sources_split_container->set_vertical(false); atlas_sources_split_container->set_h_size_flags(Control::SIZE_EXPAND_FILL); atlas_sources_split_container->set_v_size_flags(Control::SIZE_EXPAND_FILL); tiles_bottom_panel->add_child(atlas_sources_split_container); - VBoxContainer *split_container_left_side = memnew(VBoxContainer); + split_container_left_side = memnew(BoxContainer); + split_container_left_side->set_vertical(true); split_container_left_side->set_h_size_flags(Control::SIZE_EXPAND_FILL); split_container_left_side->set_v_size_flags(Control::SIZE_EXPAND_FILL); split_container_left_side->set_stretch_ratio(0.25); split_container_left_side->set_custom_minimum_size(Size2(70, 0) * EDSCALE); atlas_sources_split_container->add_child(split_container_left_side); - HBoxContainer *sources_bottom_actions = memnew(HBoxContainer); - sources_bottom_actions->set_alignment(HBoxContainer::ALIGNMENT_END); - source_sort_button = memnew(MenuButton); source_sort_button->set_flat(false); source_sort_button->set_theme_type_variation("FlatMenuButton"); source_sort_button->set_tooltip_text(TTR("Sort sources")); + source_sort_button->set_h_size_flags(Control::SIZE_SHRINK_END); + source_sort_button->set_v_size_flags(Control::SIZE_SHRINK_END); PopupMenu *p = source_sort_button->get_popup(); p->connect(SceneStringName(id_pressed), callable_mp(this, &TileMapLayerEditorTilesPlugin::_set_source_sort)); @@ -2372,7 +2384,6 @@ TileMapLayerEditorTilesPlugin::TileMapLayerEditorTilesPlugin() { p->add_radio_check_item(TTR("Sort by Name (Ascending)"), TilesEditorUtils::SOURCE_SORT_NAME); p->add_radio_check_item(TTR("Sort by Name (Descending)"), TilesEditorUtils::SOURCE_SORT_NAME_REVERSE); p->set_item_checked(TilesEditorUtils::SOURCE_SORT_ID, true); - sources_bottom_actions->add_child(source_sort_button); sources_list = memnew(TileSetSourceItemList); sources_list->connect(SceneStringName(item_selected), callable_mp(this, &TileMapLayerEditorTilesPlugin::_update_source_display).unbind(1)); @@ -2381,7 +2392,7 @@ TileMapLayerEditorTilesPlugin::TileMapLayerEditorTilesPlugin() { sources_list->connect(SceneStringName(visibility_changed), callable_mp(TilesEditorUtils::get_singleton(), &TilesEditorUtils::synchronize_sources_list).bind(sources_list, source_sort_button)); sources_list->connect("sort_request", callable_mp(this, &TileMapLayerEditorTilesPlugin::_update_tile_set_sources_list)); split_container_left_side->add_child(sources_list); - split_container_left_side->add_child(sources_bottom_actions); + split_container_left_side->add_child(source_sort_button); // Tile atlas source. tile_atlas_view = memnew(TileAtlasView); @@ -2465,28 +2476,15 @@ void TileMapLayerEditorTerrainsPlugin::tile_set_changed() { } void TileMapLayerEditorTerrainsPlugin::_update_toolbar() { - // Hide all settings. - for (int i = 0; i < tools_settings->get_child_count(); i++) { - Object::cast_to(tools_settings->get_child(i))->hide(); - } - - // Show only the correct settings. - if (tool_buttons_group->get_pressed_button() != bucket_tool_button) { - tools_settings_vsep->show(); - picker_button->show(); - erase_button->show(); - } else { - tools_settings_vsep->show(); - picker_button->show(); - erase_button->show(); - tools_settings_vsep_2->show(); - bucket_contiguous_checkbox->show(); - } + bucket_contiguous_checkbox->set_visible(tool_buttons_group->get_pressed_button() == bucket_tool_button); } Vector TileMapLayerEditorTerrainsPlugin::get_tabs() const { Vector tabs; - tabs.push_back({ toolbar, main_vbox_container }); + Vector toolbar_controls; + toolbar_controls.push_back(tilemap_tiles_tools_buttons); + toolbar_controls.push_back(tools_settings); + tabs.push_back({ toolbar_controls, wide_toolbar, main_box_container }); return tabs; } @@ -2964,7 +2962,7 @@ void TileMapLayerEditorTerrainsPlugin::_update_selection() { } bool TileMapLayerEditorTerrainsPlugin::forward_canvas_gui_input(const Ref &p_event) { - if (!main_vbox_container->is_visible_in_tree()) { + if (!main_box_container->is_visible_in_tree()) { // If the bottom editor is not visible, we ignore inputs. return false; } @@ -3119,7 +3117,7 @@ void TileMapLayerEditorTerrainsPlugin::forward_canvas_draw_over_viewport(Control bool drawing_rect = false; // Handle the preview of the tiles to be placed. - if (main_vbox_container->is_visible_in_tree() && has_mouse) { // Only if the tilemap editor is opened and the viewport is hovered. + if (main_box_container->is_visible_in_tree() && has_mouse) { // Only if the tilemap editor is opened and the viewport is hovered. RBSet preview; Rect2i drawn_grid_rect; @@ -3315,13 +3313,13 @@ void TileMapLayerEditorTerrainsPlugin::_update_terrains_tree() { TreeItem *terrain_set_tree_item = terrains_tree->create_item(); String matches; if (tile_set->get_terrain_set_mode(terrain_set_index) == TileSet::TERRAIN_MODE_MATCH_CORNERS_AND_SIDES) { - terrain_set_tree_item->set_icon(0, main_vbox_container->get_editor_theme_icon(SNAME("TerrainMatchCornersAndSides"))); + terrain_set_tree_item->set_icon(0, main_box_container->get_editor_theme_icon(SNAME("TerrainMatchCornersAndSides"))); matches = String(TTR("Matches Corners and Sides")); } else if (tile_set->get_terrain_set_mode(terrain_set_index) == TileSet::TERRAIN_MODE_MATCH_CORNERS) { - terrain_set_tree_item->set_icon(0, main_vbox_container->get_editor_theme_icon(SNAME("TerrainMatchCorners"))); + terrain_set_tree_item->set_icon(0, main_box_container->get_editor_theme_icon(SNAME("TerrainMatchCorners"))); matches = String(TTR("Matches Corners Only")); } else { - terrain_set_tree_item->set_icon(0, main_vbox_container->get_editor_theme_icon(SNAME("TerrainMatchSides"))); + terrain_set_tree_item->set_icon(0, main_box_container->get_editor_theme_icon(SNAME("TerrainMatchSides"))); matches = String(TTR("Matches Sides Only")); } terrain_set_tree_item->set_text(0, vformat(TTR("Terrain Set %d (%s)"), terrain_set_index, matches)); @@ -3364,13 +3362,13 @@ void TileMapLayerEditorTerrainsPlugin::_update_tiles_list() { ERR_FAIL_INDEX(sel_terrain_id, tile_set->get_terrains_count(sel_terrain_set)); // Add the two first generic modes - int item_index = terrains_tile_list->add_icon_item(main_vbox_container->get_editor_theme_icon(SNAME("TerrainConnect"))); + int item_index = terrains_tile_list->add_icon_item(main_box_container->get_editor_theme_icon(SNAME("TerrainConnect"))); terrains_tile_list->set_item_tooltip(item_index, TTR("Connect mode: paints a terrain, then connects it with the surrounding tiles with the same terrain.")); Dictionary list_metadata_dict; list_metadata_dict["type"] = SELECTED_TYPE_CONNECT; terrains_tile_list->set_item_metadata(item_index, list_metadata_dict); - item_index = terrains_tile_list->add_icon_item(main_vbox_container->get_editor_theme_icon(SNAME("TerrainPath"))); + item_index = terrains_tile_list->add_icon_item(main_box_container->get_editor_theme_icon(SNAME("TerrainPath"))); terrains_tile_list->set_item_tooltip(item_index, TTR("Path mode: paints a terrain, then connects it to the previous tile painted within the same stroke.")); list_metadata_dict = Dictionary(); list_metadata_dict["type"] = SELECTED_TYPE_PATH; @@ -3441,13 +3439,13 @@ void TileMapLayerEditorTerrainsPlugin::_update_tiles_list() { } void TileMapLayerEditorTerrainsPlugin::_update_theme() { - paint_tool_button->set_button_icon(main_vbox_container->get_editor_theme_icon(SNAME("Edit"))); - line_tool_button->set_button_icon(main_vbox_container->get_editor_theme_icon(SNAME("Line"))); - rect_tool_button->set_button_icon(main_vbox_container->get_editor_theme_icon(SNAME("Rectangle"))); - bucket_tool_button->set_button_icon(main_vbox_container->get_editor_theme_icon(SNAME("Bucket"))); + paint_tool_button->set_button_icon(main_box_container->get_editor_theme_icon(SNAME("Edit"))); + line_tool_button->set_button_icon(main_box_container->get_editor_theme_icon(SNAME("Line"))); + rect_tool_button->set_button_icon(main_box_container->get_editor_theme_icon(SNAME("Rectangle"))); + bucket_tool_button->set_button_icon(main_box_container->get_editor_theme_icon(SNAME("Bucket"))); - picker_button->set_button_icon(main_vbox_container->get_editor_theme_icon(SNAME("ColorPick"))); - erase_button->set_button_icon(main_vbox_container->get_editor_theme_icon(SNAME("Eraser"))); + picker_button->set_button_icon(main_box_container->get_editor_theme_icon(SNAME("ColorPick"))); + erase_button->set_button_icon(main_box_container->get_editor_theme_icon(SNAME("Eraser"))); _update_tiles_list(); } @@ -3465,21 +3463,38 @@ void TileMapLayerEditorTerrainsPlugin::edit(ObjectID p_edited_tile_map_layer_id) } } +void TileMapLayerEditorTerrainsPlugin::update_layout(EditorDock::DockLayout p_layout) { + bool is_vertical = (p_layout == EditorDock::DockLayout::DOCK_LAYOUT_VERTICAL); + // Main Panel. + main_box_container->set_vertical(is_vertical); + tilemap_tab_terrains->move_child(terrains_tree, is_vertical ? 1 : 0); + tilemap_tab_terrains->set_vertical(is_vertical); + + // Toolbar. + tilemap_tiles_tools_buttons->set_vertical(is_vertical); + tools_settings->set_vertical(is_vertical); + tools_settings_vsep->set_vertical(is_vertical); +} + TileMapLayerEditorTerrainsPlugin::TileMapLayerEditorTerrainsPlugin() { - main_vbox_container = memnew(VBoxContainer); + wide_toolbar = memnew(HBoxContainer); + main_box_container = memnew(BoxContainer); + main_box_container->set_vertical(true); // FIXME: This can trigger theme updates when the nodes that we want to update are not yet available. // The toolbar should be extracted to a dedicated control and theme updates should be handled through // the notification. - main_vbox_container->connect(SceneStringName(theme_changed), callable_mp(this, &TileMapLayerEditorTerrainsPlugin::_update_theme)); - main_vbox_container->set_name(TTR("Terrains")); + main_box_container->connect(SceneStringName(theme_changed), callable_mp(this, &TileMapLayerEditorTerrainsPlugin::_update_theme)); + main_box_container->set_name(TTRC("Terrains")); - HSplitContainer *tilemap_tab_terrains = memnew(HSplitContainer); + tilemap_tab_terrains = memnew(SplitContainer); + tilemap_tab_terrains->set_vertical(false); tilemap_tab_terrains->set_h_size_flags(Control::SIZE_EXPAND_FILL); tilemap_tab_terrains->set_v_size_flags(Control::SIZE_EXPAND_FILL); - main_vbox_container->add_child(tilemap_tab_terrains); + main_box_container->add_child(tilemap_tab_terrains); terrains_tree = memnew(Tree); terrains_tree->set_h_size_flags(Control::SIZE_EXPAND_FILL); + terrains_tree->set_v_size_flags(Control::SIZE_EXPAND_FILL); terrains_tree->set_stretch_ratio(0.25); terrains_tree->set_custom_minimum_size(Size2(70, 0) * EDSCALE); terrains_tree->set_texture_filter(CanvasItem::TEXTURE_FILTER_NEAREST); @@ -3491,6 +3506,7 @@ TileMapLayerEditorTerrainsPlugin::TileMapLayerEditorTerrainsPlugin() { terrains_tile_list = memnew(ItemList); terrains_tile_list->set_auto_translate_mode(Node::AUTO_TRANSLATE_MODE_DISABLED); terrains_tile_list->set_h_size_flags(Control::SIZE_EXPAND_FILL); + terrains_tile_list->set_v_size_flags(Control::SIZE_EXPAND_FILL); terrains_tile_list->set_max_columns(0); terrains_tile_list->set_same_column_width(true); terrains_tile_list->set_fixed_icon_size(Size2(32, 32) * EDSCALE); @@ -3498,10 +3514,7 @@ TileMapLayerEditorTerrainsPlugin::TileMapLayerEditorTerrainsPlugin() { tilemap_tab_terrains->add_child(terrains_tile_list); // --- Toolbar --- - toolbar = memnew(HBoxContainer); - - HBoxContainer *tilemap_tiles_tools_buttons = memnew(HBoxContainer); - + tilemap_tiles_tools_buttons = memnew(BoxContainer); tool_buttons_group.instantiate(); paint_tool_button = memnew(Button); @@ -3545,13 +3558,11 @@ TileMapLayerEditorTerrainsPlugin::TileMapLayerEditorTerrainsPlugin() { tilemap_tiles_tools_buttons->add_child(bucket_tool_button); viewport_shortcut_buttons.push_back(bucket_tool_button); - toolbar->add_child(tilemap_tiles_tools_buttons); - // -- TileMap tool settings -- - tools_settings = memnew(HBoxContainer); - toolbar->add_child(tools_settings); + tools_settings = memnew(BoxContainer); - tools_settings_vsep = memnew(VSeparator); + tools_settings_vsep = memnew(SwitchSeparator); + tools_settings_vsep->set_vertical(false); tools_settings->add_child(tools_settings_vsep); // Picker @@ -3574,16 +3585,13 @@ TileMapLayerEditorTerrainsPlugin::TileMapLayerEditorTerrainsPlugin() { tools_settings->add_child(erase_button); viewport_shortcut_buttons.push_back(erase_button); - // Separator 2. - tools_settings_vsep_2 = memnew(VSeparator); - tools_settings->add_child(tools_settings_vsep_2); - // Continuous checkbox. bucket_contiguous_checkbox = memnew(CheckBox); bucket_contiguous_checkbox->set_flat(true); bucket_contiguous_checkbox->set_text(TTR("Contiguous")); bucket_contiguous_checkbox->set_pressed(true); - tools_settings->add_child(bucket_contiguous_checkbox); + bucket_contiguous_checkbox->hide(); + wide_toolbar->add_child(bucket_contiguous_checkbox); } TileMapLayer *TileMapLayerEditor::_get_edited_layer() const { @@ -4062,9 +4070,16 @@ void TileMapLayerEditor::_tab_changed(int p_tab_id) { // Update toolbar. for (TileMapLayerSubEditorPlugin::TabData &tab_data : tabs_data) { - tab_data.toolbar->hide(); + for (Control *toolbar_control : tab_data.toolbar) { + toolbar_control->hide(); + } + tab_data.wide_toolbar->hide(); } - tabs_data[p_tab_id].toolbar->show(); + + for (Control *toolbar_control : tabs_data[p_tab_id].toolbar) { + toolbar_control->show(); + } + tabs_data[p_tab_id].wide_toolbar->show(); // Update visible panel. for (TileMapLayerSubEditorPlugin::TabData &tab_data : tabs_data) { @@ -4396,17 +4411,51 @@ void TileMapLayerEditor::set_show_layer_selector(bool p_show_layer_selector) { _update_layers_selector(); } +void TileMapLayerEditor::update_layout(DockLayout p_layout) { + bool is_vertical = (p_layout == EditorDock::DockLayout::DOCK_LAYOUT_VERTICAL); + tabs_bar->get_parent()->remove_child(tabs_bar); + tile_map_toolbar->set_vertical(is_vertical); + layer_selector_separator->set_vertical(is_vertical); + layer_selection_hbox->set_vertical(is_vertical); + tile_map_toolbar->set_h_size_flags(is_vertical ? SIZE_SHRINK_BEGIN : SIZE_EXPAND_FILL); + tile_map_toolbar->set_v_size_flags(is_vertical ? SIZE_EXPAND_FILL : SIZE_SHRINK_BEGIN); + + main_box_container->move_child(padding_control, is_vertical ? 0 : 3); + + if (is_vertical) { + tile_map_wide_toolbar->add_child(tabs_bar); + } else { + tile_map_toolbar->add_child(tabs_bar); + tile_map_toolbar->move_child(tabs_bar, 0); + } + + for (TileMapLayerSubEditorPlugin::TabData &tab_data : tabs_data) { + tab_data.wide_toolbar->get_parent()->remove_child(tab_data.wide_toolbar); + if (is_vertical) { + tile_map_wide_toolbar->add_child(tab_data.wide_toolbar); + } else { + tile_map_toolbar->add_child(tab_data.wide_toolbar); + } + } + + // Propagate layout change to sub plugins + for (TileMapLayerSubEditorPlugin *tab_plugin : tabs_plugins) { + tab_plugin->update_layout(p_layout); + } +} + TileMapLayerEditor::TileMapLayerEditor() { set_process_internal(true); set_name(TTRC("TileMap")); set_icon_name("TileMapDock"); set_dock_shortcut(ED_SHORTCUT_AND_COMMAND("bottom_panels/toggle_tile_map_bottom_panel", TTRC("Open TileMap Dock"))); set_default_slot(DockConstants::DOCK_SLOT_BOTTOM); - set_available_layouts(EditorDock::DOCK_LAYOUT_HORIZONTAL | EditorDock::DOCK_LAYOUT_FLOATING); + set_available_layouts(EditorDock::DOCK_LAYOUT_ALL); set_global(false); set_transient(true); - VBoxContainer *main_box_container = memnew(VBoxContainer); + main_box_container = memnew(GridContainer); + main_box_container->set_columns(2); add_child(main_box_container); // Shortcuts. @@ -4431,18 +4480,31 @@ TileMapLayerEditor::TileMapLayerEditor() { tabs_bar->connect("tab_changed", callable_mp(this, &TileMapLayerEditor::_tab_changed)); // --- TileMap toolbar --- - tile_map_toolbar = memnew(HFlowContainer); + tile_map_wide_toolbar = memnew(VBoxContainer); + main_box_container->add_child(tile_map_wide_toolbar); + + tile_map_toolbar = memnew(FlowContainer); tile_map_toolbar->set_h_size_flags(SIZE_EXPAND_FILL); main_box_container->add_child(tile_map_toolbar); + padding_control = memnew(Control); + main_box_container->add_child(padding_control); + // Tabs. tile_map_toolbar->add_child(tabs_bar); // Tabs toolbars. for (TileMapLayerSubEditorPlugin::TabData &tab_data : tabs_data) { - tab_data.toolbar->hide(); - if (!tab_data.toolbar->get_parent()) { - tile_map_toolbar->add_child(tab_data.toolbar); + for (Control *toolbar_control : tab_data.toolbar) { + toolbar_control->hide(); + if (!toolbar_control->get_parent()) { + tile_map_toolbar->add_child(toolbar_control); + } + } + + tab_data.wide_toolbar->hide(); + if (!tab_data.wide_toolbar->get_parent()) { + tile_map_toolbar->add_child(tab_data.wide_toolbar); } } @@ -4453,7 +4515,7 @@ TileMapLayerEditor::TileMapLayerEditor() { tile_map_toolbar->add_child(c); // Layer selector. - layer_selection_hbox = memnew(HBoxContainer); + layer_selection_hbox = memnew(BoxContainer); tile_map_toolbar->add_child(layer_selection_hbox); layers_selection_button = memnew(OptionButton); @@ -4477,7 +4539,6 @@ TileMapLayerEditor::TileMapLayerEditor() { select_all_layers = memnew(Button); select_all_layers->set_theme_type_variation(SceneStringName(FlatButton)); - select_all_layers->set_text(TTR("Select all layers")); select_all_layers->connect(SceneStringName(pressed), callable_mp(this, &TileMapLayerEditor::_select_all_layers_pressed)); select_all_layers->set_tooltip_text(TTR("Select all TileMapLayers in scene")); layer_selection_hbox->add_child(select_all_layers); @@ -4490,7 +4551,9 @@ TileMapLayerEditor::TileMapLayerEditor() { toggle_highlight_selected_layer_button->set_tooltip_text(TTR("Highlight Selected TileMap Layer")); tile_map_toolbar->add_child(toggle_highlight_selected_layer_button); - tile_map_toolbar->add_child(memnew(VSeparator)); + layer_selector_separator = memnew(SwitchSeparator); + layer_selector_separator->set_vertical(false); + tile_map_toolbar->add_child(layer_selector_separator); // Grid toggle. toggle_grid_button = memnew(Button); diff --git a/editor/scene/2d/tiles/tile_map_layer_editor.h b/editor/scene/2d/tiles/tile_map_layer_editor.h index 092f0eb9e83..3a207a46108 100644 --- a/editor/scene/2d/tiles/tile_map_layer_editor.h +++ b/editor/scene/2d/tiles/tile_map_layer_editor.h @@ -30,6 +30,7 @@ #pragma once +#include "scene/gui/margin_container.h" #include "tile_atlas_view.h" #include "core/os/thread.h" @@ -49,6 +50,19 @@ class TileMapLayer; class TileMapLayerEditor; class TileSetSourceItemList; +class GridContainer; + +class SwitchSeparator : public MarginContainer { + GDCLASS(SwitchSeparator, MarginContainer); + + HSeparator *h_separator = nullptr; + VSeparator *v_separator = nullptr; + +public: + void set_vertical(bool p_vertical); + + SwitchSeparator(); +}; class TileMapLayerSubEditorPlugin : public Object { GDSOFTCLASS(TileMapLayerSubEditorPlugin, Object); @@ -60,7 +74,8 @@ protected: public: struct TabData { - Control *toolbar = nullptr; + Vector toolbar; + Control *wide_toolbar; Control *panel = nullptr; }; @@ -73,6 +88,7 @@ public: virtual void tile_set_changed() {} virtual void edit(ObjectID p_tile_map_layer_id) {} virtual void draw_tile_coords_over_viewport(Control *p_overlay, const TileMapLayer *p_edited_layer, Ref p_tile_set, bool p_show_rectangle_size, const Vector2i &p_rectangle_origin); + virtual void update_layout(EditorDock::DockLayout p_layout) {} }; class TileMapLayerEditorTilesPlugin : public TileMapLayerSubEditorPlugin { @@ -88,8 +104,9 @@ public: private: ///// Toolbar ///// - HBoxContainer *toolbar = nullptr; + HBoxContainer *wide_toolbar = nullptr; + BoxContainer *tilemap_tiles_tools_buttons = nullptr; Ref tool_buttons_group; Button *select_tool_button = nullptr; Button *paint_tool_button = nullptr; @@ -97,23 +114,23 @@ private: Button *rect_tool_button = nullptr; Button *bucket_tool_button = nullptr; - HBoxContainer *tools_settings = nullptr; + BoxContainer *tools_settings = nullptr; - VSeparator *tools_settings_vsep = nullptr; + SwitchSeparator *tools_settings_vsep = nullptr; Button *picker_button = nullptr; Button *erase_button = nullptr; - HBoxContainer *transform_toolbar = nullptr; + BoxContainer *transform_toolbar = nullptr; Button *transform_button_rotate_left = nullptr; Button *transform_button_rotate_right = nullptr; Button *transform_button_flip_h = nullptr; Button *transform_button_flip_v = nullptr; + SwitchSeparator *transform_separator = nullptr; - VSeparator *tools_settings_vsep_2 = nullptr; CheckBox *bucket_contiguous_checkbox = nullptr; Button *random_tile_toggle = nullptr; - HBoxContainer *scatter_controls_container = nullptr; + BoxContainer *scatter_controls_container = nullptr; float scattering = 0.0; Label *scatter_label = nullptr; SpinBox *scatter_spinbox = nullptr; @@ -174,6 +191,8 @@ private: void patterns_item_list_empty_clicked(const Vector2 &p_pos, MouseButton p_mouse_button_index); ///// Bottom panel common //// + BoxContainer *split_container_left_side = nullptr; + void _tab_changed(); ///// Bottom panel tiles //// @@ -192,7 +211,7 @@ private: // Atlas sources. TileMapCell hovered_tile; TileAtlasView *tile_atlas_view = nullptr; - HSplitContainer *atlas_sources_split_container = nullptr; + SplitContainer *atlas_sources_split_container = nullptr; bool tile_set_dragging_selection = false; Vector2i tile_set_drag_start_mouse_pos; @@ -241,6 +260,7 @@ public: virtual Vector get_tabs() const override; virtual bool forward_canvas_gui_input(const Ref &p_event) override; virtual void forward_canvas_draw_over_viewport(Control *p_overlay) override; + virtual void update_layout(EditorDock::DockLayout p_layout) override; virtual void edit(ObjectID p_tile_map_layer_id) override; @@ -252,26 +272,27 @@ class TileMapLayerEditorTerrainsPlugin : public TileMapLayerSubEditorPlugin { private: // Toolbar. - HBoxContainer *toolbar = nullptr; + HBoxContainer *wide_toolbar = nullptr; + BoxContainer *tilemap_tiles_tools_buttons = nullptr; Ref tool_buttons_group; Button *paint_tool_button = nullptr; Button *line_tool_button = nullptr; Button *rect_tool_button = nullptr; Button *bucket_tool_button = nullptr; - HBoxContainer *tools_settings = nullptr; + BoxContainer *tools_settings = nullptr; - VSeparator *tools_settings_vsep = nullptr; + SwitchSeparator *tools_settings_vsep = nullptr; Button *picker_button = nullptr; Button *erase_button = nullptr; - VSeparator *tools_settings_vsep_2 = nullptr; CheckBox *bucket_contiguous_checkbox = nullptr; void _update_toolbar(); // Main vbox. - VBoxContainer *main_vbox_container = nullptr; + BoxContainer *main_box_container = nullptr; + SplitContainer *tilemap_tab_terrains = nullptr; // TileMap editing. bool has_mouse = false; @@ -332,6 +353,7 @@ public: virtual Vector get_tabs() const override; virtual bool forward_canvas_gui_input(const Ref &p_event) override; virtual void forward_canvas_draw_over_viewport(Control *p_overlay) override; + virtual void update_layout(EditorDock::DockLayout p_layout) override; virtual void edit(ObjectID p_tile_map_layer_id) override; @@ -360,11 +382,15 @@ private: Vector tile_map_editor_plugins; // Toolbar. - HFlowContainer *tile_map_toolbar = nullptr; + GridContainer *main_box_container = nullptr; + VBoxContainer *tile_map_wide_toolbar = nullptr; + FlowContainer *tile_map_toolbar = nullptr; + Control *padding_control = nullptr; + SwitchSeparator *layer_selector_separator = nullptr; bool show_layers_selector = false; - HBoxContainer *layer_selection_hbox = nullptr; + BoxContainer *layer_selection_hbox = nullptr; Button *select_previous_layer = nullptr; void _select_previous_layer_pressed(); Button *select_next_layer = nullptr; @@ -414,6 +440,7 @@ private: protected: void _notification(int p_what); void _draw_shape(Control *p_control, Rect2 p_region, TileSet::TileShape p_shape, TileSet::TileOffsetAxis p_offset_axis, Color p_color); + virtual void update_layout(DockLayout p_layout) override; public: bool forward_canvas_gui_input(const Ref &p_event); diff --git a/editor/scene/2d/tiles/tiles_editor_plugin.cpp b/editor/scene/2d/tiles/tiles_editor_plugin.cpp index d7ea5a19d80..0b3d6eb32ae 100644 --- a/editor/scene/2d/tiles/tiles_editor_plugin.cpp +++ b/editor/scene/2d/tiles/tiles_editor_plugin.cpp @@ -37,7 +37,6 @@ #include "editor/editor_interface.h" #include "editor/editor_node.h" #include "editor/editor_string_names.h" -#include "editor/gui/editor_bottom_panel.h" #include "editor/inspector/multi_node_edit.h" #include "editor/scene/canvas_item_editor_plugin.h" #include "editor/settings/editor_command_palette.h" @@ -483,6 +482,7 @@ void TileMapEditorPlugin::make_visible(bool p_visible) { editor->open(); } else { editor->close(); + TileSetEditor::get_singleton()->close(); } }