diff --git a/BeefLibs/Beefy2D/src/widgets/EditWidget.bf b/BeefLibs/Beefy2D/src/widgets/EditWidget.bf index 7f285bfe..f4c51ad1 100644 --- a/BeefLibs/Beefy2D/src/widgets/EditWidget.bf +++ b/BeefLibs/Beefy2D/src/widgets/EditWidget.bf @@ -1919,6 +1919,37 @@ namespace Beefy.widgets InsertAtCursor(text); } + public void CutText() + { + if (!CheckReadOnly()) + { + String selText = scope String(); + GetSelectionText(selText); + if (!selText.IsWhiteSpace) + { + BFApp.sApp.SetClipboardText(selText); + DeleteSelection(); + } + } + } + + public void CopyText() + { + String selText = scope String(); + GetSelectionText(selText); + if (!selText.IsWhiteSpace) + BFApp.sApp.SetClipboardText(selText); + } + + public void PasteText() + { + String aText = scope String(); + BFApp.sApp.GetClipboardText(aText); + aText.Replace("\r", ""); + if ((aText != null) && (!CheckReadOnly())) + PasteText(aText); + } + public override void KeyDown(KeyCode keyCode, bool isRepeat) { base.KeyDown(keyCode, isRepeat); @@ -1944,38 +1975,16 @@ namespace Beefy.widgets { case (KeyCode)'A': SelectAll(); - break; case (KeyCode)'C': - String selText = scope String(); - GetSelectionText(selText); - if (!selText.IsWhiteSpace) - BFApp.sApp.SetClipboardText(selText); - break; + CopyText(); case (KeyCode)'X': - if (!CheckReadOnly()) - { - String selText = scope String(); - GetSelectionText(selText); - if (!selText.IsWhiteSpace) - { - BFApp.sApp.SetClipboardText(selText); - DeleteSelection(); - } - } - break; + CutText(); case (KeyCode)'V': - String aText = scope String(); - BFApp.sApp.GetClipboardText(aText); - aText.Replace("\r", ""); - if ((aText != null) && (!CheckReadOnly())) - PasteText(aText); - break; + PasteText(); case (KeyCode)'Z': Undo(); - break; case (KeyCode)'Y': Redo(); - break; case .Return: if (mIsMultiline) mEditWidget.Submit(); diff --git a/BeefLibs/corlib/src/IO/Path.bf b/BeefLibs/corlib/src/IO/Path.bf index d35246d7..edefa38a 100644 --- a/BeefLibs/corlib/src/IO/Path.bf +++ b/BeefLibs/corlib/src/IO/Path.bf @@ -54,9 +54,9 @@ namespace System.IO } - public static void GetFileName(String inPath, String outFileName) + public static void GetFileName(StringView inPath, String outFileName) { - if (inPath == null) + if (inPath.IsEmpty) return; CheckInvalidPathChars(inPath); @@ -236,7 +236,7 @@ namespace System.IO outFileName.Append(inPath, lastSlash + 1); } - public static Result GetExtension(String inPath, String outExt) + public static Result GetExtension(StringView inPath, String outExt) { int i; if ((i = inPath.LastIndexOf('.')) != -1) diff --git a/BeefLibs/corlib/src/IO/StreamReader.bf b/BeefLibs/corlib/src/IO/StreamReader.bf index 2c5f2c22..0c7701a6 100644 --- a/BeefLibs/corlib/src/IO/StreamReader.bf +++ b/BeefLibs/corlib/src/IO/StreamReader.bf @@ -561,6 +561,17 @@ namespace System.IO return .Ok; } + public Result Read() + { + if (mStream == null) + return .Err; + if (mCharPos == mCharLen) + { + if (Try!(ReadBuffer()) == 0) return .Err; + } + return mCharBuffer[mCharPos++]; + } + public struct LineReader : IEnumerator> { StreamReader mStreamReader; diff --git a/BeefLibs/corlib/src/Int32.bf b/BeefLibs/corlib/src/Int32.bf index b7eb9243..7416fc6f 100644 --- a/BeefLibs/corlib/src/Int32.bf +++ b/BeefLibs/corlib/src/Int32.bf @@ -1,3 +1,5 @@ +using System.Globalization; + namespace System { struct Int32 : int32, IInteger, ISigned, IHashable, IFormattable, IOpComparable, IIsNaN, IOpNegatable, IOpAddable @@ -120,17 +122,19 @@ namespace System ToString(outString, minNumerals); } - public static Result Parse(StringView val) + public static Result Parse(StringView val, NumberStyles style) { - if (val.Length == 0) + if (val.IsEmpty) return .Err(.NoValue); bool isNeg = false; - int32 result = 0; - //TODO: Use Number.ParseNumber + int32 result = 0; + + int32 radix = style.HasFlag(.AllowHexSpecifier) ? 0x10 : 10; + for (int32 i = 0; i < val.Length; i++) { - char8 c = val.Ptr[i]; + char8 c = val[i]; if ((i == 0) && (c == '-')) { @@ -140,13 +144,39 @@ namespace System if ((c >= '0') && (c <= '9')) { - result *= 10; + result *= radix; result += (int32)(c - '0'); } + else if ((c >= 'a') && (c <= 'f')) + { + result *= radix; + result += c - 'a' + 10; + } + else if ((c >= 'A') && (c <= 'F')) + { + result *= radix; + result += c - 'A' + 10; + } + else if ((c == 'X') || (c == 'x')) + { + if (result != 0) + return .Err(.InvalidChar(result)); + radix = 0x10; + } + else if (c == '\'') + { + // Ignore + } else - return .Err(.InvalidChar(isNeg ? -result : result)); + return .Err(.InvalidChar(result)); } - return .Ok(isNeg ? -result : result); + + return isNeg ? -result : result; } + + public static Result Parse(StringView val) + { + return Parse(val, .Any); + } } } diff --git a/BeefySysLib/util/Hash.cpp b/BeefySysLib/util/Hash.cpp index 7e1bbec0..0631c368 100644 --- a/BeefySysLib/util/Hash.cpp +++ b/BeefySysLib/util/Hash.cpp @@ -1380,7 +1380,7 @@ void HashContext::Mixin(const void* data, int size) if (mDbgViz) { - int findIdx = 0x1BCF; + int findIdx = 0x2cc159; if ((mBufOffset + mBufSize <= findIdx) && (mBufOffset + mBufSize + addBytes > findIdx)) { NOP; @@ -1429,10 +1429,17 @@ Val128 HashContext::Finish128() { String filePath = StrFormat("c:\\temp\\hash%d.bin", gDbgVizIdx++); mDbgVizStream = new FileStream(); - mDbgVizStream->Open(filePath, "wb"); - OutputDebugStrF("Creating dbg hash: %s\n", filePath.c_str()); + if (mDbgVizStream->Open(filePath, "wb")) + { + OutputDebugStrF("Creating dbg hash: %s\n", filePath.c_str()); + } + else + { + OutputDebugStrF("FAILED creating dbg hash: %s\n", filePath.c_str()); + } } - mDbgVizStream->Write(mBuf, mBufSize); + if ((mDbgVizStream != NULL) && (mDbgVizStream->IsOpen())) + mDbgVizStream->Write(mBuf, mBufSize); } if (mBufSize <= 16) diff --git a/BeefySysLib/util/String.h b/BeefySysLib/util/String.h index ea23aa64..ea3923b9 100644 --- a/BeefySysLib/util/String.h +++ b/BeefySysLib/util/String.h @@ -682,12 +682,16 @@ public: intptr CompareTo(const StringImpl& strB, bool ignoreCase = false) const { - return Compare(*this, 0, strB, 0, strB.GetLength(), ignoreCase); + if (ignoreCase) + return CompareOrdinalIgnoreCaseHelper(GetPtr(), GetLength(), strB.GetPtr(), strB.GetLength()); + return CompareOrdinalHelper(GetPtr(), GetLength(), strB.GetPtr(), strB.GetLength()); } static intptr Compare(const StringImpl& strA, const StringImpl& strB, bool ignoreCase) - { - return Compare(strA, 0, strB, 0, strB.GetLength(), ignoreCase); + { + if (ignoreCase) + return CompareOrdinalIgnoreCaseHelper(strA.GetPtr(), strA.GetLength(), strB.GetPtr(), strB.GetLength()); + return CompareOrdinalHelper(strA.GetPtr(), strA.GetLength(), strB.GetPtr(), strB.GetLength()); } static intptr Compare(const StringImpl& strA, intptr indexA, const StringImpl& strB, intptr indexB, intptr length, bool ignoreCase); diff --git a/IDE/src/IDEApp.bf b/IDE/src/IDEApp.bf index b3422a1c..d85acb20 100644 --- a/IDE/src/IDEApp.bf +++ b/IDE/src/IDEApp.bf @@ -182,6 +182,7 @@ namespace IDE public AutoCompletePanel mAutoCompletePanel; public Rect mRequestedWindowRect = Rect(64, 64, 1200, 1024); + public BFWindow.ShowKind mRequestedShowKind; public WakaTime mWakaTime ~ delete _; public Settings mSettings = new Settings() ~ delete _; @@ -1417,10 +1418,11 @@ namespace IDE void SerializeWindow(StructuredData data, WidgetWindow window) { - data.Add("X", window.mX); - data.Add("Y", window.mY); - data.Add("Width", window.mWindowWidth); - data.Add("Height", window.mWindowHeight); + data.Add("X", window.mNormX); + data.Add("Y", window.mNormY); + data.Add("Width", window.mNormWidth); + data.Add("Height", window.mNormHeight); + data.Add("ShowKind", window.mShowKind); } void SerializeTabbedView(StructuredData data, DarkTabbedView tabbedView, bool serializeDocs) @@ -2670,7 +2672,10 @@ namespace IDE int32 width = data.GetInt("Width"); int32 height = data.GetInt("Height"); if ((width > 0) && (height > 0)) + { mRequestedWindowRect = Rect(x, y, width, height); + } + mRequestedShowKind = data.GetEnum("ShowKind"); } bool LoadWorkspaceUserData(StructuredData data) @@ -9730,6 +9735,8 @@ namespace IDE { scope AutoBeefPerf("IDEApp.Init"); + //int zag = 123; + if (mVerbosity == .Default) mVerbosity = .Detailed; @@ -9903,6 +9910,9 @@ namespace IDE if (mRunningTestScript) flags |= .NoActivate; + if (mRequestedShowKind == .Maximized) + flags |= .ShowMaximized; + scope AutoBeefPerf("IDEApp.Init:CreateMainWindow"); mMainWindow = new WidgetWindow(null, "Beef IDE", (int32)mRequestedWindowRect.mX, (int32)mRequestedWindowRect.mY, (int32)mRequestedWindowRect.mWidth, (int32)mRequestedWindowRect.mHeight, diff --git a/IDE/src/Settings.bf b/IDE/src/Settings.bf index e4a2f9cb..3fc1bcc1 100644 --- a/IDE/src/Settings.bf +++ b/IDE/src/Settings.bf @@ -186,6 +186,11 @@ namespace IDE public void Apply() { +#if CLI + return; +#endif + +#unwarn String symbolServerPath = scope String()..Join("\n", mSymbolSearchPath.GetEnumerator()); if (mUseSymbolServers == .No) { @@ -479,6 +484,11 @@ namespace IDE public void Apply() { +#if CLI + return; +#endif + +#unwarn gApp.mCommands.mKeyMap.Clear(); for (let entry in mEntries) diff --git a/IDE/src/ui/HoverWatch.bf b/IDE/src/ui/HoverWatch.bf index 0eb3f4da..46682a6e 100644 --- a/IDE/src/ui/HoverWatch.bf +++ b/IDE/src/ui/HoverWatch.bf @@ -1383,6 +1383,9 @@ namespace IDE.ui void ShowRightClickMenu(WatchListViewItem listViewItem, float x, float y) { + if (mOrigEvalString.StartsWith(":")) + return; + float clickX = x; float clickY = DarkTheme.sDarkTheme.mSmallFont.GetLineSpacing() + GS!(1); listViewItem.SelfToOtherTranslate(listViewItem.mListView.GetRoot(), clickX, clickY, var aX, var aY); diff --git a/IDE/src/ui/MemoryPanel.bf b/IDE/src/ui/MemoryPanel.bf index b86a0246..21464bbd 100644 --- a/IDE/src/ui/MemoryPanel.bf +++ b/IDE/src/ui/MemoryPanel.bf @@ -395,6 +395,7 @@ namespace IDE.ui String editVal = subItem.mLabel; mEditWidget.SetText(editVal); mEditWidget.Content.SelectAll(); + mEditSubmitting = true; // Default to submitting on lost focus mEditingItem = item; mEditingRepType = repType; @@ -479,6 +480,7 @@ namespace IDE.ui String editText = scope String(); mEditWidget.GetText(editText); String expr = scope String(); + editText.Append(", d"); if (!MemoryPanel.EvalExpression(editText, expr)) expr = editText; @@ -593,6 +595,7 @@ namespace IDE.ui void HandleRenameCancel(EditEvent theEvent) { + mEditSubmitting = false; HandleEditLostFocus((EditWidget)theEvent.mSender); } diff --git a/IDE/src/ui/ModulePanel.bf b/IDE/src/ui/ModulePanel.bf index 31cc2132..5f81f3a2 100644 --- a/IDE/src/ui/ModulePanel.bf +++ b/IDE/src/ui/ModulePanel.bf @@ -4,6 +4,7 @@ using Beefy.widgets; using Beefy.theme; using System.IO; using Beefy.utils; +using Beefy.gfx; namespace IDE.ui { @@ -65,6 +66,17 @@ namespace IDE.ui mModulesDirty = true; } + public void GetFileNameFrom(ListViewItem item, String filePath) + { + var pathItem = item.GetSubItem(1); + StringView label = pathItem.Label; + int parenPos = label.IndexOf('('); + if (parenPos != -1) + label.RemoveToEnd(parenPos); + label.Trim(); + filePath.Append(label); + } + protected override void ShowRightClickMenu(Widget relWidget, float x, float y) { base.ShowRightClickMenu(relWidget, x, y); @@ -76,15 +88,54 @@ namespace IDE.ui { Menu menu = new Menu(); Menu anItem; - anItem = menu.AddItem("Load Symbols..."); + anItem = menu.AddItem("Load Image..."); + anItem.mOnMenuItemSelected.Add(new (item) => + { + listView.GetRoot().WithSelectedItems(scope (item) => + { + String filePath = scope .(); + GetFileNameFrom(item, filePath); + + String dir = scope String(); + Path.GetDirectoryPath(filePath, dir); + IDEUtils.FixFilePath(dir); + + String fileName = scope String(); + Path.GetFileName(filePath, fileName); + + String extName = scope String(); + Path.GetExtension(filePath, extName); + extName.ToLower(); + + var fileDialog = scope System.IO.OpenFileDialog(); + fileDialog.ShowReadOnly = false; + fileDialog.Title = "Select Image File"; + fileDialog.Multiselect = false; + if (!dir.IsEmpty) + fileDialog.InitialDirectory = dir; + fileDialog.ValidateNames = true; + fileDialog.DefaultExt = ".exe"; + fileDialog.FileName = fileName; + fileDialog.SetFilter(scope String()..AppendF("{0}|{0}|File (*{1})|*{1}|All files (*.*)|*.*", fileName, extName)); + mWidgetWindow.PreModalChild(); + if (fileDialog.ShowDialog(gApp.GetActiveWindow()).GetValueOrDefault() == .OK) + { + var fileNames = fileDialog.FileNames; + gApp.mDebugger.LoadImageForModule(filePath, fileNames[0]); + } + }); + }); + + anItem = menu.AddItem("Load Debug Info..."); anItem.mOnMenuItemSelected.Add(new (item) => { listView.GetRoot().WithSelectedItems(scope (item) => { - var pathItem = item.GetSubItem(1); + String filePath = scope .(); + GetFileNameFrom(item, filePath); String dir = scope String(); - Path.GetDirectoryPath(pathItem.Label, dir); + Path.GetDirectoryPath(filePath, dir); IDEUtils.FixFilePath(dir); var fileDialog = scope System.IO.OpenFileDialog(); @@ -95,14 +146,14 @@ namespace IDE.ui fileDialog.InitialDirectory = dir; fileDialog.ValidateNames = true; fileDialog.DefaultExt = ".exe"; - fileDialog.SetFilter("PDB Debug Unfo (*.pdb)|*.pdb|All files (*.*)|*.*"); + fileDialog.SetFilter("PDB Debug Info (*.pdb)|*.pdb|All files (*.*)|*.*"); mWidgetWindow.PreModalChild(); if (fileDialog.ShowDialog(gApp.GetActiveWindow()).GetValueOrDefault() == .OK) { var fileNames = fileDialog.FileNames; if (gApp.mDebugger.mIsRunning) { - gApp.mDebugger.LoadDebugInfoForModule(scope String(pathItem.Label), fileNames[0]); + gApp.mDebugger.LoadDebugInfoForModule(filePath, fileNames[0]); } } }); @@ -126,20 +177,22 @@ namespace IDE.ui if (moduleInfoStr.IsEmpty) continue; + ListViewItem lvItem; + if (idx < mListView.GetRoot().GetChildCount()) { - let lvItem = mListView.GetRoot().GetChildAtIndex(idx); + lvItem = mListView.GetRoot().GetChildAtIndex(idx); int subIdx = 0; for (let moduleStr in moduleInfoStr.Split('\t')) { - let subLVItem = (subIdx == 0) ? lvItem : lvItem.GetSubItem(subIdx); - subLVItem.Label = moduleStr; + let subLVItem = (DarkListViewItem)((subIdx == 0) ? lvItem : lvItem.GetSubItem(subIdx)); + subLVItem.Label = moduleStr; subIdx++; } } else { - let lvItem = mListView.GetRoot().CreateChildItem(); + lvItem = mListView.GetRoot().CreateChildItem(); int subIdx = 0; for (let moduleStr in moduleInfoStr.Split('\t')) { @@ -149,6 +202,17 @@ namespace IDE.ui } } + DarkListViewItem subLVItem = (DarkListViewItem)lvItem.GetSubItem(1); + if (subLVItem.mLabel.StartsWith("!")) + { + subLVItem.mTextColor = 0xFFFF8080; + subLVItem.mLabel.Remove(0, 1); + } + else + { + subLVItem.mTextColor = 0xFFFFFFFF; + } + ++idx; } } diff --git a/IDE/src/ui/PanelHeader.bf b/IDE/src/ui/PanelHeader.bf index d4c99fed..63ca43aa 100644 --- a/IDE/src/ui/PanelHeader.bf +++ b/IDE/src/ui/PanelHeader.bf @@ -11,6 +11,13 @@ namespace IDE.ui { public class PanelHeader : Widget { + public enum Kind + { + None, + WrongHash + } + + public Kind mKind; public List mButtons = new List() ~ delete _; public String mLabel ~ delete _; public String mTooltipText ~ delete _; diff --git a/IDE/src/ui/SourceEditWidgetContent.bf b/IDE/src/ui/SourceEditWidgetContent.bf index 1200a26c..329143cc 100644 --- a/IDE/src/ui/SourceEditWidgetContent.bf +++ b/IDE/src/ui/SourceEditWidgetContent.bf @@ -2232,6 +2232,15 @@ namespace IDE.ui } } + SourceElementType prevElementType = SourceElementType.Normal; + char8 prevChar = 0; + int cursorTextPos = CursorTextPos; + if (cursorTextPos != 0) + { + prevElementType = (SourceElementType)mData.mText[cursorTextPos - 1].mDisplayTypeId; + prevChar = mData.mText[cursorTextPos - 1].mChar; + } + if (((theChar == '\n') || (theChar == '\r')) && (mIsMultiline) && (!CheckReadOnly())) { UndoBatchStart undoBatchStart = new UndoBatchStart("newline"); @@ -2333,6 +2342,17 @@ namespace IDE.ui mData.mUndoManager.Add(undoBatchStart.mBatchEnd); + if ((prevElementType == .Normal) && + ((prevChar == '.') || (prevChar == '('))) + { + // Leave it be + } + else + { + if (mAutoComplete != null) + mAutoComplete.CloseListWindow(); + } + mAutoComplete?.UpdateAsyncInfo(); return; @@ -2343,15 +2363,6 @@ namespace IDE.ui return; } - SourceElementType prevElementType = SourceElementType.Normal; - char8 prevChar = 0; - int cursorTextPos = CursorTextPos; - if (cursorTextPos != 0) - { - prevElementType = (SourceElementType)mData.mText[cursorTextPos - 1].mDisplayTypeId; - prevChar = mData.mText[cursorTextPos - 1].mChar; - } - if (prevElementType == SourceElementType.Comment) { if ((cursorTextPos < mData.mTextLength - 1) && (mData.mText[cursorTextPos - 1].mChar == '\n')) @@ -2565,7 +2576,7 @@ namespace IDE.ui mIsInKeyChar = false; } - if ((theChar == '\b') || (theChar >= (char8)32)) + if ((theChar == '\b') || (theChar == '\r') || (theChar >= (char8)32)) { bool isHighPri = (theChar == '(') || (theChar == '.'); bool needsFreshAutoComplete = ((isHighPri) /*|| (!mAsyncAutocomplete)*/ || (mAutoComplete == null) || (mAutoComplete.mAutoCompleteListWidget == null)); @@ -2720,7 +2731,7 @@ namespace IDE.ui /// param.isRepeat = "Whether the key is repeated" public override void KeyDown(KeyCode keyCode, bool isRepeat) { - mIgnoreKeyChar = false; + mIgnoreKeyChar = false; if (((keyCode == .Up) || (keyCode == .Down)) && (mAutoComplete != null) && (mAutoComplete.IsShowing()) && (mAutoComplete.mListWindow != null) && @@ -3022,12 +3033,34 @@ namespace IDE.ui Menu menu = new Menu(); if (!DoSpellingPopup(menu)) { + bool hasText = false; + bool hasSelection = HasSelection(); + if (hasSelection) + hasText = true; + else if ((GetLineCharAtCoord(x, y, var line, var lineChar, var overflowX)) || (overflowX < 2)) + { + int textIdx = GetTextIdx(line, lineChar); + for (int checkIdx = textIdx; checkIdx < Math.Min(textIdx + 1, mData.mTextLength); checkIdx++) + { + if (mData.mText[checkIdx].mDisplayTypeId != (uint8)BfSourceElementType.Comment) + { + char8 c = mData.mText[checkIdx].mChar; + if (!c.IsWhiteSpace) + hasText = true; + } + } + } + if (mSourceViewPanel.mIsSourceCode) { - var menuItem = menu.AddItem("Go to Definition"); + Menu menuItem; + + menuItem = menu.AddItem("Go to Definition"); + menuItem.SetDisabled(!hasText); menuItem.mOnMenuItemSelected.Add(new (evt) => IDEApp.sApp.GoToDefinition()); menuItem = menu.AddItem("Add Watch"); + menuItem.SetDisabled(!hasText); menuItem.mOnMenuItemSelected.Add(new (evt) => { int line, lineChar; @@ -3046,7 +3079,6 @@ namespace IDE.ui (textIdx >= mSelection.Value.MinPos) && (textIdx < mSelection.Value.MaxPos)) { - //CDH TODO this doesn't actually get hit right now because right-click context menus lose the selection GetSelectionText(debugExpr); } else if (bfSystem != null) @@ -3077,15 +3109,87 @@ namespace IDE.ui } }); - var debugger = IDEApp.sApp.mDebugger; - if (debugger.IsPaused()) + // Fixits { - menuItem = menu.AddItem("Show Disassembly"); - menuItem.mOnMenuItemSelected.Add(new (evt) => IDEApp.sApp.ShowDisassemblyAtCursor()); + ResolveParams resolveParams = scope .(); + mSourceViewPanel.DoClassify(ResolveType.GetFixits, resolveParams, true); + menuItem = menu.AddItem("Fixit"); + + if (resolveParams.mNavigationData != null) + { + int32 fixitIdx = 0; + for (let str in resolveParams.mNavigationData.Split('\n')) + { + var strItr = str.Split('\t'); + let cmd = strItr.GetNext().Value; + if (cmd != "fixit") + continue; + let arg = strItr.GetNext().Value; + var fixitItem = menuItem.AddItem(arg); - var stepIntoSpecificMenu = menu.AddItem("Step into Specific"); - var stepFilterMenu = menu.AddItem("Step Filter"); + var infoCopy = new String(resolveParams.mNavigationData); + fixitItem.mOnMenuItemSelected.Add(new (menu) => + { + mAutoComplete?.Close(); + var autoComplete = new AutoComplete(mEditWidget); + autoComplete.SetInfo(infoCopy); + autoComplete.mAutoCompleteListWidget.mSelectIdx = fixitIdx; + autoComplete.InsertSelection(0); + autoComplete.Close(); + } + ~ + { + delete infoCopy; + }); + fixitIdx++; + } + } + if (!menuItem.IsParent) + { + menuItem.IsParent = true; + menuItem.SetDisabled(true); + } + } + + menu.AddItem(); + menuItem = menu.AddItem("Cut|Ctrl+X"); + menuItem.mOnMenuItemSelected.Add(new (menu) => + { + CutText(); + }); + menuItem.SetDisabled(!hasSelection); + + menuItem = menu.AddItem("Copy|Ctrl+C"); + menuItem.mOnMenuItemSelected.Add(new (menu) => + { + CopyText(); + }); + menuItem.SetDisabled(!hasSelection); + + menuItem = menu.AddItem("Paste|Ctrl+V"); + menuItem.mOnMenuItemSelected.Add(new (menu) => + { + PasteText(); + }); + + // Debugger options + menu.AddItem(); + var debugger = IDEApp.sApp.mDebugger; + bool isPaused = debugger.IsPaused(); + menuItem = menu.AddItem("Show Disassembly"); + menuItem.SetDisabled(!isPaused); + menuItem.mOnMenuItemSelected.Add(new (evt) => IDEApp.sApp.ShowDisassemblyAtCursor()); + + var stepIntoSpecificMenu = menu.AddItem("Step into Specific"); + stepIntoSpecificMenu.SetDisabled(isPaused); + stepIntoSpecificMenu.IsParent = true; + var stepFilterMenu = menu.AddItem("Step Filter"); + stepFilterMenu.SetDisabled(isPaused); + stepFilterMenu.IsParent = true; + + if (isPaused) + { int addr; String file = scope String(); String stackFrameInfo = scope String(); @@ -3186,11 +3290,11 @@ namespace IDE.ui }); } } - } + } + } - stepIntoSpecificMenu.mDisabled = stepIntoSpecificMenu.mItems.Count == 0; - stepFilterMenu.mDisabled = stepFilterMenu.mItems.Count == 0; - } + stepIntoSpecificMenu.mDisabled |= stepIntoSpecificMenu.mItems.Count == 0; + stepFilterMenu.mDisabled |= stepFilterMenu.mItems.Count == 0; } else // (!mSourceViewPanel.mIsSourceCode) { diff --git a/IDE/src/ui/SourceViewPanel.bf b/IDE/src/ui/SourceViewPanel.bf index 1c389831..b437176c 100644 --- a/IDE/src/ui/SourceViewPanel.bf +++ b/IDE/src/ui/SourceViewPanel.bf @@ -933,7 +933,7 @@ namespace IDE.ui public bool Classify(ResolveType resolveType, ResolveParams resolveParams = null) { - if (resolveType == .Autocomplete) + if (resolveType == .GetFixits) { NOP!(); } @@ -1605,7 +1605,11 @@ namespace IDE.ui } else if ((resolveType == .Autocomplete) || (resolveType == .GetFixits)) { - if ((resolveParams == null) || (!resolveParams.mCancelled)) + if ((resolveParams != null) && (resolveType == .GetFixits)) + { + resolveParams.mNavigationData = new String(autocompleteInfo); + } + else if ((resolveParams == null) || (!resolveParams.mCancelled)) { bool changedAfterInfo = (resolveParams != null) && (resolveParams.mTextVersion != Content.mData.mCurTextVersionId); @@ -3113,6 +3117,7 @@ namespace IDE.ui CloseHeader(); mPanelHeader = new PanelHeader(); + mPanelHeader.mKind = .WrongHash; String fileName = scope String(); Path.GetFileName(mFilePath, fileName); String headerStr = scope String(); @@ -5345,6 +5350,18 @@ namespace IDE.ui EnsureReady(); + if (mPanelHeader != null) + { + if (mPanelHeader.mKind == .WrongHash) + { + if (!gApp.mDebugger.mIsRunning) + { + // No longer makes sense if we're not even running + CloseHeader(); + } + } + } + if (mProjectSource == null) { if (mEditData != null) diff --git a/IDE/src/ui/WatchPanel.bf b/IDE/src/ui/WatchPanel.bf index d41100de..0a6b942d 100644 --- a/IDE/src/ui/WatchPanel.bf +++ b/IDE/src/ui/WatchPanel.bf @@ -2670,6 +2670,8 @@ namespace IDE.ui if (listViewItem != null) { + var clickedHoverItem = listViewItem.GetSubItem(0) as HoverWatch.HoverListViewItem; + var watchEntry = listViewItem.mWatchEntry; if (listViewItem.mParentItem != listView.GetRoot()) { @@ -2750,13 +2752,20 @@ namespace IDE.ui } } + void WithSelected(Action func) + { + var root = listView.GetRoot(); + root.WithSelectedItems(func); + + if (clickedHoverItem != null) + func(clickedHoverItem); + } + anItem = menu.AddItem("Copy Value"); anItem.mOnMenuItemSelected.Add(new (evt) => { String selectedText = scope String(); - - var root = listView.GetRoot(); - root.WithSelectedItems(scope (listViewItem) => + WithSelected(scope (listViewItem) => { if (!selectedText.IsEmpty) { @@ -2772,9 +2781,7 @@ namespace IDE.ui anItem.mOnMenuItemSelected.Add(new (evt) => { String selectedText = scope String(); - - var root = listView.GetRoot(); - root.WithSelectedItems(scope (listViewItem) => + WithSelected(scope (listViewItem) => { String evalStr = scope String(); CompactChildExpression((WatchListViewItem)listViewItem, evalStr);