Skip to content

Commit

Permalink
Highlight context menu items at the top of the 2D/3D viewports
Browse files Browse the repository at this point in the history
This makes it easier to notice that some menu items only appear when
specific nodes are selected.

This change applies to both 2D and 3D editors, including both plugin-based
menus and the hardcoded 2D layout/animation contextual menus.
  • Loading branch information
Calinou committed Jul 27, 2021
1 parent b477808 commit 81d2d2b
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 7 deletions.
40 changes: 35 additions & 5 deletions editor/plugins/canvas_item_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3853,7 +3853,10 @@ void CanvasItemEditor::_notification(int p_what) {
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_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons")));

_update_context_menu_stylebox();

presets_menu->set_icon(get_theme_icon(SNAME("ControlLayout"), SNAME("EditorIcons")));

PopupMenu *p = presets_menu->get_popup();

p->clear();
Expand Down Expand Up @@ -3954,6 +3957,18 @@ void CanvasItemEditor::edit(CanvasItem *p_canvas_item) {
}
}

void CanvasItemEditor::_update_context_menu_stylebox() {
// This must be called when the theme changes to follow the new accent color.
Ref<StyleBoxFlat> context_menu_stylebox = memnew(StyleBoxFlat);
const Color accent_color = EditorNode::get_singleton()->get_gui_base()->get_theme_color("accent_color", "Editor");
context_menu_stylebox->set_bg_color(accent_color * Color(1, 1, 1, 0.1));
// Add an underline to the StyleBox, but prevent its minimum vertical size from changing.
context_menu_stylebox->set_border_color(accent_color);
context_menu_stylebox->set_border_width(SIDE_BOTTOM, Math::round(2 * EDSCALE));
context_menu_stylebox->set_default_margin(SIDE_BOTTOM, 0);
context_menu_container->add_theme_style_override("panel", context_menu_stylebox);
}

