diff --git a/components/iphonelazext/environment_iphone_options.lfm b/components/iphonelazext/environment_iphone_options.lfm index 72fb76d23..aad457985 100644 --- a/components/iphonelazext/environment_iphone_options.lfm +++ b/components/iphonelazext/environment_iphone_options.lfm @@ -1,74 +1,76 @@ -inherited iPhoneSpecificOptions: TiPhoneSpecificOptions - Height = 439 - Width = 485 - ClientHeight = 439 - ClientWidth = 485 - DesignLeft = 631 - DesignTop = 144 - object lblRTLUtils: TLabel[0] - Left = 11 +object iPhoneSpecificOptions: TiPhoneSpecificOptions + Left = 0 + Height = 473 + Top = 0 + Width = 487 + ClientHeight = 473 + ClientWidth = 487 + LCLVersion = '0.9.29' + object lblRTLUtils: TLabel + Left = 16 Height = 18 - Top = 128 + Top = 184 Width = 92 Caption = 'RTL units path' ParentColor = False end - object lblCompilerPath: TLabel[1] - Left = 11 + object lblCompilerPath: TLabel + Left = 16 Height = 18 - Top = 96 + Top = 152 Width = 55 Caption = 'Compiler' ParentColor = False end - object edtCompilerPath: TEdit[2] - Left = 125 + object edtCompilerPath: TEdit + Left = 136 Height = 22 - Top = 96 - Width = 347 + Top = 152 + Width = 330 Anchors = [akTop, akLeft, akRight] TabOrder = 0 Text = 'edtCompilerPath' end - object lblXCodeProject: TLabel[3] - Left = 11 + object lblXCodeProject: TLabel + Left = 16 Height = 18 - Top = 72 + Top = 128 Width = 395 Caption = 'Specific ARM compiler settings (for generated XCode projects)' ParentColor = False ParentFont = False end - object edtRTLPath: TEdit[4] - Left = 125 + object edtRTLPath: TEdit + Left = 136 Height = 22 - Top = 128 - Width = 347 + Top = 184 + Width = 330 Anchors = [akTop, akLeft, akRight] TabOrder = 1 Text = 'edtRTLPath' end - object edtCompilerOptions: TEdit[5] - Left = 125 + object edtCompilerOptions: TEdit + Left = 136 Height = 22 - Top = 160 - Width = 347 + Top = 216 + Width = 330 Anchors = [akTop, akLeft, akRight] + OnChange = edtCompilerOptionsChange TabOrder = 2 Text = 'edtCompilerOptions' end - object lblCmpOptions: TLabel[6] - Left = 11 + object lblCmpOptions: TLabel + Left = 16 Height = 18 - Top = 160 + Top = 216 Width = 106 Caption = 'Compiler options' ParentColor = False ParentFont = False OnClick = lblCmpOptionsClick end - object Label5: TLabel[7] - Left = 11 + object Label5: TLabel + Left = 16 Height = 18 Top = 16 Width = 97 @@ -76,55 +78,82 @@ inherited iPhoneSpecificOptions: TiPhoneSpecificOptions ParentColor = False ParentFont = False end - object edtPlatformsPath: TEdit[8] + object edtPlatformsPath: TEdit Left = 125 Height = 22 Top = 16 - Width = 347 + Width = 341 Anchors = [akTop, akLeft, akRight] TabOrder = 3 Text = 'edtPlatformsPath' end - object lblSimSettings: TLabel[9] - Left = 11 + object lblSimSettings: TLabel + Left = 16 Height = 18 - Top = 232 + Top = 256 Width = 161 Caption = 'iPhone Simulator settings' ParentColor = False end - object edtSimBundle: TEdit[10] + object edtSimBundle: TEdit Left = 160 Height = 22 - Top = 262 - Width = 312 + Top = 286 + Width = 306 Anchors = [akTop, akLeft, akRight] TabOrder = 4 Text = 'edtSimBundle' end - object edtSimApps: TEdit[11] + object edtSimApps: TEdit Left = 160 Height = 22 - Top = 294 - Width = 312 + Top = 318 + Width = 306 Anchors = [akTop, akLeft, akRight] TabOrder = 5 Text = 'edtSimApps' end - object lblSimBundle: TLabel[12] - Left = 11 + object lblSimBundle: TLabel + Left = 16 Height = 18 - Top = 263 + Top = 287 Width = 111 Caption = 'iPhoneSim bundle' ParentColor = False end - object lblSimAppPath: TLabel[13] - Left = 11 + object lblSimAppPath: TLabel + Left = 16 Height = 18 - Top = 294 + Top = 318 Width = 141 Caption = 'Sim Applications path:' ParentColor = False end + object Button1: TButton + Left = 16 + Height = 20 + Top = 56 + Width = 112 + AutoSize = True + Caption = 'Scan for SDKs' + OnClick = Button1Click + TabOrder = 6 + end + object Label1: TLabel + Left = 16 + Height = 18 + Top = 88 + Width = 129 + Caption = 'Default SDK version:' + ParentColor = False + end + object cmbDefaultSDK: TComboBox + Left = 152 + Height = 20 + Top = 88 + Width = 194 + ItemHeight = 0 + Style = csDropDownList + TabOrder = 7 + end end diff --git a/components/iphonelazext/environment_iphone_options.lrs b/components/iphonelazext/environment_iphone_options.lrs index 04025482b..b8a9936ae 100644 --- a/components/iphonelazext/environment_iphone_options.lrs +++ b/components/iphonelazext/environment_iphone_options.lrs @@ -1,39 +1,45 @@ { This is an automatically generated lazarus resource file } LazarusResources.Add('TiPhoneSpecificOptions','FORMDATA',[ - 'TPF0'#241#22'TiPhoneSpecificOptions'#21'iPhoneSpecificOptions'#6'Height'#3 - +#183#1#5'Width'#3#229#1#12'ClientHeight'#3#183#1#11'ClientWidth'#3#229#1#10 - +'DesignLeft'#3'w'#2#9'DesignTop'#3#144#0#0#242#2#0#6'TLabel'#11'lblRTLUtils' - +#4'Left'#2#11#6'Height'#2#18#3'Top'#3#128#0#5'Width'#2'\'#7'Caption'#6#14'RT' - +'L units path'#11'ParentColor'#8#0#0#242#2#1#6'TLabel'#15'lblCompilerPath'#4 - +'Left'#2#11#6'Height'#2#18#3'Top'#2'`'#5'Width'#2'7'#7'Caption'#6#8'Compiler' - +#11'ParentColor'#8#0#0#242#2#2#5'TEdit'#15'edtCompilerPath'#4'Left'#2'}'#6'H' - +'eight'#2#22#3'Top'#2'`'#5'Width'#3'['#1#7'Anchors'#11#5'akTop'#6'akLeft'#7 - +'akRight'#0#8'TabOrder'#2#0#4'Text'#6#15'edtCompilerPath'#0#0#242#2#3#6'TLab' - +'el'#15'lblXCodeProject'#4'Left'#2#11#6'Height'#2#18#3'Top'#2'H'#5'Width'#3 - +#139#1#7'Caption'#6'=Specific ARM compiler settings (for generated XCode pro' - +'jects)'#11'ParentColor'#8#10'ParentFont'#8#0#0#242#2#4#5'TEdit'#10'edtRTLPa' - +'th'#4'Left'#2'}'#6'Height'#2#22#3'Top'#3#128#0#5'Width'#3'['#1#7'Anchors'#11 - +#5'akTop'#6'akLeft'#7'akRight'#0#8'TabOrder'#2#1#4'Text'#6#10'edtRTLPath'#0#0 - +#242#2#5#5'TEdit'#18'edtCompilerOptions'#4'Left'#2'}'#6'Height'#2#22#3'Top'#3 - +#160#0#5'Width'#3'['#1#7'Anchors'#11#5'akTop'#6'akLeft'#7'akRight'#0#8'TabOr' - +'der'#2#2#4'Text'#6#18'edtCompilerOptions'#0#0#242#2#6#6'TLabel'#13'lblCmpOp' - +'tions'#4'Left'#2#11#6'Height'#2#18#3'Top'#3#160#0#5'Width'#2'j'#7'Caption'#6 - +#16'Compiler options'#11'ParentColor'#8#10'ParentFont'#8#7'OnClick'#7#18'lbl' - +'CmpOptionsClick'#0#0#242#2#7#6'TLabel'#6'Label5'#4'Left'#2#11#6'Height'#2#18 - +#3'Top'#2#16#5'Width'#2'a'#7'Caption'#6#15'Platforms path:'#11'ParentColor'#8 - +#10'ParentFont'#8#0#0#242#2#8#5'TEdit'#16'edtPlatformsPath'#4'Left'#2'}'#6'H' - +'eight'#2#22#3'Top'#2#16#5'Width'#3'['#1#7'Anchors'#11#5'akTop'#6'akLeft'#7 - +'akRight'#0#8'TabOrder'#2#3#4'Text'#6#16'edtPlatformsPath'#0#0#242#2#9#6'TLa' - +'bel'#14'lblSimSettings'#4'Left'#2#11#6'Height'#2#18#3'Top'#3#232#0#5'Width' - +#3#161#0#7'Caption'#6#25'iPhone Simulator settings'#11'ParentColor'#8#0#0#242 - +#2#10#5'TEdit'#12'edtSimBundle'#4'Left'#3#160#0#6'Height'#2#22#3'Top'#3#6#1#5 - +'Width'#3'8'#1#7'Anchors'#11#5'akTop'#6'akLeft'#7'akRight'#0#8'TabOrder'#2#4 - +#4'Text'#6#12'edtSimBundle'#0#0#242#2#11#5'TEdit'#10'edtSimApps'#4'Left'#3 - +#160#0#6'Height'#2#22#3'Top'#3'&'#1#5'Width'#3'8'#1#7'Anchors'#11#5'akTop'#6 - +'akLeft'#7'akRight'#0#8'TabOrder'#2#5#4'Text'#6#10'edtSimApps'#0#0#242#2#12#6 - +'TLabel'#12'lblSimBundle'#4'Left'#2#11#6'Height'#2#18#3'Top'#3#7#1#5'Width'#2 - +'o'#7'Caption'#6#16'iPhoneSim bundle'#11'ParentColor'#8#0#0#242#2#13#6'TLabe' - +'l'#13'lblSimAppPath'#4'Left'#2#11#6'Height'#2#18#3'Top'#3'&'#1#5'Width'#3 - +#141#0#7'Caption'#6#22'Sim Applications path:'#11'ParentColor'#8#0#0#0 + 'TPF0'#22'TiPhoneSpecificOptions'#21'iPhoneSpecificOptions'#4'Left'#2#0#6'Hei' + +'ght'#3#217#1#3'Top'#2#0#5'Width'#3#231#1#12'ClientHeight'#3#217#1#11'Client' + +'Width'#3#231#1#10'LCLVersion'#6#6'0.9.29'#0#6'TLabel'#11'lblRTLUtils'#4'Lef' + +'t'#2#16#6'Height'#2#18#3'Top'#3#184#0#5'Width'#2'\'#7'Caption'#6#14'RTL uni' + +'ts path'#11'ParentColor'#8#0#0#6'TLabel'#15'lblCompilerPath'#4'Left'#2#16#6 + +'Height'#2#18#3'Top'#3#152#0#5'Width'#2'7'#7'Caption'#6#8'Compiler'#11'Paren' + +'tColor'#8#0#0#5'TEdit'#15'edtCompilerPath'#4'Left'#3#136#0#6'Height'#2#22#3 + +'Top'#3#152#0#5'Width'#3'J'#1#7'Anchors'#11#5'akTop'#6'akLeft'#7'akRight'#0#8 + +'TabOrder'#2#0#4'Text'#6#15'edtCompilerPath'#0#0#6'TLabel'#15'lblXCodeProjec' + +'t'#4'Left'#2#16#6'Height'#2#18#3'Top'#3#128#0#5'Width'#3#139#1#7'Caption'#6 + +'=Specific ARM compiler settings (for generated XCode projects)'#11'ParentCo' + +'lor'#8#10'ParentFont'#8#0#0#5'TEdit'#10'edtRTLPath'#4'Left'#3#136#0#6'Heigh' + +'t'#2#22#3'Top'#3#184#0#5'Width'#3'J'#1#7'Anchors'#11#5'akTop'#6'akLeft'#7'a' + +'kRight'#0#8'TabOrder'#2#1#4'Text'#6#10'edtRTLPath'#0#0#5'TEdit'#18'edtCompi' + +'lerOptions'#4'Left'#3#136#0#6'Height'#2#22#3'Top'#3#216#0#5'Width'#3'J'#1#7 + +'Anchors'#11#5'akTop'#6'akLeft'#7'akRight'#0#8'OnChange'#7#24'edtCompilerOpt' + +'ionsChange'#8'TabOrder'#2#2#4'Text'#6#18'edtCompilerOptions'#0#0#6'TLabel' + +#13'lblCmpOptions'#4'Left'#2#16#6'Height'#2#18#3'Top'#3#216#0#5'Width'#2'j'#7 + +'Caption'#6#16'Compiler options'#11'ParentColor'#8#10'ParentFont'#8#7'OnClic' + +'k'#7#18'lblCmpOptionsClick'#0#0#6'TLabel'#6'Label5'#4'Left'#2#16#6'Height'#2 + +#18#3'Top'#2#16#5'Width'#2'a'#7'Caption'#6#15'Platforms path:'#11'ParentColo' + +'r'#8#10'ParentFont'#8#0#0#5'TEdit'#16'edtPlatformsPath'#4'Left'#2'}'#6'Heig' + +'ht'#2#22#3'Top'#2#16#5'Width'#3'U'#1#7'Anchors'#11#5'akTop'#6'akLeft'#7'akR' + +'ight'#0#8'TabOrder'#2#3#4'Text'#6#16'edtPlatformsPath'#0#0#6'TLabel'#14'lbl' + +'SimSettings'#4'Left'#2#16#6'Height'#2#18#3'Top'#3#0#1#5'Width'#3#161#0#7'Ca' + +'ption'#6#25'iPhone Simulator settings'#11'ParentColor'#8#0#0#5'TEdit'#12'ed' + +'tSimBundle'#4'Left'#3#160#0#6'Height'#2#22#3'Top'#3#30#1#5'Width'#3'2'#1#7 + +'Anchors'#11#5'akTop'#6'akLeft'#7'akRight'#0#8'TabOrder'#2#4#4'Text'#6#12'ed' + +'tSimBundle'#0#0#5'TEdit'#10'edtSimApps'#4'Left'#3#160#0#6'Height'#2#22#3'To' + +'p'#3'>'#1#5'Width'#3'2'#1#7'Anchors'#11#5'akTop'#6'akLeft'#7'akRight'#0#8'T' + +'abOrder'#2#5#4'Text'#6#10'edtSimApps'#0#0#6'TLabel'#12'lblSimBundle'#4'Left' + +#2#16#6'Height'#2#18#3'Top'#3#31#1#5'Width'#2'o'#7'Caption'#6#16'iPhoneSim b' + +'undle'#11'ParentColor'#8#0#0#6'TLabel'#13'lblSimAppPath'#4'Left'#2#16#6'Hei' + +'ght'#2#18#3'Top'#3'>'#1#5'Width'#3#141#0#7'Caption'#6#22'Sim Applications p' + +'ath:'#11'ParentColor'#8#0#0#7'TButton'#7'Button1'#4'Left'#2#16#6'Height'#2 + +#20#3'Top'#2'8'#5'Width'#2'p'#8'AutoSize'#9#7'Caption'#6#13'Scan for SDKs'#7 + +'OnClick'#7#12'Button1Click'#8'TabOrder'#2#6#0#0#6'TLabel'#6'Label1'#4'Left' + +#2#16#6'Height'#2#18#3'Top'#2'X'#5'Width'#3#129#0#7'Caption'#6#20'Default SD' + +'K version:'#11'ParentColor'#8#0#0#9'TComboBox'#13'cmbDefaultSDK'#4'Left'#3 + +#152#0#6'Height'#2#20#3'Top'#2'X'#5'Width'#3#194#0#10'ItemHeight'#2#0#5'Styl' + +'e'#7#14'csDropDownList'#8'TabOrder'#2#7#0#0#0 ]); diff --git a/components/iphonelazext/environment_iphone_options.pas b/components/iphonelazext/environment_iphone_options.pas index 42b0e87a8..ba256d80b 100644 --- a/components/iphonelazext/environment_iphone_options.pas +++ b/components/iphonelazext/environment_iphone_options.pas @@ -28,12 +28,15 @@ type { TiPhoneSpecificOptions } TiPhoneSpecificOptions = class(TAbstractIDEOptionsEditor) + Button1: TButton; + cmbDefaultSDK: TComboBox; edtCompilerPath: TEdit; edtRTLPath: TEdit; edtCompilerOptions: TEdit; edtPlatformsPath: TEdit; edtSimBundle: TEdit; edtSimApps: TEdit; + Label1: TLabel; lblRTLUtils: TLabel; lblSimAppPath: TLabel; lblCompilerPath: TLabel; @@ -42,6 +45,8 @@ type Label5: TLabel; lblSimSettings: TLabel; lblSimBundle: TLabel; + procedure Button1Click(Sender: TObject); + procedure edtCompilerOptionsChange(Sender: TObject); procedure lblCmpOptionsClick(Sender: TObject); private { private declarations } @@ -63,6 +68,26 @@ begin end; +procedure TiPhoneSpecificOptions.Button1Click(Sender: TObject); +var + dir : String; +begin + dir:=EnvOptions.PlatformsBaseDir; + EnvOptions.PlatformsBaseDir:=edtPlatformsPath.Text; + EnvOptions.RefreshVersions; + + cmbDefaultSDK.Clear; + EnvOptions.GetSDKVersions(cmbDefaultSDK.Items); + + EnvOptions.PlatformsBaseDir:=dir; + EnvOptions.RefreshVersions; +end; + +procedure TiPhoneSpecificOptions.edtCompilerOptionsChange(Sender: TObject); +begin + +end; + function TiPhoneSpecificOptions.GetTitle: String; begin Result:='Files'; @@ -87,6 +112,10 @@ begin edtCompilerOptions.Text := opt.CommonOpt; edtSimBundle.Text := opt.SimBundle; edtSimApps.Text:= opt.SimAppsPath; + + cmbDefaultSDK.Items.Clear; + opt.GetSDKVersions(cmbDefaultSDK.Items); + cmbDefaultSDK.ItemIndex:=cmbDefaultSDK.Items.IndexOf(opt.DefaultSDK); end; procedure TiPhoneSpecificOptions.WriteSettings(AOptions: TAbstractIDEOptions); diff --git a/components/iphonelazext/examples/iArkanoid/gameengine.pas b/components/iphonelazext/examples/iArkanoid/gameengine.pas new file mode 100644 index 000000000..7258bbe35 --- /dev/null +++ b/components/iphonelazext/examples/iArkanoid/gameengine.pas @@ -0,0 +1,257 @@ +// Arkanoid test game engine. +// developed for iPhone test samples +// +// Author: Dmitry 'skalogryz' Boyarintsev 2009 +// +// Arkanoid is an arcade game developed by Taito in 1986 +// http://en.wikipedia.org/wiki/Arkanoid +// +// You're free to use this unit in anyway you want + +unit gameengine; + +{$mode objfpc}{$H+} + +interface + +uses + Types, Classes, SysUtils; + +const + ballVelocity = 18; + +type + TGameItem = record + x, y : single; // coodinates + dx, dy : single; // velocity vector + sticked: Boolean; + end; + + TBrick = record + bounds : TRect; + hitRect : TRect; + health : Integer; + flash : Integer; + end; + + { TArkanoid } + + TArkanoid = class(TObject) + private + fPaddleX : single; + procedure SetPaddleX(const AValue: single); + protected + procedure BoundsBack(const HitRect: TRect; var dx, dy: single); + procedure BallMove(var move: TGameItem; atime: single); + procedure SetPaddleX(AValue: Integer); + procedure ResetPaddle; + public + bricks : array [0..99] of TBrick; + brickCount : Integer; + balls : array [0..9] of TGameItem; + ballcount : Integer; + width : Integer; + height : Integer; + PaddleY : single; + PaddleW : single; + + constructor Create(awidth, aheight: Integer); + procedure InitBricks; + procedure Init; + procedure Move; + function AnySticked: Boolean; + procedure LaunchSticked; + property PaddleX: single read fPaddleX write SetPaddleX; + end; + +implementation + +{ TArkanoid } + +procedure TArkanoid.SetPaddleX(const AValue: single); +var + dx : single; + i : integer; +begin + dx := fPaddleX - AValue; + for i := 0 to ballcount - 1 do begin + if balls[i].sticked then + balls[i].x:=balls[i].x-dx; + end; + fPaddleX := AValue; +end; + +// hacky test +procedure TArkanoid.BoundsBack(const HitRect: TRect; var dx, dy: single); +var + my : Integer; +begin + my := HitRect.Top + (HitRect.Bottom - HitRect.Top) div 2; + if abs(my - dy)>5 then dy := -dy + else dx := -dx; +end; + +procedure TArkanoid.BallMove(var move: TGameItem; atime: single); +var + cx, cy : single; + p : TPoint; + i : Integer; + + t : single; +begin + with move do begin + if sticked then Exit; + + cx := x + dx * atime; + cy := y + dy * atime; + if cy < 0 then begin + cy := 0; + dy := -dy; + end; + + if cx < 0 then begin + cx := 0; + dx := -dx; + end else if cx > width then begin + cx := width; + dx := -dx; + end; + + p.x := Round(cx); + p.y := Round(cy); + + for i := 0 to brickCount - 1 do begin + if (bricks[i].health > 0) and PtInRect(bricks[i].hitRect, p) then begin + BoundsBack(bricks[i].bounds, dx, dy); + bricks[i].flash:=2; + dec(bricks[i].health); + end; + end; + + if (cy >= PaddleY-5) and (cx >= PaddleX) and (cx <= PaddleX + PaddleW) and (dy>0) then begin + t := (cx - PaddleX - PaddleW/2) / (PaddleW/2); + + if t > 1 then t := 1 + else if t < -1 then t:=-1; + + + if t < 0 then + t := pi/2 + pi/16 - t / 2 + else + t := pi/2 - pi/16 - t / 2; + dx := cos(t)*ballVelocity; + dy := -sin(t)*ballVelocity; + cy := PaddleY-5; + end else if cy > height then begin + ResetPaddle; + Exit; + end; + + x:=cx; + y:=cy; + end; +end; + +procedure TArkanoid.SetPaddleX(AValue: Integer); +begin + +end; + +procedure TArkanoid.ResetPaddle; +var + i : integer; + a : single; +begin + PaddleW := width / 5; + PaddleY := height - 10; + fPaddleX := width / 2 - PaddleW / 2; + ballcount := 1; + for i := 0 to ballcount - 1 do + with Balls[i] do begin + {x := random(height-40)+20; + y := random(width-40)+20;} + x := PaddleX+PaddleW/2; + y := PaddleY-5; + a := random*pi/4 + (pi/2 - pi/8); + if cos(a)*5 < 0.1 then a := a + pi/5; + dx := ballVelocity*cos(a); + dy := ballVelocity*sin(a); + sticked:=true; + end; + +end; + +constructor TArkanoid.Create(awidth, aheight: Integer); +begin + width := awidth; + height := aheight; +end; + +procedure MakeHitRect(const boundsRect: TRect; var hitRect: TRect); +begin + hitRect.left := boundsRect.left - 3; + hitRect.Top := boundsRect.top - 3; + hitRect.right := boundsRect.right + 3; + hitRect.bottom:= boundsRect.bottom+ 3; +end; + +procedure TArkanoid.InitBricks; +var + i : Integer; + x, y : integer; +begin + brickCount := 8*8; + for i := 0 to brickCount - 1 do begin + x := (i mod 8) * 40; + y := (i div 8) * 20 + 40; + bricks[i].bounds:=Bounds(x,y,40,20); + end; + + for i:=0 to brickCount - 1 do begin + bricks[i].health := random(4)+1; + MakeHitRect(bricks[i].bounds, bricks[i].hitRect); + bricks[i].flash:=0; + end; +end; + +procedure TArkanoid.Init; +begin + InitBricks; + ResetPaddle; +end; + +procedure TArkanoid.Move; +var + i : Integer; +const + time : single = 1; +begin + for i := 0 to ballcount - 1 do + BallMove(balls[i], time); +end; + +function TArkanoid.AnySticked: Boolean; +var + i : Integer; +begin + Result := false; + for i := 0 to ballcount - 1 do + if balls[i].sticked then begin + Result:=true; + exit; + end; +end; + +procedure TArkanoid.LaunchSticked; +var + i : integer; +begin + for i := 0 to ballcount - 1 do + if balls[i].sticked then begin + balls[i].sticked:=false; + if balls[i].dy > 0 then balls[i].dy := - balls[i].dy; + end; +end; + +end. + diff --git a/components/iphonelazext/examples/iArkanoid/iArk.ico b/components/iphonelazext/examples/iArkanoid/iArk.ico new file mode 100644 index 000000000..9d0f58e2d Binary files /dev/null and b/components/iphonelazext/examples/iArkanoid/iArk.ico differ diff --git a/components/iphonelazext/examples/iArkanoid/iArk.lpi b/components/iphonelazext/examples/iArkanoid/iArk.lpi new file mode 100644 index 000000000..e5f3ca252 --- /dev/null +++ b/components/iphonelazext/examples/iArkanoid/iArk.lpi @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + <UseXPManifest Value="True"/> + <Icon Value="0"/> + <ActiveEditorIndexAtStart Value="0"/> + </General> + <VersionInfo> + <ProjectVersion Value=""/> + <Language Value=""/> + <CharSet Value=""/> + </VersionInfo> + <CustomData Count="4"> + <Item0 Name="iPhone/AppID" Value="com.mycompany.myapplication"/> + <Item1 Name="iPhone/SDK" Value="iPhone 2.0"/> + <Item2 Name="iPhone/SimSpaceName" Value="66F9A1EA-95F4-2F39-1C03-2ED8D5218316"/> + <Item3 Name="iPhone/isiPhoneApp" Value="true"/> + </CustomData> + <PublishOptions> + <Version Value="2"/> + <IgnoreBinaries Value="False"/> + <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/> + <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/> + </PublishOptions> + <RunParams> + <local> + <FormatVersion Value="1"/> + <LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/> + </local> + </RunParams> + <Units Count="3"> + <Unit0> + <Filename Value="iArk.pas"/> + <IsPartOfProject Value="True"/> + <UnitName Value="iArk"/> + <CursorPos X="17" Y="96"/> + <TopLine Value="94"/> + <EditorIndex Value="0"/> + <UsageCount Value="20"/> + <Loaded Value="True"/> + <SyntaxHighlighter Value="Delphi"/> + </Unit0> + <Unit1> + <Filename Value="gameengine.pas"/> + <UnitName Value="gameengine"/> + <CursorPos X="1" Y="1"/> + <TopLine Value="1"/> + <UsageCount Value="10"/> + <SyntaxHighlighter Value="Delphi"/> + </Unit1> + <Unit2> + <Filename Value="../../../../Fpc_Laz/lazarus-ccr/iphonelazext/project_iphone_options.pas"/> + <ComponentName Value="iPhoneProjectOptionsEditor"/> + <HasResources Value="True"/> + <ResourceBaseClass Value="Form"/> + <UnitName Value="project_iphone_options"/> + <CursorPos X="17" Y="82"/> + <TopLine Value="67"/> + <UsageCount Value="10"/> + </Unit2> + </Units> + <JumpHistory Count="0" HistoryIndex="-1"/> + </ProjectOptions> + <CompilerOptions> + <Version Value="8"/> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)/"/> + <LCLWidgetType Value="nogui"/> + </SearchPaths> + <Parsing> + <SyntaxOptions> + <SyntaxMode Value="Delphi"/> + <CStyleOperator Value="False"/> + <IncludeAssertionCode Value="True"/> + <CPPInline Value="False"/> + <UseAnsiStrings Value="True"/> + </SyntaxOptions> + </Parsing> + <Linking> + <Debugging> + <UseLineInfoUnit Value="False"/> + </Debugging> + <LinkSmart Value="True"/> + </Linking> + <Other> + <CompilerMessages> + <IgnoredMessages idx3018="True" idx3031="True" idx3189="True" idx4035="True" idx4036="True" idx4055="True" idx4079="True" idx4080="True" idx4081="True" idx5024="True" idx5057="True" idx5058="True" idx5060="True"/> + </CompilerMessages> + <CustomOptions Value="-XR/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator2.0.sdk"/> + <CompilerPath Value="$(CompPath)"/> + </Other> + </CompilerOptions> + <Debugging> + <Exceptions Count="4"> + <Item1> + <Name Value="EAbort"/> + </Item1> + <Item2> + <Name Value="ECodetoolError"/> + </Item2> + <Item3> + <Name Value="EFOpenError"/> + </Item3> + <Item4> + <Name Value="EXMLReadError"/> + </Item4> + </Exceptions> + </Debugging> +</CONFIG> diff --git a/components/iphonelazext/examples/iArkanoid/iArk.pas b/components/iphonelazext/examples/iArkanoid/iArk.pas new file mode 100644 index 000000000..a9d8451ad --- /dev/null +++ b/components/iphonelazext/examples/iArkanoid/iArk.pas @@ -0,0 +1,284 @@ +// iPhone Arkanoid test game +// +// Author: Dmitry 'skalogryz' Boyarintsev +// +// You're free to use this unit in anyway you want + +program iArk; + +{$mode objfpc}{$h+} +{$modeswitch objectivec1} + +uses + Types, SysUtils, CGContext, CGGeometry, iPhoneAll, gameengine; + +type + // should conform to UIApplicationDelegateProtocol + + { MyAppDelegate } + + MyAppDelegate = objcclass(NSObject) + procedure applicationDidFinishLaunching_(app: UIApplication); message 'applicationDidFinishLaunching:'; + procedure applicationWillTerminate_(application: UIApplication); message 'applicationWillTerminate:'; + end; + + { MyMainWindow } + + MyMainWindow = objcclass(UIWindow) + private + timer : NSTimer; + clr : Integer; + game : TArkanoid; + canmove : Boolean; + tx, ty : Integer; + px : Integer; + protected + procedure timerEvent_(Sender: NSTimer); message 'timerEvent:'; + + public + procedure touchesBegan_withEvent(touches: NSSetPointer; event: UIEvent); override; + procedure touchesMoved_withEvent(touches: NSSetPointer; event: UIEvent); override; + procedure touchesEnded_withEvent(touches: NSSetPointer; event: UIEvent); override; + procedure touchesCancelled_withEvent(touches: NSSetPointer; event: UIEvent); override; + + procedure initObjects; message 'initObjects'; + procedure releaseObjects; message 'releaseObjects'; + procedure drawRect(c: CGRect); override; + end; + +var + mainWin : MyMainWindow = nil; + +const + PaddleHeight = 10; + GameYOffset = 50; + +procedure MakeCGRect(const r: TRect; var cg: CGRect); inline; +begin + cg.origin.x := r.Left; + cg.origin.y := r.Top; + cg.size.width := r.Right - r.Left; + cg.size.height := r.Bottom - r.Top; +end; + +procedure DrawGame(game: TArkanoid; ctx: CGContextRef); +var + i : Integer; + r : CGRect; +const + ballsz = 10; + ballsz2 = ballsz div 2; +begin + {drawing balls} + r.size.width := ballsz; + r.size.height := ballsz; + CGContextSetRGBFillColor(ctx, 1, 1, 1, 1); + CGContextSetRGBStrokeColor(ctx, 0.0, 0.8, 0.8, 1); + for i := 0 to game.ballcount - 1 do begin + with game.Balls[i] do begin + r.origin.x := x - ballsz2; + r.origin.y := y - ballsz2; + end; + CGContextFillEllipseInRect(ctx, r); + end; + + {drawing players paddle} + r.origin.x := game.PaddleX; + r.origin.y := game.PaddleY; + r.size.width := game.PaddleW; + r.size.height := PaddleHeight; + CGContextSetRGBFillColor(ctx, 0.0, 1, 0.2, 1); + CGContextFillRect(ctx, r); + + for i := 0 to game.brickCount - 1 do begin + if game.bricks[i].flash > 0 then begin + MakeCGRect(game.bricks[i].bounds, r); + CGContextSetRGBFillColor(ctx, 1, 1, 1, 1); + CGContextFillRect(ctx, r); + dec(game.bricks[i].flash); + end else if game.bricks[i].health > 0 then begin + MakeCGRect(game.bricks[i].bounds, r); + CGContextSetRGBFillColor(ctx, 1, 0, 0, 1); + CGContextFillRect(ctx, r); + r.origin.x := r.origin.x+2; + r.origin.y := r.origin.y+2; + r.size.width := r.size.width-2; + r.size.Height := r.size.height-2; + CGContextSetRGBFillColor(ctx, 0.8, 0, 0, 1); + CGContextFillRect(ctx, r); + end; + end; +end; + +{ timer event, called every 0.1 second } +procedure MyMainWindow.timerEvent_(Sender: NSTimer); +begin + clr := Random($FFFFFF+1); + game.Move; + + setNeedsDisplay; +end; + +{ initilize game object and timers } +procedure MyMainWindow.initObjects; +begin + { create timer } + timer := NSTimer.scheduledTimerWithTimeInterval_target_selector_userInfo_repeats( + double(0.1), Self, objcselector(timerEvent_), nil, true); + game := TArkanoid.Create(300, 400); + game.Init; +end; + +procedure MyMainWindow.releaseObjects; +begin + if not Assigned(game) then Exit; + timer.invalidate; + game.Free; + game:=nil; +end; + + +function GetTouchCoord(touches: NSSetPointer; Window: UIWindow; var x, y: single): Boolean; +var + st : NSSet; + touch : UITouch; + p : CGPoint; +begin + Result := Assigned(touches); + if not Result then Exit; + st := NSSet(touches); + Result := st.count = 1; + if not Result then Exit; + + touch := UITouch(st.anyObject); + p := touch.locationInView(Window); + x := p.x; + y := p.y; +end; + + +function isCoordNearPabble(game: TArkanoid; x, y: single; Border: Integer): Boolean; +var + p : TPoint; + r : TRect; +begin + p.x := Round(x); + p.y := Round(y); + r := Bounds(Round(game.PaddleX) - Border, Round(game.PaddleY) - Border, Round(game.PaddleW)+Border*2, PaddleHeight + Border*2); + Result := PtInRect(r, p); +end; + +procedure MyMainWindow.touchesBegan_withEvent(touches: NSSetPointer; event: UIEvent); +var + x, y : single; +begin + if not GetTouchCoord(touches, self, x, y) then Exit; + canmove := isCoordNearPabble(game, x, y-GameYOffset, 20); + if canmove then px := Round(x); + tx:=round(x); + ty:=round(y); +end; + +procedure MyMainWindow.touchesMoved_withEvent(touches: NSSetPointer; event: UIEvent); +var + x, y : single; +begin + if not GetTouchCoord(touches, self, x, y) then Exit; + tx:=round(x); + ty:=round(y); + if canmove then begin + game.PaddleX := game.PaddleX + Round(x) - px; + px := Round(x); + end; + inherited touchesMoved_withEvent(touches, event); +end; + +procedure MyMainWindow.touchesEnded_withEvent(touches: NSSetPointer; + event: UIEvent); +begin + canmove := false; + + game.LaunchSticked; + inherited touchesEnded_withEvent(touches, event); +end; + +procedure MyMainWindow.touchesCancelled_withEvent(touches: NSSetPointer; + event: UIEvent); +begin + canmove := false; + inherited touchesCancelled_withEvent(touches, event); +end; + +procedure MyMainWindow.drawRect(c: CGRect); +var + ctx : CGContextRef; + txt : string; +begin + if not Assigned(game) then Exit; + + ctx := UIGraphicsGetCurrentContext; + if not canmove then + CGContextSetRGBFillColor(ctx, 0, 0.0, 0.25, 1) + else + CGContextSetRGBFillColor(ctx, 0, 0.25, 0.0, 1); + UIRectFill(c); + + + CGContextScaleCTM(ctx, 1, -1); + CGContextTranslateCTM(ctx, 0, -c.size.height); + + CGContextSetRGBFillColor(ctx, 1, 1, 0, 1); + CGContextSetRGBStrokeColor(ctx, 1, 1, 0, 1); + + CGContextSelectFont(ctx, 'Helvetica', 20, kCGEncodingMacRoman); + if Assigned(game) then begin + txt := Format('touch: %d %d; paddle: %d %d', [tx,ty, Round(game.PaddleX), Round(game.PaddleY)]); + CGContextShowTextAtPoint(ctx, 10, c.size.height - 40, PChar(txt), length(txt)); + end; + + CGContextTranslateCTM(ctx, 0, c.size.height); + CGContextScaleCTM(ctx, 1, -1); + + CGContextTranslateCTM(ctx, 0, GameYOffset); + DrawGame(game, ctx); + CGContextTranslateCTM(ctx, 0, -GameYOffset); +end; + +procedure MyAppDelegate.applicationDidFinishLaunching_(app: UIApplication); +var + screen : UIScreen; + r : CGRect; +begin + screen := UIScreen.mainScreen; + if Assigned(screen) then begin + r := screen.bounds; + if not Assigned(mainWin) then begin + mainWin := MyMainWindow(MyMainWindow.alloc).initWithFrame(r); + {initilize game object and timers} + mainWin.initObjects; + end; + mainWin.makeKeyAndVisible; + end; +end; + +procedure MyAppDelegate.applicationWillTerminate_(application: UIApplication); +begin + mainWin.releaseObjects; +end; + +var + pool : NSAutoreleasePool; + retVal : Integer; + +{$R iArk.res} + +begin + randomize; + pool := NSAutoreleasePool(NSAutoreleasePool.alloc).init; + + retVal := UIApplicationMain(argc, argv, nil, NSStr('MyAppDelegate')); + + pool.release; + ExitCode := retVal; +end. + diff --git a/components/iphonelazext/ideext.pas b/components/iphonelazext/ideext.pas index 99969365f..3d246d288 100644 --- a/components/iphonelazext/ideext.pas +++ b/components/iphonelazext/ideext.pas @@ -170,13 +170,8 @@ var idx : Integer; needfix : Boolean; sdkuse : String; - sdkname : string; begin - - if isRealDevice - then EnvOptions.GetDeviceSDK(ProjOptions.SDK, sdkname, sdkuse) - else EnvOptions.GetSimSDK(ProjOptions.SDK, sdkname, sdkuse); - sdkuse:=sdkuse; + sdkuse:=EnvOptions.GetSDKFullPath(ProjOptions.SDK, not isRealDevice); Result:=Options; if FindParam(Result, '-XR', idx, rawprm) then begin diff --git a/components/iphonelazext/iphoneextoptions.pas b/components/iphonelazext/iphoneextoptions.pas index fae2117f7..09cc28c69 100644 --- a/components/iphonelazext/iphoneextoptions.pas +++ b/components/iphonelazext/iphoneextoptions.pas @@ -20,7 +20,7 @@ unit iPhoneExtOptions; interface uses - Classes, SysUtils, IDEOptionsIntf, LazIDEIntf, ProjectIntf, iPhoneBundle, XMLConf; + Classes, SysUtils, IDEOptionsIntf, LazIDEIntf, ProjectIntf, iPhoneBundle, DOM, XMLRead, XMLConf, PlistFile; type @@ -48,6 +48,14 @@ type { TiPhoneEnvironmentOptions } + TSDKInfo = class(TObject) + devName : String; + devPath : String; + simName : String; + simPath : String; + options : String; + end; + TiPhoneEnvironmentOptions = class(TAbstractIDEEnvironmentOptions) private fPlatformsBaseDir : string; @@ -56,24 +64,29 @@ type fCommonOpt : string; fSimAppsPath : string; fSimBundle : string; + fDefaultSDK : string; + + fVersions : TStringList; protected function XMLFileName: string; + + procedure ClearVersionsInfo; + procedure FoundSDK(const Version, DevSDKName, DevSDKPath, SimSDKName, SimSDKPath: String); + function GetSDKInfo(const Version: String): TSDKInfo; public constructor Create; + destructor Destroy; override; class function GetGroupCaption: string; override; class function GetInstance: TAbstractIDEOptions; override; function Load: Boolean; function Save: Boolean; - function GetSimSDK(const ProjSDK: string; var SDKName, SDKFullPath: string): Boolean; - function GetDeviceSDK(const ProjSDK: string; var SDKName, SDKFullPath: string): Boolean; - function GetSDKName(const SDKVer: string; simulator: Boolean): string; function GetSDKFullPath(const SDKVer: string; simulator: Boolean): string; - procedure GetSDKVersions(Strings: TStringList); - + procedure GetSDKVersions(Strings: TStrings); + procedure RefreshVersions; property PlatformsBaseDir: string read fPlatformsBaseDir write fPlatformsBaseDir; property CompilerPath: string read fCompilerPath write fCompilerPath; @@ -82,11 +95,20 @@ type property SimBundle: string read fSimBundle write fSimBundle; property SimAppsPath: string read fSimAppsPath write fSimAppsPath; + + property DefaultSDK: string read fDefaultSDK write fDefaultSDK; end; function EnvOptions: TiPhoneEnvironmentOptions; function ProjOptions: TiPhoneProjectOptions; + +type + TSDKFoundEvent = procedure (const Version: String; + const DeviceSDKName, DeviceSDKPath, SimSDKName, SimSDKPath: string) of object; + +function ScanForSDK(const PlatformDir: String; FoundProc: TSDKFoundEvent): Boolean; + var iPhoneEnvGroup : Integer; iPhonePrjGroup : Integer; @@ -150,6 +172,39 @@ begin Result:=IncludeTrailingPathDelimiter(LazarusIDE.GetPrimaryConfigPath)+DefaultXMLName; end; +procedure TiPhoneEnvironmentOptions.ClearVersionsInfo; +var + i : Integer; +begin + for i:=0 to fVersions.Count-1 do begin + fVersions.Objects[i].Free; + fVersions.Objects[i]:=nil; + end; + fVersions.Clear; +end; + +procedure TiPhoneEnvironmentOptions.FoundSDK(const Version, DevSDKName, + DevSDKPath, SimSDKName, SimSDKPath: String); +var + info: TSDKInfo; +begin + info:=TSDKInfo.Create; + info.devName:=DevSDKName; + info.devPath:=DevSDKPath; + info.simName:=SimSDKName; + info.simPath:=SimSDKPath; + fVersions.AddObject(Version, info); +end; + +function TiPhoneEnvironmentOptions.GetSDKInfo(const Version: String): TSDKInfo; +var + i : Integer; +begin + i:=fVersions.IndexOf(Version); + if i<0 then Result:=nil + else Result:=TSDKInfo(fVersions.Objects[i]); +end; + function GetDefaultPlatformPath: WideString; begin //todo: @@ -177,6 +232,14 @@ begin fSimAppsPath := GetDefaultSimAppPath; fSimBundle := GetDefaultSimBundlePath; fCompilerPath := '/usr/local/bin/fpc'; + fVersions:=TStringList.Create; +end; + +destructor TiPhoneEnvironmentOptions.Destroy; +begin + ClearVersionsInfo; + fVersions.Free; + inherited Destroy; end; @@ -196,6 +259,11 @@ begin fCommonOpt := UTF8Encode(xmlcfg.GetValue('CompilerOptions', fCommonOpt)); fSimBundle := UTF8Encode(xmlcfg.GetValue('SimBundle', fSimBundle)); fSimAppsPath := UTF8Encode(xmlcfg.GetValue('SimAppPath', fSimAppsPath)); + fDefaultSDK := UTF8Encode(xmlcfg.GetValue('DefaultSDK', fDefaultSDK)); + + RefreshVersions; + if (fDefaultSDK = '') and (fVersions.Count>0) then + fDefaultSDK:=fVersions[0]; finally xmlcfg.Free; end; @@ -220,6 +288,7 @@ begin xmlcfg.SetValue('CompilerOptions', UTF8Decode(fCommonOpt)); xmlcfg.SetValue('SimBundle', UTF8Decode(fSimBundle)); xmlcfg.SetValue('SimAppPath', UTF8Decode(fSimAppsPath)); + xmlcfg.SetValue('DefaultSDK', UTF8Decode(fDefaultSDK)); finally xmlcfg.Free; end; @@ -229,41 +298,42 @@ begin end; -function TiPhoneEnvironmentOptions.GetSimSDK(const ProjSDK: string; var SDKName, SDKFullPath: string): Boolean; -const - iPhoneSimSDKDir = 'iPhoneSimulator2.0.sdk'; +function TiPhoneEnvironmentOptions.GetSDKName(const SDKVer: string; simulator: Boolean): string; +var + info : TSDKInfo; begin - SDKName:=sdk_iPhoneSim2_0; - SDKFullPath:=IncludeTrailingPathDelimiter(fPlatformsBaseDir)+'iPhoneSimulator.platform/Developer/SDKs/'+iPhoneSimSDKDir; - Result:=true; -end; - -function TiPhoneEnvironmentOptions.GetDeviceSDK(const ProjSDK: string; var SDKName, SDKFullPath: string): Boolean; -begin - SDKName:='iphoneos2.0'; - SDKFullPath:=''; - Result:=false; -end; - -function TiPhoneEnvironmentOptions.GetSDKName(const SDKVer: string; - simulator: Boolean): string; -begin - if simulator then Result:='iphonesimulator2.0' - else Result:='iphoneos2.0'; + info:=GetSDKInfo(SDKVer); + if not Assigned(info) then Result:='' + else begin + if simulator then Result:=info.devName + else Result:=info.simName; + end; end; function TiPhoneEnvironmentOptions.GetSDKFullPath(const SDKVer: string; simulator: Boolean): string; +var + info : TSDKInfo; begin - if simulator then - Result := IncludeTrailingPathDelimiter(fPlatformsBaseDir)+'iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator2.0.sdk' - else - Result := IncludeTrailingPathDelimiter(fPlatformsBaseDir)+'iPhoneOS.platform/Developer/SDKs/iPhoneOS2.0.sdk'; + info:=GetSDKInfo(SDKVer); + if not Assigned(info) then Result:='' + else begin + if simulator then Result:=info.devPath + else Result:=info.simPath; + end; end; -procedure TiPhoneEnvironmentOptions.GetSDKVersions(Strings: TStringList); +procedure TiPhoneEnvironmentOptions.GetSDKVersions(Strings: TStrings); +var + i : Integer; begin - //todo: - Strings.Add('iPhone OS 2.0'); + for i:=0 to fVersions.Count-1 do + Strings.Add( fVersions[i] ); +end; + +procedure TiPhoneEnvironmentOptions.RefreshVersions; +begin + ClearVersionsInfo; + ScanForSDK(EnvOptions.PlatformsBaseDir, @FoundSDK); end; { TiPhoneProjectOptions } @@ -321,6 +391,102 @@ begin end; end; +type + TSDKDescription = record + FullPath : String; {full SDK path} + Name : String; + Alternate : String; {alternate SDK -> iphonesimulator for iphoneos} + Version : String; + isDevice : Boolean; {true for real iPhoneOS, false for iPhoneSimulator} + end; + +// todo: implement reading .plist via OSX functions! (in case a .plist format changes) +function ReadSDKSettings(const FileName: string; var Descr: TSDKDescription): Boolean; +var + plist : TPListFile; +begin + Result:=False; + plist:=TPListFile.Create(FileName); + + Descr.Name:=plist.GetStrValue('CanonicalName'); + Descr.Alternate:=plist.GetStrValue('AlternateSDK'); + Descr.Version:=plist.GetStrValue('Version'); + + plist.Free; +end; + +function isSDKDir(const SDKDir: String; var d: TSDKDescription): Boolean; +var + plist : string; +begin + plist := IncludeTrailingPathDelimiter(SDKDir)+'SDKSettings.plist'; + Result:=FileExists(plist); + if not Result then Exit; + ReadSDKSettings(plist, d); + d.FullPath:=SDKDir; +end; + +function ScanForSDK(const PlatformDir: String; FoundProc: TSDKFoundEvent): Boolean; +const + PlatformName: array [Boolean] of string = ('iPhoneOS.platform','iPhoneSimulator.platform'); + SDKSubDir = PathDelim+'Developer'+PathDelim+'SDKs'+PathDelim; +var + isdev : Boolean; + dir : string; + sr : TSearchRec; + sdks : array of TSDKDescription; + descr : TSDKDescription; + cnt : Integer; + simname : string; + simpath : string; + i,j : Integer; + + procedure AddDescription(const d: TSDKDescription); + begin + if cnt = length(sdks) then begin + if cnt = 0 then SetLength(sdks, 16) + else SetLength(sdks, cnt*2); + end; + sdks[cnt]:=d; + inc(cnt); + end; + +begin + writeln('scan for SDK'); + Result:=Assigned(FoundProc); + if not Result then Exit; + + cnt:=0; + + for isdev:=false to true do begin + dir := IncludeTrailingPathDelimiter(PlatformDir) + PlatformName[isdev] + SDKSubDir; + if FindFirst(dir+'*', faAnyFile, sr)=0 then begin + repeat + if (sr.Attr and faDirectory>0) and (ExtractFileExt(sr.Name) = '.sdk') then + if isSDKDir( dir + sr.Name, descr) then begin + descr.isDevice:=isdev; + AddDescription(descr); + end; + until FindNext(sr)<>0; + FindClose(sr); + end; + end; + + for i:=0 to cnt-1 do + if sdks[i].isDevice then begin + simname:=''; + simpath:=''; + for j:=0 to cnt-1 do + if (not sdks[j].isDevice) and (sdks[i].Alternate=sdks[j].Name) then begin + simname:=sdks[j].Name; + simpath:=sdks[j].FullPath; + end; + FoundProc(sdks[i].Version, sdks[i].Name, sdks[i].FullPath, simname, simpath); + end; + + Result:=True; +end; + initialization InitOptions; diff --git a/components/iphonelazext/plistfile.pas b/components/iphonelazext/plistfile.pas new file mode 100644 index 000000000..1d6083960 --- /dev/null +++ b/components/iphonelazext/plistfile.pas @@ -0,0 +1,122 @@ +{ + ***************************************************************************** + * * + * This file is part of the iPhone Laz Extension * + * * + * See the file COPYING.modifiedLGPL.txt, included in this distribution, * + * for details about the copyright. * + * * + * 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. * + * * + ***************************************************************************** +} +unit PlistFile; + +{$mode delphi} + +interface + +uses + Classes, SysUtils, DOM, XMLRead; + +type + { TPListFile } + TPListFile = class(TObject) + private + fFileName : String; + fDoc : TXMLDocument; + firstkey : TDOMNode; + protected + procedure ReadValues; + //todo: add "parent" for FindKeyNode + function FindKeyNode(const keyName: string): TDOMNode; + public + constructor Create(const AFileName: String); + destructor Destroy; override; + function GetStrValue(const Key: String): String; + end; + +implementation + +{ TPListFile } + +constructor TPListFile.Create(const AFileName: String); +begin + fFileName := AFileName; + inherited Create; +end; + +destructor TPListFile.Destroy; +begin + fDOC.Free; + inherited Destroy; +end; + +function TPListFile.GetStrValue(const Key: String): String; +var + node : TDOMNode; +begin + Result:=''; + node:=FindKeyNode(Key); + if not Assigned(node) then Exit; + + node:=node.NextSibling; + if Assigned(node) and (node.NodeName='string') then + Result:=node.TextContent + else + Result:=''; +end; + +procedure TPListFile.ReadValues; +var + plist : TDOMNode; +begin + firstkey:=nil; + try + ReadXMLFile(fDoc, fFileName); + except + end; + + if not Assigned(fDoc) then begin + fDoc:=TXMLDocument.Create; + Exit; // create an empty document + end; + + try + plist:=fDoc.FindNode('plist'); + if not Assigned(plist) then Exit; + + while Assigned(plist) do begin + if (plist is TDOMElement) and (plist.NodeName='plist') and (plist.ChildNodes.Count>0) then + Break; + plist:=plist.NextSibling; + end; + + firstkey:=plist.FindNode('dict'); + if Assigned(firstkey) then + firstkey:=firstkey.FindNode('key'); + + except + firstkey:=nil; + end; +end; + +function TPListFile.FindKeyNode(const keyName: string): TDOMNode; +begin + if not Assigned(fDoc) then ReadValues; + if not Assigned(firstkey) then begin + Result:=nil; + Exit; + end; + Result:=firstkey; + while Assigned(Result) do begin + if (Result.NodeName='key') and (Result.TextContent=keyName) then Exit; + Result:=Result.NextSibling; + end; +end; + + +end. + diff --git a/components/iphonelazext/project_iphone_options.lfm b/components/iphonelazext/project_iphone_options.lfm index 4aace2fdf..a3092d781 100644 --- a/components/iphonelazext/project_iphone_options.lfm +++ b/components/iphonelazext/project_iphone_options.lfm @@ -4,6 +4,7 @@ inherited iPhoneProjectOptionsEditor: TiPhoneProjectOptionsEditor ClientHeight = 374 ClientWidth = 618 OnClick = FrameClick + TabOrder = 0 DesignLeft = 355 DesignTop = 224 object chkisPhone: TCheckBox[0] @@ -55,31 +56,11 @@ inherited iPhoneProjectOptionsEditor: TiPhoneProjectOptionsEditor Top = 48 Width = 184 ItemHeight = 0 - ItemIndex = 0 - Items.Strings = ( - 'iPhone 2.0' - 'iPhone 2.1' - 'iPhone 2.2' - 'iPhone 2.2.1' - 'iPhone 3.0' - 'iPhone 3.1' - 'iPhone 3.1.2' - ) OnChange = cmbSDKsChange Style = csDropDownList TabOrder = 2 - Text = 'iPhone 2.0' end - object btnCheckSDK: TButton[6] - Left = 312 - Height = 20 - Top = 48 - Width = 158 - AutoSize = True - Caption = 'Check available SDKs' - TabOrder = 3 - end - object lblXibFiles: TLabel[7] + object lblXibFiles: TLabel[6] Left = 16 Height = 18 Top = 168 diff --git a/components/iphonelazext/project_iphone_options.lrs b/components/iphonelazext/project_iphone_options.lrs index 9dd87cbaf..e6fa8bf52 100644 --- a/components/iphonelazext/project_iphone_options.lrs +++ b/components/iphonelazext/project_iphone_options.lrs @@ -3,27 +3,22 @@ LazarusResources.Add('TiPhoneProjectOptionsEditor','FORMDATA',[ 'TPF0'#241#27'TiPhoneProjectOptionsEditor'#26'iPhoneProjectOptionsEditor'#6'H' +'eight'#3'v'#1#5'Width'#3'j'#2#12'ClientHeight'#3'v'#1#11'ClientWidth'#3'j'#2 - +#7'OnClick'#7#10'FrameClick'#10'DesignLeft'#3'c'#1#9'DesignTop'#3#224#0#0#242 - +#2#0#9'TCheckBox'#10'chkisPhone'#4'Left'#2#16#6'Height'#2#18#3'Top'#2#16#5'W' - +'idth'#3#199#0#7'Caption'#6#29'is iPhone application project'#8'TabOrder'#2#0 - +#0#0#242#2#1#6'TLabel'#8'lblAppID'#4'Left'#2#16#6'Height'#2#18#3'Top'#2'X'#5 - +'Width'#2'W'#7'Caption'#6#14'Application ID'#11'ParentColor'#8#0#0#242#2#2#5 - +'TEdit'#8'edtAppID'#4'Left'#2'p'#6'Height'#2#22#3'Top'#2'U'#5'Width'#3#232#1 - +#7'Anchors'#11#5'akTop'#6'akLeft'#7'akRight'#0#8'TabOrder'#2#1#4'Text'#6#19 - +'com.mycompany.myapp'#0#0#242#2#3#6'TLabel'#12'lblAppIDHint'#4'Left'#2#16#6 - +'Height'#2#14#3'Top'#2'u'#5'Width'#3#237#1#7'Caption'#6'_It''s recommended b' - +'y Apple to use domain-structured name, i.e. com.mycompany.myApplication as ' - +'ID'#11'Font.Height'#2#246#11'ParentColor'#8#10'ParentFont'#8#0#0#242#2#4#6 - +'TLabel'#9'lblSDKVer'#4'Left'#2#16#6'Height'#2#18#3'Top'#2'3'#5'Width'#2'P'#7 - +'Caption'#6#12'SDK version:'#11'ParentColor'#8#0#0#242#2#5#9'TComboBox'#7'cm' - +'bSDKs'#4'Left'#2'p'#6'Height'#2#20#3'Top'#2'0'#5'Width'#3#184#0#10'ItemHeig' - +'ht'#2#0#9'ItemIndex'#2#0#13'Items.Strings'#1#6#10'iPhone 2.0'#6#10'iPhone 2' - +'.1'#6#10'iPhone 2.2'#6#12'iPhone 2.2.1'#6#10'iPhone 3.0'#6#10'iPhone 3.1'#6 - +#12'iPhone 3.1.2'#0#8'OnChange'#7#13'cmbSDKsChange'#5'Style'#7#14'csDropDown' - +'List'#8'TabOrder'#2#2#4'Text'#6#10'iPhone 2.0'#0#0#242#2#6#7'TButton'#11'bt' - +'nCheckSDK'#4'Left'#3'8'#1#6'Height'#2#20#3'Top'#2'0'#5'Width'#3#158#0#8'Aut' - +'oSize'#9#7'Caption'#6#20'Check available SDKs'#8'TabOrder'#2#3#0#0#242#2#7#6 - +'TLabel'#11'lblXibFiles'#4'Left'#2#16#6'Height'#2#18#3'Top'#3#168#0#5'Width' - +#3#219#0#7'Caption'#6'$.XIB files might appear here soon...'#11'ParentColor' - +#8#0#0#0 + +#7'OnClick'#7#10'FrameClick'#8'TabOrder'#2#0#10'DesignLeft'#3'c'#1#9'DesignT' + +'op'#3#224#0#0#242#2#0#9'TCheckBox'#10'chkisPhone'#4'Left'#2#16#6'Height'#2 + +#18#3'Top'#2#16#5'Width'#3#199#0#7'Caption'#6#29'is iPhone application proje' + +'ct'#8'TabOrder'#2#0#0#0#242#2#1#6'TLabel'#8'lblAppID'#4'Left'#2#16#6'Height' + +#2#18#3'Top'#2'X'#5'Width'#2'W'#7'Caption'#6#14'Application ID'#11'ParentCol' + +'or'#8#0#0#242#2#2#5'TEdit'#8'edtAppID'#4'Left'#2'p'#6'Height'#2#22#3'Top'#2 + +'U'#5'Width'#3#232#1#7'Anchors'#11#5'akTop'#6'akLeft'#7'akRight'#0#8'TabOrde' + +'r'#2#1#4'Text'#6#19'com.mycompany.myapp'#0#0#242#2#3#6'TLabel'#12'lblAppIDH' + +'int'#4'Left'#2#16#6'Height'#2#14#3'Top'#2'u'#5'Width'#3#237#1#7'Caption'#6 + +'_It''s recommended by Apple to use domain-structured name, i.e. com.mycompa' + +'ny.myApplication as ID'#11'Font.Height'#2#246#11'ParentColor'#8#10'ParentFo' + +'nt'#8#0#0#242#2#4#6'TLabel'#9'lblSDKVer'#4'Left'#2#16#6'Height'#2#18#3'Top' + +#2'3'#5'Width'#2'P'#7'Caption'#6#12'SDK version:'#11'ParentColor'#8#0#0#242#2 + +#5#9'TComboBox'#7'cmbSDKs'#4'Left'#2'p'#6'Height'#2#20#3'Top'#2'0'#5'Width'#3 + +#184#0#10'ItemHeight'#2#0#8'OnChange'#7#13'cmbSDKsChange'#5'Style'#7#14'csDr' + +'opDownList'#8'TabOrder'#2#2#0#0#242#2#6#6'TLabel'#11'lblXibFiles'#4'Left'#2 + +#16#6'Height'#2#18#3'Top'#3#168#0#5'Width'#3#219#0#7'Caption'#6'$.XIB files ' + +'might appear here soon...'#11'ParentColor'#8#0#0#0 ]); diff --git a/components/iphonelazext/project_iphone_options.pas b/components/iphonelazext/project_iphone_options.pas index 925033363..1dd4f3a1d 100644 --- a/components/iphonelazext/project_iphone_options.pas +++ b/components/iphonelazext/project_iphone_options.pas @@ -28,7 +28,6 @@ type { TiPhoneProjectOptionsEditor } TiPhoneProjectOptionsEditor = class(TAbstractIDEOptionsEditor) - btnCheckSDK: TButton; chkisPhone: TCheckBox; cmbSDKs: TComboBox; edtAppID: TEdit; @@ -80,7 +79,6 @@ procedure TiPhoneProjectOptionsEditor.Setup(ADialog: TAbstractOptionsEditorDialo begin chkisPhone.Caption := strPrjOptIsiPhone; lblSDKVer.Caption := strPrjOptSDKver; - btnCheckSDK.Caption := strPrjOptCheckSDK; lblAppID.Caption := strPtrOptAppID; lblAppIDHint.Caption := strPtrOptAppIDHint; end; @@ -95,10 +93,11 @@ begin Load; chkisPhone.Checked:=isIPhoneApp; + EnvOptions.GetSDKVersions(cmbSDKs.Items); i:=cmbSDKs.Items.IndexOf(SDK); - if (i<0) and (cmbSDKs.Items.Count>0) then i:=0; + if (i<0) and (cmbSDKs.Items.Count>0) then + i:=cmbSDKs.Items.IndexOf(EnvOptions.DefaultSDK); cmbSDKs.ItemIndex:=i; - edtAppID.Text:=AppID; end;