Skip to content

Commit

Permalink
Improve the looks of 2D/3D viewport contextual toolbars
Browse files Browse the repository at this point in the history
  • Loading branch information
YuriSizov committed Sep 13, 2023
1 parent 221884e commit f542dff
Show file tree
Hide file tree
Showing 17 changed files with 152 additions and 107 deletions.
3 changes: 1 addition & 2 deletions editor/editor_themes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -844,13 +844,12 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// even though it may not be immediately obvious at first.
Ref<StyleBoxFlat> toolbar_stylebox = memnew(StyleBoxFlat);
toolbar_stylebox->set_bg_color(accent_color * Color(1, 1, 1, 0.1));
toolbar_stylebox->set_corner_radius(CORNER_TOP_LEFT, corner_radius * EDSCALE);
toolbar_stylebox->set_corner_radius(CORNER_TOP_RIGHT, corner_radius * EDSCALE);
toolbar_stylebox->set_anti_aliased(false);
// Add an underline to the StyleBox, but prevent its minimum vertical size from changing.
toolbar_stylebox->set_border_color(accent_color);
toolbar_stylebox->set_border_width(SIDE_BOTTOM, Math::round(2 * EDSCALE));
toolbar_stylebox->set_content_margin(SIDE_BOTTOM, 0);
toolbar_stylebox->set_expand_margin_all(2 * EDSCALE);
theme->set_stylebox("ContextualToolbar", EditorStringName(EditorStyles), toolbar_stylebox);

// Script Editor
Expand Down
1 change: 0 additions & 1 deletion editor/plugins/abstract_polygon_2d_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -725,7 +725,6 @@ AbstractPolygon2DEditor::AbstractPolygon2DEditor(bool p_wip_destructive) {
selected_point = Vertex();
edge_point = PosVertex();

add_child(memnew(VSeparator));
button_create = memnew(Button);
button_create->set_flat(true);
add_child(button_create);
Expand Down
74 changes: 56 additions & 18 deletions editor/plugins/canvas_item_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3888,7 +3888,7 @@ void CanvasItemEditor::_update_editor_settings() {
key_auto_insert_button->add_theme_color_override("icon_pressed_color", key_auto_color.lerp(Color(1, 0, 0), 0.55));
animation_menu->set_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl")));

context_menu_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("ContextualToolbar"), EditorStringName(EditorStyles)));
context_toolbar_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("ContextualToolbar"), EditorStringName(EditorStyles)));

panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/2d_editor_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EDITOR_GET("editors/panning/simple_panning")));
panner->set_scroll_speed(EDITOR_GET("editors/panning/2d_editor_pan_speed"));
Expand Down Expand Up @@ -4941,13 +4941,51 @@ void CanvasItemEditor::clear() {
}

void CanvasItemEditor::add_control_to_menu_panel(Control *p_control) {
ERR_FAIL_COND(!p_control);
ERR_FAIL_NULL(p_control);
ERR_FAIL_COND(p_control->get_parent());

context_menu_hbox->add_child(p_control);
VSeparator *sep = memnew(VSeparator);
context_toolbar_hbox->add_child(sep);
context_toolbar_hbox->add_child(p_control);
context_toolbar_separators[p_control] = sep;

p_control->connect("visibility_changed", callable_mp(this, &CanvasItemEditor::_update_context_toolbar));

_update_context_toolbar();
}

void CanvasItemEditor::remove_control_from_menu_panel(Control *p_control) {
context_menu_hbox->remove_child(p_control);
ERR_FAIL_NULL(p_control);
ERR_FAIL_COND(p_control->get_parent() != context_toolbar_hbox);

p_control->disconnect("visibility_changed", callable_mp(this, &CanvasItemEditor::_update_context_toolbar));

context_toolbar_hbox->remove_child(context_toolbar_separators[p_control]);
context_toolbar_hbox->remove_child(p_control);
context_toolbar_separators.erase(p_control);

_update_context_toolbar();
}

