* Ability to set onTouchDown event

* Outlets and Objects may not have the same ID

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@2637 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
loesje_ 2013-01-27 10:12:50 +00:00
parent 0fa9d2fa95
commit a06ba35698
2 changed files with 271 additions and 14 deletions

View File

@ -103,6 +103,8 @@ type
NSObject = class;
tiOSFakeComponent = class(TComponent)
private
FStoredEvents: TStringList;
FAcceptChildsAtDesignTime: boolean;
FChilds: TFPList; // list of tiOSFakeComponent
FTop: integer;
@ -124,6 +126,7 @@ type
function GetXIBConnectionRecords: TDOMElement;
function GetNextObjectID: integer;
function GetXIBConnection(ASourceRef, ADestinationRef: int64; ConnectionType: TiOSXIBConnectionType; CreateIfNotExists: boolean): TDOMElement;
function FindComponentByRef(ARef: int64): tiOSFakeComponent;
function FindOrderdObjectByRef(ARef: int64): TDOMElement;
protected
procedure SetXIBObjectElement(const AValue: TDOMElement);
@ -367,11 +370,13 @@ type
UIButton = class(UIView)
private
FNSNextKeyView: UIView;
FonTouchDown: TCocoaEvent;
FTextColor: TColor;
function GetonTouchDown: TCocoaEvent;
procedure SetonTouchDown(AValue: TCocoaEvent);
protected
procedure WriteToDomElement(AnObjectDomElement: TDOMElement); override;
function WriteToConnectionRecords(AnObjectDomElement: TDOMElement): TDOMElement; override;
procedure DefineProperties(Filer: TFiler); override;
public
procedure InitializeDefaults; override;
constructor Create(AOwner: TComponent); override;
@ -380,7 +385,7 @@ type
property NSNextKeyView: UIView read FNSNextKeyView write FNSNextKeyView;
published
property TextColor: TColor read FTextColor write FTextColor;
property onTouchDown: TCocoaEvent read FonTouchDown write FonTouchDown;
property onTouchDown: TCocoaEvent read GetonTouchDown write SetonTouchDown;
end;
{ UILabel }
@ -621,9 +626,6 @@ uses
PropEdits,
base64;
var
GConnectionID: integer;
function FindKeyNode(AParentNode: TDOMNode; NodeName, Key: string): TDOMElement;
var
ANode: TDOMNode;
@ -2072,9 +2074,9 @@ begin
begin
SourceElement := FindKeyNode(AnOutletElement, 'reference', 'source');
DestElement := FindKeyNode(AnOutletElement, 'reference', 'destination');
if assigned(SourceElement) and assigned(DestElement) and
(SourceElement.AttribStrings['ref']=IntToStr(ASourceRef)) and
(DestElement.AttribStrings['ref']=IntToStr(ADestinationRef)) then
if assigned(SourceElement) and (SourceElement.AttribStrings['ref']=IntToStr(ASourceRef)) and
((assigned(DestElement) and (DestElement.AttribStrings['ref']=IntToStr(ADestinationRef))) or
(ConnectionType=ctEvent)) then
begin
if ((ConnectionType=ctOutlet) and (AnOutletElement.AttribStrings['class']='IBCocoaTouchOutletConnection')) or
((ConnectionType=ctEvent) and (AnOutletElement.AttribStrings['class']='IBCocoaTouchEventConnection')) then
@ -2100,10 +2102,29 @@ begin
SourceElement.AttribStrings['ref'] := IntToStr(ASourceRef);
DestElement := GetKeyNode(AnOutletElement,'reference','destination');
DestElement.AttribStrings['ref'] := IntToStr(ADestinationRef);
if ConnectionType=ctEvent then
GetKeyNode(AnOutletElement,'int', 'IBEventType').TextContent := '1';
result := AnOutletElement;
GetKeyNode(AnElement,'int','connectionID').TextContent:=IntToStr(GConnectionID);
inc(GConnectionID);
GetKeyNode(AnElement,'int','connectionID').TextContent:=IntToStr(GetNextObjectID);
end;
end;
function tiOSFakeComponent.FindComponentByRef(ARef: int64): tiOSFakeComponent;
var
i: integer;
begin
if Ref=ARef then
result := self
else
begin
for i := 0 to ChildCount-1 do
begin
result := Children[i].FindComponentByRef(ARef);
if assigned(result) then
exit;
end;
result := nil;
end;
end;
@ -2320,6 +2341,7 @@ end;
procedure tiOSFakeComponent.AddChild(const AValue: tiOSFakeComponent);
var
AComp: UIView;
AnElement: TDOMElement;
begin
FChilds.Add(AValue);
AddChildToDom(AValue);
@ -2328,6 +2350,10 @@ begin
AComp := UIView(AValue).ObtainSuperview;
if AComp<>AValue then
UIView(AValue).NSSuperview := AComp as UIView;
AnElement := GetXIBConnection(GetNSObject.Ref, AValue.Ref, ctOutlet, true);
AnElement := GetKeyNode(AnElement,'string','label');
AnElement.TextContent:=AValue.Name;
end;
end;
@ -2638,6 +2664,13 @@ begin
AnElement := FindOrderdObjectByRef(Ref);
AnElement := GetKeyNode(AnElement, 'string','objectName');
AnElement.TextContent := NewName;
AnElement := GetXIBConnection(GetNSObject.Ref, Ref, ctOutlet, false);
if assigned(AnElement) then
begin
AnElement := GetKeyNode(AnElement, 'string', 'label');
AnElement.TextContent:=NewName;
end;
end;
end;
@ -2662,8 +2695,8 @@ begin
AddIBReference(IBConnectionElement,'source','664661524');
AddIBReference(IBConnectionElement,'destination',self,True);
end;
AddIBInt(IBConnectionRecordElement,'connectionID',GConnectionID);
inc(GConnectionID);
//AddIBInt(IBConnectionRecordElement,'connectionID',GConnectionID);
//inc(GConnectionID);
if AEventType<>'' then
AddIBInt(IBConnectionElement,'IBEventType',StrToInt64Def(AEventType,1));
end;
@ -2750,6 +2783,9 @@ constructor tiOSFakeComponent.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FChilds:=TFPList.Create;
FStoredEvents := TStringList.Create;
FStoredEvents.Sorted:=true;
FStoredEvents.Duplicates:=dupIgnore;
end;
destructor tiOSFakeComponent.Destroy;
@ -2757,6 +2793,7 @@ begin
Parent:=nil;
while ChildCount>0 do Children[ChildCount-1].Free;
FreeAndNil(FChilds);
FreeAndNil(FStoredEvents);
inherited Destroy;
end;
@ -3382,6 +3419,81 @@ end;
{ UIButton }
function UIButton.GetonTouchDown: TCocoaEvent;
var
ConnectionElement: TDOMElement;
AnComponent: tiOSFakeComponent;
AnElement: TDOMElement;
s: shortstring;
i: integer;
begin
ConnectionElement:=GetXIBConnection(Ref, 0, ctEvent, false);
if assigned(ConnectionElement) then
begin
AnElement:=FindKeyNode(ConnectionElement,'reference','destination');
AnComponent:=GetNSObject.FindComponentByRef(StrToInt(AnElement.AttribStrings['ref']));
AnElement:=FindKeyNode(ConnectionElement,'string','label');
s := AnElement.TextContent;
i := pos(':',s);
if i > 0 then
s := copy(s,1,i-1);
i := FStoredEvents.IndexOf(s);
if i > -1 then
begin
TMethod(Result).Code := nil;
TMethod(Result).Data := FStoredEvents.Objects[i];
end
else
begin
TMethod(Result).Data := AnComponent;
TMethod(Result).Code := AnComponent.MethodAddress(s);
end;
end
else
result := nil;
end;
procedure UIButton.SetonTouchDown(AValue: TCocoaEvent);
var
AnElement: TDOMElement;
AnComponent: TObject;
AMethodName: shortstring;
ARef: int64;
s: string;
begin
//if (GetonTouchDown=AValue) then
// Exit;
if assigned(TMethod(AValue).Data) then
begin
//AnComponent := Tobject(TMethod(AValue).Data) as TComponent;
//AMethodName:=AnComponent.MethodName(TMethod(AValue).Code);
if TMethod(AValue).Code=pointer(1) then
Exit;
AnComponent := Tobject(TMethod(AValue).Data);
AMethodName := GlobalDesignHook.GetMethodName(TMethod(AValue), nil);
if (AnComponent is tiOSFakeComponent) then
ARef := tiOSFakeComponent(AnComponent).Ref
else
ARef := GetNSObject.Ref;
AnElement:=GetXIBConnection(ref, ARef, ctEvent, True);
AnElement:=GetKeyNode(AnElement, 'string', 'label');
AnElement.TextContent:=AMethodName + ':';
FStoredEvents.AddObject(AMethodName,TObject(TMethod(AValue).Data));
end
else
begin
AnElement:=GetXIBConnection(Ref, 0, ctEvent, False);
if assigned(AnElement) then
AnElement.ParentNode.ParentNode.RemoveChild(AnElement.ParentNode);
end;
end;
procedure UIButton.WriteToDomElement(AnObjectDomElement: TDOMElement);
begin
@ -3410,6 +3522,41 @@ begin
writeln('AA- Geen Touchdown ' + self.Name);
end;
procedure UIButton.DefineProperties(Filer: TFiler);
var
AnElement: TDOMElement;
AnComponent: TObject;
AMethodName: shortstring;
ARef: int64;
s: string;
Reader: TXIBReader;
Handled: boolean;
ConnectionElement: TDOMElement;
i: integer;
begin
inherited DefineProperties(Filer);
if filer is TXIBReader then
begin
ConnectionElement:=GetXIBConnection(Ref, 0, ctEvent, false);
if assigned(ConnectionElement) then
begin
AnElement:=FindKeyNode(ConnectionElement,'reference','destination');
AnComponent:=GetNSObject.FindComponentByRef(StrToInt(AnElement.AttribStrings['ref']));
AnElement:=FindKeyNode(ConnectionElement,'string','label');
s := AnElement.TextContent;
i := pos(':',s);
if i > 0 then
s := copy(s,1,i-1);
Reader := TXIBReader(Filer);
Reader.OnSetMethodProperty(Reader, Self, GetPropInfo(self,'onTouchDown'),s,Handled);
end
end;
end;
procedure UIButton.InitializeDefaults;
begin
inherited InitializeDefaults;
@ -3427,7 +3574,5 @@ begin
result := 'IBUIButton';
end;
initialization
GConnectionID:=50;
end.

View File

@ -87,10 +87,22 @@ type
class function FormClass: TComponentClass; override;
end;
{ TiOSMethodPropertyEditor }
TiOSMethodPropertyEditor = class(TMethodPropertyEditor)
public
procedure GetValues(Proc: TGetStrProc); override;
procedure SetValue(const NewValue: ansistring); override;
end;
procedure Register;
implementation
uses
ObjInspStrConsts;
procedure Register;
procedure SetFakeUnitname(AClass: TClass);
@ -121,6 +133,8 @@ begin
RegisterClass(UIViewController);
RegisterClass(UINavigationBar);
RegisterPropertyEditor(FindPropInfo(UIButton, 'onTouchDown')^.PropType , tiOSFakeComponent,'onTouchDown',TiOSMethodPropertyEditor);
// This is a hack to overwrite the unitname RTTI-information of these objects.
// This is to make sure that the Codetools add the right unit-name to the
// source when an object is added to the NIB-file.
@ -136,6 +150,104 @@ begin
SetFakeUnitname(UIProgressView);
end;
{ TiOSMethodPropertyEditor }
procedure TiOSMethodPropertyEditor.GetValues(Proc: TGetStrProc);
begin
proc(oisNone);
end;
procedure TiOSMethodPropertyEditor.SetValue(const NewValue: ansistring);
var
CreateNewMethod: Boolean;
CurValue: string;
NewMethodExists, NewMethodIsCompatible, NewMethodIsPublished,
NewIdentIsMethod: boolean;
IsNil: Boolean;
NewMethod: TMethod;
begin
CurValue := GetValue;
if CurValue = NewValue then exit;
//DebugLn('### TMethodPropertyEditor.SetValue A OldValue="',CurValue,'" NewValue=',NewValue);
IsNil := (NewValue='') or (NewValue=oisNone);
if (not IsNil) and (not IsValidIdent(NewValue)) then
begin
MessageDlg(oisIncompatibleIdentifier,
Format(oisIsNotAValidMethodName,['"',NewValue,'"']), mtError,
[mbCancel, mbIgnore], 0);
exit;
end;
NewMethodExists := (not IsNil); {and
PropertyHook.CompatibleMethodExists(NewValue, GetInstProp,
NewMethodIsCompatible, NewMethodIsPublished, NewIdentIsMethod);}
//DebugLn('### TMethodPropertyEditor.SetValue B NewMethodExists=',NewMethodExists,' NewMethodIsCompatible=',NewMethodIsCompatible,' ',NewMethodIsPublished,' ',NewIdentIsMethod);
{ if NewMethodExists then
begin
if not NewIdentIsMethod then
begin
if MessageDlg(oisIncompatibleIdentifier,
Format(oisTheIdentifierIsNotAMethodPressCancelToUndoPressIgn,
['"', NewValue, '"', LineEnding, LineEnding]),
mtWarning, [mbCancel, mbIgnore], 0)<>mrIgnore
then
exit;
end;
if not NewMethodIsPublished then
begin
if MessageDlg(oisIncompatibleMethod,
Format(oisTheMethodIsNotPublishedPressCancelToUndoPressIgnor,
['"', NewValue, '"', LineEnding, LineEnding]),
mtWarning, [mbCancel, mbIgnore], 0)<>mrIgnore
then
exit;
end;
if not NewMethodIsCompatible then
begin
if MessageDlg(oisIncompatibleMethod,
Format(oisTheMethodIsIncompatibleToThisEventPressCancelToUnd,
['"', NewValue, '"', GetName, LineEnding, LineEnding]),
mtWarning, [mbCancel, mbIgnore], 0)<>mrIgnore
then
exit;
end;
end; }
//DebugLn('### TMethodPropertyEditor.SetValue C');
if IsNil then
begin
NewMethod.Data := nil;
NewMethod.Code := nil;
SetMethodValue(NewMethod);
end
else
if IsValidIdent(CurValue) and
not NewMethodExists and
not PropertyHook.MethodFromAncestor(GetMethodValue) then
begin
// rename the method
// Note:
// All other not selected properties that use this method, contain just
// the TMethod record. So, changing the name in the jitform will change
// all other event names in all other components automatically.
PropertyHook.RenameMethod(CurValue, NewValue)
end else
begin
//DebugLn('### TMethodPropertyEditor.SetValue E');
CreateNewMethod := not NewMethodExists;
SetMethodValue(
PropertyHook.CreateMethod(NewValue, GetPropType,
GetComponent(0), GetPropertyPath(0)));
//DebugLn('### TMethodPropertyEditor.SetValue F NewValue=',GetValue);
if CreateNewMethod then
begin
//DebugLn('### TMethodPropertyEditor.SetValue G');
PropertyHook.ShowMethod(NewValue);
end;
end;
//DebugLn('### TMethodPropertyEditor.SetValue END NewValue=',GetValue);
end;
{ TNSObjectDesignerMediator }
constructor TNSObjectDesignerMediator.Create(AOwner: TComponent);