mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-15 05:59:30 +02:00
MWE:
+ Added invalidBreakpoint image * Reorganized uniteditor so that breakpoints can be added erternal * moved breakpoints events to notification object git-svn-id: trunk@1546 -
This commit is contained in:
parent
852eb5a81f
commit
d8a4f5d282
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -358,6 +358,8 @@ images/sourceeditor/ActiveBreakPoint.ico -text svneol=unset#image/x-icon
|
|||||||
images/sourceeditor/ActiveBreakPoint.xpm -text svneol=native#image/x-xpixmap
|
images/sourceeditor/ActiveBreakPoint.xpm -text svneol=native#image/x-xpixmap
|
||||||
images/sourceeditor/InactiveBreakPoint.ico -text svneol=unset#image/x-icon
|
images/sourceeditor/InactiveBreakPoint.ico -text svneol=unset#image/x-icon
|
||||||
images/sourceeditor/InactiveBreakPoint.xpm -text svneol=native#image/x-xpixmap
|
images/sourceeditor/InactiveBreakPoint.xpm -text svneol=native#image/x-xpixmap
|
||||||
|
images/sourceeditor/InvalidBreakPoint.ico -text svneol=unset#image/x-icon
|
||||||
|
images/sourceeditor/InvalidBreakPoint.xpm -text svneol=native#image/x-xpixmap
|
||||||
images/sourceeditor/bookmark0.ico -text svneol=unset#image/x-icon
|
images/sourceeditor/bookmark0.ico -text svneol=unset#image/x-icon
|
||||||
images/sourceeditor/bookmark0.xpm -text svneol=native#image/x-xpixmap
|
images/sourceeditor/bookmark0.xpm -text svneol=native#image/x-xpixmap
|
||||||
images/sourceeditor/bookmark1.ico -text svneol=unset#image/x-icon
|
images/sourceeditor/bookmark1.ico -text svneol=unset#image/x-icon
|
||||||
|
@ -52,7 +52,8 @@ type
|
|||||||
procedure popDeleteClick(Sender: TObject);
|
procedure popDeleteClick(Sender: TObject);
|
||||||
popProperties: TMenuItem;
|
popProperties: TMenuItem;
|
||||||
procedure popPropertiesClick(Sender: TObject);
|
procedure popPropertiesClick(Sender: TObject);
|
||||||
private
|
private
|
||||||
|
FBreakpointsNotification: TDBGBreakPointsNotification;
|
||||||
procedure BreakPointAdd(const ASender: TDBGBreakPoints; const ABreakpoint: TDBGBreakPoint);
|
procedure BreakPointAdd(const ASender: TDBGBreakPoints; const ABreakpoint: TDBGBreakPoint);
|
||||||
procedure BreakPointUpdate(const ASender: TDBGBreakPoints; const ABreakpoint: TDBGBreakPoint);
|
procedure BreakPointUpdate(const ASender: TDBGBreakPoints; const ABreakpoint: TDBGBreakPoint);
|
||||||
procedure BreakPointRemove(const ASender: TDBGBreakPoints; const ABreakpoint: TDBGBreakPoint);
|
procedure BreakPointRemove(const ASender: TDBGBreakPoints; const ABreakpoint: TDBGBreakPoint);
|
||||||
@ -62,6 +63,8 @@ type
|
|||||||
procedure Loaded; override;
|
procedure Loaded; override;
|
||||||
procedure SetDebugger(const ADebugger: TDebugger); override;
|
procedure SetDebugger(const ADebugger: TDebugger); override;
|
||||||
public
|
public
|
||||||
|
constructor Create(AOwner: TComponent); override;
|
||||||
|
destructor Destroy; override;
|
||||||
published
|
published
|
||||||
property Dummy: Boolean; // insert some dummies until fpcbug #1888 is fixed
|
property Dummy: Boolean; // insert some dummies until fpcbug #1888 is fixed
|
||||||
end;
|
end;
|
||||||
@ -103,6 +106,26 @@ begin
|
|||||||
lvBreakPoints.Items.FindData(ABreakpoint).Free;
|
lvBreakPoints.Items.FindData(ABreakpoint).Free;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
constructor TBreakPointsDlg.Create(AOwner: TComponent);
|
||||||
|
begin
|
||||||
|
inherited;
|
||||||
|
FBreakpointsNotification := TDBGBreakPointsNotification.Create;
|
||||||
|
FBreakpointsNotification.AddReference;
|
||||||
|
FBreakpointsNotification.OnAdd := @BreakPointAdd;
|
||||||
|
FBreakpointsNotification.OnUpdate := @BreakPointUpdate;
|
||||||
|
FBreakpointsNotification.OnRemove := @BreakPointRemove;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TBreakPointsDlg.Destroy;
|
||||||
|
begin
|
||||||
|
SetDebugger(nil);
|
||||||
|
FBreakpointsNotification.OnAdd := nil;
|
||||||
|
FBreakpointsNotification.OnUpdate := nil;
|
||||||
|
FBreakpointsNotification.OnRemove := nil;
|
||||||
|
FBreakpointsNotification.ReleaseReference;
|
||||||
|
inherited;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TBreakPointsDlg.Loaded;
|
procedure TBreakPointsDlg.Loaded;
|
||||||
begin
|
begin
|
||||||
inherited Loaded;
|
inherited Loaded;
|
||||||
@ -185,16 +208,12 @@ begin
|
|||||||
then begin
|
then begin
|
||||||
if Debugger <> nil
|
if Debugger <> nil
|
||||||
then begin
|
then begin
|
||||||
Debugger.Breakpoints.OnAdd := nil;
|
Debugger.Breakpoints.RemoveNotification(FBreakpointsNotification);
|
||||||
Debugger.Breakpoints.OnUpdate := nil;
|
|
||||||
Debugger.Breakpoints.OnRemove := nil;
|
|
||||||
end;
|
end;
|
||||||
inherited;
|
inherited;
|
||||||
if Debugger <> nil
|
if Debugger <> nil
|
||||||
then begin
|
then begin
|
||||||
Debugger.Breakpoints.OnAdd := @BreakPointAdd;
|
Debugger.Breakpoints.AddNotification(FBreakpointsNotification);
|
||||||
Debugger.Breakpoints.OnUpdate := @BreakPointUpdate;
|
|
||||||
Debugger.Breakpoints.OnRemove := @BreakPointRemove;
|
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
else inherited;
|
else inherited;
|
||||||
@ -244,6 +263,12 @@ end.
|
|||||||
|
|
||||||
{ =============================================================================
|
{ =============================================================================
|
||||||
$Log$
|
$Log$
|
||||||
|
Revision 1.3 2002/03/25 22:38:29 lazarus
|
||||||
|
MWE:
|
||||||
|
+ Added invalidBreakpoint image
|
||||||
|
* Reorganized uniteditor so that breakpoints can be added erternal
|
||||||
|
* moved breakpoints events to notification object
|
||||||
|
|
||||||
Revision 1.2 2002/03/23 15:54:30 lazarus
|
Revision 1.2 2002/03/23 15:54:30 lazarus
|
||||||
MWE:
|
MWE:
|
||||||
+ Added locals dialog
|
+ Added locals dialog
|
||||||
|
@ -124,29 +124,53 @@ type
|
|||||||
property Source: String read FSource;
|
property Source: String read FSource;
|
||||||
property Line: Integer read FLine;
|
property Line: Integer read FLine;
|
||||||
property Valid: Boolean read FValid;
|
property Valid: Boolean read FValid;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ ---------------------------------------------------------
|
||||||
|
TDebuggerNotification is a reference counted baseclass
|
||||||
|
for handling notifications for locals, watches, breakpoints etc.
|
||||||
|
---------------------------------------------------------}
|
||||||
|
TDebuggerNotification = class(TObject)
|
||||||
|
private
|
||||||
|
FRefCount: Integer;
|
||||||
|
public
|
||||||
|
procedure AddReference;
|
||||||
|
constructor Create;
|
||||||
|
destructor Destroy; override;
|
||||||
|
procedure ReleaseReference;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TDBGBreakPoints = class;
|
TDBGBreakPoints = class;
|
||||||
TDBGBreakPointsEvent = procedure(const ASender: TDBGBreakPoints; const ABreakpoint: TDBGBreakPoint) of object;
|
TDBGBreakPointsEvent = procedure(const ASender: TDBGBreakPoints; const ABreakpoint: TDBGBreakPoint) of object;
|
||||||
TDBGBreakPoints = class(TCollection)
|
TDBGBreakPointsNotification = class(TDebuggerNotification)
|
||||||
private
|
private
|
||||||
FDebugger: TDebugger; // reference to our debugger
|
|
||||||
FOnAdd: TDBGBreakPointsEvent;
|
FOnAdd: TDBGBreakPointsEvent;
|
||||||
FOnUpdate: TDBGBreakPointsEvent; //Item will be nil in case all items need to be updated
|
FOnUpdate: TDBGBreakPointsEvent; //Item will be nil in case all items need to be updated
|
||||||
FOnRemove: TDBGBreakPointsEvent;
|
FOnRemove: TDBGBreakPointsEvent;
|
||||||
|
public
|
||||||
|
property OnAdd: TDBGBreakPointsEvent read FOnAdd write FOnAdd;
|
||||||
|
property OnUpdate: TDBGBreakPointsEvent read FOnUpdate write FOnUpdate;
|
||||||
|
property OnRemove: TDBGBreakPointsEvent read FOnRemove write FonRemove;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TDBGBreakPoints = class(TCollection)
|
||||||
|
private
|
||||||
|
FDebugger: TDebugger; // reference to our debugger
|
||||||
|
FNotificationList: TList;
|
||||||
function GetItem(const AnIndex: Integer): TDBGBreakPoint;
|
function GetItem(const AnIndex: Integer): TDBGBreakPoint;
|
||||||
procedure SetItem(const AnIndex: Integer; const AValue: TDBGBreakPoint);
|
procedure SetItem(const AnIndex: Integer; const AValue: TDBGBreakPoint);
|
||||||
|
procedure Removed(const ABreakpoint: TDBGBreakPoint); // called by breakpoint when destructed
|
||||||
protected
|
protected
|
||||||
procedure DoStateChange; virtual;
|
procedure DoStateChange; virtual;
|
||||||
procedure Update(Item: TCollectionItem); override;
|
procedure Update(Item: TCollectionItem); override;
|
||||||
public
|
public
|
||||||
constructor Create(const ADebugger: TDebugger; const ABreakPointClass: TDBGBreakPointClass);
|
|
||||||
function Add(const ASource: String; const ALine: Integer): TDBGBreakPoint;
|
function Add(const ASource: String; const ALine: Integer): TDBGBreakPoint;
|
||||||
|
procedure AddNotification(const ANotification: TDBGBreakPointsNotification);
|
||||||
|
constructor Create(const ADebugger: TDebugger; const ABreakPointClass: TDBGBreakPointClass);
|
||||||
|
destructor Destroy; override;
|
||||||
function Find(const ASource: String; const ALine: Integer): TDBGBreakPoint;
|
function Find(const ASource: String; const ALine: Integer): TDBGBreakPoint;
|
||||||
|
procedure RemoveNotification(const ANotification: TDBGBreakPointsNotification);
|
||||||
property Items[const AnIndex: Integer]: TDBGBreakPoint read GetItem write SetItem; default;
|
property Items[const AnIndex: Integer]: TDBGBreakPoint read GetItem write SetItem; default;
|
||||||
property OnAdd: TDBGBreakPointsEvent read FOnAdd write FOnAdd;
|
|
||||||
property OnUpdate: TDBGBreakPointsEvent read FOnUpdate write FOnUpdate;
|
|
||||||
property OnRemove: TDBGBreakPointsEvent read FOnRemove write FonRemove;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TDBGBreakPointGroup = class(TCollectionItem)
|
TDBGBreakPointGroup = class(TCollectionItem)
|
||||||
@ -572,8 +596,7 @@ var
|
|||||||
n: Integer;
|
n: Integer;
|
||||||
begin
|
begin
|
||||||
if (TDBGBreakPoints(Collection) <> nil)
|
if (TDBGBreakPoints(Collection) <> nil)
|
||||||
and Assigned(TDBGBreakPoints(Collection).FOnRemove)
|
then TDBGBreakPoints(Collection).Removed(Self);
|
||||||
then TDBGBreakPoints(Collection).FOnRemove(TDBGBreakPoints(Collection), Self);
|
|
||||||
|
|
||||||
if FGroup <> nil
|
if FGroup <> nil
|
||||||
then FGroup.Remove(Self);
|
then FGroup.Remove(Self);
|
||||||
@ -735,16 +758,43 @@ end;
|
|||||||
{ =========================================================================== }
|
{ =========================================================================== }
|
||||||
|
|
||||||
function TDBGBreakPoints.Add(const ASource: String; const ALine: Integer): TDBGBreakPoint;
|
function TDBGBreakPoints.Add(const ASource: String; const ALine: Integer): TDBGBreakPoint;
|
||||||
|
var
|
||||||
|
n: Integer;
|
||||||
|
Notification: TDBGBreakPointsNotification;
|
||||||
begin
|
begin
|
||||||
Result := TDBGBreakPoint(inherited Add);
|
Result := TDBGBreakPoint(inherited Add);
|
||||||
Result.SetLocation(ASource, ALine);
|
Result.SetLocation(ASource, ALine);
|
||||||
if Assigned(FOnAdd) then FOnAdd(Self, Result);
|
for n := 0 to FNotificationList.Count - 1 do
|
||||||
|
begin
|
||||||
|
Notification := TDBGBreakPointsNotification(FNotificationList[n]);
|
||||||
|
if Assigned(Notification.FOnAdd)
|
||||||
|
then Notification.FOnAdd(Self, Result);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TDBGBreakPoints.AddNotification(const ANotification: TDBGBreakPointsNotification);
|
||||||
|
begin
|
||||||
|
FNotificationList.Add(ANotification);
|
||||||
|
ANotification.AddReference;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TDBGBreakPoints.Create(const ADebugger: TDebugger; const ABreakPointClass: TDBGBreakPointClass);
|
constructor TDBGBreakPoints.Create(const ADebugger: TDebugger; const ABreakPointClass: TDBGBreakPointClass);
|
||||||
begin
|
begin
|
||||||
inherited Create(ABreakPointClass);
|
inherited Create(ABreakPointClass);
|
||||||
FDebugger := ADebugger;
|
FDebugger := ADebugger;
|
||||||
|
FNotificationList := TList.Create;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TDBGBreakPoints.Destroy;
|
||||||
|
var
|
||||||
|
n: Integer;
|
||||||
|
begin
|
||||||
|
for n := FNotificationList.Count - 1 downto 0 do
|
||||||
|
TDebuggerNotification(FNotificationList[n]).ReleaseReference;
|
||||||
|
|
||||||
|
inherited;
|
||||||
|
|
||||||
|
FreeAndNil(FNotificationList);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TDBGBreakPoints.DoStateChange;
|
procedure TDBGBreakPoints.DoStateChange;
|
||||||
@ -774,16 +824,42 @@ begin
|
|||||||
Result := TDBGBreakPoint(inherited GetItem(AnIndex));
|
Result := TDBGBreakPoint(inherited GetItem(AnIndex));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TDBGBreakPoints.Removed(const ABreakpoint: TDBGBreakPoint);
|
||||||
|
var
|
||||||
|
n: Integer;
|
||||||
|
Notification: TDBGBreakPointsNotification;
|
||||||
|
begin
|
||||||
|
for n := 0 to FNotificationList.Count - 1 do
|
||||||
|
begin
|
||||||
|
Notification := TDBGBreakPointsNotification(FNotificationList[n]);
|
||||||
|
if Assigned(Notification.FOnRemove)
|
||||||
|
then Notification.FOnRemove(Self, ABreakpoint);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TDBGBreakPoints.RemoveNotification(const ANotification: TDBGBreakPointsNotification);
|
||||||
|
begin
|
||||||
|
FNotificationList.Remove(ANotification);
|
||||||
|
ANotification.ReleaseReference;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TDBGBreakPoints.SetItem(const AnIndex: Integer; const AValue: TDBGBreakPoint);
|
procedure TDBGBreakPoints.SetItem(const AnIndex: Integer; const AValue: TDBGBreakPoint);
|
||||||
begin
|
begin
|
||||||
SetItem(AnIndex, AValue);
|
SetItem(AnIndex, AValue);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TDBGBreakPoints.Update(Item: TCollectionItem);
|
procedure TDBGBreakPoints.Update(Item: TCollectionItem);
|
||||||
|
var
|
||||||
|
n: Integer;
|
||||||
|
Notification: TDBGBreakPointsNotification;
|
||||||
begin
|
begin
|
||||||
// Note: Item will be nil in case all items need to be updated
|
// Note: Item will be nil in case all items need to be updated
|
||||||
if Assigned(FOnUpdate)
|
for n := 0 to FNotificationList.Count - 1 do
|
||||||
then FOnUpdate(Self, TDBGBreakPoint(Item));
|
begin
|
||||||
|
Notification := TDBGBreakPointsNotification(FNotificationList[n]);
|
||||||
|
if Assigned(Notification.FOnUpdate)
|
||||||
|
then Notification.FOnUpdate(Self, TDBGBreakPoint(Item));
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ =========================================================================== }
|
{ =========================================================================== }
|
||||||
@ -1001,10 +1077,44 @@ function TDBGLocals.GetValue(const AnIndex: Integer): String;
|
|||||||
begin
|
begin
|
||||||
Result := '';
|
Result := '';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ =========================================================================== }
|
||||||
|
{ TDebuggerNotification }
|
||||||
|
{ =========================================================================== }
|
||||||
|
|
||||||
|
procedure TDebuggerNotification.AddReference;
|
||||||
|
begin
|
||||||
|
Inc(FRefcount);
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TDebuggerNotification.Create;
|
||||||
|
begin
|
||||||
|
FRefCount := 0;
|
||||||
|
inherited;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TDebuggerNotification.Destroy;
|
||||||
|
begin
|
||||||
|
Assert(FRefcount = 0, 'Destroying referenced object');
|
||||||
|
inherited;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TDebuggerNotification.ReleaseReference;
|
||||||
|
begin
|
||||||
|
Dec(FRefCount);
|
||||||
|
if FRefCount = 0 then Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
end.
|
end.
|
||||||
{ =============================================================================
|
{ =============================================================================
|
||||||
$Log$
|
$Log$
|
||||||
|
Revision 1.12 2002/03/25 22:38:29 lazarus
|
||||||
|
MWE:
|
||||||
|
+ Added invalidBreakpoint image
|
||||||
|
* Reorganized uniteditor so that breakpoints can be added erternal
|
||||||
|
* moved breakpoints events to notification object
|
||||||
|
|
||||||
Revision 1.11 2002/03/23 15:54:30 lazarus
|
Revision 1.11 2002/03/23 15:54:30 lazarus
|
||||||
MWE:
|
MWE:
|
||||||
+ Added locals dialog
|
+ Added locals dialog
|
||||||
|
@ -55,7 +55,7 @@ type
|
|||||||
lshCPP, lshPerl);
|
lshCPP, lshPerl);
|
||||||
|
|
||||||
TAdditionalHilightAttribute = (ahaNone, ahaTextBlock, ahaExecutionPoint,
|
TAdditionalHilightAttribute = (ahaNone, ahaTextBlock, ahaExecutionPoint,
|
||||||
ahaEnabledBreakpoint, ahaDisabledBreakpoint, ahaErrorLine);
|
ahaEnabledBreakpoint, ahaDisabledBreakpoint, ahaInvalidBreakpoint, ahaErrorLine);
|
||||||
|
|
||||||
const
|
const
|
||||||
EditorOptsFormatVersion = 2;
|
EditorOptsFormatVersion = 2;
|
||||||
@ -65,7 +65,7 @@ const
|
|||||||
'',
|
'',
|
||||||
'Text block',
|
'Text block',
|
||||||
'Execution point',
|
'Execution point',
|
||||||
'Enabled breakpoint','Disabled breakpoint',
|
'Enabled breakpoint','Disabled breakpoint','Invalid breakpoint',
|
||||||
'Error line'
|
'Error line'
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1622,6 +1622,11 @@ begin
|
|||||||
BG:=clGreen;
|
BG:=clGreen;
|
||||||
FG:=clBlack;
|
FG:=clBlack;
|
||||||
end;
|
end;
|
||||||
|
ahaInvalidBreakpoint:
|
||||||
|
begin
|
||||||
|
BG:=clOlive;
|
||||||
|
FG:=clGreen;
|
||||||
|
end;
|
||||||
ahaErrorLine:
|
ahaErrorLine:
|
||||||
begin
|
begin
|
||||||
BG:=$50a0ff;
|
BG:=$50a0ff;
|
||||||
|
@ -212,14 +212,15 @@ begin
|
|||||||
// -------------------
|
// -------------------
|
||||||
// dcRun, dcPause, dcStop, dcStepOver, dcStepInto, dcRunTo, dcJumpto, dcBreak, dcWatch
|
// dcRun, dcPause, dcStop, dcStepOver, dcStepInto, dcRunTo, dcJumpto, dcBreak, dcWatch
|
||||||
// -------------------
|
// -------------------
|
||||||
|
|
||||||
RunSpeedButton.Enabled := dcRun in FDebugger.Commands;
|
// For run end step bypass idle, so we can set the filename later
|
||||||
|
RunSpeedButton.Enabled := (dcRun in FDebugger.Commands) or (FDebugger.State = dsIdle);
|
||||||
itmProjectRun.Enabled := RunSpeedButton.Enabled;
|
itmProjectRun.Enabled := RunSpeedButton.Enabled;
|
||||||
PauseSpeedButton.Enabled := dcPause in FDebugger.Commands;
|
PauseSpeedButton.Enabled := dcPause in FDebugger.Commands;
|
||||||
itmProjectPause.Enabled := PauseSpeedButton.Enabled;
|
itmProjectPause.Enabled := PauseSpeedButton.Enabled;
|
||||||
StepIntoSpeedButton.Enabled := dcStepInto in FDebugger.Commands;
|
StepIntoSpeedButton.Enabled := (dcStepInto in FDebugger.Commands) or (FDebugger.State = dsIdle);
|
||||||
itmProjectStepInto.Enabled := StepIntoSpeedButton.Enabled;
|
itmProjectStepInto.Enabled := StepIntoSpeedButton.Enabled;
|
||||||
StepOverSpeedButton.Enabled := dcStepOver in FDebugger.Commands;
|
StepOverSpeedButton.Enabled := (dcStepOver in FDebugger.Commands) or (FDebugger.State = dsIdle);
|
||||||
itmProjectStepOver.Enabled := StepOverSpeedButton.Enabled;
|
itmProjectStepOver.Enabled := StepOverSpeedButton.Enabled;
|
||||||
|
|
||||||
itmProjectRunToCursor.Enabled := dcRunTo in FDebugger.Commands;
|
itmProjectRunToCursor.Enabled := dcRunTo in FDebugger.Commands;
|
||||||
@ -295,6 +296,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
ADialog.Tag := Integer(@ADialog);
|
ADialog.Tag := Integer(@ADialog);
|
||||||
ADialog.OnDestroy := @DebugDialogDestroy;
|
ADialog.OnDestroy := @DebugDialogDestroy;
|
||||||
|
DoInitDebugger;
|
||||||
ADialog.Debugger := FDebugger;
|
ADialog.Debugger := FDebugger;
|
||||||
end;
|
end;
|
||||||
ADialog.Show;
|
ADialog.Show;
|
||||||
@ -307,10 +309,13 @@ end;
|
|||||||
|
|
||||||
function TMainIDE.DoInitDebugger: TModalResult;
|
function TMainIDE.DoInitDebugger: TModalResult;
|
||||||
procedure ResetDialogs;
|
procedure ResetDialogs;
|
||||||
begin
|
begin
|
||||||
FDebugOutputDlg.Debugger := FDebugger;
|
if FDebugOutputDlg <> nil
|
||||||
FBreakPointsDlg.Debugger := FDebugger;
|
then FDebugOutputDlg.Debugger := FDebugger;
|
||||||
FLocalsDlg.Debugger := FDebugger;
|
if FBreakPointsDlg <> nil
|
||||||
|
then FBreakPointsDlg.Debugger := FDebugger;
|
||||||
|
if FLocalsDlg <> nil
|
||||||
|
then FLocalsDlg.Debugger := FDebugger;
|
||||||
end;
|
end;
|
||||||
var
|
var
|
||||||
OldBreakpoints: TDBGBreakpoints;
|
OldBreakpoints: TDBGBreakpoints;
|
||||||
@ -335,6 +340,7 @@ begin
|
|||||||
|
|
||||||
FDebugger.Free;
|
FDebugger.Free;
|
||||||
FDebugger := nil;
|
FDebugger := nil;
|
||||||
|
ResetDialogs;
|
||||||
end;
|
end;
|
||||||
if FDebugger = nil
|
if FDebugger = nil
|
||||||
then begin
|
then begin
|
||||||
@ -345,6 +351,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
FDebugger := TGDBMIDebugger.Create(EnvironmentOptions.DebuggerFilename);
|
FDebugger := TGDBMIDebugger.Create(EnvironmentOptions.DebuggerFilename);
|
||||||
FBreakPoints := FDebugger.BreakPoints;
|
FBreakPoints := FDebugger.BreakPoints;
|
||||||
|
ResetDialogs;
|
||||||
end;
|
end;
|
||||||
if OldBreakpoints <> nil
|
if OldBreakpoints <> nil
|
||||||
then FBreakPoints.Assign(OldBreakpoints);
|
then FBreakPoints.Assign(OldBreakpoints);
|
||||||
@ -356,6 +363,7 @@ begin
|
|||||||
|
|
||||||
FDebugger.Free;
|
FDebugger.Free;
|
||||||
FDebugger := nil;
|
FDebugger := nil;
|
||||||
|
ResetDialogs;
|
||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
FDebugger.OnState:=@OnDebuggerChangeState;
|
FDebugger.OnState:=@OnDebuggerChangeState;
|
||||||
|
@ -41,7 +41,7 @@ uses
|
|||||||
type
|
type
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
TSrcEditMarkerType = (semActiveBreakPoint, semInactiveBreakPoint);
|
TSrcEditMarkerType = (semActiveBreakPoint, semInactiveBreakPoint, semInvalidBreakPoint);
|
||||||
TSrcEditMarkerTypes = set of TSrcEditMarkerType;
|
TSrcEditMarkerTypes = set of TSrcEditMarkerType;
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
@ -141,6 +141,9 @@ type
|
|||||||
|
|
||||||
Procedure CreateEditor(AOwner : TComponent; AParent: TWinControl);
|
Procedure CreateEditor(AOwner : TComponent; AParent: TWinControl);
|
||||||
procedure SetVisible(Value: boolean);
|
procedure SetVisible(Value: boolean);
|
||||||
|
function GetBreakPointMark(const ALine: Integer): TSynEditMark;
|
||||||
|
function IsBreakPointMark(const ABreakPointMark: TSynEditMark): Boolean;
|
||||||
|
procedure RemoveBreakPoint(const ABreakPointMark: TSynEditMark); overload;
|
||||||
protected
|
protected
|
||||||
FindText : String;
|
FindText : String;
|
||||||
ErrorMsgs : TStrings;
|
ErrorMsgs : TStrings;
|
||||||
@ -191,6 +194,8 @@ type
|
|||||||
procedure FindPrevious;
|
procedure FindPrevious;
|
||||||
procedure ShowGotoLineDialog;
|
procedure ShowGotoLineDialog;
|
||||||
procedure GetDialogPosition(Width, Height:integer; var Left,Top:integer);
|
procedure GetDialogPosition(Width, Height:integer; var Left,Top:integer);
|
||||||
|
procedure SetBreakPoint(const ALine: Integer; const AType: TSrcEditMarkerType);
|
||||||
|
procedure RemoveBreakPoint(const ALine: Integer); overload;
|
||||||
|
|
||||||
// editor commands
|
// editor commands
|
||||||
procedure DoEditorExecuteCommand(EditorCommand: integer);
|
procedure DoEditorExecuteCommand(EditorCommand: integer);
|
||||||
@ -467,10 +472,12 @@ type
|
|||||||
TCompletionType = (ctNone, ctWordCompletion, ctTemplateCompletion,
|
TCompletionType = (ctNone, ctWordCompletion, ctTemplateCompletion,
|
||||||
ctIdentCompletion);
|
ctIdentCompletion);
|
||||||
|
|
||||||
const
|
const
|
||||||
TSrcEditMarkerImgIndex: array[TSrcEditMarkerType] of integer = (
|
// keep const recognizable IE. not prefixed with T(ype)
|
||||||
|
SRCEDITMARKERIMGINDEX: array[TSrcEditMarkerType] of integer = (
|
||||||
10, // active breakpoint
|
10, // active breakpoint
|
||||||
11 // inactive breakpoint
|
11, // inactive breakpoint
|
||||||
|
12 // invalid breakpoint
|
||||||
);
|
);
|
||||||
|
|
||||||
var
|
var
|
||||||
@ -801,78 +808,115 @@ Begin
|
|||||||
OnEditorChange(Sender);
|
OnEditorChange(Sender);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TSourceEditor.IsBreakPointMark(const ABreakPointMark: TSynEditMark): Boolean;
|
||||||
|
begin
|
||||||
|
Result := (ABreakPointMark <> nil)
|
||||||
|
and (ABreakPointMark.ImageIndex in [
|
||||||
|
SRCEDITMARKERIMGINDEX[semActiveBreakPoint],
|
||||||
|
SRCEDITMARKERIMGINDEX[semInactiveBreakPoint],
|
||||||
|
SRCEDITMARKERIMGINDEX[semInvalidBreakPoint]
|
||||||
|
]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSourceEditor.GetBreakPointMark(const ALine: Integer): TSynEditMark;
|
||||||
|
var
|
||||||
|
n: Integer;
|
||||||
|
AllMarks: TSynEditMarks;
|
||||||
|
begin
|
||||||
|
FEditor.Marks.GetMarksForLine(ALine, AllMarks);
|
||||||
|
|
||||||
|
for n := 1 to maxMarks do
|
||||||
|
begin
|
||||||
|
Result := AllMarks[n];
|
||||||
|
if IsBreakPointMark(Result)
|
||||||
|
then Exit;
|
||||||
|
end;
|
||||||
|
Result := nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSourceEditor.SetBreakPoint(const ALine: Integer; const AType: TSrcEditMarkerType);
|
||||||
|
var
|
||||||
|
BreakPtMark: TSynEditMark;
|
||||||
|
begin
|
||||||
|
BreakPtMark := GetBreakPointMark(ALine);
|
||||||
|
if BreakPtMark = nil
|
||||||
|
then begin
|
||||||
|
BreakPtMark := TSynEditMark.Create(FEditor);
|
||||||
|
BreakPtMark.Line := ALine;
|
||||||
|
FEditor.Marks.Place(BreakPtMark);
|
||||||
|
if Assigned(FOnCreateBreakPoint) then FOnCreateBreakPoint(Self, ALine);
|
||||||
|
end;
|
||||||
|
BreakPtMark.Visible := True;
|
||||||
|
BreakPtMark.ImageIndex := SRCEDITMARKERIMGINDEX[AType];
|
||||||
|
FModified:=true;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSourceEditor.RemoveBreakPoint(const ALine: Integer);
|
||||||
|
begin
|
||||||
|
RemoveBreakPoint(GetBreakPointMark(ALine));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSourceEditor.RemoveBreakPoint(const ABreakPointMark: TSynEditMark); overload;
|
||||||
|
begin
|
||||||
|
if not IsBreakPointMark(ABreakPointMark) then Exit;
|
||||||
|
if Assigned(FOnDeleteBreakPoint) then FOnDeleteBreakPoint(Self, ABreakPointMark.Line);
|
||||||
|
FEditor.Marks.Remove(ABreakPointMark);
|
||||||
|
ABreakPointMark.Free;
|
||||||
|
FModified:=true;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TSourceEditor.OnGutterClick(Sender: TObject; X, Y, Line: integer;
|
procedure TSourceEditor.OnGutterClick(Sender: TObject; X, Y, Line: integer;
|
||||||
mark: TSynEditMark);
|
mark: TSynEditMark);
|
||||||
var i:integer;
|
var
|
||||||
AllMarks: TSynEditMarks;
|
|
||||||
BreakPtMark: TSynEditMark;
|
BreakPtMark: TSynEditMark;
|
||||||
begin
|
begin
|
||||||
// create or delete breakpoint
|
// create or delete breakpoint
|
||||||
// find breakpoint mark at line
|
// find breakpoint mark at line
|
||||||
fEditor.Marks.GetMarksForLine(Line, AllMarks);
|
BreakPtMark := GetBreakPointMark(Line);
|
||||||
BreakPtMark:=nil;
|
if BreakPtMark = nil
|
||||||
for i:=1 to maxMarks do begin
|
then SetBreakpoint(Line, semActiveBreakPoint)
|
||||||
if (AllMarks[i]<>nil)
|
else RemoveBreakPoint(BreakPtMark);
|
||||||
and (AllMarks[i].ImageIndex=TSrcEditMarkerImgIndex[semActiveBreakPoint]) then
|
|
||||||
begin
|
|
||||||
BreakPtMark:=AllMarks[i];
|
|
||||||
break;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
if BreakPtMark<>nil then begin
|
|
||||||
// delete breakpoint
|
|
||||||
if Assigned(FOnDeleteBreakPoint) then FOnDeleteBreakPoint(Self,Line);
|
|
||||||
fEditor.Marks.Remove(BreakPtMark);
|
|
||||||
BreakPtMark.Free;
|
|
||||||
fModified:=true;
|
|
||||||
end else begin
|
|
||||||
// create breakpoint
|
|
||||||
BreakPtMark:=TSynEditMark.Create(fEditor);
|
|
||||||
with BreakPtMark do begin
|
|
||||||
ImageIndex:=TSrcEditMarkerImgIndex[semActiveBreakPoint];
|
|
||||||
Visible:=true;
|
|
||||||
end;
|
|
||||||
BreakPtMark.Line:=Line;
|
|
||||||
fEditor.Marks.Place(BreakPtMark);
|
|
||||||
if Assigned(FOnCreateBreakPoint) then FOnCreateBreakPoint(Self,Line);
|
|
||||||
fModified:=true;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSourceEditor.OnEditorSpecialLineColor(Sender: TObject; Line: integer;
|
procedure TSourceEditor.OnEditorSpecialLineColor(Sender: TObject; Line: integer;
|
||||||
var Special: boolean; var FG, BG: TColor);
|
var Special: boolean; var FG, BG: TColor);
|
||||||
var i:integer;
|
var
|
||||||
|
i:integer;
|
||||||
AllMarks: TSynEditMarks;
|
AllMarks: TSynEditMarks;
|
||||||
|
aha: TAdditionalHilightAttribute;
|
||||||
begin
|
begin
|
||||||
if ErrorLine=Line then begin
|
aha := ahaNone;
|
||||||
EditorOpts.GetSpecialLineColors(TCustomSynEdit(Sender).Highlighter,
|
|
||||||
ahaErrorLine,FG,BG);
|
if ErrorLine = Line
|
||||||
Special:=true;
|
then begin
|
||||||
end else if ExecutionLine=Line then begin
|
aha := ahaErrorLine
|
||||||
EditorOpts.GetSpecialLineColors(TCustomSynEdit(Sender).Highlighter,
|
end
|
||||||
ahaExecutionPoint,FG,BG);
|
else if ExecutionLine = Line
|
||||||
Special:=true;
|
then begin
|
||||||
end else begin
|
aha := ahaExecutionPoint;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
fEditor.Marks.GetMarksForLine(Line, AllMarks);
|
fEditor.Marks.GetMarksForLine(Line, AllMarks);
|
||||||
for i:=1 to maxMarks do begin
|
for i := 1 to maxMarks do
|
||||||
if (AllMarks[i]<>nil) then begin
|
begin
|
||||||
if (AllMarks[i].ImageIndex=TSrcEditMarkerImgIndex[semActiveBreakPoint])
|
if (AllMarks[i] <> nil)
|
||||||
then begin
|
then begin
|
||||||
EditorOpts.GetSpecialLineColors(TCustomSynEdit(Sender).Highlighter,
|
if AllMarks[i].ImageIndex = SRCEDITMARKERIMGINDEX[semActiveBreakPoint]
|
||||||
ahaEnabledBreakpoint,FG,BG);
|
then aha := ahaEnabledBreakpoint
|
||||||
Special:=true;
|
else if AllMarks[i].ImageIndex = SRCEDITMARKERIMGINDEX[semInactiveBreakPoint]
|
||||||
exit;
|
then aha := ahaDisabledBreakpoint
|
||||||
end else if
|
else if AllMarks[i].ImageIndex = SRCEDITMARKERIMGINDEX[semInvalidBreakPoint]
|
||||||
(AllMarks[i].ImageIndex=TSrcEditMarkerImgIndex[semInactiveBreakPoint])
|
then aha := ahaInvalidBreakpoint
|
||||||
then begin
|
else Continue;
|
||||||
EditorOpts.GetSpecialLineColors(TCustomSynEdit(Sender).Highlighter,
|
Break;
|
||||||
ahaDisabledBreakpoint,FG,BG);
|
|
||||||
Special:=true;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
if aha <> ahaNone
|
||||||
|
then begin
|
||||||
|
EditorOpts.GetSpecialLineColors(TCustomSynEdit(Sender).Highlighter, aha, FG, BG);
|
||||||
|
Special := True;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSourceEditor.SetSyntaxHighlighterType(
|
procedure TSourceEditor.SetSyntaxHighlighterType(
|
||||||
@ -1606,6 +1650,12 @@ begin
|
|||||||
if not LoadPixmapRes('InactiveBreakPoint',Pixmap1) then
|
if not LoadPixmapRes('InactiveBreakPoint',Pixmap1) then
|
||||||
LoadPixmapRes('default',Pixmap1);
|
LoadPixmapRes('default',Pixmap1);
|
||||||
MarksImgList.Add(Pixmap1,nil);
|
MarksImgList.Add(Pixmap1,nil);
|
||||||
|
// load invalid breakpoint image
|
||||||
|
Pixmap1:=TPixMap.Create;
|
||||||
|
Pixmap1.TransparentColor:=clBtnFace;
|
||||||
|
if not LoadPixmapRes('InvalidBreakPoint',Pixmap1) then
|
||||||
|
LoadPixmapRes('default',Pixmap1);
|
||||||
|
MarksImgList.Add(Pixmap1,nil);
|
||||||
|
|
||||||
FKeyStrokes:=TSynEditKeyStrokes.Create(Self);
|
FKeyStrokes:=TSynEditKeyStrokes.Create(Self);
|
||||||
EditorOpts.KeyMap.AssignTo(FKeyStrokes);
|
EditorOpts.KeyMap.AssignTo(FKeyStrokes);
|
||||||
|
@ -1,10 +1,26 @@
|
|||||||
LazarusResources.Add('ActiveBreakPoint','XPM',
|
LazarusResources.Add('ActiveBreakPoint','XPM',
|
||||||
'/* XPM */'#10'static char * ActiveBreakPoint_xpm[] = {'#10'"11 11 3 1",'
|
'/* XPM */'#10'static char * ActiveBreakPoint_xpm[] = {'#10'"11 11 5 1",'
|
||||||
+#10'" '#9'c None",'#10'".'#9'c #000000",'#10'"+'#9'c #FF0000",'#10'" ..'
|
+#10'" '#9'c None",'#10'".'#9'c #000000",'#10'"+'#9'c #FF0000",'#10'"@'#9
|
||||||
|
+'c #00FF00",'#10'"#'#9'c #008000",'#10'" ..... ",'#10'" .+++++. ",'
|
||||||
|
+#10'" .+++++@#. ",'#10'".++++++@#+.",'#10'".+++++@#++.",'#10'".+++++@#++.'
|
||||||
|
+'",'#10'".+@++@#+++.",'#10'".++@+@#+++.",'#10'" .++@#+++. ",'#10'" .++++'
|
||||||
|
+'+. ",'#10'" ..... "};'#10
|
||||||
|
);
|
||||||
|
LazarusResources.Add('InactiveBreakPoint','XPM',
|
||||||
|
'/* XPM */'#10'static char * InactiveBreakPoint_xpm[] = {'#10'"11 11 3 1",'
|
||||||
|
+#10'" '#9'c None",'#10'".'#9'c #000000",'#10'"+'#9'c #0DA500",'#10'" ..'
|
||||||
+'... ",'#10'" .+++++. ",'#10'" .+++++++. ",'#10'".+++++++++.",'#10'".'
|
+'... ",'#10'" .+++++. ",'#10'" .+++++++. ",'#10'".+++++++++.",'#10'".'
|
||||||
+'+++++++++.",'#10'".+++++++++.",'#10'".+++++++++.",'#10'".+++++++++.",'#10
|
+'+++++++++.",'#10'".+++++++++.",'#10'".+++++++++.",'#10'".+++++++++.",'#10
|
||||||
+'" .+++++++. ",'#10'" .+++++. ",'#10'" ..... "};'#10
|
+'" .+++++++. ",'#10'" .+++++. ",'#10'" ..... "};'#10
|
||||||
);
|
);
|
||||||
|
LazarusResources.Add('InvalidBreakPoint','XPM',
|
||||||
|
'/* XPM */'#10'static char * InvalidBreakPoint_xpm[] = {'#10'"11 11 5 1",'
|
||||||
|
+#10'" '#9'c None",'#10'".'#9'c #000000",'#10'"+'#9'c #FF0000",'#10'"@'#9
|
||||||
|
+'c #FF0400",'#10'"#'#9'c #FFFF00",'#10'" ..... ",'#10'" .+++++. ",'
|
||||||
|
+#10'" .++++++@. ",'#10'".++#+++#@+.",'#10'".+++###@++.",'#10'".++++#@@++.'
|
||||||
|
+'",'#10'".+@+###+++.",'#10'".++#+@@#++.",'#10'" .++@@+++. ",'#10'" .++++'
|
||||||
|
+'+. ",'#10'" ..... "};'#10
|
||||||
|
);
|
||||||
LazarusResources.Add('bookmark0','XPM',
|
LazarusResources.Add('bookmark0','XPM',
|
||||||
'/* XPM */'#10'static char * bookmark0_xpm[] = {'#10'"11 11 12 1",'#10'" '
|
'/* XPM */'#10'static char * bookmark0_xpm[] = {'#10'"11 11 12 1",'#10'" '
|
||||||
+#9'c None",'#10'".'#9'c #000000",'#10'"+'#9'c #336041",'#10'"@'#9'c #5F82'
|
+#9'c None",'#10'".'#9'c #000000",'#10'"+'#9'c #336041",'#10'"@'#9'c #5F82'
|
||||||
@ -105,10 +121,3 @@
|
|||||||
+'++.",'#10'".++%=&=&++.",'#10'".++;;+@*++.",'#10'" .+;&&&-+. ",'#10'" .+'
|
+'++.",'#10'".++%=&=&++.",'#10'".++;;+@*++.",'#10'" .+;&&&-+. ",'#10'" .+'
|
||||||
+'%-%+. ",'#10'" ..... "};'#10
|
+'%-%+. ",'#10'" ..... "};'#10
|
||||||
);
|
);
|
||||||
LazarusResources.Add('InactiveBreakPoint','XPM',
|
|
||||||
'/* XPM */'#10'static char * InactiveBreakPoint_xpm[] = {'#10'"11 11 3 1",'
|
|
||||||
+#10'" '#9'c None",'#10'".'#9'c #000000",'#10'"+'#9'c #0DA500",'#10'" ..'
|
|
||||||
+'... ",'#10'" .+++++. ",'#10'" .+++++++. ",'#10'".+++++++++.",'#10'".'
|
|
||||||
+'+++++++++.",'#10'".+++++++++.",'#10'".+++++++++.",'#10'".+++++++++.",'#10
|
|
||||||
+'" .+++++++. ",'#10'" .+++++. ",'#10'" ..... "};'#10
|
|
||||||
);
|
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.2 KiB |
@ -1,17 +1,19 @@
|
|||||||
/* XPM */
|
/* XPM */
|
||||||
static char * ActiveBreakPoint_xpm[] = {
|
static char * ActiveBreakPoint_xpm[] = {
|
||||||
"11 11 3 1",
|
"11 11 5 1",
|
||||||
" c None",
|
" c None",
|
||||||
". c #000000",
|
". c #000000",
|
||||||
"+ c #FF0000",
|
"+ c #FF0000",
|
||||||
|
"@ c #00FF00",
|
||||||
|
"# c #008000",
|
||||||
" ..... ",
|
" ..... ",
|
||||||
" .+++++. ",
|
" .+++++. ",
|
||||||
" .+++++++. ",
|
" .+++++@#. ",
|
||||||
".+++++++++.",
|
".++++++@#+.",
|
||||||
".+++++++++.",
|
".+++++@#++.",
|
||||||
".+++++++++.",
|
".+++++@#++.",
|
||||||
".+++++++++.",
|
".+@++@#+++.",
|
||||||
".+++++++++.",
|
".++@+@#+++.",
|
||||||
" .+++++++. ",
|
" .++@#+++. ",
|
||||||
" .+++++. ",
|
" .+++++. ",
|
||||||
" ..... "};
|
" ..... "};
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.2 KiB |
BIN
images/sourceeditor/InvalidBreakPoint.ico
Normal file
BIN
images/sourceeditor/InvalidBreakPoint.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
19
images/sourceeditor/InvalidBreakPoint.xpm
Normal file
19
images/sourceeditor/InvalidBreakPoint.xpm
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/* XPM */
|
||||||
|
static char * InvalidBreakPoint_xpm[] = {
|
||||||
|
"11 11 5 1",
|
||||||
|
" c None",
|
||||||
|
". c #000000",
|
||||||
|
"+ c #FF0000",
|
||||||
|
"@ c #FF0400",
|
||||||
|
"# c #FFFF00",
|
||||||
|
" ..... ",
|
||||||
|
" .+++++. ",
|
||||||
|
" .++++++@. ",
|
||||||
|
".++#+++#@+.",
|
||||||
|
".+++###@++.",
|
||||||
|
".++++#@@++.",
|
||||||
|
".+@+###+++.",
|
||||||
|
".++#+@@#++.",
|
||||||
|
" .++@@+++. ",
|
||||||
|
" .+++++. ",
|
||||||
|
" ..... "};
|
Loading…
Reference in New Issue
Block a user