Skip to content
Browse files

add

  • Loading branch information...
0 parents commit b9eefa77e5346942dadb01151f7d73c47dbc2740 @vestige committed Oct 7, 2012
Showing with 28,981 additions and 0 deletions.
  1. +1 −0 CHANGELOG.txt
  2. +219 −0 LICENSE
  3. +1 −0 LICENSE.txt
  4. +18 −0 README
  5. BIN Resources/KS_nav_ui.png
  6. BIN Resources/KS_nav_views.png
  7. +164 −0 Resources/app.js
  8. BIN Resources/iphone/Default-Landscape.png
  9. BIN Resources/iphone/Default-Portrait.png
  10. BIN Resources/iphone/Default.png
  11. BIN Resources/iphone/Default@2x.png
  12. BIN Resources/iphone/appicon.png
  13. BIN Resources/mobileweb/appicon.png
  14. BIN Resources/mobileweb/apple_startup_images/Default-Landscape.jpg
  15. BIN Resources/mobileweb/apple_startup_images/Default-Landscape.png
  16. BIN Resources/mobileweb/apple_startup_images/Default-Portrait.jpg
  17. BIN Resources/mobileweb/apple_startup_images/Default-Portrait.png
  18. BIN Resources/mobileweb/apple_startup_images/Default.jpg
  19. BIN Resources/mobileweb/apple_startup_images/Default.png
  20. +8 −0 Resources/mobileweb/apple_startup_images/README
  21. +49 −0 Resources/mobileweb/splash/README
  22. BIN Resources/mobileweb/splash/appc.png
  23. +60 −0 Resources/mobileweb/splash/splash.css
  24. 0 Resources/mobileweb/splash/splash.html
  25. BIN Resources/mobileweb/splash/titanium.png
  26. +48 −0 build/iphone/Classes/AFOpenFlow/AFItemView.h
  27. +97 −0 build/iphone/Classes/AFOpenFlow/AFItemView.m
  28. +33 −0 build/iphone/Classes/AFOpenFlow/AFOpenFlowConstants.h
  29. +87 −0 build/iphone/Classes/AFOpenFlow/AFOpenFlowView.h
  30. +474 −0 build/iphone/Classes/AFOpenFlow/AFOpenFlowView.m
  31. +37 −0 build/iphone/Classes/AFOpenFlow/AFUIImageReflection.h
  32. +102 −0 build/iphone/Classes/AFOpenFlow/AFUIImageReflection.m
  33. +38 −0 build/iphone/Classes/AFOpenFlow/UIImageExtras.h
  34. +80 −0 build/iphone/Classes/AFOpenFlow/UIImageExtras.m
  35. +17 −0 build/iphone/Classes/APIModule.h
  36. +119 −0 build/iphone/Classes/APIModule.m
  37. +104 −0 build/iphone/Classes/AQRecorder.h
  38. +361 −0 build/iphone/Classes/AQRecorder.mm
  39. +35 −0 build/iphone/Classes/ASI/ASIAuthenticationDialog.h
  40. +493 −0 build/iphone/Classes/ASI/ASIAuthenticationDialog.m
  41. +103 −0 build/iphone/Classes/ASI/ASICacheDelegate.h
  42. +42 −0 build/iphone/Classes/ASI/ASIDataCompressor.h
  43. +219 −0 build/iphone/Classes/ASI/ASIDataCompressor.m
  44. +41 −0 build/iphone/Classes/ASI/ASIDataDecompressor.h
  45. +218 −0 build/iphone/Classes/ASI/ASIDataDecompressor.m
  46. +46 −0 build/iphone/Classes/ASI/ASIDownloadCache.h
  47. +514 −0 build/iphone/Classes/ASI/ASIDownloadCache.m
  48. +76 −0 build/iphone/Classes/ASI/ASIFormDataRequest.h
  49. +361 −0 build/iphone/Classes/ASI/ASIFormDataRequest.m
  50. +1,019 −0 build/iphone/Classes/ASI/ASIHTTPRequest.h
  51. +5,210 −0 build/iphone/Classes/ASI/ASIHTTPRequest.m
  52. +37 −0 build/iphone/Classes/ASI/ASIHTTPRequestConfig.h
  53. +35 −0 build/iphone/Classes/ASI/ASIHTTPRequestDelegate.h
  54. +26 −0 build/iphone/Classes/ASI/ASIInputStream.h
  55. +138 −0 build/iphone/Classes/ASI/ASIInputStream.m
  56. +108 −0 build/iphone/Classes/ASI/ASINetworkQueue.h
  57. +343 −0 build/iphone/Classes/ASI/ASINetworkQueue.m
  58. +38 −0 build/iphone/Classes/ASI/ASIProgressDelegate.h
  59. +193 −0 build/iphone/Classes/ASI/Reachability.h
  60. +817 −0 build/iphone/Classes/ASI/Reachability.m
  61. +19 −0 build/iphone/Classes/AccelerometerModule.h
  62. +48 −0 build/iphone/Classes/AccelerometerModule.m
  63. +23 −0 build/iphone/Classes/AnalyticsModule.h
  64. +716 −0 build/iphone/Classes/AnalyticsModule.mm
  65. +57 −0 build/iphone/Classes/AppModule.h
  66. +509 −0 build/iphone/Classes/AppModule.m
  67. +17 −0 build/iphone/Classes/ApplicationDefaults.h
  68. +21 −0 build/iphone/Classes/ApplicationDefaults.m
  69. +11 −0 build/iphone/Classes/ApplicationMods.h
  70. +15 −0 build/iphone/Classes/ApplicationMods.m
  71. +10 −0 build/iphone/Classes/ApplicationRouting.h
  72. +19 −0 build/iphone/Classes/ApplicationRouting.m
  73. +690 −0 build/iphone/Classes/AsyncSocket.h
  74. +4,368 −0 build/iphone/Classes/AsyncSocket.m
  75. +366 −0 build/iphone/Classes/AsyncUdpSocket.h
  76. +2,343 −0 build/iphone/Classes/AsyncUdpSocket.m
  77. +139 −0 build/iphone/Classes/AudioStreamer/AudioStreamer.h
  78. +182 −0 build/iphone/Classes/AudioStreamer/AudioStreamer.m
  79. +109 −0 build/iphone/Classes/AudioStreamer/AudioStreamerCUR.h
  80. +1,863 −0 build/iphone/Classes/AudioStreamer/AudioStreamerCUR.m
  81. +232 −0 build/iphone/Classes/Base64Transcoder.c
  82. +44 −0 build/iphone/Classes/Base64Transcoder.h
  83. +36 −0 build/iphone/Classes/Bridge.h
  84. +84 −0 build/iphone/Classes/Bridge.m
  85. +94 −0 build/iphone/Classes/CADebugMacros.cpp
  86. +443 −0 build/iphone/Classes/CADebugMacros.h
  87. +74 −0 build/iphone/Classes/CAMath.h
  88. +554 −0 build/iphone/Classes/CAStreamBasicDescription.cpp
  89. +312 −0 build/iphone/Classes/CAStreamBasicDescription.h
  90. +56 −0 build/iphone/Classes/CAXException.cpp
  91. +218 −0 build/iphone/Classes/CAXException.h
  92. +42 −0 build/iphone/Classes/CodecModule.h
  93. +351 −0 build/iphone/Classes/CodecModule.m
  94. +50 −0 build/iphone/Classes/ContactsModule.h
  95. +458 −0 build/iphone/Classes/ContactsModule.m
  96. +26 −0 build/iphone/Classes/DatabaseModule.h
  97. +52 −0 build/iphone/Classes/DatabaseModule.m
  98. +25 −0 build/iphone/Classes/FBConnect/FBConnect.h
  99. +166 −0 build/iphone/Classes/FBConnect/FBDialog.h
  100. +688 −0 build/iphone/Classes/FBConnect/FBDialog.m
  101. +75 −0 build/iphone/Classes/FBConnect/FBFrictionlessRequestSettings.h
  102. +163 −0 build/iphone/Classes/FBConnect/FBFrictionlessRequestSettings.m
  103. +41 −0 build/iphone/Classes/FBConnect/FBLoginButton.h
  104. +92 −0 build/iphone/Classes/FBConnect/FBLoginButton.m
  105. +47 −0 build/iphone/Classes/FBConnect/FBLoginDialog.h
  106. +115 −0 build/iphone/Classes/FBConnect/FBLoginDialog.m
  107. +142 −0 build/iphone/Classes/FBConnect/FBRequest.h
  108. +382 −0 build/iphone/Classes/FBConnect/FBRequest.m
  109. +165 −0 build/iphone/Classes/FBConnect/Facebook.h
