mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-26 10:39:18 +02:00
IDE Window Layout: provide ability to store columns/rows/splitter sizes.
DBG: Watches, store column widths with IDE layout git-svn-id: trunk@33202 -
This commit is contained in:
parent
ed61ffb82a
commit
c6a5c6d837
@ -10,8 +10,6 @@ inherited WatchesDlg: TWatchesDlg
|
||||
Caption = 'Watch list'
|
||||
ClientHeight = 200
|
||||
ClientWidth = 500
|
||||
OnClose = FormClose
|
||||
OnCloseQuery = FormCloseQuery
|
||||
OnDestroy = FormDestroy
|
||||
OnShow = FormShow
|
||||
object lvWatches: TListView[0]
|
||||
|
@ -39,6 +39,7 @@ interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, LCLProc, Forms, Controls, Graphics, Dialogs, math,
|
||||
IDEWindowIntf, IDEOptionDefs,
|
||||
StdCtrls, Buttons, Menus, ComCtrls, LCLType, ActnList, IDEImagesIntf,
|
||||
EnvironmentOpts, LazarusIDEStrConsts, Debugger, DebuggerDlg, BaseDebugManager;
|
||||
|
||||
@ -95,8 +96,6 @@ type
|
||||
procedure actDisableSelectedExecute(Sender: TObject);
|
||||
procedure actEnableSelectedExecute(Sender: TObject);
|
||||
procedure actPowerExecute(Sender: TObject);
|
||||
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
|
||||
procedure FormCloseQuery(Sender: TObject; var CanClose: boolean);
|
||||
procedure FormDestroy(Sender: TObject);
|
||||
procedure FormShow(Sender: TObject);
|
||||
procedure lvWatchesDblClick(Sender: TObject);
|
||||
@ -112,7 +111,6 @@ type
|
||||
function GetWatches: TWatches;
|
||||
procedure ContextChanged(Sender: TObject);
|
||||
procedure SnapshotChanged(Sender: TObject);
|
||||
procedure SaveColumnWidths;
|
||||
private
|
||||
FWatchesInView: TWatches;
|
||||
FPowerImgIdx, FPowerImgIdxGrey: Integer;
|
||||
@ -134,6 +132,8 @@ type
|
||||
protected
|
||||
procedure DoEndUpdate; override;
|
||||
procedure DoWatchesChanged; override;
|
||||
function ColSizeGetter(AColId: Integer; var ASize: Integer): Boolean;
|
||||
procedure ColSizeSetter(AColId: Integer; ASize: Integer);
|
||||
public
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
property WatchesMonitor;
|
||||
@ -148,6 +148,25 @@ implementation
|
||||
|
||||
{$R *.lfm}
|
||||
|
||||
var
|
||||
WatchWindowCreator: TIDEWindowCreator;
|
||||
const
|
||||
COL_WATCH_EXPR = 1;
|
||||
COL_WATCH_VALUE = 2;
|
||||
|
||||
function WatchesDlgColSizeGetter(AForm: TCustomForm; AColId: Integer; var ASize: Integer): Boolean;
|
||||
begin
|
||||
Result := AForm is TWatchesDlg;
|
||||
if Result then
|
||||
Result := TWatchesDlg(AForm).ColSizeGetter(AColId, ASize);
|
||||
end;
|
||||
|
||||
procedure WatchesDlgColSizeSetter(AForm: TCustomForm; AColId: Integer; ASize: Integer);
|
||||
begin
|
||||
if AForm is TWatchesDlg then
|
||||
TWatchesDlg(AForm).ColSizeSetter(AColId, ASize);
|
||||
end;
|
||||
|
||||
{ TWatchesDlg }
|
||||
|
||||
constructor TWatchesDlg.Create(AOwner: TComponent);
|
||||
@ -351,27 +370,8 @@ begin
|
||||
end;
|
||||
|
||||
procedure TWatchesDlg.FormShow(Sender: TObject);
|
||||
var
|
||||
Conf: TDebuggerWatchesDlgConfig;
|
||||
begin
|
||||
UpdateAll;
|
||||
Conf := EnvironmentOptions.DebuggerConfig.DlgWatchesConfig;
|
||||
if Conf.ColumnNameWidth > 0 then
|
||||
lvWatches.Column[0].Width := Conf.ColumnNameWidth;
|
||||
if Conf.ColumnValueWidth > 0 then
|
||||
lvWatches.Column[1].Width := Conf.ColumnValueWidth;
|
||||
end;
|
||||
|
||||
procedure TWatchesDlg.FormCloseQuery(Sender: TObject; var CanClose: boolean);
|
||||
begin
|
||||
//DebugLn('TWatchesDlg.FormCloseQuery ',dbgs(CanClose));
|
||||
SaveColumnWidths;
|
||||
end;
|
||||
|
||||
procedure TWatchesDlg.FormClose(Sender: TObject; var CloseAction: TCloseAction);
|
||||
begin
|
||||
//DebugLn('TWatchesDlg.FormClose ',dbgs(ord(CloseAction)));
|
||||
SaveColumnWidths;
|
||||
end;
|
||||
|
||||
procedure TWatchesDlg.actPowerExecute(Sender: TObject);
|
||||
@ -485,15 +485,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TWatchesDlg.SaveColumnWidths;
|
||||
var
|
||||
Conf: TDebuggerWatchesDlgConfig;
|
||||
begin
|
||||
Conf := EnvironmentOptions.DebuggerConfig.DlgWatchesConfig;
|
||||
Conf.ColumnNameWidth := lvWatches.Column[0].Width;
|
||||
Conf.ColumnValueWidth := lvWatches.Column[1].Width;
|
||||
end;
|
||||
|
||||
function TWatchesDlg.GetWatches: TWatches;
|
||||
var
|
||||
Snap: TSnapshot;
|
||||
@ -522,6 +513,25 @@ begin
|
||||
UpdateAll;
|
||||
end;
|
||||
|
||||
function TWatchesDlg.ColSizeGetter(AColId: Integer; var ASize: Integer): Boolean;
|
||||
begin
|
||||
Result := True;
|
||||
case AColId of
|
||||
COL_WATCH_EXPR: ASize := lvWatches.Column[0].Width;
|
||||
COL_WATCH_VALUE: ASize := lvWatches.Column[1].Width;
|
||||
else
|
||||
Result := False;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TWatchesDlg.ColSizeSetter(AColId: Integer; ASize: Integer);
|
||||
begin
|
||||
case AColId of
|
||||
COL_WATCH_EXPR: lvWatches.Column[0].Width := ASize;
|
||||
COL_WATCH_VALUE: lvWatches.Column[1].Width := ASize;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TWatchesDlg.popDeleteClick(Sender: TObject);
|
||||
var
|
||||
Item: TCurrentWatch;
|
||||
@ -751,5 +761,13 @@ begin
|
||||
lvWatchesSelectItem(nil, nil, False);
|
||||
end;
|
||||
|
||||
initialization
|
||||
|
||||
WatchWindowCreator := IDEWindowCreators.Add(NonModalIDEWindowNames[nmiwWatches]);
|
||||
WatchWindowCreator.OnSetDividerSize := @WatchesDlgColSizeSetter;
|
||||
WatchWindowCreator.OnGetDividerSize := @WatchesDlgColSizeGetter;
|
||||
WatchWindowCreator.DividerTemplate.Add('ColumnWatchExpr', COL_WATCH_EXPR, dbgLCWatchExpression);
|
||||
WatchWindowCreator.DividerTemplate.Add('ColumnWatchValue', COL_WATCH_VALUE, dbgLCWatchValue);
|
||||
|
||||
end.
|
||||
|
||||
|
@ -1682,8 +1682,9 @@ begin
|
||||
end;
|
||||
|
||||
for DlgType:=Low(TDebugDialogType) to High(TDebugDialogType) do
|
||||
IDEWindowCreators.Add(NonModalIDEWindowNames[DebugDlgIDEWindow[DlgType]],
|
||||
nil,@CreateDebugDialog,'','','','');
|
||||
if not (DlgType in [ddtWatches]) then
|
||||
IDEWindowCreators.Add(NonModalIDEWindowNames[DebugDlgIDEWindow[DlgType]],
|
||||
nil,@CreateDebugDialog,'','','','');
|
||||
end;
|
||||
|
||||
procedure TDebugManager.ConnectSourceNotebookEvents;
|
||||
|
@ -54,7 +54,7 @@ inherited WindowOptionsFrame: TWindowOptionsFrame
|
||||
AnchorSideTop.Side = asrCenter
|
||||
Left = 6
|
||||
Height = 3
|
||||
Top = 168
|
||||
Top = 139
|
||||
Width = 50
|
||||
BorderSpacing.Left = 6
|
||||
end
|
||||
@ -67,7 +67,7 @@ inherited WindowOptionsFrame: TWindowOptionsFrame
|
||||
AnchorSideRight.Side = asrBottom
|
||||
Left = 178
|
||||
Height = 3
|
||||
Top = 168
|
||||
Top = 139
|
||||
Width = 378
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
BorderSpacing.Left = 6
|
||||
@ -79,7 +79,7 @@ inherited WindowOptionsFrame: TWindowOptionsFrame
|
||||
AnchorSideTop.Side = asrBottom
|
||||
Left = 70
|
||||
Height = 16
|
||||
Top = 161
|
||||
Top = 132
|
||||
Width = 102
|
||||
BorderSpacing.Left = 70
|
||||
BorderSpacing.Top = 6
|
||||
@ -94,7 +94,7 @@ inherited WindowOptionsFrame: TWindowOptionsFrame
|
||||
AnchorSideRight.Control = LeftEdit
|
||||
Left = 294
|
||||
Height = 16
|
||||
Top = 186
|
||||
Top = 218
|
||||
Width = 49
|
||||
Anchors = [akTop, akRight]
|
||||
BorderSpacing.Right = 3
|
||||
@ -107,7 +107,7 @@ inherited WindowOptionsFrame: TWindowOptionsFrame
|
||||
AnchorSideRight.Control = TopEdit
|
||||
Left = 293
|
||||
Height = 16
|
||||
Top = 215
|
||||
Top = 247
|
||||
Width = 50
|
||||
Anchors = [akTop, akRight]
|
||||
BorderSpacing.Right = 3
|
||||
@ -120,7 +120,7 @@ inherited WindowOptionsFrame: TWindowOptionsFrame
|
||||
AnchorSideRight.Control = WidthEdit
|
||||
Left = 417
|
||||
Height = 16
|
||||
Top = 186
|
||||
Top = 218
|
||||
Width = 61
|
||||
Anchors = [akTop, akRight]
|
||||
BorderSpacing.Right = 3
|
||||
@ -133,7 +133,7 @@ inherited WindowOptionsFrame: TWindowOptionsFrame
|
||||
AnchorSideRight.Control = HeightEdit
|
||||
Left = 413
|
||||
Height = 16
|
||||
Top = 215
|
||||
Top = 247
|
||||
Width = 65
|
||||
Anchors = [akTop, akRight]
|
||||
BorderSpacing.Right = 3
|
||||
@ -146,7 +146,7 @@ inherited WindowOptionsFrame: TWindowOptionsFrame
|
||||
AnchorSideRight.Control = WindowPositionsGroupBox
|
||||
AnchorSideRight.Side = asrBottom
|
||||
Left = 6
|
||||
Height = 149
|
||||
Height = 120
|
||||
Top = 6
|
||||
Width = 550
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
@ -157,11 +157,11 @@ inherited WindowOptionsFrame: TWindowOptionsFrame
|
||||
end
|
||||
object UseWindowManagerSettingRadioButton: TRadioButton
|
||||
AnchorSideLeft.Control = WindowPositionsGroupBox
|
||||
AnchorSideTop.Control = lblWindowCaption
|
||||
AnchorSideTop.Control = SplitterPanel
|
||||
AnchorSideTop.Side = asrBottom
|
||||
Left = 6
|
||||
Height = 19
|
||||
Top = 183
|
||||
Top = 215
|
||||
Width = 233
|
||||
BorderSpacing.Around = 6
|
||||
Caption = 'UseWindowManagerSettingRadioButton'
|
||||
@ -175,7 +175,7 @@ inherited WindowOptionsFrame: TWindowOptionsFrame
|
||||
AnchorSideTop.Side = asrBottom
|
||||
Left = 6
|
||||
Height = 19
|
||||
Top = 208
|
||||
Top = 240
|
||||
Width = 124
|
||||
BorderSpacing.Around = 6
|
||||
Caption = 'DefaultRadioButton'
|
||||
@ -187,7 +187,7 @@ inherited WindowOptionsFrame: TWindowOptionsFrame
|
||||
AnchorSideTop.Side = asrBottom
|
||||
Left = 6
|
||||
Height = 19
|
||||
Top = 233
|
||||
Top = 265
|
||||
Width = 221
|
||||
BorderSpacing.Around = 6
|
||||
Caption = 'RestoreWindowGeometryRadioButton'
|
||||
@ -199,19 +199,19 @@ inherited WindowOptionsFrame: TWindowOptionsFrame
|
||||
AnchorSideTop.Side = asrBottom
|
||||
Left = 6
|
||||
Height = 19
|
||||
Top = 258
|
||||
Top = 290
|
||||
Width = 171
|
||||
BorderSpacing.Around = 6
|
||||
Caption = 'CustomPositionRadioButton'
|
||||
TabOrder = 4
|
||||
end
|
||||
object LeftEdit: TSpinEdit
|
||||
AnchorSideTop.Control = lblWindowCaption
|
||||
AnchorSideTop.Control = SplitterPanel
|
||||
AnchorSideTop.Side = asrBottom
|
||||
AnchorSideRight.Control = WidthEdit
|
||||
Left = 346
|
||||
Height = 23
|
||||
Top = 183
|
||||
Top = 215
|
||||
Width = 75
|
||||
Anchors = [akTop, akRight]
|
||||
BorderSpacing.Top = 6
|
||||
@ -226,7 +226,7 @@ inherited WindowOptionsFrame: TWindowOptionsFrame
|
||||
AnchorSideRight.Control = HeightEdit
|
||||
Left = 346
|
||||
Height = 23
|
||||
Top = 212
|
||||
Top = 244
|
||||
Width = 75
|
||||
Anchors = [akTop, akRight]
|
||||
BorderSpacing.Top = 6
|
||||
@ -236,13 +236,13 @@ inherited WindowOptionsFrame: TWindowOptionsFrame
|
||||
TabOrder = 6
|
||||
end
|
||||
object WidthEdit: TSpinEdit
|
||||
AnchorSideTop.Control = lblWindowCaption
|
||||
AnchorSideTop.Control = SplitterPanel
|
||||
AnchorSideTop.Side = asrBottom
|
||||
AnchorSideRight.Control = WindowPositionsGroupBox
|
||||
AnchorSideRight.Side = asrBottom
|
||||
Left = 481
|
||||
Height = 23
|
||||
Top = 183
|
||||
Top = 215
|
||||
Width = 75
|
||||
Anchors = [akTop, akRight]
|
||||
BorderSpacing.Top = 6
|
||||
@ -257,7 +257,7 @@ inherited WindowOptionsFrame: TWindowOptionsFrame
|
||||
AnchorSideRight.Side = asrBottom
|
||||
Left = 481
|
||||
Height = 23
|
||||
Top = 212
|
||||
Top = 244
|
||||
Width = 75
|
||||
Anchors = [akTop, akRight]
|
||||
BorderSpacing.Top = 6
|
||||
@ -271,7 +271,7 @@ inherited WindowOptionsFrame: TWindowOptionsFrame
|
||||
AnchorSideRight.Control = ApplyButton
|
||||
Left = 290
|
||||
Height = 25
|
||||
Top = 241
|
||||
Top = 273
|
||||
Width = 167
|
||||
Anchors = [akTop, akRight]
|
||||
AutoSize = True
|
||||
@ -288,7 +288,7 @@ inherited WindowOptionsFrame: TWindowOptionsFrame
|
||||
AnchorSideRight.Side = asrBottom
|
||||
Left = 463
|
||||
Height = 25
|
||||
Top = 241
|
||||
Top = 273
|
||||
Width = 93
|
||||
Anchors = [akTop, akRight]
|
||||
AutoSize = True
|
||||
@ -298,6 +298,84 @@ inherited WindowOptionsFrame: TWindowOptionsFrame
|
||||
OnClick = ApplyButtonClick
|
||||
TabOrder = 10
|
||||
end
|
||||
object SplitterPanel: TPanel
|
||||
AnchorSideLeft.Control = WindowPositionsGroupBox
|
||||
AnchorSideTop.Control = lblWindowCaption
|
||||
AnchorSideTop.Side = asrBottom
|
||||
AnchorSideRight.Control = WindowPositionsGroupBox
|
||||
AnchorSideRight.Side = asrBottom
|
||||
AnchorSideBottom.Control = WindowPositionsGroupBox
|
||||
AnchorSideBottom.Side = asrBottom
|
||||
Left = 4
|
||||
Height = 57
|
||||
Top = 152
|
||||
Width = 554
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
BorderSpacing.Around = 4
|
||||
BevelOuter = bvNone
|
||||
BorderWidth = 1
|
||||
BorderStyle = bsSingle
|
||||
Caption = ' '
|
||||
ClientHeight = 53
|
||||
ClientWidth = 550
|
||||
TabOrder = 11
|
||||
Visible = False
|
||||
object SplitterList: TListBox
|
||||
AnchorSideLeft.Control = SplitterPanel
|
||||
AnchorSideTop.Control = SplitterPanel
|
||||
AnchorSideBottom.Control = SplitterPanel
|
||||
AnchorSideBottom.Side = asrBottom
|
||||
Left = 1
|
||||
Height = 51
|
||||
Top = 1
|
||||
Width = 275
|
||||
Anchors = [akTop, akLeft, akBottom]
|
||||
ItemHeight = 0
|
||||
OnSelectionChange = SplitterListSelectionChange
|
||||
TabOrder = 0
|
||||
end
|
||||
object SplitLabel: TLabel
|
||||
AnchorSideTop.Control = SplitEdit
|
||||
AnchorSideTop.Side = asrCenter
|
||||
AnchorSideRight.Control = SplitEdit
|
||||
Left = 422
|
||||
Height = 16
|
||||
Top = 32
|
||||
Width = 52
|
||||
Anchors = [akTop, akRight]
|
||||
Caption = 'SplitLabel'
|
||||
ParentColor = False
|
||||
end
|
||||
object SplitEdit: TSpinEdit
|
||||
AnchorSideRight.Control = SplitterPanel
|
||||
AnchorSideRight.Side = asrBottom
|
||||
AnchorSideBottom.Control = SplitterPanel
|
||||
AnchorSideBottom.Side = asrBottom
|
||||
Left = 474
|
||||
Height = 23
|
||||
Top = 29
|
||||
Width = 75
|
||||
Anchors = [akRight, akBottom]
|
||||
MaxValue = 5000
|
||||
TabOrder = 1
|
||||
end
|
||||
object dropSplitterPlacement: TComboBox
|
||||
AnchorSideLeft.Control = SplitterList
|
||||
AnchorSideLeft.Side = asrBottom
|
||||
AnchorSideTop.Control = SplitterPanel
|
||||
AnchorSideRight.Control = SplitterPanel
|
||||
AnchorSideRight.Side = asrBottom
|
||||
Left = 282
|
||||
Height = 23
|
||||
Top = 1
|
||||
Width = 267
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
BorderSpacing.Left = 6
|
||||
ItemHeight = 15
|
||||
Style = csDropDownList
|
||||
TabOrder = 2
|
||||
end
|
||||
end
|
||||
end
|
||||
object HideMessagesIconsCheckBox: TCheckBox[3]
|
||||
AnchorSideLeft.Control = Owner
|
||||
|
@ -38,6 +38,7 @@ type
|
||||
ApplyButton: TButton;
|
||||
Bevel1: TBevel;
|
||||
Bevel2: TBevel;
|
||||
dropSplitterPlacement: TComboBox;
|
||||
CustomPositionRadioButton: TRadioButton;
|
||||
DefaultRadioButton: TRadioButton;
|
||||
GetWindowPositionButton: TButton;
|
||||
@ -45,11 +46,15 @@ type
|
||||
HeightLabel: TLabel;
|
||||
HideIDEOnRunCheckBox: TCheckBox;
|
||||
HideMessagesIconsCheckBox: TCheckBox;
|
||||
SplitLabel: TLabel;
|
||||
lblWindowCaption: TLabel;
|
||||
LeftEdit: TSpinEdit;
|
||||
LeftLabel: TLabel;
|
||||
SplitterList: TListBox;
|
||||
SplitterPanel: TPanel;
|
||||
SingleTaskBarButtonCheckBox: TCheckBox;
|
||||
RestoreWindowGeometryRadioButton: TRadioButton;
|
||||
SplitEdit: TSpinEdit;
|
||||
TitleStartsWithProjectCheckBox: TCheckBox;
|
||||
ProjectDirInIdeTitleCheckBox: TCheckBox;
|
||||
TopEdit: TSpinEdit;
|
||||
@ -61,17 +66,22 @@ type
|
||||
WindowPositionsListBox: TListBox;
|
||||
procedure ApplyButtonClick(Sender: TObject);
|
||||
procedure GetWindowPositionButtonClick(Sender: TObject);
|
||||
procedure SplitterListSelectionChange(Sender: TObject; User: boolean);
|
||||
procedure WindowPositionsListBoxSelectionChange(Sender: TObject; User: boolean);
|
||||
private
|
||||
FLayouts: TSimpleWindowLayoutList;
|
||||
FLayout: TSimpleWindowLayout;
|
||||
FDivider: TSimpleWindowLayoutDividerPos;
|
||||
FShowSimpleLayout: boolean;
|
||||
function GetPlacementRadioButtons(APlacement: TIDEWindowPlacement): TRadioButton;
|
||||
procedure SetLayout(const AValue: TSimpleWindowLayout);
|
||||
procedure SetDivider(const AValue: TSimpleWindowLayoutDividerPos);
|
||||
procedure SetWindowPositionsItem(Index: integer);
|
||||
procedure SaveCurrentSplitterLayout;
|
||||
procedure SaveLayout;
|
||||
function GetLayoutCaption(ALayout: TSimpleWindowLayout): String;
|
||||
property Layout: TSimpleWindowLayout read FLayout write SetLayout;
|
||||
property Divider: TSimpleWindowLayoutDividerPos read FDivider write SetDivider;
|
||||
public
|
||||
constructor Create(TheOwner: TComponent); override;
|
||||
destructor Destroy; override;
|
||||
@ -144,6 +154,7 @@ begin
|
||||
WindowPositionsListBox.Items.AddObject(GetLayoutCaption(FLayouts[j]),FLayouts[j]);
|
||||
end;
|
||||
end;
|
||||
//WindowPositionsListBox.Sorted := True;
|
||||
WindowPositionsListBox.Items.EndUpdate;
|
||||
|
||||
LeftLabel.Caption := dlgLeftPos;
|
||||
@ -152,12 +163,19 @@ begin
|
||||
HeightLabel.Caption := DlgHeightPos;
|
||||
ApplyButton.Caption := dlgButApply;
|
||||
GetWindowPositionButton.Caption := dlgGetPosition;
|
||||
SplitLabel.Caption := dlgWidthPos;
|
||||
|
||||
UseWindowManagerSettingRadioButton.Caption := rsiwpUseWindowManagerSetting;
|
||||
DefaultRadioButton.Caption := rsiwpDefault;
|
||||
RestoreWindowGeometryRadioButton.Caption := rsiwpRestoreWindowGeometry;
|
||||
CustomPositionRadioButton.Caption := rsiwpCustomPosition;
|
||||
|
||||
dropSplitterPlacement.Clear;
|
||||
dropSplitterPlacement.Items.Add(rsiwpSplitterFollowWindow);
|
||||
dropSplitterPlacement.Items.Add(rsiwpSplitterDefault);
|
||||
dropSplitterPlacement.Items.Add(rsiwpSplitterRestoreWindowGeometry);
|
||||
dropSplitterPlacement.Items.Add(rsiwpSplitterCustomPosition);
|
||||
|
||||
SetWindowPositionsItem(0);
|
||||
end else begin
|
||||
WindowPositionsGroupBox.Parent:=nil;
|
||||
@ -198,9 +216,14 @@ var
|
||||
APlacement: TIDEWindowPlacement;
|
||||
RadioButton: TRadioButton;
|
||||
p: TPoint;
|
||||
i: Integer;
|
||||
begin
|
||||
FLayout := AValue;
|
||||
if Layout=nil then Exit;
|
||||
Divider := nil;
|
||||
if Layout=nil then begin
|
||||
SplitterPanel.Visible := False;
|
||||
Exit;
|
||||
end;
|
||||
//debugln(['TWindowOptionsFrame.SetLayout ',Layout.FormID,' ',IDEWindowPlacementNames[Layout.WindowPlacement]]);
|
||||
|
||||
for APlacement := Low(TIDEWindowPlacement) to High(TIDEWindowPlacement) do
|
||||
@ -242,6 +265,27 @@ begin
|
||||
end;
|
||||
|
||||
GetWindowPositionButton.Enabled := (Layout.Form <> nil);
|
||||
|
||||
SplitterPanel.Visible := Layout.Dividers.NamedCount > 0;
|
||||
SplitterList.Clear;
|
||||
for i := 0 to Layout.Dividers.NamedCount - 1 do
|
||||
SplitterList.AddItem(Layout.Dividers.NamedItems[i].DisplayName, Layout.Dividers.NamedItems[i]);
|
||||
if Layout.Dividers.NamedCount > 0 then
|
||||
SplitterList.ItemIndex := 0;
|
||||
end;
|
||||
|
||||
procedure TWindowOptionsFrame.SetDivider(const AValue: TSimpleWindowLayoutDividerPos);
|
||||
begin
|
||||
FDivider := AValue;
|
||||
if FDivider=nil then exit;
|
||||
|
||||
SplitEdit.Value := FDivider.Size;
|
||||
case FDivider.Placement of
|
||||
iwpdUseWindowSetting: dropSplitterPlacement.ItemIndex := 0;
|
||||
iwpdDefault: dropSplitterPlacement.ItemIndex := 1;
|
||||
iwpdRestore: dropSplitterPlacement.ItemIndex := 2;
|
||||
iwpdCustomSize: dropSplitterPlacement.ItemIndex := 3;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TWindowOptionsFrame.WindowPositionsListBoxSelectionChange(
|
||||
@ -257,29 +301,32 @@ var
|
||||
begin
|
||||
SaveLayout;
|
||||
if (Layout<>nil) and (Layout.Form<>nil) and (Layout.Form.Parent=nil)
|
||||
and (Layout.WindowPlacement in [iwpCustomPosition,iwpRestoreWindowGeometry])
|
||||
then begin
|
||||
if (Layout.CustomCoordinatesAreValid) then begin
|
||||
// explicit position
|
||||
NewBounds:=Bounds(Layout.Left,Layout.Top,Layout.Width,Layout.Height);
|
||||
// set minimum size
|
||||
if NewBounds.Right-NewBounds.Left<20 then
|
||||
NewBounds.Right:=NewBounds.Left+20;
|
||||
if NewBounds.Bottom-NewBounds.Top<20 then
|
||||
NewBounds.Bottom:=NewBounds.Top+20;
|
||||
// move to visible area
|
||||
if NewBounds.Right<20 then
|
||||
OffsetRect(NewBounds,20-NewBounds.Right,0);
|
||||
if NewBounds.Bottom<20 then
|
||||
OffsetRect(NewBounds,0,20-NewBounds.Bottom);
|
||||
if NewBounds.Left>Screen.DesktopWidth-20 then
|
||||
OffsetRect(NewBounds,NewBounds.Left-(Screen.DesktopWidth-20),0);
|
||||
if NewBounds.Top>Screen.DesktopHeight-20 then
|
||||
OffsetRect(NewBounds,NewBounds.Top-(Screen.DesktopHeight-20),0);
|
||||
Layout.Form.SetBounds(
|
||||
NewBounds.Left,NewBounds.Top,
|
||||
NewBounds.Right-NewBounds.Left,NewBounds.Bottom-NewBounds.Top);
|
||||
if (Layout.WindowPlacement in [iwpCustomPosition,iwpRestoreWindowGeometry])
|
||||
then begin
|
||||
if (Layout.CustomCoordinatesAreValid) then begin
|
||||
// explicit position
|
||||
NewBounds:=Bounds(Layout.Left,Layout.Top,Layout.Width,Layout.Height);
|
||||
// set minimum size
|
||||
if NewBounds.Right-NewBounds.Left<20 then
|
||||
NewBounds.Right:=NewBounds.Left+20;
|
||||
if NewBounds.Bottom-NewBounds.Top<20 then
|
||||
NewBounds.Bottom:=NewBounds.Top+20;
|
||||
// move to visible area
|
||||
if NewBounds.Right<20 then
|
||||
OffsetRect(NewBounds,20-NewBounds.Right,0);
|
||||
if NewBounds.Bottom<20 then
|
||||
OffsetRect(NewBounds,0,20-NewBounds.Bottom);
|
||||
if NewBounds.Left>Screen.DesktopWidth-20 then
|
||||
OffsetRect(NewBounds,NewBounds.Left-(Screen.DesktopWidth-20),0);
|
||||
if NewBounds.Top>Screen.DesktopHeight-20 then
|
||||
OffsetRect(NewBounds,NewBounds.Top-(Screen.DesktopHeight-20),0);
|
||||
Layout.Form.SetBounds(
|
||||
NewBounds.Left,NewBounds.Top,
|
||||
NewBounds.Right-NewBounds.Left,NewBounds.Bottom-NewBounds.Top);
|
||||
end;
|
||||
end;
|
||||
Layout.ApplyDivider(True);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -292,6 +339,16 @@ begin
|
||||
WidthEdit.Value := Layout.Form.Width;
|
||||
HeightEdit.Value := Layout.Form.Height;
|
||||
end;
|
||||
Layout.ReadCurrentDividers(True);
|
||||
SplitterListSelectionChange(nil, False);
|
||||
end;
|
||||
|
||||
procedure TWindowOptionsFrame.SplitterListSelectionChange(Sender: TObject; User: boolean);
|
||||
begin
|
||||
if User then SaveCurrentSplitterLayout;
|
||||
|
||||
if (SplitterList.Count = 0) or (SplitterList.ItemIndex < 0) then exit;
|
||||
SetDivider(TSimpleWindowLayoutDividerPos(SplitterList.Items.Objects[SplitterList.ItemIndex]));
|
||||
end;
|
||||
|
||||
procedure TWindowOptionsFrame.SetWindowPositionsItem(Index: integer);
|
||||
@ -308,6 +365,18 @@ begin
|
||||
lblWindowCaption.Caption := WindowPositionsListBox.Items[Index];
|
||||
end;
|
||||
|
||||
procedure TWindowOptionsFrame.SaveCurrentSplitterLayout;
|
||||
begin
|
||||
if FDivider = nil then exit;
|
||||
case dropSplitterPlacement.ItemIndex of
|
||||
0: FDivider.Placement := iwpdUseWindowSetting;
|
||||
1: FDivider.Placement := iwpdDefault;
|
||||
2: FDivider.Placement := iwpdRestore;
|
||||
3: FDivider.Placement := iwpdCustomSize;
|
||||
end;
|
||||
FDivider.Size := SplitEdit.Value;
|
||||
end;
|
||||
|
||||
procedure TWindowOptionsFrame.SaveLayout;
|
||||
var
|
||||
APlacement: TIDEWindowPlacement;
|
||||
@ -329,6 +398,7 @@ begin
|
||||
Layout.Height := HeightEdit.Value;
|
||||
end;
|
||||
end;
|
||||
SaveCurrentSplitterLayout;
|
||||
end;
|
||||
|
||||
function TWindowOptionsFrame.GetLayoutCaption(ALayout: TSimpleWindowLayout
|
||||
|
@ -2230,6 +2230,11 @@ resourcestring
|
||||
rsiwpCustomPosition = 'Custom position';
|
||||
rsiwpRestoreWindowSize = 'Restore window size';
|
||||
|
||||
rsiwpSplitterFollowWindow = 'Restore with window';
|
||||
rsiwpSplitterDefault = 'Default Size';
|
||||
rsiwpSplitterRestoreWindowGeometry = 'Restore Size';
|
||||
rsiwpSplitterCustomPosition = 'Custom Size';
|
||||
|
||||
// Code Explorer
|
||||
lisCodeExplorer = 'Code Explorer';
|
||||
lisCode = 'Code';
|
||||
@ -5366,6 +5371,8 @@ resourcestring
|
||||
lisDiscardChangesAndQuit = 'Discard changes and quit';
|
||||
dbgBreakPropertyGroupNotFound = 'Some groups in the Enable/Disable list do not exist.%0:s'
|
||||
+'Create them?%0:s%0:s%1:s';
|
||||
dbgLCWatchExpression = 'Watch Expression';
|
||||
dbgLCWatchValue = 'Watch Value';
|
||||
|
||||
|
||||
implementation
|
||||
|
@ -123,6 +123,77 @@ type
|
||||
TIDEWindowState = (iwsNormal, iwsMaximized, iwsMinimized, iwsHidden);
|
||||
TIDEWindowStates = set of TIDEWindowState;
|
||||
|
||||
TSimpleWindowLayoutDividerPosPlacement = (
|
||||
iwpdDefault, // set column/row/splitter to the default size
|
||||
iwpdCustomSize, // set column/row/splitter to the custom size
|
||||
iwpdRestore, // save column/row/splitter size on exit, and restore
|
||||
iwpdUseWindowSetting
|
||||
);
|
||||
|
||||
TSimpleWindowLayoutDividerPosSizeGetter =
|
||||
function(AForm: TCustomForm; AColId: Integer; var ASize: Integer): Boolean;
|
||||
|
||||
TSimpleWindowLayoutDividerPosSizeSetter =
|
||||
procedure(AForm: TCustomForm; AColId: Integer; ASize: Integer);
|
||||
|
||||
{ TSimpleWindowLayoutDividerPos }
|
||||
|
||||
TSimpleWindowLayoutDividerPos = class
|
||||
private
|
||||
FDefaultSize: integer;
|
||||
FDisplayName: String;
|
||||
FId: Integer;
|
||||
FIdString: String;
|
||||
FPlacement: TSimpleWindowLayoutDividerPosPlacement;
|
||||
FSize: integer;
|
||||
protected
|
||||
procedure SetDisplayName(ADisplayName: String);
|
||||
procedure SetId(AnId: Integer);
|
||||
public
|
||||
constructor Create(AnIdString: String);
|
||||
constructor Create(AnIdString: String; AnId: Integer; ADisplayName: String);
|
||||
procedure Assign(ADividerPos: TSimpleWindowLayoutDividerPos); reintroduce;
|
||||
procedure LoadFromConfig(Config: TConfigStorage; const Path: string);
|
||||
procedure SaveToConfig(Config: TConfigStorage; const Path: string);
|
||||
procedure Clear;
|
||||
property IdString: String read FIdString;
|
||||
property Id: Integer read FId;
|
||||
property DisplayName: String read FDisplayName;
|
||||
property Placement: TSimpleWindowLayoutDividerPosPlacement read FPlacement write FPlacement;
|
||||
property Size: integer read FSize write FSize;
|
||||
property DefaultSize: integer read FDefaultSize write FDefaultSize;
|
||||
end;
|
||||
|
||||
{ TSimpleWindowLayoutDividerPosList }
|
||||
|
||||
TSimpleWindowLayoutDividerPosList = class
|
||||
private
|
||||
FList: TList;
|
||||
function GetItems(Index: Integer): TSimpleWindowLayoutDividerPos;
|
||||
function GetNamedItems(Index: Integer): TSimpleWindowLayoutDividerPos;
|
||||
protected
|
||||
procedure Merge(AnItem: TSimpleWindowLayoutDividerPos);
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
procedure Assign(ADividerPosList: TSimpleWindowLayoutDividerPosList); reintroduce;
|
||||
procedure LoadFromConfig(Config: TConfigStorage; const Path: string);
|
||||
procedure SaveToConfig(Config: TConfigStorage; const Path: string);
|
||||
procedure Clear;
|
||||
procedure ClearItems;
|
||||
function Add(AnIdString: String; AnId: Integer; ADisplayName: String): TSimpleWindowLayoutDividerPos;
|
||||
function Add(AnIdString: String): TSimpleWindowLayoutDividerPos;
|
||||
function Count: Integer;
|
||||
function NamedCount: Integer;
|
||||
function Find(AnId: Integer): TSimpleWindowLayoutDividerPos;
|
||||
function Find(AnIdString: String): TSimpleWindowLayoutDividerPos;
|
||||
function IndexOf(AnId: Integer): Integer;
|
||||
function IndexOf(AnIdString: String): Integer;
|
||||
function IndexOf(AnItem: TSimpleWindowLayoutDividerPos): Integer;
|
||||
property Items[Index: Integer]: TSimpleWindowLayoutDividerPos read GetItems; default;
|
||||
property NamedItems[Index: Integer]: TSimpleWindowLayoutDividerPos read GetNamedItems;
|
||||
end;
|
||||
|
||||
{ TSimpleWindowLayout }
|
||||
|
||||
TSimpleWindowLayout = class(TComponent)
|
||||
@ -139,6 +210,7 @@ type
|
||||
fForm: TCustomForm;
|
||||
fFormID: string;
|
||||
fDefaultWindowPlacement: TIDEWindowPlacement;
|
||||
FDividers: TSimpleWindowLayoutDividerPosList;
|
||||
function GetFormCaption: string;
|
||||
function GetFormID: string;
|
||||
procedure SetForm(const AValue: TCustomForm);
|
||||
@ -148,9 +220,13 @@ type
|
||||
public
|
||||
constructor Create(AFormID: string); reintroduce;
|
||||
destructor Destroy; override;
|
||||
function CreateCopy: TSimpleWindowLayout;
|
||||
procedure Clear;
|
||||
procedure GetCurrentPosition;
|
||||
function Apply: Boolean;
|
||||
procedure ApplyDivider(AForce: Boolean = False);
|
||||
procedure Assign(Layout: TSimpleWindowLayout); reintroduce;
|
||||
procedure ReadCurrentDividers(AForce: Boolean = False);
|
||||
procedure ReadCurrentCoordinates;
|
||||
procedure ReadCurrentState;
|
||||
procedure LoadFromConfig(Config: TConfigStorage; const Path: string);
|
||||
@ -172,6 +248,7 @@ type
|
||||
property Form: TCustomForm read fForm write SetForm;
|
||||
property Visible: boolean read FVisible write FVisible;
|
||||
property Applied: boolean read FApplied write FApplied;
|
||||
property Dividers: TSimpleWindowLayoutDividerPosList read FDividers;
|
||||
end;
|
||||
|
||||
{ TSimpleWindowLayoutList }
|
||||
@ -250,10 +327,14 @@ type
|
||||
FBottom: string;
|
||||
FLeft: string;
|
||||
FMulti: boolean;
|
||||
FOnGetDividerSize: TSimpleWindowLayoutDividerPosSizeGetter;
|
||||
FOnGetLayout: TGetDefaultIDEWindowLayoutEvent;
|
||||
FOnSetDividerSize: TSimpleWindowLayoutDividerPosSizeSetter;
|
||||
FState: TIWCState;
|
||||
FTop: string;
|
||||
FRight: string;
|
||||
FDividerTemplate: TSimpleWindowLayoutDividerPosList;
|
||||
function GetDividerTemplate: TSimpleWindowLayoutDividerPosList;
|
||||
procedure SetBottom(const AValue: string);
|
||||
procedure SetLeft(const AValue: string);
|
||||
procedure SetTop(const AValue: string);
|
||||
@ -268,6 +349,7 @@ type
|
||||
aDockAlign: TAlign = alNone;
|
||||
aMulti: boolean = false;
|
||||
GetLayoutEvent: TGetDefaultIDEWindowLayoutEvent = nil); overload;
|
||||
destructor Destroy; override;
|
||||
property FormName: string read FFormName; // prefix for all forms
|
||||
property Multi: boolean read FMulti; // there can be more than one of this form, e.g. the source editors and the package editors
|
||||
property OnCreateFormMethod: TCreateIDEWindowMethod read FCreateFormMethod write FCreateFormMethod;
|
||||
@ -286,6 +368,13 @@ type
|
||||
write FOnGetLayout;
|
||||
procedure CheckBoundValue(s: string);
|
||||
procedure GetDefaultBounds(AForm: TCustomForm; out DefBounds: TRect);
|
||||
|
||||
procedure InitSimpleLayout(ALayout: TSimpleWindowLayout);
|
||||
// TODO: Need a WindowCreator factory, by class of TForm
|
||||
// then this data can be stored per window class
|
||||
property DividerTemplate: TSimpleWindowLayoutDividerPosList read GetDividerTemplate;
|
||||
property OnGetDividerSize: TSimpleWindowLayoutDividerPosSizeGetter read FOnGetDividerSize write FOnGetDividerSize;
|
||||
property OnSetDividerSize: TSimpleWindowLayoutDividerPosSizeSetter read FOnSetDividerSize write FOnSetDividerSize;
|
||||
end;
|
||||
|
||||
{ TIDEWindowCreatorList }
|
||||
@ -431,6 +520,273 @@ begin
|
||||
RegisterComponents('Misc',[TIDEDialogLayoutStorage]);
|
||||
end;
|
||||
|
||||
{ TSimpleWindowLayoutDividerPosList }
|
||||
|
||||
function TSimpleWindowLayoutDividerPosList.GetItems(Index: Integer): TSimpleWindowLayoutDividerPos;
|
||||
begin
|
||||
Result := TSimpleWindowLayoutDividerPos(FList[Index]);
|
||||
end;
|
||||
|
||||
function TSimpleWindowLayoutDividerPosList.GetNamedItems(Index: Integer): TSimpleWindowLayoutDividerPos;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Result := nil;
|
||||
i := 0;
|
||||
while i < Count do begin
|
||||
if Items[i].DisplayName <> '' then begin
|
||||
if Index = 0 then begin
|
||||
Result := Items[i];
|
||||
exit;
|
||||
end;
|
||||
dec(Index);
|
||||
end;
|
||||
inc(i);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TSimpleWindowLayoutDividerPosList.Merge(AnItem: TSimpleWindowLayoutDividerPos);
|
||||
var
|
||||
i: Integer;
|
||||
old: TSimpleWindowLayoutDividerPos;
|
||||
begin
|
||||
i := IndexOf(AnItem.IdString);
|
||||
FList.Add(AnItem);
|
||||
if i < 0 then
|
||||
exit;
|
||||
|
||||
old := Items[i];
|
||||
if AnItem.Id < 0 then
|
||||
AnItem.SetId(old.Id);
|
||||
if AnItem.DisplayName = '' then
|
||||
AnItem.SetDisplayName(old.DisplayName);
|
||||
if AnItem.DefaultSize < 0 then
|
||||
AnItem.DefaultSize := old.DefaultSize;
|
||||
|
||||
FList.Remove(old);
|
||||
old.Free;
|
||||
end;
|
||||
|
||||
constructor TSimpleWindowLayoutDividerPosList.Create;
|
||||
begin
|
||||
FList := TList.Create;
|
||||
end;
|
||||
|
||||
destructor TSimpleWindowLayoutDividerPosList.Destroy;
|
||||
begin
|
||||
Clear;
|
||||
inherited Destroy;
|
||||
FreeAndNil(FList);
|
||||
end;
|
||||
|
||||
procedure TSimpleWindowLayoutDividerPosList.Assign(ADividerPosList: TSimpleWindowLayoutDividerPosList);
|
||||
var
|
||||
i: Integer;
|
||||
tmp: TSimpleWindowLayoutDividerPos;
|
||||
begin
|
||||
Clear;
|
||||
for i := 0 to ADividerPosList.Count - 1 do begin
|
||||
tmp := Add('');
|
||||
tmp.Assign(ADividerPosList[i]);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TSimpleWindowLayoutDividerPosList.LoadFromConfig(Config: TConfigStorage;
|
||||
const Path: string);
|
||||
var
|
||||
tmp: TSimpleWindowLayoutDividerPos;
|
||||
c, i: Integer;
|
||||
begin
|
||||
ClearItems;
|
||||
c := Config.GetValue(Path+'Count', 0);
|
||||
for i := 0 to c - 1 do begin
|
||||
tmp := TSimpleWindowLayoutDividerPos.Create('');
|
||||
tmp.LoadFromConfig(Config, Path + 'Item' + IntToStr(i) + '/');
|
||||
Merge(tmp);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TSimpleWindowLayoutDividerPosList.SaveToConfig(Config: TConfigStorage;
|
||||
const Path: string);
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Config.SetDeleteValue(Path+'Count', Count, 0);
|
||||
for i := 0 to Count - 1 do
|
||||
Items[i].SaveToConfig(Config, Path + 'Item' + IntToStr(i) + '/');
|
||||
end;
|
||||
|
||||
procedure TSimpleWindowLayoutDividerPosList.Clear;
|
||||
begin
|
||||
while FList.Count > 0 do begin
|
||||
TObject(FList[0]).Free;
|
||||
FList.Delete(0);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TSimpleWindowLayoutDividerPosList.ClearItems;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
for i := 0 to Count - 1 do
|
||||
Items[i].Clear;
|
||||
end;
|
||||
|
||||
function TSimpleWindowLayoutDividerPosList.Add(AnIdString: String;
|
||||
AnId: Integer; ADisplayName: String): TSimpleWindowLayoutDividerPos;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
i := IndexOf(AnId);
|
||||
if i < 0
|
||||
then begin
|
||||
Result := TSimpleWindowLayoutDividerPos.Create(AnIdString, AnId, ADisplayName);
|
||||
FList.Add(Result);
|
||||
end
|
||||
else begin
|
||||
Result := Items[i];
|
||||
if ADisplayName = '' then
|
||||
Result.SetDisplayName(ADisplayName);
|
||||
end
|
||||
end;
|
||||
|
||||
function TSimpleWindowLayoutDividerPosList.Add(AnIdString: String): TSimpleWindowLayoutDividerPos;
|
||||
begin
|
||||
Result := Add(AnIdString, -1, '');
|
||||
end;
|
||||
|
||||
function TSimpleWindowLayoutDividerPosList.Count: Integer;
|
||||
begin
|
||||
Result := FList.Count;
|
||||
end;
|
||||
|
||||
function TSimpleWindowLayoutDividerPosList.NamedCount: Integer;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Result := 0;
|
||||
i := Count - 1;
|
||||
while i >= 0 do begin
|
||||
if Items[i].DisplayName <> '' then inc(Result);
|
||||
dec(i);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TSimpleWindowLayoutDividerPosList.Find(AnId: Integer): TSimpleWindowLayoutDividerPos;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Result := nil;
|
||||
i := IndexOf(AnId);
|
||||
if i >= 0 then
|
||||
Result := Items[i];
|
||||
end;
|
||||
|
||||
function TSimpleWindowLayoutDividerPosList.Find(AnIdString: String): TSimpleWindowLayoutDividerPos;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Result := nil;
|
||||
i := IndexOf(AnIdString);
|
||||
if i >= 0 then
|
||||
Result := Items[i];
|
||||
end;
|
||||
|
||||
function TSimpleWindowLayoutDividerPosList.IndexOf(AnId: Integer): Integer;
|
||||
begin
|
||||
Result := Flist.Count-1;
|
||||
while Result >= 0 do begin
|
||||
if Items[Result].Id = AnId then
|
||||
exit;
|
||||
dec(Result);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TSimpleWindowLayoutDividerPosList.IndexOf(AnIdString: String): Integer;
|
||||
begin
|
||||
Result := Flist.Count-1;
|
||||
while Result >= 0 do begin
|
||||
if Items[Result].IdString = AnIdString then
|
||||
exit;
|
||||
dec(Result);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TSimpleWindowLayoutDividerPosList.IndexOf(AnItem: TSimpleWindowLayoutDividerPos): Integer;
|
||||
begin
|
||||
Result := FList.IndexOf(AnItem);
|
||||
end;
|
||||
|
||||
{ TSimpleWindowLayoutDividerPos }
|
||||
|
||||
procedure TSimpleWindowLayoutDividerPos.SetDisplayName(ADisplayName: String);
|
||||
begin
|
||||
FDisplayName := ADisplayName;
|
||||
end;
|
||||
|
||||
procedure TSimpleWindowLayoutDividerPos.SetId(AnId: Integer);
|
||||
begin
|
||||
FId := AnId;
|
||||
end;
|
||||
|
||||
constructor TSimpleWindowLayoutDividerPos.Create(AnIdString: String);
|
||||
begin
|
||||
Create(AnIdString, -1, '');
|
||||
end;
|
||||
|
||||
constructor TSimpleWindowLayoutDividerPos.Create(AnIdString: String;
|
||||
AnId: Integer; ADisplayName: String);
|
||||
begin
|
||||
FDefaultSize := -1;
|
||||
Clear;
|
||||
FId := AnId;
|
||||
FIdString := AnIdString;
|
||||
FDisplayName := ADisplayName;
|
||||
end;
|
||||
|
||||
procedure TSimpleWindowLayoutDividerPos.Assign(ADividerPos: TSimpleWindowLayoutDividerPos);
|
||||
begin
|
||||
FDefaultSize := ADividerPos.FDefaultSize;
|
||||
FDisplayName := ADividerPos.FDisplayName;
|
||||
FId := ADividerPos.FId;
|
||||
FIdString := ADividerPos.FIdString;
|
||||
FPlacement := ADividerPos.FPlacement;
|
||||
FSize := ADividerPos.FSize;
|
||||
end;
|
||||
|
||||
procedure TSimpleWindowLayoutDividerPos.LoadFromConfig(Config: TConfigStorage;
|
||||
const Path: string);
|
||||
var
|
||||
s: String;
|
||||
begin
|
||||
Clear;
|
||||
FIdString := Config.GetValue(Path+'ID', '');
|
||||
FSize := Config.GetValue(Path+'Size', -1);
|
||||
s := Config.GetValue(Path+'Placement', 'iwpdUseWindowSetting');
|
||||
try
|
||||
ReadStr(s, FPlacement);
|
||||
except
|
||||
FPlacement := iwpdUseWindowSetting;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TSimpleWindowLayoutDividerPos.SaveToConfig(Config: TConfigStorage;
|
||||
const Path: string);
|
||||
var
|
||||
s: String;
|
||||
begin
|
||||
WriteStr(s, FPlacement);
|
||||
Config.SetDeleteValue(Path+'ID', FIdString, '');
|
||||
Config.SetDeleteValue(Path+'Size', FSize, -1);
|
||||
Config.SetDeleteValue(Path+'Placement', s, 'iwpdUseWindowSetting');
|
||||
end;
|
||||
|
||||
procedure TSimpleWindowLayoutDividerPos.Clear;
|
||||
begin
|
||||
FSize := FDefaultSize;
|
||||
FPlacement := iwpdUseWindowSetting;
|
||||
end;
|
||||
|
||||
{ TIDEDialogLayout }
|
||||
|
||||
procedure TIDEDialogLayout.SetList(const AValue: TIDEDialogLayoutList);
|
||||
@ -667,17 +1023,30 @@ end;
|
||||
{ TSimpleWindowLayout }
|
||||
|
||||
constructor TSimpleWindowLayout.Create(AFormID: string);
|
||||
var
|
||||
Creator: TIDEWindowCreator;
|
||||
begin
|
||||
inherited Create(nil);
|
||||
FDividers := TSimpleWindowLayoutDividerPosList.Create;
|
||||
FormID:=AFormID;
|
||||
fDefaultWindowPlacement:=iwpRestoreWindowGeometry;
|
||||
Clear;
|
||||
Creator := IDEWindowCreators.FindWithName(AFormID);
|
||||
if Creator <> nil then
|
||||
Creator.InitSimpleLayout(Self);
|
||||
end;
|
||||
|
||||
destructor TSimpleWindowLayout.Destroy;
|
||||
begin
|
||||
Form:=nil;
|
||||
inherited Destroy;
|
||||
FDividers.Free;
|
||||
end;
|
||||
|
||||
function TSimpleWindowLayout.CreateCopy: TSimpleWindowLayout;
|
||||
begin
|
||||
Result := TSimpleWindowLayout.Create(FFormID);
|
||||
Result.Assign(Self);
|
||||
end;
|
||||
|
||||
procedure TSimpleWindowLayout.LoadFromConfig(Config: TConfigStorage; const Path: string);
|
||||
@ -705,6 +1074,7 @@ begin
|
||||
P+'WindowState/Value',IDEWindowStateNames[fWindowState]));
|
||||
FVisible:=Config.GetValue(P+'Visible/Value',false);
|
||||
//debugln(['TSimpleWindowLayout.LoadFromConfig ',FormID,' ',Left,',',Top,',',Width,',',Height]);
|
||||
FDividers.LoadFromConfig(Config, P + 'Divider/');
|
||||
end;
|
||||
|
||||
procedure TSimpleWindowLayout.SaveToConfig(Config: TConfigStorage;
|
||||
@ -729,6 +1099,7 @@ begin
|
||||
// state
|
||||
Config.SetValue(P+'WindowState/Value',IDEWindowStateNames[fWindowState]);
|
||||
Config.SetDeleteValue(P+'Visible/Value',FVisible,false);
|
||||
FDividers.SaveToConfig(Config, P + 'Divider/');
|
||||
end;
|
||||
|
||||
procedure TSimpleWindowLayout.OnFormClose(Sender: TObject;
|
||||
@ -817,6 +1188,7 @@ begin
|
||||
fWidth:=0;
|
||||
fHeight:=0;
|
||||
fWindowState:=iwsNormal;
|
||||
FDividers.ClearItems;
|
||||
end;
|
||||
|
||||
procedure TSimpleWindowLayout.ReadCurrentCoordinates;
|
||||
@ -861,6 +1233,31 @@ begin
|
||||
fWindowState:=Layout.fWindowState;
|
||||
fFormID:=Layout.fFormID;
|
||||
fDefaultWindowPlacement:=Layout.fDefaultWindowPlacement;
|
||||
FDividers.Assign(Layout.FDividers);
|
||||
end;
|
||||
|
||||
procedure TSimpleWindowLayout.ReadCurrentDividers(AForce: Boolean = False);
|
||||
var
|
||||
i, j: Integer;
|
||||
f: Boolean;
|
||||
Creator: TIDEWindowCreator;
|
||||
begin
|
||||
Creator:=IDEWindowCreators.FindWithName(FormID);
|
||||
if (Creator = nil) or (Creator.OnGetDividerSize = nil) then exit;
|
||||
if fForm = nil then exit;;
|
||||
for i := 0 to FDividers.Count - 1 do begin
|
||||
if FDividers[i].FId < 0 then continue;
|
||||
f := AForce;
|
||||
case FDividers[i].Placement of
|
||||
iwpdRestore:
|
||||
f := true;
|
||||
iwpdUseWindowSetting:
|
||||
f := WindowPlacement in [iwpRestoreWindowGeometry, iwpRestoreWindowSize];
|
||||
end;
|
||||
if f then
|
||||
if Creator.OnGetDividerSize(fForm, FDividers[i].Id, j) then
|
||||
FDividers[i].Size := j;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TSimpleWindowLayout.GetCurrentPosition;
|
||||
@ -870,10 +1267,107 @@ begin
|
||||
iwpRestoreWindowGeometry, iwpRestoreWindowSize:
|
||||
ReadCurrentCoordinates;
|
||||
end;
|
||||
ReadCurrentDividers;
|
||||
ReadCurrentState;
|
||||
//debugln('TSimpleWindowLayout.GetCurrentPosition ',DbgSName(Self),' ',FormID,' Width=',dbgs(Width));
|
||||
end;
|
||||
|
||||
function TSimpleWindowLayout.Apply: Boolean;
|
||||
var
|
||||
NewBounds: TRect;
|
||||
i: Integer;
|
||||
begin
|
||||
Result := False;
|
||||
if fForm = nil then exit;
|
||||
Applied:=true;
|
||||
{$IFDEF VerboseIDEDocking}
|
||||
debugln(['TSimpleWindowLayoutList.ApplyAndShow restore ',
|
||||
FormID,' ',IDEWindowPlacementNames[WindowPlacement],
|
||||
' Valid=',CustomCoordinatesAreValid,' ',Left,',',
|
||||
Top,',',Width,',',Height]);
|
||||
{$ENDIF}
|
||||
|
||||
case WindowPlacement of
|
||||
iwpCustomPosition,iwpRestoreWindowGeometry:
|
||||
begin
|
||||
//DebugLn(['TMainIDE.OnApplyWindowLayout ',IDEWindowStateNames[WindowState]]);
|
||||
case WindowState of
|
||||
iwsMinimized: FForm.WindowState:=wsMinimized;
|
||||
iwsMaximized: FForm.WindowState:=wsMaximized;
|
||||
end;
|
||||
|
||||
if (CustomCoordinatesAreValid) then begin
|
||||
// explicit position
|
||||
NewBounds:=Bounds(Left,Top,Width,Height);
|
||||
// set minimum size
|
||||
if NewBounds.Right-NewBounds.Left<60 then
|
||||
NewBounds.Right:=NewBounds.Left+60;
|
||||
if NewBounds.Bottom-NewBounds.Top<60 then
|
||||
NewBounds.Bottom:=NewBounds.Top+60;
|
||||
|
||||
// Move to visible area :
|
||||
// window is out at left side of screen
|
||||
if NewBounds.Right<Screen.DesktopLeft+60 then
|
||||
OffsetRect(NewBounds,Screen.DesktopLeft+60-NewBounds.Right,0);
|
||||
|
||||
// window is out above the screen
|
||||
if NewBounds.Bottom<Screen.DesktopTop+60 then
|
||||
OffsetRect(NewBounds,0,Screen.DesktopTop+60-NewBounds.Bottom);
|
||||
|
||||
// window is out at right side of screen, i = right edge of screen - 60
|
||||
i:=Screen.DesktopWidth+Screen.DesktopLeft-60;
|
||||
if NewBounds.Left > i then begin
|
||||
NewBounds.Left := i;
|
||||
NewBounds.Right := NewBounds.Right + i - NewBounds.Left;
|
||||
end;
|
||||
|
||||
// window is out below the screen, i = bottom edge of screen - 60
|
||||
i:=Screen.DesktopHeight+Screen.DesktopTop-60;
|
||||
if NewBounds.Top > i then begin
|
||||
NewBounds.Top := i;
|
||||
NewBounds.Bottom := NewBounds.Bottom + i - NewBounds.Top;
|
||||
end;
|
||||
|
||||
// set bounds (do not use SetRestoredBounds - that flickers with the current LCL implementation)
|
||||
FForm.SetBounds(NewBounds.Left,NewBounds.Top,
|
||||
NewBounds.Right-NewBounds.Left,
|
||||
NewBounds.Bottom-NewBounds.Top);
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
if WindowState in [iwsMinimized, iwsMaximized] then
|
||||
Result := True;
|
||||
end;
|
||||
iwpUseWindowManagerSetting:
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
ApplyDivider;
|
||||
end;
|
||||
|
||||
procedure TSimpleWindowLayout.ApplyDivider(AForce: Boolean = False);
|
||||
var
|
||||
i: Integer;
|
||||
f: Boolean;
|
||||
Creator: TIDEWindowCreator;
|
||||
begin
|
||||
Creator:=IDEWindowCreators.FindWithName(FormID);
|
||||
if (Creator <> nil) and (Creator.OnSetDividerSize <> nil) then begin
|
||||
for i := 0 to FDividers.Count - 1 do begin
|
||||
if (FDividers[i].FId < 0) or (FDividers[i].Size < 0) then continue;
|
||||
f := AForce;
|
||||
case FDividers[i].Placement of
|
||||
iwpdRestore, iwpdCustomSize:
|
||||
f := true;
|
||||
iwpdUseWindowSetting:
|
||||
f := WindowPlacement in [iwpRestoreWindowGeometry, iwpRestoreWindowSize];
|
||||
end;
|
||||
if f then
|
||||
Creator.OnSetDividerSize(fForm, FDividers[i].Id, FDividers[i].Size);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ TSimpleWindowLayoutList }
|
||||
|
||||
procedure TSimpleWindowLayoutList.Clear;
|
||||
@ -1027,71 +1521,7 @@ begin
|
||||
begin
|
||||
ALayout.Form:=AForm;
|
||||
if ALayout.Applied then exit;
|
||||
ALayout.Applied:=true;
|
||||
{$IFDEF VerboseIDEDocking}
|
||||
debugln(['TSimpleWindowLayoutList.ApplyAndShow restore ',
|
||||
ALayout.FormID,' ',IDEWindowPlacementNames[ALayout.WindowPlacement],
|
||||
' Valid=',ALayout.CustomCoordinatesAreValid,' ',ALayout.Left,',',
|
||||
ALayout.Top,',',ALayout.Width,',',ALayout.Height]);
|
||||
{$ENDIF}
|
||||
|
||||
case ALayout.WindowPlacement of
|
||||
iwpCustomPosition,iwpRestoreWindowGeometry:
|
||||
begin
|
||||
//DebugLn(['TMainIDE.OnApplyWindowLayout ',IDEWindowStateNames[ALayout.WindowState]]);
|
||||
case ALayout.WindowState of
|
||||
iwsMinimized: AForm.WindowState:=wsMinimized;
|
||||
iwsMaximized: AForm.WindowState:=wsMaximized;
|
||||
end;
|
||||
|
||||
if (ALayout.CustomCoordinatesAreValid) then begin
|
||||
// explicit position
|
||||
NewBounds:=Bounds(ALayout.Left,ALayout.Top,ALayout.Width,ALayout.Height);
|
||||
// set minimum size
|
||||
if NewBounds.Right-NewBounds.Left<60 then
|
||||
NewBounds.Right:=NewBounds.Left+60;
|
||||
if NewBounds.Bottom-NewBounds.Top<60 then
|
||||
NewBounds.Bottom:=NewBounds.Top+60;
|
||||
|
||||
// Move to visible area :
|
||||
// window is out at left side of screen
|
||||
if NewBounds.Right<Screen.DesktopLeft+60 then
|
||||
OffsetRect(NewBounds,Screen.DesktopLeft+60-NewBounds.Right,0);
|
||||
|
||||
// window is out above the screen
|
||||
if NewBounds.Bottom<Screen.DesktopTop+60 then
|
||||
OffsetRect(NewBounds,0,Screen.DesktopTop+60-NewBounds.Bottom);
|
||||
|
||||
// window is out at right side of screen, i = right edge of screen - 60
|
||||
i:=Screen.DesktopWidth+Screen.DesktopLeft-60;
|
||||
if NewBounds.Left > i then begin
|
||||
NewBounds.Left := i;
|
||||
NewBounds.Right := NewBounds.Right + i - NewBounds.Left;
|
||||
end;
|
||||
|
||||
// window is out below the screen, i = bottom edge of screen - 60
|
||||
i:=Screen.DesktopHeight+Screen.DesktopTop-60;
|
||||
if NewBounds.Top > i then begin
|
||||
NewBounds.Top := i;
|
||||
NewBounds.Bottom := NewBounds.Bottom + i - NewBounds.Top;
|
||||
end;
|
||||
|
||||
// set bounds (do not use SetRestoredBounds - that flickers with the current LCL implementation)
|
||||
AForm.SetBounds(NewBounds.Left,NewBounds.Top,
|
||||
NewBounds.Right-NewBounds.Left,
|
||||
NewBounds.Bottom-NewBounds.Top);
|
||||
exit;
|
||||
end;
|
||||
|
||||
if ALayout.WindowState in [iwsMinimized, iwsMaximized] then
|
||||
exit;
|
||||
end;
|
||||
|
||||
iwpUseWindowManagerSetting:
|
||||
begin
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
if ALayout.Apply then exit;
|
||||
end;
|
||||
|
||||
{$IFDEF VerboseIDEDocking}
|
||||
@ -1183,15 +1613,13 @@ begin
|
||||
end;
|
||||
|
||||
procedure TSimpleWindowLayoutList.Assign(SrcList: TSimpleWindowLayoutList);
|
||||
var i: integer;
|
||||
NewLayout: TSimpleWindowLayout;
|
||||
var
|
||||
i: integer;
|
||||
begin
|
||||
Clear;
|
||||
if SrcList=nil then exit;
|
||||
for i:=0 to SrcList.Count-1 do begin
|
||||
NewLayout:=TSimpleWindowLayout.Create(SrcList[i].FormID);
|
||||
NewLayout.Assign(SrcList[i]);
|
||||
Add(NewLayout);
|
||||
Add(SrcList[i].CreateCopy);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -1227,6 +1655,13 @@ begin
|
||||
FBottom:=AValue;
|
||||
end;
|
||||
|
||||
function TIDEWindowCreator.GetDividerTemplate: TSimpleWindowLayoutDividerPosList;
|
||||
begin
|
||||
If FDividerTemplate = nil then
|
||||
FDividerTemplate := TSimpleWindowLayoutDividerPosList.Create;
|
||||
Result := FDividerTemplate;
|
||||
end;
|
||||
|
||||
procedure TIDEWindowCreator.SetLeft(const AValue: string);
|
||||
begin
|
||||
CheckBoundValue(AValue);
|
||||
@ -1337,9 +1772,18 @@ begin
|
||||
DefBounds.Bottom:=aBottom;
|
||||
end;
|
||||
|
||||
procedure TIDEWindowCreator.InitSimpleLayout(ALayout: TSimpleWindowLayout);
|
||||
begin
|
||||
if FDividerTemplate <> nil then
|
||||
ALayout.Dividers.Assign(FDividerTemplate);
|
||||
end;
|
||||
|
||||
constructor TIDEWindowCreator.Create(aFormName: string);
|
||||
var
|
||||
sl: TSimpleWindowLayout;
|
||||
begin
|
||||
FFormName:=aFormName;
|
||||
FDividerTemplate := nil;
|
||||
end;
|
||||
|
||||
constructor TIDEWindowCreator.Create(aFormName: string;
|
||||
@ -1361,6 +1805,12 @@ begin
|
||||
OnGetLayout:=GetLayoutEvent;
|
||||
end;
|
||||
|
||||
destructor TIDEWindowCreator.Destroy;
|
||||
begin
|
||||
inherited Destroy;
|
||||
FreeAndNil(FDividerTemplate);
|
||||
end;
|
||||
|
||||
function TIDEWindowCreator.NameFits(const AName: string): boolean;
|
||||
begin
|
||||
Result:=CompareText(copy(AName,1,Length(FormName)),FormName)=0;
|
||||
|
Loading…
Reference in New Issue
Block a user