This commit is contained in:
logonkhi
2025-11-14 17:02:38 +09:00
parent c98c1d9d9a
commit 934fff54a7
13 changed files with 579 additions and 162 deletions

File diff suppressed because one or more lines are too long

View File

@@ -40,7 +40,7 @@ RectTransform:
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_SizeDelta: {x: 268, y: 0}
m_Pivot: {x: 0, y: 1}
--- !u!114 &9080525835291741393
MonoBehaviour:
@@ -80,7 +80,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalFit: 2
m_HorizontalFit: 0
m_VerticalFit: 2
--- !u!114 &3350669364680364773
MonoBehaviour:
@@ -184,7 +184,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 20, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0, y: 1}
--- !u!114 &1842670862128736786
@@ -200,7 +200,7 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
m_Padding:
m_Left: 0
m_Left: 20
m_Right: 0
m_Top: 0
m_Bottom: 0
@@ -361,6 +361,7 @@ MonoBehaviour:
childRoot: {fileID: 1842670862128736785}
selectedBg: {fileID: 4496758519719229624}
itemButton: {fileID: 6688992559754752639}
layout: {fileID: 1842670860593731849}
--- !u!114 &5444376809909714340
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -570,10 +571,10 @@ RectTransform:
m_Children: []
m_Father: {fileID: 1842670860593731849}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 280, y: 20}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0, y: 1}
--- !u!222 &8781608781722668640
CanvasRenderer:
@@ -863,10 +864,10 @@ RectTransform:
m_Children: []
m_Father: {fileID: 1842670860593731849}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 300, y: 20}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0, y: 1}
--- !u!222 &5525489389801839842
CanvasRenderer:

View File

@@ -1167,7 +1167,7 @@ RectTransform:
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.00007725624}
m_AnchoredPosition: {x: 0, y: 0.00021767142}
m_SizeDelta: {x: 1920, y: 1020}
m_Pivot: {x: 0, y: 1}
--- !u!222 &7045571067825403265
@@ -1329,7 +1329,7 @@ MonoBehaviour:
m_HandleRect: {fileID: 2403078154567262100}
m_Direction: 0
m_Value: 0
m_Size: 0.23307292
m_Size: 0.19557291
m_NumberOfSteps: 0
m_OnValueChanged:
m_PersistentCalls:
@@ -1931,6 +1931,10 @@ PrefabInstance:
serializedVersion: 3
m_TransformParent: {fileID: 906658657234234412}
m_Modifications:
- target: {fileID: 709763408010213073, guid: c6c35cdcefd487f4b910ceed76b50a8f, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1574318677252675885, guid: c6c35cdcefd487f4b910ceed76b50a8f, type: 3}
propertyPath: m_Pivot.x
value: 0
@@ -2011,22 +2015,6 @@ PrefabInstance:
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1765160980165362397, guid: c6c35cdcefd487f4b910ceed76b50a8f, type: 3}
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1765160980165362397, guid: c6c35cdcefd487f4b910ceed76b50a8f, type: 3}
propertyPath: m_AnchorMin.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1765160980165362397, guid: c6c35cdcefd487f4b910ceed76b50a8f, type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1765160980165362397, guid: c6c35cdcefd487f4b910ceed76b50a8f, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 1883121240313448487, guid: c6c35cdcefd487f4b910ceed76b50a8f, type: 3}
propertyPath: m_SizeDelta.x
value: 0
@@ -2039,21 +2027,9 @@ PrefabInstance:
propertyPath: m_Name
value: ShiHierarchyWindow
objectReference: {fileID: 0}
- target: {fileID: 2792550393869914720, guid: c6c35cdcefd487f4b910ceed76b50a8f, type: 3}
propertyPath: m_OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_Target
value:
objectReference: {fileID: 8778177112406360378}
- target: {fileID: 2792550393869914720, guid: c6c35cdcefd487f4b910ceed76b50a8f, type: 3}
propertyPath: m_OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_MethodName
value: Close
objectReference: {fileID: 0}
- target: {fileID: 2792550393869914720, guid: c6c35cdcefd487f4b910ceed76b50a8f, type: 3}
propertyPath: m_OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_TargetAssemblyTypeName
value: SHI.modal.ModelDetailListView, Assembly-CSharp
objectReference: {fileID: 0}
- target: {fileID: 3351413207641142582, guid: c6c35cdcefd487f4b910ceed76b50a8f, type: 3}
propertyPath: m_SizeDelta.y
value: 2
propertyPath: m_AnchoredPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4429635802794036160, guid: c6c35cdcefd487f4b910ceed76b50a8f, type: 3}
propertyPath: m_SizeDelta.x
@@ -2071,10 +2047,6 @@ PrefabInstance:
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4629025237416871861, guid: c6c35cdcefd487f4b910ceed76b50a8f, type: 3}
propertyPath: m_AnchorMin.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4817867488375858252, guid: c6c35cdcefd487f4b910ceed76b50a8f, type: 3}
propertyPath: m_AnchorMax.x
value: 0
@@ -2083,10 +2055,6 @@ PrefabInstance:
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5551319486076175234, guid: c6c35cdcefd487f4b910ceed76b50a8f, type: 3}
propertyPath: itemPrefab
value:
objectReference: {fileID: 3936859260737040123, guid: 6d3ce8d71bb960e49a93e9ac847b300f, type: 3}
- target: {fileID: 6187330824577769946, guid: c6c35cdcefd487f4b910ceed76b50a8f, type: 3}
propertyPath: m_Size
value: 1
@@ -2107,14 +2075,6 @@ PrefabInstance:
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7450804729565234258, guid: c6c35cdcefd487f4b910ceed76b50a8f, type: 3}
propertyPath: m_AnchorMin.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7660962889100034149, guid: c6c35cdcefd487f4b910ceed76b50a8f, type: 3}
propertyPath: itemPrefab
value:
objectReference: {fileID: 3936859260737040123, guid: 6d3ce8d71bb960e49a93e9ac847b300f, type: 3}
- target: {fileID: 8252523176883135037, guid: c6c35cdcefd487f4b910ceed76b50a8f, type: 3}
propertyPath: m_Size
value: 1
@@ -2122,36 +2082,8 @@ PrefabInstance:
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents:
- targetCorrespondingSourceObject: {fileID: 1913501843011813999, guid: c6c35cdcefd487f4b910ceed76b50a8f, type: 3}
insertIndex: -1
addedObject: {fileID: 1142803725087090315}
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: c6c35cdcefd487f4b910ceed76b50a8f, type: 3}
--- !u!1 &1493151791362773288 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 1913501843011813999, guid: c6c35cdcefd487f4b910ceed76b50a8f, type: 3}
m_PrefabInstance: {fileID: 1024184554747646791}
m_PrefabAsset: {fileID: 0}
--- !u!114 &1142803725087090315
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1493151791362773288}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3}
m_Name:
m_EditorClassIdentifier:
m_IgnoreLayout: 0
m_MinWidth: -1
m_MinHeight: -1
m_PreferredWidth: 240
m_PreferredHeight: -1
m_FlexibleWidth: 0
m_FlexibleHeight: -1
m_LayoutPriority: 1
--- !u!224 &2013029954140523114 stripped
RectTransform:
m_CorrespondingSourceObject: {fileID: 1574318677252675885, guid: c6c35cdcefd487f4b910ceed76b50a8f, type: 3}
@@ -2162,7 +2094,7 @@ MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 8639307054254576253, guid: c6c35cdcefd487f4b910ceed76b50a8f, type: 3}
m_PrefabInstance: {fileID: 1024184554747646791}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1493151791362773288}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 59c744534c4342f4b9d032ed55beb194, type: 3}