Sorry, we could not display the entire diff because too many files (1,666) changed.
1 CHANGELOG.txt
@@ -0,0 +1 @@
+Place your change log text here. This file will be incorporated with your app at package time.
219 LICENSE
@@ -0,0 +1,219 @@
+Copyright 2008-2012 Appcelerator, Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ (or the full text of the license is below)
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
1 LICENSE.txt
@@ -0,0 +1 @@
+Place your license text here. This file will be incorporated with your app at package time.
18 README
@@ -0,0 +1,18 @@
+Welcome to your Appcelerator Titanium Mobile Project
+
+This is a blank project. Start by editing your application's app.js to
+make your first mobile project using Titanium.
+
+
+
+----------------------------------
+Stuff our legal folk make us say:
+
+Appcelerator, Appcelerator Titanium and associated marks and logos are
+trademarks of Appcelerator, Inc.
+
+Titanium is Copyright (c) 2008-2012 by Appcelerator, Inc. All Rights Reserved.
+
+Titanium is licensed under the Apache Public License (Version 2). Please
+see the LICENSE file for the full license.
+
BIN Resources/KS_nav_ui.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN Resources/KS_nav_views.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
164 Resources/app.js
@@ -0,0 +1,164 @@
+// 10min + 5min(Q&A) 最後に拍手
+// 20min + 5min(Q&A) 最後に拍手
+//optiondialog , switch
+
+Titanium.UI.setBackgroundColor('#000');
+
+var ground = Ti.UI.createWindow({
+ layout: 'vertical'
+});
+
+var top = Ti.UI.createView({
+ backgroundColor: '#333',
+ height: 100
+});
+
+var title = Ti.UI.createLabel({
+ text: 'toteka timer',
+ textAlign: 'center',
+ color: '#ddd',
+ height: '120%',
+})
+
+var contents = Ti.UI.createView({
+ backgroundColor: '#000',
+ height: '70%',
+ layout: 'vertical',
+});
+
+var qa = Ti.UI.createLabel({
+ text: '',
+ color: 'white',
+ font:{fontSize: '70%'},
+});
+
+var count = Ti.UI.createLabel({
+ text: '88:88',
+ color: '#444',
+ font:{fontSize: '200%'},
+});
+
+var footer = Ti.UI.createView({
+ backgroundColor: '#333',
+ height: 50
+});
+
+var toolview = Ti.UI.createView({
+ backgroundColor: '#333',
+ layout: 'horizontal',
+ left: 20,
+ top: 10
+});
+
+var start = Ti.UI.createButton({
+ title: 'start',
+});
+
+var stop = Ti.UI.createButton({
+ title: 'stop',
+ left: 10,
+});
+
+var clear = Ti.UI.createButton({
+ title: 'clear',
+ left: 10,
+});
+
+function date_format(counting) {
+ var min = parseInt(counting / 60);
+ var sec = counting % 60;
+ var disp_time = '';
+
+ console.log("min >>" + min + "sec >>" + sec);
+ if (min < 10) {
+ disp_time += '0';
+ }
+ disp_time += min;
+ disp_time += ':';
+ if (sec < 10) {
+ disp_time += '0';
+ }
+ disp_time += sec;
+ console.log(disp_time);
+ return disp_time;
+}
+
+function update () {
+ var tmp_time = new Date();
+
+ if (tmp_time.getSeconds() - past_time.getSeconds() >= 1) {
+ counting -= 1;
+ if (counting < 0) {
+ stop.fireEvent('click');
+ qa.text = '';
+ count.text = "Finish";
+ } else {
+ if (counting == remain) {
+ contents.backgroundColor = '#777';
+ qa.text = 'Question?';
+ }
+ count.text = date_format(counting);
+ past_time = tmp_time;
+ timer_id = setTimeout("update()", 100);
+ }
+ } else {
+ timer_id = setTimeout("update()", 100);
+ }
+};
+
+var start_time;
+var past_time;
+var counting;
+var timer_id;
+var pause = 0;
+
+function timerClear(){
+ start_time = new Date();
+ past_time = start_time;
+ counting = 10;
+ remain = 5;
+ count.text = date_format(counting);
+ qa.text = '';
+ contents.backgroundColor = '#000';
+ pause = 0;
+}
+
+clear.addEventListener('click', function (){
+ timerClear();
+});
+
+start.addEventListener('click', function () {
+ console.log("start");
+
+ if (pause === 0) {
+ timerClear();
+ } else {
+ var tmp_time = new Date();
+ past_time = tmp_time;
+ }
+ pause = 0;
+ timer_id = setTimeout("update()", 300);
+});
+
+stop.addEventListener('click', function () {
+ console.log("stop timer.");
+ clearTimeout(timer_id);
+ pause = 1;
+});
+
+top.add(title);
+contents.add(qa);
+contents.add(count);
+
+toolview.add(start);
+toolview.add(stop);
+toolview.add(clear);
+
+footer.add(toolview);
+
+ground.add(top);
+ground.add(contents);
+ground.add(footer);
+ground.open();
+
+
BIN Resources/iphone/Default-Landscape.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN Resources/iphone/Default-Portrait.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN Resources/iphone/Default.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN Resources/iphone/Default@2x.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN Resources/iphone/appicon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN Resources/mobileweb/appicon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN Resources/mobileweb/apple_startup_images/Default-Landscape.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN Resources/mobileweb/apple_startup_images/Default-Landscape.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN Resources/mobileweb/apple_startup_images/Default-Portrait.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN Resources/mobileweb/apple_startup_images/Default-Portrait.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN Resources/mobileweb/apple_startup_images/Default.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN Resources/mobileweb/apple_startup_images/Default.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 Resources/mobileweb/apple_startup_images/README
@@ -0,0 +1,8 @@
+These startup images are used by iPhone and iPad apps that are installed to the
+home screen. These images are displayed before the splash screen is displayed.
+
+If you want to create a new splash screen, it is recommended that you start by
+modifying the files in the adjacent "splash" folder, then take screenshots of
+device, crop, and save into this directory. This is the best way to avoid visual
+artifacts when the app transitions from the Apple startup images to the splash
+screen assets.
49 Resources/mobileweb/splash/README
@@ -0,0 +1,49 @@
+This folder contains assets to make the startup splash screen assets. Splash
+screens are made up of HTML and CSS. This allows you the flexibility to
+customize your splash screen to fit a variety of screen sizes and orientations.
+
+
+splash.html
+-----------
+Contains an HTML fragment that is inserted into a div tag with an id="splash".
+You can choose to leave this file empty. You can put <script> tags in this file,
+though it is not recommended.
+
+Currently, the HTML code is NOT minified before being inserted into the page.
+
+
+splash.css
+----------
+Contains the styles used to control the display of the HTML. In addition to
+styling the default splash div, you can style other HTML elements.
+
+One advantage of using CSS background images in your splash screen is the images
+will be inlined in the CSS using data: URIs. It's best to keep the size of your
+images as small as possible. You can use PNG, JPG, or GIF images. You should use
+an image optimization tool to remove unnecessary meta data from the images such
+as smushit.com or crushpng.
+
+It is recommended that you develop your splash screen on an iPhone-sized screen
+so that you make your splash screen look good on small screens.
+
+Additionally, it is recommended that you use CSS media queries to tweak the
+layout for various screen sizes.
+
+The CSS code is minified when your mobile web application is packaged.
+
+
+Apple Startup Images
+--------------------
+After crafting your startup screen, it is recommended that you:
+
+1) Create a sample application with an empty app.js
+2) Run your sample app in both the iphone and ipad simulator
+3) Take screenshots of your splash screen in both portrait and landscape
+4) Crop the screenshots to remove the status bar from the top
+5) Save the images in the Resources/mobileweb/apple_startup_images directory
+
+These steps are the best way to avoid visual artifacts when the app transitions
+from the Apple startup images to the splash screen assets.
+
+It is recommended you save these images in the JPG format so that these images
+download faster.
BIN Resources/mobileweb/splash/appc.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
60 Resources/mobileweb/splash/splash.css
@@ -0,0 +1,60 @@
+#splash {
+ background: #9a0707;
+ background: -moz-linear-gradient(top,#9a0707 0%,#5c0404 100%);
+ background: -webkit-gradient(linear,left top,left bottom,color-stop(0%,#9a0707),color-stop(100%,#5c0404));
+ background: -webkit-linear-gradient(top,#9a0707 0%,#5c0404 100%);
+ background: -o-linear-gradient(top,#9a0707 0%,#5c0404 100%);
+ background: -ms-linear-gradient(top,#9a0707 0%,#5c0404 100%);
+ background: linear-gradient(top,#9a0707 0%,#5c0404 100%);
+ -webkit-box-shadow: inset 0px 0px 15px 6px rgba(0,0,0,0.5);
+ -moz-box-shadow: inset 0px 0px 15px 6px rgba(0,0,0,0.5);
+ box-shadow: inset 0px 0px 15px 6px rgba(0,0,0,0.5);
+ bottom: 0;
+ min-height: 300px;
+ left: 0;
+ position: fixed;
+ right: 0;
+ top: 0;
+}
+
+#splash:before {
+ background: url(appc.png) no-repeat 0 0;
+ content: "";
+ height: 150px;
+ left: 50%;
+ margin-left: -85px;
+ position: absolute;
+ top: 22%;
+ width: 170px;
+}
+
+#splash:after {
+ background: url(titanium.png) no-repeat 0 0;
+ content: "";
+ height: 48px;
+ left: 50%;
+ margin-left: -105px;
+ position: absolute;
+ bottom: 15%;
+ width: 200px;
+}
+
+@media all and (max-height: 320px) {
+ #splash:before {
+ top: 15%;
+ }
+
+ #splash:after {
+ bottom: 12%;
+ }
+}
+
+@media all and (min-height: 699px) {
+ #splash:before {
+ top: 25%;
+ }
+
+ #splash:after {
+ bottom: 25%;
+ }
+}
0 Resources/mobileweb/splash/splash.html
No changes.
BIN Resources/mobileweb/splash/titanium.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
48 build/iphone/Classes/AFOpenFlow/AFItemView.h
@@ -0,0 +1,48 @@
+/**
+ * Copyright (c) 2009 Alex Fajkowski, Apparent Logic LLC
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#if defined(USE_TI_UIIOSCOVERFLOWVIEW) || defined(USE_TI_UICOVERFLOWVIEW)
+
+#import <UIKit/UIKit.h>
+
+
+@interface AFItemView : UIView {
+ UIImageView *imageView;
+ int number;
+ CGFloat horizontalPosition;
+ CGFloat verticalPosition;
+ CGFloat originalImageHeight;
+}
+
+@property int number;
+@property (nonatomic, readonly) CGFloat horizontalPosition;
+@property (nonatomic, readonly) CGFloat verticalPosition;
+@property (nonatomic, readonly) UIImageView *imageView;
+
+- (void)setImage:(UIImage *)newImage originalImageHeight:(CGFloat)imageHeight reflectionFraction:(CGFloat)reflectionFraction;
+- (CGSize)calculateNewSize:(CGSize)originalImageSize boundingBox:(CGSize)boundingBox;
+
+@end
+
+#endif
97 build/iphone/Classes/AFOpenFlow/AFItemView.m
@@ -0,0 +1,97 @@
+/**
+ * Copyright (c) 2009 Alex Fajkowski, Apparent Logic LLC
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#if defined(USE_TI_UIIOSCOVERFLOWVIEW) || defined(USE_TI_UICOVERFLOWVIEW)
+
+#import "AFItemView.h"
+#import <QuartzCore/QuartzCore.h>
+#import "AFOpenFlowConstants.h"
+
+
+@implementation AFItemView
+@synthesize imageView, horizontalPosition, verticalPosition;
+
+- (id)initWithFrame:(CGRect)frame {
+ if (self = [super initWithFrame:frame]) {
+ self.opaque = YES;
+ self.backgroundColor = NULL;
+ verticalPosition = 0;
+ horizontalPosition = 0;
+
+ // Image View
+ imageView = [[UIImageView alloc] initWithFrame:frame];
+ imageView.opaque = YES;
+ [self addSubview:imageView];
+ }
+
+ return self;
+}
+
+- (void)setImage:(UIImage *)newImage originalImageHeight:(CGFloat)imageHeight reflectionFraction:(CGFloat)reflectionFraction {
+ [imageView setImage:newImage];
+ verticalPosition = imageHeight * reflectionFraction / 2;
+ originalImageHeight = imageHeight;
+ self.frame = CGRectMake(0, 0, newImage.size.width, newImage.size.height);
+}
+
+- (int)number {
+ return number;
+}
+
+- (void)setNumber:(int)newNumber {
+ horizontalPosition = COVER_SPACING * newNumber;
+ number = newNumber;
+}
+
+- (CGSize)calculateNewSize:(CGSize)baseImageSize boundingBox:(CGSize)boundingBox {
+ CGFloat boundingRatio = boundingBox.width / boundingBox.height;
+ CGFloat originalImageRatio = baseImageSize.width / baseImageSize.height;
+
+ CGFloat newWidth;
+ CGFloat newHeight;
+ if (originalImageRatio > boundingRatio) {
+ newWidth = boundingBox.width;
+ newHeight = boundingBox.width * baseImageSize.height / baseImageSize.width;
+ } else {
+ newHeight = boundingBox.height;
+ newWidth = boundingBox.height * baseImageSize.width / baseImageSize.height;
+ }
+
+ return CGSizeMake(newWidth, newHeight);
+}
+
+- (void)setFrame:(CGRect)newFrame {
+ [super setFrame:newFrame];
+ [imageView setFrame:newFrame];
+}
+
+- (void)dealloc {
+ [imageView release];
+
+ [super dealloc];
+}
+
+@end
+
+#endif
33 build/iphone/Classes/AFOpenFlow/AFOpenFlowConstants.h
@@ -0,0 +1,33 @@
+/**
+ * Copyright (c) 2009 Alex Fajkowski, Apparent Logic LLC
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#if defined(USE_TI_UIIOSCOVERFLOWVIEW) || defined(USE_TI_UICOVERFLOWVIEW)
+
+// For OpenFlow
+#define COVER_SPACING 40
+#define CENTER_COVER_OFFSET 70
+#define SIDE_COVER_ANGLE .79
+#define SIDE_COVER_ZPOSITION -80
+
+#endif
87 build/iphone/Classes/AFOpenFlow/AFOpenFlowView.h
@@ -0,0 +1,87 @@
+/**
+ * Copyright (c) 2009 Alex Fajkowski, Apparent Logic LLC
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#if defined(USE_TI_UIIOSCOVERFLOWVIEW) || defined(USE_TI_UICOVERFLOWVIEW)
+
+#import <UIKit/UIKit.h>
+#import "AFItemView.h"
+#import <QuartzCore/QuartzCore.h>
+
+
+@protocol AFOpenFlowViewDataSource;
+@protocol AFOpenFlowViewDelegate;
+
+@interface AFOpenFlowView : UIView {
+ id <AFOpenFlowViewDataSource> dataSource;
+ id <AFOpenFlowViewDelegate> viewDelegate;
+ NSMutableSet *offscreenCovers;
+ NSMutableDictionary *onscreenCovers;
+ NSMutableDictionary *coverImages;
+ NSMutableDictionary *coverImageHeights;
+ UIImage *defaultImage;
+ CGFloat defaultImageHeight;
+
+ UIScrollView *scrollView;
+ int lowerVisibleCover;
+ int upperVisibleCover;
+ int numberOfImages;
+ int beginningCover;
+
+ AFItemView *selectedCoverView;
+
+ CATransform3D leftTransform, rightTransform;
+
+ CGFloat halfScreenHeight;
+ CGFloat halfScreenWidth;
+
+ Boolean isSingleTap;
+ Boolean isDoubleTap;
+ Boolean isDraggingACover;
+ CGFloat startPosition;
+}
+
+@property (nonatomic, assign) id <AFOpenFlowViewDataSource> dataSource;
+@property (nonatomic, assign) id <AFOpenFlowViewDelegate> viewDelegate;
+@property (nonatomic, retain) UIImage *defaultImage;
+@property (nonatomic) int numberOfImages;
+
+- (void)setSelectedCover:(int)newSelectedCover;
+- (void)centerOnSelectedCover:(BOOL)animated;
+- (void)setImage:(UIImage *)image forIndex:(int)index;
+- (void)updateLayout;
+
+@end
+
+@protocol AFOpenFlowViewDelegate <NSObject>
+@optional
+- (void)openFlowView:(AFOpenFlowView *)openFlowView click:(int)index;
+- (void)openFlowView:(AFOpenFlowView *)openFlowView selectionDidChange:(int)index;
+@end
+
+@protocol AFOpenFlowViewDataSource <NSObject>
+- (void)openFlowView:(AFOpenFlowView *)openFlowView requestImageForIndex:(int)index;
+- (UIImage *)defaultImage;
+@end
+
+#endif
474 build/iphone/Classes/AFOpenFlow/AFOpenFlowView.m
@@ -0,0 +1,474 @@
+/**
+ * Copyright (c) 2009 Alex Fajkowski, Apparent Logic LLC
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#if defined(USE_TI_UIIOSCOVERFLOWVIEW) || defined(USE_TI_UICOVERFLOWVIEW)
+
+#import "AFOpenFlowView.h"
+#import "AFOpenFlowConstants.h"
+#import "AFUIImageReflection.h"
+
+
+@interface AFOpenFlowView (hidden)
+
+- (void)setUpInitialState;
+- (AFItemView *)coverForIndex:(int)coverIndex;
+- (void)updateCoverImage:(AFItemView *)aCover;
+- (AFItemView *)dequeueReusableCover;
+- (void)layoutCovers:(int)selected fromCover:(int)lowerBound toCover:(int)upperBound;
+- (void)layoutCover:(AFItemView *)aCover selectedCover:(int)selectedIndex animated:(Boolean)animated;
+- (AFItemView *)findCoverOnscreen:(CALayer *)targetLayer;
+
+@end
+
+@implementation AFOpenFlowView (hidden)
+
+const static CGFloat kReflectionFraction = 0.85;
+
+- (void)setUpInitialState {
+ // Set up the default image for the coverflow.
+ self.defaultImage = [self.dataSource defaultImage];
+
+ // Create data holders for onscreen & offscreen covers & UIImage objects.
+ coverImages = [[NSMutableDictionary alloc] init];
+ coverImageHeights = [[NSMutableDictionary alloc] init];
+ offscreenCovers = [[NSMutableSet alloc] init];
+ onscreenCovers = [[NSMutableDictionary alloc] init];
+
+ scrollView = [[UIScrollView alloc] initWithFrame:self.frame];
+ scrollView.userInteractionEnabled = NO;
+ scrollView.multipleTouchEnabled = NO;
+ scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ [self addSubview:scrollView];
+
+ self.multipleTouchEnabled = NO;
+ self.userInteractionEnabled = YES;
+ self.autoresizesSubviews = YES;
+ self.layer.position=CGPointMake(self.frame.size.width / 2, self.frame.size.height / 2);
+
+ // Initialize the visible and selected cover range.
+ lowerVisibleCover = upperVisibleCover = -1;
+ selectedCoverView = nil;
+
+ // Set up the cover's left & right transforms.
+ leftTransform = CATransform3DTranslate(CATransform3DIdentity, 0, 0, SIDE_COVER_ZPOSITION);
+ leftTransform = CATransform3DRotate(leftTransform, SIDE_COVER_ANGLE, 0.0f, 1.0f, 0.0f);
+ rightTransform = CATransform3DTranslate(CATransform3DIdentity, 0, 0, SIDE_COVER_ZPOSITION);
+ rightTransform = CATransform3DRotate(rightTransform, SIDE_COVER_ANGLE, 0.0f, -1.0f, 0.0f);
+
+ // Set some perspective
+ CATransform3D sublayerTransform = CATransform3DIdentity;
+ sublayerTransform.m34 = -0.01;
+ [scrollView.layer setSublayerTransform:sublayerTransform];
+
+ [self updateLayout];
+}
+
+- (AFItemView *)coverForIndex:(int)coverIndex {
+ AFItemView *coverView = [self dequeueReusableCover];
+ if (!coverView)
+ coverView = [[[AFItemView alloc] initWithFrame:CGRectZero] autorelease];
+
+ coverView.number = coverIndex;
+
+ return coverView;
+}
+
+- (void)updateCoverImage:(AFItemView *)aCover {
+ NSNumber *coverNumber = [NSNumber numberWithInt:aCover.number];
+ UIImage *coverImage = (UIImage *)[coverImages objectForKey:coverNumber];
+ if (coverImage) {
+ NSNumber *coverImageHeightNumber = (NSNumber *)[coverImageHeights objectForKey:coverNumber];
+ if (coverImageHeightNumber)
+ [aCover setImage:coverImage originalImageHeight:[coverImageHeightNumber floatValue] reflectionFraction:kReflectionFraction];
+ } else {
+ // Bugfix for invalid defaultImage - SPT
+ UIImage* cover = defaultImage;
+ if (cover == nil) {
+ cover = [self.dataSource defaultImage];
+ }
+ [aCover setImage:cover originalImageHeight:defaultImageHeight reflectionFraction:kReflectionFraction];
+ [self.dataSource openFlowView:self requestImageForIndex:aCover.number];
+ }
+}
+
+- (AFItemView *)dequeueReusableCover {
+ AFItemView *aCover = [offscreenCovers anyObject];
+ if (aCover) {
+ [[aCover retain] autorelease];
+ [offscreenCovers removeObject:aCover];
+ }
+ return aCover;
+}
+
+- (void)layoutCover:(AFItemView *)aCover selectedCover:(int)selectedIndex animated:(Boolean)animated {
+ int coverNumber = aCover.number;
+ CATransform3D newTransform;
+ CGPoint newPosition;
+
+ newPosition.x = halfScreenWidth + aCover.horizontalPosition;
+ newPosition.y = halfScreenHeight + aCover.verticalPosition;
+ if (coverNumber < selectedIndex) {
+ newPosition.x -= CENTER_COVER_OFFSET;
+ newTransform = leftTransform;
+ } else if (coverNumber > selectedIndex) {
+ newPosition.x += CENTER_COVER_OFFSET;
+ newTransform = rightTransform;
+ } else {
+ newTransform = CATransform3DIdentity;
+ }
+
+ if (animated) {
+ [UIView beginAnimations:nil context:nil];
+ [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
+ [UIView setAnimationBeginsFromCurrentState:YES];
+ }
+
+ aCover.layer.transform = newTransform;
+ aCover.layer.position = newPosition;
+
+ if (animated) {
+ [UIView commitAnimations];
+ }
+}
+
+- (void)layoutCovers:(int)selected fromCover:(int)lowerBound toCover:(int)upperBound {
+ AFItemView *cover;
+ NSNumber *coverNumber;
+ for (int i = lowerBound; i <= upperBound; i++) {
+ coverNumber = [[NSNumber alloc] initWithInt:i];
+ cover = (AFItemView *)[onscreenCovers objectForKey:coverNumber];
+ [coverNumber release];
+ [self layoutCover:cover selectedCover:selected animated:YES];
+ }
+}
+
+- (AFItemView *)findCoverOnscreen:(CALayer *)targetLayer {
+ // See if this layer is one of our covers.
+ NSEnumerator *coverEnumerator = [onscreenCovers objectEnumerator];
+ AFItemView *aCover = nil;
+ while (aCover = (AFItemView *)[coverEnumerator nextObject])
+ if ([[aCover.imageView layer] isEqual:targetLayer])
+ break;
+
+ return aCover;
+}
+@end
+
+
+@implementation AFOpenFlowView
+@synthesize dataSource, viewDelegate, numberOfImages, defaultImage;
+
+#define COVER_BUFFER 6
+
+- (void)awakeFromNib {
+ [self setUpInitialState];
+}
+
+- (id)initWithFrame:(CGRect)frame {
+ if (self = [super initWithFrame:frame]) {
+ [self setUpInitialState];
+ }
+
+ return self;
+}
+
+- (void)dealloc {
+ [defaultImage release];
+ [scrollView release];
+
+ [coverImages release];
+ [coverImageHeights release];
+ [offscreenCovers removeAllObjects];
+ [offscreenCovers release];
+
+ [onscreenCovers removeAllObjects];
+ [onscreenCovers release];
+
+ [super dealloc];
+}
+
+- (void)updateLayout
+{
+ halfScreenWidth = self.bounds.size.width / 2;
+ halfScreenHeight = self.bounds.size.height / 2;
+
+ int lowerBound = MAX(-1, selectedCoverView.number - COVER_BUFFER);
+ int upperBound = MIN(self.numberOfImages - 1, selectedCoverView.number + COVER_BUFFER);
+
+ [self layoutCovers:selectedCoverView.number fromCover:lowerBound toCover:upperBound];
+ [self centerOnSelectedCover:NO];
+}
+
+- (void)setFrame:(CGRect)newSize {
+ [super setFrame:newSize];
+ [self updateLayout];
+}
+
+- (void)setBounds:(CGRect)newSize {
+ [super setBounds:newSize];
+ scrollView.contentSize = CGSizeMake(numberOfImages * COVER_SPACING + self.bounds.size.width, self.bounds.size.height);
+ [self updateLayout];
+}
+
+- (void)setNumberOfImages:(int)newNumberOfImages {
+ numberOfImages = newNumberOfImages;
+ scrollView.contentSize = CGSizeMake(newNumberOfImages * COVER_SPACING + self.bounds.size.width, self.bounds.size.height);
+
+ int lowerBound = MAX(0, selectedCoverView.number - COVER_BUFFER);
+ int upperBound = MIN(self.numberOfImages - 1, selectedCoverView.number + COVER_BUFFER);
+
+ if (selectedCoverView)
+ [self layoutCovers:selectedCoverView.number fromCover:lowerBound toCover:upperBound];
+ else
+ [self setSelectedCover:0];
+
+ [self centerOnSelectedCover:NO];
+}
+
+- (void)setDefaultImage:(UIImage *)newDefaultImage {
+ [defaultImage release];
+ if (newDefaultImage)
+ {
+ defaultImageHeight = newDefaultImage.size.height;
+ defaultImage = [AddImageReflection(newDefaultImage,kReflectionFraction) retain];
+ }
+}
+
+- (void)setImage:(UIImage *)image forIndex:(int)index {
+ if (image==nil) return;
+ // Create a reflection for this image.
+ UIImage *imageWithReflection = AddImageReflection(image,kReflectionFraction);
+ NSNumber *coverNumber = [NSNumber numberWithInt:index];
+ [coverImages setObject:imageWithReflection forKey:coverNumber];
+ [coverImageHeights setObject:[NSNumber numberWithFloat:image.size.height] forKey:coverNumber];
+
+ // If this cover is onscreen, set its image and call layoutCover.
+ AFItemView *aCover = (AFItemView *)[onscreenCovers objectForKey:[NSNumber numberWithInt:index]];
+ if (aCover) {
+ [aCover setImage:imageWithReflection originalImageHeight:image.size.height reflectionFraction:kReflectionFraction];
+ [self layoutCover:aCover selectedCover:selectedCoverView.number animated:NO];
+ }
+}
+
+- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
+ CGPoint startPoint = [[touches anyObject] locationInView:self];
+ isDraggingACover = NO;
+
+ // Which cover did the user tap?
+ CALayer *targetLayer = (CALayer *)[scrollView.layer hitTest:startPoint];
+ AFItemView *targetCover = [self findCoverOnscreen:targetLayer];
+ isDraggingACover = (targetCover != nil);
+
+ beginningCover = selectedCoverView.number;
+ // Make sure the user is tapping on a cover.
+ startPosition = (startPoint.x / 1.5) + scrollView.contentOffset.x;
+
+ if (isSingleTap)
+ isDoubleTap = YES;
+
+ isSingleTap = ([touches count] == 1);
+}
+
+- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
+ isSingleTap = NO;
+ isDoubleTap = NO;
+
+ // Only scroll if the user started on a cover.
+ if (!isDraggingACover)
+ return;
+
+ CGPoint movedPoint = [[touches anyObject] locationInView:self];
+ CGFloat offset = startPosition - (movedPoint.x / 1.5);
+ CGPoint newPoint = CGPointMake(offset, 0);
+ scrollView.contentOffset = newPoint;
+ int newCover = offset / COVER_SPACING;
+ if (newCover != selectedCoverView.number) {
+ if (newCover < 0)
+ [self setSelectedCover:0];
+ else if (newCover >= self.numberOfImages)
+ [self setSelectedCover:self.numberOfImages - 1];
+ else
+ [self setSelectedCover:newCover];
+ }
+}
+
+- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
+ if (isSingleTap) {
+ // Which cover did the user tap?
+ CGPoint targetPoint = [[touches anyObject] locationInView:self];
+ CALayer *targetLayer = (CALayer *)[scrollView.layer hitTest:targetPoint];
+ AFItemView *targetCover = [self findCoverOnscreen:targetLayer];
+ if (targetCover && (targetCover.number != selectedCoverView.number))
+ [self setSelectedCover:targetCover.number];
+
+ //jhaynie: modification to send click events on single taps
+ if ([self.viewDelegate respondsToSelector:@selector(openFlowView:click:)])
+ {
+ [self.viewDelegate openFlowView:self click:selectedCoverView.number];
+ }
+ }
+ [self centerOnSelectedCover:YES];
+
+ // And send the delegate the newly selected cover message.
+ if (beginningCover != selectedCoverView.number)
+ if ([self.viewDelegate respondsToSelector:@selector(openFlowView:selectionDidChange:)])
+ [self.viewDelegate openFlowView:self selectionDidChange:selectedCoverView.number];
+}
+
+- (void)centerOnSelectedCover:(BOOL)animated {
+ CGPoint selectedOffset = CGPointMake(COVER_SPACING * selectedCoverView.number, 0);
+ animated &= (self.frame.size.width > 0);
+ [scrollView setContentOffset:selectedOffset animated:animated];
+}
+
+- (void)setSelectedCover:(int)newSelectedCover {
+ if (selectedCoverView && (newSelectedCover == selectedCoverView.number))
+ return;
+
+ AFItemView *cover;
+ int newLowerBound = MAX(0, newSelectedCover - COVER_BUFFER);
+ int newUpperBound = MIN(self.numberOfImages - 1, newSelectedCover + COVER_BUFFER);
+ if (!selectedCoverView) {
+ // Allocate and display covers from newLower to newUpper bounds.
+ for (int i=newLowerBound; i <= newUpperBound; i++) {
+ cover = [self coverForIndex:i];
+ [onscreenCovers setObject:cover forKey:[NSNumber numberWithInt:i]];
+ [self updateCoverImage:cover];
+ [scrollView.layer addSublayer:cover.layer];
+ [self layoutCover:cover selectedCover:newSelectedCover animated:NO];
+ }
+
+ lowerVisibleCover = newLowerBound;
+ upperVisibleCover = newUpperBound;
+ selectedCoverView = (AFItemView *)[onscreenCovers objectForKey:[NSNumber numberWithInt:newSelectedCover]];
+
+ return;
+ }
+
+ // Check to see if the new & current ranges overlap.
+ if ((newLowerBound > upperVisibleCover) || (newUpperBound < lowerVisibleCover)) {
+ // They do not overlap at all.
+ // This does not animate--assuming it's programmatically set from view controller.
+ // Recycle all onscreen covers.
+ AFItemView *cover;
+ for (int i = lowerVisibleCover; i <= upperVisibleCover; i++) {
+ cover = (AFItemView *)[onscreenCovers objectForKey:[NSNumber numberWithInt:i]];
+ [offscreenCovers addObject:cover];
+ [cover.layer removeFromSuperlayer];
+ [onscreenCovers removeObjectForKey:[NSNumber numberWithInt:cover.number]];
+ }
+
+ // Move all available covers to new location.
+ for (int i=newLowerBound; i <= newUpperBound; i++) {
+ cover = [self coverForIndex:i];
+ [onscreenCovers setObject:cover forKey:[NSNumber numberWithInt:i]];
+ [self updateCoverImage:cover];
+ [scrollView.layer addSublayer:cover.layer];
+ }
+
+ lowerVisibleCover = newLowerBound;
+ upperVisibleCover = newUpperBound;
+ selectedCoverView = (AFItemView *)[onscreenCovers objectForKey:[NSNumber numberWithInt:newSelectedCover]];
+ [self layoutCovers:newSelectedCover fromCover:newLowerBound toCover:newUpperBound];
+
+ return;
+ } else if (newSelectedCover > selectedCoverView.number) {
+ // Move covers that are now out of range on the left to the right side,
+ // but only if appropriate (within the range set by newUpperBound).
+ for (int i=lowerVisibleCover; i < newLowerBound; i++) {
+ cover = (AFItemView *)[onscreenCovers objectForKey:[NSNumber numberWithInt:i]];
+ if (upperVisibleCover < newUpperBound) {
+ // Tack it on the right side.
+ upperVisibleCover++;
+ cover.number = upperVisibleCover;
+ [self updateCoverImage:cover];
+ [onscreenCovers setObject:cover forKey:[NSNumber numberWithInt:cover.number]];
+ [self layoutCover:cover selectedCover:newSelectedCover animated:NO];
+ } else {
+ // Recycle this cover.
+ [offscreenCovers addObject:cover];
+ [cover.layer removeFromSuperlayer];
+ }
+ [onscreenCovers removeObjectForKey:[NSNumber numberWithInt:i]];
+ }
+ lowerVisibleCover = newLowerBound;
+
+ // Add in any missing covers on the right up to the newUpperBound.
+ for (int i=upperVisibleCover + 1; i <= newUpperBound; i++) {
+ cover = [self coverForIndex:i];
+ [onscreenCovers setObject:cover forKey:[NSNumber numberWithInt:i]];
+ [self updateCoverImage:cover];
+ [scrollView.layer addSublayer:cover.layer];
+ [self layoutCover:cover selectedCover:newSelectedCover animated:NO];
+ }
+ upperVisibleCover = newUpperBound;
+ } else {
+ // Move covers that are now out of range on the right to the left side,
+ // but only if appropriate (within the range set by newLowerBound).
+ for (int i=upperVisibleCover; i > newUpperBound; i--) {
+ cover = (AFItemView *)[onscreenCovers objectForKey:[NSNumber numberWithInt:i]];
+ if (lowerVisibleCover > newLowerBound) {
+ // Tack it on the left side.
+ lowerVisibleCover --;
+ cover.number = lowerVisibleCover;
+ [self updateCoverImage:cover];
+ [onscreenCovers setObject:cover forKey:[NSNumber numberWithInt:lowerVisibleCover]];
+ [self layoutCover:cover selectedCover:newSelectedCover animated:NO];
+ } else {
+ // Recycle this cover.
+ [offscreenCovers addObject:cover];
+ [cover.layer removeFromSuperlayer];
+ }
+ [onscreenCovers removeObjectForKey:[NSNumber numberWithInt:i]];
+ }
+ upperVisibleCover = newUpperBound;
+
+ // Add in any missing covers on the left down to the newLowerBound.
+ for (int i=lowerVisibleCover - 1; i >= newLowerBound; i--) {
+ cover = [self coverForIndex:i];
+ [onscreenCovers setObject:cover forKey:[NSNumber numberWithInt:i]];
+ [self updateCoverImage:cover];
+ [scrollView.layer addSublayer:cover.layer];
+ [self layoutCover:cover selectedCover:newSelectedCover animated:NO];
+ }
+ lowerVisibleCover = newLowerBound;
+ }
+
+ if (selectedCoverView.number > newSelectedCover)
+ [self layoutCovers:newSelectedCover fromCover:newSelectedCover toCover:selectedCoverView.number];
+ else if (newSelectedCover > selectedCoverView.number)
+ [self layoutCovers:newSelectedCover fromCover:selectedCoverView.number toCover:newSelectedCover];
+
+ selectedCoverView = (AFItemView *)[onscreenCovers objectForKey:[NSNumber numberWithInt:newSelectedCover]];
+}
+
+-(void)layoutSubviews
+{
+ [self centerOnSelectedCover:NO];
+ [super layoutSubviews];
+}
+
+@end
+
+#endif
37 build/iphone/Classes/AFOpenFlow/AFUIImageReflection.h
@@ -0,0 +1,37 @@
+/**
+ * Copyright (c) 2009 Alex Fajkowski, Apparent Logic LLC
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#if defined(USE_TI_UIIOSCOVERFLOWVIEW) || defined(USE_TI_UICOVERFLOWVIEW)
+
+#import <UIKit/UIKit.h>
+
+// Toteka modification note:
+// using categories with static libraries don't seem to work
+// right on device with iphone - probably a symbol issue
+// turn this into a static function (from what was a category to UIImage
+// originally)
+
+UIImage* AddImageReflection(UIImage *src, CGFloat reflectionFraction);
+
+#endif
102 build/iphone/Classes/AFOpenFlow/AFUIImageReflection.m
@@ -0,0 +1,102 @@
+/**
+ * Copyright (c) 2009 Alex Fajkowski, Apparent Logic LLC
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#if defined(USE_TI_UIIOSCOVERFLOWVIEW) || defined(USE_TI_UICOVERFLOWVIEW)
+
+#import "AFUIImageReflection.h"
+
+
+// Toteka modification note:
+// using categories with static libraries don't seem to work
+// right on device with iphone - probably a symbol issue
+// turn this into a static function (from what was a category to UIImage
+// originally)
+
+UIImage* AddImageReflection(UIImage *image, CGFloat reflectionFraction)
+{
+ int reflectionHeight = ceilf(image.size.height * reflectionFraction);
+
+ // create a 2 bit CGImage containing a gradient that will be used for masking the
+ // main view content to create the 'fade' of the reflection. The CGImageCreateWithMask
+ // function will stretch the bitmap image as required, so we can create a 1 pixel wide gradient
+ CGImageRef gradientMaskImage = NULL;
+
+ // gradient is always black-white and the mask must be in the gray colorspace
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
+
+ // create the bitmap context
+ CGContextRef gradientBitmapContext = CGBitmapContextCreate(nil, 1, reflectionHeight,
+ 8, 0, colorSpace, kCGImageAlphaNone);
+
+ // define the start and end grayscale values (with the alpha, even though
+ // our bitmap context doesn't support alpha the gradient requires it)
+ CGFloat colors[] = {0.0, 1.0, 1.0, 1.0};
+
+ // create the CGGradient and then release the gray color space
+ CGGradientRef grayScaleGradient = CGGradientCreateWithColorComponents(colorSpace, colors, NULL, 2);
+ CGColorSpaceRelease(colorSpace);
+
+ // create the start and end points for the gradient vector (straight down)
+ CGPoint gradientStartPoint = CGPointMake(0, reflectionHeight);
+ CGPoint gradientEndPoint = CGPointZero;
+
+ // draw the gradient into the gray bitmap context
+ CGContextDrawLinearGradient(gradientBitmapContext, grayScaleGradient, gradientStartPoint,
+ gradientEndPoint, kCGGradientDrawsAfterEndLocation);
+ CGGradientRelease(grayScaleGradient);
+
+ // add a black fill with 50% opacity
+ CGContextSetGrayFillColor(gradientBitmapContext, 0.0, 0.5);
+ CGContextFillRect(gradientBitmapContext, CGRectMake(0, 0, 1, reflectionHeight));
+
+ // convert the context into a CGImageRef and release the context
+ gradientMaskImage = CGBitmapContextCreateImage(gradientBitmapContext);
+ CGContextRelease(gradientBitmapContext);
+
+ // create an image by masking the bitmap of the mainView content with the gradient view
+ // then release the pre-masked content bitmap and the gradient bitmap
+ if((image.CGImage == NULL) || (gradientMaskImage == NULL))
+ {
+ CGImageRelease(gradientMaskImage);
+ return nil;
+ }
+ CGImageRef reflectionImage = CGImageCreateWithMask(image.CGImage, gradientMaskImage);
+ CGImageRelease(gradientMaskImage);
+
+ CGSize size = CGSizeMake(image.size.width, image.size.height + reflectionHeight);
+
+ UIGraphicsBeginImageContextWithOptions(size, NO, image.scale);
+
+ [image drawAtPoint:CGPointZero];
+ CGContextRef context = UIGraphicsGetCurrentContext();
+ CGContextDrawImage(context, CGRectMake(0, image.size.height, image.size.width, reflectionHeight), reflectionImage);
+
+ UIImage* result = UIGraphicsGetImageFromCurrentImageContext();
+ UIGraphicsEndImageContext();
+ CGImageRelease(reflectionImage);
+
+ return result;
+}
+
+#endif
38 build/iphone/Classes/AFOpenFlow/UIImageExtras.h
@@ -0,0 +1,38 @@
+/**
+ * Copyright (c) 2009 Alex Fajkowski, Apparent Logic LLC
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#import <UIKit/UIKit.h>
+
+/**
+ * Convenience methods to help with resizing images retrieved from the
+ * ObjectiveFlickr library.
+ */
+@interface UIImage (OpenFlowExtras)
+
+- (UIImage *)rescaleImageToSize:(CGSize)size;
+- (UIImage *)cropImageToRect:(CGRect)cropRect;
+- (CGSize)calculateNewSizeForCroppingBox:(CGSize)croppingBox;
+- (UIImage *)cropCenterAndScaleImageToSize:(CGSize)cropSize;
+
+@end
80 build/iphone/Classes/AFOpenFlow/UIImageExtras.m
@@ -0,0 +1,80 @@
+/**
+ * Copyright (c) 2009 Alex Fajkowski, Apparent Logic LLC
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#import "UIImageExtras.h"
+
+
+@implementation UIImage (OpenFlowExtras)
+
+- (UIImage *)rescaleImageToSize:(CGSize)size {
+ CGRect rect = CGRectMake(0.0, 0.0, size.width, size.height);
+ UIGraphicsBeginImageContextWithOptions(rect.size, NO, self.scale);
+ [self drawInRect:rect]; // scales image to rect
+ UIImage *resImage = UIGraphicsGetImageFromCurrentImageContext();
+ UIGraphicsEndImageContext();
+ return resImage;
+}
+
+- (UIImage *)cropImageToRect:(CGRect)cropRect {
+ // Begin the drawing (again)
+ UIGraphicsBeginImageContextWithOptions(cropRect.size, NO, self.scale);
+ CGContextRef ctx = UIGraphicsGetCurrentContext();
+
+ // Tanslate and scale upside-down to compensate for Quartz's inverted coordinate system
+ CGContextTranslateCTM(ctx, 0.0, cropRect.size.height);
+ CGContextScaleCTM(ctx, 1.0, -1.0);
+
+ // Draw view into context
+ CGRect drawRect = CGRectMake(-cropRect.origin.x, cropRect.origin.y - (self.size.height - cropRect.size.height) , self.size.width, self.size.height);
+ CGContextDrawImage(ctx, drawRect, self.CGImage);
+
+ // Create the new UIImage from the context
+ UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
+
+ // End the drawing
+ UIGraphicsEndImageContext();
+
+ return newImage;
+}
+
+- (CGSize)calculateNewSizeForCroppingBox:(CGSize)croppingBox {
+ // Make the shortest side be equivalent to the cropping box.
+ CGFloat newHeight, newWidth;
+ if (self.size.width < self.size.height) {
+ newWidth = croppingBox.width;
+ newHeight = (self.size.height / self.size.width) * croppingBox.width;
+ } else {
+ newHeight = croppingBox.height;
+ newWidth = (self.size.width / self.size.height) *croppingBox.height;
+ }
+
+ return CGSizeMake(newWidth, newHeight);
+}
+
+- (UIImage *)cropCenterAndScaleImageToSize:(CGSize)cropSize {
+ UIImage *scaledImage = [self rescaleImageToSize:[self calculateNewSizeForCroppingBox:cropSize]];
+ return [scaledImage cropImageToRect:CGRectMake((scaledImage.size.width-cropSize.width)/2, (scaledImage.size.height-cropSize.height)/2, cropSize.width, cropSize.height)];
+}
+
+@end
17 build/iphone/Classes/APIModule.h
@@ -0,0 +1,17 @@
+/**
+ * Appcelerator Titanium Mobile
+ * Copyright (c) 2009-2012 by Appcelerator, Inc. All Rights Reserved.
+ * Licensed under the terms of the Apache Public License
+ * Please see the LICENSE included with this distribution for details.
+ *
+ * WARNING: This is generated code. Modify at your own risk and without support.
+ */
+#import "TiModule.h"
+
+@interface APIModule : TiModule {
+
+}
+
+-(void)logMessage:(NSArray*)messages severity:(NSString*)severity; // Used by TiConsole
+
+@end
119 build/iphone/Classes/APIModule.m
@@ -0,0 +1,119 @@
+/**
+ * Appcelerator Titanium Mobile
+ * Copyright (c) 2009-2012 by Appcelerator, Inc. All Rights Reserved.
+ * Licensed under the terms of the Apache Public License
+ * Please see the LICENSE included with this distribution for details.
+ *
+ * WARNING: This is generated code. Modify at your own risk and without support.
+ */
+#import "APIModule.h"
+#import "TiUtils.h"
+#import "TiBase.h"
+#import "TiApp.h"
+#import "TiDebugger.h"
+
+@implementation APIModule
+
+-(void)logMessage:(NSArray*)args severity:(NSString*)severity
+{
+ NSMutableString* message = [NSMutableString string];
+
+ if ([[TiApp app] debugMode]) {
+ NSString* lcSeverity = [severity lowercaseString];
+ DebuggerLogLevel level = OUT;
+ NSMutableArray* messages = [NSMutableArray arrayWithArray:args];
+
+ if ([lcSeverity isEqualToString:@"warn"]) {
+ level = WARN;
+ }
+ else if ([lcSeverity isEqualToString:@"error"] ||
+ [lcSeverity isEqualToString:@"critical"] ||
+ [lcSeverity isEqualToString:@"fatal"]) {
+ level = ERR;
+ }
+ else if ([lcSeverity isEqualToString:@"trace"]) {
+ level = TRACE;
+ }
+ else if ([lcSeverity isEqualToString:@"debug"]) {
+ level = LOG_DEBUG;
+ }
+ else if (![lcSeverity isEqualToString:@"info"]) { // Custom severity, or just a badly-formed log; either way, debugger treats it as info
+ [messages insertObject:[NSString stringWithFormat:@"[%@]", severity] atIndex:0];
+ }
+
+ TiDebuggerLogMessage(level, [messages componentsJoinedByString:@" "]);
+ }
+ else {
+ NSLog(@"[%@] %@", [severity uppercaseString], [args componentsJoinedByString:@" "]);
+ fflush(stderr);
+ }
+}
+
+-(id)transform:(id)arg
+{
+ return [TiUtils exceptionMessage:arg];
+}
+
+-(void)debug:(NSArray*)args
+{
+ [self logMessage:args severity:@"debug"];
+}
+
+-(void)info:(NSArray*)args
+{
+ [self logMessage:args severity:@"info"];
+}
+
+-(void)warn:(NSArray*)args
+{
+ [self logMessage:args severity:@"warn"];
+}
+
+-(void)error:(NSArray*)args
+{
+ [self logMessage:args severity:@"error"];
+}
+
+-(void)trace:(NSArray*)args
+{
+ [self logMessage:args severity:@"trace"];
+}
+
+-(void)timestamp:(NSArray*)args
+{
+ NSLog(@"[TIMESTAMP] %f %@", [NSDate timeIntervalSinceReferenceDate], [self transform:[args objectAtIndex:0]]);
+ fflush(stderr);
+}
+
+-(void)notice:(NSArray*)args
+{
+ [self logMessage:args severity:@"info"];
+}
+
+-(void)critical:(NSArray*)args
+{
+ [self logMessage:args severity:@"error"];
+}
+
+-(void)log:(NSArray*)args
+{
+ if ([args count] > 1) {
+ [self logMessage:[args subarrayWithRange:NSMakeRange(1, [args count]-1)] severity:[args objectAtIndex:0]];
+ }
+ else {
+ [self logMessage:args severity:@"info"];
+ }
+}
+
+-(void)reportUnhandledException:(NSArray*)args
+{
+ id lineNumber = [args objectAtIndex:0];
+ id source = [args objectAtIndex:1];
+ id message = [args objectAtIndex:2];
+
+ NSLog(@"[ERROR] %@:%@ %@",source,lineNumber,message);
+ fflush(stderr);
+}
+
+
+@end
104 build/iphone/Classes/AQRecorder.h
@@ -0,0 +1,104 @@
+/*
+
+ File: AQRecorder.h
+ Abstract: Helper class for recording audio files via the AudioQueue
+ Version: 2.4
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2009 Apple Inc. All Rights Reserved.
+
+
+ */
+
+#ifdef USE_TI_MEDIA
+
+#include <AudioToolbox/AudioToolbox.h>
+#include <Foundation/Foundation.h>
+#include <libkern/OSAtomic.h>
+
+#include "CAStreamBasicDescription.h"
+#include "CAXException.h"
+
+#define kNumberRecordBuffers 3
+#define kBufferDurationSeconds .5
+
+class AQRecorder
+{
+public:
+ AQRecorder();
+ ~AQRecorder();
+
+ UInt32 GetNumberChannels() const { return mRecordFormat.NumberChannels(); }
+ CFStringRef GetFileName() const { return mFileName; }
+ AudioQueueRef Queue() const { return mQueue; }
+ CAStreamBasicDescription DataFormat() const { return mRecordFormat; }
+
+ void StartRecord(CFStringRef inRecordFile,UInt32 fileFormatID);
+ void PauseRecord(); //JGH: added
+ void ResumeRecord(); //JGH: added
+ void StopRecord();
+ Boolean IsRunning() const { return mIsRunning; }
+ Boolean IsPaused() const { return mIsPaused; } //JGH: added
+ void SetupAudioFormat(UInt32 inFormatID);
+
+ UInt64 startTime;
+
+private:
+ CFStringRef mFileName;
+ AudioQueueRef mQueue;
+ AudioQueueBufferRef mBuffers[kNumberRecordBuffers];
+ AudioFileID mRecordFile;
+ SInt64 mRecordPacket; // current packet number in record file
+ CAStreamBasicDescription mRecordFormat;
+ Boolean mIsRunning;
+ Boolean mIsPaused; //JGH: added
+
+ void CopyEncoderCookieToFile();
+ int ComputeRecordBufferSize(const AudioStreamBasicDescription *format, float seconds);
+
+ static void MyInputBufferHandler( void * inUserData,
+ AudioQueueRef inAQ,
+ AudioQueueBufferRef inBuffer,
+ const AudioTimeStamp * inStartTime,
+ UInt32 inNumPackets,
+ const AudioStreamPacketDescription* inPacketDesc);
+};
+
+#endif
361 build/iphone/Classes/AQRecorder.mm
@@ -0,0 +1,361 @@
+/*
+
+ File: AQRecorder.mm
+ Abstract: n/a
+ Version: 2.4
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
+ Inc. ("Apple") in consideration of your agreement to the following
+ terms, and your use, installation, modification or redistribution of
+ this Apple software constitutes acceptance of these terms. If you do
+ not agree with these terms, please do not use, install, modify or
+ redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and
+ subject to these terms, Apple grants you a personal, non-exclusive
+ license, under Apple's copyrights in this original Apple software (the
+ "Apple Software"), to use, reproduce, modify and redistribute the Apple
+ Software, with or without modifications, in source and/or binary forms;
+ provided that if you redistribute the Apple Software in its entirety and
+ without modifications, you must retain this notice and the following
+ text and disclaimers in all such redistributions of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may
+ be used to endorse or promote products derived from the Apple Software
+ without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or
+ implied, are granted by Apple herein, including but not limited to any
+ patent rights that may be infringed by your derivative works or by other
+ works in which the Apple Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE
+ MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
+ THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
+ OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
+ MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
+ AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
+ STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2009 Apple Inc. All Rights Reserved.
+
+
+ */
+#ifdef USE_TI_MEDIA
+
+#include "AQRecorder.h"
+
+// ____________________________________________________________________________________
+// Determine the size, in bytes, of a buffer necessary to represent the supplied number
+// of seconds of audio data.
+int AQRecorder::ComputeRecordBufferSize(const AudioStreamBasicDescription *format, float seconds)
+{
+ int packets, frames, bytes = 0;
+ try {
+ frames = (int)ceil(seconds * format->mSampleRate);
+
+ if (format->mBytesPerFrame > 0)
+ bytes = frames * format->mBytesPerFrame;
+ else {
+ UInt32 maxPacketSize;
+ if (format->mBytesPerPacket > 0)
+ maxPacketSize = format->mBytesPerPacket; // constant packet size
+ else {
+ UInt32 propertySize = sizeof(maxPacketSize);
+ XThrowIfError(AudioQueueGetProperty(mQueue, kAudioQueueProperty_MaximumOutputPacketSize, &maxPacketSize,
+ &propertySize), "couldn't get queue's maximum output packet size");
+ }
+ if (format->mFramesPerPacket > 0)
+ packets = frames / format->mFramesPerPacket;
+ else
+ packets = frames; // worst-case scenario: 1 frame in a packet
+ if (packets == 0) // sanity check
+ packets = 1;
+ bytes = packets * maxPacketSize;
+ }
+ } catch (CAXException e) {
+ char buf[256];
+ fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf));
+ return 0;
+ }
+ return bytes;
+}
+
+// ____________________________________________________________________________________
+// AudioQueue callback function, called when an input buffers has been filled.
+void AQRecorder::MyInputBufferHandler( void * inUserData,
+ AudioQueueRef inAQ,
+ AudioQueueBufferRef inBuffer,
+ const AudioTimeStamp * inStartTime,
+ UInt32 inNumPackets,
+ const AudioStreamPacketDescription* inPacketDesc)
+{
+ AQRecorder *aqr = (AQRecorder *)inUserData;
+
+ try
+ {
+ if (inNumPackets > 0 && !aqr->IsPaused()) //JGH check for pause
+ {
+ // write packets to file
+ XThrowIfError(AudioFileWritePackets(aqr->mRecordFile, FALSE, inBuffer->mAudioDataByteSize,
+ inPacketDesc, aqr->mRecordPacket, &inNumPackets, inBuffer->mAudioData),
+ "AudioFileWritePackets failed");
+ aqr->mRecordPacket += inNumPackets;
+ }
+
+ // if we're not stopping, re-enqueue the buffe so that it gets filled again
+ if (aqr->IsRunning())
+ {
+ XThrowIfError(AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL), "AudioQueueEnqueueBuffer failed");
+ }
+ }
+ catch (CAXException e)
+ {
+ char buf[256];
+ fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf));
+ }
+}
+
+AQRecorder::AQRecorder()
+{
+ mIsRunning = false;
+ mIsPaused = false;
+ mRecordPacket = 0;
+}
+
+AQRecorder::~AQRecorder()
+{
+ if (mQueue!=NULL)
+ {
+ AudioQueueDispose(mQueue, TRUE);
+ mQueue = NULL;
+ }
+ if (mRecordFile!=NULL)
+ {
+ AudioFileClose(mRecordFile);
+ mRecordFile = NULL;
+ }
+ if (mFileName)
+ {
+ CFRelease(mFileName);
+ mFileName = NULL;
+ }
+}
+
+// ____________________________________________________________________________________
+// Copy a queue's encoder's magic cookie to an audio file.
+void AQRecorder::CopyEncoderCookieToFile()
+{
+ UInt32 propertySize;
+ // get the magic cookie, if any, from the converter
+ OSStatus err = AudioQueueGetPropertySize(mQueue, kAudioQueueProperty_MagicCookie, &propertySize);
+
+ // we can get a noErr result and also a propertySize == 0
+ // -- if the file format does support magic cookies, but this file doesn't have one.
+ if (err == noErr && propertySize > 0) {
+ Byte *magicCookie = new Byte[propertySize];
+ UInt32 magicCookieSize;
+ XThrowIfError(AudioQueueGetProperty(mQueue, kAudioQueueProperty_MagicCookie, magicCookie, &propertySize), "get audio converter's magic cookie");
+ magicCookieSize = propertySize; // the converter lies and tell us the wrong size
+
+ // now set the magic cookie on the output file
+ UInt32 willEatTheCookie = false;
+ // the converter wants to give us one; will the file take it?
+ err = AudioFileGetPropertyInfo(mRecordFile, kAudioFilePropertyMagicCookieData, NULL, &willEatTheCookie);
+ if (err == noErr && willEatTheCookie) {
+ err = AudioFileSetProperty(mRecordFile, kAudioFilePropertyMagicCookieData, magicCookieSize, magicCookie);
+ XThrowIfError(err, "set audio file's magic cookie");
+ }
+ delete[] magicCookie;
+ }
+}
+
+void AQRecorder::SetupAudioFormat(UInt32 inFormatID)
+{
+ memset(&mRecordFormat, 0, sizeof(mRecordFormat));
+
+ UInt32 size = sizeof(mRecordFormat.mSampleRate);
+ XThrowIfError(AudioSessionGetProperty( kAudioSessionProperty_CurrentHardwareSampleRate,
+ &size,
+ &mRecordFormat.mSampleRate), "couldn't get hardware sample rate");
+
+ size = sizeof(mRecordFormat.mChannelsPerFrame);
+
+ // WORKAROUND FOR APPLE BUG #8933998
+ // Catch the exceptions thrown by XThrowIfError, and put our faith in Mighty Apple that there will be an appropriate
+ // hardware check somewhere down the line...
+ try {
+ XThrowIfError(AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareInputNumberChannels,
+ &size,
+ &mRecordFormat.mChannelsPerFrame), "couldn't get input channel count");
+ }
+ catch (CAXException& e) {
+ char buf[256];
+ fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf));
+ }
+
+ mRecordFormat.mFormatID = inFormatID;
+
+ switch(inFormatID)
+ {
+ case kAudioFormatLinearPCM:
+ {
+ mRecordFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
+ mRecordFormat.mBitsPerChannel = 16;
+ mRecordFormat.mChannelsPerFrame = 1;
+ mRecordFormat.mBytesPerFrame = 2;
+ mRecordFormat.mFramesPerPacket = 1;
+ mRecordFormat.mSampleRate = 44100.0;
+ mRecordFormat.mBytesPerPacket = 2;
+ break;
+ }
+ case kAudioFormatALaw:
+ case kAudioFormatULaw:
+ {
+ mRecordFormat.mSampleRate = 8000.0;
+ mRecordFormat.mFormatFlags = 0;
+ mRecordFormat.mFramesPerPacket = 1;
+ mRecordFormat.mChannelsPerFrame = 1;
+ mRecordFormat.mBitsPerChannel = 8;
+ mRecordFormat.mBytesPerPacket = 1;
+ mRecordFormat.mBytesPerFrame = 1;
+ break;
+ }
+ case kAudioFormatAppleIMA4:
+ {
+ mRecordFormat.mSampleRate = 44100.0;
+ mRecordFormat.mFormatFlags = 0;
+ mRecordFormat.mChannelsPerFrame = 1;
+ mRecordFormat.mBitsPerChannel = 0;
+ mRecordFormat.mFramesPerPacket = 64;
+ mRecordFormat.mBytesPerPacket = 68;
+ break;
+ }
+ case kAudioFormatAppleLossless:
+ {
+ mRecordFormat.mFormatFlags = 0;
+ mRecordFormat.mSampleRate = 44100.0;
+ mRecordFormat.mBitsPerChannel = 0;
+ mRecordFormat.mFramesPerPacket = 4096;
+ mRecordFormat.mBytesPerFrame = 0;
+ mRecordFormat.mChannelsPerFrame = 1;
+ mRecordFormat.mBytesPerPacket = 0;
+ break;
+ }
+ case kAudioFormatMPEG4AAC:
+ {
+ mRecordFormat.mFormatFlags = 0;
+ mRecordFormat.mBitsPerChannel = 0;
+ mRecordFormat.mSampleRate = 44100.0;
+ mRecordFormat.mChannelsPerFrame = 1;
+ mRecordFormat.mBytesPerPacket = 0;
+ mRecordFormat.mBytesPerFrame = 0;
+ mRecordFormat.mFramesPerPacket = 1024;
+ break;
+ }
+ }
+}
+
+void AQRecorder::PauseRecord()
+{
+ if (!mIsPaused && mIsRunning) {
+ XThrowIfError(AudioQueuePause(mQueue),"unable to pause audio queue");
+ mIsPaused = true;
+ }
+}
+
+void AQRecorder::ResumeRecord()
+{
+ if (mIsPaused && mIsRunning) {
+ mIsPaused = false;
+ XThrowIfError(AudioQueueStart(mQueue,NULL),"unable to resume audio queue");
+ }
+}
+
+void AQRecorder::StartRecord(CFStringRef inRecordFile, UInt32 fileFormatID)
+{
+ int i, bufferByteSize;
+ UInt32 size;
+ CFURLRef url;
+
+ mIsPaused = false;
+
+ try {
+ mFileName = CFStringCreateCopy(kCFAllocatorDefault, inRecordFile);
+
+ // create the queue
+ XThrowIfError(AudioQueueNewInput(
+ &mRecordFormat,
+ MyInputBufferHandler,
+ this /* userData */,
+ NULL /* run loop */, NULL /* run loop mode */,
+ 0 /* flags */, &mQueue), "AudioQueueNewInput failed");
+
+ // get the record format back from the queue's audio converter --
+ // the file may require a more specific stream description than was necessary to create the encoder.
+ mRecordPacket = 0;
+
+ size = sizeof(mRecordFormat);
+ XThrowIfError(AudioQueueGetProperty(mQueue, kAudioQueueProperty_StreamDescription,
+ &mRecordFormat, &size), "couldn't get queue's format");
+
+ //NSString *recordFile = [NSTemporaryDirectory() stringByAppendingPathComponent: (NSString*)inRecordFile];
+
+ url = CFURLCreateWithString(kCFAllocatorDefault, (CFStringRef)mFileName, NULL);
+
+ // create the audio file
+ XThrowIfError(AudioFileCreateWithURL(url, fileFormatID, &mRecordFormat, kAudioFileFlags_EraseFile,
+ &mRecordFile), "AudioFileCreateWithURL failed");
+ CFRelease(url);
+
+ // copy the cookie first to give the file object as much info as we can about the data going in
+ // not necessary for pcm, but required for some compressed audio
+ CopyEncoderCookieToFile();
+
+ // allocate and enqueue buffers
+ bufferByteSize = ComputeRecordBufferSize(&mRecordFormat, kBufferDurationSeconds); // enough bytes for half a second
+ for (i = 0; i < kNumberRecordBuffers; ++i) {
+ X