using System; using System.Collections; using System.Text; using System.Threading.Tasks; using Beefy.widgets; using Beefy.theme.dark; using Beefy.gfx; namespace IDE.ui { public class OutputWidgetContent : SourceEditWidgetContent { public bool mRemapToHighestCompileIdx; public this() { mIsReadOnly = true; } public Event> mGotoReferenceEvent ~ _.Dispose(); public bool GotoRefrenceAtLine(int line, int lineOfs = 0) { //bool selectLine = true; //Match match = null; int lineStart = 0; int lineEnd = 0; int lineCheck = Math.Max(0, line + lineOfs); GetLinePosition(lineCheck, out lineStart, out lineEnd); mSelection = EditSelection(lineStart, lineEnd); var selectionText = scope String(); GetSelectionText(selectionText); if (selectionText.Length > 1024) // Remove middle selectionText.Remove(1024/2, selectionText.Length - 1024); int32 errLine = 0; int32 errLineChar = 0; String filePath = null; bool success = false; for (var dlg in mGotoReferenceEvent) if (dlg(line, lineOfs)) { success = true; break; } int32 inTextPos = -1; for (int32 i = 1; i < selectionText.Length; i++) { if (success) break; if (selectionText[i] == ':') { if (selectionText[i - 1] == ')') { int32 startIdx = i; while ((startIdx > 0) && (selectionText[startIdx - 1] != '(')) startIdx--; String lineStr = scope String(selectionText, startIdx, i - startIdx - 1); var lineResult = Int32.Parse(lineStr); if (lineResult case .Ok(out errLine)) { //errLine = lineResult.Value; filePath = scope:: String(selectionText, 0, startIdx - 1); filePath.Trim(); if ((filePath.Contains('\\')) || (filePath.Contains('/'))) break; } } else { int32 startIdx = i; while ((startIdx > 0) && (selectionText[startIdx - 1].IsNumber)) startIdx--; if ((startIdx > 0) && (selectionText[startIdx - 1] == ':')) { // :num: int32 columnStartIdx = startIdx; startIdx--; while ((startIdx > 0) && (selectionText[startIdx - 1].IsNumber)) startIdx--; String lineStr = scope String(selectionText, startIdx, columnStartIdx - startIdx - 1); String columnStr = scope String(selectionText, columnStartIdx, i - columnStartIdx); if ((startIdx > 0) && (selectionText[startIdx - 1] == ':')) { // fileName:line:column: var lineResult = Int32.Parse(lineStr); var columnResult = Int32.Parse(columnStr); if ((lineResult case .Ok(out errLine)) && (columnResult case .Ok(out errLineChar))) { //errLine = lineResult.Value; //errLineChar = columnResult.Value; filePath = scope:: String(selectionText, 0, startIdx - 1); filePath.Trim(); } //lineResult.Dispose(); //columnResult.Dispose(); } continue; } int32 endIdx = i; while ((endIdx < selectionText.Length - 1) && (selectionText[endIdx + 1].IsNumber)) endIdx++; String lineStr = scope String(selectionText, startIdx, i - startIdx); String columnStr = scope String(selectionText, i + 1, endIdx - i); var lineResult = Int32.Parse(lineStr); var columnResult = Int32.Parse(columnStr); if ((lineResult case .Ok) && (columnResult case .Ok)) { errLine = lineResult; errLineChar = columnResult; } /*if (lineResult.HasValue && columnResult.HasValue) { errLine = lineResult.Value; errLineChar = columnResult.Value; } lineResult.Dispose(); columnResult.Dispose();*/ } } // Match " in " if ((errLine > 0) && (i > 3) && (errLine != -1) && (selectionText[i] == ' ') && (selectionText[i - 1] == 'n') && (selectionText[i - 2] == 'i') && (selectionText[i - 3] == ' ')) { inTextPos = i + 1; //filePath = stack String(selectionText, i + 1); //break; } } if (inTextPos != -1) { filePath = scope:: String(selectionText, inTextPos); } if (filePath == null) { if (selectionText.StartsWith("ERROR: ")) { int linePos = selectionText.IndexOf(" at line "); if (linePos != -1) { int lineStartIdx = linePos + " at line ".Length; int spacePos = selectionText.IndexOf(" in ", lineStartIdx); if (spacePos != -1) { int nameStartPos = spacePos + " in ".Length; if (int32.Parse(.(selectionText, lineStartIdx, spacePos - lineStartIdx)) case .Ok(out errLine)) { filePath = scope:: String(selectionText, nameStartPos); } } } } } if ((errLine != -1) && (errLineChar != -1) && (filePath != null)) { IDEApp.sApp.CheckProjectRelativePath(filePath); IDEUtils.FixFilePath(filePath); IDEApp.sApp.ShowSourceFileLocation(filePath, -1, mRemapToHighestCompileIdx ? IDEApp.sApp.mWorkspace.GetHighestCompileIdx() : -1, errLine - 1, errLineChar - 1, LocatorType.Always); success = true; } if (success) { bool selectLine = lineOfs == 0; if (!selectLine) mSelection = null; CursorTextPos = lineStart; EnsureCursorVisible(); return true; } return false; } public override void MouseClicked(float x, float y, float origX, float origY, int32 btn) { base.MouseClicked(x, y, origX, origY, btn); if (btn == 1) { float useX = x; float useY = y; ClampMenuCoords(ref useX, ref useY); Menu menu = new Menu(); var menuItem = menu.AddItem("Clear All"); var panel = mParent.mParent.mParent as TextPanel; menuItem.mOnMenuItemSelected.Add(new (evt) => { if (panel != null) panel.Clear(); else ClearText(); }); MenuWidget menuWidget = DarkTheme.sDarkTheme.CreateMenuWidget(menu); menuWidget.Init(this, useX, useY); } } public override void MouseDown(float x, float y, int32 btn, int32 btnCount) { if ((btn == 0) && (btnCount > 1)) { for (int32 lineOfs = 0; lineOfs >= -1; lineOfs--) if (GotoRefrenceAtLine(CursorLineAndColumn.mLine, lineOfs)) return; } base.MouseDown(x, y, btn, btnCount); } public override void KeyDown(KeyCode keyCode, bool isRepeat) { base.KeyDown(keyCode, isRepeat); if (keyCode == .Apps) { GetTextCoordAtCursor(var x, var y); MouseClicked(x, y, x, y, 1); } } } public class OutputWidget : SourceEditWidget { public this() : base(null, new OutputWidgetContent()) { } public override void DrawAll(Beefy.gfx.Graphics g) { base.DrawAll(g); /*for (int i < 10) { var testStr = scope String(); for (int j < 10) { Font.StrEncodeColor(0xfffebd57, testStr); testStr.Append('A' + j); Font.StrEncodePopColor(testStr); } g.DrawString(testStr, 20, 300 + i * 20); }*/ } } }