工具栏优化
This commit is contained in:
parent
c4a507c6ac
commit
6524f8306b
46
imgui.ini
46
imgui.ini
@ -24,34 +24,34 @@ Size=832,45
|
||||
Collapsed=0
|
||||
|
||||
[Window][工具栏]
|
||||
Pos=354,20
|
||||
Size=1334,32
|
||||
Pos=255,20
|
||||
Size=1398,383
|
||||
Collapsed=0
|
||||
DockId=0x0000000D,0
|
||||
|
||||
[Window][场景树]
|
||||
Pos=0,20
|
||||
Size=352,748
|
||||
Size=274,1012
|
||||
Collapsed=0
|
||||
DockId=0x00000007,0
|
||||
|
||||
[Window][属性面板]
|
||||
Pos=1690,20
|
||||
Size=358,748
|
||||
Pos=1527,20
|
||||
Size=393,1012
|
||||
Collapsed=0
|
||||
DockId=0x00000002,0
|
||||
|
||||
[Window][控制台]
|
||||
Pos=1690,20
|
||||
Size=358,748
|
||||
Pos=276,632
|
||||
Size=1249,400
|
||||
Collapsed=0
|
||||
DockId=0x00000002,1
|
||||
DockId=0x00000006,1
|
||||
|
||||
[Window][脚本管理]
|
||||
Pos=1950,20
|
||||
Size=610,995
|
||||
Collapsed=0
|
||||
DockId=0x00000002,2
|
||||
DockId=0x00000005,2
|
||||
|
||||
[Window][中文显示测试]
|
||||
Pos=60,60
|
||||
@ -60,7 +60,7 @@ Collapsed=0
|
||||
|
||||
[Window][WindowOverViewport_11111111]
|
||||
Pos=0,20
|
||||
Size=2048,1084
|
||||
Size=1920,1012
|
||||
Collapsed=0
|
||||
|
||||
[Window][测试窗口1]
|
||||
@ -99,8 +99,8 @@ Size=600,500
|
||||
Collapsed=0
|
||||
|
||||
[Window][资源管理器]
|
||||
Pos=0,770
|
||||
Size=2048,334
|
||||
Pos=276,632
|
||||
Size=1249,400
|
||||
Collapsed=0
|
||||
DockId=0x00000006,0
|
||||
|
||||
@ -153,7 +153,7 @@ Collapsed=0
|
||||
Pos=1690,20
|
||||
Size=358,748
|
||||
Collapsed=0
|
||||
DockId=0x00000002,2
|
||||
DockId=0x00000005,2
|
||||
|
||||
[Window][LUI测试控制面板]
|
||||
Pos=6,10
|
||||
@ -204,7 +204,7 @@ Collapsed=0
|
||||
Pos=1438,20
|
||||
Size=610,748
|
||||
Collapsed=0
|
||||
DockId=0x00000002,2
|
||||
DockId=0x00000005,2
|
||||
|
||||
[Window][项目另存为]
|
||||
Pos=794,432
|
||||
@ -212,13 +212,13 @@ Size=460,240
|
||||
Collapsed=0
|
||||
|
||||
[Docking][Data]
|
||||
DockSpace ID=0x08BD597D Window=0x1BBC0F80 Pos=0,20 Size=2048,1084 Split=Y
|
||||
DockNode ID=0x00000005 Parent=0x08BD597D SizeRef=2560,995 Split=X
|
||||
DockNode ID=0x00000007 Parent=0x00000005 SizeRef=352,1084 Selected=0xE0015051
|
||||
DockNode ID=0x00000008 Parent=0x00000005 SizeRef=2206,1084 Split=X
|
||||
DockNode ID=0x00000001 Parent=0x00000008 SizeRef=1846,989 Split=Y
|
||||
DockNode ID=0x0000000D Parent=0x00000001 SizeRef=1318,32 HiddenTabBar=1 Selected=0x43A39006
|
||||
DockNode ID=0x0000000E Parent=0x00000001 SizeRef=1318,961 CentralNode=1
|
||||
DockNode ID=0x00000002 Parent=0x00000008 SizeRef=358,989 Selected=0x5DB6FF37
|
||||
DockNode ID=0x00000006 Parent=0x08BD597D SizeRef=2560,334 Selected=0x3A2E05C3
|
||||
DockSpace ID=0x08BD597D Window=0x1BBC0F80 Pos=0,20 Size=1920,1012 Split=X
|
||||
DockNode ID=0x00000001 Parent=0x08BD597D SizeRef=1525,1012 Split=X
|
||||
DockNode ID=0x00000007 Parent=0x00000001 SizeRef=274,1084 Selected=0xE0015051
|
||||
DockNode ID=0x00000008 Parent=0x00000001 SizeRef=1249,1084 Split=Y
|
||||
DockNode ID=0x00000005 Parent=0x00000008 SizeRef=2048,610 Split=Y
|
||||
DockNode ID=0x0000000D Parent=0x00000005 SizeRef=1318,383 HiddenTabBar=1 Selected=0x43A39006
|
||||
DockNode ID=0x0000000E Parent=0x00000005 SizeRef=1318,363 CentralNode=1 Selected=0xE0015051
|
||||
DockNode ID=0x00000006 Parent=0x00000008 SizeRef=2048,400 Selected=0x3A2E05C3
|
||||
DockNode ID=0x00000002 Parent=0x08BD597D SizeRef=393,1012 Selected=0x5DB6FF37
|
||||
|
||||
|
||||
@ -155,6 +155,14 @@ class EditorPanelsCenterMixin:
|
||||
return
|
||||
|
||||
self.app.set_panel_visible("web", opened)
|
||||
window_pos = imgui.get_window_pos()
|
||||
window_size = imgui.get_window_size()
|
||||
self.app._web_panel_window_rect = (
|
||||
float(window_pos.x),
|
||||
float(window_pos.y),
|
||||
float(window_size.x),
|
||||
float(window_size.y),
|
||||
)
|
||||
|
||||
changed, self.app.web_panel_url_input = imgui.input_text(
|
||||
"URL", self.app.web_panel_url_input, 1024
|
||||
|
||||
@ -146,6 +146,14 @@ class EditorPanelsRightMixin(
|
||||
return
|
||||
|
||||
self.app.showPropertyPanel = opened
|
||||
window_pos = imgui.get_window_pos()
|
||||
window_size = imgui.get_window_size()
|
||||
self.app._property_panel_window_rect = (
|
||||
float(window_pos.x),
|
||||
float(window_pos.y),
|
||||
float(window_size.x),
|
||||
float(window_size.y),
|
||||
)
|
||||
|
||||
# --- LUI Component Properties ---
|
||||
# 优先检查 LUI 组件选择
|
||||
|
||||
@ -3,6 +3,150 @@ from imgui_bundle import imgui, imgui_ctx
|
||||
class EditorPanelsTopMixin:
|
||||
"""Auto-split mixin from editor_panels.py."""
|
||||
|
||||
@staticmethod
|
||||
def _normalize_window_rect(rect):
|
||||
if not rect or len(rect) != 4:
|
||||
return None
|
||||
x, y, w, h = [float(v) for v in rect]
|
||||
if w <= 0 or h <= 0:
|
||||
return None
|
||||
return (x, y, w, h)
|
||||
|
||||
def _get_toolbar_anchor(self):
|
||||
viewport = imgui.get_main_viewport()
|
||||
menu_bar_height = imgui.get_frame_height()
|
||||
viewport_left = float(viewport.pos.x)
|
||||
viewport_top = float(viewport.pos.y) + float(menu_bar_height)
|
||||
viewport_right = float(viewport.pos.x + viewport.size.x)
|
||||
viewport_bottom = float(viewport.pos.y + viewport.size.y)
|
||||
viewport_width = max(1.0, viewport_right - viewport_left)
|
||||
viewport_height = max(1.0, viewport_bottom - viewport_top)
|
||||
edge_margin = 12.0
|
||||
panel_gap = 10.0
|
||||
top_boundary = viewport_top
|
||||
|
||||
blocker_names = (
|
||||
"_scene_tree_window_rect",
|
||||
"_resource_manager_window_rect",
|
||||
"_property_panel_window_rect",
|
||||
"_script_panel_window_rect",
|
||||
"_console_window_rect",
|
||||
"_web_panel_window_rect",
|
||||
)
|
||||
blockers = []
|
||||
for name in blocker_names:
|
||||
rect = self._normalize_window_rect(getattr(self.app, name, None))
|
||||
if rect:
|
||||
blockers.append(rect)
|
||||
|
||||
def is_top_docked(rect):
|
||||
bx, by, bw, bh = rect
|
||||
touches_left = bx <= viewport_left + 6.0
|
||||
touches_right = (bx + bw) >= viewport_right - 6.0
|
||||
return (
|
||||
by <= viewport_top + 6.0 and
|
||||
bh <= viewport_height * 0.45 and
|
||||
(
|
||||
bw >= viewport_width * 0.80 or
|
||||
touches_left or
|
||||
touches_right
|
||||
)
|
||||
)
|
||||
|
||||
def is_left_docked(rect, render_top):
|
||||
bx, by, bw, bh = rect
|
||||
touches_top_band = by <= render_top + 6.0
|
||||
reaches_bottom = (by + bh) >= viewport_bottom - 6.0
|
||||
return (
|
||||
bx <= viewport_left + 6.0 and
|
||||
bw <= viewport_width * 0.45 and
|
||||
bh >= viewport_height * 0.20 and
|
||||
by <= render_top + 40.0 and
|
||||
by + bh >= render_top + 40.0 and
|
||||
(
|
||||
touches_top_band or
|
||||
reaches_bottom or
|
||||
bh >= viewport_height * 0.60
|
||||
)
|
||||
)
|
||||
|
||||
for bx, by, bw, bh in blockers:
|
||||
if is_top_docked((bx, by, bw, bh)):
|
||||
top_boundary = max(top_boundary, by + bh)
|
||||
|
||||
left_boundary = viewport_left
|
||||
probe_y = min(viewport_bottom - edge_margin, top_boundary + 40.0)
|
||||
|
||||
for bx, by, bw, bh in blockers:
|
||||
if is_left_docked((bx, by, bw, bh), top_boundary):
|
||||
left_boundary = max(left_boundary, bx + bw)
|
||||
|
||||
anchor_x = max(viewport_left + edge_margin, left_boundary + panel_gap)
|
||||
anchor_y = max(viewport_top + panel_gap * 0.6, top_boundary + panel_gap * 0.6)
|
||||
max_x = viewport_right - edge_margin
|
||||
max_y = viewport_bottom - edge_margin
|
||||
return min(anchor_x, max_x), min(anchor_y, max_y)
|
||||
|
||||
@staticmethod
|
||||
def _draw_toolbar_icon_button(texture_id, fallback_label, active=False, tooltip=None, enabled=True, size=(26, 26)):
|
||||
"""Draw a compact icon-first toolbar button for the vertical dock toolbar."""
|
||||
if active:
|
||||
button_color = (0.24, 0.42, 0.72, 1.0)
|
||||
hovered_color = (0.28, 0.48, 0.82, 1.0)
|
||||
tint_color = (1.0, 1.0, 1.0, 1.0)
|
||||
border_color = (0.38, 0.62, 0.95, 1.0)
|
||||
else:
|
||||
button_color = (0.30, 0.31, 0.33, 1.0)
|
||||
hovered_color = (0.38, 0.39, 0.42, 1.0)
|
||||
tint_color = (0.9, 0.92, 0.96, 1.0)
|
||||
border_color = (0.20, 0.21, 0.23, 1.0)
|
||||
|
||||
imgui.push_style_color(imgui.Col_.button, button_color)
|
||||
imgui.push_style_color(imgui.Col_.button_hovered, hovered_color)
|
||||
imgui.push_style_color(imgui.Col_.button_active, hovered_color)
|
||||
imgui.push_style_color(imgui.Col_.border, border_color)
|
||||
imgui.push_style_var(imgui.StyleVar_.frame_rounding, 4.0)
|
||||
imgui.push_style_var(imgui.StyleVar_.frame_border_size, 1.0)
|
||||
imgui.push_style_var(imgui.StyleVar_.frame_padding, (3.0, 3.0))
|
||||
|
||||
if not enabled:
|
||||
imgui.begin_disabled()
|
||||
|
||||
if texture_id:
|
||||
clicked = imgui.image_button(texture_id, size, (0, 1), (1, 0), (0, 0, 0, 0), tint_color)
|
||||
else:
|
||||
clicked = imgui.button(fallback_label, size)
|
||||
|
||||
if not enabled:
|
||||
imgui.end_disabled()
|
||||
|
||||
if tooltip and imgui.is_item_hovered():
|
||||
imgui.set_tooltip(tooltip)
|
||||
|
||||
imgui.pop_style_var(3)
|
||||
imgui.pop_style_color(4)
|
||||
return clicked
|
||||
|
||||
@staticmethod
|
||||
def _draw_toolbar_separator():
|
||||
imgui.dummy((1, 2))
|
||||
draw_list = imgui.get_window_draw_list()
|
||||
cursor_pos = imgui.get_cursor_screen_pos()
|
||||
window_pos = imgui.get_window_pos()
|
||||
window_size = imgui.get_window_size()
|
||||
left_inset = 10.0
|
||||
right_inset = 10.0
|
||||
line_width = max(18.0, float(window_size.x) - left_inset - right_inset)
|
||||
start_x = float(window_pos.x) + left_inset
|
||||
line_y = float(cursor_pos.y)
|
||||
draw_list.add_line(
|
||||
(start_x, line_y),
|
||||
(start_x + line_width, line_y),
|
||||
imgui.color_convert_float4_to_u32((0.38, 0.39, 0.42, 1.0)),
|
||||
1.0,
|
||||
)
|
||||
imgui.dummy((1, 6))
|
||||
|
||||
@staticmethod
|
||||
def _truncate_toolbar_text(text, limit=20):
|
||||
text = text or ""
|
||||
@ -280,69 +424,112 @@ class EditorPanelsTopMixin:
|
||||
|
||||
def draw_toolbar(self):
|
||||
"""绘制工具栏"""
|
||||
# 工具栏可以保持无标题栏,但允许移动和调整大小
|
||||
flags = self.app.style_manager.get_window_flags("toolbar")
|
||||
|
||||
with self.app.style_manager.begin_styled_window("工具栏", self.app.showToolbar, flags) as (_, opened):
|
||||
anchor_x, anchor_y = self._get_toolbar_anchor()
|
||||
imgui.set_next_window_pos((anchor_x, anchor_y), imgui.Cond_.always)
|
||||
imgui.set_next_window_size_constraints((48.0, 170.0), (64.0, 500.0))
|
||||
|
||||
flags = (
|
||||
imgui.WindowFlags_.no_title_bar |
|
||||
imgui.WindowFlags_.no_collapse |
|
||||
imgui.WindowFlags_.no_move |
|
||||
imgui.WindowFlags_.no_scrollbar |
|
||||
imgui.WindowFlags_.always_auto_resize |
|
||||
imgui.WindowFlags_.no_saved_settings |
|
||||
imgui.WindowFlags_.no_docking
|
||||
)
|
||||
|
||||
with imgui_ctx.begin("工具栏", self.app.showToolbar, flags) as (_, opened):
|
||||
if not opened:
|
||||
self.app.showToolbar = False
|
||||
return
|
||||
|
||||
self.app.showToolbar = opened
|
||||
style_manager = self.app.style_manager
|
||||
command_manager = getattr(self.app, "command_manager", None)
|
||||
can_undo = command_manager.can_undo() if command_manager else False
|
||||
can_redo = command_manager.can_redo() if command_manager else False
|
||||
selection_name = self._truncate_toolbar_text(self._get_toolbar_selection_name(), 18)
|
||||
project_name = self._truncate_toolbar_text(self._get_toolbar_project_name(), 18)
|
||||
tool_name = getattr(self.app.tool_manager, "getCurrentTool", lambda: "选择")()
|
||||
icons = getattr(self.app, "icons", {}) or {}
|
||||
button_width = 24.0
|
||||
|
||||
imgui.push_style_var(imgui.StyleVar_.item_spacing, (8.0, 6.0))
|
||||
imgui.push_style_var(imgui.StyleVar_.frame_padding, (8.0, 5.0))
|
||||
imgui.push_style_var(imgui.StyleVar_.item_spacing, (5.0, 5.0))
|
||||
imgui.push_style_var(imgui.StyleVar_.window_padding, (7.0, 8.0))
|
||||
|
||||
tool_buttons = [
|
||||
("Q 选择", "选择", self.app.tool_manager.isSelectionTool(), "选择工具 (Q)"),
|
||||
("W 移动", "移动", self.app.tool_manager.isMoveTool(), "移动工具 (W)"),
|
||||
("E 旋转", "旋转", self.app.tool_manager.isRotateTool(), "旋转工具 (E)"),
|
||||
("R 缩放", "缩放", self.app.tool_manager.isScaleTool(), "缩放工具 (R)"),
|
||||
]
|
||||
def align_item(item_width):
|
||||
window_width = float(imgui.get_window_size().x)
|
||||
centered_x = max(0.0, (window_width - float(item_width)) * 0.5)
|
||||
imgui.set_cursor_pos_x(centered_x)
|
||||
|
||||
for index, (label, tool_id, is_active, tooltip) in enumerate(tool_buttons):
|
||||
if style_manager.draw_toolbar_button(label, active=is_active, size=(74, 28), tooltip=tooltip):
|
||||
self.app.tool_manager.setCurrentTool(tool_id)
|
||||
if index != len(tool_buttons) - 1:
|
||||
imgui.same_line()
|
||||
align_item(imgui.calc_text_size("工具").x)
|
||||
imgui.text_disabled("工具")
|
||||
self._draw_toolbar_separator()
|
||||
|
||||
imgui.same_line()
|
||||
imgui.separator()
|
||||
imgui.same_line()
|
||||
|
||||
if style_manager.draw_toolbar_button("撤销", size=(56, 28), tooltip="撤销上一步 (Ctrl+Z)", enabled=can_undo):
|
||||
self.app._on_undo()
|
||||
imgui.same_line()
|
||||
if style_manager.draw_toolbar_button("重做", size=(56, 28), tooltip="重做上一步 (Ctrl+Y)", enabled=can_redo):
|
||||
self.app._on_redo()
|
||||
imgui.same_line()
|
||||
if style_manager.draw_toolbar_button(
|
||||
"聚焦",
|
||||
size=(56, 28),
|
||||
tooltip="聚焦当前选择 (F)",
|
||||
enabled=selection_name != "未选择",
|
||||
align_item(button_width)
|
||||
if self._draw_toolbar_icon_button(
|
||||
icons.get("select"),
|
||||
"Q",
|
||||
active=self.app.tool_manager.isSelectionTool(),
|
||||
tooltip="选择工具 (Q)",
|
||||
):
|
||||
self.app.tool_manager.setCurrentTool("选择")
|
||||
align_item(button_width)
|
||||
if self._draw_toolbar_icon_button(
|
||||
icons.get("move"),
|
||||
"W",
|
||||
active=self.app.tool_manager.isMoveTool(),
|
||||
tooltip="移动工具 (W)",
|
||||
):
|
||||
self.app.tool_manager.setCurrentTool("移动")
|
||||
align_item(button_width)
|
||||
if self._draw_toolbar_icon_button(
|
||||
icons.get("rotate"),
|
||||
"E",
|
||||
active=self.app.tool_manager.isRotateTool(),
|
||||
tooltip="旋转工具 (E)",
|
||||
):
|
||||
self.app.tool_manager.setCurrentTool("旋转")
|
||||
align_item(button_width)
|
||||
if self._draw_toolbar_icon_button(
|
||||
icons.get("scale"),
|
||||
"R",
|
||||
active=self.app.tool_manager.isScaleTool(),
|
||||
tooltip="缩放工具 (R)",
|
||||
):
|
||||
self.app.tool_manager.setCurrentTool("缩放")
|
||||
|
||||
self._draw_toolbar_separator()
|
||||
|
||||
align_item(button_width)
|
||||
if self._draw_toolbar_icon_button(None, "U", tooltip="撤销上一步 (Ctrl+Z)", enabled=can_undo):
|
||||
self.app._on_undo()
|
||||
align_item(button_width)
|
||||
if self._draw_toolbar_icon_button(None, "Y", tooltip="重做上一步 (Ctrl+Y)", enabled=can_redo):
|
||||
self.app._on_redo()
|
||||
align_item(button_width)
|
||||
if self._draw_toolbar_icon_button(None, "F", tooltip="聚焦当前选择 (F)", enabled=selection_name != "未选择"):
|
||||
self.app.onFocusKeyPressed()
|
||||
|
||||
imgui.same_line()
|
||||
imgui.separator()
|
||||
imgui.same_line()
|
||||
style_manager.draw_stat_chip(f"项目 {project_name}", tint=(0.12, 0.14, 0.18, 1.0))
|
||||
imgui.same_line()
|
||||
style_manager.draw_stat_chip(f"工具 {tool_name}", tint=(0.16, 0.19, 0.24, 1.0))
|
||||
imgui.same_line()
|
||||
style_manager.draw_stat_chip(f"选择 {selection_name}", tint=(0.18, 0.24, 0.32, 1.0))
|
||||
imgui.same_line()
|
||||
style_manager.draw_stat_chip(
|
||||
f"历史 {command_manager.get_undo_count() if command_manager else 0}/{command_manager.get_redo_count() if command_manager else 0}",
|
||||
tint=(0.16, 0.18, 0.2, 1.0),
|
||||
self._draw_toolbar_separator()
|
||||
|
||||
current_label = "当前"
|
||||
align_item(imgui.calc_text_size(current_label).x)
|
||||
imgui.text_disabled("当前")
|
||||
align_item(imgui.calc_text_size(selection_name).x)
|
||||
imgui.text(selection_name)
|
||||
|
||||
history_text = (
|
||||
f"历史 {command_manager.get_undo_count() if command_manager else 0}/"
|
||||
f"{command_manager.get_redo_count() if command_manager else 0}"
|
||||
)
|
||||
align_item(imgui.calc_text_size(history_text).x)
|
||||
imgui.text_disabled(history_text)
|
||||
|
||||
window_pos = imgui.get_window_pos()
|
||||
window_size = imgui.get_window_size()
|
||||
self.app._toolbar_window_rect = (
|
||||
float(window_pos.x),
|
||||
float(window_pos.y),
|
||||
float(window_size.x),
|
||||
float(window_size.y),
|
||||
)
|
||||
|
||||
imgui.pop_style_var(2)
|
||||
|
||||
@ -28,6 +28,14 @@ class ScriptPanels:
|
||||
return
|
||||
|
||||
self.app.showConsole = opened
|
||||
window_pos = imgui.get_window_pos()
|
||||
window_size = imgui.get_window_size()
|
||||
self.app._console_window_rect = (
|
||||
float(window_pos.x),
|
||||
float(window_pos.y),
|
||||
float(window_size.x),
|
||||
float(window_size.y),
|
||||
)
|
||||
|
||||
imgui.text("控制台输出")
|
||||
imgui.separator()
|
||||
@ -114,6 +122,14 @@ class ScriptPanels:
|
||||
return
|
||||
|
||||
self.app.showScriptPanel = opened
|
||||
window_pos = imgui.get_window_pos()
|
||||
window_size = imgui.get_window_size()
|
||||
self.app._script_panel_window_rect = (
|
||||
float(window_pos.x),
|
||||
float(window_pos.y),
|
||||
float(window_size.x),
|
||||
float(window_size.y),
|
||||
)
|
||||
|
||||
# 1. 脚本系统状态组
|
||||
self._draw_script_status_group()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user