diff --git a/BeefBuild/src/BuildApp.bf b/BeefBuild/src/BuildApp.bf index 6b17027e..ee3c3878 100644 --- a/BeefBuild/src/BuildApp.bf +++ b/BeefBuild/src/BuildApp.bf @@ -13,7 +13,7 @@ namespace BeefBuild const int cProgressSize = 30; int mProgressIdx = 0; public bool mIsTest; - public bool mIsFailTest; + public bool mTestIncludeIgnored; public bool mDidRun; /*void Test() @@ -103,7 +103,7 @@ namespace BeefBuild if (mIsTest) { - RunTests(false); + RunTests(mTestIncludeIgnored, false); } else if (mVerb != .New) Compile(.Normal, null); @@ -129,8 +129,9 @@ namespace BeefBuild case "-test": mIsTest = true; return true; - case "-testfail": - mIsFailTest = true; + case "-testall": + mIsTest = true; + mTestIncludeIgnored = true; return true; case "-clean": mWantsClean = true; diff --git a/BeefLibs/Beefy2D/src/widgets/EditWidget.bf b/BeefLibs/Beefy2D/src/widgets/EditWidget.bf index f165a36a..feecc6e9 100644 --- a/BeefLibs/Beefy2D/src/widgets/EditWidget.bf +++ b/BeefLibs/Beefy2D/src/widgets/EditWidget.bf @@ -1842,22 +1842,31 @@ namespace Beefy.widgets return Math.Max(0, Math.Min(newY, mHeight - mEditWidget.mScrollContentContainer.mHeight - mMaximalScrollAddedHeight)); } - int32 GetCharType(char8 theChar) + enum CharType + { + Unknown = -1, + NewLine, + WhiteSpace, + NonBreaking, + Opening, + Other + } + CharType GetCharType(char8 theChar) { if (theChar == '\n') - return 2; + return .NewLine; if (theChar.IsWhiteSpace) - return 0; + return .WhiteSpace; if (IsNonBreakingChar(theChar)) - return 1; + return .NonBreaking; // We break on each instance of these switch (theChar) { case '<', '>', '(', ')', '[', ']', '{', '}': - return 3; + return .Opening; } - return 4; + return .Other; } public void GetTextCoordAtCursor(out float x, out float y) @@ -2053,9 +2062,11 @@ namespace Beefy.widgets } } + bool isWordMove = mWidgetWindow.IsKeyDown(.Alt); wasMoveKey = true; int anIndex = GetTextIdx(lineIdx, lineChar); - int prevCharType = (anIndex > 0) ? GetCharType((char8)mData.mText[anIndex - 1].mChar) : -1; + char8 prevC = 0; + CharType prevCharType = (anIndex > 0) ? GetCharType((char8)mData.mText[anIndex - 1].mChar) : .Unknown; while (true) { if (lineChar > 0) @@ -2082,19 +2093,23 @@ namespace Beefy.widgets if (anIndex == 0) break; - char8 aChar = (char8)mData.mText[anIndex - 1].mChar; - int32 char8Type = GetCharType(aChar); - if (prevCharType == 3) + char8 c = (char8)mData.mText[anIndex - 1].mChar; + CharType char8Type = GetCharType(c); + if (prevCharType == .Opening) break; if (char8Type != prevCharType) { if ((char8Type == 0) && (prevCharType != 0)) break; - if ((prevCharType == 2) || (prevCharType == 1) || (prevCharType == 4)) + if ((prevCharType == .NewLine) || (prevCharType == .NonBreaking) || (prevCharType == .Other)) break; } + if ((isWordMove) && (c.IsLower) && (prevC.IsUpper)) + break; + prevCharType = char8Type; + prevC = c; } } } @@ -2131,9 +2146,11 @@ namespace Beefy.widgets } } + bool isWordMove = mWidgetWindow.IsKeyDown(.Alt); wasMoveKey = true; int anIndex = GetTextIdx(lineIdx, lineChar); - int prevCharType = (anIndex < mData.mTextLength) ? GetCharType((char8)mData.mText[anIndex].mChar) : -1; + char8 prevC = 0; + CharType prevCharType = (anIndex < mData.mTextLength) ? GetCharType((char8)mData.mText[anIndex].mChar) : .Unknown; while (true) { int lineStart; @@ -2165,19 +2182,23 @@ namespace Beefy.widgets if (anIndex == mData.mTextLength) break; - char8 aChar = (char8)mData.mText[anIndex].mChar; - int32 char8Type = GetCharType(aChar); - if (char8Type == 3) + char8 c = (char8)mData.mText[anIndex].mChar; + CharType char8Type = GetCharType(c); + if (char8Type == .Opening) break; if (char8Type != prevCharType) { - if ((char8Type != 0) && (prevCharType == 0)) + if ((char8Type != .WhiteSpace) && (prevCharType == .WhiteSpace)) break; - if ((char8Type == 2) || (char8Type == 1) || (char8Type == 4)) + if ((char8Type == .NewLine) || (char8Type == .NonBreaking) || (char8Type == .Other)) break; } + if ((isWordMove) && (c.IsUpper) && (prevC.IsLower)) + break; + prevCharType = char8Type; + prevC = c; } } } diff --git a/BeefLibs/corlib/src/Collections/Generic/HashSet.bf b/BeefLibs/corlib/src/Collections/Generic/HashSet.bf index fcf9047a..d900c2cc 100644 --- a/BeefLibs/corlib/src/Collections/Generic/HashSet.bf +++ b/BeefLibs/corlib/src/Collections/Generic/HashSet.bf @@ -290,11 +290,19 @@ namespace System.Collections.Generic } /// Number of elements in this hashset - public int32 Count + public int Count { get { return mCount; } } + public bool IsEmpty + { + get + { + return mCount == 0; + } + } + /// Whether this is readonly /*bool ICollection.IsReadOnly { diff --git a/IDE/BeefProj.toml b/IDE/BeefProj.toml index 6921b2d6..c45095ed 100644 --- a/IDE/BeefProj.toml +++ b/IDE/BeefProj.toml @@ -25,7 +25,7 @@ OtherLinkFlags = "" TargetDirectory = "$(WorkspaceDir)/dist" TargetName = "BeefIDE_d" OtherLinkFlags = "$(LinkFlags) Comdlg32.lib kernel32.lib user32.lib advapi32.lib shell32.lib IDEHelper64_d.lib" -DebugCommandArguments = "-workspace=C:\\Beef\\BeefBuild" +DebugCommandArguments = "-workspace=C:\\Beef\\IDEHelper\\Tests" DebugWorkingDirectory = "c:\\Beef\\IDE\\Tests\\EmptyTest" EnvironmentVars = ["_NO_DEBUG_HEAP=1"] diff --git a/IDE/mintest/BeefSpace.toml b/IDE/mintest/BeefSpace.toml index f59c6024..069a668c 100644 --- a/IDE/mintest/BeefSpace.toml +++ b/IDE/mintest/BeefSpace.toml @@ -95,14 +95,6 @@ COptimizationLevel = "O2" ConfigSelections = {mintest = {Config = "Debug"}} [Configs.Test.Win64] -EmitDynamicCastCheck = false -EnableObjectDebugFlags = false -EmitObjectAccessCheck = false -EnableRealtimeLeakCheck = false -AllowHotSwapping = false -AllocStackTraceDepth = 0 -COptimizationLevel = "O2" -ConfigSelections = {mintest = {Config = "Debug"}} [Configs.Test.WinFart] Toolset = "GNU" diff --git a/IDE/mintest/mintest2/src/main4.bf b/IDE/mintest/mintest2/src/main4.bf index afd9b4f7..417caab0 100644 --- a/IDE/mintest/mintest2/src/main4.bf +++ b/IDE/mintest/mintest2/src/main4.bf @@ -1,33 +1,2 @@ using System; -/*class Zlobs : IDisposable -{ - int IDisposable.Floo() - { - - } - - int Zag() - { - return 123; - } -}*/ - -class Fligs -{ - class Bligs - { - class Snorf - { - - } - } - - class Zang - { - class Flang - { - - } - } -} \ No newline at end of file diff --git a/IDE/mintest/src/main3.bf b/IDE/mintest/src/main3.bf index 0b041bbf..f560f57d 100644 --- a/IDE/mintest/src/main3.bf +++ b/IDE/mintest/src/main3.bf @@ -211,7 +211,7 @@ struct Blurg } } - static int[] gArr = new .(1, 2, 3, 4, 5, ); + //static int[] gArr = new .(1, 2, 3, 4, 5, ); [Checked] public static int32 GetVal() @@ -305,12 +305,6 @@ struct Blurg //int len = str.[Friend]GetLength(); } - - static void Test(int a, int b, Span iSpan) - { - - } - public static mixin Florf(int a, int b) { @@ -324,36 +318,30 @@ struct Blurg } } + public static int sA = 123; + + /*public static void Test(T val) + { + + }*/ + + public static void Test(T val) where T : Span + { + + } + public static int32 Hey() { - for (int i < 100) - { - Yoofer.ColorizeCodeString("abc", .Callstack); - } + Span valSpan = .(); + StringView sv = "Hey"; + + Span span = sv; + + Test(sv); + return (int32)123; } } -class Yoofer -{ - public enum CodeKind - { - Callstack, - Method, - Field, - Type - } - - public static void Zorg() - { - int a = 1; - } - - public static void ColorizeCodeString(String label, CodeKind codeKind) - { - Zorg(); - int a = 1; - } -} diff --git a/IDE/src/Commands.bf b/IDE/src/Commands.bf index 02b780d8..9fbf0bc1 100644 --- a/IDE/src/Commands.bf +++ b/IDE/src/Commands.bf @@ -177,8 +177,10 @@ namespace IDE Add("Bookmark Toggle", new => gApp.Cmd_ToggleBookmark, .Editor); Add("Bookmark Clear", new => gApp.Cmd_ClearBookmarks, .Editor); Add("Break All", new => gApp.[Friend]Cmd_Break); - Add("Breakpoint Memory", new () => { gApp.mBreakpointPanel.AddMemoryBreakpoint(gApp.[Friend]GetCurrentWindow()); }, .Editor); - Add("Breakpoint Symbol", new () => { gApp.mBreakpointPanel.AddSymbolBreakpoint(gApp.[Friend]GetCurrentWindow()); }, .Editor); + Add("Breakpoint Configure", new () => gApp.ConfigureBreakpoint()); + Add("Breakpoint Disable", new () => gApp.DisableBreakpoint()); + Add("Breakpoint Memory", new () => { gApp.mBreakpointPanel.AddMemoryBreakpoint(gApp.[Friend]GetCurrentWindow()); }); + Add("Breakpoint Symbol", new () => { gApp.mBreakpointPanel.AddSymbolBreakpoint(gApp.[Friend]GetCurrentWindow()); }); Add("Breakpoint Toggle Thread", new => gApp.[Friend]ToggleThreadBreakpoint, .Editor); Add("Breakpoint Toggle", new => gApp.[Friend]ToggleBreakpoint, .Editor); Add("Build Solution", new => gApp.[Friend]Compile); @@ -189,7 +191,8 @@ namespace IDE Add("Close Window", new () => { gApp.[Friend]TryCloseCurrentDocument(); }); Add("Close Workspace", new => gApp.[Friend]Cmd_CloseWorkspaceAndSetupNew); Add("Compile File", new => gApp.Cmd_CompileFile); - Add("Debug All Tests", new () => { gApp.[Friend]RunTests(true); }); + Add("Debug All Tests", new () => { gApp.[Friend]RunTests(true, true); }); + Add("Debug Normal Tests", new () => { gApp.[Friend]RunTests(false, true); }); Add("Exit", new => gApp.[Friend]Cmd_Exit); Add("Find All References", new => gApp.Cmd_FindAllReferences); Add("Find Class", new => gApp.Cmd_FindClass); @@ -229,7 +232,8 @@ namespace IDE Add("Replace in Document", new => gApp.Cmd_Document__Replace); Add("Replace in Files", new => gApp.Cmd_Replace); Add("Report Memory", new => gApp.[Friend]ReportMemory); - Add("Run All Tests", new => gApp.Cmd_RunAllTests); + Add("Run All Tests", new () => { gApp.[Friend]RunTests(true, false); }); + Add("Run Normal Tests", new () => { gApp.[Friend]RunTests(false, false); }); Add("Run To Cursor", new => gApp.[Friend]RunToCursor); Add("Run Without Compiling", new => gApp.[Friend]RunWithoutCompiling); Add("Save All", new () => { gApp.SaveAll(); }); @@ -276,7 +280,6 @@ namespace IDE Add("Attach to Process", new => gApp.[Friend]DoAttach); Add("Test Enable Console", new => gApp.Cmd_TestEnableConsole); - Add("Test Include Ignored", new => gApp.Cmd_TestIncludeIgnored); } } } diff --git a/IDE/src/Debugger/Breakpoint.bf b/IDE/src/Debugger/Breakpoint.bf index f169f907..3c5b0499 100644 --- a/IDE/src/Debugger/Breakpoint.bf +++ b/IDE/src/Debugger/Breakpoint.bf @@ -19,6 +19,21 @@ namespace IDE.Debugger MultipleOf }; + public enum SetKind + { + Toggle, + Force, + EnsureExists, + MustExist + } + + public enum SetFlags + { + None, + Configure, + Disable + } + [StdCall, CLink] static extern void Breakpoint_Delete(void* nativeBreakpoint); diff --git a/IDE/src/IDEApp.bf b/IDE/src/IDEApp.bf index a6fa7286..32b7deca 100644 --- a/IDE/src/IDEApp.bf +++ b/IDE/src/IDEApp.bf @@ -295,7 +295,6 @@ namespace IDE public bool mEnableGCCollect = true; public bool mDbgFastUpdate; public bool mTestEnableConsole = false; - public bool mTestIncludeIgnored = false; public ProfileInstance mLongUpdateProfileId; public uint32 mLastLongUpdateCheck; public uint32 mLastLongUpdateCheckError; @@ -3988,11 +3987,11 @@ namespace IDE if (sourceViewPanel != null) { BfLog.LogDbg("Creating mRunToCursorBreakpoint\n"); - mDebugger.mRunToCursorBreakpoint = sourceViewPanel.ToggleBreakpointAtCursor(true, mDebugger.GetActiveThread()); + mDebugger.mRunToCursorBreakpoint = sourceViewPanel.ToggleBreakpointAtCursor(.Force, .None, mDebugger.GetActiveThread()); } else if (var disassemblyPanel = GetActiveDocumentPanel() as DisassemblyPanel) { - mDebugger.mRunToCursorBreakpoint = disassemblyPanel.ToggleAddrBreakpointAtCursor(true, mDebugger.GetActiveThread()); + mDebugger.mRunToCursorBreakpoint = disassemblyPanel.ToggleAddrBreakpointAtCursor(.Force, .None, mDebugger.GetActiveThread()); } if (mDebugger.mIsRunning) @@ -4090,17 +4089,17 @@ namespace IDE } } - void ToggleBreakpoint(WidgetWindow window, bool bindToThread = false) + void ToggleBreakpoint(WidgetWindow window, Breakpoint.SetKind setKind, Breakpoint.SetFlags setFlags, bool bindToThread = false) { var documentPanel = GetActiveDocumentPanel(); if (var sourceViewPanel = documentPanel as SourceViewPanel) { - sourceViewPanel.ToggleBreakpointAtCursor(false, bindToThread ? gApp.mDebugger.GetActiveThread() : -1); + sourceViewPanel.ToggleBreakpointAtCursor(setKind, setFlags, bindToThread ? gApp.mDebugger.GetActiveThread() : -1); } else if (var disassemblyPanel = documentPanel as DisassemblyPanel) { - disassemblyPanel.ToggleBreakpointAtCursor(false, bindToThread ? gApp.mDebugger.GetActiveThread() : -1); + disassemblyPanel.ToggleBreakpointAtCursor(setKind, setFlags, bindToThread ? gApp.mDebugger.GetActiveThread() : -1); } } @@ -4118,13 +4117,37 @@ namespace IDE [IDECommand] void ToggleBreakpoint() { - ToggleBreakpoint(GetCurrentWindow(), false); + ToggleBreakpoint(GetCurrentWindow(), .Toggle, .None); + } + + [IDECommand] + public void ConfigureBreakpoint() + { + if (var breakpointPanel = GetActivePanel() as BreakpointPanel) + { + breakpointPanel.ConfigureBreakpoints(breakpointPanel.mWidgetWindow); + return; + } + + ToggleBreakpoint(GetCurrentWindow(), .EnsureExists, .Configure); + } + + [IDECommand] + public void DisableBreakpoint() + { + if (var breakpointPanel = GetActivePanel() as BreakpointPanel) + { + breakpointPanel.SetBreakpointsDisabled(null); + return; + } + + ToggleBreakpoint(GetCurrentWindow(), .MustExist, .Disable); } [IDECommand] void ToggleThreadBreakpoint() { - ToggleBreakpoint(GetCurrentWindow(), true); + ToggleBreakpoint(GetCurrentWindow(), .Toggle, .None, true); } void CompileCurrentFile() @@ -4498,18 +4521,21 @@ namespace IDE var tabbedView = GetActiveTabbedView(); if ((tabbedView == null) || (tabbedView.mTabs.IsEmpty)) return; + TabbedView.TabButton activateTab = tabbedView.mTabs[0]; for (var tab in tabbedView.mTabs) { if (tab.mIsActive) { if (@tab.Index < tabbedView.mTabs.Count - 1) { - tabbedView.mTabs[@tab.Index + 1].Activate(); - return; + activateTab = tabbedView.mTabs[@tab.Index + 1]; + break; } } } - tabbedView.mTabs[0].Activate(); + activateTab.Activate(); + if (var sourceViewPanel = activateTab.mContent as SourceViewPanel) + sourceViewPanel.HilitePosition(.Extra); } [IDECommand] @@ -4518,18 +4544,21 @@ namespace IDE var tabbedView = GetActiveTabbedView(); if ((tabbedView == null) || (tabbedView.mTabs.IsEmpty)) return; + TabbedView.TabButton activateTab = tabbedView.mTabs.Back; for (var tab in tabbedView.mTabs) { if (tab.mIsActive) { if (@tab.Index > 0) { - tabbedView.mTabs[@tab.Index - 1].Activate(); - return; + activateTab = tabbedView.mTabs[@tab.Index - 1]; + break; } } } - tabbedView.mTabs.Back.Activate(); + activateTab.Activate(); + if (var sourceViewPanel = activateTab.mContent as SourceViewPanel) + sourceViewPanel.HilitePosition(.Extra); } void DoErrorTest() @@ -4630,7 +4659,7 @@ namespace IDE return (mTestManager != null); } - protected void RunTests(bool debug) + protected void RunTests(bool includeIgnored, bool debug) { if (mOutputPanel != null) { @@ -4640,13 +4669,13 @@ namespace IDE if (AreTestsRunning()) { - OutputLineSmart("ERROR: Tests already running"); + OutputErrorLine("Tests already running"); return; } if ((mDebugger != null) && (mDebugger.mIsRunning)) { - OutputLineSmart("ERROR: Tests cannot be run while program is executing"); + OutputErrorLine("Tests cannot be run while program is executing"); return; } @@ -4662,7 +4691,7 @@ namespace IDE if (workspaceOptions.mBuildKind != .Test) { mMainFrame.mStatusBar.SelectConfig(prevConfigName); - OutputLineSmart("ERROR: No valid Test workspace configuration exists"); + OutputErrorLine("No valid Test workspace configuration exists"); return; } @@ -4670,7 +4699,7 @@ namespace IDE mTestManager = new TestManager(); mTestManager.mPrevConfigName = new String(prevConfigName); mTestManager.mDebug = debug; - mTestManager.mIncludeIgnored = mTestIncludeIgnored; + mTestManager.mIncludeIgnored = includeIgnored; if (mOutputPanel != null) mOutputPanel.Clear(); @@ -4679,12 +4708,10 @@ namespace IDE { mTestManager.BuildFailed(); } - } - - [IDECommand] - public void Cmd_RunAllTests() - { - RunTests(false); + if (!mTestManager.HasProjects) + { + OutputLineSmart("WARNING: No projects have a test configuration specified"); + } } [IDECommand] @@ -4694,13 +4721,6 @@ namespace IDE ToggleCheck(ideCommand.mMenuItem, ref mTestEnableConsole); } - [IDECommand] - public void Cmd_TestIncludeIgnored() - { - let ideCommand = gApp.mCommands.mCommandMap["Test Include Ignored"]; - ToggleCheck(ideCommand.mMenuItem, ref mTestIncludeIgnored); - } - public void CreateMenu() { scope AutoBeefPerf("IDEApp.CreateMenu"); @@ -4946,13 +4966,14 @@ namespace IDE var testMenu = root.AddMenuItem("&Test"); var testRunMenu = testMenu.AddMenuItem("&Run"); + AddMenuItem(testRunMenu, "&Normal Tests", "Run Normal Tests"); AddMenuItem(testRunMenu, "&All Tests", "Run All Tests"); var testDebugMenu = testMenu.AddMenuItem("&Debug"); + AddMenuItem(testDebugMenu, "&Normal Tests", "Debug Normal Tests"); AddMenuItem(testDebugMenu, "&All Tests", "Debug All Tests"); AddMenuItem(testMenu, "Enable Console", "Test Enable Console", null, null, true, mTestEnableConsole ? 1 : 0); - AddMenuItem(testMenu, "Include Ignored Tests", "Test Include Ignored", null, null, true, mTestIncludeIgnored ? 1 : 0); ////////// diff --git a/IDE/src/Settings.bf b/IDE/src/Settings.bf index 3fc1bcc1..bd66992c 100644 --- a/IDE/src/Settings.bf +++ b/IDE/src/Settings.bf @@ -412,8 +412,10 @@ namespace IDE Add("Bookmark Toggle", "Ctrl+F2"); Add("Bookmark Clear", "Ctrl+K, Ctrl+L"); Add("Break All", "Ctrl+Alt+Break"); - Add("Breakpoint Toggle Thread", "Ctrl+F9"); + Add("Breakpoint Configure", "Alt+F9"); + Add("Breakpoint Disable", "Ctrl+F9"); Add("Breakpoint Toggle", "F9"); + Add("Breakpoint Toggle Thread", "Shift+F9"); Add("Build Solution", "F7"); Add("Cancel Build", "Ctrl+Break"); Add("Close Window", "Ctrl+W"); diff --git a/IDE/src/TestManager.bf b/IDE/src/TestManager.bf index 50ef9553..a1a8eb52 100644 --- a/IDE/src/TestManager.bf +++ b/IDE/src/TestManager.bf @@ -51,6 +51,14 @@ namespace IDE public bool mIncludeIgnored; public bool mFailed; + public bool HasProjects + { + get + { + return !mProjectInfos.IsEmpty; + } + } + public ~this() { if (mTestInstance != null) diff --git a/IDE/src/Workspace.bf b/IDE/src/Workspace.bf index 0fde0aa6..e8ab9051 100644 --- a/IDE/src/Workspace.bf +++ b/IDE/src/Workspace.bf @@ -805,10 +805,10 @@ namespace IDE Config config = new Config(); //let configName = new String(data.Keys[configIdx]); let configName = new String(configNameKey); - bool isDebug = configName.Contains("Debug"); bool isRelease = configName.Contains("Release"); bool isParanoid = configName.Contains("Paranoid"); bool isTest = configName.Contains("Test"); + //bool isDebug = configName.Contains("Debug"); mConfigs[configName] = config; for (var platformNameKey in data.Enumerate()) @@ -858,7 +858,7 @@ namespace IDE options.mIntermediateType = data.GetEnum("IntermediateType", .Object); options.mCSIMDSetting = data.GetEnum("CSIMDSetting", .SSE2); - options.mCOptimizationLevel = data.GetEnum("COptimizationLevel", isDebug ? .O0 : .O2); + options.mCOptimizationLevel = data.GetEnum("COptimizationLevel", isRelease ? .O2 : .O0); for (var projectName in data.Enumerate("ConfigSelections")) { diff --git a/IDE/src/ui/AutoComplete.bf b/IDE/src/ui/AutoComplete.bf index f67819ff..3d2604bd 100644 --- a/IDE/src/ui/AutoComplete.bf +++ b/IDE/src/ui/AutoComplete.bf @@ -195,6 +195,8 @@ namespace IDE.ui public ~this() { + //Debug.WriteLine("~this {} {}", this, mIsInitted); + if (mIsInitted) Cleanup(); } @@ -233,6 +235,13 @@ namespace IDE.ui //Console.WriteLine("AutoCompleteContent Init"); + //Debug.WriteLine("Init {} {} {} {}", this, mIsInitted, mOwnsWindow, mAutoComplete); + + if (WidgetWindow.sOnMouseDown.Count > 0) + { + NOP!(); + } + if (mOwnsWindow) { WidgetWindow.sOnWindowLostFocus.Add(new => LostFocusHandler); @@ -280,6 +289,8 @@ namespace IDE.ui public void Cleanup() { + //Debug.WriteLine("Cleanup {} {}", this, mIsInitted); + if (!mIsInitted) return; @@ -1004,6 +1015,13 @@ namespace IDE.ui mTargetEditWidget = targetEditWidget; } + public ~this() + { + //Debug.WriteLine("Autocomplete ~this {}", this); + + Close(false); + } + static ~this() { for (var key in sAutoCompleteMRU.Keys) @@ -1749,18 +1767,20 @@ namespace IDE.ui mAutoCompleteListWidget.RemoveSelf(); delete mAutoCompleteListWidget; } - if (mListWindow != null) + else if (mListWindow != null) { // Will get deleted later... Debug.Assert(mListWindow.mRootWidget == mAutoCompleteListWidget); } + else + delete mAutoCompleteListWidget; mAutoCompleteListWidget = null; } } if (mAutoCompleteListWidget == null) { mAutoCompleteListWidget = new AutoCompleteListWidget(this); - //Debug.WriteLine("Created mAutoCompleteListWidget {0}", mAutoCompleteListWidget); + //Debug.WriteLine("Created mAutoCompleteListWidget {} in {}", mAutoCompleteListWidget, this); } bool queueClearInvoke = false; @@ -2107,11 +2127,6 @@ namespace IDE.ui Close(); } - public ~this() - { - Close(false); - } - public bool IsInsertEmpty() { return mInsertStartIdx == mInsertEndIdx; diff --git a/IDE/src/ui/BinaryDataWidget.bf b/IDE/src/ui/BinaryDataWidget.bf index 03556ab3..231eac64 100644 --- a/IDE/src/ui/BinaryDataWidget.bf +++ b/IDE/src/ui/BinaryDataWidget.bf @@ -2400,7 +2400,7 @@ namespace IDE.ui SetFocus(); var sel = GetSelectionForCursor(mSelection, false); - LocatorAnim.Show(this, sel.mBinRect.Left, sel.mBinRect.Top + sel.mBinRect.mHeight / 2); + LocatorAnim.Show(.Always, this, sel.mBinRect.Left, sel.mBinRect.Top + sel.mBinRect.mHeight / 2); delete sel; } diff --git a/IDE/src/ui/BreakpointPanel.bf b/IDE/src/ui/BreakpointPanel.bf index ea8e27a4..474f68a6 100644 --- a/IDE/src/ui/BreakpointPanel.bf +++ b/IDE/src/ui/BreakpointPanel.bf @@ -177,18 +177,17 @@ namespace IDE.ui gApp.MarkDirty(); } - public void SetBreakpointDisabled(bool disabled) + public void SetBreakpointsDisabled(bool? disabled) { mListView.GetRoot().WithSelectedItems(scope (item) => { var listViewItem = (BreakpointListViewItem)item; if (listViewItem.Selected) { - gApp.mDebugger.SetBreakpointDisabled(listViewItem.mBreakpoint, disabled); - if (!disabled) - { - - } + bool wantDisabled = !listViewItem.mBreakpoint.mDisabled; + if (disabled.HasValue) + wantDisabled = disabled.Value; + gApp.mDebugger.SetBreakpointDisabled(listViewItem.mBreakpoint, wantDisabled); BreakpointsChanged(); gApp.MarkDirty(); } @@ -225,7 +224,7 @@ namespace IDE.ui gApp.MarkDirty(); } - public void ConfigureBreakpoints(Widget relWidget) + public void ConfigureBreakpoints(WidgetWindow widgetWindow) { mListView.GetRoot().WithSelectedItems(scope (item) => { @@ -235,7 +234,7 @@ namespace IDE.ui mDeselectOnFocusLost = false; ConditionDialog dialog = new ConditionDialog(); dialog.Init(listViewItem.mBreakpoint); - dialog.PopupWindow(relWidget.mWidgetWindow); + dialog.PopupWindow(widgetWindow); mDeselectOnFocusLost = true; } }); @@ -285,7 +284,7 @@ namespace IDE.ui menuItem = menu.AddItem("Configure Breakpoint"); menuItem.mOnMenuItemSelected.Add(new (evt) => { - ConfigureBreakpoints(relWidget); + ConfigureBreakpoints(relWidget.mWidgetWindow); }); menuItem = menu.AddItem("Delete Breakpoint"); menuItem.mOnMenuItemSelected.Add(new (evt) => @@ -295,12 +294,12 @@ namespace IDE.ui if (selectedEnabledBreakpoint) { menuItem = menu.AddItem("Disable Breakpoint"); - menuItem.mOnMenuItemSelected.Add(new (evt) => { SetBreakpointDisabled(true); }); + menuItem.mOnMenuItemSelected.Add(new (evt) => { SetBreakpointsDisabled(true); }); } if (selectedDisabledBreakpoint) { menuItem = menu.AddItem("Enable Breakpoint"); - menuItem.mOnMenuItemSelected.Add(new (evt) => { SetBreakpointDisabled(false); }); + menuItem.mOnMenuItemSelected.Add(new (evt) => { SetBreakpointsDisabled(false); }); } if (gApp.mDebugger.IsPaused()) { diff --git a/IDE/src/ui/DisassemblyPanel.bf b/IDE/src/ui/DisassemblyPanel.bf index 7d2ba96f..5deb4b1e 100644 --- a/IDE/src/ui/DisassemblyPanel.bf +++ b/IDE/src/ui/DisassemblyPanel.bf @@ -938,7 +938,7 @@ namespace IDE.ui }*/ // This is useful for a one-shot breakpoint within the current execution context- IE: "Run to cursor" - public Breakpoint ToggleAddrBreakpointAtCursor(bool forceSet, int threadId = -1) + public Breakpoint ToggleAddrBreakpointAtCursor(Breakpoint.SetKind setKind = .Toggle, Breakpoint.SetFlags flags = .None, int threadId = -1) { DebugManager debugManager = IDEApp.sApp.mDebugger; @@ -953,7 +953,7 @@ namespace IDE.ui return null; bool hadBreakpoint = false; - if (!forceSet) + if (setKind != .Force) { for (int32 breakIdx = 0; breakIdx < IDEApp.sApp.mDebugger.mBreakpointList.Count; breakIdx++) { @@ -988,7 +988,7 @@ namespace IDE.ui return null; } - public Breakpoint ToggleBreakpointAtCursor(bool forceSet = false, int threadId = -1) + public Breakpoint ToggleBreakpointAtCursor(Breakpoint.SetKind setKind = .Toggle, Breakpoint.SetFlags flags = .None, int threadId = -1) { DebugManager debugManager = IDEApp.sApp.mDebugger; @@ -1005,7 +1005,7 @@ namespace IDE.ui { if (checkIdx < 0) { - return ToggleAddrBreakpointAtCursor(forceSet); + return ToggleAddrBreakpointAtCursor(setKind, flags, threadId); } lineData = mLineDatas[checkIdx]; if (lineData.mSourceFile != null) @@ -1038,7 +1038,7 @@ namespace IDE.ui instrOffsetCount = -1;*/ bool hadBreakpoint = false; - if (!forceSet) + if (setKind != .Force) { for (int32 breakIdx = 0; breakIdx < IDEApp.sApp.mDebugger.mBreakpointList.Count; breakIdx++) { @@ -1246,6 +1246,9 @@ namespace IDE.ui { debugExpr = scope:: String(); content.ExtractString(leftIdx, rightIdx - leftIdx + 1, debugExpr); + int commaPos = debugExpr.LastIndexOf(','); + if (commaPos != -1) + debugExpr.RemoveToEnd(commaPos); int32 semiPos = (int32)debugExpr.IndexOf(';'); if (semiPos != -1) diff --git a/IDE/src/ui/LocatorAnim.bf b/IDE/src/ui/LocatorAnim.bf index c20c2171..31a93542 100644 --- a/IDE/src/ui/LocatorAnim.bf +++ b/IDE/src/ui/LocatorAnim.bf @@ -13,29 +13,48 @@ namespace IDE.ui { None, Smart, - Always + Always, + Extra } public class LocatorAnim : Widget { + LocatorType mType; float mPct; + public this() + { + + } + public override void Draw(Graphics g) { base.Draw(g); + bool isExtra = mType == .Extra; + int32 circleCount = 2; for (int32 i = 0; i < circleCount; i++) { float sepPct = 0.3f; float maxSep = (circleCount - 2) * sepPct; float pct = (mPct - maxSep + (i * 0.3f)) / (1.0f - maxSep); + + if (isExtra) + pct *= 1.2f; + if ((pct < 0.0f) || (pct > 1.0f)) continue; float scale = (float)Math.Sin(pct * Math.PI_f / 2) * 0.5f; float alpha = Math.Min(0.3f, (1.0f - (float)Math.Sin(pct * Math.PI_f / 2)) * 1.0f); + if (isExtra) + { + scale *= 1.2f; + alpha *= 1.2f; + } + using (g.PushColor(Color.Get(alpha))) { using (g.PushScale(scale, scale, GS!(32), GS!(32))) @@ -48,7 +67,8 @@ namespace IDE.ui { base.Update(); - mPct += 0.03f; + mPct += (mType == .Extra) ? 0.02f : 0.03f; + if (mPct >= 1.0f) { RemoveSelf(); @@ -59,7 +79,7 @@ namespace IDE.ui MarkDirty(); } - public static void Show(Widget refWidget, float x, float y) + public static void Show(LocatorType locatorType, Widget refWidget, float x, float y) { if (!gApp.mSettings.mEditorSettings.mShowLocatorAnim) return; @@ -68,6 +88,7 @@ namespace IDE.ui float yOfs = GS!(-32.0f); LocatorAnim anim = new LocatorAnim(); + anim.mType = locatorType; anim.mX = x + xOfs; anim.mY = y + yOfs; refWidget.AddWidget(anim); diff --git a/IDE/src/ui/SourceEditWidgetContent.bf b/IDE/src/ui/SourceEditWidgetContent.bf index d49c2a9d..8042b1c2 100644 --- a/IDE/src/ui/SourceEditWidgetContent.bf +++ b/IDE/src/ui/SourceEditWidgetContent.bf @@ -2799,61 +2799,8 @@ namespace IDE.ui if ((keyCode == KeyCode.Escape) && (mSelection != null) && (mSelection.Value.HasSelection)) { mSelection = null; - //return; } - /*if (keyCode == KeyCode.F2) - { - int wantCount = 10; - if (mWidgetWindow.IsKeyDown(KeyCode.Shift)) - wantCount = 100; - for (int i = 0; i < wantCount; i++) - mPanel.DoClassify(true, false, true); - } - - if ((mPanel.mUseDebugKeyboard) && (keyCode == KeyCode.Menu)) - { - if (mPanel.mClassifyPaused) - mPanel.mClassifyPaused = false; - else - mPanel.Classify(true, false, true); - return; - }*/ - - /*if ((keyCode == KeyCode.Left) && (mWidgetWindow.IsKeyDown(KeyCode.Alt))) - { - if (!IsAtCurrentHistory()) - IDEApp.sApp.mHistoryManager.GoToCurrentHistory(); - else - IDEApp.sApp.mHistoryManager.PrevHistory(); - return; - } - - if ((keyCode == KeyCode.Right) && (mWidgetWindow.IsKeyDown(KeyCode.Alt))) - { - IDEApp.sApp.mHistoryManager.NextHistory(); - return; - }*/ - - if (((keyCode == KeyCode.Up) || (keyCode == KeyCode.Down) || (keyCode == KeyCode.Left) || (keyCode == KeyCode.Right)) && - (mWidgetWindow.IsKeyDown(KeyCode.Control) && ((mWidgetWindow.IsKeyDown(KeyCode.Alt))))) - { - // Fast cursor! - /*if (mFastCursorState == null) - { - mFastCursorState = new FastCursorState(); - - float x; - float y; - GetTextCoordAtCursor(out x, out y); - - mFastCursorState.mX = x; - mFastCursorState.mY = y; - }*/ - - return; - } - if (((keyCode == KeyCode.Up) || (keyCode == KeyCode.Down) || (keyCode == KeyCode.PageUp) || (keyCode == KeyCode.PageDown)) && (mWidgetWindow.IsKeyDown(KeyCode.Control))) { diff --git a/IDE/src/ui/SourceViewPanel.bf b/IDE/src/ui/SourceViewPanel.bf index 1e69d4e7..61641bdb 100644 --- a/IDE/src/ui/SourceViewPanel.bf +++ b/IDE/src/ui/SourceViewPanel.bf @@ -2039,7 +2039,7 @@ namespace IDE.ui return Path.Equals(fileName, mFilePath); } - void HilitePosition(LocatorType hilitePosition, int32 prevLine = -1) + public void HilitePosition(LocatorType hilitePosition, int32 prevLine = -1) { if (hilitePosition == LocatorType.None) return; @@ -2057,7 +2057,7 @@ namespace IDE.ui var sourceEditWidgetContent = (SourceEditWidgetContent)mEditWidget.Content; - LocatorAnim.Show(mEditWidget.Content, x, y + sourceEditWidgetContent.mFont.GetLineSpacing() / 2); + LocatorAnim.Show(hilitePosition, mEditWidget.Content, x, y + sourceEditWidgetContent.mFont.GetLineSpacing() / 2); } public void ShowFileLocation(int cursorIdx, LocatorType hilitePosition) @@ -3657,11 +3657,11 @@ namespace IDE.ui return drawLineNum; } - public Breakpoint ToggleBreakpointAtCursor(bool forceSet = false, int threadId = -1) + public Breakpoint ToggleBreakpointAtCursor(Breakpoint.SetKind setKind = .Toggle, Breakpoint.SetFlags flags = .None, int threadId = -1) { var activePanel = GetActivePanel(); if (activePanel != this) - return activePanel.ToggleBreakpointAtCursor(forceSet, threadId); + return activePanel.ToggleBreakpointAtCursor(setKind, flags, threadId); if (mOldVersionPanel != null) { @@ -3674,8 +3674,16 @@ namespace IDE.ui int lineCharIdx; mEditWidget.Content.GetLineCharAtIdx(mEditWidget.Content.CursorTextPos, out lineIdx, out lineCharIdx); + /*let lineAndCol = mEditWidget.Content.CursorLineAndColumn; + if (SelectBreakpointsAtLine(lineAndCol.mLine)) + { + gApp.mBreakpointPanel.ConfigureBreakpoints(mWidgetWindow); + }*/ + + HashSet breakpoints = scope .(); + bool hadBreakpoint = false; - if (!forceSet) + if (setKind != .Force) { /*WithTrackedElementsAtCursor(IDEApp.sApp.mDebugger.mBreakpointList, scope [&] (breakpoint) => { @@ -3692,15 +3700,21 @@ namespace IDE.ui int drawLineNum = GetDrawLineNum(breakpoint); if (drawLineNum == lineIdx) { - BfLog.LogDbg("SourceViewPanel.ToggleBreakpointAtCursor deleting breakpoint\n"); - debugManager.DeleteBreakpoint(breakpoint); hadBreakpoint = true; + if (setKind == .Toggle) + { + BfLog.LogDbg("SourceViewPanel.ToggleBreakpointAtCursor deleting breakpoint\n"); + debugManager.DeleteBreakpoint(breakpoint); + } + else + breakpoints.Add(breakpoint); } } } } - - if (!hadBreakpoint) + + Breakpoint newBreakpoint = null; + if ((!hadBreakpoint) && (setKind != .MustExist)) { RecordHistoryLocation(); @@ -3721,12 +3735,12 @@ namespace IDE.ui if (gApp.mDebugger.mIsRunning) foundPosition = RemapActiveToCompiledLine(curCompileIdx, ref lineIdx, ref lineCharIdx); bool createNow = foundPosition || !mIsBeefSource; // Only be strict about Beef source - Breakpoint newBreakpoint = debugManager.CreateBreakpoint_Create(mAliasFilePath ?? mFilePath, lineIdx, lineCharIdx, -1); + newBreakpoint = debugManager.CreateBreakpoint_Create(mAliasFilePath ?? mFilePath, lineIdx, lineCharIdx, -1); newBreakpoint.mThreadId = threadId; debugManager.CreateBreakpoint_Finish(newBreakpoint, createNow); int newDrawLineNum = GetDrawLineNum(newBreakpoint); - if (!forceSet) + if (setKind != .Force) { for (int32 breakIdx = 0; breakIdx < IDEApp.sApp.mDebugger.mBreakpointList.Count; breakIdx++) { @@ -3743,7 +3757,9 @@ namespace IDE.ui debugManager.DeleteBreakpoint(newBreakpoint); newBreakpoint = null; var ewc = mEditWidget.mEditWidgetContent; - LocatorAnim.Show(mEditWidget, ewc.mX + -GS!(15), ewc.mY + newDrawLineNum * ewc.GetLineHeight(0) + GS!(12)); + LocatorAnim.Show(.Always, mEditWidget, ewc.mX + -GS!(15), ewc.mY + newDrawLineNum * ewc.GetLineHeight(0) + GS!(12)); + + breakpoints.Add(checkBreakpoint); break; } } @@ -3778,10 +3794,22 @@ namespace IDE.ui } } - return newBreakpoint; + if (newBreakpoint != null) + breakpoints.Add(newBreakpoint); } - return null; + if (((flags.HasFlag(.Configure)) || (flags.HasFlag(.Disable))) && + (!breakpoints.IsEmpty)) + { + gApp.mBreakpointPanel.Update(); + gApp.mBreakpointPanel.SelectBreakpoints(breakpoints); + if (flags.HasFlag(.Configure)) + gApp.mBreakpointPanel.ConfigureBreakpoints(mWidgetWindow); + if (flags.HasFlag(.Disable)) + gApp.mBreakpointPanel.SetBreakpointsDisabled(null); + } + + return newBreakpoint; } public void ToggleBookmarkAtCursor() @@ -4481,9 +4509,7 @@ namespace IDE.ui if ((mousePos.x < editX - 24) || (mousePos.x > editX - 5)) return false; - DarkEditWidgetContent darkEditWidgetContent = (DarkEditWidgetContent)mEditWidget.Content; - float lineSpacing = darkEditWidgetContent.mFont.GetLineSpacing(); - float ofsY = mEditWidget.mY + darkEditWidgetContent.mY + (lineSpacing - DarkTheme.sUnitSize + GS!(5)) / 2; + int mouseLine = GetLineAt(mousePos.x, mousePos.y); for (var breakpointView in GetTrackedElementList()) { @@ -4500,8 +4526,7 @@ namespace IDE.ui breakpointLineNum = breakpoint.mLineNum; int drawLineNum = breakpointLineNum; - float iconY = ofsY + drawLineNum * lineSpacing; - if ((mousePos.y > iconY) && (mousePos.y < iconY + GS!(20))) + if (drawLineNum == mouseLine) { if (!tooltipStr.IsEmpty) tooltipStr.Append("\n\n"); @@ -6080,44 +6105,60 @@ namespace IDE.ui } } + public int GetLineAt(float x, float y) + { + if (x > GS!(40)) + return -1; + + DarkEditWidgetContent darkEditWidgetContent = (DarkEditWidgetContent)mEditWidget.Content; + float lineSpacing = darkEditWidgetContent.mFont.GetLineSpacing(); + float relY = y - mEditWidget.mY - mEditWidget.Content.Y - GS!(3); + if (relY < 0) + return -1; + return (int)(relY / lineSpacing); + } + + public bool SelectBreakpointsAtLine(int selectLine) + { + if (selectLine == -1) + return false; + + HashSet selectedBreakpoints = scope HashSet(); + + for (var breakpointView in GetTrackedElementList()) + { + var trackedElement = breakpointView.mTrackedElement; + var breakpoint = trackedElement as Breakpoint; + if (breakpoint != null) + { + int drawLineNum = RemapActiveLineToHotLine(breakpoint.mLineNum); + if (selectLine == drawLineNum) + { + selectedBreakpoints.Add(breakpoint); + } + } + } + + if (selectedBreakpoints.IsEmpty) + return false; + + gApp.mBreakpointPanel.Update(); + gApp.mBreakpointPanel.SelectBreakpoints(selectedBreakpoints); + return true; + } + public override void MouseClicked(float x, float y, int32 btn) { base.MouseClicked(x, y, btn); if (btn == 1) { - DarkEditWidgetContent darkEditWidgetContent = (DarkEditWidgetContent)mEditWidget.Content; - float lineSpacing = darkEditWidgetContent.mFont.GetLineSpacing(); - - HashSet selectedBreakpoints = scope HashSet(); - - for (var breakpointView in GetTrackedElementList()) + int lineClick = GetLineAt(x, y); + if (SelectBreakpointsAtLine(lineClick)) { - var trackedElement = breakpointView.mTrackedElement; - var breakpoint = trackedElement as Breakpoint; - if (breakpoint != null) - { - int drawLineNum = RemapActiveLineToHotLine(breakpoint.mLineNum); - //float breakX = mEditWidget.mX - 20; - float breakY = GS!(3) + drawLineNum * lineSpacing + mEditWidget.mY + mEditWidget.Content.Y; - - if ((x <= GS!(40)) && (y >= breakY) && (y < breakY + lineSpacing + GS!(1))) - { - selectedBreakpoints.Add(breakpoint); - } - } - } - - if (selectedBreakpoints.Count > 0) - { - gApp.mBreakpointPanel.Update(); - gApp.mBreakpointPanel.SelectBreakpoints(selectedBreakpoints); #unwarn var menuWidget = gApp.mBreakpointPanel.ShowRightClickMenu(this, x, y, true); - //menuWidget.mDeletedHandler.Add(new (widget) => { gApp.mBreakpointPanel.mListView.GetRoot().SelectItemExclusively(null); }); } - - //float checkY = y + mEditWidget.mScrollContentContainer.m; } }