From e0c4cf7ee48844a0bd3e91c014941bd7a6f1b882 Mon Sep 17 00:00:00 2001 From: Michael Schimmel Date: Tue, 7 Oct 2025 13:21:25 +0200 Subject: [PATCH] Accessing RTL symbols --- ASTPlayground/MainForm.fmx | 24 +- ASTPlayground/MainForm.pas | 144 +- ASTPlayground/UserLib.json | 318 +- KI/FMX_Intf.txt | 6992 +++++++++++++++++++++++++++++++++++- 4 files changed, 7325 insertions(+), 153 deletions(-) diff --git a/ASTPlayground/MainForm.fmx b/ASTPlayground/MainForm.fmx index d9bc310..e6bbcd2 100644 --- a/ASTPlayground/MainForm.fmx +++ b/ASTPlayground/MainForm.fmx @@ -81,7 +81,7 @@ object Form1: TForm1 end object ClearButton: TButton Position.X = 24.000000000000000000 - Position.Y = 554.000000000000000000 + Position.Y = 539.000000000000000000 Size.Width = 80.000000000000000000 Size.Height = 22.000000000000000000 Size.PlatformDefault = False @@ -121,14 +121,14 @@ object Form1: TForm1 end object FromJSONButton: TButton Position.X = 24.000000000000000000 - Position.Y = 602.000000000000000000 + Position.Y = 569.000000000000000000 TabOrder = 16 Text = 'From JSON' OnClick = FromJSONButtonClick end object ToJSONButton: TButton Position.X = 24.000000000000000000 - Position.Y = 632.000000000000000000 + Position.Y = 599.000000000000000000 TabOrder = 17 Text = 'To JSON' OnClick = ToJSONButtonClick @@ -170,18 +170,32 @@ object Form1: TForm1 end object SaveUserLibButton: TButton Position.X = 24.000000000000000000 - Position.Y = 680.000000000000000000 + Position.Y = 629.000000000000000000 TabOrder = 24 Text = 'Save Lib' OnClick = SaveUserLibButtonClick end object LoadUserLibButton: TButton Position.X = 24.000000000000000000 - Position.Y = 710.000000000000000000 + Position.Y = 659.000000000000000000 TabOrder = 25 Text = 'LoadLib' OnClick = LoadUserLibButtonClick end + object RTLListView: TListView + ItemAppearanceClassName = 'TListItemAppearance' + ItemEditAppearanceClassName = 'TListItemShowCheckAppearance' + HeaderAppearanceClassName = 'TListHeaderObjects' + FooterAppearanceClassName = 'TListHeaderObjects' + Anchors = [akLeft, akBottom] + Position.X = 8.000000000000000000 + Position.Y = 689.000000000000000000 + Size.Width = 113.000000000000000000 + Size.Height = 184.000000000000000000 + Size.PlatformDefault = False + TabOrder = 26 + OnChange = RTLListViewChange + end end object Panel2: TPanel Align = Client diff --git a/ASTPlayground/MainForm.pas b/ASTPlayground/MainForm.pas index 38fe519..a4767ee 100644 --- a/ASTPlayground/MainForm.pas +++ b/ASTPlayground/MainForm.pas @@ -39,7 +39,11 @@ uses Myc.Fmx.AstEditor, Myc.Fmx.AstEditor.Node, Myc.Fmx.AstEditor.Workspace, - FMX.DialogService; // Added for platform-independent dialogs + FMX.DialogService, + FMX.ListView.Types, + FMX.ListView.Appearances, + FMX.ListView.Adapters.Base, + FMX.ListView; // Added for platform-independent dialogs type // A test record @@ -82,6 +86,7 @@ type ScriptMemo: TMemo; LoadUserLibButton: TButton; SaveUserLibButton: TButton; + RTLListView: TListView; procedure InnerLambdaButtonClick(Sender: TObject); procedure ClearButtonClick(Sender: TObject); procedure FormCreate(Sender: TObject); @@ -105,6 +110,7 @@ type procedure ToJSONButtonClick(Sender: TObject); procedure SaveUserLibButtonClick(Sender: TObject); procedure LoadUserLibButtonClick(Sender: TObject); + procedure RTLListViewChange(Sender: TObject); private FCurrAst: IAstNode; FCurrDesc: IScopeDescriptor; @@ -198,14 +204,6 @@ begin FGScope := TAst.CreateScope(nil); RegisterNativeFunctions(FGScope); - - ScriptMemo.Lines.Text := - ''' - (do - (def my-add (fn [a b] (+ a b))) - (def my-square (fn [x] (* x x))) - ) - '''; end; function TForm1.ExecuteAst(const ANode: IAstNode; const AParentScope: IExecutionScope): TDataValue; @@ -241,7 +239,7 @@ begin FWorkspace.ClipChildren := true; FWorkspace.OnMouseDown := WorkspaceMouseDown; - Tast.RegisterLibrary( + TAst.RegisterLibrary( procedure(const Scope: IExecutionScope) var smaAst, boundSmaAst: IAstNode; @@ -340,34 +338,42 @@ begin try Memo1.Lines.Add(Format('--- Loading User Library from %s ---', [ExtractFileName(UserLibName)])); var scopeDescr := FGScope.CreateDescriptor; - for pair in jsonObj do - begin - if not (pair.JsonValue is TJSONObject) then - continue; - - // First, deserialize the AST node from JSON. - funcAst := converter.Deserialize(pair.JsonValue as TJSONObject); - - var adr := scopeDescr.FindSymbol(pair.JsonString.Value); - if adr.Kind = akUnresolved then + // Populate the list view with loaded functions and macros. + RTLListView.Items.BeginUpdate; + try + for pair in jsonObj do begin - // Distinguish between loading a macro and loading a function. - if funcAst is TMacroDefinitionNode then + if not (pair.JsonValue is TJSONObject) then + continue; + + // First, deserialize the AST node from JSON. + funcAst := converter.Deserialize(pair.JsonValue as TJSONObject); + + var adr := scopeDescr.FindSymbol(pair.JsonString.Value); + if adr.Kind = akUnresolved then begin - // Macros are stored as raw AST nodes in the scope. - FGScope.Define(pair.JsonString.Value, TDataValue.FromIntf(funcAst)); - Memo1.Lines.Add(Format('Defined macro "%s"', [pair.JsonString.Value])); + // Distinguish between loading a macro and loading a function. + if funcAst is TMacroDefinitionNode then + begin + // Macros are stored as raw AST nodes in the scope. + FGScope.Define(pair.JsonString.Value, TDataValue.FromIntf(funcAst)); + Memo1.Lines.Add(Format('Defined macro "%s"', [pair.JsonString.Value])); + end + else + begin + // Functions (lambdas) must be executed to create a callable closure. + funcValue := ExecuteAst(funcAst, FGScope); + FGScope.Define(pair.JsonString.Value, funcValue); + Memo1.Lines.Add(Format('Defined function "%s"', [pair.JsonString.Value])); + end; end else - begin - // Functions (lambdas) must be executed to create a callable closure. - funcValue := ExecuteAst(funcAst, FGScope); - FGScope.Define(pair.JsonString.Value, funcValue); - Memo1.Lines.Add(Format('Defined function "%s"', [pair.JsonString.Value])); - end; - end - else - Memo1.Lines.Add(Format('Symbol "%s" already defined', [pair.JsonString.Value])); + Memo1.Lines.Add(Format('Symbol "%s" already defined', [pair.JsonString.Value])); + // Add the new function/macro to the RTL list view. + RTLListView.Items.Add.Text := pair.JsonString.Value; + end; + finally + RTLListView.Items.EndUpdate; end; finally jsonObj.Free; @@ -474,10 +480,18 @@ begin if addedList.Count > 0 then begin Memo1.Lines.Add(Format('%d new definitions added:', [addedList.Count])); - for var n in addedList do - Memo1.Lines.Add(n); + // Add the new item to the RTL list view. + RTLListView.Items.BeginUpdate; + try + for var n in addedList do + begin + Memo1.Lines.Add(n); + RTLListView.Items.Add.Text := n; + end; + finally + RTLListView.Items.EndUpdate; + end; end; - finally jsonLib.Free; addedList.Free; @@ -1204,6 +1218,62 @@ begin end; end; +procedure TForm1.RTLListViewChange(Sender: TObject); +var + itemName: string; + jsonString: string; + jsonLib, jsonObj: TJSONObject; + converter: IJsonAstConverter; + AItem: TListViewItem; +begin + if RTLListView.ItemIndex < 0 then + exit; + AItem := RTLListView.Items[RTLListView.ItemIndex]; + + itemName := AItem.Text; + Memo1.Lines.Clear; + Memo1.Lines.Add(Format('Loading "%s" from library...', [itemName])); + + if not TFile.Exists(UserLibName) then + begin + Memo1.Lines.Add(Format('Library file "%s" not found.', [UserLibName])); + exit; + end; + + jsonLib := nil; + try + try + jsonString := TFile.ReadAllText(UserLibName); + jsonLib := TJSONObject.ParseJSONValue(jsonString) as TJSONObject; + if not Assigned(jsonLib) then + raise Exception.Create('Invalid JSON library format.'); + + var jsonValue := jsonLib.GetValue(itemName); + if not Assigned(jsonValue) or not (jsonValue is TJSONObject) then + raise Exception.Create(Format('Definition for "%s" not found in library.', [itemName])); + + jsonObj := jsonValue as TJSONObject; + + converter := TJsonAstConverter.Create; + FCurrAst := converter.Deserialize(jsonObj); + + // Update the UI + UpdateScript; // This will print to ScriptMemo and show visualization + + Memo1.Lines.Add(Format('"%s" loaded into script editor and workspace.', [itemName])); + + except + on E: Exception do + begin + Memo1.Lines.Add('Error: ' + E.Message); + end; + end; + finally + if Assigned(jsonLib) then + jsonLib.Free; + end; +end; + procedure TForm1.ScriptMemoChange(Sender: TObject); begin if FScriptUpdate then diff --git a/ASTPlayground/UserLib.json b/ASTPlayground/UserLib.json index 9076f60..400bf42 100644 --- a/ASTPlayground/UserLib.json +++ b/ASTPlayground/UserLib.json @@ -1,50 +1,4 @@ { - "my-add": { - "NodeType": "LambdaExpr", - "Parameters": [ - { - "NodeType": "Identifier", - "Name": "a" - }, - { - "NodeType": "Identifier", - "Name": "b" - } - ], - "Body": { - "NodeType": "BinaryExpr", - "Operator": "+", - "Left": { - "NodeType": "Identifier", - "Name": "a" - }, - "Right": { - "NodeType": "Identifier", - "Name": "b" - } - } - }, - "my-square": { - "NodeType": "LambdaExpr", - "Parameters": [ - { - "NodeType": "Identifier", - "Name": "x" - } - ], - "Body": { - "NodeType": "BinaryExpr", - "Operator": "*", - "Left": { - "NodeType": "Identifier", - "Name": "x" - }, - "Right": { - "NodeType": "Identifier", - "Name": "x" - } - } - }, "my-3": { "NodeType": "LambdaExpr", "Parameters": [ @@ -315,5 +269,277 @@ } ] } + }, + "my-add": { + "NodeType": "LambdaExpr", + "Parameters": [ + { + "NodeType": "Identifier", + "Name": "a" + }, + { + "NodeType": "Identifier", + "Name": "b" + } + ], + "Body": { + "NodeType": "FunctionCall", + "Callee": { + "NodeType": "Identifier", + "Name": "+" + }, + "Arguments": [ + { + "NodeType": "Identifier", + "Name": "a" + }, + { + "NodeType": "Identifier", + "Name": "b" + } + ] + } + }, + "my-square": { + "NodeType": "LambdaExpr", + "Parameters": [ + { + "NodeType": "Identifier", + "Name": "x" + } + ], + "Body": { + "NodeType": "FunctionCall", + "Callee": { + "NodeType": "Identifier", + "Name": "*" + }, + "Arguments": [ + { + "NodeType": "Identifier", + "Name": "x" + }, + { + "NodeType": "Identifier", + "Name": "x" + } + ] + } + }, + "CreateSMA": { + "NodeType": "LambdaExpr", + "Parameters": [ + { + "NodeType": "Identifier", + "Name": "len" + } + ], + "Body": { + "NodeType": "Block", + "Expressions": [ + { + "NodeType": "VarDecl", + "Identifier": { + "NodeType": "Identifier", + "Name": "sum" + }, + "Initializer": { + "NodeType": "Constant", + "Value": { + "Kind": "Scalar", + "Value": { + "Kind": "Ordinal", + "Value": 0 + } + } + } + }, + { + "NodeType": "VarDecl", + "Identifier": { + "NodeType": "Identifier", + "Name": "count" + }, + "Initializer": { + "NodeType": "Constant", + "Value": { + "Kind": "Scalar", + "Value": { + "Kind": "Ordinal", + "Value": 0 + } + } + } + }, + { + "NodeType": "LambdaExpr", + "Parameters": [ + { + "NodeType": "Identifier", + "Name": "series" + }, + { + "NodeType": "Identifier", + "Name": "val" + } + ], + "Body": { + "NodeType": "Block", + "Expressions": [ + { + "NodeType": "Assignment", + "Identifier": { + "NodeType": "Identifier", + "Name": "sum" + }, + "Value": { + "NodeType": "FunctionCall", + "Callee": { + "NodeType": "Identifier", + "Name": "+" + }, + "Arguments": [ + { + "NodeType": "Identifier", + "Name": "sum" + }, + { + "NodeType": "Identifier", + "Name": "val" + } + ] + } + }, + { + "NodeType": "Assignment", + "Identifier": { + "NodeType": "Identifier", + "Name": "count" + }, + "Value": { + "NodeType": "FunctionCall", + "Callee": { + "NodeType": "Identifier", + "Name": "+" + }, + "Arguments": [ + { + "NodeType": "Identifier", + "Name": "count" + }, + { + "NodeType": "Constant", + "Value": { + "Kind": "Scalar", + "Value": { + "Kind": "Ordinal", + "Value": 1 + } + } + } + ] + } + }, + { + "NodeType": "Assignment", + "Identifier": { + "NodeType": "Identifier", + "Name": "sum" + }, + "Value": { + "NodeType": "TernaryExpr", + "Condition": { + "NodeType": "FunctionCall", + "Callee": { + "NodeType": "Identifier", + "Name": ">" + }, + "Arguments": [ + { + "NodeType": "Identifier", + "Name": "count" + }, + { + "NodeType": "Identifier", + "Name": "len" + } + ] + }, + "ThenBranch": { + "NodeType": "FunctionCall", + "Callee": { + "NodeType": "Identifier", + "Name": "-" + }, + "Arguments": [ + { + "NodeType": "Identifier", + "Name": "sum" + }, + { + "NodeType": "Indexer", + "Base": { + "NodeType": "Identifier", + "Name": "series" + }, + "Index": { + "NodeType": "Identifier", + "Name": "len" + } + } + ] + }, + "ElseBranch": { + "NodeType": "Identifier", + "Name": "sum" + } + } + }, + { + "NodeType": "FunctionCall", + "Callee": { + "NodeType": "Identifier", + "Name": "/" + }, + "Arguments": [ + { + "NodeType": "Identifier", + "Name": "sum" + }, + { + "NodeType": "TernaryExpr", + "Condition": { + "NodeType": "FunctionCall", + "Callee": { + "NodeType": "Identifier", + "Name": "<" + }, + "Arguments": [ + { + "NodeType": "Identifier", + "Name": "count" + }, + { + "NodeType": "Identifier", + "Name": "len" + } + ] + }, + "ThenBranch": { + "NodeType": "Identifier", + "Name": "count" + }, + "ElseBranch": { + "NodeType": "Identifier", + "Name": "len" + } + } + ] + } + ] + } + } + ] + } } } \ No newline at end of file diff --git a/KI/FMX_Intf.txt b/KI/FMX_Intf.txt index 902781e..b63e3c0 100644 --- a/KI/FMX_Intf.txt +++ b/KI/FMX_Intf.txt @@ -1,7 +1,7 @@ // Combined interfaces from directories: // - C:\Program Files (x86)\Embarcadero\Studio\23.0\source\fmx (recursive) // Focus mode (-fx) active for files: T:\Myc\ASTPlayground\MainForm.pas -// Generated on: 29.08.2025 17:22:17 +// Generated on: 07.10.2025 11:01:41 uses system.actions, @@ -16,14 +16,16 @@ uses system.math.vectors, system.messaging, system.rtti, + system.strutils, system.sysutils, system.types, + system.typinfo, system.uiconsts, system.uitypes, winapi.messages; //================================================================================================== -//== UNIT START: FMX.ActnList (from FMX.ActnList.pas) +//== INTERFACE START: FMX.ActnList (from FMX.ActnList.pas) //================================================================================================== {$SCOPEDENUMS ON} @@ -315,11 +317,11 @@ type function TextToShortCut(const AText: string): Integer; -//== UNIT END: FMX.ActnList +//== INTERFACE END: FMX.ActnList //================================================================================================== //================================================================================================== -//== UNIT START: FMX.Presentation.Messages (from FMX.Presentation.Messages.pas) +//== INTERFACE START: FMX.Presentation.Messages (from FMX.Presentation.Messages.pas) //================================================================================================== {$SCOPEDENUMS ON} @@ -392,11 +394,11 @@ type ['{64DD751B-91F5-4767-994F-2787E21ABEF2}'] end deprecated 'Use IMessageSendingCompatible'; -//== UNIT END: FMX.Presentation.Messages +//== INTERFACE END: FMX.Presentation.Messages //================================================================================================== //================================================================================================== -//== UNIT START: FMX.Consts (from FMX.Consts.pas) +//== INTERFACE START: FMX.Consts (from FMX.Consts.pas) //================================================================================================== {$SCOPEDENUMS ON} @@ -1184,11 +1186,11 @@ resourcestring SBiometricErrorSystemErrorInvalidContext = 'Invalid context'; SBiometricErrorSystemErrorCancelledBySystem = 'Cancelled by system'; -//== UNIT END: FMX.Consts +//== INTERFACE END: FMX.Consts //================================================================================================== //================================================================================================== -//== UNIT START: FMX.Types (from FMX.Types.pas) +//== INTERFACE START: FMX.Types (from FMX.Types.pas) //================================================================================================== {$SCOPEDENUMS ON} @@ -3124,11 +3126,11 @@ var type TKeyKind = (Usual, Functional, Unknown); -//== UNIT END: FMX.Types +//== INTERFACE END: FMX.Types //================================================================================================== //================================================================================================== -//== UNIT START: FMX.Controls.Model (from FMX.Controls.Model.pas) +//== INTERFACE START: FMX.Controls.Model (from FMX.Controls.Model.pas) //================================================================================================== @@ -3187,11 +3189,11 @@ type /// Class reference of TDataModel. TDataModelClass = class of TDataModel; -//== UNIT END: FMX.Controls.Model +//== INTERFACE END: FMX.Controls.Model //================================================================================================== //================================================================================================== -//== UNIT START: FMX.AcceleratorKey (from FMX.AcceleratorKey.pas) +//== INTERFACE START: FMX.AcceleratorKey (from FMX.AcceleratorKey.pas) //================================================================================================== {$SCOPEDENUMS ON} @@ -3241,11 +3243,11 @@ type procedure ExtractAcceleratorKey(const AText: string; out Key: Char; out KeyIndex: Integer); end; -//== UNIT END: FMX.AcceleratorKey +//== INTERFACE END: FMX.AcceleratorKey //================================================================================================== //================================================================================================== -//== UNIT START: FMX.Styles (from FMX.Styles.pas) +//== INTERFACE START: FMX.Styles (from FMX.Styles.pas) //================================================================================================== {$SCOPEDENUMS ON} @@ -3423,11 +3425,11 @@ type class function GetStyleDescriptionForControl(const AObject: TFmxObject): TStyleDescription; end; -//== UNIT END: FMX.Styles +//== INTERFACE END: FMX.Styles //================================================================================================== //================================================================================================== -//== UNIT START: FMX.VirtualKeyboard (from FMX.VirtualKeyboard.pas) +//== INTERFACE START: FMX.VirtualKeyboard (from FMX.VirtualKeyboard.pas) //================================================================================================== {$SCOPEDENUMS ON} @@ -3477,11 +3479,11 @@ type property OnExecute: TNotifyEvent read FOnExecute write FOnExecute; end; -//== UNIT END: FMX.VirtualKeyboard +//== INTERFACE END: FMX.VirtualKeyboard //================================================================================================== //================================================================================================== -//== UNIT START: FMX.InertialMovement (from FMX.InertialMovement.pas) +//== INTERFACE START: FMX.InertialMovement (from FMX.InertialMovement.pas) //================================================================================================== {$SCOPEDENUMS ON} @@ -3753,11 +3755,218 @@ type end; {$ENDREGION} -//== UNIT END: FMX.InertialMovement +//== INTERFACE END: FMX.InertialMovement //================================================================================================== //================================================================================================== -//== UNIT START: FMX.Surfaces (from FMX.Surfaces.pas) +//== INTERFACE START: FMX.Utils (from FMX.Utils.pas) +//================================================================================================== + +{$SCOPEDENUMS ON} + + +type + PAlphaColorArray = ^TAlphaColorArray; + TAlphaColorArray = array [0 .. MaxInt div 4 - 1] of TAlphaColor; + + PAlphaColorRecArray = ^TAlphaColorRecArray; + TAlphaColorRecArray = array [0 .. MaxInt div 4 - 1] of TAlphaColorRec; + + /// + /// A helper class that contains utilities to facilitate writing non-reentrant sections of code. It does not + /// provide thread-safety. A non-reentrable task is passed as a procedure or a function and can return a value. + /// Guard flag variable Guard is passed by reference and should be False in order for the procedure to execute. + /// + /// For the cases when a non-reentrant section cannot be contained in one procedure, EnterSection/LeaveSection + /// can be used. + /// + TNonReentrantHelper = class + public + /// Execute non-reentrable procedure Proc using guard variable Guard. Return True if procedure was + /// executed + class function Execute(var Guard: Boolean; const Proc: TProc): Boolean; overload; + /// Execute non-reentrable procedure Proc<A> with an argument of type A. Return True if procedure + /// was executed + class function Execute(var Guard: Boolean; const Proc: TProc; const Arg: A): Boolean; overload; + /// Execute non-reentrable function Func:R. Return function result of type R or provided Default + /// value of type R if the code was not executed + class function Execute(var Guard: Boolean; const Func: TFunc; const Default: R): R; overload; + /// Execute non-reentrable function Func with an argument of type A and return type R. Return function + /// result or provided default value of type R if the code was not executed + class function Execute(var Guard: Boolean; const Func: TFunc; const Arg: A; const Default: R): R; overload; + /// Enter non-reentrable section of code. If the value of Guard was False, it will be changed to True + /// and the result will be True. Otherwise the value is not going to be changed and the result will be False. + /// + class function EnterSection(var Guard: Boolean): Boolean; inline; + /// Leave non-reentrable section of code. This should only be called once after EnterSection with same + /// Guard variable returned True + class procedure LeaveSection(var Guard: Boolean); inline; + end; + + TFMXObjectHelper = class + public type + TFilterFunc = TFunc; + ESearchException = class(Exception); + public + /// Finds first parent, which conforms AFilter. If parent is found, returns true and parent in AResult, + /// otherwise returns false and nil in AResult + class function FindParent(const AObject: TFMXObject; const AFilter: TFilterFunc; var AResult: TFMXObject): Boolean; + /// Returns first parent, which conforms AFilter. If parent is found, returns parent, + /// otherwise raises exception ESearchException + class function GetParent(const AObject: TFMXObject; const AFilter: TFilterFunc): TFMXObject; + /// Finds nearest parent of T class. If parent is found, returns true and parent in AResult, + /// otherwise returns false and nil in AResult + class function FindNearestParentOfClass(const AObject: TFMXObject; var AResult: T): Boolean; + /// Returns first parent of T class. If parent is found, returns parent, + /// otherwise raises exception ESearchException + class function GetNearestParentOfClass(const AObject: TFMXObject): T; + end; + +/// +/// Calculate relative luminance of given TAlphaColor. +/// See: http://en.wikipedia.org/wiki/Luminance_(relative) +/// Return value in range [0..1] +/// 1 - Light +/// 0 - Dark +/// +function Luminance(const AColor: TAlphaColor): Single; +/// +/// Fill array of TAlphaColor Dest of size Count with TAlphaColor value Value. +/// +procedure FillAlphaColor(const Dest: PAlphaColorArray; const Count: Integer; const Value: TAlphaColor); +/// +/// Fill a TAlphaColor rectangle in bit plane Dest of Width x Height with TAlphaColor value Value. +/// Rectangle is specified by (X1,Y1)-(X2,Y2), right-bottom bounds not included. +/// +procedure FillAlphaColorRect(const Dest: PAlphaColorArray; Width, Height, X1, Y1, X2, Y2: Integer; + const Value: TAlphaColor); +/// +/// Fill Alpha in pixel array Dest of size Count. Other color components are intact. +/// +procedure FillAlpha(const Dest: PAlphaColorRecArray; const Count: Integer; const Alpha: Byte); +/// +/// Reverse order of bytes in place in array Dest of size Count. +/// +procedure ReverseBytes(const Dest: Pointer; const Count: Integer); deprecated; +/// +/// Return a string representation of R: TRectF. +/// +function RectToString(const R: TRectF): string; +/// +/// Return TRectF represented by string S. +/// +function StringToRect(S: string): TRectF; +/// Trying to bring a text string containing the number to the canonical form +function FixNumberText(const AText: string): string; +/// +/// Return a string representation of P: TPointF. +/// +function PointToString(const P: TPointF): string; +/// +/// Return TPointF represented by string S. +/// +function StringToPoint(S: string): TPointF; +/// +/// Return a Single value between Start and Stop at time moment T. When T = 0, Result = Start. When T = 1, Result = Stop. +/// +function InterpolateSingle(const Start, Stop, T: Single): Single; +/// +/// Used for rotation angles. Same as InterpolateSingle. +/// +function InterpolateRotation(const Start, Stop, T: Single): Single; +/// +/// Interpolate color value between colors Start and Stop at time moment T. +/// When T = 0, Result = Start. When T = 1, Result = Stop. +/// +function InterpolateColor(const Start, Stop: TAlphaColor; T: Single): TAlphaColor; +/// +/// Get a token from string S. Tokens are separated by one of the characters in Separators. Separators may be different +/// every time GetToken is called. +/// S is modified for subsequent calls to GetToken. +/// +function GetToken(var S: string; const Separators: string; const Stop: string = string.Empty): string; overload; +/// +/// Get a token from immutable string S, starting at position Pos. Pos is updated for subsequent calls to GetToken. +/// Tokens are separated by one of the characters in Separators. Separators may be different every time GetToken is +/// called. +/// +function GetToken(var Pos: Integer; const S: string; const Separators: string; + const Stop: string = string.Empty): string; overload; +/// +/// Return a string representation of P: TPoint3D. +/// +function Point3DToString(const P: TPoint3D): string; +/// +/// Return TPoint3D represented by string S. +/// +function StringToPoint3D(S: string): TPoint3D; +/// +/// Returns the short version of the hint specified in the Hint string +/// +function GetShortHint(const Hint: string): string; +/// +/// Returns the long version of the hint specified in the Hint string +/// +function GetLongHint(const Hint: string): string; +/// +/// Make a normalized TVector3D equivalent to given TAlphaColor. +/// +function ColorToVector3D(const AColor: TAlphaColor): TVector3D; deprecated 'Use TAlphaColorF instead.'; +/// +/// Make a TAlphaColor from TVector3D. The vector should be normalized. +/// +function Vector3DToColor(const AColor: TVector3D): TAlphaColor; deprecated 'Use TAlphaColorF instead.'; +/// verifies that AValue is an instance of AClass or its heir. +/// If this is not true, then it raise the exception. +/// If AValue=nil and CanBeNil=true nothing happens, otherwise it raises the exception +///EArgumentException is raised if AValue does not satisfy the conditions +///EArgumentNilException is raised if AValue or AClass is nil +procedure ValidateInheritance(const AValue: TPersistent; const AClass: TClass; const CanBeNil: Boolean = True); + +/// This function returns true if the given point (APoint) is inside or is on the contour of a +///circle centered at ACenter with radius ARadius. +function IsPointInCircle(const APoint, ACenter: TPointF; const ARadius: Integer): Boolean; + +/// Takes into account margin of error returning a percentage of match. +/// 100% match will be margin of error of deviation from the source point. +/// 0% will be at deviation away and beyond. +function CheckPoint(const APoint, ASource: TPointF; const ADeviation, ErrorMargin: Integer): Double; + +// 2D shapes +type + /// This structure represents a 2D circle centered in Center with a Radius. + TCircle2D = record + /// Center of the circle. + Center: TPointF; + /// Radius of the circle. + Radius: Single; + /// Default constructor. + constructor Create(const ACenter: TPointF; const ARadius: Single); + end; + + /// This structure represents a 2D line passing through one Origin and with a Direction. + TLine2D = record + /// Origin of the line. + Origin: TPointF; + /// Direction of the line. + Direction: TPointF; + /// Default constructor. + constructor Create(const AnOrigin, ADestination: TPointF); + /// Returns true if the line intersects with the circle, False otherwise. + function Intersects(const ACircle: TCircle2D): Boolean; + end; + +var + /// + /// used for correct string to float convertion + /// + USFormatSettings: TFormatSettings; + +//== INTERFACE END: FMX.Utils +//================================================================================================== + +//================================================================================================== +//== INTERFACE START: FMX.Surfaces (from FMX.Surfaces.pas) //================================================================================================== {$SCOPEDENUMS ON} @@ -3832,11 +4041,11 @@ type property Mip[const MipIndex: Integer]: TMipmapSurface read GetMip; end; -//== UNIT END: FMX.Surfaces +//== INTERFACE END: FMX.Surfaces //================================================================================================== //================================================================================================== -//== UNIT START: FMX.Graphics (from FMX.Graphics.pas) +//== INTERFACE START: FMX.Graphics (from FMX.Graphics.pas) //================================================================================================== {$SCOPEDENUMS ON} @@ -5289,11 +5498,11 @@ type property StyledSettings: TStyledSettings read GetStyledSettings write SetStyledSettings; end; -//== UNIT END: FMX.Graphics +//== INTERFACE END: FMX.Graphics //================================================================================================== //================================================================================================== -//== UNIT START: FMX.Ani (from FMX.Ani.pas) +//== INTERFACE START: FMX.Ani (from FMX.Ani.pas) //================================================================================================== {$SCOPEDENUMS ON} @@ -5855,11 +6064,11 @@ function InterpolateCirc(t, B, C, D: Single; AType: TAnimationType): Single; function InterpolateBounce(t, B, C, D: Single; AType: TAnimationType): Single; function InterpolateBack(t, B, C, D, S: Single; AType: TAnimationType): Single; -//== UNIT END: FMX.Ani +//== INTERFACE END: FMX.Ani //================================================================================================== //================================================================================================== -//== UNIT START: FMX.MultiResBitmap (from FMX.MultiResBitmap.pas) +//== INTERFACE START: FMX.MultiResBitmap (from FMX.MultiResBitmap.pas) //================================================================================================== {$SCOPEDENUMS ON} @@ -6054,11 +6263,11 @@ type function ScaleList: TScaleList; function RegisterScaleName(Scale: Single; Name: string): Boolean; -//== UNIT END: FMX.MultiResBitmap +//== INTERFACE END: FMX.MultiResBitmap //================================================================================================== //================================================================================================== -//== UNIT START: FMX.Types3D (from FMX.Types3D.pas) +//== INTERFACE START: FMX.Types3D (from FMX.Types3D.pas) //================================================================================================== {$SCOPEDENUMS ON} @@ -7003,11 +7212,11 @@ function RayCastTriangleIntersect(const RayPos, RayDir: TPoint3D; const Vertex1, function WideGetToken(var Pos: Integer; const S: string; const Separators: string; const Stop: string = ''): string; -//== UNIT END: FMX.Types3D +//== INTERFACE END: FMX.Types3D //================================================================================================== //================================================================================================== -//== UNIT START: FMX.TextLayout (from FMX.TextLayout.pas) +//== INTERFACE START: FMX.TextLayout (from FMX.TextLayout.pas) //================================================================================================== {$SCOPEDENUMS ON} @@ -7206,11 +7415,11 @@ type function IsPointInRect(const APoint: TPointF; const ARect: TRectF): Boolean; -//== UNIT END: FMX.TextLayout +//== INTERFACE END: FMX.TextLayout //================================================================================================== //================================================================================================== -//== UNIT START: FMX.Filter (from FMX.Filter.pas) +//== INTERFACE START: FMX.Filter (from FMX.Filter.pas) //================================================================================================== {$SCOPEDENUMS ON} @@ -7443,11 +7652,11 @@ type EFilterException = class(Exception); EFilterManagerException = class(Exception); -//== UNIT END: FMX.Filter +//== INTERFACE END: FMX.Filter //================================================================================================== //================================================================================================== -//== UNIT START: FMX.Text (from FMX.Text.pas) +//== INTERFACE START: FMX.Text (from FMX.Text.pas) //================================================================================================== {$SCOPEDENUMS ON} @@ -7801,11 +8010,11 @@ type function TryTextToValue(AText: string; var AValue: Single; DefaultValue: Single): Boolean; overload; function TryTextToValue(AText: string; var AValue: Double; DefaultValue: Double): Boolean; overload; -//== UNIT END: FMX.Text +//== INTERFACE END: FMX.Text //================================================================================================== //================================================================================================== -//== UNIT START: FMX.Effects (from FMX.Effects.pas) +//== INTERFACE START: FMX.Effects (from FMX.Effects.pas) //================================================================================================== {$SCOPEDENUMS ON} @@ -8040,11 +8249,11 @@ type procedure Blur(const Canvas: TCanvas; const Bitmap: TBitmap; const Radius: Integer; UseAlpha: Boolean = True); -//== UNIT END: FMX.Effects +//== INTERFACE END: FMX.Effects //================================================================================================== //================================================================================================== -//== UNIT START: FMX.Text.UndoManager (from FMX.Text.UndoManager.pas) +//== INTERFACE START: FMX.Text.UndoManager (from FMX.Text.UndoManager.pas) //================================================================================================== {$SCOPEDENUMS ON} @@ -8165,11 +8374,11 @@ type TEditActionStack = TUndoManager deprecated 'Use TUndoManager instead'; -//== UNIT END: FMX.Text.UndoManager +//== INTERFACE END: FMX.Text.UndoManager //================================================================================================== //================================================================================================== -//== UNIT START: FMX.Controls (from FMX.Controls.pas) +//== INTERFACE START: FMX.Controls (from FMX.Controls.pas) //================================================================================================== {$SCOPEDENUMS ON} @@ -9837,11 +10046,11 @@ type function FindProperty(var O: TObject; Path: string; const Apply: TPropertyApplyProc): Boolean; -//== UNIT END: FMX.Controls +//== INTERFACE END: FMX.Controls //================================================================================================== //================================================================================================== -//== UNIT START: FMX.Memo.Types (from FMX.Memo.Types.pas) +//== INTERFACE START: FMX.Memo.Types (from FMX.Memo.Types.pas) //================================================================================================== {$SCOPEDENUMS ON} @@ -9863,11 +10072,11 @@ type // Type alias for backward compatibility TCaretPosition = FMX.Text.TCaretPosition; -//== UNIT END: FMX.Memo.Types +//== INTERFACE END: FMX.Memo.Types //================================================================================================== //================================================================================================== -//== UNIT START: FMX.ImgList (from FMX.ImgList.pas) +//== INTERFACE START: FMX.ImgList (from FMX.ImgList.pas) //================================================================================================== {$SCOPEDENUMS ON} @@ -10381,11 +10590,11 @@ type property OnPainting; end; -//== UNIT END: FMX.ImgList +//== INTERFACE END: FMX.ImgList //================================================================================================== //================================================================================================== -//== UNIT START: FMX.Forms (from FMX.Forms.pas) +//== INTERFACE START: FMX.Forms (from FMX.Forms.pas) //================================================================================================== {$SCOPEDENUMS ON} @@ -11818,11 +12027,11 @@ function ApplicationState: TApplicationState; procedure FinalizeForms; {$ENDIF} -//== UNIT END: FMX.Forms +//== INTERFACE END: FMX.Forms //================================================================================================== //================================================================================================== -//== UNIT START: FMX.Controls.Presentation (from FMX.Controls.Presentation.pas) +//== INTERFACE START: FMX.Controls.Presentation (from FMX.Controls.Presentation.pas) //================================================================================================== {$SCOPEDENUMS ON} @@ -12188,11 +12397,11 @@ type property OnPresentationNameChoosing: TPresenterNameChoosingEvent read FOnPresenterNameChoosing write FOnPresenterNameChoosing; end; -//== UNIT END: FMX.Controls.Presentation +//== INTERFACE END: FMX.Controls.Presentation //================================================================================================== //================================================================================================== -//== UNIT START: FMX.BehaviorManager (from FMX.BehaviorManager.pas) +//== INTERFACE START: FMX.BehaviorManager (from FMX.BehaviorManager.pas) //================================================================================================== {$SCOPEDENUMS ON} @@ -12279,11 +12488,11 @@ type function BehaviorServices: TBehaviorServices; inline; deprecated 'Use TBehaviorServices.Current'; -//== UNIT END: FMX.BehaviorManager +//== INTERFACE END: FMX.BehaviorManager //================================================================================================== //================================================================================================== -//== UNIT START: FMX.Dialogs (from FMX.Dialogs.pas) +//== INTERFACE START: FMX.Dialogs (from FMX.Dialogs.pas) //================================================================================================== {$SCOPEDENUMS ON} @@ -12502,11 +12711,11 @@ procedure InputQuery(const ACaption, APrompt, ADefaultValue: string; function LocalizedButtonCaption(const AButton: TMsgDlgBtn): string; inline; function LocalizedMessageDialogTitle(const ADialogType: TMsgDlgType): string; inline; -//== UNIT END: FMX.Dialogs +//== INTERFACE END: FMX.Dialogs //================================================================================================== //================================================================================================== -//== UNIT START: FMX.Platform (from FMX.Platform.pas) +//== INTERFACE START: FMX.Platform (from FMX.Platform.pas) //================================================================================================== {$SCOPEDENUMS ON} @@ -12972,11 +13181,210 @@ type end; TPushFailToRegisterMessage = class (System.Messaging.TMessage); -//== UNIT END: FMX.Platform +//== INTERFACE END: FMX.Platform //================================================================================================== //================================================================================================== -//== UNIT START: FMX.Objects (from FMX.Objects.pas) +//== INTERFACE START: FMX.DialogService (from FMX.DialogService.pas) +//================================================================================================== + +{$SCOPEDENUMS ON} + + +type + /// Service for managing platform differences in behaviours when showing dialogs. It has a PreferredMode that + /// can have three values: + /// Platform Sync methods for Desktop OS's (Windows and OSX) and ASync for Mobile (Android adn IOS) + /// Sync Sync methods are preferred. Used when available (All but Android) + /// Async Async methods are preferred. Used when available (All platforms) + /// + TDialogService = class + public type + TPreferredMode = (Platform, Async, Sync); + + strict private + class var FPreferredMode: TPreferredMode; + class var FInSyncMode: Boolean; + class procedure SetPreferredMode(const PreferredMode: TPreferredMode); static; + + public + class constructor ClassCreate; + + /// Show a simple message box with an 'Ok' button to close it. + class procedure ShowMessage(const AMessage: string); overload; + class procedure ShowMessage(const AMessage: string; const ACloseDialogProc: TInputCloseDialogProc); overload; + class procedure ShowMessage(const AMessage: string; const ACloseDialogEvent: TInputCloseDialogEvent; + const AContext: TObject = nil); overload; + + /// Shows custom message dialog with specified buttons on it. + class procedure MessageDialog(const AMessage: string; const ADialogType: TMsgDlgType; + const AButtons: TMsgDlgButtons; const ADefaultButton: TMsgDlgBtn; const AHelpCtx: THelpContext; + const ACloseDialogProc: TInputCloseDialogProc); overload; + class procedure MessageDialog(const AMessage: string; const ADialogType: TMsgDlgType; + const AButtons: TMsgDlgButtons; const ADefaultButton: TMsgDlgBtn; const AHelpCtx: THelpContext; + const ACloseDialogEvent: TInputCloseDialogEvent; const AContext: TObject = nil); overload; + + /// Shows an input message dialog with the specified prompts and values in it. + /// Values are returned in the callback. + class procedure InputQuery(const ACaption: string; const APrompts: array of string; const AValues: array of string; + const ACloseQueryProc: TInputCloseQueryProc); overload; + /// Shows an input message dialog with the specified prompts and values in it. + /// Values are returned in the callback. + class procedure InputQuery(const ACaption: string; const APrompts: array of string; const AValues: array of string; + const ACloseQueryEvent: TInputCloseQueryWithResultEvent; const AContext: TObject = nil); overload; + + /// Sets the default presentation mode for dialogs. + class property PreferredMode: TPreferredMode read FPreferredMode write SetPreferredMode; + end; + +//== INTERFACE END: FMX.DialogService +//================================================================================================== + +//================================================================================================== +//== INTERFACE START: FMX.Clipboard (from FMX.Clipboard.pas) +//================================================================================================== + +{$SCOPEDENUMS ON} + + +type + /// + /// Clipboard support service + /// + IFMXExtendedClipboardService = interface(IFMXClipboardService) + ['{E96E4776-8234-49F9-B15F-301074E23F70}'] + /// + /// Returns True is clipboard containter text data + /// + function HasText: Boolean; + /// + /// Gets text data from then clipboard + /// + function GetText: string; + /// + /// Sets text as a clipboard data + /// + /// + /// Text data to be added to the clipboard. + /// + /// + /// Indicates whether or not the text contains sensitive content, such as password or credit card number. + /// Its default value is False. + /// + /// + /// The IsSensitive parameter is only relevant for Android applications that allow users to copy sensitive + /// content. Its use is recommended to prevent sensitive content from appearing in the clipboard editor overlay + /// introduced in Android 13. + /// + procedure SetText(const Value: string; IsSensitive: Boolean = False); + /// + /// Returns True is clipboard containter image data + /// + function HasImage: Boolean; + /// + /// Gets image data from the clipboard + /// + function GetImage: TBitmapSurface; + /// + /// Sets image as a clipboard data + /// + procedure SetImage(const Value: TBitmapSurface); + /// + /// Registers custom clipboard format with AFormatName name + /// + /// + /// Specify the name for the custom format + /// + /// + /// Methods throws EClipboardFormatRegisterError in case format with AFormatName name had already + /// registered or thare was a platform error while registration + /// + procedure RegisterCustomFormat(const AFormatName: string); + /// + /// Checks wherever custom format is registered + /// + /// + /// Specify the name for the custom format + /// + function IsCustomFormatRegistered(const AFormatName: string): Boolean; + /// + /// Unregister custom clipboard format with AFormatName name + /// + /// + /// Specify the name for the custom format + /// + /// + /// Method throws EClipboardFormatNotRegistered in case format with AFormatName was not registered + /// + procedure UnregisterCustomFormat(const AFormatName: string); + /// + /// Checks wherever clipboard contains custom format + /// + /// + /// Specify the name for the custom format + /// + /// + /// Returns True if clipboard contains custom format + /// + /// + /// Method throws EArgumentException in case AFormatName is empty + /// Method throws EClipboardFormatNotRegistered in case format with AFormatName was not registered + /// + function HasCustomFormat(const AFormatName: string): Boolean; + /// + /// Get data stream for the custom clipboard format + /// + /// + /// Specify the name for the custom format + /// + /// + /// Specify the stream that will get custom format data + /// + /// + /// Returns True in case custom format was succesfuly written in AStream + /// AFormatName data + /// + /// + /// Method throws EArgumentException in case AFormatName is empty + /// Method throws EArgumentNilException in case AStream is nil + /// Method throws EClipboardFormatNotRegistered in case format with AFormatName was not registered + /// + function GetCustomFormat(const AFormatName: string; const AStream: TStream): Boolean; + /// + /// Set clipboard data with custom format specified by AFormatName name and data in the AStream + /// + /// + /// Specify the name for the custom format + /// + /// + /// Specify the stream that contains data for the custom format + /// + /// + /// Method throws EArgumentException in case AFormatName is empty + /// Method throws EArgumentNilException in case AStream is nil + /// Method throws EClipboardFormatNotRegistered in case format with AFormatName was not registered + /// + procedure SetCustomFormat(const AFormatName: string; const AStream: TStream); + end; + + /// + /// Basic exception that can be thrown by the methods of the IFMXClipboardService + /// + EClipboardError = class(Exception); + /// + /// Throws when there was some error while registering custom format + /// + EClipboardFormatRegisterError = class(EClipboardError); + /// + /// Throws when trying to use custom format methods with format name that wasn't registered + /// + EClipboardFormatNotRegistered = class(EClipboardError); + +//== INTERFACE END: FMX.Clipboard +//================================================================================================== + +//================================================================================================== +//== INTERFACE START: FMX.Objects (from FMX.Objects.pas) //================================================================================================== {$SCOPEDENUMS ON} @@ -14044,11 +14452,11 @@ type property OnTrack: TOnChangeTracking read FOnChangeTrack write FOnChangeTrack; end; -//== UNIT END: FMX.Objects +//== INTERFACE END: FMX.Objects //================================================================================================== //================================================================================================== -//== UNIT START: FMX.StdActns (from FMX.StdActns.pas) +//== INTERFACE START: FMX.StdActns (from FMX.StdActns.pas) //================================================================================================== {$SCOPEDENUMS ON} @@ -14442,11 +14850,771 @@ type end; -//== UNIT END: FMX.StdActns +//== INTERFACE END: FMX.StdActns //================================================================================================== //================================================================================================== -//== UNIT START: FMX.StdCtrls (from FMX.StdCtrls.pas) +//== INTERFACE START: FMX.Styles.Objects (from FMX.Styles.Objects.pas) +//================================================================================================== + +{$SCOPEDENUMS ON} + + +type + TStyleTrigger = (MouseOver, Pressed, Selected, Focused, Checked, Active); + +{ Image Objects } + + TBitmapLink = class(TCollectionItem) + private + FCapInsetsChanged: Boolean; + FCapInsets: TBounds; + FSourceRect: TBounds; + FScale: Single; + procedure SetCapInsets(const Value: TBounds); + procedure SetSourceRect(const Value: TBounds); + procedure SetScale(const Value: Single); + procedure DoCapInsetsChanged(Sender: TObject); + function IsScaleStored: Boolean; + public + constructor Create(Collection: TCollection); override; + destructor Destroy; override; + procedure Assign(Source: TPersistent); override; + property CapInsetsChanged: Boolean read FCapInsetsChanged; + published + property CapInsets: TBounds read FCapInsets write SetCapInsets; + property Scale: Single read FScale write SetScale stored IsScaleStored; + property SourceRect: TBounds read FSourceRect write SetSourceRect; + end; + + TCapWrapMode = (Stretch, Tile); + + TBitmapLinks = class(TCollection) + public type + TPropertyLoader = class + private + FFiler: TFiler; + FInstance: TBitmapLinks; + FPropertyName: string; + procedure ReadBitmapMargin(Reader: TReader); + procedure ReadSourceRect(Reader: TReader); + procedure ReadBitmapMargin15x(Reader: TReader); + procedure ReadSourceRect15x(Reader: TReader); + procedure ReadBitmapMargin20x(Reader: TReader); + procedure ReadSourceRect20x(Reader: TReader); + procedure ReadBitmapMargin30x(Reader: TReader); + procedure ReadSourceRect30x(Reader: TReader); + function FindOrCreateBitmapLink(const Scale: Single): TBitmapLink; + procedure ReadBitmapLinkSourceRect(Reader: TReader; const Scale: Single); + procedure ReadBitmapLinkCapInsets(Reader: TReader; const Scale: Single); + public + constructor Create(const AInstance: TBitmapLinks; const AFiler: TFiler; const APropertyName: string = ''); + procedure ReadSourceRects; + procedure ReadCapInsets; + property Instance: TBitmapLinks read FInstance; + property PropertyName: string read FPropertyName; + property Filer: TFiler read FFiler; + end; + private + function GetLink(AIndex: Integer): TBitmapLink; + function GetEmpty: Boolean; + public + constructor Create; + procedure AssignCapInsets(const Source: TBitmapLinks); + function LinkByScale(const AScale: Single; const ExactMatch: Boolean): TBitmapLink; + property Links[AIndex: Integer]: TBitmapLink read GetLink; + property Empty: Boolean read GetEmpty; + end; + + TCustomStyleObject = class(TControl, IDrawableObject) + public type + TTintStage = (Undefined, Shadow, Mask, Shine); + private + FOpaque: Boolean; + FSource: TImage; + FSourceLookup: string; + FCapMode: TCapWrapMode; + FWrapMode: TImageWrapMode; + FTintColor: TAlphaColor; + FTintBuffer: TBitmap; + FNeedsUpdateTintBuffer: Boolean; + FTintStage: TTintStage; + procedure SetCapMode(const Value: TCapWrapMode); + procedure SetWrapMode(const Value: TImageWrapMode); + procedure ReadOpaque(Reader: TReader); + procedure WriteOpaque(Writer: TWriter); + procedure SetOpaque(const Value: Boolean); + procedure SetSource(const Value: TImage); + procedure SetSourceLookup(const Value: string); + procedure ReadMarginWrapMode(Reader: TReader); + class var + FAlignToPixels: Boolean; + protected + procedure DefineProperties(Filer: TFiler); override; + procedure Paint; override; + procedure FreeNotification(AObject: TObject); override; + procedure DoDrawToCanvas(const Canvas: TCanvas; const ARect: TRectF; const AOpacity: Single = 1.0); + function DoGetUpdateRect: TRectF; override; + protected + function GetCurrentLink: TBitmapLinks; virtual; abstract; + function GetCanBeTinted: Boolean; virtual; + procedure PrepareTintBuffer(const Canvas: TCanvas; const ATintColor: TAlphaColor); + procedure NeedsUpdateTintBuffer; + procedure SetTintColor(const ATintColor: TAlphaColor); + property CanBeTinted: Boolean read GetCanBeTinted; + property TintColor: TAlphaColor read FTintColor write SetTintColor; + property TintStage: TTintStage read FTintStage; + property TintBuffer: TBitmap read FTintBuffer; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure DrawToCanvas(const Canvas: TCanvas; const ARect: TRectF; const AOpacity: Single = 1.0); overload; inline; + procedure DrawToCanvas(const Canvas: TCanvas; const ARect: TRectF; const ATintColor: TAlphaColor; + const AOpacity: Single = 1.0); overload; + function IsEmpty: Boolean; + property Opaque: Boolean read FOpaque write SetOpaque; + property Source: TImage read FSource write SetSource; + class function ScreenScaleToStyleScale(const ScreenScale: Single): Single; + class property AlignToPixels: Boolean read FAlignToPixels write FAlignToPixels; + published + property Align; + property Anchors; + property CapMode: TCapWrapMode read FCapMode write SetCapMode default TCapWrapMode.Stretch; + property CanParentFocus; + property ClipChildren default False; + property ClipParent default False; + property Cursor default crDefault; + property DragMode default TDragMode.dmManual; + property EnableDragHighlight default True; + property Enabled default True; + property Locked default False; + property Height; + property HitTest default False; + property Padding; + property Opacity; + property Margins; + property SourceLookup: string read FSourceLookup write SetSourceLookup; + property PopupMenu; + property Position; + property RotationAngle; + property RotationCenter; + property Size; + property Scale; + property WrapMode: TImageWrapMode read FWrapMode write SetWrapMode default TImageWrapMode.Stretch; + property Visible default True; + property Width; + property OnDragEnter; + property OnDragLeave; + property OnDragOver; + property OnDragDrop; + property OnDragEnd; + property OnKeyDown; + property OnKeyUp; + property OnCanFocus; + property OnClick; + property OnDblClick; + property OnEnter; + property OnExit; + property OnMouseDown; + property OnMouseMove; + property OnMouseUp; + property OnMouseWheel; + property OnMouseEnter; + property OnMouseLeave; + property OnPainting; + property OnPaint; + property OnResize; + property OnResized; + end; + + TStyleObject = class(TCustomStyleObject) + private + FSourceLink: TBitmapLinks; + procedure SetSourceLink(const Value: TBitmapLinks); + protected + function GetCurrentLink: TBitmapLinks; override; + procedure DefineProperties(Filer: TFiler); override; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + published + property SourceLink: TBitmapLinks read FSourceLink write SetSourceLink; + end; + + ///Helpers class that incapsulated touch animation behavior, that should be attached to other style object. + TTouchAnimationAdapter = class(TPersistent) + public type + TAnimationKind = (Pressed, Unpressed); + TCustomPaint = procedure of object; + public const + DefaultUnpressingDuration = 0.3; + DefaultPressingDuration = 1; + type + TTouchAnimation = class(TAnimation) + private + [Weak] FAdapter: TTouchAnimationAdapter; + protected + procedure ProcessAnimation; override; + end; + TTouchAnimationObject = class(TCustomStyleObject) + private + [Weak] FAdapter: TTouchAnimationAdapter; + protected + function GetCurrentLink: TBitmapLinks; override; + end; + private + [Weak] FStyleObject: TCustomStyleObject; + FTouchAnimation: TTouchAnimation; + FTouchAnimationObject: TTouchAnimationObject; + FLink: TBitmapLinks; + FPressedPosition: TPointF; + FPressingDuration: Single; + FUnpressingDuration: Single; + FPadding: TBounds; + FCustomPaint: TCustomPaint; + procedure SetLink(const Value: TBitmapLinks); + function PressingDurationStored: Boolean; + function UnpressingDurationStored: Boolean; + procedure SetPadding(const Value: TBounds); + procedure ReadPaddingRect(Reader: TReader); + procedure CreateTouchAnimation; + public + constructor Create(const AStyleObject: TCustomStyleObject); virtual; + destructor Destroy; override; + ///Manually start animation. + procedure StartAnimation(const Control: TControl; const Kind: TAnimationKind); + ///Manually stop animation. + procedure StopAnimation; + ///Draw touch animation stage. + procedure DrawTouchAnimation(const Canvas: TCanvas; const Rect: TRectF); + ///Helpers that used in Owner's StartTriggerAnimation in order to activate touch animation. + procedure StartTriggerAnimation(const AInstance: TFmxObject; const ATrigger: string); + ///Helpers that used in Owner's DefineProperty + procedure DefineTouchAnimationProperty(Filer: TFiler); + ///Return True if touch animation is available in the style + function LinkExists: Boolean; + ///Link to Owner + property TouchAnimation: TTouchAnimation read FTouchAnimation; + ///Callback property called when touch animation runs. + property CustomPaint: TCustomPaint read FCustomPaint write FCustomPaint; + published + /// Part of bitmap which used to draw touch animation + property Link: TBitmapLinks read FLink write SetLink; + /// Duration of animation that started after touch is down + property PressingDuration: Single read FPressingDuration write FPressingDuration stored PressingDurationStored; + /// Duration of animation that started after touch is up + property UnpressingDuration: Single read FUnpressingDuration write FUnpressingDuration + stored UnpressingDurationStored; + /// Size of the border that decreases animation painting rectangle. + property Padding: TBounds read FPadding write SetPadding; + end; + + TTintedStages = class(TPersistent) + private + [Weak] FStyleObject: TCustomStyleObject; + FShadow: TBitmapLinks; + FMask: TBitmapLinks; + FShine: TBitmapLinks; + procedure SetMask(const Value: TBitmapLinks); + procedure SetShadow(const Value: TBitmapLinks); + procedure SetShine(const Value: TBitmapLinks); + public + constructor Create(const AStyleObject: TCustomStyleObject); + destructor Destroy; override; + /// Link to owner style object + property StyleObject: TCustomStyleObject read FStyleObject; + published + property Shadow: TBitmapLinks read FShadow write SetShadow; + property Mask: TBitmapLinks read FMask write SetMask; + property Shine: TBitmapLinks read FShine write SetShine; + end; + + TTintedStyleObject = class(TStyleObject, ITintedObject) + private + FTint: TTintedStages; + procedure SetTint(const Value: TTintedStages); + protected + function GetCurrentLink: TBitmapLinks; override; + procedure DefineProperties(Filer: TFiler); override; + procedure Loaded; override; + { ITintedObject } + function GetCanBeTinted: Boolean; override; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + published + property Tint: TTintedStages read FTint write SetTint; + end; + + /// Interface to access to touch animation adapter + ITouchAnimationObject = interface + ['{75657913-BED4-45CA-A394-B27BF7B2225F}'] + function GetTouchAnimation: TTouchAnimationAdapter; + /// Access property to touch animation adapter + property TouchAnimation: TTouchAnimationAdapter read GetTouchAnimation; + end; + + // XE3 Compatible + TSubImage = class(TStyleObject); + + TActiveStyleObject = class(TCustomStyleObject, ITouchAnimationObject) + private + FSourceLink: TBitmapLinks; + FActive: Boolean; + FActiveLink: TBitmapLinks; + FActiveAnimation: TAnimation; + FTrigger: TStyleTrigger; + FOnTriggered: TNotifyEvent; + FTouchAnimation: TTouchAnimationAdapter; + procedure SetActive(const Value: Boolean); + procedure SetActiveLink(const Value: TBitmapLinks); + procedure SetTrigger(const Value: TStyleTrigger); + procedure SetSourceLink(const Value: TBitmapLinks); + procedure Triggered(Sender: TObject); + procedure SetTouchAnimation(const Value: TTouchAnimationAdapter); + { ITouchAnimationObject } + function GetTouchAnimation: TTouchAnimationAdapter; + protected + procedure DoTriggered; virtual; + procedure SetupAnimations; virtual; + function GetCurrentLink: TBitmapLinks; override; + procedure DefineProperties(Filer: TFiler); override; + procedure Loaded; override; + procedure Paint; override; + property OnTriggered: TNotifyEvent read FOnTriggered write FOnTriggered; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure StartTriggerAnimation(const AInstance: TFmxObject; const ATrigger: string); override; + procedure SetNewScene(AScene: IScene); override; + property Active: Boolean read FActive write SetActive; + published + property ActiveTrigger: TStyleTrigger read FTrigger write SetTrigger; + property ActiveLink: TBitmapLinks read FActiveLink write SetActiveLink; + property SourceLink: TBitmapLinks read FSourceLink write SetSourceLink; + ///Used to add touch animation to the style object + property TouchAnimation: TTouchAnimationAdapter read FTouchAnimation write SetTouchAnimation; + end; + + TTabStyleObject = class(TCustomStyleObject) + private type + TTransitionRec = record + Animation: TAnimation; + Event: TNotifyEvent; + end; + protected type + TLink = (Active, Source, Hot, ActiveHot, Focused, ActiveFocused); + TState = (Active, Hot, Focused); + private + FBitmapLinks: array [TLink] of TBitmapLinks; + FTransitions: array [TState] of TTransitionRec; + FActiveTrigger: TStyleTrigger; + FState: set of TState; + procedure SetActiveTrigger(const Value: TStyleTrigger); + function GetLink(Index: TLink): TBitmapLinks; + procedure SetLink(Index: TLink; const Value: TBitmapLinks); + function GetEvent(Index: TState): TNotifyEvent; + procedure SetEvent(Index: TState; const Value: TNotifyEvent); + procedure InvokeEvent(Index: TState); + + procedure HotTriggered(Sender: TObject); + procedure FocusedTriggered(Sender: TObject); + procedure ActiveTriggered(Sender: TObject); + protected + procedure SetupAnimations; virtual; + function GetCurrentLink: TBitmapLinks; override; + procedure DefineProperties(Filer: TFiler); override; + procedure Loaded; override; + property OnHotTriggered: TNotifyEvent index TLink.Hot read GetEvent write SetEvent; + property OnFocusedTriggered: TNotifyEvent index TLink.Focused read GetEvent write SetEvent; + property OnActiveTriggered: TNotifyEvent index TLink.Active read GetEvent write SetEvent; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure StartTriggerAnimation(const AInstance: TFmxObject; const ATrigger: string); override; + published + property ActiveTrigger: TStyleTrigger read FActiveTrigger write SetActiveTrigger; + property ActiveLink: TBitmapLinks index TLink.Active read GetLink write SetLink; + property SourceLink: TBitmapLinks index TLink.Source read GetLink write SetLink; + property HotLink: TBitmapLinks index TLink.Hot read GetLink write SetLink; + property ActiveHotLink: TBitmapLinks index TLink.ActiveHot read GetLink write SetLink; + property FocusedLink: TBitmapLinks index TLink.Focused read GetLink write SetLink; + property ActiveFocusedLink: TBitmapLinks index TLink.ActiveFocused read GetLink write SetLink; + end; + + TCheckStyleObject = class(TTabStyleObject) + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + end; + + TButtonAnimation = (Normal, Hot, Pressed, Focused); // Don't change order for compatibility with TFontColorForState.TIndex + + TButtonStyleObject = class(TCustomStyleObject) + private type + TTriggerAndLink = record + Animation: TAnimation; + Link: TBitmapLinks; + end; + private + FCurrent: TButtonAnimation; + FTriggerSources: array [TButtonAnimation] of TTriggerAndLink; + FOnNormalTriggered: TNotifyEvent; + FOnHotTriggered: TNotifyEvent; + FOnFocusedTriggered: TNotifyEvent; + FOnPressedTriggered: TNotifyEvent; + FTouchAnimation: TTouchAnimationAdapter; + procedure NormalTriggered(Sender: TObject); + procedure HotTriggered(Sender: TObject); + procedure PressedTriggered(Sender: TObject); + procedure FocusedTriggered(Sender: TObject); + function GetLink(Index: TButtonAnimation): TBitmapLinks; + procedure SetLink(Index: TButtonAnimation; const Value: TBitmapLinks); + procedure SetTouchAnimation(const Value: TTouchAnimationAdapter); + protected + procedure DoNormalTriggered; + procedure DoHotTriggered; + procedure DoPressedTriggered; + procedure DoFocusedTriggered; + function GetCurrentLink: TBitmapLinks; override; + procedure DefineProperties(Filer: TFiler); override; + procedure Loaded; override; + procedure Paint; override; + property OnNormalTriggered: TNotifyEvent read FOnNormalTriggered write FOnNormalTriggered; + property OnHotTriggered: TNotifyEvent read FOnHotTriggered write FOnHotTriggered; + property OnPressedTriggered: TNotifyEvent read FOnPressedTriggered write FOnPressedTriggered; + property OnFocusedTriggered: TNotifyEvent read FOnFocusedTriggered write FOnFocusedTriggered; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure StartTriggerAnimation(const AInstance: TFmxObject; const ATrigger: string); override; + published + property HotLink: TBitmapLinks index TButtonAnimation.Hot read GetLink write SetLink; + property FocusedLink: TBitmapLinks index TButtonAnimation.Focused read GetLink write SetLink; + property NormalLink: TBitmapLinks index TButtonAnimation.Normal read GetLink write SetLink; + property PressedLink: TBitmapLinks index TButtonAnimation.Pressed read GetLink write SetLink; + ///Used to add touch animation to the style object + property TouchAnimation: TTouchAnimationAdapter read FTouchAnimation write SetTouchAnimation; + end; + + TTintedButtonStyleObject = class(TButtonStyleObject, ITintedObject) + private + FTintSources: array [TButtonAnimation] of TTintedStages; + function GetTintStage(const Index: TButtonAnimation): TTintedStages; + procedure SetTintStage(const Index: TButtonAnimation; const Value: TTintedStages); + protected + procedure Loaded; override; + procedure DefineProperties(Filer: TFiler); override; + function GetCurrentLink: TBitmapLinks; override; + { ITintedObject } + function GetCanBeTinted: Boolean; override; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + published + property HotTint: TTintedStages index TButtonAnimation.Hot read GetTintStage write SetTintStage; + property NormalTint: TTintedStages index TButtonAnimation.Normal read GetTintStage write SetTintStage; + property FocusedTint: TTintedStages index TButtonAnimation.Focused read GetTintStage write SetTintStage; + property PressedTint: TTintedStages index TButtonAnimation.Pressed read GetTintStage write SetTintStage; + end; + + TSystemButtonObject = class(TButtonStyleObject) + private + FInactive: Boolean; + FInactiveAnimation: TAnimation; + FInactiveLink: TBitmapLinks; + procedure SetInactiveLink(const Value: TBitmapLinks); + procedure InactiveTriggered(Sender: TObject); + protected + function GetCurrentLink: TBitmapLinks; override; + procedure DefineProperties(Filer: TFiler); override; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure StartTriggerAnimation(const AInstance: TFmxObject; const ATrigger: string); override; + published + property InactiveLink: TBitmapLinks read FInactiveLink write SetInactiveLink; + end; + + TMaskedImage = class(TImage) + private + FContentObject: TCustomStyleObject; + FBuffer: TBitmap; + FNeedsUpdate: Boolean; + procedure PrepareBuffer; + function GetSourceLookup: string; + procedure SetSourceLookup(const Value: string); + procedure ReadMarginWrapMode(Reader: TReader); + procedure ReadWrapMode(Reader: TReader); + protected + function CreateContentObject: TCustomStyleObject; virtual; + procedure DefineProperties(Filer: TFiler); override; + procedure DoChanged; override; + procedure Paint; override; + procedure NeedsUpdate; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure StartTriggerAnimation(const AInstance: TFmxObject; const ATrigger: string); override; + published + property ContentObject: TCustomStyleObject read FContentObject; + property SourceLookup: string read GetSourceLookup write SetSourceLookup stored False; + end; + + TActiveMaskedImage = class(TMaskedImage) + private + function GetTrigger: TStyleTrigger; + procedure SetTrigger(const Value: TStyleTrigger); + procedure DoTriggered(Sender: TObject); + protected + function CreateContentObject: TCustomStyleObject; override; + procedure DefineProperties(Filer: TFiler); override; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + published + property ActiveTrigger: TStyleTrigger read GetTrigger write SetTrigger stored False; + end; + +{ Text Objects } + + TStyleShadow = class(TPersistent) + private + FColor: TAlphaColor; + FOnChanged: TNotifyEvent; + FOffset: TPosition; + procedure SetColor(const Value: TAlphaColor); + procedure SetOffset(const Value: TPosition); + protected + procedure DoChanged; virtual; + property OnChanged: TNotifyEvent read FOnChanged write FOnChanged; + public + constructor Create; + destructor Destroy; override; + procedure Assign(Source: TPersistent); override; + function Equals(Obj: TObject): Boolean; override; + published + property Color: TAlphaColor read FColor write SetColor default claNull; + property Offset: TPosition read FOffset write SetOffset; + end; + + TStyleTextObject = class(TText, IDrawableObject) + private + FSavedShadow: TStyleShadow; + FShadow: TStyleShadow; + FShadowVisible: Boolean; + FCharCase: TEditCharCase; + FCurrentColor: TAlphaColor; + FCurrentShadow: TStyleShadow; + procedure SetShadow(const Value: TStyleShadow); + procedure SetShadowVisible(const Value: Boolean); + procedure SetCharCase(const Value: TEditCharCase); + function GetSavedColor: TAlphaColor; + protected + procedure Paint; override; + function ConvertText(const Value: string): string; override; + procedure ShadowChanged; + procedure FontChanged; override; + procedure UpdateDefaultTextSettings; override; + function UpdateCurrentProperties: Boolean; virtual; + function SetCurrentProperties(const AColor: TAlphaColorRec; const AShadow: TStyleShadow): Boolean; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure DrawToCanvas(const Canvas: TCanvas; const ARect: TRectF; const AOpacity: Single = 1.0); + property SavedColor: TAlphaColor read GetSavedColor; + property SavedShadow: TStyleShadow read FSavedShadow; + property CurrentColor: TAlphaColor read FCurrentColor; + property CurrentShadow: TStyleShadow read FCurrentShadow; + published + property CharCase: TEditCharCase read FCharCase write SetCharCase default TEditCharCase.ecNormal; + property Color stored False; + property Shadow: TStyleShadow read FShadow write SetShadow; + property ShadowVisible: Boolean read FShadowVisible write SetShadowVisible; + property HitTest default False; + end; + + TStyleTextAnimation = class(TAnimation) + private + FColor: TAlphaColor; + FShadow: TStyleShadow; + procedure SetShadow(const Value: TStyleShadow); + protected + procedure ProcessAnimation; override; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + class function CreateAnimation(const Trigger: string; const Event: TNotifyEvent): TStyleTextAnimation; + procedure AssignIfEmpty(const StyleTextObject: TStyleTextObject); + property Color: TAlphaColor read FColor write FColor; + property Shadow: TStyleShadow read FShadow write SetShadow; + end; + + TActiveStyleTextObject = class(TStyleTextObject) + private + FTrigger: TStyleTrigger; + FActiveAnimation: TStyleTextAnimation; + FActive: Boolean; + FSavedActive: Boolean; + procedure SetTrigger(const Value: TStyleTrigger); + function GetActiveColor: TAlphaColor; + function GetActiveShadow: TStyleShadow; + procedure SetActiveColor(const Value: TAlphaColor); + procedure SetActiveShadow(const Value: TStyleShadow); + procedure SetActive(const Value: Boolean); + protected + procedure Triggered(Sender: TObject); + procedure SetupAnimations; virtual; + function UpdateCurrentProperties: Boolean; override; + procedure Loaded; override; + function SaveState: Boolean; override; + function RestoreState: Boolean; override; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure StartTriggerAnimation(const AInstance: TFmxObject; const ATrigger: string); override; + procedure SetNewScene(AScene: IScene); override; + property Active: Boolean read FActive write SetActive; + published + property ActiveTrigger: TStyleTrigger read FTrigger write SetTrigger; + property ActiveColor: TAlphaColor read GetActiveColor write SetActiveColor; + property ActiveShadow: TStyleShadow read GetActiveShadow write SetActiveShadow; + end; + + TTabStyleTextObject = class(TActiveStyleTextObject) + private + FHotAnimation: TStyleTextAnimation; + FHot: Boolean; + FSavedHot: Boolean; + procedure SetHotColor(const Value: TAlphaColor); + procedure SetHotShadow(const Value: TStyleShadow); + function GetHotColor: TAlphaColor; + function GetHotShadow: TStyleShadow; + procedure SetHot(const Value: Boolean); + protected + procedure HotTriggered(Sender: TObject); + procedure SetupAnimations; override; + procedure Loaded; override; + function UpdateCurrentProperties: Boolean; override; + function SaveState: Boolean; override; + function RestoreState: Boolean; override; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure StartTriggerAnimation(const AInstance: TFmxObject; const ATrigger: string); override; + property Hot: Boolean read FHot write SetHot; + published + property HotColor: TAlphaColor read GetHotColor write SetHotColor default claNull; + property HotShadow: TStyleShadow read GetHotShadow write SetHotShadow; + end; + + TButtonStyleTextObject = class(TStyleTextObject) + private + FTriggerSources: array [TButtonAnimation] of TStyleTextAnimation; + FButtonState: TButtonAnimation; + FSavedButtonState: TButtonAnimation; + procedure NormalTriggered(Sender: TObject); + procedure HotTriggered(Sender: TObject); + procedure PressedTriggered(Sender: TObject); + procedure FocusedTriggered(Sender: TObject); + function GetColor(Index: TButtonAnimation): TAlphaColor; + procedure SetColor(Index: TButtonAnimation; const Value: TAlphaColor); + function GetShadow(Index: TButtonAnimation): TStyleShadow; + procedure SetShadow(Index: TButtonAnimation; const Value: TStyleShadow); + procedure SetButtonState(const Value: TButtonAnimation); + procedure GetFontColors(var AColors, ADefColors: TFontColorForState); + protected + procedure Loaded; override; + procedure UpdateDefaultTextSettings; override; + function UpdateCurrentProperties: Boolean; override; + function GetTextSettingsClass: TTextSettingsClass; override; + function SaveState: Boolean; override; + function RestoreState: Boolean; override; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure StartTriggerAnimation(const AInstance: TFmxObject; const ATrigger: string); override; + property ButtonState: TButtonAnimation read FButtonState write SetButtonState; + published + property HotColor: TAlphaColor index TButtonAnimation.Hot read GetColor write SetColor default claNull; + property HotShadow: TStyleShadow index TButtonAnimation.Hot read GetShadow write SetShadow; + property FocusedColor: TAlphaColor index TButtonAnimation.Focused read GetColor write SetColor default claNull; + property FocusedShadow: TStyleShadow index TButtonAnimation.Focused read GetShadow write SetShadow; + property NormalColor: TAlphaColor index TButtonAnimation.Normal read GetColor write SetColor default claNull; + property NormalShadow: TStyleShadow index TButtonAnimation.Normal read GetShadow write SetShadow; + property PressedColor: TAlphaColor index TButtonAnimation.Pressed read GetColor write SetColor default claNull; + property PressedShadow: TStyleShadow index TButtonAnimation.Pressed read GetShadow write SetShadow; + end; + + TActiveOpacityObject = class(TControl) + private + FTrigger: TStyleTrigger; + FActiveAnimation: TAnimation; + FActiveOpacity: Single; + FSavedOpacity: Single; + function IsActiveOpacityStored: Boolean; + procedure SetTrigger(const Value: TStyleTrigger); + procedure Triggered(Sender: TObject); + protected + procedure SetupAnimation; virtual; + procedure Loaded; override; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure StartTriggerAnimation(const AInstance: TFmxObject; const ATrigger: string); override; + published + property ActiveTrigger: TStyleTrigger read FTrigger write SetTrigger; + property ActiveOpacity: Single read FActiveOpacity write FActiveOpacity stored IsActiveOpacityStored; + property Align; + property Anchors; + property ClipChildren default False; + property ClipParent default False; + property Cursor default crDefault; + property DragMode default TDragMode.dmManual; + property EnableDragHighlight default True; + property Enabled default True; + property Locked default False; + property Height; + property HitTest default False; + property Padding; + property Opacity; + property Margins; + property PopupMenu; + property Position; + property RotationAngle; + property RotationCenter; + property Scale; + property Size; + property TouchTargetExpansion; + property Visible default True; + property Width; + { Events } + property OnPainting; + property OnPaint; + property OnResize; + property OnResized; + { Drag and Drop events } + property OnDragEnter; + property OnDragLeave; + property OnDragOver; + property OnDragDrop; + property OnDragEnd; + { Mouse events } + property OnClick; + property OnDblClick; + property OnMouseDown; + property OnMouseMove; + property OnMouseUp; + property OnMouseWheel; + property OnMouseEnter; + property OnMouseLeave; + end; + +//== INTERFACE END: FMX.Styles.Objects +//================================================================================================== + +//================================================================================================== +//== INTERFACE START: FMX.StdCtrls (from FMX.StdCtrls.pas) //================================================================================================== {$SCOPEDENUMS ON} @@ -17255,11 +18423,3075 @@ type property OnResized; end; -//== UNIT END: FMX.StdCtrls +//== INTERFACE END: FMX.StdCtrls //================================================================================================== //================================================================================================== -//== UNIT START: FMX.ScrollBox (from FMX.ScrollBox.pas) +//== INTERFACE START: FMX.ListView.Types (from FMX.ListView.Types.pas) +//================================================================================================== + +{$SCOPEDENUMS ON} + + +{$IF DEFINED(IOS) OR DEFINED(ANDROID)} +{$DEFINE LISTVIEW_TOUCH} +{$ENDIF} + +{.$DEFINE PIXEL_ALIGNMENT} +{.$DEFINE DRAW_ITEM_MARGINS} + +type + TListItemAlign = (Leading, Center, Trailing); + TListItemPurpose = (None, Header, Footer); + TListItemPurposes = set of TListItemPurpose; + + TListItemPurposeHelper = record helper for TListItemPurpose + function ToString: string; + end; + + TListItem = class; + IListViewAdapter = interface; + IListViewController = interface; + + TListItemStyleResources = class; + + TListItemDrawState = (Selected, Deleting, EditMode); + TListItemDrawStates = set of TListItemDrawState; + + TListItemDrawable = class; + TListItemView = class; + TListItemCallbackOp = (CreateDrawables, InvalidateOwner, Click); + TListItemCallback = TProc; + + /// TListItem view is comprised of TListViewDrawables. These are the actual + /// view elements that are being painted in the item cells. + TListItemDrawable = class(TInterfacedPersistent) + public type + TParams = record + AbsoluteOpacity: Single; + ItemSelectedAlpha: Single; + DeletingUnwantedOpacity: Single; + EditModeTransitionAlpha: Single; + ParentAbsoluteRect: TRectF; + Images: TCustomImageList; + end; + strict private + FPlaceOffsetX: TPosition; + protected type + TStyleResource = (FontSize, FontFamily, FontStyle, TextColor, SelectedTextColor, + TextShadowColor, PressedTextColor); + TStyleResources = set of TStyleResource; + protected const + TextResources: set of TStyleResource = [TStyleResource.FontFamily, + TStyleResource.FontSize, TStyleResource.FontStyle, TStyleResource.TextColor, + TStyleResource.TextShadowColor, TStyleResource.SelectedTextColor, TStyleResource.PressedTextColor]; + private + FAlign: TListItemAlign; + FVertAlign: TListItemAlign; + FVisible: Boolean; + FWidth: Single; + FHeight: Single; + FOpacity: Single; + FUpdating: Integer; + NeedRepaint: Boolean; + FOnSelect: TNotifyEvent; + FName: string; + [Weak] FTagObject: TObject; + FTagFloat: Single; + FTagString: string; + FLocalRect: TRectF; + FStyleValuesNeedUpdate: TStyleResources; + FController: IListViewController; + FCallback: TListItemCallback; + + procedure SetOneDimension(const Index: Integer; const Value: Single); + procedure SetSize(const Value: TPointF); + function GetSize: TPointF; + procedure SetOpacity(const Value: Single); + procedure SetAlign(const Value: TListItemAlign); + procedure SetVertAlign(const Value: TListItemAlign); + procedure SetVisible(const Value: Boolean); + function GetData: TValue; virtual; + procedure SetData(const Value: TValue); virtual; + function GetPlaceOffset: TPosition; inline; + procedure SetInvalidateCallback(const Callback: TListItemCallback); virtual; + procedure PlaceOffsetChanged(Sender: TObject); + + protected + /// Called when the Size of this drawable changes + procedure DoResize; virtual; + /// Called when the Opacity of this drawable changes + procedure DoOpacityChange; virtual; + /// Called when TListItem comprising + /// this drawable is selected. + procedure DoSelect; virtual; + /// Called when PlaceOffset changes + procedure DoPlaceOffsetChanged; virtual; + /// Called when Align or VertAlign changes + procedure DoAlignChanged; virtual; + /// Finds an embedded TControl at given Point + function ObjectAtPoint(const Point: TPointF): TControl; virtual; + + /// Handle MouseDown event. Called by + /// TListItem.MouseDown + function MouseDown(const Button: TMouseButton; const Shift: TShiftState; const MousePos: TPointF): Boolean; virtual; + /// Handle MouseMove event. Called by host + /// TListItem.MouseMove + procedure MouseMove(const Shift: TShiftState; const MousePos: TPointF); virtual; + /// Handle MouseUp event. Called by + /// TListItem.MouseUp + procedure MouseUp(const Button: TMouseButton; const Shift: TShiftState; const MousePos: TPointF); virtual; + /// Called by UpdateValuesFromResources. + /// Updates default parameters defined by style in descendants such as font, font syle and colors. + procedure DoUpdateValuesFromResources(const Resources: TListItemStyleResources; const Purpose: TListItemPurpose); virtual; + public + constructor Create(const AOwner: TListItem); virtual; + destructor Destroy; override; + function ToString: string; override; + + /// Return amount of rendering passes. See TListViewBase.DrawListItems + function GetRenderPassCount: Integer; virtual; + /// Align and calculate this drawable's local rectangle for given item's DestRect and DrawStates + procedure CalculateLocalRect(const DestRect: TRectF; const SceneScale: Single; + const DrawStates: TListItemDrawStates; const Item: TListItem); virtual; + /// Return True if Point is inside local rect + function InLocalRect(const Point: TPointF): Boolean; + /// Request repaint. When between BeginUpdate/EndUpdate the request will be held back until the + /// update cycle is finished + procedure Invalidate; + /// Render this drawable + /// Canvas destination canvas + /// DrawItemIndex index within parent TListView of item being rendered + /// DrawStates which of the item states to render: Selected, Deleting, EditMode; + /// see TListItemDrawStates + /// Resources default style resources to use for rendering; + /// TListItemStyleResources + /// Params extra rendering parameters; see + /// TListItemDrawable.TParams + /// + procedure Render(const Canvas: TCanvas; const DrawItemIndex: Integer; const DrawStates: TListItemDrawStates; + const Resources: TListItemStyleResources; const Params: TParams; const SubPassNo: Integer = 0); virtual; abstract; + /// Begin update. During update calling InvalidateCallback + /// will be held back until EndUpdate + procedure BeginUpdate; + /// End update. If invalidation was required during the update cycle, + /// InvalidateCallback will be invoked + procedure EndUpdate; + /// Initializes or updates default parameters defined by style in descendants such as font, font syle + /// and colors. + procedure UpdateValuesFromResources(const Resources: TListItemStyleResources; const Purpose: TListItemPurpose); + /// Set flag that enables UpdateValuesFromResources + procedure UpdateValuesFromStyle; + /// Local width of list item inside its designated area + property Width: Single index 0 read FWidth write SetOneDimension; + /// Local height of list item inside its designated area + property Height: Single index 1 read FHeight write SetOneDimension; + /// Size of this drawable + property Size: TPointF read GetSize write SetSize; + /// Horizontal alignment of drawable inside its designated area + property Align: TListItemAlign read FAlign write SetAlign; + /// Vertical alignment of drawable inside its designated area + property VertAlign: TListItemAlign read FVertAlign write SetVertAlign; + /// Determines whether the current drawable is visible or not + property Visible: Boolean read FVisible write SetVisible; + /// The offset in logical units regarding aligned location for finer placement control + property PlaceOffset: TPosition read GetPlaceOffset; + /// Name of this drawable + property Name: string read FName write FName; + /// Drawing opacity + property Opacity: Single read FOpacity write SetOpacity; + /// LocalRect of this drawable + property LocalRect: TRectF read FLocalRect; + /// Invoked when owner TListItem is selected + property OnSelect: TNotifyEvent read FOnSelect write FOnSelect; + // Polymorphic property access + property Data: TValue read GetData write SetData; + /// User-defined object reference for this drawable + property TagObject: TObject read FTagObject write FTagObject; + /// User-defined floating-point number for this drawable + property TagFloat: Single read FTagFloat write FTagFloat; + /// User-defined string for this drawable + property TagString: string read FTagString write FTagString; + /// Callback invoked when item is being invalidated + /// TListItemCallback + /// + property InvalidateCallback: TListItemCallback write SetInvalidateCallback; + end; + + /// Declared for compatibility + TListItemObject = class(TListItemDrawable) + end; + + /// Represents a text drawable in ListView items + TListItemText = class(TListItemDrawable) + private const + DefaultFontFamily = 'Helvetica'; // do not localize + DefaultFontSize = 14; + ShadowOffset: TPointF = (X: 0; Y: 1); + private type + TFontSettings = record + Family: string; + Size: Single; + Style: TFontStyles; + end; + strict private + FFontX: TFont; + FFontSettings: TFontSettings; + private + FTextLayout: TTextLayout; + FText: string; + FTextAlign: TTextAlign; + FTextVertAlign: TTextAlign; + FWordWrap: Boolean; + LayoutChanged: Boolean; + FTextColor: TAlphaColor; + FSelectedTextColor: TAlphaColor; + FTrimming: TTextTrimming; + FTextShadowOffsetX: TPosition; + FTextShadowColor: TAlphaColor; + FIsDetailText: Boolean; + + procedure FontChanged(Sender: TObject); + procedure TextShadowOffsetChanged(Sender: TObject); + procedure SetText(const Value: string); + procedure SetTextAlign(const Value: TTextAlign); + procedure SetTextVertAlign(const Value: TTextAlign); + procedure SetWordWrap(const Value: Boolean); + procedure SetTextColor(const Value: TAlphaColor); + procedure SetTrimming(const Value: TTextTrimming); + procedure SetSelectedTextColor(const Value: TAlphaColor); + procedure SetTextShadowColor(const Value: TAlphaColor); + procedure SetIsDetailText(const Value: Boolean); + procedure SetData(const AValue: TValue); override; + function GetData: TValue; override; + function GetShadowOffset: TPosition; inline; + function GetFont: TFont; + function FontSettingsSnapshot: TFontSettings; + protected + procedure DoResize; override; + procedure DoUpdateValuesFromResources(const Resources: TListItemStyleResources; const Purpose: TListItemPurpose); override; + public + constructor Create(const AOwner: TListItem); override; + destructor Destroy; override; + + procedure CalculateLocalRect(const DestRect: TRectF; const SceneScale: Single; + const DrawStates: TListItemDrawStates; const Item: TListItem); override; + procedure Render(const Canvas: TCanvas; const DrawItemIndex: Integer; const DrawStates: TListItemDrawStates; + const Resources: TListItemStyleResources; const Params: TListItemDrawable.TParams; const SubPassNo: Integer = 0); override; + /// Font used to drawing text in this drawable + property Font: TFont read GetFont; + /// Text displayed in this drawable + property Text: string read FText write SetText; + /// Horizontal text alignment inside local item rectangle + property TextAlign: TTextAlign read FTextAlign write SetTextAlign; + /// Vertical text alignment inside local item rectangle + property TextVertAlign: TTextAlign read FTextVertAlign write SetTextVertAlign; + /// Wrap the text it does not fit in the available width + property WordWrap: Boolean read FWordWrap write SetWordWrap; + /// Text color in neutral state + property TextColor: TAlphaColor read FTextColor write SetTextColor; + /// Text color in selected state + property SelectedTextColor: TAlphaColor read FSelectedTextColor write SetSelectedTextColor; + /// Text shadow color. The text shadow will appear behind normal text only when its color is + /// set to non-zero value (default) + property TextShadowColor: TAlphaColor read FTextShadowColor write SetTextShadowColor; + /// Text shadow offset. The text shadow will appear behind normal text only when its color is + /// set to non-zero value (default) + property TextShadowOffset: TPosition read GetShadowOffset; + /// Text trimming + /// TTextTrimming + /// + property Trimming: TTextTrimming read FTrimming write SetTrimming; + /// Hints regarding the contents of this text object, which affecs visual style + property IsDetailText: Boolean read FIsDetailText write SetIsDetailText; + end; + + /// An empty drawable + TListItemDummy = class(TListItemDrawable) + public + procedure Render(const Canvas: TCanvas; const DrawItemIndex: Integer; const DrawStates: TListItemDrawStates; + const Resources: TListItemStyleResources; const Params: TListItemDrawable.TParams; + const SubPassNo: Integer = 0); override; + end; + + /// Image scaling modes for TListItemImage + /// TListItemImage.ScalingMode + /// StretchWithAspect stretch while preserving aspect ratio + /// Original keep original size and proportion + /// Stretch stertch to fill available area disregarding proportions + /// + TImageScalingMode = (StretchWithAspect, Original, Stretch); + + /// A TListItemDrawable representing an image + TListItemImage = class(TListItemDrawable) + public type + /// Image source: + /// None no image source + /// Bitmap bitmap or bitmap reference + /// ImageList bitmap is specified by an index in an ImageList + /// + TImageSource = (None, Bitmap, ImageList); + private + FStaticBitmap: TBitmap; + [Weak]FReferBitmap: TBitmap; + FSrcRect: TRectF; + FOwnsBitmap: Boolean; + FImageScalingMode: TImageScalingMode; + FImageIndex: TImageIndex; + FImageSource: TImageSource; + function GetBitmap: TBitmap; + procedure SetBitmap(const Value: TBitmap); + procedure SetOwnsBitmap(const Value: Boolean); + procedure SetSrcRect(const Value: TRectF); + procedure SetImageScalingMode(const Value: TImageScalingMode); + procedure SetImageIndex(const Value: TImageIndex); + function GetImageSource: TImageSource; inline; + procedure SetData(const Value: TValue); override; + public + constructor Create(const AOwner: TListItem); override; + destructor Destroy; override; + procedure CalculateLocalRect(const DestRect: TRectF; const SceneScale: Single; + const DrawStates: TListItemDrawStates; const Item: TListItem); override; + procedure Render(const Canvas: TCanvas; const DrawItemIndex: Integer; const DrawStates: TListItemDrawStates; + const Resources: TListItemStyleResources; const Params: TListItemDrawable.TParams; + const SubPassNo: Integer = 0); override; + /// Bitmap, used if ImageSource equals TImageSource.Bitmap + property Bitmap: TBitmap read GetBitmap write SetBitmap; + /// Determines whether this list owns and maintains the bitmap, or whether it is a reference only. + /// It is must faster and memory efficient to have multiple references to a single bitmap rather than multiple + /// copies of the same bitmap copied across the items + property OwnsBitmap: Boolean read FOwnsBitmap write SetOwnsBitmap; + /// Fit InputRect part of Bitmap into DestinationRect according to current ScalingMode + /// Bitmap TBitmap being fit + /// InputRect source rectangle + /// DestinationRect destination rectangle where the bitmap is to be placed + /// + procedure FitInto(const Bitmap: TBitmap; var InputRect, DestinationRect: TRectF); + /// Source rectangle in ImageSource + property SrcRect: TRectF read FSrcRect write SetSrcRect; + /// Scaling mode used for fitting the bitmap into destination rectangle + property ScalingMode: TImageScalingMode read FImageScalingMode write SetImageScalingMode + default TImageScalingMode.StretchWithAspect; + /// Indicates whether the images are obtained from TImageList or directly by using Bitmap property. + property ImageSource: TImageSource read GetImageSource; + /// Zero based index of an image. The default is -1. + /// See also FMX.ActnList.IGlyph + /// If non-existing index is specified, an image is not drawn and no exception is raised + property ImageIndex: TImageIndex read FImageIndex write SetImageIndex default -1; + end; + + TListItemEmbeddedControl = class; + /// IScene implementation for TListItemEmbeddedControl + TListItemControlScene = class(TFmxObject, IStyleBookOwner, IScene) + strict private + FCanvas: TCanvas; + [Weak] FContainer: TControl; + [Weak] FOwnerItem: TListItem; + FDrawing: Boolean; + FDisableUpdating: Integer; + private + FLayoutSize: TPoint; + function GetRealScene: IScene; + protected + // TFmxObject + procedure DoAddObject(const AObject: TFmxObject); override; + procedure DoRemoveObject(const AObject: TFmxObject); override; + // IStyleBookOwner + function GetStyleBook: TStyleBook; + procedure SetStyleBook(const Value: TStyleBook); + // IScene + function GetCanvas: TCanvas; + function GetSceneScale: Single; + function GetObject: TFmxObject; + procedure AddUpdateRect(const R: TRectF); + function GetUpdateRectsCount: Integer; + function GetUpdateRect(const Index: Integer): TRectF; + function LocalToScreen(const P: TPointF): TPointF; + function ScreenToLocal(const P: TPointF): TPointF; + procedure ChangeScrollingState(const AControl: TControl; const Active: Boolean); + procedure DisableUpdating; + procedure EnableUpdating; + /// Set item that contains this scene + procedure SetOwnerItem(const Item: TListItem); + /// Set container control + procedure SetContainer(const Container: TControl); + /// Get IScene of the parent control, i.e. TListView + property RealScene: IScene read GetRealScene; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + /// Repaint scene on canvas Canvas + procedure RepaintScene(const Canvas: TCanvas); + /// Container control + property Container: TControl read FContainer; + end; + + /// A dummy TControl that contains a TListItemEmbeddedControl + TListItemControlContainer = class(TControl) + private + [weak]FItemOwner: TListItemEmbeddedControl; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + end; + + /// Base class for TListItem embedded controls + TListItemEmbeddedControl = class(TListItemDrawable) + private + FScene: TListItemControlScene; + FContainer: TListItemControlContainer; + protected + /// Return TControl located at given Point + function ObjectAtPoint(const Point: TPointF): TControl; override; + public + constructor Create(const AOwner: TListItem); override; + destructor Destroy; override; + procedure Render(const Canvas: TCanvas; const DrawItemIndex: Integer; const DrawStates: TListItemDrawStates; + const Resources: TListItemStyleResources; const Params: TListItemDrawable.TParams; + const SubPassNo: Integer = 0); override; + /// TListItemControlContainer of this embedded control + property Container: TListItemControlContainer read FContainer; + end; + + /// Simple embedded control base class + TListItemSimpleControl = class(TListItemDrawable) + private const + DisabledOpacity = 0.6; + private + FEnabled: Boolean; + FPressed: Boolean; + FMouseOver: Boolean; + FTouchExpand: Single; + procedure SetEnabled(const Value: Boolean); + protected + /// Shall intercept clicks + function IsClickOpaque: Boolean; virtual; + function MouseDown(const Button: TMouseButton; const Shift: TShiftState; const MousePos: TPointF): Boolean; + override; + procedure MouseMove(const Shift: TShiftState; const MousePos: TPointF); override; + procedure MouseUp(const Button: TMouseButton; const Shift: TShiftState; const MousePos: TPointF); override; + /// Handle click + procedure DoClick; virtual; + /// Handle change of Enabled + procedure DoEnabledChange; virtual; + public + constructor Create(const AOwner: TListItem); override; + /// Test if point Pos belongs to local rectangle of this control + function PointInLocalRect(const Pos: TPointF): Boolean; + /// This method is called when click event is sent to the control to handle any actions associated + /// with this item + procedure Click; + /// Control state: Enabled + property Enabled: Boolean read FEnabled write SetEnabled; + /// Control state: Pressed + property Pressed: Boolean read FPressed; + /// Control state: MouseOver + property MouseOver: Boolean read FMouseOver; + /// Additional area (in logical units) around the control that is sensitive to touch + property TouchExpand: Single read FTouchExpand write FTouchExpand; + end; + + /// Accessory type for TListItemAccessory + /// More more + /// Checkmark checkmark + /// Detail detail disclosure + /// + TAccessoryType = (More, Checkmark, Detail); + + /// List item accessory, a glyph typically displayed at the right edge of the list item + TListItemAccessory = class(TListItemDrawable) + private + FAccessoryType: TAccessoryType; + protected + /// Set accessory type: More, Checkmark or Detail + procedure SetAccessoryType(Value: TAccessoryType); + public + constructor Create(const AOwner: TListItem); override; + + procedure CalculateLocalRect(const DestRect: TRectF; const SceneScale: Single; + const DrawStates: TListItemDrawStates; const Item: TListItem); override; + procedure Render(const Canvas: TCanvas; const DrawItemIndex: Integer; const DrawStates: TListItemDrawStates; + const Resources: TListItemStyleResources; const Params: TListItemDrawable.TParams; + const SubPassNo: Integer = 0); override; + + /// Accessory type, TAccessoryType + property AccessoryType: TAccessoryType read FAccessoryType write SetAccessoryType; + end; + + /// Glyph type for TListItemGlyphButton + /// Add plus button + /// Delete delete button + /// Checkbox selection checkbox + /// + TGlyphButtonType = (Add, Delete, Checkbox); + + /// Glyph button is an additional control usually used in Edit mode. It can be an Add/Plus sign, + /// a Delete button or a Checkbox + TListItemGlyphButton = class(TListItemSimpleControl) + private const + CheckedAnimationFrameRate = 60; + CheckedAnimationDuration = 0.15; // in seconds + private + FButtonType: TGlyphButtonType; + FClickOnSelect: Boolean; + FChecked: Boolean; + FTransitionEnabled: Boolean; + FTransitionAlpha: Single; + FTransitionTimer: TTimer; + FTransitionStartTicks: Double; + FTimerService: IFMXTimerService; + procedure SetButtonType(const Value: TGlyphButtonType); + procedure SetChecked(const Value: Boolean); + procedure InitCheckedTransition; + procedure ResetCheckedTransition; + procedure TransitionTimerNotify(Sender: TObject); + protected + procedure DoSelect; override; + procedure DoClick; override; + function MouseDown(const Button: TMouseButton; const Shift: TShiftState; const MousePos: TPointF): Boolean; + override; + procedure SetData(const AValue: TValue); override; + public + constructor Create(const AOwner: TListItem); override; + destructor Destroy; override; + procedure CalculateLocalRect(const DestRect: TRectF; const SceneScale: Single; + const DrawStates: TListItemDrawStates; const Item: TListItem); override; + procedure Render(const Canvas: TCanvas; const DrawItemIndex: Integer; const DrawStates: TListItemDrawStates; + const Resources: TListItemStyleResources; const Params: TListItemDrawable.TParams; + const SubPassNo: Integer = 0); override; + /// Button type, TGlyphButtonType + property ButtonType: TGlyphButtonType read FButtonType write SetButtonType; + /// If set to True, this button will receive click events from entire list by using of selection + property ClickOnSelect: Boolean read FClickOnSelect write FClickOnSelect; + /// Determines whether checkbox is checked, has no effect for other button types + property Checked: Boolean read FChecked write SetChecked; + end; + + /// Type of TListItemTextButton + /// Normal a regular button + /// Delete a delete button + /// + TTextButtonType = (Normal, Delete); + + /// A button with text that can be clicked inside of a TListItem + TListItemTextButton = class(TListItemSimpleControl) + private + FTextDrawable: TListItemText; + FButtonType: TTextButtonType; + FTintColor: TAlphaColor; + FPressedTextColor: TAlphaColor; + FTextColor: TAlphaColor; + + // getters routing to FTextDrawable + function GetFont: TFont; + function GetText: string; + procedure SetText(const Value: string); + procedure SetTextAlign(const Value: TTextAlign); + function GetTextAlign: TTextAlign; + procedure SetTextVertAlign(const Value: TTextAlign); + function GetTextVertAlign: TTextAlign; + procedure SetWordWrap(const Value: Boolean); + function GetWordWrap: Boolean; + procedure SetTextColor(const Value: TAlphaColor); + function GetTextColor: TAlphaColor; + procedure SetTrimming(const Value: TTextTrimming); + function GetTrimming: TTextTrimming; + procedure SetTextShadowColor(const Value: TAlphaColor); + function GetTextShadowColor: TAlphaColor; + + // button-specific text properties + procedure SetPressedTextColor(const Value: TAlphaColor); + function GetTextShadowOffset: TPosition; inline; + procedure SetButtonType(const Value: TTextButtonType); + procedure SetTintColor(const Value: TAlphaColor); + procedure SetInvalidateCallback(const Callback: TListItemCallback); override; + protected + function IsClickOpaque: Boolean; override; + procedure DoResize; override; + procedure DoOpacityChange; override; + procedure DoPlaceOffsetChanged; override; + procedure DoAlignChanged; override; + procedure SetData(const AValue: TValue); override; + public + constructor Create(const AOwner: TListItem); override; + destructor Destroy; override; + + procedure DoUpdateValuesFromResources(const Resources: TListItemStyleResources; + const Purpose: TListItemPurpose); override; + function GetRenderPassCount: Integer; override; + procedure CalculateLocalRect(const DestRect: TRectF; const SceneScale: Single; + const DrawStates: TListItemDrawStates; const Item: TListItem); override; + procedure Render(const Canvas: TCanvas; const DrawItemIndex: Integer; const DrawStates: TListItemDrawStates; + const Resources: TListItemStyleResources; const Params: TListItemDrawable.TParams; + const SubPassNo: Integer = 0); override; + + /// Button type, TTextButtonType + property ButtonType: TTextButtonType read FButtonType write SetButtonType; + /// Button tint color + property TintColor: TAlphaColor read FTintColor write SetTintColor; + /// Font used to draw button text + property Font: TFont read GetFont; + /// Button text + property Text: string read GetText write SetText; + /// Horizontal alignment of text within the button area + property TextAlign: TTextAlign read GetTextAlign write SetTextAlign; + /// Vertical alignment of text within the button area + property TextVertAlign: TTextAlign read GetTextVertAlign write SetTextVertAlign; + /// If true, the text that does not fit in button width will be wrapped + property WordWrap: Boolean read GetWordWrap write SetWordWrap; + /// Text color in neutral state + property TextColor: TAlphaColor read GetTextColor write SetTextColor; + /// Text color in pressed state + property PressedTextColor: TAlphaColor read FPressedTextColor write SetPressedTextColor; + /// Text shadow color + property TextShadowColor: TAlphaColor read GetTextShadowColor write SetTextShadowColor; + /// Text shadow offset + property TextShadowOffset: TPosition read GetTextShadowOffset; + /// Text trimming + /// TTextTrimming + /// + property Trimming: TTextTrimming read GetTrimming write SetTrimming; + end; + + /// TListItemView is a collection of drawables that comprise the view of a TListItem + TListItemView = class + private type + TViewList = TObjectList; + private + FCallback: TListItemCallback; + FViewList: TListItemView.TViewList; + FInitialized: Boolean; + + function GetCount: Integer; + function GetObject(const Index: Integer): TListItemDrawable; + function GetViewList: TViewList; inline; + protected + procedure Include(const AItem: TListItemDrawable); + procedure Exclude(const AItem: TListItemDrawable); + function GetInitialized: Boolean; + procedure SetInitialized(const Value: Boolean); + public + constructor Create(const AOwner: TListItem); + destructor Destroy; override; + /// Add a drawable to view + function Add(const AItem: TListItemDrawable): Integer; + /// Insert a drawable at a position indicated by Index + procedure Insert(const Index: Integer; const Value: TListItemDrawable); + /// Clear the view + procedure Clear; virtual; + /// Delete drawable at index Index + procedure Delete(Index: Integer); + /// Find TListItemDrawable + /// specified by name AName + function FindDrawable(const AName: string): TListItemDrawable; + /// Find TListItemDrawable specified by name AName + function FindObject(const AName: string): TListItemDrawable; deprecated 'Use FindDrawable'; + + + /// Find TListItemDrawable specified by name AName and throw an error if not found + function DrawableByName(const AName: string): TListItemDrawable; + /// Find TListItemDrawable specified by name AName and throw an error if not found + function ObjectByName(const AName: string): TListItemDrawable; deprecated 'Use DrawableByName'; + /// Number of drawables in this view + property Count: Integer read GetCount; + /// TListItemDrawable by index + property Drawables[const Index: Integer]: TListItemDrawable read GetObject; default; + /// Get TViewList that contains the drawables + property ViewList: TViewList read GetViewList; + /// Used internally to notify owner about changes + property Callback: TListItemCallback write FCallback; + /// Used internally + property Initialized: Boolean read GetInitialized write SetInitialized; + end; + + /// Compatibility class for TListItemView + TListItemObjects = class(TListItemView) + end; + + /// TListItem is an element that comprises TListView. Each individual item contains a View, + /// which in turn is comprised of instances of TListItemDrawable + TListItem = class + public type + TListItemViewType = class of TListItemView; + TListItemNotifyEvent = procedure(const Item: TListItem) of object; + strict private + FHeaderRef: Integer; + FAdapter: IListViewAdapter; + FController: IListViewController; + private + FIndex: Integer; + FHeight: Integer; + FPurpose: TListItemPurpose; + FUpdating: Integer; + FNeedRepaint: Boolean; + FView: TListItemView; + [Weak] FTagObject: TObject; + FTag: NativeInt; + FTagFloat: Single; + FTagString: string; + function GetCount: Integer; + procedure SetHeight(const Value: Integer); + function GetController: IListViewController; + protected + /// Invoked when item height changes and heights of all items need to be recounted + procedure InvalidateHeights; virtual; + /// Setter for Purpose property + procedure SetPurpose(const AValue: TListItemPurpose); virtual; + /// Require repaint, notify the controller that the item is invalid + procedure Repaint; virtual; + /// Return class of TListItemView + function ListItemObjectsClass: TListItemViewType; virtual; + /// Getter for Index property + function GetIndex: Integer; virtual; + /// Setter for Index property + procedure SetIndex(const Value: Integer); virtual; + public + constructor Create(const AAdapter: IListViewAdapter; const AController: IListViewController = nil); + destructor Destroy; override; + function ToString: string; override; + /// Invalidate item, request repainting + procedure Invalidate; + /// Begin update. Invalidation request will not cause immediate action during update. + procedure BeginUpdate; + /// End update + procedure EndUpdate; + /// Called when the view drawables need to be created + procedure CreateObjects; virtual; + /// Called when the item is about to be painted + procedure WillBePainted; virtual; + /// Locate a control at a point, used with embedded controls + function ObjectAtPoint(const Point: TPointF): TControl; + /// Handle MouseDown event + function MouseDown(const Button: TMouseButton; const Shift: TShiftState; const MousePos: TPointF): Boolean; + /// Handle MouseMove event + procedure MouseMove(const Shift: TShiftState; const MousePos: TPointF); + /// Handle MouseUp event + procedure MouseUp(const Button: TMouseButton; const Shift: TShiftState; const MousePos: TPointF); + /// Handle selection + procedure MouseSelect; + /// True if there are items inside that react as clicked when the item is selected + function HasClickOnSelectItems: Boolean; + /// Adapter that observes this item + property Adapter: IListViewAdapter read FAdapter; + /// Number of drawables in the View, shorthand for View.Count + property Count: Integer read GetCount; + /// The view, drawables that comprise the visual of this item + property View: TListItemView read FView; + /// Height of this item + property Height: Integer read FHeight write SetHeight; + /// Reference to IListViewController + property Controller: IListViewController read GetController; + /// Which purpose item serves for: normal item (none), header or footer. + /// TListItemPurpose + property Purpose: TListItemPurpose read FPurpose write SetPurpose; + /// Reference to header of the group this item belongs to, for grouped views + property HeaderRef: Integer read FHeaderRef write FHeaderRef; + /// Index of this item in TListView.Adapter + property Index: Integer read GetIndex write SetIndex; + /// User-defined integer tag for this item + property Tag: NativeInt read FTag write FTag; + /// User-defined object reference for this item + property TagObject: TObject read FTagObject write FTagObject; + /// User-defined floating-point number for this drawable + property TagFloat: Single read FTagFloat write FTagFloat; + /// User-defined string tag for this item + property TagString: string read FTagString write FTagString; + end; + + /// A container used for passing various style-defined properties used in TListView + TListItemStyleResources = class + private + FOwnsObjects: Boolean; + public type + /// References to TStyleObjects used for rendering of TListItemAccessory + TAccessoryStyleObject = record + /// Accessory TStyleObject in neutral state + [Weak] Normal: TStyleObject; + /// Accessory TStyleObject in selected state + [Weak] Selected: TStyleObject; + end; + + /// Style objects used for button rendering + TButtonStyleObject = record + /// Button TStyleObject in neutral state + [Weak] Normal: TStyleObject; + /// Button TStyleObject in pressed state + [Weak] Pressed: TStyleObject; + end; + public + /// Style references used for Accessory rendering + AccessoryImages: array [TAccessoryType] of TAccessoryStyleObject; + /// Font used in header items + HeaderTextFont: TFont; + /// Color of header text + HeaderTextColor: TAlphaColor; + /// Color of header text shadow + HeaderTextShadowColor: TAlphaColor; + /// Default font for text drawables + DefaultTextFont: TFont; + /// Default color for text drawables + DefaultTextColor: TAlphaColor; + /// Default font for detail text + DetailTextFont: TFont; + /// Default color for detail text + DetailTextColor: TAlphaColor; + /// Default color for text in selected state + DefaultTextSelectedColor: TAlphaColor; + /// Style objects for Add Item TListItemGlyphButton + ButtonAddItemStyleImage: TButtonStyleObject; + /// Style objects for Delete Item TListItemGlyphButton + ButtonDeleteItemStyleImage: TButtonStyleObject; + /// Background image for regular TListItemTextButton + ButtonNormalStyleImage: TButtonStyleObject; + /// Background image for delete-themed TListItemTextButton + ButtonDeleteStyleImage: TButtonStyleObject; + /// Style objects for Checkbox TListItemGlyphButton + ButtonCheckboxStyleImage: TButtonStyleObject; + /// Font for TListItemTextButton + ButtonTextFont: TFont; + /// Text color for neutral state TListItemTextButton + ButtonTextColor: TAlphaColor; + /// Text color for pressed state TListItemTextButton + ButtonTextPressedColor: TAlphaColor; + /// Font for delete-themed TListItemTextButton + DeleteButtonTextFont: TFont; + /// Text color for neutral state delete-themed TListItemTextButton + DeleteButtonTextColor: TAlphaColor; + /// Text color for pressed state delete-themed TListItemTextButton + DeleteButtonTextPressedColor: TAlphaColor; + /// Glow color that appears at the top or the bottom of screen when scrolling + /// is being stretched out + ScrollingStretchGlowColor: TAlphaColor; + /// Indicator color for drawing Pull Refresh indicator + PullRefreshIndicatorColor: TAlphaColor; + /// Stroke color for drawing Pull Refresh indicator + PullRefreshStrokeColor: TAlphaColor; + constructor Create; overload; + constructor Create(const Source: TListItemStyleResources); overload; + destructor Destroy; override; + end; + + /// Interface providing access to style resources. Implemented by TListViewBase + IListItemStyleResources = interface + ['{0328C6F1-432C-4F8B-994B-7AB2543CD172}'] + /// Getter for StyleResources property + function GetStyleResources: TListItemStyleResources; + /// TListView style resources + property StyleResources: TListItemStyleResources read GetStyleResources; + /// True if style resources should be reloaded + function StyleResourcesNeedUpdate: Boolean; + end; + + /// Interface providing loose coupling between TListView and TListItem. Implemented by + /// TListViewBase + IListViewController = interface + ['{3855EF72-3B32-41BE-9068-7B109B2DD8E5}'] + function GetEditModeTransitionAlpha: Single; + function GetDeleteModeTransitionAlpha: Single; + function GetImages: TCustomImageList; + /// True if delete mode is enabled + function IsDeleteModeAllowed: Boolean; + /// Left offset of item rectangle in edit mode + function GetItemEditOffset(const Item: TListItem): Single; + /// Right cutoff of item rectangle in delete mode + function GetItemDeleteCutoff(const Item: TListItem): Single; + /// Item selection alpha + function GetItemSelectionAlpha(const Item: TListItem): Single; + /// Client area margins + function GetClientMargins: TRectF; + /// IScene of the TListView control + function GetScene: IScene; + /// Request TListView to initialize item indices; see "FMX.ListView.Appearances.TListViewItem" + procedure RequestReindexing(const Item: TListItem); + /// Notify TListView that item size has changed; see "TListViewItem.InvalidateHeights" + procedure ItemResized(const Item: TListItem); + /// Notify TListView that item requires repainting + procedure ItemInvalidated(const Item: TListItem); + /// Notify TListView that a control inside of an item has been clicked + procedure ControlClicked(const Item: TListItem; const Control: TListItemDrawable); + /// Notify TListView that a control inside of an item has been clicked + procedure CheckStateChanged(const Item: TListItem; const Control: TListItemDrawable); + /// Item alpha during edit mode transition + property EditModeTransitionAlpha: Single read GetEditModeTransitionAlpha; + /// Item alpha during delete transition + property DeleteModeTransitionAlpha: Single read GetDeleteModeTransitionAlpha; + ///TImageList used when ImageSource = ImageList; can be nil + property Images: TCustomImageList read GetImages; + end; + + /// Presentation of TPresentedListView. The control passes messages to the + /// presentation layer by the means of this interface. + IListViewPresentation = interface + ['{85C07617-2BB7-44DC-BBCB-2E3FE422B006}'] + /// Called when ancestor's visible property is changed + procedure AncestorVisibleChanged(const Visible: Boolean); + /// Called when Parent is changed + procedure ParentChanged; + /// Called when position in parent list is changed + procedure OrderChanged; + /// Called when control size has changed + procedure SizeChanged; + /// Called when edit mode has changed + procedure EditModeChanged; + /// Called when visibility status has changed + procedure StatusChanged; + /// Called when item presentation requires update + procedure ItemsUpdated; + /// Item has been invalidated, presentation should reinitialize its view + procedure ItemInvalidated(const Item: TListItem); + /// Item has been selected by the control, presentation should update its selection + procedure SetItemSelected(const ItemIndex: Integer; const Value: Boolean); + /// Selected item index has been changed by the control, presentation should update selection + procedure SetItemIndex(const ItemIndex: Integer); + /// Force stop pull refresh + procedure StopPullRefresh; + end; + + /// Base interface from presented control to presentation + IListViewCustomPresentationParent = interface + ['{EBBE5FAA-F2B3-4606-AE32-8027DB97EC92}'] + /// Get root object, normally Root.GetObject + function GetRootObject: TObject; + /// Get content frame of the presented control + function GetContentFrame: TRect; + /// Get opacity of the presented control + function GetControlOpacity: Single; + end; + + /// Enumeration of internally used boolean flags + TListViewModeFlag = (Edit, Enabled, Visible, Deletion, PullRefresh, Buttons, Search, SearchOnTop, PullRefreshWait, + SwipeDelete); + /// Set of boolean flags used internally + TListViewModeFlags = set of TListViewModeFlag; + + /// View options specific to native iOS presentation + TListViewNativeOption = (Grouped, Indexed, Styled); + /// View options specific to native iOS presentation. + /// IListViewPresentationParent + TListViewNativeOptions = set of TListViewNativeOption; + + /// Interface from presented control to presentation + IListViewPresentationParent = interface(IListViewCustomPresentationParent) + ['{F5657E45-0955-4A9F-9FE6-6C5E019846E4}'] + /// Obtains IListViewAdapter + function GetAdapter: IListViewAdapter; + /// Obtains client rectangle for item with index ItemIndex + function GetItemClientRect(const ItemIndex: Integer): TRectF; + /// Obtains item count + function GetItemCount: Integer; + /// Obtains height of item ItemIndex + function GetItemHeight(const ItemIndex: Integer): Integer; + /// Guess item height before exact values can be calculated + function GetEstimatedItemHeight: Single; + /// Guess header height before exact values can be calculated + function GetEstimatedHeaderHeight: Single; + /// Guess footer height before exact values can be calculated + function GetEstimatedFooterHeight: Single; + /// Get main text of item ItemIndex + function GetItemText(const ItemIndex: Integer): string; + /// Get index title for item ItemIndex + function GetItemIndexTitle(const ItemIndex: Integer): string; + /// Query if item ItemIndex is selectable + function CanSelectItem(const ItemIndex: Integer): Boolean; + /// Notify control when item ItemIndex was selected + procedure DidSelectItem(const ItemIndex: Integer); + /// Query if item ItemIndex can be unselected + function CanUnselectItem(const ItemIndex: Integer): Boolean; + /// Notify control that item ItemIndex was unselected + procedure DidUnselectItem(const ItemIndex: Integer); + /// Notify control that an item button was clicked + procedure ItemButtonClicked(const ItemIndex: Integer); + /// Obtain presentation-specific boolean flags + function GetFlags: TListViewModeFlags; + /// Obtain native presentation-specific boolean flags + function GetOptions: TListViewNativeOptions; + /// Commit deletion of item ItemIndex + function DeleteItem(const ItemIndex: Integer): Boolean; + /// Invoke pull refresh + procedure InvokePullRefresh; + /// Set search filter string + procedure SetSearchFilter(const Filter: string); + /// Pass scroll view position to the control + procedure SetScrollViewPos(const Value: Single); + /// Require rebuild of the list + procedure RebuildList; + /// Set boolean flag that indicates that native view is being created. It is used + /// as a guard condition to prevent TListView logic from interfering with the presentation + /// while a view is being initialized + procedure SetCreatingNativeView(const Value: Boolean); + /// True if TListView is transparent + function GetIsTransparent: Boolean; + /// Obtain control opacity + function GetOpacity: Single; + /// Obtain background color defined by TListView style + function GetBackgroundStyleColor: TAlphaColor; + /// Request complete recreation of presentation + procedure RecreateNativePresentation; + end; + + /// Used to check if there is a design presentation attached to ListView + IListViewDesignPresentationParent = interface + ['{C62F3FE5-FE96-47A7-99CB-2EEBC85664FA}'] + ///True if design presentation is attached + function HasDesignPresentationAttached: Boolean; + end; + + /// A drawable shim extension to apply bounds changes from + /// the designer. + IListViewDrawableShim = interface + ['{9FB67E2A-37B9-473B-A95A-13EDD19ED91B}'] + ///Calculate appearance PlaceOffset, Width, Height for given rect from designer + function CalcAppearanceBounds(const AValue: TRect; const CurrentBounds: TRectF): TRectF; + end; + + /// Predicate used for item filtering. + /// + TFilterPredicate = TPredicate; + + TListItemsList = TList; + + /// IListViewAdapter provides interface between the data and their representation. + /// The essential part of this interface is implemented in FMX.ListView.Adapters.Base.TAbstractListViewAdapter + /// + IListViewAdapter = interface + ['{6E850F76-BABD-4756-BF05-A30C66A692AD}'] + /// Return number of items that this Adapter represents. See Item[Index]. + function GetCount: Integer; + /// Get TListItem by index Index + function GetItem(const Index: Integer): TListItem; + /// Get index of given TListItem + function IndexOf(const AItem: TListItem): Integer; + /// Return TEnumerator<TListItem> + function GetEnumerator: TEnumerator; + /// Height of items that do not have it explicitly defined + function GetDefaultViewHeight: Integer; + /// Subscribe to OnChanged event + procedure SetOnChanged(const Value: TNotifyEvent); + /// Subscribe to OnItemsMayChange event + procedure SetOnItemsMayChange(const Value: TNotifyEvent); + /// Subscribe to OnItemsCouldHaveChanged event + procedure SetOnItemsCouldHaveChanged(const Value: TNotifyEvent); + /// Subscribe to OnItemsInvalidate event + procedure SetOnItemsInvalidate(const Value: TNotifyEvent); + /// Subscribe to OnItemsResize event + procedure SetOnItemsResize(const Value: TNotifyEvent); + /// Subscribe to OnResetView event + procedure SetOnResetView(const Value: TNotifyEvent); + /// Notifies adapter about item's changes. + procedure Changed; + /// Sort data + procedure Sort(AComparer: IComparer); + /// Called by TListView every time it needs to paint. In dynamic adapters this is where + /// new TListItems should be created for data. + procedure CreateNewViews; + /// Recreate views for items that have specified purposes. May be called when item + /// views may need update, for example when host TListView is being resized + procedure ResetViews(const Purposes: TListItemPurposes); + // Called by ResetViews to invoke OnResetView event for each ListItem + procedure ResetView(const Item: TListItem); + /// Get item by Index. Items would normally be already created by CreateNewViews by the time + /// this property is accessed. Index should be in range of [0, Count) + property Item[const Index: Integer]: TListItem read GetItem; default; + /// Count of items + property Count: Integer read GetCount; + /// Invoked when items have changed + property OnChanged: TNotifyEvent write SetOnChanged; + /// Invoked before an edit operation, items or their contents may change + property OnItemsMayChange: TNotifyEvent write SetOnItemsMayChange; + /// Invoked after an edit operation, items could have been changed + property OnItemsCouldHaveChanged: TNotifyEvent write SetOnItemsCouldHaveChanged; + /// Invoked when items are invalidated and a repaint is necessary + property OnItemsInvalidate: TNotifyEvent write SetOnItemsInvalidate; + /// Item sizes were changed, notify the view that the sizes of items need recalculation + property OnItemsResize: TNotifyEvent write SetOnItemsResize; + /// View has been reset + property OnResetView: TNotifyEvent write SetOnResetView; + end; + + IListViewEditor = interface; + TBeforeItemAddedNotify = procedure(Sender: IListViewEditor) of object; + TAfterItemAddedNotify = procedure(Sender: IListViewEditor; const Item: TListItem) of object; + TBeforeItemDeletedNotify = procedure(Sender: IListViewEditor; const Index: Integer) of object; + TAfterItemDeletedNotify = procedure(Sender: IListViewEditor) of object; + + /// Extension of IListViewAdapter for editable content. Implemented by TAppearanceListViewItems + IListViewEditor = interface + ['{19A0606B-8C8E-49B2-A6B3-A708B7B8AD46}'] + /// Create a new Item and append at end + function Add: TListItem; + /// Delete Item at Index + procedure Delete(const Index: Integer); + /// Create a new Item and insert at Index + function Insert(const Index: Integer): TListItem; + /// Delete all items + procedure Clear; + /// Set OnBeforeItemAdded handler + procedure SetBeforeItemAdded(const AHandler: TBeforeItemAddedNotify); + /// Set OnAfterItemAdded handler + procedure SetAfterItemAdded(const AHandler: TAfterItemAddedNotify); + /// Set OnBeforeItemDeleted handler + procedure SetBeforeItemDeleted(const AHandler: TBeforeItemDeletedNotify); + /// Set OnAfterItemDeleted handler + procedure SetAfterItemDeleted(const AHandler: TAfterItemDeletedNotify); + /// Notification before item is added + property OnBeforeItemAdded: TBeforeItemAddedNotify write SetBeforeItemAdded; + /// Notification after item is added + property OnAfterItemAdded: TAfterItemAddedNotify write SetAfterItemAdded; + /// Notification before item is deleted + property OnBeforeItemDeleted: TBeforeItemDeletedNotify write SetBeforeItemDeleted; + /// Notification after item is deleted + property OnAfterItemDeleted: TAfterItemDeletedNotify write SetAfterItemDeleted; + end; + + /// Extension of IListViewAdapter for items with checkboxes. + /// Implemented by TAppearanceListViewItems + IListViewCheckProvider = interface + ['{032EB974-1C25-4B5E-BB07-01FA82554748}'] + /// Index of first checked item + function FirstChecked(const Checked: Boolean = True): Integer; + /// A quick query to see if one or all of the items are in checked state. + /// If AChecked = True, True if at least one item is checked + /// If AChecked = False, True if every item is checked + /// + function AnyChecked(const AChecked: Boolean = True): Boolean; + /// Change check state of all items + procedure CheckAll(const NewState: Boolean = True); + /// Get checked state for item at Index + function GetChecked(const Index: Integer): Boolean; + /// Set checked state for item at Index + procedure SetChecked(const Index: Integer; const Value: Boolean); + /// Get/set checked state of item at Index + property Checked[const Index: Integer]: Boolean read GetChecked write SetChecked; default; + end; + + /// Extension of IListViewAdapter for items with text and indexes. + /// Implemented by TAppearanceListViewItems + IListViewTextProvider = interface + ['{C6D52C15-423D-4B2F-AC87-7D7D47A9C7CC}'] + /// Get primary text of item at Index + function GetText(const Index: Integer): string; + /// Get index title at Index + function GetIndexTitle(const Index: Integer): string; + /// Primary text of item at Index + property Text[const Index: Integer]: string read GetText; + /// Index title of item at Index + property IndexTitle[const Index: Integer]: string read GetIndexTitle; + end; + + /// Extension of IListViewAdapter for items with embedded text buttons. + /// Implemented by TAppearanceListViewItems + IListViewTextButtonProvider = interface + ['{42CC3926-0A23-465B-9ECE-229C60B3BA8E}'] + /// Get drawable of text button for item at Index + function GetTextButtonDrawable(const Index: Integer): TListItemTextButton; + /// Drawable of text button for item at Index + property TextButtonDrawable[const Index: Integer]: TListItemTextButton read GetTextButtonDrawable; + end; + + /// Extension of IListViewAdapter for items with glyph buttons. + /// Implemented by TAppearanceListViewItems + IListViewGlyphButtonProvider = interface + ['{64FF4B01-E378-4F40-A9A5-E4C1A7C942D6}'] + /// Get drawable of button for item at Index + function GetGlyphButtonDrawable(const Index: Integer): TListItemGlyphButton; + /// Drawable of button for item at Index + property GlyphButtonDrawable[const Index: Integer]: TListItemGlyphButton read GetGlyphButtonDrawable; + end; + + /// Extension of IListViewAdapter for items with data. + /// Implemented by TAppearanceListViewItems + IListViewExtrasProvider = interface + ['{0BCFB611-3763-4C49-974F-1104F6116D6E}'] + /// Get indexed data DataIndex for item at Index + function GetItemData(const Index: Integer; const DataIndex: string): TValue; + /// Set indexed data DataIndex for item at Index + procedure SetItemData(const Index: Integer; const DataIndex: string; const AValue: TValue); + /// True if item at Index has indexed data DataIndex + function GetHasData(const Index: Integer; const DataIndex: string): Boolean; + /// Get tag of item at Index + function GetItemTag(const Index: Integer): NativeInt; + /// Set tag of item at Index + procedure SetItemTag(const Index: Integer; const AValue: NativeInt); + + /// Indexed data DataIndex of item at Index + property Data[const Index: Integer; const DataIndex: string]: TValue read GetItemData write SetItemData; + /// Tag of item at Index + property Tag[const Index: Integer]: NativeInt read GetItemTag write SetItemTag; + /// True if item at Index has Indexed data DataIndex + property HasData[const Index: Integer; const DataIndex: string]: Boolean read GetHasData; + end; + + /// Extension of IListViewAdapter items of which can be filtered by a search box. + /// Implemented by TAppearanceListViewItems + IListViewFilterable = interface + ['{02F85899-8787-4378-9622-105820EB4577}'] + /// Get filter predicate + function GetFilterPredicate: TFilterPredicate; + /// Set filter predicate + procedure SetFilterPredicate(const Value: TFilterPredicate); + /// Return a complete list of all items regardless of filter state + function GetUnfilteredItems: TListItemsList; + /// True if filter is applied + function GetFiltered: Boolean; + + /// Notifies the adapter that all items have been deleted + procedure ItemsCleared; + /// Notifies the adapter that item at Index have been deleted + procedure ItemDeleted(const Index: Integer); + /// Notifies the adapter that item at Index have been added + procedure ItemAdded(const Index: Integer; const Item: TListItem); + + /// Complete list of all items regardless of filter state + property UnfilteredItems: TListItemsList read GetUnfilteredItems; + /// True if filter is applied + property Filtered: Boolean read GetFiltered; + /// Filter predicate + property Filter: TFilterPredicate read GetFilterPredicate write SetFilterPredicate; + end; + +//== INTERFACE END: FMX.ListView.Types +//================================================================================================== + +//================================================================================================== +//== INTERFACE START: FMX.Edit (from FMX.Edit.pas) +//================================================================================================== + +{$SCOPEDENUMS ON} + + +const + MM_EDIT_SELSTART_CHANGED = MM_USER + 1; + MM_EDIT_SELLENGTH_CHANGED = MM_USER + 2; + MM_EDIT_READONLY_CHANGED = MM_USER + 3; + MM_EDIT_MAXLENGTH_CHANGED = MM_USER + 4; + MM_EDIT_ISPASSWORD_CHANGED = MM_USER + 5; + MM_EDIT_IMEMODE_CHANGED = MM_USER + 6; + MM_EDIT_KEYBOARDTYPE_CHANGED = MM_USER + 7; + MM_EDIT_RETURNKEYTYPE_CHANGED = MM_USER + 8; + MM_EDIT_KILLFOCUSBYRETURN_CHANGED = MM_USER + 9; + MM_EDIT_CHECKSPELLING_CHANGED = MM_USER + 10; + MM_EDIT_PROMPTTEXT_CHANGED = MM_USER + 11; + MM_EDIT_CARETPOSITION_CHANGED = MM_USER + 15; + MM_EDIT_CARETCHANGED = MM_USER + 16; + MM_EDIT_TYPING_CHANGED = MM_USER + 17; + MM_EDIT_TEXT_SETTINGS_CHANGED = MM_USER + 18; + MM_EDIT_TEXT_CHANGED = MM_USER + 19; + MM_EDIT_EDITBUTTONS_CHANGED = MM_USER + 21; + MM_EDIT_TEXT_CHANGING = MM_USER + 22; + MM_EDIT_CHARCASE_CHANGED = MM_USER + 23; + MM_EDIT_FILTERCHAR_CHANGED = MM_USER + 24; + MM_EDIT_GET_CARET_POSITION_BY_POINT = MM_USER + 25; + MM_EDIT_CAN_SET_FOCUS = MM_USER + 26; + MM_EDIT_AUTOSELECT_CHANGED = MM_USER + 27; + MM_EDIT_HIDESELECTIONONEXIT_CHANGED = MM_USER + 28; + MM_EDIT_USER = MM_USER + 29; + + PM_EDIT_REALIGN_BUTTONS_CONTAINER = PM_USER + 1; + PM_EDIT_GET_TEXT_CONTENT_RECT = PM_USER + 2; + PM_EDIT_UNDO_MANAGER_INSERT_TEXT = PM_USER + 3; + PM_EDIT_UNDO_MANAGER_DELETE_TEXT = PM_USER + 4; + PM_EDIT_UNDO_MANAGER_UNDO = PM_USER + 5; + PM_EDIT_USER = PM_USER + 6; + +type + +{ TCustomEdit } + + TCustomEditModel = class(TDataModel, ITextLinesSource) + public const + DefaultSelectionColor = $802A8ADF; + DefaultHorzAlign = TTextAlign.Leading; + DefaultFontColor = TAlphaColorRec.Black; + DefaultInputSupport = True; + DefaultCharCase = TEditCharCase.ecNormal; + DefaultAutoSelect = False; + DefaultHideSelectionOnExit = True; + public type + /// Data for requesting caret position by HitTest point. + TGetCaretPositionInfo = record + HitPoint: TPointF; + CaretPosition: Integer; + end; + private + FChanged: Boolean; + FText: string; + FSelStart: Integer; + FSelLength: Integer; + FReadOnly: Boolean; + FMaxLength: Integer; + FPassword: Boolean; + FKeyboardType : TVirtualkeyboardType; + FReturnKeyType: TReturnKeyType; + FImeMode: TImeMode; + FHideSelectionOnExit: Boolean; + FKillFocusByReturn: Boolean; + FCheckSpelling: Boolean; + FTextPrompt: string; + FCaretPosition: Integer; + FCaret: TCustomCaret; + FTyping: Boolean; + FFilterChar: string; + FInputSupport: Boolean; + FTextSettingsInfo: TTextSettingsInfo; + FSelectionFill: TBrush; + FOnChange: TNotifyEvent; + FOnChangeTracking: TNotifyEvent; + FOnTyping: TNotifyEvent; + FOnValidating: TValidateTextEvent; + FOnValidate: TValidateTextEvent; + FValidating: Boolean; + FCharCase: TEditCharCase; + FAutoSelect: Boolean; + procedure SetAutoSelect(const Value: Boolean); + procedure SetSelStart(const Value: Integer); + procedure SetSelLength(const Value: Integer); + procedure SetMaxLength(const Value: Integer); + procedure SetReadOnly(const Value: Boolean); + procedure SetPassword(const Value: Boolean); + procedure SetImeMode(const Value: TImeMode); + procedure SetKeyboardType(const Value: TVirtualKeyboardType); + procedure SetReturnKeyType(const Value: TReturnKeyType); + procedure SetKillFocusByReturn(const Value: Boolean); + procedure SetCheckSpelling(const Value: Boolean); + procedure SetTextPrompt(const Value: string); + procedure SetCaretPosition(const Value: Integer); + procedure SetCaret(const Value: TCustomCaret); + procedure SetTyping(const Value: Boolean); + /// + /// Invokes sequence: DoFiltering -> DoTruncating -> DoValidating + /// + procedure SetText(const Value: string); + procedure SetSelectionFill(const Value: TBrush); + procedure SetFilterChar(const Value: string); + procedure SetCharCase(const Value: TEditCharCase); + function CanSetFocus: Boolean; + procedure SetHideSelectionOnExit(const Value: Boolean); + { ITextLinesSource } + function GetLine(const ALineIndex: Integer): string; + function GetLineBreak: string; + function GetCount: Integer; + function TextPosToPos(const APos: Integer): TCaretPosition; + function PosToTextPos(const APosition: TCaretPosition): Integer; + function GetText: string; + protected + ///Initial text filtering before calling DoTruncating + function DoFiltering(const Value: string): string; virtual; + ///Maximum available text length filtering before calling DoValidating + function DoTruncating(const Value: string): string; virtual; + ///Validate inputing text. Calling before OnChangeTracking + function DoValidating(const Value: string): string; virtual; + function DoValidate(const Value: string): string; virtual; + procedure DoChangeTracking; virtual; + procedure DoChange; virtual; + procedure ResultTextSettingsChanged; virtual; + function GetTextSettingsClass: TTextSettingsInfo.TCustomTextSettingsClass; virtual; + /// + /// This property indicates that the control is in validate value mode. See DoValidate, Change + /// + property Validating: Boolean read FValidating; + public + constructor Create; override; + destructor Destroy; override; + function HasSelection: Boolean; + function SelectedText: string; + procedure Change; + ///Set text in model without text validation and sending notification to presenter + procedure SetTextWithoutValidation(const Value: string); + + { Editing } + ///Insert text in memo after defined position + procedure InsertAfter(const APosition: Integer; const AFragment: string; const Options: TInsertOptions); + ///Delete fragment of the text from the memo after defined position + procedure DeleteFrom(const APosition: Integer; const ALength: Integer; const Options: TDeleteOptions); + /// Replace fragment of text from the memo in the specifeid range. + procedure Replace(const APosition: Integer; const ALength: Integer; const AFragment: string); + + function GetPositionShift(const APosition: Integer; const ADelta: Integer): Integer; + function GetNextWordBegin(const APosition: Integer): Integer; + function GetPrevWordBegin(const APosition: Integer): Integer; + { Caret position } + procedure MoveCaretHorizontal(const ADelta: Integer); + procedure MoveCaretLeft; + procedure MoveCaretRight; + /// Returns caret position by specified hittest point. + /// Works only for TEdit.ControlType=Styled. + function GetCaretPositionByPoint(const AHitPoint: TPointF): Integer; + public + ///Select all text when control getting focus + property AutoSelect: Boolean read FAutoSelect write SetAutoSelect; + property CaretPosition: Integer read FCaretPosition write SetCaretPosition; + property Caret: TCustomCaret read FCaret write SetCaret; + property CheckSpelling: Boolean read FCheckSpelling write SetCheckSpelling; + property FilterChar: string read FFilterChar write SetFilterChar; + ///Do not draw selected text region when component not in focus + property HideSelectionOnExit: Boolean read FHideSelectionOnExit write SetHideSelectionOnExit default True; + ///Text control is in read-only mode + property ReadOnly: Boolean read FReadOnly write SetReadOnly; + property ImeMode: TImeMode read FImeMode write SetImeMode; + property InputSupport: Boolean read FInputSupport write FInputSupport; + property KeyboardType : TVirtualkeyboardType read FKeyboardType write SetKeyboardType; + property KillFocusByReturn: Boolean read FKillFocusByReturn write SetKillFocusByReturn; + property MaxLength: Integer read FMaxLength write SetMaxLength; + property Password: Boolean read FPassword write SetPassword; + property ReturnKeyType: TReturnKeyType read FReturnKeyType write SetReturnKeyType; + property SelectionFill: TBrush read FSelectionFill write SetSelectionFill; + property SelStart: Integer read FSelStart write SetSelStart; + property SelLength: Integer read FSelLength write SetSelLength; + property Text: string read FText write SetText; + property TextSettingsInfo: TTextSettingsInfo read FTextSettingsInfo; + property TextPrompt: string read FTextPrompt write SetTextPrompt; + property Typing: Boolean read FTyping write SetTyping; + ///Defines character case for text in component + property CharCase: TEditCharCase read FCharCase write SetCharCase; + property OnChange: TNotifyEvent read FOnChange write FOnChange; + property OnChangeTracking: TNotifyEvent read FOnChangeTracking write FOnChangeTracking; + property OnTyping: TNotifyEvent read FOnTyping write FOnTyping; + property OnValidating: TValidateTextEvent read FOnValidating write FOnValidating; + property OnValidate: TValidateTextEvent read FOnValidate write FOnValidate; + end; + + TCustomEdit = class; + + TContentEdit = class(TContent) + private + function GetEdit: TCustomEdit; + protected + procedure DoRemoveObject(const AObject: TFmxObject); override; + procedure DoAddObject(const AObject: TFmxObject); override; + procedure DoInsertObject(Index: Integer; const AObject: TFmxObject); override; + public + constructor Create(AOwner: TComponent); override; + property Edit: TCustomEdit read GetEdit; + end; + + TCustomEdit = class(TPresentedControl, ITextActions, IVirtualKeyboardControl, IItemsContainer, ITextSettings, + IReadOnly, ICaret) + private + FButtonsContent: TContentEdit; + FSavedReadOnly: Boolean; + FSavedMaxLength: Integer; + FSavedTextAlign: TTextAlign; + function GetAutoSelect: Boolean; + procedure SetAutoSelect(const Value: Boolean); + function GetOriginCaretPosition: Integer; + procedure SetSelText(const Value: string); + function GetSelText: string; + procedure SetSelLength(const Value: Integer); + function GetSelLength: Integer; + procedure SetSelStart(const Value: Integer); + function GetSelStart: Integer; + procedure SetCaretPosition(const Value: Integer); + function GetCaretPosition: Integer; + procedure SetCaret(const Value: TCustomCaret); + function GetCaret: TCustomCaret; + procedure SetPromptText(const Prompt: string); + function GetPromptText: string; + procedure SetOnChange(const Value: TNotifyEvent); + function GetOnChange: TNotifyEvent; + procedure SetOnChangeTracking(const Value: TNotifyEvent); + function GetOnChangeTracking: TNotifyEvent; + procedure SetMaxLength(const Value: Integer); + function GetMaxLength: Integer; + procedure SetPassword(const Value: Boolean); + function GetPassword: Boolean; + procedure SetOnTyping(const Value: TNotifyEvent); + function GetOnTyping: TNotifyEvent; + procedure SetKillFocusByReturn(const Value: Boolean); + function GetKillFocusByReturn: Boolean; + procedure SetCheckSpelling(const Value: Boolean); + function GetCheckSpelling: Boolean; + function GetSelectionFill: TBrush; + function GetCharCase: TEditCharCase; + procedure SetCharCase(const Value: TEditCharCase); + { ITextSettings } + function GetDefaultTextSettings: TTextSettings; + function GetTextSettings: TTextSettings; + function GetResultingTextSettings: TTextSettings; + function GetStyledSettings: TStyledSettings; + procedure SetTextAlign(const Value: TTextAlign); + function GetTextAlign: TTextAlign; + procedure SetVertTextAlign(const Value: TTextAlign); + function GetVertTextAlign: TTextAlign; + procedure SetFont(const Value: TFont); + function GetFont: TFont; + procedure SetFontColor(const Value: TAlphaColor); + function GetFontColor: TAlphaColor; + function GetTyping: Boolean; + procedure SetTyping(const Value: Boolean); + function GetFilterChar: string; + procedure SetFilterChar(const Value: string); + function GetInputSupport: Boolean; + function GetModel: TCustomEditModel; overload; + function GetTextContentRect: TRectF; + function GetOnValidate: TValidateTextEvent; + function GetOnValidating: TValidateTextEvent; + procedure SetOnValidate(const Value: TValidateTextEvent); + procedure SetOnValidating(const Value: TValidateTextEvent); + procedure ReadReadOnly(Reader: TReader); + function GetHideSelectionOnExit: Boolean; + procedure SetHideSelectionOnExit(const Value: Boolean); + { IReadOnly } + procedure SetReadOnly(const Value: Boolean); + function GetReadOnly: Boolean; + { ICaret } + function ICaret.GetObject = GetCaret; + procedure ShowCaret; + procedure HideCaret; + protected + FClipboardSvc: IFMXExtendedClipboardService; + function GetData: TValue; override; + procedure SetData(const Value: TValue); override; + procedure Loaded; override; + function GetText: string; virtual; + procedure SetText(const Value: string); virtual; + procedure DoAddObject(const AObject: TFmxObject); override; + procedure DoInsertObject(Index: Integer; const AObject: TFmxObject); override; + procedure DoRemoveObject(const AObject: TFmxObject); override; + function GetImeMode: TImeMode; virtual; + procedure SetImeMode(const Value: TImeMode); virtual; + procedure SetInputSupport(const Value: Boolean); virtual; + procedure DefineProperties(Filer: TFiler); override; + function GetDefaultSize: TSizeF; override; + procedure Resize; override; + procedure RealignButtonsContainer; virtual; + function GetCanFocus: Boolean; override; + { Live Binding } + function CanObserve(const ID: Integer): Boolean; override; + procedure ObserverAdded(const ID: Integer; const Observer: IObserver); override; + procedure ObserverToggle(const AObserver: IObserver; const Value: Boolean); + { ITextSettings } + procedure SetTextSettings(const Value: TTextSettings); virtual; + procedure SetStyledSettings(const Value: TStyledSettings); virtual; + function StyledSettingsStored: Boolean; virtual; + { IVirtualKeyboardControl } + procedure SetKeyboardType(Value: TVirtualKeyboardType); + function GetKeyboardType: TVirtualKeyboardType; + procedure SetReturnKeyType(Value: TReturnKeyType); + function GetReturnKeyType: TReturnKeyType; + function IVirtualKeyboardControl.IsPassword = GetPassword; + property InputSupport: Boolean read GetInputSupport write SetInputSupport; + { IItemsContainer } + function GetItemsCount: Integer; + function GetItem(const AIndex: Integer): TFmxObject; + procedure ButtonsChanged; virtual; + protected + function DefineModelClass: TDataModelClass; override; + function DefinePresentationName: string; override; + public + property ControlType; + property Model: TCustomEditModel read GetModel; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure SelectAll(const AKeepCaretPosition: Boolean); overload; + { ITextActions } + procedure DeleteSelection; + procedure CopyToClipboard; + procedure CutToClipboard; + procedure PasteFromClipboard; + procedure SelectAll; overload; + procedure SelectWord; + procedure ResetSelection; + procedure GoToTextEnd; + procedure GoToTextBegin; + procedure Replace(const AStartPos: Integer; const ALength: Integer; const AStr: string); + function HasSelection: Boolean; + procedure Undo; + public + ///Determines whether all the text in the edit is automatically selected when the control gets + ///focus + property AutoSelect: Boolean read GetAutoSelect write SetAutoSelect; + property ButtonsContent: TContentEdit read FButtonsContent; + property Caret: TCustomCaret read GetCaret write SetCaret; + property CaretPosition: Integer read GetCaretPosition write SetCaretPosition; + property TextContentRect: TRectF read GetTextContentRect; + property CheckSpelling: Boolean read GetCheckSpelling write SetCheckSpelling default False; + property DefaultTextSettings: TTextSettings read GetDefaultTextSettings; + property Font: TFont read GetFont write SetFont; + property FontColor: TAlphaColor read GetFontColor write SetFontColor default TAlphaColorRec.Black; + property FilterChar: string read GetFilterChar write SetFilterChar; + property ImeMode: TImeMode read GetImeMode write SetImeMode default TImeMode.imDontCare; + property KeyboardType: TVirtualKeyboardType read GetKeyboardType write SetKeyboardType default TVirtualKeyboardType.Default; + property KillFocusByReturn: Boolean read GetKillFocusByReturn write SetKillFocusByReturn default False; + property MaxLength: Integer read GetMaxLength write SetMaxLength default 0; + ///Determines whether to cancel the visual indication of the selected text when the focus moves to another + ///control. + property HideSelectionOnExit: Boolean read GetHideSelectionOnExit write SetHideSelectionOnExit; + property Password: Boolean read GetPassword write SetPassword default False; + property ReadOnly: Boolean read GetReadOnly write SetReadOnly default False; + property ReturnKeyType: TReturnKeyType read GetReturnKeyType write SetReturnKeyType default TReturnKeyType.Default; + property ResultingTextSettings: TTextSettings read GetResultingTextSettings; + property SelectionFill: TBrush read GetSelectionFill; + property SelStart: Integer read GetSelStart write SetSelStart; + property SelLength: Integer read GetSelLength write SetSelLength; + property SelText: string read GetSelText write SetSelText; + property StyledSettings: TStyledSettings read GetStyledSettings write SetStyledSettings stored StyledSettingsStored nodefault; + property Text: string read GetText write SetText; + property TextAlign: TTextAlign read GetTextAlign write SetTextAlign default TTextAlign.Leading; + property TextSettings: TTextSettings read GetTextSettings write SetTextSettings; + property TextPrompt: string read GetPromptText write SetPromptText; + property Typing: Boolean read GetTyping write SetTyping default False; + property VertTextAlign: TTextAlign read GetVertTextAlign write SetVertTextAlign default TTextAlign.Center; + ///Defines whether to implement the 'UPPER' or 'lower' case conversion to the memo's text + property CharCase: TEditCharCase read GetCharCase write SetCharCase; + property OnChange: TNotifyEvent read GetOnChange write SetOnChange; + property OnChangeTracking: TNotifyEvent read GetOnChangeTracking write SetOnChangeTracking; + property OnTyping: TNotifyEvent read GetOnTyping write SetOnTyping; + property OnValidating: TValidateTextEvent read GetOnValidating write SetOnValidating; + property OnValidate: TValidateTextEvent read GetOnValidate write SetOnValidate; + published + property Align; + property Anchors; + property StyleLookup; + property TabOrder; + property TabStop; + end; + +{ TEditButton } + + IEditControl = interface + ['{4C7EE0A7-06EC-4515-B843-B608FB984468}'] + function BoundsRect: TRectF; + function GetControl: TControl; + end; + + TEditButton = class(TCustomButton, IEditControl) + protected + function GetDefaultStyleLookupName: string; override; + procedure SetName(const NewName: TComponentName); override; + function GetDefaultSize: TSizeF; override; + { IEditControl } + function IEditControl.BoundsRect = GetBoundsRect; + function GetControl: TControl; + public + constructor Create(AOwner: TComponent); override; + function GetEdit: TCustomEdit; + published + property Action; + property Anchors; + property AutoTranslate default True; + property CanFocus default True; + property CanParentFocus; + property ClipChildren default False; + property ClipParent default False; + property Cursor default crDefault; + property DisableFocusEffect; + property DragMode default TDragMode.dmManual; + property EnableDragHighlight default True; + property Enabled default True; + property TextSettings; + property Font; + property Height; + property HelpContext; + property HelpKeyword; + property HelpType; + property Hint; + property HitTest default True; + property IsPressed default False; + property Locked default False; + property Padding; + property ModalResult default mrNone; + property Opacity; + property Margins; + property PopupMenu; + property Position; + property RepeatClick default False; + property RotationAngle; + property RotationCenter; + property Scale; + property Size; + property StaysPressed default False; + property StyleLookup; + property TabOrder; + property Text; + property TextAlign default TTextAlign.Center; + property TouchTargetExpansion; + property Visible default True; + property Width; + property WordWrap default False; + property ParentShowHint; + property ShowHint; + {events} + property OnApplyStyleLookup; + property OnFreeStyle; + property OnDragEnter; + property OnDragLeave; + property OnDragOver; + property OnDragDrop; + property OnDragEnd; + property OnKeyDown; + property OnKeyUp; + property OnCanFocus; + property OnClick; + property OnDblClick; + property OnEnter; + property OnExit; + property OnMouseDown; + property OnMouseMove; + property OnMouseUp; + property OnMouseWheel; + property OnMouseEnter; + property OnMouseLeave; + property OnPainting; + property OnPaint; + property OnResize; + property OnResized; + end; + +{ TClearEditButton } + + TClearEditButton = class(TEditButton) + protected + procedure Click; override; + function GetDefaultStyleLookupName: string; override; + end; + +{ TPasswordEditButton } + + TPasswordEditButton = class(TEditButton) + protected + function GetDefaultStyleLookupName: string; override; + public + procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X: Single; Y: Single); override; + procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X: Single; Y: Single); override; + end; + +{ TSearchEditButton } + + TSearchEditButton = class(TEditButton) + protected + function GetDefaultStyleLookupName: string; override; + end; + +{ TEllipsesEditButton } + + TEllipsesEditButton = class(TEditButton) + protected + function GetDefaultStyleLookupName: string; override; + end; + +{ TDropDownEditButton } + + TDropDownEditButton = class(TEditButton) + protected + function GetDefaultStyleLookupName: string; override; + end; + +{ TSpinEditButton } + + TSpinEditButton = class(TStyledControl, IEditControl) + private + FRepeatClick: Boolean; + { Style } + FUpButton: TCustomButton; + FDownButton: TCustomButton; + { Events } + FOnUpClick: TNotifyEvent; + FOnDownClick: TNotifyEvent; + procedure SetRepeatClick(const Value: Boolean); + protected + { Style } + procedure ApplyStyle; override; + procedure FreeStyle; override; + function GetDefaultStyleLookupName: string; override; + function GetDefaultSize: TSizeF; override; + { Events } + procedure DoUpButtonClick(Sender: TObject); + procedure DoDownButtonClick(Sender: TObject); + { IEditControl } + function IEditControl.BoundsRect = GetBoundsRect; + function GetControl: TControl; + public + constructor Create(AOwner: TComponent); override; + published + property Anchors; + property AutoTranslate default True; + property CanFocus default True; + property CanParentFocus; + property ClipChildren default False; + property ClipParent default False; + property Cursor default crDefault; + property DisableFocusEffect; + property DragMode default TDragMode.dmManual; + property EnableDragHighlight default True; + property Enabled default True; + property Height; + property HelpContext; + property HelpKeyword; + property HelpType; + property Hint; + property HitTest default True; + property Locked default False; + property Padding; + property Opacity; + property Margins; + property PopupMenu; + property Position; + property RepeatClick: Boolean read FRepeatClick write SetRepeatClick default False; + property RotationAngle; + property RotationCenter; + property Scale; + property Size; + property StyleLookup; + property TabOrder; + property TouchTargetExpansion; + property Visible default True; + property Width; + property ParentShowHint; + property ShowHint; + {events} + property OnApplyStyleLookup; + property OnFreeStyle; + property OnDragEnter; + property OnDragLeave; + property OnDragOver; + property OnDragDrop; + property OnDragEnd; + property OnKeyDown; + property OnKeyUp; + property OnDownClick: TNotifyEvent read FOnDownClick write FOnDownClick; + property OnUpClick: TNotifyEvent read FOnUpClick write FOnUpClick; + property OnCanFocus; + property OnClick; + property OnDblClick; + property OnEnter; + property OnExit; + property OnMouseDown; + property OnMouseMove; + property OnMouseUp; + property OnMouseWheel; + property OnMouseEnter; + property OnMouseLeave; + property OnPainting; + property OnPaint; + property OnResize; + property OnResized; + end; + +{ TEdit } + + TEdit = class(TCustomEdit) + public + property Action; + published + property ControlType; + property OnPresentationNameChoosing; + { inherited } + property AutoSelect default TCustomEditModel.DefaultAutoSelect; + property Cursor default crIBeam; + property CanFocus default True; + property CanParentFocus; + property DisableFocusEffect; + property KeyboardType; + property ReturnKeyType; + property Password; + property ReadOnly; + ///Maxmimum length of text that can be input in the edit field. + ///On Android due to platform limitations text is truncated only after pressing ENTER key or after losing + ///focus. + property MaxLength; + property HideSelectionOnExit default TCustomEditModel.DefaultHideSelectionOnExit; + ///Defines characters which can be input in the edit field. All characters not in FilterChar will be + ///ignored. Empty FilterChar value means no filtering. + ///On Android due to platform limitations text is filtered only after pressing ENTER key or after control + ///losing focus. + property FilterChar; + property Text; + property TextSettings; + property ImeMode; + property Position; + property Width; + property Height; + property ClipChildren default False; + property ClipParent default False; + property DragMode default TDragMode.dmManual; + property EnableDragHighlight default True; + property Enabled default True; + property Locked default False; + property Hint; + property HitTest default True; + property HelpContext; + property HelpKeyword; + property HelpType; + property Padding; + property Opacity; + property Margins; + property PopupMenu; + property RotationAngle; + property RotationCenter; + property Scale; + property Size; + property TextPrompt; + property StyleLookup; + property StyledSettings; + property TouchTargetExpansion; + property Visible default True; + property Caret; + property KillFocusByReturn; + property CheckSpelling; + property ParentShowHint; + property ShowHint; + property CharCase default TCustomEditModel.DefaultCharCase; + { events } + property OnChange; + property OnChangeTracking; + property OnTyping; + property OnApplyStyleLookup; + property OnFreeStyle; + property OnValidating; + property OnValidate; + property OnDragEnter; + property OnDragLeave; + property OnDragOver; + property OnDragDrop; + property OnDragEnd; + property OnKeyDown; + property OnKeyUp; + property OnCanFocus; + property OnClick; + property OnDblClick; + property OnEnter; + property OnExit; + property OnMouseDown; + property OnMouseMove; + property OnMouseUp; + property OnMouseWheel; + property OnMouseEnter; + property OnMouseLeave; + property OnPainting; + property OnPaint; + property OnResize; + property OnResized; + end; + +{ TClearingEdit } + + TClearingEdit = class(TEdit) + protected + function DefinePresentationName: string; override; + function GetDefaultStyleLookupName: string; override; + public + constructor Create(AOwner: TComponent); override; + end deprecated 'Use TEdit with TClearEditButton'; + +//== INTERFACE END: FMX.Edit +//================================================================================================== + +//================================================================================================== +//== INTERFACE START: FMX.Layouts (from FMX.Layouts.pas) +//================================================================================================== + +{$SCOPEDENUMS ON} + + +type + +{ TLayout } + + TLayout = class(TControl) + protected + procedure Paint; override; + public + constructor Create(AOwner: TComponent); override; + published + property Align; + property Anchors; + property ClipChildren; + property ClipParent; + property Cursor; + property DragMode; + property EnableDragHighlight; + property Enabled; + property Locked; + property Height; + property Hint; + property HitTest default False; + property Padding; + property Opacity; + property Margins; + property PopupMenu; + property Position; + property RotationAngle; + property RotationCenter; + property Scale; + property Size; + property TouchTargetExpansion; + property Visible; + property Width; + property ParentShowHint; + property ShowHint; + property TabOrder; + property TabStop; + { Events } + property OnPainting; + property OnPaint; + property OnResize; + property OnResized; + { Drag and Drop events } + property OnDragEnter; + property OnDragLeave; + property OnDragOver; + property OnDragDrop; + property OnDragEnd; + { Mouse events } + property OnClick; + property OnDblClick; + property OnMouseDown; + property OnMouseMove; + property OnMouseUp; + property OnMouseWheel; + property OnMouseEnter; + property OnMouseLeave; + end; + +{ TScaledLayout } + + TScaledLayout = class(TControl) + private + FOriginalWidth: Single; + FOriginalHeight: Single; + procedure SetOriginalWidth(const Value: Single); + procedure SetOriginalHeight(const Value: Single); + protected + procedure DoRealign; override; + function GetChildrenMatrix(var Matrix: TMatrix; var Simple: Boolean): Boolean; override; + procedure SetHeight(const Value: Single); override; + procedure SetWidth(const Value: Single); override; + procedure Paint; override; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + published + property Align; + property Anchors; + property ClipChildren; + property ClipParent; + property Cursor; + property DragMode; + property EnableDragHighlight; + property Enabled; + property Locked; + property Height; + property Hint; + property HitTest default False; + property Padding; + property Opacity; + property OriginalWidth: Single read FOriginalWidth write SetOriginalWidth; + property OriginalHeight: Single read FOriginalHeight write SetOriginalHeight; + property Margins; + property PopupMenu; + property Position; + property RotationAngle; + property RotationCenter; + property Scale; + property Size; + property TouchTargetExpansion; + property Visible; + property Width; + property ParentShowHint; + property ShowHint; + { Events } + property OnPainting; + property OnPaint; + property OnResize; + property OnResized; + { Drag and Drop events } + property OnDragEnter; + property OnDragLeave; + property OnDragOver; + property OnDragDrop; + property OnDragEnd; + { Mouse events } + property OnClick; + property OnDblClick; + property OnMouseDown; + property OnMouseMove; + property OnMouseUp; + property OnMouseWheel; + property OnMouseEnter; + property OnMouseLeave; + end; + + TCustomScrollBox = class; + +{ TScrollContent } + + TScrollContent = class(TContent) + private + [Weak] FScrollBox: TCustomScrollBox; + FIsContentChanged: Boolean; + protected + function GetClipRect: TRectF; override; + function GetChildrenRect: TRectF; override; + function ObjectAtPoint(P: TPointF): IControl; override; + function DoGetUpdateRect: TRectF; override; + procedure DoAddObject(const AObject: TFmxObject); override; + procedure DoInsertObject(Index: Integer; const AObject: TFmxObject); override; + procedure DoRemoveObject(const AObject: TFmxObject); override; + procedure DoRealign; override; + procedure ContentChanged; override; + /// This flag is set in the method ContentChanged. Used to optimize ScrollBox + property IsContentChanged: Boolean read FIsContentChanged write FIsContentChanged; + public + constructor Create(AOwner: TComponent); override; + property ScrollBox: TCustomScrollBox read FScrollBox; + function PointInObjectLocal(X, Y: Single): Boolean; override; + end; + + TScrollCalculations = class (TAniCalculations) + private + [Weak] FScrollBox: TCustomScrollBox; + protected + procedure DoChanged; override; + procedure DoStart; override; + procedure DoStop; override; + public + constructor Create(AOwner: TPersistent); override; + property ScrollBox: TCustomScrollBox read FScrollBox; + end; + +{ TCustomScrollBox } + + TPositionChangeEvent = procedure (Sender: TObject; const OldViewportPosition, NewViewportPosition: TPointF; + const ContentSizeChanged: Boolean) of object; + + TOnCalcContentBoundsEvent = procedure (Sender: TObject; var ContentBounds: TRectF) of object; + + TCustomScrollBox = class(TStyledControl) + private + const + SmallChangeFraction = 5; + DesignBorderColor: TAlphaColor = $80A070A0; + type + TScrollInfo = record + [Weak] Scroll: TScrollBar; + Align: TAlignLayout; + Margins: TRectF; + end; + var + FSystemInfoSrv: IFMXSystemInformationService; + FDisableMouseWheel: Boolean; + + FAniCalculations: TScrollCalculations; + FLastViewportPosition: TPointF; + FInInternalAlign: Boolean; + + FBackground: TControl; + FContent: TScrollContent; + FContentLayout: TControl; + FContentBounds: TRectF; + FCachedContentSize: TSizeF; + FCachedAutoShowing: Boolean; + FOriginalContentLayoutSize: TSizeF; + + FShowScrollBars: Boolean; + FAutoHide: Boolean; + FHScrollInfo: array of TScrollInfo; + FVScrollInfo: array of TScrollInfo; + FContentMargins: TRectF; + FVDisablePaint: Boolean; + FHDisablePaint: Boolean; + FGDisablePaint: Boolean; + + FSizeGripContent: TControl; + FSizeGripParent: TControl; + FSizeGrip: TControl; + FShowSizeGrip: Boolean; + FOnViewportPositionChange: TPositionChangeEvent; + FOnHScrollChange: TNotifyEvent; + FOnVScrollChange: TNotifyEvent; + FOnCalcContentBounds: TOnCalcContentBoundsEvent; + FMouseEvents: Boolean; + FContentCalculated: Boolean; + function HScrollIndex: Integer; + function VScrollIndex: Integer; + function GetHScrollAlign: TAlignLayout; + function GetVScrollAlign: TAlignLayout; + function GetHScrollMargins: TRectF; + function GetVScrollMargins: TRectF; + function GetSceneScale: Single; + procedure SetShowScrollBars(const Value: Boolean); + procedure SetShowSizeGrip(const Value: Boolean); + function GetVScrollBar: TScrollBar; + function GetHScrollBar: TScrollBar; + procedure UpdateSizeGrip; + procedure UpdateVScrollBar(const Value: Single; const ViewportSize: Single); + procedure UpdateHScrollBar(const Value: Single; const ViewportSize: Single); + procedure InternalAlign; + procedure HScrollChangeProc(Sender: TObject); + procedure VScrollChangeProc(Sender: TObject); + procedure MousePosToAni(var X, Y: Single); + procedure SetAutoHide(const Value: Boolean); + procedure SaveDisablePaint; + procedure RestoreDisablePaint; + procedure SetDisablePaint; + function GetViewportPosition: TPointF; + procedure SetViewportPosition(const Value: TPointF); + procedure StartScrolling; + procedure StopScrolling; + procedure UpdateOriginalContentLayoutSize(const Force: Boolean); + procedure ReadPartSize(Reader: TReader; var Size: Single); + procedure ReadContentLayoutHeight(Reader: TReader); + procedure ReadContentLayoutWidth(Reader: TReader); + procedure WriteContentLayoutHeight(Writer: TWriter); + procedure WriteContentLayoutWidth(Writer: TWriter); + protected + //Animation mouse events + procedure AniMouseDown(const Touch: Boolean; const X, Y: Single); virtual; + procedure AniMouseMove(const Touch: Boolean; const X, Y: Single); virtual; + procedure AniMouseUp(const Touch: Boolean; const X, Y: Single); virtual; + + function GetScrollingBehaviours: TScrollingBehaviours; + procedure Loaded; override; + procedure PaddingChanged; override; + procedure DefineProperties(Filer: TFiler); override; + procedure DoAddObject(const AObject: TFmxObject); override; + procedure DoRealign; override; + function IsAddToContent(const AObject: TFmxObject): Boolean; virtual; + procedure ContentAddObject(const AObject: TFmxObject); virtual; + procedure ContentInsertObject(Index: Integer; const AObject: TFmxObject); virtual; + procedure ContentBeforeRemoveObject(AObject: TFmxObject); virtual; + procedure ContentRemoveObject(const AObject: TFmxObject); virtual; + procedure HScrollChange; virtual; + procedure VScrollChange; virtual; + procedure ViewportPositionChange(const OldViewportPosition, NewViewportPosition: TPointF; + const ContentSizeChanged: boolean); virtual; + procedure CMGesture(var EventInfo: TGestureEventInfo); override; + procedure Painting; override; + procedure AfterPaint; override; + procedure ApplyStyle; override; + procedure FreeStyle; override; + function IsOpaque: Boolean; virtual; + function ContentRect: TRectF; + function VScrollBarValue: Single; + function HScrollBarValue: Single; + function CreateScrollContent: TScrollContent; virtual; + function CreateAniCalculations: TScrollCalculations; virtual; + procedure DoUpdateAniCalculations(const AAniCalculations: TScrollCalculations); virtual; + procedure UpdateAniCalculations; + function DoCalcContentBounds: TRectF; virtual; + procedure DoRealignContent(R: TRectF); virtual; + function GetContentBounds: TRectF; + procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Single); override; + procedure MouseMove(Shift: TShiftState; X, Y: Single); override; + procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Single); override; + procedure DoMouseLeave; override; + procedure MouseWheel(Shift: TShiftState; WheelDelta: Integer; var Handled: Boolean); override; + property ContentLayout: TControl read FContentLayout; + property Content: TScrollContent read FContent; + property HScrollAlign: TAlignLayout read GetHScrollAlign; + property VScrollAlign: TAlignLayout read GetVScrollAlign; + property HScrollMargins: TRectF read GetHScrollMargins; + property VScrollMargins: TRectF read GetVScrollMargins; + property InInternalAlign: Boolean read FInInternalAlign; + property HScrollBar: TScrollBar read GetHScrollBar; + property VScrollBar: TScrollBar read GetVScrollBar; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + property AniCalculations: TScrollCalculations read FAniCalculations; + property ViewportPosition: TPointF read GetViewportPosition write SetViewportPosition; + procedure Sort(Compare: TFmxObjectSortCompare); override; + procedure Center; + procedure ScrollTo(const Dx, Dy: Single); deprecated 'use ScrollBy(const Dx, Dy: Single)'; + procedure ScrollBy(const Dx, Dy: Single); + procedure InViewRect(const Rect: TRectF); + function ClientWidth: Single; + function ClientHeight: Single; + function GetTabList: ITabList; override; + property ContentBounds: TRectF read GetContentBounds; + procedure InvalidateContentSize; + procedure RealignContent; + + property AutoHide: Boolean read FAutoHide write SetAutoHide default True; + property DisableMouseWheel: Boolean read FDisableMouseWheel write FDisableMouseWheel default False; + property ShowScrollBars: Boolean read FShowScrollBars write SetShowScrollBars default True; + property ShowSizeGrip: Boolean read FShowSizeGrip write SetShowSizeGrip default False; + property OnViewportPositionChange: TPositionChangeEvent read FOnViewportPositionChange write FOnViewportPositionChange; + property OnHScrollChange: TNotifyEvent read FOnHScrollChange write FOnHScrollChange; + property OnVScrollChange: TNotifyEvent read FOnVScrollChange write FOnVScrollChange; + property OnCalcContentBounds: TOnCalcContentBoundsEvent read FOnCalcContentBounds write FOnCalcContentBounds; + published + property Align; + property Anchors; + property ClipChildren; + property ClipParent; + property Cursor; + property DragMode; + property EnableDragHighlight; + property Enabled; + property Locked; + property Height; + property HelpContext; + property HelpKeyword; + property HelpType; + property Hint; + property HitTest; + property Padding; + property Opacity; + property Margins; + property PopupMenu; + property Position; + property RotationAngle; + property RotationCenter; + property Scale; + property Size; + property StyleLookup; + property TabOrder; + property TabStop; + property TouchTargetExpansion; + property Visible; + property Width; + property ParentShowHint; + property ShowHint; + { Events } + property OnApplyStyleLookup; + property OnFreeStyle; + property OnPainting; + property OnPaint; + property OnResize; + property OnResized; + { Drag and Drop events } + property OnDragEnter; + property OnDragLeave; + property OnDragOver; + property OnDragDrop; + property OnDragEnd; + { Mouse events } + property OnClick; + property OnDblClick; + property OnMouseDown; + property OnMouseMove; + property OnMouseUp; + property OnMouseWheel; + property OnMouseEnter; + property OnMouseLeave; + end; + +{ TScrollBox } + + TScrollBox = class(TCustomScrollBox) + protected + procedure Paint; override; + public + property Content; + published + property Align; + property Anchors; + property AutoHide; + property ClipChildren; + property ClipParent; + property Cursor; + property DisableMouseWheel; + property DragMode; + property Enabled; + property EnableDragHighlight; + property Height; + property HelpContext; + property HelpKeyword; + property HelpType; + property Hint; + property HitTest; + property Locked; + property Margins; + property Opacity; + property Padding; + property PopupMenu; + property Position; + property RotationAngle; + property RotationCenter; + property Scale; + property ShowScrollBars; + property ShowSizeGrip; + property Size; + property StyleLookup; + property TabOrder; + property TabStop; + property TouchTargetExpansion; + property Visible; + property Width; + property ParentShowHint; + property ShowHint; + { Events } + property OnApplyStyleLookup; + property OnFreeStyle; + property OnPainting; + property OnPaint; + property OnResize; + property OnResized; + { Drag and Drop events } + property OnDragEnter; + property OnDragLeave; + property OnDragOver; + property OnDragDrop; + property OnDragEnd; + { Mouse events } + property OnClick; + property OnDblClick; + property OnMouseDown; + property OnMouseMove; + property OnMouseUp; + property OnMouseWheel; + property OnMouseEnter; + property OnMouseLeave; + { ScrollBox events } + property OnViewportPositionChange; + property OnHScrollChange; + property OnVScrollChange; + property OnCalcContentBounds; + end; + +{ TVertScrollBox } + + TVertScrollBox = class(TCustomScrollBox) + protected + function GetDefaultStyleLookupName: string; override; + function DoCalcContentBounds: TRectF; override; + procedure Paint; override; + procedure DoUpdateAniCalculations(const AAniCalculations: TScrollCalculations); override; + public + property Content; + published + property Align; + property Anchors; + property AutoHide; + property ClipChildren; + property ClipParent; + property Cursor; + property DisableMouseWheel; + property DragMode; + property Enabled; + property EnableDragHighlight; + property Height; + property HelpContext; + property HelpKeyword; + property HelpType; + property Hint; + property HitTest; + property Locked; + property Margins; + property Opacity; + property Padding; + property PopupMenu; + property Position; + property RotationAngle; + property RotationCenter; + property Scale; + property ShowScrollBars; + property ShowSizeGrip; + property Size; + property StyleLookup; + property TabOrder; + property TabStop; + property TouchTargetExpansion; + property Visible; + property Width; + property ParentShowHint; + property ShowHint; + { Events } + property OnApplyStyleLookup; + property OnFreeStyle; + property OnPainting; + property OnPaint; + property OnResize; + property OnResized; + { Drag and Drop events } + property OnDragEnter; + property OnDragLeave; + property OnDragOver; + property OnDragDrop; + property OnDragEnd; + { Mouse events } + property OnClick; + property OnDblClick; + property OnMouseDown; + property OnMouseMove; + property OnMouseUp; + property OnMouseWheel; + property OnMouseEnter; + property OnMouseLeave; + { ScrollBox events } + property OnViewportPositionChange; + property OnVScrollChange; + property OnCalcContentBounds; + end; + +{ THorzScrollBox } + + THorzScrollBox = class(TCustomScrollBox) + protected + function GetDefaultStyleLookupName: string; override; + function DoCalcContentBounds: TRectF; override; + procedure Paint; override; + procedure DoUpdateAniCalculations(const AAniCalculations: TScrollCalculations); override; + public + property Content; + published + property Align; + property Anchors; + property AutoHide; + property ClipChildren; + property ClipParent; + property Cursor; + property DisableMouseWheel; + property DragMode; + property Enabled; + property EnableDragHighlight; + property Height; + property HelpContext; + property HelpKeyword; + property HelpType; + property Hint; + property HitTest; + property Locked; + property Margins; + property Opacity; + property Padding; + property PopupMenu; + property Position; + property RotationAngle; + property RotationCenter; + property Scale; + property ShowScrollBars; + property ShowSizeGrip; + property Size; + property StyleLookup; + property TabOrder; + property TabStop; + property TouchTargetExpansion; + property Visible; + property Width; + property ParentShowHint; + property ShowHint; + { Events } + property OnApplyStyleLookup; + property OnFreeStyle; + property OnPainting; + property OnPaint; + property OnResize; + property OnResized; + { Drag and Drop events } + property OnDragEnter; + property OnDragLeave; + property OnDragOver; + property OnDragDrop; + property OnDragEnd; + { Mouse events } + property OnClick; + property OnDblClick; + property OnMouseDown; + property OnMouseMove; + property OnMouseUp; + property OnMouseWheel; + property OnMouseEnter; + property OnMouseLeave; + { ScrollBox events } + property OnViewportPositionChange; + property OnHScrollChange; + property OnCalcContentBounds; + end; + +{ TFramedScrollBox } + + TFramedScrollBox = class(TCustomScrollBox) + protected + function IsOpaque: Boolean; override; + public + property Content; + published + property Align; + property Anchors; + property AutoHide; + property ClipChildren; + property ClipParent; + property Cursor; + property DisableMouseWheel; + property DragMode; + property Enabled; + property EnableDragHighlight; + property Height; + property HelpContext; + property HelpKeyword; + property HelpType; + property Hint; + property HitTest; + property Locked; + property Margins; + property Opacity; + property Padding; + property PopupMenu; + property Position; + property RotationAngle; + property RotationCenter; + property Scale; + property ShowScrollBars; + property ShowSizeGrip; + property Size; + property StyleLookup; + property TabOrder; + property TabStop; + property TouchTargetExpansion; + property Visible; + property Width; + property ParentShowHint; + property ShowHint; + { Events } + property OnApplyStyleLookup; + property OnFreeStyle; + property OnPainting; + property OnPaint; + property OnResize; + property OnResized; + { Drag and Drop events } + property OnDragEnter; + property OnDragLeave; + property OnDragOver; + property OnDragDrop; + property OnDragEnd; + { Mouse events } + property OnClick; + property OnDblClick; + property OnMouseDown; + property OnMouseMove; + property OnMouseUp; + property OnMouseWheel; + property OnMouseEnter; + property OnMouseLeave; + { ScrollBox events } + property OnViewportPositionChange; + property OnHScrollChange; + property OnVScrollChange; + property OnCalcContentBounds; + end; + +{ TFramedVertScrollBox } + + TFramedVertScrollBox = class(TVertScrollBox) + protected + function IsOpaque: Boolean; override; + function GetDefaultStyleLookupName: string; override; + end; + +{ TGridLayout } + + TGridLayout = class(TControl) + private + FItemWidth: Single; + FItemHeight: Single; + FOrientation: TOrientation; + procedure SetItemHeight(const Value: Single); + procedure SetItemWidth(const Value: Single); + procedure SetOrientation(const Value: TOrientation); + protected + procedure DoRealign; override; + procedure DoAddObject(const AObject: TFmxObject); override; + procedure DoRemoveObject(const AObject: TFmxObject); override; + procedure Paint; override; + public + constructor Create(AOwner: TComponent); override; + published + property Align; + property Anchors; + property ClipChildren; + property ClipParent; + property Cursor; + property DragMode; + property EnableDragHighlight; + property Enabled; + property Locked; + property Height; + property Hint; + property HitTest; + property ItemHeight: Single read FItemHeight write SetItemHeight; + property ItemWidth: Single read FItemWidth write SetItemWidth; + property Padding; + property Opacity; + property Orientation: TOrientation read FOrientation write SetOrientation; + property Margins; + property PopupMenu; + property Position; + property RotationAngle; + property RotationCenter; + property Scale; + property Size; + property TouchTargetExpansion; + property Visible; + property Width; + property TabOrder; + property TabStop; + property ParentShowHint; + property ShowHint; + {Drag and Drop events} + property OnDragEnter; + property OnDragLeave; + property OnDragOver; + property OnDragDrop; + property OnDragEnd; + property OnCanFocus; + property OnClick; + property OnDblClick; + property OnMouseDown; + property OnMouseMove; + property OnMouseUp; + property OnMouseWheel; + property OnMouseEnter; + property OnMouseLeave; + property OnPainting; + property OnPaint; + property OnResize; + property OnResized; + end; + +{ TGridPanelLayout } + + TGridPanelLayout = class(TControl) + public type + TSizeStyle = (Absolute, Percent, Auto, Weight); + + EGridLayoutException = class(Exception); + + TCellItem = class(TCollectionItem) + private + FSizeStyle: TSizeStyle; + FValue: Double; + FSize: Single; + FAutoAdded: Boolean; + protected + procedure AssignTo(Dest: TPersistent); override; + procedure SetSizeStyle(Value: TSizeStyle); + procedure SetValue(Value: Double); + property Size: Single read FSize write FSize; + property AutoAdded: Boolean read FAutoAdded write FAutoAdded; + public + constructor Create(Collection: TCollection); override; + published + property SizeStyle: TSizeStyle read FSizeStyle write SetSizeStyle default TSizeStyle.Percent; + property Value: Double read FValue write SetValue; + end; + + TRowItem = class(TCellItem); + + TColumnItem = class(TCellItem); + + TCellCollection = class(TOwnedCollection) + protected + function GetAttrCount: Integer; override; + function GetAttr(Index: Integer): string; override; + function GetItemAttr(Index, ItemIndex: Integer): string; override; + function GetItem(Index: Integer): TCellItem; + procedure SetItem(Index: Integer; Value: TCellItem); + procedure Update(Item: TCollectionItem); override; + public + function Owner: TGridPanelLayout; + property Items[Index: Integer]: TCellItem read GetItem write SetItem; default; + end; + + TCellSpan = 1..MaxInt; + + TRowCollection = class(TCellCollection) + protected + function GetItemAttr(Index, ItemIndex: Integer): string; override; + procedure Notify(Item: TCollectionItem; Action: System.Classes.TCollectionNotification); override; + public + constructor Create(AOwner: TPersistent); + function Add: TRowItem; + end; + + TColumnCollection = class(TCellCollection) + protected + function GetItemAttr(Index, ItemIndex: Integer): string; override; + procedure Notify(Item: TCollectionItem; Action: System.Classes.TCollectionNotification); override; + public + constructor Create(AOwner: TPersistent); + function Add: TColumnItem; + end; + + TControlItem = class(TCollectionItem) + private + [Weak] FControl: TControl; + FColumn, FRow: Integer; + FColumnSpan, FRowSpan: TCellSpan; + FPushed: Integer; + function GetGridPanelLayout: TGridPanelLayout; + function GetPushed: Boolean; + procedure SetColumn(Value: Integer); + procedure SetColumnSpan(Value: TCellSpan); + procedure SetControl(Value: TControl); + procedure SetRow(Value: Integer); + procedure SetRowSpan(Value: TCellSpan); + protected + procedure AssignTo(Dest: TPersistent); override; + procedure InternalSetLocation(AColumn, ARow: Integer; APushed: Boolean; MoveExisting: Boolean); + property GridPanelLayout: TGridPanelLayout read GetGridPanelLayout; + property Pushed: Boolean read GetPushed; + public + constructor Create(Collection: TCollection); override; + destructor Destroy; override; + procedure SetLocation(AColumn, ARow: Integer; APushed: Boolean = False); + published + property Column: Integer read FColumn write SetColumn; + property ColumnSpan: TCellSpan read FColumnSpan write SetColumnSpan default 1; + property Control: TControl read FControl write SetControl; + property Row: Integer read FRow write SetRow; + property RowSpan: TCellSpan read FRowSpan write SetRowSpan default 1; + end; + + TControlCollection = class(TOwnedCollection) + protected + function GetControl(AColumn, ARow: Integer): TControl; + function GetControlItem(AColumn, ARow: Integer): TControlItem; + function GetItem(Index: Integer): TControlItem; + procedure SetControl(AColumn, ARow: Integer; Value: TControl); + procedure SetItem(Index: Integer; Value: TControlItem); + procedure Update(Item: TCollectionItem); override; + public + constructor Create(AOwner: TPersistent); + function Add: TControlItem; + procedure AddControl(AControl: TControl; AColumn: Integer = -1; ARow: Integer = -1); + procedure RemoveControl(AControl: TControl); + function IndexOf(AControl: TControl): Integer; + function Owner: TGridPanelLayout; + property Controls[AColumn, ARow: Integer]: TControl read GetControl write SetControl; + property ControlItems[AColumn, ARow: Integer] : TControlItem read GetControlItem; + property Items[Index: Integer]: TControlItem read GetItem write SetItem; default; + end; + + TLayoutManager = class + private type + TCollectionInfo = record + FlexibleSize: Single; + WeightSum: Single; + WeightCount: Integer; + PercentageSum: Single; + PercentageCount: Integer; + end; + private + FOwner: TGridPanelLayout; + function CalculateMaxWidth(const AColumn: Integer): Single; + function CalculateMaxHeight(const ARow: Integer): Single; + function CollectColumnsInfo(const AWidth: Single): TCollectionInfo; + function CollectRowsInfo(const AHeight: Single): TCollectionInfo; + procedure NormalizePercentages(const ACollection: TCellCollection; const AInfo: TCollectionInfo; const ABaseCell: TCellItem = nil); + function ShouldNormalizePercentages(const ACollectionInfo: TCollectionInfo): Boolean; + procedure RealignItems(const ACollection: TCellCollection; const AInfo: TCollectionInfo; const ABaseCell: TCellItem = nil); + public + constructor Create(const AOwner: TGridPanelLayout); + procedure RecalcCellDimensions(const ARect: TRectF; const ABasedRow: TRowItem = nil; const ABasedColumn: TColumnItem = nil); + end; + + TExpandStyle = (AddRows, AddColumns, FixedSize); + + TState = (NeedRecalculateCellSizes, RecalculatingCellSizes); + TStates = set of TState; + private + FState: TStates; + FExpandStyle: TExpandStyle; + FRowCollection: TRowCollection; + FColumnCollection: TColumnCollection; + FControlCollection: TControlCollection; + FLayoutManager: TLayoutManager; + procedure SetColumnCollection(const Value: TColumnCollection); + procedure SetControlCollection(const Value: TControlCollection); + procedure SetRowCollection(const Value: TRowCollection); + function GetCellCount: Integer; + function GetCellSizes(AColumn, ARow: Integer): TPointF; + function GetCellRect(AColumn, ARow: Integer): TRectF; + function GetColumnSpanIndex(AColumn, ARow: Integer): Integer; + function GetRowSpanIndex(AColumn, ARow: Integer): Integer; + procedure NeedRecalculateCellSizes; + procedure RecalcCellDimensions(const ABasedRow: TRowItem = nil; const ABasedColumn: TColumnItem = nil); overload; + procedure RecalcCellDimensions(const ARect: TRectF; const ABasedRow: TRowItem = nil; const ABasedColumn: TColumnItem = nil); overload; + protected + procedure DoRealign; override; + procedure DoAddObject(const AObject: TFmxObject); override; + procedure DoRemoveObject(const AObject: TFmxObject); override; + procedure DoDeleteChildren; override; + function AutoAddColumn: TColumnItem; + function AutoAddRow: TRowItem; + procedure RemoveEmptyAutoAddColumns; + procedure RemoveEmptyAutoAddRows; + function CellToCellIndex(AColumn, ARow: Integer): Integer; + procedure CellIndexToCell(AIndex: Integer; var AColumn, ARow: Integer); + procedure DoPaint; override; + procedure Resize; override; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + + function IsColumnEmpty(AColumn: Integer): Boolean; + function IsRowEmpty(ARow: Integer): Boolean; + procedure UpdateControlsColumn(AColumn: Integer); + procedure UpdateControlsRow(ARow: Integer); + property ColumnSpanIndex[AColumn, ARow: Integer]: Integer read GetColumnSpanIndex; + property CellCount: Integer read GetCellCount; + property CellSize[AColumn, ARow: Integer]: TPointF read GetCellSizes; + property CellRect[AColumn, ARow: Integer]: TRectF read GetCellRect; + property RowSpanIndex[AColumn, ARow: Integer]: Integer read GetRowSpanIndex; + published + property Align; + property Anchors; + property ClipChildren; + property ClipParent; + property Cursor; + property DragMode; + property EnableDragHighlight; + property Enabled; + property Locked; + property Height; + property Hint; + property HitTest; + property Padding; + property Opacity; + property Margins; + property PopupMenu; + property Position; + property RotationAngle; + property RotationCenter; + property Scale; + property Size; + property TouchTargetExpansion; + property Visible; + property Width; + property TabOrder; + property TabStop; + property ParentShowHint; + property ShowHint; + { Columns and rows } + property ColumnCollection: TColumnCollection read FColumnCollection write SetColumnCollection; + property ControlCollection: TControlCollection read FControlCollection write SetControlCollection; + property ExpandStyle: TExpandStyle read FExpandStyle write FExpandStyle default TExpandStyle.AddRows; + property RowCollection: TRowCollection read FRowCollection write SetRowCollection; + {Drag and Drop events} + property OnDragEnter; + property OnDragLeave; + property OnDragOver; + property OnDragDrop; + property OnDragEnd; + property OnCanFocus; + property OnClick; + property OnDblClick; + property OnMouseDown; + property OnMouseMove; + property OnMouseUp; + property OnMouseWheel; + property OnMouseEnter; + property OnMouseLeave; + property OnPainting; + property OnPaint; + property OnResize; + property OnResized; + end; + + TFlowJustify = (Left, Right, Center, Justify); + + TFlowDirection = (LeftToRight, RightToLeft); + + TFlowLayoutRules = record + Justify: TFlowJustify; + JustifyLast: TFlowJustify; + Direction: TFlowDirection; + HorizontalGap: Single; + VerticalGap: Single; + end; + + TFlowLayoutBreak = class(TControl) + private + FRules: TFlowLayoutRules; + FChangesRules: Boolean; + protected + procedure SetChangesRules(AChangesRules: Boolean); + procedure Paint; override; + function VisibleStored: Boolean; override; + public + constructor Create(AOwner: TComponent); override; + published + property ChangesRules: Boolean read FChangesRules write SetChangesRules; + property Justify: TFlowJustify read FRules.Justify write FRules.Justify; + property JustifyLastLine: TFlowJustify read FRules.JustifyLast write FRules.JustifyLast; + property FlowDirection: TFlowDirection read FRules.Direction write FRules.Direction; + property HorizontalGap: Single read FRules.HorizontalGap write FRules.HorizontalGap; + property VerticalGap: Single read FRules.VerticalGap write FRules.VerticalGap; + property Visible; + end; + + TFlowLayout = class(TControl, IContentObserver) + private + FRules: TFlowLayoutRules; + protected + procedure DoRealign; override; + procedure DoAddObject(const AObject: TFmxObject); override; + procedure DoRemoveObject(const AObject: TFmxObject); override; + procedure Paint; override; + procedure SetJustify(AJustify: TFlowJustify); + procedure SetJustifyLast(AJustify: TFlowJustify); + procedure SetFlowDirection(ADirection: TFlowDirection); + procedure SetHGap(AHGap: Single); + procedure SetVGap(AVGap: Single); + { IContentObserver } + procedure IContentObserver.Changed = ContentChanged; + procedure ContentChanged(const AChild: TFmxObject); virtual; + public + constructor Create(AOwner: TComponent); override; + published + property Align; + property Anchors; + property ClipChildren; + property ClipParent; + property Cursor; + property DragMode; + property EnableDragHighlight; + property Enabled; + property Locked; + property Height; + property Hint; + property HitTest; + property Padding; + property Opacity; + property Margins; + property PopupMenu; + property Position; + property RotationAngle; + property RotationCenter; + property Scale; + property Size; + property TouchTargetExpansion; + property Visible; + property Width; + property TabOrder; + property TabStop; + property Justify : TFlowJustify read FRules.Justify write SetJustify; + property JustifyLastLine : TFlowJustify read FRules.JustifyLast write SetJustifyLast; + property FlowDirection : TFlowDirection read FRules.Direction write SetFlowDirection; + property HorizontalGap : Single read FRules.HorizontalGap write SetHGap; + property VerticalGap : Single read FRules.VerticalGap write SetVGap; + property ParentShowHint; + property ShowHint; + {Drag and Drop events} + property OnDragEnter; + property OnDragLeave; + property OnDragOver; + property OnDragDrop; + property OnDragEnd; + {Mouse events} + property OnClick; + property OnDblClick; + property OnMouseDown; + property OnMouseMove; + property OnMouseUp; + property OnMouseWheel; + property OnMouseEnter; + property OnMouseLeave; + property OnPainting; + property OnPaint; + property OnResize; + property OnResized; + end; + +//== INTERFACE END: FMX.Layouts +//================================================================================================== + +//================================================================================================== +//== INTERFACE START: FMX.ScrollBox (from FMX.ScrollBox.pas) //================================================================================================== {$SCOPEDENUMS ON} @@ -18081,11 +22313,184 @@ type /// Normalizes the target rectangle AContentRect. function NormalizeInViewRect(const AContentRect: TRectF; const AViewportSize: TSizeF; const AWishedViewPortRect: TRectF): TRectF; -//== UNIT END: FMX.ScrollBox +//== INTERFACE END: FMX.ScrollBox //================================================================================================== //================================================================================================== -//== UNIT START: FMX.Memo (from FMX.Memo.pas) +//== INTERFACE START: FMX.ListView.Adapters.Base (from FMX.ListView.Adapters.Base.pas) +//================================================================================================== + + +type + TAbstractListViewAdapter = class abstract (TInterfacedPersistent) + strict private + FUpdatingCount: Integer; + FOnChanged: TNotifyEvent; + FOnItemsMayChange: TNotifyEvent; + FOnItemsCouldHaveChanged: TNotifyEvent; + FOnItemsInvalidate: TNotifyEvent; + FOnItemsResize: TNotifyEvent; + FOnResetView: TNotifyEvent; + strict protected + procedure CreateNewViews; + procedure DoCreateNewViews; virtual; + + procedure ResetViews(const APurposes: TListItemPurposes); + procedure DoResetViews(const APurposes: TListItemPurposes); virtual; + + procedure ResetView(const Item: TListItem); + procedure DoResetView(const Item: TListItem); virtual; + procedure DoSort(AComparer: IComparer); virtual; + + procedure SetOnChanged(const Value: TNotifyEvent); + procedure SetOnItemsMayChange(const Value: TNotifyEvent); + procedure SetOnItemsCouldHaveChanged(const Value: TNotifyEvent); + procedure SetOnItemsInvalidate(const Value: TNotifyEvent); + procedure SetOnItemsResize(const Value: TNotifyEvent); + procedure SetOnResetView(const Value: TNotifyEvent); + /// It's invoked when updating process is finished. + procedure DoEndUpdate; virtual; + public + procedure Changed; virtual; + procedure ItemsMayChange; + procedure ItemsCouldHaveChanged; + procedure ItemsInvalidate; + procedure ItemsResize; + procedure BeginUpdate; + procedure EndUpdate; + function IsUpdating: Boolean; + procedure Sort(AComparer: IComparer); + property OnChanged: TNotifyEvent write SetOnChanged; + property OnItemsMayChange: TNotifyEvent write SetOnItemsMayChange; + property OnItemsCouldHaveChanged: TNotifyEvent write SetOnItemsCouldHaveChanged; + /// notify the view that repaint is necessary + property OnItemsInvalidate: TNotifyEvent write SetOnItemsInvalidate; + /// notify the view that the sizes of items need recalculation + property OnItemsResize: TNotifyEvent write SetOnItemsResize; + property OnResetView: TNotifyEvent write SetOnResetView; + end; + + /// Minimal concrete implementation of IListViewAdapter + TListViewItems = class(TAbstractListViewAdapter, IListViewAdapter) + public type + TOrder = (FirstToLast, LastToFirst); + strict private + FActiveItems: TListItemsList; + FOnNotify: TCollectionNotifyEvent; + + { IListViewAdapter } + function GetDefaultViewHeight: Integer; + strict protected + function GetCount: Integer; virtual; + function GetItem(const Index: Integer): TListItem; virtual; + procedure ResetIndexes; + procedure ObjectsNotify(Sender: TObject; const Item: TListItem; Action: TCollectionNotification); + property ActiveItems: TListItemsList read FActiveItems write FActiveItems; + procedure DoSort(AComparer: IComparer); override; + public + constructor Create; + destructor Destroy; override; + /// Return index of AItem + function IndexOf(const AItem: TListItem): Integer; + /// Return TEnumerator<TListItem> of items in this adapter + function GetEnumerator: TEnumerator; + /// Access TListItem by Index + property Item[const Index: Integer]: TListItem read GetItem; default; + /// Count of items + property Count: Integer read GetCount; + /// Collection notify event, used internally + property OnNotify: TCollectionNotifyEvent read FOnNotify write FOnNotify; + end; + + /// Implementation of IListViewAdapter and IListViewFilterable + TFilterableListViewItems = class(TListViewItems, IListViewFilterable) + strict private + FUnfilteredItems: TListItemsList; + FFilteredItems: TListItemsList; + FFilterPredicate: TFilterPredicate; + FNeedApplyFilter: Boolean; + FIsFiltering: Boolean; + + procedure ItemsCleared; + procedure ItemDeleted(const Index: Integer); + procedure ItemAdded(const Index: Integer; const Item: TListItem); + { IListViewFilterable } + function GetFilterPredicate: TFilterPredicate; + function GetUnfilteredItems: TListItemsList; + procedure SetFilterPredicate(const Value: TFilterPredicate); + function GetFiltered: Boolean; + strict protected + /// Return True if item should be shown + function DoFilterItem(const Item: TListItem): Boolean; virtual; abstract; + /// Return unfiltered items. FFilteredItems by default. + function DoGetUnfilteredItems: TListItemsList; virtual; + procedure DoEndUpdate; override; + public + constructor Create; + destructor Destroy; override; + procedure Changed; override; + /// Filters items if the adapter is not in the process of batch updating data. + procedure ApplyFilter; + /// Filter predicate + property Filter: TFilterPredicate read GetFilterPredicate write SetFilterPredicate; + /// A complete list of all items, regardless of state of Filtered + property UnfilteredItems: TListItemsList read GetUnfilteredItems; + ///Filtered is True if some items are not displayed + property Filtered: Boolean read GetFiltered; + end; + +//== INTERFACE END: FMX.ListView.Adapters.Base +//================================================================================================== + +//================================================================================================== +//== INTERFACE START: FMX.SearchBox (from FMX.SearchBox.pas) +//================================================================================================== + +{$SCOPEDENUMS ON} + + +type + + /// Type of event handler for filtering of string value. If value is filtered by the filter condition, + /// Accept should be True, Otherwise - false + TFilterEvent = procedure (Sender: TObject; const AFilter: string; const AValue: string; var Accept: Boolean) of object; + +{ TSearchBox } + + TSearchBoxModel = class(TCustomEditModel) + private + [Weak] FSearchResponder: ISearchResponder; + FOnFilter: TFilterEvent; + protected + procedure DoChangeTracking; override; + public + property SearchResponder: ISearchResponder read FSearchResponder write FSearchResponder; + /// Event handler for setting custom filter on text of TSearchBox. + property OnFilter: TFilterEvent read FOnFilter write FOnFilter; + end; + + TSearchBox = class(TEdit, IListBoxHeaderTrait) + private + function GetOnFilter: TFilterEvent; + procedure SetOnFilter(const Value: TFilterEvent); + function GetModel: TSearchBoxModel; overload; + protected + function DefinePresentationName: string; override; + function DefineModelClass: TDataModelClass; override; + procedure ParentChanged; override; + public + constructor Create(AOwner: TComponent); override; + property Model: TSearchBoxModel read GetModel; + published + /// Event handler for setting custom filter on text of TSearchBox. + property OnFilter: TFilterEvent read GetOnFilter write SetOnFilter; + end; + +//== INTERFACE END: FMX.SearchBox +//================================================================================================== + +//================================================================================================== +//== INTERFACE START: FMX.Memo (from FMX.Memo.pas) //================================================================================================== {$SCOPEDENUMS ON} @@ -18595,6 +23000,2463 @@ type property OnPresentationNameChoosing; end; -//== UNIT END: FMX.Memo +//== INTERFACE END: FMX.Memo +//================================================================================================== + +//================================================================================================== +//== INTERFACE START: FMX.ListView.Appearances (from FMX.ListView.Appearances.pas) +//================================================================================================== + + +type + TItemControlEvent = procedure(const Sender: TObject; const AItem: TListItem; const AObject: TListItemSimpleControl) of object; + + TListViewItem = class; + TItemAppearanceProperties = class; + TPublishedObjects = class; + + /// An extension of TListView that uses appearance-based items. + /// + IAppearanceItemOwner = interface + ['{A3CAF8E2-ECD5-4989-9B03-B3E79B02DFBC}'] + /// Return array of TItemAppearanceProperties specific for this ListView. + /// The array includes appearances for various item purposes and state, namely + /// Item, ItemEdit, Header and Footer. + /// + function GetAppearanceProperties: TArray; + /// Begin control update. Uses the same semantics as TControl.BeginUpdate + procedure BeginUpdate; + /// End control update. Uses the same semantics as TControl.EndUpdate + procedure EndUpdate; + end; + + /// Interface from TPublishedAppearance and TItemAppearanceProperties + /// to its owner (TAppearanceListView). + IPublishedAppearanceOwner = interface + ['{990AB866-92AB-4552-BB12-223F44CFD062}'] + /// Notify the owner of appearance change + procedure ItemAppearanceChange(const Sender: TItemAppearanceProperties); + /// Notify the owner of appearance view change + procedure ItemAppearanceChangeObjects(const Sender: TItemAppearanceProperties); + /// Notify the owner of appearance height change + procedure ItemAppearanceChangeHeight(const Sender: TItemAppearanceProperties); + /// Query owner if it's currently in edit mode + function IsEditMode: Boolean; + /// Get header height + function GetHeaderHeight: Integer; + /// Set header height + procedure SetHeaderHeight(const Value: Integer); + /// Get footer height + function GetFooterHeight: Integer; + /// Set footer height + procedure SetFooterHeight(const Value: Integer); + /// Get regular item height + function GetItemHeight: Integer; + /// Set regular item height + procedure SetItemHeight(const Value: Integer); + /// Get regular item edit mode height + function GetItemEditHeight: Integer; + /// Set regular item edit mode height + procedure SetItemEditHeight(const Value: Integer); + + /// Get footer apperance name + function GetFooterAppearanceName: string; + /// Set footer apperance name + procedure SetFooterAppearanceName(const Value: string); + /// Get header appearance name + function GetHeaderAppearanceName: string; + /// Set header appearance name + procedure SetHeaderAppearanceName(const Value: string); + /// Get regular item appearance name + function GetItemAppearanceName: string; + /// Set regular item appearance name + procedure SetItemAppearanceName(const Value: string); + /// Get regular item appearance name in edit mode + function GetItemEditAppearanceName: string; + /// Set regular item appearance name in edit mode + procedure SetItemEditAppearanceName(const Value: string); + + /// Get footer appearance properties + function GetFooterAppearanceProperties: TItemAppearanceProperties; + /// Get header appearance properties + function GetHeaderAppearanceProperties: TItemAppearanceProperties; + /// Get regular item appearance properties + function GetItemAppearanceProperties: TItemAppearanceProperties; + /// Get regular item appearance properties in edit mode + function GetItemEditAppearanceProperties: TItemAppearanceProperties; + /// Setter for ItemAppearanceObjects property + procedure SetItemAppearanceObjects(const Value: TPublishedObjects); + /// Getter for ItemAppearanceObjects property + function GetItemAppearanceObjects: TPublishedObjects; + + /// Footer height + property FooterHeight: Integer read GetFooterHeight write SetFooterHeight; + /// Header height + property HeaderHeight: Integer read GetHeaderHeight write SetHeaderHeight; + /// Regular item height + property ItemHeight: Integer read GetItemHeight write SetItemHeight; + /// Regular item height in edit mode + property ItemEditHeight: Integer read GetItemEditHeight write SetItemEditHeight; + + /// Footer appearance name + property FooterAppearanceName: string read GetFooterAppearanceName write SetFooterAppearanceName; + /// Header appearance name + property HeaderAppearanceName: string read GetHeaderAppearanceName write SetHeaderAppearanceName; + /// Regular item appearance name + property ItemAppearanceName: string read GetItemAppearanceName write SetItemAppearanceName; + /// Regular appearance name in edit mode + property ItemEditAppearanceName: string read GetItemEditAppearanceName write SetItemEditAppearanceName; + + /// Footer appearance properties + property FooterAppearanceProperties: TItemAppearanceProperties read GetFooterAppearanceProperties; + /// Header appearance properties + property HeaderAppearanceProperties: TItemAppearanceProperties read GetHeaderAppearanceProperties; + /// Regular item appearance properties + property ItemAppearanceProperties: TItemAppearanceProperties read GetItemAppearanceProperties; + /// Regular item appearance properties in edit mode + property ItemEditAppearanceProperties: TItemAppearanceProperties read GetItemEditAppearanceProperties; + /// Access instance of TPublishedObjects used by ListView + property ItemAppearanceObjects: TPublishedObjects read GetItemAppearanceObjects write SetItemAppearanceObjects; + end; + + TAppearanceNamePair = TPair; + TAppearanceType = (Item, ItemEdit, Header, Footer); + + TItemAppearanceObjects = class; + + /// Standard appearance names + TAppearanceNames = class + public const + Empty = ''; + Null = 'Null'; + Custom = 'Custom'; + ListHeader = 'ListHeader'; + // ListItem group + ListItem = 'ListItem'; + ListItemDelete = 'ListItemDelete'; + ListItemShowCheck = 'ListItemShowCheck'; + // ListItemRightDetail group + ListItemRightDetail = 'ListItemRightDetail'; + ListItemRightDetailDelete = 'ListItemRightDetailDelete'; + ListItemRightDetailShowCheck = 'ListItemRightDetailShowCheck'; + // ImageListItemgec group + ImageListItem = 'ImageListItem'; + ImageListItemDelete = 'ImageListItemDelete'; + ImageListItemShowCheck = 'ImageListItemShowCheck'; + ImageListItemBottomDetail = 'ImageListItemBottomDetail'; + ImageListItemBottomDetailShowCheck = 'ImageListItemBottomDetailShowCheck'; + ImageListItemBottomDetailRightButton = 'ImageListItemBottomDetailRightButton'; + ImageListItemBottomDetailRightButtonShowCheck = 'ImageListItemBottomDetailRightButtonShowCheck'; + // ListItemRightButton group + ImageListItemRightButton = 'ImageListItemRightButton'; + ImageListItemRightButtonDelete = 'ImageListItemRightButtonDelete'; + ImageListItemRightButtonShowCheck = 'ImageListItemRightButtonShowCheck'; + end; + + /// Extended items adapter that supports item appearances. This is the default adapter used by + /// TAppearanceListView. It implements all extensions supported by TAppearanceListView. + /// + TAppearanceListViewItems = class(TFilterableListViewItems, IListViewAdapter, IListViewCheckProvider, IListViewEditor, + IListViewFilterable, IListViewTextProvider, IListViewTextButtonProvider, IListViewGlyphButtonProvider, + IListViewExtrasProvider) + strict private + [Weak] FOwnerControl: TControl; + FIsDelayedChanged: Boolean; + FNewItems: TListItemsList; + FAsFilterable: IListViewFilterable; + FPresentationParent: IListViewPresentationParent; + FListViewController: IListViewController; + { IListViewEditor } + FBeforeItemAdded: TBeforeItemAddedNotify; + FAfterItemAdded: TAfterItemAddedNotify; + FBeforeItemDeleted: TBeforeItemDeletedNotify; + FAfterItemDeleted: TAfterItemDeletedNotify; + FCheckedCount: Integer; + + { IListViewEditor } + function EditorAdd: TListItem; + function EditorInsert(const Index: Integer): TListItem; + + procedure SetBeforeItemAdded(const AHandler: TBeforeItemAddedNotify); + procedure SetAfterItemAdded(const AHandler: TAfterItemAddedNotify); + procedure SetBeforeItemDeleted(const AHandler: TBeforeItemDeletedNotify); + procedure SetAfterItemDeleted(const AHandler: TAfterItemDeletedNotify); + + { IListViewTextProvider } + function GetText(const Index: Integer): string; + function GetIndexTitle(const Index: Integer): string; + + { IListViewGlyphButtonProvider } + function GetGlyphButtonDrawable(const Index: Integer): TListItemGlyphButton; + + { IListViewTextButtonProvider } + function GetTextButtonDrawable(const Index: Integer): TListItemTextButton; + + { IListViewExtrasProvider } + function GetItemData(const Index: Integer; const DataIndex: string): TValue; + procedure SetItemData(const Index: Integer; const DataIndex: string; const AValue: TValue); + function GetHasData(const Index: Integer; const DataIndex: string): Boolean; + function GetItemTag(const Index: Integer): NativeInt; + procedure SetItemTag(const Index: Integer; const AValue: NativeInt); + + strict private + function GetAppearanceItem(const Index: Integer): TListViewItem; + strict protected + /// Create drawables for newly added items. + procedure DoCreateNewViews; override; + /// Apply filter to given item + function DoFilterItem(const Item: TListItem): Boolean; override; + /// Recreate drawables for items with given purposes. + procedure DoResetViews(const APurposes: TListItemPurposes); override; + /// Clear the list of items. + procedure DoClear; virtual; + /// Add new item at index Index and return it. + function DoAddItem(const Index: Integer = -1): TListViewItem; virtual; + procedure DoEndUpdate; override; + protected + /// Owner control, TAppearanceListView + property OwnerControl: TControl read FOwnerControl; + /// Owner control as IAppearanceItemOwner + function AppearanceItemOwner: IAppearanceItemOwner; + public + constructor Create(const Owner: TControl); + destructor Destroy; override; + function IListViewEditor.Add = EditorAdd; + function IListViewEditor.Insert = EditorInsert; + /// Sort items using given AComparer + procedure Sort(AComparer: IComparer); overload; + { IListViewCheckable } + /// True if there is an item such that Item.Checked = AChecked + function AnyChecked(const AChecked: Boolean = True): Boolean; + /// Index of the first item where Item.Checked = AChecked + function FirstChecked(const AChecked: Boolean = True): Integer; + /// Count items where Item.Checked = AChecked + function CheckedCount(const AChecked: Boolean = True): Integer; + /// Change check state of all items + procedure CheckAll(const AChecked: Boolean = True); overload; + /// Change check state of all items. If ACallback is not nil, it should return True + /// for items state of which should be changed. Callback argument is Item Index, return value is + /// a Boolean which enables or disables state change for given index. + procedure CheckAll(const ACallback: TFunc; const AChecked: Boolean = True); overload; + function GetChecked(const Index: Integer): Boolean; + procedure SetChecked(const Index: Integer; const Value: Boolean); + /// Get/set checked state of item at Index + property Checked[const Index: Integer]: Boolean read GetChecked write SetChecked; + /// Return indexes of all checked (if AChecked = True) or unchecked (AChecked = False) items. + function CheckedIndexes(const AChecked: Boolean): TArray; overload; + /// Return indexes of all checked (if AChecked = True) or unchecked (AChecked = False) items. + /// AOrder specifies order of returned items, TListViewItems.TOrder.FirstToLast or + /// TListViewItems.TOrder.LastToFirst. + function CheckedIndexes(const AOrder: TListViewItems.TOrder; const AChecked: Boolean): TArray; overload; + /// Obtain TEnumerator for this adapter + function GetEnumerator: TEnumerator; reintroduce; + /// Perform recounting of all items, find AItem and return its index or -1 if not found. + /// This method is called by implementation IListViewController.RequestReindexing in + /// TListViewBase + function ReindexAndFindItem(const AItem: TListViewItem): Integer; // item reindexer, formerly in ListView + + { IListViewEditor } + /// Create a new TListViewItem and append it at the end of list of items + /// New item instance + function Add: TListViewItem; + /// Create a new TListViewItem and insert it before position specified by Index + /// New item instance + function Insert(const Index: Integer): TListViewItem; + /// Delete an item with index Index + procedure Delete(const Index: Integer); + /// Dispose of all items at once + procedure Clear; + /// Same as Insert(Index) + function AddItem(const Index: Integer = -1): TListViewItem; + /// Default index property. Get a TListViewItem at index. + property AppearanceItem[const Index: Integer]: TListViewItem read GetAppearanceItem; default; + /// Return this adapter as IListViewFilterable + property AsFilterable: IListViewFilterable read FAsFilterable; + end; + + /// Extension of TListItem that supports Appearances. + /// Forms content of TAppearanceListViewItems + TListViewItem = class(TListItem) + private type + TFlag = (HasButtonText, HasCheck); + TFlags = set of TFlag; + public type + /// Standard appearance object names + TObjectNames = class + public const + Text = 'T'; // do not localize + Detail = 'D'; // do not localize + Accessory = 'A'; // do not localize + TextButton = 'B'; // do not localize + GlyphButton = 'G'; // do not localize + Image = 'I'; // do not localize + end; + /// Standard appearance object data members + TMemberNames = class + public const + Text = 'Text'; // do not localize + Detail = 'Detail'; // do not localize + ButtonText = 'ButtonText'; // do not localize + Bitmap = 'Bitmap'; // do not localize + ImageIndex = 'ImageIndex'; // do not localize + end; + + /// Extension of TListItemView which defines public properties for commonly used drawables + TListViewItemObjects = class(TListItemView) + strict private + FAppearance: TItemAppearanceObjects; + function GetDetailObject: TListItemText; + function GetGlyphButton: TListItemGlyphButton; + function GetImageObject: TListItemImage; + function GetTextButton: TListItemTextButton; + function GetTextObject: TListItemText; + function GetAccessoryObject: TListItemAccessory; + public + procedure Clear; override; + /// Find TListItemDrawable object of type T with the name AName + function FindObjectT(const AName: string): T; + /// Text drawable object + property TextObject: TListItemText read GetTextObject; + /// Detail text drawable object + property DetailObject: TListItemText read GetDetailObject; + /// Image drawable object + property ImageObject: TListItemImage read GetImageObject; + /// Text button drawable object + property TextButton: TListItemTextButton read GetTextButton; + /// Glyph button drawable object + property GlyphButton: TListItemGlyphButton read GetGlyphButton; + /// Accessory drawable object + property AccessoryObject: TListItemAccessory read GetAccessoryObject; + /// Reference to TItemAppearanceObjects that serve as prototypes + /// for the drawables in this view + property Appearance: TItemAppearanceObjects read FAppearance write FAppearance; + end; + + private type + TDirtyDrawable = (Text, Detail, Check, ButtonText, Accessory, ImageIndex, BitmapValue, BitmapRef); + TDirtyDrawables = set of TDirtyDrawable; + + private + FData: TDictionary; + FDataBitmaps: TDictionary; + FFlags: TFlags; + FText: string; + FDetail: string; + FIndexTitle: string; + FButtonText: string; + FAccessory: TAccessoryType; + FBitmap: TBitmap; + FChecked: Boolean; + FImageIndex: Integer; + [Weak] FBitmapRef: TBitmap; + FCreatingObjectsGuard: Boolean; + FDirtyDrawables: TDirtyDrawables; + FPresentationParent: IListViewPresentationParent; + procedure SetText(const Value: string); + function GetBitmap: TBitmap; + procedure SetAccessory(const Value: TAccessoryType); + procedure SetDetail(const Value: string); + procedure SetButtonText(const Value: string); + procedure SetImageIndex(Value: Integer); + procedure SetBitmap(const Value: TBitmap); + procedure OnBitmapChanged(Sender: TObject); + procedure SetBitmapRef(const Value: TBitmap); + procedure CheckBitmap; + function GetChecked: Boolean; + procedure SetChecked(const Value: Boolean); + function GetViewObjects: TListViewItemObjects; + function GetData(const AIndex: string): TValue; + procedure SetData(const AIndex: string; const AValue: TValue); + function GetIndexTitle: string; + procedure SetIndexTitle(const Value: string); + procedure UpdateDrawables; + protected + function GetIndex: Integer; override; + /// True if user-specified button text is set for this item. If user text is not specified, + /// the value defined by Text Button Appearance will be used. + function GetHasButtonText: Boolean; + function GetHasData(const AIndex: string): Boolean; + function ListItemObjectsClass: TListItem.TListItemViewType; override; + procedure SetPurpose(const AValue: TListItemPurpose); override; + procedure InvalidateHeights; override; + procedure ClearData(const AIndex: string); + public + constructor Create(const Owner: TAppearanceListViewItems; PresentationParent: IListViewPresentationParent; + AController: IListViewController); + destructor Destroy; override; + procedure CreateObjects; override; + procedure WillBePainted; override; + /// Main text for the cell. + property Text: string read FText write SetText; + /// Detail (smaller) text for the cell. This may either appear below or to the right of main text, + /// depending on currently selected appearance. It may also not appear at all. + property Detail: string read FDetail write SetDetail; + /// Shortcut letter that appears on the right of the list in native iOS presentations. + property IndexTitle: string read GetIndexTitle write SetIndexTitle; + /// Accessory type. Used if the appearance defines an accessory item. + property Accessory: TAccessoryType read FAccessory write SetAccessory; + /// Bitmap to be used by default Image Appearance Item. Assigning this property will + /// create a bitmap copy stored in this item. + property Bitmap: TBitmap read GetBitmap write SetBitmap; + /// Bitmap reference to be used by default Image Appearance Item. The bitmap will not be + /// copied to the item, the original TBitmap object should be managed by the user. + property BitmapRef: TBitmap read FBitmapRef write SetBitmapRef; + /// Text to be used by default TextButton Appearance Item. + property ButtonText: string read FButtonText write SetButtonText; + ///Zero based index of an image in the ImageList. The default is -1. + /// See also FMX.ActnList.IGlyph + ///If non-existing index is specified, an image is not drawn and no exception is raised + property ImageIndex: Integer read FImageIndex write SetImageIndex; + ///True if this item is checked. Only valid in EditMode + property Checked: Boolean read GetChecked write SetChecked; + ///An extension of TListItemView that has public references to the default set of drawables + /// used by predefined appearances + property Objects: TListViewItemObjects read GetViewObjects; + /// Set or get arbitrary data values. Once set, the values will be stored in the item. + /// Data values with AIndex matching AppearanceItem Name will be used to initialize + /// that the Drawable created by that Appearance Item. For example, Data['Text'] := MyText will initialize + /// the drawable managed by the appearance item called 'Text' using myText. + property Data[const AIndex: string]: TValue read GetData write SetData; + /// True if a value with index AIndex is stored in this item + property HasData[const AIndex: string]: Boolean read GetHasData; + end; + + /// Compatibility alias + TAppearanceListViewItem = TListViewItem; + +{$REGION 'Appearance object declarations'} + /// Base object appearance class. Object appearance creates a TListItemDrawable in a given item, + /// thus serving as a kind of view constructor for item views. + /// When TAppearanceListView needs to create an item view, it gets TItemAppearanceObjects (Item Appearance) + /// and invokes TObjectAppearance.ResetObject(TListViewItem) on each of them + /// + TObjectAppearance = class abstract (TInterfacedPersistent, IDesignablePersistent) + public type + /// Display name :-> Data member + TDataMember = TPair; + TDataMembers = TArray; + private + [Weak] FOwner: TItemAppearanceObjects; + FName: string; + FDefaultValues: TObjectAppearance; + FVisible: Boolean; + FOnChange: TNotifyEvent; + FOnHeightChange: TNotifyEvent; + FInitializing: Boolean; + FDataMembers: TDataMembers; + FUsingDefaultValues: Boolean; + FShim: IPersistentShim; + + procedure SetDefaultValues(const Value: TObjectAppearance); + function IgnoreChanges: Boolean; + procedure SetVisible(const Value: Boolean); + { IDesignablePersistent } + function GetBoundsRect: TRect; + function GetDesignParent: TPersistent; + procedure BindShim(AShim: IPersistentShim); + procedure UnbindShim; + procedure IDesignablePersistent.Bind = BindShim; + procedure IDesignablePersistent.Unbind = UnbindShim; + function BeingDesigned: Boolean; + protected + /// Invoke OnChange + procedure DoChange; virtual; + /// Invoke OnHeightChange + procedure DoHeightChange; virtual; deprecated; + function IsActive: Boolean; virtual; + function GetHeight: Integer; virtual; + function CreateDefaultValues: TObjectAppearance; virtual; + public + constructor Create; overload; virtual; + constructor Create(AIsDefaultValues: Boolean); overload; + destructor Destroy; override; + /// Initialize self using default values + procedure RestoreDefaults; virtual; + procedure AfterConstruction; override; + /// BeginUpdate/EndUpdate delegates update cycle to the owner control + procedure BeginUpdate; + /// BeginUpdate/EndUpdate delegates update cycle to the owner control + procedure EndUpdate; + /// Create a drawable in the view after own image and initialize it with appearance properties. + /// For example, TCustomTextObjectAppearance.CreateObject creates an instance of TListItemText + procedure CreateObject(const AListViewItem: TListViewItem); virtual; abstract; + /// Find drawable that matches type and name of self in AListViewItem.View, and initialize it. + procedure ResetObject(const AListViewItem: TListViewItem); virtual; abstract; + /// Default values + property DefaultValues: TObjectAppearance read FDefaultValues write SetDefaultValues; + /// Owner appearance + property Owner: TItemAppearanceObjects read FOwner write FOwner; + /// Name of object appearance + property Name: string read FName write FName; + /// Data members + property DataMembers: TDataMembers read FDataMembers write FDataMembers; + /// Invoked on change + property OnChange: TNotifyEvent read FOnChange write FOnChange; + /// Invoked on height change + property OnHeightChange: TNotifyEvent read FOnHeightChange write FOnHeightChange; + /// Height + property Height: Integer read GetHeight; + /// Determines whether the current item is visible or not + property Visible: Boolean read FVisible write SetVisible; + end; + + /// Compatibility alias + TListItemObjectClass = class of TListItemDrawable; + + /// Common implementation of TObjectAppearance + TCommonObjectAppearance = class(TObjectAppearance, IMovablePersistent) + strict private + FWidth: Single; + FHeight: Single; + FAlign: TListItemAlign; + FVertAlign: TListItemAlign; + FPlaceOffset: TPosition; + FInternalPlaceOffset: TPosition; + FInternalWidth: Single; + FInternalHeight: Single; + FOpacity: Single; + procedure SetAlign(const Value: TListItemAlign); + procedure SetPlaceOffset(const Value: TPosition); + procedure SetVertAlign(const Value: TListItemAlign); + procedure SetHeight(const Value: Single); + procedure SetWidth(const Value: Single); + procedure OnPlaceOffsetChange(Sender: TObject); + procedure SetInternalPlaceOffset(const Value: TPosition); + procedure SetOpacity(const Value: Single); + procedure SetInternalWidth(const Value: Single); + procedure SetInternalHeight(const Value: Single); + private + function GetActualHeight: Single; + function GetActualPlaceOffset: TPointF; + function GetActualWidth: Single; + function GetWidthWhenVisible: Single; + function GetHeightWhenVisible: Single; + function GetSizeWhenVisible: TPointF; + protected + procedure AssignTo(ADest: TPersistent); override; + /// + procedure InitDefaultValues(const ADefaults: TCommonObjectAppearance); virtual; + /// Find or create new drawable object of type T named Name in item AListViewItem + /// and initialize it by assigning self. + procedure ResetObjectT(const AListViewItem: TListViewItem); + function IsAlignStored: Boolean; + function IsVertAlignStored: Boolean; + function IsVisibleStored: Boolean; + function IsPlaceOffsetStored: Boolean; + function IsWidthStored: Boolean; + function IsHeightStored: Boolean; + function IsOpacityStored: Boolean; + + { IMovablePersistent } + procedure SetBoundsRect(const AValue: TRect); + public + constructor Create; override; + destructor Destroy; override; + /// Get actual height of the Appearance Object. The return value is: + /// If Visible = True: + /// Value of property Height if it is not zero. + /// Value of property InternalHeight otherwise. + /// If Visible = False: + /// 0 + /// + property ActualHeight: Single read GetActualHeight; + /// Get actual width of the Appearance Object. The return value is: + /// If Visible = True: + /// Value of property Width if it is not zero. + /// Value of property InternalWidth otherwise. + /// If Visible = False: + /// 0 + /// + property ActualWidth: Single read GetActualWidth; + /// Width of this object appearance regardless of current visibility + property WidthWhenVisible: Single read GetWidthWhenVisible; + /// Height of this object appearance regardless of current visibility + property HeightWhenVisible: Single read GetHeightWhenVisible; + /// Size of this object appearance regardless of current visibility + property SizeWhenVisible: TPointF read GetSizeWhenVisible; + /// Actual offset from the calculated position: PlaceOffset if nonzero, InternalPlaceOffset otherwise. + property ActualPlaceOffset: TPointF read GetActualPlaceOffset; + /// Internal width + property InternalWidth: Single read FInternalWidth write SetInternalWidth; + /// Internal height + property InternalHeight: Single read FInternalHeight write SetInternalHeight; + /// Internal PlaceOffset + property InternalPlaceOffset: TPosition read FInternalPlaceOffset write SetInternalPlaceOffset; + // Local width of list item inside its designated area. + property Width: Single read FWidth write SetWidth; + // Local height of list item inside its designated area. + property Height: Single read FHeight write SetHeight; + /// Horizontal alignment of Appearance Object inside its designated area. + property Align: TListItemAlign read FAlign write SetAlign; + /// Vertical alignment of Appearance Object inside its designated area. + property VertAlign: TListItemAlign read FVertAlign write SetVertAlign; + /// Offset from aligned location for placement control + property PlaceOffset: TPosition read FPlaceOffset write SetPlaceOffset; + /// Opacity of this Appearance Object + property Opacity: Single read FOpacity write SetOpacity; + end; + + TTextShadowOptions = class(TPersistent) + public const + DefaultEnabled = True; + DefaultColor = TAlphaColorRec.Null; + private + [Weak] FOwner: TPersistent; + FEnabled: Boolean; + FColor: TAlphaColor; + FOnChanged: TNotifyEvent; + procedure SetColor(const Value: TAlphaColor); + procedure SetEnabled(const Value: Boolean); + protected + function GetOwner: TPersistent; override; + procedure AssignTo(Dest: TPersistent); override; + procedure Changed; virtual; + public + constructor Create(AOwner: TPersistent); + destructor Destroy; override; + function Equals(Obj: TObject): Boolean; override; + property OnChanged: TNotifyEvent read FOnChanged write FOnChanged; + published + property Color: TAlphaColor read FColor write SetColor default DefaultColor; + property Enabled: Boolean read FEnabled write SetEnabled default DefaultEnabled; + end; + + /// Text object appearance: main item text or detail text + TCustomTextObjectAppearance = class(TCommonObjectAppearance) + private + FFont: TFont; + FFontDirty: Boolean; + FTextLayout: TTextLayout; + + FTextAlign: TTextAlign; + FTextVertAlign: TTextAlign; + FWordWrap: Boolean; + + FTextColor: TAlphaColor; + FTextShadow: TTextShadowOptions; + FTrimming: TTextTrimming; + FIsDetailText: Boolean; + + procedure FontChanged(Sender: TObject); + procedure TextShadowChanged(Sender: TObject); + + procedure SetTextAlign(const Value: TTextAlign); + procedure SetTextVertAlign(const Value: TTextAlign); + procedure SetWordWrap(const Value: Boolean); + procedure SetTextColor(const Value: TAlphaColor); + procedure SetTrimming(const Value: TTextTrimming); + procedure SetFont(const Value: TFont); + function GetDefaultValues: TCustomTextObjectAppearance; + procedure SetIsDetailText(const Value: Boolean); + procedure SetTextShadow(const Value: TTextShadowOptions); + protected + procedure AssignTo(ADest: TPersistent); override; + function CreateDefaultValues: TObjectAppearance; override; + + function IsFontStored: Boolean; + function IsTextAlignStored: Boolean; + function IsTextVertAlignStored: Boolean; + function IsWordWrapStored: Boolean; + function IsDetailTextStored: Boolean; + function IsTextColorStored: Boolean; + function IsTextShadowStored: Boolean; + function IsOpacityStored: Boolean; + function IsTrimmingStored: Boolean; + public + constructor Create; override; + destructor Destroy; override; + procedure CreateObject(const AListViewItem: TListViewItem); override; + procedure ResetObject(const AListViewItem: TListViewItem); override; + /// Text font + property Font: TFont read FFont write SetFont; + /// Horizontal text alignment inside local item rectangle + property TextAlign: TTextAlign read FTextAlign write SetTextAlign; + /// Vertical text alignment inside local item rectangle + property TextVertAlign: TTextAlign read FTextVertAlign write SetTextVertAlign; + /// Word wrap + property WordWrap: Boolean read FWordWrap write SetWordWrap; + /// Text color + property TextColor: TAlphaColor read FTextColor write SetTextColor; + /// Shadow text color + property TextShadow: TTextShadowOptions read FTextShadow write SetTextShadow; + /// Text trimming + property Trimming: TTextTrimming read FTrimming write SetTrimming; + /// Is this regular or detail text + property IsDetailText: Boolean read FIsDetailText write SetIsDetailText; + /// Default appearance + property DefaultValues: TCustomTextObjectAppearance read GetDefaultValues; + end; + + /// Published text object appearance + TTextObjectAppearance = class(TCustomTextObjectAppearance) + published + property Font stored IsFontStored nodefault; + property TextAlign stored IsTextAlignStored nodefault; + property TextVertAlign stored IsTextVertAlignStored nodefault; + property WordWrap stored IsWordWrapStored nodefault; + property TextShadow stored IsTextShadowStored nodefault; + property TextColor stored IsTextColorStored nodefault; + property Trimming stored IsTrimmingStored nodefault; + // Common + property Width stored IsWidthStored nodefault; + property Height stored IsHeightStored nodefault; + property Align stored IsAlignStored nodefault; + property VertAlign stored IsVertAlignStored nodefault; + property Visible stored IsVisibleStored nodefault; + property PlaceOffset stored IsPlaceOffsetStored nodefault; + property Opacity stored IsOpacityStored nodefault; + end; + + /// Image object appearance, e.g. item bitmap + TCustomImageObjectAppearance = class(TCommonObjectAppearance) + strict private var + FScalingMode: TImageScalingMode; + procedure SetScalingMode(const Value: TImageScalingMode); + private + function GetDefaultValues: TCustomImageObjectAppearance; + protected + procedure AssignTo(ADest: TPersistent); override; + function CreateDefaultValues: TObjectAppearance; override; + function IsOpacityStored: Boolean; + function IsScalingModeStored: Boolean; + public + constructor Create; override; + procedure CreateObject(const AListViewItem: TListViewItem); override; + procedure ResetObject(const AListViewItem: TListViewItem); override; + property ScalingMode: TImageScalingMode read FScalingMode write SetScalingMode; + property DefaultValues: TCustomImageObjectAppearance read GetDefaultValues; + end; + + /// Published image object appearance + TImageObjectAppearance = class(TCustomImageObjectAppearance) + published + property ScalingMode stored IsScalingModeStored nodefault; + // Common + property Width stored IsWidthStored nodefault; + property Height stored IsHeightStored nodefault; + property Align stored IsAlignStored nodefault; + property VertAlign stored IsVertAlignStored nodefault; + property Visible stored IsVisibleStored nodefault; + property PlaceOffset stored IsPlaceOffsetStored nodefault; + property Opacity stored IsOpacityStored nodefault; + end; + + /// Accessory object appearance: more, disclosure, checkmark + TCustomAccessoryObjectAppearance = class(TCommonObjectAppearance) + strict private var + FAccessoryType: TAccessoryType; + procedure SetAccessoryType(const Value: TAccessoryType); + private + function GetDefaultValues: TCustomAccessoryObjectAppearance; + protected + procedure AssignTo(ADest: TPersistent); override; + function CreateDefaultValues: TObjectAppearance; override; + function IsAccessoryTypeStored: Boolean; + public + constructor Create; override; + procedure CreateObject(const AListViewItem: TListViewItem); override; + procedure ResetObject(const AListViewItem: TListViewItem); override; + property AccessoryType: TAccessoryType read FAccessoryType write SetAccessoryType; + property DefaultValues: TCustomAccessoryObjectAppearance read GetDefaultValues; + end; + + /// Published accessory object appearance + TAccessoryObjectAppearance = class(TCustomAccessoryObjectAppearance) + published + property AccessoryType stored IsAccessoryTypeStored nodefault; + // Common + property Width stored IsWidthStored nodefault; + property Height stored IsHeightStored nodefault; + property Align stored IsAlignStored nodefault; + property VertAlign stored IsVertAlignStored nodefault; + property Visible stored IsVisibleStored nodefault; + property PlaceOffset stored IsPlaceOffsetStored nodefault; + property Opacity stored IsOpacityStored nodefault; + end; + + /// Text button object appearance: text button that can be embedded in TListItem + TCustomTextButtonObjectAppearance = class(TCommonObjectAppearance) + strict private var + FButtonType: TTextButtonType; + procedure SetButtonType(const Value: TTextButtonType); + private + FOnControlClick: TNotifyEvent; + FOnControlChange: TNotifyEvent; + FText: string; + FFont: TFont; + FTrimming: TTextTrimming; + FTextVertAlign: TTextAlign; + FTextAlign: TTextAlign; + FWordWrap: Boolean; + FTextColor: TAlphaColor; + FTintColor: TAlphaColor; + FPressedTextColor: TAlphaColor; + FTextShadowColor: TAlphaColor; + FEnabled: Boolean; + FHasButtonText: Boolean; + function GetDefaultValues: TCustomTextButtonObjectAppearance; + procedure SetText(const Value: string); + procedure SetFont(const Value: TFont); + procedure SetTextAlign(const Value: TTextAlign); + procedure SetTextVertAlign(const Value: TTextAlign); + procedure SetTrimming(const Value: TTextTrimming); + procedure SetWordWrap(const Value: Boolean); + procedure FontChanged(Sender: TObject); + procedure SetPressedTextColor(const Value: TAlphaColor); + procedure SetTextColor(const Value: TAlphaColor); + procedure SetTintColor(const Value: TAlphaColor); + procedure SetTextShadowColor(const Value: TAlphaColor); + procedure SetEnabled(const Value: Boolean); + protected + procedure AssignTo(ADest: TPersistent); override; + function CreateDefaultValues: TObjectAppearance; override; + function IsButtonTypeStored: Boolean; + function IsTextStored: Boolean; + function IsTrimmingStored: Boolean; + function IsFontStored: Boolean; + function IsTextAlignStored: Boolean; + function IsTextColorStored: Boolean; + function IsTintColorStored: Boolean; + function IsPressedTextColorStored: Boolean; + function IsTextShadowColorStored: Boolean; + function IsTextVertAlignStored: Boolean; + function IsWordWrapStored: Boolean; + function IsEnabledStored: Boolean; + procedure DoControlClick(Sender: TObject); virtual; + procedure DoControlChange(Sender: TObject); virtual; + public + constructor Create; override; + destructor Destroy; override; + procedure CreateObject(const AListViewItem: TListViewItem); override; + procedure ResetObject(const AListViewItem: TListViewItem); override; + property ButtonType: TTextButtonType read FButtonType write SetButtonType; + property Enabled: Boolean read FEnabled write SetEnabled; + property Text: string read FText write SetText; + property Trimming: TTextTrimming read FTrimming write SetTrimming; + property Font: TFont read FFont write SetFont; + property TextColor: TAlphaColor read FTextColor write SetTextColor; + property TintColor: TAlphaColor read FTintColor write SetTintColor; + property PressedTextColor: TAlphaColor read FPressedTextColor write SetPressedTextColor; + property TextShadowColor: TAlphaColor read FTextShadowColor write SetTextShadowColor; + // Horizontal text alignment inside local item rectangle. + property TextAlign: TTextAlign read FTextAlign write SetTextAlign; + // Vertical text alignment inside local item rectangle. + property TextVertAlign: TTextAlign read FTextVertAlign write SetTextVertAlign; + property WordWrap: Boolean read FWordWrap write SetWordWrap; + property DefaultValues: TCustomTextButtonObjectAppearance read GetDefaultValues; + property OnControlClick: TNotifyEvent read FOnControlClick write FOnControlClick; + property OnControlChange: TNotifyEvent read FOnControlChange write FOnControlChange; + end; + + /// Text button object appearance: text button that can be embedded in TListItem + TTextButtonObjectAppearance = class(TCustomTextButtonObjectAppearance) + published + property ButtonType stored IsButtonTypeStored nodefault; + property Trimming stored IsTrimmingStored nodefault; + property Font stored IsFontStored nodefault; + property Enabled stored IsEnabledStored nodefault; + property TextAlign stored IsTextAlignStored nodefault; + property TextVertAlign stored IsTextVertAlignStored nodefault; + property WordWrap stored IsWordWrapStored nodefault; + property TextColor stored IsTextColorStored nodefault; + property TintColor stored IsTintColorStored nodefault; + property PressedTextColor stored IsPressedTextColorStored nodefault; + property TextShadowColor stored IsTextShadowColorStored nodefault; + // Common + property Width stored IsWidthStored nodefault; + property Height stored IsHeightStored nodefault; + // property Height stored IsHeightStored nodefault; // Not adjustable + property Align stored IsAlignStored nodefault; + property VertAlign stored IsVertAlignStored nodefault; + property Visible stored IsVisibleStored nodefault; + property PlaceOffset stored IsPlaceOffsetStored nodefault; + property Opacity stored IsOpacityStored nodefault; + property Text stored IsTextStored nodefault; + end; + + /// Glyph button appearance: checkmark, add, delete + TCustomGlyphButtonObjectAppearance = class(TCommonObjectAppearance) + strict private var + FButtonType: TGlyphButtonType; + FEnabled: Boolean; + procedure SetButtonType(const Value: TGlyphButtonType); + private + FOnControlClick: TNotifyEvent; + FOnControlChange: TNotifyEvent; + FClickOnSelect: Boolean; + function GetDefaultValues: TCustomGlyphButtonObjectAppearance; + procedure SetClickOnSelect(const AValue: Boolean); + procedure SetEnabled(const Value: Boolean); + protected + procedure AssignTo(ADest: TPersistent); override; + function CreateDefaultValues: TObjectAppearance; override; + function IsButtonTypeStored: Boolean; + function IsEnabledStored: Boolean; + function IsClickOnSelectStored: Boolean; + procedure DoControlClick(Sender: TObject); virtual; + procedure DoControlChange(Sender: TObject); virtual; + public + constructor Create; override; + procedure CreateObject(const AListViewItem: TListViewItem); override; + procedure ResetObject(const AListViewItem: TListViewItem); override; + property ButtonType: TGlyphButtonType read FButtonType write SetButtonType; + property Enabled: Boolean read FEnabled write SetEnabled; + property ClickOnSelect: Boolean read FClickOnSelect write SetClickOnSelect; + property DefaultValues: TCustomGlyphButtonObjectAppearance read GetDefaultValues; + property OnControlClick: TNotifyEvent read FOnControlClick write FOnControlClick; + property OnControlChange: TNotifyEvent read FOnControlChange write FOnControlChange; + end; + + /// Glyph button appearance: checkmark, add, delete + TGlyphButtonObjectAppearance = class(TCustomGlyphButtonObjectAppearance) + published + property ButtonType stored IsButtonTypeStored nodefault; + property Enabled stored IsEnabledStored nodefault; + property ClickOnSelect stored IsClickOnSelectStored nodefault; + // Common + property Width stored IsWidthStored nodefault; + property Height stored IsHeightStored nodefault; + property Align stored IsAlignStored nodefault; + property VertAlign stored IsVertAlignStored nodefault; + property Visible stored IsVisibleStored nodefault; + property PlaceOffset stored IsPlaceOffsetStored nodefault; + property Opacity stored IsOpacityStored nodefault; + end; + + TAppearanceObjects = class abstract (TPersistent) + public type + TControlEvent = procedure(const Sender: TObject; const AControl: TListItemSimpleControl) of object; + TCreatingObjectsEvent = procedure(const Sender: TObject; const AListViewItem: TListViewItem; var AHandled: Boolean) of object; + TCreateObjectsEvent = procedure(const Sender: TObject; const AListViewItem: TListViewItem) of object; + private const + cDefaultHeight = 44; + cDefaultHeaderHeight = 24; + strict private + [Weak] FOwnerControl: TControl; + FResources: IListItemStyleResources; + private + FOnChange: TNotifyEvent; + FOnChangeHeight: TNotifyEvent; + FOnButtonClick: TItemControlEvent; + FOnButtonChange: TItemControlEvent; + function GetHeight: Integer; virtual; + procedure SetHeight(Value: Integer); virtual; + procedure TakeOwnership(const NewOwner: TControl); + protected + procedure ItemPropertyChange(Sender: TObject); + procedure DoChange; virtual; + procedure DoChangeHeight; virtual; + procedure AssignTo(ADest: TPersistent); override; + procedure UpdateSizes(const FinalSize: TSizeF); virtual; + function DefaultHeight: Integer; virtual; + function GetPublishedObjects: TArray; virtual; + function GetObjects: TArray; virtual; + // For custom appearances to read/write TAppearanceListViewItem.Data + procedure SetObjectData(const AListViewItem: TListViewItem; const AIndex: string; const AValue: TValue; var AHandled: Boolean); virtual; + function StyleResourcesNeedUpdate: Boolean; + function GetStyleResources: TListItemStyleResources; + property OwnerControl: TControl read FOwnerControl; + public + constructor Create(const Owner: TControl); virtual; + /// Initialize view ("objects") of specified TListViewItem using objects of this Appearance. If + /// the view is already initialized, it will be fully updated. + procedure ResetObjects(const AListViewItem: TListViewItem; const FinalSize: TSizeF); virtual; + property Height: Integer read GetHeight write SetHeight; + procedure BeginUpdate; + procedure EndUpdate; + property OnChange: TNotifyEvent read FOnChange write FOnChange; + property OnChangeHeight: TNotifyEvent read FOnChangeHeight write FOnChangeHeight; + property Objects: TArray read GetObjects; + property PublishedObjects: TArray read GetPublishedObjects; + property OnButtonClick: TItemControlEvent write FOnButtonClick; + property OnButtonChange: TItemControlEvent write FOnButtonChange; + end; + + // Includes Text, Detail, etc. + TItemAppearanceObjects = class(TAppearanceObjects) + private const + cDefaultHeight = TAppearanceObjects.cDefaultHeight; + strict private + FText: TTextObjectAppearance; + FDetail: TTextObjectAppearance; + FImage: TImageObjectAppearance; + FAccessory: TAccessoryObjectAppearance; + FTextButton: TTextButtonObjectAppearance; + FGlyphButton: TGlyphButtonObjectAppearance; + FHeight: Integer; + FObjects: TArray; + FPublishedObjects: TArray; + procedure SetAccessoryElement(const Value: TAccessoryObjectAppearance); + procedure SetTextButtonElement(const Value: TTextButtonObjectAppearance); + procedure SetGlyphButtonElement(const Value: TGlyphButtonObjectAppearance); + procedure SetImageElement(const Value: TImageObjectAppearance); + procedure SetTextElement(const Value: TTextObjectAppearance); + procedure SetDetailElement(const Value: TTextObjectAppearance); + protected + procedure AssignTo(ADest: TPersistent); override; + function GetHeight: Integer; override; + procedure SetHeight(Value: Integer); override; + function DefaultHeight: Integer; override; + function GetPublishedObjects: TArray; override; + procedure AddObject(const AObjectAppearance: TCommonObjectAppearance; APublished: Boolean); + /// Search Objects and PublishedObjects for an object with the same name as that of given + /// AObjectAppearance and replace them with it. If not found, append. + function UpdateObject(const AObjectAppearance: TCommonObjectAppearance; APublished: Boolean): + TCommonObjectAppearance; + /// Remove given AObjectAppearance from Objects and PublishedObjects + procedure RemoveObject(const AObjectAppearance: TCommonObjectAppearance); + function GetObjects: TArray; override; + public + constructor Create(const Owner: TControl); overload; override; + destructor Destroy; override; + property Text: TTextObjectAppearance read FText write SetTextElement; + property Detail: TTextObjectAppearance read FDetail write SetDetailElement; + property Image: TImageObjectAppearance read FImage write SetImageElement; + property Accessory: TAccessoryObjectAppearance read FAccessory write SetAccessoryElement; + property TextButton: TTextButtonObjectAppearance read FTextButton write SetTextButtonElement; + property GlyphButton: TGlyphButtonObjectAppearance read FGlyphButton write SetGlyphButtonElement; + end; + TItemAppearanceObjectsClass = class of TItemAppearanceObjects; +{$ENDREGION} + + TRegisterAppearanceOption = (Footer, Header, Item, ItemEdit, DefaultFooter, DefaultHeader, DefaultItem, DefaultItemEdit); + TRegisterAppearanceOptions = set of TRegisterAppearanceOption; + TRegisteredAppearance = record + Name: string; + Value: TItemAppearanceObjectsClass; + UnitName: string; + Options: TRegisterAppearanceOptions; + end; + + ///Represents properties of Item Appearance that define geometric properties of the entire ListViewItem, + /// specify AppearanceClass and AppearanceClassName that define Item Appearance Objects that comprise item's view. + /// + TItemAppearanceProperties = class(TInterfacedPersistent, IDesignablePersistent, ISpriggedPersistent) + public type + TControlEvent = TAppearanceObjects.TControlEvent; + TItemAppearanceObjectsClass = TItemAppearanceObjectsClass; + TAppearancePropertiesEvent = procedure(const Sender: TItemAppearanceProperties) of object; + public const + cDefaultHeight = TAppearanceObjects.cDefaultHeight; + strict private + FOwnerControl: TControl; + FName: string; + FAppearanceType: TAppearanceType; + FAppearanceCache: TDictionary; + FAppearance: TItemAppearanceObjects; + FAppearanceClass: TItemAppearanceObjectsClass; + FPurpose: TListItemPurpose; + FPropertiesOwner: IPublishedAppearanceOwner; + FOnChange: TNotifyEvent; + FOnDestroy: TNotifyEvent; + FSprig: TPersistent; + FShim: IPersistentShim; + + procedure SetName(const Value: string); + procedure SetObjects(const Value: TItemAppearanceObjects); + procedure PropertiesChange(Sender: TObject); + procedure PropertiesChangeHeight(Sender: TObject); + function GetHeight: Integer; + procedure SetHeight(AValue: Integer); + procedure SetAppearanceClass(const Value: TItemAppearanceObjectsClass); + function GetAppearanceClassName: string; + procedure SetAppearanceClassName(const Value: string); + function GetActive: Boolean; + function PropertiesOwner: IPublishedAppearanceOwner; + + { IDesignableAppearance } + function GetBoundsRect: TRect; + function GetDesignParent: TPersistent; + + procedure BindShim(AShim: IPersistentShim); + procedure UnbindShim; + procedure IDesignablePersistent.Bind = BindShim; + procedure IDesignablePersistent.Unbind = UnbindShim; + function BeingDesigned: Boolean; + + procedure SetSprig(const APersistent: TPersistent); + function GetSprig: TPersistent; + protected + /// Notify PropertiesOwner of change in its Item Appearance Properties and invoke + /// FOnChange event if it is assigned. + procedure DoChange; virtual; + /// Notify PropertiesOwner of item height change + procedure DoChangeHeight; virtual; + /// Notify PropertiesOwner that the objects that comprise the appearance represented by these + /// properties have been changed + procedure DoChangeObjects; virtual; + /// True if the Height property is user modified + function IsHeightStored: Boolean; + public + constructor Create(const Owner: TControl; AType: TAppearanceType); + destructor Destroy; override; + /// Owner control for property editors. The host TListView. + property Owner: TControl read FOwnerControl; + /// Item purpose: None (regular), Header, Footer. + property Purpose: TListItemPurpose read FPurpose; + /// The class that defines objects that comprise item appearance. E.g. TListItemAppearance. See also + /// AppearanceClassName. + property AppearanceClass: TItemAppearanceObjectsClass read FAppearanceClass write SetAppearanceClass; + /// AppearanceClass name. The class with given name will be searched in TAppearancesRegistry + /// and if found, used to intialize appearance. + property AppearanceClassName: string read GetAppearanceClassName write SetAppearanceClassName; + /// Indicates that this appearance is currently active. EditMode appearance will be inactive in regular + /// mode and active when ListView is in Edit Mode. The opposite is true for regular Item Appearances. + property Active: Boolean read GetActive; + /// Display name for this Item Appearance + property Name: string read FName write SetName stored False; + /// Specifies Item Height. + property Height: Integer read GetHeight write SetHeight; + /// Appearance Item Objects that comprise this Item Appearance, e.g. 'Text', 'Image', etc + property Objects: TItemAppearanceObjects read FAppearance write SetObjects; // Objects is published name of Appearance + /// Appearance type: (Item, ItemEdit, Header, Footer) + property AppearanceType: TAppearanceType read FAppearanceType; + /// Event to be invoked when these change + property OnChange: TNotifyEvent read FOnChange write FOnChange; + /// Event to be invoked when is instance is being destroyed + property OnDestroy: TNotifyEvent read FOnDestroy write FOnDestroy; + end; + + // Does not create objects + TEmptyItemObjects = class(TItemAppearanceObjects) + private const + cDefaultHeight = TAppearanceObjects.cDefaultHeight; + private var + FHeight: Integer; + protected + procedure SetHeight(Value: Integer); override; + function GetHeight: Integer; override; + function DefaultHeight: Integer; override; + public + constructor Create(const Owner: TControl); override; + end; + + // Disables all services for managing TAppearanceListViewItem.Objects, such as creating and resizing + TNullItemObjects = class(TEmptyItemObjects) + end; + + // Set some defaults on Text, Detail, etc. + TCustomItemObjects = class(TItemAppearanceObjects) + public const + cDefaultHeight = TAppearanceObjects.cDefaultHeight; + cDefaultButtonHeight = 31; + cDefaultTextButtonWidth = 64; + cDefaultImageWidth = 29; + cDefaultImageHeight = 29; + cDefaultImageTextPlaceOffsetX = 10; + cDefaultGlyphPlaceOffsetX = -6; + protected + procedure UpdateSizes(const FinalSize: TSizeF); override; + procedure SetInternalSize(const AGlyphButton: TGlyphButtonObjectAppearance; + AStyleResources: TListItemStyleResources); overload; + procedure SetInternalSize(const AAccessory: TAccessoryObjectAppearance; + AStyleResources: TListItemStyleResources); overload; + function DefaultHeight: Integer; override; + public + constructor Create(const Owner: TControl); override; + property Text; + property Detail; + property Image; + property Accessory; + property TextButton; + property GlyphButton; + end; + + // Base class for item object presets + TPresetItemObjects = class(TCustomItemObjects) + public type + TGroupClass = class of TPresetItemObjects; + protected + // Identify the ancestor class that supports resetobjects + function GetGroupClass: TGroupClass; virtual; + // Indicate if this is an itemedit appearance + function GetIsItemEdit: Boolean; virtual; + property IsItemEdit: Boolean read GetIsItemEdit; + property GroupClass: TGroupClass read GetGroupClass; + public + procedure ResetObjects(const AListViewItem: TListViewItem; const FinalSize: TSizeF); override; + end; + + /// Represents appearance in the object inspector: appearance names for all item purposes and + /// item heights + TPublishedAppearance = class(TPersistent) + strict private + FOwnerComponent: TComponent; + FPropertiesOwner: IPublishedAppearanceOwner; + + function GetFooterAppearance: string; + function GetFooterHeight: Integer; + function GetHeaderAppearance: string; + function GetHeaderHeight: Integer; + function GetItemAppearance: string; + function GetItemEditAppearance: string; + function GetItemHeight: Integer; + function GetItemEditHeight: Integer; + procedure SetFooterAppearance(const Value: string); + procedure SetFooterHeight(const Value: Integer); + procedure SetHeaderAppearance(const Value: string); + procedure SetHeaderHeight(const Value: Integer); + procedure SetItemAppearance(const Value: string); + procedure SetItemEditAppearance(const Value: string); + procedure SetItemHeight(const Value: Integer); + procedure SetItemEditHeight(const Value: Integer); + function IsFooterHeightStored: Boolean; + function IsHeaderHeightStored: Boolean; + function IsItemEditHeightStored: Boolean; + function IsItemHeightStored: Boolean; + published + constructor Create(const AOwner: TComponent); + property Owner: TComponent read FOwnerComponent; + property ItemHeight: Integer read GetItemHeight write SetItemHeight stored IsItemHeightStored nodefault; + property ItemEditHeight: Integer read GetItemEditHeight write SetItemEditHeight stored IsItemEditHeightStored nodefault; + property HeaderHeight: Integer read GetHeaderHeight write SetHeaderHeight stored IsHeaderHeightStored nodefault; + property FooterHeight: Integer read GetFooterHeight write SetFooterHeight stored IsFooterHeightStored nodefault; + property ItemAppearance: string read GetItemAppearance write SetItemAppearance stored False; + property ItemEditAppearance: string read GetItemEditAppearance write SetItemEditAppearance stored False; + property HeaderAppearance: string read GetHeaderAppearance write SetHeaderAppearance stored False; + property FooterAppearance: string read GetFooterAppearance write SetFooterAppearance stored False; + end; + + /// Represents appearance items (collections of objects comprising appearances) + /// in the object inspector + TPublishedObjects = class(TPersistent) + private + FOwner: IPublishedAppearanceOwner; + + function GetFooterObjects: TItemAppearanceObjects; + function GetHeaderObjects: TItemAppearanceObjects; + function GetItemEditObjects: TItemAppearanceObjects; + function GetItemObjects: TItemAppearanceObjects; + procedure SetFooterObjects(const Value: TItemAppearanceObjects); + procedure SetHeaderObjects(const Value: TItemAppearanceObjects); + procedure SetItemEditObjects(const Value: TItemAppearanceObjects); + procedure SetItemObjects(const Value: TItemAppearanceObjects); + published + constructor Create(const AOwner: IPublishedAppearanceOwner); + property ItemObjects: TItemAppearanceObjects read GetItemObjects write SetItemObjects; + property ItemEditObjects: TItemAppearanceObjects read GetItemEditObjects write SetItemEditObjects; + property HeaderObjects: TItemAppearanceObjects read GetHeaderObjects write SetHeaderObjects; + property FooterObjects: TItemAppearanceObjects read GetFooterObjects write SetFooterObjects; + end; + + /// Registered appearance descriptor used in TAppearancesRegistry + TRegisterAppearanceValue = record + /// Appearance name + Name: string; + /// Appearance unit name + UnitName: string; + /// Appearance options: Footer, Header, Item, ItemEdit, DefaultFooter, + /// DefaultHeader, DefaultItem, DefaultItemEdit + Options: TRegisterAppearanceOptions; + constructor Create(const AName: string; AOptions: TRegisterAppearanceOptions; const AUnitName: string); + end; + + /// Global registry of Item Appearances + TAppearancesRegistry = class + private class var + FFactories: TDictionary; + public const + cRegisterDefault = [TRegisterAppearanceOption.DefaultFooter, TRegisterAppearanceOption.DefaultHeader, + TRegisterAppearanceOption.DefaultItem, TRegisterAppearanceOption.DefaultItemEdit]; + cRegisterAll = [ + TRegisterAppearanceOption.Footer, TRegisterAppearanceOption.Header, TRegisterAppearanceOption.Item, + TRegisterAppearanceOption.ItemEdit, TRegisterAppearanceOption.DefaultFooter, + TRegisterAppearanceOption.DefaultHeader, TRegisterAppearanceOption.DefaultItem, + TRegisterAppearanceOption.DefaultItemEdit]; + class constructor Create; + class destructor Destroy; + /// Register appearances from an array + class procedure RegisterAppearances(AFactories: TArray; ADisplayNames: TArray; + AOptions: TRegisterAppearanceOptions = [TRegisterAppearanceOption.Item]; const AUnitName: string = ''); overload; + /// Register a single appearance + class procedure RegisterAppearance(const AFactory: TItemAppearanceObjectsClass; const ADisplayName: string; + AOptions: TRegisterAppearanceOptions = [TRegisterAppearanceOption.Item]; const AUnitName: string = ''); overload; + /// Unregister an item appearance + class procedure UnregisterAppearance(const AFactory: TItemAppearanceObjectsClass); overload; + /// Unregister appearances from an array + class procedure UnregisterAppearances(AFactories: TArray); overload; + /// Get registered appearances, filtered by kind. See TRegisterAppearanceOption + class function GetRegisteredAppearances(AFilter: TRegisterAppearanceOptions = []): TArray; + /// Find TItemAppearanceObjectsClass by option. + /// See TRegisterAppearanceOption, TItemAppearanceObjectsClass + class function FindItemAppearanceObjectsClassByOption(AOption: TRegisterAppearanceOption): TItemAppearanceObjectsClass; + end; + +//== INTERFACE END: FMX.ListView.Appearances +//================================================================================================== + +//================================================================================================== +//== INTERFACE START: FMX.ListView.DynamicAppearance (from FMX.ListView.DynamicAppearance.pas) +//================================================================================================== + + +type + TDynamicAppearance = class; + + /// + /// TAppearanceObjectItem is an item in TAppearanceObjectItemCollection with + /// AppearanceObjectName, AppearanceObjectClassName and the object itself (Appearance). + /// + TAppearanceObjectItem = class(TCollectionItem) + private const + FObjectAppearanceClassNames: array [0..4] of TClass = (TTextObjectAppearance, TImageObjectAppearance, + TTextButtonObjectAppearance, TGlyphButtonObjectAppearance, TAccessoryObjectAppearance); + private + [Weak] FOwner: TDynamicAppearance; + FAppearance: TCommonObjectAppearance; + FAppearanceClass: TClass; + FObjectName: string; + procedure SetAppearanceClass(Value: TClass); + procedure SetAppearance(Value: TCommonObjectAppearance); + + function GetObjectName: string; + procedure SetObjectName(Value: string); + + function GetClassName: string; + procedure SetClassName(Value: string); + public + procedure Assign(Source: TPersistent); override; + constructor Create(Collection: TCollection); override; + destructor Destroy; override; + published + ///Name of this appearance object, e.g. 'text' + property AppearanceObjectName: string read GetObjectName write SetObjectName nodefault; + ///Class name of this appearance object, e.g. TTextObjectAppearance + property AppearanceClassName: string read GetClassName write SetClassName nodefault; + ///Object appearance itself + property Appearance: TCommonObjectAppearance read FAppearance write SetAppearance; + end; + + ///Collection of Items representing Appearance Objects that comprise a dynamic appearance. + TAppearanceObjectItemCollection = class(TOwnedCollection) + private + [Weak] FDynamicAppearance: TDynamicAppearance; + protected + procedure Notify(Item: TCollectionItem; Action: TCollectionNotification); override; + { Design } + function GetAttrCount: Integer; override; + function GetAttr(Index: Integer): string; override; + function GetItemAttr(Index, ItemIndex: Integer): string; override; + public + ///Create new TAppearanceObjectItemCollection for specified DynamicAppearance + constructor Create(Owner: TComponent; DynamicAppearance: TDynamicAppearance); reintroduce; + procedure BeginUpdate; override; + procedure EndUpdate; override; + end; + + ///User-defined, designable ListView Item appearance. This class is one of the items + ///that can be selected in the Object Inspector as an item appearance for Header, Item and Footer. + /// + ///Unlike static appearances, the objects in this one are stored in a collection. The collection can be + ///filled with any combination of objects, which can then be edited in the designer to create fully + ///customized item look. + TDynamicAppearance = class(TPresetItemObjects) + strict private + FObjectsCollection: TCollection; + protected + function GetGroupClass: TPresetItemObjects.TGroupClass; override; + + function GetObjectsCollection: TCollection; + procedure SetObjectsCollection(Value: TCollection); + + ///Create new Object Apperance specified by AppearanceClass and Name and initialize Item.Appearance + ///with it. + procedure CreateObjectAppearance(const AppearanceClass: TClass; const Name: string; const Item: TAppearanceObjectItem); + ///Initialize DataMember for given ObjectAppearance. The expression is Data[ObjectAppearance.Name]. + procedure InitDataMember(const ObjectAppearance: TCommonObjectAppearance); + ///Invoked when an appearance object is modified + procedure ObjectPropertyChange(Sender: TObject); + ///Invoked when an appearance object is renamed + procedure ObjectRenamed(const Sender: TCommonObjectAppearance; const OldName: string); + ///Propagate change notification up. Used by ObjectRemoving, ObjectAdded. + procedure ItemAppearanceChange; + ///Called when item is removed from the ObjectsCollection + procedure ObjectRemoving(const Value: TCommonObjectAppearance); + ///Called when item is added to the ObjectsCollection + procedure ObjectAdded(const Value: TCommonObjectAppearance); + public + constructor Create(const Owner: TControl); override; + destructor Destroy; override; + published + ///Collection of Object Appearances that comprise this Item Appearance + property ObjectsCollection: TCollection read GetObjectsCollection write SetObjectsCollection; + end; + +//== INTERFACE END: FMX.ListView.DynamicAppearance +//================================================================================================== + +//================================================================================================== +//== INTERFACE START: FMX.ListView (from FMX.ListView.pas) +//================================================================================================== + +{$SCOPEDENUMS ON} + + +type + /// List view class that provides members that subclasses may use to + /// communicate with a list view adapter that contains the actual items of the + /// list view. + TAdapterListView = class(TStyledControl) + strict private + FAdapter: IListViewAdapter; + FHeightSumsNeedUpdate: Boolean; + + procedure ItemsMayChange(Sender: TObject); + procedure ItemsCouldHaveChanged(Sender: TObject); + procedure ItemsChange(Sender: TObject); + procedure ItemsResize(Sender: TObject); + procedure ItemsInvalidate(Sender: TObject); + procedure ResetView(Sender: TObject); + protected + /// Called after the adapter had been set, SetAdapter + procedure DoAdapterSet; virtual; + /// Set IListViewAdapter + procedure SetAdapter(Adapter: IListViewAdapter); + /// Request update of item heights + procedure InvalidateHeights; + /// Handler of IListViewAdapter.OnItemsMayChange + procedure DoItemsMayChange; virtual; + /// Handler of + /// IListViewAdapter.OnItemsCouldHaveChanged + procedure DoItemsCouldHaveChanged; virtual; + /// Handler of IListViewAdapter.OnItemsResize + procedure DoItemsResize; virtual; + /// Handler of + /// IListViewAdapter.OnItemsInvalidate + procedure DoItemsInvalidate; virtual; + /// Handler of + /// IListViewAdapter.OnResetView + procedure DoResetView(const Sender: TListItem); virtual; + /// True if update of item height cache is required. Set by InvalidateHeights + property HeightSumsNeedUpdate: Boolean read FHeightSumsNeedUpdate write FHeightSumsNeedUpdate; + public + /// IListViewAdapter providing contents of this TAdapterListView + property Adapter: IListViewAdapter read FAdapter write SetAdapter; + end; + + /// The minimal ListView that's actually a real UI control. It implements all scrolling and drawing + /// functionality. It needs a valid IListViewAdapter to provide item views; + /// see TAdapterListView.Adapter + /// + /// + /// Implements: + /// ISearchResponder enables setting a filter predicate + /// IListItemStyleResources access to style resources + /// IListViewController mediator protocol between TListView and TListItem + /// IGlyph interface to TImageList + /// IMessageSendingCompatible TMessageSender object for FMX.Presentation compatibility + /// + TListViewBase = class(TAdapterListView, ISearchResponder, IListItemStyleResources, IListViewController, IGlyph, + IMessageSendingCompatible, IControlTypeSupportable) + private const + ChangeRepaintedIncidentDelay = 0.1; // seconds + PhysicsProcessingInterval = 8; // 8 ms for ~120 frames per second + RecurrentTimerInterval = 16; // 16 ms for ~60 frames per second + AutoTapScrollingSpeed = 8; // pixels per frame + AutoTapMaxScrollingTime = 1; // seconds + TapSelectWaitTime = 0.25; // seconds + SelectionFadeInTime = 0.125; // seconds + SelectionFadeOutTime = 0.25; // seconds + MinScrollThreshold = 10; + MinSwypeThreshold = 40; + + DefaultDeleteButtonWidth = 72; + + ItemSeparatorTop = 1; + ItemSeparatorBottom = 2; + + EditModeSelectionAlpha = 0.25; // how bright the checked items are in editmode + + EditModeAnimationDuration = 0.1; // in seconds + DeleteModeAnimationDuration = 0.15; // in seconds + DefaultDeleteButtonText = 'Delete'; + + PullRefreshIndicatorStrengthStart = 16; + PullRefreshIndicatorMaxSteps = 12; + + DefaultLeftMargin = 10; + DefaultRightMargin = 11; + + public type + /// Edit mode change event + /// event source (TListViewBase) + /// set to True if event was handled + THandleChangeEvent = procedure(const Sender: TObject; var AHandled: Boolean) of object; + /// Generic TListItem event; used for OnListItemClick, OnItemChange + /// event source (TListViewBase) + /// item being acted upon + TListItemEvent = procedure(const Sender: TObject; const AItem: TListItem) of object; + /// OnItemClickEx event + /// event source + /// index of item + /// click position in item local coordinates + /// TListItemDrawable that received the click + TListItemClickEventEx = procedure(const Sender: TObject; ItemIndex: Integer; const LocalClickPos: TPointF; + const ItemObject: TListItemDrawable) of object; + /// OnUpdateItemView event + TUpdateItemViewEvent = TListItemEvent; + /// OnUpdatingItemView event + TUpdatingItemViewEvent = procedure(const Sender: TObject; const AItem: TListItem; var AHandled: Boolean) of object; + /// OnDeletingItem event + TDeletingItemEvent = procedure(Sender: TObject; AIndex: Integer; var ACanDelete: Boolean) of object; + /// OnDeleteItem event + TDeleteItemEvent = procedure(Sender: TObject; AIndex: Integer) of object; + /// OnDeleteChangeVisible event + TDeleteChangeVisibilityEvent = procedure(Sender: TObject; AValue: Boolean) of object; + + private type + TItemHeightSums = TList; + + TDelayedIncident = (ChangeRepainted, Invalidate, SetItemIndex, ClickEvent); + + TDelayedIncidentEntry = record + Incident: TDelayedIncident; + Triggered: Boolean; + StartTime: Double; + TimeToWait: Double; + CustomData: NativeInt; + end; + + TDelayedIncidents = TList; + + TTransitionType = (None, EditMode, DeleteMode); + + TInternalDragMode = (None, Drag, Swype); + + TItemSelectionAlpha = record + StartTime: Double; + Alpha: Single; + StartAlpha: Single; + + class function Create(const StartTime: Double; const Alpha, StartAlpha: Single): TItemSelectionAlpha; static; inline; + end; + + TItemSelectionAlphas = TDictionary; + TPullRefreshAnimation = (NotPlaying, Playing, Finished); + TStateFlag = (NeedsRebuild, NeedsScrollingLimitsUpdate, Invalid, Painting, ResettingObjects, ScrollingActive, + ScrollingMouseTouch, NeedsScrollBarDisplay); + TStateFlags = set of TStateFlag; + TEstimatedHeights = record + Item: Single; + Header: Single; + Footer: Single; + end; + + private + FTimerService: IFMXTimerService; + FSystemInformationService: IFMXSystemInformationService; + FListingService: IFMXListingService; + FStateFlags: TStateFlags; + FRecurrentTimerHandle: TFmxHandle; + FDelayedIncidents: TDelayedIncidents; + FSelectionAlphas: TItemSelectionAlphas; + FItemIndex: Integer; + FAniCalc: TAniCalculations; + FScrollViewPos: Single; + FBrush: TBrush; + FStroke: TStrokeBrush; + FMouseDownAt: TPointF; + FMouseClickPrev: TPointF; + FMouseClickDelta: TPointF; + FMouseClicked: Boolean; + FMouseClickIndex: Integer; + FMouseEventIndex: Integer; + FItemSpaces: TBounds; + FMousePrevScrollPos: Single; + FClickEventItemIndex: Integer; + FClickEventMousePos: TPointF; + [Weak] FClickEventControl: TListItemDrawable; + FHeightSums: TItemHeightSums; + FMaxKnownHeight: Integer; + FSideSpace: Integer; + FScrollScale: Single; + FBackgroundStyleColor: TAlphaColor; + FSelectionStyleColor: TAlphaColor; + FItemStyleFillColor: TAlphaColor; + FItemStyleFillAltColor: TAlphaColor; + FItemStyleFrameColor: TAlphaColor; + [Weak] FSelectionStyleImage: TStyleObject; + [Weak] FHeaderStyleImage: TStyleObject; + FTouchAnimationObject: ITouchAnimationObject; + FScrollBar: TScrollBar; + FTransparent: Boolean; + FAllowSelection: Boolean; + FAlternatingColors: Boolean; + FTapSelectItemIndex: Integer; + FTapSelectNewIndexApplied: Integer; + FTapSelectStartTime: Double; + FShowSelection: Boolean; + FOnChange: TNotifyEvent; + FOnChangeRepainted: TNotifyEvent; + FOnItemsChange: TNotifyEvent; + FOnScrollViewChange: TNotifyEvent; + FOnSearchChange: TNotifyEvent; + FOnFilter: TFilterEvent; + FAutoTapScroll: Boolean; + FAutoTapTreshold: Integer; + FAutoTapDistance: Integer; + FOnListItemClick: TListItemEvent; + FOnItemClickEx: TListItemClickEventEx; + FOnItemChange: TListItemEvent; + FOnEditModeChanging: THandleChangeEvent; + FOnEditModeChange: TNotifyEvent; + FOnUpdateItemView: TUpdateItemViewEvent; + FOnUpdatingItemView: TUpdatingItemViewEvent; + FOnDeleteChange: TDeleteChangeVisibilityEvent; + FOnDeletingItem: TDeletingItemEvent; + FOnDeleteItem: TDeleteItemEvent; + FOnPullRefresh: TNotifyEvent; + FDeleteButtonText: string; + FEditMode: Boolean; + FCanSwipeDelete: Boolean; + FDeleteButtonIndex: Integer; + FPrevDeleteButtonIndex: Integer; + FStyleResources: TListItemStyleResources; + FUpdatingStyleResources: Boolean; + FDisableMouseWheel: Boolean; + FTransitionStartTime: Double; + FTransitionType: TTransitionType; + FEditModeTransitionAlpha: Single; + FDeleteModeTransitionAlpha: Single; + FDeleteLayout: TLayout; + FDeleteButton: TSpeedButton; + FDragListMode: TInternalDragMode; + FSearchEdit: TSearchBox; + FSearchVisible: Boolean; + FSearchAlwaysOnTop: Boolean; + FSelectionCrossfade: Boolean; + FPullToRefresh: Boolean; + FPullRefreshWait: Boolean; + FPullRefreshTriggered: Boolean; + FPullRefreshAnimation: TPullRefreshAnimation; + FPullRefreshAnimationStartTime: Double; + FPullRefreshAnimationStopTime: Double; + FScrollStretchStrength: Single; + FControlType: TControlType; + FNativeOptions: TListViewNativeOptions; + FImageLink: TGlyphImageLink; + FMessageSender: TMessageSender; + FItemSelectedBeforeChange: TListItem; + FEstimatedHeights: TEstimatedHeights; + + function IsRunningOnDesktop: Boolean; + function HasTouchTracking: Boolean; + function HasSearchFeatures: Boolean; + function HasSearchAsItem: Boolean; + function IsDeleteModeAllowed: Boolean; + function HasStretchyScrolling: Boolean; + function HasPhysicsStretchyScrolling: Boolean; + function HasScrollingStretchGlow: Boolean; + function HasPullRefreshStroke: Boolean; + + function CanDisplaySelectionForItem(const Index: Integer; const Item: TListItem = nil; + const IncludeMultiSelect: Boolean = False; const IncludeCrossFaded: Boolean = False): Boolean; + function GetDefaultSelectionAlpha: Single; + function GetItemSelectionAlpha(const Index: Integer): Single; + procedure DestroyRecurrentTimer; + procedure UpdateRecurrentTimer; + function HasRecurrentTimerEvents: Boolean; + procedure RecurrentTimerEvent; + procedure StartIncident(const Incident: TDelayedIncident; const Triggered: Boolean = True; + const TimeToWait: Single = 0; const CustomData: NativeInt = 0); + procedure ProcessIncident(const Entry: TDelayedIncidentEntry); + procedure TriggerIncidents(const Incident: TDelayedIncident; const ResetStartupTime: Boolean = True); + procedure ProcessDelayedIncidents; + procedure ProcessTransitionAnimation; + procedure ProcessTapSelectItem; + procedure ProcessSelectionAlphas; + procedure InsertItemCrossFade(const Index: Integer; const ShowAnimation: Boolean); + procedure RemoveItemCrossFade(const Index: Integer); + procedure StartPullRefreshAnimation; + procedure ProcessPullRefreshAnimation; + function GetPullRefreshStrength: Single; + function GetPullRefreshIndicatorSteps: Integer; + function GetPullRefreshIndicatorAlpha: Single; + function GetPullRefreshStrokeWidth: Single; + procedure PaintPullRefreshIndicator(const ACanvas: TCanvas; const AStrength, AOpacity: Single); + procedure PaintPullRefreshStroke(const ACanvas: TCanvas; const AStrength, AOpacity: Single); + procedure PaintScrollingStretchGlow(const ACanvas: TCanvas; const AIntensity, AOpacity: Single); + procedure UpdatePullRefreshState; + procedure UpdateScrollStretchStrength(const NewValue: Single); + procedure DeleteButtonClicked(Sender: TObject); + procedure ScrollBarChange(Sender: TObject); + procedure ItemSpacesChange(Sender: TObject); + procedure AniCalcChange(Sender: TObject); + procedure AniCalcStart(Sender: TObject); + procedure AniCalcStop(Sender: TObject); + function GetItemIndex: Integer; + procedure SetItemIndex(const Value: Integer); + procedure SetItemIndexInternal(const Value: Integer; const DisableSelection: Boolean = False; + const DisableCrossfade: Boolean = False); + function GetMaxScrollViewPos: Integer; + procedure UpdateScrollViewPos(const Value: Single); + procedure UpdateSearchEditPos; + procedure SetScrollViewPos(const Value: Single); + procedure UpdateScrollingLimits; + procedure UpdateScrollBar; + procedure GetNumberOfRenderingPasses(const StartItem, EndItem: Integer; var Passes, Subpasses: Integer); + function GetItemHeight(const Index: Integer): Integer; overload; virtual; + function GetItemRelRect(const Index: Integer; const LocRect: TRectF; const SideSpace: Integer = 0): TRectF; inline; + function GetItemGroupSeparators(const Index: Integer): Integer; inline; + function FindLocalItemObjectAtPosition(const ItemIndex: Integer; const Position: TPointF): TListItemDrawable; + + function GetSeparatorLineHeight: Single; + function AlignValueToPixel(const Value: Single): Single; + procedure DrawItemsFill(const StartItem, EndItem: Integer; const LocRect: TRectF; const Opacity: Single; + const HeaderIndex: Integer = -1); + procedure DrawIndexFill(const AIndex: Integer; const LocRect: TRectF; const Opacity: Single); + procedure DrawTouchAnimation(const Index: Integer; const LocRect: TRectF; const Opacity: Single); + + function GetHeaderRelRect(const StartItem, HeaderIndex: Integer; const LocRect: TRectF; + const SideSpace: Integer = 0): TRectF; + procedure DrawHeaderItem(const LocRect: TRectF; const StartItem, HeaderIndex: Integer; const Opacity: Single); + + procedure DrawListItems(const AbsOpacity: Single); + + procedure UpdateItemLookups; + function FindItemAbsoluteAt(const ViewAt: Integer): Integer; + function FindItemAbsoluteAtWithCheck(const ViewAt: Integer): Integer; + procedure SetSideSpace(const Value: Integer); + procedure SetTransparent(const Value: Boolean); + procedure SetAlternatingColors(const Value: Boolean); + procedure SetShowSelection(const Value: Boolean); + procedure RecreateNativePresentation; virtual; + + procedure SetEditMode(const Value: Boolean); + procedure SetCanSwipeDelete(const Value: Boolean); + + procedure SelectItem(const ItemIndex: Integer); virtual; + procedure UnselectItem(const ItemIndex: Integer); virtual; + function GetSelected: TListItem; + procedure SetSelected(const Value: TListItem); + procedure SetNewItemIndex(const NewIndex: Integer); + + procedure SetSearchVisible(const Value: Boolean); + procedure SetSearchAlwaysOnTop(const Value: Boolean); + procedure SetOnFilter(const Value: TFilterEvent); + procedure OnSearchEditResize(Sender: TObject); + procedure OnSearchEditChange(Sender: TObject); + function DeleteButtonTextStored: Boolean; + // ISearchResponder + procedure SetFilterPredicate(const Predicate: TPredicate); + // IMessageSendingCompatible + function GetMessageSender: TMessageSender; + // Custom readers + procedure ReadCanSwipeDelete(Reader: TReader); + procedure ReadIsSearchVisible(Reader: TReader); + procedure ReadIsSearchAlwaysOnTop(Reader: TReader); + procedure ReadEditModeOptions(Reader: TReader); + + function GetItemCount: Integer; + + { IListViewController } + procedure RequestReindexing(const Item: TListItem); + procedure ItemResized(const Item: TListItem); + procedure ItemInvalidated(const Item: TListItem); + procedure ControlClicked(const Item: TListItem; const Control: TListItemDrawable); + procedure CheckStateChanged(const Item: TListItem; const Control: TListItemDrawable); + function GetScene: IScene; + protected + procedure DefineProperties(Filer: TFiler); override; + /// True if in Edit Mode + function IsEditMode: Boolean; virtual; + /// Used internally by presentation hook + procedure DoSetItemIndexInternal(const Value: Integer); virtual; + /// Used internally by presentation hook + procedure DoUpdateScrollViewPos(const Value: Single); virtual; + /// Used internally by presentation hook + procedure DoSetScrollViewPos(const Value: Single); virtual; + /// Invoked when Edit Mode is being changed; if Edit Mode requires a different appearance, this + /// is where update of appearances should be initiated + procedure WillEnterEditMode(const Animated: Boolean); virtual; + /// Used internally by presentation hook + function HasButtonsInCells: Boolean; virtual; + /// Used internally by presentation hook + function HasDeletionEditMode: Boolean; virtual; + /// Used internally by presentation hook + function HasCheckboxMode: Boolean; virtual; + + /// Stop edit mode transition animation + procedure ResetEditModeAnimation; + /// Initialize edit mode transition animation + procedure InitEditModeAnimation; + /// Stop delete mode transition animation + procedure ResetDeleteModeAnimation; + /// Initialize delete mode transition animation + procedure InitDeleteModeAnimation; + /// Update layout to place a Delete button + procedure UpdateDeleteButtonLayout; + /// Perform item deletion + procedure ProceedDeleteItem; + + /// Invokes Pull-to-Refresh when applicable + procedure ScrollStretchChanged; virtual; + /// Scroll stretch threshold value when Pull-to-Refresh is invoked + property ScrollStretchStrength: Single read FScrollStretchStrength; + + procedure SetSelectionCrossfade(const Value: Boolean); + function GetDeleteButtonText: string; + procedure SetDeleteButtonText(const Value: string); + procedure SetPullToRefresh(const Value: Boolean); + { IControlTypeSupportable } + procedure SetControlType(const Value: TControlType); + function GetControlType: TControlType; + procedure SetNativeOptions(const Value: TListViewNativeOptions); + + { IListViewController } + function GetEditModeTransitionAlpha: Single; + function GetDeleteModeTransitionAlpha: Single; + procedure SetDeleteButtonIndex(const NewItemIndex: Integer); + function GetItemEditOffset(const Item: TListItem): Single; + function GetItemDeleteCutoff(const Item: TListItem): Single; + function GetClientMargins: TRectF; + function GetItemCurrentSelectionAlpha(const Item: TListItem): Single; + function IListViewController.GetItemSelectionAlpha = GetItemCurrentSelectionAlpha; + function GetImages: TCustomImageList; + procedure SetImages(const Value: TCustomImageList); + + /// Hook for IListViewController.RequestReindexing + procedure DoRequestReindexing(const Item: TListItem); virtual; + /// Hook for IListViewController.ItemResized + procedure DoItemResized(const Item: TListItem); virtual; + /// Hook for IListViewController.ItemInvalidated + procedure DoItemInvalidated(const Item: TListItem); virtual; + /// Hook for IListViewController.CheckStateChanged + procedure DoCheckStateChanged(const Item: TListItem; const Control: TListItemDrawable); virtual; + /// Hook for IListViewController.ControlClicked + procedure DoControlClicked(const Item: TListItem; const Control: TListItemDrawable); virtual; + + { IGlyph } + function GetImageIndex: TImageIndex; + procedure SetImageIndex(const Value: TImageIndex); + function GetImageList: TBaseImageList; inline; + procedure SetImageList(const Value: TBaseImageList); + function IGlyph.GetImages = GetImageList; + procedure IGlyph.SetImages = SetImageList; + { IListItemStyleResources } + function GetStyleResources: TListItemStyleResources; + function StyleResourcesNeedUpdate: Boolean; + + procedure SetItemSpaces(const Value: TBounds); + function GetItemClientRect(const Index: Integer): TRectF; // part of IListViewPresentationParent + function GetEstimatedItemHeight: Single; // part of IListViewPresentationParent + function GetEstimatedHeaderHeight: Single; // part of IListViewPresentationParent + function GetEstimatedFooterHeight: Single; // part of IListViewPresentationParent + + /// Called when an instance or reference to instance of TBaseImageList or the + /// ImageIndex property is changed. + /// See also FMX.ActnList.IGlyph + procedure ImagesChanged; virtual; + procedure Paint; override; + procedure AfterPaint; override; + procedure Loaded; override; + procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Single); override; + procedure MouseMove(Shift: TShiftState; X, Y: Single); override; + procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Single); override; + procedure MouseWheel(Shift: TShiftState; WheelDelta: Integer; var Handled: Boolean); override; + procedure KeyDown(var Key: Word; var KeyChar: System.WideChar; Shift: TShiftState); override; + function ObjectAtPoint(P: TPointF): IControl; override; + procedure DoMouseLeave; override; + procedure Resize; override; + function GetDefaultStyleLookupName: string; override; + procedure ApplyStyle; override; + procedure FreeStyle; override; + procedure Invalidate; + procedure DoRealign; override; + procedure DoExit; override; + /// General state change. Starts TDelayedIncident.ChangeRepainted incident and + /// invokes OnChange + procedure DoChange; virtual; + /// Handle TDelayedIncident.ChangeRepainted incident + procedure DoChangeRepainted; virtual; + /// Invoke OnItemChange handler + procedure DoListItemChange(const AListItem: TListItem); virtual; + /// Invoke OnListItemClick handler + procedure DoListItemClick(const AListItem: TListItem); virtual; + /// Invoke OnEditModeChange handler + procedure DoEditModeChange; virtual; + /// Invoke OnEditModeChanging handler + procedure DoEditModeChanging(var AHandled: Boolean); virtual; + /// Reset edit mode animation + procedure DoResetEditModeAnimation; virtual; + /// Update scrolling limits and animation boundaries + procedure DoUpdateScrollingLimits; virtual; + + // Notifications from IListViewAdapter + procedure DoItemsMayChange; override; + procedure DoItemsCouldHaveChanged; override; + procedure DoItemsInvalidate; override; + /// This virtual method is called immediately after list of items has been changed. + procedure DoItemsChange; override; + procedure DoAdapterSet; override; + /// Deletes an item + /// index of item to be deleted + /// True if deleted succesfully + function DeleteItem(const ItemIndex: Integer): Boolean; + /// Perform actual item deletion. Called from DeleteItem: Boolean + procedure DoDeleteItem(const ItemIndex: Integer); virtual; + /// Get area available to item layout + function GetFinalItemSpaces(const ForceIncludeScrollBar: Boolean = True): TRectF; virtual; + /// Get item size + function GetFinalItemSize(const ForceIncludeScrollBar: Boolean = True): TSizeF; virtual; + function CanObserve(const ID: Integer): Boolean; override; + /// Notify observers about selection change + procedure ObserversBeforeSelection(out LAllowSelection: Boolean); + /// Return True if this item should handle input events + function ShouldHandleEvents: Boolean; virtual; + /// Invoke OnUpdatingItemView handler + procedure DoUpdatingItemView(const AListItem: TListItem; var AHandled: Boolean); virtual; + // Invoke OnUpdateItemView handler + procedure DoUpdateItemView(const AListItem: TListItem); virtual; + /// Get glyph button for item Index + function GetGlyphButton(const Index: Integer): TListItemGlyphButton; + /// Invoked before item view will be updated (before calling ResetObjects) + property OnUpdatingItemView: TUpdatingItemViewEvent read FOnUpdatingItemView write FOnUpdatingItemView; + /// Invoked after item view has been updated (after calling ResetObjects) + property OnUpdateItemView: TUpdateItemViewEvent read FOnUpdateItemView write FOnUpdateItemView; + /// Invoked after EditMode has been changed + property OnEditModeChange: TNotifyEvent read FOnEditModeChange write FOnEditModeChange; + /// Invoked before changing EditMode + property OnEditModeChanging: THandleChangeEvent read FOnEditModeChanging write FOnEditModeChanging; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + class function GetDefaultMargins: TRectF; + procedure EndUpdate; override; + /// When using native presentation, re-creates the list and updates visible item content + procedure RebuildList; virtual; + /// Scrolls the view (instantly) to the desired item placing it within the view + procedure ScrollTo(const AItemIndex: Integer); + /// Index of selected item + property ItemIndex: Integer read GetItemIndex write SetItemIndex default -1; + /// Selected item + property Selected: TListItem read GetSelected write SetSelected; + /// Scroll position in dimension units + property ScrollViewPos: Single read FScrollViewPos write SetScrollViewPos; + /// Get rectangle of item, relative control + function GetItemRect(const AItemIndex: Integer): TRectF; + /// This method should be called when "pull to refresh" mode has been triggered to stop spinning wheel + /// + /// This has only effect in native iOS control and only when PullRefreshWait property is set to True + /// + procedure StopPullRefresh; virtual; + /// Space in logical units around the content of each list item + property ItemSpaces: TBounds read FItemSpaces write SetItemSpaces; + /// The list of images. Can be nil. See also FMX.ActnList.IGlyph + property Images: TCustomImageList read GetImages write SetImages; + /// Space in logical units on all sides around the list box encompassing the items + property SideSpace: Integer read FSideSpace write SetSideSpace default 0; + /// If the control is transparent, it will not draw its background + property Transparent: Boolean read FTransparent write SetTransparent; + /// Determines whether the items are selectable or not. If items are not selectable, user will still be + /// able to click on embedded controls + property AllowSelection: Boolean read FAllowSelection write FAllowSelection default True; + // Enabling this will switch fill colors for odd and even elements + property AlternatingColors: Boolean read FAlternatingColors write SetAlternatingColors default False; + /// Determines whether the selection is visible when selecting items. + /// It may be disabled when using list of checkboxes + property ShowSelection: Boolean read FShowSelection write SetShowSelection default True; + /// Enables swipe delete + property CanSwipeDelete: Boolean read FCanSwipeDelete write SetCanSwipeDelete default True; + /// Enable automatic scrolling to the top when tapped at the top edge + property AutoTapScroll: Boolean read FAutoTapScroll write FAutoTapScroll default False; + /// Threshold distance from the top edge at which the tap would initiate autoscroll to top + property AutoTapTreshold: Integer read FAutoTapTreshold write FAutoTapTreshold default 8; + /// Disables mouse wheel + property DisableMouseWheel: Boolean read FDisableMouseWheel write FDisableMouseWheel default False; + /// Item count + property ItemCount: Integer read GetItemCount; + /// Item click handler + property OnListItemClick: TListItemEvent read FOnListItemClick write FOnListItemClick; + /// Extended item click handler which gets click coordinates and clicked drawable + property OnItemClickEx: TListItemClickEventEx read FOnItemClickEx write FOnItemClickEx; + /// Reserved + property OnItemChange: TListItemEvent read FOnItemChange write FOnItemChange; + /// General OnChange event handler + property OnChange: TNotifyEvent read FOnChange write FOnChange; + /// TDelayedIncident.ChangeRepainted delayed incident handler + property OnChangeRepainted: TNotifyEvent read FOnChangeRepainted write FOnChangeRepainted; + /// This event occurs after list of items has been changed. + property OnItemsChange: TNotifyEvent read FOnItemsChange write FOnItemsChange; + /// Called when ScrollViewPos has changed (manually or in code) + property OnScrollViewChange: TNotifyEvent read FOnScrollViewChange write FOnScrollViewChange; + /// Query before item deletion, see TDeletingItemEvent. + /// Application can veto deletion by returning False in handler Result + /// Deletion is performed by DoDeleteItem + property OnDeletingItem: TDeletingItemEvent read FOnDeletingItem write FOnDeletingItem; + /// Invoked after item has been deleted + property OnDeleteItem: TDeleteItemEvent read FOnDeleteItem write FOnDeleteItem; + /// Invoked when Delete button changes visibility + property OnDeleteChangeVisible: TDeleteChangeVisibilityEvent read FOnDeleteChange write FOnDeleteChange; + /// + property OnSearchChange: TNotifyEvent read FOnSearchChange write FOnSearchChange; + /// Event handler for setting custom filter on text of TListView. + property OnFilter: TFilterEvent read FOnFilter write SetOnFilter; + /// Invoked when pull refresh is triggered + property OnPullRefresh: TNotifyEvent read FOnPullRefresh write FOnPullRefresh; + /// Text to display in Delete button + property DeleteButtonText: string read GetDeleteButtonText write SetDeleteButtonText stored + DeleteButtonTextStored nodefault; + /// Enable/disable Edit Mode + property EditMode: Boolean read FEditMode write SetEditMode default False; + /// True if search bar is visible + property SearchVisible: Boolean read FSearchVisible write SetSearchVisible default False; + /// Always display search bar + property SearchAlwaysOnTop: Boolean read FSearchAlwaysOnTop write SetSearchAlwaysOnTop default True; + /// Enable selection crossfade animation + property SelectionCrossfade: Boolean read FSelectionCrossfade write SetSelectionCrossfade default False; + /// Enable pull to refresh + property PullToRefresh: Boolean read FPullToRefresh write SetPullToRefresh default False; + /// When set to True, the spinning wheel does not disappear automatically and StopPullRefresh method needs + /// to be called after refresh operation is done. If this is set to False (default), then spinning wheel disappears + /// automatically shortly after triggering the effect. This option works only in native iOS control and has no + /// effect otherwise. + property PullRefreshWait: Boolean read FPullRefreshWait write FPullRefreshWait default False; + /// Control type: Styled or Native + property ControlType: TControlType read FControlType write SetControlType default TControlType.Styled; + /// Options for Native control; see ControlType + property NativeOptions: TListViewNativeOptions read FNativeOptions write SetNativeOptions default []; + end; + + /// TListView that supports native presentation + TPresentedListView = class(TListViewBase, IListViewPresentationParent, IListViewDesignPresentationParent) + strict private + FPresentation: IListViewPresentation; + FPresentationLocked: Integer; + FCreatingNativeView: Boolean; + protected + /// Lock presentation and execute P + procedure ExecuteInterlocked(const P: TProc); + /// True if item can be selected + function CanSelectItem(const AItemIndex: Integer): Boolean; + /// True if item can be unselected + function CanUnselectItem(const AItemIndex: Integer): Boolean; + /// Called after item has been selected + procedure DidSelectItem(const AItemIndex: Integer); + /// Called after item has been unselected + procedure DidUnselectItem(const AItemIndex: Integer); + procedure ChangeOrder; override; + procedure ParentChanged; override; + procedure PaintChildren; override; + procedure AncestorVisibleChanged(const Visible: Boolean); override; + procedure DoSetItemIndexInternal(const Value: Integer); override; + procedure DoEditModeChange; override; + procedure DoItemsChange; override; + procedure DoItemsInvalidate; override; + procedure DoItemInvalidated(const Item: TListItem); override; + procedure DoCheckStateChanged(const AItem: TListItem; const Control: TListItemDrawable); override; + procedure DoUpdateScrollViewPos(const Value: Single); override; + procedure DoSetScrollViewPos(const Value: Single); override; + procedure DoDeleteItem(const ItemIndex: Integer); override; + procedure DoResetEditModeAnimation; override; + procedure DoUpdateScrollingLimits; override; + procedure DoAbsoluteChanged; override; + // Presentation + /// Parent control has been loaded + procedure PMAncesstorPresentationLoaded(var AMessage: TDispatchMessageWithValue); message PM_ANCESTOR_PRESENTATION_LOADED; + procedure RecreateNativePresentation; override; + function ShouldHandleEvents: Boolean; override; + // IPresentationParent + function GetRootObject: TObject; + function GetContentFrame: TRect; + function GetControlOpacity: Single; + // IListViewPresentationParent + function GetAdapter: IListViewAdapter; + function GetItemText(const ItemIndex: Integer): string; + function GetItemIndexTitle(const ItemIndex: Integer): string; + procedure ItemButtonClicked(const ItemIndex: Integer); + procedure InvokePullRefresh; + procedure SetSearchFilter(const Filter: string); + function GetTableViewFlags: TListViewModeFlags; + function GetTableViewOptions: TListViewNativeOptions; + function IListViewPresentationParent.GetFlags = GetTableViewFlags; + function IListViewPresentationParent.GetOptions = GetTableViewOptions; + procedure SetCreatingNativeView(const Value: Boolean); + function GetIsTransparent: Boolean; + function GetOpacity: Single; + function GetBackgroundStyleColor: TAlphaColor; + procedure DoItemsResize; override; + // IListViewDesignPresentationParent + function HasDesignPresentationAttached: Boolean; + public + destructor Destroy; override; + procedure BeforeDestruction; override; + procedure RecalcEnabled; override; + procedure Show; override; + procedure Hide; override; + procedure Resize; override; + procedure Paint; override; + procedure RebuildList; override; + procedure StopPullRefresh; override; + procedure RecalcOpacity; override; + end; + + /// TAppearanceListView supports Appearances. Appearances are templates used for dynamic creation + /// of item views. Normally all items of the same purpose in the List View share the same appearance, differing + /// only in data + TAppearanceListView = class(TPresentedListView, IAppearanceItemOwner, IPublishedAppearanceOwner) + public type + /// Generic event invoked on TListViewItem + TItemEvent = procedure(const Sender: TObject; const AItem: TListViewItem) of object; + /// See DoUpdateItemView + TUpdateObjectsEvent = TItemEvent; + /// See DoUpdatingItemView + TUpdatingObjectsEvent = procedure(const Sender: TObject; const AItem: TListViewItem; var AHandled: Boolean) of object; + + strict private + FAppearanceViewItems: TAppearanceListViewItems; + FAppearanceProperties: TPublishedAppearance; + FItemAppearanceObjects: TPublishedObjects; + FItemAppearanceProperties: TItemAppearanceProperties; + FItemEditAppearanceProperties: TItemAppearanceProperties; + FHeaderAppearanceProperties: TItemAppearanceProperties; + FFooterAppearanceProperties: TItemAppearanceProperties; + FUpdatingAppearance: Integer; + FChangedAppearanceObjects: TListItemPurposes; + FChangedAppearanceHeights: TListItemPurposes; + // See also FItemSelectedBeforeChange + FItemSelectedBeforeEdit: TListItem; + FOnButtonClick: TItemControlEvent; + FOnButtonChange: TItemControlEvent; + FAppearanceAllowsCheckboxes: Boolean; + FAppearanceAllowsDeleteMode: Boolean; + FOnItemClick: TItemEvent; + FOnUpdatingObjects: TUpdatingObjectsEvent; + FOnUpdateObjects: TUpdateObjectsEvent; + + function GetFooterAppearanceName: string; + function GetFooterAppearanceClassName: string; + function GetHeaderAppearanceName: string; + function GetHeaderAppearanceClassName: string; + function GetItemAppearanceName: string; + function GetItemEditAppearanceName: string; + function GetItemObjectsClassName: string; + function GetItemEditObjectsClassName: string; + procedure SetFooterAppearanceClassName(const Value: string); + procedure SetHeaderAppearanceClassName(const Value: string); + procedure SetItemObjectsClassName(const Value: string); + procedure SetItemEditObjectsClassName(const Value: string); + procedure SetFooterAppearanceName(const Value: string); + procedure SetHeaderAppearanceName(const Value: string); + procedure SetItemAppearanceName(const Value: string); + procedure SetItemEditAppearanceName(const Value: string); + + procedure SetAppearanceProperties(const Value: TPublishedAppearance); + procedure SetItemAppearanceObjects(const Value: TPublishedObjects); + function GetItemAppearanceObjects: TPublishedObjects; + procedure AppearanceResetObjects(APurposes: TListItemPurposes); + procedure AppearanceResetHeights(APurposes: TListItemPurposes); + + { IPublishedAppearanceOwner } + + function GetFooterAppearanceProperties: TItemAppearanceProperties; + function GetHeaderAppearanceProperties: TItemAppearanceProperties; + function GetItemAppearanceProperties: TItemAppearanceProperties; + function GetItemEditAppearanceProperties: TItemAppearanceProperties; + + procedure EditorBeforeItemAdded(Sender: IListViewEditor); + procedure EditorAfterItemAdded(Sender: IListViewEditor; const Item: TListItem); + procedure EditorBeforeItemDeleted(Sender: IListViewEditor; const Index: Integer); + procedure EditorAfterItemDeleted(Sender: IListViewEditor); + procedure ResetViewAppearance(const AItem: TListViewItem); + + protected + procedure ApplyStyle; override; + /// Handler of + /// TAppearanceListViewItems.OnNotify + procedure ObjectsNotify(Sender: TObject; const Item: TListItem; Action: TCollectionNotification); + /// TAppearanceListView needs adapter to be TAppearanceListViewItems or derivative. + /// If TAppearanceListView is used with a custom adapter, use Items property to set it + /// instead of Adapter property of the base class + procedure SetAppearanceListViewItems(const AItems: TAppearanceListViewItems); + procedure DoResetView(const Item: TListItem); override; + + function HasButtonsInCells: Boolean; override; + function HasDeletionEditMode: Boolean; override; + function HasCheckboxMode: Boolean; override; + procedure SetItemHeight(const Value: Integer); virtual; + procedure SetItemEditHeight(const Value: Integer); virtual; + procedure SetHeaderHeight(const Value: Integer); virtual; + procedure SetFooterHeight(const Value: Integer); virtual; + + function GetAppearanceListViewItem(const Index: Integer): TListViewItem; virtual; + /// Get height of a specific item + function GetItemHeight(const Index: Integer): Integer; overload; override; + // See respective properties + function GetItemHeight: Integer; overload; virtual; + function GetItemEditHeight: Integer; overload; virtual; + function GetHeaderHeight: Integer; overload; virtual; + function GetFooterHeight: Integer; overload; virtual; + + procedure WillEnterEditMode(const Animated: Boolean); override; + procedure DoResetEditModeAnimation; override; + + procedure DoAdapterSet; override; + // hooks from IListViewController + procedure DoRequestReindexing(const Item: TListItem); override; + procedure DoItemResized(const Item: TListItem); override; + procedure DoCheckStateChanged(const AItem: TListItem; const Control: TListItemDrawable); override; + procedure DoControlClicked(const Item: TListItem; const Control: TListItemDrawable); override; + /// Returns an array of 4 elements comprised by + /// ItemEditAppearanceProperties + /// ItemAppearanceProperties + /// HeaderAppearanceProperties + /// FooterAppearanceProperties + function GetAppearanceProperties: TArray; + /// Refresh items with specified purposes; all items if the set is empty; + /// see also IListViewAdapter.ResetViews + procedure RefreshAppearances(const APurposes: TListItemPurposes = []); + /// Same as RefreshAppearances + procedure UpdateAppearanceStyleResources; + /// Invoked when item appearance changes; resets all item views + procedure ItemAppearanceChange(const Sender: TItemAppearanceProperties); + /// Invoked when Appearance Objects (view prototype) change + procedure ItemAppearanceChangeObjects(const Sender: TItemAppearanceProperties); + /// Invoked when appearance height is changed + procedure ItemAppearanceChangeHeight(const Sender: TItemAppearanceProperties); + /// Resets all item views when entering edit mode + procedure EditModeAppearances; + /// Reset appearance. When TAppearanceListView is created, it creates appearances + /// for Item, Edit mode Item, Header, Footer and initializes them by calling this virtual method. + /// By contract it must select TItemAppearanceProperties.AppearanceClass by searching in + /// appearances registry for item purpose specified during TItemAppearanceProperties creation + /// instance of TItemAppearanceProperties + /// See implementation in + /// TListView.InitializeItemAppearance + /// See also TAppearancesRegistry + /// + procedure InitializeItemAppearance(const AAppearance: TItemAppearanceProperties); virtual; + + procedure DoListItemClick(const AItem: TListItem); override; + procedure DoUpdatingItemView(const AListItem: TListItem; var AHandled: Boolean); override; + procedure DoUpdateItemView(const AListItem: TListItem); override; + + // General compatibility properties + /// Item height defined by appearance + property ItemHeight: Integer read GetItemHeight write SetItemHeight; + /// Item height in edit mode defined by appearance + property ItemEditHeight: Integer read GetItemEditHeight write SetItemEditHeight; + /// Header height defined by appearance + property HeaderHeight: Integer read GetHeaderHeight write SetHeaderHeight; + /// Footer height defined by appearance + property FooterHeight: Integer read GetFooterHeight write SetFooterHeight; + + // Appearance related properties + /// Item in edit mode appearance class name + /// Must be loaded prior to other Item, header and footer properties + /// Changing class name will load new appearance and reinitialize all views + /// + property ItemEditAppearanceClassName: string read GetItemEditObjectsClassName write SetItemEditObjectsClassName; + /// Item appearance class name + /// Must be loaded prior to other Item, header and footer properties + /// Changing class name will load new appearance and reinitialize all views + /// + property ItemAppearanceClassName: string read GetItemObjectsClassName write SetItemObjectsClassName; + /// Header appearance class name + /// Must be loaded prior to other Item, header and footer properties + /// Changing class name will load new appearance and reinitialize all views + /// + property HeaderAppearanceClassName: string read GetHeaderAppearanceClassName write SetHeaderAppearanceClassName; + /// Footer appearance class name + /// Must be loaded prior to other Item, header and footer properties + /// Changing class name will load new appearance and reinitialize all views + /// + property FooterAppearanceClassName: string read GetFooterAppearanceClassName write SetFooterAppearanceClassName; + + /// Assign new appearance by name; this will effectively change ItemAppearanceClassName and reload + /// all views + property ItemAppearanceName: string read GetItemAppearanceName write SetItemAppearanceName stored False; + /// Assign new appearance by name; this will effectively change ItemEditAppearanceClassName and reload + /// all views + property ItemEditAppearanceName: string read GetItemEditAppearanceName write SetItemEditAppearanceName stored False; + /// Assign new appearance by name; this will effectively change HeaderAppearanceClassName and reload + /// all views + property HeaderAppearanceName: string read GetHeaderAppearanceName write SetHeaderAppearanceName stored False; + /// Assign new appearance by name; this will effectively change FooterAppearanceClassName and reload + /// all views + property FooterAppearanceName: string read GetFooterAppearanceName write SetFooterAppearanceName stored False; + // TPublishedAppearance represents appearances in the object inspector + property ItemAppearance: TPublishedAppearance read FAppearanceProperties write SetAppearanceProperties; + /// TPublishedObjects represents appearance items (collections of objects comprising appearances) + /// in the object inspector + property ItemAppearanceObjects: TPublishedObjects read GetItemAppearanceObjects write SetItemAppearanceObjects; + /// Invoked on check button state change + property OnButtonChange: TItemControlEvent read FOnButtonChange write FOnButtonChange; + /// Invoked on embedded button click + property OnButtonClick: TItemControlEvent read FOnButtonClick write FOnButtonClick; + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + procedure BeginUpdate; override; + procedure EndUpdate; override; + procedure Resize; override; + /// Access to the extended adapter that supports appearances and works with extended + /// items; see TListViewItem + property Items: TAppearanceListViewItems read FAppearanceViewItems write SetAppearanceListViewItems; + /// Item click event handler + property OnItemClick: TItemEvent read FOnItemClick write FOnItemClick; + /// Invoked when view is being created by TAppearanceListView.ResetViewAppearance before + /// calling ResetObjects. If not Handled, the view will be recreated + /// Call sequence: + /// TAppearanceListView.ResetViewAppearance: + /// OnUpdatingObjects -> + /// TItemAppearanceObjects.ResetObjects -> OnUpdateObjects + property OnUpdatingObjects: TUpdatingObjectsEvent read FOnUpdatingObjects write FOnUpdatingObjects; + /// Invoked when view is being created by TAppearanceListView.ResetViewAppearance after + /// calling ResetObjects + /// Call sequence: + /// TAppearanceListView.ResetViewAppearance: + /// OnUpdatingObjects -> + /// TItemAppearanceObjects.ResetObjects -> OnUpdateObjects + property OnUpdateObjects: TUpdateObjectsEvent read FOnUpdateObjects write FOnUpdateObjects; + end; + + TCustomListView = class(TAppearanceListView) + end; + + TListView = class(TCustomListView) + protected + procedure InitializeItemAppearance(const AAppearance: TItemAppearanceProperties); override; + public + // Hoist protected appearance properties + property ItemAppearanceName; + property ItemEditAppearanceName; + property HeaderAppearanceName; + property FooterAppearanceName; + published + // Hoist protected appearance properties + property ItemAppearanceClassName; + property ItemEditAppearanceClassName; + property HeaderAppearanceClassName; + property FooterAppearanceClassName; + + property OnUpdatingObjects; + property OnUpdateObjects; + property OnEditModeChange; + property OnEditModeChanging; + property EditMode; + + property Transparent default false; + property AllowSelection; + property AlternatingColors; + property ItemIndex; + property Images; + property ScrollViewPos; + property ItemSpaces; + property SideSpace; + + property Align; + property Anchors; + property CanFocus default True; + property CanParentFocus; + property ClipChildren default True; + property ClipParent default False; + property Cursor default crDefault; + property DisableFocusEffect default True; + property DragMode default TDragMode.dmManual; + property EnableDragHighlight default True; + property Enabled default True; + property Locked default False; + property Height; + property Hint; + property HitTest default True; + property Margins; + property Opacity; + property Padding; + property PopupMenu; + property Position; + property RotationAngle; + property RotationCenter; + property Scale; + property Size; + property TabOrder; + property TabStop; + property Visible default True; + property Width; + property ParentShowHint; + property ShowHint; + + {events} + property OnApplyStyleLookup; + property OnFreeStyle; + {Drag and Drop events} + property OnDragEnter; + property OnDragLeave; + property OnDragOver; + property OnDragDrop; + property OnDragEnd; + {Keyboard events} + property OnKeyDown; + property OnKeyUp; + {Mouse events} + property OnCanFocus; + + property OnEnter; + property OnExit; + property OnMouseDown; + property OnMouseMove; + property OnMouseUp; + property OnMouseWheel; + property OnMouseEnter; + property OnMouseLeave; + + property OnPainting; + property OnPaint; + property OnResize; + property OnResized; + + property ItemAppearance; + property ItemAppearanceObjects; + + property HelpContext; + property HelpKeyword; + property HelpType; + + property StyleLookup; + property TouchTargetExpansion; + property OnClick; + property OnDblClick; + + { ListView selection events } + property CanSwipeDelete; + + property OnChange; + property OnChangeRepainted; + property OnItemsChange; + property OnScrollViewChange; + property OnItemClick; + property OnItemClickEx; + property OnButtonClick; + property OnButtonChange; + + property OnDeletingItem; + property OnDeleteItem; + property OnDeleteChangeVisible; + property OnSearchChange; + property OnFilter; + property OnPullRefresh; + property DeleteButtonText; + + property AutoTapScroll; + property AutoTapTreshold; + property ShowSelection; + property DisableMouseWheel; + + property SearchVisible; + property SearchAlwaysOnTop; + property SelectionCrossfade; + property PullToRefresh; + property PullRefreshWait; + + property ControlType; + property NativeOptions; + end; + + EListViewError = class(Exception); + +//== INTERFACE END: FMX.ListView //==================================================================================================