View File

@@ -550,6 +550,7 @@ GameObject:
- component: {fileID: 1941791058898214053}
- component: {fileID: 5260132368171820871}
- component: {fileID: 8639307054254576253}
- component: {fileID: 5211500305101215241}
m_Layer: 5
m_Name: ShiHierarchyWindow
m_TagString: Untagged
@@ -578,7 +579,7 @@ RectTransform:
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 0, y: -64}
m_SizeDelta: {x: 300, y: -64}
m_SizeDelta: {x: 240, y: -64}
m_Pivot: {x: 0, y: 1}
--- !u!222 &1941791058898214053
CanvasRenderer:
@@ -637,6 +638,26 @@ MonoBehaviour:
loadingImage: {fileID: 1613511791166383164}
loadingRotateSpeed: 360
loadingFillCycle: 0.5
--- !u!114 &5211500305101215241
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1913501843011813999}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3}
m_Name:
m_EditorClassIdentifier:
m_IgnoreLayout: 0
m_MinWidth: -1
m_MinHeight: -1
m_PreferredWidth: 240
m_PreferredHeight: -1
m_FlexibleWidth: 0
m_FlexibleHeight: -1
m_LayoutPriority: 1
--- !u!1 &2176369568386752279
GameObject:
m_ObjectHideFlags: 0
@@ -893,9 +914,9 @@ MonoBehaviour:
m_OnClick:
m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 0}
m_TargetAssemblyTypeName: UVC.UI.Window.PropertyWindow.PropertyWindow, Assembly-CSharp
m_MethodName: Hide
- m_Target: {fileID: 8639307054254576253}
m_TargetAssemblyTypeName: SHI.modal.ModelDetailListView, Assembly-CSharp
m_MethodName: Close
m_Mode: 1
m_Arguments:
m_ObjectArgument: {fileID: 0}
@@ -1311,6 +1332,10 @@ PrefabInstance:
propertyPath: m_Name
value: TreeListSearch
objectReference: {fileID: 0}
- target: {fileID: 4856300785373777908, guid: a030935af8c62d748b6fe3d01bd4851f, type: 3}
propertyPath: m_Size
value: 0.8752399
objectReference: {fileID: 0}
- target: {fileID: 6081086258189437538, guid: a030935af8c62d748b6fe3d01bd4851f, type: 3}
propertyPath: m_AnchorMax.x
value: 0
@@ -1410,7 +1435,7 @@ PrefabInstance:
- target: {fileID: 9000987459549261387, guid: a030935af8c62d748b6fe3d01bd4851f, type: 3}
propertyPath: itemPrefab
value:
objectReference: {fileID: 4190301731963491743, guid: 6d3ce8d71bb960e49a93e9ac847b300f, type: 3}
objectReference: {fileID: 3936859260737040123, guid: 6d3ce8d71bb960e49a93e9ac847b300f, type: 3}
- target: {fileID: 9000987459549261387, guid: a030935af8c62d748b6fe3d01bd4851f, type: 3}
propertyPath: enableDragDrop
value: 0
@@ -1476,6 +1501,10 @@ PrefabInstance:
propertyPath: m_Name
value: TreeList
objectReference: {fileID: 0}
- target: {fileID: 4856300785373777908, guid: a030935af8c62d748b6fe3d01bd4851f, type: 3}
propertyPath: m_Size
value: 0.8771593
objectReference: {fileID: 0}
- target: {fileID: 6081086258189437538, guid: a030935af8c62d748b6fe3d01bd4851f, type: 3}
propertyPath: m_AnchorMax.x
value: 0
@@ -1575,7 +1604,7 @@ PrefabInstance:
- target: {fileID: 9000987459549261387, guid: a030935af8c62d748b6fe3d01bd4851f, type: 3}
propertyPath: itemPrefab
value:
objectReference: {fileID: 4190301731963491743, guid: 6d3ce8d71bb960e49a93e9ac847b300f, type: 3}
objectReference: {fileID: 3936859260737040123, guid: 6d3ce8d71bb960e49a93e9ac847b300f, type: 3}
- target: {fileID: 9000987459549261387, guid: a030935af8c62d748b6fe3d01bd4851f, type: 3}
propertyPath: enableDragDrop
value: 0

