git-svn-id: https://192.168.0.254/svn/Componentes.Terceros.DevExpressVCL@38 05c56307-c608-d34a-929d-697000501d7a
1392 lines
43 KiB
ObjectPascal
1392 lines
43 KiB
ObjectPascal
|
|
{********************************************************************}
|
|
{ }
|
|
{ Developer Express Visual Component Library }
|
|
{ ExpressLayoutControl customize form }
|
|
{ }
|
|
{ Copyright (c) 2001-2009 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 EXPRESSLAYOUTCONTROL AND ALL }
|
|
{ ACCOMPANYING VCL CONTROLS AS PART OF AN EXECUTABLE PROGRAM }
|
|
{ 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 dxLayoutCustomizeForm;
|
|
|
|
{$I cxVer.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
Windows, Messages, SysUtils, Classes, Graphics, Contnrs, Controls, Forms, Dialogs,
|
|
ComCtrls, ActnList, Menus, ToolWin, StdCtrls, ImgList, cxClasses,
|
|
dxLayoutLookAndFeels, cxControls, cxGraphics, dxLayoutControl;
|
|
|
|
type
|
|
TdxLayoutControlCustomizeFormClass = class of TdxLayoutControlCustomizeForm;
|
|
|
|
TdxLayoutControlCustomizeForm = class(TForm)
|
|
alMain: TActionList;
|
|
acAddGroup: TAction;
|
|
acAddItem: TAction;
|
|
acClose: TAction;
|
|
acTreeViewExpandAll: TAction;
|
|
acTreeViewCollapseAll: TAction;
|
|
acTreeViewItemsDelete: TAction;
|
|
acAlignLeftSide: TAction;
|
|
acAlignRightSide: TAction;
|
|
acAlignTopSide: TAction;
|
|
acAlignBottomSide: TAction;
|
|
acAlignNone: TAction;
|
|
ilActions: TcxImageList;
|
|
ilItems: TcxImageList;
|
|
tlbAvailableItems: TToolBar;
|
|
tbAddGroup: TToolButton;
|
|
tbAddItem: TToolButton;
|
|
tbListBoxItemDelete: TToolButton;
|
|
ToolButton1: TToolButton;
|
|
tbAlignBy: TToolButton;
|
|
tbTreeViewExpandAll: TToolButton;
|
|
tbTreeViewCollapseAll: TToolButton;
|
|
tbTreeViewItemDelete: TToolButton;
|
|
ToolButton5: TToolButton;
|
|
tvItems: TTreeView;
|
|
pmTreeViewActions: TPopupMenu;
|
|
miExpandAll: TMenuItem;
|
|
miCallapseAll: TMenuItem;
|
|
miSeparator1: TMenuItem;
|
|
miTreeViewDelete: TMenuItem;
|
|
miSeparator2: TMenuItem;
|
|
miAlignBy: TMenuItem;
|
|
pmAvailableItemsActions: TPopupMenu;
|
|
AddGroup1: TMenuItem;
|
|
AddItem1: TMenuItem;
|
|
Delete1: TMenuItem;
|
|
pmAlign: TPopupMenu;
|
|
Left1: TMenuItem;
|
|
Right1: TMenuItem;
|
|
op1: TMenuItem;
|
|
Bottom1: TMenuItem;
|
|
miSeparator3: TMenuItem;
|
|
miSeparator4: TMenuItem;
|
|
None1: TMenuItem;
|
|
btnClose: TButton;
|
|
lcMainGroup_Root: TdxLayoutGroup;
|
|
lcMain: TdxLayoutControl;
|
|
lcMainItem3: TdxLayoutItem;
|
|
lcMainItem4: TdxLayoutItem;
|
|
lcgTreeView: TdxLayoutGroup;
|
|
lcgAvailableItems: TdxLayoutGroup;
|
|
lcMainItem5: TdxLayoutItem;
|
|
lcMainItem6: TdxLayoutItem;
|
|
acAvailableItemsDelete: TAction;
|
|
tvAvailableItems: TTreeView;
|
|
lcMainItem1: TdxLayoutItem;
|
|
ToolButton2: TToolButton;
|
|
tbAvailableItemsExpandAll: TToolButton;
|
|
tbAvailableItemsCollapseAll: TToolButton;
|
|
ToolButton7: TToolButton;
|
|
tbAvailableItemsViewAsList: TToolButton;
|
|
acAvailableItemsExpandAll: TAction;
|
|
acAvailableItemsCollapseAll: TAction;
|
|
acAvailableItemsViewAsList: TAction;
|
|
tlbCustomize: TToolBar;
|
|
lcMainItem2: TdxLayoutItem;
|
|
ToolButton4: TToolButton;
|
|
acTabbedView: TAction;
|
|
acHighlightRoot: TAction;
|
|
lcMainGroup1: TdxLayoutGroup;
|
|
acShowDesignSelectors: TAction;
|
|
ToolButton6: TToolButton;
|
|
cbTabbedView: TCheckBox;
|
|
lcMainItem7: TdxLayoutItem;
|
|
lcMainGroup2: TdxLayoutGroup;
|
|
lcMainGroup3: TdxLayoutGroup;
|
|
ilToolBarActionsDisabled: TcxImageList;
|
|
ilToolBarActions: TcxImageList;
|
|
ToolButton3: TToolButton;
|
|
ToolButton8: TToolButton;
|
|
acStore: TAction;
|
|
acRestore: TAction;
|
|
tlbTreeView: TToolBar;
|
|
procedure acCloseExecute(Sender: TObject);
|
|
procedure acAddGroupExecute(Sender: TObject);
|
|
procedure acAddItemExecute(Sender: TObject);
|
|
procedure tvItemsEdited(Sender: TObject; Node: TTreeNode;
|
|
var S: String);
|
|
procedure tvItemsMouseDown(Sender: TObject; Button: TMouseButton;
|
|
Shift: TShiftState; X, Y: Integer);
|
|
procedure ItemsMouseMove(Sender: TObject; Shift: TShiftState; X,
|
|
Y: Integer);
|
|
procedure ItemsMouseUp(Sender: TObject; Button: TMouseButton;
|
|
Shift: TShiftState; X, Y: Integer);
|
|
procedure tvItemsChange(Sender: TObject; Node: TTreeNode);
|
|
procedure tvItemsChanging(Sender: TObject; Node: TTreeNode;
|
|
var AllowChange: Boolean);
|
|
procedure AlignExecute(Sender: TObject);
|
|
procedure acTreeViewItemsDeleteExecute(Sender: TObject);
|
|
procedure FormClose(Sender: TObject; var Action: TCloseAction);
|
|
procedure tvItemsContextPopup(Sender: TObject; MousePos: TPoint;
|
|
var Handled: Boolean);
|
|
procedure acAvailableItemsDeleteExecute(Sender: TObject);
|
|
procedure tvItemsCustomDrawItem(Sender: TCustomTreeView;
|
|
Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
|
|
procedure tvAvailableItemsContextPopup(Sender: TObject;
|
|
MousePos: TPoint; var Handled: Boolean);
|
|
procedure acAvailableItemsExpandAllExecute(Sender: TObject);
|
|
procedure acAvailableItemsCollapseAllExecute(Sender: TObject);
|
|
procedure acTreeViewExpandAllExecute(Sender: TObject);
|
|
procedure acTreeViewCollapseAllExecute(Sender: TObject);
|
|
procedure acAvailableItemsViewAsListExecute(Sender: TObject);
|
|
procedure tvItemsEditing(Sender: TObject; Node: TTreeNode;
|
|
var AllowEdit: Boolean);
|
|
procedure FormShortCut(var Msg: TWMKey; var Handled: Boolean);
|
|
procedure FormKeyDown(Sender: TObject; var Key: Word;
|
|
Shift: TShiftState);
|
|
procedure acTabbedViewExecute(Sender: TObject);
|
|
procedure acHighlightRootExecute(Sender: TObject);
|
|
procedure acShowDesignSelectorsExecute(Sender: TObject);
|
|
procedure acStoreExecute(Sender: TObject);
|
|
procedure acRestoreExecute(Sender: TObject);
|
|
private
|
|
FControl: TdxCustomLayoutControl;
|
|
FDragHelper: TdxLayoutDragAndDropHelper;
|
|
FLockCount: Integer;
|
|
FAvailableItemsWndProc: TWndMethod;
|
|
FItemsWndProc: TWndMethod;
|
|
procedure AddItemNode(ANodes: TTreeNodes; ANode: TTreeNode; AItem: TdxCustomLayoutItem;
|
|
const ACustomName: string = '');
|
|
procedure AvailableItemsWndProc(var Message: TMessage);
|
|
procedure DoAfterInsertionItem(AItem: TdxCustomLayoutItem);
|
|
function GetImageIndex(AItem: TdxCustomLayoutItem): Integer;
|
|
function GetIsLocked: Boolean;
|
|
function GetNextToSelectItem(ATreeView: TTreeView): TdxCustomLayoutItem;
|
|
procedure InitializePopupMenu;
|
|
procedure ItemsWndProc(var Message: TMessage);
|
|
procedure RefreshLists(ARefreshSelection: Boolean = False);
|
|
procedure RefreshButtonStates;
|
|
procedure RefreshView;
|
|
procedure SelectItem(AItem: TdxCustomLayoutItem);
|
|
procedure SetControl(AValue: TdxCustomLayoutControl);
|
|
procedure SetItemsSelections(AList: TList);
|
|
procedure SetLayoutItemsSelections(ATreeView: TTreeView);
|
|
function TreeViewWndProcHandler(ATreeView: TTreeView; var Message: TMessage): Boolean;
|
|
protected
|
|
procedure CreateParams(var Params: TCreateParams); override;
|
|
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
|
|
|
|
procedure CalculateAddItemsActionStates;
|
|
procedure CalculateDeleteItemsActionStates;
|
|
function CanDeleteItems(ATreeView: TTreeView): Boolean;
|
|
procedure DeleteItems(AList: TComponentList; ASelectedItem: TdxCustomLayoutItem);
|
|
procedure InitializeControl;
|
|
procedure Localize; virtual;
|
|
function NeedRefreshItemsAfterDeleting(AComponent: TPersistent): Boolean;
|
|
procedure RefreshAvailableItems;
|
|
procedure RefreshEnableds;
|
|
procedure RefreshTreeView;
|
|
|
|
property DragHelper: TdxLayoutDragAndDropHelper read FDragHelper;
|
|
property IsLocked: Boolean read GetIsLocked;
|
|
property LockCount: Integer read FLockCount;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
|
|
function GetHitTest(const P: TPoint): TdxCustomLayoutHitTest; virtual;
|
|
|
|
// Updates
|
|
procedure BeginUpdate;
|
|
procedure CancelUpdate;
|
|
procedure EndUpdate;
|
|
procedure UpdateCaption;
|
|
procedure UpdateContent;
|
|
procedure UpdateSelection;
|
|
|
|
property Control: TdxCustomLayoutControl read FControl write SetControl;
|
|
end;
|
|
|
|
procedure cxTreeViewGetSelection(ATreeView: TTreeView; AList: TList);
|
|
procedure cxTreeViewSyncSelection(ATreeView: TTreeView; AList: TList);
|
|
procedure cxListViewGetSelection(AListView: TListView; AList: TList);
|
|
procedure cxListViewSyncSelection(AListView: TListView; AList: TList);
|
|
|
|
implementation
|
|
|
|
{$R *.DFM}
|
|
|
|
uses
|
|
Types, Math, CommCtrl, dxLayoutCommon, dxLayoutEditForm, cxGeometry,
|
|
dxLayoutStrs, dxCore, dxOffice11;
|
|
|
|
type
|
|
TdxLayoutControlAccess = class(TdxCustomLayoutControl);
|
|
TdxCustomLayoutItemAccess = class(TdxCustomLayoutItem);
|
|
|
|
function CompareItemsByClass(Item1, Item2: Pointer): Integer;
|
|
var
|
|
AItem1, AItem2: TdxCustomLayoutItem;
|
|
begin
|
|
AItem1 := TdxCustomLayoutItem(Item1);
|
|
AItem2 := TdxCustomLayoutItem(Item2);
|
|
Result := Integer(AItem1.ClassType) - Integer(AItem2.ClassType);
|
|
end;
|
|
|
|
function CompareItemsByName(Item1, Item2: Pointer): Integer;
|
|
|
|
procedure SplitNameByTrailingDigits(const AName: string; out ATrailingDigits: Integer;
|
|
out ANameWithoutTrailingDigitals: string);
|
|
var
|
|
ACurrentLength: Integer;
|
|
begin
|
|
ANameWithoutTrailingDigitals := AName;
|
|
ACurrentLength := Length(ANameWithoutTrailingDigitals);
|
|
while (ACurrentLength > 0) and
|
|
dxCharIsNumeric(ANameWithoutTrailingDigitals[ACurrentLength]) do
|
|
begin
|
|
ATrailingDigits := ATrailingDigits * 10 +
|
|
StrToInt(ANameWithoutTrailingDigitals[ACurrentLength]);
|
|
ANameWithoutTrailingDigitals := Copy(ANameWithoutTrailingDigitals, 1, ACurrentLength - 1);
|
|
ACurrentLength := Length(ANameWithoutTrailingDigitals);
|
|
end;
|
|
if ACurrentLength = Length(AName) then
|
|
ATrailingDigits := -1
|
|
else
|
|
ATrailingDigits := StrToInt(Copy(AName, ACurrentLength + 1, Length(AName) - ACurrentLength));
|
|
end;
|
|
|
|
var
|
|
AName1, AName2: string;
|
|
ANameWithoutLastDigitals1, ANameWithoutLastDigitals2: string;
|
|
ANumber1, ANumber2: Integer;
|
|
begin
|
|
Result := CompareItemsByClass(Item1, Item2);
|
|
if Result = 0 then
|
|
begin
|
|
AName1 := TdxCustomLayoutItem(Item1).CaptionForCustomizeForm;
|
|
SplitNameByTrailingDigits(AName1, ANumber1, ANameWithoutLastDigitals1);
|
|
AName2 := TdxCustomLayoutItem(Item2).CaptionForCustomizeForm;
|
|
SplitNameByTrailingDigits(AName2, ANumber2, ANameWithoutLastDigitals2);
|
|
Result := CompareText(ANameWithoutLastDigitals1, ANameWithoutLastDigitals2);
|
|
if Result = 0 then
|
|
Result := ANumber1 - ANumber2;
|
|
end;
|
|
end;
|
|
|
|
function CompareItems(Item1, Item2: Pointer): Integer;
|
|
begin
|
|
Result := CompareItemsByClass(Item1, Item2);
|
|
if (Result = 0) and (TObject(Item1) is TdxLayoutGroup) then
|
|
Result := Integer(TdxLayoutGroup(Item1).Count > 0) - Integer(TdxLayoutGroup(Item2).Count > 0);
|
|
if Result = 0 then
|
|
Result := CompareItemsByName(Item1, Item2);
|
|
end;
|
|
|
|
procedure cxTreeViewGetSelection(ATreeView: TTreeView; AList: TList);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to ATreeView.SelectionCount - 1 do
|
|
AList.Add(ATreeView.Selections[I].Data);
|
|
end;
|
|
|
|
procedure cxTreeViewSyncSelection(ATreeView: TTreeView; AList: TList);
|
|
|
|
procedure InternalSyncSelection(ANode: TTreeNode);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if ANode = nil then
|
|
Exit;
|
|
if ANode.Selected xor (ANode.Data <> nil) and (AList.IndexOf(ANode.Data) >= 0) then
|
|
if ANode.Selected then
|
|
ATreeView.Deselect(ANode)
|
|
else
|
|
ATreeView.Select(ANode, [ssCtrl]);
|
|
ANode.Focused := ANode.Selected;
|
|
for I := 0 to ANode.Count - 1 do
|
|
InternalSyncSelection(ANode[I]);
|
|
end;
|
|
|
|
var
|
|
I: Integer;
|
|
begin
|
|
with ATreeView do
|
|
begin
|
|
if AList.Count > 0 then
|
|
for I := 0 to Items.Count - 1 do
|
|
InternalSyncSelection(Items[I])
|
|
else
|
|
ATreeView.ClearSelection(False);
|
|
end;
|
|
if ATreeView.SelectionCount = 0 then
|
|
ATreeView.Selected := nil;
|
|
end;
|
|
|
|
procedure cxListViewGetSelection(AListView: TListView; AList: TList);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
AList.Clear;
|
|
with AListView do
|
|
for I := 0 to Items.Count - 1 do
|
|
if (Items[I].Data <> nil) and Items[I].Selected then
|
|
AList.Add(Items[I].Data);
|
|
end;
|
|
|
|
procedure cxListViewSyncSelection(AListView: TListView; AList: TList);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
with AListView do
|
|
begin
|
|
for I := 0 to AListView.Items.Count - 1 do
|
|
with Items[I] do
|
|
begin
|
|
Selected := AList.IndexOf(Items[I].Data) >= 0;
|
|
Focused := Focused or Selected;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ TdxLayoutDesignForm }
|
|
|
|
constructor TdxLayoutControlCustomizeForm.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
if not IsXPManifestEnabled then
|
|
begin
|
|
tlbCustomize.DisabledImages := ilToolBarActionsDisabled;
|
|
tlbAvailableItems.DisabledImages := ilToolBarActionsDisabled;
|
|
tlbTreeView.DisabledImages := ilToolBarActionsDisabled;
|
|
ilToolBarActions.Clear;
|
|
cxTransformImages(ilActions, ilToolBarActions, clBtnFace);
|
|
ilToolBarActionsDisabled.Clear;
|
|
cxTransformImages(ilActions, ilToolBarActionsDisabled, clBtnFace, False);
|
|
cxTransformImages(ilItems, clWindow);
|
|
end;
|
|
|
|
Localize;
|
|
InitializePopupMenu;
|
|
FItemsWndProc := tvItems.WindowProc;
|
|
tvItems.WindowProc := ItemsWndProc;
|
|
FAvailableItemsWndProc := tvAvailableItems.WindowProc;
|
|
tvAvailableItems.WindowProc := AvailableItemsWndProc;
|
|
end;
|
|
|
|
destructor TdxLayoutControlCustomizeForm.Destroy;
|
|
begin
|
|
Control.Customization := False;
|
|
FreeAndNil(FDragHelper);
|
|
tvItems.WindowProc := FItemsWndProc;
|
|
tvAvailableItems.WindowProc := FAvailableItemsWndProc;
|
|
inherited;
|
|
end;
|
|
|
|
function TdxLayoutControlCustomizeForm.GetHitTest(const P: TPoint): TdxCustomLayoutHitTest;
|
|
begin
|
|
if tvItems.Visible and PtInRect(tvItems.BoundsRect, P) then
|
|
Result := TdxLayoutCustomizeFormTreeViewItemsHitTest.Instance
|
|
else
|
|
if tvAvailableItems.Visible and PtInRect(tvAvailableItems.BoundsRect, P) then
|
|
Result := TdxLayoutCustomizeFormAvailableItemsHitTest.Instance
|
|
else
|
|
Result := TdxLayoutCustomizeFormHitTest.Instance
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.BeginUpdate;
|
|
begin
|
|
Inc(FLockCount);
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.CancelUpdate;
|
|
begin
|
|
Dec(FLockCount);
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.EndUpdate;
|
|
begin
|
|
Dec(FLockCount);
|
|
if LockCount = 0 then
|
|
RefreshLists(True);
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.UpdateCaption;
|
|
begin
|
|
if Control.IsDesigning then
|
|
Caption := Format(cxGetResourceString(@sdxLayoutControlDesignerCaptionFormat), [cxGetFullComponentName(Control)])
|
|
else
|
|
Caption := cxGetResourceString(@sdxLayoutControlCustomizeFormCaption);
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.UpdateContent;
|
|
begin
|
|
RefreshLists;
|
|
RefreshButtonStates;
|
|
RefreshView;
|
|
if (FDragHelper.DragItem <> nil) and (Control.DragAndDropState = ddsNone) then
|
|
FDragHelper.Reset;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.UpdateSelection;
|
|
var
|
|
AList: TList;
|
|
begin
|
|
if IsLocked then
|
|
Exit;
|
|
AList := TList.Create;
|
|
try
|
|
(Control as IdxLayoutDesignerHelper).GetSelection(AList);
|
|
SetItemsSelections(AList);
|
|
finally
|
|
AList.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.CalculateAddItemsActionStates;
|
|
begin
|
|
acAddGroup.Enabled := True;
|
|
acAddItem.Enabled := Control.IsDesigning;
|
|
acAddItem.Visible := Control.IsDesigning;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.CalculateDeleteItemsActionStates;
|
|
begin
|
|
acTreeViewItemsDelete.Enabled := CanDeleteItems(tvItems);
|
|
acAvailableItemsDelete.Enabled := CanDeleteItems(tvAvailableItems);
|
|
end;
|
|
|
|
function TdxLayoutControlCustomizeForm.CanDeleteItems(ATreeView: TTreeView): Boolean;
|
|
var
|
|
AList: TList;
|
|
I: Integer;
|
|
begin
|
|
Result := not ATreeView.IsEditing;
|
|
if Result then
|
|
begin
|
|
AList := TList.Create;
|
|
try
|
|
cxTreeViewGetSelection(ATreeView, AList);
|
|
Result := AList.Count > 0;
|
|
if Result then
|
|
for I := 0 to AList.Count - 1 do
|
|
begin
|
|
Result := (Control as IdxLayoutDesignerHelper).CanDeleteComponent(TComponent(AList[I]));
|
|
if not Result then
|
|
Break;
|
|
end;
|
|
finally
|
|
AList.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.DeleteItems(AList: TComponentList;
|
|
ASelectedItem: TdxCustomLayoutItem);
|
|
begin
|
|
if AList.Count = 0 then
|
|
Exit;
|
|
BeginUpdate;
|
|
try
|
|
SelectItem(ASelectedItem);
|
|
Control.BeginUpdate;
|
|
try
|
|
while AList.Count > 0 do
|
|
AList[0].Free;
|
|
finally
|
|
Control.EndUpdate;
|
|
end;
|
|
finally
|
|
CancelUpdate;
|
|
end;
|
|
RefreshLists(True);
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.CreateParams(var Params: TCreateParams);
|
|
begin
|
|
inherited;
|
|
if Control <> nil then
|
|
Params.WndParent := Control.Handle;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.Notification(AComponent: TComponent; Operation: TOperation);
|
|
begin
|
|
inherited;
|
|
if (Operation = opRemove) and (AComponent = Control) then
|
|
Free;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.InitializeControl;
|
|
begin
|
|
UpdateCaption;
|
|
FDragHelper.Free;
|
|
FDragHelper := TdxLayoutDragAndDropHelper.Create(Control);
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.Localize;
|
|
begin
|
|
acAddGroup.Caption := cxGetResourceString(@sdxLayoutControlCustomizeFormAddGroup);
|
|
acAddGroup.Hint := StripHotKey(acAddGroup.Caption);
|
|
|
|
acAddItem.Caption := cxGetResourceString(@sdxLayoutControlCustomizeFormAddItem);
|
|
acAddItem.Hint := StripHotKey(acAddItem.Caption);
|
|
|
|
acAvailableItemsDelete.Caption := cxGetResourceString(@sdxLayoutControlCustomizeFormDelete);
|
|
acAvailableItemsDelete.Hint := cxGetResourceString(@sdxLayoutControlCustomizeFormDeleteHint);
|
|
|
|
acTreeViewItemsDelete.Caption := cxGetResourceString(@sdxLayoutControlCustomizeFormDelete);
|
|
acTreeViewItemsDelete.Hint := cxGetResourceString(@sdxLayoutControlCustomizeFormDeleteHint);
|
|
|
|
tbAlignBy.Caption := cxGetResourceString(@sdxLayoutControlCustomizeFormAlignBy);
|
|
tbAlignBy.Hint := StripHotKey(tbAlignBy.Caption);
|
|
|
|
acClose.Caption := cxGetResourceString(@sdxLayoutControlCustomizeFormClose);
|
|
acClose.Hint := StripHotKey(acClose.Caption);
|
|
|
|
acTreeViewExpandAll.Caption := cxGetResourceString(@sdxLayoutControlCustomizeFormExpandAll);
|
|
acTreeViewExpandAll.Hint := StripHotKey(acTreeViewExpandAll.Caption);
|
|
|
|
acAvailableItemsExpandAll.Caption := acTreeViewExpandAll.Caption;
|
|
acAvailableItemsExpandAll.Hint := acTreeViewExpandAll.Hint;
|
|
|
|
acTreeViewCollapseAll.Caption := cxGetResourceString(@sdxLayoutControlCustomizeFormCollapseAll);
|
|
acTreeViewCollapseAll.Hint := StripHotKey(acTreeViewCollapseAll.Caption);
|
|
|
|
acAvailableItemsCollapseAll.Caption := acTreeViewCollapseAll.Caption;
|
|
acAvailableItemsCollapseAll.Hint := StripHotKey(acTreeViewCollapseAll.Hint);
|
|
|
|
acAlignLeftSide.Caption := cxGetResourceString(@sdxLayoutControlCustomizeFormAlignLeftSide);
|
|
acAlignRightSide.Caption := cxGetResourceString(@sdxLayoutControlCustomizeFormAlignRightSide);
|
|
acAlignTopSide.Caption := cxGetResourceString(@sdxLayoutControlCustomizeFormAlignTopSide);
|
|
acAlignBottomSide.Caption := cxGetResourceString(@sdxLayoutControlCustomizeFormAlignBottomSide);
|
|
acAlignNone.Caption := cxGetResourceString(@sdxLayoutControlCustomizeFormAlignNone);
|
|
|
|
lcgTreeView.Caption := cxGetResourceString(@sdxLayoutControlCustomizeFormTreeViewGroup);
|
|
lcgAvailableItems.Caption := cxGetResourceString(@sdxLayoutControlCustomizeFormListViewGroup);
|
|
|
|
acTabbedView.Caption := cxGetResourceString(@sdxLayoutControlCustomizeFormTabbedView);
|
|
acTabbedView.Hint := StripHotKey(acTabbedView.Caption);
|
|
|
|
acAvailableItemsViewAsList.Caption := cxGetResourceString(@sdxLayoutControlCustomizeFormTreeView);
|
|
acAvailableItemsViewAsList.Hint := StripHotKey(acAvailableItemsViewAsList.Caption);
|
|
|
|
acStore.Caption := cxGetResourceString(@sdxLayoutControlCustomizeFormStore);
|
|
acStore.Hint := StripHotKey(acStore.Caption);
|
|
|
|
acRestore.Caption := cxGetResourceString(@sdxLayoutControlCustomizeFormRestore);
|
|
acRestore.Hint := StripHotKey(acRestore.Caption);
|
|
end;
|
|
|
|
function TdxLayoutControlCustomizeForm.NeedRefreshItemsAfterDeleting(AComponent: TPersistent): Boolean;
|
|
begin
|
|
Result := (AComponent is TdxCustomLayoutItem) and
|
|
(TdxCustomLayoutItem(AComponent).Container = Control);
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.RefreshAvailableItems;
|
|
|
|
procedure PopulateItemChildren(AList: TList; AItem: TdxCustomLayoutItem);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if AItem is TdxLayoutGroup then
|
|
begin
|
|
for I := 0 to TdxLayoutGroup(AItem).Count - 1 do
|
|
begin
|
|
AList.Add(TdxLayoutGroup(AItem).Items[I]);
|
|
PopulateItemChildren(AList, TdxLayoutGroup(AItem).Items[I]);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure PopulateItems(AList: TList);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to Control.AvailableItemCount - 1 do
|
|
begin
|
|
AList.Add(Control.AvailableItems[I]);
|
|
if Control.CustomizeAvailableItemsViewKind = oivkList then
|
|
PopulateItemChildren(AList, Control.AvailableItems[I]);
|
|
end;
|
|
end;
|
|
|
|
var
|
|
AList: TList;
|
|
I: Integer;
|
|
begin
|
|
with tvAvailableItems do
|
|
begin
|
|
Items.BeginUpdate;
|
|
try
|
|
Items.Clear;
|
|
AList := TList.Create;
|
|
try
|
|
PopulateItems(AList);
|
|
case Control.CustomizeAvailableItemsViewKind of
|
|
oivkList:
|
|
begin
|
|
AList.Sort(CompareItemsByName);
|
|
for I := 0 to AList.Count - 1 do
|
|
with Items.AddObject(Items.GetFirstNode,
|
|
TdxCustomLayoutItem(AList[I]).CaptionForCustomizeForm, AList[I]) do
|
|
begin
|
|
ImageIndex := GetImageIndex(AList[I]);
|
|
SelectedIndex := ImageIndex;
|
|
Selected := False;
|
|
Focused := False;
|
|
end;
|
|
end;
|
|
oivkTree:
|
|
begin
|
|
AList.Sort(CompareItems);
|
|
for I := 0 to AList.Count - 1 do
|
|
AddItemNode(Items, nil, TdxCustomLayoutItem(AList[I]));
|
|
end;
|
|
end;
|
|
finally
|
|
AList.Free;
|
|
end;
|
|
FullExpand;
|
|
finally
|
|
Items.EndUpdate;
|
|
end;
|
|
end;
|
|
tvAvailableItems.ShowRoot := Control.CustomizeAvailableItemsViewKind = oivkTree;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.RefreshEnableds;
|
|
begin
|
|
if not IsLocked then
|
|
begin
|
|
tbAlignBy.Enabled := (tvItems.SelectionCount > 1);
|
|
miAlignBy.Enabled := tbAlignBy.Enabled;
|
|
acAvailableItemsExpandAll.Enabled := Control.CustomizeAvailableItemsViewKind = oivkTree;
|
|
acAvailableItemsCollapseAll.Enabled := Control.CustomizeAvailableItemsViewKind = oivkTree;
|
|
acRestore.Enabled := Control.CanRestore;
|
|
CalculateAddItemsActionStates;
|
|
CalculateDeleteItemsActionStates;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.RefreshTreeView;
|
|
begin
|
|
with tvItems do
|
|
begin
|
|
Items.BeginUpdate;
|
|
try
|
|
Items.Clear;
|
|
AddItemNode(Items, Items.GetFirstNode, Control.Items, cxGetResourceString(@sdxLayoutControlRoot));
|
|
FullExpand;
|
|
finally
|
|
Items.EndUpdate;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.AddItemNode(ANodes: TTreeNodes; ANode: TTreeNode; AItem: TdxCustomLayoutItem;
|
|
const ACustomName: string = '');
|
|
var
|
|
AName: string;
|
|
I: Integer;
|
|
AThisNode: TTreeNode;
|
|
AGroup: TdxLayoutGroup;
|
|
begin
|
|
if ACustomName = '' then
|
|
AName := AItem.CaptionForCustomizeForm
|
|
else
|
|
AName := ACustomName;
|
|
if ANode = nil then
|
|
AThisNode := ANodes.AddObject(ANodes.GetFirstNode, AName, AItem)
|
|
else
|
|
AThisNode := ANodes.AddChildObject(ANode, AName, AItem);
|
|
|
|
if AItem is TdxLayoutGroup then
|
|
begin
|
|
AGroup := TdxLayoutGroup(AItem);
|
|
for I := 0 to AGroup.Count - 1 do
|
|
AddItemNode(ANodes, AThisNode, AGroup[I]);
|
|
end;
|
|
AThisNode.ImageIndex := GetImageIndex(AItem);
|
|
AThisNode.SelectedIndex := AThisNode.ImageIndex;
|
|
AThisNode.Selected := False;
|
|
AThisNode.Focused := False;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.AvailableItemsWndProc(var Message: TMessage);
|
|
begin
|
|
if not TreeViewWndProcHandler(tvAvailableItems, Message) then
|
|
FAvailableItemsWndProc(Message);
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.DoAfterInsertionItem(AItem: TdxCustomLayoutItem);
|
|
begin
|
|
(Control as IdxLayoutDesignerHelper).SelectComponent(AItem);
|
|
end;
|
|
|
|
function TdxLayoutControlCustomizeForm.GetImageIndex(AItem: TdxCustomLayoutItem): Integer;
|
|
var
|
|
AGroup: TdxLayoutGroup;
|
|
begin
|
|
if AItem is TdxLayoutGroup then
|
|
begin
|
|
Result := 1;
|
|
AGroup := AItem as TdxLayoutGroup;
|
|
if AGroup.Hidden and not AGroup.IsRoot then
|
|
Inc(Result);
|
|
end
|
|
else
|
|
Result := 0;
|
|
end;
|
|
|
|
function TdxLayoutControlCustomizeForm.GetIsLocked: Boolean;
|
|
begin
|
|
Result := (LockCount > 0) or TdxLayoutControlAccess(Control).IsUpdateLocked;
|
|
end;
|
|
|
|
function TdxLayoutControlCustomizeForm.GetNextToSelectItem(ATreeView: TTreeView): TdxCustomLayoutItem;
|
|
var
|
|
ANode: TTreeNode;
|
|
begin
|
|
Result := nil;
|
|
ANode := ATreeView.FindNextToSelect;
|
|
if ANode <> nil then
|
|
Result := TdxCustomLayoutItem(ANode.Data)
|
|
else
|
|
begin
|
|
ANode := ATreeView.Selected;
|
|
while (ANode <> nil) and ANode.Selected do
|
|
ANode := ANode.GetPrev;
|
|
if ANode <> nil then
|
|
Result := TdxCustomLayoutItem(ANode.Data);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.InitializePopupMenu;
|
|
var
|
|
I: Integer;
|
|
AMenuItem: TMenuItem;
|
|
begin
|
|
for I := 0 to pmAlign.Items.Count - 1 do
|
|
begin
|
|
AMenuItem := TMenuItem.Create(miAlignBy);
|
|
AMenuItem.Caption := pmAlign.Items[I].Caption;
|
|
AMenuItem.Action := pmAlign.Items[I].Action;
|
|
miAlignBy.Add(AMenuItem);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.ItemsWndProc(var Message: TMessage);
|
|
begin
|
|
if not TreeViewWndProcHandler(tvItems, Message) then
|
|
FItemsWndProc(Message);
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.RefreshLists(ARefreshSelection: Boolean = False);
|
|
begin
|
|
if IsLocked then
|
|
Exit;
|
|
BeginUpdate;
|
|
try
|
|
RefreshAvailableItems;
|
|
RefreshTreeView;
|
|
finally
|
|
CancelUpdate;
|
|
end;
|
|
if ARefreshSelection then
|
|
UpdateSelection;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.RefreshButtonStates;
|
|
begin
|
|
acAvailableItemsViewAsList.Checked := Control.CustomizeAvailableItemsViewKind = oivkTree;
|
|
acTabbedView.Checked := Control.CustomizeFormTabbedView;
|
|
acHighlightRoot.Checked := Control.HighlightRoot;
|
|
acShowDesignSelectors.Checked := Control.ShowDesignSelectors;
|
|
RefreshEnableds;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.RefreshView;
|
|
begin
|
|
if Control.CustomizeFormTabbedView then
|
|
lcMainGroup1.LayoutDirection := ldTabbed
|
|
else
|
|
lcMainGroup1.LayoutDirection := ldHorizontal;
|
|
acShowDesignSelectors.Visible := Control.IsDesigning;
|
|
acHighlightRoot.Visible := Control.IsDesigning;
|
|
acStore.Visible := not Control.IsDesigning;
|
|
acRestore.Visible := not Control.IsDesigning;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.SelectItem(AItem: TdxCustomLayoutItem);
|
|
begin
|
|
if AItem <> nil then
|
|
(Control as IdxLayoutDesignerHelper).SelectComponent(AItem)
|
|
else
|
|
(Control as IdxLayoutDesignerHelper).SelectComponent(Control);
|
|
RefreshEnableds;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.SetControl(AValue: TdxCustomLayoutControl);
|
|
|
|
procedure StoreMetrics;
|
|
begin
|
|
cxDialogsMetricsStore.StoreMetrics(Self);
|
|
end;
|
|
|
|
procedure RestoreMetrics;
|
|
begin
|
|
if Control <> nil then
|
|
if EqualRect(Control.CustomizeFormBounds, cxNullRect) then
|
|
BoundsRect := TdxLayoutControlAccess(Control).CalculateCustomizeFormBounds(BoundsRect)
|
|
else
|
|
BoundsRect := Control.CustomizeFormBounds;
|
|
cxDialogsMetricsStore.InitDialog(Self);
|
|
Position := poDesigned;
|
|
end;
|
|
|
|
begin
|
|
if Control <> AValue then
|
|
begin
|
|
if Control <> nil then
|
|
begin
|
|
StoreMetrics;
|
|
Control.RemoveFreeNotification(Self);
|
|
end;
|
|
FControl := AValue;
|
|
if Control <> nil then
|
|
begin
|
|
Control.FreeNotification(Self);
|
|
RestoreMetrics;
|
|
end;
|
|
RecreateWnd;
|
|
end;
|
|
InitializeControl;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.SetItemsSelections(AList: TList);
|
|
|
|
procedure SetTreeViewAsActiveControl(ATreeView: TTreeView);
|
|
begin
|
|
if ATreeView.Visible then
|
|
ActiveControl := ATreeView
|
|
else
|
|
ActiveControl := nil;
|
|
end;
|
|
|
|
var
|
|
AItem: TdxCustomLayoutItemAccess;
|
|
begin
|
|
if IsLocked then
|
|
Exit;
|
|
BeginUpdate;
|
|
try
|
|
cxTreeViewSyncSelection(tvItems, AList);
|
|
cxTreeViewSyncSelection(tvAvailableItems, AList);
|
|
if (AList.Count > 0) and (TObject(AList.Last) is TdxCustomLayoutItem) then
|
|
begin
|
|
AItem := TdxCustomLayoutItemAccess(AList.Last);
|
|
if AItem.IsAvailable then
|
|
SetTreeViewAsActiveControl(tvAvailableItems)
|
|
else
|
|
SetTreeViewAsActiveControl(tvItems);
|
|
end;
|
|
finally
|
|
CancelUpdate;
|
|
end;
|
|
RefreshEnableds;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.SetLayoutItemsSelections(ATreeView: TTreeView);
|
|
var
|
|
AList: TList;
|
|
begin
|
|
AList := TList.Create;
|
|
try
|
|
cxTreeViewGetSelection(ATreeView, AList);
|
|
(Control as IdxLayoutDesignerHelper).SetSelection(AList);
|
|
finally
|
|
AList.Free;
|
|
end;
|
|
end;
|
|
|
|
function TdxLayoutControlCustomizeForm.TreeViewWndProcHandler(ATreeView: TTreeView; var Message: TMessage): Boolean;
|
|
var
|
|
ANode: TTreeNode;
|
|
AHitTest : THitTests;
|
|
AShift: TShiftState;
|
|
begin
|
|
Result := False;
|
|
case Message.Msg of
|
|
CN_NOTIFY:
|
|
case TWMNotify(Message).NMHdr^.code of
|
|
NM_RCLICK:
|
|
begin
|
|
AHitTest := ATreeView.GetHitTestInfoAt(Message.LParamLo, Message.LParamHi);
|
|
if (htOnItem in AHitTest) then
|
|
tvItems.Perform(WM_CONTEXTMENU, ATreeView.Handle, Integer(PointToSmallPoint(GetMouseCursorPos)));
|
|
Message.Result := 1;
|
|
Result := True;
|
|
end;
|
|
end;
|
|
WM_RBUTTONDOWN:
|
|
begin
|
|
ANode := ATreeView.GetNodeAt(Message.LParamLo, Message.LParamHi);
|
|
if ANode <> nil then
|
|
begin
|
|
ANode.Focused := True;
|
|
AShift := KeysToShiftState(Message.WParam);
|
|
if not ANode.Selected then
|
|
begin
|
|
if [ssShift, ssCtrl] * AShift <> [] then
|
|
AShift := [];
|
|
BeginUpdate;
|
|
try
|
|
ATreeView.Select(ANode, AShift);
|
|
finally
|
|
CancelUpdate;
|
|
end;
|
|
SetLayoutItemsSelections(ATreeView);
|
|
end;
|
|
end;
|
|
Message.Result := 1;
|
|
Result := True;
|
|
end;
|
|
WM_LBUTTONDOWN:
|
|
begin
|
|
ANode := ATreeView.GetNodeAt(Message.LParamLo, Message.LParamHi);
|
|
if (ANode <> nil) and (ATreeView.SelectionCount > 1) then
|
|
begin
|
|
ANode.Focused := True;
|
|
AShift := KeysToShiftState(Message.WParam);
|
|
if ANode.Selected and ([ssCtrl, ssShift] * AShift = []) then
|
|
begin
|
|
BeginUpdate;
|
|
try
|
|
ATreeView.ClearSelection;
|
|
finally
|
|
CancelUpdate;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.acCloseExecute(Sender: TObject);
|
|
begin
|
|
Close;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.acAddGroupExecute(Sender: TObject);
|
|
var
|
|
AGroup: TdxLayoutGroup;
|
|
begin
|
|
Control.BeginUpdate;
|
|
try
|
|
AGroup := Control.CreateGroup;
|
|
AGroup.Caption := cxGetResourceString(@sdxLayoutControlNewGroupCaption);
|
|
finally
|
|
Control.EndUpdate;
|
|
end;
|
|
DoAfterInsertionItem(AGroup);
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.acAddItemExecute(Sender: TObject);
|
|
var
|
|
AItem: TdxCustomLayoutItem;
|
|
begin
|
|
Control.BeginUpdate;
|
|
try
|
|
AItem := Control.CreateItem;
|
|
AItem.Caption := cxGetResourceString(@sdxLayoutControlNewItemCaption);
|
|
finally
|
|
Control.EndUpdate;
|
|
end;
|
|
DoAfterInsertionItem(AItem);
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.tvItemsEdited(Sender: TObject; Node: TTreeNode;
|
|
var S: String);
|
|
begin
|
|
if TdxCustomLayoutItem(Node.Data).IsRoot then
|
|
Exit;
|
|
BeginUpdate;
|
|
try
|
|
if Control.IsDesigning then
|
|
TdxCustomLayoutItem(Node.Data).Name := S
|
|
else
|
|
TdxCustomLayoutItem(Node.Data).Caption := S;
|
|
Node.Text := TdxCustomLayoutItem(Node.Data).CaptionForCustomizeForm;
|
|
finally
|
|
CancelUpdate;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.tvItemsMouseDown(Sender: TObject;
|
|
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
|
var
|
|
ANode: TTreeNode;
|
|
ATreeView: TTreeView;
|
|
AHitTests: THitTests;
|
|
begin
|
|
ATreeView := TTreeView(Sender);
|
|
AHitTests := ATreeView.GetHitTestInfoAt(X, Y);
|
|
if htOnItem in AHitTests then
|
|
begin
|
|
ANode := ATreeView.GetNodeAt(X, Y);
|
|
if ANode = nil then
|
|
Exit;
|
|
ANode.Selected := True;
|
|
if (Button = mbLeft) and ANode.Selected and (ANode = ATreeView.Selected) then
|
|
DragHelper.InitializeDragItem(ATreeView.Selected.Data, X, Y);
|
|
if (Button = mbRight) or (ssCtrl in Shift) then
|
|
SetLayoutItemsSelections(ATreeView);
|
|
end;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.ItemsMouseMove(Sender: TObject; Shift: TShiftState;
|
|
X, Y: Integer);
|
|
var
|
|
ASource: TdxLayoutDragSource;
|
|
begin
|
|
if Sender = tvItems then
|
|
ASource := dsCustomizeFormTreeViewItems
|
|
else
|
|
ASource := dsCustomizeFormAvailableItems;
|
|
if ssLeft in Shift then
|
|
DragHelper.TryBeginDragAndDrop(X, Y, ASource);
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.ItemsMouseUp(Sender: TObject; Button: TMouseButton;
|
|
Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
if Button = mbLeft then
|
|
DragHelper.Reset;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.tvItemsChange(Sender: TObject; Node: TTreeNode);
|
|
begin
|
|
if not IsLocked then
|
|
SetLayoutItemsSelections(TTreeView(Sender));
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.tvItemsChanging(Sender: TObject; Node: TTreeNode;
|
|
var AllowChange: Boolean);
|
|
begin
|
|
AllowChange := (Node = nil) or (Node.Data <> nil);
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.AlignExecute(Sender: TObject);
|
|
var
|
|
AList: TList;
|
|
I: Integer;
|
|
ATag: Integer;
|
|
begin
|
|
ATag := (Sender as TAction).Tag;
|
|
AList := TList.Create;
|
|
try
|
|
(Control as IdxLayoutDesignerHelper).GetSelection(AList);
|
|
BeginUpdate;
|
|
try
|
|
Control.BeginUpdate;
|
|
try
|
|
if ATag = -1 then
|
|
for I := 0 to AList.Count - 1 do
|
|
TdxCustomLayoutItem(AList[I]).AlignmentConstraint := nil
|
|
else
|
|
with Control.CreateAlignmentConstraint do
|
|
begin
|
|
Kind := TdxLayoutAlignmentConstraintKind(ATag);
|
|
for I := 0 to AList.Count - 1 do
|
|
AddItem(TdxCustomLayoutItem(AList[I]));
|
|
end;
|
|
finally
|
|
Control.EndUpdate;
|
|
end;
|
|
finally
|
|
CancelUpdate;
|
|
end;
|
|
finally
|
|
AList.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.acTreeViewItemsDeleteExecute(Sender: TObject);
|
|
|
|
procedure CheckSelectedParent(ANode: TTreeNode);
|
|
var
|
|
AParentNode: TTreeNode;
|
|
AItem: TdxCustomLayoutItem;
|
|
ANotSelectedChildCount: Integer;
|
|
I: Integer;
|
|
begin
|
|
AParentNode := ANode.Parent;
|
|
if AParentNode = nil then
|
|
Exit;
|
|
AItem := TdxCustomLayoutItem(AParentNode.Data);
|
|
if not AParentNode.Selected and not AItem.IsRoot and (AItem is TdxLayoutGroup)
|
|
and TdxLayoutGroup(AItem).Hidden then
|
|
begin
|
|
ANotSelectedChildCount := AParentNode.Count;
|
|
for I := 0 to AParentNode.Count - 1 do
|
|
if AParentNode[I].Selected then
|
|
Dec(ANotSelectedChildCount);
|
|
if ANotSelectedChildCount < 2 then
|
|
tvItems.Select(AParentNode, [ssCtrl]);
|
|
end;
|
|
end;
|
|
|
|
procedure SelectChildren(ANode: TTreeNode);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if ANode.Count > 0 then
|
|
for I := 0 to ANode.Count - 1 do
|
|
begin
|
|
tvItems.Select(ANode[I], [ssCtrl]);
|
|
SelectChildren(ANode[I]);
|
|
end
|
|
end;
|
|
|
|
procedure CheckNeighbors(ANode: TTreeNode);
|
|
var
|
|
I: Integer;
|
|
AParentNode: TTreeNode;
|
|
ANeighborsSelectedCount: Integer;
|
|
begin
|
|
if (ANode.Parent = nil) or (ANode.Parent.Count = 0) then
|
|
Exit;
|
|
AParentNode := ANode.Parent;
|
|
ANeighborsSelectedCount := 0;
|
|
for I := 0 to AParentNode.Count - 1 do
|
|
if AParentNode[I].Selected then
|
|
Inc(ANeighborsSelectedCount);
|
|
if AParentNode.Count - ANeighborsSelectedCount = 1 then
|
|
for I := 0 to AParentNode.Count - 1 do
|
|
if not AParentNode[I].Selected and (TObject(AParentNode[I].Data) is TdxLayoutGroup) and
|
|
TdxLayoutGroup(AParentNode[I].Data).Hidden then
|
|
tvItems.Select(AParentNode[I], [ssCtrl]);
|
|
end;
|
|
|
|
procedure AdjustSelectionForDeletion;
|
|
var
|
|
I: Integer;
|
|
AList: TList;
|
|
ASaveSelectedNode: TTreeNode;
|
|
begin
|
|
BeginUpdate;
|
|
try
|
|
AList := TList.Create;
|
|
try
|
|
ASaveSelectedNode := tvItems.GetSelections(AList);
|
|
for I := 0 to AList.Count - 1 do
|
|
begin
|
|
SelectChildren(AList[I]);
|
|
CheckNeighbors(AList[I]);
|
|
CheckSelectedParent(AList[I]);
|
|
end;
|
|
with ASaveSelectedNode do
|
|
TreeView_SelectItem(Handle, ItemId);
|
|
finally
|
|
AList.Free;
|
|
end;
|
|
finally
|
|
CancelUpdate;
|
|
end;
|
|
end;
|
|
|
|
var
|
|
AList: TComponentList;
|
|
begin
|
|
if tvItems.IsEditing then
|
|
Exit;
|
|
AList := TComponentList.Create;
|
|
try
|
|
cxTreeViewGetSelection(tvItems, AList);
|
|
AdjustSelectionForDeletion;
|
|
DeleteItems(AList, GetNextToSelectItem(tvItems));
|
|
finally
|
|
AList.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.FormClose(Sender: TObject;
|
|
var Action: TCloseAction);
|
|
begin
|
|
cxDialogsMetricsStore.StoreMetrics(Self);
|
|
Action := caFree;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.tvItemsContextPopup(
|
|
Sender: TObject; MousePos: TPoint; var Handled: Boolean);
|
|
begin
|
|
CalculateDeleteItemsActionStates;
|
|
acAvailableItemsDelete.Enabled := False;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.acAvailableItemsDeleteExecute(
|
|
Sender: TObject);
|
|
var
|
|
AList: TComponentList;
|
|
begin
|
|
if tvAvailableItems.IsEditing then
|
|
Exit;
|
|
AList := TComponentList.Create;
|
|
try
|
|
cxTreeViewGetSelection(tvAvailableItems, AList);
|
|
DeleteItems(AList, GetNextToSelectItem(tvAvailableItems));
|
|
finally
|
|
AList.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.tvItemsCustomDrawItem(
|
|
Sender: TCustomTreeView; Node: TTreeNode; State: TCustomDrawState;
|
|
var DefaultDraw: Boolean);
|
|
begin
|
|
if (TObject(Node.Data) is TdxLayoutGroup) and TdxLayoutGroup(Node.Data).Hidden and
|
|
not TdxLayoutGroup(Node.Data).IsRoot then
|
|
Sender.Canvas.Font.Style := [fsItalic];
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.tvAvailableItemsContextPopup(
|
|
Sender: TObject; MousePos: TPoint; var Handled: Boolean);
|
|
begin
|
|
CalculateDeleteItemsActionStates;
|
|
acTreeViewItemsDelete.Enabled := False;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.acAvailableItemsExpandAllExecute(
|
|
Sender: TObject);
|
|
begin
|
|
tvAvailableItems.FullExpand;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.acAvailableItemsCollapseAllExecute(
|
|
Sender: TObject);
|
|
begin
|
|
tvAvailableItems.FullCollapse;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.acTreeViewExpandAllExecute(
|
|
Sender: TObject);
|
|
begin
|
|
tvItems.FullExpand;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.acTreeViewCollapseAllExecute(
|
|
Sender: TObject);
|
|
begin
|
|
tvItems.FullCollapse;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.acAvailableItemsViewAsListExecute(
|
|
Sender: TObject);
|
|
begin
|
|
if acAvailableItemsViewAsList.Checked then
|
|
Control.CustomizeAvailableItemsViewKind := oivkTree
|
|
else
|
|
Control.CustomizeAvailableItemsViewKind := oivkList;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.tvItemsEditing(Sender: TObject;
|
|
Node: TTreeNode; var AllowEdit: Boolean);
|
|
|
|
function IsKeyDown(AShift: TShiftState): Boolean;
|
|
begin
|
|
Result := (AShift * KeyboardStateToShiftState) <> [];
|
|
end;
|
|
|
|
begin
|
|
AllowEdit := not (TdxCustomLayoutItem(Node.Data).IsRoot or (DragHelper.DragItem <> nil) or
|
|
IsKeyDown([ssCtrl, ssShift]));
|
|
if not AllowEdit or Control.IsDesigning then
|
|
Exit;
|
|
Node.Text := TdxCustomLayoutItem(Node.Data).Caption;
|
|
RefreshEnableds;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.FormShortCut(var Msg: TWMKey;
|
|
var Handled: Boolean);
|
|
begin
|
|
case Msg.CharCode of
|
|
VK_ESCAPE:
|
|
begin
|
|
Handled := tvItems.IsEditing or tvAvailableItems.IsEditing;
|
|
if Handled then
|
|
if tvItems.Selected <> nil then
|
|
tvItems.Selected.EndEdit(True)
|
|
else
|
|
if tvAvailableItems.Selected <> nil then
|
|
tvAvailableItems.Selected.EndEdit(True);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.FormKeyDown(Sender: TObject;
|
|
var Key: Word; Shift: TShiftState);
|
|
begin
|
|
if Key = VK_DELETE then
|
|
begin
|
|
if tvItems.Focused and not tvItems.IsEditing then
|
|
acTreeViewItemsDelete.Execute;
|
|
if tvAvailableItems.Focused and not tvAvailableItems.IsEditing then
|
|
acAvailableItemsDelete.Execute;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.acTabbedViewExecute(
|
|
Sender: TObject);
|
|
begin
|
|
Control.CustomizeFormTabbedView := acTabbedView.Checked;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.acHighlightRootExecute(
|
|
Sender: TObject);
|
|
begin
|
|
Control.HighlightRoot := acHighlightRoot.Checked;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.acShowDesignSelectorsExecute(
|
|
Sender: TObject);
|
|
begin
|
|
Control.ShowDesignSelectors := acShowDesignSelectors.Checked;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.acStoreExecute(Sender: TObject);
|
|
begin
|
|
Control.Store;
|
|
RefreshEnableds;
|
|
end;
|
|
|
|
procedure TdxLayoutControlCustomizeForm.acRestoreExecute(Sender: TObject);
|
|
begin
|
|
Control.Restore;
|
|
end;
|
|
|
|
end.
|