Componentes.Terceros.DevExp.../official/x.30/ExpressWeb Framework/Sources/cxWebDsgnComponentDesigners.pas
2007-12-16 17:06:54 +00:00

1378 lines
38 KiB
ObjectPascal

{*******************************************************************}
{ }
{ ExpressWeb Framework by Developer Express }
{ Designer Module }
{ }
{ Copyright (c) 2000-2007 Developer Express Inc. }
{ ALL RIGHTS RESERVED }
{ }
{ The entire contents of this file is protected by U.S. and }
{ International Copyright Laws. Unauthorized reproduction, }
{ reverse-engineering, and distribution of all or any portion of }
{ the code contained in this file is strictly prohibited and may }
{ result in severe civil and criminal penalties and will be }
{ prosecuted to the maximum extent possible under the law. }
{ }
{ RESTRICTIONS }
{ }
{ THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES }
{ (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE }
{ SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS }
{ LICENSED TO DISTRIBUTE THE EXPRESSWEB FRAMEWORK AND ALL }
{ ACCOMPANYING VCL CLASSES AS PART OF AN EXECUTABLE WEB }
{ APPLICATION ONLY. }
{ }
{ THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED }
{ FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE }
{ COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE }
{ AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT }
{ AND PERMISSION FROM DEVELOPER EXPRESS INC. }
{ }
{ CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON }
{ ADDITIONAL RESTRICTIONS. }
{ }
{*******************************************************************}
unit cxWebDsgnComponentDesigners;
interface
{$I cxVer.inc}
uses
{$IFDEF VCL}
Windows, Messages, Graphics, Controls, Forms, ImgList, StdCtrls, Menus,
DesignWindows, ExtCtrls, VCLEditors, Registry, Clipbrd,
{$ELSE}
Qt, QGraphics, QControls, QForms, QImgList, QStdCtrls, QMenus,
QExtCtrls, CLXEditors, QClipbrd,
{$ENDIF}
SysUtils, Variants, Classes, DesignIntf, ComponentDesigner;
type
TcxWebDesignWindow = class(TForm, IUnknown, IDesignWindow, IDesignNotification,
IEditHandler, IActivatable)
private
FSelection: IDesignerSelections;
FOwner: TComponent;
FDesigner: IDesigner;
FComponentDesigner: IComponentDesigner;
FActive: Boolean;
procedure ComponentRead(Component: TComponent);
procedure ReaderSetName(Reader: TReader; Component: TComponent; var Name: string);
{$IFDEF VCL}
procedure WMActivate(var Msg: TWMActivate); message WM_ACTIVATE;
{$ENDIF}
protected
procedure Activated; dynamic;
procedure ActivateInspector(Ch: Char);
function ClipboardComponents: Boolean;
procedure CopyComponents(Root: TComponent;
const Components: IDesignerSelections);
procedure PasteComponents(AOwner, AParent: TComponent;
const Components: IDesignerSelections);
procedure SetSelection(const Components: IDesignerSelections);
function UniqueName(Component: TComponent): string; virtual; abstract;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
// IDesignEditQuery
function GetEditState: TEditState; virtual;
function EditAction(Action: TEditAction): Boolean; virtual;
// IDesignNotification
procedure ItemDeleted(const ADesigner: IDesigner; Item: TPersistent); virtual;
procedure ItemInserted(const ADesigner: IDesigner; Item: TPersistent); virtual;
procedure SelectionChanged(const ADesigner: IDesigner; const ASelection: IDesignerSelections); virtual;
procedure DesignerOpened(const Designer: IDesigner; AResurrecting: Boolean); virtual;
procedure DesignerClosed(const Designer: IDesigner; AGoingDormant: Boolean); virtual;
procedure ItemsModified(const Designer: IDesigner); virtual;
// IDesignWindowActions
procedure WindowHide; virtual;
procedure WindowShow; virtual;
// IActivatable
procedure IActivatable.Activate = ForceActive;
procedure ForceActive;
{IFNDEF VCL}
// IDesignerThreadAffinity
// function GetThreadAffinity: TThreadAffinity;
{ENDIF}
property Active: Boolean read FActive;
property Designer: IDesigner read FDesigner write FDesigner;
property ComponentDesigner: IComponentDesigner read FComponentDesigner;
end;
TcxWebBaseComponentDesigner = class(TcxWebDesignWindow)
private
FMainControl: TWinControl;
FComponent: TComponent;
FSaveCursor: TCursor;
FUpdateCount: Integer;
procedure SetComponent(const Value: TComponent);
procedure StartWait;
procedure StopWait;
{$IFDEF VCL}
procedure WMNCCreate(var Message: TWMNCCreate); message WM_NCCREATE;
procedure WMNCDestroy(var message: TWMNCCreate); message WM_NCDESTROY;
procedure WMGetMinMaxInfo(var message: TWMGetMinMaxInfo); message WM_GETMINMAXINFO;
{$ENDIF}
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormResize(Sender: TObject);
procedure pmColumnsPopup(Sender: TObject);
protected
pnlButtons: TPanel;
MenuImages: TImageList;
pmMain: TPopupMenu;
miEdit: TMenuItem;
miDelete: TMenuItem;
miShowButtons: TMenuItem;
miSelectAll: TMenuItem;
miCut: TMenuItem;
miCopy: TMenuItem;
miPaste: TMenuItem;
{$IFDEF VCL}
procedure CreateParams(var Params: TCreateParams); override;
{$ENDIF}
procedure Activated; override;
procedure CreateComponents; virtual;
function CreateMainControl: TWinControl; virtual; abstract;
procedure UpdateHScrollBar; virtual;
function CreateButton(ALeft, ATop: Integer; ACaption: string; AOnClick: TNotifyEvent): TButton;
function CreateMenuItem(ACaption: string; AShortCut: TShortCut; AImageIndex: Integer;
AOnClick: TNotifyEvent; AParent: TMenuItem = nil): TMenuItem;
procedure AddMenuSeparator(AParent: TMenuItem = nil);
procedure CreateEditMenuItems;
procedure CreateShowButtonsMenuItem;
procedure RestoreLayout; virtual;
procedure SaveLayout; virtual;
procedure HandleException;
function RegistryPath: string;
function GetCaptionFormat: string; virtual; abstract;
procedure UpdateCaption;
procedure RefreshMainControl; virtual;
procedure InternalUpdateItem(AComponent: TComponent); virtual; abstract;
procedure UpdateItem(AComponent: TComponent);
procedure UpdateMenuState; virtual;
procedure UpdateControlsState; virtual;
procedure UpdateSelections(const ASelections: IDesignerSelections);
procedure BeginUpdate; virtual;
procedure EndUpdate; virtual;
procedure CancelUpdate; virtual;
function CanAdd: Boolean;
function CanCopy: Boolean;
function CanCut: Boolean;
function CanDelete: Boolean;
function CanPaste: Boolean;
function CanSelectAll: Boolean;
procedure Copy;
procedure Cut;
procedure Delete;
procedure Paste;
procedure Select(AItem: TPersistent; AddToSelection: Boolean);
procedure SelectAll;
procedure SelectComponent;
procedure GetSelections(const ASelections: IDesignerSelections);
procedure RemoveChildrenBeforeDelete(ASelections, ADeleteList: IDesignerSelections); virtual;
function GetComponentCount: Integer; virtual; abstract;
function GetComponent(Index: Integer): TComponent; virtual; abstract;
function GetComponentIndex(AComponent: TComponent): Integer; virtual; abstract;
procedure SetComponentIndex(AComponent: TComponent; AValue: Integer); virtual; abstract;
function SelectedCount: Integer; virtual; abstract;
function GetSelected(Index: Integer): Boolean; virtual; abstract;
procedure SetSelected(Index: Integer; const Value: Boolean); virtual; abstract;
function CurrentComponent: TComponent; virtual; abstract;
procedure DeleteItem(AComponent: TComponent); virtual; abstract;
procedure BeginUpdateComponent;
procedure EndUpdateComponent;
procedure CancelUpdateComponent;
procedure SelectAllClick(Sender: TObject);
procedure ButtonBarClick(Sender: TObject);
property MainControl: TWinControl read FMainControl;
property Selected[Index: Integer]: Boolean read GetSelected write SetSelected;
property UpdateCount: Integer read FUpdateCount;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
{ IDesignEditQuery }
function EditAction(Action: TEditAction): Boolean; override;
function GetEditState: TEditState; override;
{ IDesignNotification }
procedure ItemDeleted(const ADesigner: IDesigner; AComponent: TPersistent); override;
procedure ItemsModified(const ADesigner: IDesigner); override;
procedure SelectionChanged(const ADesigner: IDesigner; const ASelection: IDesignerSelections); override;
property Component: TComponent read FComponent write SetComponent;
end;
TcxWebListComponentDesigner = class(TcxWebBaseComponentDesigner)
private
FLastDragIndex: Integer;
procedure ListBoxClick(Sender: TObject);
procedure ListBoxDblClick(Sender: TObject);
procedure ListBoxKeyPress(Sender: TObject; var Key: Char);
procedure ListBoxEndDrag(Sender, Target: TObject; X, Y: Integer);
procedure ListBoxDragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
procedure ListBoxDragDrop(Sender, Source: TObject; X, Y: Integer);
procedure ListBoxStartDrag(Sender: TObject;
var DragObject: TDragObject);
protected
function CreateMainControl: TWinControl; override;
function ListBox: TListBox;
function IndexOf(AComponent: TComponent): Integer;
function SelectedCount: Integer; override;
function GetSelected(Index: Integer): Boolean; override;
procedure SetSelected(Index: Integer; const Value: Boolean); override;
function CurrentComponent: TComponent; override;
procedure InternalUpdateItem(AComponent: TComponent); override;
procedure DeleteItem(AComponent: TComponent); override;
procedure RefreshMainControl; override;
procedure BeginUpdate; override;
procedure EndUpdate; override;
procedure CancelUpdate; override;
procedure RestoreLayout; override;
procedure UpdateHScrollBar; override;
function CanMoveDown: Boolean;
function CanMoveUp: Boolean;
procedure DrawDragRect;
procedure MoveSelection(ADelta: Integer);
end;
implementation
uses ToolsAPI, TypInfo, DesignEditors,
cxWebDsgnUtils, cxWebDsgnConsts, cxWebControls, cxwebDsgnStrs;
{$R cxWebDsgnCompEditors.res}
{TcxWebDesignWindow}
constructor TcxWebDesignWindow.Create(AOwner: TComponent);
begin
inherited CreateNew(AOwner);
FComponentDesigner := ActiveDesigner;
RegisterDesignNotification(Self);
SetBounds(200, ComponentDesigner.Environment.GetMainWindowSize.Bottom + 2, Width, Height);
end;
destructor TcxWebDesignWindow.Destroy;
begin
UnregisterDesignNotification(Self);
inherited Destroy;
end;
procedure TcxWebDesignWindow.Activated;
begin
end;
{$IFDEF VCL}
procedure TcxWebDesignWindow.WMActivate(var Msg: TWMActivate);
begin
inherited;
FActive := Msg.Active <> 0;
if FActive then
Activated;
end;
{$ENDIF}
procedure TcxWebDesignWindow.ActivateInspector(Ch: Char);
begin
ComponentDesigner.Environment.ModalEdit(Ch, Self);
end;
function TcxWebDesignWindow.ClipboardComponents: Boolean;
begin
try
{$IFDEF VCL}
Result := Clipboard.HasFormat(CF_COMPONENTS) or
(Clipboard.HasFormat(CF_TEXT) and PossibleStream(Clipboard.AsText));
{$ELSE}
Result := PossibleStream(Clipboard.AsText);
{$ENDIF}
except
Result := False;
end;
end;
procedure TcxWebDesignWindow.CopyComponents(Root: TComponent;
const Components: IDesignerSelections);
var
S: TMemoryStream;
W: TWriter;
I: Integer;
begin
S := TMemoryStream.Create;
try
W := TWriter.Create(S, 1024);
try
W.Root := Root;
for I := 0 to Components.Count - 1 do
begin
W.WriteSignature;
W.WriteComponent(TComponent(Components[I]));
end;
W.WriteListEnd;
finally
W.Free;
end;
CopyStreamToClipboard(S);
finally
S.Free;
end;
end;
function TcxWebDesignWindow.GetEditState: TEditState;
begin
Result := [];
end;
function TcxWebDesignWindow.EditAction(Action: TEditAction): Boolean;
begin
Result := False;
end;
procedure TcxWebDesignWindow.ForceActive;
begin
{$IFDEF VCL}
SetActiveWindow(Handle);
{$ELSE}
QWidget_setActiveWindow(Handle);
{$ENDIF}
end;
procedure TcxWebDesignWindow.WindowHide;
begin
if Visible then
{$IFDEF VCL}
ShowWindow(Handle, Integer(False));
{$ELSE}
QWidget_hide(Handle);
{$ENDIF}
end;
procedure TcxWebDesignWindow.WindowShow;
begin
if Visible then
{$IFDEF VCL}
ShowWindow(Handle, Integer(True));
{$ELSE}
QWidget_show(Handle);
{$ENDIF}
end;
procedure TcxWebDesignWindow.ComponentRead(Component: TComponent);
begin
FSelection.Add(Component);
end;
procedure TcxWebDesignWindow.ReaderSetName(Reader: TReader; Component: TComponent;
var Name: string);
begin
if (Reader.Root = FOwner) and (FOwner.FindComponent(Name) <> nil) then
Name := UniqueName(Component);
end;
procedure TcxWebDesignWindow.PasteComponents(AOwner, AParent: TComponent;
const Components: IDesignerSelections);
var
S: TStream;
R: TReader;
begin
S := GetClipboardStream;
try
R := TReader.Create(S, 1024);
try
R.OnSetName := ReaderSetName;
FOwner := AOwner;
FSelection := Components;
R.ReadComponents(AOwner, AParent, ComponentRead);
finally
R.Free;
end;
finally
S.Free;
end;
end;
procedure TcxWebDesignWindow.SelectionChanged(const ADesigner: IDesigner;
const ASelection: IDesignerSelections);
begin
end;
procedure TcxWebDesignWindow.SetSelection(const Components: IDesignerSelections);
begin
ComponentDesigner.SetSelection(Designer, Self, Components);
end;
procedure TcxWebDesignWindow.ItemDeleted(const ADesigner: IDesigner; Item: TPersistent);
begin
end;
procedure TcxWebDesignWindow.ItemInserted(const ADesigner: IDesigner; Item: TPersistent);
begin
end;
procedure TcxWebDesignWindow.DesignerClosed(const Designer: IDesigner; AGoingDormant: Boolean);
begin
if FDesigner = Designer then
begin
FDesigner := nil;
FComponentDesigner := nil;
end;
end;
procedure TcxWebDesignWindow.DesignerOpened(const Designer: IDesigner; AResurrecting: Boolean);
begin
FDesigner := Designer;
FComponentDesigner := ActiveDesigner;
end;
procedure TcxWebDesignWindow.ItemsModified(const Designer: IDesigner);
begin
end;
{$IFNDEF VCL}
//function TcxWebDesignWindow.GetThreadAffinity: TThreadAffinity;
//begin
// Result := taQt;
//end;
{$ENDIF}
{ TcxWebBaseComponentDesigner }
constructor TcxWebBaseComponentDesigner.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
CreateComponents;
RestoreLayout;
end;
destructor TcxWebBaseComponentDesigner.Destroy;
begin
SaveLayout;
inherited Destroy;
end;
procedure TcxWebBaseComponentDesigner.SetComponent(const Value: TComponent);
begin
if FComponent <> Value then
begin
FComponent := Value;
UpdateCaption;
RefreshMainControl;
end;
end;
procedure TcxWebBaseComponentDesigner.StartWait;
begin
FSaveCursor := Screen.Cursor;
Screen.Cursor := crHourGlass;
end;
procedure TcxWebBaseComponentDesigner.StopWait;
begin
Screen.Cursor := FSaveCursor;
end;
{$IFDEF VCL}
procedure TcxWebBaseComponentDesigner.WMNCCreate(var Message: TWMNCCreate);
var
SysMenu: HMENU;
Info: TMenuItemInfo;
S: array[0..31] of Char;
ItemExist: Boolean;
begin
SysMenu := GetSystemMenu(Handle, False);
Info.cbSize := SizeOf(Info) - SizeOf(HBITMAP);
Info.fMask := MIIM_ID or MIIM_TYPE;
Info.dwTypeData := @S[0];
Info.cch := 32;
ItemExist := GetMenuItemInfo(SysMenu, SC_SIZE, False, Info);
inherited;
if ItemExist then
InsertMenuItem(SysMenu, 0, True, Info);
end;
procedure TcxWebBaseComponentDesigner.WMNCDestroy(var message: TWMNCCreate);
begin
GetSystemMenu(Handle, True);
inherited;
end;
procedure TcxWebBaseComponentDesigner.WMGetMinMaxInfo(var message: TWMGetMinMaxInfo);
begin
inherited;
message.MinMaxInfo^.ptMinTrackSize := Point(240, 240);
end;
{$ENDIF}
procedure TcxWebBaseComponentDesigner.pmColumnsPopup(Sender: TObject);
begin
UpdateMenuState;
end;
procedure TcxWebBaseComponentDesigner.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
if not (csDestroying in Component.ComponentState) then
SelectComponent;
Action := caFree;
end;
procedure TcxWebBaseComponentDesigner.FormResize(Sender: TObject);
begin
UpdateHScrollBar;
end;
{$IFDEF VCL}
procedure TcxWebBaseComponentDesigner.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
with Params do
Style := Style or WS_THICKFRAME;
end;
{$ENDIF}
procedure TcxWebBaseComponentDesigner.Activated;
var
Selections: IDesignerSelections;
begin
inherited;
Selections := CreateSelectionList;
Designer.GetSelections(Selections);
UpdateSelections(Selections);
end;
procedure TcxWebBaseComponentDesigner.CreateComponents;
begin
BorderIcons := [biSystemMenu];
BorderStyle := {$IFDEF VCL}bsDialog{$ELSE}fbsDialog{$ENDIF};
Position := poScreenCenter;
OnClose := FormClose;
OnResize := FormResize;
menuImages := TImageList.Create(self);
{$IFDEF VCL}
menuImages.ResourceLoad(rtBitmap, 'CXWEBDSGNCOMPONENTEDITORSIMAGES', clFuchsia);
{$ELSE}
ImageListResourceLoad(HInstance, menuImages, 'CXWEBDSGNCOMPONENTEDITORSIMAGES', clFuchsia);
{$ENDIF}
ClientHeight := 278;
ClientWidth := 328;
pmMain := TPopupMenu.Create(self);
pmMain.Images := menuImages;
pmMain.OnPopup := pmColumnsPopup;
FMainControl := CreateMainControl;
MainControl.Parent := self;
MainControl.Align := alClient;
pnlButtons := TPanel.Create(self);
pnlButtons.Width := 124;
pnlButtons.Parent := self;
pnlButtons.Align := alRight;
pnlButtons.BevelOuter := bvNone;
ActiveControl := MainControl;
end;
procedure TcxWebBaseComponentDesigner.UpdateHScrollBar;
begin
end;
function TcxWebBaseComponentDesigner.CreateButton(ALeft, ATop: Integer;
ACaption: string; AOnClick: TNotifyEvent): TButton;
begin
Result := TButton.Create(self);
Result.Parent := pnlButtons;
Result.SetBounds(ALeft, ATop, 110, 24);
Result.Caption := ACaption;
Result.onClick := AOnClick;
end;
function TcxWebBaseComponentDesigner.CreateMenuItem(ACaption: string;
AShortCut: TShortCut; AImageIndex: Integer;
AOnClick: TNotifyEvent; AParent: TMenuItem = nil): TMenuItem;
begin
Result := TMenuItem.Create(self);
if AParent = nil then
AParent := pmMain.Items;
AParent.Add(Result);
Result.Caption := ACaption;
Result.ShortCut := AShortCut;
Result.ImageIndex := AImageIndex;
Result.OnClick := AOnClick;
end;
procedure TcxWebBaseComponentDesigner.AddMenuSeparator(AParent: TMenuItem = nil);
begin
CreateMenuItem('-', 0, -1, nil, AParent);
end;
procedure TcxWebBaseComponentDesigner.CreateEditMenuItems;
begin
miEdit := CreateMenuItem(scxEdit, 0, -1, nil);
miCut := CreateMenuItem(scxCut, ShortCut(Ord('X'), [ssCtrl]), 1, SelectAllClick, miEdit);
miCopy := CreateMenuItem(scxCopy, ShortCut(Ord('C'), [ssCtrl]), 2, SelectAllClick, miEdit);
miPaste := CreateMenuItem(scxPaste, ShortCut(Ord('V'), [ssCtrl]), 3, SelectAllClick, miEdit);
miDelete := CreateMenuItem(scxDelete, ShortCut({$IFDEF VCL}VK_DELETE{$ELSE}KEY_DELETE{$ENDIF}, []), 4, SelectAllClick, miEdit);
AddMenuSeparator(miEdit);
miSelectAll := CreateMenuItem(scxSelectAll, ShortCut(Ord('A'), [ssCtrl]), -1, SelectAllClick, miEdit);
miCut.Tag := Integer(eaCut);
miCopy.Tag := Integer(eaCopy);
miPaste.Tag := Integer(eaPaste);
miDelete.Tag := Integer(eaDelete);
miSelectAll.Tag := Integer(eaSelectAll);
end;
procedure TcxWebBaseComponentDesigner.CreateShowButtonsMenuItem;
begin
miShowButtons := CreateMenuItem(cxWebCompEditorButtonBar, 0, -1, ButtonBarClick);
miShowButtons.Checked := True;
end;
procedure TcxWebBaseComponentDesigner.RestoreLayout;
begin
{$IFDEF VCL}
with TRegistry.Create do
try
try
if OpenKey(RegistryPath, False) then
begin
if ValueExists(scxButtonBar) then
pnlButtons.Visible := ReadBool(scxButtonBar);
if ValueExists(scxWidth) then
Width := ReadInteger(scxWidth);
if ValueExists(scxHeight) then
Height := ReadInteger(scxHeight);
end;
except
HandleException;
end;
finally
Free;
end;
{$ELSE}
//TODO LINUX_NOT_IMPL
{$ENDIF}
end;
procedure TcxWebBaseComponentDesigner.SaveLayout;
begin
{$IFDEF VCL}
with TRegistry.Create do
try
try
if OpenKey(RegistryPath, True) then
begin
WriteBool(scxButtonBar, pnlButtons.Visible);
WriteInteger(scxWidth, Width);
WriteInteger(scxHeight, Height);
end;
except
HandleException;
end;
finally
Free;
end;
{$ELSE}
//TODO LINUX_NOT_IMPL
{$ENDIF}
end;
procedure TcxWebBaseComponentDesigner.HandleException;
begin
Abort;
end;
function TcxWebBaseComponentDesigner.RegistryPath: string;
var
Services: IOTAServices50;
begin
if Supports(BorlandIDEServices, IOTAServices50, Services) then
Result :=
Services.GetBaseRegistryKey + '\' + scxExpressWebObjectsFormLayoutsRegPath + '\' + DropT(ClassName)
else
Result := '';
end;
procedure TcxWebBaseComponentDesigner.UpdateCaption;
var
NewCaption: string;
begin
if (Component <> nil) and (Component.Owner <> nil) then
NewCaption :=
Format(GetCaptionFormat, [Component.Owner.Name, DotSep, Component.Name]);
if Caption <> NewCaption then
Caption := NewCaption;
end;
procedure TcxWebBaseComponentDesigner.RefreshMainControl;
begin
end;
procedure TcxWebBaseComponentDesigner.UpdateItem(AComponent: TComponent);
begin
if UpdateCount = 0 then exit;
if AComponent <> nil then
InternalUpdateItem(AComponent)
else RefreshMainControl;
UpdateControlsState;
end;
procedure TcxWebBaseComponentDesigner.UpdateMenuState;
begin
miCut.Enabled := CanCut;
miCopy.Enabled := CanCopy;
miPaste.Enabled := CanPaste;
miDelete.Enabled := CanDelete;
miSelectAll.Enabled := CanSelectAll;
miShowButtons.Checked := pnlButtons.Visible;
end;
procedure TcxWebBaseComponentDesigner.UpdateControlsState;
begin
end;
procedure TcxWebBaseComponentDesigner.UpdateSelections(const ASelections: IDesignerSelections);
function InSelection(AColumn: TComponent): Boolean;
var
I: Integer;
begin
for I := 0 to ASelections.Count - 1 do
if AColumn = ASelections[I] then
begin
Result := True;
Exit;
end;
Result := False;
end;
var
I: Integer;
begin
if (ASelections = nil) or (Component = nil) or (csDestroying in Component.ComponentState)
and (FUpdateCount <> 0) then
Exit;
for I := 0 to GetComponentCount - 1 do
if Selected[I] xor InSelection(GetComponent(I)) then
Selected[I] := not Selected[I];
UpdateControlsState;
end;
procedure TcxWebBaseComponentDesigner.BeginUpdate;
begin
BeginUpdateComponent;
Inc(FUpdateCount);
end;
procedure TcxWebBaseComponentDesigner.EndUpdate;
begin
EndUpdateComponent;
if FUpdateCount <> 0 then
begin
Dec(FUpdateCount);
if FUpdateCount = 0 then
UpdateItem(nil);
end;
end;
procedure TcxWebBaseComponentDesigner.CancelUpdate;
begin
CancelUpdate;
if FUpdateCount <> 0 then
Dec(FUpdateCount);
end;
type
TcxWebControlAccess = class(TcxWebControl);
procedure TcxWebBaseComponentDesigner.BeginUpdateComponent;
begin
if (Component is TcxWebControl) then
TcxWebControlAccess(Component).BeginUpdateDesignerContext;
end;
procedure TcxWebBaseComponentDesigner.EndUpdateComponent;
begin
if (Component is TcxWebControl) then
TcxWebControlAccess(Component).EndUpdateDesignerContext;
end;
procedure TcxWebBaseComponentDesigner.CancelUpdateComponent;
begin
if (Component is TcxWebControl) then
TcxWebControlAccess(Component).CancelUpdateDesignerContext;
end;
procedure TcxWebBaseComponentDesigner.SelectAllClick(Sender: TObject);
begin
BeginUpdateComponent;
EditAction(TEditAction(TComponent(Sender).Tag));
EndUpdateComponent;
end;
procedure TcxWebBaseComponentDesigner.ButtonBarClick(Sender: TObject);
begin
pnlButtons.Visible := not pnlButtons.Visible;
UpdateHScrollBar;
end;
function TcxWebBaseComponentDesigner.CanAdd: Boolean;
begin
Result := not ((Component <> nil) and (Component.Owner <> nil) and
(csInline in Component.Owner.ComponentState));
end;
function TcxWebBaseComponentDesigner.CanCopy: Boolean;
begin
Result := SelectedCount <> 0;
end;
function TcxWebBaseComponentDesigner.CanCut: Boolean;
begin
Result := CanCopy and CanDelete;
end;
function TcxWebBaseComponentDesigner.CanDelete: Boolean;
var
I: Integer;
begin
Result := SelectedCount <> 0;
if Result then
for I := 0 to GetComponentCount - 1 do
if Selected[I] and (csAncestor in GetComponent(I).ComponentState) then
begin
Result := False;
Exit;
end;
end;
function TcxWebBaseComponentDesigner.CanPaste: Boolean;
begin
Result := CanAdd and ClipboardComponents and Designer.CanPaste;
end;
function TcxWebBaseComponentDesigner.CanSelectAll: Boolean;
begin
Result := (GetComponentCount > 0) and (GetComponentCount <> SelectedCount);
end;
procedure TcxWebBaseComponentDesigner.Copy;
var
Components: IDesignerSelections;
begin
Components := CreateSelectionList;
GetSelections(Components);
CopyComponents(Component.Owner, Components);
UpdateHScrollBar;
end;
procedure TcxWebBaseComponentDesigner.Cut;
begin
Copy;
Delete;
end;
procedure TcxWebBaseComponentDesigner.RemoveChildrenBeforeDelete(
ASelections, ADeleteList: IDesignerSelections);
var
I: Integer;
begin
for I := 0 to ASelections.Count - 1 do
ADeleteList.Add(ASelections.Items[I]);
end;
procedure TcxWebBaseComponentDesigner.Delete;
var
Selections, ADeleteList: IDesignerSelections;
I: Integer;
begin
StartWait;
try
Selections := CreateSelectionList;
ADeleteList := TDesignerSelections.Create;
GetSelections(Selections);
RemoveChildrenBeforeDelete(Selections, ADeleteList);
for I := 0 to ADeleteList.Count - 1 do
ADeleteList[I].Free;
finally
StopWait;
end;
end;
procedure TcxWebBaseComponentDesigner.Paste;
var
AComponents: IDesignerSelections;
I: Integer;
begin
AComponents := CreateSelectionList;
StartWait;
try
BeginUpdate;
try
PasteComponents(Component.Owner, Component, AComponents);
RefreshMainControl;
for I := GetComponentCount - 1 downto GetComponentCount - AComponents.Count do
Selected[I] := True;
Designer.SetSelections(AComponents);
finally
EndUpdate;
end;
finally
StopWait;
end;
UpdateHScrollBar;
end;
procedure TcxWebBaseComponentDesigner.Select(AItem: TPersistent; AddToSelection: Boolean);
var
Selections: IDesignerSelections;
begin
Selections := CreateSelectionList;
if AddToSelection then
Designer.GetSelections(Selections);
Selections.Add(AItem);
Designer.SetSelections(Selections);
end;
procedure TcxWebBaseComponentDesigner.SelectAll;
var
Selections: IDesignerSelections;
I: Integer;
begin
Selections := CreateSelectionList;
for I := 0 to GetComponentCount - 1 do
Selections.Add(GetComponent(I));
Designer.SetSelections(Selections);
end;
procedure TcxWebBaseComponentDesigner.SelectComponent;
begin
Select(Component, False);
end;
procedure TcxWebBaseComponentDesigner.GetSelections(const ASelections: IDesignerSelections);
var
I: Integer;
begin
for I := 0 to GetComponentCount - 1 do
if Selected[I] then
ASelections.Add(GetComponent(I));
if ASelections.Count = 0 then
ASelections.Add(Component);
end;
function TcxWebBaseComponentDesigner.EditAction(
Action: TEditAction): Boolean;
begin
Result := True;
case Action of
eaCut: Cut;
eaCopy: Copy;
eaPaste: Paste;
eaDelete: Delete;
eaSelectAll: SelectAll;
end;
end;
function TcxWebBaseComponentDesigner.GetEditState: TEditState;
begin
Result := [];
if CanCut then
Result := Result + [esCanCut];
if CanCopy then
Result := Result + [esCanCopy];
if CanPaste then
Result := Result + [esCanPaste];
if CanDelete then
Result := Result + [esCanDelete];
if CanSelectAll then
Result := Result + [esCanSelectAll];
end;
procedure TcxWebBaseComponentDesigner.ItemDeleted(const ADesigner: IDesigner;
AComponent: TPersistent);
begin
inherited;
if (ADesigner = Designer) and (AComponent is TComponent) and
(Component <> nil) and not (csDestroying in Component.ComponentState) then
DeleteItem(TComponent(AComponent));
end;
procedure TcxWebBaseComponentDesigner.ItemsModified(const ADesigner: IDesigner);
begin
inherited;
if (ADesigner = Designer) and (UpdateCount = 0) and
(Component <> nil) and not (csDestroying in Component.ComponentState) then
begin
UpdateCaption;
RefreshMainControl;
end;
end;
procedure TcxWebBaseComponentDesigner.SelectionChanged(const ADesigner: IDesigner;
const ASelection: IDesignerSelections);
begin
inherited;
if (ADesigner = Designer) and (Component <> nil) and
not (csDestroying in Component.ComponentState) then
UpdateSelections(ASelection);
end;
{ TcxWebListComponentDesigner }
function TcxWebListComponentDesigner.CreateMainControl: TWinControl;
begin
Result := TListBox.Create(self);
with TListBox(Result) do
begin
{$IFDEF VCL} //TODO: CLX
DragMode := dmAutomatic;
{$ENDIF}
MultiSelect := True;
PopupMenu := pmMain;
OnClick := ListBoxClick;
OnDblClick := ListBoxDblClick;
OnDragDrop := ListBoxDragDrop;
OnDragOver := ListBoxDragOver;
OnEndDrag := ListBoxEndDrag;
OnKeyPress := ListBoxKeyPress;
OnStartDrag := ListBoxStartDrag;
end;
end;
function TcxWebListComponentDesigner.ListBox: TListBox;
begin
Result := MainControl as TListBox;
end;
function TcxWebListComponentDesigner.IndexOf(AComponent: TComponent): Integer;
begin
Result := ListBox.Items.IndexOfObject(AComponent);
end;
function TcxWebListComponentDesigner.SelectedCount: Integer;
begin
Result := ListBox.SelCount;
end;
function TcxWebListComponentDesigner.GetSelected(Index: Integer): Boolean;
begin
if Index < ListBox.Items.Count then
Result := ListBox.Selected[Index]
else Result := False;
end;
procedure TcxWebListComponentDesigner.SetSelected(Index: Integer; const Value: Boolean);
begin
ListBox.Selected[Index] := Value;
end;
function TcxWebListComponentDesigner.CurrentComponent: TComponent;
begin
if GetComponentCount <> 0 then
Result := GetComponent(ListBox.ItemIndex)
else
Result := nil;
end;
procedure TcxWebListComponentDesigner.InternalUpdateItem(AComponent: TComponent);
var
AIndex: Integer;
begin
AIndex := IndexOf(AComponent);
if AIndex <> -1 then
begin
ListBox.Items[AIndex] := AComponent.Name;
UpdateHScrollBar;
end
end;
procedure TcxWebListComponentDesigner.DeleteItem(AComponent: TComponent);
var
Index, ItemIndex: Integer;
begin
Index := IndexOf(AComponent);
if Index <> -1 then
begin
ItemIndex := ListBox.ItemIndex;
ListBox.Items.Delete(Index);
if ItemIndex > GetComponentCount - 1 then
ItemIndex := GetComponentCount - 1;
if ItemIndex <> -1 then
Select(GetComponent(ItemIndex), False)
else
SelectComponent;
UpdateHScrollBar;
end;
end;
procedure TcxWebListComponentDesigner.RefreshMainControl;
var
Selections: IDesignerSelections;
I, AIndex: Integer;
begin
ListBox.Items.BeginUpdate;
try
Selections := CreateSelectionList;
Designer.GetSelections(Selections);
ListBox.Items.Clear;
if Component = nil then Exit;
for I := 0 to GetComponentCount - 1 do
if GetComponent(I).GetParentComponent = Component then
ListBox.Items.AddObject(GetComponent(I).Name, GetComponent(I));
for I := 0 to Selections.Count - 1 do
if (Selections[I] is TComponent) and
(TComponent(Selections[I]).GetParentComponent = Component) then
begin
AIndex := IndexOf(Selections[I] as TComponent);
if AIndex <> -1 then
Selected[AIndex] := True;
end;
finally
ListBox.Items.EndUpdate;
end;
end;
procedure TcxWebListComponentDesigner.RestoreLayout;
begin
inherited RestoreLayout;
UpdateHScrollBar;
end;
procedure TcxWebListComponentDesigner.BeginUpdate;
begin
inherited BeginUpdate;
if ListBox <> nil then
ListBox.Items.BeginUpdate;
end;
procedure TcxWebListComponentDesigner.EndUpdate;
begin
inherited EndUpdate;
if ListBox <> nil then
ListBox.Items.EndUpdate;
if FUpdateCount = 0 then
UpdateItem(nil);
end;
procedure TcxWebListComponentDesigner.CancelUpdate;
begin
inherited CancelUpdate;
if ListBox <> nil then
ListBox.Items.EndUpdate;
end;
procedure TcxWebListComponentDesigner.UpdateHScrollBar;
var
I, NewWidth, CurrentWidth: Integer;
begin
if ListBox = nil then exit;
NewWidth := 0;
with ListBox do
begin
for I := 0 to Items.Count - 1 do
begin
CurrentWidth := 2 + Canvas.TextWidth(Items[I]) + 1;
if CurrentWidth > NewWidth then
NewWidth := CurrentWidth;
end;
{$IFDEF VCL}
SendMessage(Handle, LB_SETHORIZONTALEXTENT, NewWidth, 0);
{$ELSE}
//TODO LINUX_NOT_IMPL
{$ENDIF}
end;
end;
function TcxWebListComponentDesigner.CanMoveDown: Boolean;
var
I, Counter: Integer;
begin
Counter := 0;
for I := GetComponentCount - 1 downto 0 do
begin
if not Selected[I] then
begin
Result := Counter < SelectedCount;
Exit;
end;
Inc(Counter);
end;
Result := False;
end;
function TcxWebListComponentDesigner.CanMoveUp: Boolean;
var
I: Integer;
begin
for I := 0 to GetComponentCount - 1 do
if not Selected[I] then
begin
Result := I < SelectedCount;
Exit;
end;
Result := False;
end;
procedure TcxWebListComponentDesigner.DrawDragRect;
begin
with ListBox do
if (FLastDragIndex <> -1) and (FLastDragIndex <> ItemIndex) then
Canvas.DrawFocusRect(ItemRect(FLastDragIndex));
end;
procedure TcxWebListComponentDesigner.MoveSelection(ADelta: Integer);
procedure MoveDown(ADelta: Integer);
var
I, Index: Integer;
begin
for I := GetComponentCount - 1 downto 0 do
if Selected[I] then
begin
Index := GetComponentIndex(GetComponent(I));
Inc(Index, ADelta);
if Index > GetComponentCount - 1 then
Index := GetComponentCount - 1;
while (Index < GetComponentCount) and Selected[Index] do
Inc(Index);
SetComponentIndex(GetComponent(I), Index);
end;
end;
procedure MoveUp(ADelta: Integer);
var
I, Index: Integer;
begin
for I := 0 to GetComponentCount - 1 do
if Selected[I] then
begin
Index := GetComponentIndex(GetComponent(I));
Inc(Index, ADelta);
if Index < 0 then
Index := 0;
while (Index > -1) and Selected[Index] do
Dec(Index);
SetComponentIndex(GetComponent(I), Index);
end;
end;
begin
BeginUpdate;
try
if ADelta > 0 then
MoveDown(ADelta)
else
MoveUp(ADelta);
finally
EndUpdate;
end;
end;
procedure TcxWebListComponentDesigner.ListBoxClick(Sender: TObject);
var
Selections: IDesignerSelections;
begin
Selections := CreateSelectionList;
GetSelections(Selections);
Designer.SetSelections(Selections);
end;
procedure TcxWebListComponentDesigner.ListBoxDblClick(Sender: TObject);
begin
Designer.Edit(CurrentComponent);
end;
procedure TcxWebListComponentDesigner.ListBoxStartDrag(Sender: TObject;
var DragObject: TDragObject);
begin
FLastDragIndex := -1;
end;
procedure TcxWebListComponentDesigner.ListBoxEndDrag(Sender,
Target: TObject; X, Y: Integer);
begin
DrawDragRect;
end;
procedure TcxWebListComponentDesigner.ListBoxDragOver(Sender,
Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
var
Index: Integer;
begin
Accept := Sender = Source;
if Accept then
with TListBox(Sender) do
begin
Index := ItemAtPos(Point(X, Y), True);
Accept := (Index <> -1) and (FLastDragIndex <> ItemIndex);
DrawDragRect;
FLastDragIndex := Index;
DrawDragRect;
end;
end;
procedure TcxWebListComponentDesigner.ListBoxDragDrop(Sender,
Source: TObject; X, Y: Integer);
begin
MoveSelection(FLastDragIndex - TListBox(Sender).ItemIndex);
end;
procedure TcxWebListComponentDesigner.ListBoxKeyPress(Sender: TObject;
var Key: Char);
begin
case Key of
#13, #33..#126:
begin
if Key = #13 then Key := #0;
ActivateInspector(Key);
Key := #0;
end;
#27:
begin
SelectComponent;
Key := #0;
end;
end;
end;
end.