You've already forked lazarus-ccr
manualdocker: fix the LCL resize endless loop, by doing resizing manually instead of Align. * Changed to manual controls alignment (of panel and splitter) by explicit setting top of each one; * fixed the initial state of the menu check box
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@2776 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
unit mandocking;
|
unit mandocking;
|
||||||
|
{$APPTYPE CONSOLE}
|
||||||
{$mode objfpc}{$H+}
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
interface
|
interface
|
||||||
@@ -30,6 +30,7 @@ type
|
|||||||
FloatRect : TRect;
|
FloatRect : TRect;
|
||||||
FloatBrd : TFormBorderStyle;
|
FloatBrd : TFormBorderStyle;
|
||||||
DockSize : TSize;
|
DockSize : TSize;
|
||||||
|
EverDocked : Boolean; // if "docking" has even been since start of IDE.
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TManualDocker }
|
{ TManualDocker }
|
||||||
@@ -38,6 +39,7 @@ type
|
|||||||
private
|
private
|
||||||
FCurrentSrcWin : TWinControl;
|
FCurrentSrcWin : TWinControl;
|
||||||
protected
|
protected
|
||||||
|
procedure AdjustControlsOrder;
|
||||||
function DoChangeDocking(DockingEnabled: Boolean): Boolean;
|
function DoChangeDocking(DockingEnabled: Boolean): Boolean;
|
||||||
procedure LoadState(cfg: TXMLConfig; var Astate: TDockState; const StateName: string);
|
procedure LoadState(cfg: TXMLConfig; var Astate: TDockState; const StateName: string);
|
||||||
procedure SaveState(cfg: TXMLConfig; const Astate: TDockState; const StateName: string);
|
procedure SaveState(cfg: TXMLConfig; const Astate: TDockState; const StateName: string);
|
||||||
@@ -46,8 +48,10 @@ type
|
|||||||
|
|
||||||
procedure AllocControls(AParent: TWinControl);
|
procedure AllocControls(AParent: TWinControl);
|
||||||
procedure DeallocControls;
|
procedure DeallocControls;
|
||||||
procedure RealignControls;
|
procedure ReallocControls;
|
||||||
procedure UpdateDockState(var astate: TDockState; wnd: TWinControl);
|
procedure UpdateDockState(var astate: TDockState; wnd: TWinControl);
|
||||||
|
procedure DoPanelResize;
|
||||||
|
procedure PanelResize(Sender: TObject);
|
||||||
|
|
||||||
procedure SourceWindowCreated(Sender: TObject);
|
procedure SourceWindowCreated(Sender: TObject);
|
||||||
procedure SourceWindowDestroyed(Sender: TObject);
|
procedure SourceWindowDestroyed(Sender: TObject);
|
||||||
@@ -88,9 +92,28 @@ begin
|
|||||||
else Result := b;
|
else Result := b;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TManualDocker.AdjustControlsOrder;
|
||||||
|
var
|
||||||
|
bar : TControl;
|
||||||
|
i:Integer;
|
||||||
|
begin
|
||||||
|
if not Assigned(FCurrentSrcWin) then Exit;
|
||||||
|
//HACK: the actual "bottom" controls are unknown!
|
||||||
|
bar:=nil;
|
||||||
|
for i:=0 to FCurrentSrcWin.ControlCount-1 do
|
||||||
|
if ((FCurrentSrcWin.Controls[i].Name='StatusBar') or (FCurrentSrcWin.Controls[i].ClassName='TStatusBar')) then begin
|
||||||
|
bar:=FCurrentSrcWin.Controls[i];
|
||||||
|
Break;
|
||||||
|
end;
|
||||||
|
split.Top:=bar.Top;
|
||||||
|
panel.Top:=split.Height+split.Top;
|
||||||
|
if Assigned(bar) then bar.Top:=panel.Top+panel.Height;
|
||||||
|
end;
|
||||||
|
|
||||||
function TManualDocker.DoChangeDocking(DockingEnabled:Boolean):Boolean;
|
function TManualDocker.DoChangeDocking(DockingEnabled:Boolean):Boolean;
|
||||||
var
|
var
|
||||||
i : Integer;
|
i : Integer;
|
||||||
|
wnd : TSourceEditorWindowInterface;
|
||||||
begin
|
begin
|
||||||
if DockingEnabled then begin
|
if DockingEnabled then begin
|
||||||
Result:=False;
|
Result:=False;
|
||||||
@@ -101,45 +124,46 @@ begin
|
|||||||
if not Assigned(panel) then
|
if not Assigned(panel) then
|
||||||
AllocControls(SourceEditorManagerIntf.ActiveSourceWindow);
|
AllocControls(SourceEditorManagerIntf.ActiveSourceWindow);
|
||||||
|
|
||||||
if panel.Parent <> SourceEditorManagerIntf.ActiveSourceWindow then begin
|
if IDEMessagesWindow.Parent = nil then begin
|
||||||
split.Parent:=SourceEditorManagerIntf.ActiveSourceWindow;
|
MsgWnd.FloatRect := IDEMessagesWindow.BoundsRect;
|
||||||
panel.Parent:=SourceEditorManagerIntf.ActiveSourceWindow;
|
MsgWnd.FloatBrd := IDEMessagesWindow.BorderStyle;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
split.visible:=true;
|
|
||||||
panel.visible:=true;
|
panel.visible:=true;
|
||||||
with IDEMessagesWindow do
|
split.visible:=true;
|
||||||
if IDEMessagesWindow.Parent = nil then begin
|
panel.Height:=MsgWnd.DockSize.cy;
|
||||||
MsgWnd.FloatRect := Bounds(Left, Top, Width, Height);
|
AdjustControlsOrder;
|
||||||
MsgWnd.FloatBrd := IDEMessagesWindow.BorderStyle;
|
|
||||||
end;
|
|
||||||
IDEMessagesWindow.Parent := panel;
|
|
||||||
IDEMessagesWindow.Align := alClient;
|
|
||||||
IDEMessagesWindow.BorderStyle := bsNone;
|
IDEMessagesWindow.BorderStyle := bsNone;
|
||||||
|
IDEMessagesWindow.Parent := panel;
|
||||||
|
|
||||||
|
// LCL fails with "infinite resize loop", using manual size adjustement instead
|
||||||
|
panel.OnResize:=@PanelResize;
|
||||||
|
DoPanelResize;
|
||||||
|
|
||||||
IDEMessagesWindow.TabStop := False;
|
IDEMessagesWindow.TabStop := False;
|
||||||
|
{ // this code has been used to keep the cursor back to the source code
|
||||||
|
// whenever IDE is focused back, instead of focusing a compiler message
|
||||||
for i := 0 to IDEMessagesWindow.ControlCount - 1 do
|
for i := 0 to IDEMessagesWindow.ControlCount - 1 do
|
||||||
if IDEMessagesWindow.Controls[i] is TWinControl then
|
if IDEMessagesWindow.Controls[i] is TWinControl then
|
||||||
TWinControl(IDEMessagesWindow.Controls[i]).TabStop := False;
|
TWinControl(IDEMessagesWindow.Controls[i]).TabStop := False;
|
||||||
panel.Height := MsgWnd.DockSize.cy;
|
}
|
||||||
Result:=True;
|
Result:=True;
|
||||||
end else begin
|
MsgWnd.EverDocked:=True;
|
||||||
|
end else if MsgWnd.EverDocked then begin
|
||||||
if Assigned(panel) then begin
|
if Assigned(panel) then begin
|
||||||
panel.visible := False;
|
panel.visible := False;
|
||||||
UpdateDockState(MsgWnd, panel);
|
UpdateDockState(MsgWnd, panel);
|
||||||
end;
|
end;
|
||||||
if Assigned(split) then split.visible := False;
|
if Assigned(split) then split.visible := False;
|
||||||
IDEMessagesWindow.Parent := nil;
|
IDEMessagesWindow.Parent := nil;
|
||||||
with MsgWnd do begin
|
IDEMessagesWindow.BoundsRect := SafeRect(MsgWnd.FloatRect,
|
||||||
IDEMessagesWindow.BoundsRect := SafeRect(FloatRect,
|
Max(30, IDEMessagesWindow.ClientWidth), Max(30, IDEMessagesWindow.ClientHeight));
|
||||||
Max(30, IDEMessagesWindow.ClientWidth), Max(30, IDEMessagesWindow.ClientHeight));
|
IDEMessagesWindow.BorderStyle := MsgWnd.FloatBrd;
|
||||||
IDEMessagesWindow.BorderStyle := FloatBrd;
|
|
||||||
end;
|
|
||||||
IDEMessagesWindow.TabStop := true;
|
IDEMessagesWindow.TabStop := true;
|
||||||
IDEMessagesWindow.Show;
|
IDEMessagesWindow.Show;
|
||||||
|
|
||||||
{undocking is always succesfull}
|
|
||||||
Result:=True;
|
Result:=True;
|
||||||
end;
|
end else
|
||||||
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TManualDocker.Create;
|
constructor TManualDocker.Create;
|
||||||
@@ -199,14 +223,15 @@ end;
|
|||||||
procedure TManualDocker.AllocControls(AParent: TWinControl);
|
procedure TManualDocker.AllocControls(AParent: TWinControl);
|
||||||
begin
|
begin
|
||||||
FCurrentSrcWin := AParent;
|
FCurrentSrcWin := AParent;
|
||||||
panel := TPanel.Create(AParent);
|
|
||||||
panel.Parent := AParent;
|
panel := TPanel.Create(FCurrentSrcWin);
|
||||||
panel.BorderStyle := bsNone;
|
panel.BorderStyle := bsNone;
|
||||||
|
panel.Align:=alBottom;
|
||||||
|
FCurrentSrcWin.InsertControl(panel);
|
||||||
|
|
||||||
split := TSplitter.Create(AParent);
|
split := TSplitter.Create(AParent);
|
||||||
split.Parent := AParent;
|
split.Align:=alBottom;
|
||||||
|
FCurrentSrcWin.InsertControl(split);
|
||||||
RealignControls;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TManualDocker.DeallocControls;
|
procedure TManualDocker.DeallocControls;
|
||||||
@@ -215,12 +240,9 @@ begin
|
|||||||
panel:=nil;
|
panel:=nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TManualDocker.RealignControls;
|
procedure TManualDocker.ReallocControls;
|
||||||
begin
|
begin
|
||||||
panel.Align := alClient;
|
|
||||||
split.Align := alClient;
|
|
||||||
panel.Align := alBottom;
|
|
||||||
split.Align := alBottom;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TManualDocker.UpdateDockState(var astate: TDockState; wnd: TWinControl);
|
procedure TManualDocker.UpdateDockState(var astate: TDockState; wnd: TWinControl);
|
||||||
@@ -229,6 +251,17 @@ begin
|
|||||||
astate.DockSize.cy := wnd.ClientHeight;
|
astate.DockSize.cy := wnd.ClientHeight;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TManualDocker.DoPanelResize;
|
||||||
|
begin
|
||||||
|
IDEMessagesWindow.BoundsRect:=panel.ClientRect;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TManualDocker.PanelResize(Sender: TObject);
|
||||||
|
begin
|
||||||
|
if not Assigned(panel) or not Assigned(IDEMessagesWindow) or not MsgWnd.Docked then Exit;
|
||||||
|
DoPanelResize;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TManualDocker.SourceWindowCreated(Sender: TObject);
|
procedure TManualDocker.SourceWindowCreated(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
if Assigned(FCurrentSrcWin) or (SourceEditorManagerIntf.SourceWindowCount > 1) then
|
if Assigned(FCurrentSrcWin) or (SourceEditorManagerIntf.SourceWindowCount > 1) then
|
||||||
@@ -304,6 +337,7 @@ procedure Register;
|
|||||||
begin
|
begin
|
||||||
docker := TManualDocker.Create;
|
docker := TManualDocker.Create;
|
||||||
cmd := RegisterIDEMenuCommand(itmViewMainWindows, 'makeMessagesDocked', mnuDockMsgWindow, @docker.OnCmdClick, nil, nil, '');
|
cmd := RegisterIDEMenuCommand(itmViewMainWindows, 'makeMessagesDocked', mnuDockMsgWindow, @docker.OnCmdClick, nil, nil, '');
|
||||||
|
cmd.Checked:=docker.MsgWnd.Docked;
|
||||||
LazarusIDE.AddHandlerOnProjectOpened(@docker.OnProjectOpen, False);
|
LazarusIDE.AddHandlerOnProjectOpened(@docker.OnProjectOpen, False);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user