void CanvasItemEditor::_update_context_toolbar() {
bool has_visible = false;
bool first_visible = false;

for (int i = 0; i < context_toolbar_hbox->get_child_count(); i++) {
Control *child = Object::cast_to<Control>(context_toolbar_hbox->get_child(i));
if (!child || !context_toolbar_separators.has(child)) {
continue;
}
if (child->is_visible()) {
first_visible = !has_visible;
has_visible = true;
}

VSeparator *sep = context_toolbar_separators[child];
sep->set_visible(!first_visible && child->is_visible());
}

context_toolbar_panel->set_visible(has_visible);
}

void CanvasItemEditor::add_control_to_left_panel(Control *p_control) {
Expand Down Expand Up @@ -4997,9 +5035,17 @@ CanvasItemEditor::CanvasItemEditor() {
EditorRunBar::get_singleton()->call_deferred(SNAME("connect"), "play_pressed", callable_mp(this, &CanvasItemEditor::_update_override_camera_button).bind(true));
EditorRunBar::get_singleton()->call_deferred(SNAME("connect"), "stop_pressed", callable_mp(this, &CanvasItemEditor::_update_override_camera_button).bind(false));

// Add some margin to the sides for better aesthetics.
// This prevents the first button's hover/pressed effect from "touching" the panel's border,
// which looks ugly.
MarginContainer *toolbar_margin = memnew(MarginContainer);
toolbar_margin->add_theme_constant_override("margin_left", 4 * EDSCALE);
toolbar_margin->add_theme_constant_override("margin_right", 4 * EDSCALE);
add_child(toolbar_margin);

// A fluid container for all toolbars.
HFlowContainer *main_flow = memnew(HFlowContainer);
add_child(main_flow);
toolbar_margin->add_child(main_flow);

// Main toolbars.
HBoxContainer *main_menu_hbox = memnew(HBoxContainer);
Expand Down Expand Up @@ -5107,13 +5153,6 @@ CanvasItemEditor::CanvasItemEditor() {

viewport->add_child(controls_vb);

// Add some margin to the left for better esthetics.
// This prevents the first button's hover/pressed effect from "touching" the panel's border,
// which looks ugly.
Control *margin_left = memnew(Control);
main_menu_hbox->add_child(margin_left);
margin_left->set_custom_minimum_size(Size2(2, 0) * EDSCALE);

select_button = memnew(Button);
select_button->set_flat(true);
main_menu_hbox->add_child(select_button);
Expand Down Expand Up @@ -5355,15 +5394,14 @@ CanvasItemEditor::CanvasItemEditor() {
main_menu_hbox->add_child(memnew(VSeparator));

// Contextual toolbars.
context_menu_panel = memnew(PanelContainer);
context_menu_hbox = memnew(HBoxContainer);
context_menu_panel->add_child(context_menu_hbox);
main_flow->add_child(context_menu_panel);
context_toolbar_panel = memnew(PanelContainer);
context_toolbar_hbox = memnew(HBoxContainer);
context_toolbar_panel->add_child(context_toolbar_hbox);
main_flow->add_child(context_toolbar_panel);

// Animation controls.
animation_hb = memnew(HBoxContainer);
context_menu_hbox->add_child(animation_hb);
animation_hb->add_child(memnew(VSeparator));
add_control_to_menu_panel(animation_hb);
animation_hb->hide();

key_loc_button = memnew(Button);
Expand Down
9 changes: 7 additions & 2 deletions editor/plugins/canvas_item_editor_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class PanelContainer;
class StyleBoxTexture;
class ViewPanner;
class VScrollBar;
class VSeparator;
class VSplitContainer;

class CanvasItemEditorSelectedItem : public Object {
Expand Down Expand Up @@ -192,10 +193,14 @@ class CanvasItemEditor : public VBoxContainer {

HScrollBar *h_scroll = nullptr;
VScrollBar *v_scroll = nullptr;

// Used for secondary menu items which are displayed depending on the currently selected node
// (such as MeshInstance's "Mesh" menu).
PanelContainer *context_menu_panel = nullptr;
HBoxContainer *context_menu_hbox = nullptr;
PanelContainer *context_toolbar_panel = nullptr;
HBoxContainer *context_toolbar_hbox = nullptr;
HashMap<Control *, VSeparator *> context_toolbar_separators;

void _update_context_toolbar();

Transform2D transform;
GridVisibility grid_visibility = GRID_VISIBILITY_SHOW_WHEN_SNAPPING;
Expand Down
2 changes: 0 additions & 2 deletions editor/plugins/control_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -976,8 +976,6 @@ void ControlEditorToolbar::_notification(int p_what) {
}

ControlEditorToolbar::ControlEditorToolbar() {
add_child(memnew(VSeparator));

// Anchor and offset tools.
anchors_button = memnew(ControlEditorPopupButton);
anchors_button->set_tooltip_text(TTR("Presets for the anchor and offset values of a Control node."));
Expand Down
2 changes: 0 additions & 2 deletions editor/plugins/cpu_particles_2d_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,8 +267,6 @@ CPUParticles2DEditorPlugin::CPUParticles2DEditorPlugin() {
add_control_to_container(CONTAINER_CANVAS_EDITOR_MENU, toolbar);
toolbar->hide();

toolbar->add_child(memnew(VSeparator));

menu = memnew(MenuButton);
menu->get_popup()->add_item(TTR("Restart"), MENU_RESTART);
menu->get_popup()->add_item(TTR("Load Emission Mask"), MENU_LOAD_EMISSION_MASK);
Expand Down
2 changes: 0 additions & 2 deletions editor/plugins/gpu_particles_2d_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -369,8 +369,6 @@ GPUParticles2DEditorPlugin::GPUParticles2DEditorPlugin() {
add_control_to_container(CONTAINER_CANVAS_EDITOR_MENU, toolbar);
toolbar->hide();

toolbar->add_child(memnew(VSeparator));

menu = memnew(MenuButton);
menu->get_popup()->add_item(TTR("Restart"), MENU_RESTART);
menu->get_popup()->add_item(TTR("Generate Visibility Rect"), MENU_GENERATE_VISIBILITY_RECT);
Expand Down
1 change: 0 additions & 1 deletion editor/plugins/navigation_obstacle_3d_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,6 @@ void NavigationObstacle3DEditor::_bind_methods() {
NavigationObstacle3DEditor::NavigationObstacle3DEditor() {
obstacle_node = nullptr;

add_child(memnew(VSeparator));
button_create = memnew(Button);
button_create->set_flat(true);
add_child(button_create);
Expand Down
71 changes: 56 additions & 15 deletions editor/plugins/node_3d_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7581,7 +7581,7 @@ void Node3DEditor::_update_theme() {
environ_sky_color->set_custom_minimum_size(Size2(0, get_theme_constant(SNAME("color_picker_button_height"), EditorStringName(Editor))));
environ_ground_color->set_custom_minimum_size(Size2(0, get_theme_constant(SNAME("color_picker_button_height"), EditorStringName(Editor))));

context_menu_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("ContextualToolbar"), EditorStringName(EditorStyles)));
context_toolbar_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("ContextualToolbar"), EditorStringName(EditorStyles)));
}

void Node3DEditor::_notification(int p_what) {
Expand Down Expand Up @@ -7679,11 +7679,51 @@ Vector<int> Node3DEditor::get_subgizmo_selection() {
}

void Node3DEditor::add_control_to_menu_panel(Control *p_control) {
context_menu_hbox->add_child(p_control);
ERR_FAIL_NULL(p_control);
ERR_FAIL_COND(p_control->get_parent());

VSeparator *sep = memnew(VSeparator);
context_toolbar_hbox->add_child(sep);
context_toolbar_hbox->add_child(p_control);
context_toolbar_separators[p_control] = sep;

p_control->connect("visibility_changed", callable_mp(this, &Node3DEditor::_update_context_toolbar));

_update_context_toolbar();
}

void Node3DEditor::remove_control_from_menu_panel(Control *p_control) {
context_menu_hbox->remove_child(p_control);
ERR_FAIL_NULL(p_control);
ERR_FAIL_COND(p_control->get_parent() != context_toolbar_hbox);

p_control->disconnect("visibility_changed", callable_mp(this, &Node3DEditor::_update_context_toolbar));

context_toolbar_hbox->remove_child(context_toolbar_separators[p_control]);
context_toolbar_hbox->remove_child(p_control);
context_toolbar_separators.erase(p_control);

_update_context_toolbar();
}

void Node3DEditor::_update_context_toolbar() {
bool has_visible = false;
bool first_visible = false;

for (int i = 0; i < context_toolbar_hbox->get_child_count(); i++) {
Control *child = Object::cast_to<Control>(context_toolbar_hbox->get_child(i));
if (!child || !context_toolbar_separators.has(child)) {
continue;
}
if (child->is_visible()) {
first_visible = !has_visible;
has_visible = true;
}

VSeparator *sep = context_toolbar_separators[child];
sep->set_visible(!first_visible && child->is_visible());
}

context_toolbar_panel->set_visible(has_visible);
}

void Node3DEditor::set_can_preview(Camera3D *p_preview) {
Expand Down Expand Up @@ -8161,23 +8201,24 @@ Node3DEditor::Node3DEditor() {

camera_override_viewport_id = 0;

// Add some margin to the sides for better aesthetics.
// This prevents the first button's hover/pressed effect from "touching" the panel's border,
// which looks ugly.
MarginContainer *toolbar_margin = memnew(MarginContainer);
toolbar_margin->add_theme_constant_override("margin_left", 4 * EDSCALE);
toolbar_margin->add_theme_constant_override("margin_right", 4 * EDSCALE);
vbc->add_child(toolbar_margin);

// A fluid container for all toolbars.
HFlowContainer *main_flow = memnew(HFlowContainer);
vbc->add_child(main_flow);
toolbar_margin->add_child(main_flow);

// Main toolbars.
HBoxContainer *main_menu_hbox = memnew(HBoxContainer);
main_flow->add_child(main_menu_hbox);

String sct;

// Add some margin to the left for better esthetics.
// This prevents the first button's hover/pressed effect from "touching" the panel's border,
// which looks ugly.
Control *margin_left = memnew(Control);
main_menu_hbox->add_child(margin_left);
margin_left->set_custom_minimum_size(Size2(2, 0) * EDSCALE);

tool_button[TOOL_MODE_SELECT] = memnew(Button);
main_menu_hbox->add_child(tool_button[TOOL_MODE_SELECT]);
tool_button[TOOL_MODE_SELECT]->set_toggle_mode(true);
Expand Down Expand Up @@ -8365,10 +8406,10 @@ Node3DEditor::Node3DEditor() {

main_menu_hbox->add_child(memnew(VSeparator));

context_menu_panel = memnew(PanelContainer);
context_menu_hbox = memnew(HBoxContainer);
context_menu_panel->add_child(context_menu_hbox);
main_flow->add_child(context_menu_panel);
context_toolbar_panel = memnew(PanelContainer);
context_toolbar_hbox = memnew(HBoxContainer);
context_toolbar_panel->add_child(context_toolbar_hbox);
main_flow->add_child(context_toolbar_panel);

// Get the view menu popup and have it stay open when a checkable item is selected
p = view_menu->get_popup();
Expand Down
10 changes: 7 additions & 3 deletions editor/plugins/node_3d_editor_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,10 @@ class PanelContainer;
class ProceduralSkyMaterial;
class SubViewport;
class SubViewportContainer;
class VSeparator;
class VSplitContainer;
class WorldEnvironment;
class ViewportNavigationControl;
class WorldEnvironment;

class ViewportRotationControl : public Control {
GDCLASS(ViewportRotationControl, Control);
Expand Down Expand Up @@ -715,8 +716,11 @@ class Node3DEditor : public VBoxContainer {
void _update_camera_override_viewport(Object *p_viewport);
// Used for secondary menu items which are displayed depending on the currently selected node
// (such as MeshInstance's "Mesh" menu).
PanelContainer *context_menu_panel = nullptr;
HBoxContainer *context_menu_hbox = nullptr;
PanelContainer *context_toolbar_panel = nullptr;
HBoxContainer *context_toolbar_hbox = nullptr;
HashMap<Control *, VSeparator *> context_toolbar_separators;

void _update_context_toolbar();

void _generate_selection_boxes();

Expand Down
Loading

0 comments on commit f542dff

Please sign in to comment.