View File

@@ -131,9 +131,9 @@ RectTransform:
m_Father: {fileID: 1842670862426916798}
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: -20}
m_SizeDelta: {x: 10, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: -33}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0, y: 1}
--- !u!114 &1842670861640538160
MonoBehaviour:
@@ -185,7 +185,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 20, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0, y: 1}
--- !u!114 &1842670862128736786
@@ -201,7 +201,7 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
m_Padding:
m_Left: 0
m_Left: 20
m_Right: 0
m_Top: 0
m_Bottom: 0
@@ -326,7 +326,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalFit: 2
m_HorizontalFit: 0
m_VerticalFit: 2
--- !u!114 &1842670862426916795
MonoBehaviour:
@@ -362,6 +362,7 @@ MonoBehaviour:
childRoot: {fileID: 1842670862128736785}
selectedBg: {fileID: 4496758519719229624}
itemButton: {fileID: 6688992559754752639}
layout: {fileID: 1842670860593731849}
visibleToggle: {fileID: 6281030357286915976}
--- !u!114 &5444376809909714340
MonoBehaviour:
@@ -376,7 +377,7 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
dragAlpha: 0.5
enableDragDrop: 1
enableDragDrop: 0
dropEdgeRatio: 0.3
autoScrollWhileDragging: 1
autoScrollPixelsPerSecond: 800
@@ -820,7 +821,7 @@ MonoBehaviour:
m_OnClick:
m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 0}
- m_Target: {fileID: 3936859260737040123}
m_TargetAssemblyTypeName: UVC.UI.List.Tree.TreeListItem, Assembly-CSharp
m_MethodName: ToggleChild
m_Mode: 1
@@ -1036,14 +1037,26 @@ PrefabInstance:
propertyPath: offSprite
value:
objectReference: {fileID: 21300000, guid: 4bf22c6843632e7498852dfd90b193f0, type: 3}
- target: {fileID: 8218436774850926758, guid: 980df90e424253b40aedc29b34f04e3d, type: 3}
propertyPath: OnValueChanged.m_PersistentCalls.m_Calls.Array.size
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8218436774850926758, guid: 980df90e424253b40aedc29b34f04e3d, type: 3}
propertyPath: onValueChanged.m_PersistentCalls.m_Calls.Array.size
value: 1
objectReference: {fileID: 0}
- target: {fileID: 8218436774850926758, guid: 980df90e424253b40aedc29b34f04e3d, type: 3}
propertyPath: OnValueChanged.m_PersistentCalls.m_Calls.Array.data[0].m_Mode
value: 1
objectReference: {fileID: 0}
- target: {fileID: 8218436774850926758, guid: 980df90e424253b40aedc29b34f04e3d, type: 3}
propertyPath: onValueChanged.m_PersistentCalls.m_Calls.Array.data[0].m_Mode
value: 5
objectReference: {fileID: 0}
- target: {fileID: 8218436774850926758, guid: 980df90e424253b40aedc29b34f04e3d, type: 3}
propertyPath: OnValueChanged.m_PersistentCalls.m_Calls.Array.data[0].m_CallState
value: 2
objectReference: {fileID: 0}
- target: {fileID: 8218436774850926758, guid: 980df90e424253b40aedc29b34f04e3d, type: 3}
propertyPath: onValueChanged.m_PersistentCalls.m_Calls.Array.data[0].m_CallState
value: 2

View File

