CodeEditorPanel - Change font size via Ctrl+Scroll Wheel (#44)
Co-authored-by: Matt Parker <61717342+MattParkerDev@users.noreply.github.com>
This commit is contained in:
@@ -15,202 +15,233 @@ namespace SharpIDE.Godot.Features.CodeEditor;
|
|||||||
|
|
||||||
public partial class CodeEditorPanel : MarginContainer
|
public partial class CodeEditorPanel : MarginContainer
|
||||||
{
|
{
|
||||||
[Export]
|
[Export]
|
||||||
public Texture2D CsFileTexture { get; set; } = null!;
|
public Texture2D CsFileTexture { get; set; } = null!;
|
||||||
public SharpIdeSolutionModel Solution { get; set; } = null!;
|
public SharpIdeSolutionModel Solution { get; set; } = null!;
|
||||||
private PackedScene _sharpIdeCodeEditScene = GD.Load<PackedScene>("res://Features/CodeEditor/SharpIdeCodeEdit.tscn");
|
private PackedScene _sharpIdeCodeEditScene = GD.Load<PackedScene>("res://Features/CodeEditor/SharpIdeCodeEdit.tscn");
|
||||||
private TabContainer _tabContainer = null!;
|
private TabContainer _tabContainer = null!;
|
||||||
private ConcurrentDictionary<SharpIdeProjectModel, ExecutionStopInfo> _debuggerExecutionStopInfoByProject = [];
|
private ConcurrentDictionary<SharpIdeProjectModel, ExecutionStopInfo> _debuggerExecutionStopInfoByProject = [];
|
||||||
|
|
||||||
[Inject] private readonly RunService _runService = null!;
|
[Inject] private readonly RunService _runService = null!;
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
_tabContainer = GetNode<TabContainer>("TabContainer");
|
_tabContainer = GetNode<TabContainer>("TabContainer");
|
||||||
_tabContainer.RemoveChildAndQueueFree(_tabContainer.GetChild(0)); // Remove the default tab
|
_tabContainer.RemoveChildAndQueueFree(_tabContainer.GetChild(0)); // Remove the default tab
|
||||||
_tabContainer.TabClicked += OnTabClicked;
|
_tabContainer.TabClicked += OnTabClicked;
|
||||||
var tabBar = _tabContainer.GetTabBar();
|
var tabBar = _tabContainer.GetTabBar();
|
||||||
tabBar.TabCloseDisplayPolicy = TabBar.CloseButtonDisplayPolicy.ShowAlways;
|
tabBar.TabCloseDisplayPolicy = TabBar.CloseButtonDisplayPolicy.ShowAlways;
|
||||||
tabBar.TabClosePressed += OnTabClosePressed;
|
tabBar.TabClosePressed += OnTabClosePressed;
|
||||||
GlobalEvents.Instance.DebuggerExecutionStopped.Subscribe(OnDebuggerExecutionStopped);
|
GlobalEvents.Instance.DebuggerExecutionStopped.Subscribe(OnDebuggerExecutionStopped);
|
||||||
GlobalEvents.Instance.ProjectStoppedDebugging.Subscribe(OnProjectStoppedDebugging);
|
GlobalEvents.Instance.ProjectStoppedDebugging.Subscribe(OnProjectStoppedDebugging);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void _ExitTree()
|
public override void _GuiInput(InputEvent @event)
|
||||||
{
|
{
|
||||||
var selectedTabIndex = _tabContainer.CurrentTab;
|
if (Input.IsActionPressed(InputStringNames.EditorFontSizeIncrease))
|
||||||
var thisSolution = Singletons.AppState.RecentSlns.Single(s => s.FilePath == Solution.FilePath);
|
{
|
||||||
thisSolution.IdeSolutionState.OpenTabs = _tabContainer.GetChildren().OfType<SharpIdeCodeEdit>()
|
AdjustCodeEditorUiScale(true);
|
||||||
.Select((t, index) => new OpenTab
|
}
|
||||||
{
|
else if (Input.IsActionPressed(InputStringNames.EditorFontSizeDecrease))
|
||||||
FilePath = t.SharpIdeFile.Path,
|
{
|
||||||
CaretLine = t.GetCaretLine(),
|
AdjustCodeEditorUiScale(false);
|
||||||
CaretColumn = t.GetCaretColumn(),
|
}
|
||||||
IsSelected = index == selectedTabIndex
|
}
|
||||||
})
|
|
||||||
.ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void _UnhandledKeyInput(InputEvent @event)
|
private void AdjustCodeEditorUiScale(bool increase)
|
||||||
{
|
{
|
||||||
if (@event.IsActionPressed(InputStringNames.StepOver))
|
const int minFontSize = 8;
|
||||||
{
|
const int maxFontSize = 72;
|
||||||
SendDebuggerStepCommand(DebuggerStepAction.StepOver);
|
|
||||||
}
|
|
||||||
else if (@event.IsActionPressed(InputStringNames.DebuggerStepOut))
|
|
||||||
{
|
|
||||||
SendDebuggerStepCommand(DebuggerStepAction.StepOut);
|
|
||||||
}
|
|
||||||
else if (@event.IsActionPressed(InputStringNames.DebuggerStepIn))
|
|
||||||
{
|
|
||||||
SendDebuggerStepCommand(DebuggerStepAction.StepIn);
|
|
||||||
}
|
|
||||||
else if (@event.IsActionPressed(InputStringNames.DebuggerContinue))
|
|
||||||
{
|
|
||||||
SendDebuggerStepCommand(DebuggerStepAction.Continue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnTabClicked(long tab)
|
var editors = _tabContainer.GetChildren().OfType<SharpIdeCodeEdit>().ToList();
|
||||||
{
|
if (editors.Count is 0) return;
|
||||||
var sharpIdeCodeEdit = _tabContainer.GetChild<SharpIdeCodeEdit>((int)tab);
|
|
||||||
var sharpIdeFile = sharpIdeCodeEdit.SharpIdeFile;
|
|
||||||
var caretLinePosition = new SharpIdeFileLinePosition(sharpIdeCodeEdit.GetCaretLine(), sharpIdeCodeEdit.GetCaretColumn());
|
|
||||||
GodotGlobalEvents.Instance.FileExternallySelected.InvokeParallelFireAndForget(sharpIdeFile, caretLinePosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnTabClosePressed(long tabIndex)
|
var currentFontSize = editors.First().GetThemeFontSize(ThemeStringNames.FontSize);
|
||||||
{
|
var newFontSize = increase
|
||||||
var tab = _tabContainer.GetChild<Control>((int)tabIndex);
|
? Mathf.Clamp(currentFontSize + 2, minFontSize, maxFontSize)
|
||||||
var previousSibling = _tabContainer.GetChildOrNull<SharpIdeCodeEdit>((int)tabIndex - 1);
|
: Mathf.Clamp(currentFontSize - 2, minFontSize, maxFontSize);
|
||||||
if (previousSibling is not null)
|
|
||||||
{
|
|
||||||
var sharpIdeFile = previousSibling.SharpIdeFile;
|
|
||||||
var caretLinePosition = new SharpIdeFileLinePosition(previousSibling.GetCaretLine(), previousSibling.GetCaretColumn());
|
|
||||||
// This isn't actually necessary - closing a tab automatically selects the previous tab, however we need to do it to select the file in sln explorer, record navigation event etc
|
|
||||||
GodotGlobalEvents.Instance.FileExternallySelected.InvokeParallelFireAndForget(sharpIdeFile, caretLinePosition);
|
|
||||||
}
|
|
||||||
_tabContainer.RemoveChild(tab);
|
|
||||||
tab.QueueFree();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task SetSharpIdeFile(SharpIdeFile file, SharpIdeFileLinePosition? fileLinePosition)
|
foreach (var editor in editors)
|
||||||
{
|
{
|
||||||
|
editor.AddThemeFontSizeOverride(ThemeStringNames.FontSize, newFontSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _ExitTree()
|
||||||
|
{
|
||||||
|
var selectedTabIndex = _tabContainer.CurrentTab;
|
||||||
|
var thisSolution = Singletons.AppState.RecentSlns.Single(s => s.FilePath == Solution.FilePath);
|
||||||
|
thisSolution.IdeSolutionState.OpenTabs = _tabContainer.GetChildren().OfType<SharpIdeCodeEdit>()
|
||||||
|
.Select((t, index) => new OpenTab
|
||||||
|
{
|
||||||
|
FilePath = t.SharpIdeFile.Path,
|
||||||
|
CaretLine = t.GetCaretLine(),
|
||||||
|
CaretColumn = t.GetCaretColumn(),
|
||||||
|
IsSelected = index == selectedTabIndex
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _UnhandledKeyInput(InputEvent @event)
|
||||||
|
{
|
||||||
|
if (@event.IsActionPressed(InputStringNames.StepOver))
|
||||||
|
{
|
||||||
|
SendDebuggerStepCommand(DebuggerStepAction.StepOver);
|
||||||
|
}
|
||||||
|
else if (@event.IsActionPressed(InputStringNames.DebuggerStepOut))
|
||||||
|
{
|
||||||
|
SendDebuggerStepCommand(DebuggerStepAction.StepOut);
|
||||||
|
}
|
||||||
|
else if (@event.IsActionPressed(InputStringNames.DebuggerStepIn))
|
||||||
|
{
|
||||||
|
SendDebuggerStepCommand(DebuggerStepAction.StepIn);
|
||||||
|
}
|
||||||
|
else if (@event.IsActionPressed(InputStringNames.DebuggerContinue))
|
||||||
|
{
|
||||||
|
SendDebuggerStepCommand(DebuggerStepAction.Continue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnTabClicked(long tab)
|
||||||
|
{
|
||||||
|
var sharpIdeCodeEdit = _tabContainer.GetChild<SharpIdeCodeEdit>((int)tab);
|
||||||
|
var sharpIdeFile = sharpIdeCodeEdit.SharpIdeFile;
|
||||||
|
var caretLinePosition = new SharpIdeFileLinePosition(sharpIdeCodeEdit.GetCaretLine(), sharpIdeCodeEdit.GetCaretColumn());
|
||||||
|
GodotGlobalEvents.Instance.FileExternallySelected.InvokeParallelFireAndForget(sharpIdeFile, caretLinePosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnTabClosePressed(long tabIndex)
|
||||||
|
{
|
||||||
|
var tab = _tabContainer.GetChild<Control>((int)tabIndex);
|
||||||
|
var previousSibling = _tabContainer.GetChildOrNull<SharpIdeCodeEdit>((int)tabIndex - 1);
|
||||||
|
if (previousSibling is not null)
|
||||||
|
{
|
||||||
|
var sharpIdeFile = previousSibling.SharpIdeFile;
|
||||||
|
var caretLinePosition = new SharpIdeFileLinePosition(previousSibling.GetCaretLine(), previousSibling.GetCaretColumn());
|
||||||
|
// This isn't actually necessary - closing a tab automatically selects the previous tab, however we need to do it to select the file in sln explorer, record navigation event etc
|
||||||
|
GodotGlobalEvents.Instance.FileExternallySelected.InvokeParallelFireAndForget(sharpIdeFile, caretLinePosition);
|
||||||
|
}
|
||||||
|
_tabContainer.RemoveChild(tab);
|
||||||
|
tab.QueueFree();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SetSharpIdeFile(SharpIdeFile file, SharpIdeFileLinePosition? fileLinePosition)
|
||||||
|
{
|
||||||
await Task.CompletedTask.ConfigureAwait(ConfigureAwaitOptions.ForceYielding);
|
await Task.CompletedTask.ConfigureAwait(ConfigureAwaitOptions.ForceYielding);
|
||||||
var existingTab = await this.InvokeAsync(() => _tabContainer.GetChildren().OfType<SharpIdeCodeEdit>().FirstOrDefault(t => t.SharpIdeFile == file));
|
var existingTab = await this.InvokeAsync(() => _tabContainer.GetChildren().OfType<SharpIdeCodeEdit>().FirstOrDefault(t => t.SharpIdeFile == file));
|
||||||
if (existingTab is not null)
|
if (existingTab is not null)
|
||||||
{
|
{
|
||||||
var existingTabIndex = existingTab.GetIndex();
|
var existingTabIndex = existingTab.GetIndex();
|
||||||
await this.InvokeAsync(() =>
|
await this.InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
_tabContainer.CurrentTab = existingTabIndex;
|
_tabContainer.CurrentTab = existingTabIndex;
|
||||||
if (fileLinePosition is not null) existingTab.SetFileLinePosition(fileLinePosition.Value);
|
if (fileLinePosition is not null) existingTab.SetFileLinePosition(fileLinePosition.Value);
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var newTab = _sharpIdeCodeEditScene.Instantiate<SharpIdeCodeEdit>();
|
var newTab = _sharpIdeCodeEditScene.Instantiate<SharpIdeCodeEdit>();
|
||||||
newTab.Solution = Solution;
|
newTab.Solution = Solution;
|
||||||
await this.InvokeAsync(() =>
|
await this.InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
_tabContainer.AddChild(newTab);
|
_tabContainer.AddChild(newTab);
|
||||||
var newTabIndex = _tabContainer.GetTabCount() - 1;
|
var newTabIndex = _tabContainer.GetTabCount() - 1;
|
||||||
_tabContainer.SetIconsForFileExtension(file, newTabIndex);
|
_tabContainer.SetIconsForFileExtension(file, newTabIndex);
|
||||||
_tabContainer.SetTabTitle(newTabIndex, file.Name);
|
_tabContainer.SetTabTitle(newTabIndex, file.Name);
|
||||||
_tabContainer.SetTabTooltip(newTabIndex, file.Path);
|
_tabContainer.SetTabTooltip(newTabIndex, file.Path);
|
||||||
_tabContainer.CurrentTab = newTabIndex;
|
_tabContainer.CurrentTab = newTabIndex;
|
||||||
|
|
||||||
file.IsDirty.Skip(1).SubscribeOnThreadPool().ObserveOnThreadPool().SubscribeAwait(async (isDirty, ct) =>
|
file.IsDirty.Skip(1).SubscribeOnThreadPool().ObserveOnThreadPool().SubscribeAwait(async (isDirty, ct) =>
|
||||||
{
|
{
|
||||||
//GD.Print($"File dirty state changed: {file.Path} is now {(isDirty ? "dirty" : "clean")}");
|
//GD.Print($"File dirty state changed: {file.Path} is now {(isDirty ? "dirty" : "clean")}");
|
||||||
await this.InvokeAsync(() =>
|
await this.InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
var tabIndex = newTab.GetIndex();
|
var tabIndex = newTab.GetIndex();
|
||||||
var title = file.Name + (isDirty ? " (*)" : "");
|
var title = file.Name + (isDirty ? " (*)" : "");
|
||||||
_tabContainer.SetTabTitle(tabIndex, title);
|
_tabContainer.SetTabTitle(tabIndex, title);
|
||||||
});
|
});
|
||||||
}).AddTo(newTab); // needs to be on ui thread
|
}).AddTo(newTab); // needs to be on ui thread
|
||||||
});
|
});
|
||||||
|
|
||||||
await newTab.SetSharpIdeFile(file, fileLinePosition);
|
await newTab.SetSharpIdeFile(file, fileLinePosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly Color ExecutingLineColor = new Color("665001");
|
private static readonly Color ExecutingLineColor = new Color("665001");
|
||||||
private async Task OnDebuggerExecutionStopped(ExecutionStopInfo executionStopInfo)
|
private async Task OnDebuggerExecutionStopped(ExecutionStopInfo executionStopInfo)
|
||||||
{
|
{
|
||||||
Guard.Against.Null(Solution, nameof(Solution));
|
Guard.Against.Null(Solution, nameof(Solution));
|
||||||
|
|
||||||
var currentSharpIdeFile = await this.InvokeAsync<SharpIdeFile>(() => _tabContainer.GetChild<SharpIdeCodeEdit>(_tabContainer.CurrentTab).SharpIdeFile);
|
var currentSharpIdeFile = await this.InvokeAsync<SharpIdeFile>(() => _tabContainer.GetChild<SharpIdeCodeEdit>(_tabContainer.CurrentTab).SharpIdeFile);
|
||||||
|
|
||||||
if (executionStopInfo.FilePath != currentSharpIdeFile?.Path)
|
if (executionStopInfo.FilePath != currentSharpIdeFile?.Path)
|
||||||
{
|
{
|
||||||
var file = Solution.AllFiles[executionStopInfo.FilePath];
|
var file = Solution.AllFiles[executionStopInfo.FilePath];
|
||||||
await GodotGlobalEvents.Instance.FileExternallySelected.InvokeParallelAsync(file, null).ConfigureAwait(false);
|
await GodotGlobalEvents.Instance.FileExternallySelected.InvokeParallelAsync(file, null).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
var lineInt = executionStopInfo.Line - 1; // Debugging is 1-indexed, Godot is 0-indexed
|
var lineInt = executionStopInfo.Line - 1; // Debugging is 1-indexed, Godot is 0-indexed
|
||||||
Guard.Against.Negative(lineInt, nameof(lineInt));
|
Guard.Against.Negative(lineInt, nameof(lineInt));
|
||||||
if (_debuggerExecutionStopInfoByProject.TryGetValue(executionStopInfo.Project, out _)) throw new InvalidOperationException("Debugger is already stopped for this project.");
|
if (_debuggerExecutionStopInfoByProject.TryGetValue(executionStopInfo.Project, out _)) throw new InvalidOperationException("Debugger is already stopped for this project.");
|
||||||
_debuggerExecutionStopInfoByProject[executionStopInfo.Project] = executionStopInfo;
|
_debuggerExecutionStopInfoByProject[executionStopInfo.Project] = executionStopInfo;
|
||||||
|
|
||||||
await this.InvokeAsync(() =>
|
await this.InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
var tabForStopInfo = _tabContainer.GetChildren().OfType<SharpIdeCodeEdit>().Single(t => t.SharpIdeFile.Path == executionStopInfo.FilePath);
|
var tabForStopInfo = _tabContainer.GetChildren().OfType<SharpIdeCodeEdit>().Single(t => t.SharpIdeFile.Path == executionStopInfo.FilePath);
|
||||||
tabForStopInfo.SetLineBackgroundColor(lineInt, ExecutingLineColor);
|
tabForStopInfo.SetLineBackgroundColor(lineInt, ExecutingLineColor);
|
||||||
tabForStopInfo.SetLineAsExecuting(lineInt, true);
|
tabForStopInfo.SetLineAsExecuting(lineInt, true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum DebuggerStepAction { StepOver, StepIn, StepOut, Continue }
|
private enum DebuggerStepAction { StepOver, StepIn, StepOut, Continue }
|
||||||
[RequiresGodotUiThread]
|
[RequiresGodotUiThread]
|
||||||
private void SendDebuggerStepCommand(DebuggerStepAction debuggerStepAction)
|
private void SendDebuggerStepCommand(DebuggerStepAction debuggerStepAction)
|
||||||
{
|
{
|
||||||
// TODO: Debugging needs a rework - debugging commands should be scoped to a debug session, ie the debug panel sub-tabs
|
// TODO: Debugging needs a rework - debugging commands should be scoped to a debug session, ie the debug panel sub-tabs
|
||||||
// For now, just use the first project that is currently stopped
|
// For now, just use the first project that is currently stopped
|
||||||
var stoppedProjects = _debuggerExecutionStopInfoByProject.Keys.ToList();
|
var stoppedProjects = _debuggerExecutionStopInfoByProject.Keys.ToList();
|
||||||
if (stoppedProjects.Count == 0) return; // ie not currently stopped anywhere
|
if (stoppedProjects.Count == 0) return; // ie not currently stopped anywhere
|
||||||
var project = stoppedProjects[0];
|
var project = stoppedProjects[0];
|
||||||
if (!_debuggerExecutionStopInfoByProject.TryRemove(project, out var executionStopInfo)) return;
|
if (!_debuggerExecutionStopInfoByProject.TryRemove(project, out var executionStopInfo)) return;
|
||||||
var godotLine = executionStopInfo.Line - 1;
|
var godotLine = executionStopInfo.Line - 1;
|
||||||
var tabForStopInfo = _tabContainer.GetChildren().OfType<SharpIdeCodeEdit>().Single(t => t.SharpIdeFile.Path == executionStopInfo.FilePath);
|
var tabForStopInfo = _tabContainer.GetChildren().OfType<SharpIdeCodeEdit>().Single(t => t.SharpIdeFile.Path == executionStopInfo.FilePath);
|
||||||
tabForStopInfo.SetLineAsExecuting(godotLine, false);
|
tabForStopInfo.SetLineAsExecuting(godotLine, false);
|
||||||
tabForStopInfo.SetLineColour(godotLine);
|
tabForStopInfo.SetLineColour(godotLine);
|
||||||
var threadId = executionStopInfo.ThreadId;
|
var threadId = executionStopInfo.ThreadId;
|
||||||
_ = Task.GodotRun(async () =>
|
_ = Task.GodotRun(async () =>
|
||||||
{
|
{
|
||||||
var task = debuggerStepAction switch
|
var task = debuggerStepAction switch
|
||||||
{
|
{
|
||||||
DebuggerStepAction.StepOver => _runService.SendDebuggerStepOver(threadId),
|
DebuggerStepAction.StepOver => _runService.SendDebuggerStepOver(threadId),
|
||||||
DebuggerStepAction.StepIn => _runService.SendDebuggerStepInto(threadId),
|
DebuggerStepAction.StepIn => _runService.SendDebuggerStepInto(threadId),
|
||||||
DebuggerStepAction.StepOut => _runService.SendDebuggerStepOut(threadId),
|
DebuggerStepAction.StepOut => _runService.SendDebuggerStepOut(threadId),
|
||||||
DebuggerStepAction.Continue => _runService.SendDebuggerContinue(threadId),
|
DebuggerStepAction.Continue => _runService.SendDebuggerContinue(threadId),
|
||||||
_ => throw new ArgumentOutOfRangeException(nameof(debuggerStepAction), debuggerStepAction, null)
|
_ => throw new ArgumentOutOfRangeException(nameof(debuggerStepAction), debuggerStepAction, null)
|
||||||
};
|
};
|
||||||
await task;
|
await task;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task OnProjectStoppedDebugging(SharpIdeProjectModel project)
|
private async Task OnProjectStoppedDebugging(SharpIdeProjectModel project)
|
||||||
{
|
{
|
||||||
if (!_debuggerExecutionStopInfoByProject.TryRemove(project, out var executionStopInfo)) return;
|
if (!_debuggerExecutionStopInfoByProject.TryRemove(project, out var executionStopInfo)) return;
|
||||||
await this.InvokeAsync(() =>
|
await this.InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
var godotLine = executionStopInfo.Line - 1;
|
var godotLine = executionStopInfo.Line - 1;
|
||||||
var tabForStopInfo = _tabContainer.GetChildren().OfType<SharpIdeCodeEdit>().Single(t => t.SharpIdeFile.Path == executionStopInfo.FilePath);
|
var tabForStopInfo = _tabContainer.GetChildren().OfType<SharpIdeCodeEdit>().Single(t => t.SharpIdeFile.Path == executionStopInfo.FilePath);
|
||||||
tabForStopInfo.SetLineAsExecuting(godotLine, false);
|
tabForStopInfo.SetLineAsExecuting(godotLine, false);
|
||||||
tabForStopInfo.SetLineColour(godotLine);
|
tabForStopInfo.SetLineColour(godotLine);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
file static class TabContainerExtensions
|
file static class TabContainerExtensions
|
||||||
{
|
{
|
||||||
extension(TabContainer tabContainer)
|
extension(TabContainer tabContainer)
|
||||||
{
|
{
|
||||||
public void SetIconsForFileExtension(SharpIdeFile file, int newTabIndex)
|
public void SetIconsForFileExtension(SharpIdeFile file, int newTabIndex)
|
||||||
{
|
{
|
||||||
var (icon, overlayIcon) = FileIconHelper.GetIconForFileExtension(file.Extension);
|
var (icon, overlayIcon) = FileIconHelper.GetIconForFileExtension(file.Extension);
|
||||||
tabContainer.SetTabIcon(newTabIndex, icon);
|
tabContainer.SetTabIcon(newTabIndex, icon);
|
||||||
|
|
||||||
// Unfortunately TabContainer doesn't have a SetTabIconOverlay method
|
// Unfortunately TabContainer doesn't have a SetTabIconOverlay method
|
||||||
//tabContainer.SetIconOverlay(0, overlayIcon);
|
//tabContainer.SetIconOverlay(0, overlayIcon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -14,6 +14,8 @@ public static class InputStringNames
|
|||||||
public static readonly StringName FindFiles = nameof(FindFiles);
|
public static readonly StringName FindFiles = nameof(FindFiles);
|
||||||
public static readonly StringName SaveFile = nameof(SaveFile);
|
public static readonly StringName SaveFile = nameof(SaveFile);
|
||||||
public static readonly StringName SaveAllFiles = nameof(SaveAllFiles);
|
public static readonly StringName SaveAllFiles = nameof(SaveAllFiles);
|
||||||
|
public static readonly StringName EditorFontSizeIncrease = nameof(EditorFontSizeIncrease);
|
||||||
|
public static readonly StringName EditorFontSizeDecrease = nameof(EditorFontSizeDecrease);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ThemeStringNames
|
public static class ThemeStringNames
|
||||||
|
|||||||
@@ -88,6 +88,16 @@ DebuggerStepOut={
|
|||||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":true,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194342,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":true,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194342,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
EditorFontSizeIncrease={
|
||||||
|
"deadzone": 0.2,
|
||||||
|
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":true,"meta_pressed":false,"button_mask":8,"position":Vector2(96, 15),"global_position":Vector2(105, 63),"factor":1.0,"button_index":4,"canceled":false,"pressed":true,"double_click":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
EditorFontSizeDecrease={
|
||||||
|
"deadzone": 0.2,
|
||||||
|
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":true,"meta_pressed":false,"button_mask":16,"position":Vector2(120, 12),"global_position":Vector2(129, 60),"factor":1.0,"button_index":5,"canceled":false,"pressed":true,"double_click":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
[rendering]
|
[rendering]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user