lazarus/components/dockedformeditor/source/dockedformaccesses.pas

257 lines
6.7 KiB
ObjectPascal

{
*****************************************************************************
See the file COPYING.modifiedLGPL.txt, included in this distribution,
for details about the license.
*****************************************************************************
Author: Maciej Izak
DaThoX 2004-2015
FreeSparta.com
}
unit DockedFormAccesses;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils,
// LCL
Forms, Controls, LCLIntf, LCLType,
// IdeIntf
FormEditingIntf, SrcEditorIntf, ObjectInspector, ComponentEditors,
// DockedFormEditor
DockedBasicAnchorDesigner;
type
{ TFormAccess }
TFormAccess = class
private
FForm: TCustomForm;
FOnChangeHackedBounds: TNotifyEvent;
FUpdate: Boolean;
protected
function GetPublishedBounds(AIndex: Integer): Integer;
procedure SetPublishedBounds(AIndex: Integer; AValue: Integer);
procedure DoChangeHackedBounds;
public
constructor Create(AForm: TCustomForm); virtual;
procedure BeginUpdate; virtual;
function ClientOffset: TPoint;
procedure EndUpdate({%H-}AModified: Boolean = False); virtual;
procedure HideWindow;
procedure ShowWindow;
public
property Form: TCustomForm read FForm;
property Left: Integer index 0 read GetPublishedBounds write SetPublishedBounds;
property Top: Integer index 1 read GetPublishedBounds write SetPublishedBounds;
property Width: Integer index 2 read GetPublishedBounds write SetPublishedBounds;
property Height: Integer index 3 read GetPublishedBounds write SetPublishedBounds;
property OnChangeHackedBounds: TNotifyEvent read FOnChangeHackedBounds write FOnChangeHackedBounds;
property Update: Boolean read FUpdate;
end;
{ TDesignFormIDE }
TDesignFormIDE = class(TFormAccess)
private
FAnchorDesigner: TBasicAnchorDesigner;
FLastActiveSourceWindow: TSourceEditorWindowInterface;
FSelectedControl: TControl;
function GetCurrentObjectInspector: TObjectInspectorDlg;
function GetDesigner: TIDesigner;
function GetDesignWinControl: TWinControl;
public
constructor Create(AForm: TCustomForm); override;
destructor Destroy; override;
procedure BeginUpdate; override;
procedure EndUpdate(AModified: Boolean = False); override;
function IsAnchorDesign: Boolean;
function MainMenuFaked: Boolean;
function MainMenuHeight: Integer;
public
property AnchorDesigner: TBasicAnchorDesigner read FAnchorDesigner write FAnchorDesigner;
property CurrentObjectInspector: TObjectInspectorDlg read GetCurrentObjectInspector;
property Designer: TIDesigner read GetDesigner;
property DesignWinControl: TWinControl read GetDesignWinControl;
property LastActiveSourceWindow: TSourceEditorWindowInterface read FLastActiveSourceWindow write FLastActiveSourceWindow;
property SelectedControl: TControl read FSelectedControl write FSelectedControl;
end;
implementation
type
THackForm = class(TForm);
{ TDesignFormIDE }
function TFormAccess.GetPublishedBounds(AIndex: Integer): Integer;
begin
case AIndex of
0: Result := FForm.Left;
1: Result := FForm.Top;
2: Result := FForm.Width;
3: Result := FForm.Height;
end;
end;
procedure TFormAccess.SetPublishedBounds(AIndex: Integer; AValue: Integer);
const
cMinWidth = 135;
cMaxWidth = 5*1024; // huge Mac monitors have 5K pixels width
begin
if AIndex = 2 then
if AValue < cMinWidth then
AValue := cMinWidth;
if AIndex in [2, 3] then
if AValue > cMaxWidth then
AValue := cMaxWidth;
DoChangeHackedBounds;
end;
procedure TFormAccess.DoChangeHackedBounds;
begin
if not FUpdate and Assigned(FOnChangeHackedBounds) then
FOnChangeHackedBounds(FForm);
end;
constructor TFormAccess.Create(AForm: TCustomForm);
begin
FForm := AForm;
FUpdate := False;
end;
procedure TFormAccess.BeginUpdate;
begin
FUpdate := True;
end;
function TFormAccess.ClientOffset: TPoint;
begin
Result := Point(0, 0);
{$IFDEF LCLWin32}
Result.X := GetSystemMetrics(SM_CXSIZEFRAME);
Result.Y := GetSystemMetrics(SM_CYSIZEFRAME) + GetSystemMetrics(SM_CYCAPTION);
{$ENDIF}
end;
procedure TFormAccess.EndUpdate(AModified: Boolean);
begin
FUpdate := False;
end;
procedure TFormAccess.HideWindow;
begin
if FForm.Parent = nil then
LCLIntf.ShowWindow(FForm.Handle, SW_HIDE);
end;
procedure TFormAccess.ShowWindow;
begin
if FForm.Parent = nil then
LCLIntf.ShowWindow(FForm.Handle, SW_SHOW);
end;
{ TDesignFormIDE }
function TDesignFormIDE.GetDesigner: TIDesigner;
begin
Result := FForm.Designer;
end;
function TDesignFormIDE.GetCurrentObjectInspector: TObjectInspectorDlg;
begin
if Assigned(FormEditingHook) and (FormEditingHook.GetCurrentDesigner = Designer) then
Result := FormEditingHook.GetCurrentObjectInspector
else
Result := nil;
end;
function TDesignFormIDE.GetDesignWinControl: TWinControl;
begin
Result := Form;
if Form is TNonFormProxyDesignerForm then
if TNonFormProxyDesignerForm(Form).LookupRoot is TWinControl then
Result := TWinControl(TNonFormProxyDesignerForm(Form).LookupRoot)
else
Result := nil;
end;
constructor TDesignFormIDE.Create(AForm: TCustomForm);
begin
inherited Create(AForm);
FAnchorDesigner := nil;
FLastActiveSourceWindow := nil;
end;
destructor TDesignFormIDE.Destroy;
begin
FreeAndNil(FAnchorDesigner);
inherited Destroy;
end;
procedure TDesignFormIDE.BeginUpdate;
begin
THackForm(FForm).SetDesigning(False, False);
if Assigned(FAnchorDesigner) then
FAnchorDesigner.BeginUpdate;
inherited BeginUpdate;
end;
procedure TDesignFormIDE.EndUpdate(AModified: Boolean);
begin
THackForm(FForm).SetDesigning(True, False);
if Assigned(FAnchorDesigner) then
FAnchorDesigner.EndUpdate;
inherited EndUpdate(AModified);
if AModified and Assigned(CurrentObjectInspector) then
CurrentObjectInspector.RefreshPropertyValues;
end;
function TDesignFormIDE.IsAnchorDesign: Boolean;
begin
Result := Assigned(DesignWinControl);
end;
function TDesignFormIDE.MainMenuFaked: Boolean;
var
i: Integer;
begin
Result := False;
// {$IF DEFINED(LCLWin32) OR DEFINED(LCLGtk2) OR DEFINED(LCLQt) OR DEFINED(LCLQt5)}
{$IF DEFINED(LCLQt) OR DEFINED(LCLQt5)}
// Menu is already shown in designer
Exit;
{$ENDIF}
if Assigned(Form.Menu)
and not (csDestroying in Form.Menu.ComponentState)
and (Form.Menu.Items.Count > 0)
then
for i := 0 to Form.Menu.Items.Count - 1 do
if Form.Menu.Items[i].Visible then
Exit(True);
end;
function TDesignFormIDE.MainMenuHeight: Integer;
begin
// some WS (Gtk2) return too big SM_CYMENU, just set it according to font height
// no problem, it is used only for the fake main menu
{$IFDEF LCLWin32}
Result := lclintf.GetSystemMetrics(SM_CYMENU);
{$ELSE}
if Form.HandleAllocated then
Result := Form.Canvas.TextHeight('Hg') * 4 div 3
else
Result := 20;
{$ENDIF}
end;
end.