Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions editor/docks/dock_tab_container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "editor/editor_string_names.h"
#include "editor/settings/editor_settings.h"
#include "editor/themes/editor_scale.h"
#include "scene/gui/button.h"
#include "scene/resources/style_box_flat.h"

bool EditorDockDragHint::can_drop_data(const Point2 &p_point, const Variant &p_data) const {
Expand Down Expand Up @@ -222,6 +223,10 @@ void DockTabContainer::load_selected_tab(int p_idx) {
void DockTabContainer::set_dock_context_popup(DockContextPopup *p_popup) {
dock_context_popup = p_popup;
set_popup(dock_context_popup);
Button *btn = get_popup_button();
if (btn) {
btn->set_accessibility_name(TTRC("Dock Position"));
}
}

void DockTabContainer::move_dock_index(EditorDock *p_dock, int p_to_index, bool p_set_current) {
Expand Down
163 changes: 162 additions & 1 deletion editor/docks/editor_dock_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include "scene/gui/split_container.h"
#include "scene/gui/tab_container.h"
#include "scene/main/window.h"
#include "servers/display/accessibility_server.h"
#include "servers/display/display_server.h"

////////////////////////////////////////////////
Expand Down Expand Up @@ -939,8 +940,10 @@ DockContextPopup::DockContextPopup() {
dock_select_popup_vb->add_child(header_hb);

dock_select = memnew(DockSlotGrid);
dock_select->set_accessibility_name(TTRC("Slot Selector"));
dock_select_popup_vb->add_child(dock_select);
dock_select->connect("slot_clicked", callable_mp(this, &DockContextPopup::_slot_clicked));
dock_select->set_focus_mode(Control::FOCUS_ACCESSIBILITY);

Control *separator = memnew(Control);
separator->set_custom_minimum_size(Vector2(0, 8 * EDSCALE));
Expand Down Expand Up @@ -1014,12 +1017,107 @@ void DockSlotGrid::_bind_methods() {
ADD_SIGNAL(MethodInfo("slot_clicked", PropertyInfo(Variant::INT, "slot")));
}

void DockSlotGrid::_slot_action_click(int p_idx) {
ERR_FAIL_INDEX(p_idx, EditorDock::DOCK_SLOT_MAX);

DockTabContainer *target_tab_container = EditorDockManager::get_singleton()->dock_slots[p_idx];
if (context_dock->get_parent_container() == target_tab_container) {
return;
}

if (!(context_dock->available_layouts & target_tab_container->layout)) {
return;
}

emit_signal("slot_clicked", p_idx);
}

RID DockSlotGrid::get_focused_accessibility_element() const {
if (selected_slot > -1) {
return ac_element[selected_slot];
} else {
return get_accessibility_element();
}
}

String DockSlotGrid::_get_slot_name(int p_idx) const {
String slot_name;
switch (p_idx) {
case EditorDock::DockSlot::DOCK_SLOT_LEFT_UL: {
slot_name = TTRC("Left side, upper left slot");
} break;
case EditorDock::DockSlot::DOCK_SLOT_LEFT_BL: {
slot_name = TTRC("Left side, bottom left slot");
} break;
case EditorDock::DockSlot::DOCK_SLOT_LEFT_UR: {
slot_name = TTRC("Left side, upper right slot");
} break;
case EditorDock::DockSlot::DOCK_SLOT_LEFT_BR: {
slot_name = TTRC("Left side, bottom right slot");
} break;
case EditorDock::DockSlot::DOCK_SLOT_RIGHT_UL: {
slot_name = TTRC("Right side, upper left slot");
} break;
case EditorDock::DockSlot::DOCK_SLOT_RIGHT_BL: {
slot_name = TTRC("Right side, bottom left slot");
} break;
case EditorDock::DockSlot::DOCK_SLOT_RIGHT_UR: {
slot_name = TTRC("Right side, upper right slot");
} break;
case EditorDock::DockSlot::DOCK_SLOT_RIGHT_BR: {
slot_name = TTRC("Right side, bottom right slot");
} break;
case EditorDock::DockSlot::DOCK_SLOT_BOTTOM: {
slot_name = TTRC("Bottom slot");
} break;
case EditorDock::DockSlot::DOCK_SLOT_BOTTOM_L: {
slot_name = TTRC("Bottom left slot");
} break;
case EditorDock::DockSlot::DOCK_SLOT_BOTTOM_R: {
slot_name = TTRC("Bottom right slot");
} break;
default: {
slot_name = vformat(TTRC("Slot %d"), p_idx + 1);
} break;
}
return slot_name;
}

void DockSlotGrid::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_LAYOUT_DIRECTION_CHANGED:
case NOTIFICATION_TRANSLATION_CHANGED: {
rect_cache_dirty = true;
} break;
case NOTIFICATION_ACCESSIBILITY_INVALIDATE: {
for (int i = 0; i < EditorDock::DOCK_SLOT_MAX; i++) {
ac_element[i] = RID();
}
} break;

case NOTIFICATION_ACCESSIBILITY_UPDATE: {
RID ae = get_accessibility_element();
ERR_FAIL_COND(ae.is_null());

if (rect_cache_dirty) {
_update_rect_cache();
rect_cache_dirty = false;
}

for (int i = 0; i < EditorDock::DOCK_SLOT_MAX; i++) {
if (ac_element[i].is_null()) {
ac_element[i] = AccessibilityServer::get_singleton()->create_sub_element(ae, AccessibilityServerEnums::AccessibilityRole::ROLE_BUTTON);
}
DockTabContainer *target_tab_container = EditorDockManager::get_singleton()->dock_slots[i];
String slot_name = _get_slot_name(target_tab_container->dock_slot);

AccessibilityServer::get_singleton()->update_add_action(ac_element[i], AccessibilityServerEnums::AccessibilityAction::ACTION_CLICK, callable_mp(this, &DockSlotGrid::_slot_action_click).bind(i));
AccessibilityServer::get_singleton()->update_set_description(ac_element[i], vformat(TTR("This slot has %d tabs."), target_tab_container->get_tab_count()));
AccessibilityServer::get_singleton()->update_set_name(ac_element[i], atr(slot_name));
AccessibilityServer::get_singleton()->update_set_bounds(ac_element[i], rect_cache[i]);
}
AccessibilityServer::get_singleton()->update_set_description(ae, vformat(TTR("Dock currently is in the %s."), atr(_get_slot_name(context_dock->dock_slot_index))));
} break;

case NOTIFICATION_DRAW: {
if (rect_cache_dirty) {
Expand Down Expand Up @@ -1055,7 +1153,7 @@ void DockSlotGrid::_notification(int p_what) {
draw_rect(slot_rect, tab_selected_color);
} else if (!is_slot_available) {
draw_rect(slot_rect, unusable_dock_color);
} else if (i == hovered_slot) {
} else if (i == hovered_slot || i == selected_slot) {
draw_rect(slot_rect, hovered_dock_color);
} else if (tabs_to_draw == 0) {
draw_rect(slot_rect, unused_dock_color);
Expand Down Expand Up @@ -1087,6 +1185,19 @@ void DockSlotGrid::_notification(int p_what) {
if (hovered_slot > -1) {
hovered_slot = -1;
queue_redraw();
queue_accessibility_update();
}
} break;
case NOTIFICATION_FOCUS_ENTER: {
selected_slot = -1;
queue_redraw();
queue_accessibility_update();
} break;
case NOTIFICATION_FOCUS_EXIT: {
if (selected_slot > -1) {
selected_slot = -1;
queue_redraw();
queue_accessibility_update();
}
} break;
}
Expand All @@ -1107,6 +1218,7 @@ void DockSlotGrid::gui_input(const Ref<InputEvent> &p_event) {

if (over_dock_slot != hovered_slot) {
queue_redraw();
queue_accessibility_update();
hovered_slot = over_dock_slot;
}

Expand All @@ -1127,6 +1239,55 @@ void DockSlotGrid::gui_input(const Ref<InputEvent> &p_event) {
if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && mb->is_pressed()) {
emit_signal("slot_clicked", over_dock_slot);
}
} else if ((p_event->is_action("ui_up", true) || p_event->is_action("ui_left", true)) && p_event->is_pressed()) {
int start_slot = (selected_slot > -1) ? selected_slot : 0;
do {
selected_slot--;
if (selected_slot < 0) {
selected_slot = EditorDock::DOCK_SLOT_MAX - 1;
}
DockTabContainer *target_tab_container = EditorDockManager::get_singleton()->dock_slots[selected_slot];
if (context_dock->get_parent_container() == target_tab_container) {
continue;
}
if (!(context_dock->available_layouts & target_tab_container->layout)) {
continue;
}
break;
} while (selected_slot != start_slot);
queue_redraw();
accept_event();
queue_accessibility_update();
} else if ((p_event->is_action("ui_down", true) || p_event->is_action("ui_right", true)) && p_event->is_pressed()) {
int start_slot = (selected_slot > -1) ? selected_slot : EditorDock::DOCK_SLOT_MAX - 1;
do {
selected_slot++;
if (selected_slot >= EditorDock::DOCK_SLOT_MAX) {
selected_slot = 0;
}
DockTabContainer *target_tab_container = EditorDockManager::get_singleton()->dock_slots[selected_slot];
if (context_dock->get_parent_container() == target_tab_container) {
continue;
}
if (!(context_dock->available_layouts & target_tab_container->layout)) {
continue;
}
break;
} while (selected_slot != start_slot);
accept_event();
queue_redraw();
queue_accessibility_update();
} else if (p_event->is_action("ui_accept", true) && p_event->is_pressed() && selected_slot > -1) {
DockTabContainer *target_tab_container = EditorDockManager::get_singleton()->dock_slots[selected_slot];
if (context_dock->get_parent_container() == target_tab_container) {
return;
}
if (!(context_dock->available_layouts & target_tab_container->layout)) {
return;
}
accept_event();

emit_signal("slot_clicked", selected_slot);
}
}

Expand Down
7 changes: 7 additions & 0 deletions editor/docks/editor_dock_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,20 +163,27 @@ class DockSlotGrid : public Control {
static constexpr int TAB_MARGIN = 2;

int hovered_slot = -1;
int selected_slot = -1;

Rect2 rect_cache[EditorDock::DOCK_SLOT_MAX];
RID ac_element[EditorDock::DOCK_SLOT_MAX];
Rect2 main_screen_rect;
bool rect_cache_dirty = true;

void _slot_action_click(int p_idx);
void _update_rect_cache();

String _get_slot_name(int p_idx) const;

protected:
static void _bind_methods();
void _notification(int p_what);

virtual void gui_input(const Ref<InputEvent> &p_event) override;
virtual Size2 get_minimum_size() const override;

virtual RID get_focused_accessibility_element() const override;

public:
EditorDock *context_dock = nullptr;
};
Expand Down
4 changes: 4 additions & 0 deletions editor/gui/editor_bottom_panel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ void EditorBottomPanel::_repaint() {
set_popup(nullptr);
} else if (!panel_collapsed && !get_popup()) {
set_popup(dock_context_popup);
Button *btn = get_popup_button();
if (btn) {
btn->set_accessibility_name(TTRC("Bottom Panel Position"));
}
}
if (!panel_collapsed && (previous_tab != -1)) {
return;
Expand Down
4 changes: 4 additions & 0 deletions scene/gui/tab_container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1121,6 +1121,10 @@ void TabContainer::set_popup(Node *p_popup) {
}
}

Button *TabContainer::get_popup_button() const {
return popup_button;
}

Popup *TabContainer::get_popup() const {
if (popup_obj_id.is_valid()) {
Popup *popup = ObjectDB::get_instance<Popup>(popup_obj_id);
Expand Down
1 change: 1 addition & 0 deletions scene/gui/tab_container.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ class TabContainer : public Container {

void set_popup(Node *p_popup);
Popup *get_popup() const;
Button *get_popup_button() const;

void move_tab_from_tab_container(TabContainer *p_from, int p_from_index, int p_to_index = -1);

Expand Down
Loading