@@ -64,14 +64,12 @@ namespace SHI.modal
{
listView.OnItemSelected += data =>
{
Debug.Log($"BlockDetailModal: ListView OnItemSelected, data:{data==null}");
if (data == null) return;
HandleSelection(data.Id, "ListView");
};
listView.OnItemDeselected += data =>
{
Debug.Log("BlockDetailModal: ListView OnItemDeselected");
HandleDeselection(data.Id, "ListView");
};
@@ -156,7 +154,7 @@ namespace SHI.modal
_idToKey[it.Id] = it.ExternalKey;
}
}
if (listView != null) listView.Populate(items);
if (listView != null) listView.SetupData(items);
if (chartView != null) chartView.LoadData(gantt);
}

View File

@@ -18,15 +18,14 @@ namespace SHI.modal
[SerializeField]
protected ImageToggle visibleToggle;
public virtual void Init(TreeListItemData data, TreeList control, TreeListDragDropManager dragDropManager)
public override void Init(TreeListItemData data, TreeList control, TreeListDragDropManager dragDropManager)
{
base.Init(data, control, dragDropManager);
Debug.Log($"ModelDetailListItem Init. visibleToggle:{visibleToggle==null}");
if (visibleToggle != null)
{
visibleToggle.OnValueChanged.AddListener(isOn =>
{
if(data is ModelDetailListItemData modelData)
if (data is ModelDetailListItemData modelData)
{
modelData.IsVisible = isOn;
modelData.OnClickVisibleAction?.Invoke(modelData, isOn);

View File

@@ -136,10 +136,16 @@ namespace SHI.modal
/// NEW: 데이터 주입
/// </summary>
/// <param name="items"></param>
public void Populate(IEnumerable<ModelDetailListItemData> items)
public void SetupData(IEnumerable<ModelDetailListItemData> items)
{
// 기존 아이템 클리어
treeList.ClearItems();
SetVisiblilityAction(items);
AddItems(items);
}
private void SetVisiblilityAction(IEnumerable<ModelDetailListItemData> items)
{
foreach (var item in items)
{
// 가시성 아이콘 클릭 연동
@@ -152,9 +158,11 @@ namespace SHI.modal
OnVisibilityChanged?.Invoke(md.Id, isVisible);
}
};
treeList.AddItem<ModelDetailListItem>(item);
if(item.Children != null && item.Children.Count > 0)
{
SetVisiblilityAction(item.Children.OfType<ModelDetailListItemData>());
}
}
treeList.ScheduleFlattenedUpdate();
}
/// <summary>
@@ -179,6 +187,15 @@ namespace SHI.modal
treeList.AddItem<ModelDetailListItem>(data);
}
/// <summary>
/// 메인 트리에 항목들을 추가합니다.
/// </summary>
/// <param name="dataList">추가 할 데이터들</param>
public void AddItems(IEnumerable<TreeListItemData> dataList)
{
treeList.AddItems<ModelDetailListItem>(dataList);
}
/// <summary>
/// 메인 트리에 항목을 특정 인덱스에 삽입합니다.
/// </summary>
@@ -214,7 +231,6 @@ namespace SHI.modal
public void SelectItem(string name)
{
//검색 중이면 취소
CancelSearch();
treeListSearch.gameObject.SetActive(false);
treeList.gameObject.SetActive(true);
@@ -222,6 +238,15 @@ namespace SHI.modal
treeList.SelectItem(name);
}
/// <summary>
/// 이름으로 아이템 선택 해제
/// </summary>
/// <param name="name"></param>
public void DeselectItem(string name)
{
treeList.DeselectItem(name);
}
protected void StartLoadingAnimation()
{
if (loadingImage == null) return;

View File

@@ -53,12 +53,15 @@ namespace SHI.modal
private float _yawStart;
private float _pitchStart;
private Quaternion _modelStartRot;
private Vector3 _modelStartPos; // RMB 드래그 시작 시 모델 위치
private Vector3 _rmbPivot; // RMB 회전의 피벗(모델 중심)
private readonly Dictionary<Guid, GameObject> _idToObject = new Dictionary<Guid, GameObject>();
private readonly Dictionary<GameObject, (Renderer[] rends, UnityEngine.Material[][] originals)> _matCache = new Dictionary<GameObject, (Renderer[], UnityEngine.Material[][])>();
private GameObject? _root;
private Guid? _focusedId;
public async UniTask<IEnumerable<ModelDetailListItemData>> LoadModelAsync(string path, CancellationToken ct)
{
Debug.Log($"ModelDetailView.LoadModelAsync: {path}");
@@ -345,8 +348,8 @@ namespace SHI.modal
dist = Mathf.Clamp(dist, 1f, 1e4f);
_viewCamera.transform.position = center + new Vector3(1, 0.5f, 1).normalized * dist;
_viewCamera.transform.LookAt(center);
_viewCamera.nearClipPlane = Mathf.Max(0.01f, dist - radius * 2f);
_viewCamera.farClipPlane = dist + radius * 4f;
//_viewCamera.nearClipPlane = Mathf.Max(0.01f, dist - radius * 2f);
//_viewCamera.farClipPlane = dist + radius * 4f;
_orbitTarget = center;
_orbitDistance = Vector3.Distance(_viewCamera.transform.position, _orbitTarget);
@@ -530,7 +533,7 @@ namespace SHI.modal
// 드래그 상태 전이 처리 (점프 방지)
if (Input.GetMouseButtonDown(2)) { _mmbDragging = true; _mmbLastPos = Input.mousePosition; }
if (Input.GetMouseButtonUp(2)) { _mmbDragging = false; }
if (Input.GetMouseButtonDown(1)) { _rmbDragging = true; _rmbStartPos = Input.mousePosition; _yawStart = _yaw; _pitchStart = _pitch; if (_root != null) _modelStartRot = _root.transform.rotation; }
if (Input.GetMouseButtonDown(1)) { _rmbDragging = true; _rmbStartPos = Input.mousePosition; _yawStart = _yaw; _pitchStart = _pitch; if (_root != null) { _modelStartRot = _root.transform.rotation; _modelStartPos = _root.transform.position; } _rmbPivot = _orbitTarget; }
if (Input.GetMouseButtonUp(1)) { _rmbDragging = false; }
// 가운데 버튼: 모델 이동 (좌/우/상/하) - 카메라 기준, 픽셀 델타 기반
@@ -565,7 +568,7 @@ namespace SHI.modal
_orbitTarget += deltaZ;
}
// 오른쪽 버튼: 모델 회전 (카메라 기준 yaw/pitch)
// 오른쪽 버튼: 모델 회전 (카메라 기준 yaw/pitch) - 모델 중심(_orbitTarget) 기준으로 회전
if (_rmbDragging && _root != null)
{
Vector3 cur = Input.mousePosition;
@@ -573,10 +576,16 @@ namespace SHI.modal
// 반전: 좌우/상하 모두 반대 방향으로 회전
float yaw = -dpAbs.x * rotateDegPerPixel; // 좌우 반전
float pitch = dpAbs.y * rotateDegPerPixel; // 위아래 반전
// 카메라 기준 축으로 모델 회전
// 카메라 기준 축으로 회전 행렬 구성
Quaternion yawQ = Quaternion.AngleAxis(yaw, _viewCamera.transform.up);
Quaternion pitchQ = Quaternion.AngleAxis(pitch, _viewCamera.transform.right);
_root.transform.rotation = yawQ * pitchQ * _modelStartRot;
Quaternion r = yawQ * pitchQ;
// 피벗(_rmbPivot, 보통 모델 중심) 기준으로 위치+회전 동시 적용
Vector3 startVec = _modelStartPos - _rmbPivot;
_root.transform.position = _rmbPivot + r * startVec;
_root.transform.rotation = r * _modelStartRot;
}
}

View File

@@ -530,6 +530,17 @@ namespace UVC.UI.List.Tree
UpdateFlattenedItemDataList();
}
/// <summary>
/// TreeListItem 프리팹 인스턴스화
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
protected T? Create<T>() where T : TreeListItem
{
T? item = GameObject.Instantiate(ItemPrefab, root) as T;
return item;
}
/// <summary>
/// 새 아이템 추가
///
@@ -548,11 +559,11 @@ namespace UVC.UI.List.Tree
data.Parent = null;
// Instantiate(템플릿, 부모 Transform)
// = 템플릿을 복제하고 부모의 자식으로 설정
T item = GameObject.Instantiate(ItemPrefab, root) as T;
T? item = Create<T>();
// 생성된 아이템 초기화
// 데이터를 UI에 바인딩하고 이벤트 리스너 등록
item.Init(data, this, dragDropManager);
item?.Init(data, this, dragDropManager);
items.Add(data);
// 범위 선택에 필요한 평탄화 리스트 업데이트
@@ -560,6 +571,27 @@ namespace UVC.UI.List.Tree
}
/// <summary>
/// 새 아이템들 추가
/// </summary>
/// <typeparam name="T">추가 할 타입</typeparam>
/// <param name="datas">추가 할 데이터들</param>
public void AddItems<T>(IEnumerable<TreeListItemData> datas) where T : TreeListItem
{
foreach (var data in datas)
{
data.Parent = null;
// Instantiate(템플릿, 부모 Transform)
// = 템플릿을 복제하고 부모의 자식으로 설정
T? item = Create<T>();
// 생성된 아이템 초기화
// 데이터를 UI에 바인딩하고 이벤트 리스너 등록
item?.Init(data, this, dragDropManager);
items.Add(data);
}
UpdateFlattenedItemDataList();
}
/// <summary>
/// 지정 인덱스에 아이템 추가
///
@@ -970,6 +1002,19 @@ namespace UVC.UI.List.Tree
OnItemSelectionChanged?.Invoke(data, true);
}
/// <summary>
/// 이름으로 아이템 선택 해제
/// </summary>
/// <param name="name"></param>
public void DeselectItem(string name)
{
var item = allItemDataFlattened.FirstOrDefault(x => x.Name == name);
if (item != null)
{
DeselectItem(item);
}
}
/// <summary>
/// 아이템 선택 해제
///

