mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-05-12 01:42:40 +02:00
257 lines
6.7 KiB
ObjectPascal
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.
|
|
|