mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-11 14:37:48 +02:00
LCL: improved painting dock frame e.g. TLazDockTree.PaintDockFrame from Paul
git-svn-id: trunk@13632 -
This commit is contained in:
parent
ebe8b6788b
commit
0eda8d5b38
@ -2328,8 +2328,10 @@ var
|
||||
CurAnchorSide:=Control.AnchorSide[Kind];
|
||||
//if CheckPosition(Control) and (Kind=akLeft) then debugln(['GetAnchorSidePosition A Self=',DbgSName(Self),' Control=',DbgSName(Control),' CurAnchorSide.Control=',DbgSName(CurAnchorSide.Control),' Spacing=',Control.BorderSpacing.GetSpace(Kind)]);
|
||||
CurAnchorSide.GetSidePosition(ReferenceControl,ReferenceSide,Position);
|
||||
if ReferenceControl<>nil then
|
||||
if ReferenceControl<>nil then begin
|
||||
//DebugLn(['GetAnchorSidePosition ',DbgSName(Control),' ReferenceControl=',DbgSName(ReferenceControl)]);
|
||||
Result:=Position;
|
||||
end;
|
||||
//if CheckPosition(Control) and (Kind=akLeft) then begin
|
||||
//debugln('GetAnchorSidePosition B Self=',DbgSName(Self),' Control=',DbgSName(Control),' Result=',dbgs(Result),' ReferenceControl=',dbgsName(ReferenceControl));
|
||||
//if ReferenceControl<>nil then DebugLn(['GetAnchorSidePosition ReferenceControl.BoundsRect=',dbgs(ReferenceControl.BoundsRect)]);
|
||||
@ -4184,7 +4186,12 @@ begin
|
||||
|
||||
Assert(False, Format('Trace:> [TWinControl.PaintHandler] %s --> Msg.DC: 0x%x', [ClassName, TheMessage.DC]));
|
||||
DC := TheMessage.DC;
|
||||
if DC = 0 then DC := BeginPaint(Handle, PS);
|
||||
if DC = 0 then
|
||||
DC := BeginPaint(Handle, PS);
|
||||
|
||||
if FDockSite and FUseDockManager then
|
||||
FDockManager.PaintSite(DC);
|
||||
|
||||
try
|
||||
// check if child controls need clipping
|
||||
//DebugLn('[TWinControl.PaintHandler] ',DbgSName(Self),' B');
|
||||
@ -4221,7 +4228,8 @@ begin
|
||||
//DebugLn('[TWinControl.PaintHandler] ',DbgSName(Self),' PaintControls ...');
|
||||
PaintControls(DC, nil);
|
||||
finally
|
||||
if TheMessage.DC = 0 then EndPaint(Handle, PS);
|
||||
if TheMessage.DC = 0 then
|
||||
EndPaint(Handle, PS);
|
||||
end;
|
||||
Assert(False, Format('Trace:< [TWinControl.PaintHandler] %s', [ClassName]));
|
||||
//DebugLn('[TWinControl.PaintHandler] END ',Name,':',ClassName,' DC=',DbgS(Message.DC,8));
|
||||
|
@ -31,8 +31,8 @@ unit LDockTree;
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, LCLProc, LCLType, Forms, Controls, ExtCtrls, Menus,
|
||||
LCLStrConsts;
|
||||
Types, Classes, SysUtils, LCLProc, LCLType, LCLStrConsts,
|
||||
Graphics, Controls, ExtCtrls, Forms, Menus, Themes;
|
||||
|
||||
type
|
||||
TLazDockPages = class;
|
||||
@ -61,10 +61,13 @@ type
|
||||
private
|
||||
FAutoFreeDockSite: boolean;
|
||||
protected
|
||||
procedure UndockControlForDocking(AControl: TControl);
|
||||
procedure BreakAnchors(Zone: TDockZone);
|
||||
procedure CreateDockLayoutHelperControls(Zone: TLazDockZone);
|
||||
procedure AdjustDockRect(AControl: TControl; var ARect: TRect); override;
|
||||
procedure AnchorDockLayout(Zone: TLazDockZone);
|
||||
procedure CreateDockLayoutHelperControls(Zone: TLazDockZone);
|
||||
procedure BreakAnchors(Zone: TDockZone);
|
||||
procedure PaintDockFrame(ACanvas: TCanvas; AControl: TControl;
|
||||
const ARect: TRect); override;
|
||||
procedure UndockControlForDocking(AControl: TControl);
|
||||
public
|
||||
constructor Create(TheDockSite: TWinControl); override;
|
||||
destructor Destroy; override;
|
||||
@ -76,6 +79,7 @@ type
|
||||
function FindBorderControl(Zone: TLazDockZone; Side: TAnchorKind): TControl;
|
||||
function GetAnchorControl(Zone: TLazDockZone; Side: TAnchorKind;
|
||||
OutSide: boolean): TControl;
|
||||
procedure PaintSite(DC: HDC); override;
|
||||
public
|
||||
property AutoFreeDockSite: boolean read FAutoFreeDockSite write FAutoFreeDockSite;
|
||||
end;
|
||||
@ -196,6 +200,7 @@ type
|
||||
|
||||
|
||||
const
|
||||
DefaultDockGrabberSize = 15;
|
||||
DockAlignOrientations: array[TAlign] of TDockOrientation = (
|
||||
doPages, //alNone,
|
||||
doVertical, //alTop,
|
||||
@ -602,6 +607,79 @@ begin
|
||||
BreakAnchors(Zone.NextSibling);
|
||||
end;
|
||||
|
||||
procedure TLazDockTree.PaintDockFrame(ACanvas: TCanvas; AControl: TControl;
|
||||
const ARect: TRect);
|
||||
var
|
||||
Details: TThemedElementDetails;
|
||||
BtnRect: TRect;
|
||||
DrawRect: TRect;
|
||||
d: integer;
|
||||
begin
|
||||
DrawRect := ARect;
|
||||
InflateRect(DrawRect, -1, -1);
|
||||
ACanvas.Brush.Color := clBtnShadow;
|
||||
ACanvas.FrameRect(DrawRect);
|
||||
InflateRect(DrawRect, -1, -1);
|
||||
case AControl.DockOrientation of
|
||||
doHorizontal:
|
||||
begin
|
||||
d := DrawRect.Bottom - DrawRect.Top;
|
||||
BtnRect := DrawRect;
|
||||
Dec(BtnRect.Right);
|
||||
BtnRect.Left := BtnRect.Right - d;
|
||||
Details := ThemeServices.GetElementDetails(twCloseButtonNormal);
|
||||
ThemeServices.DrawElement(ACanvas.Handle, Details, BtnRect);
|
||||
|
||||
DrawRect.Right := BtnRect.Left;
|
||||
BtnRect := DrawRect;
|
||||
Dec(BtnRect.Right);
|
||||
BtnRect.Left := BtnRect.Right - d;
|
||||
Details := ThemeServices.GetElementDetails(twRestoreButtonNormal);
|
||||
ThemeServices.DrawElement(ACanvas.Handle, Details, BtnRect);
|
||||
|
||||
DrawRect.Right := BtnRect.Left;
|
||||
InflateRect(DrawRect, -4, 0);
|
||||
d := (DrawRect.Bottom + DrawRect.Top) div 2;
|
||||
|
||||
ACanvas.Pen.Color := clBtnHighlight;
|
||||
ACanvas.MoveTo(DrawRect.Left, d - 1);
|
||||
ACanvas.LineTo(DrawRect.Right, d - 1);
|
||||
|
||||
ACanvas.Pen.Color := clBtnShadow;
|
||||
ACanvas.MoveTo(DrawRect.Left, d);
|
||||
ACanvas.LineTo(DrawRect.Right, d);
|
||||
end;
|
||||
doVertical:
|
||||
begin
|
||||
d := DrawRect.Right - DrawRect.Left;
|
||||
BtnRect := DrawRect;
|
||||
Inc(BtnRect.Top);
|
||||
BtnRect.Bottom := BtnRect.Top + d;
|
||||
Details := ThemeServices.GetElementDetails(twCloseButtonNormal);
|
||||
ThemeServices.DrawElement(ACanvas.Handle, Details, BtnRect);
|
||||
|
||||
DrawRect.Top := BtnRect.Bottom;
|
||||
BtnRect := DrawRect;
|
||||
Inc(BtnRect.Top);
|
||||
BtnRect.Bottom := BtnRect.Top + d;
|
||||
Details := ThemeServices.GetElementDetails(twRestoreButtonNormal);
|
||||
ThemeServices.DrawElement(ACanvas.Handle, Details, BtnRect);
|
||||
|
||||
DrawRect.Top := BtnRect.Bottom;
|
||||
InflateRect(DrawRect, 0, -4);
|
||||
d := (DrawRect.Right + DrawRect.Left) div 2;
|
||||
|
||||
ACanvas.Pen.Color := clBtnHighlight;
|
||||
ACanvas.MoveTo(d - 1, DrawRect.Top);
|
||||
ACanvas.LineTo(d - 1, DrawRect.Bottom);
|
||||
|
||||
ACanvas.Pen.Color := clBtnShadow;
|
||||
ACanvas.MoveTo(d, DrawRect.Top);
|
||||
ACanvas.LineTo(d, DrawRect.Bottom);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TLazDockTree.CreateDockLayoutHelperControls(Zone: TLazDockZone);
|
||||
var
|
||||
ParentPages: TLazDockPages;
|
||||
@ -658,6 +736,15 @@ begin
|
||||
CreateDockLayoutHelperControls(Zone.NextSibling as TLazDockZone);
|
||||
end;
|
||||
|
||||
procedure TLazDockTree.AdjustDockRect(AControl: TControl; var ARect: TRect);
|
||||
begin
|
||||
// offset one of the borders of control rect in order to get space for frame
|
||||
case AControl.DockOrientation of
|
||||
doHorizontal: Inc(ARect.Top, DefaultDockGrabberSize);
|
||||
doVertical : Inc(ARect.Left, DefaultDockGrabberSize);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TLazDockTree.AnchorDockLayout(Zone: TLazDockZone);
|
||||
// setup all anchors between all docked controls and helper controls
|
||||
var
|
||||
@ -771,6 +858,16 @@ procedure TLazDockTree.InsertControl(AControl: TControl; InsertAt: TAlign;
|
||||
+-Zone2 (Form1,doNoOrient)
|
||||
+-Zone3 (Form2,doNoOrient)
|
||||
}
|
||||
|
||||
procedure PrepareControlForResize(AControl: TControl); inline;
|
||||
begin
|
||||
AControl.Align := alNone;
|
||||
AControl.Anchors := [akLeft, akTop];
|
||||
AControl.AnchorSide[akLeft].Control := nil;
|
||||
AControl.AnchorSide[akTop].Control := nil;
|
||||
AControl.AutoSize := False;
|
||||
end;
|
||||
|
||||
const
|
||||
SplitterWidth = 5;
|
||||
SplitterHeight = 5;
|
||||
@ -803,14 +900,22 @@ begin
|
||||
if (DropZone=RootZone) and (RootZone.FirstChild=nil) then begin
|
||||
// this is the first child
|
||||
debugln('TLazDockTree.InsertControl First Child');
|
||||
RootZone.Orientation:=NewOrientation;
|
||||
RootZone.Orientation := NewOrientation;
|
||||
RootZone.AddAsFirstChild(NewZone);
|
||||
AControl.DockOrientation := NewOrientation;
|
||||
if not AControl.Visible then
|
||||
DockSite.Visible:=false;
|
||||
DockSite.BoundsRect:=AControl.BoundsRect;
|
||||
AControl.Parent:=DockSite;
|
||||
DockSite.Visible := False;
|
||||
|
||||
NewBounds := AControl.BoundsRect;
|
||||
AdjustDockRect(AControl, NewBounds);
|
||||
DockSite.BoundsRect := NewBounds;
|
||||
|
||||
PrepareControlForResize(AControl);
|
||||
AControl.BoundsRect := NewBounds;
|
||||
AControl.Parent := DockSite;
|
||||
|
||||
if AControl.Visible then
|
||||
DockSite.Visible:=true;
|
||||
DockSite.Visible := True;
|
||||
end else begin
|
||||
// there are already other childs
|
||||
|
||||
@ -862,24 +967,20 @@ begin
|
||||
|
||||
// break anchors and resize DockSite
|
||||
BreakAnchors(RootZone);
|
||||
NewBounds:=DockSite.BoundsRect;
|
||||
NewBounds := DockSite.BoundsRect;
|
||||
case InsertAt of
|
||||
alLeft: dec(NewBounds.Left,SplitterWidth+AControl.Width);
|
||||
alRight: inc(NewBounds.Right,SplitterWidth+AControl.Width);
|
||||
alTop: dec(NewBounds.Top,SplitterHeight+AControl.Height);
|
||||
alBottom:inc(NewBounds.Bottom,SplitterHeight+AControl.Height);
|
||||
alLeft: dec(NewBounds.Left,SplitterWidth+AControl.Width);
|
||||
alRight: inc(NewBounds.Right,SplitterWidth+AControl.Width);
|
||||
alTop: dec(NewBounds.Top,SplitterHeight+AControl.Height);
|
||||
alBottom:inc(NewBounds.Bottom,SplitterHeight+AControl.Height);
|
||||
else // no change
|
||||
end;
|
||||
DockSite.BoundsRect:=NewBounds;
|
||||
DockSite.BoundsRect := NewBounds;
|
||||
|
||||
// add AControl to DockSite
|
||||
AControl.Visible:=false;
|
||||
AControl.Parent:=nil;
|
||||
AControl.Align:=alNone;
|
||||
AControl.Anchors:=[akLeft,akTop];
|
||||
AControl.AnchorSide[akLeft].Control:=nil;
|
||||
AControl.AnchorSide[akTop].Control:=nil;
|
||||
AControl.AutoSize:=false;
|
||||
AControl.Visible := False;
|
||||
AControl.Parent := nil;
|
||||
PrepareControlForResize(AControl);
|
||||
// resize control
|
||||
RaiseGDBException('TLazDockTree.InsertControl TODO resize control');
|
||||
if NewOrientation in [doHorizontal,doVertical] then begin
|
||||
@ -892,7 +993,8 @@ begin
|
||||
AControl.Width:=ASibling.Width;
|
||||
end;
|
||||
end;
|
||||
AControl.Parent:=NewZone.GetParentControl;
|
||||
AControl.DockOrientation := NewOrientation;
|
||||
AControl.Parent := NewZone.GetParentControl;
|
||||
|
||||
// Build dock layout (anchors, splitters, pages)
|
||||
BuildDockLayout(RootZone as TLazDockZone);
|
||||
@ -1022,6 +1124,41 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TLazDockTree.PaintSite(DC: HDC);
|
||||
var
|
||||
ACanvas: TCanvas;
|
||||
ARect: TRect;
|
||||
i: integer;
|
||||
begin
|
||||
// paint bounds for each control and close button
|
||||
if DockSite.ControlCount > 0 then
|
||||
begin
|
||||
ACanvas := TCanvas.Create;
|
||||
ACanvas.Handle := DC;
|
||||
try
|
||||
for i := 0 to DockSite.ControlCount - 1 do
|
||||
begin
|
||||
ARect := DockSite.Controls[i].BoundsRect;
|
||||
case DockSite.Controls[i].DockOrientation of
|
||||
doHorizontal:
|
||||
begin
|
||||
ARect.Bottom := ARect.Top;
|
||||
Dec(ARect.Top, DefaultDockGrabberSize);
|
||||
end;
|
||||
doVertical:
|
||||
begin
|
||||
ARect.Right := ARect.Left;
|
||||
Dec(ARect.Left, DefaultDockGrabberSize);
|
||||
end;
|
||||
end;
|
||||
PaintDockFrame(ACanvas, DockSite.Controls[i], ARect);
|
||||
end;
|
||||
finally
|
||||
ACanvas.Free;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ TLazDockZone }
|
||||
|
||||
destructor TLazDockZone.Destroy;
|
||||
@ -2219,4 +2356,7 @@ begin
|
||||
FindCandidate(Self,0);
|
||||
end;
|
||||
|
||||
initialization
|
||||
DefaultDockTreeClass := TLazDockTree;
|
||||
|
||||
end.
|
||||
|
Loading…
Reference in New Issue
Block a user