修复由于tabledata忘了标记可序列化导致数据全部为null导致报错的问题。

添加快捷键功能。
This commit is contained in:
2026-06-26 23:27:19 +08:00
parent 391beb75ea
commit 2e91832f39
3 changed files with 949 additions and 40 deletions
@@ -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();
}
/// <summary>将行列约束到有效范围,若已到边界则返回 false(不移动)</summary>
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;
@@ -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}
@@ -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;
/// <summary>判断单元格是否在多选范围内</summary>
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);
}
/// <summary>开始多选(以当前格为锚点)</summary>
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);
}
/// <summary>扩展多选范围到目标格</summary>
public void ExtendMultiSelect(int row, int col)
{
m_SelectEndRow = row;
m_SelectEndCol = col;
m_SelectedRow = row;
m_SelectedCol = col;
MarkDirty(TableDirtyType.SelectionChanged);
}
/// <summary>清除多选范围</summary>
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);