From 2e91832f3956a679b6a23b1e4d153ccf6db5e88e Mon Sep 17 00:00:00 2001
From: lrc <571244399@qq.com>
Date: Fri, 26 Jun 2026 23:27:19 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=94=B1=E4=BA=8Etabledata?=
=?UTF-8?q?=E5=BF=98=E4=BA=86=E6=A0=87=E8=AE=B0=E5=8F=AF=E5=BA=8F=E5=88=97?=
=?UTF-8?q?=E5=8C=96=E5=AF=BC=E8=87=B4=E6=95=B0=E6=8D=AE=E5=85=A8=E9=83=A8?=
=?UTF-8?q?=E4=B8=BAnull=E5=AF=BC=E8=87=B4=E6=8A=A5=E9=94=99=E7=9A=84?=
=?UTF-8?q?=E9=97=AE=E9=A2=98=E3=80=82=20=E6=B7=BB=E5=8A=A0=E5=BF=AB?=
=?UTF-8?q?=E6=8D=B7=E9=94=AE=E5=8A=9F=E8=83=BD=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../XTable/XericUIActionTableSceneEditor.cs | 80 ++
.../Test/xuiSceen.unity | 808 +++++++++++++++++-
.../Rendering/Component/XericUIActionTable.cs | 101 ++-
3 files changed, 949 insertions(+), 40 deletions(-)
diff --git a/Editor/XTable/XericUIActionTableSceneEditor.cs b/Editor/XTable/XericUIActionTableSceneEditor.cs
index a1bf9ef..c16eac4 100644
--- a/Editor/XTable/XericUIActionTableSceneEditor.cs
+++ b/Editor/XTable/XericUIActionTableSceneEditor.cs
@@ -105,6 +105,7 @@ namespace XericUIEditor.XTable
DrawSelectionHighlight(rh, cw, tableRect, xScale, yScale, table);
DrawInputBar(table, tableRect.x, tableRect.y + tableRect.height + MARGIN);
HandleInput(table, rh, cw, tableRect, xScale, yScale);
+ HandleKeyboard(table, rh, cw);
Handles.EndGUI();
}
@@ -276,6 +277,16 @@ namespace XericUIEditor.XTable
margin = new RectOffset(2, 2, 2, 2)
};
Rect inputRect = new Rect(barRect.x + 56, barRect.y + 2, 180, barRect.height - 4);
+
+ // 回车键提交
+ if (Event.current.isKey && Event.current.keyCode == KeyCode.Return
+ && GUI.GetNameOfFocusedControl() == "XTableSceneEditInput")
+ {
+ ApplyEdit(table);
+ Event.current.Use();
+ }
+
+ GUI.SetNextControlName("XTableSceneEditInput");
s_EditText = GUI.TextField(inputRect, s_EditText, inputStyle);
var btnStyle = new GUIStyle(GUI.skin.button)
@@ -287,6 +298,7 @@ namespace XericUIEditor.XTable
if (GUI.Button(new Rect(barRect.x + 242, barRect.y + 2, 50, barRect.height - 4),
"应用", btnStyle))
{
+ GUI.FocusControl(null);
ApplyEdit(table);
}
}
@@ -345,6 +357,74 @@ namespace XericUIEditor.XTable
#endregion
+ #region 键盘快捷键
+
+ private static void HandleKeyboard(XericUIActionTable table, float[] rh, float[] cw)
+ {
+ Event e = Event.current;
+ if (e.type != EventType.KeyDown) return;
+
+ // 输入框获得焦点时不拦截方向键(用于文本光标移动)
+ if (GUI.GetNameOfFocusedControl() == "XTableSceneEditInput")
+ return;
+
+ int row = table.SelectedRow;
+ int col = table.SelectedCol;
+ bool shift = e.shift;
+
+ switch (e.keyCode)
+ {
+ case KeyCode.UpArrow:
+ if (!TryClampToValid(row - 1, col, rh, cw, out row, out col)) return;
+ break;
+ case KeyCode.DownArrow:
+ if (!TryClampToValid(row + 1, col, rh, cw, out row, out col)) return;
+ break;
+ case KeyCode.LeftArrow:
+ if (!TryClampToValid(row, col - 1, rh, cw, out row, out col)) return;
+ break;
+ case KeyCode.RightArrow:
+ if (!TryClampToValid(row, col + 1, rh, cw, out row, out col)) return;
+ break;
+ default:
+ return;
+ }
+
+ if (shift)
+ {
+ // Shift: 扩展/开始多选
+ if (!table.HasMultiSelection && table.SelectedRow >= 0 && table.SelectedCol >= 0)
+ table.StartMultiSelect(table.SelectedRow, table.SelectedCol);
+ table.ExtendMultiSelect(row, col);
+ }
+ else
+ {
+ table.SelectCell(row, col);
+ }
+
+ UpdateEditText(table, row, col);
+ table.RefreshView();
+ e.Use();
+ SceneView.RepaintAll();
+ }
+
+ /// 将行列约束到有效范围,若已到边界则返回 false(不移动)
+ private static bool TryClampToValid(int row, int col, float[] rh, float[] cw,
+ out int outRow, out int outCol)
+ {
+ if (row < 0 || row >= rh.Length || col < 0 || col >= cw.Length)
+ {
+ outRow = row;
+ outCol = col;
+ return false;
+ }
+ outRow = row;
+ outCol = col;
+ return true;
+ }
+
+ #endregion
+
private static int IndexFromCoord(float coord, float[] sizes)
{
float acc = 0;
diff --git a/Runtime/InterfaceAttributeReflectionGenerator/Test/xuiSceen.unity b/Runtime/InterfaceAttributeReflectionGenerator/Test/xuiSceen.unity
index 5b1d595..e62a9ad 100644
--- a/Runtime/InterfaceAttributeReflectionGenerator/Test/xuiSceen.unity
+++ b/Runtime/InterfaceAttributeReflectionGenerator/Test/xuiSceen.unity
@@ -122,7 +122,7 @@ NavMeshSettings:
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
---- !u!1 &427173231
+--- !u!1 &176805029
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
@@ -130,63 +130,376 @@ GameObject:
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- - component: {fileID: 427173232}
- - component: {fileID: 427173233}
- m_Layer: 5
- m_Name: GameObject
+ - component: {fileID: 176805030}
+ - component: {fileID: 176805031}
+ - component: {fileID: 176805033}
+ - component: {fileID: 176805032}
+ m_Layer: 0
+ m_Name: Xeric UI Action Table
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
---- !u!224 &427173232
+--- !u!224 &176805030
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
- m_GameObject: {fileID: 427173231}
+ m_GameObject: {fileID: 176805029}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
- m_Children: []
+ m_Children:
+ - {fileID: 1607234778}
+ - {fileID: 759304923}
+ - {fileID: 1586214056}
m_Father: {fileID: 1305945111}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
- m_AnchoredPosition: {x: 386, y: 0}
- m_SizeDelta: {x: 424.7212, y: 503.0022}
+ m_AnchoredPosition: {x: 110.4, y: -224.9}
+ m_SizeDelta: {x: 499.2139, y: 296.9379}
m_Pivot: {x: 0.5, y: 0.5}
---- !u!114 &427173233
+--- !u!114 &176805031
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
- m_GameObject: {fileID: 427173231}
+ m_GameObject: {fileID: 176805029}
m_Enabled: 1
m_EditorHideFlags: 0
- m_Script: {fileID: 11500000, guid: 8a8695521f0d02e499659fee002a26c2, type: 3}
+ m_Script: {fileID: 11500000, guid: 1aa08ab6e0800fa44ae55d278d1423e3, type: 3}
m_Name:
m_EditorClassIdentifier:
- m_Padding:
- m_Left: 0
- m_Right: 0
- m_Top: 0
- m_Bottom: 0
- m_ChildAlignment: 0
- m_StartCorner: 0
- m_StartAxis: 0
- m_CellSize: {x: 100, y: 100}
- m_Spacing: {x: 0, y: 0}
- m_Constraint: 0
- m_ConstraintCount: 2
+ m_Content: {fileID: 779072858}
+ m_Horizontal: 1
+ m_Vertical: 1
+ m_MovementType: 2
+ m_Elasticity: 0.1
+ m_Inertia: 1
+ m_DecelerationRate: 0.135
+ m_ScrollSensitivity: 1
+ m_Viewport: {fileID: 1607234778}
+ m_HorizontalScrollbar: {fileID: 759304926}
+ m_VerticalScrollbar: {fileID: 1586214059}
+ m_HorizontalScrollbarVisibility: 1
+ m_VerticalScrollbarVisibility: 1
+ m_HorizontalScrollbarSpacing: 0
+ m_VerticalScrollbarSpacing: 0
+ m_OnValueChanged:
+ m_PersistentCalls:
+ m_Calls: []
+--- !u!114 &176805032
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 176805029}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_Material: {fileID: 0}
+ m_Color: {r: 0.1, g: 0.1, b: 0.1, a: 0.3}
+ m_RaycastTarget: 1
+ m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+ m_Maskable: 1
+ m_OnCullStateChanged:
+ m_PersistentCalls:
+ m_Calls: []
+ m_Sprite: {fileID: 0}
+ m_Type: 0
+ m_PreserveAspect: 0
+ m_FillCenter: 1
+ m_FillMethod: 4
+ m_FillAmount: 1
+ m_FillClockwise: 1
+ m_FillOrigin: 0
+ m_UseSpriteMesh: 0
+ m_PixelsPerUnitMultiplier: 1
+--- !u!222 &176805033
+CanvasRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 176805029}
+ m_CullTransparentMesh: 1
--- !u!224 &473756093 stripped
RectTransform:
m_CorrespondingSourceObject: {fileID: 7740888090637087881, guid: 4f25b16125eac234e820506fff28a4b0, type: 3}
m_PrefabInstance: {fileID: 2652053894482773542}
m_PrefabAsset: {fileID: 0}
+--- !u!1 &524897086
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 524897087}
+ m_Layer: 0
+ m_Name: Sliding Area
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &524897087
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 524897086}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children:
+ - {fileID: 2007027292}
+ m_Father: {fileID: 759304923}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+ m_AnchorMin: {x: 0, y: 0}
+ m_AnchorMax: {x: 1, y: 1}
+ m_AnchoredPosition: {x: 0, y: 0}
+ m_SizeDelta: {x: -20, y: -20}
+ m_Pivot: {x: 0.5, y: 0.5}
+--- !u!1 &581047150
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 581047151}
+ m_Layer: 0
+ m_Name: Sliding Area
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &581047151
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 581047150}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children:
+ - {fileID: 1175835292}
+ m_Father: {fileID: 1586214056}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+ m_AnchorMin: {x: 0, y: 0}
+ m_AnchorMax: {x: 1, y: 1}
+ m_AnchoredPosition: {x: 0, y: 0}
+ m_SizeDelta: {x: -20, y: -20}
+ m_Pivot: {x: 0.5, y: 0.5}
+--- !u!1 &759304922
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 759304923}
+ - component: {fileID: 759304926}
+ - component: {fileID: 759304925}
+ - component: {fileID: 759304924}
+ m_Layer: 0
+ m_Name: Scrollbar Horizontal
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &759304923
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 759304922}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children:
+ - {fileID: 524897087}
+ m_Father: {fileID: 176805030}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+ m_AnchorMin: {x: 0, y: 0}
+ m_AnchorMax: {x: 1, y: 0}
+ m_AnchoredPosition: {x: 0, y: 4}
+ m_SizeDelta: {x: -16, y: 20}
+ m_Pivot: {x: 0.5, y: 0}
+--- !u!114 &759304924
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 759304922}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_Material: {fileID: 0}
+ m_Color: {r: 0.15, g: 0.15, b: 0.15, a: 0.5}
+ m_RaycastTarget: 1
+ m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+ m_Maskable: 1
+ m_OnCullStateChanged:
+ m_PersistentCalls:
+ m_Calls: []
+ m_Sprite: {fileID: 0}
+ m_Type: 0
+ m_PreserveAspect: 0
+ m_FillCenter: 1
+ m_FillMethod: 4
+ m_FillAmount: 1
+ m_FillClockwise: 1
+ m_FillOrigin: 0
+ m_UseSpriteMesh: 0
+ m_PixelsPerUnitMultiplier: 1
+--- !u!222 &759304925
+CanvasRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 759304922}
+ m_CullTransparentMesh: 1
+--- !u!114 &759304926
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 759304922}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 2a4db7a114972834c8e4117be1d82ba3, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_Navigation:
+ m_Mode: 3
+ m_WrapAround: 0
+ m_SelectOnUp: {fileID: 0}
+ m_SelectOnDown: {fileID: 0}
+ m_SelectOnLeft: {fileID: 0}
+ m_SelectOnRight: {fileID: 0}
+ m_Transition: 1
+ m_Colors:
+ m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
+ m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+ m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
+ m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+ m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
+ m_ColorMultiplier: 1
+ m_FadeDuration: 0.1
+ m_SpriteState:
+ m_HighlightedSprite: {fileID: 0}
+ m_PressedSprite: {fileID: 0}
+ m_SelectedSprite: {fileID: 0}
+ m_DisabledSprite: {fileID: 0}
+ m_AnimationTriggers:
+ m_NormalTrigger: Normal
+ m_HighlightedTrigger: Highlighted
+ m_PressedTrigger: Pressed
+ m_SelectedTrigger: Selected
+ m_DisabledTrigger: Disabled
+ m_Interactable: 1
+ m_TargetGraphic: {fileID: 0}
+ m_HandleRect: {fileID: 2007027292}
+ m_Direction: 0
+ m_Value: 0
+ m_Size: 1
+ m_NumberOfSteps: 0
+ m_OnValueChanged:
+ m_PersistentCalls:
+ m_Calls: []
+--- !u!1 &779072857
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 779072858}
+ - component: {fileID: 779072860}
+ - component: {fileID: 779072859}
+ m_Layer: 0
+ m_Name: Content
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &779072858
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 779072857}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 1607234778}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+ m_AnchorMin: {x: 0, y: 1}
+ m_AnchorMax: {x: 0, y: 1}
+ m_AnchoredPosition: {x: 0, y: 0}
+ m_SizeDelta: {x: 300, y: 70}
+ m_Pivot: {x: 0, y: 1}
+--- !u!114 &779072859
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 779072857}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 13944afb118d5de499192b64114ec4f2, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_RowHeights:
+ - 40
+ - 30
+ m_ColWidths:
+ - 100
+ - 80
+ - 120
+ m_DefaultStyleNamespace: xeric_table_default
+ m_ScrollRect: {fileID: 176805031}
+--- !u!222 &779072860
+CanvasRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 779072857}
+ m_CullTransparentMesh: 1
--- !u!224 &879192284 stripped
RectTransform:
m_CorrespondingSourceObject: {fileID: 3719551361696879033, guid: 1715f06fee075eb45b68d43575e9aa88, type: 3}
@@ -197,6 +510,81 @@ RectTransform:
m_CorrespondingSourceObject: {fileID: 788574964665247507, guid: 0dc894baa18f5cb4eb9c82fd3c40d2bd, type: 3}
m_PrefabInstance: {fileID: 5908854057788947888}
m_PrefabAsset: {fileID: 0}
+--- !u!1 &1175835291
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1175835292}
+ - component: {fileID: 1175835294}
+ - component: {fileID: 1175835293}
+ m_Layer: 0
+ m_Name: Handle
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &1175835292
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1175835291}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 581047151}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+ m_AnchorMin: {x: 0, y: 0}
+ m_AnchorMax: {x: 0, y: 0}
+ m_AnchoredPosition: {x: 0, y: 0}
+ m_SizeDelta: {x: 0, y: 0}
+ m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1175835293
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1175835291}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_Material: {fileID: 0}
+ m_Color: {r: 0.4, g: 0.4, b: 0.4, a: 0.8}
+ m_RaycastTarget: 1
+ m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+ m_Maskable: 1
+ m_OnCullStateChanged:
+ m_PersistentCalls:
+ m_Calls: []
+ m_Sprite: {fileID: 0}
+ m_Type: 0
+ m_PreserveAspect: 0
+ m_FillCenter: 1
+ m_FillMethod: 4
+ m_FillAmount: 1
+ m_FillClockwise: 1
+ m_FillOrigin: 0
+ m_UseSpriteMesh: 0
+ m_PixelsPerUnitMultiplier: 1
+--- !u!222 &1175835294
+CanvasRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1175835291}
+ m_CullTransparentMesh: 1
--- !u!1 &1189569455
GameObject:
m_ObjectHideFlags: 0
@@ -289,6 +677,38 @@ Transform:
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1227271787
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1227271788}
+ m_Layer: 0
+ m_Name: '[SingleInstance]'
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &1227271788
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1227271787}
+ serializedVersion: 2
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children:
+ - {fileID: 1830323039}
+ m_Father: {fileID: 0}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1305945107
GameObject:
m_ObjectHideFlags: 0
@@ -383,8 +803,8 @@ RectTransform:
m_LocalScale: {x: 0, y: 0, z: 0}
m_ConstrainProportionsScale: 0
m_Children:
- - {fileID: 427173232}
- {fileID: 1376882762}
+ - {fileID: 176805030}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
@@ -482,11 +902,271 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
_currentTheme: Default
+--- !u!1 &1586214055
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1586214056}
+ - component: {fileID: 1586214059}
+ - component: {fileID: 1586214058}
+ - component: {fileID: 1586214057}
+ m_Layer: 0
+ m_Name: Scrollbar Vertical
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &1586214056
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1586214055}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children:
+ - {fileID: 581047151}
+ m_Father: {fileID: 176805030}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+ m_AnchorMin: {x: 1, y: 0}
+ m_AnchorMax: {x: 1, y: 1}
+ m_AnchoredPosition: {x: -4, y: 0}
+ m_SizeDelta: {x: 20, y: -16}
+ m_Pivot: {x: 1, y: 0.5}
+--- !u!114 &1586214057
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1586214055}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_Material: {fileID: 0}
+ m_Color: {r: 0.15, g: 0.15, b: 0.15, a: 0.5}
+ m_RaycastTarget: 1
+ m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+ m_Maskable: 1
+ m_OnCullStateChanged:
+ m_PersistentCalls:
+ m_Calls: []
+ m_Sprite: {fileID: 0}
+ m_Type: 0
+ m_PreserveAspect: 0
+ m_FillCenter: 1
+ m_FillMethod: 4
+ m_FillAmount: 1
+ m_FillClockwise: 1
+ m_FillOrigin: 0
+ m_UseSpriteMesh: 0
+ m_PixelsPerUnitMultiplier: 1
+--- !u!222 &1586214058
+CanvasRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1586214055}
+ m_CullTransparentMesh: 1
+--- !u!114 &1586214059
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1586214055}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 2a4db7a114972834c8e4117be1d82ba3, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_Navigation:
+ m_Mode: 3
+ m_WrapAround: 0
+ m_SelectOnUp: {fileID: 0}
+ m_SelectOnDown: {fileID: 0}
+ m_SelectOnLeft: {fileID: 0}
+ m_SelectOnRight: {fileID: 0}
+ m_Transition: 1
+ m_Colors:
+ m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
+ m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+ m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
+ m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
+ m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
+ m_ColorMultiplier: 1
+ m_FadeDuration: 0.1
+ m_SpriteState:
+ m_HighlightedSprite: {fileID: 0}
+ m_PressedSprite: {fileID: 0}
+ m_SelectedSprite: {fileID: 0}
+ m_DisabledSprite: {fileID: 0}
+ m_AnimationTriggers:
+ m_NormalTrigger: Normal
+ m_HighlightedTrigger: Highlighted
+ m_PressedTrigger: Pressed
+ m_SelectedTrigger: Selected
+ m_DisabledTrigger: Disabled
+ m_Interactable: 1
+ m_TargetGraphic: {fileID: 0}
+ m_HandleRect: {fileID: 1175835292}
+ m_Direction: 2
+ m_Value: 0
+ m_Size: 1
+ m_NumberOfSteps: 0
+ m_OnValueChanged:
+ m_PersistentCalls:
+ m_Calls: []
+--- !u!1 &1607234777
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1607234778}
+ - component: {fileID: 1607234781}
+ - component: {fileID: 1607234780}
+ - component: {fileID: 1607234779}
+ m_Layer: 0
+ m_Name: Viewport
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &1607234778
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1607234777}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children:
+ - {fileID: 779072858}
+ m_Father: {fileID: 176805030}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+ m_AnchorMin: {x: 0, y: 0}
+ m_AnchorMax: {x: 1, y: 1}
+ m_AnchoredPosition: {x: 0, y: 0}
+ m_SizeDelta: {x: 0, y: 0}
+ m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1607234779
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1607234777}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 31a19414c41e5ae4aae2af33fee712f6, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_ShowMaskGraphic: 1
+--- !u!114 &1607234780
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1607234777}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_Material: {fileID: 0}
+ m_Color: {r: 1, g: 1, b: 1, a: 0.01}
+ m_RaycastTarget: 1
+ m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+ m_Maskable: 1
+ m_OnCullStateChanged:
+ m_PersistentCalls:
+ m_Calls: []
+ m_Sprite: {fileID: 0}
+ m_Type: 0
+ m_PreserveAspect: 0
+ m_FillCenter: 1
+ m_FillMethod: 4
+ m_FillAmount: 1
+ m_FillClockwise: 1
+ m_FillOrigin: 0
+ m_UseSpriteMesh: 0
+ m_PixelsPerUnitMultiplier: 1
+--- !u!222 &1607234781
+CanvasRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1607234777}
+ m_CullTransparentMesh: 1
--- !u!224 &1802681382 stripped
RectTransform:
m_CorrespondingSourceObject: {fileID: 496212968317797178, guid: a58d335e7df1a994d9f1c0fd58aff68f, type: 3}
m_PrefabInstance: {fileID: 2478084580577702765}
m_PrefabAsset: {fileID: 0}
+--- !u!1 &1830323038
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1830323039}
+ - component: {fileID: 1830323040}
+ m_Layer: 0
+ m_Name: '[XericLifeCycleCore-OnlGlbInsImn]'
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &1830323039
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1830323038}
+ serializedVersion: 2
+ m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 1227271788}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &1830323040
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1830323038}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 682102342, guid: 9bf3ac4b721466c4c99ca1ff9ff19f35, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
--- !u!1 &1836412398
GameObject:
m_ObjectHideFlags: 0
@@ -678,6 +1358,81 @@ RectTransform:
m_CorrespondingSourceObject: {fileID: 101967088653580022, guid: f601d441cf135fe479d319c5eb01abd8, type: 3}
m_PrefabInstance: {fileID: 1170375175641943129}
m_PrefabAsset: {fileID: 0}
+--- !u!1 &2007027291
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 2007027292}
+ - component: {fileID: 2007027294}
+ - component: {fileID: 2007027293}
+ m_Layer: 0
+ m_Name: Handle
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!224 &2007027292
+RectTransform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2007027291}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 524897087}
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+ m_AnchorMin: {x: 0, y: 0}
+ m_AnchorMax: {x: 0, y: 0}
+ m_AnchoredPosition: {x: 0, y: 0}
+ m_SizeDelta: {x: 20, y: 20}
+ m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &2007027293
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2007027291}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_Material: {fileID: 0}
+ m_Color: {r: 0.4, g: 0.4, b: 0.4, a: 0.8}
+ m_RaycastTarget: 1
+ m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
+ m_Maskable: 1
+ m_OnCullStateChanged:
+ m_PersistentCalls:
+ m_Calls: []
+ m_Sprite: {fileID: 0}
+ m_Type: 0
+ m_PreserveAspect: 0
+ m_FillCenter: 1
+ m_FillMethod: 4
+ m_FillAmount: 1
+ m_FillClockwise: 1
+ m_FillOrigin: 0
+ m_UseSpriteMesh: 0
+ m_PixelsPerUnitMultiplier: 1
+--- !u!222 &2007027294
+CanvasRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2007027291}
+ m_CullTransparentMesh: 1
--- !u!1 &2007728709
GameObject:
m_ObjectHideFlags: 0
@@ -1259,3 +2014,4 @@ SceneRoots:
- {fileID: 1836412401}
- {fileID: 1305945111}
- {fileID: 1920416618}
+ - {fileID: 1227271788}
diff --git a/Runtime/XTable/Rendering/Component/XericUIActionTable.cs b/Runtime/XTable/Rendering/Component/XericUIActionTable.cs
index f82c54f..76fcdac 100644
--- a/Runtime/XTable/Rendering/Component/XericUIActionTable.cs
+++ b/Runtime/XTable/Rendering/Component/XericUIActionTable.cs
@@ -50,6 +50,13 @@ namespace XericUI.XTable.Rendering.Component
private int m_SelectedRow = -1;
private int m_SelectedCol = -1;
+
+ // 多选范围
+ private int m_SelectStartRow = -1;
+ private int m_SelectStartCol = -1;
+ private int m_SelectEndRow = -1;
+ private int m_SelectEndCol = -1;
+
[System.NonSerialized] private GameObject m_BackgroundGo;
private float m_TotalWidth;
@@ -71,7 +78,12 @@ namespace XericUI.XTable.Rendering.Component
public XTableData TableData
{
- get => m_TableData;
+ get
+ {
+ if (m_TableData == null)
+ m_TableData = new XTableData();
+ return m_TableData;
+ }
set { m_TableData = value; MarkDirty(TableDirtyType.DataChanged); }
}
@@ -82,6 +94,23 @@ namespace XericUI.XTable.Rendering.Component
public int SelectedRow => m_SelectedRow;
public int SelectedCol => m_SelectedCol;
+ public int SelectStartRow => m_SelectStartRow;
+ public int SelectStartCol => m_SelectStartCol;
+ public int SelectEndRow => m_SelectEndRow;
+ public int SelectEndCol => m_SelectEndCol;
+ public bool HasMultiSelection => m_SelectStartRow >= 0 && m_SelectEndRow >= 0;
+
+ /// 判断单元格是否在多选范围内
+ public bool IsInSelectionRange(int row, int col)
+ {
+ if (!HasMultiSelection) return false;
+ int minR = Mathf.Min(m_SelectStartRow, m_SelectEndRow);
+ int maxR = Mathf.Max(m_SelectStartRow, m_SelectEndRow);
+ int minC = Mathf.Min(m_SelectStartCol, m_SelectEndCol);
+ int maxC = Mathf.Max(m_SelectStartCol, m_SelectEndCol);
+ return row >= minR && row <= maxR && col >= minC && col <= maxC;
+ }
+
#endregion
#region 生命周期
@@ -148,7 +177,7 @@ namespace XericUI.XTable.Rendering.Component
#region 默认示例数据
- private bool m_DefaultDataCreated;
+ [System.NonSerialized] private bool m_DefaultDataCreated;
private void CreateDefaultSampleData()
{
@@ -168,11 +197,11 @@ namespace XericUI.XTable.Rendering.Component
private void SetCellTextInternal(int row, int col, string text, bool skipDirty)
{
- var data = m_TableData.GetCell(row, col);
+ var data = TableData.GetCell(row, col);
if (data == null)
{
data = new XTableCellData();
- m_TableData.SetCell(row, col, data);
+ TableData.SetCell(row, col, data);
}
data.Text = text;
if (!skipDirty) MarkDirty(TableDirtyType.DataChanged);
@@ -221,7 +250,7 @@ namespace XericUI.XTable.Rendering.Component
public void SetCellData(int row, int col, XTableCellData data)
{
- m_TableData.SetCell(row, col, data);
+ TableData.SetCell(row, col, data);
MarkDirty(TableDirtyType.DataChanged);
}
@@ -231,37 +260,70 @@ namespace XericUI.XTable.Rendering.Component
}
public XTableCellData GetCellData(int row, int col)
- => m_TableData?.GetCell(row, col);
+ => TableData.GetCell(row, col);
public void MergeCells(int startRow, int startCol, int rowSpan, int colSpan)
{
- m_TableData.MergeCells(startRow, startCol, rowSpan, colSpan);
+ TableData.MergeCells(startRow, startCol, rowSpan, colSpan);
MarkDirty(TableDirtyType.DataChanged);
}
public void UnmergeCells(int startRow, int startCol)
{
- m_TableData.UnmergeCells(startRow, startCol);
+ TableData.UnmergeCells(startRow, startCol);
MarkDirty(TableDirtyType.DataChanged);
}
public void SelectCell(int row, int col)
{
+ ClearMultiSelection();
m_SelectedRow = row;
m_SelectedCol = col;
- MarkDirty(TableDirtyType.DataChanged);
+ MarkDirty(TableDirtyType.SelectionChanged);
}
public void ClearSelection()
{
m_SelectedRow = -1;
m_SelectedCol = -1;
- MarkDirty(TableDirtyType.DataChanged);
+ ClearMultiSelection();
+ MarkDirty(TableDirtyType.SelectionChanged);
+ }
+
+ /// 开始多选(以当前格为锚点)
+ public void StartMultiSelect(int row, int col)
+ {
+ m_SelectStartRow = row;
+ m_SelectStartCol = col;
+ m_SelectEndRow = row;
+ m_SelectEndCol = col;
+ m_SelectedRow = row;
+ m_SelectedCol = col;
+ MarkDirty(TableDirtyType.SelectionChanged);
+ }
+
+ /// 扩展多选范围到目标格
+ public void ExtendMultiSelect(int row, int col)
+ {
+ m_SelectEndRow = row;
+ m_SelectEndCol = col;
+ m_SelectedRow = row;
+ m_SelectedCol = col;
+ MarkDirty(TableDirtyType.SelectionChanged);
+ }
+
+ /// 清除多选范围
+ public void ClearMultiSelection()
+ {
+ m_SelectStartRow = -1;
+ m_SelectStartCol = -1;
+ m_SelectEndRow = -1;
+ m_SelectEndCol = -1;
}
public void RefreshView()
{
- if (m_TableData == null || m_Assembler == null) return;
+ if (m_Assembler == null) return;
if (m_RowHeights == null || m_ColWidths == null) return;
if (m_RowHeights.Length == 0 || m_ColWidths.Length == 0) return;
@@ -354,6 +416,8 @@ namespace XericUI.XTable.Rendering.Component
Color fgColor = GetStyleColor(m_DefaultStyleNamespace, "/cell/fg/color",
new Color(0.05f, 0.05f, 0.05f));
Color selectionColor = new Color(0.18f, 0.42f, 0.82f, 0.25f);
+ Color multiSelectColor = new Color(0.18f, 0.42f, 0.82f, 0.12f);
+ Color focusColor = new Color(0.22f, 0.55f, 0.95f, 0.35f);
int fontSize = GetStyleInt(m_DefaultStyleNamespace, "/cell/font/size", 14);
for (int r = sr; r < er && r < m_RowHeights.Length; r++)
@@ -364,10 +428,19 @@ namespace XericUI.XTable.Rendering.Component
float cellY = -GetRowTopY(r);
float cellW = m_ColWidths[c];
float cellH = m_RowHeights[r];
- XTableCellData data = m_TableData.GetCell(r, c);
+ XTableCellData data = TableData.GetCell(r, c);
- // 选中高亮背景
- if (r == m_SelectedRow && c == m_SelectedCol)
+ // 多选范围高亮(覆盖被选中范围内的所有格)
+ if (IsInSelectionRange(r, c))
+ {
+ var selImg = m_Assembler.GetImage("cell_multiselect");
+ selImg.Rect.anchoredPosition = new Vector2(cellX, cellY);
+ selImg.Rect.sizeDelta = new Vector2(cellW, cellH);
+ selImg.Image.color = (r == m_SelectedRow && c == m_SelectedCol)
+ ? focusColor : multiSelectColor;
+ }
+ // 单选高亮
+ else if (r == m_SelectedRow && c == m_SelectedCol)
{
var selImg = m_Assembler.GetImage("cell_select");
selImg.Rect.anchoredPosition = new Vector2(cellX, cellY);