FastReport_2022_VCL/LibD28x64/frxInPlaceEditors.pas
2024-01-01 16:13:08 +01:00

976 lines
28 KiB
ObjectPascal

{******************************************}
{ }
{ FastReport VCL }
{ Basic InPlace Editors }
{ }
{ Copyright (c) 1998-2021 }
{ by Fast Reports Inc. }
{ }
{******************************************}
unit frxInPlaceEditors;
interface
{$I frx.inc}
uses
{$IFDEF FPC}LazHelper{$ELSE}Windows{$ENDIF},
Types, Classes, SysUtils, Graphics, Controls, StdCtrls, ComCtrls, Forms,
Menus, TypInfo,
Dialogs, frxClass, frxUtils, frxGraphicControls,
frxRes, frxUnicodeCtrls, frxUnicodeUtils, Buttons, frxPopupForm
{$IFDEF Delphi6}
, Variants
{$ENDIF}
{$IFDEF Delphi10}
, WideStrings
{$ENDIF};
type
TfrxInPlaceMemoEditorBase = class(TfrxInPlaceEditor)
private
procedure LinesChange(Sender: TObject);
procedure MemoKeyPress(Sender: TObject; var Key: Char);
procedure DoExit(Sender: TObject);
procedure MemoKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
protected
FInPlaceMemo: TCustomMemo;
FEdited: Boolean;
procedure InitControlFromComponent; virtual;
procedure InitComponentFromControl; virtual;
procedure EditDone;
procedure CreateMemo; virtual; abstract;
public
constructor Create(aClassRef: TfrxComponentClass;
aOwner: TWinControl); override;
destructor Destroy; override;
function HasCustomEditor: Boolean; override;
function DoMouseUp(X, Y: Integer; Button: TMouseButton;
Shift: TShiftState; var EventParams: TfrxInteractiveEventsParams): Boolean; override;
procedure EditInPlace(aParent: TComponent; aRect: TRect); override;
function EditInPlaceDone: Boolean; override;
function DoMouseWheel(Shift: TShiftState;
WheelDelta: Integer; MousePos: TPoint; var EventParams: TfrxInteractiveEventsParams): Boolean; override;
procedure FinalizeUI(var EventParams: TfrxInteractiveEventsParams); override;
end;
TfrxInPlaceTextEditorBase = class(TfrxInPlaceMemoEditorBase)
protected
procedure CreateMemo; override;
end;
TfrxInPlaceMemoEditor = class(TfrxInPlaceTextEditorBase)
protected
procedure InitControlFromComponent; override;
procedure InitComponentFromControl; override;
end;
TfrxInPlaceBaseChoiceEditor = class(TfrxInPlaceEditor)
protected
FDrawDragDrop: Boolean;
FDrawDropDown: Boolean;
FDrawButton: Boolean;
FModified: Boolean;
FListBox: TListBox;
FRect: TRect;
FPopUpRect: TRect;
FPopupForm: TfrxPopupForm;
procedure DoPopupHide(Sender: TObject);
procedure DoLBClick(Sender: TObject); virtual; abstract;
procedure LBDrawItem(Control: TWinControl; Index: Integer; aRect: TRect;
State: TOwnerDrawState); virtual; abstract;
function GetButtonSize: Integer; virtual; abstract;
function GetButtonBevelWidth: Integer;
function IsFillListBox: Boolean; virtual; abstract;
procedure CalcPopupBounds(out TopLeft: TPoint; out w, h: Integer); virtual; abstract;
function ListBoxCreate: TListBox; virtual;
procedure UpdateRect; virtual;
public
function GetActiveRect: TRect; override;
function ShowPopup(aParent: TComponent; aRect: TRect; X, Y: Integer): Boolean; virtual;
procedure DrawCustomEditor(aCanvas: TCanvas; aRect: TRect); override;
function DoMouseDown(X, Y: Integer; Button: TMouseButton; Shift: TShiftState;
var EventParams: TfrxInteractiveEventsParams): Boolean; override;
function DoMouseMove(X, Y: Integer; Shift: TShiftState;
var EventParams: TfrxInteractiveEventsParams): Boolean; override;
end;
TfrxInPlaceDataFiledEditor = class(TfrxInPlaceBaseChoiceEditor)
private
function GetParentDS: TfrxDataSet;
protected
procedure DoLBClick(Sender: TObject); override;
function IsFillListBox: Boolean; override;
function GetButtonSize: Integer; override;
procedure CalcPopupBounds(out TopLeft: TPoint; out w, h: Integer); override;
function ListBoxCreate: TListBox; override;
procedure LBDrawItem(Control: TWinControl; Index: Integer; aRect: TRect;
State: TOwnerDrawState); override;
public
procedure InitializeUI(var EventParams: TfrxInteractiveEventsParams); override;
procedure FinalizeUI(var EventParams: TfrxInteractiveEventsParams); override;
function DoCustomDragOver(Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean;
var EventParams: TfrxInteractiveEventsParams): Boolean; override;
function DoCustomDragDrop(Source: TObject; X, Y: Integer;
var EventParams: TfrxInteractiveEventsParams): Boolean; override;
end;
TfrxInPlaceBasePanelEditor = class(TfrxInPlaceEditor)
private
FButtonsPanel: TfrxSwitchButtonsPanel;
FSwitchMode: Boolean;
FPosition: TPoint;
function DestroyPanel: Boolean;
protected
FMouseDown: Boolean;
function GetItem(Index: Integer): Boolean; virtual; abstract;
procedure SetItem(Index: Integer; const Value: Boolean); virtual; abstract;
function Count: Integer; virtual; abstract;
function GetName(Index: Integer): String; virtual; abstract;
function GetColor(Index: Integer): TColor; virtual; abstract;
public
destructor Destroy; override;
procedure AfterConstruction; override;
procedure InitializeUI(var EventParams: TfrxInteractiveEventsParams); override;
procedure FinalizeUI(var EventParams: TfrxInteractiveEventsParams); override;
function GetActiveRect: TRect; override;
function DoMouseDown(X, Y: Integer; Button: TMouseButton;
Shift: TShiftState; var EventParams: TfrxInteractiveEventsParams): Boolean; override;
function DoMouseUp(X, Y: Integer; Button: TMouseButton;
Shift: TShiftState; var EventParams: TfrxInteractiveEventsParams): Boolean; override;
procedure DrawCustomEditor(aCanvas: TCanvas; aRect: TRect); override;
property Item[Index: Integer]: Boolean read GetItem write SetItem;
end;
implementation
uses
Math,
frxInPlaceClipboards, frxDataLinkInPlaceEditor;
const
frx_DefaultBtnSize = 16;
ListBoxItemHeight = 16;
type
{ InPlace editors }
TfrxHackView = class(TfrxView);
THackCustomMemo = class(TCustomMemo);
TfrxInPlaceBandEditor = class(TfrxInPlaceEditor)
private
FDrawDragDrop: Boolean;
public
constructor Create(aClassRef: TfrxComponentClass;
aOwner: TWinControl); override;
function HasCustomEditor: Boolean; override;
procedure FinalizeUI(var EventParams: TfrxInteractiveEventsParams); override;
procedure DrawCustomEditor(aCanvas: TCanvas; aRect: TRect); override;
function DoCustomDragOver(Source: TObject; X, Y: Integer; State: TDragState;
var Accept: Boolean; var EventParams: TfrxInteractiveEventsParams): Boolean; override;
function DoCustomDragDrop(Source: TObject; X, Y: Integer; var EventParams: TfrxInteractiveEventsParams): Boolean;
override;
end;
{ TfrxMemoEditor }
constructor TfrxInPlaceMemoEditorBase.Create(aClassRef: TfrxComponentClass;
aOwner: TWinControl);
begin
inherited;
CreateMemo;
THackCustomMemo(FInPlaceMemo).OnExit := DoExit;
with THackCustomMemo(FInPlaceMemo) do
begin
Visible := False;
WordWrap := False;
OnChange := LinesChange;
OnKeyPress := MemoKeyPress;
OnKeyDown := MemoKeyDown;
Parent := FOwner;
end;
end;
procedure TfrxInPlaceMemoEditorBase.DoExit(Sender: TObject);
begin
EditDone;
end;
function TfrxInPlaceMemoEditorBase.DoMouseUp(X, Y: Integer;
Button: TMouseButton; Shift: TShiftState; var EventParams: TfrxInteractiveEventsParams): Boolean;
begin
Result := inherited DoMouseUp(X, Y, Button, Shift, EventParams);
OnFinishInPlace := EventParams.OnFinish;
EditInPlaceDone;
if ((EventParams.EditMode = dtText) or ((EventParams.EventSender = esPreview) and (ssAlt in Shift) and (ferAllowInPreview in FComponent.Editable))) then
EditInPlace(EventParams.Sender as TComponent, Rect(TfrxHackView(FComponent).FX, TfrxHackView(FComponent).FY, TfrxHackView(FComponent).FX1, TfrxHackView(FComponent).FY1));
//OnFinishInPlace := EventParams.OnFinish;
end;
function TfrxInPlaceMemoEditorBase.DoMouseWheel(Shift: TShiftState;
WheelDelta: Integer; MousePos: TPoint;
var EventParams: TfrxInteractiveEventsParams): Boolean;
begin
Result := FInPlaceMemo.Visible;
end;
procedure TfrxInPlaceMemoEditorBase.EditDone;
begin
if (csDestroying in FInPlaceMemo.ComponentState) or
Assigned(FInPlaceMemo.Parent) and
(csDestroying in FInPlaceMemo.Parent.ComponentState) then
Exit;
if FInPlaceMemo.Modified then
begin
InitComponentFromControl;
DoFinishInPlace(Component, True, True);
FInPlaceMemo.Modified := False;
FEdited := True;
end;
FInPlaceMemo.Hide;
end;
procedure TfrxInPlaceMemoEditorBase.EditInPlace(aParent: TComponent; aRect: TRect);
var
View: TfrxView;
Scale: Extended;
r: TRect;
begin
View := TfrxView(Component);
Scale := FScale;
with THackCustomMemo(FInPlaceMemo) do
begin
r := Rect(Round(View.AbsLeft * Scale), Round(View.AbsTop * Scale),
Round((View.AbsLeft + View.Width) * Scale + 1),
Round((View.AbsTop + View.Height) * Scale + 1));
OffsetRect(r, Round(FOffsetX), Round(FOffsetY));
SetBounds(r.Left, r.Top, r.Right - r.Left, r.Bottom - r.Top);
InitControlFromComponent;
// FOriginalSize.cx := Width;
// FOriginalSize.cy := Height;
if View.Color = clNone then
Color := clWhite
else
Color := View.Color;
{$IFNDEF FPC}
Ctl3D := False;
{$ENDIF}
BorderStyle := bsNone;
Show;
SetFocus;
SelectAll;
FEdited := False;
end;
end;
function TfrxInPlaceMemoEditorBase.EditInPlaceDone: Boolean;
begin
EditDone;
Result := FEdited;
end;
procedure TfrxInPlaceMemoEditorBase.FinalizeUI(
var EventParams: TfrxInteractiveEventsParams);
begin
inherited;
EventParams.Refresh := EventParams.Refresh or EditInPlaceDone;
// EventParams.Modified := EventParams.Refresh;
end;
function TfrxInPlaceMemoEditorBase.HasCustomEditor: Boolean;
begin
Result := True;
end;
procedure TfrxInPlaceMemoEditorBase.InitComponentFromControl;
begin
//
end;
procedure TfrxInPlaceMemoEditorBase.InitControlFromComponent;
begin
//
end;
procedure TfrxInPlaceMemoEditorBase.MemoKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if (Key = $0D) and (ssCtrl in Shift) then
EditDone;
end;
procedure TfrxInPlaceMemoEditorBase.MemoKeyPress(Sender: TObject; var Key: Char);
begin
if Key = #27 then
begin
FInPlaceMemo.Modified := False;
EditDone;
end;
end;
procedure TfrxInPlaceMemoEditorBase.LinesChange(Sender: TObject);
// var
// i, w0, w, h: Integer;
begin
{ h := (-FInPlaceMemo.Font.Height + 3) * FInPlaceMemo.Lines.Count + 4;
if h > FInPlaceMemo.Height - FInPlaceMemo.Font.Height then
FInPlaceMemo.Height := h;
TPanel(FInPlaceMemo.Parent).Canvas.Font := FInPlaceMemo.Font;
w := FInPlaceMemo.Width;
for i := 0 to FInPlaceMemo.Lines.Count - 1 do
begin
w0 := FDesigner.Canvas.TextWidth(FInPlaceMemo.Lines[i]) + 6;
if w0 > w then
w := w0;
end;
if w > FInPlaceMemo.Width then
FInPlaceMemo.Width := w; }
end;
{ TfrxInPlaceBandEditor }
constructor TfrxInPlaceBandEditor.Create(aClassRef: TfrxComponentClass;
aOwner: TWinControl);
begin
inherited;
end;
function TfrxInPlaceBandEditor.DoCustomDragDrop(Source: TObject;
X, Y: Integer; var EventParams: TfrxInteractiveEventsParams): Boolean;
var
Band: TfrxBand;
Node: TTreeNode;
i: Integer;
s: String;
aEventParams: TfrxInteractiveEventsParams;
e: TfrxEventObject;
c: TfrxComponent;
function GetComponentByIndex(Index: Integer): TfrxComponent;
var
i: Integer;
c: TfrxComponent;
begin
Result := nil;
for i := 0 to Band.Objects.Count - 1 do
if TObject(Band.Objects[i]) is TfrxComponent then
begin
c := TfrxComponent(Band.Objects[i]);
if c.IndexTag = Index then
begin
Result := c;
Exit;
end;
end;
end;
begin
Result := False;
if not FDrawDragDrop then Exit;
Band := nil;
if Component is TfrxBand then
Band := TfrxBand(Component);
if (Source is TTreeView) and Assigned(Band) then
with Band do
for i := TTreeView(Source).SelectionCount - 1 downto 0 do
begin
Node := TTreeView(Source).Selections[i];
s := '';
if (Node <> nil) and (Node.Data <> nil) then
s := Report.GetAlias(TfrxDataSet(Node.Data));
if s <> '' then
begin
c := GetComponentByIndex(i + 1);
Result := True;
if Assigned(c) then
begin
// Result := True;
// pass helper class which helps to determanate sender
e := TfrxEventObject.Create;
try
e.Sender := Source;
e.Index := i;
aEventParams.EditorsList := Editors;
c.DragDrop(e, X, Y, aEventParams);
finally
e.Free;
end;
end;
end;
end;
end;
function TfrxInPlaceBandEditor.DoCustomDragOver(Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean; var EventParams: TfrxInteractiveEventsParams): Boolean;
var
Band: TfrxBand;
begin
Result := False;
Band := nil;
Accept := False;
if Component is TfrxBand then
Band := TfrxBand(Component);
if (Source is TTreeView) and Assigned(Band) and (Band.AbsLeft * FScale < X)
and ((Band.AbsLeft + Band.Width) * FScale > X) and
((Band.AbsTop - Band.BandDesignHeader) * FScale < Y) and
(Band.AbsTop * FScale > Y) then
begin
Accept := True;
Result := True;
end;
FDrawDragDrop := Accept;
EventParams.Refresh := True;
end;
procedure TfrxInPlaceBandEditor.DrawCustomEditor(aCanvas: TCanvas; aRect: TRect);
var
Band: TfrxBand;
begin
Band := TfrxBand(Component);
if FDrawDragDrop then
begin
frxResources.MainButtonImages.Draw(aCanvas, Round((Band.AbsLeft + Band.Width) * FScale / 2),
Round((Band.AbsTop - Band.BandDesignHeader) * FScale), 112);
TransparentFillRect(aCanvas.Handle, Round(Band.AbsLeft * FScale), Round((Band.AbsTop - Band.BandDesignHeader) * FScale),
Round((Band.AbsLeft + Band.Width) * FScale), Round(Band.AbsTop * FScale), clGray);
end;
end;
procedure TfrxInPlaceBandEditor.FinalizeUI(
var EventParams: TfrxInteractiveEventsParams);
begin
EventParams.Refresh := FDrawDragDrop;
FDrawDragDrop := False;
end;
function TfrxInPlaceBandEditor.HasCustomEditor: Boolean;
begin
Result := inherited HasCustomEditor;
end;
{ TfrxInPlaceDataFiledEditor }
procedure TfrxInPlaceDataFiledEditor.CalcPopupBounds(out TopLeft: TPoint; out w, h: Integer);
var
r: TRect;
begin
r.Top := FRect.Top + GetButtonSize + 2;
r.Right := FRect.Right;
r.Left := r.Right - Round(140 * FDevicePPI / frx_DefaultPPI);
r.Bottom := r.Top + Round(162 * FDevicePPI / frx_DefaultPPI);
if r.Left < 0 then
begin
Inc(r.Right, -r.Left);
r.Left := 0;
end;
TopLeft := r.TopLeft;
w := Round((r.Right - r.Left) / (FDevicePPI / frx_DefaultPPI));
h := Round((r.Bottom - r.Top) / (FDevicePPI / frx_DefaultPPI));
end;
function TfrxInPlaceDataFiledEditor.DoCustomDragDrop(Source: TObject; X,
Y: Integer; var EventParams: TfrxInteractiveEventsParams): Boolean;
var
Memo: TfrxCustomMemoView;
View: TfrxView;
Node: TTreeNode;
i, nStart, nCount: Integer;
s: String;
begin
Result := False;
FDRawDragDrop := False;
Memo := nil;
nCount := 0;
nStart := 0;
if Component is TfrxCustomMemoView then
Memo := TfrxCustomMemoView(Component);
View := TfrxView(Component);
if (Source is TTreeView) and Assigned(View) then
begin
nCount := TTreeView(Source).SelectionCount - 1;
nStart := 0;
end
{ called from another editor with TfrxEventObject }
else if (Source is TfrxEventObject) and Assigned(View) then
begin
nStart := TfrxEventObject(Source).Index;
nCount := nStart;
Source := TfrxEventObject(Source).Sender;
end;
if (Source is TTreeView) then
with View do
for i := nCount downto nStart do
begin
Node := TTreeView(Source).Selections[i];
s := '';
EventParams.Refresh := True;
EventParams.Modified := True;
if (Node <> nil) and Assigned(Node.Data) and (TObject(Node.Data) is TfrxDataSet) then
s := Report.GetAlias(TfrxDataSet(Node.Data));
if s <> '' then
begin
Result := True;
if (nCount = nStart) or ((Memo = nil) and (i = nCount)) then
begin
DataSet := TfrxDataSet(Node.Data);
DataField := Node.Text;
Break;
end
else
begin
if i = nCount then
Memo.Text := '';
Memo.DataSet := nil;
Memo.DataField := '';
Memo.Text := Memo.Text + '[' + s + '."' + Node.Text + '"]';
end;
end
else if Assigned(Memo) then
begin
Result := True;
if i = nCount then
Memo.Text := '';
Memo.DataSet := nil;
Memo.DataField := '';
Memo.Text := Memo.Text + '[' + Node.Text + ']';
end;
end;
end;
function TfrxInPlaceDataFiledEditor.DoCustomDragOver(Source: TObject; X,
Y: Integer; State: TDragState; var Accept: Boolean;
var EventParams: TfrxInteractiveEventsParams): Boolean;
var
View: TfrxView;
begin
Result := False;
View := nil;
if Component is TfrxView then
View := TfrxCustomMemoView(Component);
if (Source is TTreeView) and Assigned(View) then
begin
Accept := True;
Result := True;
FDrawDragDrop := True;
EventParams.Refresh := True;
end;
end;
procedure TfrxInPlaceDataFiledEditor.DoLBClick(Sender: TObject);
var
i: Integer;
begin
if Component is TfrxView then
begin
TfrxView(Component).DataSet :=
GetParentDS;
TfrxView(Component).DataField :=
FListBox.Items[FListBox.ItemIndex];
end;
if Assigned(FComponents) then
for i := 0 to FComponents.Count - 1 do
if TObject(FComponents[i]) is Component.ClassType then
begin
TfrxView(FComponents[i]).DataSet :=
GetParentDS;
TfrxView(FComponents[i]).DataField :=
FListBox.Items[FListBox.ItemIndex];
end;
FModified := True;
FPopupForm.Hide;
end;
procedure TfrxInPlaceDataFiledEditor.FinalizeUI(var EventParams: TfrxInteractiveEventsParams);
begin
if not FLocked then
FDrawButton := False;
FDrawDragDrop := False;
end;
function TfrxInPlaceDataFiledEditor.GetButtonSize: Integer;
begin
Result := Round(frx_DefaultBtnSize * FDevicePPI / frx_DefaultPPI);
if (Result > FRect.Bottom - FRect.Top) and (Result > frx_DefaultBtnSize) then
Result := FRect.Bottom - FRect.Top;
Result := Result - Result mod 2;
end;
function TfrxInPlaceDataFiledEditor.GetParentDS: TfrxDataSet;
var
p: TfrxComponent;
begin
Result := nil;
p := FComponent.Parent;
while (p.Parent <> nil) and not(p is TfrxDataBand) do
p := p.Parent;
if (p is TfrxDataBand) then
Result := TfrxDataBand(p).DataSet;
end;
procedure TfrxInPlaceDataFiledEditor.InitializeUI(var EventParams: TfrxInteractiveEventsParams);
begin
inherited;
FModified := False;
FDrawButton := GetParentDS <> nil;
FDrawDragDrop := False;
UpdateRect;
end;
function TfrxInPlaceDataFiledEditor.IsFillListBox: Boolean;
var
ds: TfrxDataSet;
begin
ds := GetParentDS;
Result := ds <> nil;
if Result then
begin
ds.GetFieldList(FListBox.Items);
FListBox.ItemIndex := FListBox.Items.IndexOf(TfrxCustomMemoView(Component).DataField);
end;
end;
procedure TfrxInPlaceDataFiledEditor.LBDrawItem(Control: TWinControl; Index: Integer; aRect: TRect; State: TOwnerDrawState);
begin
with FListBox do
begin
Canvas.FillRect(aRect);
frxResources.MainButtonImages.Draw(Canvas, aRect.Left, aRect.Top, 54);
Canvas.TextOut(aRect.Left + frxResources.MainButtonImages.Width + 2, aRect.Top + 1, Items[Index]);
end;
end;
function TfrxInPlaceDataFiledEditor.ListBoxCreate: TListBox;
begin
Result := inherited ListBoxCreate;
Result.ItemHeight := ListBoxItemHeight;
end;
{ TfrxInPlaceBasePanelEditor }
procedure TfrxInPlaceBasePanelEditor.AfterConstruction;
begin
inherited;
FPosition := Point(1, 20);
end;
destructor TfrxInPlaceBasePanelEditor.Destroy;
begin
DestroyPanel;
inherited;
end;
function TfrxInPlaceBasePanelEditor.DestroyPanel: Boolean;
begin
Result := False;
if Assigned(FButtonsPanel) then
begin
Result := True;
FreeAndNil(FButtonsPanel);
end;
end;
function TfrxInPlaceBasePanelEditor.DoMouseDown(X, Y: Integer; Button: TMouseButton;
Shift: TShiftState; var EventParams: TfrxInteractiveEventsParams): Boolean;
begin
Result := False;
FMouseDown := True;
end;
function TfrxInPlaceBasePanelEditor.DoMouseUp(X, Y: Integer; Button: TMouseButton;
Shift: TShiftState; var EventParams: TfrxInteractiveEventsParams): Boolean;
var
i: Integer;
btn: TfrxSwithcButton;
begin
Result := False;
if not Assigned(FButtonsPanel) or not FMouseDown then Exit;
FMouseDown := False;
btn := FButtonsPanel.DoClick(Round(X - (FComponent.AbsLeft + FComponent.Width) * FScale) + FButtonsPanel.CalcWidth - FPosition.X, Round(Y - FComponent.AbsTop * FScale) - FPosition.Y);
if btn <> nil then
for i := 0 to Count - 1 do
begin
if FSwitchMode then
begin
if (FButtonsPanel.Count > i) and (btn.Tag <> i) then
FButtonsPanel[i].Switch := False;
if btn.Switch = false and FSwitchMode then btn.Switch := True;
end;
Item[i] := FButtonsPanel[i].Switch;
end;
EventParams.Refresh := True;
end;
procedure TfrxInPlaceBasePanelEditor.DrawCustomEditor(aCanvas: TCanvas;
aRect: TRect);
begin
inherited;
if Assigned(FButtonsPanel) then
FButtonsPanel.Draw(aCanvas, aRect.Right - FButtonsPanel.CalcWidth - FPosition.X, aRect.Top + FPosition.Y);
end;
procedure TfrxInPlaceBasePanelEditor.FinalizeUI(var EventParams: TfrxInteractiveEventsParams);
begin
inherited;
EventParams.Refresh := DestroyPanel;
end;
function TfrxInPlaceBasePanelEditor.GetActiveRect: TRect;
begin
Result := inherited GetActiveRect;
end;
procedure TfrxInPlaceBasePanelEditor.InitializeUI(var EventParams: TfrxInteractiveEventsParams);
var
i: integer;
bFirst: Boolean;
begin
DestroyPanel;
EventParams.Refresh := True;
FButtonsPanel := TfrxSwitchButtonsPanel.Create;
FButtonsPanel.ShowColors := True;
FButtonsPanel.ShowCaption := True;
bFirst := True;
for i := 0 to Count - 1 do
if FButtonsPanel.Count - 1 < i then
with FButtonsPanel.AddButton(GetName(i)) do
begin
Switch := Item[i];
if bFirst and Switch then
begin
FSwitchMode := Switch and (EventParams.EventSender <> esDesigner);
bFirst := False;
end
else if Switch then
FSwitchMode := False;
Tag := i;
ColorTag := GetColor(i);
end;
FSwitchMode := FSwitchMode and (FButtonsPanel.Count > 1);
end;
{ TfrxInPlaceMemoEditor }
procedure TfrxInPlaceMemoEditor.InitControlFromComponent;
var
s: WideString;
MemoView: TfrxCustomMemoView;
function frxAlignToAlignment(HAlign: TfrxHAlign): TAlignment;
begin
case HAlign of
haLeft: Result := taLeftJustify;
haRight: Result := taRightJustify;
else
Result := taCenter;
end;
end;
begin
MemoView := FComponent as TfrxCustomMemoView;
if not Assigned(MemoView) then Exit;
THackCustomMemo(FInPlaceMemo).WordWrap := MemoView.WordWrap;
THackCustomMemo(FInPlaceMemo).Alignment := frxAlignToAlignment(MemoView.HAlign);
s := MemoView.Text;
if (s <> '') and (s[Length(s)] = #10) then
Delete(s, Length(s) - 1, 2);
FInPlaceMemo.Text := s;
THackCustomMemo(FInPlaceMemo).Font.Assign(MemoView.Font);
THackCustomMemo(FInPlaceMemo).Font.Height := Round(THackCustomMemo(FInPlaceMemo).Font.Height * FScale);
end;
procedure TfrxInPlaceMemoEditor.InitComponentFromControl;
var
MemoView: TfrxCustomMemoView;
begin
MemoView := TfrxCustomMemoView(Component);
MemoView.Text := FInPlaceMemo.Text;
end;
{ TfrxInPlaceTextEditorBase }
procedure TfrxInPlaceTextEditorBase.CreateMemo;
begin
FInPlaceMemo := TUnicodeMemo.Create(nil);
end;
destructor TfrxInPlaceMemoEditorBase.Destroy;
begin
FInPlaceMemo.Free;
inherited;
end;
{ TfrxInPlaceBaseChoiceEditor }
function TfrxInPlaceBaseChoiceEditor.DoMouseDown(X, Y: Integer; Button: TMouseButton; Shift: TShiftState;
var EventParams: TfrxInteractiveEventsParams): Boolean;
begin
UpdateRect;
if not FLocked then
begin
OnFinishInPlace := EventParams.OnFinish;
ShowPopup(EventParams.Sender as TComponent, FRect, X, Y);
end;
Result := FLocked;
end;
function TfrxInPlaceBaseChoiceEditor.DoMouseMove(X, Y: Integer; Shift: TShiftState;
var EventParams: TfrxInteractiveEventsParams): Boolean;
begin
Result := False;
end;
procedure TfrxInPlaceBaseChoiceEditor.DoPopupHide(Sender: TObject);
begin
FLocked := False;
if Component <> nil then
DoFinishInPlace(Component, True, FModified);
FDrawDropDown := False;
OnFinishInPlace := nil;
FPopUpRect := Rect(0, 0, 0, 0);
end;
procedure TfrxInPlaceBaseChoiceEditor.DrawCustomEditor(aCanvas: TCanvas; aRect: TRect);
var
r: TRect;
rHeight, bSize: Integer;
begin
UpdateRect;
rHeight := FRect.Bottom - FRect.Top;
if FDrawDragDrop then
begin
frxResources.MainButtonImages.Draw(aCanvas, FRect.Left - 10,
FRect.Top + (rHeight - 5) div 2, 111);
TransparentFillRect(aCanvas.Handle, FRect.Left + 1, FRect.Top + 1,
FRect.Right - 1, FRect.Bottom - 1, clGray);
end;
if not FDrawButton then Exit;
// move same code to function
with aCanvas do
begin
bSize := GetButtonSize;
r.TopLeft := Point(FRect.Right - bSize, FRect.Top + 2);
r.BottomRight := Point(r.Left + bSize, r.Top + bSize);
DrawButtonFace(aCanvas, r, GetButtonBevelWidth, bsNew, False, False, False);
frxDrawArrow(aCanvas, r, clBlack, FDrawDropDown);
end;
// frxResources.WizardImages.Draw(aCanvas, aRect.Left + rWidth div 2 - 16, aRect.Top + rHeight div 2 - 16, Index, True);
end;
function TfrxInPlaceBaseChoiceEditor.GetActiveRect: TRect;
begin
if (FPopUpRect.Right <> 0) or (FPopUpRect.Bottom <> 0) then
Result := FPopUpRect
else
Result := inherited GetActiveRect;
end;
function TfrxInPlaceBaseChoiceEditor.GetButtonBevelWidth: Integer;
begin
Result := Round(GetButtonSize / frx_DefaultBtnSize);
end;
function TfrxInPlaceBaseChoiceEditor.ListBoxCreate: TListBox;
begin
Result := TListBox.Create(FPopupForm);
with Result do
begin
Parent := FPopupForm;
{$IFNDEF FPC}
Ctl3D := False;
{$ENDIF}
Align := alClient;
Style := lbOwnerDrawFixed;
OnClick := DoLBClick;
OnDrawItem := LBDrawItem;
end;
end;
function TfrxInPlaceBaseChoiceEditor.ShowPopup(aParent: TComponent; aRect: TRect; X, Y: Integer): Boolean;
var
ButtonRect: TRect;
TopLeft: TPoint;
w, h: Integer;
c: TWinControl;
begin
Result := False;
ButtonRect := FRect;
ButtonRect.Left := ButtonRect.Right - GetButtonSize;
if not PtInRect(ButtonRect, Point(X, Y)) then
Exit;
FPopupForm := TfrxPopupForm.Create(aParent);
{$IFDEF FPC}
FPopupForm.PopupParent := Screen.ActiveForm;
{$ENDIF}
{$IFNDEF Linux}
FPopupForm.OnDestroy := DoPopupHide;
{$ENDIF}
FListBox := ListBoxCreate;
CalcPopupBounds(TopLeft, w, h);
FPopUpRect := Rect(0, 0, w, h);
c := aParent as TWinControl;
if c = nil then
c := Screen.ActiveForm;
TopLeft := c.ClientToScreen(TopLeft);
FPopupForm.SetBounds(TopLeft.X, TopLeft.Y, w, h);
if IsFillListBox then
begin
{$IFNDEF Linux}
FPopupForm.Show;
{$ELSE}
FPopupForm.ShowModal;
{$ENDIF}
FLocked := True;
Result := True;
FDrawDropDown := True;
{$IFDEF Linux}
DoPopupHide(Self);
{$ENDIF}
end
else
begin
FListBox.Free;
FPopupForm.Free;
end;
end;
procedure TfrxInPlaceBaseChoiceEditor.UpdateRect;
begin
FRect := Rect(TfrxHackView(FComponent).FX, TfrxHackView(FComponent).FY, TfrxHackView(FComponent).FX1, TfrxHackView(FComponent).FY1);
end;
initialization
frxRegEditorsClasses.Register(TfrxMemoView, [TfrxInPlaceDataFiledEditor, TfrxInPlaceMemoEditor, TfrxInPlaceDataLinkEditor], [[evDesigner], [evDesigner, evPreview], [evDesigner, evPreview], [evDesigner]]);
frxRegEditorsClasses.Register(TfrxPictureView, [TfrxInPlaceDataFiledEditor, TfrxInPlaceDataLinkEditor], [[evDesigner], [evDesigner, evPreview]]);
frxRegEditorsClasses.Register(TfrxMasterData, [TfrxInPlaceBandEditor], [[evDesigner]]);
finalization
frxUnregisterEditorsClass(TfrxMemoView, TfrxInPlaceDataFiledEditor);
frxUnregisterEditorsClass(TfrxMemoView, TfrxInPlaceMemoEditor);
frxUnregisterEditorsClass(TfrxMemoView, TfrxInPlaceDataLinkEditor);
frxUnregisterEditorsClass(TfrxPictureView, TfrxInPlaceDataFiledEditor);
frxUnregisterEditorsClass(TfrxPictureView, TfrxInPlaceDataLinkEditor);
frxUnregisterEditorsClass(TfrxMasterData, TfrxInPlaceBandEditor);
end.