mirror of
				https://gitlab.com/freepascal.org/lazarus/lazarus.git
				synced 2025-11-04 01:19:47 +01:00 
			
		
		
		
	dockmanager example: updated EasyEditor
git-svn-id: trunk@25099 -
This commit is contained in:
		
							parent
							
								
									ec6aecbdc0
								
							
						
					
					
						commit
						171318e5f5
					
				@ -6,7 +6,7 @@ object MainForm: TMainForm
 | 
			
		||||
  Caption = 'MainForm'
 | 
			
		||||
  Menu = MainMenu1
 | 
			
		||||
  OnCreate = FormCreate
 | 
			
		||||
  LCLVersion = '0.9.27'
 | 
			
		||||
  LCLVersion = '0.9.29'
 | 
			
		||||
  object MainMenu1: TMainMenu
 | 
			
		||||
    left = 10
 | 
			
		||||
    top = 10
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@
 | 
			
		||||
LazarusResources.Add('TMainForm','FORMDATA',[
 | 
			
		||||
  'TPF0'#9'TMainForm'#8'MainForm'#4'Left'#2#9#6'Height'#2'+'#3'Top'#2'g'#5'Widt'
 | 
			
		||||
  +'h'#3#144#1#7'Caption'#6#8'MainForm'#4'Menu'#7#9'MainMenu1'#8'OnCreate'#7#10
 | 
			
		||||
  +'FormCreate'#10'LCLVersion'#6#6'0.9.27'#0#9'TMainMenu'#9'MainMenu1'#4'left'#2
 | 
			
		||||
  +'FormCreate'#10'LCLVersion'#6#6'0.9.29'#0#9'TMainMenu'#9'MainMenu1'#4'left'#2
 | 
			
		||||
  +#10#3'top'#2#10#0#9'TMenuItem'#7'mnuFile'#7'Caption'#6#5'&File'#0#9'TMenuIte'
 | 
			
		||||
  +'m'#6'mnOpen'#7'Caption'#6#8'&Open...'#7'OnClick'#7#11'mnOpenClick'#0#0#9'TM'
 | 
			
		||||
  +'enuItem'#9'MenuItem1'#7'Caption'#6#1'-'#0#0#9'TMenuItem'#7'mnClose'#7'Capti'
 | 
			
		||||
 | 
			
		||||
@ -59,10 +59,14 @@ var
 | 
			
		||||
 | 
			
		||||
implementation
 | 
			
		||||
 | 
			
		||||
uses
 | 
			
		||||
  uMakeSite;
 | 
			
		||||
 | 
			
		||||
{ TMainForm }
 | 
			
		||||
 | 
			
		||||
procedure TMainForm.FormCreate(Sender: TObject);
 | 
			
		||||
begin
 | 
			
		||||
  TDockMaster.Create(self);
 | 
			
		||||
{
 | 
			
		||||
  MyEdit := TEasyPages.Create(self);
 | 
			
		||||
  MyEdit.Align := alClient;
 | 
			
		||||
 | 
			
		||||
@ -206,9 +206,14 @@ procedure TMainBar.buSaveClick(Sender: TObject);
 | 
			
		||||
var
 | 
			
		||||
  strm: TFileStream;
 | 
			
		||||
begin
 | 
			
		||||
(* Save layout.
 | 
			
		||||
  This should inlude ALL forms, not only the dockable ones!
 | 
			
		||||
*)
 | 
			
		||||
  if dlgLayout.Execute then begin
 | 
			
		||||
    strm := TFileStream.Create(dlgLayout.FileName, fmCreate);
 | 
			
		||||
    try
 | 
			
		||||
    //save non-dockable forms
 | 
			
		||||
    //save dockable forms and sites
 | 
			
		||||
      DockMaster.SaveToStream(strm);
 | 
			
		||||
    finally
 | 
			
		||||
      strm.Free;
 | 
			
		||||
@ -225,6 +230,8 @@ begin
 | 
			
		||||
(* Create a client form, and dock it into a floating dock host site.
 | 
			
		||||
  We must force docking here, later the client will dock itself into
 | 
			
		||||
  a float host site, when it becomes floating.
 | 
			
		||||
 | 
			
		||||
  Should use: DockMaster.CreateDockable(TViewWindow) - RegisterClass!
 | 
			
		||||
*)
 | 
			
		||||
//lookup existing (assume single instance forms)
 | 
			
		||||
  n := StringReplace(cap, ' ', '', [rfReplaceAll]);
 | 
			
		||||
@ -233,12 +240,16 @@ begin
 | 
			
		||||
  //create the form
 | 
			
		||||
    Client := TViewWindow.Create(Self);
 | 
			
		||||
    Client.Label1.Caption := cap;
 | 
			
		||||
    Client.Visible := True;
 | 
			
		||||
  //name it
 | 
			
		||||
    Client.Caption := cap;
 | 
			
		||||
    TryRename(Client, n);
 | 
			
		||||
    DockMaster.MakeDockable(Client, fWrap, True);
 | 
			
		||||
    Client.Visible := True;
 | 
			
		||||
    Result := Client;
 | 
			
		||||
  end else begin
 | 
			
		||||
  //activate the existing form
 | 
			
		||||
    Result.Show; //might be invisible
 | 
			
		||||
    Result.SetFocus;
 | 
			
		||||
  end;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -300,9 +300,10 @@ type
 | 
			
		||||
    procedure IdToRec(const ID: string);
 | 
			
		||||
    function  RecToId: string;
 | 
			
		||||
  public //become class functions?
 | 
			
		||||
    TryCreateControls: boolean;
 | 
			
		||||
    function  MakeDockable(AForm: TWinControl; fWrap: boolean = True; fVisible: boolean = False): TForm; virtual;
 | 
			
		||||
    function SaveControl(Control: TControl; Site: TWinControl): string; virtual;
 | 
			
		||||
    function ReloadControl(const AName: string; Site: TWinControl): TControl; virtual;
 | 
			
		||||
    function  SaveControl(Control: TControl; Site: TWinControl): string; virtual;
 | 
			
		||||
    function  ReloadControl(const AName: string; Site: TWinControl): TControl; virtual;
 | 
			
		||||
    property OnSave: TOnSaveControl read FOnSave write FOnSave;
 | 
			
		||||
    property OnRestore: TOnReloadControl read FOnRestore write FOnRestore;
 | 
			
		||||
    property ControlDescriptor: RControlDescriptor read rc;
 | 
			
		||||
@ -2087,6 +2088,7 @@ var
 | 
			
		||||
  dst: TDockSiteClass absolute ct;
 | 
			
		||||
begin
 | 
			
		||||
(* Restore from typename, then restore clients.
 | 
			
		||||
  Called when AName[1]=CustomDockSiteID.
 | 
			
		||||
*)
 | 
			
		||||
  Result := nil;
 | 
			
		||||
  ss := TStringStream.Create(AName);
 | 
			
		||||
@ -2115,6 +2117,10 @@ var
 | 
			
		||||
  ss: TStringStream;
 | 
			
		||||
begin
 | 
			
		||||
(* Save typename and clients.
 | 
			
		||||
  Write to string:
 | 
			
		||||
  - CustomDockSiteID
 | 
			
		||||
  - ClassName
 | 
			
		||||
  - content (SaveToStream)
 | 
			
		||||
*)
 | 
			
		||||
  ss := TStringStream.Create('');
 | 
			
		||||
  try
 | 
			
		||||
@ -2135,6 +2141,15 @@ var
 | 
			
		||||
begin
 | 
			
		||||
(* Save all docked controls.
 | 
			
		||||
  Flag nested custom dock sites - how?
 | 
			
		||||
*)
 | 
			
		||||
  if assigned(DockManager) then begin
 | 
			
		||||
    DockManager.SaveToStream(strm);
 | 
			
		||||
    exit;
 | 
			
		||||
  end;
 | 
			
		||||
{$IFDEF new}
 | 
			
		||||
(* requires:
 | 
			
		||||
- flag unmanaged
 | 
			
		||||
- ctl.BoundsRect (within site!) -> translate for ManualDock
 | 
			
		||||
*)
 | 
			
		||||
  n := DockClientCount;
 | 
			
		||||
  strm.WriteByte(n);
 | 
			
		||||
@ -2143,6 +2158,9 @@ begin
 | 
			
		||||
    s := DockLoader.SaveControl(ctl, self);
 | 
			
		||||
    strm.WriteAnsiString(s);
 | 
			
		||||
  end;
 | 
			
		||||
{$ELSE}
 | 
			
		||||
  //unmanaged docksites unhandled
 | 
			
		||||
{$ENDIF}
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
procedure TCustomDockSite.LoadFromStream(strm: TStream);
 | 
			
		||||
@ -2151,6 +2169,12 @@ var
 | 
			
		||||
  ctl: TControl;
 | 
			
		||||
  cn: string;
 | 
			
		||||
begin
 | 
			
		||||
  if assigned(DockManager) then begin
 | 
			
		||||
    DockManager.LoadFromStream(strm);
 | 
			
		||||
    exit;
 | 
			
		||||
  end
 | 
			
		||||
{$IFDEF new}
 | 
			
		||||
//see SaveToStream!
 | 
			
		||||
  n := strm.ReadByte;
 | 
			
		||||
  for i := 1 to n do begin
 | 
			
		||||
    cn := strm.ReadAnsiString;
 | 
			
		||||
@ -2159,6 +2183,9 @@ begin
 | 
			
		||||
      ctl.ManualDock(self); //orientation???
 | 
			
		||||
    //make visible?
 | 
			
		||||
  end;
 | 
			
		||||
{$ELSE}
 | 
			
		||||
  //unmanaged docksites unhandled
 | 
			
		||||
{$ENDIF}
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
{ TCustomDockMaster }
 | 
			
		||||
@ -2229,9 +2256,7 @@ var
 | 
			
		||||
begin
 | 
			
		||||
(* Result is the floating site, if created (fWrap).
 | 
			
		||||
  fWrap here is ignored.
 | 
			
		||||
To be overridden by final TDockMaster, for
 | 
			
		||||
- wrapping
 | 
			
		||||
- visibility
 | 
			
		||||
To be overridden by final TDockMaster, for wrapping.
 | 
			
		||||
*)
 | 
			
		||||
//make it dockable
 | 
			
		||||
  wctl.DragKind := dkDock;
 | 
			
		||||
@ -2248,12 +2273,12 @@ var
 | 
			
		||||
  fo: TComponent; //form owner
 | 
			
		||||
  cmp: TComponent absolute Result;
 | 
			
		||||
begin
 | 
			
		||||
(* Reload from
 | 
			
		||||
- saved site info (if CustomDockSite)
 | 
			
		||||
(* Reload from:
 | 
			
		||||
- CustomDockSite (allow for nested layouts)
 | 
			
		||||
- AppLoadStore
 | 
			
		||||
- OnRestore
 | 
			
		||||
- Owner
 | 
			
		||||
- create from descriptor
 | 
			
		||||
- our Owner
 | 
			
		||||
- create from descriptor (optionally)
 | 
			
		||||
- DockSite
 | 
			
		||||
*)
 | 
			
		||||
  Result := nil;
 | 
			
		||||
@ -2275,18 +2300,20 @@ begin
 | 
			
		||||
  if Result is TControl then
 | 
			
		||||
    exit;
 | 
			
		||||
  Result := nil; //exclude non-controls
 | 
			
		||||
//load from descriptor
 | 
			
		||||
  fc := TWinControlClass(GetClass(rc.ClassName));
 | 
			
		||||
  if not assigned(fc) then begin
 | 
			
		||||
    DebugLn(rc.ClassName, ' is not a registered class');
 | 
			
		||||
    //exit(nil); //bad form name
 | 
			
		||||
  end else begin
 | 
			
		||||
  //init from descriptor
 | 
			
		||||
    Result := fc.Create(fo);
 | 
			
		||||
    if Result.Name <> rc.Name then
 | 
			
		||||
      TryRename(Result, rc.Name);
 | 
			
		||||
    if Result.Caption <> rc.Caption then
 | 
			
		||||
      Result.Caption := rc.Caption; //really?
 | 
			
		||||
//create from descriptor?
 | 
			
		||||
  if TryCreateControls then begin
 | 
			
		||||
    fc := TWinControlClass(GetClass(rc.ClassName));
 | 
			
		||||
    if not assigned(fc) then begin
 | 
			
		||||
      DebugLn(rc.ClassName, ' is not a registered class');
 | 
			
		||||
      //exit(nil); //bad form name
 | 
			
		||||
    end else begin
 | 
			
		||||
    //init from descriptor
 | 
			
		||||
      Result := fc.Create(fo);
 | 
			
		||||
      if Result.Name <> rc.Name then
 | 
			
		||||
        TryRename(Result, rc.Name);
 | 
			
		||||
      if Result.Caption <> rc.Caption then
 | 
			
		||||
        Result.Caption := rc.Caption; //really?
 | 
			
		||||
    end;
 | 
			
		||||
  end;
 | 
			
		||||
//last resort
 | 
			
		||||
  if Result = nil then
 | 
			
		||||
 | 
			
		||||
@ -277,7 +277,7 @@ var
 | 
			
		||||
  s: string;
 | 
			
		||||
  ctl: TControl;
 | 
			
		||||
begin
 | 
			
		||||
(* Reload docked forms
 | 
			
		||||
(* Reload any docked forms, from Screen's collection
 | 
			
		||||
*)
 | 
			
		||||
//search existing forms
 | 
			
		||||
  Result := nil;
 | 
			
		||||
@ -292,7 +292,7 @@ begin
 | 
			
		||||
  end;
 | 
			
		||||
//not found
 | 
			
		||||
  Result := inherited ReloadControl(AName, Site);
 | 
			
		||||
  if Result = nil then
 | 
			
		||||
  if (Result = nil) and TryCreateControls then
 | 
			
		||||
    Result := ReloadForm(AName, False, True);
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
@ -424,27 +424,11 @@ Notebooks?
 | 
			
		||||
  Ownership?
 | 
			
		||||
    When notebooks are dockable, they cannot be owned by the DockSite!
 | 
			
		||||
*)
 | 
			
		||||
  Stream.Position := 0; //rewind!
 | 
			
		||||
//Allow for non-dockable forms information in front of this part!
 | 
			
		||||
  //Stream.Position := 0; //rewind! - must be done by the caller
 | 
			
		||||
{ TODO : add non-dockable forms, for full application layout }
 | 
			
		||||
//restore all top level sites
 | 
			
		||||
  while ReadSite do begin
 | 
			
		||||
  {$IFDEF old}
 | 
			
		||||
    if SiteRec.NameLen = 0 then begin
 | 
			
		||||
    //floating site
 | 
			
		||||
      site := TFloatingSite.Create(self);
 | 
			
		||||
      site.BoundsRect := SiteRec.Bounds;
 | 
			
		||||
    end else begin
 | 
			
		||||
    //hosted panel - find parent form
 | 
			
		||||
      site := MakePanel(SiteName, SiteRec.Align);
 | 
			
		||||
    end;
 | 
			
		||||
  //debug
 | 
			
		||||
    if site = nil then begin
 | 
			
		||||
      exit; //stream error!
 | 
			
		||||
    end;
 | 
			
		||||
  //adjust host form
 | 
			
		||||
    if site.DockManager = nil then
 | 
			
		||||
      TAppDockManager.Create(site);
 | 
			
		||||
    site.DockManager.LoadFromStream(Stream);
 | 
			
		||||
  {$ELSE}
 | 
			
		||||
    case SiteRec.Kind of
 | 
			
		||||
    skEnd,      //end marker
 | 
			
		||||
    skNone:     //not to be saved/restored
 | 
			
		||||
@ -471,17 +455,16 @@ Notebooks?
 | 
			
		||||
      ShowMessage('unhandled site kind: ' + SiteName);
 | 
			
		||||
      exit;
 | 
			
		||||
    end;
 | 
			
		||||
    //debug
 | 
			
		||||
      if site = nil then begin
 | 
			
		||||
        ShowMessage('could not reload ' + SiteName);
 | 
			
		||||
        exit; //stream error!
 | 
			
		||||
      end;
 | 
			
		||||
    //adjust host form
 | 
			
		||||
      if site.DockManager = nil then
 | 
			
		||||
        TAppDockManager.Create(site);
 | 
			
		||||
      site.DockManager.LoadFromStream(Stream);
 | 
			
		||||
      site.Show;
 | 
			
		||||
  {$ENDIF}
 | 
			
		||||
  //debug
 | 
			
		||||
    if site = nil then begin
 | 
			
		||||
      ShowMessage('could not reload ' + SiteName);
 | 
			
		||||
      exit; //stream error!
 | 
			
		||||
    end;
 | 
			
		||||
  //adjust host form
 | 
			
		||||
    if site.DockManager = nil then
 | 
			
		||||
      TAppDockManager.Create(site);
 | 
			
		||||
    site.DockManager.LoadFromStream(Stream);
 | 
			
		||||
    site.Show;
 | 
			
		||||
  end;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
@ -497,29 +480,6 @@ procedure TDockMaster.SaveToStream(Stream: TStream);
 | 
			
		||||
      //destroy empty floating sites?
 | 
			
		||||
      exit;
 | 
			
		||||
    end;
 | 
			
		||||
  {$IFDEF old}
 | 
			
		||||
    if Site.DockManager = nil then
 | 
			
		||||
      exit;
 | 
			
		||||
    if Site is TDockPanel then begin
 | 
			
		||||
      if site.Parent = nil then begin
 | 
			
		||||
      //destroy orphaned panel?
 | 
			
		||||
        site.Free;
 | 
			
		||||
        exit;
 | 
			
		||||
      end;
 | 
			
		||||
      SiteRec.Bounds := Site.Parent.BoundsRect;
 | 
			
		||||
      SiteRec.Extent := site.BoundsRect;
 | 
			
		||||
      SiteRec.AutoExpand := (site as TDockPanel).AutoExpand;
 | 
			
		||||
    end else {if Site.Parent = nil then} begin
 | 
			
		||||
      SiteRec.Bounds := Site.BoundsRect
 | 
			
		||||
    end;
 | 
			
		||||
    SiteName := AName;
 | 
			
		||||
    SiteRec.Align := Site.Align;
 | 
			
		||||
    SiteRec.NameLen := Length(SiteName);
 | 
			
		||||
    Stream.Write(SiteRec, sizeof(SiteRec));
 | 
			
		||||
    if AName <> '' then
 | 
			
		||||
      Stream.Write(SiteName[1], Length(SiteName));
 | 
			
		||||
    Site.DockManager.SaveToStream(Stream);
 | 
			
		||||
  {$ELSE}
 | 
			
		||||
    SiteRec.Kind := skNone;
 | 
			
		||||
  //handle elastic sites first!
 | 
			
		||||
    if Site is TDockPanel then begin
 | 
			
		||||
@ -569,7 +529,6 @@ procedure TDockMaster.SaveToStream(Stream: TStream);
 | 
			
		||||
      ShowMessage('unhandled site ' + SiteName);
 | 
			
		||||
      //raise...
 | 
			
		||||
    end;
 | 
			
		||||
  {$ENDIF}
 | 
			
		||||
  end;
 | 
			
		||||
 | 
			
		||||
var
 | 
			
		||||
@ -578,7 +537,7 @@ var
 | 
			
		||||
  wc: TWinControl absolute cmp;
 | 
			
		||||
begin
 | 
			
		||||
(* Save all floating sites and elastic panels.
 | 
			
		||||
  The sites are in Components[].
 | 
			
		||||
  The sites are in our Components[].
 | 
			
		||||
  The panels are in ElasticSites (if ownPanels is undefined).
 | 
			
		||||
*)
 | 
			
		||||
//save floating sites
 | 
			
		||||
@ -589,13 +548,8 @@ begin
 | 
			
		||||
    end;
 | 
			
		||||
  end;
 | 
			
		||||
//end marker
 | 
			
		||||
{$IFDEF old}
 | 
			
		||||
  SiteRec.Bounds.Right := -1;
 | 
			
		||||
  SiteRec.NameLen := 0;
 | 
			
		||||
{$ELSE}
 | 
			
		||||
  SiteRec.Kind := skEnd;
 | 
			
		||||
  //SiteName:='';
 | 
			
		||||
{$ENDIF}
 | 
			
		||||
  Stream.Write(SiteRec, sizeof(SiteRec));
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user