dockmanager example: notebook page selection

git-svn-id: trunk@26319 -
This commit is contained in:
dodi 2010-06-29 09:35:03 +00:00
parent 2787b3b9f6
commit 5720fa2392
3 changed files with 116 additions and 31 deletions

View File

@ -32,6 +32,8 @@ unit RegisterEasyDockMgr;
{$mode objfpc}{$H+} {$mode objfpc}{$H+}
{.$DEFINE DockMaster} //must match IDE setting
interface interface
uses uses
@ -42,9 +44,14 @@ uses
const const
DefaultConfigFileName = 'easydocklayout.lyt'; DefaultConfigFileName = 'easydocklayout.lyt';
type type
TDockSides = set of TAlign;
{ TIDEEasyDockMaster } { TIDEEasyDockMaster }
{$IFDEF DockMaster}
{$ELSE}
TIDEDockMaster = TIDELayout;
{$ENDIF}
TIDEEasyDockMaster = class(TIDEDockMaster) TIDEEasyDockMaster = class(TIDEDockMaster)
private private
function DockMasterRestore(const CtrlName: string; ASite: TWinControl function DockMasterRestore(const CtrlName: string; ASite: TWinControl
@ -53,9 +60,15 @@ type
procedure GetDefaultBounds(AForm: TCustomForm; out Creator: TIDEWindowCreator; procedure GetDefaultBounds(AForm: TCustomForm; out Creator: TIDEWindowCreator;
out NewBounds: TRect; out DockSiblingName: string; out DockAlign: TAlign); out NewBounds: TRect; out DockSiblingName: string; out DockAlign: TAlign);
public public
{$IFDEF DockMaster}
constructor Create; constructor Create;
{$ELSE}
constructor Create; override;
function AddableInWindowMenu(AForm: TCustomForm): boolean; override;
procedure RestoreIDEWindows; override;
{$ENDIF}
destructor Destroy; override; destructor Destroy; override;
procedure MakeIDEWindowDockSite(AForm: TCustomForm); override; procedure MakeIDEWindowDockSite(AForm: TCustomForm; ASides: TDockSides = [alBottom]); override;
procedure MakeIDEWindowDockable(AControl: TWinControl); override; procedure MakeIDEWindowDockable(AControl: TWinControl); override;
function IsDockSite(AForm: TCustomForm): boolean; function IsDockSite(AForm: TCustomForm): boolean;
function IsDockable(AForm: TCustomForm): boolean; function IsDockable(AForm: TCustomForm): boolean;
@ -77,8 +90,13 @@ implementation
procedure Register; procedure Register;
begin begin
//required?
{$IFDEF DockMaster}
LazarusIDE.AddHandlerOnIDERestoreWindows(@IDEEasyDockMaster.OnIDERestoreWindows); LazarusIDE.AddHandlerOnIDERestoreWindows(@IDEEasyDockMaster.OnIDERestoreWindows);
LazarusIDE.AddHandlerOnIDEClose(@IDEEasyDockMaster.OnIDEClose); LazarusIDE.AddHandlerOnIDEClose(@IDEEasyDockMaster.OnIDEClose);
{$ELSE}
//should not be required
{$ENDIF}
end; end;
{ TIDEEasyDockMaster } { TIDEEasyDockMaster }
@ -125,13 +143,27 @@ begin
DockMaster.OnSave:=@DockMasterSave; DockMaster.OnSave:=@DockMasterSave;
end; end;
{$IFDEF DockMaster}
{$ELSE}
function TIDEEasyDockMaster.AddableInWindowMenu(AForm: TCustomForm): boolean;
begin
Result:=inherited AddableInWindowMenu(AForm);
end;
procedure TIDEEasyDockMaster.RestoreIDEWindows;
begin
inherited RestoreIDEWindows; //required?
LoadDefaultLayout;
end;
{$ENDIF}
destructor TIDEEasyDockMaster.Destroy; destructor TIDEEasyDockMaster.Destroy;
begin begin
IDEEasyDockMaster:=nil; IDEEasyDockMaster:=nil;
inherited Destroy; inherited Destroy;
end; end;
procedure TIDEEasyDockMaster.MakeIDEWindowDockSite(AForm: TCustomForm); procedure TIDEEasyDockMaster.MakeIDEWindowDockSite(AForm: TCustomForm; ASides: TDockSides);
var var
Creator: TIDEWindowCreator; Creator: TIDEWindowCreator;
NewBounds: TRect; NewBounds: TRect;
@ -142,7 +174,7 @@ begin
GetDefaultBounds(AForm,Creator,NewBounds,DockSiblingName,DockAlign); GetDefaultBounds(AForm,Creator,NewBounds,DockSiblingName,DockAlign);
if Creator<>nil then if Creator<>nil then
AForm.BoundsRect:=NewBounds; AForm.BoundsRect:=NewBounds;
DockMaster.AddElasticSites(AForm, [alBottom]); DockMaster.AddElasticSites(AForm, ASides);
debugln(['TIDEEasyDockMaster.MakeIDEWindowDockSite AFTER ',DbgSName(AForm),' ',dbgs(AForm.BoundsRect)]); debugln(['TIDEEasyDockMaster.MakeIDEWindowDockSite AFTER ',DbgSName(AForm),' ',dbgs(AForm.BoundsRect)]);
end; end;
@ -257,10 +289,14 @@ begin
AControl:=AForm; AControl:=AForm;
while AControl<>nil do begin while AControl<>nil do begin
// ToDo: if this is a page switch pageindex of parent // ToDo: if this is a page switch pageindex of parent
{$IFDEF old}
if AControl is TCustomForm then if AControl is TCustomForm then
TCustomForm(AControl).Show TCustomForm(AControl).Show
else else
AControl.Visible:=true; AControl.Visible:=true;
{$ELSE}
AControl.Visible := True;
{$ENDIF}
AControl:=AControl.Parent; AControl:=AControl.Parent;
end; end;
AForm.EnableAlign; AForm.EnableAlign;
@ -276,6 +312,7 @@ end;
procedure TIDEEasyDockMaster.CloseAll; procedure TIDEEasyDockMaster.CloseAll;
begin begin
SaveDefaultLayout;
inherited CloseAll; inherited CloseAll;
end; end;
@ -293,10 +330,19 @@ initialization
// create the dockmaster in the initialization section, so that it is ready // create the dockmaster in the initialization section, so that it is ready
// when the Register procedures of the packages are called. // when the Register procedures of the packages are called.
TDockMaster.Create(nil); TDockMaster.Create(nil);
{$IFDEF DockMaster}
IDEDockMaster:=TIDEEasyDockMaster.Create; IDEDockMaster:=TIDEEasyDockMaster.Create;
{$ELSE}
if IDELayout = nil then
IDELayout := TIDEEasyDockMaster.Create;
{$ENDIF}
finalization finalization
{$IFDEF DockMaster}
FreeAndNil(IDEDockMaster); FreeAndNil(IDEDockMaster);
{$ELSE}
FreeAndNil(IDELayout);
{$ENDIF}
FreeAndNil(DockMaster); FreeAndNil(DockMaster);
end. end.

View File

@ -262,6 +262,7 @@ type
public public
StayDocked: boolean; //here??? StayDocked: boolean; //here???
class function ReloadSite(AName: string; AOwner: TComponent): TCustomDockSite; class function ReloadSite(AName: string; AOwner: TComponent): TCustomDockSite;
procedure ShowForm(AForm: TControl); virtual;
function SaveSite: string; virtual; function SaveSite: string; virtual;
procedure LoadFromStream(strm: TStream); virtual; procedure LoadFromStream(strm: TStream); virtual;
procedure SaveToStream(strm: TStream); virtual; procedure SaveToStream(strm: TStream); virtual;
@ -2200,6 +2201,13 @@ begin
end; end;
end; end;
procedure TCustomDockSite.ShowForm(AForm: TControl);
begin
(* Notebooks activate this control
*)
AForm.Visible := True;
end;
function TCustomDockSite.SaveSite: string; function TCustomDockSite.SaveSite: string;
var var
ss: TStringStream; ss: TStringStream;

View File

@ -65,8 +65,8 @@ uses
type type
TTabButton = class(TToolButton) TTabButton = class(TToolButton)
protected protected
function GetDefaultDockCaption: String; override;
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override; procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
public public
Control: TControl; Control: TControl;
constructor Create(TheOwner: TComponent); override; constructor Create(TheOwner: TComponent); override;
@ -111,6 +111,8 @@ type
destructor Destroy; override; destructor Destroy; override;
{$ENDIF} {$ENDIF}
procedure Clear; virtual; procedure Clear; virtual;
procedure ShowForm(AForm: TControl); override;
procedure ShowPage(ATab: TTabButton);
procedure LoadFromStream(strm: TStream); override; procedure LoadFromStream(strm: TStream); override;
procedure SaveToStream(strm: TStream); override; procedure SaveToStream(strm: TStream); override;
end; end;
@ -128,6 +130,10 @@ begin
//RegisterComponents('Common Controls', [TEasyDockBook]); //RegisterComponents('Common Controls', [TEasyDockBook]);
end; end;
type
TControlAccess = class(TControl)
end;
{ TEasyDockBook } { TEasyDockBook }
{$IFDEF undockFix} {$IFDEF undockFix}
@ -197,6 +203,32 @@ begin
end; end;
end; end;
procedure TEasyDockBook.ShowForm(AForm: TControl);
var
btn: TTabButton;
begin
//activate page of this control
btn := GetControlTab(AForm);
if btn = nil then
inherited ShowForm(AForm)
else
ShowPage(btn);
end;
procedure TEasyDockBook.ShowPage(ATab: TTabButton);
begin
(* Show the (clicked) page
*)
if (ATab = nil) or (ATab = CurTab) then
exit; //nothing to change
if CurTab <> nil then
CurTab.Control.Visible := false;
if ATab.Control <> nil then
ATab.Control.Visible := True;
CurTab := ATab;
end;
procedure TEasyDockBook.FormClose(Sender: TObject; procedure TEasyDockBook.FormClose(Sender: TObject;
var CloseAction: TCloseAction); var CloseAction: TCloseAction);
@ -385,15 +417,21 @@ end;
function TEasyDockBook.GetDefaultDockCaption: string; function TEasyDockBook.GetDefaultDockCaption: string;
var var
i: integer; i: integer;
pg: TToolButton; btn: TToolButton;
pg: TTabButton absolute btn;
begin begin
(* Update button captions?
If 1 control docked: get full caption?
*)
Result := ''; Result := '';
for i := 0 to Tabs.ButtonCount - 1 do begin for i := 0 to Tabs.ButtonCount - 1 do begin
pg := Tabs.Buttons[i]; btn := Tabs.Buttons[i];
if Result = '' then if Result <> '' then
Result := pg.Caption Result := Result + ', ' + pg.GetDefaultDockCaption
else if tabs.ButtonCount = 1 then
Result := pg.Control.Caption //full Caption of single client
else else
Result := Result + ', ' + pg.Caption; Result := pg.GetDefaultDockCaption;
end; end;
end; end;
@ -444,12 +482,7 @@ procedure TEasyDockBook.ToolButton1Click(Sender: TObject);
var var
btn: TTabButton absolute Sender; btn: TTabButton absolute Sender;
begin begin
if CurTab <> nil then begin ShowPage(btn);
CurTab.Control.Visible := false;
end;
if btn.Control <> nil then
btn.Control.Visible := True;
CurTab := btn;
end; end;
{ TTabButton } { TTabButton }
@ -465,28 +498,26 @@ begin
Grouped := True; Grouped := True;
end; end;
function TTabButton.GetDefaultDockCaption: String;
begin
(* Also update button caption, to reflect an eventually changed control caption.
*)
if Control = nil then
Result:=inherited GetDefaultDockCaption
else begin
Result := TControlAccess(Control).GetDefaultDockCaption;
Caption := Result;
end;
end;
procedure TTabButton.MouseMove(Shift: TShiftState; X, Y: Integer); procedure TTabButton.MouseMove(Shift: TShiftState; X, Y: Integer);
//var AControl: TControl;
begin begin
(* Implement dragging of the associated page. (* Implement dragging of the associated page.
*) *)
inherited MouseMove(Shift, X, Y); inherited MouseMove(Shift, X, Y);
if (ssLeft in Shift) and not DragManager.IsDragging then begin if (ssLeft in Shift) and not DragManager.IsDragging then begin
if Control <> nil then begin if Control <> nil then
{ Problems with TWinControls - must be wrapped into forms :-( Control.BeginDrag(True); //immediate drag
//DebugLn('---undock "', Control.GetDefaultDockCaption, '"');
DebugLn('---undock "', Control.ClassName, '"');
if False and (Control is TWinControl) then begin
AControl := Control; //will change when undocked?
AControl.ManualDock(nil);
if AControl.HostDockSite <> nil then
AControl.HostDockSite.BeginDrag(True);
end else
}
//both immediate and delayed drag start seem to work
//Control.BeginDrag(False); //delayed docking
Control.BeginDrag(True); //immediate drag
end;
end; end;
end; end;