diff --git a/Source/fmx/WrapFmxControls.pas b/Source/fmx/WrapFmxControls.pas index fcc70861..2d0ed951 100644 --- a/Source/fmx/WrapFmxControls.pas +++ b/Source/fmx/WrapFmxControls.pas @@ -6,7 +6,7 @@ interface uses Classes, SysUtils, TypInfo, Types, - Fmx.Controls, + FMX.Types, FMX.Controls, PythonEngine, WrapDelphi, WrapDelphiClasses, WrapFmxTypes; type @@ -31,14 +31,17 @@ TPyDelphiControl = class (TPyDelphiFmxObject) function CanFocus_Wrapper(args: PPyObject): PPyObject; cdecl; function SetFocus_Wrapper(args: PPyObject): PPyObject; cdecl; function ResetFocus_Wrapper(args: PPyObject): PPyObject; cdecl; + function PrepareForPaint_Wrapper(args : PPyObject) : PPyObject; cdecl; // Property Getters function Get_Visible(AContext: Pointer): PPyObject; cdecl; function Get_ControlsCount( AContext : Pointer) : PPyObject; cdecl; function Get_Controls(AContext: Pointer): PPyObject; cdecl; function Get_IsFocused( AContext : Pointer) : PPyObject; cdecl; function Get_ParentControl( AContext : Pointer) : PPyObject; cdecl; + function Get_Position(AContext: Pointer): PPyObject; cdecl; // Property Setters function Set_Visible(AValue: PPyObject; AContext: Pointer): integer; cdecl; + function Set_Position(AValue: PPyObject; AContext: Pointer): integer; cdecl; public class function DelphiObjectClass : TClass; override; class procedure RegisterGetSets( PythonType : TPythonType ); override; @@ -65,10 +68,34 @@ TControlsAccess = class(TContainerAccess) property Container : TControl read GetContainer; end; -implementation + TPyDelphiStyledControl = class(TPyDelphiControl) + private + function GetDelphiObject: TStyledControl; + procedure SetDelphiObject(const Value: TStyledControl); + protected + // Exposed Methods + function ApplyStyleLookup_Wrapper(args : PPyObject) : PPyObject; cdecl; + function NeedStyleLookup_Wrapper(args : PPyObject) : PPyObject; cdecl; + function Inflate_Wrapper(args : PPyObject) : PPyObject; cdecl; + // Property Getters + function Get_DefaultStyleLookupName(AContext: Pointer): PPyObject; cdecl; + function Get_StyleLookup(AContext: Pointer): PPyObject; cdecl; + function Get_AutoTranslate(AContext: Pointer): PPyObject; cdecl; + function Get_AdjustSizeValue(AContext: Pointer): PPyObject; cdecl; + function Get_AdjustType(AContext: Pointer): PPyObject; cdecl; + function Get_StyleState(AContext: Pointer): PPyObject; cdecl; + // Property Setters + function Set_StyleLookup(AValue: PPyObject; AContext: Pointer): integer; cdecl; + function Set_AutoTranslate(AValue: PPyObject; AContext: Pointer): integer; cdecl; + public + class function DelphiObjectClass: TClass; override; + class procedure RegisterGetSets(PythonType: TPythonType); override; + class procedure RegisterMethods(PythonType: TPythonType); override; + // Properties + property DelphiObject: TStyledControl read GetDelphiObject write SetDelphiObject; + end; -uses - FMX.Types; +implementation type { Register the wrappers, the globals and the constants } @@ -125,6 +152,18 @@ function TPyDelphiControl.LocalToAbsolute_Wrapper( end; end; +function TPyDelphiControl.PrepareForPaint_Wrapper(args: PPyObject): PPyObject; +begin + Adjust(@Self); + with GetPythonEngine do begin + if PyArg_ParseTuple( args, ':PrepareForPaint') <> 0 then begin + DelphiObject.PrepareForPaint; + Result := ReturnNone; + end else + Result := nil; + end; +end; + class function TPyDelphiControl.DelphiObjectClass: TClass; begin Result := TControl; @@ -161,6 +200,12 @@ function TPyDelphiControl.Get_ParentControl(AContext: Pointer): PPyObject; Result := Wrap(DelphiObject.ParentControl); end; +function TPyDelphiControl.Get_Position(AContext: Pointer): PPyObject; +begin + Adjust(@Self); + Result := Wrap(DelphiObject.Position); +end; + function TPyDelphiControl.Get_Visible(AContext: Pointer): PPyObject; begin Adjust(@Self); @@ -178,6 +223,8 @@ class procedure TPyDelphiControl.RegisterGetSets(PythonType: TPythonType); 'Returns an iterator over contained controls', nil); PythonType.AddGetSet('IsFocused', @TPyDelphiControl.Get_IsFocused, nil, 'Determines whether the control has input focus.', nil); + PythonType.AddGetSet('Position', @TPyDelphiControl.Get_Position, @TPyDelphiControl.Set_Position, + 'Returns an access to the position of the control inside its parent', nil); end; class procedure TPyDelphiControl.RegisterMethods(PythonType: TPythonType); @@ -210,6 +257,9 @@ class procedure TPyDelphiControl.RegisterMethods(PythonType: TPythonType); PythonType.AddMethod('ResetFocus', @TPyDelphiControl.ResetFocus_Wrapper, 'TControl.ResetFocus()'#10 + 'Removes the focus from a control of from any children of the control.'); + PythonType.AddMethod('PrepareForPaint', @TPyDelphiControl.PrepareForPaint_Wrapper, + 'TControl.PrepareForPaint()'#10 + + 'Prepares the current control for painting.'); end; function TPyDelphiControl.Repaint_Wrapper(args: PPyObject): PPyObject; @@ -304,6 +354,21 @@ function TPyDelphiControl.SetFocus_Wrapper(args: PPyObject): PPyObject; end; end; +function TPyDelphiControl.Set_Position(AValue: PPyObject; + AContext: Pointer): integer; +var + LValue: TObject; +begin + Adjust(@Self); + if CheckObjAttribute(AValue, 'Position', TPosition, LValue) then + begin + DelphiObject.Position := TPosition(LValue); + Result := 0; + end + else + Result := -1; +end; + function TPyDelphiControl.Set_Visible(AValue: PPyObject; AContext: Pointer): integer; var @@ -336,6 +401,7 @@ procedure TControlsRegistration.RegisterWrappers( begin inherited; APyDelphiWrapper.RegisterDelphiWrapper(TPyDelphiControl); + APyDelphiWrapper.RegisterDelphiWrapper(TPyDelphiStyledControl); end; { TControlsAccess } @@ -404,6 +470,163 @@ class function TControlsAccess.SupportsIndexOf: Boolean; Result := True; end; +{ TPyDelphiStyledControl } + +function TPyDelphiStyledControl.ApplyStyleLookup_Wrapper( + args: PPyObject): PPyObject; +begin + Adjust(@Self); + with GetPythonEngine do begin + if PyArg_ParseTuple( args, ':ApplyStyleLookup') <> 0 then begin + DelphiObject.ApplyStyleLookup; + Result := ReturnNone; + end else + Result := nil; + end; +end; + +class function TPyDelphiStyledControl.DelphiObjectClass: TClass; +begin + Result := TStyledControl; +end; + +function TPyDelphiStyledControl.GetDelphiObject: TStyledControl; +begin + Result := TStyledControl(inherited DelphiObject); +end; + +function TPyDelphiStyledControl.Get_AdjustSizeValue( + AContext: Pointer): PPyObject; +begin + Adjust(@Self); + Result := WrapSizeF(PyDelphiWrapper, DelphiObject.AdjustSizeValue); +end; + +function TPyDelphiStyledControl.Get_AdjustType(AContext: Pointer): PPyObject; +begin + Adjust(@Self); + Result := GetPythonEngine.PyLong_FromLong(Ord(DelphiObject.AdjustType)); +end; + +function TPyDelphiStyledControl.Get_AutoTranslate(AContext: Pointer): PPyObject; +begin + Adjust(@Self); + Result := GetPythonEngine.VariantAsPyObject(Self.DelphiObject.AutoTranslate); +end; + +function TPyDelphiStyledControl.Get_DefaultStyleLookupName( + AContext: Pointer): PPyObject; +begin + Adjust(@Self); + Result := GetPythonEngine.PyUnicodeFromString(DelphiObject.DefaultStyleLookupName); +end; + +function TPyDelphiStyledControl.Get_StyleLookup(AContext: Pointer): PPyObject; +begin + Adjust(@Self); + Result := GetPythonEngine.PyUnicodeFromString(DelphiObject.StyleLookup); +end; + +function TPyDelphiStyledControl.Get_StyleState(AContext: Pointer): PPyObject; +begin + Adjust(@Self); + Result := GetPythonEngine.PyLong_FromLong(Ord(DelphiObject.StyleState)); +end; + +function TPyDelphiStyledControl.Inflate_Wrapper(args: PPyObject): PPyObject; +begin + Adjust(@Self); + with GetPythonEngine do begin + if PyArg_ParseTuple( args, ':Inflate') <> 0 then begin + DelphiObject.Inflate; + Result := ReturnNone; + end else + Result := nil; + end; +end; + +function TPyDelphiStyledControl.NeedStyleLookup_Wrapper( + args: PPyObject): PPyObject; +begin + Adjust(@Self); + with GetPythonEngine do begin + if PyArg_ParseTuple( args, ':NeedStyleLookup') <> 0 then begin + DelphiObject.NeedStyleLookup; + Result := ReturnNone; + end else + Result := nil; + end; +end; + +class procedure TPyDelphiStyledControl.RegisterGetSets(PythonType: TPythonType); +begin + inherited; + with PythonType do begin + AddGetSet('DefaultStyleLookupName', @TPyDelphiStyledControl.Get_StyleLookup, nil, + 'Returns a string with the name of the default style of this control', nil); + AddGetSet('StyleLookup', @TPyDelphiStyledControl.Get_StyleLookup, @TPyDelphiStyledControl.Set_StyleLookup, + 'Specifies the name of the resource object to which the current TStyledControl is linked', nil); + AddGetSet('AutoTranslate', @TPyDelphiStyledControl.Get_AutoTranslate, @TPyDelphiStyledControl.Set_AutoTranslate, + 'Specifies whether the control''s text should be translated', nil); + AddGetSet('AdjustSizeValue', @TPyDelphiStyledControl.Get_AdjustSizeValue, nil, + 'Updates the width and height of this control according to its current style', nil); + AddGetSet('AdjustType', @TPyDelphiStyledControl.Get_AdjustType, nil, + 'Determines if and how the width and height of this control should be ' + + 'modified to take the fixed space dictated by the style of this control', nil); + AddGetSet('StyleState', @TPyDelphiStyledControl.Get_StyleState, nil, + 'This property allows you to define the current state of style', nil); + end; +end; + +class procedure TPyDelphiStyledControl.RegisterMethods(PythonType: TPythonType); +begin + inherited; + PythonType.AddMethod('ApplyStyleLookup', @TPyDelphiStyledControl.ApplyStyleLookup_Wrapper, + 'TStyledControl.ApplyStyleLookup()'#10 + + 'Gets and applies the style of a TStyledControl.'); + PythonType.AddMethod('NeedStyleLookup', @TPyDelphiStyledControl.NeedStyleLookup_Wrapper, + 'TStyledControl.NeedStyleLookup()'#10 + + 'Call this procedure to indicate that this control requires to get and apply its style lookup.'); + PythonType.AddMethod('Inflate', @TPyDelphiStyledControl.Inflate_Wrapper, + 'TStyledControl.Inflate()'#10 + + 'Call this procedure to get and apply its style lookup.'); +end; + +procedure TPyDelphiStyledControl.SetDelphiObject(const Value: TStyledControl); +begin + inherited DelphiObject := Value; +end; + +function TPyDelphiStyledControl.Set_AutoTranslate(AValue: PPyObject; + AContext: Pointer): integer; +var + LValue: Boolean; +begin + Adjust(@Self); + if CheckBoolAttribute(AValue, 'AutoTranslate', LValue) then + begin + DelphiObject.AutoTranslate := LValue; + Result := 0; + end + else + Result := -1; +end; + +function TPyDelphiStyledControl.Set_StyleLookup(AValue: PPyObject; + AContext: Pointer): integer; +var + LValue: string; +begin + if CheckStrAttribute(AValue, 'StyleLookup', LValue) then + with GetPythonEngine do begin + Adjust(@Self); + DelphiObject.StyleLookup := LValue; + Result := 0; + end + else + Result := -1; +end; + initialization RegisteredUnits.Add(TControlsRegistration.Create); diff --git a/Source/fmx/WrapFmxTypes.pas b/Source/fmx/WrapFmxTypes.pas index 3d9ddf50..0a649307 100644 --- a/Source/fmx/WrapFmxTypes.pas +++ b/Source/fmx/WrapFmxTypes.pas @@ -34,6 +34,28 @@ TPyDelphiPointF = class(TPyObject) property Value : TPointF read FValue write FValue; end; + TPyDelphiSizeF = class(TPyObject) + private + FValue: TSizeF; + protected + // Exposed Getters + function Get_Width(Acontext: Pointer): PPyObject; cdecl; + function Get_Height(Acontext: Pointer): PPyObject; cdecl; + // Exposed Setters + function Set_Width(AValue: PPyObject; AContext: Pointer): integer; cdecl; + function Set_Height(AValue: PPyObject; AContext: Pointer): integer; cdecl; + public + constructor CreateWith(APythonType: TPythonType; args: PPyObject); override; + + function Compare(obj: PPyObject): Integer; override; + function Repr: PPyObject; override; + + class procedure RegisterGetSets(PythonType: TPythonType); override; + class procedure SetupType(PythonType: TPythonType); override; + + property Value : TSizeF read FValue write FValue; + end; + TPyDelphiFmxObject = class(TPyDelphiComponent) private function GetDelphiObject: TFmxObject; @@ -51,9 +73,32 @@ TPyDelphiFmxObject = class(TPyDelphiComponent) property DelphiObject: TFmxObject read GetDelphiObject write SetDelphiObject; end; + TPyDelphiPosition = class(TPyDelphiPersistent) + private + function GetDelphiObject: TPosition; + procedure SetDelphiObject(const Value: TPosition); + protected + //Exposed Getters + function Get_X(Acontext: Pointer): PPyObject; cdecl; + function Get_Y(Acontext: Pointer): PPyObject; cdecl; + function Get_Point(Acontext: Pointer): PPyObject; cdecl; + //Exposed Setters + function Set_X(AValue: PPyObject; AContext: Pointer): integer; cdecl; + function Set_Y(AValue: PPyObject; AContext: Pointer): integer; cdecl; + function Set_Point(AValue: PPyObject; AContext: Pointer): integer; cdecl; + public + class function DelphiObjectClass: TClass; override; + class procedure RegisterMethods(PythonType: TPythonType); override; + class procedure RegisterGetSets(PythonType: TPythonType); override; + // Properties + property DelphiObject: TPosition read GetDelphiObject write SetDelphiObject; + end; + {Helper functions} function WrapPointF(APyDelphiWrapper: TPyDelphiWrapper; const APoint : TPointF) : PPyObject; + function WrapSizeF(APyDelphiWrapper: TPyDelphiWrapper; const ASize : TSizeF) : PPyObject; function CheckPointFAttribute(AAttribute : PPyObject; const AAttributeName : string; out AValue : TPointF) : Boolean; + function CheckSizeFAttribute(AAttribute : PPyObject; const AAttributeName : string; out AValue : TSizeF) : Boolean; implementation @@ -185,7 +230,9 @@ procedure TTypesRegistration.RegisterWrappers( begin inherited; APyDelphiWrapper.RegisterHelperType(TPyDelphiPointF); + APyDelphiWrapper.RegisterHelperType(TPyDelphiSizeF); APyDelphiWrapper.RegisterDelphiWrapper(TPyDelphiFmxObject); + APyDelphiWrapper.RegisterDelphiWrapper(TPyDelphiPosition); end; { Helper functions } @@ -198,6 +245,15 @@ function WrapPointF(APyDelphiWrapper : TPyDelphiWrapper; const APoint : TPointF) (PythonToDelphi(Result) as TPyDelphiPointF).Value := APoint; end; +function WrapSizeF(APyDelphiWrapper: TPyDelphiWrapper; const ASize : TSizeF) : PPyObject; +var + LType : TPythonType; +begin + LType := APyDelphiWrapper.GetHelperType('SizeFType'); + Result := LType.CreateInstance; + (PythonToDelphi(Result) as TPyDelphiSizeF).Value := ASize; +end; + function CheckPointFAttribute(AAttribute : PPyObject; const AAttributeName : string; out AValue : TPointF) : Boolean; begin with GetPythonEngine do @@ -217,6 +273,25 @@ function CheckPointFAttribute(AAttribute : PPyObject; const AAttributeName : str end; end; +function CheckSizeFAttribute(AAttribute : PPyObject; const AAttributeName : string; out AValue : TSizeF) : Boolean; +begin + with GetPythonEngine do + begin + if IsDelphiObject(AAttribute) and (PythonToDelphi(AAttribute) is TPyDelphiSizeF) then + begin + AValue := TPyDelphiSizeF(PythonToDelphi(AAttribute)).Value; + Result := True; + end + else + begin + Result := False; + with GetPythonEngine do + PyErr_SetString (PyExc_AttributeError^, + PAnsiChar(AnsiString(Format('%s receives only SizeF objects', [AAttributeName])))); + end; + end; +end; + { TPyDelphiFmxObject } class function TPyDelphiFmxObject.DelphiObjectClass: TClass; @@ -267,6 +342,203 @@ function TPyDelphiFmxObject.Set_Parent(AValue: PPyObject; Result := -1; end; +{ TPyDelphiPosition } + +class function TPyDelphiPosition.DelphiObjectClass: TClass; +begin + Result := TPosition; +end; + +function TPyDelphiPosition.GetDelphiObject: TPosition; +begin + Result := TPosition(inherited DelphiObject); +end; + +function TPyDelphiPosition.Get_Point(Acontext: Pointer): PPyObject; +begin + Adjust(@Self); + Result := WrapPointF(PyDelphiWrapper, DelphiObject.Point); +end; + +function TPyDelphiPosition.Get_X(Acontext: Pointer): PPyObject; +begin + Adjust(@Self); + Result := GetPythonEngine.PyFloat_FromDouble(DelphiObject.X); +end; + +function TPyDelphiPosition.Get_Y(Acontext: Pointer): PPyObject; +begin + Adjust(@Self); + Result := GetPythonEngine.PyFloat_FromDouble(DelphiObject.Y); +end; + +class procedure TPyDelphiPosition.RegisterGetSets(PythonType: TPythonType); +begin + inherited; + with PythonType do begin + AddGetSet('X', @TPyDelphiPosition.Get_X, @TPyDelphiPosition.Set_X, + 'Provides access to the X coordinate of a control inside its parent', nil); + AddGetSet('Y', @TPyDelphiPosition.Get_Y, @TPyDelphiPosition.Set_Y, + 'Provides access to the Y coordinate of a control inside its parent', nil); + AddGetSet('Point', @TPyDelphiPosition.Get_Point, @TPyDelphiPosition.Set_Point, + 'Provides access to the position of a control inside its parent', nil); + end; +end; + +class procedure TPyDelphiPosition.RegisterMethods(PythonType: TPythonType); +begin + inherited; +end; + +procedure TPyDelphiPosition.SetDelphiObject(const Value: TPosition); +begin + inherited DelphiObject := Value; +end; + +function TPyDelphiPosition.Set_Point(AValue: PPyObject; + AContext: Pointer): integer; +var + LValue: TPointF; +begin + Adjust(@Self); + if CheckPointFAttribute(AValue, 'Point', LValue) then + begin + DelphiObject.Point := LValue; + Result := 0; + end + else + Result := -1; +end; + +function TPyDelphiPosition.Set_X(AValue: PPyObject; AContext: Pointer): integer; +var + x: double; +begin + if CheckFloatAttribute(AValue, 'X', x) then + with GetPythonEngine do begin + Adjust(@Self); + DelphiObject.X := x; + Result := 0; + end + else + Result := -1; +end; + +function TPyDelphiPosition.Set_Y(AValue: PPyObject; AContext: Pointer): integer; +var + y: double; +begin + if CheckFloatAttribute(AValue, 'Y', y) then + with GetPythonEngine do begin + Adjust(@Self); + DelphiObject.Y := y; + Result := 0; + end + else + Result := -1; +end; + +{ TPyDelphiSizeF } + +function TPyDelphiSizeF.Compare(obj: PPyObject): Integer; +var + LOther : TPyDelphiSizeF; +begin + if IsDelphiObject(obj) and (PythonToDelphi(obj) is TPyDelphiPointF) then + begin + LOther := TPyDelphiSizeF(PythonToDelphi(obj)); + Result := CompareValue(Value.Width, LOther.Value.Width); + if Result = 0 then + Result := CompareValue(Value.Height, LOther.Value.Height); + end + else + Result := 1; +end; + +constructor TPyDelphiSizeF.CreateWith(APythonType: TPythonType; + args: PPyObject); +var + LWidth, LHeight : single; +begin + inherited; + if APythonType.Engine.PyArg_ParseTuple(args, 'ff:Create', @LWidth, @LHeight) <> 0 then + begin + FValue.Width := LWidth; + FValue.Height := LHeight; + end +end; + +function TPyDelphiSizeF.Get_Height(Acontext: Pointer): PPyObject; +begin + Adjust(@Self); + Result := GetPythonEngine.PyFloat_FromDouble(Value.Height); +end; + +function TPyDelphiSizeF.Get_Width(Acontext: Pointer): PPyObject; +begin + Adjust(@Self); + Result := GetPythonEngine.PyFloat_FromDouble(Value.Width); +end; + +class procedure TPyDelphiSizeF.RegisterGetSets(PythonType: TPythonType); +begin + inherited; + with PythonType do + begin + AddGetSet('Width', @TPyDelphiSizeF.Get_Width, @TPyDelphiSizeF.Set_Width, + 'Provides access to the width of a sizef', nil); + AddGetSet('Height', @TPyDelphiSizeF.Get_Height, @TPyDelphiSizeF.Set_Height, + 'Provides access to the height of a sizef', nil); + end; +end; + +function TPyDelphiSizeF.Repr: PPyObject; +begin + Result := GetPythonEngine.PyUnicodeFromString(Format('', + [Value.Width, Value.Height])); +end; + +class procedure TPyDelphiSizeF.SetupType(PythonType: TPythonType); +begin + inherited; + PythonType.TypeName := 'SizeF'; + PythonType.Name := string(PythonType.TypeName) + 'Type'; + PythonType.TypeFlags := PythonType.TypeFlags + [tpfBaseType]; + PythonType.GenerateCreateFunction := False; + PythonType.DocString.Text := 'wrapper for Delphi FMX TSizeF type'; + PythonType.Services.Basic := [bsGetAttrO, bsSetAttrO, bsRepr, bsStr, bsRichCompare]; +end; + +function TPyDelphiSizeF.Set_Height(AValue: PPyObject; + AContext: Pointer): integer; +var + LValue: double; +begin + if CheckFloatAttribute(AValue, 'Height', LValue) then + with GetPythonEngine do begin + Adjust(@Self); + FValue.Height := LValue; + Result := 0; + end + else + Result := -1; +end; + +function TPyDelphiSizeF.Set_Width(AValue: PPyObject; + AContext: Pointer): integer; +var + LValue: double; +begin + if CheckFloatAttribute(AValue, 'Width', LValue) then + with GetPythonEngine do begin + Adjust(@Self); + FValue.Width := LValue; + Result := 0; + end + else + Result := -1; +end; + initialization RegisteredUnits.Add(TTypesRegistration.Create);