1818 lines
48 KiB
ObjectPascal
1818 lines
48 KiB
ObjectPascal
|
|
||
|
{******************************************}
|
||
|
{ }
|
||
|
{ FastReport VCL }
|
||
|
{ Object Inspector }
|
||
|
{ }
|
||
|
{ Copyright (c) 1998-2021 }
|
||
|
{ by Fast Reports Inc. }
|
||
|
{ }
|
||
|
{******************************************}
|
||
|
|
||
|
unit frxInsp;
|
||
|
|
||
|
interface
|
||
|
|
||
|
{$I frx.inc}
|
||
|
|
||
|
uses
|
||
|
{$IFNDEF FPC}Windows, Messages, {$ENDIF}
|
||
|
Types, SysUtils, Classes, Graphics, Controls, Forms,
|
||
|
Dialogs, ExtCtrls, StdCtrls, Buttons, frxDsgnIntf, frxPopupForm,
|
||
|
frxClass, Menus, ComCtrls, frxBaseForm, frxCtrls, frxDock
|
||
|
{$IFDEF FPC}
|
||
|
, LResources, LCLType, LMessages, LazHelper, LCLProc, LCLIntf
|
||
|
{$ENDIF}
|
||
|
{$IFDEF UseTabset}
|
||
|
, Tabs
|
||
|
{$ENDIF}
|
||
|
{$IFDEF Delphi6}
|
||
|
, Variants
|
||
|
{$ENDIF}
|
||
|
{$IFDEF DELPHI16}
|
||
|
, System.UITypes
|
||
|
{$ENDIF};
|
||
|
|
||
|
|
||
|
type
|
||
|
|
||
|
{ TfrxObjectInspector }
|
||
|
|
||
|
TfrxObjectInspector = class(TfrxDockForm)
|
||
|
ObjectsCB: TComboBox;
|
||
|
PopupMenu1: TPopupMenu;
|
||
|
N11: TMenuItem;
|
||
|
N21: TMenuItem;
|
||
|
N31: TMenuItem;
|
||
|
BackPanel: TPanel;
|
||
|
Box: TScrollBox;
|
||
|
PB: TPaintBox;
|
||
|
Edit1: TEdit;
|
||
|
EditPanel: TPanel;
|
||
|
EditBtn: TSpeedButton;
|
||
|
ComboPanel: TPanel;
|
||
|
ComboBtn: TSpeedButton;
|
||
|
HintPanel: TScrollBox;
|
||
|
Splitter1: TSplitter;
|
||
|
PropL: TLabel;
|
||
|
DescrL: TLabel;
|
||
|
N41: TMenuItem;
|
||
|
N51: TMenuItem;
|
||
|
N61: TMenuItem;
|
||
|
LInstruction: TLabel;
|
||
|
procedure PBPaint(Sender: TObject);
|
||
|
procedure FormResize(Sender: TObject);
|
||
|
procedure PBMouseDown(Sender: TObject; Button: TMouseButton;
|
||
|
Shift: TShiftState; X, Y: Integer);
|
||
|
procedure PBMouseUp(Sender: TObject; Button: TMouseButton;
|
||
|
Shift: TShiftState; X, Y: Integer);
|
||
|
procedure PBMouseMove(Sender: TObject; Shift: TShiftState; X,
|
||
|
Y: Integer);
|
||
|
procedure Edit1KeyDown(Sender: TObject; var Key: Word;
|
||
|
Shift: TShiftState);
|
||
|
procedure Edit1KeyPress(Sender: TObject; var Key: Char);
|
||
|
procedure EditBtnClick(Sender: TObject);
|
||
|
procedure ComboBtnClick(Sender: TObject);
|
||
|
procedure Edit1MouseDown(Sender: TObject; Button: TMouseButton;
|
||
|
Shift: TShiftState; X, Y: Integer);
|
||
|
procedure ObjectsCBClick(Sender: TObject);
|
||
|
procedure ObjectsCBDrawItem(Control: TWinControl; Index: Integer;
|
||
|
Rect: TRect; State: TOwnerDrawState);
|
||
|
procedure PBDblClick(Sender: TObject);
|
||
|
procedure FormMouseWheelDown(Sender: TObject; Shift: TShiftState;
|
||
|
MousePos: TPoint; var Handled: Boolean);
|
||
|
procedure FormMouseWheelUp(Sender: TObject; Shift: TShiftState;
|
||
|
MousePos: TPoint; var Handled: Boolean);
|
||
|
procedure FormEndDock(Sender, Target: TObject; X, Y: Integer);
|
||
|
procedure ComboBtnMouseDown(Sender: TObject; Button: TMouseButton;
|
||
|
Shift: TShiftState; X, Y: Integer);
|
||
|
procedure FormShow(Sender: TObject);
|
||
|
procedure TabChange(Sender: TObject);
|
||
|
procedure N11Click(Sender: TObject);
|
||
|
procedure N21Click(Sender: TObject);
|
||
|
procedure N31Click(Sender: TObject);
|
||
|
procedure FormDeactivate(Sender: TObject);
|
||
|
procedure FormKeyDown(Sender: TObject; var Key: Word;
|
||
|
Shift: TShiftState);
|
||
|
procedure FormKeyUp(Sender: TObject; var Key: Word;
|
||
|
Shift: TShiftState);
|
||
|
procedure ObjectsCBDropDown(Sender: TObject);
|
||
|
private
|
||
|
{ Private declarations }
|
||
|
FDesigner: TfrxCustomDesigner;
|
||
|
FDisableDblClick: Boolean;
|
||
|
FDisableUpdate: Boolean;
|
||
|
FDown: Boolean;
|
||
|
FEventList: TfrxPropertyList;
|
||
|
FHintWindow: THintWindow;
|
||
|
FItemIndex: Integer;
|
||
|
FLastPosition: String;
|
||
|
FList: TfrxPropertyList;
|
||
|
FPopupForm: TfrxPopupForm;
|
||
|
FPopupLB: TListBox;
|
||
|
FPopupLBVisible: Boolean;
|
||
|
FPropertyList: TfrxPropertyList;
|
||
|
FPanel: TPanel;
|
||
|
FRowHeight: Integer;
|
||
|
FSelectedObjects: TfrxSelectedObjectsList;
|
||
|
FSplitterPos: Integer;
|
||
|
{$IFDEF UseTabset}
|
||
|
FTabs: TTabSet;
|
||
|
{$ELSE}
|
||
|
FTabs: TTabControl;
|
||
|
{$ENDIF}
|
||
|
{$IFNDEF FPC}
|
||
|
FTempBMP: TBitmap;
|
||
|
{$ENDIF}
|
||
|
FTempList: TfrxSelectedObjectsList;
|
||
|
FTickCount: UInt;
|
||
|
FUpdatingObjectsCB: Boolean;
|
||
|
FUpdatingPB: Boolean;
|
||
|
FOnSelectionChanged: TNotifyEvent;
|
||
|
FOnModify: TNotifyEvent;
|
||
|
FComboBtnGlyph: TBitmap;
|
||
|
FEditBtnGlyph: TBitmap;
|
||
|
FFilter: String;
|
||
|
FFilterEdit: TfrxFilterEdit;
|
||
|
FFileterMinWidth: Integer;
|
||
|
FFileterMaxWidth: Integer;
|
||
|
FColor: TColor;
|
||
|
FSavedPositions: TStringList;
|
||
|
FSavePosLocked: Boolean;
|
||
|
FMaxSavedPos: Integer;
|
||
|
FFavorPress: Boolean;
|
||
|
FIsFavorZone: Boolean;
|
||
|
FFavorites: TStringList;
|
||
|
FFullList, FFavoritesList: TfrxPropertyList;
|
||
|
function Count: Integer;
|
||
|
function GetItem(Index: Integer): TfrxPropertyItem;
|
||
|
function GetName(Index: Integer): String;
|
||
|
function GetOffset(Index: Integer): Integer;
|
||
|
function GetType(Index: Integer): TfrxPropertyAttributes;
|
||
|
function GetValue(Index: Integer): String;
|
||
|
procedure AdjustControls;
|
||
|
procedure CMMouseLeave(var Msg: TMessage); message CM_MouseLeave;
|
||
|
procedure DrawOneLine({$IFDEF FPC}ACanvas: TCanvas;{$ENDIF}
|
||
|
i: Integer; Selected: Boolean);
|
||
|
procedure DoModify;
|
||
|
procedure SetObjects(Value: TList);
|
||
|
procedure SetItemIndex(Value: Integer);
|
||
|
procedure SetSelectedObjects(Value: TfrxSelectedObjectsList);
|
||
|
procedure SetValue(Index: Integer; Value: String);
|
||
|
procedure LBClick(Sender: TObject);
|
||
|
procedure FilterChange(Sender: TObject);
|
||
|
function GetSplitter1Pos: Integer;
|
||
|
procedure SetSplitter1Pos(const Value: Integer);
|
||
|
procedure SetFilter(const Value: String);
|
||
|
procedure SetFileterMaxWidth(const Value: Integer);
|
||
|
procedure SetFileterMinWidth(const Value: Integer);
|
||
|
procedure PBOnDragDrop(Sender, Source: TObject; X, Y: Integer);
|
||
|
procedure PBOnDragOver(Sender, Source: TObject; X, Y: Integer;
|
||
|
State: TDragState; var Accept: Boolean);
|
||
|
procedure RestorePosition;
|
||
|
procedure SavePosition;
|
||
|
procedure SetFavoritesActive(const Value: Boolean);
|
||
|
function GetFavoritesActive: Boolean;
|
||
|
procedure RebildFavorites;
|
||
|
procedure PBRePaint;
|
||
|
function FindProp(PropertyList: TfrxPropertyList; FullName: String): Integer;
|
||
|
protected
|
||
|
procedure LoadFormPreferences(PreferencesStorage: TObject; DefPreferencesStorage: TObject); override;
|
||
|
procedure SaveFormPreferences(PreferencesStorage: TObject; DefPreferencesStorage: TObject); override;
|
||
|
public
|
||
|
{ Public declarations }
|
||
|
constructor Create(AOwner: TComponent); override;
|
||
|
destructor Destroy; override;
|
||
|
procedure DisableUpdate;
|
||
|
procedure EnableUpdate;
|
||
|
procedure Inspect(AObjects: array of TPersistent);
|
||
|
procedure SetColor(Color: TColor);
|
||
|
procedure UpdateProperties;
|
||
|
procedure UpdateFormPPI(aNewPPI: Integer); override;
|
||
|
procedure SetActiveProperty(const PropName: String);
|
||
|
property Objects: TList write SetObjects;
|
||
|
property ItemIndex: Integer read FItemIndex write SetItemIndex;
|
||
|
property Filter: String read FFilter write SetFilter;
|
||
|
property FileterMinWidth: Integer read FFileterMinWidth write SetFileterMinWidth;
|
||
|
property FileterMaxWidth: Integer read FFileterMaxWidth write SetFileterMaxWidth;
|
||
|
property FavoritesAcrive: Boolean read GetFavoritesActive write SetFavoritesActive;
|
||
|
property SelectedObjects: TfrxSelectedObjectsList read FSelectedObjects write SetSelectedObjects;
|
||
|
property SplitterPos: Integer read FSplitterPos write FSplitterPos;
|
||
|
property Splitter1Pos: Integer read GetSplitter1Pos write SetSplitter1Pos;
|
||
|
property OnModify: TNotifyEvent read FOnModify write FOnModify;
|
||
|
property OnSelectionChanged: TNotifyEvent read FOnSelectionChanged write FOnSelectionChanged;
|
||
|
end;
|
||
|
|
||
|
const FavorButt = ssCtrl;
|
||
|
|
||
|
implementation
|
||
|
{$IFDEF FPC}
|
||
|
{$R *.lfm}
|
||
|
{$ELSE}
|
||
|
{$R *.DFM}
|
||
|
{$ENDIF}
|
||
|
|
||
|
uses typinfo, frxUtils, frxRes, frxrcInsp{$IFDEF LCLGTK2}, frxDesgn{$ENDIF}, IniFiles;
|
||
|
|
||
|
|
||
|
type
|
||
|
TInspPanel = class(TPanel)
|
||
|
protected
|
||
|
procedure WMEraseBackground(var Message: TMessage); message WM_ERASEBKGND;
|
||
|
procedure Paint; override;
|
||
|
end;
|
||
|
|
||
|
THackWinControl = class(TWinControl);
|
||
|
|
||
|
|
||
|
{ TInspPanel }
|
||
|
|
||
|
procedure TInspPanel.WMEraseBackground(var Message: TMessage);
|
||
|
begin
|
||
|
// empty method
|
||
|
end;
|
||
|
|
||
|
procedure TInspPanel.Paint;
|
||
|
begin
|
||
|
// empty method
|
||
|
end;
|
||
|
|
||
|
|
||
|
{ TfrxObjectInspector }
|
||
|
|
||
|
constructor TfrxObjectInspector.Create(AOwner: TComponent);
|
||
|
begin
|
||
|
if not (AOwner is TfrxCustomDesigner) then
|
||
|
raise Exception.Create('The Owner of the object inspector should be TfrxCustomDesigner');
|
||
|
inherited Create(AOwner);
|
||
|
FSavedPositions := TStringList.Create;
|
||
|
FItemIndex := -1;
|
||
|
FMaxSavedPos := 20;
|
||
|
FFileterMinWidth := 60;
|
||
|
FFileterMaxWidth := 200;
|
||
|
{$IFNDEF FPC}
|
||
|
FTempBMP := TBitmap.Create;
|
||
|
{$ENDIF}
|
||
|
FTempList := TfrxSelectedObjectsList.Create;
|
||
|
FDesigner := TfrxCustomDesigner(AOwner);
|
||
|
FHintWindow := THintWindow.Create(Self);
|
||
|
FHintWindow.Color := clInfoBk;
|
||
|
FColor := clWindow;
|
||
|
FPanel := TInspPanel.Create(Self);
|
||
|
with FPanel do
|
||
|
begin
|
||
|
Parent := Box;
|
||
|
BevelInner := bvNone;
|
||
|
BevelOuter := bvNone;
|
||
|
end;
|
||
|
PB.Parent := FPanel;
|
||
|
PB.OnDragDrop := PBOnDragDrop;
|
||
|
PB.OnDragOver := PBOnDragOver;
|
||
|
ComboPanel.Parent := FPanel;
|
||
|
EditPanel.Parent := FPanel;
|
||
|
Edit1.Parent := FPanel;
|
||
|
{$IFDEF UseTabset}
|
||
|
Box.BevelKind := bkFlat;
|
||
|
HintPanel.BevelKind := bkFlat;
|
||
|
{$ELSE}
|
||
|
Box.BorderStyle := bsSingle;
|
||
|
HintPanel.BorderStyle := bsSingle;
|
||
|
{$IFDEF Delphi7}
|
||
|
Box.ControlStyle := Box.ControlStyle + [csNeedsBorderPaint];
|
||
|
HintPanel.ControlStyle := HintPanel.ControlStyle + [csNeedsBorderPaint];
|
||
|
{$ENDIF}
|
||
|
{$ENDIF}
|
||
|
|
||
|
{$IFDEF UseTabset}
|
||
|
FTabs := TTabSet.Create(Self);
|
||
|
FTabs.OnClick := TabChange;
|
||
|
FTabs.ShrinkToFit := True;
|
||
|
FTabs.Style := tsSoftTabs;
|
||
|
FTabs.TabPosition := tpTop;
|
||
|
{$ELSE}
|
||
|
FTabs := TTabControl.Create(Self);
|
||
|
FTabs.OnChange := TabChange;
|
||
|
{$ENDIF}
|
||
|
FTabs.Parent := Self;
|
||
|
FFilterEdit := TfrxFilterEdit.Create(Self);
|
||
|
FFilterEdit.OnFilterChanged := FilterChange;
|
||
|
FFilterEdit.Parent := FTabs;
|
||
|
FTabs.SendToBack;
|
||
|
FTabs.Tabs.Add(frxResources.Get('oiProp'));
|
||
|
FTabs.Tabs.Add(frxResources.Get('oiEvent'));
|
||
|
FTabs.Tabs.Add(frxResources.Get('oiFavorites'));
|
||
|
FTabs.TabIndex := 0;
|
||
|
FSplitterPos := PB.Width div 2;
|
||
|
AutoScroll := False;
|
||
|
{$IFNDEF DELPHI22}
|
||
|
FormResize(nil);
|
||
|
{$ENDIF}
|
||
|
Caption := frxGet(2000);
|
||
|
LInstruction.Alignment := taCenter;
|
||
|
LInstruction.Caption := frxResources.Get('oiFavIns');
|
||
|
FFavorPress := False;
|
||
|
FFavorites := TStringList.Create();
|
||
|
FFavorites.Delimiter := '/';
|
||
|
FFavorites.Sorted := True;
|
||
|
end;
|
||
|
|
||
|
destructor TfrxObjectInspector.Destroy;
|
||
|
begin
|
||
|
FFavorites.Free;
|
||
|
{$IFNDEF FPC}
|
||
|
FTempBMP.Free;
|
||
|
{$ENDIF}
|
||
|
FTempList.Free;
|
||
|
if FPropertyList <> nil then
|
||
|
FPropertyList.Free;
|
||
|
if FEventList <> nil then
|
||
|
FEventList.Free;
|
||
|
if FFullList <> nil then
|
||
|
FFullList.Free;
|
||
|
if FFavoritesList <> nil then
|
||
|
FFavoritesList.Free;
|
||
|
if Assigned(FComboBtnGlyph) then
|
||
|
FreeAndNil(FComboBtnGlyph);
|
||
|
if Assigned(FEditBtnGlyph) then
|
||
|
FreeAndNil(FEditBtnGlyph);
|
||
|
FreeAndNil(FSavedPositions);
|
||
|
inherited;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.UpdateProperties;
|
||
|
begin
|
||
|
SetSelectedObjects(FSelectedObjects);
|
||
|
end;
|
||
|
|
||
|
|
||
|
procedure TfrxObjectInspector.UpdateFormPPI(aNewPPI: Integer);
|
||
|
var
|
||
|
r: TRect;
|
||
|
ImgList: TImageList;
|
||
|
|
||
|
procedure ClearBitmap(aBitmap: TBitmap);
|
||
|
begin
|
||
|
aBitmap.Width := 0;
|
||
|
aBitmap.Height := 0;
|
||
|
end;
|
||
|
|
||
|
begin
|
||
|
if aNewPPI > frx_DefaultPPI then
|
||
|
begin
|
||
|
if FComboBtnGlyph = nil then
|
||
|
begin
|
||
|
FComboBtnGlyph := TBitmap.Create;
|
||
|
FComboBtnGlyph.Assign(ComboBtn.Glyph);
|
||
|
end;
|
||
|
if FEditBtnGlyph = nil then
|
||
|
begin
|
||
|
FEditBtnGlyph := TBitmap.Create;
|
||
|
FEditBtnGlyph.Assign(EditBtn.Glyph);
|
||
|
end;
|
||
|
ComboBtn.Glyph.Width := Round(12 * aNewPPI / frx_DefaultPPI);
|
||
|
ComboBtn.Glyph.Height := Round(12 * aNewPPI / frx_DefaultPPI);
|
||
|
r := Rect(0, 0, ComboBtn.Glyph.Width, ComboBtn.Glyph.Height);
|
||
|
ComboBtn.Glyph.Canvas.Lock;
|
||
|
ComboBtn.Glyph.Canvas.Brush.Color := clBtnFace;
|
||
|
ComboBtn.Glyph.Canvas.FillRect(r);
|
||
|
frxDrawArrow(ComboBtn.Glyph.Canvas, r, clBlack);
|
||
|
ComboBtn.Glyph.Canvas.Unlock;
|
||
|
ScaleBitmap(EditBtn.Glyph, aNewPPI);
|
||
|
end
|
||
|
else if aNewPPI = frx_DefaultPPI then
|
||
|
begin
|
||
|
if Assigned(FComboBtnGlyph) then
|
||
|
ComboBtn.Glyph.Assign(FComboBtnGlyph);
|
||
|
if Assigned(FEditBtnGlyph) then
|
||
|
EditBtn.Glyph.Assign(FEditBtnGlyph);
|
||
|
end;
|
||
|
FRowHeight := Canvas.TextHeight('Wg') + {$IFDEF NONWINFPC}6{$ELSE}3{$ENDIF};
|
||
|
with Box.VertScrollBar do
|
||
|
begin
|
||
|
Increment := FRowHeight;
|
||
|
Tracking := True;
|
||
|
end;
|
||
|
ObjectsCB.ItemHeight := Round(16 * aNewPPI / frx_DefaultPPI);
|
||
|
ImgList := frxResources.MainButtonImages;
|
||
|
ClearBitmap(FFilterEdit.BitmapActive);
|
||
|
ClearBitmap(FFilterEdit.BitmapUnactive);
|
||
|
frxDrawIcon(ImgList, FFilterEdit.BitmapActive, 121, FFilterEdit.FilterColor);
|
||
|
frxDrawIcon(ImgList, FFilterEdit.BitmapUnactive, 122, FFilterEdit.FilterColor);
|
||
|
|
||
|
FormResize(nil);
|
||
|
FSplitterPos := PB.Width div 2;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.Inspect(AObjects: array of TPersistent);
|
||
|
var
|
||
|
i: Integer;
|
||
|
begin
|
||
|
FTempList.Clear;
|
||
|
FTempList.ClearInspectorList;
|
||
|
for i := Low(AObjects) to High(AObjects) do
|
||
|
FTempList.Add(AObjects[i]);
|
||
|
Objects := FTempList;
|
||
|
SelectedObjects := FTempList;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.ObjectsCBDropDown(Sender: TObject);
|
||
|
var
|
||
|
Index: Integer;
|
||
|
begin
|
||
|
ObjectsCB.Items.BeginUpdate;
|
||
|
Index := ObjectsCB.Items.IndexOfObject(nil);
|
||
|
if Index <> -1 then
|
||
|
ObjectsCB.Items.Delete(Index);
|
||
|
ObjectsCB.Items.EndUpdate;
|
||
|
end;
|
||
|
|
||
|
function TfrxObjectInspector.GetSplitter1Pos: Integer;
|
||
|
begin
|
||
|
Result := HintPanel.Height;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.SetSplitter1Pos(const Value: Integer);
|
||
|
begin
|
||
|
HintPanel.Height := Value;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.DisableUpdate;
|
||
|
begin
|
||
|
FDisableUpdate := True;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.EnableUpdate;
|
||
|
begin
|
||
|
FDisableUpdate := False;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.SaveFormPreferences(PreferencesStorage: TObject; DefPreferencesStorage: TObject);
|
||
|
var
|
||
|
Ini: TCustomIniFile;
|
||
|
lName: String;
|
||
|
lScale: Single;
|
||
|
begin
|
||
|
inherited;
|
||
|
if not(PreferencesStorage is TCustomIniFile) then Exit;
|
||
|
Ini := TCustomIniFile(PreferencesStorage);
|
||
|
lScale := CurrentFormPPI / frx_DefaultPPI;
|
||
|
lName := GetFormSectionName;
|
||
|
Ini.WriteInteger(lName, 'SplitPos', Round(SplitterPos / lScale));
|
||
|
Ini.WriteInteger(lName, 'Split1Pos', Round(Splitter1Pos / lScale));
|
||
|
Ini.WriteString(lName, 'Favorites', FFavorites.DelimitedText);
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.SavePosition;
|
||
|
|
||
|
function EnumProperties(p: TfrxPropertyList; var Index: Integer): String;
|
||
|
var
|
||
|
i: Integer;
|
||
|
begin
|
||
|
Result := '';
|
||
|
for i := 0 to p.Count - 1 do
|
||
|
begin
|
||
|
Dec(Index);
|
||
|
if Index < 0 then
|
||
|
begin
|
||
|
Result := p[i].Editor.GetName;
|
||
|
break;
|
||
|
end;
|
||
|
if (p[i].SubProperty <> nil) and p[i].Expanded then
|
||
|
Result := p[i].Editor.GetName + '.' + EnumProperties(p[i].SubProperty, Index);
|
||
|
if Index < 0 then
|
||
|
break;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
var
|
||
|
i, n: Integer;
|
||
|
begin
|
||
|
n := -1;
|
||
|
if FSelectedObjects.Count = 0 then Exit;
|
||
|
for i := 0 to FSavedPositions.Count - 1 do
|
||
|
if TObject(FSelectedObjects[0]).ClassType = TClass(FSavedPositions.Objects[i]) then
|
||
|
n := i;
|
||
|
i := ItemIndex;
|
||
|
FLastPosition := EnumProperties(FPropertyList, i);
|
||
|
if n > -1 then
|
||
|
FSavedPositions[n] := FLastPosition
|
||
|
else
|
||
|
begin
|
||
|
if FMaxSavedPos < FSavedPositions.Count then
|
||
|
FSavedPositions.Delete(0);
|
||
|
FSavedPositions.AddObject(FLastPosition, TObject(TObject(FSelectedObjects[0]).ClassType));
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.SetFavoritesActive(const Value: Boolean);
|
||
|
var
|
||
|
Repaint: Boolean;
|
||
|
begin
|
||
|
Repaint := Value <> FFavorPress;
|
||
|
FFavorPress := Value;
|
||
|
if Repaint then
|
||
|
PBRePaint;
|
||
|
end;
|
||
|
|
||
|
function TfrxObjectInspector.GetFavoritesActive: Boolean;
|
||
|
begin
|
||
|
Result := FFavorPress and (FTabs.TabIndex <> 1);
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.RebildFavorites;
|
||
|
var
|
||
|
i, j: Integer;
|
||
|
p: TfrxPropertyItem;
|
||
|
begin
|
||
|
while 0 < FFavoritesList.Count do
|
||
|
begin
|
||
|
p := FFavoritesList[0];
|
||
|
p.Collection := FFullList;
|
||
|
end;
|
||
|
for i := 0 to FFavorites.Count - 1 do
|
||
|
for j := 0 to FFullList.Count - 1 do
|
||
|
if (FFullList[j].Editor.GetName = FFavorites[i]) then
|
||
|
begin
|
||
|
FFullList[j].Collection := FFavoritesList;
|
||
|
break;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.PBRePaint;
|
||
|
begin
|
||
|
{$IFDEF FPC}
|
||
|
PB.Repaint;
|
||
|
{$ELSE}
|
||
|
PBPaint(nil);
|
||
|
{$ENDIF}
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.SetActiveProperty(const PropName: String);
|
||
|
var
|
||
|
i: Integer;
|
||
|
begin
|
||
|
if FSelectedObjects.Count = 0 then Exit;
|
||
|
i := FindProp(FPropertyList, PropName);
|
||
|
if i <> -1 then
|
||
|
SetItemIndex(i);
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.SetColor(Color: TColor);
|
||
|
var
|
||
|
ImgList: TImageList;
|
||
|
procedure ClearBitmap(aBitmap: TBitmap);
|
||
|
begin
|
||
|
aBitmap.Width := 0;
|
||
|
aBitmap.Height := 0;
|
||
|
end;
|
||
|
|
||
|
begin
|
||
|
ObjectsCB.Color := Color;
|
||
|
Box.Color := Color;
|
||
|
HintPanel.Color := Color;
|
||
|
Edit1.Color := Color;
|
||
|
FFilterEdit.FilterColor := Color;
|
||
|
ClearBitmap(FFilterEdit.BitmapActive);
|
||
|
ClearBitmap(FFilterEdit.BitmapUnactive);
|
||
|
ImgList := frxResources.MainButtonImages;
|
||
|
frxDrawIcon(ImgList, FFilterEdit.BitmapActive, 121, Color);
|
||
|
frxDrawIcon(ImgList, FFilterEdit.BitmapUnactive, 122, Color);
|
||
|
FColor := Color;
|
||
|
PB.Repaint;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.SetFileterMaxWidth(const Value: Integer);
|
||
|
begin
|
||
|
FFileterMaxWidth := Value;
|
||
|
FormResize(nil);
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.SetFileterMinWidth(const Value: Integer);
|
||
|
begin
|
||
|
FFileterMinWidth := Value;
|
||
|
FormResize(nil);
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.SetFilter(const Value: String);
|
||
|
begin
|
||
|
FFilter := Value;
|
||
|
UpdateProperties;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.SetObjects(Value: TList);
|
||
|
var
|
||
|
i: Integer;
|
||
|
s: String;
|
||
|
begin
|
||
|
ObjectsCB.Items.Clear;
|
||
|
for i := 0 to Value.Count - 1 do
|
||
|
begin
|
||
|
if TObject(Value[i]) is TComponent then
|
||
|
s := TComponent(Value[i]).Name + ': ' + TComponent(Value[i]).ClassName else
|
||
|
s := '';
|
||
|
ObjectsCB.Items.AddObject(s, Value[i]);
|
||
|
end;
|
||
|
ObjectsCB.Items.AddObject(FDesigner.Report.Name + ': ' + TComponent(FDesigner.Report).ClassName, FDesigner.Report);
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.SetSelectedObjects(Value: TfrxSelectedObjectsList);
|
||
|
var
|
||
|
s: String;
|
||
|
aList: TList;
|
||
|
|
||
|
procedure CreateLists;
|
||
|
var
|
||
|
i: Integer;
|
||
|
p: TfrxPropertyItem;
|
||
|
s: String;
|
||
|
begin
|
||
|
if FPropertyList <> nil then
|
||
|
FPropertyList.Free;
|
||
|
if FEventList <> nil then
|
||
|
FEventList.Free;
|
||
|
if FFullList <> nil then
|
||
|
FreeAndNil(FFullList);
|
||
|
if FFavoritesList <> nil then
|
||
|
FreeAndNil(FFavoritesList);
|
||
|
FEventList := nil;
|
||
|
FPropertyList := frxCreatePropertyList(Value.InspSelectedObjects, FDesigner, FFilter);
|
||
|
if (FPropertyList <> nil) then
|
||
|
begin
|
||
|
FFullList := frxCreatePropertyList(Value.InspSelectedObjects, FDesigner, FFilter);
|
||
|
FFavoritesList := TfrxPropertyList.Create(FDesigner);
|
||
|
RebildFavorites;
|
||
|
end;
|
||
|
if FPropertyList <> nil then
|
||
|
begin
|
||
|
FEventList := TfrxPropertyList.Create(FDesigner);
|
||
|
|
||
|
i := 0;
|
||
|
while i < FPropertyList.Count do
|
||
|
begin
|
||
|
p := FPropertyList[i];
|
||
|
s := String(p.Editor.PropInfo.PropType^.Name);
|
||
|
if (Pos('Tfrx', s) = 1) and (Pos('Event', s) = Length(s) - 4) then
|
||
|
p.Collection := FEventList else
|
||
|
Inc(i);
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
case (FTabs.TabIndex) of
|
||
|
0: FList := FPropertyList;
|
||
|
1: FList := FEventList;
|
||
|
2: FList := FFavoritesList;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
begin
|
||
|
FSelectedObjects := Value;
|
||
|
aList := FSelectedObjects.InspSelectedObjects;
|
||
|
CreateLists;
|
||
|
|
||
|
FUpdatingObjectsCB := True;
|
||
|
if aList.Count = 1 then
|
||
|
begin
|
||
|
ObjectsCB.ItemIndex := ObjectsCB.Items.IndexOfObject(aList[0]);
|
||
|
if ObjectsCB.ItemIndex = -1 then
|
||
|
begin
|
||
|
if TObject(aList[0]) is TComponent then
|
||
|
s := TComponent(aList[0]).Name + ': ' +
|
||
|
TComponent(aList[0]).ClassName;
|
||
|
if TComponent(aList[0]) is TfrxComponent then
|
||
|
begin
|
||
|
ObjectsCB.Items.AddObject(s, aList[0]);
|
||
|
ObjectsCB.ItemIndex := ObjectsCB.Items.IndexOfObject(aList[0]);
|
||
|
end
|
||
|
else if s <> '' then
|
||
|
ObjectsCB.ItemIndex := ObjectsCB.Items.Add(s);
|
||
|
end;
|
||
|
end
|
||
|
else
|
||
|
ObjectsCB.ItemIndex := -1;
|
||
|
FUpdatingObjectsCB := False;
|
||
|
|
||
|
FItemIndex := -1;
|
||
|
FormResize(nil);
|
||
|
// if Count > 0 then
|
||
|
// begin
|
||
|
// for i := 0 to Count - 1 do
|
||
|
// if GetName(i) = FLastPosition then
|
||
|
// begin
|
||
|
// ItemIndex := i;
|
||
|
// Exit;
|
||
|
// end;
|
||
|
// s := FLastPosition;
|
||
|
// ItemIndex := 0;
|
||
|
// FLastPosition := s;
|
||
|
// end;
|
||
|
RestorePosition;
|
||
|
end;
|
||
|
|
||
|
function TfrxObjectInspector.Count: Integer;
|
||
|
|
||
|
function EnumProperties(p: TfrxPropertyList): Integer;
|
||
|
var
|
||
|
i: Integer;
|
||
|
begin
|
||
|
Result := 0;
|
||
|
for i := 0 to p.Count - 1 do
|
||
|
begin
|
||
|
Inc(Result);
|
||
|
if (p[i].SubProperty <> nil) and p[i].Expanded then
|
||
|
Inc(Result, EnumProperties(p[i].SubProperty));
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
begin
|
||
|
if FList <> nil then
|
||
|
Result := EnumProperties(FList) else
|
||
|
Result := 0;
|
||
|
end;
|
||
|
|
||
|
function TfrxObjectInspector.GetItem(Index: Integer): TfrxPropertyItem;
|
||
|
|
||
|
function EnumProperties(p: TfrxPropertyList; var Index: Integer): TfrxPropertyItem;
|
||
|
var
|
||
|
i: Integer;
|
||
|
begin
|
||
|
Result := nil;
|
||
|
for i := 0 to p.Count - 1 do
|
||
|
begin
|
||
|
Dec(Index);
|
||
|
if Index < 0 then
|
||
|
begin
|
||
|
Result := p[i];
|
||
|
break;
|
||
|
end;
|
||
|
if (p[i].SubProperty <> nil) and p[i].Expanded then
|
||
|
Result := EnumProperties(p[i].SubProperty, Index);
|
||
|
if Index < 0 then
|
||
|
break;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
begin
|
||
|
if (Index >= 0) and (Index < Count) then
|
||
|
Result := EnumProperties(FList, Index) else
|
||
|
Result := nil;
|
||
|
end;
|
||
|
|
||
|
function TfrxObjectInspector.GetOffset(Index: Integer): Integer;
|
||
|
var
|
||
|
p: TfrxPropertyList;
|
||
|
begin
|
||
|
Result := 0;
|
||
|
p := TfrxPropertyList(GetItem(Index).Collection);
|
||
|
while p.Parent <> nil do
|
||
|
begin
|
||
|
Inc(Result);
|
||
|
p := p.Parent;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
function TfrxObjectInspector.GetName(Index: Integer): String;
|
||
|
begin
|
||
|
Result := GetItem(Index).Editor.GetName;
|
||
|
end;
|
||
|
|
||
|
function TfrxObjectInspector.GetType(Index: Integer): TfrxPropertyAttributes;
|
||
|
begin
|
||
|
Result := GetItem(Index).Editor.GetAttributes;
|
||
|
end;
|
||
|
|
||
|
function TfrxObjectInspector.GetValue(Index: Integer): String;
|
||
|
begin
|
||
|
Result := GetItem(Index).Editor.Value;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.DoModify;
|
||
|
var
|
||
|
i: Integer;
|
||
|
aList: TList;
|
||
|
begin
|
||
|
// {$IFDEF LCLGTK2}
|
||
|
// if Assigned(FDesigner.Report.Designer) then
|
||
|
// if TfrxDesignerForm(FDesigner.Report.Designer).LockSelectionChanged then
|
||
|
// begin
|
||
|
// TfrxDesignerForm(FDesigner.Report.Designer).LockSelectionChanged := False;
|
||
|
// Exit;
|
||
|
// end;
|
||
|
// {$ENDIF}
|
||
|
|
||
|
aList := FSelectedObjects.InspSelectedObjects;
|
||
|
if aList.Count = 1 then
|
||
|
begin
|
||
|
i := ObjectsCB.Items.IndexOfObject(aList[0]);
|
||
|
if i <> -1 then
|
||
|
begin
|
||
|
if TObject(aList[0]) is TComponent then
|
||
|
ObjectsCB.Items.Strings[i] := TComponent(aList[0]).Name + ': ' +
|
||
|
TComponent(aList[0]).ClassName;
|
||
|
ObjectsCB.ItemIndex := ObjectsCB.Items.IndexOfObject(aList[0]);
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
if Assigned(FOnModify) then
|
||
|
FOnModify(Self);
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.SetItemIndex(Value: Integer);
|
||
|
var
|
||
|
p: TfrxPropertyItem;
|
||
|
s: String;
|
||
|
begin
|
||
|
PropL.Caption := '';
|
||
|
DescrL.Caption := '';
|
||
|
if Value > Count - 1 then
|
||
|
Value := Count - 1;
|
||
|
if Value < 0 then
|
||
|
Value := -1;
|
||
|
|
||
|
Edit1.Visible := Count > 0;
|
||
|
if Count = 0 then Exit;
|
||
|
|
||
|
if FItemIndex <> -1 then
|
||
|
if Edit1.Modified then
|
||
|
begin
|
||
|
Edit1.Modified := False;
|
||
|
SetValue(FItemIndex, Edit1.Text);
|
||
|
end;
|
||
|
FItemIndex := Value;
|
||
|
|
||
|
if FItemIndex <> -1 then
|
||
|
begin
|
||
|
//FLastPosition := GetName(FItemIndex);
|
||
|
p := GetItem(FItemIndex);
|
||
|
s := GetName(FItemIndex);
|
||
|
PropL.Caption := s;
|
||
|
if TfrxPropertyList(p.Collection).Component <> nil then
|
||
|
begin
|
||
|
s := 'prop' + s + '.' + TfrxPropertyList(p.Collection).Component.ClassName;
|
||
|
if frxResources.Get(s) = s then
|
||
|
s := frxResources.Get('prop' + GetName(FItemIndex)) else
|
||
|
s := frxResources.Get(s);
|
||
|
DescrL.Caption := s;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
AdjustControls;
|
||
|
if not FSavePosLocked then
|
||
|
SavePosition;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.SetValue(Index: Integer; Value: String);
|
||
|
begin
|
||
|
try
|
||
|
GetItem(Index).Editor.Value := Value;
|
||
|
DoModify;
|
||
|
PBRePaint;
|
||
|
except
|
||
|
on E: Exception do
|
||
|
begin
|
||
|
frxErrorMsg(E.Message);
|
||
|
Edit1.Text := GetItem(Index).Editor.Value;
|
||
|
end;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.AdjustControls;
|
||
|
var
|
||
|
PropType: TfrxPropertyAttributes;
|
||
|
y, ww: Integer;
|
||
|
begin
|
||
|
if (csDocking in ControlState) or FDisableUpdate then Exit;
|
||
|
if FItemIndex = -1 then
|
||
|
begin
|
||
|
EditPanel.Visible := False;
|
||
|
ComboPanel.Visible := False;
|
||
|
Edit1.Visible := False;
|
||
|
FUpdatingPB := False;
|
||
|
PBRePaint;
|
||
|
Exit;
|
||
|
end;
|
||
|
|
||
|
FUpdatingPB := True;
|
||
|
PropType := GetType(FItemIndex);
|
||
|
|
||
|
EditPanel.Visible := paDialog in PropType;
|
||
|
ComboPanel.Visible := paValueList in PropType;
|
||
|
Edit1.ReadOnly := paReadOnly in PropType;
|
||
|
|
||
|
ww := PB.Width - FSplitterPos - 2;
|
||
|
y := FItemIndex * FRowHeight{$IFDEF NONWINFPC}-3{$ELSE}+1{$ENDIF};
|
||
|
if EditPanel.Visible then
|
||
|
begin
|
||
|
EditPanel.SetBounds(PB.Width - FRowHeight, y - 1, FRowHeight, FRowHeight - 1);
|
||
|
EditBtn.SetBounds(0, 0, EditPanel.Width, EditPanel.Height);
|
||
|
Dec(ww, FRowHeight);
|
||
|
end;
|
||
|
if ComboPanel.Visible then
|
||
|
begin
|
||
|
ComboPanel.SetBounds(PB.Width - FRowHeight, y - 1, FRowHeight, FRowHeight - 1);
|
||
|
ComboBtn.SetBounds(0, 0, ComboPanel.Width, ComboPanel.Height);
|
||
|
Dec(ww, FRowHeight);
|
||
|
end;
|
||
|
|
||
|
Edit1.Text := GetValue(FItemIndex);
|
||
|
Edit1.Modified := False;
|
||
|
Edit1.SetBounds(FSplitterPos + 2, y, ww, FRowHeight - 2);
|
||
|
Edit1.SelectAll;
|
||
|
|
||
|
if y + FRowHeight > Box.VertScrollBar.Position + Box.ClientHeight then
|
||
|
Box.VertScrollBar.Position := y - Box.ClientHeight + FRowHeight;
|
||
|
if y < Box.VertScrollBar.Position then
|
||
|
Box.VertScrollBar.Position := y - 1;
|
||
|
|
||
|
FUpdatingPB := False;
|
||
|
PBRePaint;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.DrawOneLine({$IFDEF FPC}ACanvas: TCanvas;{$ENDIF}
|
||
|
i: Integer; Selected: Boolean);
|
||
|
var
|
||
|
R: TRect;
|
||
|
s: String;
|
||
|
p: TfrxPropertyItem;
|
||
|
offs, add: Integer;
|
||
|
lScale: Single;
|
||
|
|
||
|
procedure LineInternal(x, y, dx, dy: Integer);
|
||
|
begin
|
||
|
{$IFDEF FPC}
|
||
|
ACanvas.MoveTo(x, y);
|
||
|
ACanvas.LineTo(x + dx, y + dy);
|
||
|
{$ELSE}
|
||
|
FTempBMP.Canvas.MoveTo(x, y);
|
||
|
FTempBMP.Canvas.LineTo(x + dx, y + dy);
|
||
|
{$ENDIF}
|
||
|
end;
|
||
|
|
||
|
const DefaultSquareSide = 9;
|
||
|
procedure DrawProperty;
|
||
|
var
|
||
|
x, y, y1, idx, w, SquareSide: Integer;
|
||
|
InnerRect: TRect;
|
||
|
begin
|
||
|
x := offs + GetOffset(i) * Round(12 * lScale);
|
||
|
y := 1 + i * FRowHeight;
|
||
|
y1 := y + Round(FRowHeight - DefaultSquareSide * lScale) div 2 - 1 ;
|
||
|
|
||
|
{$IFDEF FPC}
|
||
|
with ACanvas do
|
||
|
{$ELSE}
|
||
|
with FTempBMP.Canvas do
|
||
|
{$ENDIF}
|
||
|
begin
|
||
|
Pen.Color := clGray;
|
||
|
Brush.Color := clWhite;
|
||
|
w := 1;
|
||
|
if (FavoritesAcrive) then
|
||
|
begin
|
||
|
x := x - offs;
|
||
|
SquareSide := Round(9 * lScale);
|
||
|
InnerRect := Rect(x + 1 + add mod 2, y1 + add mod 2, x + 1 + SquareSide - add div 2, y1 + SquareSide - add div 2);
|
||
|
if add > 1 then
|
||
|
begin
|
||
|
w := add;
|
||
|
Inc(InnerRect.Right);
|
||
|
Inc(InnerRect.Bottom);
|
||
|
end;
|
||
|
if (s[1] = '+') or (s[1] = '-') then
|
||
|
s := Copy(s, 2, 255);
|
||
|
if (x = 0) then
|
||
|
begin
|
||
|
Pen.Width := w;
|
||
|
Rectangle(x + 1 - add div 2, y1 - add div 2, x + SquareSide + 1 + add , y1 + SquareSide + add);
|
||
|
|
||
|
Pen.Width := 1;
|
||
|
if (FFavorites.IndexOf(s) <> -1) then
|
||
|
begin
|
||
|
Brush.Color := clBlack;
|
||
|
FillRect(Rect(x + 1 - add div 2 + (w * 2 - add div 2), y1 - add div 2 + (w * 2 - add div 2), x + SquareSide + 1 + add - w * 2, y1 + SquareSide + add - w * 2));
|
||
|
end;
|
||
|
end;
|
||
|
Pen.Width := 1;
|
||
|
Inc(x, 2 + SquareSide + Round(2 * lScale));
|
||
|
end
|
||
|
else
|
||
|
if offs < Round(12 * lScale) then
|
||
|
begin
|
||
|
SquareSide := Round(9 * lScale);
|
||
|
InnerRect := Rect(x + 1 + add mod 2, y1 + add mod 2, x + 1 + SquareSide - add div 2, y1 + SquareSide - add div 2);
|
||
|
if add > 1 then
|
||
|
begin
|
||
|
w := add;
|
||
|
Inc(InnerRect.Right);
|
||
|
Inc(InnerRect.Bottom);
|
||
|
end;
|
||
|
Pen.Width := w;
|
||
|
Rectangle(x + 1 - add div 2, y1 - add div 2, x + SquareSide + 1 + add , y1 + SquareSide + add);
|
||
|
|
||
|
Pen.Width := 1;
|
||
|
for idx := 0 to w - 1 do
|
||
|
begin
|
||
|
LineInternal(InnerRect.Left + 2, y1 + SquareSide div 2 - (add div 2) + add mod 2 + idx, (InnerRect.Right - InnerRect.Left) - 4, 0);
|
||
|
if s[1] = '+' then
|
||
|
LineInternal(x + SquareSide div 2 + 1 - (add div 2) + add mod 2 + idx, InnerRect.Top + 2, 0, (InnerRect.Bottom - InnerRect.Top) - 4 );
|
||
|
end;
|
||
|
s := Copy(s, 2, 255);
|
||
|
Pen.Width := 1;
|
||
|
Inc(x, 2 + SquareSide + Round(2 * lScale));
|
||
|
end;
|
||
|
|
||
|
Brush.Style := bsClear;
|
||
|
if ((s = 'Name') or (s = 'Width') or (s = 'Height') or (s = 'Left') or (s = 'Top'))
|
||
|
and (GetOffset(i) = 0) then
|
||
|
Font.Style := [fsBold];
|
||
|
TextRect(R, x, y, s);
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
function IsDefault(i: Integer): Boolean;
|
||
|
var
|
||
|
Obj: TObject;
|
||
|
PropInfo: PPropInfo;
|
||
|
val: Integer;
|
||
|
PropItem: TfrxPropertyItem;
|
||
|
begin
|
||
|
Result := False;
|
||
|
PropItem := GetItem(i);
|
||
|
if PropItem = nil then Exit;
|
||
|
Obj := PropItem.Editor.Component;
|
||
|
if (Obj = nil) then
|
||
|
Exit;
|
||
|
PropInfo := GetPropInfo(Obj, PropItem.Editor.GetName);
|
||
|
if PropInfo = nil then Exit;
|
||
|
case PropInfo.PropType^.Kind of
|
||
|
tkInteger{$IFDEF FPC}, tkInt64{$ENDIF}
|
||
|
{$IFDEF DELPHI12}, tkInt64{$ENDIF},
|
||
|
tkSet, tkEnumeration{$IFDEF FPC}, tkBool{$ENDIF}:
|
||
|
begin
|
||
|
if PropInfo.Default = Integer($80000000) then
|
||
|
begin
|
||
|
Result := False;
|
||
|
Exit;
|
||
|
end;
|
||
|
val := GetOrdProp(Obj, PropItem.Editor.GetName);
|
||
|
Result := val <> PropInfo.Default;
|
||
|
end;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
begin
|
||
|
if Count > 0 then
|
||
|
{$IFDEF FPC}
|
||
|
with ACanvas do
|
||
|
{$ELSE}
|
||
|
with FTempBMP.Canvas do
|
||
|
{$ENDIF}
|
||
|
begin
|
||
|
Pen.Color := clBtnShadow;
|
||
|
Font.Assign(Self.Font);
|
||
|
R := Rect(0, i * FRowHeight, FSplitterPos, i * FRowHeight + FRowHeight - 1);
|
||
|
add := 0;
|
||
|
lScale := CurrentFormPPI / frx_DefaultPPI;
|
||
|
if lScale > 1 then
|
||
|
add := Round(lScale);
|
||
|
|
||
|
p := GetItem(i);
|
||
|
s := GetName(i);
|
||
|
if p.SubProperty <> nil then
|
||
|
begin
|
||
|
offs := Round(lScale - 1);
|
||
|
if p.Expanded then
|
||
|
s := '-' + s else
|
||
|
s := '+' + s;
|
||
|
end
|
||
|
else
|
||
|
offs := Round(13 * lScale);
|
||
|
|
||
|
p.Editor.ItemHeight := FRowHeight;
|
||
|
|
||
|
if Selected then
|
||
|
begin
|
||
|
Pen.Color := clBtnFace;
|
||
|
LineInternal(0, FRowHeight + -1 + i * FRowHeight, PB.Width, 0);
|
||
|
Brush.Color := clBtnFace;
|
||
|
FillRect(R);
|
||
|
DrawProperty;
|
||
|
end
|
||
|
else
|
||
|
begin
|
||
|
Pen.Color := clBtnFace;
|
||
|
LineInternal(0, FRowHeight + -1 + i * FRowHeight, PB.Width, 0);
|
||
|
Pen.Color := clBtnFace;
|
||
|
LineInternal(FSplitterPos - 1, 0 + i * FRowHeight, 0, FRowHeight);
|
||
|
DrawProperty;
|
||
|
Font.Color := clNavy;
|
||
|
if (IsDefault(i)) then
|
||
|
Font.Style := Font.Style + [fsBold];
|
||
|
if paOwnerDraw in p.Editor.GetAttributes then
|
||
|
p.Editor.OnDrawItem({$IFNDEF FPC}FTempBMP.Canvas{$ELSE}ACanvas{$ENDIF},
|
||
|
Rect(FSplitterPos + 2, 1 + i * FRowHeight, Width, 1 + (i + 1) * FRowHeight))
|
||
|
else
|
||
|
TextOut(FSplitterPos + 2, 1 + i * FRowHeight, GetValue(i));
|
||
|
Font.Style := Font.Style - [fsBold];
|
||
|
end;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
|
||
|
{ Form events }
|
||
|
|
||
|
procedure TfrxObjectInspector.FormShow(Sender: TObject);
|
||
|
begin
|
||
|
AdjustControls;
|
||
|
end;
|
||
|
|
||
|
{$IFDEF UseTabset}
|
||
|
type
|
||
|
THackTabSet = class(TTabSet);
|
||
|
{$ENDIF}
|
||
|
procedure TfrxObjectInspector.FormResize(Sender: TObject);
|
||
|
function GetTabsWidth: Integer;
|
||
|
var
|
||
|
{$IFNDEF UseTabset}
|
||
|
i: Integer;
|
||
|
{$ENDIF}
|
||
|
r: TRect;
|
||
|
begin
|
||
|
{$IFDEF UseTabset}
|
||
|
Result := 4;
|
||
|
r := FTabs.MinClientRect(FTabs.Tabs.Count, false);
|
||
|
Inc(Result, r.Right + 4);
|
||
|
{$ELSE}
|
||
|
Result := 4;
|
||
|
for i := 0 to FTabs.Tabs.Count - 1 do
|
||
|
begin
|
||
|
{$IFDEF FPC}
|
||
|
if FTabs.Tabs is TTabControlNoteBookStrings then
|
||
|
r := TTabControlNoteBookStrings(FTabs.Tabs).NoteBook.TabRect(i)
|
||
|
else
|
||
|
{$ENDIF}
|
||
|
r := FTabs.TabRect(i);
|
||
|
Inc(Result, r.Right - r.Left);
|
||
|
end;
|
||
|
{$ENDIF}
|
||
|
end;
|
||
|
|
||
|
var
|
||
|
h, lWidth: Integer;
|
||
|
begin
|
||
|
if (FTabs = nil) or (FFilterEdit = nil) then Exit;
|
||
|
{$IFDEF FPC}
|
||
|
FTabs.Font.Height := -11;
|
||
|
FTabs.Height := Abs(FTabs.Font.Height) + 8;
|
||
|
{$ELSE}
|
||
|
FTabs.Font.Height := Round(-11 * CurrentFormPPI / frx_DefaultPPI);
|
||
|
FTabs.Height := Abs(FTabs.Font.Height) + Round(8 * CurrentFormPPI / frx_DefaultPPI);
|
||
|
{$ENDIF}
|
||
|
h := FTabs.Height + 4;
|
||
|
if h < frxResources.MainButtonImages.Height then
|
||
|
h := frxResources.MainButtonImages.Height + 4;
|
||
|
FTabs.TabHeight := h;
|
||
|
FTabs.SetBounds(0, ObjectsCB.Top + ObjectsCB.Height + 4, ClientWidth, h);
|
||
|
{$IFDEF UseTabset}
|
||
|
// calculates tabs width
|
||
|
if FTabs.HandleAllocated then
|
||
|
THackTabSet(FTabs).Paint;
|
||
|
{$ENDIF}
|
||
|
lWidth := FTabs.Width - GetTabsWidth;
|
||
|
if lWidth > FFileterMaxWidth then
|
||
|
lWidth := FFileterMaxWidth
|
||
|
else if lWidth < FFileterMinWidth then
|
||
|
FFilterEdit.Visible := False;
|
||
|
if not FFilterEdit.Visible and (lWidth > FFileterMinWidth) then
|
||
|
FFilterEdit.Visible := True;
|
||
|
h := FTabs.Height;
|
||
|
FFilterEdit.SetBounds(FTabs.Width - lWidth - 1, 1, lWidth, h - 3);
|
||
|
{$IFDEF UseTabset}
|
||
|
BackPanel.Top := FTabs.Top + FTabs.Height - 1;
|
||
|
{$ELSE}
|
||
|
BackPanel.Top := FTabs.Top + FTabs.Height - 2;
|
||
|
{$ENDIF}
|
||
|
BackPanel.Width := ClientWidth;
|
||
|
BackPanel.Height := ClientHeight - BackPanel.Top;
|
||
|
ObjectsCB.Width := ClientWidth;
|
||
|
|
||
|
FPanel.Height := Count * FRowHeight;
|
||
|
FPanel.Width := Box.ClientWidth;
|
||
|
AdjustControls;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.FormEndDock(Sender, Target: TObject; X, Y: Integer);
|
||
|
begin
|
||
|
FormResize(nil);
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.TabChange(Sender: TObject);
|
||
|
begin
|
||
|
if FDesigner.IsPreviewDesigner then
|
||
|
if (FTabs.TabIndex = 1) then
|
||
|
FTabs.TabIndex := 0;
|
||
|
|
||
|
case (FTabs.TabIndex) of
|
||
|
0: FList := FPropertyList;
|
||
|
1:
|
||
|
{$IFNDEF FR_VER_BASIC}
|
||
|
FList := FEventList;
|
||
|
{$ELSE}
|
||
|
FTabs.TabIndex := 0;
|
||
|
{$ENDIF}
|
||
|
2: FList := FFavoritesList;
|
||
|
end;
|
||
|
FItemIndex := -1;
|
||
|
FormResize(nil);
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.N11Click(Sender: TObject);
|
||
|
begin
|
||
|
if Edit1.Visible and Edit1.Focused then
|
||
|
Edit1.CutToClipboard
|
||
|
else if FFilterEdit.EditControl.Focused then
|
||
|
FFilterEdit.EditControl.CutToClipboard;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.N21Click(Sender: TObject);
|
||
|
begin
|
||
|
if Edit1.Visible and Edit1.Focused then
|
||
|
Edit1.PasteFromClipboard
|
||
|
else if FFilterEdit.EditControl.Focused then
|
||
|
FFilterEdit.EditControl.PasteFromClipboard;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.N31Click(Sender: TObject);
|
||
|
begin
|
||
|
if Edit1.Visible and Edit1.Focused then
|
||
|
Edit1.CopyToClipboard
|
||
|
else if FFilterEdit.EditControl.Focused then
|
||
|
FFilterEdit.EditControl.CopyToClipboard;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.FilterChange(Sender: TObject);
|
||
|
begin
|
||
|
SetFilter(FFilterEdit.EditControl.Text);
|
||
|
end;
|
||
|
|
||
|
function TfrxObjectInspector.FindProp(PropertyList: TfrxPropertyList;
|
||
|
FullName: String): Integer;
|
||
|
var
|
||
|
i: Integer;
|
||
|
PropName: String;
|
||
|
begin
|
||
|
Result := 0;
|
||
|
i := Pos('.', FullName);
|
||
|
if i > 0 then
|
||
|
begin
|
||
|
PropName := Copy(FullName, 1, i - 1);
|
||
|
FullName := Copy(FullName, i + 1, Length(FullName) - i);
|
||
|
end
|
||
|
else
|
||
|
begin
|
||
|
PropName := FullName;
|
||
|
FullName := '';
|
||
|
end;
|
||
|
for i := 0 to PropertyList.Count - 1 do
|
||
|
begin
|
||
|
PropertyList[i].Expanded := False;
|
||
|
if SameText(PropertyList[i].Editor.GetName, PropName) then
|
||
|
begin
|
||
|
PropertyList[i].Expanded := True;
|
||
|
Result := i;
|
||
|
if (FullName <> '') and Assigned(PropertyList[i].SubProperty) then
|
||
|
Result := Result + FindProp(PropertyList[i].SubProperty, FullName) + 1;
|
||
|
break;
|
||
|
end;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
|
||
|
procedure TfrxObjectInspector.FormDeactivate(Sender: TObject);
|
||
|
begin
|
||
|
if FDisableUpdate then Exit;
|
||
|
SetItemIndex(FItemIndex);
|
||
|
FavoritesAcrive := False;
|
||
|
end;
|
||
|
|
||
|
|
||
|
{ PB events }
|
||
|
|
||
|
procedure TfrxObjectInspector.PBPaint(Sender: TObject);
|
||
|
var
|
||
|
i: Integer;
|
||
|
r: TRect;
|
||
|
begin
|
||
|
if FUpdatingPB then Exit;
|
||
|
{$IFNDEF FPC}
|
||
|
r := PB.BoundsRect;
|
||
|
FTempBMP.Width := PB.Width;
|
||
|
FTempBMP.Height := PB.Height;
|
||
|
with FTempBMP.Canvas do
|
||
|
begin
|
||
|
Brush.Color := Box.Color;
|
||
|
FillRect(r);
|
||
|
end;
|
||
|
|
||
|
if not FDisableUpdate then
|
||
|
begin
|
||
|
for i := 0 to Count - 1 do
|
||
|
if i <> ItemIndex then
|
||
|
DrawOneLine(i, False);
|
||
|
if FItemIndex <> -1 then
|
||
|
DrawOneLine(ItemIndex, True);
|
||
|
end;
|
||
|
|
||
|
PB.Canvas.Draw(0, 0, FTempBMP);
|
||
|
{$ELSE}
|
||
|
// better use this one
|
||
|
with PB do
|
||
|
begin
|
||
|
r := BoundsRect;
|
||
|
Canvas.Brush.Color := Box.Brush.Color;
|
||
|
Canvas.Brush.Style:=bsSolid;
|
||
|
Canvas.FillRect(r);
|
||
|
if not FDisableUpdate then
|
||
|
begin
|
||
|
for i := 0 to Count - 1 do
|
||
|
if i <> ItemIndex then
|
||
|
DrawOneLine(Canvas,i, False);
|
||
|
if FItemIndex <> -1 then
|
||
|
DrawOneLine(Canvas,ItemIndex, True);
|
||
|
end;
|
||
|
end;
|
||
|
{$ENDIF}
|
||
|
LInstruction.Visible := (FTabs.TabIndex = 2) and (Count = 0)
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.RestorePosition;
|
||
|
var
|
||
|
i: Integer;
|
||
|
pName: String;
|
||
|
begin
|
||
|
if FSelectedObjects.Count = 0 then Exit;
|
||
|
pName := FLastPosition;
|
||
|
for i := 0 to FSavedPositions.Count - 1 do
|
||
|
if TObject(FSelectedObjects[0]).ClassType = TClass(FSavedPositions.Objects[i]) then
|
||
|
pName := FSavedPositions[i];
|
||
|
if pName = '' then Exit;
|
||
|
FSavePosLocked := True;
|
||
|
try
|
||
|
i := -1;
|
||
|
if FLastPosition <> pName then
|
||
|
i := FindProp(FPropertyList, FLastPosition);
|
||
|
{ check saved }
|
||
|
if i = -1 then
|
||
|
i := FindProp(FPropertyList, pName);
|
||
|
SetItemIndex(i);
|
||
|
FormResize(nil);
|
||
|
finally
|
||
|
FSavePosLocked := False;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.PBMouseDown(Sender: TObject;
|
||
|
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
||
|
var
|
||
|
p: TfrxPropertyItem;
|
||
|
n, fn, x1: Integer;
|
||
|
lScale: Single;
|
||
|
begin
|
||
|
FDisableDblClick := False;
|
||
|
if Count = 0 then Exit;
|
||
|
lScale := CurrentFormPPI / frx_DefaultPPI;
|
||
|
if PB.Cursor = crHSplit then
|
||
|
FDown := True
|
||
|
else
|
||
|
begin
|
||
|
n := Y div FRowHeight;
|
||
|
|
||
|
if (X > FSplitterPos) and (X < FSplitterPos + Round(15 * lScale)) and
|
||
|
(n >= 0) and (n < Count) then
|
||
|
begin
|
||
|
p := GetItem(n);
|
||
|
if p.Editor.ClassName = 'TfrxBooleanProperty' then
|
||
|
begin
|
||
|
p.Editor.Edit;
|
||
|
DoModify;
|
||
|
PBRePaint;
|
||
|
Exit;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
if (FavoritesAcrive) then
|
||
|
begin
|
||
|
x1 := Round(GetOffset(n) * 12 * lScale);
|
||
|
if (X > x1) and (X < x1 + Round(13 + lScale)) then
|
||
|
begin
|
||
|
fn := FFavorites.IndexOf(GetName(n));
|
||
|
if not(fn <> -1) then
|
||
|
FFavorites.Add(GetName(n))
|
||
|
else
|
||
|
FFavorites.Delete(fn);
|
||
|
RebildFavorites;
|
||
|
TabChange(Self);
|
||
|
AdjustControls;
|
||
|
PBRePaint;
|
||
|
Exit;
|
||
|
end
|
||
|
end;
|
||
|
|
||
|
ItemIndex := n;
|
||
|
Edit1.SetFocus;
|
||
|
FTickCount := GetTickCount;
|
||
|
|
||
|
p := GetItem(ItemIndex);
|
||
|
x1 := Round(GetOffset(ItemIndex) * 12 * lScale);
|
||
|
if (X > x1) and (X < x1 + Round(13 + lScale)) and (p.SubProperty <> nil) then
|
||
|
begin
|
||
|
p.Expanded := not p.Expanded;
|
||
|
FormResize(nil);
|
||
|
FDisableDblClick := True;
|
||
|
end;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.PBMouseUp(Sender: TObject;
|
||
|
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
||
|
begin
|
||
|
FDown := False;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.PBOnDragDrop(Sender, Source: TObject; X,
|
||
|
Y: Integer);
|
||
|
var
|
||
|
n: Integer;
|
||
|
p: TfrxPropertyItem;
|
||
|
begin
|
||
|
if not Assigned(FDesigner) then Exit;
|
||
|
n := Y div FRowHeight;
|
||
|
ItemIndex := n;
|
||
|
p := GetItem(ItemIndex);
|
||
|
if p.Editor.PropInfo^.PropType^.Kind in [tkString, tkLString, tkWString{$IFDEF DEL12ORFPC}, tkUString{$ENDIF}
|
||
|
{$IFDEF FPC}, tkAString{$ENDIF}] then
|
||
|
begin
|
||
|
SetValue(n, FDesigner.GetDataSelectedAsExp);
|
||
|
AdjustControls;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.PBOnDragOver(Sender, Source: TObject; X,
|
||
|
Y: Integer; State: TDragState; var Accept: Boolean);
|
||
|
begin
|
||
|
Accept := Assigned(FDesigner) and (FDesigner.IsDataTree(Source));
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.PBMouseMove(Sender: TObject;
|
||
|
Shift: TShiftState; X, Y: Integer);
|
||
|
var
|
||
|
n, OffsetX, MaxWidth: Integer;
|
||
|
s: String;
|
||
|
HideHint: Boolean;
|
||
|
|
||
|
procedure ShowHint(const s: String; x, y: Integer);
|
||
|
var
|
||
|
HintRect: TRect;
|
||
|
p: TPoint;
|
||
|
begin
|
||
|
p := PB.ClientToScreen(Point(x - 2, y - 2));
|
||
|
HintRect := FHintWindow.CalcHintRect(1000, s, nil);
|
||
|
OffsetRect(HintRect, p.X, p.Y);
|
||
|
FHintWindow.ActivateHint(HintRect, s);
|
||
|
HideHint := False;
|
||
|
end;
|
||
|
|
||
|
begin
|
||
|
HideHint := True;
|
||
|
FIsFavorZone := (X > 0) and (X < FSplitterPos);
|
||
|
SetFavoritesActive(FIsFavorZone and (ssCtrl in Shift));
|
||
|
if not FDown then
|
||
|
begin
|
||
|
if (X > FSplitterPos - 4) and (X < FSplitterPos + 2) then
|
||
|
PB.Cursor := crHSplit
|
||
|
else
|
||
|
begin
|
||
|
PB.Cursor := crDefault;
|
||
|
|
||
|
{ hint window }
|
||
|
n := Y div FRowHeight;
|
||
|
if (X > 12) and (n >= 0) and (n < Count) then
|
||
|
begin
|
||
|
if X <= FSplitterPos - 4 then
|
||
|
begin
|
||
|
OffsetX := (GetOffset(n) + 1) * 12;
|
||
|
s := GetName(n);
|
||
|
MaxWidth := FSplitterPos - OffsetX;
|
||
|
end
|
||
|
else
|
||
|
begin
|
||
|
OffsetX := FSplitterPos + 1;
|
||
|
s := GetValue(n);
|
||
|
MaxWidth := PB.ClientWidth - FSplitterPos;
|
||
|
if n = ItemIndex then
|
||
|
MaxWidth := 1000;
|
||
|
end;
|
||
|
|
||
|
if PB.Canvas.TextWidth(s) > MaxWidth then
|
||
|
ShowHint(s, OffsetX, n * FRowHeight);
|
||
|
end;
|
||
|
end;
|
||
|
end
|
||
|
else
|
||
|
begin
|
||
|
if (x > 30) and (x < PB.ClientWidth - 30) then
|
||
|
FSplitterPos := X;
|
||
|
AdjustControls;
|
||
|
end;
|
||
|
|
||
|
if HideHint then
|
||
|
FHintWindow.ReleaseHandle;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.PBDblClick(Sender: TObject);
|
||
|
var
|
||
|
p: TfrxPropertyItem;
|
||
|
begin
|
||
|
if (Count = 0) or FDisableDblClick then Exit;
|
||
|
|
||
|
p := GetItem(ItemIndex);
|
||
|
if (p <> nil) and (p.SubProperty <> nil) then
|
||
|
begin
|
||
|
p.Expanded := not p.Expanded;
|
||
|
FormResize(nil);
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
|
||
|
{ Edit1 events }
|
||
|
|
||
|
procedure TfrxObjectInspector.Edit1MouseDown(Sender: TObject;
|
||
|
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
||
|
begin
|
||
|
if GetTickCount - FTickCount < GetDoubleClickTime then
|
||
|
EditBtnClick(nil);
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.Edit1KeyDown(Sender: TObject; var Key: Word;
|
||
|
Shift: TShiftState);
|
||
|
var
|
||
|
i: Integer;
|
||
|
begin
|
||
|
if Count = 0 then Exit;
|
||
|
if Key = vk_Escape then
|
||
|
begin
|
||
|
{$IFDEF FPC}
|
||
|
Edit1.Undo;
|
||
|
{$ELSE}
|
||
|
Edit1.Perform(EM_UNDO, 0, 0);
|
||
|
{$ENDIF}
|
||
|
Edit1.Modified := False;
|
||
|
end;
|
||
|
if Key = vk_Up then
|
||
|
begin
|
||
|
if ItemIndex > 0 then
|
||
|
ItemIndex := ItemIndex - 1;
|
||
|
Key := 0;
|
||
|
end
|
||
|
else if Key = vk_Down then
|
||
|
begin
|
||
|
if ItemIndex < Count - 1 then
|
||
|
ItemIndex := ItemIndex + 1;
|
||
|
Key := 0;
|
||
|
end
|
||
|
else if Key = vk_Prior then
|
||
|
begin
|
||
|
i := Box.Height div FRowHeight;
|
||
|
i := ItemIndex - i;
|
||
|
if i < 0 then
|
||
|
i := 0;
|
||
|
ItemIndex := i;
|
||
|
Key := 0;
|
||
|
end
|
||
|
else if Key = vk_Next then
|
||
|
begin
|
||
|
i := Box.Height div FRowHeight;
|
||
|
i := ItemIndex + i;
|
||
|
ItemIndex := i;
|
||
|
Key := 0;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.Edit1KeyPress(Sender: TObject; var Key: Char);
|
||
|
begin
|
||
|
if Key = #13 then
|
||
|
begin
|
||
|
if paDialog in GetType(ItemIndex) then
|
||
|
EditBtnClick(nil)
|
||
|
else
|
||
|
if Edit1.Modified then
|
||
|
begin
|
||
|
Edit1.Modified := False;
|
||
|
SetValue(ItemIndex, Edit1.Text);
|
||
|
end;
|
||
|
Edit1.SelectAll;
|
||
|
Key := #0;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
|
||
|
{ EditBtn and ComboBtn events }
|
||
|
|
||
|
procedure TfrxObjectInspector.EditBtnClick(Sender: TObject);
|
||
|
begin
|
||
|
if GetItem(ItemIndex).Editor.Edit then
|
||
|
begin
|
||
|
ItemIndex := FItemIndex;
|
||
|
DoModify;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.ComboBtnMouseDown(Sender: TObject;
|
||
|
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
||
|
begin
|
||
|
FPopupLBVisible := GetTickCount - frxPopupFormCloseTime < 100;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.ComboBtnClick(Sender: TObject);
|
||
|
var
|
||
|
i, wItems, nItems, pWidth, pHeight: Integer;
|
||
|
p: TPoint;
|
||
|
CurrMonitor: TMonitor;
|
||
|
begin
|
||
|
if FPopupLBVisible then
|
||
|
Edit1.SetFocus
|
||
|
else
|
||
|
begin
|
||
|
FPopupForm := TfrxPopupForm.Create(Self);
|
||
|
FPopupLB := TListBox.Create(FPopupForm);
|
||
|
with FPopupLB do
|
||
|
begin
|
||
|
Parent := FPopupForm;
|
||
|
Color := FColor;
|
||
|
{$IFNDEF FPC}
|
||
|
Ctl3D := False;
|
||
|
{$ENDIF}
|
||
|
Align := alClient;
|
||
|
if paOwnerDraw in GetItem(FItemIndex).Editor.GetAttributes then
|
||
|
Style := lbOwnerDrawFixed;
|
||
|
OnClick := LBClick;
|
||
|
OnDrawItem := GetItem(FItemIndex).Editor.OnDrawLBItem;
|
||
|
GetItem(FItemIndex).Editor.GetValues;
|
||
|
Items.Assign(GetItem(FItemIndex).Editor.Values);
|
||
|
{$IFDEF NONWINFPC}
|
||
|
pHeight := FPopupForm.Canvas.TextHeight('Wg') + 6;
|
||
|
{$ELSE}
|
||
|
pHeight := FPopupForm.Canvas.TextHeight('Wg') + 3;
|
||
|
{$ENDIF}
|
||
|
pWidth := Round((PB.Width - FSplitterPos) / (CurrentFormPPI / FPopupForm.CurrentFormPPI));
|
||
|
ItemHeight := pHeight;
|
||
|
if Items.Count > 0 then
|
||
|
begin
|
||
|
ItemIndex := Items.IndexOf(GetValue(FItemIndex));
|
||
|
wItems := 0;
|
||
|
for i := 0 to Items.Count - 1 do
|
||
|
begin
|
||
|
if Canvas.TextWidth(Items[i]) > wItems then
|
||
|
wItems := Canvas.TextWidth(Items[i]);
|
||
|
end;
|
||
|
|
||
|
Inc(wItems, 8);
|
||
|
if paOwnerDraw in GetItem(FItemIndex).Editor.GetAttributes then
|
||
|
Inc(wItems, GetItem(FItemIndex).Editor.GetExtraLBSize);
|
||
|
nItems := Items.Count;
|
||
|
if nItems > 8 then
|
||
|
begin
|
||
|
nItems := 8;
|
||
|
Inc(wItems, GetSystemMetrics(SM_CXVSCROLL));
|
||
|
end;
|
||
|
|
||
|
{$IFDEF NONWINFPC}
|
||
|
pHeight := 20;
|
||
|
{$ELSE}
|
||
|
pHeight := ItemHeight + 2;
|
||
|
{$ENDIF}
|
||
|
|
||
|
p := Edit1.ClientToScreen(Point(0, Edit1.Height));
|
||
|
if wItems < pWidth then
|
||
|
FPopupForm.SetBounds(p.X - 3, p.Y,
|
||
|
pWidth + 1, nItems * pHeight)
|
||
|
else
|
||
|
FPopupForm.SetBounds(p.X + (pWidth - wItems) - 2, p.Y,
|
||
|
wItems, nItems * pHeight);
|
||
|
if (FPopupForm.Left < 0) and (Abs(FPopupForm.Left) < FPopupForm.Width) then
|
||
|
FPopupForm.Left := 0;
|
||
|
|
||
|
pHeight := Screen.Height;
|
||
|
CurrMonitor := Screen.MonitorFromWindow(FPopupForm.Handle);
|
||
|
if CurrMonitor <> nil then
|
||
|
pHeight := CurrMonitor.Top + CurrMonitor.Height;
|
||
|
if FPopupForm.Top + FPopupForm.Height > pHeight then
|
||
|
FPopupForm.Top := pHeight - FPopupForm.Height;
|
||
|
FDisableUpdate := True;
|
||
|
FPopupForm.Show;
|
||
|
FDisableUpdate := False;
|
||
|
end;
|
||
|
end;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.LBClick(Sender: TObject);
|
||
|
begin
|
||
|
Edit1.Text := FPopupLB.Items[FPopupLB.ItemIndex];
|
||
|
SetValue(ItemIndex, Edit1.Text);
|
||
|
FPopupForm.Hide;
|
||
|
Edit1.SetFocus;
|
||
|
Edit1.SelectAll;
|
||
|
end;
|
||
|
|
||
|
|
||
|
procedure TfrxObjectInspector.LoadFormPreferences(PreferencesStorage: TObject; DefPreferencesStorage: TObject);
|
||
|
var
|
||
|
Ini: TCustomIniFile;
|
||
|
lName: String;
|
||
|
begin
|
||
|
inherited;
|
||
|
if not(PreferencesStorage is TCustomIniFile) then Exit;
|
||
|
Ini := TCustomIniFile(PreferencesStorage);
|
||
|
lName := GetFormSectionName;
|
||
|
|
||
|
SplitterPos := Round(Ini.ReadInteger(lName,
|
||
|
'SplitPos', Width div 2) * CurrentFormPPI /
|
||
|
frx_DefaultPPI);
|
||
|
if SplitterPos > Width - 10 then
|
||
|
SplitterPos := Width div 2;
|
||
|
Splitter1Pos := Round(Ini.ReadInteger(lName,
|
||
|
'Split1Pos', 65) * CurrentFormPPI / frx_DefaultPPI);
|
||
|
if Splitter1Pos < 10 then
|
||
|
Splitter1Pos := 65;
|
||
|
FFavorites.DelimitedText := Ini.ReadString(lName, 'Favorites', '');
|
||
|
end;
|
||
|
|
||
|
{ ObjectsCB events }
|
||
|
|
||
|
procedure TfrxObjectInspector.ObjectsCBClick(Sender: TObject);
|
||
|
begin
|
||
|
if FUpdatingObjectsCB then Exit;
|
||
|
FSelectedObjects.Clear;
|
||
|
if ObjectsCB.ItemIndex <> -1 then
|
||
|
if ObjectsCB.Items.Objects[ObjectsCB.ItemIndex] is TfrxComponent then
|
||
|
FSelectedObjects.Add(ObjectsCB.Items.Objects[ObjectsCB.ItemIndex]);
|
||
|
SetSelectedObjects(FSelectedObjects);
|
||
|
if Edit1.Visible then
|
||
|
Edit1.SetFocus;
|
||
|
if Assigned(FOnSelectionChanged) then
|
||
|
FOnSelectionChanged(Self);
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.ObjectsCBDrawItem(Control: TWinControl;
|
||
|
Index: Integer; Rect: TRect; State: TOwnerDrawState);
|
||
|
begin
|
||
|
if FDisableUpdate then exit;
|
||
|
with ObjectsCB.Canvas do
|
||
|
begin
|
||
|
FillRect(Rect);
|
||
|
if Index <> -1 then
|
||
|
TextOut(Rect.Left + 2, Rect.Top + 1, ObjectsCB.Items[Index]);
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
|
||
|
{ Mouse wheel }
|
||
|
|
||
|
procedure TfrxObjectInspector.FormMouseWheelDown(Sender: TObject;
|
||
|
Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
|
||
|
begin
|
||
|
with Box.VertScrollBar do
|
||
|
Position := Position + FRowHeight;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.FormMouseWheelUp(Sender: TObject;
|
||
|
Shift: TShiftState; MousePos: TPoint; var Handled: Boolean);
|
||
|
begin
|
||
|
with Box.VertScrollBar do
|
||
|
Position := Position - FRowHeight;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.CMMouseLeave(var Msg: TMessage);
|
||
|
begin
|
||
|
FHintWindow.ReleaseHandle;
|
||
|
inherited;
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.FormKeyDown(Sender: TObject; var Key: Word;
|
||
|
Shift: TShiftState);
|
||
|
begin
|
||
|
FavoritesAcrive := FavorButt in Shift;
|
||
|
if Assigned(FDesigner.OnKeyDown) then
|
||
|
FDesigner.OnKeyDown(Sender, Key, Shift);
|
||
|
end;
|
||
|
|
||
|
procedure TfrxObjectInspector.FormKeyUp(Sender: TObject; var Key: Word;
|
||
|
Shift: TShiftState);
|
||
|
begin
|
||
|
FavoritesAcrive := FavorButt in Shift;
|
||
|
if Assigned(FDesigner.OnKeyUp) then
|
||
|
FDesigner.OnKeyUp(Sender, Key, Shift);
|
||
|
end;
|
||
|
|
||
|
end.
|