2024-11-19 11:48:21 +01:00

326 lines
9.2 KiB
C#

using System;
using UnityEditor;
using UnityEngine;
namespace Gley.UrbanSystem.Editor
{
internal abstract class SettingsWindowBase : EditorWindow
{
private static bool _firstAnchorClicked;
private WindowProperties[] _allWindowsData;
private AllSettingsWindows _allSettingsWindows;
private NavigationRuntimeData _backData;
private SceneCameraTracker _sceneCameraTracker;
private SettingsWindowBase _window;
private Type _defaultWindow;
private RaycastHit _hitInfo;
private bool _playState;
private bool _blockClicks;
private bool _canClick;
private bool _initialized;
protected SetupWindowBase _activeSetupWindow;
internal delegate void RefreshWindow();
internal static RefreshWindow OnRefreshWindow;
internal static void TriggerRefreshWindowEvent()
{
OnRefreshWindow?.Invoke();
}
internal abstract LayerMask GetGroundLayer();
protected abstract void Reinitialize();
protected abstract void MouseMove(Vector3 point);
#region Initialization
protected void Init(SettingsWindowBase window, Type defaultWindowType, WindowProperties[] allWindowsProperties, AllSettingsWindows allSettingsWindows)
{
_allSettingsWindows = allSettingsWindows;
_initialized = false;
_window = window;
_allWindowsData = allWindowsProperties;
_defaultWindow = defaultWindowType;
_sceneCameraTracker = new SceneCameraTracker();
ResetToHomeScreen(_defaultWindow, false);
}
protected virtual void OnEnable()
{
OnRefreshWindow -= Refresh;
OnRefreshWindow += Refresh;
SceneView.duringSceneGui += OnScene;
}
protected virtual void OnDisable()
{
OnRefreshWindow -= Refresh;
BlockClicks(false);
SceneView.duringSceneGui -= OnScene;
}
protected virtual void OnFocus()
{
ResetToHomeScreen(_defaultWindow, false);
}
protected virtual void ResetToHomeScreen(Type defaultWindow, bool now)
{
if (defaultWindow == null || _allSettingsWindows == null || _allWindowsData == null)
{
_initialized = false;
Reinitialize();
}
else
{
if (!now)
{
if (_initialized == true)
return;
}
_initialized = true;
_playState = Application.isPlaying;
_allSettingsWindows.Initialize(_allWindowsData);
_backData = new NavigationRuntimeData(_allSettingsWindows);
SetActiveWindow(defaultWindow, false);
SceneView.RepaintAll();
}
}
#endregion
#region WindowNavigation
internal void SetActiveWindow(Type windowType, bool addCurrent)
{
if (windowType == null)
{
return;
}
if (_activeSetupWindow != null)
{
_activeSetupWindow.DestroyWindow();
}
if (addCurrent)
{
_backData.AddWindow(_activeSetupWindow.GetFullClassName());
}
_activeSetupWindow = ((SetupWindowBase)CreateInstance(windowType)).Initialize(_allSettingsWindows.GetWindowProperties(windowType.Name), this);
BlockClicks(_activeSetupWindow.GetBlockClicksState());
if (_window)
{
_window.Repaint();
}
}
internal string GetBackPath()
{
return _backData.GetBackPath();
}
private void Back()
{
SetActiveWindow(Type.GetType(_backData.RemoveLastWindow()), false);
}
#endregion
#region WindowGUI
protected virtual void OnGUI()
{
if (_playState != Application.isPlaying)
{
ResetToHomeScreen(_defaultWindow, true);
}
EditorStyles.label.wordWrap = true;
EditorGUILayout.Space();
if (_activeSetupWindow == null)
{
if (_defaultWindow == null)
{
return;
}
ResetToHomeScreen(_defaultWindow, false);
}
if (_activeSetupWindow.DrawInWindow(position.width, position.height) == false)
{
Back();
}
}
private void Refresh()
{
if (_window)
{
_window.Repaint();
}
}
#endregion
#region SceneDisplay
protected virtual void OnScene(SceneView obj)
{
if (_playState != Application.isPlaying)
{
ResetToHomeScreen(_defaultWindow, true);
}
if (GleyPrefabUtilities.PrefabChanged())
{
ResetToHomeScreen(_defaultWindow, true);
}
if (_blockClicks == false)
return;
Color handlesColor = Handles.color;
Matrix4x4 handlesMatrix = Handles.matrix;
Draw();
Input();
_sceneCameraTracker.MoveCheck();
Handles.color = handlesColor;
Handles.matrix = handlesMatrix;
}
internal void BlockClicks(bool block)
{
if (_window)
{
_window._blockClicks = block;
}
}
private void Input()
{
HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive));
Event e = Event.current;
if (e.type == EventType.KeyDown && e.control && e.keyCode == KeyCode.Z)
{
UndoAction();
}
if (e.type == EventType.MouseMove)
{
Ray worldRay = HandleUtility.GUIPointToWorldRay(e.mousePosition);
if (GleyPrefabUtilities.EditingInsidePrefab())
{
if (GleyPrefabUtilities.GetScenePrefabRoot().scene.GetPhysicsScene().Raycast(worldRay.origin, worldRay.direction, out _hitInfo, Mathf.Infinity, GetGroundLayer()))
{
_canClick = true;
}
else
{
_canClick = false;
}
}
else
{
if (Physics.Raycast(worldRay, out _hitInfo, Mathf.Infinity, GetGroundLayer()))
{
_canClick = true;
}
else
{
_canClick = false;
}
}
MouseMove(_hitInfo.point);
}
if (_canClick)
{
#if GLEY_PEDESTRIAN_SYSTEM
if (e.type == EventType.Layout && GUIUtility.hotControl == Gley.PedestrianSystem.Internal.PedestrianSystemConstants.PATH_ID)
{
//click on the first gizmo
if (e.shift)
{
_firstAnchorClicked = true;
LeftClick(_hitInfo.point, _firstAnchorClicked);
}
}
else
{
_firstAnchorClicked = false;
}
#endif
if (e.type == EventType.MouseDown && e.shift)
{
if (e.button == 0)
{
LeftClick(_hitInfo.point, _firstAnchorClicked);
e.Use();
}
if (e.button == 1)
{
RightClick(_hitInfo.point);
e.Use();
}
}
}
}
private void LeftClick(Vector3 point, bool clicked)
{
if (_activeSetupWindow != null)
{
_activeSetupWindow.LeftClick(point, clicked);
}
}
private void RightClick(Vector3 point)
{
if (_activeSetupWindow != null)
{
_activeSetupWindow.RightClick(point);
}
}
private void UndoAction()
{
if (_activeSetupWindow != null)
{
_activeSetupWindow.UndoAction();
}
}
private void Draw()
{
_activeSetupWindow.DrawInScene();
}
#endregion
private void OnDestroy()
{
if (_activeSetupWindow != null)
{
_activeSetupWindow.DestroyWindow();
}
}
}
}