diff --git a/.gitattributes b/.gitattributes index e46ab5882b..b71c7618e3 100644 --- a/.gitattributes +++ b/.gitattributes @@ -7308,6 +7308,10 @@ ide/editoroptions.pp svneol=native#text/pascal ide/editoroptions.rc svneol=native#text/plain ide/editoroptions.res -text ide/editortoolbarstatic.pas svneol=native#text/pascal +ide/embedded_designer_basics.pas svneol=native#text/plain +ide/embedded_designer_formeditor.lfm svneol=native#text/plain +ide/embedded_designer_formeditor.pas svneol=native#text/plain +ide/embedded_designer_notebook.pas svneol=native#text/plain ide/emptymethodsdlg.lfm svneol=native#text/plain ide/emptymethodsdlg.pas svneol=native#text/plain ide/encloseifdef.lfm svneol=native#text/plain @@ -7435,6 +7439,8 @@ ide/frames/editor_multiwindow_options.lfm svneol=native#text/plain ide/frames/editor_multiwindow_options.pas svneol=native#text/pascal ide/frames/editortoolbar_options.lfm svneol=native#text/plain ide/frames/editortoolbar_options.pas svneol=native#text/pascal +ide/frames/embedded_designer_options.lfm svneol=native#text/plain +ide/frames/embedded_designer_options.pas svneol=native#text/plain ide/frames/env_file_filters.lfm svneol=native#text/plain ide/frames/env_file_filters.pas svneol=native#text/plain ide/frames/files_options.lfm svneol=native#text/plain diff --git a/components/ideintf/componenteditors.pas b/components/ideintf/componenteditors.pas index ac270a3e32..98a3dc1a5d 100644 --- a/components/ideintf/componenteditors.pas +++ b/components/ideintf/componenteditors.pas @@ -60,6 +60,8 @@ type protected FForm: TCustomForm; FHandlers: array[TComponentEditorDesignerHookType] of TMethodList; + FIsActive: Boolean; + procedure SetIsActive(const AVal: Boolean); virtual; function GetPropertyEditorHook: TPropertyEditorHook; virtual; abstract; function GetHandlerCount(HookType: TComponentEditorDesignerHookType): integer; procedure AddHandler(HookType: TComponentEditorDesignerHookType; const Handler: TMethod); @@ -108,6 +110,7 @@ type property Form: TCustomForm read FForm; property ChangeStamp: int64 read FChangeStamp;// increased on calling Modified procedure DisconnectComponent; virtual; + property IsActive:boolean read FIsActive write SetIsActive; public // Handlers procedure RemoveAllHandlersForObject(const HandlerObject: TObject); @@ -1659,6 +1662,13 @@ end; { TComponentEditorDesigner } +procedure TComponentEditorDesigner.SetIsActive(const AVal: Boolean); +begin + if FIsActive <> AVal then + FIsActive := AVal; +end; + + function TComponentEditorDesigner.GetHandlerCount( HookType: TComponentEditorDesignerHookType): integer; begin diff --git a/components/ideintf/ideoptionsintf.pas b/components/ideintf/ideoptionsintf.pas index 650f3efea2..4910850566 100644 --- a/components/ideintf/ideoptionsintf.pas +++ b/components/ideintf/ideoptionsintf.pas @@ -164,6 +164,7 @@ const EnvOptionsBackup = 700; EnvOptionsNaming = 800; EnvOptionsFileFilters = 900; + EnvOptionsEmbeddedDsg = 950; GroupEditor = 200; EdtOptionsGeneral = 100; diff --git a/components/ideintf/idewindowintf.pas b/components/ideintf/idewindowintf.pas index f01ebc1938..c0bf7dbcb2 100644 --- a/components/ideintf/idewindowintf.pas +++ b/components/ideintf/idewindowintf.pas @@ -438,6 +438,7 @@ type TIDEDockMaster = class protected FHideSimpleLayoutOptions: boolean; + FLoaded: Boolean; public procedure MakeIDEWindowDockable(AControl: TWinControl); virtual; abstract; // make AControl dockable, it can be docked and other dockable windows can be docked to it, this does not make it visible procedure MakeIDEWindowDockSite(AForm: TCustomForm; ASides: TDockSides = [alBottom]); virtual; abstract; // make AForm a dock site, AForm can not be docked, its Parent must be kept nil, this does not make it visible @@ -449,6 +450,7 @@ type procedure ResetSplitters; virtual; abstract; // if the dock site has been resized after loading, you have to reset (percentual) splitters function DockedDesktopOptClass: TAbstractDesktopDockingOptClass; virtual; abstract; property HideSimpleLayoutOptions: boolean read FHideSimpleLayoutOptions; + property Loaded: Boolean read FLoaded write FLoaded Default False; end; TIDEWindowGlobalOption = class diff --git a/components/ideintf/srceditorintf.pas b/components/ideintf/srceditorintf.pas index bf402b779d..f0b34ae0f8 100644 --- a/components/ideintf/srceditorintf.pas +++ b/components/ideintf/srceditorintf.pas @@ -358,6 +358,9 @@ type procedure InvalidateMarklingsOfAllFiles(aProducer: TSourceMarklingProducer); virtual; abstract; procedure InvalidateMarklings(aProducer: TSourceMarklingProducer; aFilename: string); virtual; abstract; property ShowTabs: Boolean read GetShowTabs write SetShowTabs; + procedure UpdateEmbedFormDsgSettings; virtual; abstract; + Procedure StartExecuteDock(TheDockSite: TCustomForm; TheDockControl : TControl); virtual; abstract; + Procedure StartExecuteUnDock(TheDockSite: TCustomForm; TheUnDockControl : TControl); virtual; abstract; end; diff --git a/docs/Contributors.txt b/docs/Contributors.txt index 4036beaf52..a36bf7204a 100644 --- a/docs/Contributors.txt +++ b/docs/Contributors.txt @@ -21,7 +21,7 @@ Arnold Bosch Attila Tamás - Hungarian translation August Klein Babak Mahmoudabadi -Balazs Szekely +Balázs Székely Bald Zhang Bart Broersma Benito van der Zander @@ -186,6 +186,7 @@ Petr Kristan Philip J. Hess Philippe Picard Pierre Gillmann +PilotLogic Software House Pino Toscano Przemyslaw Nagay Radek Cervinka diff --git a/ide/embedded_designer_basics.pas b/ide/embedded_designer_basics.pas new file mode 100644 index 0000000000..0be40a9118 --- /dev/null +++ b/ide/embedded_designer_basics.pas @@ -0,0 +1,181 @@ +{********************************************************************** + Copyright (c) PilotLogic Software House + All rights reserved + + This file is part of CodeTyphon Studio (https://www.pilotlogic.com/) + + *************************************************************************** + * * + * This source is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This code is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * General Public License for more details. * + * * + * A copy of the GNU General Public License is available on the World * + * Wide Web at . You can also * + * obtain it by writing to the Free Software Foundation, * + * Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1335, USA. * + * * + ***************************************************************************} + +unit embedded_designer_basics; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, Controls, LMessages, Forms, + FormEditingIntf, IDEWindowIntf; + +type + TEmbedParentType = (ctptParent, ctptParentWindow, ctptDock, ctptNone); + TEmbedMessageHandlerEvent = procedure(Sender: TObject; SenderCtrl: TControl; Msg: TLMessage) of object; + +const + CN_PREVIEW_FACTOR: Single = 7; + +{$if defined(LCLCocoa)} + CN_BORDER_PX=6; +{$elseif defined(LCLCarbon)} + CN_BORDER_PX=6; +{$else} + CN_BORDER_PX=6; +{$endif} + + CN_CAPTION_HEIGHT=18; + +//=== Parent Type =========================== + +{$IF DEFINED(WINDOWS)} //------------ Win -------------------------------- + + {$IF DEFINED(LCLWin32) or DEFINED(LCLWin64)} + CN_FORM_DESIGNER_PARENT_TYPE : TEmbedParentType = ctptParentWindow; + {$ELSEIF DEFINED(LCLGTK2)} + CN_FORM_DESIGNER_PARENT_TYPE : TEmbedParentType = ctptParentWindow; + {$ELSEIF DEFINED(LCLGTK3)} + CN_FORM_DESIGNER_PARENT_TYPE : TEmbedParentType = ctptParentWindow; + {$elseif DEFINED(LCLQT)} + CN_FORM_DESIGNER_PARENT_TYPE : TEmbedParentType = ctptParent; + {$elseif DEFINED(LCLQT5)} + CN_FORM_DESIGNER_PARENT_TYPE : TEmbedParentType = ctptParent; + {$ELSE} + CN_FORM_DESIGNER_PARENT_TYPE : TEmbedParentType = ctptParentWindow; + {$ENDIF} + +{$ELSEIF DEFINED(DARWIN)} //------------ MacOS ------------------------------ + + {$IF DEFINED(LCLCocoa)} + CN_FORM_DESIGNER_PARENT_TYPE : TEmbedParentType = ctptParent; + {$ELSEIF DEFINED(LCLGTK2)} + CN_FORM_DESIGNER_PARENT_TYPE : TEmbedParentType = ctptParentWindow; + {$ELSEIF DEFINED(LCLGTK3)} + CN_FORM_DESIGNER_PARENT_TYPE : TEmbedParentType = ctptParentWindow; + {$elseif DEFINED(LCLQT)} + CN_FORM_DESIGNER_PARENT_TYPE : TEmbedParentType = ctptParent; + {$elseif DEFINED(LCLQT5)} + CN_FORM_DESIGNER_PARENT_TYPE : TEmbedParentType = ctptParent; + {$ELSEIF DEFINED(LCLWin32) or DEFINED(LCLWin64)} + CN_FORM_DESIGNER_PARENT_TYPE : TEmbedParentType = ctptParentWindow; + {$ELSE} + CN_FORM_DESIGNER_PARENT_TYPE : TEmbedParentType = ctptParentWindow; + {$ENDIF} + +{$ELSE} //------------- Unix -------------------------------- + + {$IF DEFINED(LCLGTK2)} + CN_FORM_DESIGNER_PARENT_TYPE : TEmbedParentType = ctptParentWindow; + {$ELSEIF DEFINED(LCLGTK3)} + CN_FORM_DESIGNER_PARENT_TYPE : TEmbedParentType = ctptParent; + {$ELSEIF DEFINED(LCLQT)} + CN_FORM_DESIGNER_PARENT_TYPE : TEmbedParentType = ctptParentWindow; + {$ELSEIF DEFINED(LCLQT5)} + CN_FORM_DESIGNER_PARENT_TYPE : TEmbedParentType = ctptParentWindow; + {$ELSEIF DEFINED(LCLWin32) or DEFINED(LCLWin64)} + CN_FORM_DESIGNER_PARENT_TYPE : TEmbedParentType = ctptParentWindow; + {$ELSE} + CN_FORM_DESIGNER_PARENT_TYPE : TEmbedParentType = ctptParentWindow; + {$ENDIF} + +{$ENDIF} + +//=== OTHER ================================== + +{$IF DEFINED(MSWINDOWS)} //------------ Win -------------------------------- + + {$IF DEFINED(LCLWin32) or DEFINED(LCLWin64)} + CN_REMOVE_FORM_BORDER = True; //Windows Has Form Border + CN_MUST_FIND_MAINMENU_HEIGHT = True; //On Windows MainMenu Height is NOT part of Total Form Height + CN_USE_FAKE_MAINMENU = False; + {$ELSE} + CN_REMOVE_FORM_BORDER = False; //QT and GTK2 NOT has Form Border + CN_MUST_FIND_MAINMENU_HEIGHT = False; //On QT MainMenu Height is part of Total Form Height + + {$IF DEFINED(LCLGTK2) or DEFINED(GTK2) or DEFINED(LCLGTK) or DEFINED(GTK)} + CN_USE_FAKE_MAINMENU = True; //On GTK Must Use Fake Menu + {$ELSE} + CN_USE_FAKE_MAINMENU = False; + {$ENDIF} + + {$ENDIF} + +{$ELSEIF DEFINED(DARWIN)} //------------ MacOS ------------------------------ + + {$IF DEFINED(LCLGTK2) or DEFINED(GTK2) or DEFINED(LCLGTK) or DEFINED(GTK)} + CN_REMOVE_FORM_BORDER = False; + CN_MUST_FIND_MAINMENU_HEIGHT = False; + CN_USE_FAKE_MAINMENU = True; //On GTK Must Use Fake Menu + {$elseif defined(LCLCocoa)} + CN_REMOVE_FORM_BORDER = False; + CN_MUST_FIND_MAINMENU_HEIGHT = True; + CN_USE_FAKE_MAINMENU = True; + {$elseif defined(LCLCarbon)} + CN_REMOVE_FORM_BORDER = False; + CN_MUST_FIND_MAINMENU_HEIGHT = True; + CN_USE_FAKE_MAINMENU = True; + {$ELSE} + CN_REMOVE_FORM_BORDER = False; //QT and GTK2 NOT has Form Border + CN_MUST_FIND_MAINMENU_HEIGHT = False; //On QT MainMenu Height is part of Total Form Height + CN_USE_FAKE_MAINMENU = False; + {$ENDIF} + +{$ELSE} //------------- Unix -------------------------------- + CN_REMOVE_FORM_BORDER = False; //QT and GTK2 NOT has Form Border + CN_MUST_FIND_MAINMENU_HEIGHT = False; //On QT MainMenu Height is part of Total Form Height + + {$IF DEFINED(LCLGTK) or DEFINED(LCLGTK2) or DEFINED(LCLGTK3)} + CN_USE_FAKE_MAINMENU = True; //On GTK Must Use Fake Menu + {$ELSE} + CN_USE_FAKE_MAINMENU = False; + {$ENDIF} + +{$ENDIF} + +var + Embedded_Updating : boolean = false; + +// Functions + +function Embed_IsDesignForm(fm: TCustomForm): boolean; + +implementation + +function Embed_IsDesignForm(fm: TCustomForm): boolean; +begin + result:=false; + if fm = nil then Exit; + result:=IsFormDesign(fm); + + //.... + if result=true then Exit; + Result := ( (csDesignInstance in fm.ComponentState) or + (csDesigning in fm.ComponentState) ) and + (fm.InheritsFrom(TCustomForm) ); +end; + +end. diff --git a/ide/embedded_designer_formeditor.lfm b/ide/embedded_designer_formeditor.lfm new file mode 100644 index 0000000000..4ed900afe0 --- /dev/null +++ b/ide/embedded_designer_formeditor.lfm @@ -0,0 +1,437 @@ +object EmbedFormEditor: TEmbedFormEditor + Left = 0 + Height = 352 + Top = 0 + Width = 474 + Align = alClient + ClientHeight = 352 + ClientWidth = 474 + Color = clDefault + ParentColor = False + TabOrder = 0 + DesignLeft = 372 + DesignTop = 117 + object RootPanel: TPanel + Left = 0 + Height = 352 + Top = 0 + Width = 474 + Align = alClient + BevelOuter = bvNone + ClientHeight = 352 + ClientWidth = 474 + DoubleBuffered = True + ParentColor = False + ParentDoubleBuffered = False + TabOrder = 0 + object pnDesignBox: TScrollBox + Left = 0 + Height = 352 + Top = 0 + Width = 474 + HorzScrollBar.Increment = 1 + HorzScrollBar.Page = 1 + HorzScrollBar.Smooth = True + HorzScrollBar.Tracking = True + VertScrollBar.Increment = 1 + VertScrollBar.Page = 1 + VertScrollBar.Smooth = True + VertScrollBar.Tracking = True + Align = alClient + BorderStyle = bsNone + Color = clWindow + ParentColor = False + TabOrder = 0 + end + object pnScreenPreview: TPanel + AnchorSideRight.Side = asrBottom + AnchorSideBottom.Side = asrBottom + Left = 333 + Height = 74 + Hint = 'Set edit form position to virtual screen' + Top = 250 + Width = 119 + Anchors = [akRight, akBottom] + BorderSpacing.Right = 3 + BorderSpacing.Bottom = 3 + BevelInner = bvLowered + ClientHeight = 74 + ClientWidth = 119 + Color = 10841658 + DoubleBuffered = False + ParentColor = False + ParentDoubleBuffered = False + ParentShowHint = False + ShowHint = True + TabOrder = 1 + object pnWindowScreenPreview: TPanel + Left = 40 + Height = 35 + Top = 24 + Width = 50 + ClientHeight = 35 + ClientWidth = 50 + Color = clForm + ParentColor = False + TabOrder = 0 + object pnCaptionWindowScreenPreview: TPanel + Left = 1 + Height = 3 + Top = 1 + Width = 48 + Align = alTop + BevelOuter = bvNone + Color = clActiveCaption + ParentColor = False + TabOrder = 0 + OnMouseDown = imgWindowScreenPreviewMouseDown + OnMouseMove = imgWindowScreenPreviewMouseMove + OnMouseUp = imgWindowScreenPreviewMouseUp + end + object imgWindowScreenPreview: TImage + Cursor = crCross + Left = 1 + Height = 30 + Top = 4 + Width = 48 + Align = alClient + OnMouseDown = imgWindowScreenPreviewMouseDown + OnMouseMove = imgWindowScreenPreviewMouseMove + OnMouseUp = imgWindowScreenPreviewMouseUp + Stretch = True + end + end + end + object pnScreenPreviewBtns: TPanel + Left = 333 + Height = 80 + Top = 162 + Width = 112 + Anchors = [akRight, akBottom] + BevelOuter = bvNone + ClientHeight = 80 + ClientWidth = 112 + DoubleBuffered = False + ParentDoubleBuffered = False + TabOrder = 2 + object sb_up: TSpeedButton + Left = 56 + Height = 22 + Hint = 'Move edit form Up' + Top = 8 + Width = 23 + Anchors = [akTop, akRight] + Glyph.Data = { + 76020000424D760200000000000036000000280000000C0000000C0000000100 + 2000000000004002000064000000640000000000000000000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00CEF0F0FF0036 + 87FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 + 00FF873600FFF0F0CEFFFFFFFF0087CEF0FF000036FF000000FF000000FF0000 + 00FF000000FF000000FF000000FF360000FFF0CE87FFFFFFFF00FFFFFF00FFFF + FF000060ABFF000000FF000000FF000000FF000000FF000000FF000000FFAB60 + 00FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00ABF0F0FF000060FF000000FF0000 + 00FF000000FF000000FF600000FFF0F0ABFFFFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF003687CEFF000000FF000000FF000000FF000000FFCE8736FFFFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00ABF0F0FF000060FF0000 + 00FF000000FF600000FFF0F0ABFFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF0060ABF0FF000000FF000000FFF0AB60FFFFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00CEF0F0FF0036 + 87FF873600FFF0F0CEFFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF0060ABF0FFF0AB60FFFFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + } + OnClick = sb_upClick + ShowHint = True + ParentShowHint = False + end + object sb_bottom: TSpeedButton + Left = 56 + Height = 22 + Hint = 'Move edit form Down' + Top = 56 + Width = 23 + Anchors = [akTop, akRight] + Glyph.Data = { + 76020000424D760200000000000036000000280000000C0000000C0000000100 + 2000000000004002000064000000640000000000000000000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF005FABF1FEEFAB61FFF1AB5F01FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00CFF1F0FD0137 + 89FF873600FFF0F0CEFFF0F1CF01FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00ABF0F000FFFFFF0061ADF1FE000101FF000000FFF0AB60FFFF000000FFFF + FF00F0F0AB00FFFFFF00FFFFFF00FFFFFF00FFFFFF00ACF1F1FD010262FF0000 + 00FF000000FF600000FFF0EFABFFF1F1AC01FFFFFF00FFFFFF00FFFFFF00ABF0 + F000FFFFFF003788CFFE000101FF000000FF000000FF000000FFCE8736FF0000 + 0000FFFFFF00F0F0AB00FFFFFF00FFFFFF00ACF1F1FD010162FF000000FF0000 + 00FF000000FF000000FF600000FFF0F0ABFFF1F1AC01FFFFFF00FFFFFF00FFFF + FF000161ACFE000001FF000000FF000000FF000000FF000000FF000000FFAB61 + 01FF00000000FFFFFF00FFFFFF0088CFF1FD010138FF000000FF000000FF0000 + 00FF000000FF000000FF000000FF360000FFF0CE87FFFF000000CEF0F0FF0138 + 88FF000001FF000000FF000000FF000000FF000000FF000000FF000000FF0000 + 00FF863600FFF0EFCDFFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + } + OnClick = sb_upClick + ShowHint = True + ParentShowHint = False + end + object sb_left: TSpeedButton + Left = 30 + Height = 22 + Hint = 'Move edit form Left' + Top = 32 + Width = 23 + Anchors = [akTop, akRight] + Glyph.Data = { + 76020000424D760200000000000036000000280000000C0000000C0000000100 + 2000000000004002000064000000640000000000000000000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00CE873600FFFF + FF00FFFFFF00F1F0CE01BC824302EECD86FF363687FFFFFFFF00FFFFFF00FFFF + FF00F0AB6000FFFFFF00FFFFFF00FFFFFF00DFBC8202EFEECCFF863500FF0000 + 00FF003687FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00F0AB60016743 + 1B02CC8636FF000000FF000000FF000001FF003687FFFFFFFF00FFFFFF00F0EF + CD018534000178563002EEAA5FFF000000FF000000FF000000FF000000FF0000 + 01FF003687FFFFFFFF00FFFFFF00F0EFCDFF863600FF000000FF000000FF0000 + 00FF000000FF000000FF000000FF000001FF003687FFFFFFFF00FFFFFF00FFFF + 0000F0F0ABFF5F0000FE010100FF000000FF000000FF000000FF000000FF0000 + 01FF003687FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00F0AB60FF0000 + 00FE010100FF000000FF000000FF000001FF003687FFFFFFFF00FFFFFF00FFFF + FF00F0AB6000FFFFFF00FFFFFF00FFFFFF00CE8736FF000001FF010000FF0000 + 01FF003687FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00CE873600FFFF + FF00FFFFFF00F1F0CEFF873500FE000101FF003687FFFFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00F1CF8701EFCD + 87FF363687FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + } + OnClick = sb_upClick + ShowHint = True + ParentShowHint = False + end + object sb_right: TSpeedButton + Left = 82 + Height = 22 + Hint = 'Move edit form Right' + Top = 32 + Width = 23 + Anchors = [akTop, akRight] + Glyph.Data = { + 76020000424D760200000000000036000000280000000C0000000C0000000100 + 2000000000004002000064000000640000000000000000000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00363687FFF0CE87FFFFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000036 + 87FF000000FF873600FFF0F0CEFFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00003687FF000000FF000000FF000000FFCE87 + 36FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000036 + 87FF000000FF000000FF000000FF000000FF000000FFF0AB60FFFFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00003687FF000000FF000000FF000000FF0000 + 00FF000000FF000000FF000000FF873600FFF0F0CEFFFFFFFF00FFFFFF000036 + 87FF000000FF000000FF000000FF000000FF000000FF000000FF600000FFF0F0 + ABFFFFFFFF00FFFFFF00FFFFFF00003687FF000000FF000000FF000000FF0000 + 00FF000000FFF0AB60FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000036 + 87FF000000FF000000FF000000FFCE8736FFFFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00003687FF000000FF873600FFF0F0CEFFFFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF003636 + 87FFF0CE87FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + } + OnClick = sb_upClick + ShowHint = True + ParentShowHint = False + end + object sb_zero: TSpeedButton + Left = 56 + Height = 22 + Hint = 'Reset edit form to Screen position (0,0)' + Top = 32 + Width = 23 + Anchors = [akTop, akRight] + Glyph.Data = { + 76020000424D760200000000000036000000280000000C0000000C0000000100 + 2000000000004002000064000000640000000000000000000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00000000FF000000FF0000 + 00FF000000FF000000FF000000FFFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00000000FF000000FFF0F0F0FFF0F0F0FFF0F0F0FFF0F0F0FF000000FF0000 + 00FFFFFFFF00FFFFFF00FFFFFF00000000FF000000FFF0F0F0FFF0F0F0FF0000 + 00FF000000FFF0F0F0FFF0F0F0FF000000FF000000FFFFFFFF00FFFFFF000000 + 00FF000000FFF0F0F0FF000000FFF0F0F0FFF0F0F0FF000000FFF0F0F0FF0000 + 00FF000000FFFFFFFF00FFFFFF00000000FF000000FFF0F0F0FF000000FFF0F0 + F0FFF0F0F0FFF0F0F0FFF0F0F0FF000000FF000000FFFFFFFF00FFFFFF000000 + 00FF000000FFF0F0F0FF000000FFF0F0F0FFF0F0F0FFF0F0F0FFF0F0F0FF0000 + 00FF000000FFFFFFFF00FFFFFF00000000FF000000FFF0F0F0FF000000FFF0F0 + F0FFF0F0F0FF000000FFF0F0F0FF000000FF000000FFFFFFFF00FFFFFF000000 + 00FF000000FFF0F0F0FFF0F0F0FF000000FF000000FFF0F0F0FFF0F0F0FF0000 + 00FF000000FFFFFFFF00FFFFFF00FFFFFF00000000FF000000FFF0F0F0FFF0F0 + F0FFF0F0F0FFF0F0F0FF000000FF000000FFFFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00000000FF000000FF000000FF000000FF000000FF000000FFFFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + } + OnClick = sb_upClick + ShowHint = True + ParentShowHint = False + end + object sb_update: TSpeedButton + Left = 1 + Height = 22 + Hint = 'Update Embedded Form Designer' + Top = 32 + Width = 23 + Anchors = [akTop, akRight] + Glyph.Data = { + 36040000424D3604000000000000360000002800000010000000100000000100 + 2000000000000004000064000000640000000000000000000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00000000020000000B0000001C0000002B0000 + 003100000029000000180000000900000002FFFFFF00FFFFFF00CE7D7500CE7D + 7500CE7D7500CE7D7500CE7D75000000000562241F4C8A362DAC8D3730BA6E2B + 26A01306055C0000003A020202250000000D00000002CE7D7500CE7D7500CE7D + 7500CE7D7500000000012A100E04A4403667A64138CCAB4138E8AF463AFFAF44 + 3AFFA33E36DB6528228300000043000000270000000C00000001CE7D7500CE7D + 7500000000010000000A0803031585342D334019160555221D04A841384CB144 + 3CE6B5473DFFB3453DFF792E2899000000410000001D00000005CE7D7500CE7D + 75000000000684322C5E000000340000002500000009CE7D7500CE7D7500A53F + 371CB6473FE8B7483FFFB6483EFF441B176C000000300000000ECE7D75000000 + 000280312A3DB5473DFF712C278D0000003E0000001B00000004CE7D75000000 + 0001A641394BBD493FFFBB493FFF9B3C33C20000004200000023000000010000 + 000DAC423BD7B7493FFFB0453BF21E0C0A5B000000320000001000000001993C + 330D4119161DB4483DDBBE4B41FFB2463DED1C0B095A3815134B00000003A23E + 377DB7483FFFB8493FFFB84A3FFF9E3D35C6000000370000001600000003B043 + 3C30BC483FF6BD4940F8BE4E43FFBF4A41FEB8483EF7973C3398AA433941B648 + 3FE7BB493FFFBA4940FFBB483EFAB9483FFB83332C690000000E00000002CE7D + 7500BD49408EC04F44FFBF4E44FFBF4E44FFA74239BD0000001BAF463A16A740 + 3716B5483EC7BC4940FFB6473DF02F13105D3A17143B0000000D00000001CE7D + 75009F3D3504BE4E43DCC15147FFBB4D42F5411916370000000ACE7D7500CE7D + 7500B4493E7CBE4B41FFBF4A41FF7D312B9400000042000000220000000A0000 + 0001CE7D7500B8493F3DC15248FFA64138700000000E00000002CE7D7500CE7D + 7500B5473D14BD4A40F0C04F44FFBE5046F54C1D19690000003F000000270000 + 0017000000110000000DB4473D5F0000000500000002CE7D7500CE7D7500CE7D + 7500CE7D7500B9483E4AC3554CFDC55E56FFC0564DF178322C7C000000410000 + 00364F201C3F3A1815210000000800000001CE7D7500CE7D7500CE7D7500CE7D + 7500CE7D7500CE7D7500BB4B403DC0534AC8C2554BFFC2544BFFBC5249E6B74E + 44D1AE483E9A602A251A00000003CE7D7500CE7D7500CE7D7500CE7D7500CE7D + 7500CE7D7500CE7D7500CE7D75005E242002BD49406ABC4D43ADBB4F46B0AE47 + 3E5F0000000700000002CE7D7500CE7D7500CE7D7500CE7D7500FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + } + OnClick = sb_upClick + ShowHint = True + ParentShowHint = False + end + end + object pnInfoPanel: TPanel + Left = 353 + Height = 74 + Top = 56 + Width = 83 + Anchors = [akTop, akRight] + BevelInner = bvLowered + ClientHeight = 74 + ClientWidth = 83 + Color = 15400943 + ParentColor = False + TabOrder = 3 + Visible = False + object LabelX: TLabel + Left = 8 + Height = 15 + Top = 8 + Width = 10 + Caption = 'X:' + ParentColor = False + end + object LabelY: TLabel + Left = 8 + Height = 15 + Top = 24 + Width = 10 + Caption = 'Y:' + ParentColor = False + end + object LabelW: TLabel + Left = 8 + Height = 15 + Top = 40 + Width = 14 + Caption = 'W:' + ParentColor = False + end + object LabelH: TLabel + Left = 8 + Height = 15 + Top = 56 + Width = 12 + Caption = 'H:' + ParentColor = False + end + end + end + object pnShowHide: TPanel + Left = 420 + Height = 24 + Top = 136 + Width = 24 + Anchors = [akRight, akBottom] + BevelOuter = bvNone + ClientHeight = 24 + ClientWidth = 24 + DoubleBuffered = False + ParentDoubleBuffered = False + TabOrder = 1 + object sb_hide: TSpeedButton + Left = 0 + Height = 22 + Hint = 'Hide/Show Sreen Preview and Buttons Panels' + Top = 0 + Width = 23 + Flat = True + Glyph.Data = { + 36040000424D3604000000000000360000002800000010000000100000000100 + 2000000000000004000064000000640000000000000000000000FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF007295C5076686B3575F7FACA85F80B0E95F81B6F55C81B9F6597D + B7F45175AEC2496DA572476BA629FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00BAC1CBB194A9C5FB85AADDFF8DB4E9FF9BBBE9FFA5C0E7FFA5BFE6FFA1BD + E7FF90B1E3FF6C9AE3FF6086C3FE8296B6CA4971AF04FFFFFF00FFFFFF00C7CF + D9C69CBCE3FF9DC0ECFFBED1EBEED3DCEBE6E4E7EBE0EBEBEBDEEBEBEBDEEBEB + EBDEEAEAEADEC9D5E9E691B3E7FF6696E1FF728EBAE64A72B001D5DBE199ADC8 + E8FFC0D3EAFFE0E6EDFFEFEFEFFFE9DAD1FFE1B9A1FFDA9C77FFD99871FFDFB0 + 95FFE8D4C9FFF0F0F0FFE6E9EEFFB5C9E9FF6696E2FF819BC6C6C2D2E3EED7E0 + E9FFF0F0F0FFF4F4F4FFF2E4DCFFE7B79AFFE2A17BFFE19D73FFDF986CFFDE93 + 64FFE2A27CFFEFDBCFFFF4F4F4FFF0F0F0FFCBD5E7FF79A1DFF9DDE0E4FCEEEE + EEFFF4F4F4FFF9F9F9FFF0D1BEFFE9B18EFFE7AB86FFE5A67EFFE4A077FFE39B + 70FFE19668FFEBBB9EFFF9F9F9FFF4F4F4FFEEEEEEFF94B1DDFEB1CADFFEDCE2 + E8FFF7F7F7FFFBFBFBFFF0C4ABFFECB898FFECB491FF1B130FFF19120EFFE7A4 + 7AFFE59D73FFE7A47DFFFBFBFBFFF7F7F7FFD2DCECFF688FCCFFD3DCE4E8ADCB + E5FFBDCAD6FFFBFBFBFFF1C9B2FFEFBFA2FFEEBA9BFF1D1510FF1B140FFFEAAA + 84FFE8A57CFFE9AA84FFFBFBFBFFC4D2E7FF7BA6E5FF779AD1FBE0E0E08EC5D6 + E6FFB7D1ECFF97ABBFFFD6CAC5FFEFC4A9FFEFC0A4FFEEBB9DFFEDB695FFEBB1 + 8EFFE9AB85FFEFC7B1FFA4BAD9FF83ACE4FF86B1F0FFC7D3E3A0FFFFFF00E3E3 + E3B9C0D3E6FFBBD3ECFFA1B9D0FF8FA0B3FF9BA1ABFFB3A8A6FFB4A5A1FFB2A1 + 9BFF9B9DA6FF819DC0FF94BAECFF91B8EEFFBFD2ECD2FFFFFF00FFFFFF00FFFF + FF00E3E3E3A1CDDAE6F9BAD3E8FFBED5EEFFB6CFE9FFA5BED9FF9FB8D5FF9FBB + DCFFAAC8F1FFA3C3EEFFA2C1EAFED3DCE9B2FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00E1E1E13CD8DFE4B5C6D6E5F6BCD0E5FFB8CEE6FFB4CBE6FFB1C9 + E6FFB4CAE7F8C7D5E7C4E5E5E53CFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00 + } + OnClick = sb_hideClick + ShowHint = True + ParentShowHint = False + end + end +end diff --git a/ide/embedded_designer_formeditor.pas b/ide/embedded_designer_formeditor.pas new file mode 100644 index 0000000000..74c9c647ee --- /dev/null +++ b/ide/embedded_designer_formeditor.pas @@ -0,0 +1,1516 @@ +{********************************************************************** + Copyright (c) PilotLogic Software House + All rights reserved + + This file is part of CodeTyphon Studio (https://www.pilotlogic.com/) + + *************************************************************************** + * * + * This source is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This code is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * General Public License for more details. * + * * + * A copy of the GNU General Public License is available on the World * + * Wide Web at . You can also * + * obtain it by writing to the Free Software Foundation, * + * Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1335, USA. * + * * + ***************************************************************************} + +unit embedded_designer_formeditor; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, FileUtil, Forms, Controls, ExtCtrls, Buttons, + Math, EnvironmentOpts, + Embedded_Designer_Basics, IDEWindowIntf, Toolwin, + Graphics, Dialogs, + ComCtrls, LMessages, + LCLIntf, + LCLType, + LCLClasses, + LazLoggerBase, + intfgraphics, StdCtrls, Menus, ComponentEditors, + dateutils, types, typinfo; + +type + +TEmbedHandlerOption=(ehoSendBefore,ehoSendAfter,ehoSendToForm); +TEmbedHandlerOptions=Set of TEmbedHandlerOption; + +TEmbedTabSheet = class; +TEmbedFormEditor = class; + +TEmbedMessageHandler = class(TPersistent) + protected + FHookControl: TControl; + InheritedWndMethod: TWndMethod; + public + FOptions:TEmbedHandlerOptions; + OnBeforeMessage, + OnAfterMessage : TEmbedMessageHandlerEvent; + constructor Create; + destructor Destroy; override; + procedure HookControl(AControl: TControl); + procedure UnHookControl; + function HasHookControl: Boolean; + procedure SelfWndMethod(var TheMessage: TLMessage); + Procedure SetDefaulOptions; + Property TheHookControl: TControl read FHookControl; + end; + +TTEmbedFakeMainMenu = class(TToolBar) + protected + FMainMenu:TMainMenu; + public + constructor Create(TheOwner: TComponent); override; + destructor Destroy; override; + Procedure MainMenuAssign(aMainMenu:TMainMenu); + Procedure MainMenuClear; + Procedure MainMenuUpdate; +end; + +TEmbedDesignPanel = class(TPanel) + protected + FHasLoadedForm: Boolean; + FLoadedForm: TCustomForm; + FFakeWindow: TPanel; + FFakeWindow_MouseDown: Boolean; + FFakeWindow_MousePos: TPoint; + FFakeWindowCaption: TPanel; + FMessagesHandler:TEmbedMessageHandler; + FFakeMainMenu:TTEmbedFakeMainMenu; + FMouseArea:integer; + FExecuteBeforeMessage: Boolean; + FIniOK:boolean; + FFormEditor: TFrame; + OnFormLoad: TNotifyEvent; + OnLoadedFormChangeBounds: TNotifyEvent; + + FZeroOriginPoint:Tpoint; + FDeltaPointMousePos: TPoint; + + dsParentPage:TEmbedTabSheet; + dsParentFormEditor: TEmbedFormEditor; + + procedure InitializeWnd; override; + procedure HideWindowDesign(aForm: TCustomForm); + function FormIsValid(aForm: TCustomForm): Boolean; + function LoadedFormIsValid: Boolean; + function FormZeroOrigin(aForm: TCustomForm): TPoint; + Function CheckForFakeMainMenu(aForm: TCustomForm):Boolean; + Procedure UpdateFakeMainMenu; + procedure AddForm(aForm: TCustomForm); + public + constructor Create(TheOwner: TComponent; AFormEditor: TFrame); reintroduce; + destructor Destroy; override; + procedure EmbeddedForm(Sender: TObject; aForm: TCustomForm); + procedure Form_BeforeMessage(Sender: TObject; SenderForm: TControl; Msg: TLMessage); + procedure Form_AfterMessage(Sender: TObject; SenderForm: TControl; Msg: TLMessage); + procedure FFakeWindowMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); + procedure FFakeWindowMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); + procedure FFakeWindowMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); + procedure FFakeWindowResize(Sender: TObject); + procedure FFakeWindowCaptionPaint(Sender: TObject); + Function FindMouseArea(const X,Y:integer):integer; + procedure UnLoadLoadedForm; + + property IniOK:boolean read FIniOK write FIniOK; + property LoadedForm: TCustomForm read FLoadedForm; + end; + + { TEmbedFormEditor } + + TEmbedFormEditor = class(TFrame) + imgWindowScreenPreview: TImage; + LabelX: TLabel; + LabelY: TLabel; + LabelW: TLabel; + LabelH: TLabel; + pnShowHide: TPanel; + RootPanel: TPanel; + pnInfoPanel: TPanel; + pnScreenPreviewBtns: TPanel; + pnCaptionWindowScreenPreview: TPanel; + pnScreenPreview: TPanel; + pnWindowScreenPreview: TPanel; + pnDesignBox: TScrollBox; + sb_hide: TSpeedButton; + sb_zero: TSpeedButton; + sb_up: TSpeedButton; + sb_bottom: TSpeedButton; + sb_left: TSpeedButton; + sb_right: TSpeedButton; + sb_update: TSpeedButton; + procedure imgWindowScreenPreviewMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); + procedure imgWindowScreenPreviewMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); + procedure imgWindowScreenPreviewMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); + procedure sb_upClick(Sender: TObject); + procedure sb_hideClick(Sender: TObject); + private + FPreviewMoving: boolean; + FPreviewMovingPoint: TPoint; + FDesignAreaViewMoving: boolean; + FDesignAreaViewMovingPoint: TPoint; + public + FDesignPanel: TEmbedDesignPanel; + function PixelPerc(vl, perc: single): integer; + procedure DesignPanel_OnLoadForm(Sender: TObject); + procedure DesignPanel_OnLoadedFormChangeBounds(Sender: TObject); + procedure SetupPreviewFormDesign(_Form: TCustomForm); + Procedure ActivatedDesigner; + end; + + TEmbedTabSheet = class(TTabSheet) + private + FOnToggleFormOrSource:TNotifyEvent; + Function GetLoadedForm:TCustomForm; + public + FEditPages : TPageControl; + FEditPageForSource : TTabSheet; + FEditPageForDesigner : TTabSheet; + + FFormEditor: TEmbedFormEditor; + FSynEditor : TCustomControl; + constructor Create(TheOwner: TComponent); override; + destructor Destroy; override; + + procedure DoOnTabControlChange(Sender: TObject); + + procedure ShowSourceTab; + procedure ShowFormEditorTab; + + procedure EditPages_Create; + procedure EditPages_Free; + + procedure FormEditorsInit; + Procedure FormEditorDelete; + Procedure FormEditorPause; + + Procedure FormEditorAdd; + Procedure EmbeddedForm(Sender: TObject; aForm: TCustomForm); + + Procedure UpdateEmbedFormDsgSettings; + + property LoadedForm: TCustomForm read GetLoadedForm; + + property OnToggleFormOrSource:TNotifyEvent read FOnToggleFormOrSource write FOnToggleFormOrSource; + end; + +implementation + +{$R *.lfm} + +var + EMBEDDED_FORM_DESIGNER: PLazLoggerLogGroup; + +// ============================================================================== +// =========================== TEmbedFormEditor =================================== +// ============================================================================== + +Procedure TEmbedFormEditor.ActivatedDesigner; +begin + if Embedded_Updating then exit; + + if FDesignPanel=nil then Exit; + if FDesignPanel.LoadedFormIsValid=false then Exit; + if FDesignPanel.FLoadedForm=nil then exit; + +//------------------------------------------ +//Fix FDesignPanel Geometry + if FDesignPanel.FIniOK=false then + begin + FDesignPanel.Visible:=true; + self.Visible:=true; + + FDesignPanel.FLoadedForm.SetBounds(FDesignPanel.FLoadedForm.Left, + FDesignPanel.FLoadedForm.Top, + FDesignPanel.FLoadedForm.Width+1, + FDesignPanel.FLoadedForm.Height); + FDesignPanel.FLoadedForm.SetBounds(FDesignPanel.FLoadedForm.Left, + FDesignPanel.FLoadedForm.Top, + FDesignPanel.FLoadedForm.Width-1, + FDesignPanel.FLoadedForm.Height); + + FDesignPanel.FIniOK:=true; + + LCLIntf.ShowWindow(FDesignPanel.FLoadedForm.Handle,SW_SHOWNORMAL); + end; + +//-------------------------------------- +// Activate Embedded Form Designer +// Call main.pp procedure TMainIDE.OnDesignerActivated(Sender: TObject); + + if FDesignPanel.FLoadedForm.Designer<>nil then + TComponentEditorDesigner(FDesignPanel.FLoadedForm.Designer).IsActive:=true; + +end; + +procedure TEmbedFormEditor.SetupPreviewFormDesign(_Form: TCustomForm); +begin + + Self.DoubleBuffered := True; + if (FPreviewMoving) then Exit; + + with pnWindowScreenPreview do + begin + Width := PixelPerc(_Form.Width , CN_PREVIEW_FACTOR); + Height := PixelPerc(_Form.Height, CN_PREVIEW_FACTOR); + Top := PixelPerc(_Form.Top , CN_PREVIEW_FACTOR); + Left := PixelPerc(_Form.Left , CN_PREVIEW_FACTOR); + end; + + with pnCaptionWindowScreenPreview do + begin + Height := PixelPerc(Parent.Height, 15); + end; + +end; + +procedure TEmbedFormEditor.DesignPanel_OnLoadForm(Sender: TObject); +begin + //----------------------- +end; + +procedure TEmbedFormEditor.DesignPanel_OnLoadedFormChangeBounds(Sender: TObject); +begin + if FDesignPanel.LoadedFormIsValid then + begin + SetupPreviewFormDesign(FDesignPanel.FLoadedForm); + end; + +end; + +function TEmbedFormEditor.PixelPerc(vl, perc: single): integer; +begin + Result := Round((vl / 100) * perc); +end; + + +//------------------------ imgWindowScreenPreview Mouse Events ---------------------- +procedure TEmbedFormEditor.imgWindowScreenPreviewMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); +begin + if FDesignPanel=nil then Exit; + if FDesignPanel.LoadedFormIsValid=false then Exit; + + SetCapture(pnWindowScreenPreview.Handle); + FPreviewMoving := True; + FPreviewMovingPoint.X := x; + FPreviewMovingPoint.Y := Y; + + pnInfoPanel.Visible:=True; +end; + +procedure TEmbedFormEditor.imgWindowScreenPreviewMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); + Var R:TRect; +begin + if FPreviewMoving=false then exit; + + pnWindowScreenPreview.SetBounds(pnWindowScreenPreview.Left - (FPreviewMovingPoint.x - X), + pnWindowScreenPreview.Top - (FPreviewMovingPoint.Y - Y), + pnWindowScreenPreview.Width, + pnWindowScreenPreview.Height ); + + //............................................................ + R:=Rect(round(((max(pnWindowScreenPreview.Left - (FPreviewMovingPoint.X - X), 0)) / pnWindowScreenPreview.Parent.Width) * Screen.Width ), + round(((max(pnWindowScreenPreview.Top - (FPreviewMovingPoint.Y - Y), 0)) / pnWindowScreenPreview.Parent.Height) * Screen.Height), + FDesignPanel.FLoadedForm.Width, + FDesignPanel.FLoadedForm.Height ); + + LabelX.Caption:='X: '+IntToStr(R.Left); + LabelY.Caption:='Y: '+IntToStr(R.Top); + LabelW.Caption:='W: '+IntToStr(R.Right); + LabelH.Caption:='H: '+IntToStr(R.Bottom); +end; + +procedure TEmbedFormEditor.imgWindowScreenPreviewMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); +begin + if FPreviewMoving then + begin + ReleaseCapture; + FPreviewMoving := False; + pnInfoPanel.Visible:=False; + + with pnWindowScreenPreview do + begin + Left := max(Left - (FPreviewMovingPoint.X - X), 0); + Top := max(Top - (FPreviewMovingPoint.Y - Y), 0); + + if FDesignPanel.LoadedForm<>nil then + begin + FDesignPanel.FLoadedForm.SetBounds(round((Left / Parent.Width) * Screen.Width ), + round((Top / Parent.Height) * Screen.Height), + FDesignPanel.FLoadedForm.Width, + FDesignPanel.FLoadedForm.Height ); + + end; + end; + end; +end; + +//------------------------ Mouse Events ---------------------- + +procedure TEmbedFormEditor.sb_upClick(Sender: TObject); +begin + if FDesignPanel=nil then Exit; + if FDesignPanel.LoadedFormIsValid=false then Exit; + + imgWindowScreenPreviewMouseDown(nil,mbLeft, [ssLeft], 0, 0); + + if Sender = sb_up then pnWindowScreenPreview.Top := pnWindowScreenPreview.Top - 5; + if Sender = sb_bottom then pnWindowScreenPreview.Top := pnWindowScreenPreview.Top + 5; + if Sender = sb_left then pnWindowScreenPreview.Left := pnWindowScreenPreview.Left - 5; + if Sender = sb_right then pnWindowScreenPreview.Left := pnWindowScreenPreview.Left + 5; + if Sender = sb_zero then + begin + pnWindowScreenPreview.Top := CN_BORDER_PX; + pnWindowScreenPreview.Left := CN_BORDER_PX; + end; + + if Sender = sb_update then // Update button 5555 + begin + ActivatedDesigner; + DesignPanel_OnLoadForm(nil); + DesignPanel_OnLoadedFormChangeBounds(nil); + FDesignPanel.Paint; + FDesignPanel.FFakeWindowCaption.Repaint; + end; + + imgWindowScreenPreviewMouseUp( nil,mbLeft, [ssLeft], 0, 0); +end; + +procedure TEmbedFormEditor.sb_hideClick(Sender: TObject); +begin + if pnScreenPreview.Visible then + begin + pnScreenPreview.Visible:=False; + pnScreenPreviewBtns.Visible:=False; + end else + begin + pnScreenPreview.Visible:=True; + pnScreenPreviewBtns.Visible:=True; + end; +end; + +//=========================================================================== +//======================= TEmbedDesignPanel ==================================== +//=========================================================================== + +constructor TEmbedDesignPanel.Create(TheOwner: TComponent; AFormEditor: TFrame); +begin + inherited Create(TheOwner); + FLoadedForm:=nil; + FFakeMainMenu:=nil; + dsParentPage:=nil; + dsParentFormEditor:=nil; + FFormEditor := AFormEditor; + + SetInitialBounds(0,0,screen.Width,Screen.Height); + + BevelInner := bvNone; + BevelOuter := bvNone; + + FHasLoadedForm := False; + FIniOK:=false; + + FFakeWindow_MouseDown := false; + + FExecuteBeforeMessage := True; + + FMessagesHandler:=TEmbedMessageHandler.Create; + + FFakeWindow := TPanel.Create(Self); + with FFakeWindow do + begin + BorderWidth := CN_BORDER_PX; + OnResize := @FFakeWindowResize; + + OnMouseDown := @FFakeWindowMouseDown; + OnMouseMove := @FFakeWindowMouseMove; + OnMouseUp := @FFakeWindowMouseUp; + end; + + FFakeWindowCaption := TPanel.Create(FFakeWindow); + with FFakeWindowCaption do + begin + Parent := FFakeWindow; + Align := alTop; + Height := CN_CAPTION_HEIGHT; + BevelInner := bvNone; + BevelOuter := bvNone; + ParentColor := False; + Color := clActiveCaption; + OnPaint := @FFakeWindowCaptionPaint; + end; +end; + +destructor TEmbedDesignPanel.Destroy; +begin + if FormIsValid(FLoadedForm) then + UnLoadLoadedForm; + FMessagesHandler.Free; + inherited Destroy; +end; + +procedure TEmbedDesignPanel.EmbeddedForm(Sender: TObject; aForm: TCustomForm); +begin + if EnvironmentOptions.UseEmbeddedDesigner = False then + Exit; + if Embed_IsDesignForm(aForm) then + AddForm(aForm); +end; + +procedure TEmbedDesignPanel.AddForm(AForm: TCustomForm); +begin + if AForm=nil then + Exit; + if FormIsValid(FLoadedForm) then + Exit; + if (aForm.ParentWindow = Self.Handle) or (aForm.Parent = Self) then + Exit; + FLoadedForm := AForm; + HideWindowDesign(FLoadedForm); + if dsParentPage <> nil then + dsParentPage.FormEditorAdd; + FMessagesHandler.UnHookControl; + FMessagesHandler.HookControl(FLoadedForm); + FMessagesHandler.OnBeforeMessage := @Self.Form_BeforeMessage; + FMessagesHandler.OnAfterMessage := @Self.Form_AfterMessage; + FHasLoadedForm := True; +end; + +procedure TEmbedDesignPanel.UnLoadLoadedForm; +begin + if LoadedFormIsValid=False then Exit; + try + if FFakeWindow<>nil then FFakeWindow.Visible := false; + if FMessagesHandler.HasHookControl then FMessagesHandler.UnHookControl; + FLoadedForm:=nil; + finally + FHasLoadedForm := False; + end; +end; + +function TEmbedDesignPanel.FormIsValid(aForm: TCustomForm): Boolean; +begin + Result := (Assigned(aForm)) and (aForm <> Nil); +end; + +function TEmbedDesignPanel.LoadedFormIsValid: Boolean; +begin + Result := FormIsValid(FLoadedForm); +end; + +procedure TEmbedDesignPanel.HideWindowDesign(aForm: TCustomForm); +begin + if (aForm = Nil) or (not Assigned(aForm)) then Exit; + + ShowWindow(aForm.Handle, SW_HIDE); +end; + +function TEmbedDesignPanel.FormZeroOrigin(aForm: TCustomForm): TPoint; + +//------------------------------------------ + procedure _FindFormBorder; + var + w: TWinControl; + rc1, rc2: TRect; + begin + if CN_REMOVE_FORM_BORDER=False then exit; + + try + w := TWinControl.Create(Self); + w.Left := 0; + w.Top := 0; + w.Parent := aForm; + + GetWindowRect(w.Handle, rc1); + GetWindowRect(aForm.Handle, rc2); + + Result.x := Max(rc1.Left - rc2.Left, 0); + Result.y := Max(rc1.Top - rc2.Top, 0); + finally + w.free; + end; + end; + +//------------------------------------------ + procedure _FindCompSizes; + var i: Integer; + begin + if CN_MUST_FIND_MAINMENU_HEIGHT=False then Exit; + + for i := 0 to aForm.ComponentCount - 1 do + begin + if aForm.Components[i] is TMainMenu then + if TMainMenu(aForm.Components[i]).Items.Count>0 then // 8888 Don't add Height of TmainMenu with No Items + begin + Result.y := Result.y - LCLIntf.GetSystemMetrics(SM_CYMENU); + Exit; + end; + end; + end; + +//----------------------------------------- +begin +Result := Point(0,0); + +if FormIsValid(aForm)=false then exit; + +if FFakeWindow_MouseDown then +begin + result:=FZeroOriginPoint; + EXIT; +end; + +_FindFormBorder; +_FindCompSizes; + +FZeroOriginPoint:=Result; +end; + +Function TEmbedDesignPanel.CheckForFakeMainMenu(aForm: TCustomForm):Boolean; + var i: Integer; + xMainMenu:TMainMenu; +begin + +Result:=False; + +if FormIsValid(aForm)=False then Exit; +if Embed_IsDesignForm(aform)=false then Exit; +if CN_USE_FAKE_MAINMENU=False then Exit; +if FFakeWindow_MouseDown then EXIT; + +xMainMenu:=nil; + +//..... Find Form MainMenu ... +for i := 0 to aForm.ComponentCount - 1 do + begin + if aForm.Components[i] is TMainMenu then + if TMainMenu(aForm.Components[i]).Items.Count>0 then + begin + xMainMenu:=TMainMenu(aForm.Components[i]); + end; + end; + +Result:=(xMainMenu<>nil); + +//............................ +if xMainMenu=nil then +begin + if FFakeMainMenu<>nil then + begin + FFakeMainMenu.Free; + FFakeWindowCaption.Height:=CN_CAPTION_HEIGHT; + end; + FFakeMainMenu:=nil; +end else +begin + if FFakeWindow=nil then Exit; + + if FFakeMainMenu=nil then + begin + FFakeMainMenu:=TTEmbedFakeMainMenu.Create(FFakeWindowCaption); + FFakeMainMenu.Parent:=FFakeWindowCaption; + FFakeMainMenu.MainMenuAssign(xMainMenu); + FFakeWindowCaption.Height:=CN_CAPTION_HEIGHT+FFakeMainMenu.Height; + end; +end; +end; + +Procedure TEmbedDesignPanel.UpdateFakeMainMenu; +begin +if CN_USE_FAKE_MAINMENU=False then Exit; +if FFakeMainMenu=nil then Exit; + +FFakeMainMenu.MainMenuUpdate; +end; + +//=============================== Before LoadedForm Message ===================== +procedure TEmbedDesignPanel.Form_BeforeMessage(Sender: TObject; SenderForm: TControl; Msg: TLMessage); +var + pRect: TRect; +//.................................................................. + procedure _AdjustSelfPosition(aForm: TCustomForm); + begin + + if aForm.ParentWindow <> Self.Handle then + begin + Self.SetBounds(0,0,Self.Width,Self.Height); + end; + + GetWindowRect(Self.Handle, pRect); + + Self.SetBounds(-(pRect.Left - Self.Left), + -(pRect.Top - Self.Top), + Self.Width, + Self.Height ); + end; +//.................................................................. +begin +if NOT FExecuteBeforeMessage then Exit; +if NOT (Sender=FMessagesHandler) then Exit; +if LoadedFormIsValid=false then Exit; +if TCustomForm(SenderForm)<>FLoadedForm then Exit; + +//debugln('TEmbedDesignPanel.Form_BeforeMessage : '+GetMessageName(Msg.msg)); //--- ct7777 ----- + +//-------------------------------------------------------- + + if NOT (csDestroying in FLoadedForm.ComponentState) then + if ((CN_FORM_DESIGNER_PARENT_TYPE=ctptParentWindow) and (FLoadedForm.ParentWindow <> Self.Handle)) or + ((CN_FORM_DESIGNER_PARENT_TYPE=ctptParent) and (FLoadedForm.Parent <> Self)) or + ( CN_FORM_DESIGNER_PARENT_TYPE=ctptDock) or + ( CN_FORM_DESIGNER_PARENT_TYPE=ctptNone) then + begin + try + FExecuteBeforeMessage := False; + FLoadedForm.BeginUpdateBounds; + pRect.Left := FLoadedForm.Left; + pRect.Top := FLoadedForm.Top; + pRect.Right := FLoadedForm.Left + FLoadedForm.Width; + pRect.Bottom := FLoadedForm.Top + FLoadedForm.Height; + + case CN_FORM_DESIGNER_PARENT_TYPE of + ctptParentWindow : FLoadedForm.ParentWindow := Self.Handle; + ctptParent : FLoadedForm.Parent := Self; + ctptDock : FLoadedForm.Dock(Self, pRect); + ctptNone : ; + end; + + finally + FLoadedForm.EndUpdateBounds; + FExecuteBeforeMessage := True; + end; + + if Assigned(OnFormLoad) then OnFormLoad(Self); + if Assigned(OnLoadedFormChangeBounds) then OnLoadedFormChangeBounds(Self); + end; + + //-------------------------------------------------------- +end; + +//=============================== After LoadedForm Message ===================== +procedure TEmbedDesignPanel.Form_AfterMessage(Sender: TObject; SenderForm: TControl; Msg: TLMessage); +var pRect: TRect; + +//.................................................................. + procedure _UpdateFakeWindow(aForm: TCustomForm); + var zoPoint:TPoint; + begin + FFakeWindow.Visible := ((aForm <> Nil) and (Assigned(aForm))); + + if FFakeWindow.Visible then + begin + zoPoint:=FormZeroOrigin(aForm); + FFakeWindow.SetBounds( + ((aForm.Left) - (FFakeWindowCaption.Left)) + zoPoint.x, + ((aForm.Top ) - (FFakeWindowCaption.Top + FFakeWindowCaption.Height)) + zoPoint.y, + aForm.Width + (FFakeWindowCaption.Left * 2), + aForm.Height + (FFakeWindowCaption.Top + FFakeWindowCaption.Height) + FFakeWindowCaption.Top + ); + end; + + if FFakeWindow_MouseDown then exit; + FFakeWindowResize(FFakeWindow); + end; +//.................................................................. + procedure _UpdateLoadedFormBorder(aForm: TCustomForm); + var + xRegion: TRegion; + begin + if CN_REMOVE_FORM_BORDER=false then Exit; + + with aForm, FormZeroOrigin(aForm) do + begin + xRegion := TRegion.Create; + try + xRegion.AddRectangle( x, + y, + x + Width, + y + Height ); + + aForm.SetShape(xRegion); + finally + xRegion.Free; + end; + + end; + end; +//.................................................................. + procedure _UpdateFormDesigner(aForm: TCustomForm); + begin + with TCustomForm(aForm) do UpdateControlState; + end; +//.................................................................. + procedure _UpdateSelf; + var R:TRect; + begin + + if FFakeWindow.Visible then + R:=Rect((-FFakeWindow.Left) + 5,(-FFakeWindow.Top) + 5, Screen.Width, Screen.Height) else + R:=Rect((-FLoadedForm.Left) + 5,(-FLoadedForm.Top) + 5, Screen.Width, Screen.Height); + + Self.SetBounds(R.Left, R.Top, R.Right, R.Bottom); + end; +//.................................................................. +begin +if FHasLoadedForm=false then exit; +if NOT (Sender=FMessagesHandler) then Exit; +if LoadedFormIsValid=false then Exit; +if TCustomForm(SenderForm)<>FLoadedForm then Exit; + +if (csDestroying in FLoadedForm.ComponentState) then Exit; +if (csFreeNotification in FLoadedForm.ComponentState) then Exit; +if (csLoading in FLoadedForm.ComponentState) then Exit; +if (csUpdating in FLoadedForm.ComponentState) then Exit; +if (csReading in FLoadedForm.ComponentState) then Exit; +if (csWriting in FLoadedForm.ComponentState) then Exit; + + +//-------------------------------- +case Msg.msg of +LM_SHOWWINDOW: + begin + if TLMShowWindow(Msg).Show then + begin + + if CN_USE_FAKE_MAINMENU then + if CheckForFakeMainMenu(FLoadedForm) then + UpdateFakeMainMenu; + + _UpdateFakeWindow(FLoadedForm); + _UpdateLoadedFormBorder(FLoadedForm); + _UpdateSelf; + end; + end; + +LM_ACTIVATE, +LM_SETFOCUS, +LM_MOVE, +LM_SIZE: + begin + _UpdateFakeWindow(FLoadedForm); + _UpdateLoadedFormBorder(FLoadedForm); + _UpdateSelf; + _UpdateFormDesigner(FLoadedForm); + if Assigned(OnLoadedFormChangeBounds) then OnLoadedFormChangeBounds(Self); + end; + +CM_TEXTCHANGED: //Change Stored Form/Module/Frame Caption/Name + begin + FFakeWindowCaption.Repaint; + end; + +CM_MENUCHANGED: // for Fake MainMemu added + begin + if CN_USE_FAKE_MAINMENU=false then exit; + + if FFakeMainMenu=nil then // Used Only for Init Greate FakeMainMenu + if CheckForFakeMainMenu(FLoadedForm) then + begin + UpdateFakeMainMenu; + _UpdateFakeWindow(FLoadedForm); + _UpdateLoadedFormBorder(FLoadedForm); + _UpdateSelf; + if Assigned(OnLoadedFormChangeBounds) then OnLoadedFormChangeBounds(Self); + end; + + end; + +LM_ERASEBKGND,LM_PAINT: // for Fake MainMemu Deleted + begin + if CN_USE_FAKE_MAINMENU=false then exit; + if FFakeMainMenu=nil then exit; //Used Only for Init Greate FakeMainMenu + + if CheckForFakeMainMenu(FLoadedForm) then // FakeMainMenu Exists so Update Items + begin + UpdateFakeMainMenu; + end else // FakeMainMenu Deleted so Update DesignPanel + begin + _UpdateFakeWindow(FLoadedForm); + _UpdateLoadedFormBorder(FLoadedForm); + _UpdateSelf; + if Assigned(OnLoadedFormChangeBounds) then OnLoadedFormChangeBounds(Self); + end; + end; + +end; +end; + +//Result=0 Mouse is in LoadedForm +//Result=1 Mouse in Bottom-Righr Corner +//Result=2 Mouse in Righr Bar +//Result=3 Mouse in Bottom Bar +Function TEmbedDesignPanel.FindMouseArea(const X,Y:integer):integer; +begin + result:=0; + + if (x < FFakeWindow.Width - 4*CN_BORDER_PX) and + (y >= FFakeWindow.Height - CN_BORDER_PX) + then begin result:=3; exit; end; // Bottom Bar + + if (x >= FFakeWindow.Width - CN_BORDER_PX) and + (y < FFakeWindow.Height - 4*CN_BORDER_PX) + then begin result:=2; exit; end; // Right Bar + + if (x >= FFakeWindow.Width - CN_BORDER_PX) or + (y >= FFakeWindow.Height - CN_BORDER_PX) + then begin result:=1; exit; end; // Bottom-Righr Corner + +end; + +procedure TEmbedDesignPanel.FFakeWindowMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); +begin + if LoadedFormIsValid=false then Exit; + + FFakeWindow_MouseDown := false; + + if + (x >= FFakeWindow.Width - CN_BORDER_PX) or + (y >= FFakeWindow.Height - CN_BORDER_PX) then + begin + FFakeWindow_MouseDown := True; + GetCursorPos(FFakeWindow_MousePos); + + FDeltaPointMousePos:=Point(FFakeWindowCaption.Left-X,FFakeWindowCaption.Top-Y); + + dsParentFormEditor.pnInfoPanel.Visible:=True; + end; + +end; + +procedure TEmbedDesignPanel.FFakeWindowMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); +const + minWidth = 120; + minHeight = 50; +var + newPos: TPoint; + frmPoint : TPoint; + w, h: Integer; +begin + +if Sender= nil then Exit; + +with TWinControl(Sender) do +begin + + if FFakeWindow_MouseDown=false then // NO Resize Mode + begin + FMouseArea:=FindMouseArea(x,y); + case FMouseArea of + 1: Cursor := crSizeNWSE; // Bottom-Right Corner + 2: Cursor := crSizeWE; // Right Bar + 3: Cursor := crSizeNS; // Bottom Bar + else + Cursor := crDefault; + end; + end else // Resize Mode + begin + GetCursorPos(newPos); + frmPoint := ScreenToClient(Mouse.CursorPos); + + if CN_REMOVE_FORM_BORDER then + begin + frmPoint.X:=frmPoint.X-FZeroOriginPoint.X; + frmPoint.Y:=frmPoint.Y-FZeroOriginPoint.Y; + end else + begin + frmPoint.X:=frmPoint.X-CN_BORDER_PX; + frmPoint.Y:=frmPoint.Y-CN_BORDER_PX-FFakeWindowCaption.Height; + end; + + if frmPoint.Xnil then // Resize Only if Loaded Form is Valid + begin + case FMouseArea of + 1: begin + FLoadedForm.SetBounds(FLoadedForm.Left, FLoadedForm.Top, frmPoint.X, frmPoint.Y); + end; + 2: begin + FLoadedForm.SetBounds(FLoadedForm.Left, FLoadedForm.Top, frmPoint.X, FLoadedForm.Height); + end; + 3: begin + FLoadedForm.SetBounds(FLoadedForm.Left, FLoadedForm.Top, FLoadedForm.Width, frmPoint.Y); + end; + end; + end; + end; +end; +end; + +procedure TEmbedDesignPanel.FFakeWindowMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); +begin + if FFakeWindow_MouseDown then + begin + FFakeWindow_MouseDown := False; + dsParentFormEditor.pnInfoPanel.Visible:=False; + end; +end; + +procedure TEmbedDesignPanel.FFakeWindowResize(Sender: TObject); +var + fk_rgn, fm_rgn, Region, Region2 : HRGN; + fk_rc, fm_rc: TRect; + xRegion : TRegion; +begin + + fk_rc.Left := 0; + fk_rc.Top := 0; + fk_rc.Right := FFakeWindow.Width; + fk_rc.Bottom := FFakeWindow.Height; + + with fm_rc do + begin + Left := FFakeWindowCaption.Left; + Top := FFakeWindowCaption.Top + FFakeWindowCaption.Height; + Right := Left + FFakeWindowCaption.Width; + Bottom := FFakeWindow.Height - (FFakeWindowCaption.Top); + end; + + fk_rgn := CreateRectRgn(fk_rc.Left, fk_rc.Top, fk_rc.Right, fk_rc.Bottom); + fm_rgn := CreateRectRgn(fm_rc.Left, fm_rc.Top, fm_rc.Right, fm_rc.Bottom); + + CombineRgn(fk_rgn, fk_rgn, fm_rgn, RGN_DIFF); + + //........................................ + GetRgnBox(fk_rgn,PRect(@fk_rc)); + + xRegion := TRegion.Create; + try + xRegion.AddRectangle( + fk_rc.Left, + fk_rc.Top, + fk_rc.Right, + fk_rc.Bottom); + + FFakeWindow.SetShape(xRegion); + finally + xRegion.Free; + end; + FFormEditor.Update; +end; + +procedure TEmbedDesignPanel.FFakeWindowCaptionPaint(Sender: TObject); +var + R: TRect; +begin + if LoadedFormIsValid=false then Exit; + FFakeWindowCaption.Canvas.Font.Color := clHighlightText; + R := FFakeWindowCaption.ClientRect; + R.Left := R.Left + 5; + DrawText(FFakeWindowCaption.Canvas.Handle, PChar(FLoadedForm.Caption), -1, R, DT_SINGLELINE or DT_VCENTER or DT_END_ELLIPSIS or DT_NOPREFIX); +end; + +procedure TEmbedDesignPanel.InitializeWnd; +var fm: TForm; +begin + inherited InitializeWnd; + + with FFakeWindow do + begin + Parent := Self; + ParentColor := False; + Color := clForm; + end; + +end; + +//=========================================================================== +//======================== TEmbedMessageHandler ============================= +//=========================================================================== + +constructor TEmbedMessageHandler.Create; +begin + inherited Create; + SetDefaulOptions; + FHookControl := nil; + OnBeforeMessage := nil; + OnAfterMessage := nil; +end; + +destructor TEmbedMessageHandler.Destroy; +begin + UnHookControl; + inherited Destroy; +end; + +Procedure TEmbedMessageHandler.SetDefaulOptions; +begin + FOptions:=[ehoSendBefore,ehoSendAfter,ehoSendToForm]; +end; + +procedure TEmbedMessageHandler.HookControl(AControl: TControl); +begin + SetDefaulOptions; + + if AControl=nil then exit; + FHookControl := AControl; + InheritedWndMethod := FHookControl.WindowProc; //Save Control WindowProc + FHookControl.WindowProc := @SelfWndMethod; //Change Control WindowProc +end; + +procedure TEmbedMessageHandler.UnHookControl; +begin + OnBeforeMessage := nil; + OnAfterMessage := nil; + if NOT HasHookControl then Exit; + FHookControl.WindowProc:=InheritedWndMethod; //Restore Control WindowProc + FHookControl:=nil; + InheritedWndMethod:=nil; + + SetDefaulOptions; +end; + +function TEmbedMessageHandler.HasHookControl: Boolean; +begin + Result := (Assigned(FHookControl)) and (FHookControl <> Nil); +end; + +procedure TEmbedMessageHandler.SelfWndMethod(var TheMessage: TLMessage); +begin + if (not HasHookControl) then Exit; + +// debugln('TEmbedMessageHandler.SelfWndMethod : '+GetMessageName(TheMessage.msg)); //--- ct7777 ----- + + case TheMessage.msg of + LM_SHOWWINDOW, + LM_ACTIVATE, + LM_SETFOCUS, + LM_MOVE, + LM_SIZE, + LM_ERASEBKGND, + LM_PAINT, + CM_MENUCHANGED, + CM_TEXTCHANGED + :begin + if (ehoSendBefore in Foptions) and Assigned(OnBeforeMessage) then OnBeforeMessage(Self, FHookControl, TheMessage); + if (ehoSendToForm in Foptions) and Assigned(InheritedWndMethod) then InheritedWndMethod(TheMessage); + if (ehoSendAfter in Foptions) and Assigned(OnAfterMessage) then OnAfterMessage(Self, FHookControl, TheMessage); + end; + else + if (ehoSendToForm in Foptions) and Assigned(InheritedWndMethod) then InheritedWndMethod(TheMessage); + end; + +end; + + +//=========================================================================== +//======================= TTEmbedFakeMainMenu =============================== +//=========================================================================== + +constructor TTEmbedFakeMainMenu.Create(TheOwner: TComponent); +begin + inherited Create(TheOwner); + FMainMenu:=nil; + Color:=clMenuBar; + EdgeBorders:=[ebTop,ebBottom]; + ShowCaptions:=true; + Align:=alBottom; + List:=True; +end; + +destructor TTEmbedFakeMainMenu.Destroy; +begin + MainMenuClear; + inherited Destroy; +end; + +Procedure TTEmbedFakeMainMenu.MainMenuAssign(aMainMenu:TMainMenu); +begin + FMainMenu:=aMainMenu; + if FMainMenu=nil then exit; + + self.Images:=FMainMenu.Images; +end; + +Procedure TTEmbedFakeMainMenu.MainMenuClear; + var i:Integer; +begin + + for i := ButtonCount - 1 downto 0 do + begin + TToolButton(Buttons[i]).MenuItem:=nil; + TToolButton(Buttons[i]).Free; + end; + + ButtonList.Clear; +end; + +Procedure TTEmbedFakeMainMenu.MainMenuUpdate; + var i:Integer; + xMenu :TMenuItem; + xButton :TToolButton; + + Procedure _SetMenuItem(const val:integer); + begin + xMenu:=FMainMenu.Items[i]; + + if xMenu<>nil then + if xMenu.Visible then + begin + xButton:=TToolButton.Create(self); + xButton.Parent:=self; + xButton.Name:=xMenu.Name; + xButton.Caption :=xMenu.Caption; + xButton.MenuItem:=xMenu; + end; + end; + +begin +if FMainMenu=nil then exit; + +MainMenuClear; + +if FMainMenu.IsRightToLeft=false then +begin + for i:=FMainMenu.Items.Count-1 Downto 0 do _SetMenuItem(i); +end else +begin + for i:=0 to FMainMenu.Items.Count-1 do _SetMenuItem(i); +end; + +end; + +//=========================================================================== +//========================== TEmbedTabSheet ================================= +//=========================================================================== + +constructor TEmbedTabSheet.Create(TheOwner: TComponent); +begin + inherited Create(TheOwner); + FEditPages:=nil; + FEditPageForSource:=nil; + FEditPageForDesigner:=nil; + FFormEditor:=nil; + FSynEditor:=nil; +end; + +destructor TEmbedTabSheet.Destroy; +begin + inherited Destroy; +end; + + +procedure TEmbedTabSheet.EditPages_Create; +begin + + if FEditPages<>nil then exit; + + Embedded_Updating:=True; + + //----------------- + FEditPages:= TPageControl.Create(self); + FEditPages.Parent:=self; + FEditPages.Align:=alClient;//alBottom; + FEditPages.TabPosition:=tpBottom; + FEditPages.ShowTabs := EnvironmentOptions.UseEmbeddedDesigner; + + //--- page for Source code SynEdit ---- + FEditPageForSource:=FEditPages.AddTabSheet; + FEditPageForSource.Name:='EditPageForSource1'; + FEditPageForSource.Caption:='Source'; + FEditPageForSource.TabVisible:=true; + + //--- page for FormDesigner ----------- + FEditPageForDesigner:=FEditPages.AddTabSheet; + FEditPageForDesigner.Name:='EditPageForDesigner1'; + FEditPageForDesigner.Caption:='Designer'; + FEditPageForDesigner.TabVisible:=false; + + + FEditPages.OnChange:=@DoOnTabControlChange; + + Embedded_Updating:=False; +end; + +procedure TEmbedTabSheet.EditPages_Free; +begin + if FEditPages=nil then exit; + + Embedded_Updating:=True; + + FormEditorDelete; + FEditPages.Free; + + FEditPages:=nil; + FEditPageForSource:=nil; + FEditPageForDesigner:=nil; + + Embedded_Updating:=False; +end; + +procedure TEmbedTabSheet.DoOnTabControlChange(Sender: TObject); +begin + if Embedded_Updating then exit; + if FEditPages=nil then exit; + + if FEditPages.ActivePage=FEditPageForDesigner then + if FFormEditor<>nil then + FFormEditor.ActivatedDesigner; +end; + +procedure TEmbedTabSheet.ShowSourceTab; +begin + if Embedded_Updating then exit; + + if (FEditPages.ActivePage<>FEditPageForSource) then + FEditPages.ActivePage:=FEditPageForSource; + + if FSynEditor<>nil then FSynEditor.SetFocus; +end; + +procedure TEmbedTabSheet.ShowFormEditorTab; + var xform:TCustomForm; +begin + if Embedded_Updating then exit; + + if FEditPages=nil then exit; + +//------------------------------------- Check FFormEditor + xform:=nil; + + if FFormEditor<>nil then + if FFormEditor.FDesignPanel<>nil then + if FFormEditor.FDesignPanel.FHasLoadedForm=false then + begin + xform:=FFormEditor.FDesignPanel.FLoadedForm; // Get LoadedForm + FormEditorDelete; // Delete OLD FormEditor + + if xform<>nil then + begin + + if (CN_FORM_DESIGNER_PARENT_TYPE=ctptParentWindow) then + xForm.ParentWindow:=0; // Reset LoadedForm ParentWindow + + xForm.Parent:=nil; // Reset LoadedForm Parent + ShowWindow(xform.Handle, SW_HIDE); // Hide LoadedForm + EmbeddedForm(nil,xform); // Embedded LoadedForm + end; + end; + +//-------------------------------------- + + if FEditPageForDesigner.TabVisible then // Only if Tab is visible for "Clone" Forms + if (FEditPages.ActivePage<>FEditPageForDesigner) then + begin + + FEditPages.ActivePage:=FEditPageForDesigner; + if FFormEditor<>nil then FFormEditor.ActivatedDesigner; + + end; +end; + +Procedure TEmbedTabSheet.UpdateEmbedFormDsgSettings; +begin + if NOT Assigned(FFormEditor) then exit; + + Embedded_Updating:=True; + + FFormEditor.RootPanel.ParentColor := false; + FFormEditor.RootPanel.Color := EnvironmentOptions.UseEmbeddedDesignerBackColor; + + FFormEditor.pnDesignBox.ParentColor := false; + FFormEditor.pnDesignBox.Color := EnvironmentOptions.UseEmbeddedDesignerBackColor; + + FFormEditor.pnInfoPanel.Color := EnvironmentOptions.UseEmbeddedInfopanelColor; + + FFormEditor.pnScreenPreview.Color := EnvironmentOptions.UseEmbeddedSreenPreviewBackColor; + FFormEditor.pnScreenPreview.Visible := EnvironmentOptions.UseEmbeddedScreenPreview; + + FFormEditor.pnScreenPreviewBtns.Color := EnvironmentOptions.UseEmbeddedDesignerBackColor; + FFormEditor.pnScreenPreviewBtns.Visible:= EnvironmentOptions.UseEmbeddedScreenPreview; + + Embedded_Updating:=False; +end; + +procedure TEmbedTabSheet.FormEditorsInit; + var R:TRect; +begin + if EnvironmentOptions.UseEmbeddedDesigner = False then + Exit; + Embedded_Updating := True; + if FFormEditor<>nil then FFormEditor.Free; + + FFormEditor:=TEmbedFormEditor.Create(FEditPageForDesigner); + FFormEditor.Parent:=FEditPageForDesigner; + FFormEditor.Visible:=false; + FFormEditor.Align:=alClient; + + //........... Info Panel .......................... + FFormEditor.pnInfoPanel.Visible:=False; + FFormEditor.pnInfoPanel.SetBounds(FFormEditor.Width-FFormEditor.pnInfoPanel.Width-(LCLIntf.GetSystemMetrics(SM_CYVSCROLL)+4), + 4, + FFormEditor.pnInfoPanel.Width,FFormEditor.pnInfoPanel.Height); + + //........... Screen Preview Panel..................... + R:=Rect(FFormEditor.pnScreenPreview.Left, + FFormEditor.pnScreenPreview.top, + FFormEditor.PixelPerc(Screen.Width, CN_PREVIEW_FACTOR), + FFormEditor.PixelPerc(Screen.Height, CN_PREVIEW_FACTOR) + ); + R.Left:=FFormEditor.Width -(R.Right +LCLIntf.GetSystemMetrics(SM_CYVSCROLL)+4); + R.Top :=FFormEditor.Height-(R.Bottom+LCLIntf.GetSystemMetrics(SM_CXHSCROLL)+4); + + FFormEditor.pnScreenPreview.SetBounds(R.Left, R.top, R.Right, R.Bottom); + + //.......... Show Hide Panel .......................... + R:=Rect(FFormEditor.pnShowHide.Left, + FFormEditor.pnShowHide.top, + FFormEditor.pnShowHide.Width, + FFormEditor.pnShowHide.Height + ); + + R.Left:=FFormEditor.pnScreenPreview.Left + (FFormEditor.pnScreenPreview.Width-R.Right); + R.Top :=FFormEditor.pnScreenPreview.Top - FFormEditor.pnShowHide.Height - 4; + + FFormEditor.pnShowHide.SetBounds(R.Left, R.top, R.Right, R.Bottom); + + //.......... Screen Preview Buttons Panel ............. + R:=Rect(FFormEditor.pnScreenPreviewBtns.Left, + FFormEditor.pnScreenPreviewBtns.top, + FFormEditor.pnScreenPreviewBtns.Width, + FFormEditor.pnScreenPreviewBtns.Height + ); + R.Left:=FFormEditor.pnScreenPreview.Left + (FFormEditor.pnScreenPreview.Width-R.Right-FFormEditor.pnShowHide.Width-4); + R.Top :=FFormEditor.pnScreenPreview.Top - FFormEditor.pnScreenPreviewBtns.Height - 4; + + FFormEditor.pnScreenPreviewBtns.SetBounds(R.Left, R.top, R.Right, R.Bottom); + + + //........... Design Panel ....................... + FFormEditor.FDesignPanel := TEmbedDesignPanel.Create(FFormEditor.pnDesignBox, FFormEditor); + FFormEditor.FDesignPanel.Parent := FFormEditor.pnDesignBox; + FFormEditor.FDesignPanel.Visible:=false; + FFormEditor.FDesignPanel.dsParentPage:=self; + FFormEditor.FDesignPanel.dsParentFormEditor:=FFormEditor; + FFormEditor.FDesignPanel.OnFormLoad := @FFormEditor.DesignPanel_OnLoadForm; + FFormEditor.FDesignPanel.OnLoadedFormChangeBounds := @FFormEditor.DesignPanel_OnLoadedFormChangeBounds; + + UpdateEmbedFormDsgSettings; + + FEditPageForDesigner.TabVisible:=true; + + Embedded_Updating := False; +end; + +Procedure TEmbedTabSheet.FormEditorDelete; +begin + if EnvironmentOptions.UseEmbeddedDesigner = False then + Exit; + if FFormEditor <> nil then + FFormEditor.free; + FFormEditor := nil; + if FEditPageForDesigner<> nil then + FEditPageForDesigner.TabVisible:=false; +end; + +Procedure TEmbedTabSheet.FormEditorAdd; +begin + if EnvironmentOptions.UseEmbeddedDesigner = False then + Exit; + if FEditPageForDesigner <> nil then + FEditPageForDesigner.TabVisible := True; +end; + + +Function TEmbedTabSheet.GetLoadedForm:TCustomForm; +begin + Result:=nil; + + if FFormEditor<>nil then + if FFormEditor.FDesignPanel<>nil then + if FFormEditor.FDesignPanel.LoadedForm<>nil then + Result:=FFormEditor.FDesignPanel.LoadedForm; +end; + +Procedure TEmbedTabSheet.EmbeddedForm(Sender: TObject; aForm: TCustomForm); +begin + if FEditPages=nil then exit; + if FFormEditor<>nil then exit; // if has form then exit... + + FormEditorsInit; + + if FFormEditor=nil then exit; + if FFormEditor.FDesignPanel=nil then exit; + + Embedded_Updating := True; + FFormEditor.FDesignPanel.EmbeddedForm(Sender,aForm); + + if FEditPageForDesigner<> nil then FEditPageForDesigner.TabVisible:=true; + + FFormEditor.FDesignPanel.IniOK:=false; + FFormEditor.ActivatedDesigner; + + Embedded_Updating := False; + + if aForm=nil then + DebugLn(EMBEDDED_FORM_DESIGNER,'TEmbedTabSheet.EmbeddedForm : NIL') else + DebugLn(EMBEDDED_FORM_DESIGNER,'TEmbedTabSheet.EmbeddedForm :'+aForm.Name); +end; + + +//================================================================== SOS SOS SOS +// This Is for Problem of "Docking Embedded Form Designer" +// The GlassDocking send LM_DESTROY msg to FLoadedForm +// On Windows give Error 1400 and crash the IDE +// On GTK2 give Error and crash the IDE +// We don't know why, must find this and remove the next code... +//================================================================== + +Procedure TEmbedTabSheet.FormEditorPause; +begin + if EnvironmentOptions.UseEmbeddedDesigner = False then + Exit; + if FEditPages=nil then exit; + if FFormEditor=nil then exit; // if has form then exit... + if FFormEditor.FDesignPanel=nil then exit; + if FFormEditor.FDesignPanel.FHasLoadedForm=false then exit; + + DebugLn(EMBEDDED_FORM_DESIGNER,'TEmbedTabSheet.FormEditorPause START'); + + Embedded_Updating:=True; +{$IF (NOT DEFINED(LCLGTK2))} +// Must on LCLWin32, LCLWin64 +// Must NOT on LCLGTK2 + if (CN_FORM_DESIGNER_PARENT_TYPE=ctptParentWindow) then + FFormEditor.FDesignPanel.FLoadedForm.Parent:=FFormEditor.FDesignPanel; + +{$ENDIF} + + FFormEditor.FDesignPanel.FMessagesHandler.UnHookControl; + FFormEditor.FDesignPanel.FHasLoadedForm := False; + + + if FEditPageForDesigner<> nil then FEditPageForDesigner.TabVisible:=false; + Embedded_Updating:=False; +end; + +//==================================== + +initialization + EMBEDDED_FORM_DESIGNER := DebugLogger.RegisterLogGroup('EMBEDDED_FORM_DESIGNER' {$IFDEF EMBEDDED_FORM_DESIGNER} , True {$ENDIF} ); + +end. + + + + diff --git a/ide/embedded_designer_notebook.pas b/ide/embedded_designer_notebook.pas new file mode 100644 index 0000000000..6154bc197f --- /dev/null +++ b/ide/embedded_designer_notebook.pas @@ -0,0 +1,632 @@ +{********************************************************************** + Copyright (c) PilotLogic Software House + All rights reserved + + This file is part of CodeTyphon Studio (https://www.pilotlogic.com/) + + *************************************************************************** + * * + * This source is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This code is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * General Public License for more details. * + * * + * A copy of the GNU General Public License is available on the World * + * Wide Web at . You can also * + * obtain it by writing to the Free Software Foundation, * + * Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1335, USA. * + * * + ***************************************************************************} + +unit embedded_designer_notebook; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, sysutils, math, LCLIntf, LCLType, LResources, Forms, Controls, + embedded_designer_basics, embedded_designer_formeditor, IDEWindowIntf, + MainIntf, environmentopts, Graphics, Dialogs, ExtCtrls, ComCtrls, LMessages; + +type + + TEmbedNotebookTabDragDropEvent = procedure(Sender, Source: TObject; + OldIndex, NewIndex: Integer; + CopyDrag: Boolean; + var Done: Boolean) of object; + TEmbedNotebookTabDragOverEvent = procedure(Sender, Source: TObject; + OldIndex, NewIndex: Integer; + CopyDrag: Boolean; + var Accept: Boolean) of object; + + +TEmbedNotebook = class(TPageControl) + private + FDraggingTabIndex: Integer; + FOnTabDragDrop: TDragDropEvent; + FOnTabDragOver: TDragOverEvent; + FOnTabDragOverEx: TEmbedNotebookTabDragOverEvent; + FOnTabDragDropEx: TEmbedNotebookTabDragDropEvent; + FOnTabEndDrag: TEndDragEvent; + FOnTabStartDrag: TStartDragEvent; + FTabDragMode: TDragMode; + FTabDragAcceptMode: TDragMode; + + FTabDragged: boolean; + FDragOverIndex: Integer; + FDragToRightSide: Boolean; + FDragOverTabRect, FDragNextToTabRect: TRect; + + FMouseWaitForDrag: Boolean; + FMouseDownIndex: Integer; + FMouseDownX, FMouseDownY, FTriggerDragX, FTriggerDragY: Integer; + + procedure InitDrag; + procedure InvalidateRect(ARect: TRect); + function TabIndexForDrag(x, y: Integer): Integer; + function TabRectEx(AIndex, X, Y: Integer; out IsRightHalf: Boolean): TRect; + protected + procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; + procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; + procedure MouseMove(Shift: TShiftState; X, Y: Integer); override; + procedure CNNotify(var Message: TLMNotify); message CN_NOTIFY; + procedure RemovePage(Index: Integer); override; + procedure InsertPage(APage: TCustomPage; Index: Integer); override; + procedure CaptureChanged; override; + procedure DoStartDrag(var DragObject: TDragObject); override; + procedure DoEndDrag(Target: TObject; X,Y: Integer); override; + procedure DragOver(Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); override; + procedure DragCanceled; override; + procedure PaintWindow(DC: HDC); override; + //-------------------------------------------------- ct9999 + + function GetPageClass: TCustomPageClass; override; + Function GetDisplayState: TDisplayState; + Procedure SetDisplayState(const val:TDisplayState); + public + procedure ActivatedDesigner; + procedure EmbeddedForm(Sender: TObject; aForm: TCustomForm; aPage:TEmbedTabSheet); + procedure CloseAllEmbedFormEditors; + procedure UpdateEmbedFormDsgSettings; + Procedure ToggleFormUnit; + property DisplayState: TDisplayState read GetDisplayState write SetDisplayState; + //------------------------------------------------- + constructor Create(TheOwner: TComponent); override; + procedure DragDrop(Source: TObject; X, Y: Integer); override; + procedure BeginDragTab(ATabIndex: Integer; Immediate: Boolean; Threshold: Integer = -1); + property DraggingTabIndex: Integer read FDraggingTabIndex; + published + property OnTabDragOver: TDragOverEvent read FOnTabDragOver write FOnTabDragOver; + property OnTabDragOverEx: TEmbedNotebookTabDragOverEvent read FOnTabDragOverEx write FOnTabDragOverEx; + property OnTabDragDrop: TDragDropEvent read FOnTabDragDrop write FOnTabDragDrop; + property OnTabDragDropEx: TEmbedNotebookTabDragDropEvent read FOnTabDragDropEx write FOnTabDragDropEx; + property OnTabEndDrag: TEndDragEvent read FOnTabEndDrag write FOnTabEndDrag; + property OnTabStartDrag: TStartDragEvent read FOnTabStartDrag write FOnTabStartDrag; + + property TabDragMode: TDragMode read FTabDragMode write FTabDragMode default dmManual; + property TabDragAcceptMode: TDragMode read FTabDragAcceptMode write FTabDragAcceptMode default dmManual; + end; + +implementation + +//======================= TEmbedNotebook =========================================== + +constructor TEmbedNotebook.Create(TheOwner: TComponent); +begin + inherited Create(TheOwner); + + InitDrag; + FMouseDownIndex := -1; + fTabDragMode := dmManual; +end; + +function TEmbedNotebook.GetPageClass: TCustomPageClass; +begin + Result:=TEmbedTabSheet; +end; + +procedure TEmbedNotebook.InitDrag; +Begin + FMouseWaitForDrag := False; + DragCursor := crDrag; + FDragOverIndex := -1; + FDraggingTabIndex := -1; + FDragOverTabRect := Rect(0, 0, 0, 0); + FDragNextToTabRect := Rect(0, 0, 0, 0); +end; + +procedure TEmbedNotebook.InvalidateRect(ARect: TRect); +begin + LCLIntf.InvalidateRect(Handle, @ARect, false); +end; + +function TEmbedNotebook.TabIndexForDrag(x, y: Integer): Integer; +var + TabPos: TRect; +begin + Result := IndexOfPageAt(X, Y); + if Result < 0 then begin + TabPos := TabRect(PageCount-1); + // Check empty space after last tab + if (TabPos.Right > 1) and (X > TabPos.Left) and + (Y >= TabPos.Top) and (Y <= TabPos.Bottom) + then + Result := PageCount - 1; + end; + +end; + +function TEmbedNotebook.TabRectEx(AIndex, X, Y: Integer; out IsRightHalf: Boolean): TRect; +begin + Result := TabRect(AIndex); + if (TabPosition in [tpLeft, tpRight]) then // Drag-To-Bottom/Lower + IsRightHalf := Y > (Result.Top + Result.Bottom) div 2 + else + IsRightHalf := X > (Result.Left + Result.Right) div 2; +end; + +procedure TEmbedNotebook.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); +Begin + InitDrag; + FTabDragged:=false; + inherited MouseDown(Button, Shift, X, Y); + if (fTabDragMode = dmAutomatic) and (Button = mbLeft) then Begin + // Defer BeginDrag to MouseMove. + // On GTK2 if BeginDrag is called before PageChanging, the GTK notebook no longer works + FMouseWaitForDrag := True; + if FMouseDownIndex < 0 then + FMouseDownIndex := IndexOfPageAt(X, Y); + FMouseDownX := X; + FMouseDownY := Y; + FTriggerDragX := GetSystemMetrics(SM_CXDRAG); + FTriggerDragY := GetSystemMetrics(SM_CYDRAG); + MouseCapture := True; + end; +end; + +procedure TEmbedNotebook.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); +begin + + MouseCapture := False; + InitDrag; + inherited MouseUp(Button, Shift, X, Y); + FMouseDownIndex := -1; +end; + +procedure TEmbedNotebook.MouseMove(Shift: TShiftState; X, Y: Integer); +begin + inherited MouseMove(Shift, X, Y); + if (FMouseWaitForDrag) and (FMouseDownIndex >= 0) and + ( (Abs(fMouseDownX - X) >= FTriggerDragX) or (Abs(fMouseDownY - Y) >= FTriggerDragY) ) + then begin + + FMouseWaitForDrag := False; + BeginDragTab(FMouseDownIndex, True); + end; +end; + +procedure TEmbedNotebook.CNNotify(var Message: TLMNotify); +Begin + if (Dragging or (FDraggingTabIndex >= 0)) and + ( (Message.NMHdr^.code = TCN_SELCHANGING) or + (Message.NMHdr^.code = TCN_SELCHANGE) ) + then + CancelDrag + else + if Message.NMHdr^.code = TCN_SELCHANGING then Begin + if (fTabDragMode = dmAutomatic) and (not FMouseWaitForDrag) then + FMouseDownIndex := IndexOfPageAt(ScreenToClient(Mouse.CursorPos)); + end; + inherited CNNotify(Message); +end; + +procedure TEmbedNotebook.RemovePage(Index: Integer); +begin + CancelDrag; + FMouseDownIndex := -1; + FMouseWaitForDrag := False; + inherited RemovePage(Index); +end; + +procedure TEmbedNotebook.InsertPage(APage: TCustomPage; Index: Integer); +begin + CancelDrag; + FMouseDownIndex := -1; + FMouseWaitForDrag := False; + inherited InsertPage(APage, Index); +end; + +procedure TEmbedNotebook.CaptureChanged; +begin + FMouseDownIndex := -1; + FMouseWaitForDrag := False; + inherited CaptureChanged; +end; + +procedure TEmbedNotebook.DoStartDrag(var DragObject: TDragObject); +begin + + if FDraggingTabIndex < 0 then + inherited DoStartDrag(DragObject) + else + if Assigned(FOnTabStartDrag) then FOnTabStartDrag(Self, DragObject); +end; + +procedure TEmbedNotebook.DoEndDrag(Target: TObject; X, Y: Integer); +begin + if FDraggingTabIndex < 0 then + inherited DoEndDrag(Target, X, Y) else + if Assigned(FOnTabEndDrag) then FOnTabEndDrag(Self, Target, x, Y); +end; + +procedure TEmbedNotebook.DragOver(Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); +var + TabId: Integer; + LastRect, LastNRect: TRect; + LastIndex: Integer; + LastRight, NeedInvalidate: Boolean; + Ctrl: Boolean; + Src: TEmbedNotebook; +begin + if (not (Source is TEmbedNotebook)) or + (TEmbedNotebook(Source).FDraggingTabIndex < 0) + then begin + // normal DragOver + inherited DragOver(Source, X, Y, State, Accept); + exit; + end; + + // Tab drag over + TabId := TabIndexForDrag(X,Y); + + Accept := (FTabDragAcceptMode = dmAutomatic) and (Source = Self) and + (TabId >= 0) and (TabId <> FDraggingTabIndex); + + if Assigned(FOnTabDragOver) then + FOnTabDragOver(Self,Source,X,Y,State,Accept); + + if ((state = dsDragLeave) or (TabId < 0)) and (FDragOverIndex >= 0) + then begin + InvalidateRect(FDragOverTabRect); + InvalidateRect(FDragNextToTabRect); + FDragOverIndex := -1; + end; + + if (TabId < 0) then exit; + + Ctrl := (GetKeyState(VK_CONTROL) and $8000)<>0; + if Ctrl then + DragCursor := crMultiDrag + else + DragCursor := crDrag; + + LastIndex := FDragOverIndex; + LastRight := FDragToRightSide; + LastRect := FDragOverTabRect; + LastNRect := FDragNextToTabRect; + FDragOverIndex := TabId; + FDragOverTabRect := TabRectEx(TabId, X, Y, FDragToRightSide); + + if (Source = Self) and (TabId = FDraggingTabIndex - 1) then + FDragToRightSide := False; + if (Source = Self) and (TabId = FDraggingTabIndex + 1) then + FDragToRightSide := True; + + NeedInvalidate := (FDragOverIndex <> LastIndex) or (FDragToRightSide <> LastRight); + if NeedInvalidate then begin + InvalidateRect(LastRect); + InvalidateRect(LastNRect); + InvalidateRect(FDragOverTabRect); + InvalidateRect(FDragNextToTabRect); + end; + + if FDragToRightSide then begin + inc(TabId); + if TabId < PageCount then + FDragNextToTabRect := TabRect(TabId); + end else begin + if TabId > 0 then + FDragNextToTabRect := TabRect(TabId - 1); + end; + if NeedInvalidate then + InvalidateRect(FDragNextToTabRect); + + Src := TEmbedNotebook(Source); + if (Source = self) and (TabId > Src.DraggingTabIndex) then + dec(TabId); + + if Assigned(FOnTabDragOverEx) then + FOnTabDragOverEx(Self, Source, Src.DraggingTabIndex, TabId, Ctrl, Accept); + + if (not Accept) or (state = dsDragLeave) then begin + InvalidateRect(FDragOverTabRect); + InvalidateRect(FDragNextToTabRect); + FDragOverIndex := -1; + end; +end; + +procedure TEmbedNotebook.DragCanceled; +begin + inherited DragCanceled; + if (FDragOverIndex >= 0) then begin + InvalidateRect(FDragOverTabRect); + InvalidateRect(FDragNextToTabRect); + end; + FDragOverIndex := -1; + DragCursor := crDrag; +end; + +procedure TEmbedNotebook.PaintWindow(DC: HDC); +var + Points: Array [0..3] of TPoint; + + procedure DrawLeftArrow(ARect: TRect); + var y, h: Integer; + begin + h := Min( (Abs(ARect.Bottom - ARect.Top) - 4) div 2, + (Abs(ARect.Left - ARect.Right) - 4) div 2 ); + y := (ARect.Top + ARect.Bottom) div 2; + Points[0].X := ARect.Left + 2 + h; + Points[0].y := y - h; + Points[1].X := ARect.Left + 2 + h; + Points[1].y := y + h; + Points[2].X := ARect.Left + 2; + Points[2].y := y; + Points[3] := Points[0]; + Polygon(DC, @Points, 4, False); + end; + procedure DrawRightArrow(ARect: TRect); + var y, h: Integer; + begin + h := Min( (Abs(ARect.Bottom - ARect.Top) - 4) div 2, + (Abs(ARect.Left - ARect.Right) - 4) div 2 ); + y := (ARect.Top + ARect.Bottom) div 2; + Points[0].X := ARect.Right - 2 - h; + Points[0].y := y - h; + Points[1].X := ARect.Right - 2 - h; + Points[1].y := y + h; + Points[2].X := ARect.Right - 2; + Points[2].y := y; + Points[3] := Points[0]; + Polygon(DC, @Points, 4, False); + end; + procedure DrawTopArrow(ARect: TRect); + var x, h: Integer; + begin + h := Min( (Abs(ARect.Bottom - ARect.Top) - 4) div 2, + (Abs(ARect.Left - ARect.Right) - 4) div 2 ); + x := (ARect.Left + ARect.Right) div 2; + Points[0].Y := ARect.Top + 2 + h; + Points[0].X := x - h; + Points[1].Y := ARect.Top + 2 + h; + Points[1].X := x + h; + Points[2].Y := ARect.Top + 2; + Points[2].X := x; + Points[3] := Points[0]; + Polygon(DC, @Points, 4, False); + end; + procedure DrawBottomArrow(ARect: TRect); + var x, h: Integer; + begin + h := Min( (Abs(ARect.Bottom - ARect.Top) - 4) div 2, + (Abs(ARect.Left - ARect.Right) - 4) div 2 ); + x := (ARect.Left + ARect.Right) div 2; + Points[0].Y := ARect.Bottom - 2 - h; + Points[0].X := X - h; + Points[1].Y := ARect.Bottom - 2 - h; + Points[1].X := X + h; + Points[2].Y := ARect.Bottom - 2; + Points[2].X := X; + Points[3] := Points[0]; + Polygon(DC, @Points, 4, False); + end; + +begin + inherited PaintWindow(DC); + if FDragOverIndex < 0 then exit; + + if (TabPosition in [tpLeft, tpRight]) then begin + if FDragToRightSide then begin + DrawBottomArrow(FDragOverTabRect); + if (FDragOverIndex < PageCount - 1) then + DrawTopArrow(FDragNextToTabRect); + end else begin + DrawTopArrow(FDragOverTabRect); + if (FDragOverIndex > 0) then + DrawBottomArrow(FDragNextToTabRect); + end; + end + else + begin + if FDragToRightSide then begin + DrawRightArrow(FDragOverTabRect); + if (FDragOverIndex < PageCount - 1) then + DrawLeftArrow(FDragNextToTabRect); + end else begin + DrawLeftArrow(FDragOverTabRect); + if (FDragOverIndex > 0) then + DrawRightArrow(FDragNextToTabRect); + end; + end; +end; + +procedure TEmbedNotebook.DragDrop(Source: TObject; X, Y: Integer); +var + TabId, TabId2: Integer; + ToRight: Boolean; + Ctrl: Boolean; + Src: TEmbedNotebook; + Accept: Boolean; +begin + if (not (Source is TEmbedNotebook)) or + (TEmbedNotebook(Source).FDraggingTabIndex < 0) + then begin + // normal DragDrop + inherited DragDrop(Source, X, Y); + exit; + end; + + // Tab DragDrop + If Assigned(FOnTabDragDrop) then FOnTabDragDrop(Self, Source,X,Y); + + if (FDragOverIndex >= 0) then begin + InvalidateRect(FDragOverTabRect); + InvalidateRect(FDragNextToTabRect); + end; + FDragOverIndex := -1; + DragCursor := crDrag; + + TabId := TabIndexForDrag(X,Y); + TabRectEx(TabId, X, Y, ToRight); + + if (Source = Self) and (TabId = FDraggingTabIndex - 1) then + ToRight := False; + if (Source = Self) and (TabId = FDraggingTabIndex + 1) then + ToRight := True; + if ToRight then + inc(TabId); + + Src := TEmbedNotebook(Source); + TabId2 := TabId; + if (Source = self) and (TabId > Src.DraggingTabIndex) then + dec(TabId); + + if assigned(FOnTabDragDropEx) then begin + Ctrl := (GetKeyState(VK_CONTROL) and $8000)<>0; + Accept := True; + if Assigned(FOnTabDragOverEx) then + FOnTabDragOverEx(Self, Source, Src.DraggingTabIndex, TabId, Ctrl, Accept); + if Accept then + FOnTabDragDropEx(Self, Source, Src.DraggingTabIndex, TabId, Ctrl, FTabDragged); + end; + + if (not FTabDragged) and (FTabDragAcceptMode = dmAutomatic) and + (Source = Self) and (TabId2 >= 0) and (TabId2 <> FDraggingTabIndex) + then begin + TCustomTabControl(Self).Pages.Move(Src.DraggingTabIndex, TabId); + FTabDragged := True; + end; +end; + +procedure TEmbedNotebook.BeginDragTab(ATabIndex: Integer; Immediate: Boolean; + Threshold: Integer = -1); +begin + if (ATabIndex < 0) or (ATabIndex >= PageCount) then + raise Exception.Create('Bad index'); + FDraggingTabIndex := ATabIndex; + BeginDrag(Immediate, Threshold); +end; + +//======================================================= ct9999 for CodeTyphon Studio +//======================================================= +//======================================================= + +procedure TEmbedNotebook.UpdateEmbedFormDsgSettings; + var i:integer; +begin + if PageCount<1 then exit; + + for i:=0 to PageCount-1 do + if Assigned(Pages[i]) then + TEmbedTabSheet(Pages[i]).UpdateEmbedFormDsgSettings; +end; + +procedure TEmbedNotebook.CloseAllEmbedFormEditors; + var i:integer; +begin + if EnvironmentOptions.UseEmbeddedDesigner = False then + Exit; + if PageCount<1 then exit; + + for i:=0 to PageCount-1 do + if Assigned(Pages[i]) then + TEmbedTabSheet(Pages[i]).FormEditorPause; +end; + +Procedure TEmbedNotebook.ActivatedDesigner; +begin + if EnvironmentOptions.UseEmbeddedDesigner = False then + Exit; + if Pages[PageIndex]=nil then exit; + if TEmbedTabSheet(Pages[PageIndex]).FFormEditor=nil then exit; + + TEmbedTabSheet(Pages[PageIndex]).FFormEditor.ActivatedDesigner; +end; + +Function TEmbedNotebook.GetDisplayState: TDisplayState; +var ts:TEmbedTabSheet; +begin + result:=dsSource; + if EnvironmentOptions.UseEmbeddedDesigner = False then + Exit; + + ts:=TEmbedTabSheet(Pages[PageIndex]); + if ts=nil then exit; + if ts.FEditPages=nil then exit; + + if ts.FEditPages.ActivePage=ts.FEditPageForDesigner then + result:=dsForm else + result:=dsSource; +end; + +Procedure TEmbedNotebook.SetDisplayState(const val:TDisplayState); +var ts:TEmbedTabSheet; +begin + if EnvironmentOptions.UseEmbeddedDesigner = False then + Exit; + + ts:=TEmbedTabSheet(Pages[PageIndex]); + if ts=nil then exit; + +//.......................... + if val=dsSource then + begin + ts.ShowSourceTab; + end else + begin + ts.ShowFormEditorTab; + end; +end; + +Procedure TEmbedNotebook.ToggleFormUnit; +begin + if DisplayState=dsSource then + DisplayState:=dsForm else + DisplayState:=dsSource; +end; + +procedure TEmbedNotebook.EmbeddedForm(Sender: TObject; aForm: TCustomForm; aPage:TEmbedTabSheet); + var ts:TEmbedTabSheet; +begin + if EnvironmentOptions.UseEmbeddedDesigner = False then + Exit; + if Embed_IsDesignForm(aForm)=false then exit; + +if aPage=nil then +begin + ShowMessage('[DEV IDE ERROR 140 ] Can NOT Find TabPage to Embedded Form: '+aForm.Name); +end else +begin + if aPage.Parent=self then + aPage.EmbeddedForm(Sender,aForm); +end; + +end; + +Initialization + + RegisterClass(TEmbedNotebook); + +//======================================================= ct9999 +//======================================================= +//======================================================= + + +end. + diff --git a/ide/environmentopts.pp b/ide/environmentopts.pp index 8b93eb4415..d3467b18c7 100644 --- a/ide/environmentopts.pp +++ b/ide/environmentopts.pp @@ -715,6 +715,13 @@ type //component list FComponentListKeepOpen: Boolean; + //Embedded designer + FUseEmbeddedDesigner: Boolean; + FUseEmbeddedScreenPreview: Boolean; + FUseEmbeddedDesignerBackColor: TColor; + FUseEmbeddedSreenPreviewBackColor: TColor; + FUseEmbeddedInfopanelColor: TColor; + // Desktop FDesktops: TDesktopOptList; FDesktop: TDesktopOpt; @@ -1048,6 +1055,14 @@ type // default template for each 'new item' category: Name=Path, Value=TemplateName property NewUnitTemplate: string read FNewUnitTemplate write FNewUnitTemplate; property NewFormTemplate: string read FNewFormTemplate write FNewFormTemplate; + + //Embedded designer + property UseEmbeddedDesigner: Boolean read FUseEmbeddedDesigner write FUseEmbeddedDesigner; + property UseEmbeddedScreenPreview: Boolean read FUseEmbeddedScreenPreview write FUseEmbeddedScreenPreview; + property UseEmbeddedDesignerBackColor: TColor read FUseEmbeddedDesignerBackColor write FUseEmbeddedDesignerBackColor; + property UseEmbeddedSreenPreviewBackColor: TColor read FUseEmbeddedSreenPreviewBackColor write FUseEmbeddedSreenPreviewBackColor; + property UseEmbeddedInfopanelColor: TColor read FUseEmbeddedInfopanelColor write FUseEmbeddedInfopanelColor; + // Desktop property Desktops: TDesktopOptList read FDesktops; property Desktop: TDesktopOpt read FDesktop; // the working desktop, standalone @@ -2227,6 +2242,13 @@ begin // global build options FBuildMatrixOptions:=TBuildMatrixOptions.Create; + //Embedded designer + FUseEmbeddedDesigner := False; + FUseEmbeddedScreenPreview := True; + FUseEmbeddedDesignerBackColor := clWhite; + FUseEmbeddedSreenPreviewBackColor := $00A56E3A; + FUseEmbeddedInfopanelColor := $00EAFFEF; + // Desktop collection FDesktops := TDesktopOptList.Create(Self); // FDesktop points to the IDE properties @@ -2741,6 +2763,13 @@ begin end; end; + //Embedded designer + FUseEmbeddedDesigner := FXMLCfg.GetValue(Path+'EmbeddedDesigner/UseEmbeddedDesigner/Value', False); + FUseEmbeddedScreenPreview := FXMLCfg.GetValue(Path+'EmbeddedDesigner/UseEmbeddedScreenPreview/Value', True); + FUseEmbeddedDesignerBackColor := FXMLCfg.GetValue(Path+'EmbeddedDesigner/UseEmbeddedDesignerBackColor/Value', clWhite); + FUseEmbeddedSreenPreviewBackColor := FXMLCfg.GetValue(Path+'EmbeddedDesigner/UseEmbeddedSreenPreviewBackColor/Value', $00A56E3A); + FUseEmbeddedInfopanelColor:=FXMLCfg.GetValue(Path+'EmbeddedDesigner/UseEmbeddedInfopanelColor/Value', $00EAFFEF); + // The user can define many desktops. They are saved under path Desktops/. FDesktops.Clear; FDesktops.SetConfig(FXMLCfg, FConfigStore); @@ -3087,6 +3116,13 @@ begin end; end; + //Embedded designer + FXMLCfg.SetDeleteValue(Path+'EmbeddedDesigner/UseEmbeddedDesigner/Value', FUseEmbeddedDesigner, False); + FXMLCfg.SetDeleteValue(Path+'EmbeddedDesigner/UseEmbeddedScreenPreview/Value', FUseEmbeddedScreenPreview, True); + FXMLCfg.SetDeleteValue(Path+'EmbeddedDesigner/UseEmbeddedDesignerBackColor/Value', FUseEmbeddedDesignerBackColor, clWhite); + FXMLCfg.SetDeleteValue(Path+'EmbeddedDesigner/UseEmbeddedSreenPreviewBackColor/Value', FUseEmbeddedSreenPreviewBackColor, $00A56E3A); + FXMLCfg.SetDeleteValue(Path+'EmbeddedDesigner/UseEmbeddedInfopanelColor/Value', FUseEmbeddedInfopanelColor, $00EAFFEF); + //automatically save active desktops if AutoSaveActiveDesktop and (Application.MainForm<>nil) and Application.MainForm.Visible then diff --git a/ide/frames/embedded_designer_options.lfm b/ide/frames/embedded_designer_options.lfm new file mode 100644 index 0000000000..ef5e7aa7f1 --- /dev/null +++ b/ide/frames/embedded_designer_options.lfm @@ -0,0 +1,118 @@ +object IDEEmbeddedDesignerSettingsFrame: TIDEEmbeddedDesignerSettingsFrame + Left = 0 + Height = 443 + Top = 0 + Width = 435 + ClientHeight = 443 + ClientWidth = 435 + TabOrder = 0 + DesignLeft = 324 + DesignTop = 144 + object ButtonSetDafault: TButton + Left = 10 + Height = 25 + Hint = 'Set Default' + Top = 240 + Width = 126 + Caption = 'Restore Defaults' + OnClick = ButtonSetDafaultClick + ParentShowHint = False + ShowHint = True + TabOrder = 1 + end + object UseEmbeddedDesignerCheckBox: TCheckBox + Left = 10 + Height = 19 + Top = 16 + Width = 153 + BorderSpacing.Left = 6 + Caption = 'Enable embedded design' + OnClick = UseEmbeddedDesignerCheckBoxClick + TabOrder = 0 + end + object grOptions: TGroupBox + AnchorSideLeft.Control = Owner + AnchorSideRight.Control = Owner + AnchorSideRight.Side = asrBottom + Left = 10 + Height = 169 + Top = 56 + Width = 415 + Anchors = [akTop, akLeft, akRight] + BorderSpacing.Left = 10 + BorderSpacing.Right = 10 + Caption = 'Options' + ClientHeight = 149 + ClientWidth = 411 + TabOrder = 2 + object UseEmbeddedScreenPreviewCheckBox: TCheckBox + Left = 17 + Height = 19 + Top = 111 + Width = 151 + BorderSpacing.Left = 6 + Caption = 'Use/View Screen Preview' + TabOrder = 0 + end + object UseDesignerBackColorText: TLabel + AnchorSideTop.Side = asrCenter + Left = 16 + Height = 15 + Top = 18 + Width = 106 + Caption = 'Designer Back Color' + ParentColor = False + end + object UseDesignerBackColorClrBox: TColorBox + Left = 217 + Height = 22 + Top = 16 + Width = 112 + DefaultColorColor = 12320767 + Style = [cbStandardColors, cbExtendedColors, cbSystemColors, cbIncludeDefault, cbCustomColor, cbPrettyNames, cbCustomColors] + DropDownCount = 20 + ItemHeight = 16 + TabOrder = 1 + end + object UseSreenPreviewBackColorText: TLabel + AnchorSideTop.Side = asrCenter + Left = 18 + Height = 15 + Top = 50 + Width = 139 + Caption = 'Screen Preview Back Color' + ParentColor = False + end + object UseSreenPreviewBackColorClrBox: TColorBox + Left = 217 + Height = 22 + Top = 50 + Width = 112 + DefaultColorColor = 12320767 + Style = [cbStandardColors, cbExtendedColors, cbSystemColors, cbIncludeDefault, cbCustomColor, cbPrettyNames, cbCustomColors] + DropDownCount = 20 + ItemHeight = 16 + TabOrder = 2 + end + object UseInfopanelColorCheckText: TLabel + AnchorSideTop.Side = asrCenter + Left = 18 + Height = 15 + Top = 80 + Width = 85 + Caption = 'Info Panel Color' + ParentColor = False + end + object UseInfopanelColorClrBox: TColorBox + Left = 217 + Height = 22 + Top = 80 + Width = 112 + DefaultColorColor = 12320767 + Style = [cbStandardColors, cbExtendedColors, cbSystemColors, cbIncludeDefault, cbCustomColor, cbPrettyNames, cbCustomColors] + DropDownCount = 20 + ItemHeight = 16 + TabOrder = 3 + end + end +end diff --git a/ide/frames/embedded_designer_options.pas b/ide/frames/embedded_designer_options.pas new file mode 100644 index 0000000000..b96173dacf --- /dev/null +++ b/ide/frames/embedded_designer_options.pas @@ -0,0 +1,156 @@ +{********************************************************************** + Copyright (c) PilotLogic Software House + All rights reserved + + This file is part of CodeTyphon Studio (https://www.pilotlogic.com/) + + *************************************************************************** + * * + * This source is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This code is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * General Public License for more details. * + * * + * A copy of the GNU General Public License is available on the World * + * Wide Web at . You can also * + * obtain it by writing to the Free Software Foundation, * + * Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1335, USA. * + * * + ***************************************************************************} + +unit embedded_designer_options; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, + // LCL + FileUtil, Forms, Controls, Graphics, StdCtrls, ColorBox, Dialogs, + //IDE intf + IDEOptionsIntf, SrcEditorIntf, IDEOptEditorIntf, IDEWindowIntf, + //IDE + LazarusIDEStrConsts, EnvironmentOpts, IDEDialogs; + +type + + { TIDEEmbeddedDesignerSettingsFrame } + + TIDEEmbeddedDesignerSettingsFrame = class(TAbstractIDEOptionsEditor) + ButtonSetDafault: TButton; + grOptions: TGroupBox; + UseDesignerBackColorClrBox: TColorBox; + UseDesignerBackColorText: TLabel; + UseEmbeddedDesignerCheckBox: TCheckBox; + UseEmbeddedScreenPreviewCheckBox: TCheckBox; + UseInfopanelColorCheckText: TLabel; + UseInfopanelColorClrBox: TColorBox; + UseSreenPreviewBackColorClrBox: TColorBox; + UseSreenPreviewBackColorText: TLabel; + procedure ButtonSetDafaultClick(Sender: TObject); + procedure UseEmbeddedDesignerCheckBoxClick(Sender: TObject); + private + FOldUseEmbeddedDesigner: Boolean; + procedure EnableDisableControls(const AEnable: Boolean); + public + function GetTitle: String; override; + procedure Setup({%H-}ADialog: TAbstractOptionsEditorDialog); override; + procedure ReadSettings(AOptions: TAbstractIDEOptions); override; + procedure WriteSettings(AOptions: TAbstractIDEOptions); override; + class function SupportedOptionsClass: TAbstractIDEOptionsClass; override; + end; + +implementation + +{$R *.lfm} + +function TIDEEmbeddedDesignerSettingsFrame.GetTitle: String; +begin + Result := lisEmbDsgn_Title; +end; + +procedure TIDEEmbeddedDesignerSettingsFrame.ButtonSetDafaultClick(Sender: TObject); +begin + UseEmbeddedDesignerCheckBox.Checked := False; + UseEmbeddedScreenPreviewCheckBox.Checked := True; + UseDesignerBackColorClrBox.Selected := clWhite; + UseSreenPreviewBackColorClrBox.Selected := $00A56E3A; + UseInfopanelColorClrBox.Selected := $00EAFFEF; + EnableDisableControls(UseEmbeddedDesignerCheckBox.Checked); +end; + +procedure TIDEEmbeddedDesignerSettingsFrame.Setup(ADialog: TAbstractOptionsEditorDialog); +begin + UseEmbeddedDesignerCheckBox.Caption := lisEmbDsgn_UseEmbeddedDesign; + grOptions.Caption := lisEmbDsgn_Options; + UseEmbeddedScreenPreviewCheckBox.Caption := lisEmbDsgn_UseScreenPreview; + UseDesignerBackColorText.Caption := lisEmbDsgn_BackColor; + UseSreenPreviewBackColorText.Caption := lisEmbDsgn_SreenPreviewBackColor; + UseInfopanelColorCheckText.Caption := lisEmbDsgn_InfopanelColor; + ButtonSetDafault.Caption := lisEmbDsgn_SetDafault; +end; + +procedure TIDEEmbeddedDesignerSettingsFrame.ReadSettings(AOptions: TAbstractIDEOptions); +begin + with (AOptions as TEnvironmentOptions) do + begin + UseEmbeddedDesignerCheckBox.Checked := UseEmbeddedDesigner; + UseEmbeddedScreenPreviewCheckBox.Checked := UseEmbeddedScreenPreview; + UseDesignerBackColorClrBox.Selected := UseEmbeddedDesignerBackColor; + UseSreenPreviewBackColorClrBox.Selected := UseEmbeddedSreenPreviewBackColor; + UseInfopanelColorClrBox.Selected := UseEmbeddedInfopanelColor; + end; + EnableDisableControls(UseEmbeddedDesignerCheckBox.Checked); + FOldUseEmbeddedDesigner := (AOptions as TEnvironmentOptions).UseEmbeddedDesigner; +end; + +procedure TIDEEmbeddedDesignerSettingsFrame.WriteSettings(AOptions: TAbstractIDEOptions); +begin + with (AOptions as TEnvironmentOptions) do + begin + UseEmbeddedDesigner := UseEmbeddedDesignerCheckBox.Checked; + UseEmbeddedScreenPreview := UseEmbeddedScreenPreviewCheckBox.Checked; + UseEmbeddedDesignerBackColor := UseDesignerBackColorClrBox.Selected; + UseEmbeddedSreenPreviewBackColor:= UseSreenPreviewBackColorClrBox.Selected; + UseEmbeddedInfopanelColor := UseInfopanelColorClrBox.Selected; + end; + if Assigned(SourceEditorManagerIntf) then + SourceEditorManagerIntf.UpdateEmbedFormDsgSettings; + if FOldUseEmbeddedDesigner <> (AOptions as TEnvironmentOptions).UseEmbeddedDesigner then + IDEMessageDialog(lisEmbDsgn_RestartIDECaption, lisEmbDsgn_RestartIDEText, mtInformation, [mbOk]); +end; + +procedure TIDEEmbeddedDesignerSettingsFrame.EnableDisableControls( + const AEnable: Boolean); +begin + UseDesignerBackColorText.Enabled := AEnable; + UseDesignerBackColorClrBox.Enabled := AEnable; + UseSreenPreviewBackColorText.Enabled := AEnable; + UseSreenPreviewBackColorClrBox.Enabled := AEnable; + UseInfopanelColorCheckText.Enabled := AEnable; + UseInfopanelColorClrBox.Enabled := AEnable; + UseEmbeddedScreenPreviewCheckBox.Enabled := AEnable; +end; + +procedure TIDEEmbeddedDesignerSettingsFrame.UseEmbeddedDesignerCheckBoxClick( + Sender: TObject); +begin + EnableDisableControls(UseEmbeddedDesignerCheckBox.Checked); +end; + +class function TIDEEmbeddedDesignerSettingsFrame.SupportedOptionsClass: TAbstractIDEOptionsClass; +begin + Result := TEnvironmentOptions; +end; + +initialization + RegisterIDEOptionsEditor(GroupEnvironment, TIDEEmbeddedDesignerSettingsFrame, EnvOptionsEmbeddedDsg); + +end. + diff --git a/ide/lazarusidestrconsts.pas b/ide/lazarusidestrconsts.pas index 6f0790b13c..8af122650d 100644 --- a/ide/lazarusidestrconsts.pas +++ b/ide/lazarusidestrconsts.pas @@ -4947,6 +4947,18 @@ resourcestring lisCoolbarDeleteWarning = 'There must be at least one toolbar!'; lisCoolbarRestoreDefaults = 'Restore defaults'; + //embedded designer + lisEmbDsgn_Title = 'Embedded Designer'; + lisEmbDsgn_Options = 'Options'; + lisEmbDsgn_UseEmbeddedDesign = 'Enable embedded design'; + lisEmbDsgn_UseScreenPreview = 'Use/View Screen Preview'; + lisEmbDsgn_BackColor = 'Designer Back Color'; + lisEmbDsgn_SreenPreviewBackColor = 'Screen Preview Back Color'; + lisEmbDsgn_InfopanelColor = 'Info Panel Color'; + lisEmbDsgn_SetDafault = 'Restore Defaults'; + lisEmbDsgn_RestartIDECaption = 'Information'; + lisEmbDsgn_RestartIDEText = 'In order for the chagnes to take effect, please restart the IDE.'; + // Editor Toolbar lisEditorToolbar = 'Editor ToolBar'; lisConfigureEditorToolbar = 'Configure Toolbar'; diff --git a/ide/main.pp b/ide/main.pp index 8aab15a283..d094b9d9da 100644 --- a/ide/main.pp +++ b/ide/main.pp @@ -113,7 +113,7 @@ uses ChgEncodingDlg, ConvertDelphi, MissingPropertiesDlg, LazXMLForms, // environment option frames editor_general_options, componentpalette_options, formed_options, OI_options, - MsgWnd_Options, files_options, desktop_options, window_options, + MsgWnd_Options, files_options, desktop_options, window_options, embedded_designer_options, Backup_Options, naming_options, fpdoc_options, idecoolbar_options, editortoolbar_options, editor_display_options, editor_keymapping_options, editor_mouseaction_options, editor_mouseaction_options_advanced, editor_color_options, editor_markup_options, @@ -1658,6 +1658,8 @@ begin IDECommandList.StartUpdateEvents; FIDEStarted:=true; {$IFDEF IDE_MEM_CHECK}CheckHeapWrtMemCnt('TMainIDE.StartIDE END');{$ENDIF} + if IDEDockMaster <> nil then + IDEDockMaster.Loaded := True; end; destructor TMainIDE.Destroy; @@ -2210,6 +2212,8 @@ begin SourceEditorManager.OnPopupMenu := @SrcNoteBookPopupMenu; SourceEditorManager.OnNoteBookCloseQuery := @SrcNoteBookCloseQuery; SourceEditorManager.OnPackageForSourceEditor := @PkgBoss.GetPackageOfSourceEditor; + if EnvironmentOptions.UseEmbeddedDesigner then + SourceEditorManager.OnToggleFormOrSource := @SrcNoteBookActivated; DebugBoss.ConnectSourceNotebookEvents; OnSearchResultsViewSelectionChanged := @SearchResultsViewSelectionChanged; @@ -3848,6 +3852,11 @@ begin AForm.BringToFront; LCLIntf.ShowWindow(AForm.Handle,SW_SHOWNORMAL); end; + if EnvironmentOptions.UseEmbeddedDesigner then + begin + DisplayState := dsForm; + SourceEditorManager.DisplayState := dsForm; + end; end; procedure TMainIDE.DoViewAnchorEditor(State: TIWGetFormState); @@ -4228,6 +4237,8 @@ begin for i := 0 to SourceEditorManager.SourceWindowCount - 1 do SourceEditorManager.SourceWindows[i].Show; SourceEditorManager.ShowActiveWindowOnTop(False); + if EnvironmentOptions.UseEmbeddedDesigner then + SourceEditorManager.DisplayState := dsSource; end; {------------------------------------------------------------------------------} @@ -8876,10 +8887,19 @@ begin {$IFDEF VerboseIDEDisplayState} debugln(['TMainIDE.DoBringToFrontFormOrUnit ',dbgs(DisplayState)]); {$ENDIF} - if DisplayState <> dsSource then begin - DoShowSourceOfActiveDesignerForm; - end else begin - DoShowDesignerFormOfCurrentSrc(false); + if EnvironmentOptions.UseEmbeddedDesigner then + begin + if SourceEditorManager.DisplayState <> dsSource then + DoShowSourceOfActiveDesignerForm + else + DoShowDesignerFormOfCurrentSrc(true); + end + else + begin + if DisplayState <> dsSource then + DoShowSourceOfActiveDesignerForm + else + DoShowDesignerFormOfCurrentSrc(false); end; end; @@ -9043,6 +9063,7 @@ begin {$IFDEF VerboseIDEDisplayState} debugln(['TMainIDE.DoShowSourceOfActiveDesignerForm ']); {$ENDIF} + SourceEditorManager.DisplayState := dsSource; DisplayState:=dsSource; end; @@ -9147,6 +9168,8 @@ begin if FocusEditor then begin IDEWindowCreators.ShowForm(MessagesView,true); SourceEditorManager.ShowActiveWindowOnTop(True); + if EnvironmentOptions.UseEmbeddedDesigner then + SourceEditorManager.DisplayState := dsSource; end; if IDETabMaster <> nil then IDETabMaster.JumpToCompilerMessage(SrcEdit); @@ -9232,6 +9255,8 @@ begin if FocusEditor then begin IDEWindowCreators.ShowForm(SearchResultsView,true); SourceEditorManager.ShowActiveWindowOnTop(True); + if EnvironmentOptions.UseEmbeddedDesigner then + SourceEditorManager.DisplayState := dsSource; end; try SrcEdit.BeginUpdate; @@ -9278,6 +9303,8 @@ begin SearchResultsView.DisableAutoSizing{$IFDEF DebugDisableAutoSizing}('TMainIDE.DoShowSearchResultsView'){$ENDIF}; if State>=iwgfShow then IDEWindowCreators.ShowForm(SearchresultsView,State=iwgfShowOnTop); + if EnvironmentOptions.UseEmbeddedDesigner then + SourceEditorManager.DisplayState := dsSource; end; function TMainIDE.GetTestBuildDirectory: string; @@ -10146,6 +10173,8 @@ begin if jfFocusEditor in Flags then SourceEditorManager.ShowActiveWindowOnTop(True); + if EnvironmentOptions.UseEmbeddedDesigner then + SourceEditorManager.DisplayState := dsSource; UpdateSourceNames; Result:=mrOk; finally @@ -10317,6 +10346,8 @@ begin TopLine:=ErrorTopLine; end; SourceEditorManager.ShowActiveWindowOnTop(True); + if EnvironmentOptions.UseEmbeddedDesigner then + SourceEditorManager.DisplayState := dsSource; SourceEditorManager.ClearErrorLines; ActiveSrcEdit.ErrorLine:=ErrorCaret.Y; end; @@ -10975,6 +11006,8 @@ procedure TMainIDE.JumpHistoryViewSelectionChanged(sender : TObject); begin SourceEditorManager.HistoryJump(self, jhaViewWindow); SourceEditorManager.ShowActiveWindowOnTop(True); + if EnvironmentOptions.UseEmbeddedDesigner then + SourceEditorManager.DisplayState := dsSource; end; procedure TMainIDE.LazInstancesGetOpenedProjectFileName( @@ -10997,7 +11030,11 @@ begin {$IFDEF VerboseIDEDisplayState} debugln(['TMainIDE.OnSrcNotebookEditorActived']); {$ENDIF} - DisplayState:=dsSource; + if EnvironmentOptions.UseEmbeddedDesigner = False then + DisplayState := dsSource + else + DisplayState := SourceEditorManager.DisplayState; + Project1.UpdateVisibleUnit(ASrcEdit, ASrcEdit.SourceNotebook.WindowID); ActiveUnitInfo := Project1.UnitWithEditorComponent(ASrcEdit); @@ -11249,6 +11286,8 @@ begin SourceEditorManager.ActiveEditor := AnEditor; SourceEditorManager.ShowActiveWindowOnTop(True); + if EnvironmentOptions.UseEmbeddedDesigner then + SourceEditorManager.DisplayState := dsSource; try AnEditor.BeginUpdate; AnEditor.EditorComponent.GotoBookMark(ID); @@ -11534,10 +11573,16 @@ begin {$IFDEF VerboseIDEDisplayState} debugln(['TMainIDE.OnSrcNoteBookActivated']); {$ENDIF} - DisplayState:=dsSource; + if EnvironmentOptions.UseEmbeddedDesigner = False then + DisplayState := dsSource + else + DisplayState := SourceEditorManager.DisplayState; end; procedure TMainIDE.DesignerActivated(Sender: TObject); +var + ActiveSourceEditor: TSourceEditor; + ActiveUnitInfo: TUnitInfo; begin {$IFDEF VerboseIDEDisplayState} if DisplayState<>dsForm then begin @@ -11545,17 +11590,30 @@ begin DumpStack; end; {$ENDIF} - DisplayState:= dsForm; - LastFormActivated := (Sender as TDesigner).Form; - if EnvironmentOptions.FormTitleBarChangesObjectInspector - and (TheControlSelection.SelectionForm <> LastFormActivated) then - TheControlSelection.AssignPersistent(LastFormActivated); - {$IFDEF VerboseComponentPalette} - DebugLn('***'); - DebugLn(['** TMainIDE.DesignerActivated: Calling UpdateIDEComponentPalette(true)', - ', IDEStarted=', FIDEStarted, ' **']); - {$ENDIF} - MainIDEBar.UpdateIDEComponentPalette(true); + + if EnvironmentOptions.UseEmbeddedDesigner then + begin + if LastFormActivated <> nil then + begin + GetCurrentUnit(ActiveSourceEditor, ActiveUnitInfo); + if (ActiveUnitInfo <> nil) then + TheControlSelection.AssignPersistent(ActiveUnitInfo.Component); + end; + end else + begin + DisplayState:= dsForm; + LastFormActivated := (Sender as TDesigner).Form; + if EnvironmentOptions.FormTitleBarChangesObjectInspector + and (TheControlSelection.SelectionForm <> LastFormActivated) then + TheControlSelection.AssignPersistent(LastFormActivated); + {$IFDEF VerboseComponentPalette} + DebugLn('***'); + DebugLn(['** TMainIDE.DesignerActivated: Calling UpdateIDEComponentPalette(true)', + ', IDEStarted=', FIDEStarted, ' **']); + {$ENDIF} + MainIDEBar.UpdateIDEComponentPalette(true); + end; + end; procedure TMainIDE.DesignerCloseQuery(Sender: TObject); @@ -11585,7 +11643,8 @@ begin end; if FDesignerToBeFreed=nil then FDesignerToBeFreed:=TFilenameToStringTree.Create(false); - FDesignerToBeFreed[AnUnitInfo.Filename]:='1'; + if EnvironmentOptions.UseEmbeddedDesigner = False then + FDesignerToBeFreed[AnUnitInfo.Filename] := '1'; end; procedure TMainIDE.DesignerRenameComponent(ADesigner: TDesigner; diff --git a/ide/sourceeditor.pp b/ide/sourceeditor.pp index 503f6ed72d..2dbec3354a 100644 --- a/ide/sourceeditor.pp +++ b/ide/sourceeditor.pp @@ -70,6 +70,8 @@ uses EditorSyntaxHighlighterDef, // DebuggerIntf DbgIntfDebuggerBase, + //Embedded designer + embedded_designer_basics, embedded_designer_formeditor, embedded_designer_notebook, // IDE units IDECmdLine, LazarusIDEStrConsts, EditorOptions, EnvironmentOpts, WordCompletion, FindReplaceDialog, IDEProcs, IDEOptionDefs, @@ -365,6 +367,12 @@ type procedure AfterCodeBufferReplace; function Close: Boolean; public + FParentEmbedTabSheet: TEmbedTabSheet; + Function GetNotebook: TEmbedNotebook; + procedure ShowSourceTab; + procedure ShowFormTab; + property Notebook: TEmbedNotebook read GetNotebook; + property TabSheet: TEmbedTabSheet read fParentEmbedTabSheet; constructor Create(AOwner: TComponent; AParent: TWinControl; ASharedEditor: TSourceEditor = nil); destructor Destroy; override; @@ -655,7 +663,9 @@ type const ARect: TRect); procedure TabPopUpMenuPopup(Sender: TObject); private - FNotebook: TExtendedNotebook; + FNotebook: TEmbedNotebook; + FOnToggleFormOrSource: TNotifyEvent; + Last_Source_Editor: TSourceEditor; FBaseCaption: String; FIsClosing: Boolean; FSrcEditsSortedForFilenames: TAvlTree; // TSourceEditorInterface sorted for Filename @@ -663,6 +673,7 @@ type procedure ApplyPageIndex; procedure ExecuteEditorItemClick(Sender: TObject); public + property OnToggleFormOrSource: TNotifyEvent read FOnToggleFormOrSource write FOnToggleFormOrSource; procedure DeleteBreakpointClicked(Sender: TObject); procedure ToggleBreakpointClicked(Sender: TObject); procedure ToggleBreakpointEnabledClicked(Sender: TObject); @@ -1131,10 +1142,27 @@ type procedure DeleteLastJumpPointClicked(Sender: TObject); procedure ViewJumpHistoryClicked(Sender: TObject); protected + FOnToggleFormOrSource: TNotifyEvent; + Function GetDisplayState: TDisplayState; + Procedure SetDisplayState(const val:TDisplayState); // Bookmarks procedure BookMarkToggleClicked(Sender: TObject); procedure BookMarkGotoClicked(Sender: TObject); public + procedure EmbeddedForm(Sender: TObject; aForm: TCustomForm); + procedure ScreenFormVisibleChanged(Sender: TObject; aForm: TCustomForm); + procedure UpdateEmbedFormDsgSettings; override; + + Procedure StartExecuteDock(TheDockSite: TCustomForm; TheDockControl : TControl); override; + Procedure StartExecuteUnDock(TheDockSite: TCustomForm; TheUnDockControl : TControl); override; + + procedure CloseAllEmbedFormEditors; + Function GetSEWithEmbedForm(aform:TcustomForm):TSourceEditor; + Function SetActiveSEWithEmbedForm(aform:TcustomForm):Boolean; + + property DisplayState: TDisplayState read GetDisplayState write SetDisplayState; + property OnToggleFormOrSource:TNotifyEvent read FOnToggleFormOrSource write FOnToggleFormOrSource; + procedure BookMarkNextClicked(Sender: TObject); procedure BookMarkPrevClicked(Sender: TObject); procedure JumpToPos(FileName: string; Pos: TCodeXYPosition; TopLine: Integer); @@ -3433,6 +3461,10 @@ begin FInEditorChangedUpdating := False; end; PopupMenu := nil; + + if FParentEmbedTabSheet<>nil then + FParentEmbedTabSheet.EditPages_Free; + if (FAOwner<>nil) and (FEditor<>nil) then begin UnbindEditor; FEditor.Visible:=false; @@ -5052,6 +5084,8 @@ begin end; procedure TSourceEditor.UpdateNoteBook(const ANewNoteBook: TSourceNotebook; ANewPage: TTabSheet); +var + xForm: TCustomForm; begin if FSourceNoteBook = ANewNoteBook then exit; @@ -5063,8 +5097,31 @@ begin // Change the Owner of the SynEdit EditorComponent.Owner.RemoveComponent(EditorComponent); FSourceNoteBook.InsertComponent(EditorComponent); - // And the Parent - EditorComponent.Parent := ANewPage; + + TEmbedTabSheet(ANewPage).EditPages_Create; + EditorComponent.Parent := TEmbedTabSheet(ANewPage).FEditPageForSource; + ANewNoteBook.Last_Source_Editor := Self; + xForm := nil; + if FParentEmbedTabSheet <> nil then + begin + xForm:= FParentEmbedTabSheet.LoadedForm; + FParentEmbedTabSheet.EditPages_Free; + if xForm <> nil then + begin + if (CN_FORM_DESIGNER_PARENT_TYPE = ctptParentWindow) then + xForm.ParentWindow := 0; + xForm.Parent := nil; + ShowWindow(xform.Handle, SW_HIDE); + end; + end; + FParentEmbedTabSheet := TEmbedTabSheet(ANewPage); + FParentEmbedTabSheet.FSynEditor := Self.FEditor; + if xForm<>nil then + begin + FParentEmbedTabSheet.EmbeddedForm(nil, xForm); + FParentEmbedTabSheet.ShowSourceTab; + end; + FEditor.Visible := True; end; { AOwner is the TSourceNotebook @@ -5122,7 +5179,13 @@ Begin OnMultiCaretBeforeCommand := @DoMultiCaretBeforeCommand; RegisterMouseActionExecHandler(@EditorHandleMouseAction); // IMPORTANT: when you change above, don't forget updating UnbindEditor - Parent := AParent; + + FParentEmbedTabSheet:=TEmbedTabSheet(AParent); + FParentEmbedTabSheet.EditPages_Free; + FParentEmbedTabSheet.EditPages_Create; + FEditor.Parent := TEmbedTabSheet(AParent).FEditPageForSource; + TSourceNotebook(FAOwner).Last_Source_Editor:=self; + if AParent.Font.PixelsPerInch<>96 then AutoAdjustLayout(lapAutoAdjustForDPI, 96, AParent.Font.PixelsPerInch, 0, 0); end; @@ -5139,8 +5202,13 @@ Begin RefreshEditorSettings; FEditor.EndUpdate; - end else begin - FEditor.Parent:=AParent; + end else + begin + FParentEmbedTabSheet:=TEmbedTabSheet(AParent); + FParentEmbedTabSheet.EditPages_Free; + FParentEmbedTabSheet.EditPages_Create; + FEditor.Parent := TEmbedTabSheet(AParent).FEditPageForSource; + TSourceNotebook(FAOwner).Last_Source_Editor:=self; end; end; @@ -5393,6 +5461,9 @@ end; function TSourceEditor.Close: Boolean; Begin DebugLnEnter(SRCED_CLOSE, ['TSourceEditor.Close ShareCount=', FSharedValues.SharedEditorCount]); + if FParentEmbedTabSheet <> nil then + FParentEmbedTabSheet.EditPages_Free; + Result := True; Visible := False; Manager.EditorRemoved(Self); @@ -5920,6 +5991,9 @@ var Dialog: TMultiPasteDialog; begin if ReadOnly then Exit; + + ShowSourceTab; + Dialog := TMultiPasteDialog.Create(nil); try if Dialog.ShowModal <> mrOK then Exit; @@ -6332,9 +6406,35 @@ end; procedure TSourceEditor.DoEditorExecuteCommand(EditorCommand: word); begin + ShowSourceTab; EditorComponent.CommandProcessor(TSynEditorCommand(EditorCommand),' ',nil); end; +Function TSourceEditor.GetNotebook:TEmbedNotebook; +begin + result:=nil; + if FSourceNotebook<> nil then + if FSourceNotebook.FNotebook<>nil then + result:=FSourceNotebook.FNotebook; +end; + +procedure TSourceEditor.ShowSourceTab; +begin + if EnvironmentOptions.UseEmbeddedDesigner then + if FSourceNotebook<> nil then + if FSourceNotebook.FNotebook<>nil then + if FSourceNotebook.FNotebook.DisplayState<>dsSource then + FSourceNotebook.FNotebook.DisplayState:=dsSource; +end; + +procedure TSourceEditor.ShowFormTab; +begin + if EnvironmentOptions.UseEmbeddedDesigner then + if FSourceNotebook<> nil then + if FSourceNotebook.FNotebook<>nil then + if FSourceNotebook.FNotebook.DisplayState<>dsForm then + FSourceNotebook.FNotebook.DisplayState:=dsForm; +end; {------------------------------------------------------------------------} { TSourceNotebook } @@ -6406,6 +6506,10 @@ begin except end; {$ENDIF} + + if EnvironmentOptions.UseEmbeddedDesigner then + if Manager <> nil then + OnToggleFormOrSource := Manager.OnToggleFormOrSource; end; destructor TSourceNotebook.Destroy; @@ -6435,7 +6539,7 @@ end; procedure TSourceNotebook.CreateNotebook; var - APage: TTabSheet; + APage: TEmbedTabSheet; Begin {$IFDEF IDE_DEBUG} debugln('[TSourceNotebook.CreateNotebook] START'); @@ -6443,7 +6547,7 @@ Begin {$IFDEF IDE_MEM_CHECK} CheckHeapWrtMemCnt('[TSourceNotebook.CreateNotebook] A '); {$ENDIF} - FNotebook := TExtendedNotebook.Create(self); + FNotebook := TEmbedNotebook.Create(self); {$IFDEF IDE_DEBUG} debugln('[TSourceNotebook.CreateNotebook] B'); {$ENDIF} @@ -6458,7 +6562,7 @@ Begin debugln('[TSourceNotebook.CreateNotebook] C'); {$ENDIF} Align := alClient; - APage:=TTabSheet.Create(FNotebook); + APage:=TEmbedTabSheet.Create(FNotebook); APage.Caption:='unit1'; APage.Parent:=FNotebook; PageIndex := 0; // Set it to the first page @@ -7593,7 +7697,7 @@ begin inherited DragOver(Source, X, Y, State, Accept); if State = dsDragLeave then FUpdateTabAndPageTimer.Enabled := True - else if Source is TExtendedNotebook then + else if Source is TEmbedNotebook then FNotebook.ShowTabs := (Manager=nil) or Manager.ShowTabs; end; @@ -8604,6 +8708,8 @@ begin if TabIndex>=0 then FNotebook.ActivePageIndex := TabIndex; end; + if Manager.ActiveSourceWindow <> self then + Manager.ActiveSourceWindow := Self; end; procedure TSourceNotebook.NotebookMouseUp(Sender: TObject; @@ -8690,7 +8796,7 @@ begin FUpdateTabAndPageTimer.Enabled := False; if State = dsDragLeave then FUpdateTabAndPageTimer.Enabled := True - else if Source is TExtendedNotebook then + else if Source is TEmbedNotebook then FNotebook.ShowTabs := (Manager=nil) or Manager.ShowTabs; end; @@ -8760,6 +8866,9 @@ Begin DebugBoss.UnLockCommandProcessing; end; DebugLnExit(SRCED_PAGES, ['<< TSourceNotebook.NotebookPageChanged ']); + if EnvironmentOptions.UseEmbeddedDesigner then + if FNotebook.DisplayState=dsForm then + FNotebook.ActivatedDesigner; end; procedure TSourceNotebook.ProcessParentCommand(Sender: TObject; @@ -10246,6 +10355,7 @@ end; procedure TSourceEditorManager.ReloadEditorOptions; var i: Integer; + Filename: string; begin for i := FSourceWindowList.Count - 1 downto 0 do SourceWindows[i].ReloadEditorOptions; @@ -11203,10 +11313,19 @@ begin Application.AddOnIdleHandler(@OnIdle); Application.AddOnUserInputHandler(@OnUserInput); + if EnvironmentOptions.UseEmbeddedDesigner then + begin + Screen.AddHandlerFormAdded(@EmbeddedForm); + Screen.AddHandlerFormVisibleChanged(@ScreenFormVisibleChanged); + end; end; destructor TSourceEditorManager.Destroy; begin + if EnvironmentOptions.UseEmbeddedDesigner then + begin + Screen.RemoveAllHandlersOfObject(Self); + end; FreeAndNil(FHints); SourceEditorMarks.OnAction := nil; Application.RemoveAllHandlersOfObject(Self); @@ -11375,6 +11494,221 @@ begin LazarusIDE.DoOpenIDEOptions(TEditorGeneralOptionsFrame); end; +function TSourceEditorManager.GetDisplayState: TDisplayState; +var + aa: TSourceNotebook; +begin + Result := dsSource; + aa := GetActiveSourceNotebook; + if aa = nil then + Exit; + if aa.FNotebook = nil then + Exit; + Result := aa.FNotebook.DisplayState; +end; + +procedure TSourceEditorManager.SetDisplayState(const val: TDisplayState); +var + aa: TSourceNotebook; +begin + if EnvironmentOptions.UseEmbeddedDesigner = False then + Exit; + aa := GetActiveSourceNotebook; + if aa = nil then + Exit; + if aa.FNotebook = nil then + Exit; + aa.FNotebook.DisplayState := val; +end; + +function TSourceEditorManager.GetSEWithEmbedForm(aform: TcustomForm): TSourceEditor; +var + i,j: integer; + xEmbedNotebook: TEmbedNotebook; + xPage: TEmbedTabSheet; +begin + Result := nil; + if EnvironmentOptions.UseEmbeddedDesigner = False then + Exit; + if aform = nil then + Exit; + if SourceWindowCount < 1 then + Exit; + xEmbedNotebook := Nil; + xPage := Nil; + + for i := 0 to SourceWindowCount - 1 do + begin + xEmbedNotebook := SourceWindows[i].FNotebook; + if xEmbedNotebook<>nil then + begin + for j := 0 to xEmbedNotebook.PageCount - 1 do + begin + xPage := TEmbedTabSheet(xEmbedNotebook.Page[j]); + if xPage <> nil then + if xPage.FFormEditor <> nil then + if xPage.FFormEditor.FDesignPanel <> nil then + if xPage.FFormEditor.FDesignPanel.LoadedForm <> nil then + if xPage.FFormEditor.FDesignPanel.LoadedForm = aform then + Result:=FindSourceEditorWithEditorComponent(xPage.FSynEditor); + + end; + end; + end; +end; + +function TSourceEditorManager.SetActiveSEWithEmbedForm(aform:TcustomForm):Boolean; +var + xSE: TSourceEditor; +begin + Result := False; + if EnvironmentOptions.UseEmbeddedDesigner = False then + Exit; + if aform = nil then + Exit; + xSE := GetSEWithEmbedForm(aform); + if xSE = nil then + Exit; + ActiveEditor := xSE; +end; + +procedure TSourceEditorManager.UpdateEmbedFormDsgSettings; +var + i: Integer; +begin + if EnvironmentOptions.UseEmbeddedDesigner = False then + Exit; + if SourceWindowCount < 1 then + Exit; + for i := 0 to SourceWindowCount-1 do + if Assigned(SourceWindows[i]) then + if Assigned(SourceWindows[i].FNotebook) then + SourceWindows[i].FNotebook.UpdateEmbedFormDsgSettings; +end; + +procedure TSourceEditorManager.CloseAllEmbedFormEditors; +var + i: integer; +begin + if EnvironmentOptions.UseEmbeddedDesigner = False then + Exit; + if SourceWindowCount < 1 then + Exit; + for i := 0 to SourceWindowCount-1 do + if Assigned(SourceWindows[i]) then + if Assigned(SourceWindows[i].FNotebook) then + SourceWindows[i].FNotebook.CloseAllEmbedFormEditors; +end; + +function _HasSameDockSite(aControl1, aControl2: TControl): Boolean; +var + xtest, xParent1, xParent2: TControl; +begin + Result:=false; + if aControl1 = nil then + Exit; + if aControl2 = nil then + Exit; + + xParent1 := aControl1; + xParent2 := aControl2; + + xtest := aControl1; + repeat + if xtest.Parent<>nil then + xtest := xtest.Parent + else + xtest := nil; + if xtest <> nil then + xParent1:=xtest; + until xtest=nil; + + xtest := aControl2; + repeat + if xtest.Parent <> nil then + xtest := xtest.Parent + else + xtest:=nil; + if xtest <> nil then + xParent2 := xtest; + until xtest = nil; + result:=(xParent1=xParent2); +end; + +procedure TSourceEditorManager.StartExecuteDock(TheDockSite: TCustomForm; TheDockControl : TControl); + var i:integer; +begin + if EnvironmentOptions.UseEmbeddedDesigner = False then + Exit; + if SourceWindowCount < 1 then + Exit; + for i:=0 to SourceWindowCount-1 do + if Assigned(SourceWindows[i]) then + if Assigned(SourceWindows[i].FNotebook) then + if _HasSameDockSite(SourceWindows[i].FNotebook,TheDockSite) then + SourceWindows[i].FNotebook.CloseAllEmbedFormEditors; + +end; + +procedure TSourceEditorManager.StartExecuteUnDock(TheDockSite: TCustomForm; TheUnDockControl : TControl); + var i:integer; +Begin + if EnvironmentOptions.UseEmbeddedDesigner = False then + Exit; + if SourceWindowCount < 1 then + Exit; + for i := 0 to SourceWindowCount - 1 do + if Assigned(SourceWindows[i]) then + if Assigned(SourceWindows[i].FNotebook) then + if _HasSameDockSite(SourceWindows[i].FNotebook, TheDockSite) then + SourceWindows[i].FNotebook.CloseAllEmbedFormEditors; +end; + +procedure TSourceEditorManager.ScreenFormVisibleChanged(Sender: TObject; aForm: TCustomForm); +begin + // +end; + +procedure TSourceEditorManager.EmbeddedForm(Sender: TObject; aForm: TCustomForm); +var + xSE: TSourceEditor; + xPage: TEmbedTabSheet; + I: integer; + + procedure CheckSourceWin(aWin : TSourceNotebook); + begin + if aWin= nil then exit; + xPage:=nil; + xSE:=nil; + + if xSE = nil then xSE:=TSourceEditor(aWin.ActiveEditor); + if xSE = nil then xSE:=aWin.Last_Source_Editor; + if xSE = nil then Exit; + if sepuNewShared in xSE.FProjectFileUpdatesNeeded then + Exit; + + xPage:=xSE.FParentEmbedTabSheet; + if xPage=nil then + Exit; + xPage.FSynEditor:=xSE.FEditor; + TEmbedNotebook(aWin.FNotebook).EmbeddedForm(Sender,aForm,xPage); + if xSE.FSourceNoteBook <> nil then + xPage.OnToggleFormOrSource:=xSE.FSourceNoteBook.OnToggleFormOrSource; + end; + +begin + if EnvironmentOptions.UseEmbeddedDesigner = False then + Exit; + if Embed_IsDesignForm(aForm)=false then + Exit; + if SourceWindowCount < 1 then + Exit; + + for i:=0 to SourceWindowCount-1 do + CheckSourceWin(SourceWindows[i]); +end; + + initialization InternalInit;