View File

@@ -72,6 +72,12 @@ namespace UVC.UI.List.Tree
[SerializeField]
protected Button itemButton;
/// <summary>
/// text가 배치 된 RectTransform.
/// </summary>
[SerializeField]
protected RectTransform layout;
#endregion
#region (Data Fields)
@@ -91,6 +97,8 @@ namespace UVC.UI.List.Tree
/// </summary>
protected bool isAnimating = false;
protected VerticalLayoutGroup? childRootLayoutGroup = null;
#endregion
#region (Initialization)
@@ -123,7 +131,12 @@ namespace UVC.UI.List.Tree
valueText.text = data.Name;
// 3. 자식 아이템들을 UI로 생성
Debug.Log("Creating Children for " + data.Name + ", " + data.Children.Count);
//Debug.Log("Creating Children for " + data.Name + ", " + data.Children.Count);
if (childRootLayoutGroup == null)
{
childRootLayoutGroup = childRoot.GetComponent<VerticalLayoutGroup>();
}
if (data.Children.Count > 0)
@@ -164,7 +177,7 @@ namespace UVC.UI.List.Tree
if (dragHandler == null)
{
dragHandler = gameObject.AddComponent<TreeListItemDragHandler>();
Debug.Log($"[TreeListItem.Init] 새로운 TreeListItemDragHandler 추가: {data.Name}");
//Debug.Log($"[TreeListItem.Init] 새로운 TreeListItemDragHandler 추가: {data.Name}");
}
dragHandler.SetDragDropManager(this, control, dragDropManager);
@@ -173,7 +186,7 @@ namespace UVC.UI.List.Tree
// Register view to map
treeList.RegisterView(data, this);
Debug.Log($"[TreeListItem.Init] 초기화 완료: {data.Name}");
//Debug.Log($"[TreeListItem.Init] 초기화 완료: {data.Name}");
}
#endregion
@@ -305,7 +318,7 @@ namespace UVC.UI.List.Tree
else if (changedType == ChangedType.RemoveChild)
{
//따로 할것 없음 - 펼침 버튼 갱신 용
Debug.Log($"RemoveChild 처리 완료 {changedData.Name}, {index}");
//Debug.Log($"RemoveChild 처리 완료 {changedData.Name}, {index}");
}
UniTask.DelayFrame(1).ContinueWith(() =>
@@ -539,6 +552,12 @@ namespace UVC.UI.List.Tree
treeList.ItemPrefab, // 복제할 프리팹
childRoot // 부모로 배치할 위치
);
//item.layout의 너비를 childRootLayoutGroup의 padding.left 만큼 줄이기
if (item != null && item.layout != null && childRootLayoutGroup != null)
{
item.layout.sizeDelta = new Vector2(layout.sizeDelta.x - childRootLayoutGroup.padding.left, item.layout.sizeDelta.y);
}
// 2. 생성된 아이템 초기화
item.Init(data, treeList, treeList.DragDropManager);

