| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508 |
- using UnityEngine;
- using UnityEngine.UIElements;
- using System.Reflection;
- public class MapSceneLegendUI : MonoBehaviour, IClickBlocker
- {
- [Header("UI References")]
- public UIDocument uiDocument;
- [Header("Settings")]
- public bool startVisible = true;
- public KeyCode toggleKey = KeyCode.L;
- public bool debugMode = false;
- // UI Elements
- private VisualElement legendContainer;
- private Button toggleButton;
- private VisualElement legendContent;
- private VisualElement nameToggleSection;
- // Name toggle buttons
- private Toggle settlementNamesToggle;
- private Toggle forestNamesToggle;
- private Toggle lakeNamesToggle;
- private Toggle plainNamesToggle;
- private Toggle mountainNamesToggle;
- private Toggle riverNamesToggle;
- // References
- private MapLocationNameDisplay nameDisplay;
- private bool isLegendVisible;
- // Helper method to call methods on WorldSpaceLocationNames using reflection
- private void TryCallWorldSpaceMethod(string methodName, bool parameter)
- {
- var allMonoBehaviours = FindObjectsByType<MonoBehaviour>(FindObjectsSortMode.None);
- foreach (var mb in allMonoBehaviours)
- {
- if (mb.GetType().Name == "WorldSpaceLocationNames")
- {
- var method = mb.GetType().GetMethod(methodName);
- if (method != null)
- {
- method.Invoke(mb, new object[] { parameter });
- break;
- }
- }
- }
- }
- private void Awake()
- {
- if (uiDocument == null)
- uiDocument = GetComponent<UIDocument>();
- }
- private void Start()
- {
- nameDisplay = FindFirstObjectByType<MapLocationNameDisplay>();
- if (debugMode)
- {
- Debug.Log($"MapSceneLegendUI: Starting setup. UIDocument: {(uiDocument != null ? "Found" : "NULL")}");
- Debug.Log($"MapSceneLegendUI: NameDisplay: {(nameDisplay != null ? "Found" : "NULL")}");
- Debug.Log($"MapSceneLegendUI: Root Visual Element: {(uiDocument?.rootVisualElement != null ? "Found" : "NULL")}");
- }
- SetupUI();
- SetLegendVisible(startVisible);
- if (debugMode)
- {
- Debug.Log($"MapSceneLegendUI: Setup complete. Legend visible: {isLegendVisible}");
- Debug.Log($"MapSceneLegendUI: Legend container: {(legendContainer != null ? "Found" : "NULL")}");
- }
- // Register with ClickManager
- if (ClickManager.Instance != null)
- {
- ClickManager.Instance.RegisterClickBlocker(this);
- if (debugMode) Debug.Log("MapSceneLegendUI: Registered with ClickManager");
- }
- else if (debugMode)
- {
- Debug.LogWarning("MapSceneLegendUI: ClickManager not found");
- }
- }
- private void OnDestroy()
- {
- // Unregister from ClickManager
- if (ClickManager.Instance != null)
- {
- ClickManager.Instance.UnregisterClickBlocker(this);
- }
- }
- private void Update()
- {
- if (Input.GetKeyDown(toggleKey))
- {
- ToggleLegend();
- }
- }
- private void SetupUI()
- {
- if (uiDocument == null)
- {
- if (debugMode) Debug.LogError("MapSceneLegendUI: UIDocument is null! Cannot setup UI.");
- return;
- }
- var root = uiDocument.rootVisualElement;
- if (root == null)
- {
- if (debugMode) Debug.LogError("MapSceneLegendUI: Root visual element is null!");
- return;
- }
- if (debugMode) Debug.Log("MapSceneLegendUI: Setting up UI...");
- // Try to find existing legend container from UXML first
- legendContainer = root.Q<VisualElement>("map-legend-container");
- if (legendContainer != null)
- {
- // UXML is loaded, use existing structure
- if (debugMode) Debug.Log("MapSceneLegendUI: Using UXML structure");
- legendContent = legendContainer;
- // Find the name toggle section
- nameToggleSection = root.Q<VisualElement>("name-toggle-section");
- if (nameToggleSection == null)
- {
- // Create it if not found
- nameToggleSection = new VisualElement();
- nameToggleSection.name = "name-toggle-section";
- nameToggleSection.AddToClassList("legend-section");
- var sectionTitle = new Label("Location Names");
- sectionTitle.AddToClassList("legend-section-title");
- nameToggleSection.Add(sectionTitle);
- legendContainer.Add(nameToggleSection);
- }
- // Create name toggles
- CreateNameTogglesSection();
- }
- else
- {
- // Fallback to programmatic creation
- if (debugMode) Debug.Log("MapSceneLegendUI: Using programmatic UI creation");
- // Create main legend container
- legendContainer = new VisualElement();
- legendContainer.name = "map-legend-container";
- legendContainer.AddToClassList("map-legend");
- // Create toggle button
- toggleButton = new Button(() => ToggleLegend());
- toggleButton.text = "Map Legend";
- toggleButton.name = "legend-toggle-button";
- toggleButton.AddToClassList("legend-toggle-btn");
- // Create legend content
- legendContent = new VisualElement();
- legendContent.name = "legend-content";
- legendContent.AddToClassList("legend-content");
- // Add title
- var title = new Label("Map Legend");
- title.AddToClassList("legend-title");
- legendContent.Add(title);
- // Create terrain legend section
- CreateTerrainLegend();
- // Create name toggles section
- CreateNameTogglesSection();
- // Create controls info
- CreateControlsInfo();
- // Assemble the UI
- legendContainer.Add(toggleButton);
- legendContainer.Add(legendContent);
- root.Add(legendContainer);
- }
- // Apply styles
- ApplyStyles();
- if (debugMode) Debug.Log("MapSceneLegendUI: UI setup complete");
- }
- private void CreateTerrainLegend()
- {
- var terrainSection = new VisualElement();
- terrainSection.AddToClassList("legend-section");
- var terrainTitle = new Label("Terrain");
- terrainTitle.AddToClassList("legend-section-title");
- terrainSection.Add(terrainTitle);
- // Terrain items
- var terrainItems = new[]
- {
- ("Ocean", "ocean-color"),
- ("Rivers / Lakes", "river-color"),
- ("Plains / Grasslands", "plain-color"),
- ("Forests", "forest-color"),
- ("Mountains", "mountain-color"),
- ("Towns / Cities", "town-color"),
- ("Villages", "village-color"),
- ("Roads", "road-color")
- };
- foreach (var (label, colorClass) in terrainItems)
- {
- var item = CreateLegendItem(label, colorClass);
- terrainSection.Add(item);
- }
- legendContent.Add(terrainSection);
- }
- private void CreateNameTogglesSection()
- {
- nameToggleSection = new VisualElement();
- nameToggleSection.AddToClassList("legend-section");
- var nameTitle = new Label("Location Names");
- nameTitle.AddToClassList("legend-section-title");
- nameToggleSection.Add(nameTitle);
- // Create toggle switches for each name type
- settlementNamesToggle = CreateNameToggle("Settlements", true, (show) =>
- {
- // Try both old and new name display systems
- if (nameDisplay == null) nameDisplay = FindFirstObjectByType<MapLocationNameDisplay>();
- if (nameDisplay != null) nameDisplay.ToggleSettlementNames(show);
- // Also try to find WorldSpaceLocationNames component using reflection
- TryCallWorldSpaceMethod("ToggleSettlementNames", show);
- });
- forestNamesToggle = CreateNameToggle("Forests", true, (show) =>
- {
- if (nameDisplay == null) nameDisplay = FindFirstObjectByType<MapLocationNameDisplay>();
- if (nameDisplay != null) nameDisplay.ToggleForestNames(show);
- TryCallWorldSpaceMethod("ToggleForestNames", show);
- });
- lakeNamesToggle = CreateNameToggle("Lakes", true, (show) =>
- {
- if (nameDisplay == null) nameDisplay = FindFirstObjectByType<MapLocationNameDisplay>();
- if (nameDisplay != null) nameDisplay.ToggleLakeNames(show);
- TryCallWorldSpaceMethod("ToggleLakeNames", show);
- });
- plainNamesToggle = CreateNameToggle("Plains", true, (show) =>
- {
- if (nameDisplay == null) nameDisplay = FindFirstObjectByType<MapLocationNameDisplay>();
- if (nameDisplay != null) nameDisplay.TogglePlainNames(show);
- TryCallWorldSpaceMethod("TogglePlainNames", show);
- });
- mountainNamesToggle = CreateNameToggle("Mountains", true, (show) =>
- {
- if (nameDisplay == null) nameDisplay = FindFirstObjectByType<MapLocationNameDisplay>();
- if (nameDisplay != null) nameDisplay.ToggleMountainNames(show);
- TryCallWorldSpaceMethod("ToggleMountainNames", show);
- });
- riverNamesToggle = CreateNameToggle("Rivers", true, (show) =>
- {
- if (nameDisplay == null) nameDisplay = FindFirstObjectByType<MapLocationNameDisplay>();
- if (nameDisplay != null) nameDisplay.ToggleRiverNames(show);
- TryCallWorldSpaceMethod("ToggleRiverNames", show);
- });
- nameToggleSection.Add(settlementNamesToggle);
- nameToggleSection.Add(forestNamesToggle);
- nameToggleSection.Add(lakeNamesToggle);
- nameToggleSection.Add(plainNamesToggle);
- nameToggleSection.Add(mountainNamesToggle);
- nameToggleSection.Add(riverNamesToggle);
- legendContent.Add(nameToggleSection);
- }
- private Toggle CreateNameToggle(string labelText, bool defaultValue, System.Action<bool> onValueChanged)
- {
- var toggle = new Toggle();
- toggle.text = labelText;
- toggle.value = defaultValue;
- toggle.AddToClassList("name-toggle");
- toggle.RegisterValueChangedCallback(evt => onValueChanged(evt.newValue));
- return toggle;
- }
- private void CreateControlsInfo()
- {
- var controlsSection = new VisualElement();
- controlsSection.AddToClassList("legend-section");
- controlsSection.AddToClassList("controls-info");
- var controlsTitle = new Label("Controls");
- controlsTitle.AddToClassList("legend-section-title");
- controlsSection.Add(controlsTitle);
- var controls = new[]
- {
- "WASD / Arrow Keys: Move Camera",
- "Mouse Wheel: Zoom In/Out",
- $"{toggleKey}: Toggle Legend",
- "Click: Select Location",
- "Mouse Hover: Show Details"
- };
- foreach (var controlText in controls)
- {
- var controlLabel = new Label(controlText);
- controlLabel.AddToClassList("controls-text");
- controlsSection.Add(controlLabel);
- }
- legendContent.Add(controlsSection);
- }
- private VisualElement CreateLegendItem(string labelText, string colorClass)
- {
- var item = new VisualElement();
- item.AddToClassList("legend-item");
- var colorBox = new VisualElement();
- colorBox.AddToClassList("color-box");
- colorBox.AddToClassList(colorClass);
- var label = new Label(labelText);
- label.AddToClassList("legend-text");
- item.Add(colorBox);
- item.Add(label);
- return item;
- }
- private void ApplyStyles()
- {
- var styleSheet = Resources.Load<StyleSheet>("UI/MapLegend");
- if (styleSheet != null)
- {
- uiDocument.rootVisualElement.styleSheets.Add(styleSheet);
- }
- else
- {
- // Apply inline styles if stylesheet not found
- ApplyInlineStyles();
- }
- }
- private void ApplyInlineStyles()
- {
- // Legend container positioning
- legendContainer.style.position = Position.Absolute;
- legendContainer.style.top = 20;
- legendContainer.style.left = 20;
- legendContainer.style.width = 250;
- // Toggle button
- toggleButton.style.backgroundColor = new Color(0.2f, 0.2f, 0.2f, 0.9f);
- toggleButton.style.color = Color.white;
- toggleButton.style.borderTopLeftRadius = 5;
- toggleButton.style.borderTopRightRadius = 5;
- toggleButton.style.borderBottomLeftRadius = 0;
- toggleButton.style.borderBottomRightRadius = 0;
- toggleButton.style.paddingTop = 8;
- toggleButton.style.paddingBottom = 8;
- toggleButton.style.paddingLeft = 12;
- toggleButton.style.paddingRight = 12;
- // Legend content
- legendContent.style.backgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.9f);
- legendContent.style.borderBottomLeftRadius = 5;
- legendContent.style.borderBottomRightRadius = 5;
- legendContent.style.borderTopWidth = 1;
- legendContent.style.borderTopColor = new Color(0.4f, 0.4f, 0.4f, 0.8f);
- legendContent.style.paddingTop = 10;
- legendContent.style.paddingBottom = 10;
- legendContent.style.paddingLeft = 12;
- legendContent.style.paddingRight = 12;
- // Apply basic color classes
- ApplyTerrainColors();
- }
- private void ApplyTerrainColors()
- {
- // This would ideally be done via USS, but for now we'll handle it in the legend creation
- // The actual color styling should be handled by the MapLegend.uss file
- }
- public void ToggleLegend()
- {
- if (debugMode) Debug.Log($"MapSceneLegendUI: Toggling legend. Current state: {isLegendVisible}");
- SetLegendVisible(!isLegendVisible);
- }
- public void SetLegendVisible(bool visible)
- {
- isLegendVisible = visible;
- if (legendContent != null)
- {
- legendContent.style.display = visible ? DisplayStyle.Flex : DisplayStyle.None;
- if (debugMode) Debug.Log($"MapSceneLegendUI: Set legend visible: {visible}");
- }
- else if (debugMode)
- {
- Debug.LogWarning("MapSceneLegendUI: Cannot set visibility - legendContent is null");
- }
- if (toggleButton != null)
- {
- toggleButton.text = visible ? "Hide Legend" : "Map Legend";
- }
- }
- public void OnFeaturesGenerated()
- {
- // Refresh the toggle states to match the current display settings
- if (nameDisplay != null)
- {
- settlementNamesToggle?.SetValueWithoutNotify(nameDisplay.showSettlementNames);
- forestNamesToggle?.SetValueWithoutNotify(nameDisplay.showForestNames);
- lakeNamesToggle?.SetValueWithoutNotify(nameDisplay.showLakeNames);
- plainNamesToggle?.SetValueWithoutNotify(nameDisplay.showPlainNames);
- mountainNamesToggle?.SetValueWithoutNotify(nameDisplay.showMountainNames);
- riverNamesToggle?.SetValueWithoutNotify(nameDisplay.showRiverNames);
- }
- }
- // IClickBlocker implementation
- public bool IsBlockingClick(Vector2 screenPosition)
- {
- if (!isLegendVisible || legendContainer == null)
- return false;
- // Convert screen position to UI coordinates and check if it's within the legend bounds
- var panelGeometry = legendContainer.worldBound;
- return panelGeometry.Contains(screenPosition);
- }
- [ContextMenu("Toggle Legend")]
- public void ToggleLegendManual()
- {
- ToggleLegend();
- }
- [ContextMenu("Show Legend")]
- public void ShowLegend()
- {
- SetLegendVisible(true);
- }
- [ContextMenu("Hide Legend")]
- public void HideLegend()
- {
- SetLegendVisible(false);
- }
- [ContextMenu("Debug Legend")]
- public void RefreshNameDisplayConnection()
- {
- // Try to find the name display if it wasn't found initially
- if (nameDisplay == null)
- {
- nameDisplay = FindFirstObjectByType<MapLocationNameDisplay>();
- if (debugMode && nameDisplay != null)
- {
- Debug.Log("MapSceneLegendUI: Successfully connected to MapLocationNameDisplay");
- }
- }
- }
- public void DebugLegend()
- {
- Debug.Log($"=== MapSceneLegendUI Debug Info ===");
- Debug.Log($"UIDocument: {(uiDocument != null ? "Found" : "NULL")}");
- Debug.Log($"LegendContainer: {(legendContainer != null ? "Found" : "NULL")}");
- Debug.Log($"LegendContent: {(legendContent != null ? "Found" : "NULL")}");
- Debug.Log($"IsLegendVisible: {isLegendVisible}");
- Debug.Log($"NameDisplay: {(nameDisplay != null ? "Found" : "NULL")}");
- if (uiDocument?.rootVisualElement != null)
- {
- Debug.Log($"Root element children: {uiDocument.rootVisualElement.childCount}");
- }
- }
- }
|