FastReport_2022_VCL/Source/frxCrossInPlaceEditor.pas
2024-01-01 16:13:08 +01:00

229 lines
7.7 KiB
ObjectPascal

{******************************************}
{ }
{ FastReport VCL }
{ Cross Object Editors }
{ }
{ Copyright (c) 1998-2021 }
{ by Fast Reports Inc. }
{ }
{******************************************}
unit frxCrossInPlaceEditor;
interface
{$I frx.inc}
implementation
uses
{$IFDEF FPC}LazHelper{$ELSE}Windows{$ENDIF},
Types, Classes, SysUtils, Graphics, Controls, StdCtrls, ComCtrls, Forms, Menus,
Dialogs, frxClass, frxDesgn, frxDsgnIntf, frxUtils,
frxRes, frxDesgnWorkspace, frxCross
{$IFDEF Delphi6}
, Variants
{$ENDIF}
{$IFDEF Delphi10}
, WideStrings
{$ENDIF};
type
{ Inline editors }
TfrxHackCustomCrossView = class(TfrxCustomCrossView);
TfrxInPlaceCrossEditor = class(TfrxInPlaceEditor)
private
FDragActive: Boolean;
FActiveGrid: TfrxCrossEditGrid;
public
constructor Create(aClassRef: TfrxComponentClass; aOwner: TWinControl); override;
function HasCustomEditor: Boolean; 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;
procedure InitializeUI(var EventParams: TfrxInteractiveEventsParams); override;
procedure FinalizeUI(var EventParams: TfrxInteractiveEventsParams); override;
end;
{ TfrxMemoEditor }
{ TfrxInPlaceCrossEditor }
constructor TfrxInPlaceCrossEditor.Create(aClassRef: TfrxComponentClass;
aOwner: TWinControl);
begin
inherited;
end;
function TfrxInPlaceCrossEditor.DoCustomDragDrop(Source: TObject; X,
Y: Integer; var EventParams: TfrxInteractiveEventsParams): Boolean;
var
Node: TTreeNode;
i, selcount: Integer;
s: String;
cross: TfrxHackCustomCrossView;
begin
Inherited DoCustomDragDrop(Source, X, Y, EventParams);
Result := False;
cross := nil;
if Component is TfrxCustomCrossView then
cross := TfrxHackCustomCrossView(Component);
if Assigned(cross) then
with cross do
begin
selcount := TTreeView(Source).SelectionCount - 1;
for i := selcount 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
Result := True;
if DataSet = nil then
DataSet := TfrxDataSet(Node.Data);
if (FActiveGrid = seRightBottom) or
((FActiveGrid = seLeftTop) and (selcount - i >= 2)) then
begin
CellLevels := CellLevels + 1;
CellFields.Add(Node.Text);
end
else if (FActiveGrid = seRightTop) or
((FActiveGrid = seLeftTop) and (selcount - i = 1)) then
begin
ColumnLevels := ColumnLevels + 1;
ColumnFields.Add(Node.Text)
end
else if (FActiveGrid = seLeftBottom) or
((FActiveGrid = seLeftTop) and (selcount - i = 0)) then
begin
if (FActiveGrid = seLeftTop) then
begin
RowFields.Clear;
ColumnFields.Clear;
CellFields.Clear;
RowLevels := 0;
ColumnLevels := 0;
CellLevels := 0;
DataSet := TfrxDataSet(Node.Data);
end;
RowLevels := RowLevels + 1;
RowFields.Add(Node.Text)
end;
end;
end;
end;
end;
function TfrxInPlaceCrossEditor.DoCustomDragOver(Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean; var EventParams: TfrxInteractiveEventsParams): Boolean;
var
cross: TfrxHackCustomCrossView;
begin
cross := nil;
Result := False;
if Component is TfrxCustomCrossView then
cross := TfrxHackCustomCrossView(Component);
with cross do
if (Source is TTreeView) and Assigned(cross) then
begin
FActiveGrid := seLeftTop;
if (AbsLeft + Width / 2 < X) and (AbsLeft + Width > X) and
(AbsTop + Height / 2 < Y) and (cross.AbsTop + cross.Height > Y) then
FActiveGrid := seRightBottom
else if (AbsLeft + Width / 2 < X) and (AbsLeft + Width > X) and
(AbsTop < Y) and (AbsTop + Height / 2 > Y) then
FActiveGrid := seRightTop
else if (AbsLeft < X) and (AbsLeft + Width / 2 > X) and
(AbsTop + Height / 2 < Y) and (AbsTop + Height > Y) then
FActiveGrid := seLeftBottom;
Accept := True;
Result := True;
end;
if Accept then
FDragActive := True;
end;
procedure TfrxInPlaceCrossEditor.DrawCustomEditor(aCanvas: TCanvas;
aRect: TRect);
var
TempRect: TRect;
s: String;
AbsLeft, AbsTop, Width, Height: Extended;
begin
AbsLeft := TfrxHackCustomCrossView(FComponent).AbsLeft;
AbsTop := TfrxHackCustomCrossView(FComponent).AbsTop;
Width := TfrxHackCustomCrossView(FComponent).Width;
Height := TfrxHackCustomCrossView(FComponent).Height;
{ TODO : Move strings to editor DrawCustomEditor }
if FDragActive and Assigned(aCanvas) then
begin
aCanvas.Brush.Color := clWhite;
aCanvas.FillRect(Rect(TfrxHackCustomCrossView(FComponent).FX, TfrxHackCustomCrossView(FComponent).FY, TfrxHackCustomCrossView(FComponent).FX1, TfrxHackCustomCrossView(FComponent).FY1));
aCanvas.MoveTo(Round((AbsLeft + Width / 2) * FScale), Round(AbsTop * FScale));
aCanvas.LineTo(Round((AbsLeft + Width / 2) * FScale), Round((AbsTop + Height) * FScale));
aCanvas.MoveTo(Round(AbsLeft * FScale), Round((AbsTop + Height / 2) * FScale));
aCanvas.LineTo(Round((AbsLeft + Width) * FScale), Round((AbsTop + Height / 2) * FScale));
aCanvas.Brush.Color := $00E8E3E3;
aCanvas.Brush.Style := bsSolid;
TempRect := Rect(Round(AbsLeft * FScale) + 1, Round(AbsTop * FScale) + 1, Round((AbsLeft + Width / 2) * FScale), Round((AbsTop + Height / 2) * FScale));
s := 'New table';
case FActiveGrid of
seRightTop:
begin
TempRect := Rect(Round((AbsLeft + Width/ 2) * FScale) + 1, Round(AbsTop * FScale) + 1, Round((AbsLeft + Width) * FScale) - 1, Round((AbsTop + Height / 2) * FScale) - 1);
s := 'Drop column';
end;
seLeftBottom:
begin
TempRect := Rect(Round(AbsLeft * FScale) + 1, Round((AbsTop + Height / 2) * FScale) + 1, Round((AbsLeft + Width / 2) * FScale), Round((AbsTop + Height) * FScale) - 1);
s := 'Drop row';
end;
seRightBottom:
begin
TempRect := Rect(Round((AbsLeft + Width/ 2) * FScale) + 1, Round((AbsTop + Height / 2) * FScale) + 1, Round((AbsLeft + Width) * FScale) - 1, Round((AbsTop + Height) * FScale) - 1);
s := 'Drop cell';
end;
end;
aCanvas.FillRect(TempRect);
//TempRect.Top := TempRect.Top + Round(Height * FScale / 10);
aCanvas.Font.Size := 12;
aCanvas.Font.Color := clBlack;
aCanvas.Pen.Color := clBlack;
aCanvas.Font.Height := Round(aCanvas.Font.Height * FScale);
aCanvas.Font.Style := [fsBold];
aCanvas.TextRect(TempRect, 4, 4, s);
end;
end;
procedure TfrxInPlaceCrossEditor.FinalizeUI(
var EventParams: TfrxInteractiveEventsParams);
begin
inherited;
FDragActive := False;
end;
function TfrxInPlaceCrossEditor.HasCustomEditor: Boolean;
begin
Result := True;
end;
procedure TfrxInPlaceCrossEditor.InitializeUI(
var EventParams: TfrxInteractiveEventsParams);
begin
inherited;
FDragActive := False;
end;
initialization
frxRegEditorsClasses.Register(TfrxDBCrossView, [TfrxInPlaceCrossEditor], []);
finalization
frxUnregisterEditorsClass(TfrxDBCrossView, TfrxInPlaceCrossEditor);
end.