View File

@@ -92,12 +92,11 @@ namespace UVC.UI.List.Tree
treeList = list;
dragDropManager = manager;
treeListRootParent = list.Root.parent as RectTransform;
Debug.Log($"[TreeListItemDragHandler] 드래그 핸들러 설정: {item.Data?.Name ?? "Unknown"}");
//Debug.Log($"[TreeListItemDragHandler] 드래그 핸들러 설정: {item.Data?.Name ?? "Unknown"}");
}
public void OnBeginDrag(PointerEventData eventData)
{
Debug.Log("[OnPointerDown]");
if (!enableDragDrop || treeListItem?.Data == null || dragDropManager == null)
{
return;
@@ -117,7 +116,7 @@ namespace UVC.UI.List.Tree
dragOffset = localPoint;
_lastPointerScreenPos = eventData.position;
Debug.Log($"[OnPointerDown] {treeListItem.Data.Name}에 포인터 다운, offset: {dragOffset}");
//Debug.Log($"[OnPointerDown] {treeListItem.Data.Name}에 포인터 다운, offset: {dragOffset}");
}
public void OnDrag(PointerEventData eventData)
@@ -134,7 +133,7 @@ namespace UVC.UI.List.Tree
}
_lastPointerScreenPos = eventData.position;
Debug.Log($"[OnDrag] {treeListItem.Data.Name} 드래그 중");
//Debug.Log($"[OnDrag] {treeListItem.Data.Name} 드래그 중");
if (!dragDropManager.IsDragging)
{
@@ -151,7 +150,7 @@ namespace UVC.UI.List.Tree
CreateDropIndicator();
Debug.Log($"[OnDrag] {treeListItem.Data.Name} 드래그 시작");
//Debug.Log($"[OnDrag] {treeListItem.Data.Name} 드래그 시작");
}
// 마우스 위의 드롭 대상 찾기
@@ -191,13 +190,12 @@ namespace UVC.UI.List.Tree
public void OnEndDrag(PointerEventData eventData)
{
Debug.Log("[OnPointerUp]");
if (!enableDragDrop || dragDropManager == null)
{
return;
}
Debug.Log("[OnPointerUp] 드래그 완료");
//Debug.Log("[OnPointerUp] 드래그 완료");
if (canvasGroup != null)
{
@@ -228,7 +226,7 @@ namespace UVC.UI.List.Tree
if (treeListItem?.Data != null)
{
var result = dragDropManager.TryDrop(targetItem?.Data);
Debug.Log($"[OnPointerUp] 드롭 결과: {(result ? "" : "")}");
//Debug.Log($"[OnPointerUp] 드롭 결과: {(result ? "성공" : "실패")}");
if (result) HandleDropSuccess(treeListItem.Data, targetItem);
}
@@ -305,7 +303,6 @@ namespace UVC.UI.List.Tree
private void CreateDropIndicator()
{
Debug.Log($"[CreateDropIndicator] dropIndicator != null:{dropIndicator != null}");
if (dropIndicator != null)
{
return;
@@ -318,7 +315,7 @@ namespace UVC.UI.List.Tree
dropIndicatorRect = existingDropIndicator.GetComponent<RectTransform>();
dropIndicatorParent = treeListRootParent;
Debug.Log("[CreateDropIndicator] 기존 DropIndicator를 재사용합니다");
//Debug.Log("[CreateDropIndicator] 기존 DropIndicator를 재사용합니다");
return;
}
@@ -348,7 +345,7 @@ namespace UVC.UI.List.Tree
dropIndicator.raycastTarget = false;
indicatorGo.SetActive(false);
Debug.Log("[CreateDropIndicator] 드롭 위치 표시 막대 생성됨");
//Debug.Log("[CreateDropIndicator] 드롭 위치 표시 막대 생성됨");
}
private void UpdateDropIndicator(TreeListItem? targetItem)
@@ -422,7 +419,7 @@ namespace UVC.UI.List.Tree
dropIndicatorRect.anchoredPosition = new Vector2(indicatorX, indicatorY);
dropIndicatorRect.sizeDelta = new Vector2(dropIndicatorRect.sizeDelta.x, indicatorHeight);
Debug.Log($"[UpdateDropIndicator] {targetItem?.Data?.Name} 위치: {dropPosition}, targetY: {targetWorldY}, parentY: {parentWorldY}, indicatorY: {indicatorY}");
//Debug.Log($"[UpdateDropIndicator] {targetItem?.Data?.Name} 위치: {dropPosition}, targetY: {targetWorldY}, parentY: {parentWorldY}, indicatorY: {indicatorY}");
}
private void HideDropIndicator()
@@ -446,12 +443,10 @@ namespace UVC.UI.List.Tree
Transform child = treeListRootParent.GetChild(i);
if (child.name == "DropIndicator")
{
Debug.Log("[FindDropIndicatorInRoot] DropIndicator를 찾았습니다");
return child.gameObject;
}
}
Debug.Log("[FindDropIndicatorInRoot] DropIndicator를 찾지 못했습니다");
return null;
}
@@ -476,7 +471,7 @@ namespace UVC.UI.List.Tree
es.RaycastAll(eventData, s_RaycastResults);
Debug.Log($"[GetItemAtMousePosition] Raycast 결과: {s_RaycastResults.Count}개");
//Debug.Log($"[GetItemAtMousePosition] Raycast 결과: {s_RaycastResults.Count}개");
for (int i = 0; i < s_RaycastResults.Count; i++)
{
@@ -484,7 +479,7 @@ namespace UVC.UI.List.Tree
var item = result.gameObject.GetComponentInParent<TreeListItem>();
if (item != null)
{
Debug.Log($"[GetItemAtMousePosition] 찾은 아이템: {item.Data?.Name ?? "Unknown"}");
//Debug.Log($"[GetItemAtMousePosition] 찾은 아이템: {item.Data?.Name ?? "Unknown"}");
return item;
}
}
@@ -501,7 +496,6 @@ namespace UVC.UI.List.Tree
if (targetItem == null)
{
Debug.Log("[HandleDropSuccess] 루트로 이동");
MoveToRoot(draggedData);
treeList.ScheduleFlattenedUpdate();
return;
@@ -515,7 +509,7 @@ namespace UVC.UI.List.Tree
var dropPosition = GetDropPosition(targetItem.GetComponent<RectTransform>());
Debug.Log($"[HandleDropSuccess] 드롭 위치: {targetItem?.Data?.Name} {dropPosition}");
//Debug.Log($"[HandleDropSuccess] 드롭 위치: {targetItem?.Data?.Name} {dropPosition}");
switch (dropPosition)
{
@@ -561,7 +555,7 @@ namespace UVC.UI.List.Tree
private void MoveToRoot(TreeListItemData draggedData)
{
Debug.Log($"[MoveToRoot] {draggedData.Name}을(를) 루트로 이동");
//Debug.Log($"[MoveToRoot] {draggedData.Name}을(를) 루트로 이동");
if (treeList == null)
{
@@ -583,13 +577,13 @@ namespace UVC.UI.List.Tree
{
treeList.AddCloneItem(draggedData);
}
Debug.Log($"[MoveToRoot] {draggedData.Name}을(를) 루트 레벨의 끝에 추가");
//Debug.Log($"[MoveToRoot] {draggedData.Name}을(를) 루트 레벨의 끝에 추가");
}
private void MoveAsChild(TreeListItemData draggedData, TreeListItemData targetData)
{
targetData.AddCloneChild(draggedData);
Debug.Log($"[MoveAsChild] {draggedData.Name}을(를) {targetData.Name}의 자식으로 이동");
//Debug.Log($"[MoveAsChild] {draggedData.Name}을(를) {targetData.Name}의 자식으로 이동");
}
private void MoveBefore(TreeListItemData draggedData, TreeListItemData targetData)
@@ -604,7 +598,7 @@ namespace UVC.UI.List.Tree
if (targetIndex >= 0)
{
draggedData.Parent.SwapChild(draggedData, targetIndex);
Debug.Log($"[MoveBefore] {draggedData.Name}을(를) {targetData.Name} 앞으로 {targetIndex} 순서 변경");
//Debug.Log($"[MoveBefore] {draggedData.Name}을(를) {targetData.Name} 앞으로 {targetIndex} 순서 변경");
}
}
else
@@ -617,7 +611,7 @@ namespace UVC.UI.List.Tree
if (targetIndex >= 0)
{
treeList?.SwapItem(draggedData, targetIndex);
Debug.Log($"[MoveBefore] {draggedData.Name}을(를) {targetData.Name} 앞으로 {targetIndex} 순서 변경(루트레벨)");
//Debug.Log($"[MoveBefore] {draggedData.Name}을(를) {targetData.Name} 앞으로 {targetIndex} 순서 변경(루트레벨)");
}
}
}
@@ -631,7 +625,7 @@ namespace UVC.UI.List.Tree
if (targetIndex >= 0)
{
parentData.AddCloneAtChild(draggedData, targetIndex);
Debug.Log($"[MoveBefore] {draggedData.Name}을(를) {targetData.Name} 앞으로 {targetIndex} 이동");
//Debug.Log($"[MoveBefore] {draggedData.Name}을(를) {targetData.Name} 앞으로 {targetIndex} 이동");
}
}
else
@@ -643,7 +637,7 @@ namespace UVC.UI.List.Tree
if (targetIndex >= 0)
{
treeList?.AddCloneItemAt(draggedData, targetIndex);
Debug.Log($"[MoveBefore] {draggedData.Name}을(를) {targetData.Name} 앞으로 {targetIndex} 이동 (루트 레벨)");
//Debug.Log($"[MoveBefore] {draggedData.Name}을(를) {targetData.Name} 앞으로 {targetIndex} 이동 (루트 레벨)");
}
}
}
@@ -662,7 +656,7 @@ namespace UVC.UI.List.Tree
if (targetIndex >= 0)
{
draggedData.Parent.SwapChild(draggedData, targetIndex + 1);
Debug.Log($"[MoveAfter] {draggedData.Name}을(를) {targetData.Name} 뒤로 {targetIndex} 순서 변경");
//Debug.Log($"[MoveAfter] {draggedData.Name}을(를) {targetData.Name} 뒤로 {targetIndex} 순서 변경");
}
}
else
@@ -675,7 +669,7 @@ namespace UVC.UI.List.Tree
if (targetIndex >= 0)
{
treeList?.SwapItem(draggedData, targetIndex + 1);
Debug.Log($"[MoveAfter] {draggedData.Name}을(를) {targetData.Name} 뒤로 {targetIndex} 순서 변경(루트레벨)");
//Debug.Log($"[MoveAfter] {draggedData.Name}을(를) {targetData.Name} 뒤로 {targetIndex} 순서 변경(루트레벨)");
}
}
}
@@ -690,7 +684,7 @@ namespace UVC.UI.List.Tree
if (targetIndex >= 0)
{
parentData.AddCloneAtChild(draggedData, targetIndex + 1);
Debug.Log($"[MoveAfter] {draggedData.Name}을(를) {targetData.Name} 뒤로 {targetIndex} 이동");
//Debug.Log($"[MoveAfter] {draggedData.Name}을(를) {targetData.Name} 뒤로 {targetIndex} 이동");
}
}
else
@@ -702,7 +696,7 @@ namespace UVC.UI.List.Tree
if (targetIndex >= 0)
{
treeList?.AddCloneItemAt(draggedData, targetIndex + 1);
Debug.Log($"[MoveAfter] {draggedData.Name}을(를) {targetData.Name} 뒤로 {targetIndex} 이동 (루트 레벨)");
//Debug.Log($"[MoveAfter] {draggedData.Name}을(를) {targetData.Name} 뒤로 {targetIndex} 이동 (루트 레벨)");
}
}
}

View File

@@ -132,6 +132,15 @@ namespace UVC.UI.Window
treeList.AddItem<TreeListItem>(data);
}
/// <summary>
/// 메인 트리에 항목들을 추가합니다.
/// </summary>
/// <param name="dataList">추가 할 데이터들</param>
public void AddItems(System.Collections.Generic.IEnumerable<TreeListItemData> dataList)
{
treeList.AddItems<TreeListItem>(dataList);
}
/// <summary>
/// 메인 트리에 항목을 특정 인덱스에 삽입합니다.
/// </summary>
@@ -175,6 +184,15 @@ namespace UVC.UI.Window
treeList.SelectItem(name);
}
/// <summary>
/// 이름으로 아이템 선택 해제
/// </summary>
/// <param name="name"></param>
public void DeselectItem(string name)
{
treeList.DeselectItem(name);
}
protected void StartLoadingAnimation()
{
if (loadingImage == null) return;