mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 03:37:59 +01:00
use common
This commit is contained in:
133
src/modules/fancyzones/FancyZonesCLI/FancyZonesData.cs
Normal file
133
src/modules/fancyzones/FancyZonesCLI/FancyZonesData.cs
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization.Metadata;
|
||||||
|
|
||||||
|
namespace FancyZonesCLI;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides methods to read and write FancyZones configuration data.
|
||||||
|
/// </summary>
|
||||||
|
internal static class FancyZonesData
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Try to read applied layouts configuration.
|
||||||
|
/// </summary>
|
||||||
|
public static bool TryReadAppliedLayouts(out AppliedLayouts result, out string error)
|
||||||
|
{
|
||||||
|
return TryReadJsonFile(FancyZonesPaths.AppliedLayouts, FancyZonesJsonContext.Default.AppliedLayouts, out result, out error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Read applied layouts or return null if not found.
|
||||||
|
/// </summary>
|
||||||
|
public static AppliedLayouts ReadAppliedLayouts()
|
||||||
|
{
|
||||||
|
return ReadJsonFileOrDefault(FancyZonesPaths.AppliedLayouts, FancyZonesJsonContext.Default.AppliedLayouts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Write applied layouts configuration.
|
||||||
|
/// </summary>
|
||||||
|
public static void WriteAppliedLayouts(AppliedLayouts layouts)
|
||||||
|
{
|
||||||
|
WriteJsonFile(FancyZonesPaths.AppliedLayouts, layouts, FancyZonesJsonContext.Default.AppliedLayouts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Read custom layouts or return null if not found.
|
||||||
|
/// </summary>
|
||||||
|
public static CustomLayouts ReadCustomLayouts()
|
||||||
|
{
|
||||||
|
return ReadJsonFileOrDefault(FancyZonesPaths.CustomLayouts, FancyZonesJsonContext.Default.CustomLayouts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Read layout templates or return null if not found.
|
||||||
|
/// </summary>
|
||||||
|
public static LayoutTemplates ReadLayoutTemplates()
|
||||||
|
{
|
||||||
|
return ReadJsonFileOrDefault(FancyZonesPaths.LayoutTemplates, FancyZonesJsonContext.Default.LayoutTemplates);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Read layout hotkeys or return null if not found.
|
||||||
|
/// </summary>
|
||||||
|
public static LayoutHotkeys ReadLayoutHotkeys()
|
||||||
|
{
|
||||||
|
return ReadJsonFileOrDefault(FancyZonesPaths.LayoutHotkeys, FancyZonesJsonContext.Default.LayoutHotkeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Write layout hotkeys configuration.
|
||||||
|
/// </summary>
|
||||||
|
public static void WriteLayoutHotkeys(LayoutHotkeys hotkeys)
|
||||||
|
{
|
||||||
|
WriteJsonFile(FancyZonesPaths.LayoutHotkeys, hotkeys, FancyZonesJsonContext.Default.LayoutHotkeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check if editor parameters file exists.
|
||||||
|
/// </summary>
|
||||||
|
public static bool EditorParametersExist()
|
||||||
|
{
|
||||||
|
return File.Exists(FancyZonesPaths.EditorParameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool TryReadJsonFile<T>(string filePath, JsonTypeInfo<T> jsonTypeInfo, out T result, out string error)
|
||||||
|
where T : class
|
||||||
|
{
|
||||||
|
result = null;
|
||||||
|
error = null;
|
||||||
|
|
||||||
|
if (!File.Exists(filePath))
|
||||||
|
{
|
||||||
|
error = $"File not found: {Path.GetFileName(filePath)}";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var json = File.ReadAllText(filePath);
|
||||||
|
result = JsonSerializer.Deserialize(json, jsonTypeInfo);
|
||||||
|
if (result == null)
|
||||||
|
{
|
||||||
|
error = $"Failed to parse {Path.GetFileName(filePath)}";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (JsonException ex)
|
||||||
|
{
|
||||||
|
error = $"JSON parse error in {Path.GetFileName(filePath)}: {ex.Message}";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (IOException ex)
|
||||||
|
{
|
||||||
|
error = $"Failed to read {Path.GetFileName(filePath)}: {ex.Message}";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static T ReadJsonFileOrDefault<T>(string filePath, JsonTypeInfo<T> jsonTypeInfo, T defaultValue = null)
|
||||||
|
where T : class
|
||||||
|
{
|
||||||
|
if (TryReadJsonFile(filePath, jsonTypeInfo, out var result, out _))
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void WriteJsonFile<T>(string filePath, T data, JsonTypeInfo<T> jsonTypeInfo)
|
||||||
|
{
|
||||||
|
var json = JsonSerializer.Serialize(data, jsonTypeInfo);
|
||||||
|
File.WriteAllText(filePath, json);
|
||||||
|
}
|
||||||
|
}
|
||||||
30
src/modules/fancyzones/FancyZonesCLI/FancyZonesPaths.cs
Normal file
30
src/modules/fancyzones/FancyZonesCLI/FancyZonesPaths.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace FancyZonesCLI;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides paths to FancyZones configuration files.
|
||||||
|
/// </summary>
|
||||||
|
internal static class FancyZonesPaths
|
||||||
|
{
|
||||||
|
private static readonly string DataPath = Path.Combine(
|
||||||
|
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
|
||||||
|
"Microsoft",
|
||||||
|
"PowerToys",
|
||||||
|
"FancyZones");
|
||||||
|
|
||||||
|
public static string AppliedLayouts => Path.Combine(DataPath, "applied-layouts.json");
|
||||||
|
|
||||||
|
public static string CustomLayouts => Path.Combine(DataPath, "custom-layouts.json");
|
||||||
|
|
||||||
|
public static string LayoutTemplates => Path.Combine(DataPath, "layout-templates.json");
|
||||||
|
|
||||||
|
public static string LayoutHotkeys => Path.Combine(DataPath, "layout-hotkeys.json");
|
||||||
|
|
||||||
|
public static string EditorParameters => Path.Combine(DataPath, "editor-parameters.json");
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Globalization;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
|
||||||
@@ -12,20 +12,21 @@ namespace FancyZonesCLI;
|
|||||||
|
|
||||||
public static class LayoutVisualizer
|
public static class LayoutVisualizer
|
||||||
{
|
{
|
||||||
public static void DrawTemplateLayout(TemplateLayout template)
|
public static string DrawTemplateLayout(TemplateLayout template)
|
||||||
{
|
{
|
||||||
Console.WriteLine(" Visual Preview:");
|
var sb = new StringBuilder();
|
||||||
|
sb.AppendLine(" Visual Preview:");
|
||||||
|
|
||||||
switch (template.Type.ToLowerInvariant())
|
switch (template.Type.ToLowerInvariant())
|
||||||
{
|
{
|
||||||
case "focus":
|
case "focus":
|
||||||
DrawFocusLayout(template.ZoneCount > 0 ? template.ZoneCount : 3);
|
sb.Append(RenderFocusLayout(template.ZoneCount > 0 ? template.ZoneCount : 3));
|
||||||
break;
|
break;
|
||||||
case "columns":
|
case "columns":
|
||||||
DrawGridLayout(1, template.ZoneCount > 0 ? template.ZoneCount : 3);
|
sb.Append(RenderGridLayout(1, template.ZoneCount > 0 ? template.ZoneCount : 3));
|
||||||
break;
|
break;
|
||||||
case "rows":
|
case "rows":
|
||||||
DrawGridLayout(template.ZoneCount > 0 ? template.ZoneCount : 3, 1);
|
sb.Append(RenderGridLayout(template.ZoneCount > 0 ? template.ZoneCount : 3, 1));
|
||||||
break;
|
break;
|
||||||
case "grid":
|
case "grid":
|
||||||
// Grid layout: calculate rows and columns from zone count
|
// Grid layout: calculate rows and columns from zone count
|
||||||
@@ -45,28 +46,31 @@ public static class LayoutVisualizer
|
|||||||
cols++;
|
cols++;
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawGridLayoutWithZoneCount(rows, cols, zoneCount);
|
sb.Append(RenderGridLayoutWithZoneCount(rows, cols, zoneCount));
|
||||||
break;
|
break;
|
||||||
case "priority-grid":
|
case "priority-grid":
|
||||||
DrawPriorityGridLayout(template.ZoneCount > 0 ? template.ZoneCount : 3);
|
sb.Append(RenderPriorityGridLayout(template.ZoneCount > 0 ? template.ZoneCount : 3));
|
||||||
break;
|
break;
|
||||||
case "blank":
|
case "blank":
|
||||||
Console.WriteLine(" (No zones)");
|
sb.AppendLine(" (No zones)");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Console.WriteLine($" ({template.Type} layout)");
|
sb.AppendLine(CultureInfo.InvariantCulture, $" ({template.Type} layout)");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DrawCustomLayout(CustomLayout layout)
|
public static string DrawCustomLayout(CustomLayout layout)
|
||||||
{
|
{
|
||||||
if (layout.Info.ValueKind == JsonValueKind.Undefined || layout.Info.ValueKind == JsonValueKind.Null)
|
if (layout.Info.ValueKind == JsonValueKind.Undefined || layout.Info.ValueKind == JsonValueKind.Null)
|
||||||
{
|
{
|
||||||
return;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine(" Visual Preview:");
|
var sb = new StringBuilder();
|
||||||
|
sb.AppendLine(" Visual Preview:");
|
||||||
|
|
||||||
if (layout.Type == "grid" &&
|
if (layout.Type == "grid" &&
|
||||||
layout.Info.TryGetProperty("rows", out var rows) &&
|
layout.Info.TryGetProperty("rows", out var rows) &&
|
||||||
@@ -78,12 +82,12 @@ public static class LayoutVisualizer
|
|||||||
// Check if there's a cell-child-map (merged cells)
|
// Check if there's a cell-child-map (merged cells)
|
||||||
if (layout.Info.TryGetProperty("cell-child-map", out var cellMap))
|
if (layout.Info.TryGetProperty("cell-child-map", out var cellMap))
|
||||||
{
|
{
|
||||||
DrawGridLayoutWithMergedCells(r, c, cellMap);
|
sb.Append(RenderGridLayoutWithMergedCells(r, c, cellMap));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int height = r >= 4 ? 12 : 8;
|
int height = r >= 4 ? 12 : 8;
|
||||||
DrawGridLayout(r, c, 30, height);
|
sb.Append(RenderGridLayout(r, c, 30, height));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (layout.Type == "canvas" &&
|
else if (layout.Type == "canvas" &&
|
||||||
@@ -91,60 +95,61 @@ public static class LayoutVisualizer
|
|||||||
layout.Info.TryGetProperty("ref-width", out var refWidth) &&
|
layout.Info.TryGetProperty("ref-width", out var refWidth) &&
|
||||||
layout.Info.TryGetProperty("ref-height", out var refHeight))
|
layout.Info.TryGetProperty("ref-height", out var refHeight))
|
||||||
{
|
{
|
||||||
DrawCanvasLayout(zones, refWidth.GetInt32(), refHeight.GetInt32());
|
sb.Append(RenderCanvasLayout(zones, refWidth.GetInt32(), refHeight.GetInt32()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void DrawFocusLayout(int zoneCount = 3)
|
private static string RenderFocusLayout(int zoneCount = 3)
|
||||||
{
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
|
||||||
// Focus layout: overlapping zones with cascading offset
|
// Focus layout: overlapping zones with cascading offset
|
||||||
// Show first 2, ellipsis, and last 1 if more than 4 zones
|
|
||||||
if (zoneCount == 1)
|
if (zoneCount == 1)
|
||||||
{
|
{
|
||||||
Console.WriteLine(" +-------+");
|
sb.AppendLine(" +-------+");
|
||||||
Console.WriteLine(" | |");
|
sb.AppendLine(" | |");
|
||||||
Console.WriteLine(" | |");
|
sb.AppendLine(" | |");
|
||||||
Console.WriteLine(" +-------+");
|
sb.AppendLine(" +-------+");
|
||||||
}
|
}
|
||||||
else if (zoneCount == 2)
|
else if (zoneCount == 2)
|
||||||
{
|
{
|
||||||
Console.WriteLine(" +-------+");
|
sb.AppendLine(" +-------+");
|
||||||
Console.WriteLine(" | |");
|
sb.AppendLine(" | |");
|
||||||
Console.WriteLine(" | +-------+");
|
sb.AppendLine(" | +-------+");
|
||||||
Console.WriteLine(" +-| |");
|
sb.AppendLine(" +-| |");
|
||||||
Console.WriteLine(" | |");
|
sb.AppendLine(" | |");
|
||||||
Console.WriteLine(" +-------+");
|
sb.AppendLine(" +-------+");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Console.WriteLine(" +-------+");
|
sb.AppendLine(" +-------+");
|
||||||
Console.WriteLine(" | |");
|
sb.AppendLine(" | |");
|
||||||
Console.WriteLine(" | +-------+");
|
sb.AppendLine(" | +-------+");
|
||||||
Console.WriteLine(" +-| |");
|
sb.AppendLine(" +-| |");
|
||||||
Console.WriteLine(" | +-------+");
|
sb.AppendLine(" | +-------+");
|
||||||
Console.WriteLine(" +-| |");
|
sb.AppendLine(" +-| |");
|
||||||
|
sb.AppendLine(" ...");
|
||||||
// Middle ellipsis
|
sb.AppendLine(CultureInfo.InvariantCulture, $" (total: {zoneCount} zones)");
|
||||||
Console.WriteLine(" ...");
|
sb.AppendLine(" ...");
|
||||||
Console.WriteLine($" (total: {zoneCount} zones)");
|
sb.AppendLine(" | +-------+");
|
||||||
Console.WriteLine(" ...");
|
sb.AppendLine(" +-| |");
|
||||||
|
sb.AppendLine(" | |");
|
||||||
// Show indication of last zone (without full indent)
|
sb.AppendLine(" +-------+");
|
||||||
Console.WriteLine(" | +-------+");
|
|
||||||
Console.WriteLine(" +-| |");
|
|
||||||
Console.WriteLine(" | |");
|
|
||||||
Console.WriteLine(" +-------+");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void DrawPriorityGridLayout(int zoneCount = 3)
|
private static string RenderPriorityGridLayout(int zoneCount = 3)
|
||||||
{
|
{
|
||||||
// Priority Grid has predefined layouts for zone counts 1-11
|
// Priority Grid has predefined layouts for zone counts 1-11
|
||||||
// Data format from GridLayoutModel._priorityData
|
// Data format from GridLayoutModel._priorityData
|
||||||
if (zoneCount >= 1 && zoneCount <= 11)
|
if (zoneCount >= 1 && zoneCount <= 11)
|
||||||
{
|
{
|
||||||
int[,] cellMap = GetPriorityGridCellMap(zoneCount);
|
int[,] cellMap = GetPriorityGridCellMap(zoneCount);
|
||||||
DrawGridLayoutWithCellMap(cellMap);
|
return RenderGridLayoutWithCellMap(cellMap);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -162,7 +167,7 @@ public static class LayoutVisualizer
|
|||||||
cols++;
|
cols++;
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawGridLayoutWithZoneCount(rows, cols, zoneCount);
|
return RenderGridLayoutWithZoneCount(rows, cols, zoneCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,8 +191,9 @@ public static class LayoutVisualizer
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void DrawGridLayoutWithCellMap(int[,] cellMap, int width = 30, int height = 8)
|
private static string RenderGridLayoutWithCellMap(int[,] cellMap, int width = 30, int height = 8)
|
||||||
{
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
int rows = cellMap.GetLength(0);
|
int rows = cellMap.GetLength(0);
|
||||||
int cols = cellMap.GetLength(1);
|
int cols = cellMap.GetLength(1);
|
||||||
|
|
||||||
@@ -197,79 +203,54 @@ public static class LayoutVisualizer
|
|||||||
for (int r = 0; r < rows; r++)
|
for (int r = 0; r < rows; r++)
|
||||||
{
|
{
|
||||||
// Top border
|
// Top border
|
||||||
Console.Write(" +");
|
sb.Append(" +");
|
||||||
for (int c = 0; c < cols; c++)
|
for (int c = 0; c < cols; c++)
|
||||||
{
|
{
|
||||||
// Check if this cell should merge with the cell above
|
|
||||||
bool mergeTop = r > 0 && cellMap[r, c] == cellMap[r - 1, c];
|
bool mergeTop = r > 0 && cellMap[r, c] == cellMap[r - 1, c];
|
||||||
|
|
||||||
// Check if this cell should merge with the cell to the left
|
|
||||||
bool mergeLeft = c > 0 && cellMap[r, c] == cellMap[r, c - 1];
|
bool mergeLeft = c > 0 && cellMap[r, c] == cellMap[r, c - 1];
|
||||||
|
|
||||||
if (mergeTop)
|
if (mergeTop)
|
||||||
{
|
{
|
||||||
if (mergeLeft)
|
sb.Append(mergeLeft ? new string(' ', cellWidth) : new string(' ', cellWidth - 1) + "+");
|
||||||
{
|
|
||||||
Console.Write(new string(' ', cellWidth));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.Write(new string(' ', cellWidth - 1));
|
|
||||||
Console.Write("+");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (mergeLeft)
|
sb.Append(mergeLeft ? new string('-', cellWidth) : new string('-', cellWidth - 1) + "+");
|
||||||
{
|
|
||||||
Console.Write(new string('-', cellWidth));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.Write(new string('-', cellWidth - 1));
|
|
||||||
Console.Write("+");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine();
|
sb.AppendLine();
|
||||||
|
|
||||||
// Cell content
|
// Cell content
|
||||||
for (int h = 0; h < cellHeight - 1; h++)
|
for (int h = 0; h < cellHeight - 1; h++)
|
||||||
{
|
{
|
||||||
Console.Write(" ");
|
sb.Append(" ");
|
||||||
for (int c = 0; c < cols; c++)
|
for (int c = 0; c < cols; c++)
|
||||||
{
|
{
|
||||||
bool mergeLeft = c > 0 && cellMap[r, c] == cellMap[r, c - 1];
|
bool mergeLeft = c > 0 && cellMap[r, c] == cellMap[r, c - 1];
|
||||||
if (mergeLeft)
|
sb.Append(mergeLeft ? ' ' : '|');
|
||||||
{
|
sb.Append(' ', cellWidth - 1);
|
||||||
Console.Write(" ");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.Write("|");
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.Write(new string(' ', cellWidth - 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine("|");
|
sb.AppendLine("|");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bottom border
|
// Bottom border
|
||||||
Console.Write(" +");
|
sb.Append(" +");
|
||||||
for (int c = 0; c < cols; c++)
|
for (int c = 0; c < cols; c++)
|
||||||
{
|
{
|
||||||
Console.Write(new string('-', cellWidth - 1));
|
sb.Append('-', cellWidth - 1);
|
||||||
Console.Write("+");
|
sb.Append('+');
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine();
|
sb.AppendLine();
|
||||||
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void DrawGridLayoutWithMergedCells(int rows, int cols, JsonElement cellMap)
|
private static string RenderGridLayoutWithMergedCells(int rows, int cols, JsonElement cellMap)
|
||||||
{
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
const int displayWidth = 39;
|
const int displayWidth = 39;
|
||||||
const int displayHeight = 12;
|
const int displayHeight = 12;
|
||||||
|
|
||||||
@@ -284,45 +265,20 @@ public static class LayoutVisualizer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find unique zones and their count
|
|
||||||
var zones = new HashSet<int>();
|
|
||||||
for (int r = 0; r < rows; r++)
|
|
||||||
{
|
|
||||||
for (int c = 0; c < cols; c++)
|
|
||||||
{
|
|
||||||
zones.Add(zoneMap[r, c]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int cellHeight = displayHeight / rows;
|
int cellHeight = displayHeight / rows;
|
||||||
int cellWidth = displayWidth / cols;
|
int cellWidth = displayWidth / cols;
|
||||||
|
|
||||||
// Draw top border
|
// Draw top border
|
||||||
Console.Write(" +");
|
sb.Append(" +");
|
||||||
Console.Write(new string('-', displayWidth));
|
sb.Append('-', displayWidth);
|
||||||
Console.WriteLine("+");
|
sb.AppendLine("+");
|
||||||
|
|
||||||
// Draw rows
|
// Draw rows
|
||||||
for (int r = 0; r < rows; r++)
|
for (int r = 0; r < rows; r++)
|
||||||
{
|
{
|
||||||
// For each row, find the column range of each zone
|
|
||||||
var zoneRanges = new Dictionary<int, (int Start, int End)>();
|
|
||||||
for (int c = 0; c < cols; c++)
|
|
||||||
{
|
|
||||||
int zone = zoneMap[r, c];
|
|
||||||
if (zoneRanges.TryGetValue(zone, out var range))
|
|
||||||
{
|
|
||||||
zoneRanges[zone] = (range.Start, c);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
zoneRanges[zone] = (c, c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int h = 0; h < cellHeight; h++)
|
for (int h = 0; h < cellHeight; h++)
|
||||||
{
|
{
|
||||||
Console.Write(" |");
|
sb.Append(" |");
|
||||||
|
|
||||||
for (int c = 0; c < cols; c++)
|
for (int c = 0; c < cols; c++)
|
||||||
{
|
{
|
||||||
@@ -330,47 +286,35 @@ public static class LayoutVisualizer
|
|||||||
int leftZone = c > 0 ? zoneMap[r, c - 1] : -1;
|
int leftZone = c > 0 ? zoneMap[r, c - 1] : -1;
|
||||||
bool needLeftBorder = c > 0 && currentZone != leftZone;
|
bool needLeftBorder = c > 0 && currentZone != leftZone;
|
||||||
|
|
||||||
// Check if this zone has a top border
|
bool zoneHasTopBorder = r > 0 && h == 0 && currentZone != zoneMap[r - 1, c];
|
||||||
bool zoneHasTopBorder = false;
|
|
||||||
if (r > 0 && h == 0)
|
|
||||||
{
|
|
||||||
int topZone = zoneMap[r - 1, c];
|
|
||||||
zoneHasTopBorder = currentZone != topZone;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw left border if needed
|
|
||||||
if (needLeftBorder)
|
if (needLeftBorder)
|
||||||
{
|
{
|
||||||
Console.Write("|");
|
sb.Append('|');
|
||||||
|
sb.Append(zoneHasTopBorder ? '-' : ' ', cellWidth - 1);
|
||||||
// Fill rest of cell
|
|
||||||
for (int w = 1; w < cellWidth; w++)
|
|
||||||
{
|
|
||||||
Console.Write(zoneHasTopBorder ? "-" : " ");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// No left border, fill entire cell
|
sb.Append(zoneHasTopBorder ? '-' : ' ', cellWidth);
|
||||||
for (int w = 0; w < cellWidth; w++)
|
|
||||||
{
|
|
||||||
Console.Write(zoneHasTopBorder ? "-" : " ");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine("|");
|
sb.AppendLine("|");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw bottom border
|
// Draw bottom border
|
||||||
Console.Write(" +");
|
sb.Append(" +");
|
||||||
Console.Write(new string('-', displayWidth));
|
sb.Append('-', displayWidth);
|
||||||
Console.WriteLine("+");
|
sb.AppendLine("+");
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DrawGridLayoutWithZoneCount(int rows, int cols, int zoneCount, int width = 30, int height = 8)
|
public static string RenderGridLayoutWithZoneCount(int rows, int cols, int zoneCount, int width = 30, int height = 8)
|
||||||
{
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
|
||||||
// Build zone map like Editor's InitGrid
|
// Build zone map like Editor's InitGrid
|
||||||
int[,] zoneMap = new int[rows, cols];
|
int[,] zoneMap = new int[rows, cols];
|
||||||
int index = 0;
|
int index = 0;
|
||||||
@@ -392,103 +336,93 @@ public static class LayoutVisualizer
|
|||||||
for (int r = 0; r < rows; r++)
|
for (int r = 0; r < rows; r++)
|
||||||
{
|
{
|
||||||
// Top border
|
// Top border
|
||||||
Console.Write(" +");
|
sb.Append(" +");
|
||||||
for (int c = 0; c < cols; c++)
|
for (int c = 0; c < cols; c++)
|
||||||
{
|
{
|
||||||
// Check if this cell should merge with the previous one (same zone)
|
|
||||||
bool mergeLeft = c > 0 && zoneMap[r, c] == zoneMap[r, c - 1];
|
bool mergeLeft = c > 0 && zoneMap[r, c] == zoneMap[r, c - 1];
|
||||||
if (mergeLeft)
|
sb.Append('-', mergeLeft ? cellWidth : cellWidth - 1);
|
||||||
|
if (!mergeLeft)
|
||||||
{
|
{
|
||||||
Console.Write(new string('-', cellWidth));
|
sb.Append('+');
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.Write(new string('-', cellWidth - 1));
|
|
||||||
Console.Write("+");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine();
|
sb.AppendLine();
|
||||||
|
|
||||||
// Cell content
|
// Cell content
|
||||||
for (int h = 0; h < cellHeight - 1; h++)
|
for (int h = 0; h < cellHeight - 1; h++)
|
||||||
{
|
{
|
||||||
Console.Write(" ");
|
sb.Append(" ");
|
||||||
for (int c = 0; c < cols; c++)
|
for (int c = 0; c < cols; c++)
|
||||||
{
|
{
|
||||||
// Check if this cell should merge with the previous one
|
|
||||||
bool mergeLeft = c > 0 && zoneMap[r, c] == zoneMap[r, c - 1];
|
bool mergeLeft = c > 0 && zoneMap[r, c] == zoneMap[r, c - 1];
|
||||||
if (mergeLeft)
|
sb.Append(mergeLeft ? ' ' : '|');
|
||||||
{
|
sb.Append(' ', cellWidth - 1);
|
||||||
Console.Write(" ");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.Write("|");
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.Write(new string(' ', cellWidth - 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine("|");
|
sb.AppendLine("|");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bottom border
|
// Bottom border
|
||||||
Console.Write(" +");
|
sb.Append(" +");
|
||||||
for (int c = 0; c < cols; c++)
|
for (int c = 0; c < cols; c++)
|
||||||
{
|
{
|
||||||
Console.Write(new string('-', cellWidth - 1));
|
sb.Append('-', cellWidth - 1);
|
||||||
Console.Write("+");
|
sb.Append('+');
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine();
|
sb.AppendLine();
|
||||||
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DrawGridLayout(int rows, int cols, int width = 30, int height = 8)
|
public static string RenderGridLayout(int rows, int cols, int width = 30, int height = 8)
|
||||||
{
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
int cellWidth = width / cols;
|
int cellWidth = width / cols;
|
||||||
int cellHeight = height / rows;
|
int cellHeight = height / rows;
|
||||||
|
|
||||||
for (int r = 0; r < rows; r++)
|
for (int r = 0; r < rows; r++)
|
||||||
{
|
{
|
||||||
// Top border
|
// Top border
|
||||||
Console.Write(" +");
|
sb.Append(" +");
|
||||||
for (int c = 0; c < cols; c++)
|
for (int c = 0; c < cols; c++)
|
||||||
{
|
{
|
||||||
Console.Write(new string('-', cellWidth - 1));
|
sb.Append('-', cellWidth - 1);
|
||||||
Console.Write("+");
|
sb.Append('+');
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine();
|
sb.AppendLine();
|
||||||
|
|
||||||
// Cell content
|
// Cell content
|
||||||
for (int h = 0; h < cellHeight - 1; h++)
|
for (int h = 0; h < cellHeight - 1; h++)
|
||||||
{
|
{
|
||||||
Console.Write(" ");
|
sb.Append(" ");
|
||||||
for (int c = 0; c < cols; c++)
|
for (int c = 0; c < cols; c++)
|
||||||
{
|
{
|
||||||
Console.Write("|");
|
sb.Append('|');
|
||||||
Console.Write(new string(' ', cellWidth - 1));
|
sb.Append(' ', cellWidth - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine("|");
|
sb.AppendLine("|");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bottom border
|
// Bottom border
|
||||||
Console.Write(" +");
|
sb.Append(" +");
|
||||||
for (int c = 0; c < cols; c++)
|
for (int c = 0; c < cols; c++)
|
||||||
{
|
{
|
||||||
Console.Write(new string('-', cellWidth - 1));
|
sb.Append('-', cellWidth - 1);
|
||||||
Console.Write("+");
|
sb.Append('+');
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine();
|
sb.AppendLine();
|
||||||
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void DrawCanvasLayout(JsonElement zones, int refWidth, int refHeight)
|
private static string RenderCanvasLayout(JsonElement zones, int refWidth, int refHeight)
|
||||||
{
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
const int displayWidth = 49;
|
const int displayWidth = 49;
|
||||||
const int displayHeight = 15;
|
const int displayHeight = 15;
|
||||||
|
|
||||||
@@ -518,7 +452,6 @@ public static class LayoutVisualizer
|
|||||||
int dw = Math.Max(3, w * displayWidth / refWidth);
|
int dw = Math.Max(3, w * displayWidth / refWidth);
|
||||||
int dh = Math.Max(2, h * displayHeight / refHeight);
|
int dh = Math.Max(2, h * displayHeight / refHeight);
|
||||||
|
|
||||||
// Clamp to display bounds
|
|
||||||
if (dx + dw > displayWidth)
|
if (dx + dw > displayWidth)
|
||||||
{
|
{
|
||||||
dw = displayWidth - dx;
|
dw = displayWidth - dx;
|
||||||
@@ -531,7 +464,6 @@ public static class LayoutVisualizer
|
|||||||
|
|
||||||
zoneList.Add((dx, dy, dw, dh, zoneId));
|
zoneList.Add((dx, dy, dw, dh, zoneId));
|
||||||
|
|
||||||
// Fill the grid for this zone
|
|
||||||
for (int r = dy; r < dy + dh && r < displayHeight; r++)
|
for (int r = dy; r < dy + dh && r < displayHeight; r++)
|
||||||
{
|
{
|
||||||
for (int c = dx; c < dx + dw && c < displayWidth; c++)
|
for (int c = dx; c < dx + dw && c < displayWidth; c++)
|
||||||
@@ -544,82 +476,75 @@ public static class LayoutVisualizer
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw top border
|
// Draw top border
|
||||||
Console.Write(" +");
|
sb.Append(" +");
|
||||||
Console.Write(new string('-', displayWidth));
|
sb.Append('-', displayWidth);
|
||||||
Console.WriteLine("+");
|
sb.AppendLine("+");
|
||||||
|
|
||||||
// Draw each row
|
// Draw each row
|
||||||
|
char[] shades = { '.', ':', '░', '▒', '▓', '█', '◆', '●', '■', '▪' };
|
||||||
|
|
||||||
for (int r = 0; r < displayHeight; r++)
|
for (int r = 0; r < displayHeight; r++)
|
||||||
{
|
{
|
||||||
Console.Write(" |");
|
sb.Append(" |");
|
||||||
for (int c = 0; c < displayWidth; c++)
|
for (int c = 0; c < displayWidth; c++)
|
||||||
{
|
{
|
||||||
var zonesHere = zoneGrid[r, c];
|
var zonesHere = zoneGrid[r, c];
|
||||||
|
|
||||||
if (zonesHere.Count == 0)
|
if (zonesHere.Count == 0)
|
||||||
{
|
{
|
||||||
Console.Write(" ");
|
sb.Append(' ');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Get the topmost zone at this position
|
|
||||||
int topZone = zonesHere[zonesHere.Count - 1];
|
int topZone = zonesHere[zonesHere.Count - 1];
|
||||||
var rect = zoneList[topZone];
|
var rect = zoneList[topZone];
|
||||||
|
|
||||||
int x = rect.X;
|
bool isTopEdge = r == rect.Y;
|
||||||
int y = rect.Y;
|
bool isBottomEdge = r == rect.Y + rect.Height - 1;
|
||||||
int w = rect.Width;
|
bool isLeftEdge = c == rect.X;
|
||||||
int h = rect.Height;
|
bool isRightEdge = c == rect.X + rect.Width - 1;
|
||||||
|
|
||||||
bool isTopEdge = r == y;
|
|
||||||
bool isBottomEdge = r == y + h - 1;
|
|
||||||
bool isLeftEdge = c == x;
|
|
||||||
bool isRightEdge = c == x + w - 1;
|
|
||||||
|
|
||||||
// Draw borders
|
|
||||||
if ((isTopEdge || isBottomEdge) && (isLeftEdge || isRightEdge))
|
if ((isTopEdge || isBottomEdge) && (isLeftEdge || isRightEdge))
|
||||||
{
|
{
|
||||||
Console.Write("+");
|
sb.Append('+');
|
||||||
}
|
}
|
||||||
else if (isTopEdge || isBottomEdge)
|
else if (isTopEdge || isBottomEdge)
|
||||||
{
|
{
|
||||||
Console.Write("-");
|
sb.Append('-');
|
||||||
}
|
}
|
||||||
else if (isLeftEdge || isRightEdge)
|
else if (isLeftEdge || isRightEdge)
|
||||||
{
|
{
|
||||||
Console.Write("|");
|
sb.Append('|');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Use shading to show different zones
|
sb.Append(shades[topZone % shades.Length]);
|
||||||
char[] shades = { '.', ':', '░', '▒', '▓', '█', '◆', '●', '■', '▪' };
|
|
||||||
Console.Write(shades[topZone % shades.Length]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine("|");
|
sb.AppendLine("|");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw bottom border
|
// Draw bottom border
|
||||||
Console.Write(" +");
|
sb.Append(" +");
|
||||||
Console.Write(new string('-', displayWidth));
|
sb.Append('-', displayWidth);
|
||||||
Console.WriteLine("+");
|
sb.AppendLine("+");
|
||||||
|
|
||||||
// Draw legend
|
// Draw legend
|
||||||
Console.WriteLine();
|
sb.AppendLine();
|
||||||
Console.Write(" Legend: ");
|
sb.Append(" Legend: ");
|
||||||
char[] legendShades = { '.', ':', '░', '▒', '▓', '█', '◆', '●', '■', '▪' };
|
for (int i = 0; i < Math.Min(zoneId, shades.Length); i++)
|
||||||
for (int i = 0; i < Math.Min(zoneId, legendShades.Length); i++)
|
|
||||||
{
|
{
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
{
|
{
|
||||||
Console.Write(", ");
|
sb.Append(", ");
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.Write($"Zone {i} = {legendShades[i]}");
|
sb.Append(CultureInfo.InvariantCulture, $"Zone {i} = {shades[i]}");
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine();
|
sb.AppendLine();
|
||||||
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user