148 lines
5.0 KiB
Python
148 lines
5.0 KiB
Python
from imgui_bundle import imgui
|
|
|
|
|
|
class EditorPanelsRightTransformMixin:
|
|
"""Compact Unity-style transform editor."""
|
|
|
|
def _draw_transform_properties(self, node):
|
|
imgui.push_style_var(imgui.StyleVar_.frame_padding, (6.0, 4.0))
|
|
imgui.push_style_var(imgui.StyleVar_.item_spacing, (6.0, 4.0))
|
|
try:
|
|
position = node.getPos()
|
|
rotation = node.getHpr()
|
|
scale = node.getScale()
|
|
|
|
self._draw_transform_row(
|
|
"位置",
|
|
"position",
|
|
(position.x, position.y, position.z),
|
|
lambda values: node.setPos(*values),
|
|
speed=0.05,
|
|
value_format="%.3f",
|
|
reset_values=(0.0, 0.0, 0.0),
|
|
)
|
|
self._draw_transform_row(
|
|
"旋转",
|
|
"rotation",
|
|
(rotation.x, rotation.y, rotation.z),
|
|
lambda values: node.setHpr(*values),
|
|
speed=0.25,
|
|
value_format="%.2f",
|
|
reset_values=(0.0, 0.0, 0.0),
|
|
)
|
|
self._draw_transform_row(
|
|
"缩放",
|
|
"scale",
|
|
(scale.x, scale.y, scale.z),
|
|
lambda values: node.setScale(*values),
|
|
speed=0.02,
|
|
value_format="%.3f",
|
|
reset_values=(1.0, 1.0, 1.0),
|
|
linked=getattr(self, "_transform_scale_locked", True),
|
|
show_lock=True,
|
|
)
|
|
finally:
|
|
imgui.pop_style_var(2)
|
|
|
|
def _draw_transform_row(
|
|
self,
|
|
label,
|
|
row_id,
|
|
values,
|
|
apply_callback,
|
|
speed,
|
|
value_format,
|
|
reset_values,
|
|
linked=False,
|
|
show_lock=False,
|
|
):
|
|
axis_names = ("X", "Y", "Z")
|
|
axis_colors = (
|
|
(0.85, 0.32, 0.32, 1.0),
|
|
(0.36, 0.78, 0.42, 1.0),
|
|
(0.30, 0.55, 0.92, 1.0),
|
|
)
|
|
current_values = [float(value) for value in values]
|
|
original_values = list(current_values)
|
|
changed_any = False
|
|
|
|
table_flags = (
|
|
imgui.TableFlags_.sizing_stretch_same.value
|
|
| imgui.TableFlags_.no_pad_outer_x.value
|
|
| imgui.TableFlags_.no_borders_in_body.value
|
|
)
|
|
if imgui.begin_table(f"{row_id}_table", 8, table_flags):
|
|
imgui.table_setup_column("label", imgui.TableColumnFlags_.width_fixed.value, 52.0)
|
|
imgui.table_setup_column("lock", imgui.TableColumnFlags_.width_fixed.value, 22.0)
|
|
for axis_name in axis_names:
|
|
imgui.table_setup_column(f"{axis_name}_label", imgui.TableColumnFlags_.width_fixed.value, 16.0)
|
|
imgui.table_setup_column(f"{axis_name}_value", imgui.TableColumnFlags_.width_stretch.value, 1.0)
|
|
|
|
imgui.table_next_row()
|
|
imgui.table_next_column()
|
|
imgui.text_disabled(label)
|
|
|
|
imgui.table_next_column()
|
|
if show_lock:
|
|
changed, self._transform_scale_locked = imgui.checkbox(
|
|
f"##{row_id}_lock",
|
|
getattr(self, "_transform_scale_locked", True),
|
|
)
|
|
if imgui.is_item_hovered():
|
|
imgui.set_tooltip("锁定 XYZ 缩放比例")
|
|
else:
|
|
imgui.text("")
|
|
|
|
for axis_index, axis_name in enumerate(axis_names):
|
|
imgui.table_next_column()
|
|
imgui.text_colored(axis_colors[axis_index], axis_name)
|
|
|
|
imgui.table_next_column()
|
|
imgui.set_next_item_width(-1)
|
|
axis_changed, new_value = imgui.drag_float(
|
|
f"##{row_id}_{axis_name}",
|
|
current_values[axis_index],
|
|
speed,
|
|
format=value_format,
|
|
)
|
|
if axis_changed:
|
|
current_values = self._apply_vector_value_change(
|
|
original_values,
|
|
current_values,
|
|
axis_index,
|
|
float(new_value),
|
|
linked,
|
|
reset_values,
|
|
)
|
|
changed_any = True
|
|
|
|
imgui.end_table()
|
|
|
|
if changed_any:
|
|
apply_callback(tuple(current_values))
|
|
|
|
def _apply_vector_value_change(
|
|
self,
|
|
original_values,
|
|
current_values,
|
|
axis_index,
|
|
new_value,
|
|
linked,
|
|
reset_values,
|
|
):
|
|
next_values = list(current_values)
|
|
if not linked:
|
|
next_values[axis_index] = new_value
|
|
return next_values
|
|
|
|
old_value = original_values[axis_index]
|
|
if abs(old_value) > 1e-6:
|
|
ratio = new_value / old_value
|
|
return [value * ratio for value in original_values]
|
|
|
|
if abs(reset_values[axis_index]) > 1e-6:
|
|
ratio = new_value / float(reset_values[axis_index])
|
|
return [float(default_value) * ratio for default_value in reset_values]
|
|
|
|
return [new_value, new_value, new_value]
|