
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@708 8e941d3f-bd1b-0410-a28a-d453659cc2b4
255 lines
6.5 KiB
ObjectPascal
255 lines
6.5 KiB
ObjectPascal
unit mandocking;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Types,
|
|
Forms,
|
|
SysUtils,
|
|
Controls,
|
|
ExtCtrls,
|
|
ProjectIntf,
|
|
LazIDEIntf,
|
|
MenuIntf,
|
|
IDEMsgIntf,
|
|
SrcEditorIntf,
|
|
XMLConf;
|
|
|
|
procedure Register;
|
|
|
|
resourcestring
|
|
mnuDockMsgWindow = 'Dock "Messages" window';
|
|
|
|
implementation
|
|
|
|
type
|
|
TDockState = record
|
|
Docked : Boolean;
|
|
FloatRect : TRect;
|
|
FloatBrd : TFormBorderStyle;
|
|
DockSize : TSize;
|
|
end;
|
|
|
|
{ TManualDocker }
|
|
|
|
TManualDocker = class(TObject)
|
|
protected
|
|
procedure ChangeDocking(DockingEnabled: Boolean);
|
|
procedure LoadState(cfg: TXMLConfig; var Astate: TDockState; const StateName: string);
|
|
procedure SaveState(cfg: TXMLConfig; const Astate: TDockState; const StateName: string);
|
|
procedure LoadStates;
|
|
procedure SaveStates;
|
|
|
|
procedure AllocControls(AParent: TWinControl);
|
|
procedure RealignControls;
|
|
procedure UpdateDockState(var astate: TDockState; wnd: TWinControl);
|
|
public
|
|
ConfigPath : AnsiString;
|
|
split : TSplitter;
|
|
panel : TPanel;
|
|
MsgWnd : TDockState;
|
|
constructor Create;
|
|
destructor Destroy; override;
|
|
procedure OnCmdClick(Sender: TObject);
|
|
function OnProjectOpen(Sender: TObject; AProject: TLazProject): TModalResult;
|
|
end;
|
|
|
|
var
|
|
cmd : TIDEMenuCommand = nil;
|
|
docker : TManualDocker = nil;
|
|
|
|
const
|
|
DockCfgRoot = 'ManualDockConfig';
|
|
DockCfgXML = 'manualdockconfig.xml';
|
|
MsgDockedName = 'Messages';
|
|
|
|
{ TManualDocker }
|
|
|
|
function SafeRect(const c: TREct; MinWidth, MinHeight: Integer): TRect;
|
|
begin
|
|
Result := c;
|
|
if Result.Top < 0 then Result.Top := 0;
|
|
if Result.Left < 0 then Result.Left := 0;
|
|
if c.Right - c.Left < MinWidth then Result.Right := Result.Left + MinWidth;
|
|
if c.Bottom - c.Top < MinHeight then Result.Bottom := Result.Top + MinHeight;
|
|
end;
|
|
|
|
function Max(a, b: Integer): Integer;
|
|
begin
|
|
if a > b then Result := a
|
|
else Result := b;
|
|
end;
|
|
|
|
procedure TManualDocker.ChangeDocking(DockingEnabled: Boolean);
|
|
begin
|
|
if DockingEnabled then begin
|
|
if not Assigned(SourceEditorWindow) or not Assigned(IDEMessagesWindow) then Exit;
|
|
if not Assigned(panel) then AllocControls(SourceEditorWindow);
|
|
split.visible:=true;
|
|
panel.visible:=true;
|
|
with IDEMessagesWindow do
|
|
if IDEMessagesWindow.Parent = nil then begin
|
|
MsgWnd.FloatRect := Bounds(Left, Top, Width, Height);
|
|
MsgWnd.FloatBrd := IDEMessagesWindow.BorderStyle;
|
|
end;
|
|
IDEMessagesWindow.Parent := panel;
|
|
IDEMessagesWindow.Align := alClient;
|
|
IDEMessagesWindow.BorderStyle := bsNone;
|
|
IDEMessagesWindow.TabStop := false;
|
|
panel.Height := MsgWnd.DockSize.cy;
|
|
end else begin
|
|
if Assigned(panel) then begin
|
|
panel.visible := false;
|
|
UpdateDockState(MsgWnd, panel);
|
|
end;
|
|
if Assigned(split) then split.visible := false;
|
|
IDEMessagesWindow.Parent := nil;
|
|
with MsgWnd do begin
|
|
IDEMessagesWindow.BoundsRect := SafeRect(FloatRect,
|
|
Max(30, IDEMessagesWindow.ClientWidth), Max(30, IDEMessagesWindow.ClientHeight));
|
|
IDEMessagesWindow.BorderStyle := FloatBrd;
|
|
end;
|
|
IDEMessagesWindow.TabStop := true;
|
|
end;
|
|
MsgWnd.docked := DockingEnabled;
|
|
cmd.Checked := DockingEnabled;
|
|
end;
|
|
|
|
constructor TManualDocker.Create;
|
|
var
|
|
pths : array [0..1] of String;
|
|
i : Integer;
|
|
begin
|
|
pths[0]:= LazarusIDE.GetPrimaryConfigPath;
|
|
pths[1]:= LazarusIDE.GetSecondaryConfigPath;
|
|
for i := 0 to length(pths)-1 do begin
|
|
try
|
|
ConfigPath := IncludeTrailingPathDelimiter(pths[i])+DockCfgXML;
|
|
LoadStates;
|
|
Break;
|
|
except
|
|
end;
|
|
end;
|
|
MsgWnd.FloatBrd := bsToolWindow;
|
|
end;
|
|
|
|
destructor TManualDocker.Destroy;
|
|
begin
|
|
if Assigned(panel) then UpdateDockState(MsgWnd, panel);
|
|
SaveStates;
|
|
split.Free;
|
|
panel.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TManualDocker.OnCmdClick(Sender: TObject);
|
|
begin
|
|
ChangeDocking(not Cmd.Checked );
|
|
end;
|
|
|
|
function TManualDocker.OnProjectOpen(Sender: TObject; AProject: TLazProject): TModalResult;
|
|
begin
|
|
if MsgWnd.Docked then ChangeDocking(true);
|
|
Result := mrOK;
|
|
end;
|
|
|
|
function CreateXMLConfig(const xmlfile: string) : TXMLConfig;
|
|
begin
|
|
Result := TXMLConfig.Create(nil);
|
|
Result.RootName := DockCfgRoot;
|
|
Result.Filename := xmlfile;
|
|
end;
|
|
|
|
procedure TManualDocker.AllocControls(AParent: TWinControl);
|
|
begin
|
|
panel := TPanel.Create(nil);
|
|
panel.Parent := AParent;
|
|
panel.BorderStyle := bsNone;
|
|
|
|
split := TSplitter.Create(nil);
|
|
split.Parent := AParent;
|
|
|
|
RealignControls;
|
|
end;
|
|
|
|
procedure TManualDocker.RealignControls;
|
|
begin
|
|
panel.Align := alClient;
|
|
split.Align := alClient;
|
|
panel.Align := alBottom;
|
|
split.Align := alBottom;
|
|
end;
|
|
|
|
procedure TManualDocker.UpdateDockState(var astate: TDockState; wnd: TWinControl);
|
|
begin
|
|
astate.DockSize.cx := wnd.ClientWidth;
|
|
astate.DockSize.cy := wnd.ClientHeight;
|
|
end;
|
|
|
|
procedure TManualDocker.LoadState(cfg: TXMLConfig; var Astate: TDockState;
|
|
const StateName: string);
|
|
begin
|
|
AState.docked := cfg.GetValue(StateName+'/docked', false);
|
|
AState.FloatRect.Left := cfg.GetValue(StateName+'/float/left', -1);
|
|
AState.FloatRect.Top := cfg.GetValue(StateName+'/float/top', -1);
|
|
AState.FloatRect.Right := cfg.GetValue(StateName+'/float/right', -1);
|
|
AState.FloatRect.Bottom := cfg.GetValue(StateName+'/float/bottom', -1);
|
|
AState.DockSize.cx := cfg.GetValue(StateName+'/docked/cx', 30);
|
|
AState.DockSize.cy := cfg.GetValue(StateName+'/docked/cy', 50);
|
|
end;
|
|
|
|
procedure TManualDocker.SaveState(cfg: TXMLConfig; const Astate: TDockState; const StateName: string);
|
|
begin
|
|
cfg.SetValue(StateName+'/docked', AState.docked);
|
|
cfg.SetValue(StateName+'/float/left', AState.FloatRect.Left);
|
|
cfg.SetValue(StateName+'/float/top', AState.FloatRect.Top);
|
|
cfg.SetValue(StateName+'/float/right', AState.FloatRect.Right);
|
|
cfg.SetValue(StateName+'/float/bottom', AState.FloatRect.Bottom);
|
|
cfg.SetValue(StateName+'/docked/cx', AState.DockSize.cx);
|
|
cfg.SetValue(StateName+'/docked/cy', AState.DockSize.cy)
|
|
end;
|
|
|
|
procedure TManualDocker.LoadStates;
|
|
var
|
|
cfg : TXMLConfig;
|
|
begin
|
|
cfg := CreateXMLConfig(ConfigPath);
|
|
try
|
|
LoadState(cfg, MsgWnd, MsgDockedName)
|
|
finally
|
|
cfg.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TManualDocker.SaveStates;
|
|
var
|
|
cfg : TXMLConfig;
|
|
begin
|
|
cfg := CreateXMLConfig(ConfigPath);
|
|
try
|
|
try
|
|
SaveState(cfg, MsgWnd, MsgDockedName)
|
|
finally
|
|
cfg.Free;
|
|
end;
|
|
except
|
|
end;
|
|
end;
|
|
|
|
procedure Register;
|
|
begin
|
|
docker := TManualDocker.Create;
|
|
cmd := RegisterIDEMenuCommand(itmViewMainWindows, 'makeMessagesDocked', mnuDockMsgWindow, @docker.OnCmdClick, nil, nil, '');
|
|
LazarusIDE.AddHandlerOnProjectOpened(@docker.OnProjectOpen, false);
|
|
end;
|
|
|
|
initialization
|
|
|
|
finalization
|
|
docker.Free;
|
|
|
|
end.
|
|
|