void CanvasItemEditor::_update_scrollbars() {
updating_scroll = true;

Expand Down Expand Up @@ -5127,11 +5142,11 @@ void CanvasItemEditor::remove_control_from_info_overlay(Control *p_control) {
void CanvasItemEditor::add_control_to_menu_panel(Control *p_control) {
ERR_FAIL_COND(!p_control);

hb->add_child(p_control);
hbc_context_menu->add_child(p_control);
}

void CanvasItemEditor::remove_control_from_menu_panel(Control *p_control) {
hb->remove_child(p_control);
hbc_context_menu->remove_child(p_control);
}

HSplitContainer *CanvasItemEditor::get_palette_split() {
Expand Down Expand Up @@ -5516,10 +5531,21 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
p->add_separator();
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/preview_canvas_scale", TTR("Preview Canvas Scale"), KEY_MASK_SHIFT | KEY_MASK_CMD | KEY_P), PREVIEW_CANVAS_SCALE);

hb->add_child(memnew(VSeparator));

context_menu_container = memnew(PanelContainer);
hbc_context_menu = memnew(HBoxContainer);
context_menu_container->add_child(hbc_context_menu);
// Use a custom stylebox to make contextual menu items stand out from the rest.
// This helps with editor usability as contextual menu items change when selecting nodes,
// even though it may not be immediately obvious at first.
hb->add_child(context_menu_container);
_update_context_menu_stylebox();

presets_menu = memnew(MenuButton);
presets_menu->set_shortcut_context(this);
presets_menu->set_text(TTR("Layout"));
hb->add_child(presets_menu);
hbc_context_menu->add_child(presets_menu);
presets_menu->hide();
presets_menu->set_switch_on_hover(true);

Expand All @@ -5533,17 +5559,18 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {

anchor_mode_button = memnew(Button);
anchor_mode_button->set_flat(true);
hb->add_child(anchor_mode_button);
hbc_context_menu->add_child(anchor_mode_button);
anchor_mode_button->set_toggle_mode(true);
anchor_mode_button->hide();
anchor_mode_button->connect("toggled", callable_mp(this, &CanvasItemEditor::_button_toggle_anchor_mode));

animation_hb = memnew(HBoxContainer);
hb->add_child(animation_hb);
hbc_context_menu->add_child(animation_hb);
animation_hb->add_child(memnew(VSeparator));
animation_hb->hide();

key_loc_button = memnew(Button);
key_loc_button->set_flat(true);
key_loc_button->set_toggle_mode(true);
key_loc_button->set_pressed(true);
key_loc_button->set_focus_mode(FOCUS_NONE);
Expand All @@ -5552,6 +5579,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
animation_hb->add_child(key_loc_button);

key_rot_button = memnew(Button);
key_rot_button->set_flat(true);
key_rot_button->set_toggle_mode(true);
key_rot_button->set_pressed(true);
key_rot_button->set_focus_mode(FOCUS_NONE);
Expand All @@ -5560,13 +5588,15 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
animation_hb->add_child(key_rot_button);

key_scale_button = memnew(Button);
key_scale_button->set_flat(true);
key_scale_button->set_toggle_mode(true);
key_scale_button->set_focus_mode(FOCUS_NONE);
key_scale_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback), varray(ANIM_INSERT_SCALE));
key_scale_button->set_tooltip(TTR("Scale mask for inserting keys."));
animation_hb->add_child(key_scale_button);

key_insert_button = memnew(Button);
key_insert_button->set_flat(true);
key_insert_button->set_focus_mode(FOCUS_NONE);
key_insert_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_popup_callback), varray(ANIM_INSERT_KEY));
key_insert_button->set_tooltip(TTR("Insert keys (based on mask)."));
Expand Down
5 changes: 5 additions & 0 deletions editor/plugins/canvas_item_editor_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,10 @@ class CanvasItemEditor : public VBoxContainer {
HScrollBar *h_scroll;
VScrollBar *v_scroll;
HBoxContainer *hb;
// Used for secondary menu items which are displayed depending on the currently selected node
// (such as MeshInstance's "Mesh" menu).
PanelContainer *context_menu_container;
HBoxContainer *hbc_context_menu;

Map<Control *, Timer *> popup_temporarily_timers;

Expand Down Expand Up @@ -535,6 +539,7 @@ class CanvasItemEditor : public VBoxContainer {
HSplitContainer *palette_split;
VSplitContainer *bottom_split;

void _update_context_menu_stylebox();
void _popup_warning_temporarily(Control *p_control, const float p_duration);
void _popup_warning_depop(Control *p_control);

Expand Down
28 changes: 26 additions & 2 deletions editor/plugins/node_3d_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5963,6 +5963,18 @@ void fragment() {
_generate_selection_boxes();
}

void Node3DEditor::_update_context_menu_stylebox() {
// This must be called when the theme changes to follow the new accent color.
Ref<StyleBoxFlat> context_menu_stylebox = memnew(StyleBoxFlat);
const Color accent_color = EditorNode::get_singleton()->get_gui_base()->get_theme_color("accent_color", "Editor");
context_menu_stylebox->set_bg_color(accent_color * Color(1, 1, 1, 0.1));
// Add an underline to the StyleBox, but prevent its minimum vertical size from changing.
context_menu_stylebox->set_border_color(accent_color);
context_menu_stylebox->set_border_width(SIDE_BOTTOM, Math::round(2 * EDSCALE));
context_menu_stylebox->set_default_margin(SIDE_BOTTOM, 0);
context_menu_container->add_theme_style_override("panel", context_menu_stylebox);
}

void Node3DEditor::_update_gizmos_menu() {
gizmos_menu->clear();

Expand Down Expand Up @@ -6530,6 +6542,7 @@ void Node3DEditor::_notification(int p_what) {
case NOTIFICATION_THEME_CHANGED: {
_update_theme();
_update_gizmos_menu_theme();
_update_context_menu_stylebox();
sun_title->add_theme_font_override("font", get_theme_font(SNAME("title_font"), SNAME("Window")));
environ_title->add_theme_font_override("font", get_theme_font(SNAME("title_font"), SNAME("Window")));
} break;
Expand Down Expand Up @@ -6578,11 +6591,11 @@ Vector<int> Node3DEditor::get_subgizmo_selection() {
}

void Node3DEditor::add_control_to_menu_panel(Control *p_control) {
hbc_menu->add_child(p_control);
hbc_context_menu->add_child(p_control);
}

void Node3DEditor::remove_control_from_menu_panel(Control *p_control) {
hbc_menu->remove_child(p_control);
hbc_context_menu->remove_child(p_control);
}

void Node3DEditor::set_can_preview(Camera3D *p_preview) {
Expand Down Expand Up @@ -7165,6 +7178,17 @@ Node3DEditor::Node3DEditor(EditorNode *p_editor) {
view_menu->set_shortcut_context(this);
hbc_menu->add_child(view_menu);

hbc_menu->add_child(memnew(VSeparator));

context_menu_container = memnew(PanelContainer);
hbc_context_menu = memnew(HBoxContainer);
context_menu_container->add_child(hbc_context_menu);
// Use a custom stylebox to make contextual menu items stand out from the rest.
// This helps with editor usability as contextual menu items change when selecting nodes,
// even though it may not be immediately obvious at first.
hbc_menu->add_child(context_menu_container);
_update_context_menu_stylebox();

p = view_menu->get_popup();

accept = memnew(AcceptDialog);
Expand Down
5 changes: 5 additions & 0 deletions editor/plugins/node_3d_editor_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -625,13 +625,18 @@ class Node3DEditor : public VBoxContainer {
void _update_camera_override_viewport(Object *p_viewport);

HBoxContainer *hbc_menu;
// Used for secondary menu items which are displayed depending on the currently selected node
// (such as MeshInstance's "Mesh" menu).
PanelContainer *context_menu_container;
HBoxContainer *hbc_context_menu;

void _generate_selection_boxes();
UndoRedo *undo_redo;

int camera_override_viewport_id;

void _init_indicators();
void _update_context_menu_stylebox();
void _update_gizmos_menu();
void _update_gizmos_menu_theme();
void _init_grid();
Expand Down

0 comments on commit 81d2d2b

Please sign in to comment.