mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-19 16:40:26 +02:00
Initial checkin
This commit is contained in:
parent
c74712dad9
commit
078564ac9e
3242 changed files with 1616395 additions and 0 deletions
382
IDE/src/ui/ConditionDialog.bf
Normal file
382
IDE/src/ui/ConditionDialog.bf
Normal file
|
@ -0,0 +1,382 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Beefy.gfx;
|
||||
using Beefy.theme.dark;
|
||||
using Beefy.widgets;
|
||||
using IDE.Debugger;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace IDE.ui
|
||||
{
|
||||
public class EmbeddedEditWidget : ExpressionEditWidget
|
||||
{
|
||||
public override EditSelection GetCurExprRange()
|
||||
{
|
||||
int cursorPos = mEditWidgetContent.CursorTextPos;
|
||||
|
||||
let data = mEditWidgetContent.mData;
|
||||
int exprStart = -1;
|
||||
|
||||
for (int pos < data.mTextLength)
|
||||
{
|
||||
char8 c = data.mText[pos].mChar;
|
||||
if (c == '{')
|
||||
{
|
||||
if (pos < data.mTextLength - 1)
|
||||
{
|
||||
char8 nextC = data.mText[pos + 1].mChar;
|
||||
if (nextC != '{')
|
||||
{
|
||||
exprStart = pos + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (c == '}')
|
||||
{
|
||||
if (exprStart != -1)
|
||||
{
|
||||
if ((cursorPos >= exprStart) && (cursorPos <= pos))
|
||||
{
|
||||
return .(exprStart, pos);
|
||||
}
|
||||
|
||||
exprStart = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return .();
|
||||
}
|
||||
}
|
||||
|
||||
public class ClearCountButton : Widget
|
||||
{
|
||||
public override void Draw(Graphics g)
|
||||
{
|
||||
base.Draw(g);
|
||||
|
||||
if ((mMouseOver) || (mMouseDown))
|
||||
g.Draw(DarkTheme.sDarkTheme.GetImage(.CloseOver));
|
||||
else
|
||||
g.Draw(DarkTheme.sDarkTheme.GetImage(.Close));
|
||||
}
|
||||
}
|
||||
|
||||
public class ConditionDialog : IDEDialog
|
||||
{
|
||||
ExpressionEditWidget mConditionEdit;
|
||||
DarkEditWidget mThreadEdit;
|
||||
EmbeddedEditWidget mLogEdit;
|
||||
DarkCheckBox mBreakAfterLoggingCheckbox;
|
||||
DarkEditWidget mHitCountEdit;
|
||||
DarkComboBox mHitCountCombo;
|
||||
ClearCountButton mClearCountButton;
|
||||
List<String> mHitCountKinds = new List<String>() ~ delete _;
|
||||
int32 mStartingHitCount;
|
||||
int32 mExtraField;
|
||||
Breakpoint mBreakpoint;
|
||||
|
||||
public this()
|
||||
{
|
||||
mHitCountKinds.Add("Always Break");
|
||||
mHitCountKinds.Add("When equals");
|
||||
mHitCountKinds.Add("When at least");
|
||||
mHitCountKinds.Add("When multiple of");
|
||||
mWindowFlags &= ~.Modal;
|
||||
}
|
||||
|
||||
public ~this()
|
||||
{
|
||||
mBreakpoint?.Deref();
|
||||
}
|
||||
|
||||
public override void CalcSize()
|
||||
{
|
||||
mWidth = GS!(360);
|
||||
mHeight = GS!(270);
|
||||
}
|
||||
|
||||
public bool Finish()
|
||||
{
|
||||
/*if ((mConditionEdit.mLastError != null) && (mConditionEdit.mLastError != "sideeffects"))
|
||||
{
|
||||
var err = scope String();
|
||||
err.AppendF("Error in Condition:\n{0}", mConditionEdit.mLastError);
|
||||
gApp.Fail(err);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mLogEdit.mLastError != null)
|
||||
{
|
||||
var err = scope String();
|
||||
err.AppendF("Error in Log String:\n{0}", mConditionEdit.mLastError);
|
||||
gApp.Fail(err);
|
||||
return false;
|
||||
}*/
|
||||
|
||||
var sourceEditWidgetContent = (SourceEditWidgetContent)mConditionEdit.Content;
|
||||
if (sourceEditWidgetContent.mAutoComplete != null)
|
||||
sourceEditWidgetContent.KeyChar('\t');
|
||||
|
||||
String conditionStr = scope String();
|
||||
mConditionEdit.GetText(conditionStr);
|
||||
conditionStr.Trim();
|
||||
|
||||
int threadId = -1;
|
||||
String threadStr = scope String();
|
||||
mThreadEdit.GetText(threadStr);
|
||||
threadStr.Trim();
|
||||
if (!threadStr.IsWhiteSpace)
|
||||
{
|
||||
if (threadStr == ".")
|
||||
{
|
||||
threadId = gApp.mDebugger.GetActiveThread();
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (Int.Parse(threadStr))
|
||||
{
|
||||
case .Ok(out threadId):
|
||||
case .Err:
|
||||
gApp.Fail("Invalid value for Thread Id");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String loggingStr = scope String();
|
||||
mLogEdit.GetText(loggingStr);
|
||||
loggingStr.Trim();
|
||||
|
||||
String hitCountTargetStr = scope String();
|
||||
mHitCountEdit.GetText(hitCountTargetStr);
|
||||
hitCountTargetStr.Trim();
|
||||
int32 targetHitCount = 0;
|
||||
|
||||
Breakpoint.HitCountBreakKind hitCountBreakKind = (.)mHitCountKinds.IndexOf(scope String(mHitCountCombo.Label));
|
||||
|
||||
if (!hitCountTargetStr.IsWhiteSpace)
|
||||
{
|
||||
if (hitCountTargetStr == ".")
|
||||
{
|
||||
targetHitCount = mStartingHitCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (Int32.Parse(hitCountTargetStr))
|
||||
{
|
||||
case .Ok(out targetHitCount):
|
||||
case .Err:
|
||||
gApp.Fail("Invalid value for Target Hit Count");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool breakOnLogging = mBreakAfterLoggingCheckbox.Checked;
|
||||
gApp.mBreakpointPanel.ConfigureBreakpoint(mBreakpoint, conditionStr, threadId, loggingStr, breakOnLogging, targetHitCount, hitCountBreakKind);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetupExprEvaluator(ExpressionEditWidget exprEditWidget)
|
||||
{
|
||||
if (mBreakpoint.mAddrType != null)
|
||||
{
|
||||
var exprPre = new String();
|
||||
var exprPost = new String();
|
||||
exprEditWidget.mExprPre = exprPre;
|
||||
exprEditWidget.mExprPost = exprPost;
|
||||
|
||||
var enumerator = mBreakpoint.mAddrType.Split('\t');
|
||||
int langVal = int.Parse(enumerator.GetNext().Get()).Get();
|
||||
StringView addrVal = enumerator.GetNext().Get();
|
||||
if (langVal == (.)DebugManager.Language.C)
|
||||
exprPre.Append("@C:");
|
||||
else
|
||||
exprPre.Append("@Beef:");
|
||||
exprPost.AppendF(",_=({0}*)0x", addrVal);
|
||||
mBreakpoint.mMemoryAddress.ToString(exprPost, "X", null);
|
||||
exprPost.Append("L");
|
||||
}
|
||||
}
|
||||
|
||||
public void Init(Breakpoint breakpoint)
|
||||
{
|
||||
bool ignoreErrors = !gApp.mDebugger.IsPaused();
|
||||
|
||||
mBreakpoint = breakpoint;
|
||||
mBreakpoint.AddRef();
|
||||
|
||||
var title = scope String();
|
||||
title.Append("Configure Breakpoint - ");
|
||||
breakpoint.ToString_Location(title);
|
||||
Title = title;
|
||||
|
||||
mDefaultButton = AddButton("OK", new (evt) => { if (!Finish()) evt.mCloseDialog = false; });
|
||||
mEscButton = AddButton("Cancel", new (evt) => Close());
|
||||
|
||||
mStartingHitCount = (.)breakpoint.GetHitCount();
|
||||
|
||||
mConditionEdit = new ExpressionEditWidget();
|
||||
SetupExprEvaluator(mConditionEdit);
|
||||
mConditionEdit.mIgnoreErrors = ignoreErrors;
|
||||
// Just try at first address
|
||||
void* nextAddr = null;
|
||||
mConditionEdit.mEvalAtAddress = breakpoint.GetAddress(ref nextAddr);
|
||||
if (breakpoint.mCondition != null)
|
||||
{
|
||||
mConditionEdit.SetText(breakpoint.mCondition);
|
||||
mConditionEdit.Content.SelectAll();
|
||||
}
|
||||
AddEdit(mConditionEdit);
|
||||
|
||||
mThreadEdit = new DarkEditWidget();
|
||||
((DarkEditWidgetContent)mThreadEdit.mEditWidgetContent).mScrollToStartOnLostFocus = true;
|
||||
if (breakpoint.mThreadId != -1)
|
||||
{
|
||||
var str = scope String();
|
||||
breakpoint.mThreadId.ToString(str);
|
||||
mThreadEdit.SetText(str);
|
||||
mThreadEdit.Content.SelectAll();
|
||||
}
|
||||
AddEdit(mThreadEdit);
|
||||
|
||||
mHitCountCombo = new DarkComboBox();
|
||||
mHitCountCombo.Label = mHitCountKinds[(int)breakpoint.mHitCountBreakKind];
|
||||
mHitCountCombo.mPopulateMenuAction.Add(new (dlg) =>
|
||||
{
|
||||
for (let str in mHitCountKinds)
|
||||
{
|
||||
var item = dlg.AddItem(str);
|
||||
item.mOnMenuItemSelected.Add(new (item) =>
|
||||
{
|
||||
// If there is no number etered yet, default to
|
||||
var hitCountStr = scope String();
|
||||
mHitCountEdit.GetText(hitCountStr);
|
||||
if ((hitCountStr.IsWhiteSpace) && (item.mLabel != mHitCountKinds[0]))
|
||||
{
|
||||
hitCountStr.Clear();
|
||||
breakpoint.GetHitCount().ToString(hitCountStr);
|
||||
mHitCountEdit.SetText(hitCountStr);
|
||||
}
|
||||
|
||||
mHitCountCombo.Label = item.mLabel;
|
||||
MarkDirty();
|
||||
});
|
||||
}
|
||||
});
|
||||
AddDialogComponent(mHitCountCombo);
|
||||
|
||||
mHitCountEdit = new DarkEditWidget();
|
||||
((DarkEditWidgetContent)mHitCountEdit.mEditWidgetContent).mScrollToStartOnLostFocus = true;
|
||||
if (breakpoint.mHitCountTarget != 0)
|
||||
{
|
||||
var str = scope String();
|
||||
breakpoint.mHitCountTarget.ToString(str);
|
||||
mHitCountEdit.SetText(str);
|
||||
mHitCountEdit.Content.SelectAll();
|
||||
}
|
||||
AddEdit(mHitCountEdit);
|
||||
|
||||
mClearCountButton = new ClearCountButton();
|
||||
mClearCountButton.mOnMouseDown.Add(new (widget) =>
|
||||
{
|
||||
gApp.mBreakpointPanel.ClearHitCounts();
|
||||
mStartingHitCount = 0;
|
||||
});
|
||||
AddWidget(mClearCountButton);
|
||||
|
||||
mLogEdit = new EmbeddedEditWidget();
|
||||
mLogEdit.mIgnoreErrors = ignoreErrors;
|
||||
SetupExprEvaluator(mLogEdit);
|
||||
AddEdit(mLogEdit);
|
||||
if (breakpoint.mLogging != null)
|
||||
{
|
||||
mLogEdit.SetText(breakpoint.mLogging);
|
||||
mLogEdit.Content.SelectAll();
|
||||
}
|
||||
|
||||
mBreakAfterLoggingCheckbox = new DarkCheckBox();
|
||||
mBreakAfterLoggingCheckbox.Label = "Break after logging";
|
||||
mBreakAfterLoggingCheckbox.Checked = breakpoint.mBreakAfterLogging;
|
||||
AddDialogComponent(mBreakAfterLoggingCheckbox);
|
||||
}
|
||||
|
||||
public override void PopupWindow(WidgetWindow parentWindow, float offsetX = 0, float offsetY = 0)
|
||||
{
|
||||
base.PopupWindow(parentWindow, offsetX, offsetY);
|
||||
mConditionEdit.SetFocus();
|
||||
}
|
||||
|
||||
public override void ResizeComponents()
|
||||
{
|
||||
base.ResizeComponents();
|
||||
|
||||
float editWidth = GS!(100);
|
||||
|
||||
float curY = mHeight - GS!(20) - mButtonBottomMargin;
|
||||
mLogEdit.Resize(GS!(16), curY - GS!(36), mWidth - GS!(16) * 2, GS!(28));
|
||||
mBreakAfterLoggingCheckbox.Resize(mWidth - mBreakAfterLoggingCheckbox.CalcWidth() - GS!(16), curY - GS!(36) - GS!(20), mBreakAfterLoggingCheckbox.CalcWidth() + GS!(4), GS!(28));
|
||||
|
||||
curY -= GS!(56);
|
||||
mHitCountEdit.Resize(mWidth - editWidth - GS!(16), curY - GS!(36), editWidth, GS!(28));
|
||||
mHitCountCombo.Resize(GS!(16), curY - GS!(36) + GS!(2), mWidth - GS!(16)*2 - editWidth - GS!(4), GS!(28));
|
||||
mClearCountButton.Resize(mWidth - GS!(28), curY - GS!(36) - GS!(19), GS!(20), GS!(20));
|
||||
|
||||
curY -= GS!(56);
|
||||
mThreadEdit.Resize(GS!(16), curY - GS!(36), mWidth - GS!(16) * 2, GS!(28));
|
||||
|
||||
curY -= GS!(56);
|
||||
mConditionEdit.Resize(GS!(16), curY - GS!(36), mWidth - GS!(16) * 2, GS!(28));
|
||||
|
||||
delete mClearCountButton.mMouseInsets;
|
||||
mClearCountButton.mMouseInsets = new .(GS!(4), GS!(4), GS!(4), GS!(4));
|
||||
}
|
||||
|
||||
public override bool HandleTab(int dir)
|
||||
{
|
||||
var sourceEditWidgetContent = (SourceEditWidgetContent)mConditionEdit.Content;
|
||||
if ((sourceEditWidgetContent.mAutoComplete != null) && (sourceEditWidgetContent.mAutoComplete.IsShowing()))
|
||||
{
|
||||
//sourceEditWidgetContent.KeyChar('\t');
|
||||
return false;
|
||||
}
|
||||
|
||||
return base.HandleTab(dir);
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
base.Update();
|
||||
int hitCount = mBreakpoint.GetHitCount();
|
||||
if (hitCount != mStartingHitCount)
|
||||
{
|
||||
mStartingHitCount = (.)hitCount;
|
||||
MarkDirty();
|
||||
}
|
||||
|
||||
if (mBreakpoint.mIsDead)
|
||||
{
|
||||
// This breakpoint was deleted
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Draw(Graphics g)
|
||||
{
|
||||
base.Draw(g);
|
||||
|
||||
g.DrawString("Breakpoint Condition", mConditionEdit.mX, mConditionEdit.mY - GS!(20));
|
||||
g.DrawString("Thread Id", mThreadEdit.mX, mThreadEdit.mY - GS!(20));
|
||||
g.DrawString("Log String", mLogEdit.mX, mLogEdit.mY - GS!(20));
|
||||
g.DrawString("Break on Hit Count", mHitCountCombo.mX, mHitCountEdit.mY - GS!(19));
|
||||
|
||||
var str = scope String();
|
||||
str.AppendF("Current: {0}", mStartingHitCount);
|
||||
g.DrawString(str, mWidth - GS!(16) - GS!(8), mHitCountEdit.mY - GS!(19), .Right);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue