diff --git a/components/iosdesigner/MainWindow_iPhone.template b/components/iosdesigner/MainWindow_iPhone.template
new file mode 100644
index 000000000..6f9a4d4b2
--- /dev/null
+++ b/components/iosdesigner/MainWindow_iPhone.template
@@ -0,0 +1,100 @@
+
+
+
+ 1280
+ 11D50
+ 2182
+ 1138.32
+ 568.00
+
+
+
+
+
+
+
+
+ YES
+
+ AppDelegate
+ NSObject
+
+ window
+ UIWindow
+
+
+ window
+
+ window
+ UIWindow
+
+
+
+ IBProjectSource
+ ./Classes/AppDelegate.h
+
+
+
+
+ 0
+ IBCocoaTouchFramework
+
+ com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3
+
+
+ YES
+ 3
+ 1181
+
+
diff --git a/components/iosdesigner/README.txt b/components/iosdesigner/README.txt
new file mode 100644
index 000000000..8170d86d9
--- /dev/null
+++ b/components/iosdesigner/README.txt
@@ -0,0 +1,2 @@
+This package contains a designer to create NIB-files which can be integrated
+into an iOS application.
diff --git a/components/iosdesigner/ios_views.pas b/components/iosdesigner/ios_views.pas
new file mode 100644
index 000000000..b71d1108d
--- /dev/null
+++ b/components/iosdesigner/ios_views.pas
@@ -0,0 +1,1697 @@
+{ Fake components to mimic iOS's views in the Lazarus designer
+
+ Copyright (C) 2012 Joost van der Sluis/CNOC joost@cnoc.nl
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version with the following modification:
+
+ As a special exception, the copyright holders of this library give you
+ permission to link this library with independent modules to produce an
+ executable, regardless of the license terms of these independent modules,and
+ to copy and distribute the resulting executable under terms of your choice,
+ provided that you also meet, for each linked independent module, the terms
+ and conditions of the license of that module. An independent module is a
+ module which is not derived from or based on this library. If you modify
+ this library, you may extend this exception to your version of the library,
+ but you are not obligated to do so. If you do not wish to do so, delete this
+ exception statement from your version.
+
+ This program is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
+ for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+}
+// The name of this unit has to be of the same length as the name of the
+// iPhoneAll unit.
+unit iOS_Views;
+
+{$mode objfpc}{$H+}
+{$modeswitch ObjectiveC1}
+
+interface
+
+uses
+ Classes, SysUtils, Math, types, DOM, XMLWrite, Graphics;
+
+type
+ IMyWidgetDesigner = interface(IUnknown)
+ procedure InvalidateRect(Sender: TObject; ARect: TRect; Erase: boolean);
+ function CreateComponent(ParentComp: TComponent;
+ TypeClass: TComponentClass;
+ const AUnitName: shortstring;
+ X,Y,W,H: Integer;
+ DisableAutoSize: boolean): TComponent;
+ end;
+
+ TiOSFakeFontType = (ftNotSet, ftSystem, ftSystemBold, ftSystemItalic);
+
+ { TiOSFakeFontDescription }
+
+ TiOSFakeFontDescription = class(TPersistent)
+ private
+ FFontType: TiOSFakeFontType;
+ FpointSize: double;
+ public
+ constructor Create;
+ published
+ property FontType: TiOSFakeFontType read FFontType write FFontType;
+ property pointSize: double read FpointSize write FpointSize;
+ end;
+
+ { tiOSFakeComponent }
+
+ tiOSWriteDomMethod = function (AnObjectDomElement: TDOMElement): TDOMElement of object;
+
+ tiOSFakeComponent = class(TComponent)
+ private
+ FAcceptChildsAtDesignTime: boolean;
+ FChilds: TFPList; // list of tiOSFakeComponent
+ FHeight: integer;
+ FLeft: integer;
+ FObjectID: integer;
+ FParent: tiOSFakeComponent;
+ FTop: integer;
+ FWidth: integer;
+ // iOS
+ FRef: integer;
+ function ElementToString(AWriteDomMethod: tiOSWriteDomMethod): string;
+ protected
+ procedure SetParentComponent(Value: TComponent); override;
+ procedure SetParent(const AValue: tiOSFakeComponent);
+ function HasParent: Boolean; override;
+ function GetParentComponent: TComponent; override;
+ procedure SetHeight(const AValue: integer);
+ procedure SetLeft(const AValue: integer);
+ procedure SetTop(const AValue: integer);
+ procedure SetWidth(const AValue: integer);
+ function GetChilds(Index: integer): tiOSFakeComponent;
+ procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
+ procedure InternalInvalidateRect(ARect: TRect; Erase: boolean); virtual;
+ // iOS
+ procedure AddConnectionRecord(AnObjectDomElement: TDOMElement; AConnectionType, ALabel, AEventType: string);
+ procedure WriteToDomElement(AnObjectDomElement: TDOMElement); virtual;
+ function WriteToObject(AnObjectDomElement: TDOMElement): TDOMElement; virtual;
+ function WriteToConnectionRecords(AnObjectDomElement: TDOMElement): TDOMElement; virtual;
+ function WriteToObjectRecord(AnObjectDomElement: TDOMElement): TDOMElement; virtual;
+ class function GetIBClassName: string; virtual;
+ function GetDesigner: IMyWidgetDesigner; virtual;
+ function GetHeight: integer; virtual;
+ function GetLeft: integer; virtual;
+ function GetTop: integer; virtual;
+ function GetWidth: integer; virtual;
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ procedure InitializeDefaultChildren; virtual;
+ procedure paint(ACanvas: TCanvas); virtual;
+ procedure SetBounds(NewLeft, NewTop, NewWidth, NewHeight: integer); virtual;
+ procedure InvalidateRect(ARect: TRect; Erase: boolean);
+ procedure Invalidate;
+ function ChildCount: integer;
+ property Parent: tiOSFakeComponent read FParent write SetParent;
+ property Children[Index: integer]: tiOSFakeComponent read GetChilds;
+ property AcceptChildsAtDesignTime: boolean read FAcceptChildsAtDesignTime;
+ // iOS
+ function getAsXIBObject: string; virtual;
+ function getConnectionRecords: string; virtual;
+ function getObjectRecord: string; virtual;
+ property Ref: integer read FRef write FRef;
+ property ObjectID: integer read FObjectID;
+ // Dom utils
+ function AddElement(ADomNode: TDOMElement; AName: string): TDOMElement;
+ function AddIBInt(ADomNode: TDOMElement; APropName: string; APropValue: integer; ADefaultValue: integer = MaxInt): TDOMElement;
+ function AddIBDouble(ADomNode: TDOMElement; APropName: string; APropValue: double): TDOMElement;
+ function AddIBFloat(ADomNode: TDOMElement; APropName: string; APropValue: double; ADefaultValue: double = MaxFloat): TDOMElement;
+ function AddIBString(ADomNode: TDOMElement; APropName: string; APropValue: string): TDOMElement;
+ function AddIBReference(ADomNode: TDOMElement; APropName: string; APropValue: tiOSFakeComponent; ForceValue: boolean = false): TDOMElement;
+ function AddIBReference(ADomNode: TDOMElement; APropName: string; APropValue: string): TDOMElement;
+ function AddIBBoolean(ADomNode: TDOMElement; APropName: string; APropValue: Boolean): TDOMElement;
+ function AddIBBoolean(ADomNode: TDOMElement; APropName: string; APropValue: Boolean; ADefaultValue: boolean): TDOMElement;
+ function AddIBBytes(ADomNode: TDOMElement; APropName: string; APropValue: string): TDOMElement;
+ function AddIBObject(ADomNode: TDOMElement; APropName: string; AClass: string): TDOMElement;
+ function AddIBObject(ADomDocument: TXMLDocument; APropName: string; AClass: string): TDOMElement;
+ function AddIBColor(ADomNode: TDOMElement; APropName: string; AColor: TColor): TDOMElement;
+ function AddIBFontDescription(ADomNode: TDOMElement; APropName: string; AFontDescription: TiOSFakeFontDescription): TDOMElement;
+ published
+ property Left: integer read GetLeft write SetLeft;
+ property Top: integer read GetTop write SetTop;
+ property Width: integer read GetWidth write SetWidth;
+ property Height: integer read GetHeight write SetHeight;
+ end;
+
+ { UIView }
+
+ UIView = class(tiOSFakeComponent)
+ private
+ FCaption: string;
+ FNSNextResponder: UIView;
+ FOpaque: boolean;
+ FAlpha: double;
+ FBackgroundColor: TColor;
+ FHidden: boolean;
+ function GetNSSuperview: UIView;
+ procedure SetCaption(const AValue: string);
+ protected
+ procedure SetName(const NewName: TComponentName); override;
+ // Dom
+ procedure WriteToDomElement(AnObjectDomElement: TDOMElement); override;
+ public
+ constructor Create(AOwner: TComponent); override;
+ procedure paint(ACanvas: TCanvas); override;
+ class function GetIBClassName: string; override;
+ property NSSuperview: UIView read GetNSSuperview;
+ property NSNextResponder: UIView read FNSNextResponder write FNSNextResponder;
+ published
+ property Caption: string read FCaption write SetCaption;
+ property Opaque: boolean read FOpaque write FOpaque;
+ property BackgroundColor: TColor read FBackgroundColor write FBackgroundColor;
+ property Alpha: double read FAlpha write FAlpha;
+ property Hidden: boolean read FHidden write FHidden;
+ end;
+ TUIViewClass = class of UIView;
+
+ { NSObject }
+
+ NSObject = class(tiOSFakeComponent)
+ private
+ FDesigner: IMyWidgetDesigner;
+ FFilesOwnerClass: string;
+ FHiddenObjectOutletName: string;
+ FIsHiddenObject: boolean;
+ procedure GetXIBSaveParam(Sender: TObject; const ParamName: String; out AValue: String);
+ function IsNIBRoot: boolean;
+ function GetFilesOwnerID: string;
+ protected
+ function GetFlattenedProperties: string;
+ procedure InternalInvalidateRect(ARect: TRect; Erase: boolean); override;
+ public
+ constructor Create(AOwner: TComponent); override;
+ procedure SaveAsXIB(const Filename: string);
+ function getObjectRecord: string; override;
+ function getAsXIBObject: string; override;
+ function getConnectionRecords: string; override;
+ function GetDesigner: IMyWidgetDesigner; override;
+ property Designer: IMyWidgetDesigner read FDesigner write FDesigner;
+ published
+ property FilesOwnerClass: string read FFilesOwnerClass write FFilesOwnerClass stored IsNIBRoot;
+ property IsHiddenObject: boolean read FIsHiddenObject write FIsHiddenObject stored IsNIBRoot;
+ property HiddenObjectOutletName: string read FHiddenObjectOutletName write FHiddenObjectOutletName stored IsNIBRoot;
+ end;
+
+ UIResponder = class(NSObject);
+
+ { UIWindow }
+
+ UIWindow = class(UIView)
+ private
+ protected
+ procedure WriteToDomElement(AnObjectDomElement: TDOMElement); override;
+ procedure SetBounds(NewLeft, NewTop, NewWidth, NewHeight: integer); override;
+ public
+ constructor Create(AOwner: TComponent); override;
+ procedure paint(ACanvas: TCanvas); override;
+ class function GetIBClassName: string; override;
+ published
+ end;
+
+ { UIViewController }
+
+ UIViewController = class(tiOSFakeComponent)
+ protected
+ procedure WriteToDomElement(AnObjectDomElement: TDOMElement); override;
+ function GetHeight: integer; override;
+ function GetWidth: integer; override;
+ procedure SetBounds(NewLeft, NewTop, NewWidth, NewHeight: integer); override;
+ public
+ constructor Create(AOwner: TComponent); override;
+ class function GetIBClassName: string; override;
+ end;
+
+ { UINavigationBar }
+
+ UINavigationBar = class(UIView)
+ protected
+ procedure WriteToDomElement(AnObjectDomElement: TDOMElement); override;
+ procedure SetBounds(NewLeft, NewTop, NewWidth, NewHeight: integer); override;
+ procedure paint(ACanvas: TCanvas); override;
+ public
+ constructor Create(AOwner: TComponent); override;
+ class function GetIBClassName: string; override;
+ end;
+
+ { UINavigationItem }
+
+ UINavigationItem = class(UIView)
+ protected
+ function GetWidth: integer; override;
+ procedure SetBounds(NewLeft, NewTop, NewWidth, NewHeight: integer); override;
+ public
+ constructor Create(AOwner: TComponent); override;
+ class function GetIBClassName: string; override;
+ end;
+
+ { UINavigationController }
+
+ UINavigationController = class(UIViewController)
+ private
+ protected
+ procedure WriteToDomElement(AnObjectDomElement: TDOMElement); override;
+ procedure SetBounds(NewLeft, NewTop, NewWidth, NewHeight: integer); override;
+ public
+ constructor Create(AOwner: TComponent); override;
+ procedure InitializeDefaultChildren; override;
+ class function GetIBClassName: string; override;
+ published
+ end;
+
+ { UIButton }
+ id = ^objc_object;
+ TcocoaEvent = procedure(sender: id) of object;
+
+ UIButton = class(UIView)
+ private
+ FNSNextKeyView: UIView;
+ FonTouchDown: TCocoaEvent;
+ FTextColor: TColor;
+ protected
+ procedure WriteToDomElement(AnObjectDomElement: TDOMElement); override;
+ function WriteToConnectionRecords(AnObjectDomElement: TDOMElement): TDOMElement; override;
+ public
+ constructor Create(AOwner: TComponent); override;
+ class function GetIBClassName: string; override;
+
+ property NSNextKeyView: UIView read FNSNextKeyView write FNSNextKeyView;
+ published
+ property TextColor: TColor read FTextColor write FTextColor;
+ property onTouchDown: TCocoaEvent read FonTouchDown write FonTouchDown;
+ end;
+
+ { UILabel }
+ TLineBreaks = (lbWordWrap,lbCharacterMode,lbClip,lbTruncateHead,lbTruncateTail,lbTruncateMiddle);
+ TiOSFakeAlignment = (alLeft, alCenter, alRight);
+
+ UILabel = class(UIView)
+ private
+ FEnabled: boolean;
+ FFont: TiOSFakeFontDescription;
+ FHighlighted: boolean;
+ FLineBreaks: TLineBreaks;
+ FLines: integer;
+ FTextAlignment: TiOSFakeAlignment;
+ FTextColor: TColor;
+ procedure SetFont(AValue: TiOSFakeFontDescription);
+ protected
+ procedure WriteToDomElement(AnObjectDomElement: TDOMElement); override;
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ class function GetIBClassName: string; override;
+ procedure paint(ACanvas: TCanvas); override;
+ published
+ property Lines: integer read FLines write FLines;
+ property TextAlignment: TiOSFakeAlignment read FTextAlignment write FTextAlignment;
+ property TextColor: TColor read FTextColor write FTextColor;
+ property Font: TiOSFakeFontDescription read FFont write SetFont;
+ property Enabled: boolean read FEnabled write FEnabled;
+ property Highlighted: boolean read FHighlighted write FHighlighted;
+ property LineBreaks: TLineBreaks read FLineBreaks write FLineBreaks;
+ end;
+
+ { UITextField }
+
+ UITextField = class(UIView)
+ private
+ FPlaceholder: string;
+ FText: string;
+ FTextAlignment: TiOSFakeAlignment;
+ protected
+ procedure WriteToDomElement(AnObjectDomElement: TDOMElement); override;
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ class function GetIBClassName: string; override;
+ //procedure paint(ACanvas: TCanvas); override;
+ published
+ property Text: string read FText write FText;
+ property Placeholder: string read FPlaceholder write FPlaceholder;
+ property Alignment: TiOSFakeAlignment read FTextAlignment write FTextAlignment;
+ end;
+
+ TiOSFakeSeparatorStyle = (ssNone,ssSingleLine,ssSingleLineEtched);
+
+ { UITableView }
+
+ UITableView = class(UIView)
+ private
+ FClipSubviews: boolean;
+ FRowHeight: float;
+ FSectionFooterHeight: float;
+ FSectionHeaderHeight: float;
+ FSeparatorColor: TColor;
+ FSeparatorStyle: TiOSFakeSeparatorStyle;
+ protected
+ procedure WriteToDomElement(AnObjectDomElement: TDOMElement); override;
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ class function GetIBClassName: string; override;
+ published
+ property RowHeight: float read FRowHeight write FRowHeight;
+ property SectionHeaderHeight: float read FSectionHeaderHeight write FSectionHeaderHeight;
+ property SectionFooterHeight: float read FSectionFooterHeight write FSectionFooterHeight;
+ property SeparatorStyle: TiOSFakeSeparatorStyle read FSeparatorStyle write FSeparatorStyle;
+ property SeparatorColor: TColor read FSeparatorColor write FSeparatorColor;
+ property ClipSubviews: boolean read FClipSubviews write FClipSubviews;
+ end;
+
+ { UISearchBar }
+
+ UISearchBar = class(UIView)
+ private
+ FPlaceholder: string;
+ FPrompt: string;
+ FText: string;
+ protected
+ procedure WriteToDomElement(AnObjectDomElement: TDOMElement); override;
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ class function GetIBClassName: string; override;
+ published
+ property Text: string read FText write FText;
+ property Placeholder: string read FPlaceholder write FPlaceholder;
+ property Prompt: string read FPrompt write FPrompt;
+ end;
+
+ { UIProgressView }
+
+ TiOSFakeProgressViewStyle = (pvUIProgressViewStyleDefault,pvUIProgressViewStyleBar);
+
+ UIProgressView = class(UIView)
+ private
+ FProgress: float;
+ FprogressTintColor: TColor;
+ FProgressViewStyle: TiOSFakeProgressViewStyle;
+ FtrackTintColor: TColor;
+ protected
+ procedure WriteToDomElement(AnObjectDomElement: TDOMElement); override;
+ public
+ constructor Create(AOwner: TComponent); override;
+ class function GetIBClassName: string; override;
+ published
+ property progressViewStyle: TiOSFakeProgressViewStyle read FProgressViewStyle write FprogressViewStyle;
+ property progress: float read FProgress write FProgress;
+ property progressTintColor: TColor read FprogressTintColor write FprogressTintColor;
+ property trackTintColor: TColor read FtrackTintColor write FtrackTintColor;
+ end;
+
+
+implementation
+
+uses
+ fpTemplate,
+ variants, varutils,
+ typinfo,
+{$ifndef OutsideIDE}
+ MacroIntf,
+{$endif OutsideIDE}
+ PropEdits,
+ base64;
+
+var
+ GConnectionID: integer;
+
+{ UIProgressView }
+
+procedure UIProgressView.WriteToDomElement(AnObjectDomElement: TDOMElement);
+begin
+ inherited WriteToDomElement(AnObjectDomElement);
+ AddIBFloat(AnObjectDomElement,'IBUIProgress',FProgress);
+ AddIBInt(AnObjectDomElement,'IBUIProgressViewStyle',ord(progressViewStyle),0);
+ AddIBColor(AnObjectDomElement,'IBUIProgressTintColor',progressTintColor);
+ AddIBColor(AnObjectDomElement,'IBUITrackTintColor',trackTintColor);
+end;
+
+constructor UIProgressView.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FAcceptChildsAtDesignTime := false;
+ FprogressTintColor := clDefault;
+ FtrackTintColor := clDefault;
+end;
+
+class function UIProgressView.GetIBClassName: string;
+begin
+ Result:='IBUIProgressView';
+end;
+
+{ UINavigationItem }
+
+function UINavigationItem.GetWidth: integer;
+begin
+ if assigned(parent) then
+ result := parent.Width
+ else
+ result := 320;
+end;
+
+procedure UINavigationItem.SetBounds(NewLeft, NewTop, NewWidth, NewHeight: integer);
+begin
+ inherited SetBounds(Left, Top, Width, Height);
+end;
+
+constructor UINavigationItem.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FHeight:=44;
+end;
+
+class function UINavigationItem.GetIBClassName: string;
+begin
+ Result:='IBUINavigationItem';
+end;
+
+{ UIViewController }
+
+procedure UIViewController.WriteToDomElement(AnObjectDomElement: TDOMElement);
+var
+ ASubElement: TDOMElement;
+ i: Integer;
+begin
+ AddIBString(AnObjectDomElement,'targetRuntimeIdentifier','IBCocoaTouchFramework');
+
+ for i := 0 to ChildCount-1 do
+ begin
+ ASubElement := Children[i].WriteToObject(AnObjectDomElement);
+ if Children[i] is UIView then
+ ASubElement.AttribStrings['key']:='IBUIView'
+ else
+ ASubElement.AttribStrings['key']:=Children[i].GetIBClassName;
+ end;
+end;
+
+function UIViewController.GetHeight: integer;
+begin
+ if FHeight<>0 then
+ result := FHeight
+ else if assigned(parent) then
+ result := min(Parent.Height,480)
+ else
+ result := 480;
+end;
+
+function UIViewController.GetWidth: integer;
+begin
+ if FWidth <> 0 then
+ result := FWidth
+ else if assigned(parent) then
+ result := min(Parent.Width,320)
+ else
+ result := 320;
+end;
+
+procedure UIViewController.SetBounds(NewLeft, NewTop, NewWidth, NewHeight: integer);
+begin
+ if (FWidth<>0) or (FHeight<>0) or ((width=320) and (height=480)) then
+ inherited SetBounds(NewLeft, NewTop, Width, Height)
+ else
+ inherited SetBounds(Left, Top, Width, Height)
+end;
+
+constructor UIViewController.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FAcceptChildsAtDesignTime:=true;
+ FObjectID:=GConnectionID;
+ inc(GConnectionID);
+ FRef:=random(999999999);
+end;
+
+class function UIViewController.GetIBClassName: string;
+begin
+ Result:='IBUIViewController';
+end;
+
+{ UINavigationBar }
+
+procedure UINavigationBar.WriteToDomElement(AnObjectDomElement: TDOMElement);
+var
+ AnElement: TDOMElement;
+begin
+ inherited WriteToDomElement(AnObjectDomElement);
+ AnElement := AnObjectDomElement.FindNode('NSFrame') as TDOMElement;
+ if assigned(AnElement) then
+ AnElement.NodeValue:='{{0, -44}, {0, 44}}';
+end;
+
+procedure UINavigationBar.SetBounds(NewLeft, NewTop, NewWidth, NewHeight: integer);
+begin
+ inherited SetBounds(0, 0, 0, 0);
+end;
+
+procedure UINavigationBar.paint(ACanvas: TCanvas);
+begin
+ // Do not paint;
+end;
+
+constructor UINavigationBar.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FAcceptChildsAtDesignTime:=false;
+end;
+
+class function UINavigationBar.GetIBClassName: string;
+begin
+ Result:='IBUINavigationBar';
+end;
+
+{ UINavigationController }
+
+procedure UINavigationController.WriteToDomElement(AnObjectDomElement: TDOMElement);
+var
+ NavigationBarElement: TDOMElement;
+ ViewControllesArray: TDOMElement;
+ ViewController: TDOMElement;
+ NavigationItemElement: TDOMElement;
+ i: Integer;
+begin
+ AddIBString(AnObjectDomElement,'targetRuntimeIdentifier','IBCocoaTouchFramework');
+
+ ViewControllesArray := AddIBObject(AnObjectDomElement,'IBUIViewControllers','NSMutableArray');
+ AddIBBoolean(ViewControllesArray,'EncodedWithXMLCoder',true);
+
+ for i := 0 to ChildCount-1 do
+ begin
+ if Children[i] is UINavigationBar then
+ begin
+ NavigationBarElement := Children[i].WriteToObject(AnObjectDomElement);
+ NavigationBarElement.AttribStrings['key']:=Children[i].GetIBClassName;
+ end;
+ if children[i] is UIViewController then
+ begin
+ ViewController := children[i].WriteToObject(ViewControllesArray);
+ AddIBString(ViewController,'targetRuntimeIdentifier','IBCocoaTouchFramework');
+ AddIBReference(ViewController,'IBUIParentViewController',self,true);
+ end;
+ end;
+
+end;
+
+procedure UINavigationController.SetBounds(NewLeft, NewTop, NewWidth, NewHeight: integer);
+begin
+ inherited SetBounds(NewLeft, NewTop, Width, Height);
+end;
+
+constructor UINavigationController.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FAcceptChildsAtDesignTime:=false;
+ FWidth:=320;
+ FHeight:=480;
+end;
+
+procedure UINavigationController.InitializeDefaultChildren;
+var
+ AChild: tiOSFakeComponent;
+ AViewController: TComponent;
+ Designer: IMyWidgetDesigner;
+begin
+ designer := GetDesigner;
+ if assigned(designer) then
+ begin
+ Designer.CreateComponent(self,UINavigationBar,'iOS_Views',0,0,0,0,true);
+ AViewController := Designer.CreateComponent(self,UIViewController,'iOS_Views',0,0,0,0,true);
+ Designer.CreateComponent(AViewController,UINavigationItem,'iOS_Views',0,0,0,0,true);
+ end
+ else
+ begin
+ AChild := UINavigationBar.Create(self);
+ AChild.Parent := self;
+
+ AViewController := UIViewController.Create(self);
+ tiOSFakeComponent(AViewController).Parent := self;
+
+ AChild := UINavigationItem.Create(self);
+ AChild.Parent := tiOSFakeComponent(AViewController);
+ end
+end;
+
+class function UINavigationController.GetIBClassName: string;
+begin
+ Result:='IBUINavigationController';
+end;
+
+{ UIWindow }
+
+procedure UIWindow.WriteToDomElement(AnObjectDomElement: TDOMElement);
+begin
+ inherited WriteToDomElement(AnObjectDomElement);
+ AddIBReference(AnObjectDomElement,'NSWindow',self);
+ AddIBString(AnObjectDomElement,'targetRuntimeIdentifier','IBCocoaTouchFramework');
+ AddIBBoolean(AnObjectDomElement,'IBUIResizesToFullScreen',True);
+end;
+
+procedure UIWindow.SetBounds(NewLeft, NewTop, NewWidth, NewHeight: integer);
+begin
+ inherited SetBounds(NewLeft, NewTop, Width, Height);
+end;
+
+constructor UIWindow.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ NSNextResponder:=self;
+ FWidth:=320;
+ FHeight:=480;
+ BackgroundColor:=clWhite;
+ // Value from template
+ FObjectID:=2;
+end;
+
+procedure UIWindow.paint(ACanvas: TCanvas);
+begin
+ with ACanvas do
+ begin
+ Brush.Style:=bsSolid;
+ Brush.Color:=BackgroundColor;
+ // outer frame
+ Pen.Color:=clRed;
+ Rectangle(0,0,self.Width,self.Height);
+ end;
+end;
+
+class function UIWindow.GetIBClassName: string;
+begin
+ Result:='IBUIWindow';
+end;
+
+{ NSObject }
+
+procedure NSObject.GetXIBSaveParam(Sender: TObject; const ParamName: String; out AValue: String);
+var
+ i: Integer;
+begin
+ if ParamName='Objects' then
+ begin
+ AValue:=getAsXIBObject;
+ for i := 0 to self.ChildCount-1 do
+ begin
+ avalue := AValue + self.Children[i].getAsXIBObject;
+ end;
+ end
+ else if ParamName='flattenedProperties' then
+ begin
+ AValue := GetFlattenedProperties;
+ end
+ else if ParamName='ConnectionRecords' then
+ begin
+ avalue := getConnectionRecords;
+ for i := 0 to self.ChildCount-1 do
+ begin
+ avalue := AValue + self.Children[i].getConnectionRecords;
+ end;
+ end
+ else if ParamName='ObjectRecords' then
+ begin
+ AValue := getObjectRecord;
+ for i := 0 to self.ChildCount-1 do
+ begin
+ avalue := AValue + self.Children[i].getObjectRecord;
+ end;
+ end;
+end;
+
+function NSObject.IsNIBRoot: boolean;
+begin
+ result := Parent=Nil;
+end;
+
+function NSObject.GetFilesOwnerID: string;
+begin
+ if IsHiddenObject then
+ Result:='841351856'
+ else
+ Result:='664661524';
+end;
+
+function NSObject.GetFlattenedProperties: string;
+var
+ XMLDoc: TXMLDocument;
+ AStream: TStringStream;
+ FlattenedPropertiesElement: TDOMElement;
+ SortedKeysElements: TDOMElement;
+ ValuesElements: TDOMElement;
+ AnElement: TDOMElement;
+ i: integer;
+begin
+// assert(self is AppDelegate);
+ XMLDoc := TXMLDocument.Create;
+ try
+ FlattenedPropertiesElement := AddIBObject(XMLDoc,'flattenedProperties','NSMutableDictionary');
+ AddIBBoolean(FlattenedPropertiesElement,'EncodedWithXMLCoder',True);
+
+ SortedKeysElements := AddIBObject(FlattenedPropertiesElement,'dict.sortedKeys','NSArray');
+ AddIBBoolean(SortedKeysElements,'EncodedWithXMLCoder',True);
+ // Add props for File's Owner
+ AddIBString(SortedKeysElements,'','-1.CustomClassName');
+ AddIBString(SortedKeysElements,'','-1.IBPluginDependency');
+ // Add props for First Responder
+ AddIBString(SortedKeysElements,'','-2.CustomClassName');
+ AddIBString(SortedKeysElements,'','-2.IBPluginDependency');
+ AddIBString(SortedKeysElements,'','10.IBPluginDependency');
+ AddIBString(SortedKeysElements,'','2.IBAttributePlaceholdersKey');
+ AddIBString(SortedKeysElements,'','2.IBPluginDependency');
+ if IsHiddenObject then
+ begin
+ AddIBString(SortedKeysElements,'','3.CustomClassName');
+ AddIBString(SortedKeysElements,'','3.IBPluginDependency');
+ end;
+ for i := 0 to ChildCount -1 do
+ AddIBString(SortedKeysElements,'',inttostr(Children[i].ObjectID)+'.IBPluginDependency');
+
+ ValuesElements := AddIBObject(FlattenedPropertiesElement,'dict.values','NSArray');
+ AddIBBoolean(ValuesElements,'EncodedWithXMLCoder',True);
+ // Add props for File's Owner
+ AddIBString(ValuesElements,'',FilesOwnerClass);
+ AddIBString(ValuesElements,'','com.apple.InterfaceBuilder.IBCocoaTouchPlugin');
+ // Add props for First Responder
+ AddIBString(ValuesElements,'','UIResponder');
+ AddIBString(ValuesElements,'','com.apple.InterfaceBuilder.IBCocoaTouchPlugin');
+ AddIBString(ValuesElements,'','com.apple.InterfaceBuilder.IBCocoaTouchPlugin');
+
+ AnElement := AddIBObject(ValuesElements,'','NSMutableDictionary');
+ AddIBBoolean(AnElement,'EncodedWithXMLCoder',True);
+ AddIBReference(AnElement,'dict.sortedKeys','0');
+ AddIBReference(AnElement,'dict.values','0');
+
+ AddIBString(ValuesElements,'','com.apple.InterfaceBuilder.IBCocoaTouchPlugin');
+ if IsHiddenObject then
+ begin
+ AddIBString(ValuesElements,'',self.ClassName);
+ AddIBString(ValuesElements,'','com.apple.InterfaceBuilder.IBCocoaTouchPlugin');
+ end;
+ for i := 0 to ChildCount -1 do
+ AddIBString(ValuesElements,'','com.apple.InterfaceBuilder.IBCocoaTouchPlugin');
+
+ AStream := TStringStream.Create('');
+ try
+ for i := 0 to XMLDoc.ChildNodes.Count-1 do
+ WriteXML(XMLDoc.ChildNodes.Item[i],AStream);
+ result := AStream.DataString;
+ finally
+ AStream.Free;
+ end;
+ finally
+ XMLDoc.Free;
+ end;
+end;
+
+procedure NSObject.InternalInvalidateRect(ARect: TRect; Erase: boolean);
+begin
+ if (Parent=nil) and (Designer<>nil) then
+ Designer.InvalidateRect(Self,ARect,Erase);
+end;
+
+function NSObject.getObjectRecord: string;
+begin
+ if IsNIBRoot then
+ begin
+ // ObjectRecord's for the File's Owner and First Responder
+ result :=
+ '' + LineEnding +
+ ' -1' +LineEnding +
+ ' ' + LineEnding +
+ ' ' + LineEnding +
+ ' File''s Owner' + LineEnding +
+ '' + LineEnding +
+ '' + LineEnding +
+ ' -2' + LineEnding +
+ ' ' + LineEnding +
+ ' ' + LineEnding +
+ ''+ LineEnding;
+ if IsHiddenObject then
+ result := result +
+ '' + LineEnding +
+ ' 3' + LineEnding +
+ ' ' + LineEnding +
+ ' ' + LineEnding +
+ '' + LineEnding;
+ end
+ else
+ result := inherited getObjectRecord;
+end;
+
+function NSObject.getAsXIBObject: string;
+begin
+ if IsNIBRoot then
+ begin
+ // Objects for the File's Owner and First Responder
+ result :=
+ // File's owner
+ '' + LineEnding +
+ ' IBFilesOwner' + LineEnding +
+ ' IBCocoaTouchFramework' + LineEnding +
+ '' + LineEnding +
+ // First responder
+ '' + LineEnding +
+ ' IBFirstResponder' + LineEnding +
+ ' IBCocoaTouchFramework' + LineEnding +
+ '' + LineEnding;
+ if IsHiddenObject then
+ result := result +
+ '' + LineEnding +
+ ' IBCocoaTouchFramework' + LineEnding +
+ '' + LineEnding;
+
+ end
+ else
+ result := inherited getObjectRecord;
+end;
+
+function NSObject.getConnectionRecords: string;
+begin
+ if IsNIBRoot then
+ begin
+ if IsHiddenObject then
+ result := result +
+ '' + LineEnding +
+ ' ' + LineEnding +
+ ' '+HiddenObjectOutletName+'' + LineEnding +
+ ' ' + LineEnding +
+ ' ' + LineEnding +
+ ' ' + LineEnding +
+ ' 4' + LineEnding +
+ '' + LineEnding;
+ end
+ else
+ Result:=inherited getConnectionRecords;
+end;
+
+constructor NSObject.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FIsHiddenObject:=true;
+ FHiddenObjectOutletName:='delegate';
+ FWidth:=320;
+ FHeight:=480;
+end;
+
+procedure NSObject.SaveAsXIB(const Filename: string);
+var
+ ATemplate: TFPTemplate;
+ fs: TFileStream;
+ s: string;
+ dir: string;
+
+begin
+ ATemplate := TFPTemplate.Create;
+ try
+ ATemplate.StartDelimiter:='[{';
+ ATemplate.EndDelimiter:='}]';
+
+{$ifndef OutsideIDE}
+ dir := '$PkgDir(iOSDesigner)';
+ IDEMacros.SubstituteMacros(dir);
+{$else}
+ dir := '/Users/joost/svn/ccr-components/iosdesigner';
+{$endif OutsideIDE}
+ if dir <>'' then
+ ATemplate.FileName:=dir+PathDelim+ 'MainWindow_iPhone.template'
+ else
+ raise exception.create('iOSDesigner package could not be found.');
+
+ ATemplate.OnGetParam :=@GetXIBSaveParam;
+ s := ATemplate.GetContent;
+ fs := TFileStream.Create(Filename,fmCreate);
+ try
+ fs.Write(s[1],length(s));
+ finally
+ fs.free;
+ end;
+ finally
+ ATemplate.Free;
+ end;
+end;
+
+function NSObject.GetDesigner: IMyWidgetDesigner;
+begin
+ Result:=Designer;
+end;
+
+{ tiOSFakeComponent }
+
+procedure tiOSFakeComponent.SetHeight(const AValue: integer);
+begin
+ SetBounds(Left,Top,Width,AValue);
+end;
+
+procedure tiOSFakeComponent.SetLeft(const AValue: integer);
+begin
+ SetBounds(AValue,Top,Width,Height);
+end;
+
+function tiOSFakeComponent.ElementToString(AWriteDomMethod: tiOSWriteDomMethod): string;
+var
+ XMLDoc: TXMLDocument;
+ AStream: TStringStream;
+ RootElement: TDOMElement;
+ i: integer;
+begin
+ XMLDoc := TXMLDocument.Create;
+ try
+ RootElement := XMLDoc.CreateElement('root');
+ XMLDoc.AppendChild(RootElement);
+ AWriteDomMethod(RootElement);
+
+ AStream := TStringStream.Create('');
+ try
+ for i := 0 to RootElement.ChildNodes.Count-1 do
+ WriteXML(RootElement.ChildNodes.Item[i],AStream);
+ result := AStream.DataString;
+ finally
+ AStream.Free;
+ end;
+ finally
+ XMLDoc.Free;
+ end;
+end;
+
+function tiOSFakeComponent.GetHeight: integer;
+begin
+ result := FHeight;
+end;
+
+function tiOSFakeComponent.GetLeft: integer;
+begin
+ result := FLeft;
+end;
+
+function tiOSFakeComponent.GetTop: integer;
+begin
+ result := FTop;
+end;
+
+function tiOSFakeComponent.GetWidth: integer;
+begin
+ result := FWidth;
+end;
+
+procedure tiOSFakeComponent.SetParentComponent(Value: TComponent);
+begin
+ if Value is tiOSFakeComponent then
+ Parent:=UIView(Value);
+end;
+
+procedure tiOSFakeComponent.SetParent(const AValue: tiOSFakeComponent);
+begin
+ if FParent=AValue then exit;
+ if FParent<>nil then begin
+ Invalidate;
+ FParent.FChilds.Remove(Self);
+ end;
+ FParent:=AValue;
+ if FParent<>nil then begin
+ FParent.FChilds.Add(Self);
+ end;
+ Invalidate;
+end;
+
+function tiOSFakeComponent.HasParent: Boolean;
+begin
+ Result:=Parent<>nil;
+end;
+
+function tiOSFakeComponent.GetParentComponent: TComponent;
+begin
+ Result:=Parent;
+end;
+
+procedure tiOSFakeComponent.SetTop(const AValue: integer);
+begin
+ SetBounds(Left,AValue,Width,Height);
+end;
+
+procedure tiOSFakeComponent.SetWidth(const AValue: integer);
+begin
+ SetBounds(Left,Top,AValue,Height);
+end;
+
+function tiOSFakeComponent.GetChilds(Index: integer): tiOSFakeComponent;
+begin
+ Result:=tiOSFakeComponent(FChilds[Index]);
+end;
+
+procedure tiOSFakeComponent.GetChildren(Proc: TGetChildProc; Root: TComponent);
+var
+ i: Integer;
+begin
+ for i:=0 to ChildCount-1 do
+ if Children[i].Owner=Root then
+ Proc(Children[i]);
+end;
+
+procedure tiOSFakeComponent.InternalInvalidateRect(ARect: TRect; Erase: boolean);
+begin
+ //
+end;
+
+procedure tiOSFakeComponent.AddConnectionRecord(AnObjectDomElement: TDOMElement; AConnectionType, ALabel, AEventType: string);
+var
+ IBConnectionRecordElement : TDOMElement;
+ IBConnectionElement : TDOMElement;
+begin
+ if name='' then Exit;
+ IBConnectionRecordElement := AddIBObject(AnObjectDomElement,'','IBConnectionRecord');
+
+ IBConnectionElement := AddIBObject(IBConnectionRecordElement,'connection',AConnectionType);
+
+ AddIBString(IBConnectionElement,'label',ALabel);
+ if AEventType<>'' then
+ begin
+ AddIBReference(IBConnectionElement,'source',self,True);
+ AddIBReference(IBConnectionElement,'destination','664661524');
+ end
+ else
+ begin
+ AddIBReference(IBConnectionElement,'source','664661524');
+ AddIBReference(IBConnectionElement,'destination',self,True);
+ end;
+ AddIBInt(IBConnectionRecordElement,'connectionID',GConnectionID);
+ inc(GConnectionID);
+ if AEventType<>'' then
+ AddIBInt(IBConnectionElement,'IBEventType',StrToInt64Def(AEventType,1));
+end;
+
+procedure tiOSFakeComponent.WriteToDomElement(AnObjectDomElement: TDOMElement);
+var
+ ChildsMutableArray: TDOMElement;
+ i: Integer;
+begin
+ if ChildCount>0 then
+ begin
+ ChildsMutableArray := AddIBObject(AnObjectDomElement,'NSSubviews','NSMutableArray');
+ AddIBBoolean(ChildsMutableArray,'EncodedWithXMLCoder',true);
+ for i := 0 to ChildCount-1 do
+ Children[i].WriteToObject(ChildsMutableArray);
+ end;
+end;
+
+function tiOSFakeComponent.WriteToObject(AnObjectDomElement: TDOMElement) : TDOMElement;
+var
+ ClassDomElement: TDOMElement;
+ AnAttribute: TDOMNode;
+
+begin
+ ClassDomElement := AddIBObject(AnObjectDomElement,'',GetIBClassName);
+ ClassDomElement.AttribStrings['id']:=IntToStr(Ref);
+
+ WriteToDomElement(ClassDomElement);
+ result := ClassDomElement;
+end;
+
+function tiOSFakeComponent.WriteToConnectionRecords(
+ AnObjectDomElement: TDOMElement): TDOMElement;
+var
+ i: Integer;
+begin
+ AddConnectionRecord(AnObjectDomElement,'IBCocoaTouchOutletConnection',Name,'');
+ for i := 0 to ChildCount-1 do
+ Children[i].WriteToConnectionRecords(AnObjectDomElement);
+end;
+
+function tiOSFakeComponent.WriteToObjectRecord(AnObjectDomElement: TDOMElement
+ ): TDOMElement;
+var
+ ObjectRecordElement: TDOMElement;
+ ChildArray: TDOMElement;
+ i: Integer;
+begin
+ ObjectRecordElement := AddIBObject(AnObjectDomElement,'','IBObjectRecord');
+ AddIBInt(ObjectRecordElement,'objectID',ObjectID);
+ AddIBReference(ObjectRecordElement,'object',self,True);
+
+ if ChildCount>0 then
+ begin
+ ChildArray := AddIBObject(ObjectRecordElement,'children','NSMutableArray');
+ AddIBBoolean(ChildArray,'EncodedWithXMLCoder',True);
+ for i := 0 to ChildCount-1 do
+ AddIBReference(ChildArray,'',Children[i]);
+ end;
+
+ if assigned(Parent) then
+ AddIBReference(ObjectRecordElement,'parent',parent)
+ else
+ AddIBReference(ObjectRecordElement,'parent','0');
+ for i := 0 to ChildCount-1 do
+ Children[i].WriteToObjectRecord(AnObjectDomElement);
+ result := ObjectRecordElement;
+end;
+
+class function tiOSFakeComponent.GetIBClassName: string;
+begin
+ result := '';
+end;
+
+function tiOSFakeComponent.GetDesigner: IMyWidgetDesigner;
+begin
+ if assigned(parent) then
+ result := parent.GetDesigner
+ else
+ result := nil;
+end;
+
+constructor tiOSFakeComponent.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FChilds:=TFPList.Create;
+end;
+
+destructor tiOSFakeComponent.Destroy;
+begin
+ Parent:=nil;
+ while ChildCount>0 do Children[ChildCount-1].Free;
+ FreeAndNil(FChilds);
+ inherited Destroy;
+end;
+
+procedure tiOSFakeComponent.InitializeDefaultChildren;
+begin
+ // Do nothing
+end;
+
+procedure tiOSFakeComponent.paint(ACanvas: TCanvas);
+begin
+ with ACanvas do
+ begin
+ Brush.Style:=bsSolid;
+ Brush.Color:=clLtGray;
+ // outer frame
+ Pen.Color:=clRed;
+ Rectangle(0,0,self.Width,self.Height);
+ end;
+end;
+
+procedure tiOSFakeComponent.SetBounds(NewLeft, NewTop, NewWidth, NewHeight: integer);
+begin
+ if (Left=NewLeft) and (Top=NewTop) and (Width=NewWidth) and (Height=NewHeight) then
+ exit;
+ Invalidate;
+ FLeft:=NewLeft;
+ FTop:=NewTop;
+ FWidth:=NewWidth;
+ FHeight:=NewHeight;
+ Invalidate;
+end;
+
+procedure tiOSFakeComponent.InvalidateRect(ARect: TRect; Erase: boolean);
+begin
+ //writeln('TMyWidget.InvalidateRect ',Name,' ',ARect.Left,',',ARect.Top);
+ ARect.Left:=Max(0,ARect.Left);
+ ARect.Top:=Max(0,ARect.Top);
+ ARect.Right:=Min(Width,ARect.Right);
+ ARect.Bottom:=Max(Height,ARect.Bottom);
+ if Parent<>nil then begin
+ Parent.InvalidateRect(ARect,Erase);
+ end else begin
+ InternalInvalidateRect(ARect,Erase);
+ end;
+end;
+
+procedure tiOSFakeComponent.Invalidate;
+begin
+ InvalidateRect(Rect(0,0,Width,Height),false);
+end;
+
+function tiOSFakeComponent.ChildCount: integer;
+begin
+ Result:=FChilds.Count;
+end;
+
+function tiOSFakeComponent.getAsXIBObject: string;
+begin
+ result := ElementToString(@WriteToObject);
+end;
+
+function tiOSFakeComponent.getConnectionRecords: string;
+begin
+ result := ElementToString(@WriteToConnectionRecords);
+ inherited;
+end;
+
+function tiOSFakeComponent.getObjectRecord: string;
+
+begin
+ result := ElementToString(@WriteToObjectRecord);
+end;
+
+function tiOSFakeComponent.AddElement(ADomNode: TDomElement; AName: string): TDOMElement;
+begin
+ result := ADomNode.OwnerDocument.CreateElement(AName);
+ ADomNode.AppendChild(result);
+end;
+
+function tiOSFakeComponent.AddIBInt(ADomNode: TDOMElement; APropName: string;
+ APropValue: integer; ADefaultValue: integer): TDOMElement;
+begin
+ if APropValue<>ADefaultValue then
+ begin
+ result := AddElement(ADomNode,'int');
+ result.AttribStrings['key']:=APropName;
+ result.TextContent:=inttostr(APropValue);
+ end;
+end;
+
+function tiOSFakeComponent.AddIBDouble(ADomNode: TDOMElement; APropName: string; APropValue: double): TDOMElement;
+begin
+ result := AddElement(ADomNode,'double');
+ result.AttribStrings['key']:=APropName;
+ result.TextContent:=floattostr(APropValue);
+end;
+
+function tiOSFakeComponent.AddIBFloat(ADomNode: TDOMElement; APropName: string;
+ APropValue: double; ADefaultValue: double): TDOMElement;
+begin
+ if APropValue<>ADefaultValue then
+ begin
+ result := AddElement(ADomNode,'double');
+ result.AttribStrings['key']:=APropName;
+ result.TextContent:=floattostr(APropValue);
+ end;
+end;
+
+function tiOSFakeComponent.AddIBString(ADomNode: TDOMElement; APropName: string; APropValue: string): TDOMElement;
+begin
+ result := AddElement(ADomNode,'string');
+ if APropName<>'' then
+ result.AttribStrings['key']:=APropName;
+ result.TextContent:=APropValue;
+end;
+
+function tiOSFakeComponent.AddIBReference(ADomNode: TDOMElement;APropName: string; APropValue: tiOSFakeComponent; ForceValue: boolean): TDOMElement;
+begin
+ if assigned(APropValue) then
+ begin
+ result := AddElement(ADomNode,'reference');
+ if APropName<>'' then
+ result.AttribStrings['key']:=APropName;
+ if ForceValue or (APropValue<>self) then
+ result.AttribStrings['ref']:=inttostr(APropValue.Ref);
+ end;
+end;
+
+function tiOSFakeComponent.AddIBReference(ADomNode: TDOMElement; APropName: string; APropValue: string): TDOMElement;
+begin
+ result := AddElement(ADomNode,'reference');
+ result.AttribStrings['key']:=APropName;
+ result.AttribStrings['ref']:=APropValue;
+end;
+
+function tiOSFakeComponent.AddIBBoolean(ADomNode: TDOMElement; APropName: string; APropValue: Boolean): TDOMElement;
+begin
+ result := AddElement(ADomNode,'bool');
+ if APropName<>'' then
+ result.AttribStrings['key']:=APropName;
+ if APropValue then
+ result.TextContent:='YES'
+ else
+ result.TextContent:='NO';
+end;
+
+function tiOSFakeComponent.AddIBBoolean(ADomNode: TDOMElement; APropName: string; APropValue: Boolean; ADefaultValue: boolean): TDOMElement;
+begin
+ if APropValue<>ADefaultValue then
+ AddIBBoolean(ADomNode,APropName,APropValue);
+end;
+
+function tiOSFakeComponent.AddIBBytes(ADomNode: TDOMElement; APropName: string; APropValue: string): TDOMElement;
+begin
+ if APropValue<>'' then
+ begin
+ APropValue:=EncodeStringBase64(APropValue);
+ while APropValue[length(APropValue)]='=' do
+ APropValue:=copy(APropValue,1,length(APropValue)-1);
+ result := AddElement(ADomNode,'bytes');
+ result.AttribStrings['key']:=APropName;
+ result.TextContent:=APropValue;
+
+ end;
+end;
+
+function tiOSFakeComponent.AddIBObject(ADomNode: TDOMElement; APropName: string; AClass: string): TDOMElement;
+begin
+ result := AddElement(ADomNode,'object');
+ result.AttribStrings['class']:=AClass;
+ if APropName<>'' then
+ result.AttribStrings['key']:=APropName;
+end;
+
+function tiOSFakeComponent.AddIBObject(ADomDocument: TXMLDocument; APropName: string; AClass: string): TDOMElement;
+begin
+ result := ADomDocument.CreateElement('object');
+ ADomDocument.AppendChild(result);
+ result.AttribStrings['class']:=AClass;
+ if APropName<>'' then
+ result.AttribStrings['key']:=APropName;
+end;
+
+function tiOSFakeComponent.AddIBColor(ADomNode: TDOMElement; APropName: string; AColor: TColor): TDOMElement;
+var
+ l: longint;
+ fr,fg,fb: single;
+ b: byte;
+ s: string;
+ AnElement: TDOMElement;
+begin
+ if AColor=clDefault then
+ Exit;
+
+ l:=ColorToRGB(AColor);
+ b := l and ($ff0000) shr 16;
+ fb := b / $ff;
+ b := l and ($00ff00) shr 8;
+ fg := b / $ff;
+ b := l and ($0000ff);
+ fr := b / $ff;
+ s := FloatToStr(fr)+' '+FloatToStr(fg)+' '+FloatToStr(fb);
+
+ AnElement := AddIBObject(ADomNode,APropName,'NSColor');
+ AddIBInt(AnElement,'NSColorSpace',1);
+ AddIBBytes(AnElement,'NSRGB',s);
+end;
+
+function tiOSFakeComponent.AddIBFontDescription(ADomNode: TDOMElement; APropName: string; AFontDescription: TiOSFakeFontDescription): TDOMElement;
+var
+ l: longint;
+ fr,fg,fb: single;
+ b: byte;
+ s: string;
+ AnElement: TDOMElement;
+begin
+ if AFontDescription.FontType<>ftNotSet then
+ begin
+ AnElement := AddIBObject(ADomNode,APropName,'IBUIFontDescription');
+ AddIBInt(AnElement,'type',ord(AFontDescription.FontType));
+ AddIBDouble(AnElement,'pointSize',AFontDescription.pointSize);
+ end;
+end;
+
+
+
+{ UISearchBar }
+
+procedure UISearchBar.WriteToDomElement(AnObjectDomElement: TDOMElement);
+begin
+ inherited WriteToDomElement(AnObjectDomElement);
+ AddIBString(AnObjectDomElement,'IBText',Text);
+ AddIBString(AnObjectDomElement,'IBPlaceholder',Placeholder);
+ AddIBString(AnObjectDomElement,'IBPrompt',Prompt);
+end;
+
+constructor UISearchBar.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FAcceptChildsAtDesignTime:=false;
+end;
+
+destructor UISearchBar.Destroy;
+begin
+ inherited Destroy;
+end;
+
+class function UISearchBar.GetIBClassName: string;
+begin
+ Result:='IBUISearchBar';
+end;
+
+{ UITableView }
+
+procedure UITableView.WriteToDomElement(AnObjectDomElement: TDOMElement);
+begin
+ inherited WriteToDomElement(AnObjectDomElement);
+ AddIBFloat(AnObjectDomElement,'IBUIRowHeight',RowHeight);
+ AddIBFloat(AnObjectDomElement,'IBUISectionHeaderHeight',SectionHeaderHeight);
+ AddIBFloat(AnObjectDomElement,'IBUISectionFooterHeight',SectionFooterHeight);
+ AddIBInt(AnObjectDomElement,'IBUISeparatorStyle',ord(SeparatorStyle),0);
+ AddIBColor(AnObjectDomElement,'IBUISeparatorColor',SeparatorColor);
+ AddIBBoolean(AnObjectDomElement,'IBUIClipsSubviews',ClipSubviews);
+end;
+
+constructor UITableView.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FRowHeight:=44;
+ FSectionFooterHeight:=22;
+ FSectionHeaderHeight:=22;
+ FSeparatorStyle:=ssSingleLine;
+ FSeparatorColor:=clDefault;
+ FClipSubviews:=true;
+ FAcceptChildsAtDesignTime:=false;
+ FBackgroundColor := clWhite;
+end;
+
+destructor UITableView.Destroy;
+begin
+ inherited Destroy;
+end;
+
+class function UITableView.GetIBClassName: string;
+begin
+ Result:='IBUITableView';
+end;
+
+{ UITextField }
+
+procedure UITextField.WriteToDomElement(AnObjectDomElement: TDOMElement);
+begin
+ inherited WriteToDomElement(AnObjectDomElement);
+ AddIBString(AnObjectDomElement,'IBUIText',Text);
+ AddIBString(AnObjectDomElement,'IBUIPlaceholder',Placeholder);
+ AddIBInt(AnObjectDomElement,'IBUITextAlignment',ord(Alignment),0)
+end;
+
+constructor UITextField.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FAcceptChildsAtDesignTime:=false;
+end;
+
+destructor UITextField.Destroy;
+begin
+ inherited Destroy;
+end;
+
+class function UITextField.GetIBClassName: string;
+begin
+ Result:='IBUITextField';
+end;
+
+{ TiOSFakeFontDescription }
+
+constructor TiOSFakeFontDescription.Create;
+begin
+ pointSize:=12;
+end;
+
+{ TMyLabelButton }
+
+procedure UILabel.SetFont(AValue: TiOSFakeFontDescription);
+begin
+ if FFont=AValue then Exit;
+ FFont.Assign(AValue);
+end;
+
+procedure UILabel.WriteToDomElement(AnObjectDomElement: TDOMElement);
+var
+ AnElement: TDOMElement;
+begin
+ inherited WriteToDomElement(AnObjectDomElement);
+ AddIBString(AnObjectDomElement,'IBUIText',Caption);
+ AddIBInt(AnObjectDomElement,'IBUINumberOfLines',Lines,1);
+ AddIBInt(AnObjectDomElement,'IBUITextAlignment',ord(TextAlignment),0);
+ AddIBColor(AnObjectDomElement,'IBUITextColor',TextColor);
+ AddIBFontDescription(AnObjectDomElement,'IBUIFontDescription',Font);
+ AddIBBoolean(AnObjectDomElement,'IBUIEnabled',Enabled,True);
+ AddIBBoolean(AnObjectDomElement,'IBUIHighlighted',Highlighted,false);
+ AddIBInt(AnObjectDomElement,'IBUILineBreakMode',ord(LineBreaks),4);
+end;
+
+
+constructor UILabel.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FAcceptChildsAtDesignTime:=false;
+ FLines := 1;
+ FFont := TiOSFakeFontDescription.Create;
+ FEnabled := true;
+end;
+
+destructor UILabel.Destroy;
+begin
+ FFont.Free;
+ inherited Destroy;
+end;
+
+class function UILabel.GetIBClassName: string;
+begin
+ result := 'IBUILabel';
+end;
+
+procedure UILabel.paint(ACanvas: TCanvas);
+begin
+ ACanvas.Font.Color:=TextColor;
+ case Font.FontType of
+ ftSystemBold: begin
+ ACanvas.font.Name:='Helvetica';
+ ACanvas.Font.Size:=round(Font.FpointSize);
+ ACanvas.Font.Bold:=true;
+ ACanvas.Font.Italic:=False;
+ end;
+ ftSystem: begin
+ ACanvas.font.Name:='Helvetica';
+ ACanvas.Font.Size:=round(Font.FpointSize);
+ ACanvas.Font.Bold:=false;
+ ACanvas.Font.Italic:=False;
+ end;
+ ftSystemItalic: begin
+ ACanvas.font.Name:='Helvetica';
+ ACanvas.Font.Size:=round(Font.FpointSize);
+ ACanvas.Font.Italic:=true;
+ ACanvas.Font.Bold:=false;
+ end
+ else
+ begin
+ ACanvas.font.Name:='Helvetica';
+ ACanvas.Font.Size:=12;
+ ACanvas.Font.Italic:=false;
+ ACanvas.Font.Bold:=false;
+ end;
+ end;
+ ACanvas.TextOut(5,2,Caption);
+end;
+
+
+{ UIView }
+
+function UIView.GetNSSuperView: UIView;
+begin
+ if assigned(Parent) and (Parent is UIView) then
+ result := uiview(parent).GetNSSuperView
+ else
+ result := self;
+end;
+
+procedure UIView.SetCaption(const AValue: string);
+begin
+ if FCaption=AValue then exit;
+ FCaption:=AValue;
+ Invalidate;
+end;
+
+procedure UIView.SetName(const NewName: TComponentName);
+begin
+ if Name=Caption then Caption:=NewName;
+ inherited SetName(NewName);
+end;
+
+procedure UIView.WriteToDomElement(AnObjectDomElement: TDOMElement);
+var
+ b: integer;
+begin
+ AddIBString(AnObjectDomElement,'NSFrame','{{'+inttostr(Left)+', '+inttostr(top)+'}, {'+inttostr(width)+', '+inttostr(height)+'}}');
+ AddIBReference(AnObjectDomElement,'NSSuperview',NSSuperview);
+ AddIBReference(AnObjectDomElement,'NSNextResponder',NSNextResponder);
+ AddIBBoolean(AnObjectDomElement,'IBUIOpaque',Opaque);
+ b := 1316; //1325;
+ if Hidden then
+ b := b or (1 shl 31);
+ AddIBInt(AnObjectDomElement,'NSvFlags',b);
+ AddIBFloat(AnObjectDomElement,'IBUIAlpha',Alpha,1);
+ AddIBColor(AnObjectDomElement,'IBUIBackgroundColor',BackgroundColor);
+ inherited WriteToDomElement(AnObjectDomElement);
+end;
+
+constructor UIView.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FObjectID:=GConnectionID;
+ inc(GConnectionID);
+ FRef:=random(999999999);
+ FAcceptChildsAtDesignTime:=true;
+ FAlpha:=1;
+ FBackgroundColor:=clDefault;
+end;
+
+procedure UIView.paint(ACanvas: TCanvas);
+begin
+ with ACanvas do
+ begin
+ Brush.Style:=bsSolid;
+ Brush.Color:=BackgroundColor;
+ // outer frame
+ Pen.Color:=clRed;
+ Rectangle(0,0,self.Width,self.Height);
+ // caption
+ Font.Color:=clBlack;
+ Font.Name:='Helvetica';
+ Font.Size:=12;
+ Font.Italic:=false;
+ Font.Bold:=false;
+ TextOut(5,2,Caption);
+ end;
+end;
+
+class function UIView.GetIBClassName: string;
+begin
+ result := 'IBUIView';
+end;
+
+{ UIButton }
+
+procedure UIButton.WriteToDomElement(AnObjectDomElement: TDOMElement);
+
+begin
+ inherited WriteToDomElement(AnObjectDomElement);
+ AddIBReference(AnObjectDomElement,'NSNextKeyView',NSNextKeyView);
+ AddIBInt(AnObjectDomElement,'IBUIButtonType',1);
+ AddIBString(AnObjectDomElement,'IBUINormalTitle',Caption);
+ AddIBColor(AnObjectDomElement,'IBUINormalTitleColor',TextColor);
+end;
+
+function UIButton.WriteToConnectionRecords(AnObjectDomElement: TDOMElement): TDOMElement;
+var
+ AMethod: TMethod;
+begin
+ inherited WriteToConnectionRecords(AnObjectDomElement);
+ //writeln('PROPVAL: ' + vartostr(GetPropValue(self,'onTouchDown')));
+ AMethod := LazGetMethodProp(self,GetPropInfo(self,'onTouchDown'));
+
+ writeln('PROPVAL: ' + hexStr(PtrInt( AMethod.Code),8) + ' - ' + hexStr(ptrint(AMethod.Data),8));
+ if AMethod.Data<>nil then
+ begin
+ AddConnectionRecord(AnObjectDomElement,'IBCocoaTouchEventConnection',Name+'TouchDown:','1');
+ writeln(TObject(AMethod.Data).MethodName(self));
+ end
+ else
+ writeln('AA- Geen Touchdown ' + self.Name);
+end;
+
+constructor UIButton.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FAcceptChildsAtDesignTime:=false;
+end;
+
+class function UIButton.GetIBClassName: string;
+begin
+ result := 'IBUIButton';
+end;
+
+initialization
+ GConnectionID:=50;
+end.
+
diff --git a/components/iosdesigner/iosdesigner.lpk b/components/iosdesigner/iosdesigner.lpk
new file mode 100644
index 000000000..c565eb844
--- /dev/null
+++ b/components/iosdesigner/iosdesigner.lpk
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/iosdesigner/iosdesigner.pas b/components/iosdesigner/iosdesigner.pas
new file mode 100644
index 000000000..e3fc3db81
--- /dev/null
+++ b/components/iosdesigner/iosdesigner.pas
@@ -0,0 +1,22 @@
+{ This file was automatically created by Lazarus. Do not edit!
+ This source is only used to compile and install the package.
+ }
+
+unit iOSDesigner;
+
+interface
+
+uses
+ iOSNIBDesigner, iOS_Views, iOSIdeIntf, LazarusPackageIntf;
+
+implementation
+
+procedure Register;
+begin
+ RegisterUnit('iOSNIBDesigner', @iOSNIBDesigner.Register);
+ RegisterUnit('iOSIdeIntf', @iOSIdeIntf.Register);
+end;
+
+initialization
+ RegisterPackage('iOSDesigner', @Register);
+end.
diff --git a/components/iosdesigner/iosideintf.pas b/components/iosdesigner/iosideintf.pas
new file mode 100644
index 000000000..e3ab187d7
--- /dev/null
+++ b/components/iosdesigner/iosideintf.pas
@@ -0,0 +1,297 @@
+unit iOSIdeIntf;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, Forms, ProjectIntf, iPhoneExtOptions;
+
+type
+
+ { TiOSApplicationDescriptor }
+
+ TiOSApplicationDescriptor = class(TProjectDescriptor)
+ public
+ constructor Create; override;
+ function GetLocalizedName: string; override;
+ function GetLocalizedDescription: string; override;
+ function InitProject(AProject: TLazProject): TModalResult; override;
+ function CreateStartFiles(AProject: TLazProject): TModalResult; override;
+ end;
+
+ { TiOSObjectDelegateWindowFileDesc }
+
+ TiOSObjectDelegateWindowFileDesc = class(TFileDescPascalUnitWithResource)
+ protected
+ function GetDelegateProtocols: string; virtual;
+ public
+ constructor Create; override;
+ function GetInterfaceUsesSection: string; override;
+ function GetImplementationSource(const Filename, SourceName, ResourceName: string): string;override;
+ function GetInterfaceSource(const Filename, SourceName, ResourceName: string): string; override;
+ function GetUnitDirectives: string; override;
+ function GetLocalizedName: string; override;
+ function GetLocalizedDescription: string; override;
+ end;
+
+
+ { TiOSAppDelegateWindowFileDesc }
+
+ TiOSAppDelegateWindowFileDesc = class(TiOSObjectDelegateWindowFileDesc)
+ protected
+ function GetDelegateProtocols: string; override;
+ public
+ constructor Create; override;
+ end;
+
+ { TiOSInfo_PlistFileDesc }
+
+ TiOSInfo_PlistFileDesc = class(TProjectFileDescriptor)
+ public
+ constructor Create; override;
+ function CreateSource(const Filename, SourceName, ResourceName: string): string; override;
+ end;
+
+var
+ GiOSApplicationDescriptor: TiOSApplicationDescriptor;
+ GiOSAppDelegateWindowFileDesc: TiOSAppDelegateWindowFileDesc;
+ GiOSInfo_PlistFileDesc: TiOSInfo_PlistFileDesc;
+ GiOSObjectDelegateWindowFileDesc: TiOSObjectDelegateWindowFileDesc;
+
+procedure register;
+
+implementation
+
+uses LazIDEIntf, Controls, iOS_Views;
+
+procedure register;
+begin
+ GiOSApplicationDescriptor:=TiOSApplicationDescriptor.Create;
+ RegisterProjectDescriptor(GiOSApplicationDescriptor);
+ GiOSAppDelegateWindowFileDesc:=TiOSAppDelegateWindowFileDesc.Create;
+ RegisterProjectFileDescriptor(GiOSAppDelegateWindowFileDesc);
+ GiOSInfo_PlistFileDesc:=TiOSInfo_PlistFileDesc.Create;
+ RegisterProjectFileDescriptor(GiOSInfo_PlistFileDesc);
+ GiOSObjectDelegateWindowFileDesc:=TiOSObjectDelegateWindowFileDesc.Create;
+ RegisterProjectFileDescriptor(GiOSObjectDelegateWindowFileDesc);
+
+end;
+
+{ TiOSObjectDelegateWindowFileDesc }
+
+function TiOSObjectDelegateWindowFileDesc.GetDelegateProtocols: string;
+begin
+ result := '';
+end;
+
+constructor TiOSObjectDelegateWindowFileDesc.Create;
+begin
+ inherited Create;
+ Name:='iOS NIB-Delegate';
+ ResourceClass:=NSObject;
+ UseCreateFormStatements:=false;
+ VisibleInNewDialog:=true;
+end;
+
+function TiOSObjectDelegateWindowFileDesc.GetInterfaceUsesSection: string;
+begin
+ Result:='iPhoneAll';
+end;
+
+function TiOSObjectDelegateWindowFileDesc.GetImplementationSource(
+ const Filename, SourceName, ResourceName: string): string;
+begin
+ Result:='procedure T'+ResourceName+'.dealloc;' + LineEnding +
+ 'begin' + LineEnding +
+ ' inherited dealloc;' + LineEnding +
+ 'end;' + LineEnding +
+ LineEnding +
+ '{$R *.lfm}' + LineEnding + LineEnding;
+end;
+
+function TiOSObjectDelegateWindowFileDesc.GetInterfaceSource(const Filename, SourceName, ResourceName: string): string;
+var
+ DelegateProtocol: string;
+begin
+ DelegateProtocol:=GetDelegateProtocols;
+ if DelegateProtocol<>'' then
+ DelegateProtocol:=','+DelegateProtocol;
+ Result:=
+ 'type'+LineEnding
+ +' T'+ResourceName+' = objcclass('+ResourceClass.ClassName+DelegateProtocol+')'+LineEnding
+ +' private'+LineEnding
+ +' { private declarations }'+LineEnding
+ +' public'+LineEnding
+ +' procedure dealloc; override;'+LineEnding
+ +' end;'+LineEnding
+ +LineEnding;
+end;
+
+function TiOSObjectDelegateWindowFileDesc.GetUnitDirectives: string;
+begin
+ Result:='{$modeswitch ObjectiveC1}';
+end;
+
+function TiOSObjectDelegateWindowFileDesc.GetLocalizedName: string;
+begin
+ Result:='iOS NIB Delegate';
+end;
+
+function TiOSObjectDelegateWindowFileDesc.GetLocalizedDescription: string;
+begin
+ Result:='Create a new iOS-NIB file with a delegate to handle it''s contents. '+
+ 'The contents of the NIB can be changed with the designer.';
+end;
+
+{ TiOSInfo_PlistFileDesc }
+
+constructor TiOSInfo_PlistFileDesc.Create;
+begin
+ inherited Create;
+ Name:='Info_Plist';
+ DefaultFilename:='Info.Plist';
+ IsPascalUnit:=false;
+ VisibleInNewDialog:=false;
+end;
+
+function TiOSInfo_PlistFileDesc.CreateSource(const Filename, SourceName, ResourceName: string): string;
+begin
+ Result:='' + LineEnding +
+ '' + LineEnding +
+ '' + LineEnding +
+ '' + LineEnding +
+ ' CFBundleDevelopmentRegion' + LineEnding +
+ ' en' + LineEnding +
+ ' CFBundleDisplayName' + LineEnding +
+ ' ${PRODUCT_NAME}' + LineEnding +
+ ' CFBundleExecutable' + LineEnding +
+ ' ${EXECUTABLE_NAME}' + LineEnding +
+ ' CFBundleIconFile' + LineEnding +
+ ' ' + LineEnding +
+ ' CFBundleIdentifier' + LineEnding +
+ ' CNOC.${PRODUCT_NAME:rfc1034identifier}' + LineEnding +
+ ' CFBundleInfoDictionaryVersion' + LineEnding +
+ ' 6.0' + LineEnding +
+ ' CFBundleName' + LineEnding +
+ ' ${PRODUCT_NAME}' + LineEnding +
+ ' CFBundlePackageType' + LineEnding +
+ ' APPL' + LineEnding +
+ ' CFBundleShortVersionString' + LineEnding +
+ ' 1.0' + LineEnding +
+ ' CFBundleSignature' + LineEnding +
+ ' ????' + LineEnding +
+ ' CFBundleVersion' + LineEnding +
+ ' 1.0' + LineEnding +
+ ' LSRequiresIPhoneOS' + LineEnding +
+ ' ' + LineEnding +
+ ' NSMainNibFile' + LineEnding +
+ ' MainWindow_iPhone' + LineEnding +
+ ' NSMainNibFile~ipad' + LineEnding +
+ ' MainWindow_iPad' + LineEnding +
+ ' UISupportedInterfaceOrientations' + LineEnding +
+ ' ' + LineEnding +
+ ' UIInterfaceOrientationLandscapeLeft' + LineEnding +
+ ' UIInterfaceOrientationLandscapeRight' + LineEnding +
+ ' UIInterfaceOrientationPortrait' + LineEnding +
+ ' ' + LineEnding +
+ ' UISupportedInterfaceOrientations~ipad' + LineEnding +
+ ' ' + LineEnding +
+ ' UIInterfaceOrientationPortrait' + LineEnding +
+ ' UIInterfaceOrientationPortraitUpsideDown' + LineEnding +
+ ' UIInterfaceOrientationLandscapeLeft' + LineEnding +
+ ' UIInterfaceOrientationLandscapeRight' + LineEnding +
+ ' ' + LineEnding +
+ '' + LineEnding +
+ ''+LineEnding+LineEnding;
+end;
+
+{ TiOSAppDelegateWindowFileDesc }
+
+function TiOSAppDelegateWindowFileDesc.GetDelegateProtocols: string;
+begin
+ Result:='UIApplicationDelegateProtocol';
+end;
+
+constructor TiOSAppDelegateWindowFileDesc.Create;
+begin
+ inherited Create;
+ Name:='iOS UIApplicationDelegate';
+ VisibleInNewDialog:=false;
+end;
+
+{ TiOSApplicationDescriptor }
+
+constructor TiOSApplicationDescriptor.Create;
+begin
+ inherited Create;
+ Name := 'iOS application';
+end;
+
+function TiOSApplicationDescriptor.GetLocalizedName: string;
+begin
+ Result := 'iOS application';
+end;
+
+function TiOSApplicationDescriptor.GetLocalizedDescription: string;
+begin
+ Result:='iOS application'#13#13'An iOS program '
+ +'designed in Lazarus without using the LCL. The program file is '
+ +'automatically maintained by Lazarus.';
+end;
+
+function TiOSApplicationDescriptor.InitProject(AProject: TLazProject): TModalResult;
+var
+ NewSource: String;
+ MainFile: TLazProjectFile;
+begin
+ inherited InitProject(AProject);
+
+ MainFile:=AProject.CreateProjectFile('iosapp.lpr');
+ MainFile.IsPartOfProject:=true;
+ AProject.AddFile(MainFile,false);
+ AProject.MainFileID:=0;
+
+ // create program source
+ NewSource:='program iosapp;' + LineEnding +
+ LineEnding +
+ '{$modeswitch ObjectiveC1}' + LineEnding +
+ LineEnding +
+ 'uses' + LineEnding +
+ ' iPhoneAll, AppDelegate_iPhoneU;' + LineEnding +
+ LineEnding +
+ 'var' + LineEnding +
+ ' pool : NSAutoreleasePool;' + LineEnding +
+ 'begin' + LineEnding +
+ ' pool := NSAutoreleasePool.alloc.init;' + LineEnding +
+ ' UIApplicationMain(argc, argv, nil, nil);' + LineEnding +
+ ' pool.release;' + LineEnding +
+ 'end.' + LineEnding + LineEnding;
+
+ AProject.MainFile.SetSourceText(NewSource);
+
+ // add
+ AProject.AddPackageDependency('FCL');
+
+ // compiler options
+ AProject.LazCompilerOptions.Win32GraphicApp:=false;
+
+ //AProject.LazCompilerOptions.CustomOptions:='-XR/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.1.sdk';
+ AProject.LazCompilerOptions.TargetOS:='iphonesim';
+ AProject.Flags := AProject.Flags - [pfMainUnitHasCreateFormStatements];
+ Result:= mrOK;
+end;
+
+function TiOSApplicationDescriptor.CreateStartFiles(AProject: TLazProject): TModalResult;
+begin
+ //LazarusIDE.DoSaveAll([sfProjectSaving]);
+ GiOSAppDelegateWindowFileDesc.DefaultResourceName:='AppDelegate_iPhone';
+ LazarusIDE.DoNewEditorFile(GiOSAppDelegateWindowFileDesc,'appdelegate_iphoneu.pas','',[nfIsPartOfProject,nfOpenInEditor,nfCreateDefaultSrc]);
+ result := mrOK;
+ ProjOptions.isIPhoneApp:=true;
+ ProjOptions.MainNib:='appdelegate_iphoneu';
+ ProjOptions.Save;
+end;
+
+end.
+
diff --git a/components/iosdesigner/iosnibdesigner.pas b/components/iosdesigner/iosnibdesigner.pas
new file mode 100644
index 000000000..f32365fd4
--- /dev/null
+++ b/components/iosdesigner/iosnibdesigner.pas
@@ -0,0 +1,333 @@
+{ iOS NOB-designer for the Lazarus IDE
+
+ Copyright (C) 2012 Joost van der Sluis joost@cnoc.nl
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version with the following modification:
+
+ As a special exception, the copyright holders of this library give you
+ permission to link this library with independent modules to produce an
+ executable, regardless of the license terms of these independent modules,and
+ to copy and distribute the resulting executable under terms of your choice,
+ provided that you also meet, for each linked independent module, the terms
+ and conditions of the license of that module. An independent module is a
+ module which is not derived from or based on this library. If you modify
+ this library, you may extend this exception to your version of the library,
+ but you are not obligated to do so. If you do not wish to do so, delete this
+ exception statement from your version.
+
+ This program is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
+ for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+}
+
+unit iOSNIBDesigner;
+
+{$mode objfpc}{$H+}
+{$typeinfo off}
+
+interface
+
+uses
+ LCLProc, LCLType, Classes, SysUtils, FormEditingIntf, LCLIntf, Graphics, propedits, CodeToolManager,
+ ProjectIntf,
+ iOS_Views,
+ dom,
+ IDEIntf,
+ IDEWindowIntf,
+ LazIDEIntf,
+ Dialogs,
+{$ifndef OutsideIDE}
+ CustomNonFormDesigner,
+{$endif OutsideIDE}
+ Controls,
+ ComponentReg,
+ typinfo,
+ forms;
+
+type
+
+ { TNSObjectDesignerMediator }
+
+ TNSObjectDesignerMediator = class(TDesignerMediator,IMyWidgetDesigner)
+ private
+ FMyForm: NSObject;
+ procedure DoOnLoadBounds(Sender: TObject);
+ protected
+ procedure SetLCLForm(const AValue: TForm); override;
+ public
+ procedure SaveToXIB(AForm: NSObject);
+ // needed by the lazarus form editor
+ class function CreateMediator(TheOwner, aForm: TComponent): TDesignerMediator; override;
+ class function FormClass: TComponentClass; override;
+ procedure GetBounds(AComponent: TComponent; out CurBounds: TRect); override;
+ procedure SetBounds(AComponent: TComponent; NewBounds: TRect); override;
+ procedure GetClientArea(AComponent: TComponent; out CurClientArea: TRect; out ScrollOffset: TPoint); override;
+ procedure Paint; override;
+ function ComponentIsIcon(AComponent: TComponent): boolean; override;
+ function ParentAcceptsChild(Parent: TComponent; Child: TComponentClass): boolean; override;
+ procedure InitComponent(AComponent, NewParent: TComponent; NewBounds: TRect); override;
+ function CreateComponent(ParentComp: TComponent;
+ TypeClass: TComponentClass;
+ const AUnitName: shortstring;
+ X,Y,W,H: Integer;
+ DisableAutoSize: boolean): TComponent;
+ public
+ // needed by UIView
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ procedure InvalidateRect(Sender: TObject; ARect: TRect; Erase: boolean);
+ property MyForm: NSObject read FMyForm;
+ end;
+
+ { TUIResponderDesignerMediator }
+
+ TUIResponderDesignerMediator = class(TNSObjectDesignerMediator)
+ public
+ class function FormClass: TComponentClass; override;
+ end;
+
+procedure Register;
+
+implementation
+
+procedure Register;
+
+ procedure SetFakeUnitname(AClass: TClass);
+ var
+ ATypInfo: PTypeInfo;
+ ATypData: PTypeData;
+ begin
+ ATypInfo:=PTypeInfo(AClass.ClassInfo);
+ ATypData:=GetTypeData(ATypInfo);
+
+ ATypData^.UnitName[1]:='i';
+ ATypData^.UnitName[2]:='P';
+ ATypData^.UnitName[3]:='h';
+ ATypData^.UnitName[4]:='o';
+ ATypData^.UnitName[5]:='n';
+ ATypData^.UnitName[6]:='e';
+ ATypData^.UnitName[7]:='A';
+ ATypData^.UnitName[8]:='l';
+ ATypData^.UnitName[9]:='l';
+ end;
+
+begin
+ FormEditingHook.RegisterDesignerMediator(TNSObjectDesignerMediator);
+ FormEditingHook.RegisterDesignerMediator(TUIResponderDesignerMediator);
+ RegisterComponents('iOS',[UIWindow,UINavigationController,UIButton,UILabel,UITextField,UITableView,UISearchBar,UIView,UIViewController, UIProgressView]);
+
+ RegisterClass(UINavigationItem);
+ RegisterClass(UIViewController);
+ RegisterClass(UINavigationBar);
+
+ // 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.
+ SetFakeUnitname(UIButton);
+ SetFakeUnitname(UILabel);
+ SetFakeUnitname(UITextField);
+ SetFakeUnitname(UITableView);
+ SetFakeUnitname(UISearchBar);
+ SetFakeUnitname(UIWindow);
+ SetFakeUnitname(UIView);
+ SetFakeUnitname(UINavigationController);
+ SetFakeUnitname(UIViewController);
+ SetFakeUnitname(UIProgressView);
+end;
+
+{ TNSObjectDesignerMediator }
+
+constructor TNSObjectDesignerMediator.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+end;
+
+destructor TNSObjectDesignerMediator.Destroy;
+begin
+ if FMyForm<>nil then FMyForm.Designer:=nil;
+ FMyForm:=nil;
+ inherited Destroy;
+end;
+
+procedure TNSObjectDesignerMediator.DoOnLoadBounds(Sender: TObject);
+begin
+ //debugln('----onsaveloadbounds--------');
+ SaveToXIB(FMyForm);
+end;
+
+procedure TNSObjectDesignerMediator.SetLCLForm(const AValue: TForm);
+begin
+{$ifndef OutsideIDE}
+ if assigned(LCLForm) then
+ TCustomNonFormDesignerForm(LCLForm).OnSaveBounds:=nil;
+{$endif OutsideIDE}
+ inherited SetLCLForm(AValue);
+{$ifndef OutsideIDE}
+ if assigned(LCLForm) then
+ TCustomNonFormDesignerForm(LCLForm).OnSaveBounds:=@DoOnLoadBounds;
+{$endif OutsideIDE}
+end;
+
+procedure TNSObjectDesignerMediator.SaveToXIB(AForm: NSObject);
+var
+ AFileName: string;
+ AResourcesPath: string;
+ ALazFile: TLazProjectFile;
+begin
+ ALazFile := LazarusIDE.GetProjectFileWithRootComponent(AForm);
+ if assigned(ALazFile) then
+ begin
+ AFileName:=ChangeFileExt(ALazFile.Filename,'.xib');
+ AResourcesPath:=ExtractFilePath(AFileName)+'Resources';
+ ForceDirectories(AResourcesPath);
+ AFileName:=AResourcesPath+PathDelim+ExtractFileName(AFileName);
+ AForm.SaveAsXIB(AFileName);
+ //DebugLn('XIB saved: '+AFileName);
+ end;
+end;
+
+class function TNSObjectDesignerMediator.CreateMediator(TheOwner, aForm: TComponent): TDesignerMediator;
+var
+ Mediator: TNSObjectDesignerMediator;
+begin
+ Result:=inherited CreateMediator(TheOwner,aForm);
+ Mediator:=TNSObjectDesignerMediator(Result);
+ Mediator.FMyForm:=aForm as NSObject;
+ Mediator.FMyForm.Designer:=Mediator;
+end;
+
+class function TNSObjectDesignerMediator.FormClass: TComponentClass;
+begin
+ Result:=NSObject;
+end;
+
+procedure TNSObjectDesignerMediator.GetBounds(AComponent: TComponent; out CurBounds: TRect);
+var
+ w: tiOSFakeComponent;
+begin
+ if AComponent is tiOSFakeComponent then begin
+ w:=tiOSFakeComponent(AComponent);
+ CurBounds:=Bounds(w.Left,w.Top,w.Width,w.Height);
+ end else
+ inherited GetBounds(AComponent,CurBounds);
+end;
+
+procedure TNSObjectDesignerMediator.InvalidateRect(Sender: TObject; ARect: TRect; Erase: boolean);
+begin
+ if (LCLForm=nil) or (not LCLForm.HandleAllocated) then exit;
+ LCLIntf.InvalidateRect(LCLForm.Handle,@ARect,Erase);
+end;
+
+procedure TNSObjectDesignerMediator.SetBounds(AComponent: TComponent; NewBounds: TRect);
+begin
+ if AComponent is tiOSFakeComponent then begin
+ tiOSFakeComponent(AComponent).SetBounds(NewBounds.Left,NewBounds.Top,
+ NewBounds.Right-NewBounds.Left,NewBounds.Bottom-NewBounds.Top);
+ end else
+ inherited SetBounds(AComponent,NewBounds);
+end;
+
+procedure TNSObjectDesignerMediator.GetClientArea(AComponent: TComponent; out CurClientArea: TRect; out ScrollOffset: TPoint);
+var
+ Widget: tiOSFakeComponent;
+begin
+ if AComponent is tiOSFakeComponent then begin
+ Widget:=tiOSFakeComponent(AComponent);
+ CurClientArea:=Rect(0,0,
+ Widget.Width,
+ Widget.Height);
+ ScrollOffset:=Point(0,0);
+ end else
+ inherited GetClientArea(AComponent, CurClientArea, ScrollOffset);
+end;
+
+procedure TNSObjectDesignerMediator.Paint;
+
+ procedure PaintWidget(AWidget: tiOSFakeComponent);
+ var
+ i: Integer;
+ Child: tiOSFakeComponent;
+ begin
+ with LCLForm.Canvas do
+ begin
+ if AWidget is NSObject then
+ begin
+ Brush.Style:=bsClear;
+ Brush.Color:=clLtGray;
+ Pen.Color:=clMaroon;
+ Rectangle(0,0,AWidget.Width,AWidget.Height);
+ end
+ else
+ begin
+ AWidget.Paint(LCLForm.Canvas);
+ end;
+ // children
+ if AWidget.ChildCount>0 then
+ begin
+ //SaveHandleState;
+ // clip client area
+ {if IntersectClipRect(Handle, AWidget.left, AWidget.Top, AWidget.left+AWidget.Width,
+ AWidget.Height+AWidget.Top)<>NullRegion
+ then} begin
+ for i:=0 to AWidget.ChildCount-1 do begin
+ SaveHandleState;
+ Child:=AWidget.Children[i];
+ // clip child area
+ MoveWindowOrgEx(Handle,Child.Left,Child.Top);
+ if IntersectClipRect(Handle,0,0,Child.Width,Child.Height)<>NullRegion then
+ PaintWidget(Child);
+ RestoreHandleState;
+ end;
+ end;
+ //RestoreHandleState;
+ end;
+ end;
+ end;
+
+begin
+ PaintWidget(MyForm);
+ inherited Paint;
+end;
+
+function TNSObjectDesignerMediator.ComponentIsIcon(AComponent: TComponent): boolean;
+begin
+ Result:=not (AComponent is tiOSFakeComponent);
+end;
+
+function TNSObjectDesignerMediator.ParentAcceptsChild(Parent: TComponent; Child: TComponentClass): boolean;
+begin
+ Result:=(Parent is tiOSFakeComponent) and (Child.InheritsFrom(tiOSFakeComponent))
+ and (tiOSFakeComponent(Parent).AcceptChildsAtDesignTime);
+end;
+
+procedure TNSObjectDesignerMediator.InitComponent(AComponent, NewParent: TComponent; NewBounds: TRect);
+begin
+ inherited InitComponent(AComponent, NewParent, NewBounds);
+ if AComponent is tiOSFakeComponent then
+ tiOSFakeComponent(AComponent).InitializeDefaultChildren;
+end;
+
+function TNSObjectDesignerMediator.CreateComponent(ParentComp: TComponent;
+ TypeClass: TComponentClass; const AUnitName: shortstring; X, Y, W,
+ H: Integer; DisableAutoSize: boolean): TComponent;
+begin
+ result := FormEditingHook.CreateComponent(ParentComp,TypeClass,AUnitName,x,y,w,h,DisableAutoSize);
+end;
+
+{ TUIResponderDesignerMediator }
+
+class function TUIResponderDesignerMediator.FormClass: TComponentClass;
+begin
+ Result:=UIResponder;
+end;
+
+end.
+