diff --git a/debugger/debuggerdlg.pp b/debugger/debuggerdlg.pp index bb56326a39..a11e2e9911 100644 --- a/debugger/debuggerdlg.pp +++ b/debugger/debuggerdlg.pp @@ -83,13 +83,9 @@ begin end; *) procedure TDebuggerDlg.DoClose(var CloseAction: TCloseAction); -var - Layout: TSimpleWindowLayout; begin CloseAction := caFree; // we default to free inherited DoClose(CloseAction); - Layout := EnvironmentOptions.IDEWindowLayoutList.ItemByFormID(Name); - if Layout <> nil then Layout.GetCurrentPosition; end; procedure TDebuggerDlg.DoBeginUpdate; diff --git a/designer/anchoreditor.lfm b/designer/anchoreditor.lfm index 2af07a4119..7e572b44c1 100644 --- a/designer/anchoreditor.lfm +++ b/designer/anchoreditor.lfm @@ -9,7 +9,6 @@ object AnchorDesigner: TAnchorDesigner ClientWidth = 596 Constraints.MinHeight = 282 Constraints.MinWidth = 476 - OnClose = AnchorDesignerClose OnCreate = AnchorDesignerCreate OnDestroy = AnchorDesignerDestroy OnShow = AnchorDesignerShow @@ -22,22 +21,22 @@ object AnchorDesigner: TAnchorDesigner AnchorSideTop.Side = asrBottom AnchorSideBottom.Control = BottomGroupBox Left = 193 - Height = 166 - Top = 61 + Height = 168 + Top = 60 Width = 210 Anchors = [akTop, akLeft, akBottom] BorderSpacing.Top = 4 BorderSpacing.Bottom = 4 Caption = 'BorderSpaceGroupBox' - ClientHeight = 147 - ClientWidth = 206 + ClientHeight = 150 + ClientWidth = 202 TabOrder = 0 object LeftBorderSpaceSpinEdit: TSpinEdit AnchorSideTop.Control = AroundBorderSpaceSpinEdit AnchorSideRight.Control = AroundBorderSpaceSpinEdit - Left = 11 + Left = 9 Height = 27 - Top = 60 + Top = 62 Width = 56 Anchors = [akTop, akRight] BorderSpacing.Right = 8 @@ -52,9 +51,9 @@ object AnchorDesigner: TAnchorDesigner AnchorSideLeft.Control = AroundBorderSpaceSpinEdit AnchorSideLeft.Side = asrBottom AnchorSideTop.Control = AroundBorderSpaceSpinEdit - Left = 139 + Left = 137 Height = 27 - Top = 60 + Top = 62 Width = 56 BorderSpacing.Left = 8 MaxValue = 2048 @@ -67,9 +66,9 @@ object AnchorDesigner: TAnchorDesigner object TopBorderSpaceSpinEdit: TSpinEdit AnchorSideLeft.Control = AroundBorderSpaceSpinEdit AnchorSideBottom.Control = AroundBorderSpaceSpinEdit - Left = 75 + Left = 73 Height = 27 - Top = 21 + Top = 23 Width = 56 Anchors = [akLeft, akBottom] BorderSpacing.Bottom = 12 @@ -84,9 +83,9 @@ object AnchorDesigner: TAnchorDesigner AnchorSideLeft.Control = AroundBorderSpaceSpinEdit AnchorSideTop.Control = AroundBorderSpaceSpinEdit AnchorSideTop.Side = asrBottom - Left = 75 + Left = 73 Height = 27 - Top = 99 + Top = 101 Width = 56 BorderSpacing.Top = 12 MaxValue = 2048 @@ -101,9 +100,9 @@ object AnchorDesigner: TAnchorDesigner AnchorSideLeft.Side = asrCenter AnchorSideTop.Control = BorderSpaceGroupBox AnchorSideTop.Side = asrCenter - Left = 75 + Left = 73 Height = 27 - Top = 60 + Top = 62 Width = 56 MaxValue = 2048 OnChange = BorderSpaceSpinEditChange @@ -115,20 +114,20 @@ object AnchorDesigner: TAnchorDesigner end object TopGroupBox: TGroupBox Left = 56 - Height = 57 + Height = 56 Top = 0 Width = 484 Anchors = [akTop, akLeft, akRight] AutoSize = True Caption = 'TopGroupBox' ClientHeight = 38 - ClientWidth = 480 + ClientWidth = 476 TabOrder = 1 object TopRefTopSpeedButton: TSpeedButton AnchorSideTop.Control = TopRefCenterSpeedButton AnchorSideRight.Control = TopRefBottomSpeedButton AnchorSideBottom.Side = asrBottom - Left = 374 + Left = 370 Height = 30 Top = 0 Width = 30 @@ -146,7 +145,7 @@ object AnchorDesigner: TAnchorDesigner AnchorSideTop.Control = TopRefCenterSpeedButton AnchorSideRight.Control = TopRefCenterSpeedButton AnchorSideBottom.Side = asrBottom - Left = 408 + Left = 404 Height = 30 Top = 0 Width = 30 @@ -165,7 +164,7 @@ object AnchorDesigner: TAnchorDesigner AnchorSideRight.Side = asrBottom AnchorSideBottom.Control = TopGroupBox AnchorSideBottom.Side = asrBottom - Left = 442 + Left = 438 Height = 30 Top = 0 Width = 30 @@ -185,10 +184,10 @@ object AnchorDesigner: TAnchorDesigner AnchorSideLeft.Side = asrBottom AnchorSideTop.Control = TopRefCenterSpeedButton AnchorSideTop.Side = asrCenter - Left = 99 + Left = 104 Height = 18 Top = 6 - Width = 43 + Width = 45 BorderSpacing.Left = 16 Caption = 'Sibling' ParentColor = False @@ -199,7 +198,7 @@ object AnchorDesigner: TAnchorDesigner Left = 8 Height = 22 Top = 4 - Width = 75 + Width = 80 BorderSpacing.Left = 8 Caption = 'Enabled' OnChange = AnchorEnabledCheckBoxChange @@ -211,10 +210,10 @@ object AnchorDesigner: TAnchorDesigner AnchorSideTop.Control = TopRefCenterSpeedButton AnchorSideTop.Side = asrCenter AnchorSideRight.Control = TopRefTopSpeedButton - Left = 146 - Height = 29 - Top = 1 - Width = 216 + Left = 153 + Height = 27 + Top = 2 + Width = 205 Anchors = [akTop, akLeft, akRight] BorderSpacing.Left = 4 BorderSpacing.Right = 12 @@ -228,19 +227,19 @@ object AnchorDesigner: TAnchorDesigner end object BottomGroupBox: TGroupBox Left = 56 - Height = 57 - Top = 231 + Height = 56 + Top = 232 Width = 484 Anchors = [akLeft, akRight, akBottom] AutoSize = True Caption = 'BottomGroupBox' ClientHeight = 38 - ClientWidth = 480 + ClientWidth = 476 TabOrder = 2 object BottomRefTopSpeedButton: TSpeedButton AnchorSideTop.Control = BottomRefCenterSpeedButton AnchorSideRight.Control = BottomRefBottomSpeedButton - Left = 374 + Left = 370 Height = 30 Top = 0 Width = 30 @@ -257,7 +256,7 @@ object AnchorDesigner: TAnchorDesigner object BottomRefBottomSpeedButton: TSpeedButton AnchorSideTop.Control = BottomRefCenterSpeedButton AnchorSideRight.Control = BottomRefCenterSpeedButton - Left = 408 + Left = 404 Height = 30 Top = 0 Width = 30 @@ -276,7 +275,7 @@ object AnchorDesigner: TAnchorDesigner AnchorSideRight.Side = asrBottom AnchorSideBottom.Control = BottomGroupBox AnchorSideBottom.Side = asrBottom - Left = 442 + Left = 438 Height = 30 Top = 0 Width = 30 @@ -296,10 +295,10 @@ object AnchorDesigner: TAnchorDesigner AnchorSideLeft.Side = asrBottom AnchorSideTop.Control = BottomRefCenterSpeedButton AnchorSideTop.Side = asrCenter - Left = 99 + Left = 104 Height = 18 Top = 6 - Width = 43 + Width = 45 BorderSpacing.Left = 16 Caption = 'Sibling' ParentColor = False @@ -310,7 +309,7 @@ object AnchorDesigner: TAnchorDesigner Left = 8 Height = 22 Top = 4 - Width = 75 + Width = 80 BorderSpacing.Left = 8 Caption = 'Enabled' OnChange = AnchorEnabledCheckBoxChange @@ -322,10 +321,10 @@ object AnchorDesigner: TAnchorDesigner AnchorSideTop.Control = BottomRefCenterSpeedButton AnchorSideTop.Side = asrCenter AnchorSideRight.Control = BottomRefTopSpeedButton - Left = 146 - Height = 29 - Top = 1 - Width = 216 + Left = 153 + Height = 27 + Top = 2 + Width = 205 Anchors = [akTop, akLeft, akRight] BorderSpacing.Left = 4 BorderSpacing.Right = 12 @@ -344,21 +343,21 @@ object AnchorDesigner: TAnchorDesigner AnchorSideBottom.Control = BorderSpaceGroupBox AnchorSideBottom.Side = asrBottom Left = 407 - Height = 166 - Top = 61 + Height = 168 + Top = 60 Width = 179 Anchors = [akTop, akLeft, akRight, akBottom] BorderSpacing.Left = 4 Caption = 'RightGroupBox' - ClientHeight = 147 - ClientWidth = 175 + ClientHeight = 150 + ClientWidth = 171 TabOrder = 3 object RightRefLeftSpeedButton: TSpeedButton AnchorSideTop.Control = RightRefCenterSpeedButton AnchorSideRight.Control = RightRefRightSpeedButton - Left = 69 + Left = 65 Height = 30 - Top = 100 + Top = 101 Width = 30 Anchors = [akTop, akRight] BorderSpacing.Right = 4 @@ -373,9 +372,9 @@ object AnchorDesigner: TAnchorDesigner object RightRefRightSpeedButton: TSpeedButton AnchorSideTop.Control = RightRefCenterSpeedButton AnchorSideRight.Control = RightRefCenterSpeedButton - Left = 103 + Left = 99 Height = 30 - Top = 100 + Top = 101 Width = 30 Anchors = [akTop, akRight] BorderSpacing.Right = 4 @@ -392,9 +391,9 @@ object AnchorDesigner: TAnchorDesigner AnchorSideTop.Side = asrBottom AnchorSideRight.Control = RightSiblingComboBox AnchorSideRight.Side = asrBottom - Left = 137 + Left = 133 Height = 30 - Top = 100 + Top = 101 Width = 30 Anchors = [akTop, akRight] BorderSpacing.Top = 12 @@ -412,8 +411,8 @@ object AnchorDesigner: TAnchorDesigner AnchorSideBottom.Control = RightSiblingComboBox Left = 8 Height = 18 - Top = 41 - Width = 43 + Top = 44 + Width = 45 Anchors = [akLeft, akBottom] BorderSpacing.Top = 2 Caption = 'Sibling' @@ -425,8 +424,8 @@ object AnchorDesigner: TAnchorDesigner AnchorSideBottom.Control = RightSiblingLabel Left = 8 Height = 22 - Top = 11 - Width = 75 + Top = 14 + Width = 80 Anchors = [akLeft, akBottom] BorderSpacing.Bottom = 8 Caption = 'Enabled' @@ -440,9 +439,9 @@ object AnchorDesigner: TAnchorDesigner AnchorSideRight.Control = RightGroupBox AnchorSideRight.Side = asrBottom Left = 8 - Height = 29 - Top = 59 - Width = 159 + Height = 27 + Top = 62 + Width = 155 Anchors = [akTop, akLeft, akRight] BorderSpacing.Left = 8 BorderSpacing.Right = 8 @@ -460,21 +459,21 @@ object AnchorDesigner: TAnchorDesigner AnchorSideBottom.Control = BorderSpaceGroupBox AnchorSideBottom.Side = asrBottom Left = 8 - Height = 166 - Top = 61 + Height = 168 + Top = 60 Width = 181 Anchors = [akTop, akLeft, akRight, akBottom] BorderSpacing.Right = 4 Caption = 'LeftGroupBox' - ClientHeight = 147 - ClientWidth = 177 + ClientHeight = 150 + ClientWidth = 173 TabOrder = 4 object LeftRefLeftSpeedButton: TSpeedButton AnchorSideTop.Control = LeftRefCenterSpeedButton AnchorSideRight.Control = LeftRefRightSpeedButton - Left = 71 + Left = 68 Height = 30 - Top = 100 + Top = 101 Width = 30 Anchors = [akTop, akRight] BorderSpacing.Right = 4 @@ -490,9 +489,9 @@ object AnchorDesigner: TAnchorDesigner AnchorSideLeft.Side = asrBottom AnchorSideTop.Control = LeftRefCenterSpeedButton AnchorSideRight.Control = LeftRefCenterSpeedButton - Left = 105 + Left = 102 Height = 30 - Top = 100 + Top = 101 Width = 30 Anchors = [akTop] BorderSpacing.Right = 4 @@ -510,9 +509,9 @@ object AnchorDesigner: TAnchorDesigner AnchorSideTop.Side = asrBottom AnchorSideRight.Control = LeftSiblingComboBox AnchorSideRight.Side = asrBottom - Left = 139 + Left = 135 Height = 30 - Top = 100 + Top = 101 Width = 30 Anchors = [akTop, akRight] BorderSpacing.Top = 12 @@ -529,8 +528,8 @@ object AnchorDesigner: TAnchorDesigner AnchorSideBottom.Control = LeftSiblingComboBox Left = 8 Height = 18 - Top = 41 - Width = 43 + Top = 44 + Width = 45 Anchors = [akLeft, akBottom] BorderSpacing.Top = 2 Caption = 'Sibling' @@ -541,8 +540,8 @@ object AnchorDesigner: TAnchorDesigner AnchorSideBottom.Control = LeftSiblingLabel Left = 8 Height = 22 - Top = 11 - Width = 75 + Top = 14 + Width = 80 Anchors = [akLeft, akBottom] BorderSpacing.Bottom = 8 Caption = 'Enabled' @@ -556,9 +555,9 @@ object AnchorDesigner: TAnchorDesigner AnchorSideRight.Control = LeftGroupBox AnchorSideRight.Side = asrBottom Left = 8 - Height = 29 - Top = 59 - Width = 161 + Height = 27 + Top = 62 + Width = 157 Anchors = [akTop, akLeft, akRight] BorderSpacing.Left = 8 BorderSpacing.Right = 8 diff --git a/designer/anchoreditor.pas b/designer/anchoreditor.pas index 10ff161e5b..0acb552dc7 100644 --- a/designer/anchoreditor.pas +++ b/designer/anchoreditor.pas @@ -131,8 +131,6 @@ type TopRefTopSpeedButton: TSpeedButton; TopSiblingComboBox: TComboBox; TopSiblingLabel: TLabel; - procedure AnchorDesignerClose(Sender: TObject; var CloseAction: TCloseAction - ); procedure AnchorDesignerCreate(Sender: TObject); procedure AnchorDesignerDestroy(Sender: TObject); procedure AnchorDesignerShow(Sender: TObject); @@ -912,12 +910,6 @@ begin Refresh(false); end; -procedure TAnchorDesigner.AnchorDesignerClose(Sender: TObject; - var CloseAction: TCloseAction); -begin - EnvironmentOptions.IDEWindowLayoutList.ItemByForm(Self).GetCurrentPosition; -end; - { TAnchorDesignerValues } function TAnchorDesignerValues.GetSides(Kind: TAnchorKind diff --git a/ide/codeexplorer.lfm b/ide/codeexplorer.lfm index dceea9b529..fcae1d6b67 100644 --- a/ide/codeexplorer.lfm +++ b/ide/codeexplorer.lfm @@ -8,7 +8,6 @@ object CodeExplorerView: TCodeExplorerView ClientHeight = 517 ClientWidth = 215 KeyPreview = True - OnClose = CodeExplorerViewCLOSE OnCreate = CodeExplorerViewCREATE OnDestroy = CodeExplorerViewDestroy LCLVersion = '0.9.29' @@ -44,7 +43,7 @@ object CodeExplorerView: TCodeExplorerView OnDblClick = CodeTreeviewDblClick OnDeletion = CodeTreeviewDeletion OnKeyUp = CodeTreeviewKeyUp - Options = [tvoAutoItemHeight, tvoKeepCollapsedNodes, tvoReadOnly, tvoRightClickSelect, tvoShowButtons, tvoShowLines, tvoShowRoot, tvoToolTips, tvoThemedDraw, tvoNoDoubleClickExpand] + Options = [tvoAutoItemHeight, tvoKeepCollapsedNodes, tvoReadOnly, tvoRightClickSelect, tvoShowButtons, tvoShowLines, tvoShowRoot, tvoToolTips, tvoNoDoubleClickExpand, tvoThemedDraw] end object CodeTreeviewButtonPanel: TPanel Left = 0 @@ -112,8 +111,8 @@ object CodeExplorerView: TCodeExplorerView end object DirectivesPage: TPage Caption = 'DirectivesPage' - ClientWidth = 213 - ClientHeight = 488 + ClientWidth = 211 + ClientHeight = 482 object DirectivesFilterEdit: TEdit AnchorSideLeft.Control = DirectivesPage AnchorSideTop.Control = DirectivesPage @@ -122,7 +121,7 @@ object CodeExplorerView: TCodeExplorerView Left = 0 Height = 27 Top = 0 - Width = 213 + Width = 211 Anchors = [akTop, akLeft, akRight] OnChange = DirectivesFilterEditChange TabOrder = 0 @@ -132,9 +131,9 @@ object CodeExplorerView: TCodeExplorerView AnchorSideTop.Control = DirectivesFilterEdit AnchorSideTop.Side = asrBottom Left = 0 - Height = 460 + Height = 454 Top = 28 - Width = 213 + Width = 211 Align = alBottom Anchors = [akTop, akLeft, akRight, akBottom] BorderSpacing.Top = 1 diff --git a/ide/codeexplorer.pas b/ide/codeexplorer.pas index 2d0a3b3e17..45a7e3815e 100644 --- a/ide/codeexplorer.pas +++ b/ide/codeexplorer.pas @@ -134,8 +134,6 @@ type RefreshSpeedButton: TSpeedButton; ModeSpeedButton: TSpeedButton; TreePopupmenu: TPopupMenu; - procedure CodeExplorerViewClose(Sender: TObject; - var CloseAction: TCloseAction); procedure CodeExplorerViewCreate(Sender: TObject); procedure CodeExplorerViewDestroy(Sender: TObject); procedure CodeTreeviewDblClick(Sender: TObject); @@ -509,12 +507,6 @@ begin end; end; -procedure TCodeExplorerView.CodeExplorerViewCLOSE(Sender: TObject; - var CloseAction: TCloseAction); -begin - EnvironmentOptions.IDEWindowLayoutList.ItemByForm(Self).GetCurrentPosition; -end; - procedure TCodeExplorerView.JumpToMenuitemCLICK(Sender: TObject); begin JumpToSelection; diff --git a/ide/environmentopts.pp b/ide/environmentopts.pp index fcca7be877..2a77af8439 100644 --- a/ide/environmentopts.pp +++ b/ide/environmentopts.pp @@ -157,7 +157,6 @@ type FLastSavedProjectFile: string; // window layout - FIDEWindowLayoutList: TSimpleWindowLayoutList; FIDEDialogLayoutList: TIDEDialogLayoutList; FSingleTaskBarButton: boolean; FHideIDEOnRun: boolean; @@ -296,8 +295,6 @@ type property Filename: string read FFilename write SetFilename; procedure SetLazarusDefaultFilename; procedure GetDefaultFPCSourceDirectory; - function CreateWindowLayout(const TheFormID: string): TSimpleWindowLayout; - function CreateWindowLayout(const TheForm: TCustomForm): TSimpleWindowLayout; function IsDebuggerClassDefined: boolean; function GetTestBuildDirectory: string; function GetFPCSourceDirectory: string; @@ -330,8 +327,6 @@ type write FAutoSaveIntervalInSecs; // window layouts - property IDEWindowLayoutList: TSimpleWindowLayoutList - read FIDEWindowLayoutList write FIDEWindowLayoutList; property IDEDialogLayoutList: TIDEDialogLayoutList read FIDEDialogLayoutList write FIDEDialogLayoutList; property SingleTaskBarButton: boolean read FSingleTaskBarButton @@ -790,7 +785,6 @@ begin if IDEWindowIntf.IDEDialogLayoutList=FIDEDialogLayoutList then IDEWindowIntf.IDEDialogLayoutList:=nil; FreeAndNil(FIDEDialogLayoutList); - FreeAndNil(fIDEWindowLayoutList); FreeAndNil(FConfigStore); FreeAndNil(FXMLCfg); inherited Destroy; @@ -921,16 +915,7 @@ begin FAutoCloseCompileDialog:=XMLConfig.GetValue( Path+'AutoCloseCompileDialog/Value',false); - // windows - i := XMLConfig.GetValue(Path+'Desktop/FormIdCount', 0); - while i > 0 do begin - name := XMLConfig.GetValue(Path+'Desktop/FormIdList/a'+IntToStr(i), ''); - if (name <> '') and (IDEWindowLayoutList.ItemByFormID(name) = nil) then - CreateWindowLayout(name); - dec(i); - end; - - FIDEWindowLayoutList.LoadFromConfig(Cfg,Path+'Desktop/'); + IDEWindowCreators.SimpleLayoutStorage.LoadFromConfig(Cfg,Path+'Desktop/'); FIDEDialogLayoutList.LoadFromConfig(FConfigStore, Path+'Desktop/Dialogs/'); FSingleTaskBarButton := XMLConfig.GetValue( @@ -1251,7 +1236,7 @@ begin FOpenLastProjectAtStart,true); // windows - FIDEWindowLayoutList.SaveToConfig(Cfg,Path+'Desktop/'); + IDEWindowCreators.SimpleLayoutStorage.SaveToConfig(Cfg,Path+'Desktop/'); FIDEDialogLayoutList.SaveToConfig(FConfigStore,Path+'Desktop/Dialogs/'); XMLConfig.SetDeleteValue(Path+'Desktop/SingleTaskBarButton/Value', FSingleTaskBarButton, False); @@ -1499,30 +1484,10 @@ procedure TEnvironmentOptions.InitLayoutList; var l: TNonModalIDEWindow; begin - fIDEWindowLayoutList:=TSimpleWindowLayoutList.Create; - for l:=Low(TNonModalIDEWindow) to High(TNonModalIDEWindow) do if l<>nmiwNone then - CreateWindowLayout(NonModalIDEWindowNames[l]); - CreateWindowLayout(DefaultObjectInspectorName); -end; - -function TEnvironmentOptions.CreateWindowLayout(const TheFormID: string - ): TSimpleWindowLayout; -begin - if TheFormID='' then - RaiseException('TEnvironmentOptions.CreateWindowLayout TheFormID empty'); - if IDEWindowLayoutList.ItemByFormID(TheFormID)<>nil then - RaiseException('TEnvironmentOptions.CreateWindowLayout TheFormID exists'); - Result:=TSimpleWindowLayout.Create(TheFormID); - IDEWindowLayoutList.Add(Result); -end; - -function TEnvironmentOptions.CreateWindowLayout(const TheForm: TCustomForm - ): TSimpleWindowLayout; -begin - Result:=CreateWindowLayout(TheForm.Name); - Result.Form:=TheForm; + IDEWindowCreators.SimpleLayoutStorage.CreateWindowLayout(NonModalIDEWindowNames[l]); + IDEWindowCreators.SimpleLayoutStorage.CreateWindowLayout(DefaultObjectInspectorName); end; function TEnvironmentOptions.IsDebuggerClassDefined: boolean; diff --git a/ide/frames/window_options.pas b/ide/frames/window_options.pas index d5839537cf..d754cb4436 100644 --- a/ide/frames/window_options.pas +++ b/ide/frames/window_options.pas @@ -26,7 +26,7 @@ interface uses Classes, SysUtils, types, FileUtil, Forms, Controls, StdCtrls, ExtCtrls, - Spin, + LCLProc, Spin, ObjInspStrConsts, ObjectInspector, IDEOptionsIntf, IDEWindowIntf, EnvironmentOpts, IDEOptionDefs, InterfaceBase, LazarusIDEStrConsts; @@ -72,6 +72,8 @@ type function GetLayoutCaption(ALayout: TSimpleWindowLayout): String; property Layout: TSimpleWindowLayout read FLayout write SetLayout; public + constructor Create(TheOwner: TComponent); override; + destructor Destroy; override; function GetTitle: String; override; procedure Setup(ADialog: TAbstractOptionsEditorDialog); override; procedure ReadSettings(AOptions: TAbstractIDEOptions); override; @@ -91,10 +93,6 @@ begin end; procedure TWindowOptionsFrame.Setup(ADialog: TAbstractOptionsEditorDialog); -var - i: Integer; - Creator: TIDEWindowCreator; - j: Integer; begin // windows SingleTaskBarButtonCheckBox.Caption := dlgSingleTaskBarButton; @@ -108,22 +106,42 @@ begin ProjectDirInIdeTitleCheckBox.Caption:=lisIDEProjectDirInIdeTitle; ProjectDirInIdeTitleCheckBox.Hint:= lisProjectDirectoryIsShowedInIdeTitleBar; +end; + +procedure TWindowOptionsFrame.ReadSettings(AOptions: TAbstractIDEOptions); +var + Creator: TIDEWindowCreator; + i: Integer; + j: Integer; +begin + with AOptions as TEnvironmentOptions do + begin + // window minimizing and hiding + SingleTaskBarButtonCheckBox.Checked := SingleTaskBarButton; + HideIDEOnRunCheckBox.Checked := HideIDEOnRun; + HideMessagesIconsCheckBox.Checked := HideMessagesIcons; + TitleStartsWithProjectCheckBox.Checked:=IDETitleStartsWithProject; + ProjectDirInIdeTitleCheckBox.Checked:=IDEProjectDirectoryInIdeTitle; + + end; + + FLayouts.Assign(IDEWindowCreators.SimpleLayoutStorage); if IDEDockMaster=nil then begin // Window Positions - FLayouts:=EnvironmentOptions.IDEWindowLayoutList; + FLayouts.Assign(IDEWindowCreators.SimpleLayoutStorage); WindowPositionsGroupBox.Parent:=Self; WindowPositionsGroupBox.Caption := dlgWinPos; WindowPositionsListBox.Items.BeginUpdate; + WindowPositionsListBox.Items.Clear; // show all registered windows // Note: the layouts also contain forms, that were once registered and may be // registered in the future again for i:=0 to IDEWindowCreators.Count-1 do begin Creator:=IDEWindowCreators[i]; for j:=0 to FLayouts.Count-1 do begin - if CompareText(Creator.FormName,copy(FLayouts[j].FormID,1,length(Creator.FormName)))<>0 - then continue; - WindowPositionsListBox.Items.AddObject(GetLayoutCaption(FLayouts[j]),FLayouts[j]); + if Creator.NameFits(FLayouts[j].FormID) then + WindowPositionsListBox.Items.AddObject(GetLayoutCaption(FLayouts[j]),FLayouts[j]); end; end; WindowPositionsListBox.Items.EndUpdate; @@ -139,32 +157,20 @@ begin DefaultRadioButton.Caption := rsiwpDefault; RestoreWindowGeometryRadioButton.Caption := rsiwpRestoreWindowGeometry; CustomPositionRadioButton.Caption := rsiwpCustomPosition; + + SetWindowPositionsItem(0); end else begin WindowPositionsGroupBox.Parent:=nil; end; end; -procedure TWindowOptionsFrame.ReadSettings(AOptions: TAbstractIDEOptions); -begin - with AOptions as TEnvironmentOptions do - begin - FLayouts := IDEWindowLayoutList; - SetWindowPositionsItem(0); - - // window minimizing and hiding - SingleTaskBarButtonCheckBox.Checked := SingleTaskBarButton; - HideIDEOnRunCheckBox.Checked := HideIDEOnRun; - HideMessagesIconsCheckBox.Checked := HideMessagesIcons; - TitleStartsWithProjectCheckBox.Checked:=IDETitleStartsWithProject; - ProjectDirInIdeTitleCheckBox.Checked:=IDEProjectDirectoryInIdeTitle; - end; -end; - procedure TWindowOptionsFrame.WriteSettings(AOptions: TAbstractIDEOptions); begin + SaveLayout; + IDEWindowCreators.SimpleLayoutStorage.Assign(FLayouts); + with AOptions as TEnvironmentOptions do begin - SaveLayout; // window minimizing SingleTaskBarButton := SingleTaskBarButtonCheckBox.Checked; HideIDEOnRun:=HideIDEOnRunCheckBox.Checked; @@ -195,6 +201,7 @@ var begin FLayout := AValue; if Layout=nil then Exit; + //debugln(['TWindowOptionsFrame.SetLayout ',Layout.FormID,' ',IDEWindowPlacementNames[Layout.WindowPlacement]]); for APlacement := Low(TIDEWindowPlacement) to High(TIDEWindowPlacement) do begin @@ -308,7 +315,7 @@ var begin if Layout = nil then Exit; - + //debugln(['TWindowOptionsFrame.SaveLayout ',Layout.FormID]); for APlacement := Low(TIDEWindowPlacement) to High(TIDEWindowPlacement) do begin ARadioButton := GetPlacementRadioButtons(APlacement); @@ -369,6 +376,18 @@ begin Result:=ALayout.FormCaption; end; +constructor TWindowOptionsFrame.Create(TheOwner: TComponent); +begin + inherited Create(TheOwner); + FLayouts:=TSimpleWindowLayoutList.Create; +end; + +destructor TWindowOptionsFrame.Destroy; +begin + FreeAndNil(FLayouts); + inherited Destroy; +end; + class function TWindowOptionsFrame.SupportedOptionsClass: TAbstractIDEOptionsClass; begin Result := TEnvironmentOptions; diff --git a/ide/ideoptiondefs.pas b/ide/ideoptiondefs.pas index 00ebc3bb97..935b712218 100644 --- a/ide/ideoptiondefs.pas +++ b/ide/ideoptiondefs.pas @@ -145,123 +145,6 @@ const 'JumpHistory' ); -type - { TIDEWindowLayout stores information about the position, min/maximized state - and similar things for an IDE window or dialog, like the source editor, - the object inspector, the main bar or the message view. - } - TIDEWindowPlacement = ( - iwpUseWindowManagerSetting, // leave window position, where window manager - // creates the window - iwpDefault, // set window to the default position - iwpRestoreWindowGeometry, // save window geometry at end and restore it - // at start - iwpCustomPosition, // set window to custom position - iwpRestoreWindowSize // save window size at end and restore it - // at start - ); - TIDEWindowPlacements = set of TIDEWindowPlacement; - TIDEWindowState = (iwsNormal, iwsMaximized, iwsMinimized, iwsHidden); - TIDEWindowStates = set of TIDEWindowState; - - TSimpleWindowLayout = class; - TOnGetDefaultIDEWindowPos = procedure(Sender: TSimpleWindowLayout; - var Bounds: TRect) of object; - TOnApplySimpleWindowLayout = procedure(Layout: TSimpleWindowLayout) of object; - - { TSimpleWindowLayout } - - TSimpleWindowLayout = class(TComponent) - private - FApplied: boolean; - FFormCaption: string; - FVisible: boolean; - fWindowPlacement: TIDEWindowPlacement; - fLeft: integer; - fTop: integer; - fWidth: integer; - fHeight: integer; - fWindowState: TIDEWindowState; - fForm: TCustomForm; - fFormID: string; - fDefaultWindowPlacement: TIDEWindowPlacement; - function GetFormCaption: string; - function GetFormID: string; - procedure SetForm(const AValue: TCustomForm); - procedure OnFormClose(Sender: TObject; var CloseAction: TCloseAction); - protected - procedure Notification(AComponent: TComponent; Operation: TOperation); override; - public - constructor Create(AFormID: string); reintroduce; - destructor Destroy; override; - procedure Clear; - procedure GetCurrentPosition; - procedure Assign(Layout: TSimpleWindowLayout); reintroduce; - procedure ReadCurrentCoordinates; - procedure ReadCurrentState; - procedure LoadFromConfig(Config: TConfigStorage; const Path: string); - procedure SaveToConfig(Config: TConfigStorage; const Path: string); - function CustomCoordinatesAreValid: boolean; - procedure CloseForm; - public - property FormID: string read GetFormID write FFormID; - function FormBaseID(out SubIndex: Integer): String; // split FormID into name+number - property FormCaption: string read GetFormCaption; - property WindowPlacement: TIDEWindowPlacement read fWindowPlacement write FWindowPlacement; - property DefaultWindowPlacement: TIDEWindowPlacement - read fDefaultWindowPlacement write fDefaultWindowPlacement; - property Left: integer read fLeft write FLeft; - property Top: integer read fTop write FTop; - property Width: integer read fWidth write FWidth; - property Height: integer read fHeight write FHeight; - property WindowState: TIDEWindowState read fWindowState write FWindowState; - property Form: TCustomForm read fForm write SetForm; - property Visible: boolean read FVisible write FVisible; - property Applied: boolean read FApplied write FApplied; - end; - - { TSimpleWindowLayoutList } - - TSimpleWindowLayoutList = class - private - fItems: TFPList; - function GetItems(Index: Integer): TSimpleWindowLayout; - public - constructor Create; - destructor Destroy; override; - procedure Clear; - procedure Delete(Index: Integer); - procedure ApplyAndShow(Sender: TObject; AForm: TCustomForm; - BringToFront: boolean); - procedure StoreWindowPositions; - procedure Assign(SrcList: TSimpleWindowLayoutList); - function Add(ALayout: TSimpleWindowLayout): integer; - function IndexOf(const FormID: string): integer; - function ItemByForm(AForm: TCustomForm): TSimpleWindowLayout; - function ItemByFormID(const FormID: string): TSimpleWindowLayout; - function ItemByFormCaption(const aFormCaption: string): TSimpleWindowLayout; - procedure CloseForm(AForm: TCustomForm); - procedure LoadFromConfig(Config: TConfigStorage; const Path: string); - procedure SaveToConfig(Config: TConfigStorage; const Path: string); - public - function Count: integer; - property Items[Index: Integer]: TSimpleWindowLayout read GetItems; default; - end; - -const - IDEWindowPlacementNames: array[TIDEWindowPlacement] of string = ( - 'UseWindowManagerSetting', - 'Default', - 'RestoreWindowGeometry', - 'CustomPosition', - 'RestoreWindowSize' - ); - IDEWindowStateNames: array[TIDEWindowState] of string = ( - 'Normal', 'Maximized', 'Minimized', 'Hidden' - ); - -function StrToIDEWindowPlacement(const s: string): TIDEWindowPlacement; -function StrToIDEWindowState(const s: string): TIDEWindowState; function CreateNiceWindowPosition(Width, Height: integer): TRect; function NonModalIDEFormIDToEnum(const FormID: string): TNonModalIDEWindow; @@ -272,20 +155,6 @@ function GetLazIDEConfigStorage(const Filename: string; LoadFromDisk: Boolean implementation -function StrToIDEWindowPlacement(const s: string): TIDEWindowPlacement; -begin - for Result:=Low(TIDEWindowPlacement) to High(TIDEWindowPlacement) do - if AnsiCompareText(s,IDEWindowPlacementNames[Result])=0 then exit; - Result:=iwpDefault; -end; - -function StrToIDEWindowState(const s: string): TIDEWindowState; -begin - for Result:=Low(TIDEWindowState) to High(TIDEWindowState) do - if AnsiCompareText(s,IDEWindowStateNames[Result])=0 then exit; - Result:=iwsNormal; -end; - function CreateNiceWindowPosition(Width, Height: integer): TRect; function FindFormAt(x,y: integer): TCustomForm; @@ -368,492 +237,6 @@ begin Result:=TXMLOptionsStorage.Create(ConfigFilename,LoadFromDisk); end; -{ TSimpleWindowLayout } - -constructor TSimpleWindowLayout.Create(AFormID: string); -begin - inherited Create(nil); - FormID:=AFormID; - fDefaultWindowPlacement:=iwpRestoreWindowGeometry; - Clear; -end; - -destructor TSimpleWindowLayout.Destroy; -begin - Form:=nil; - inherited Destroy; -end; - -procedure TSimpleWindowLayout.LoadFromConfig(Config: TConfigStorage; - const Path: string); -var - P: string; -begin - // set all values to default - Clear; - // read settings - // build path - P:=FormID; - if P='' then exit; - P:=Path+P+'/'; - FFormCaption := Config.GetValue(P+'Caption/Value', fFormID); - // placement - fWindowPlacement:=StrToIDEWindowPlacement(Config.GetValue( - P+'WindowPlacement/Value',IDEWindowPlacementNames[fWindowPlacement])); - // custom position - fLeft:=Config.GetValue(P+'CustomPosition/Left',fLeft); - fTop:=Config.GetValue(P+'CustomPosition/Top',fTop); - fWidth:=Config.GetValue(P+'CustomPosition/Width',fWidth); - fHeight:=Config.GetValue(P+'CustomPosition/Height',fHeight); - // state - fWindowState:=StrToIDEWindowState(Config.GetValue( - P+'WindowState/Value',IDEWindowStateNames[fWindowState])); - FVisible:=Config.GetValue(P+'Visible/Value',false); -end; - -procedure TSimpleWindowLayout.SaveToConfig(Config: TConfigStorage; - const Path: string); -var - P: string; -begin - // build path - P:=FormID; - if P='' then exit; - P:=Path+P+'/'; - Config.SetDeleteValue(P+'Caption/Value',FFormCaption,''); - // placement - Config.SetDeleteValue(P+'WindowPlacement/Value', - IDEWindowPlacementNames[fWindowPlacement], - IDEWindowPlacementNames[iwpRestoreWindowSize]); - // custom position - Config.SetDeleteValue(P+'CustomPosition/Left',fLeft,0); - Config.SetDeleteValue(P+'CustomPosition/Top',fTop,0); - Config.SetDeleteValue(P+'CustomPosition/Width',fWidth,0); - Config.SetDeleteValue(P+'CustomPosition/Height',fHeight,0); - // state - Config.SetValue(P+'WindowState/Value',IDEWindowStateNames[fWindowState]); - Config.SetDeleteValue(P+'Visible/Value',FVisible,false); -end; - -procedure TSimpleWindowLayout.OnFormClose(Sender: TObject; - var CloseAction: TCloseAction); -begin - GetCurrentPosition; -end; - -procedure TSimpleWindowLayout.Notification(AComponent: TComponent; - Operation: TOperation); -begin - inherited Notification(AComponent, Operation); - if Operation=opRemove then begin - if fForm=AComponent then begin - fForm:=nil; - Applied:=false; - end; - end; -end; - -function TSimpleWindowLayout.CustomCoordinatesAreValid: boolean; -begin - Result:=(Width>0) and (Height>0) and (Left>10-Width) and (Top>10-Height); -end; - -procedure TSimpleWindowLayout.CloseForm; -begin - GetCurrentPosition; - Form:=nil; -end; - -function TSimpleWindowLayout.FormBaseID(out SubIndex: Integer): String; -var - i: Integer; -begin - Result := FormID; - SubIndex := -1; - i := length(Result); - while (i > 0) and (Result[i] in ['0'..'9']) do - dec(i); - if (i < 1) or (i = length(Result)) then - exit; - SubIndex := StrToInt(copy(Result, i+1, length(Result))); - Result := copy(Result, 1, i); -end; - -procedure TSimpleWindowLayout.SetForm(const AValue: TCustomForm); -begin - if fForm=AValue then exit; - if (Form<>nil) then begin - RemoveFreeNotification(Form); - Form.RemoveHandlerClose(@OnFormClose); - end; - fForm:=AValue; - if (Form<>nil) then begin - fFormID := Form.Name; - FFormCaption := Form.Caption; - FreeNotification(Form); - Applied:=false; - end; -end; - -function TSimpleWindowLayout.GetFormID: string; -begin - if Form=nil then - Result:=fFormID - else - Result:=Form.Name; -end; - -function TSimpleWindowLayout.GetFormCaption: string; -begin - if Form<>nil then - FFormCaption:=Form.Caption - else if FFormCaption='' then - FFormCaption:=FormID; - Result:=FFormCaption; -end; - -procedure TSimpleWindowLayout.Clear; -begin - fWindowPlacement:=fDefaultWindowPlacement; - fLeft:=0; - fTop:=0; - fWidth:=0; - fHeight:=0; - fWindowState:=iwsNormal; -end; - -procedure TSimpleWindowLayout.ReadCurrentCoordinates; -var - p: TPoint; -begin - if (Form<>nil) and (Form.WindowState=wsNormal) then begin - if Form.Parent<>nil then - p:=Form.ClientOrigin - else - p:=Point(0,0); - Left:=Form.Left+p.X; - Top:=Form.Top+p.Y; - Width:=Form.Width; - Height:=Form.Height; - end; -end; - -procedure TSimpleWindowLayout.ReadCurrentState; -begin - Visible:=(Form<>nil) and Form.IsVisible; - if Form<>nil then begin - case Form.WindowState of - wsMinimized: fWindowState:=iwsMinimized; - wsMaximized: fWindowState:=iwsMaximized; - else - fWindowState:=iwsNormal; - end; - end; -end; - -procedure TSimpleWindowLayout.Assign(Layout: TSimpleWindowLayout); -begin - Clear; - FApplied:=Layout.Applied; - Form:=Layout.Form; - fWindowPlacement:=Layout.fWindowPlacement; - fLeft:=Layout.fLeft; - fTop:=Layout.fTop; - fWidth:=Layout.fWidth; - fHeight:=Layout.fHeight; - fWindowState:=Layout.fWindowState; - fFormID:=Layout.fFormID; - fDefaultWindowPlacement:=Layout.fDefaultWindowPlacement; -end; - -procedure TSimpleWindowLayout.GetCurrentPosition; -begin - //debugln('TSimpleWindowLayout.GetCurrentPosition ',DbgSName(Self),' ',FormID,' ',IDEWindowPlacementNames[WindowPlacement]); - case WindowPlacement of - iwpRestoreWindowGeometry, iwpRestoreWindowSize: - ReadCurrentCoordinates; - end; - ReadCurrentState; - //debugln('TSimpleWindowLayout.GetCurrentPosition ',DbgSName(Self),' ',FormID,' Width=',dbgs(Width)); -end; - -{ TSimpleWindowLayoutList } - -procedure TSimpleWindowLayoutList.Clear; -var i: integer; -begin - for i:=0 to Count-1 do Items[i].Free; - fItems.Clear; -end; - -procedure TSimpleWindowLayoutList.Delete(Index: Integer); -begin - Items[Index].Free; - fItems.Delete(Index); -end; - -function TSimpleWindowLayoutList.GetItems(Index: Integer): TSimpleWindowLayout; -begin - Result:=TSimpleWindowLayout(fItems[Index]); -end; - -constructor TSimpleWindowLayoutList.Create; -begin - fItems:=TFPList.Create; -end; - -destructor TSimpleWindowLayoutList.Destroy; -begin - Clear; - FreeAndNil(fItems); - inherited Destroy; -end; - -function TSimpleWindowLayoutList.IndexOf(const FormID: string): integer; -begin - Result:=Count-1; - while (Result>=0) and (FormID<>Items[Result].GetFormID) do dec(Result); -end; - -procedure TSimpleWindowLayoutList.LoadFromConfig(Config: TConfigStorage; - const Path: string); -var i: integer; -begin - for i:=0 to Count-1 do - Items[i].LoadFromConfig(Config,Path); -end; - -procedure TSimpleWindowLayoutList.SaveToConfig(Config: TConfigStorage; - const Path: string); -var i: integer; -begin - Config.SetDeleteValue(Path+'FormIdCount',Count,0); - for i:=0 to Count-1 do - Items[i].SaveToConfig(Config,Path); -end; - -function TSimpleWindowLayoutList.Count: integer; -begin - Result:=fItems.Count; -end; - -function TSimpleWindowLayoutList.ItemByForm(AForm: TCustomForm): TSimpleWindowLayout; -var i: integer; -begin - i:=Count-1; - while (i>=0) do begin - Result:=Items[i]; - if Result.Form=AForm then exit; - dec(i); - end; - Result:=nil; -end; - -function TSimpleWindowLayoutList.ItemByFormID(const FormID: string - ): TSimpleWindowLayout; -var i: integer; -begin - i:=IndexOf(FormID); - if i>=0 then - Result:=Items[i] - else - Result:=nil; -end; - -function TSimpleWindowLayoutList.ItemByFormCaption(const aFormCaption: string - ): TSimpleWindowLayout; -var i: integer; -begin - i := Count - 1; - while i >= 0 do begin - Result := Items[i]; - if Result.FormCaption = aFormCaption then - exit; - dec(i); - end; - Result:=nil; -end; - -procedure TSimpleWindowLayoutList.CloseForm(AForm: TCustomForm); -var - ALayout: TSimpleWindowLayout; -begin - ALayout:=ItemByForm(AForm); - if ALayout<>nil then - ALayout.CloseForm; -end; - -procedure TSimpleWindowLayoutList.ApplyAndShow(Sender: TObject; - AForm: TCustomForm; BringToFront: boolean); -var - ALayout: TSimpleWindowLayout; - NewBounds: TRect; - Creator: TIDEWindowCreator; - DockSiblingName: string; - DockAlign: TAlign; - DockSibling: TCustomForm; - DockSiblingBounds: TRect; - Offset: TPoint; -begin - {$IFDEF VerboseIDEDocking} - debugln(['TSimpleWindowLayoutList.ApplyAndShow Form=',DbgSName(AForm),' ',BringToFront]); - {$ENDIF} - try - ALayout:=ItemByFormID(AForm.Name); - if ALayout<>nil then - begin - ALayout.Form:=AForm; - if ALayout.Applied then exit; - ALayout.Applied:=true; - {$IFDEF VerboseIDEDocking} - debugln(['TSimpleWindowLayoutList.ApplyAndShow restore ',ALayout.FormID,' ',IDEWindowPlacementNames[ALayout.WindowPlacement]]); - {$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<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); - // 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; - end; - - {$IFDEF VerboseIDEDocking} - debugln(['TSimpleWindowLayoutList.ApplyAndShow no stored layout found, layout registered=',ALayout<>nil,' AForm=',DbgSName(AForm)]); - {$ENDIF} - - // no layout found => use default - Creator:=IDEWindowCreators.FindWithName(AForm.Name); - if Creator<>nil then - begin - if Creator.OnGetLayout<>nil then - Creator.OnGetLayout(Self,AForm.Name,NewBounds,DockSiblingName,DockAlign) - else begin - Creator.GetDefaultBounds(AForm,NewBounds); - DockSiblingName:=Creator.DockSibling; - DockAlign:=Creator.DockAlign; - end; - {$IFDEF VerboseIDEDocking} - debugln(['TSimpleWindowLayoutList.ApplyAndShow creator found for ',DbgSName(AForm),': Left=',Creator.Left,' Top=',Creator.Top,' Right=',Creator.Right,' Bottom=',Creator.Bottom,' Creator.DockSibling=',Creator.DockSibling,' Creator.DockAlign=',dbgs(Creator.DockAlign),' NewBounds=',dbgs(NewBounds),' DockSibling=',DockSiblingName,' DockAlign=',dbgs(DockAlign)]); - {$ENDIF} - if DockSiblingName<>'' then - begin - DockSibling:=Screen.FindForm(DockSiblingName); - if DockSibling<>nil then - begin - DockSiblingBounds:=DockSibling.BoundsRect; - if DockSibling.Parent<>nil then - begin - Offset:=DockSibling.ClientToScreen(Point(0,0)); - OffsetRect(DockSiblingBounds,Offset.X,Offset.Y); - end; - case DockAlign of - alLeft: - begin - NewBounds.Top:=DockSiblingBounds.Top; - NewBounds.Bottom:=DockSiblingBounds.Bottom; - OffsetRect(NewBounds,DockSiblingBounds.Left-6-NewBounds.Right,0); - end; - alRight: - begin - NewBounds.Top:=DockSiblingBounds.Top; - NewBounds.Bottom:=DockSiblingBounds.Bottom; - OffsetRect(NewBounds,DockSiblingBounds.Right+6-NewBounds.Left,0); - end; - alTop: - begin - NewBounds.Left:=DockSiblingBounds.Left; - NewBounds.Right:=DockSiblingBounds.Right; - OffsetRect(NewBounds,0,DockSiblingBounds.Top-25-NewBounds.Bottom); - end; - alBottom: - begin - NewBounds.Left:=DockSiblingBounds.Left; - NewBounds.Right:=DockSiblingBounds.Right; - OffsetRect(NewBounds,0,DockSiblingBounds.Bottom+25-NewBounds.Top); - end; - alClient: - NewBounds:=DockSibling.BoundsRect; - end; - end; - end; - {$IFDEF VerboseIDEDocking} - debugln(['TSimpleWindowLayoutList.ApplyAndShow ',DbgSName(AForm),' NewBounds=',dbgs(NewBounds)]); - {$ENDIF} - NewBounds.Left:=Min(10000,Max(-10000,NewBounds.Left)); - NewBounds.Top:=Min(10000,Max(-10000,NewBounds.Top)); - NewBounds.Right:=Max(NewBounds.Left+100,NewBounds.Right); - NewBounds.Bottom:=Max(NewBounds.Top+100,NewBounds.Bottom); - AForm.BoundsRect:=NewBounds; - end; - finally - if (AForm.WindowState in [wsNormal,wsMaximized]) and BringToFront then - AForm.ShowOnTop - else - AForm.Visible:=true; - end; -end; - -procedure TSimpleWindowLayoutList.StoreWindowPositions; -var i: integer; -begin - for i:=0 to Count-1 do - Items[i].GetCurrentPosition; -end; - -procedure TSimpleWindowLayoutList.Assign(SrcList: TSimpleWindowLayoutList); -var i: integer; - NewLayout: TSimpleWindowLayout; -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); - end; -end; - -function TSimpleWindowLayoutList.Add(ALayout: TSimpleWindowLayout): integer; -begin - Result:=fItems.Add(ALayout); -end; - { TXMLOptionsStorage } function TXMLOptionsStorage.GetFullPathValue(const APath, ADefault: String): String; diff --git a/ide/main.pp b/ide/main.pp index 55aa135f53..1ee0dd853c 100644 --- a/ide/main.pp +++ b/ide/main.pp @@ -1223,7 +1223,7 @@ begin Application.ShowButtonGlyphs := ShowButtonGlyphs; Application.ShowMenuGlyphs := ShowMenuGlyphs; end; - IDEWindowCreators.OnShowForm:=@EnvironmentOptions.IDEWindowLayoutList.ApplyAndShow; + IDEWindowCreators.OnShowForm:=@IDEWindowCreators.SimpleLayoutStorage.ApplyAndShow; UpdateDefaultPascalFileExtensions; EditorOpts := TEditorOptions.Create; @@ -1308,7 +1308,7 @@ begin FormCreator:=IDEWindowCreators.Add(MainIDEBar.Name); FormCreator.Right:='100%'; FormCreator.Bottom:='+90'; - Layout:=EnvironmentOptions.IDEWindowLayoutList.ItemByFormID(MainIDEBar.Name); + Layout:=IDEWindowCreators.SimpleLayoutStorage.ItemByFormID(MainIDEBar.Name); if not (Layout.WindowState in [iwsNormal,iwsMaximized]) then Layout.WindowState:=iwsNormal; if IDEDockMaster<>nil then @@ -2234,8 +2234,8 @@ begin DoCallNotifyHandler(lihtIDERestoreWindows); if IDEDockMaster<>nil then exit; - for i:=0 to EnvironmentOptions.IDEWindowLayoutList.Count-1 do begin - ALayout:=EnvironmentOptions.IDEWindowLayoutList[i]; + for i:=0 to IDEWindowCreators.SimpleLayoutStorage.Count-1 do begin + ALayout:=IDEWindowCreators.SimpleLayoutStorage[i]; if not ALayout.Visible then continue; AForm:=IDEWindowCreators.GetForm(ALayout.FormID,true); if AForm=nil then continue; @@ -4227,8 +4227,8 @@ end; procedure TMainIDE.SaveDesktopSettings( TheEnvironmentOptions: TEnvironmentOptions); begin + IDEWindowCreators.SimpleLayoutStorage.StoreWindowPositions; with TheEnvironmentOptions do begin - IDEWindowLayoutList.StoreWindowPositions; ObjectInspectorOptions.Assign(ObjectInspector1); end; end; @@ -12718,7 +12718,7 @@ begin if SourceEditorManager.SourceWindowCount = 0 then exit; SrcNoteBook := SourceEditorManager.SourceWindows[0]; - Layout:=EnvironmentOptions.IDEWindowLayoutList.ItemByFormID(SrcNoteBook.Name); + Layout:=IDEWindowCreators.SimpleLayoutStorage.ItemByFormID(SrcNoteBook.Name); if (Layout<>nil) and (Layout.WindowPlacement=iwpDefault) and ((SrcNoteBook.Top + SrcNoteBook.Height) > MessagesView.Top) and (MessagesView.Parent = nil) then @@ -15916,7 +15916,6 @@ end; procedure TMainIDE.OnScreenRemoveForm(Sender: TObject; AForm: TCustomForm); begin HiddenWindowsOnRun.Remove(AForm); - EnvironmentOptions.IDEWindowLayoutList.CloseForm(AForm); end; procedure TMainIDE.OnRemoteControlTimer(Sender: TObject); diff --git a/ide/sourceeditor.pp b/ide/sourceeditor.pp index 56987830ae..c9ed44a8b6 100644 --- a/ide/sourceeditor.pp +++ b/ide/sourceeditor.pp @@ -4816,7 +4816,6 @@ constructor TSourceNotebook.Create(AOwner: TComponent); var i: Integer; n: TComponent; - Layout: TSimpleWindowLayout; begin inherited Create(AOwner); FManager := TSourceEditorManager(AOwner); @@ -4842,16 +4841,6 @@ begin KeyPreview:=true; FProcessingCommand := false; - Layout:=EnvironmentOptions.IDEWindowLayoutList.ItemByFormID(self.Name); - if Layout = nil then - begin - Layout:=EnvironmentOptions.CreateWindowLayout(self); - Layout.Clear; - end else - begin - Layout.Form:=Self; - end; - FSourceEditorList := TList.Create; // key mapping @@ -5681,7 +5670,7 @@ begin if PageCount = 0 then begin { $NOTE maybe keep the last one} // Make the name unique, because it may not immediately be released // disconnect first - Layout:=EnvironmentOptions.IDEWindowLayoutList.ItemByForm(Self); + Layout:=IDEWindowCreators.SimpleLayoutStorage.ItemByForm(Self); if Layout<>nil then Layout.Form:=nil; Name := Name + '___' + IntToStr(PtrUInt(Pointer(Self))); diff --git a/ide/unitdependencies.lfm b/ide/unitdependencies.lfm index 493d2c255d..9cc4df6cda 100644 --- a/ide/unitdependencies.lfm +++ b/ide/unitdependencies.lfm @@ -8,9 +8,8 @@ object UnitDependenciesView: TUnitDependenciesView ClientHeight = 300 ClientWidth = 400 KeyPreview = True - OnClose = UnitDependenciesViewClose Position = poScreenCenter - LCLVersion = '0.9.27' + LCLVersion = '0.9.29' object ToolBar: TToolBar Left = 0 Height = 48 @@ -24,7 +23,7 @@ object UnitDependenciesView: TUnitDependenciesView ShowHint = True TabOrder = 0 object ShowProjectButton: TToolButton - Left = 167 + Left = 219 Top = 2 Caption = 'ShowProjectButton' OnClick = ShowProjectButtonClick @@ -36,7 +35,7 @@ object UnitDependenciesView: TUnitDependenciesView OnClick = SelectUnitButtonClick end object RefreshButton: TToolButton - Left = 89 + Left = 119 Top = 2 Caption = 'RefreshButton' OnClick = RefreshButtonClick @@ -44,14 +43,12 @@ object UnitDependenciesView: TUnitDependenciesView end object UnitHistoryList: TComboBox Left = 6 - Height = 21 + Height = 27 Top = 54 Width = 388 Align = alTop - AutoComplete = False BorderSpacing.Around = 6 - ItemHeight = 13 - ItemWidth = 0 + ItemHeight = 0 OnEditingDone = UnitHistoryListEditingDone TabOrder = 1 Text = 'UnitHistoryList' @@ -61,10 +58,10 @@ object UnitDependenciesView: TUnitDependenciesView AnchorSideRight.Side = asrBottom AnchorSideBottom.Control = Owner AnchorSideBottom.Side = asrBottom - Left = 319 - Height = 26 - Top = 268 - Width = 75 + Left = 309 + Height = 30 + Top = 264 + Width = 85 Anchors = [akRight, akBottom] AutoSize = True BorderSpacing.Around = 6 @@ -77,13 +74,13 @@ object UnitDependenciesView: TUnitDependenciesView object UnitTreeView: TTreeView AnchorSideBottom.Control = CloseButton Left = 6 - Height = 181 - Top = 81 + Height = 171 + Top = 87 Width = 388 Align = alTop Anchors = [akTop, akLeft, akRight, akBottom] BorderSpacing.Around = 6 - DefaultItemHeight = 15 + DefaultItemHeight = 19 ReadOnly = True TabOrder = 3 OnAdvancedCustomDrawItem = UnitTreeViewAdvancedCustomDrawItem diff --git a/ide/unitdependencies.pas b/ide/unitdependencies.pas index cf0590acc4..ab8791c963 100644 --- a/ide/unitdependencies.pas +++ b/ide/unitdependencies.pas @@ -155,8 +155,6 @@ type procedure RefreshButtonClick(Sender: TObject); procedure SelectUnitButtonClick(Sender: TObject); procedure ShowProjectButtonClick(Sender: TObject); - procedure UnitDependenciesViewClose(Sender: TObject; - var CloseAction: TCloseAction); procedure UnitHistoryListEditingDone(Sender: TObject); procedure UnitTreeViewAdvancedCustomDrawItem(Sender: TCustomTreeView; Node: TTreeNode; State: TCustomDrawState; Stage: TCustomDrawStage; @@ -263,12 +261,6 @@ begin end; end; -procedure TUnitDependenciesView.UnitDependenciesViewClose(Sender: TObject; - var CloseAction: TCloseAction); -begin - EnvironmentOptions.IDEWindowLayoutList.ItemByForm(Self).GetCurrentPosition; -end; - procedure TUnitDependenciesView.UnitHistoryListEditingDone(Sender: TObject); begin //DebugLn('TUnitDependenciesView.UnitHistoryListEditingDone ',UnitHistoryList.Text,' ',dbgs(UnitHistoryList.Items.IndexOf(UnitHistoryList.Text))); diff --git a/ideintf/idewindowintf.pas b/ideintf/idewindowintf.pas index 1fc5b7e679..6eca89ae9c 100644 --- a/ideintf/idewindowintf.pas +++ b/ideintf/idewindowintf.pas @@ -23,7 +23,7 @@ unit IDEWindowIntf; interface uses - Classes, SysUtils, LCLProc, LazConfigStorage, Forms, Controls; + Math, Classes, SysUtils, LCLProc, LazConfigStorage, Forms, Controls; //---------------------------------------------------------------------------- // layout settings of modal forms (dialogs) in the IDE @@ -104,6 +104,122 @@ type var IDEDialogLayoutList: TIDEDialogLayoutList = nil;// set by the IDE +type + { TIDEWindowLayout stores information about the position, min/maximized state + and similar things for an IDE window or dialog, like the source editor, + the object inspector, the main bar or the message view. + } + TIDEWindowPlacement = ( + iwpUseWindowManagerSetting, // leave window position, where window manager + // creates the window + iwpDefault, // set window to the default position + iwpRestoreWindowGeometry, // save window geometry at end and restore it + // at start + iwpCustomPosition, // set window to custom position + iwpRestoreWindowSize // save window size at end and restore it + // at start + ); + TIDEWindowPlacements = set of TIDEWindowPlacement; + TIDEWindowState = (iwsNormal, iwsMaximized, iwsMinimized, iwsHidden); + TIDEWindowStates = set of TIDEWindowState; + + { TSimpleWindowLayout } + + TSimpleWindowLayout = class(TComponent) + private + FApplied: boolean; + FFormCaption: string; + FVisible: boolean; + fWindowPlacement: TIDEWindowPlacement; + fLeft: integer; + fTop: integer; + fWidth: integer; + fHeight: integer; + fWindowState: TIDEWindowState; + fForm: TCustomForm; + fFormID: string; + fDefaultWindowPlacement: TIDEWindowPlacement; + function GetFormCaption: string; + function GetFormID: string; + procedure SetForm(const AValue: TCustomForm); + procedure OnFormClose(Sender: TObject; var CloseAction: TCloseAction); + protected + procedure Notification(AComponent: TComponent; Operation: TOperation); override; + public + constructor Create(AFormID: string); reintroduce; + destructor Destroy; override; + procedure Clear; + procedure GetCurrentPosition; + procedure Assign(Layout: TSimpleWindowLayout); reintroduce; + procedure ReadCurrentCoordinates; + procedure ReadCurrentState; + procedure LoadFromConfig(Config: TConfigStorage; const Path: string); + procedure SaveToConfig(Config: TConfigStorage; const Path: string); + function CustomCoordinatesAreValid: boolean; + procedure CloseForm; + public + property FormID: string read GetFormID write FFormID; + function FormBaseID(out SubIndex: Integer): String; // split FormID into name+number + property FormCaption: string read GetFormCaption; + property WindowPlacement: TIDEWindowPlacement read fWindowPlacement write FWindowPlacement; + property DefaultWindowPlacement: TIDEWindowPlacement + read fDefaultWindowPlacement write fDefaultWindowPlacement; + property Left: integer read fLeft write FLeft; + property Top: integer read fTop write FTop; + property Width: integer read fWidth write FWidth; + property Height: integer read fHeight write FHeight; + property WindowState: TIDEWindowState read fWindowState write FWindowState; + property Form: TCustomForm read fForm write SetForm; + property Visible: boolean read FVisible write FVisible; + property Applied: boolean read FApplied write FApplied; + end; + + { TSimpleWindowLayoutList } + + TSimpleWindowLayoutList = class + private + fItems: TFPList; + function GetItems(Index: Integer): TSimpleWindowLayout; + procedure OnScreenRemoveForm(Sender: TObject; AForm: TCustomForm); + public + constructor Create; + destructor Destroy; override; + procedure Clear; + procedure Delete(Index: Integer); + procedure ApplyAndShow(Sender: TObject; AForm: TCustomForm; + BringToFront: boolean); + procedure StoreWindowPositions; + procedure Assign(SrcList: TSimpleWindowLayoutList); + function Add(ALayout: TSimpleWindowLayout): integer; + function CreateWindowLayout(const TheFormID: string): TSimpleWindowLayout; + function CreateWindowLayout(const TheForm: TCustomForm): TSimpleWindowLayout; + function IndexOf(const FormID: string): integer; + function ItemByForm(AForm: TCustomForm): TSimpleWindowLayout; + function ItemByFormID(const FormID: string): TSimpleWindowLayout; + function ItemByFormCaption(const aFormCaption: string): TSimpleWindowLayout; + procedure CloseForm(AForm: TCustomForm); + procedure LoadFromConfig(Config: TConfigStorage; const Path: string); + procedure SaveToConfig(Config: TConfigStorage; const Path: string); + public + function Count: integer; + property Items[Index: Integer]: TSimpleWindowLayout read GetItems; default; + end; + +const + IDEWindowPlacementNames: array[TIDEWindowPlacement] of string = ( + 'UseWindowManagerSetting', + 'Default', + 'RestoreWindowGeometry', + 'CustomPosition', + 'RestoreWindowSize' + ); + IDEWindowStateNames: array[TIDEWindowState] of string = ( + 'Normal', 'Maximized', 'Minimized', 'Hidden' + ); + +function StrToIDEWindowPlacement(const s: string): TIDEWindowPlacement; +function StrToIDEWindowState(const s: string): TIDEWindowState; + type TIWCState = ( iwcsHidden, @@ -156,6 +272,7 @@ type 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; property OnCreateFormProc: TCreateIDEWindowProc read FCreateFormProc write FCreateFormProc; + function NameFits(const AName: string): boolean; // hints for the layout system / dock master. It may ignore them completely. property State: TIWCState read FState write FState; @@ -177,6 +294,7 @@ type private fItems: TFPList; // list of TIDEWindowCreator FOnShowForm: TShowIDEWindowEvent; + FSimpleLayoutStorage: TSimpleWindowLayoutList; function GetItems(Index: integer): TIDEWindowCreator; procedure ErrorIfFormExists(FormName: string); public @@ -209,6 +327,8 @@ type DoDisableAutoSizing: boolean; TheOwner: TComponent); // utility function to create a form with delayed autosizing property OnShowForm: TShowIDEWindowEvent read FOnShowForm write FOnShowForm; // set by the IDE to implement a default + + property SimpleLayoutStorage: TSimpleWindowLayoutList read FSimpleLayoutStorage; end; var @@ -237,6 +357,20 @@ procedure Register; implementation +function StrToIDEWindowPlacement(const s: string): TIDEWindowPlacement; +begin + for Result:=Low(TIDEWindowPlacement) to High(TIDEWindowPlacement) do + if AnsiCompareText(s,IDEWindowPlacementNames[Result])=0 then exit; + Result:=iwpDefault; +end; + +function StrToIDEWindowState(const s: string): TIDEWindowState; +begin + for Result:=Low(TIDEWindowState) to High(TIDEWindowState) do + if AnsiCompareText(s,IDEWindowStateNames[Result])=0 then exit; + Result:=iwsNormal; +end; + procedure MakeIDEWindowDockable(AControl: TWinControl); begin if Assigned(IDEDockMaster) then @@ -522,6 +656,533 @@ begin inherited Destroy; end; +{ TSimpleWindowLayout } + +constructor TSimpleWindowLayout.Create(AFormID: string); +begin + inherited Create(nil); + FormID:=AFormID; + fDefaultWindowPlacement:=iwpRestoreWindowGeometry; + Clear; +end; + +destructor TSimpleWindowLayout.Destroy; +begin + Form:=nil; + inherited Destroy; +end; + +procedure TSimpleWindowLayout.LoadFromConfig(Config: TConfigStorage; + const Path: string); +var + P: string; +begin + // set all values to default + Clear; + // read settings + // build path + P:=FormID; + if P='' then exit; + P:=Path+P+'/'; + FFormCaption := Config.GetValue(P+'Caption/Value', fFormID); + // placement + fWindowPlacement:=StrToIDEWindowPlacement(Config.GetValue( + P+'WindowPlacement/Value',IDEWindowPlacementNames[fWindowPlacement])); + // custom position + fLeft:=Config.GetValue(P+'CustomPosition/Left',fLeft); + fTop:=Config.GetValue(P+'CustomPosition/Top',fTop); + fWidth:=Config.GetValue(P+'CustomPosition/Width',fWidth); + fHeight:=Config.GetValue(P+'CustomPosition/Height',fHeight); + // state + fWindowState:=StrToIDEWindowState(Config.GetValue( + P+'WindowState/Value',IDEWindowStateNames[fWindowState])); + FVisible:=Config.GetValue(P+'Visible/Value',false); +end; + +procedure TSimpleWindowLayout.SaveToConfig(Config: TConfigStorage; + const Path: string); +var + P: string; +begin + // build path + P:=FormID; + if P='' then exit; + P:=Path+P+'/'; + Config.SetDeleteValue(P+'Caption/Value',FFormCaption,''); + // placement + Config.SetDeleteValue(P+'WindowPlacement/Value', + IDEWindowPlacementNames[fWindowPlacement], + IDEWindowPlacementNames[iwpRestoreWindowSize]); + // custom position + Config.SetDeleteValue(P+'CustomPosition/Left',fLeft,0); + Config.SetDeleteValue(P+'CustomPosition/Top',fTop,0); + Config.SetDeleteValue(P+'CustomPosition/Width',fWidth,0); + Config.SetDeleteValue(P+'CustomPosition/Height',fHeight,0); + // state + Config.SetValue(P+'WindowState/Value',IDEWindowStateNames[fWindowState]); + Config.SetDeleteValue(P+'Visible/Value',FVisible,false); +end; + +procedure TSimpleWindowLayout.OnFormClose(Sender: TObject; + var CloseAction: TCloseAction); +begin + GetCurrentPosition; +end; + +procedure TSimpleWindowLayout.Notification(AComponent: TComponent; + Operation: TOperation); +begin + inherited Notification(AComponent, Operation); + if Operation=opRemove then begin + if fForm=AComponent then begin + fForm:=nil; + Applied:=false; + end; + end; +end; + +function TSimpleWindowLayout.CustomCoordinatesAreValid: boolean; +begin + Result:=(Width>0) and (Height>0) and (Left>10-Width) and (Top>10-Height); +end; + +procedure TSimpleWindowLayout.CloseForm; +begin + GetCurrentPosition; + Form:=nil; +end; + +function TSimpleWindowLayout.FormBaseID(out SubIndex: Integer): String; +var + i: Integer; +begin + Result := FormID; + SubIndex := -1; + i := length(Result); + while (i > 0) and (Result[i] in ['0'..'9']) do + dec(i); + if (i < 1) or (i = length(Result)) then + exit; + SubIndex := StrToInt(copy(Result, i+1, length(Result))); + Result := copy(Result, 1, i); +end; + +procedure TSimpleWindowLayout.SetForm(const AValue: TCustomForm); +begin + if fForm=AValue then exit; + if (Form<>nil) then begin + RemoveFreeNotification(Form); + Form.RemoveHandlerClose(@OnFormClose); + end; + fForm:=AValue; + if (Form<>nil) then begin + fFormID := Form.Name; + FFormCaption := Form.Caption; + FreeNotification(Form); + Applied:=false; + end; +end; + +function TSimpleWindowLayout.GetFormID: string; +begin + if Form=nil then + Result:=fFormID + else + Result:=Form.Name; +end; + +function TSimpleWindowLayout.GetFormCaption: string; +begin + if Form<>nil then + FFormCaption:=Form.Caption + else if FFormCaption='' then + FFormCaption:=FormID; + Result:=FFormCaption; +end; + +procedure TSimpleWindowLayout.Clear; +begin + fWindowPlacement:=fDefaultWindowPlacement; + fLeft:=0; + fTop:=0; + fWidth:=0; + fHeight:=0; + fWindowState:=iwsNormal; +end; + +procedure TSimpleWindowLayout.ReadCurrentCoordinates; +var + p: TPoint; +begin + if (Form<>nil) and (Form.WindowState=wsNormal) then begin + if Form.Parent<>nil then + p:=Form.ClientOrigin + else + p:=Point(0,0); + Left:=Form.Left+p.X; + Top:=Form.Top+p.Y; + Width:=Form.Width; + Height:=Form.Height; + end; +end; + +procedure TSimpleWindowLayout.ReadCurrentState; +begin + Visible:=(Form<>nil) and Form.IsVisible; + if Form<>nil then begin + case Form.WindowState of + wsMinimized: fWindowState:=iwsMinimized; + wsMaximized: fWindowState:=iwsMaximized; + else + fWindowState:=iwsNormal; + end; + end; +end; + +procedure TSimpleWindowLayout.Assign(Layout: TSimpleWindowLayout); +begin + Clear; + FApplied:=Layout.Applied; + Form:=Layout.Form; + fWindowPlacement:=Layout.fWindowPlacement; + fLeft:=Layout.fLeft; + fTop:=Layout.fTop; + fWidth:=Layout.fWidth; + fHeight:=Layout.fHeight; + fWindowState:=Layout.fWindowState; + fFormID:=Layout.fFormID; + fDefaultWindowPlacement:=Layout.fDefaultWindowPlacement; +end; + +procedure TSimpleWindowLayout.GetCurrentPosition; +begin + //debugln('TSimpleWindowLayout.GetCurrentPosition ',DbgSName(Self),' ',FormID,' ',IDEWindowPlacementNames[WindowPlacement]); + case WindowPlacement of + iwpRestoreWindowGeometry, iwpRestoreWindowSize: + ReadCurrentCoordinates; + end; + ReadCurrentState; + //debugln('TSimpleWindowLayout.GetCurrentPosition ',DbgSName(Self),' ',FormID,' Width=',dbgs(Width)); +end; + +{ TSimpleWindowLayoutList } + +procedure TSimpleWindowLayoutList.Clear; +var i: integer; +begin + for i:=0 to Count-1 do Items[i].Free; + fItems.Clear; +end; + +procedure TSimpleWindowLayoutList.Delete(Index: Integer); +begin + Items[Index].Free; + fItems.Delete(Index); +end; + +function TSimpleWindowLayoutList.GetItems(Index: Integer): TSimpleWindowLayout; +begin + Result:=TSimpleWindowLayout(fItems[Index]); +end; + +procedure TSimpleWindowLayoutList.OnScreenRemoveForm(Sender: TObject; + AForm: TCustomForm); +begin + CloseForm(AForm); +end; + +constructor TSimpleWindowLayoutList.Create; +begin + fItems:=TFPList.Create; + Screen.AddHandlerRemoveForm(@OnScreenRemoveForm); +end; + +destructor TSimpleWindowLayoutList.Destroy; +begin + Screen.RemoveHandlerRemoveForm(@OnScreenRemoveForm); + Clear; + FreeAndNil(fItems); + inherited Destroy; +end; + +function TSimpleWindowLayoutList.IndexOf(const FormID: string): integer; +begin + Result:=Count-1; + while (Result>=0) and (FormID<>Items[Result].GetFormID) do dec(Result); +end; + +procedure TSimpleWindowLayoutList.LoadFromConfig(Config: TConfigStorage; + const Path: string); +var + i: integer; + Name: String; +begin + // do not clear, just add/replace the values from the config + + // create new windows + i := Config.GetValue(Path+'Desktop/FormIdCount', 0); + while i > 0 do begin + Name := Config.GetValue(Path+'Desktop/FormIdList/a'+IntToStr(i), ''); + if (Name <> '') and (IDEWindowCreators.SimpleLayoutStorage.ItemByFormID(Name) = nil) then + CreateWindowLayout(Name); + dec(i); + end; + + for i:=0 to Count-1 do + Items[i].LoadFromConfig(Config,Path); +end; + +procedure TSimpleWindowLayoutList.SaveToConfig(Config: TConfigStorage; + const Path: string); +var i: integer; +begin + Config.SetDeleteValue(Path+'FormIdCount',Count,0); + for i:=0 to Count-1 do begin + Config.SetDeleteValue(Path+'Desktop/FormIdList/a'+IntToStr(i+1),Items[i].Name,''); + Items[i].SaveToConfig(Config,Path); + end; +end; + +function TSimpleWindowLayoutList.Count: integer; +begin + Result:=fItems.Count; +end; + +function TSimpleWindowLayoutList.ItemByForm(AForm: TCustomForm): TSimpleWindowLayout; +var i: integer; +begin + i:=Count-1; + while (i>=0) do begin + Result:=Items[i]; + if Result.Form=AForm then exit; + dec(i); + end; + Result:=nil; +end; + +function TSimpleWindowLayoutList.ItemByFormID(const FormID: string + ): TSimpleWindowLayout; +var i: integer; +begin + i:=IndexOf(FormID); + if i>=0 then + Result:=Items[i] + else + Result:=nil; +end; + +function TSimpleWindowLayoutList.ItemByFormCaption(const aFormCaption: string + ): TSimpleWindowLayout; +var i: integer; +begin + i := Count - 1; + while i >= 0 do begin + Result := Items[i]; + if Result.FormCaption = aFormCaption then + exit; + dec(i); + end; + Result:=nil; +end; + +procedure TSimpleWindowLayoutList.CloseForm(AForm: TCustomForm); +var + ALayout: TSimpleWindowLayout; +begin + ALayout:=ItemByForm(AForm); + if ALayout<>nil then + ALayout.CloseForm; +end; + +procedure TSimpleWindowLayoutList.ApplyAndShow(Sender: TObject; + AForm: TCustomForm; BringToFront: boolean); +var + ALayout: TSimpleWindowLayout; + NewBounds: TRect; + Creator: TIDEWindowCreator; + DockSiblingName: string; + DockAlign: TAlign; + DockSibling: TCustomForm; + DockSiblingBounds: TRect; + Offset: TPoint; +begin + {$IFDEF VerboseIDEDocking} + debugln(['TSimpleWindowLayoutList.ApplyAndShow Form=',DbgSName(AForm),' ',BringToFront]); + {$ENDIF} + try + ALayout:=ItemByFormID(AForm.Name); + if ALayout<>nil then + begin + ALayout.Form:=AForm; + if ALayout.Applied then exit; + ALayout.Applied:=true; + {$IFDEF VerboseIDEDocking} + debugln(['TSimpleWindowLayoutList.ApplyAndShow restore ',ALayout.FormID,' ',IDEWindowPlacementNames[ALayout.WindowPlacement]]); + {$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<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); + // 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; + end; + + {$IFDEF VerboseIDEDocking} + debugln(['TSimpleWindowLayoutList.ApplyAndShow no stored layout found, layout registered=',ALayout<>nil,' AForm=',DbgSName(AForm)]); + {$ENDIF} + + // no layout found => use default + Creator:=IDEWindowCreators.FindWithName(AForm.Name); + if Creator<>nil then + begin + if Creator.OnGetLayout<>nil then + Creator.OnGetLayout(Self,AForm.Name,NewBounds,DockSiblingName,DockAlign) + else begin + Creator.GetDefaultBounds(AForm,NewBounds); + DockSiblingName:=Creator.DockSibling; + DockAlign:=Creator.DockAlign; + end; + {$IFDEF VerboseIDEDocking} + debugln(['TSimpleWindowLayoutList.ApplyAndShow creator found for ',DbgSName(AForm),': Left=',Creator.Left,' Top=',Creator.Top,' Right=',Creator.Right,' Bottom=',Creator.Bottom,' Creator.DockSibling=',Creator.DockSibling,' Creator.DockAlign=',dbgs(Creator.DockAlign),' NewBounds=',dbgs(NewBounds),' DockSibling=',DockSiblingName,' DockAlign=',dbgs(DockAlign)]); + {$ENDIF} + if DockSiblingName<>'' then + begin + DockSibling:=Screen.FindForm(DockSiblingName); + if DockSibling<>nil then + begin + DockSiblingBounds:=DockSibling.BoundsRect; + if DockSibling.Parent<>nil then + begin + Offset:=DockSibling.ClientToScreen(Point(0,0)); + OffsetRect(DockSiblingBounds,Offset.X,Offset.Y); + end; + case DockAlign of + alLeft: + begin + NewBounds.Top:=DockSiblingBounds.Top; + NewBounds.Bottom:=DockSiblingBounds.Bottom; + OffsetRect(NewBounds,DockSiblingBounds.Left-6-NewBounds.Right,0); + end; + alRight: + begin + NewBounds.Top:=DockSiblingBounds.Top; + NewBounds.Bottom:=DockSiblingBounds.Bottom; + OffsetRect(NewBounds,DockSiblingBounds.Right+6-NewBounds.Left,0); + end; + alTop: + begin + NewBounds.Left:=DockSiblingBounds.Left; + NewBounds.Right:=DockSiblingBounds.Right; + OffsetRect(NewBounds,0,DockSiblingBounds.Top-25-NewBounds.Bottom); + end; + alBottom: + begin + NewBounds.Left:=DockSiblingBounds.Left; + NewBounds.Right:=DockSiblingBounds.Right; + OffsetRect(NewBounds,0,DockSiblingBounds.Bottom+25-NewBounds.Top); + end; + alClient: + NewBounds:=DockSibling.BoundsRect; + end; + end; + end; + {$IFDEF VerboseIDEDocking} + debugln(['TSimpleWindowLayoutList.ApplyAndShow ',DbgSName(AForm),' NewBounds=',dbgs(NewBounds)]); + {$ENDIF} + NewBounds.Left:=Min(10000,Max(-10000,NewBounds.Left)); + NewBounds.Top:=Min(10000,Max(-10000,NewBounds.Top)); + NewBounds.Right:=Max(NewBounds.Left+100,NewBounds.Right); + NewBounds.Bottom:=Max(NewBounds.Top+100,NewBounds.Bottom); + AForm.BoundsRect:=NewBounds; + end; + finally + if (AForm.WindowState in [wsNormal,wsMaximized]) and BringToFront then + AForm.ShowOnTop + else + AForm.Visible:=true; + end; +end; + +procedure TSimpleWindowLayoutList.StoreWindowPositions; +var i: integer; +begin + for i:=0 to Count-1 do + Items[i].GetCurrentPosition; +end; + +procedure TSimpleWindowLayoutList.Assign(SrcList: TSimpleWindowLayoutList); +var i: integer; + NewLayout: TSimpleWindowLayout; +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); + end; +end; + +function TSimpleWindowLayoutList.Add(ALayout: TSimpleWindowLayout): integer; +begin + Result:=fItems.Add(ALayout); +end; + +function TSimpleWindowLayoutList.CreateWindowLayout(const TheFormID: string + ): TSimpleWindowLayout; +begin + if TheFormID='' then + raise Exception.Create('TEnvironmentOptions.CreateWindowLayout TheFormID empty'); + if ItemByFormID(TheFormID)<>nil then + raise Exception.Create('TEnvironmentOptions.CreateWindowLayout TheFormID exists'); + Result:=TSimpleWindowLayout.Create(TheFormID); + Add(Result); +end; + +function TSimpleWindowLayoutList.CreateWindowLayout(const TheForm: TCustomForm + ): TSimpleWindowLayout; +begin + Result:=CreateWindowLayout(TheForm.Name); + Result.Form:=TheForm; +end; + { TIDEWindowCreator } procedure TIDEWindowCreator.SetBottom(const AValue: string); @@ -638,6 +1299,11 @@ begin OnGetLayout:=GetLayoutEvent; end; +function TIDEWindowCreator.NameFits(const AName: string): boolean; +begin + Result:=CompareText(copy(AName,1,Length(FormName)),FormName)=0; +end; + { TIDEWindowCreatorList } function TIDEWindowCreatorList.GetItems(Index: integer @@ -655,12 +1321,14 @@ end; constructor TIDEWindowCreatorList.Create; begin fItems:=TFPList.Create; + FSimpleLayoutStorage:=TSimpleWindowLayoutList.Create; end; destructor TIDEWindowCreatorList.Destroy; begin Clear; FreeAndNil(fItems); + FreeAndNil(FSimpleLayoutStorage); inherited Destroy; end; @@ -712,17 +1380,10 @@ begin end; function TIDEWindowCreatorList.IndexOfName(FormName: string): integer; -var - Item: TIDEWindowCreator; begin Result:=Count-1; - while (Result>=0) do begin - Item:=Items[Result]; - if (SysUtils.CompareText(copy(FormName,1,length(Item.FormName)),Item.FormName)=0) - then - exit; + while (Result>=0) and not Items[Result].NameFits(FormName) do dec(Result); - end; end; function TIDEWindowCreatorList.FindWithName(FormName: string @@ -771,7 +1432,19 @@ end; procedure TIDEWindowCreatorList.ShowForm(AForm: TCustomForm; BringToFront: boolean); +var + Layout: TSimpleWindowLayout; begin + if (AForm.Name='') or (not IsValidIdent(AForm.Name)) then + raise Exception.Create('TIDEWindowCreatorList.ShowForm invalid form name '+AForm.Name); + + // auto create a storage for every shown form + Layout:=SimpleLayoutStorage.ItemByFormID(AForm.Name); + if Layout=nil then + SimpleLayoutStorage.CreateWindowLayout(AForm) + else + Layout.Form:=AForm; + if IDEDockMaster<>nil then IDEDockMaster.ShowForm(AForm,BringToFront) else if Assigned(OnShowForm) then