lazarus/components/dockedformeditor/source/dockedmainide.pas

755 lines
28 KiB
ObjectPascal

{
*****************************************************************************
See the file COPYING.modifiedLGPL.txt, included in this distribution,
for details about the license.
*****************************************************************************
Authors: Maciej Izak
Michael W. Vogel
DaThoX 2004-2015
FreeSparta.com
Known Issues:
- when form / frame is moved out of screen, there the form has no designer
grid (dots)
- ObjectInspector eats focus of AnchorDesigner (bug or feature?)
- Qt5 shows own menu in form, this isn't shown in anchor editor
- designer: mouse wheel to scroll content doesn't work - csDesigning is set and
form doesn't get a LM_MOUSEWHEEL message
TODO:
- Undo
}
unit DockedMainIDE;
{$mode objfpc}{$H+}
{ $define DEBUGDOCKEDFORMEDITOR}
interface
uses
// RTL
Classes, SysUtils, Contnrs,
// LCL
LCLIntf, Controls, Forms,
// IdeIntf
SrcEditorIntf, LazIDEIntf, FormEditingIntf, PropEdits, LazLoggerBase,
// DockedFormEditor
DockedResizer, DockedModulePageControl, DockedTools,
DockedSourceEditorPageControls, DockedOptionsIDE, DockedDesignForm,
DockedSourceEditorWindow;
type
{ TDockedTabMaster }
TDockedTabMaster = class(TIDETabMaster)
private
// enable autosizing for docked form editor forms, see issue #32207 - disabled
// in SourceFileManager per PreventAutoSize
FAutoSizeControlList: TObjectList;
protected
function GetTabDisplayState: TTabDisplayState; override;
function GetTabDisplayStateEditor(ASourceEditor: TSourceEditorInterface): TTabDisplayState; override;
public
constructor Create;
destructor Destroy; override;
function AutoSizeInShowDesigner(AControl: TControl): Boolean; override;
procedure EnableAutoSizing(AControl: TControl);
procedure ToggleFormUnit; override;
procedure JumpToCompilerMessage(ASourceEditor: TSourceEditorInterface); override;
procedure ShowCode(ASourceEditor: TSourceEditorInterface); override;
procedure ShowDesigner(ASourceEditor: TSourceEditorInterface; AIndex: Integer = 0); override;
procedure ShowForm(AForm: TCustomForm); override;
procedure OptionsModified;
end;
{ TDockedMainIDE }
TDockedMainIDE = class(TObject)
public
class function GetCurrentPageControl: TModulePageControl;
class procedure Screen_FormAdded(Sender: TObject; AForm: TCustomForm);
class procedure Screen_FormDel(Sender: TObject; AForm: TCustomForm);
class procedure WindowCreate(Sender: TObject);
class procedure WindowDestroy(Sender: TObject);
class procedure WindowHide(Sender: TObject);
class procedure WindowShow(Sender: TObject);
class procedure EditorActivated(Sender: TObject);
class procedure EditorCreate(Sender: TObject);
class procedure EditorDestroyed(Sender: TObject);
class procedure TabChange(Sender: TObject);
class procedure GlobalSNOnChangeBounds(Sender: TObject);
class procedure OnShowDesignerForm(Sender: TObject; {%H-}AEditor: TSourceEditorInterface;
AComponentPaletteClassSelected: Boolean);
class procedure OnShowSrcEditor(Sender: TObject);
class procedure OnDesignShowMethod(const Name: String);
class procedure OnDesignRefreshPropertyValues;
class procedure OnDesignModified(Sender: TObject);
class procedure OnDesignPersistentAdded({%H-}APersistent: TPersistent; {%H-}Select: Boolean);
class procedure OnDesignPersistentDeleted({%H-}APersistent: TPersistent);
class procedure OnDesignMouseDown(Sender: TObject; {%H-}Button: TMouseButton;
{%H-}Shift: TShiftState; {%H-}X, {%H-}Y: Integer);
class procedure OnDesignSetSelection(const ASelection: TPersistentSelectionList);
end;
var
DockedTabMaster: TDockedTabMaster absolute IDETabMaster;
implementation
{ TDockedTabMaster }
function TDockedTabMaster.GetTabDisplayState: TTabDisplayState;
begin
Result := GetTabDisplayStateEditor(SourceEditorManagerIntf.ActiveEditor);
end;
function TDockedTabMaster.GetTabDisplayStateEditor(ASourceEditor: TSourceEditorInterface): TTabDisplayState;
var
LPageCtrl: TModulePageControl;
begin
if ASourceEditor = nil then
Exit(tdsNone);
LPageCtrl := SourceEditorWindows.FindModulePageControl(ASourceEditor);
if LPageCtrl = nil then Exit(tdsNone);
case LPageCtrl.PageIndex of
0: Exit(tdsCode);
1: Exit(tdsDesign);
2: Exit(tdsDesign);
else
Exit(tdsNone);
end;
end;
constructor TDockedTabMaster.Create;
begin
FAutoSizeControlList := TObjectList.Create(False);
end;
destructor TDockedTabMaster.Destroy;
begin
FAutoSizeControlList.Free;
inherited Destroy;
end;
function TDockedTabMaster.AutoSizeInShowDesigner(AControl: TControl): Boolean;
begin
// enable autosizing for docked form editor forms, see issue #32207 - disabled
// in SourceFileManager per PreventAutoSize
FAutoSizeControlList.Add(AControl);
Result := True;
end;
procedure TDockedTabMaster.EnableAutoSizing(AControl: TControl);
var
AIndex: Integer;
AutoSizeControl: TControl;
begin
// enable autosizing for docked form editor forms, see issue #32207 - disabled
// in SourceFileManager per PreventAutoSize
{$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedTabMaster.EnableAutoSizing: ', DbgSName(AControl)); {$ENDIF}
if not Assigned(AControl) then Exit;
AutoSizeControl := nil;
if AControl is TNonFormProxyDesignerForm then
begin
if (TNonFormProxyDesignerForm(AControl).LookupRoot is TControl) then
AutoSizeControl := TControl(TNonFormProxyDesignerForm(AControl).LookupRoot);
end else
AutoSizeControl := AControl;
AIndex := FAutoSizeControlList.IndexOf(AutoSizeControl);
if (AIndex >= 0) then
begin
FAutoSizeControlList.Delete(AIndex);
AutoSizeControl.EnableAutoSizing{$IFDEF DebugDisableAutoSizing}('TAnchorDockMaster Delayed'){$ENDIF};
end;
end;
procedure TDockedTabMaster.ToggleFormUnit;
begin
{$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedTabMaster.ToggleFormUnit'); {$ENDIF}
case TabDisplayState of
tdsCode:
ShowDesigner(SourceEditorManagerIntf.ActiveEditor);
tdsDesign:
ShowCode(SourceEditorManagerIntf.ActiveEditor);
end;
end;
procedure TDockedTabMaster.JumpToCompilerMessage(
ASourceEditor: TSourceEditorInterface);
begin
{$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedTabMaster.JumpToCompilerMessage'); {$ENDIF}
SourceEditorManagerIntf.ActiveEditor := ASourceEditor;
ShowCode(ASourceEditor);
end;
procedure TDockedTabMaster.ShowCode(ASourceEditor: TSourceEditorInterface);
var
LPageCtrl: TModulePageControl;
begin
{$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedTabMaster.ShowCode'); {$ENDIF}
if ASourceEditor = nil then Exit;
LPageCtrl := SourceEditorWindows.FindModulePageControl(ASourceEditor);
LPageCtrl.ShowCode;
ASourceEditor.EditorControl.SetFocus;
end;
procedure TDockedTabMaster.ShowDesigner(ASourceEditor: TSourceEditorInterface; AIndex: Integer);
var
LPageCtrl: TModulePageControl;
begin
{$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedTabMaster.ShowDesigner'); {$ENDIF}
if ASourceEditor = nil then Exit;
LPageCtrl := SourceEditorWindows.FindModulePageControl(ASourceEditor);
LPageCtrl.ShowDesigner(AIndex);
end;
procedure TDockedTabMaster.ShowForm(AForm: TCustomForm);
var
LEditor: TSourceEditorInterface;
begin
{$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedTabMaster.ShowForm'); {$ENDIF}
LEditor := FindSourceEditorForDesigner(AForm.Designer);
SourceEditorManagerIntf.ActiveEditor := LEditor;
ShowDesigner(LEditor);
end;
procedure TDockedTabMaster.OptionsModified;
var
LPageCtrl: TModulePageControl;
LPageIndex: Integer;
begin
LPageCtrl := SourceEditorWindows.LastActiveModulePageControl;
LPageIndex := LPageCtrl.PageIndex;
DesignForms.RemoveAllAnchorDesigner;
SourceEditorWindows.ShowCodeTabSkipCurrent(nil, nil);
SourceEditorWindows.RefreshActivePageControls;
TDockedMainIDE.EditorActivated(SourceEditorWindows.LastActiveSourceEditor);
if LPageIndex = 0 then Exit;
LPageCtrl.TabIndex := LPageIndex;
LPageCtrl.OnChange(LPageCtrl);
end;
{ TDockedMainIDE }
class function TDockedMainIDE.GetCurrentPageControl: TModulePageControl;
var
LForm: TCustomForm;
LDesignForm: TDesignForm;
LSourceEditorWindowInterface: TSourceEditorWindowInterface;
begin
Result := nil;
if (FormEditingHook = nil) or (GlobalDesignHook = nil) then Exit;
LForm := FormEditingHook.GetDesignerForm(GlobalDesignHook.LookupRoot);
LDesignForm := DesignForms.Find(LForm);
if LDesignForm = nil then Exit;
LSourceEditorWindowInterface := LDesignForm.LastActiveSourceWindow;
if not Assigned(LSourceEditorWindowInterface) then Exit;
Result := SourceEditorWindows.FindModulePageControl(LSourceEditorWindowInterface.ActiveEditor);
end;
class procedure TDockedMainIDE.Screen_FormAdded(Sender: TObject; AForm: TCustomForm);
var
LSourceEditor: TSourceEditorInterface;
LDesignForm: TDesignForm;
LPageCtrl: TModulePageControl;
begin
if IsFormDesign(AForm) then
begin
{$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.Screen_FormAdded ', DbgSName(AForm)); {$ENDIF}
// AForm like TForm1 etc...
if not (csDesignInstance in AForm.ComponentState) and not (AForm is TNonFormProxyDesignerForm) then
Exit;
LDesignForm := TDesignForm.Create(AForm);
LDesignForm.Hiding := True;
DesignForms.Add(LDesignForm);
LSourceEditor := FindSourceEditorForDesigner(AForm.Designer);
if LSourceEditor <> nil then
begin
LPageCtrl := SourceEditorWindows.FindModulePageControl(LSourceEditor);
if LPageCtrl <> nil then
begin
LPageCtrl.DesignForm := LDesignForm;
LPageCtrl.CreateTabSheetDesigner;
if LDesignForm.IsAnchorDesign then
LPageCtrl.CreateTabSheetAnchors;
end;
end;
SetTimer(AForm.Handle, WM_SETNOFRAME, 10, nil);
end else begin
if AForm is TSourceEditorWindowInterface then
AForm.AddHandlerOnChangeBounds(@GlobalSNOnChangeBounds);
end;
end;
class procedure TDockedMainIDE.Screen_FormDel(Sender: TObject; AForm: TCustomForm);
var
LSourceEditorWindow: TSourceEditorWindow;
LSourceEditorPageControl: TSourceEditorPageControl;
begin
if IsFormDesign(AForm) then
begin
{$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.Screen_FormDel ', DbgSName(AForm)); {$ENDIF}
AForm.Parent := nil;
for LSourceEditorWindow in SourceEditorWindows do
begin
if LSourceEditorWindow.ActiveDesignForm <> nil then
if LSourceEditorWindow.ActiveDesignForm.Form = AForm then
// don't set ActiveDesignForm := nil! we can't call OnChange tab, because tab don't exist anymore
LSourceEditorWindow.RemoveActiveDesignForm;
for LSourceEditorPageControl in LSourceEditorWindow.PageControlList do
if LSourceEditorPageControl.PageControl.DesignForm <> nil then
if LSourceEditorPageControl.PageControl.DesignForm.Form = AForm then
begin
LSourceEditorPageControl.PageControl.DesignForm := nil;
LSourceEditorPageControl.PageControl.PageIndex := 0;
end;
end;
DesignForms.Remove(AForm);
end
else
if AForm is TSourceEditorWindowInterface then
AForm.RemoveHandlerOnChangeBounds(@GlobalSNOnChangeBounds);
end;
class procedure TDockedMainIDE.WindowCreate(Sender: TObject);
var
LSourceEditorWindow: TSourceEditorWindowInterface;
begin
if not (Sender is TSourceEditorWindowInterface) then Exit;
if Sender.ClassNameIs('TSourceNotebook') then
begin
{$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.WindowCreate SourceEditor created'); {$ENDIF}
LSourceEditorWindow := Sender as TSourceEditorWindowInterface;
SourceEditorWindows.Add(TSourceEditorWindow.Create(LSourceEditorWindow));
end;
end;
class procedure TDockedMainIDE.WindowDestroy(Sender: TObject);
var
LDesignForm: TDesignForm;
begin
if not (Sender is TSourceEditorWindowInterface) then Exit;
{$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.WindowDestroy'); {$ENDIF}
for LDesignForm in DesignForms do
if LDesignForm.LastActiveSourceWindow = Sender then
LDesignForm.LastActiveSourceWindow := nil;
SourceEditorWindows.Remove(Sender as TSourceEditorWindowInterface);
end;
class procedure TDockedMainIDE.WindowHide(Sender: TObject);
var
LSourceEditorWindow: TSourceEditorWindow;
LDesignForm: TDesignForm;
begin
{$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.WindowHide'); {$ENDIF}
LSourceEditorWindow := SourceEditorWindows.SourceEditorWindow[Sender as TSourceEditorWindowInterface];
if not Assigned(LSourceEditorWindow) or (LSourceEditorWindow.ActiveDesignForm = nil) then
Exit;
LDesignForm := LSourceEditorWindow.ActiveDesignForm;
LDesignForm.HideWindow;
end;
class procedure TDockedMainIDE.WindowShow(Sender: TObject);
var
LSourceEditorWindow: TSourceEditorWindow;
LDesignForm: TDesignForm;
begin
{$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.WindowShow'); {$ENDIF}
LSourceEditorWindow := SourceEditorWindows.SourceEditorWindow[Sender as TSourceEditorWindowInterface];
if not Assigned(LSourceEditorWindow) or (LSourceEditorWindow.ActiveDesignForm = nil) then
Exit;
LDesignForm := LSourceEditorWindow.ActiveDesignForm;
LDesignForm.ShowWindow;
end;
class procedure TDockedMainIDE.EditorActivated(Sender: TObject);
var
LDesigner: TIDesigner;
LSourceEditor: TSourceEditorInterface;
var
LPageCtrl: TModulePageControl;
LSourceEditorWindowInterface: TSourceEditorWindowInterface;
LDesignForm: TDesignForm;
begin
if Sender is TSourceEditorInterface then
begin
LSourceEditor := TSourceEditorInterface(Sender);
{$IFDEF DEBUGDOCKEDFORMEDITOR}
DebugLn('TDockedMainIDE.EditorActivated [' + LSourceEditor.PageCaption +
'] SourceEditorWindow[' + SourceEditorWindowCaption(LSourceEditor) + ']');
{$ENDIF}
// if we create directly new project then Activate is called without EditorCreate...
if not (LSourceEditor.EditorControl.Parent.Parent is TModulePageControl) then
begin
// possible is situation when we moved tab into other window
// then was not called event EditorDestroy - that generates problems with switching tabs
// or when we moving tab to first window ( then is raising : duplicates not allowed in dictionary).
if SourceEditorWindows.LastSourceEditorNotFound then
EditorDestroyed(nil);
EditorCreate(Sender);
end;
LDesigner := LSourceEditor.GetDesigner(True);
// should be performed during EditorCreate (parent of parent is module page ctrl)
LPageCtrl := TModulePageControl(LSourceEditor.EditorControl.Parent.Parent);
if LPageCtrl = nil then Exit;
LDesignForm := SourceEditorWindows.FindDesignForm(LPageCtrl);
if LDesigner = nil then
LPageCtrl.RemoveDesignPages
else begin
if not Assigned(LPageCtrl.Resizer) then
LPageCtrl.CreateResizer;
LPageCtrl.CreateTabSheetDesigner;
if LDesignForm.IsAnchorDesign then
LPageCtrl.CreateTabSheetAnchors;
end;
LSourceEditorWindowInterface := TSourceEditorWindowInterface(LPageCtrl.Owner);
SourceEditorWindows.LastActiveSourceEditorWindow := LSourceEditorWindowInterface;
SourceEditorWindows.LastActiveSourceEditor := LSourceEditor;
// when we switch tab, design form should be hidden
if (LDesigner = nil) or (LDesignForm = nil) then
SourceEditorWindows.SourceEditorWindow[LSourceEditorWindowInterface].ActiveDesignForm := nil
else begin
// during form loading for example from package, ActiveDesignForm assignment,
// blocks the message queue responsible for hiding form
// We can't check it because there are some forms where designing is not handled yet.
// (for that kind of forms is returned empty designform data)
// maybe we can fix this in future
if not LDesignForm.Hiding then
// Prevent unexpected events (when is deactivated some control outside designed form)
if (LDesignForm.LastActiveSourceWindow = LSourceEditorWindowInterface)
// important!!! for many error - switching between editors...
and LPageCtrl.DesignerPageActive then
SourceEditorWindows.SourceEditorWindow[LSourceEditorWindowInterface].ActiveDesignForm := LDesignForm
else
SourceEditorWindows.SourceEditorWindow[LSourceEditorWindowInterface].ActiveDesignForm := nil;
end;
if LPageCtrl.DesignerPageActive then
begin
if not LDesignForm.Hiding then
begin
SourceEditorWindows.ShowCodeTabSkipCurrent(LPageCtrl, LDesignForm);
LPageCtrl.AdjustPage;
// don't focus designer here, focus can be on ObjectInspector, then
// <Del> in OI Events deletes component instead event handler
end;
end else begin
if LDesignForm <> nil then
LDesignForm.HideWindow;
LPageCtrl.InitPage;
end;
end else begin
{$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.EditorActivated [' + DbgSName(Sender) + '] - not a Source Editor!');{$ENDIF}
end;
end;
class procedure TDockedMainIDE.EditorCreate(Sender: TObject);
var
LSourceEditor: TSourceEditorInterface;
LSourceEditorWindowInterface: TSourceEditorWindowInterface;
LParent: TWinControl;
LPageCtrl: TModulePageControl;
begin
{$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.EditorCreate'); {$ENDIF}
LSourceEditor := Sender as TSourceEditorInterface;
if LSourceEditor.EditorControl.Parent.Parent is TModulePageControl then Exit;
LParent := LSourceEditor.EditorControl.Parent;
LPageCtrl := TModulePageControl.Create(LSourceEditor.EditorControl.Owner);
LSourceEditor.EditorControl.Parent := LPageCtrl.Pages[0]; // ! SynEdit :)
LPageCtrl.OnChange := @TabChange;
LPageCtrl.Parent := LParent;
LSourceEditorWindowInterface := TSourceEditorWindowInterface(LPageCtrl.Owner);
SourceEditorWindows.SourceEditorWindow[LSourceEditorWindowInterface].AddPageCtrl(LSourceEditor, LPageCtrl);
end;
class procedure TDockedMainIDE.EditorDestroyed(Sender: TObject);
var
LSourceEditor: TSourceEditorInterface;
LPageCtrl: TModulePageControl;
LSourceEditorWindowInterface: TSourceEditorWindowInterface;
LDesignForm: TDesignForm;
begin
{$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.EditorDestroyed'); {$ENDIF}
// sender is here as special parameter, because is possible situation where is moved editor
// to another window and was not triggered EditorDestroy - for more info goto editoractivate
if Sender = nil then
LSourceEditor := SourceEditorWindows.LastActiveSourceEditor
else
LSourceEditor := TSourceEditorInterface(Sender);
// parent don't exist anymore and we must search in each window...
if Sender = nil then // but not for Sender = nil :P
LPageCtrl := SourceEditorWindows.LastActiveModulePageControl
else
LPageCtrl := SourceEditorWindows.FindModulePageControl(LSourceEditor);
if LPageCtrl = nil then Exit;
LDesignForm := DesignForms.Find(LSourceEditor.GetDesigner(False));
// goto first comment (forced destroy)
if Sender = nil then
LSourceEditorWindowInterface := SourceEditorWindows.LastActiveSourceEditorWindow
else
LSourceEditorWindowInterface := TSourceEditorWindowInterface(LPageCtrl.Owner);
if LDesignForm <> nil then
begin
SourceEditorWindows.SourceEditorWindow[LSourceEditorWindowInterface].ActiveDesignForm := nil;
LDesignForm.LastActiveSourceWindow := nil;
end;
SourceEditorWindows.SourceEditorWindow[LSourceEditorWindowInterface].RemovePageCtrl(LSourceEditor);
LPageCtrl.Free;
end;
class procedure TDockedMainIDE.TabChange(Sender: TObject);
var
LActiveSourceWindowInterface: TSourceEditorWindowInterface;
LSourceEditorWindow: TSourceEditorWindow;
LDesigner: TIDesigner;
LDesignForm: TDesignForm;
LPageCtrl: TModulePageControl;
begin
{$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.TabChange'); {$ENDIF}
// activate proper source editor window when user is clicking on page.
// (at clicking time can be active other source window)
LActiveSourceWindowInterface := TComponent(Sender).Owner as TSourceEditorWindowInterface;
if LActiveSourceWindowInterface <> SourceEditorManagerIntf.ActiveSourceWindow then
SourceEditorManagerIntf.ActiveSourceWindow := LActiveSourceWindowInterface;
LPageCtrl := TModulePageControl(Sender);
if LActiveSourceWindowInterface.ActiveEditor = nil then Exit;
if LPageCtrl = nil then Exit;
// in case there is no module and is visible page other than code page.
LDesigner := LActiveSourceWindowInterface.ActiveEditor.GetDesigner(True);
LDesignForm := DesignForms.Find(LDesigner);
if LDesignForm = nil then Exit;
LSourceEditorWindow := SourceEditorWindows.SourceEditorWindow[LActiveSourceWindowInterface];
if LSourceEditorWindow = nil then Exit;
if not LPageCtrl.DesignerPageActive then
begin
LSourceEditorWindow.ActiveDesignForm := nil;
LPageCtrl.InitPage;
LActiveSourceWindowInterface.ActiveEditor.EditorControl.SetFocus;
end else begin
LSourceEditorWindow.ActiveDesignForm := LDesignForm;
// enable autosizing after creating a new form
DockedTabMaster.EnableAutoSizing(LDesignForm.Form);
SourceEditorWindows.ShowCodeTabSkipCurrent(LPageCtrl, LDesignForm);
LPageCtrl.DesignerSetFocus;
end;
end;
class procedure TDockedMainIDE.GlobalSNOnChangeBounds(Sender: TObject);
var
LSourceEditorWindowInterface: TSourceEditorWindowInterface;
LSourceEditorWindow: TSourceEditorWindow;
LDesignForm: TDesignForm;
LPageCtrl: TModulePageControl;
LResizer: TResizer;
begin
{$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.GlobalSNOnChangeBounds'); {$ENDIF}
// Check parent. Maybe is different? If yes then window changed state (docked/undocked) and we need to perform few actions
LSourceEditorWindowInterface := Sender as TSourceEditorWindowInterface;
// dock/undock event :)
LSourceEditorWindow := SourceEditorWindows.SourceEditorWindow[LSourceEditorWindowInterface];
if LSourceEditorWindow = nil then Exit;
if LSourceEditorWindow.LastTopParent <> LSourceEditorWindowInterface.GetTopParent then
begin
LSourceEditorWindow.LastTopParent := LSourceEditorWindowInterface.GetTopParent;
// refresh for popupparent
LDesignForm := LSourceEditorWindow.ActiveDesignForm;
LSourceEditorWindow.ActiveDesignForm := nil;
LSourceEditorWindow.ActiveDesignForm := LDesignForm;
if LDesignForm <> nil then
begin
LPageCtrl := SourceEditorWindows.FindModulePageControl(LSourceEditorWindowInterface.ActiveEditor);
if not Assigned(LPageCtrl) then Exit;
LResizer := LPageCtrl.Resizer;
if not Assigned(LResizer) then Exit;
LDesignForm.Form.Parent := LResizer.FormContainer;
SetTimer(LDesignForm.Form.Handle, WM_BOUNDTODESIGNTABSHEET, 10, nil);
end;
end;
end;
class procedure TDockedMainIDE.OnShowDesignerForm(Sender: TObject; AEditor: TSourceEditorInterface;
AComponentPaletteClassSelected: Boolean);
var
LDesignForm: TDesignForm;
LPageCtrl: TModulePageControl;
LSourceEditorWindow: TSourceEditorWindow;
LSourceEditorInterface: TSourceEditorInterface;
begin
{$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.OnShowDesignerForm'); {$ENDIF}
LDesignForm := DesignForms.Find(TCustomForm(Sender).Designer);
if (LDesignForm = nil) or LDesignForm.Hiding then Exit;
LPageCtrl := SourceEditorWindows.FindModulePageControl(SourceEditorManagerIntf.ActiveEditor);
if LPageCtrl = nil then Exit;
if AComponentPaletteClassSelected then
begin
// if form is already opened do nothing, if not then show form for active module.
for LSourceEditorWindow in SourceEditorWindows do
begin
LSourceEditorInterface := LSourceEditorWindow.SourceEditorWindowInterface.ActiveEditor;
if (LSourceEditorInterface = nil) or (LSourceEditorInterface.GetDesigner(True) <> LDesignForm.Designer) then
Continue;
LPageCtrl := SourceEditorWindows.FindModulePageControl(LSourceEditorInterface);
if LPageCtrl.FormPageActive then
Exit;
end;
end;
DockedTabMaster.ShowDesigner(SourceEditorManagerIntf.ActiveEditor);
end;
class procedure TDockedMainIDE.OnShowSrcEditor(Sender: TObject);
begin
{$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.OnShowSrcEditor'); {$ENDIF}
DockedTabMaster.ShowCode(Sender as TSourceEditorInterface);
end;
class procedure TDockedMainIDE.OnDesignShowMethod(const Name: String);
var
LDesignForm: TDesignForm;
LSecondEditor: TSourceEditorInterface = nil;
LSourceEditorWindowInterface: TSourceEditorWindowInterface;
i: Integer;
begin
{$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.OnDesignShowMethod'); {$ENDIF}
if FormEditingHook = nil then Exit;
LDesignForm := DesignForms.Find(FormEditingHook.GetCurrentDesigner);
if LDesignForm = nil then Exit;
for i := 0 to SourceEditorManagerIntf.SourceWindowCount - 1 do
begin
LSourceEditorWindowInterface := SourceEditorManagerIntf.SourceWindows[i];
if LDesignForm.LastActiveSourceWindow = LSourceEditorWindowInterface then
Continue;
if LSourceEditorWindowInterface.ActiveEditor <> nil then
if LSourceEditorWindowInterface.ActiveEditor.GetDesigner(True) = LDesignForm.Designer then
begin
LSecondEditor := LSourceEditorWindowInterface.ActiveEditor;
Break;
end;
end;
if Assigned(LSecondEditor) then
begin
DockedTabMaster.ShowCode(LSecondEditor);
LazarusIDE.DoShowMethod(LSecondEditor, Name);
end else
if Assigned(LDesignForm.LastActiveSourceWindow) then
DockedTabMaster.ShowCode(LDesignForm.LastActiveSourceWindow.ActiveEditor);
end;
class procedure TDockedMainIDE.OnDesignRefreshPropertyValues;
var
LPageCtrl: TModulePageControl;
function RootIsSelected: Boolean;
var
LSelection: TPersistentSelectionList;
i: Integer;
begin
Result := False;
LSelection := TPersistentSelectionList.Create;
try
GlobalDesignHook.GetSelection(LSelection);
for i := 0 to LSelection.Count - 1 do
if LSelection.Items[i] = GlobalDesignHook.LookupRoot then
begin
Result := True;
Break;
end;
finally
LSelection.Free;
end;
end;
begin
{$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.OnDesignRefreshPropertyValues'); {$ENDIF}
if not (GlobalDesignHook.LookupRoot is TCustomFrame)
and not (GlobalDesignHook.LookupRoot is TCustomForm) then Exit;
LPageCtrl := GetCurrentPageControl;
if not Assigned(LPageCtrl) then Exit;
if not ((LPageCtrl.PageIndex = 2) or RootIsSelected) then Exit;
LPageCtrl.AdjustPage;
end;
class procedure TDockedMainIDE.OnDesignModified(Sender: TObject);
var
LPageCtrl: TModulePageControl;
begin
{$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.OnDesignModified'); {$ENDIF}
LPageCtrl := GetCurrentPageControl;
if not Assigned(LPageCtrl) then Exit;
if not Assigned(LPageCtrl.Resizer) then Exit;
LPageCtrl.Resizer.ResizeControl.OnModified;
end;
class procedure TDockedMainIDE.OnDesignPersistentAdded(APersistent: TPersistent; Select: Boolean);
begin
{$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.OnDesignPersistentAdded'); {$ENDIF}
OnDesignModified(nil);
end;
class procedure TDockedMainIDE.OnDesignPersistentDeleted(APersistent: TPersistent);
begin
{$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.OnDesignPersistentDeleted'); {$ENDIF}
OnDesignModified(nil);
end;
class procedure TDockedMainIDE.OnDesignMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
LPageCtrl: TModulePageControl;
begin
{$IFDEF DEBUGDOCKEDFORMEDITOR} writeln('TDockedMainIDE.OnDesignMouseDown'); {$ENDIF}
LPageCtrl := GetCurrentPageControl;
if not Assigned(LPageCtrl) then Exit;
LPageCtrl.DesignerSetFocus;
end;
class procedure TDockedMainIDE.OnDesignSetSelection(
const ASelection: TPersistentSelectionList);
var
LDesignForm: TDesignForm;
LSelectedControl: TControl;
begin
{$IFDEF DEBUGDOCKEDFORMEDITOR} DebugLn('TDockedMainIDE.OnDesignSetSelection'); {$ENDIF}
LDesignForm := DesignForms.Find(FormEditingHook.GetCurrentDesigner);
if LDesignForm = nil then Exit;
if (ASelection.Count = 1) and (ASelection[0] is TControl) then
LSelectedControl := TControl(ASelection[0]);
if LSelectedControl = LDesignForm.SelectedControl then Exit;
LDesignForm.SelectedControl := LSelectedControl;
OnDesignModified(nil);
end;
end.