mirror of
https://github.com/Leonmmcoset/CMLeonOS.git
synced 2026-03-03 15:30:27 +00:00
打开文件可视化窗口+CodeStudio代码高亮
This commit is contained in:
@@ -1 +1 @@
|
|||||||
2026-03-01 21:19:06
|
2026-03-02 21:39:15
|
||||||
@@ -1 +1 @@
|
|||||||
6a9d39a
|
5c952e7
|
||||||
50
Gui/Apps/CodeStudio/CodeEditor.cs
Normal file
50
Gui/Apps/CodeStudio/CodeEditor.cs
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
using CMLeonOS.Gui.UILib;
|
||||||
|
using Cosmos.System.Graphics;
|
||||||
|
using System.Drawing;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace CMLeonOS.Gui.Apps.CodeStudio
|
||||||
|
{
|
||||||
|
internal class CodeEditor : TextBox
|
||||||
|
{
|
||||||
|
private bool enableSyntaxHighlighting = false;
|
||||||
|
private string fileExtension = "";
|
||||||
|
|
||||||
|
public CodeEditor(Window parent, int x, int y, int width, int height) : base(parent, x, y, width, height)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void SetSyntaxHighlighting(bool enable, string extension = "")
|
||||||
|
{
|
||||||
|
enableSyntaxHighlighting = enable;
|
||||||
|
fileExtension = extension.ToLower();
|
||||||
|
MarkAllLines();
|
||||||
|
Render();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal override void RenderLine(int lineIndex, string lineText, int lineY, int xOffset)
|
||||||
|
{
|
||||||
|
if (enableSyntaxHighlighting && fileExtension == ".lua")
|
||||||
|
{
|
||||||
|
var tokens = LuaSyntaxHighlighter.HighlightLine(lineText);
|
||||||
|
int currentXOffset = xOffset;
|
||||||
|
|
||||||
|
foreach (var token in tokens)
|
||||||
|
{
|
||||||
|
if (currentXOffset + token.Text.Length * 8 > 0 && currentXOffset < Width)
|
||||||
|
{
|
||||||
|
DrawString(token.Text, token.Color, currentXOffset, lineY);
|
||||||
|
}
|
||||||
|
currentXOffset += token.Text.Length * 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
base.RenderLine(lineIndex, lineText, lineY, xOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,12 +29,14 @@ namespace CMLeonOS.Gui.Apps.CodeStudio
|
|||||||
|
|
||||||
Button runButton;
|
Button runButton;
|
||||||
|
|
||||||
TextBox editor;
|
CodeEditor editor;
|
||||||
|
|
||||||
TextBox problems;
|
TextBox problems;
|
||||||
|
|
||||||
TextBox output;
|
TextBox output;
|
||||||
|
|
||||||
|
FileBrowser fileBrowser;
|
||||||
|
|
||||||
private const int headersHeight = 24;
|
private const int headersHeight = 24;
|
||||||
private const int problemsHeight = 128;
|
private const int problemsHeight = 128;
|
||||||
private const int outputHeight = 128;
|
private const int outputHeight = 128;
|
||||||
@@ -90,6 +92,9 @@ namespace CMLeonOS.Gui.Apps.CodeStudio
|
|||||||
{
|
{
|
||||||
editor.Text = File.ReadAllText(path);
|
editor.Text = File.ReadAllText(path);
|
||||||
|
|
||||||
|
string extension = Path.GetExtension(path).ToLower();
|
||||||
|
editor.SetSyntaxHighlighting(extension == ".lua", extension);
|
||||||
|
|
||||||
editor.MarkAllLines();
|
editor.MarkAllLines();
|
||||||
editor.Render();
|
editor.Render();
|
||||||
|
|
||||||
@@ -101,35 +106,27 @@ namespace CMLeonOS.Gui.Apps.CodeStudio
|
|||||||
|
|
||||||
private void OpenFilePrompt()
|
private void OpenFilePrompt()
|
||||||
{
|
{
|
||||||
PromptBox prompt = new PromptBox(process, "Open File", "Enter the path to open.", "Path", (string newPath) =>
|
fileBrowser = new FileBrowser(process, wm, (string selectedPath) =>
|
||||||
{
|
{
|
||||||
if (!newPath.Contains(':'))
|
if (selectedPath != null)
|
||||||
{
|
{
|
||||||
newPath = $@"0:\{newPath}";
|
Open(selectedPath);
|
||||||
}
|
}
|
||||||
Open(newPath);
|
|
||||||
});
|
});
|
||||||
prompt.Show();
|
fileBrowser.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SaveAsPrompt()
|
private void SaveAsPrompt()
|
||||||
{
|
{
|
||||||
PromptBox prompt = new PromptBox(process, "Save As", "Enter the path to save to.", "Path", (string newPath) =>
|
fileBrowser = new FileBrowser(process, wm, (string selectedPath) =>
|
||||||
{
|
{
|
||||||
if (!newPath.Contains(':'))
|
if (selectedPath != null)
|
||||||
{
|
|
||||||
newPath = $@"0:\{newPath}";
|
|
||||||
}
|
|
||||||
|
|
||||||
Open(newPath, readFile: false);
|
|
||||||
|
|
||||||
// Check if open succeeded.
|
|
||||||
if (path != null)
|
|
||||||
{
|
{
|
||||||
|
path = selectedPath;
|
||||||
Save();
|
Save();
|
||||||
}
|
}
|
||||||
});
|
}, selectDirectoryOnly: true);
|
||||||
prompt.Show();
|
fileBrowser.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Save()
|
private void Save()
|
||||||
@@ -270,7 +267,7 @@ namespace CMLeonOS.Gui.Apps.CodeStudio
|
|||||||
runButton.OnClick = RunClicked;
|
runButton.OnClick = RunClicked;
|
||||||
wm.AddWindow(runButton);
|
wm.AddWindow(runButton);
|
||||||
|
|
||||||
editor = new TextBox(mainWindow, 0, headersHeight, mainWindow.Width, mainWindow.Height - headersHeight - problemsHeight - outputHeight - (headersHeight * 3))
|
editor = new CodeEditor(mainWindow, 0, headersHeight, mainWindow.Width, mainWindow.Height - headersHeight - problemsHeight - outputHeight - (headersHeight * 3))
|
||||||
{
|
{
|
||||||
Background = Theme.CodeBackground,
|
Background = Theme.CodeBackground,
|
||||||
Foreground = Color.White,
|
Foreground = Color.White,
|
||||||
@@ -278,6 +275,7 @@ namespace CMLeonOS.Gui.Apps.CodeStudio
|
|||||||
Changed = TextChanged,
|
Changed = TextChanged,
|
||||||
MultiLine = true
|
MultiLine = true
|
||||||
};
|
};
|
||||||
|
editor.SetSyntaxHighlighting(true, ".lua");
|
||||||
wm.AddWindow(editor);
|
wm.AddWindow(editor);
|
||||||
|
|
||||||
problems = new TextBox(mainWindow, 0, headersHeight + editor.Height + headersHeight, mainWindow.Width, problemsHeight + (headersHeight * 2))
|
problems = new TextBox(mainWindow, 0, headersHeight + editor.Height + headersHeight, mainWindow.Width, problemsHeight + (headersHeight * 2))
|
||||||
|
|||||||
150
Gui/Apps/CodeStudio/LuaSyntaxHighlighter.cs
Normal file
150
Gui/Apps/CodeStudio/LuaSyntaxHighlighter.cs
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
namespace CMLeonOS.Gui.Apps.CodeStudio
|
||||||
|
{
|
||||||
|
internal static class LuaSyntaxHighlighter
|
||||||
|
{
|
||||||
|
private static readonly List<string> Keywords = new List<string>
|
||||||
|
{
|
||||||
|
"and", "break", "do", "else", "elseif", "end", "false", "for", "function", "if", "in", "local", "nil", "not", "or", "repeat", "return", "then", "true", "until", "while"
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly List<string> Builtins = new List<string>
|
||||||
|
{
|
||||||
|
"print", "type", "tostring", "tonumber", "ipairs", "pairs", "table", "string", "math", "io", "os", "coroutine", "debug", "package", "utf8", "bit32"
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly List<string> Operators = new List<string>
|
||||||
|
{
|
||||||
|
"+", "-", "*", "/", "%", "^", "#", "==", "~=", "<=", ">=", "<", ">", "=", "(", ")", "[", "]", "{", "}", ";", ":", ",", "..", "...", "."
|
||||||
|
};
|
||||||
|
|
||||||
|
internal static class Colors
|
||||||
|
{
|
||||||
|
internal static Color Keyword = Color.FromArgb(255, 0, 128);
|
||||||
|
internal static Color Builtin = Color.FromArgb(0, 128, 0);
|
||||||
|
internal static Color String = Color.FromArgb(163, 21, 21);
|
||||||
|
internal static Color Number = Color.FromArgb(0, 0, 255);
|
||||||
|
internal static Color Comment = Color.FromArgb(128, 128, 128);
|
||||||
|
internal static Color Operator = Color.FromArgb(0, 0, 0);
|
||||||
|
internal static Color Default = Color.White;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class HighlightedToken
|
||||||
|
{
|
||||||
|
internal string Text;
|
||||||
|
internal Color Color;
|
||||||
|
|
||||||
|
internal HighlightedToken(string text, Color color)
|
||||||
|
{
|
||||||
|
Text = text;
|
||||||
|
Color = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static List<HighlightedToken> HighlightLine(string line)
|
||||||
|
{
|
||||||
|
var tokens = new List<HighlightedToken>();
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while (i < line.Length)
|
||||||
|
{
|
||||||
|
char c = line[i];
|
||||||
|
|
||||||
|
if (char.IsWhiteSpace(c))
|
||||||
|
{
|
||||||
|
int start = i;
|
||||||
|
while (i < line.Length && char.IsWhiteSpace(line[i]))
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
tokens.Add(new HighlightedToken(line.Substring(start, i - start), Colors.Default));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c == '-' && i + 1 < line.Length && line[i + 1] == '-')
|
||||||
|
{
|
||||||
|
int start = i;
|
||||||
|
i += 2;
|
||||||
|
while (i < line.Length && line[i] != '\n')
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
tokens.Add(new HighlightedToken(line.Substring(start, i - start), Colors.Comment));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c == '"' || c == '\'')
|
||||||
|
{
|
||||||
|
int start = i;
|
||||||
|
i++;
|
||||||
|
while (i < line.Length && line[i] != c)
|
||||||
|
{
|
||||||
|
if (line[i] == '\\' && i + 1 < line.Length)
|
||||||
|
{
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i < line.Length)
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
tokens.Add(new HighlightedToken(line.Substring(start, i - start), Colors.String));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (char.IsDigit(c))
|
||||||
|
{
|
||||||
|
int start = i;
|
||||||
|
while (i < line.Length && (char.IsDigit(line[i]) || line[i] == '.'))
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
tokens.Add(new HighlightedToken(line.Substring(start, i - start), Colors.Number));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (char.IsLetter(c) || c == '_')
|
||||||
|
{
|
||||||
|
int start = i;
|
||||||
|
while (i < line.Length && (char.IsLetterOrDigit(line[i]) || line[i] == '_'))
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
string word = line.Substring(start, i - start);
|
||||||
|
|
||||||
|
if (Keywords.Contains(word))
|
||||||
|
{
|
||||||
|
tokens.Add(new HighlightedToken(word, Colors.Keyword));
|
||||||
|
}
|
||||||
|
else if (Builtins.Contains(word))
|
||||||
|
{
|
||||||
|
tokens.Add(new HighlightedToken(word, Colors.Builtin));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tokens.Add(new HighlightedToken(word, Colors.Default));
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Operators.Contains(c.ToString()))
|
||||||
|
{
|
||||||
|
tokens.Add(new HighlightedToken(c.ToString(), Colors.Operator));
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
tokens.Add(new HighlightedToken(c.ToString(), Colors.Default));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,13 +19,13 @@ namespace CMLeonOS.Gui.Apps
|
|||||||
AppWindow window;
|
AppWindow window;
|
||||||
|
|
||||||
WindowManager wm = ProcessManager.GetProcess<WindowManager>();
|
WindowManager wm = ProcessManager.GetProcess<WindowManager>();
|
||||||
|
|
||||||
SettingsService settingsService = ProcessManager.GetProcess<SettingsService>();
|
SettingsService settingsService = ProcessManager.GetProcess<SettingsService>();
|
||||||
|
|
||||||
TextBox textBox;
|
TextBox textBox;
|
||||||
|
|
||||||
ShortcutBar shortcutBar;
|
ShortcutBar shortcutBar;
|
||||||
|
|
||||||
|
FileBrowser fileBrowser;
|
||||||
|
|
||||||
private string? path = null;
|
private string? path = null;
|
||||||
|
|
||||||
private bool modified = false;
|
private bool modified = false;
|
||||||
@@ -70,12 +70,6 @@ namespace CMLeonOS.Gui.Apps
|
|||||||
{
|
{
|
||||||
if (newPath == null) return;
|
if (newPath == null) return;
|
||||||
|
|
||||||
if (!FileSecurity.CanAccess(path))
|
|
||||||
{
|
|
||||||
MessageBox messageBox = new MessageBox(this, "Notepad", $"Access to '{Path.GetFileName(newPath)}' is unauthorised.");
|
|
||||||
messageBox.Show();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (readFile && !File.Exists(newPath))
|
if (readFile && !File.Exists(newPath))
|
||||||
{
|
{
|
||||||
MessageBox messageBox = new MessageBox(this, "Notepad", $"No such file '{Path.GetFileName(newPath)}'.");
|
MessageBox messageBox = new MessageBox(this, "Notepad", $"No such file '{Path.GetFileName(newPath)}'.");
|
||||||
@@ -99,35 +93,27 @@ namespace CMLeonOS.Gui.Apps
|
|||||||
|
|
||||||
private void OpenFilePrompt()
|
private void OpenFilePrompt()
|
||||||
{
|
{
|
||||||
PromptBox prompt = new PromptBox(this, "Open File", "Enter the path to open.", "Path", (string newPath) =>
|
fileBrowser = new FileBrowser(this, wm, (string selectedPath) =>
|
||||||
{
|
{
|
||||||
if (!newPath.Contains(':'))
|
if (selectedPath != null)
|
||||||
{
|
{
|
||||||
newPath = $@"0:\{newPath}";
|
Open(selectedPath);
|
||||||
}
|
}
|
||||||
Open(newPath);
|
|
||||||
});
|
});
|
||||||
prompt.Show();
|
fileBrowser.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SaveAsPrompt()
|
private void SaveAsPrompt()
|
||||||
{
|
{
|
||||||
PromptBox prompt = new PromptBox(this, "Save As", "Enter the path to save to.", "Path", (string newPath) =>
|
fileBrowser = new FileBrowser(this, wm, (string selectedPath) =>
|
||||||
{
|
{
|
||||||
if (!newPath.Contains(':'))
|
if (selectedPath != null)
|
||||||
{
|
|
||||||
newPath = $@"0:\{newPath}";
|
|
||||||
}
|
|
||||||
|
|
||||||
Open(newPath, readFile: false);
|
|
||||||
|
|
||||||
// Check if open succeeded.
|
|
||||||
if (path != null)
|
|
||||||
{
|
{
|
||||||
|
path = selectedPath;
|
||||||
Save();
|
Save();
|
||||||
}
|
}
|
||||||
});
|
}, selectDirectoryOnly: true);
|
||||||
prompt.Show();
|
fileBrowser.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Save()
|
private void Save()
|
||||||
|
|||||||
313
Gui/UILib/FileBrowser.cs
Normal file
313
Gui/UILib/FileBrowser.cs
Normal file
@@ -0,0 +1,313 @@
|
|||||||
|
using CMLeonOS;
|
||||||
|
using CMLeonOS.Gui.UILib;
|
||||||
|
using Cosmos.System.Graphics;
|
||||||
|
using System.Drawing;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace CMLeonOS.Gui.UILib
|
||||||
|
{
|
||||||
|
internal class FileBrowser
|
||||||
|
{
|
||||||
|
private Process process;
|
||||||
|
private WindowManager wm;
|
||||||
|
private Window window;
|
||||||
|
private Table fileTable;
|
||||||
|
private TextBox pathBox;
|
||||||
|
private TextBox fileNameBox;
|
||||||
|
private Button upButton;
|
||||||
|
private Button selectButton;
|
||||||
|
private Button cancelButton;
|
||||||
|
|
||||||
|
private string currentPath = @"0:\";
|
||||||
|
private string selectedPath = null;
|
||||||
|
private Action<string> onFileSelected;
|
||||||
|
private bool selectDirectoryOnly = false;
|
||||||
|
|
||||||
|
private const int headerHeight = 32;
|
||||||
|
private const int buttonHeight = 28;
|
||||||
|
private const int buttonWidth = 80;
|
||||||
|
private const int fileNameBoxHeight = 24;
|
||||||
|
|
||||||
|
internal FileBrowser(Process process, WindowManager wm, Action<string> onFileSelected, bool selectDirectoryOnly = false)
|
||||||
|
{
|
||||||
|
this.process = process;
|
||||||
|
this.wm = wm;
|
||||||
|
this.onFileSelected = onFileSelected;
|
||||||
|
this.selectDirectoryOnly = selectDirectoryOnly;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Icons
|
||||||
|
{
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.Files.Directory.bmp")]
|
||||||
|
private static byte[] _iconBytes_Directory;
|
||||||
|
internal static Bitmap Icon_Directory = new Bitmap(_iconBytes_Directory);
|
||||||
|
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.Files.File.bmp")]
|
||||||
|
private static byte[] _iconBytes_File;
|
||||||
|
internal static Bitmap Icon_File = new Bitmap(_iconBytes_File);
|
||||||
|
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.Files.File_Text.bmp")]
|
||||||
|
private static byte[] _iconBytes_File_Text;
|
||||||
|
internal static Bitmap Icon_File_Text = new Bitmap(_iconBytes_File_Text);
|
||||||
|
|
||||||
|
[IL2CPU.API.Attribs.ManifestResourceStream(ResourceName = "CMLeonOS.Gui.Resources.Files.Up.bmp")]
|
||||||
|
private static byte[] _iconBytes_Up;
|
||||||
|
internal static Bitmap Icon_Up = new Bitmap(_iconBytes_Up);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Bitmap GetFileIcon(string path)
|
||||||
|
{
|
||||||
|
string extension = Path.GetExtension(path).ToLower();
|
||||||
|
|
||||||
|
return extension switch
|
||||||
|
{
|
||||||
|
".txt" or ".md" or ".log" or ".lua" or ".rs" => Icons.Icon_File_Text,
|
||||||
|
_ => Icons.Icon_File
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PopulateFileTable()
|
||||||
|
{
|
||||||
|
fileTable.Cells.Clear();
|
||||||
|
fileTable.SelectedCellIndex = -1;
|
||||||
|
|
||||||
|
bool empty = true;
|
||||||
|
|
||||||
|
foreach (string path in Directory.GetDirectories(currentPath))
|
||||||
|
{
|
||||||
|
fileTable.Cells.Add(new TableCell(Icons.Icon_Directory, Path.GetFileName(path), tag: "Directory"));
|
||||||
|
empty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (string path in Directory.GetFiles(currentPath))
|
||||||
|
{
|
||||||
|
fileTable.Cells.Add(new TableCell(GetFileIcon(path), Path.GetFileName(path), tag: "File"));
|
||||||
|
empty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty)
|
||||||
|
{
|
||||||
|
fileTable.Clear(fileTable.Background);
|
||||||
|
fileTable.DrawString("This folder is empty.", Color.Black, (fileTable.Width / 2) - 80, 12);
|
||||||
|
wm.Update(fileTable);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fileTable.Render();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PathBoxChanged()
|
||||||
|
{
|
||||||
|
string inputPath = pathBox.Text;
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(inputPath))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inputPath.Contains(':'))
|
||||||
|
{
|
||||||
|
inputPath = $@"0:\{inputPath}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Directory.Exists(inputPath))
|
||||||
|
{
|
||||||
|
currentPath = inputPath;
|
||||||
|
PopulateFileTable();
|
||||||
|
}
|
||||||
|
else if (File.Exists(inputPath))
|
||||||
|
{
|
||||||
|
currentPath = Path.GetDirectoryName(inputPath);
|
||||||
|
PopulateFileTable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PathBoxSubmitted()
|
||||||
|
{
|
||||||
|
string inputPath = pathBox.Text;
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(inputPath))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inputPath.Contains(':'))
|
||||||
|
{
|
||||||
|
inputPath = $@"0:\{inputPath}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (File.Exists(inputPath) || (selectDirectoryOnly && Directory.Exists(inputPath)))
|
||||||
|
{
|
||||||
|
selectedPath = inputPath;
|
||||||
|
onFileSelected?.Invoke(selectedPath);
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
else if (Directory.Exists(inputPath))
|
||||||
|
{
|
||||||
|
currentPath = inputPath;
|
||||||
|
PopulateFileTable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpClicked(int x, int y)
|
||||||
|
{
|
||||||
|
if (currentPath.Length > 3)
|
||||||
|
{
|
||||||
|
string parentPath = Path.GetDirectoryName(currentPath);
|
||||||
|
if (!string.IsNullOrEmpty(parentPath))
|
||||||
|
{
|
||||||
|
currentPath = @"0:\";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentPath = parentPath;
|
||||||
|
}
|
||||||
|
PopulateFileTable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SelectClicked(int x, int y)
|
||||||
|
{
|
||||||
|
if (fileTable.SelectedCellIndex >= 0)
|
||||||
|
{
|
||||||
|
TableCell selectedCell = fileTable.Cells[fileTable.SelectedCellIndex];
|
||||||
|
string selectedName = selectedCell.Text;
|
||||||
|
string fullPath = Path.Combine(currentPath, selectedName);
|
||||||
|
|
||||||
|
string tag = selectedCell.Tag as string;
|
||||||
|
if (tag == "Directory")
|
||||||
|
{
|
||||||
|
currentPath = fullPath;
|
||||||
|
PopulateFileTable();
|
||||||
|
}
|
||||||
|
else if (tag == "File")
|
||||||
|
{
|
||||||
|
if (selectDirectoryOnly)
|
||||||
|
{
|
||||||
|
string fileName = fileNameBox.Text;
|
||||||
|
if (string.IsNullOrWhiteSpace(fileName))
|
||||||
|
{
|
||||||
|
fileName = selectedName;
|
||||||
|
}
|
||||||
|
selectedPath = Path.Combine(currentPath, fileName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
selectedPath = fullPath;
|
||||||
|
}
|
||||||
|
onFileSelected?.Invoke(selectedPath);
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (selectDirectoryOnly)
|
||||||
|
{
|
||||||
|
string fileName = fileNameBox.Text;
|
||||||
|
if (!string.IsNullOrWhiteSpace(fileName))
|
||||||
|
{
|
||||||
|
selectedPath = Path.Combine(currentPath, fileName);
|
||||||
|
onFileSelected?.Invoke(selectedPath);
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FileTableSelected(int index)
|
||||||
|
{
|
||||||
|
SelectClicked(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CancelClicked(int x, int y)
|
||||||
|
{
|
||||||
|
selectedPath = null;
|
||||||
|
onFileSelected?.Invoke(null);
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FileTableDoubleClicked(int index)
|
||||||
|
{
|
||||||
|
SelectClicked(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Show()
|
||||||
|
{
|
||||||
|
window = new Window(process, 100, 100, 500, 400);
|
||||||
|
wm.AddWindow(window);
|
||||||
|
|
||||||
|
window.DrawString(selectDirectoryOnly ? "Save As" : "Open File", Color.DarkBlue, 12, 12);
|
||||||
|
|
||||||
|
pathBox = new TextBox(window, 8, 40, window.Width - 16, 24)
|
||||||
|
{
|
||||||
|
Background = Color.White,
|
||||||
|
Foreground = Color.Black,
|
||||||
|
Text = currentPath,
|
||||||
|
ReadOnly = false
|
||||||
|
};
|
||||||
|
pathBox.Changed = PathBoxChanged;
|
||||||
|
pathBox.Submitted = PathBoxSubmitted;
|
||||||
|
wm.AddWindow(pathBox);
|
||||||
|
|
||||||
|
if (selectDirectoryOnly)
|
||||||
|
{
|
||||||
|
window.DrawString("File name:", Color.Black, 8, 72);
|
||||||
|
|
||||||
|
fileNameBox = new TextBox(window, 8, 96, window.Width - 16, fileNameBoxHeight)
|
||||||
|
{
|
||||||
|
Background = Color.White,
|
||||||
|
Foreground = Color.Black,
|
||||||
|
Text = "",
|
||||||
|
ReadOnly = false
|
||||||
|
};
|
||||||
|
wm.AddWindow(fileNameBox);
|
||||||
|
}
|
||||||
|
|
||||||
|
upButton = new Button(window, 8, selectDirectoryOnly ? 128 : 72, 60, buttonHeight)
|
||||||
|
{
|
||||||
|
Text = "Up",
|
||||||
|
Image = Icons.Icon_Up,
|
||||||
|
ImageLocation = Button.ButtonImageLocation.Left
|
||||||
|
};
|
||||||
|
upButton.OnClick = UpClicked;
|
||||||
|
wm.AddWindow(upButton);
|
||||||
|
|
||||||
|
int tableY = selectDirectoryOnly ? 128 + buttonHeight + 8 : 72 + buttonHeight + 8;
|
||||||
|
int tableHeight = window.Height - tableY - buttonHeight - 8 - buttonHeight - 16;
|
||||||
|
|
||||||
|
fileTable = new Table(window, 8, tableY, window.Width - 16, tableHeight)
|
||||||
|
{
|
||||||
|
AllowDeselection = false
|
||||||
|
};
|
||||||
|
fileTable.TableCellSelected = FileTableSelected;
|
||||||
|
PopulateFileTable();
|
||||||
|
wm.AddWindow(fileTable);
|
||||||
|
|
||||||
|
int buttonY = window.Height - buttonHeight - 8;
|
||||||
|
selectButton = new Button(window, window.Width - buttonWidth - 8, buttonY, buttonWidth, buttonHeight)
|
||||||
|
{
|
||||||
|
Text = selectDirectoryOnly ? "Save" : "Open"
|
||||||
|
};
|
||||||
|
selectButton.OnClick = SelectClicked;
|
||||||
|
wm.AddWindow(selectButton);
|
||||||
|
|
||||||
|
cancelButton = new Button(window, window.Width - buttonWidth * 2 - 16, buttonY, buttonWidth, buttonHeight)
|
||||||
|
{
|
||||||
|
Text = "Cancel"
|
||||||
|
};
|
||||||
|
cancelButton.OnClick = CancelClicked;
|
||||||
|
wm.AddWindow(cancelButton);
|
||||||
|
|
||||||
|
wm.Update(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Close()
|
||||||
|
{
|
||||||
|
if (window != null)
|
||||||
|
{
|
||||||
|
wm.RemoveWindow(window);
|
||||||
|
window = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,6 +19,11 @@ namespace CMLeonOS.Gui.UILib
|
|||||||
internal Action Submitted;
|
internal Action Submitted;
|
||||||
internal Action Changed;
|
internal Action Changed;
|
||||||
|
|
||||||
|
internal virtual void RenderLine(int lineIndex, string lineText, int lineY, int xOffset)
|
||||||
|
{
|
||||||
|
DrawString(lineText, Foreground, xOffset, lineY);
|
||||||
|
}
|
||||||
|
|
||||||
internal string Text
|
internal string Text
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -355,7 +360,8 @@ namespace CMLeonOS.Gui.UILib
|
|||||||
|
|
||||||
if (i < lines.Count)
|
if (i < lines.Count)
|
||||||
{
|
{
|
||||||
DrawString(Shield ? new string('*', lines[i].Length) : lines[i], Foreground, -scrollX, lineY);
|
string lineText = Shield ? new string('*', lines[i].Length) : lines[i];
|
||||||
|
RenderLine(i, lineText, lineY, -scrollX);
|
||||||
|
|
||||||
if (caretLine == i)
|
if (caretLine == i)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user