Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Temporarily hack guide into the raw JS so it works with ApplicationCa…

…che.
  • Loading branch information...
commit 60019be3543b5c1d6012ddf2bfe8e0683ae28d26 1 parent ac177ac
@ialexi ialexi authored
View
3  Buildfile
@@ -5,5 +5,6 @@
# Add initial buildfile information here
config :all, :required => [:sproutcore, "sproutcore/animation", "sproutcore/forms"], :theme=>:pig, :url_prefix => "/static/hedwig/",
- :html5_manifest=> true
+ :html5_manifest=> true,
+ :layout => 'lib/index.rhtml'
View
4 apps/hedwig/controllers/guides.js
@@ -16,7 +16,9 @@ Hedwig.guidesController = SC.ObjectController.create(
currentGuide: null,
loadGuide: function(path) {
- SC.Request.getUrl(path).json().notify(this, "didLoadGuide").send();
+ // we are short-circuiting for now
+ this.set("currentGuide", Hedwig.GUIDE_CONTENT);
+ //SC.Request.getUrl(path).json().notify(this, "didLoadGuide").send();
},
didLoadGuide: function(response) {
View
117 apps/hedwig/lib/index.rhtml
@@ -0,0 +1,117 @@
+<% # SPROUTCORE DEFAULT INDEX TEMPLATE
+ # This template provide provides a basic wrapper for a SproutCore client.
+ # Most of the time, it will be sufficient for your own needs. However, if
+ # you need to create your own template, you can do so by copying this file
+ # into your client, naming it 'index.rhtml' and then adding the options
+ # :layout => 'lib/index' to your Buildfile.
+ #
+ # See the comments in this file for more information on what you can
+ # change.
+-%>
+<!DOCTYPE html>
+<html<% unless @content_for_html5_manifest.blank? %> manifest="app.manifest"<% end %>>
+ <head>
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=8" />
+ <meta http-equiv="Content-Script-Type" content="text/javascript" />
+ <meta name="apple-mobile-web-app-capable" content="yes" />
+ <meta name="apple-mobile-web-app-status-bar-style" content="black" />
+ <meta name = "viewport" content = "initial-scale = 1.0, minimum-scale=1.0, maximum-scale = 1.0, user-scalable = no" />
+ <link rel="apple-touch-icon-precomposed" href="<%= sc_static('icon-precomposed.png') %>"/>
+ <link rel="apple-touch-startup-image" href="<%= sc_static('startup.png') %>">
+
+<% # Set the 'title' in your config to alter this setting %>
+ <title><%= title %></title>
+<% #
+ # You may choose to load one or more bootstrap resources. These are
+ # JS targets that you would like to load at the top of the page. Specify
+ # these in your Buildfile with the 'bootstrap' config.
+-%>
+ <%= bootstrap %>
+
+<% #
+ # This line should appear in your head area to include the stylesheets
+ # generated by your client. If you need to include your own
+ # stylesheets, you don't need to change it here. Instead use the
+ # required option in your config.
+-%>
+ <%= stylesheets_for_client %>
+ <%= @content_for_page_styles %>
+
+ </head>
+
+<% # The theme CSS class is added automatically based on your chosen theme.
+ # If you need to specify a custom theme name, use CONFIG.theme_name
+-%>
+ <body class="<%= [theme_name(:default => 'sc-theme'), 'focus'].compact.join(' ') %>">
+<% # This section is used to setup additional optional class names on the
+ # body content based on JS-selected conditions. Use this to make sure you
+ # show the proper CSS as soon as the page appears.
+-%>
+<%= inline_javascript('sproutcore/bootstrap:setup_body_class_names') %>
+
+<% #
+ # This is where you root body element will appear. To cause your
+ # content to appear here, just declare content_for('body') in one of
+ # your partials.
+-%>
+<%= @content_for_body %>
+<% #
+ # This is where your loading screen will appear. To add a loading screen
+ # just declare content_for('loading') in one of your partials. If you use
+ # sc-gen to generate your app, it will create a file called loading.rhtml
+ # under english.lproj. You can insert the desired content there.
+-%>
+<% unless @content_for_loading.blank? %>
+<div id="loading">
+<%= @content_for_loading %>
+</div>
+<% end -%>
+<% #
+ # This is where the resources you declare will appear. By default anything
+ # you add to partials will be added to this section unless you specify
+ # otherwise. Note that resources are initially hidden so you can pull them
+ # apart as needed on page load.
+-%>
+<% unless @content_for_resources.blank? %>
+ <!-- Resources to be removed from DOM on page load -->
+ <div id="resources" style="display:none; visibility: hidden;">
+ <%= @content_for_resources -%>
+ </div>
+<% end -%>
+<% #
+ # This line should appear at the bottom of your page to include your
+ # generated JavaScript and any libraries you reference. If you need
+ # to include other javascripts, add them to the :requires option of
+ # your client in routes.rb instead of changing it here.
+-%>
+<%= javascripts_for_client %>
+<% unless @content_for_page_javascript.blank? %>
+<%= @content_for_page_javascript %>
+<% end -%>
+<% #
+ # If you use old-style view helpers in your page, this method must be
+ # called to actually add the page views to your HTML. Normally this will
+ # not generate any content.
+-%>
+<% #render_page_views -%>
+<% # Older SproutCore applications need SC.didLoad to be called after onload.
+ # This is no longer required by SproutCore so it is off by default. To
+ # reenable set use_window_onload = true in yur config.
+-%>
+<% if config.use_window_onload %>
+<!-- Start SproutCore on Page Load -->
+ <script type="text/javascript">window.onload = SC.didLoad;</script>
+<% end -%>
+<% #
+ # The final content section can be used to add any last minute setup you
+ # need to do before the page ends. This is required for loading unit
+ # tests among other things.
+-%>
+<%= @content_for_final -%>
+<%
+ #disable main if the application is loaded in design mode
+%>
+<%= @content_for_designer -%>
+ </body>
+</html>
View
1  apps/hedwig/resources/guide/touch.js
@@ -0,0 +1 @@
+Hedwig.GUIDE_CONTENT={"title":"Touch Application Guide","sections":[{"title":"Introduction","articles":[{"content":"<h1>A Brief Touch</h1>\n\n<p>It is very possible to build <em>awesome</em> touch-enabled applications in SproutCore.</p>\n\n<p>But, what makes an awesome touch-enabled application? Sure, it must accept touches,\nbut with SproutCore's (constantly growing) touch support, this is now pretty easy:\nmany existing interfaces, if built with newer SproutCore varieties, will function fine (or mostly fine),\non both larger-screened touch devices (such as iPad) and the traditional desktop environment.</p>\n\n<p>But there are many differences between desktop and touch platforms:</p>\n\n<ul>\n<li><strong>Precision.</strong> Touches are less precise than clicks. To compensate, controls should be larger.</li>\n<li><strong>Performance.</strong> Touch-based devices tend to be slow (for now). To get around this just takes \nsome elbow grease: there are many techniques to speed things up... many of which SproutCore will\nhandle for you.</li>\n<li><strong>Animation.</strong> Lack of animation looks okay on desktop (even if animation is cool)... but on\ntouch devices, non-animated interfaces look strange: touch is so much more realistic than mouse,\nbut sudden changes without transitions are not realistic at all.</li>\n<li><strong>Coolness.</strong> Touch-based interfaces are cool. That is all.</li>\n</ul>\n\n<p>In this guide, we go over each of these, except for the last, which is rather vague; you'll have to figure out\nyour own meaning of \"coolness\".</p>","errors":[],"demos":{},"articleDirectory":"articles/touch/","outputDirectory":"build/","title":"A Brief Touch","any":"metadata","goes":"Here","damn":"gruber","this":"is still eye-readable","and":"He is wrong about touch apps."},{"content":"<h1>Touch Events</h1>\n\n<p>SproutCore's touch events have a few great features:</p>\n\n<ul>\n<li>Multiple views can receive touches simultaneously.</li>\n<li>A single view can receive multiple touches.</li>\n<li>A view can capture touches before allowing them to pass through to children.</li>\n<li>Child views can release touches back to parent views that originally captured them.</li>\n</ul>\n\n<p>We won't get into the last two in this article&emdash;they're quite sophisticated!</p>\n\n<h1>Simple Single-Touch Handling</h1>\n\n<p>You may be familiar with this SC.View method signature if you are familiar with SproutCore:</p>\n\n<pre><code class='syntax js'><span class=\"variable\">mouseDown</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">evt</span>)\n</code></pre>\n\n<p>With <code class='syntax js'><span class=\"variable\">mouseDown</span></code>, you can decide whether or not to accept the mouse event by returning either\n<code class='syntax js'><span class=\"class\">YES</span></code> or <code class='syntax js'><span class=\"class\">NO</span></code>.</p>\n\n<p>Touch events are similar, but work a bit differently:</p>\n\n<pre><code class='syntax js'><span class=\"variable\">touchStart</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>)\n</code></pre>\n\n<p>Instead of being passed a raw event, <code class='syntax js'><span class=\"variable\">touchStart</span></code> is passed an <code class='syntax js'><span class=\"class\">SC</span>.<span class=\"class\">Touch</span></code> object.\nIf you return YES from touchStart, your view will \"own\" the touch&emdash;in SproutCore terms, your\nview will be the <em>touch responder</em>. For more information about what this entails, see\nthe \"Internals\" article. Your view will own the touch until the touch ends.</p>\n\n<p><code class='syntax js'><span class=\"variable\">touchStart</span></code> will be called once for every touch that touches the view.</p>\n\n<p><strong>Note:</strong> By default, views only receive <code class='syntax js'><span class=\"variable\">touchStart</span></code> and touchEnd for a single touch. This is\na feature intended to make it easier to handle such cases, very similar to Cocoa Touch's <code class='syntax js'><span class=\"variable\">acceptsMultitouch</span></code>\nproperty&emdash;actually, SC.View uses the same property name! See the \"Multitouch\" article.</p>\n\n<h2>Anatomy of an SC.Touch</h2>\n\n<p>SC.Touch represents the touch from the time the user puts their finger on the screen until the time they lift it.</p>\n\n<p>The touch object acts like an event object in many ways. It has many other useful things, as well:</p>\n\n<ul>\n<li><code class='syntax js'><span class=\"variable\">pageX</span></code> and <code class='syntax js'><span class=\"variable\">pageY</span></code> for the touch</li>\n<li><code class='syntax js'><span class=\"variable\">event</span></code>: if in an event cycle, this contains the event. Otherwise, it is <code class='syntax js'><span class=\"variable\">undefined</span></code>. \nYou will probably never need to access this.</li>\n<li><code class='syntax js'><span class=\"variable\">preventDefault</span></code>: if the touch is connected with an event, this calls <code class='syntax js'><span class=\"variable\">preventDefault</span>()</code> on the event.</li>\n<li><code class='syntax js'><span class=\"variable\">touchesForView</span>(<span class=\"variable\">view</span>)</code>: when supplied a view, will find all touches that the view is the\ntouch responder for. It is a CoreSet; to get an array, call <code class='syntax js'>.<span class=\"variable\">toArray</span></code> on the result.</li>\n<li><code class='syntax js'><span class=\"variable\">averagedTouchesForView</span>(<span class=\"variable\">view</span>)</code>: When supplied a view, averages all the touches on that view,\nreturning both an average position and an average distance from that position.</li>\n</ul>\n\n<p><strong>Note:</strong> If you call <code class='syntax js'><span class=\"variable\">touchesForView</span>(<span class=\"this\">this</span>)</code> from <code class='syntax js'><span class=\"variable\">touchStart</span></code>, the touch supplied will not be in the set\nreturned by <code class='syntax js'><span class=\"variable\">touchesForView</span>(<span class=\"this\">this</span>)</code>: you don't own the touch until you return YES.</p>\n\n<h2>touchEnd</h2>\n\n<p>Knowing when the touch starts is not very useful. At the very least, you will likely want to know when the touch\nends as well.</p>\n\n<p>It is quite simple:</p>\n\n<pre><code class='syntax js'><span class=\"variable\">touchEnd</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>)\n</code></pre>\n\n<p>It works exactly like <code class='syntax js'><span class=\"variable\">touchStart</span></code>. The touch will no longer be in the set of touches for the view,\nso if you call <code class='syntax js'><span class=\"variable\">touch</span>.<span class=\"variable\">touchesForView</span>(<span class=\"this\">this</span>)</code>, you'll only receive any other active touches. If your\nview does not accept multitouch, then the set is guaranteed to have no touches in it&emdash;you only receive\n<code class='syntax js'><span class=\"variable\">touchEnd</span></code> for the last touch that ends.</p>\n\n<h2>Tracking Touches</h2>\n\n<p>Tracking touch movement is simple:</p>\n\n<pre><code class='syntax js'><span class=\"variable\">touchesDragged</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">evt</span>, <span class=\"variable\">touches</span>)\n</code></pre>\n\n<p>The <code class='syntax js'><span class=\"variable\">touches</span></code> argument is the set of touches on the view&emdash;the same set you get by calling <code class='syntax js'><span class=\"variable\">touchesForView</span>(<span class=\"this\">this</span>)</code>.\nThis will have <em>all</em> touches, regardless of whether or not your view accepts multitouch.</p>\n\n<p>If your view does <em>not</em> accept multitouch, then it is even simpler:</p>\n\n<pre><code class='syntax js'><span class=\"variable\">x</span> = <span class=\"variable\">evt</span>.<span class=\"variable\">pageX</span>;\n<span class=\"variable\">y</span> = <span class=\"variable\">evt</span>.<span class=\"variable\">pageY</span>;\n</code></pre>\n\n<h2>Tip: Cross-Platform-iness</h2>\n\n<p>Did you realize that, assuming you don't use the set of view touches or other touch-specific API,\nyou can do this:</p>\n\n<pre><code class='syntax js'><span class=\"variable\">mouseDown</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">evt</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">touchStart</span>(<span class=\"variable\">evt</span>);\n},\n\n<span class=\"variable\">mouseDragged</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">evt</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">touchesDragged</span>(<span class=\"variable\">evt</span>);\n},\n\n<span class=\"variable\">mouseUp</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">evt</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">touchEnd</span>(<span class=\"variable\">evt</span>);\n}\n</code></pre>\n\n<p>Of course, you can also redirect touch events to mouse events, but that is not as fun.</p>\n\n<h2>Putting it All Together</h2>\n\n<p>Here is a very simple demo that uses the methods described above to allow the user to move two views\naround the screen:</p>\n\n<p><a href='touch-demo.js' class='demo'>touch-demo.js</a></p>","errors":[],"demos":{"touch-demo.js":{"ex":"var Dot = SC.View.extend({\n touchStart: function(touch) {\n var f = this.get(\"frame\");\n this._touch = {\n start: { x: touch.pageX, y: touch.pageY },\n ourStart: { x: f.x, y: f.y, width: f.width, height: f.height }\n };\n return YES; // or we won't get touchesDragged\n },\n \n touchesDragged: function(evt, touches) {\n var t = this._touch;\n this.set(\"layout\", { \n left: t.ourStart.x + evt.pageX - t.start.x,\n top: t.ourStart.y + evt.pageY - t.start.y,\n width: t.ourStart.width,\n height: t.ourStart.height\n });\n },\n \n touchEnd: function() {\n // actually, we don't need to do anything here...\n },\n \n // and now, redirect mouse events :)\n mouseDown: function(evt) {\n this.touchStart(evt);\n },\n \n mouseDragged: function(evt) {\n this.touchesDragged(evt);\n },\n \n mouseUp: function(evt) {\n this.touchEnd(evt);\n }\n});\nvar MyExampleView = SC.View.extend({\n backgroundColor: \"white\",\n childViews: \"dot1 dot2\".w(),\n dot1: Dot.design({\n backgroundColor: \"red\",\n layout: { left: 10, top: 10, width: 100, height: 100 }\n }),\n dot2: Dot.design({\n backgroundColor: \"blue\",\n layout: { right: 10, bottom: 10, width: 100, height: 100 }\n })\n});\n\n// bootstrap code :)\nexports.getDemoView = function() {\n return MyExampleView;\n};\n","highlighted":"<span class=\"keyword\">var</span> <span class=\"class\">Dot</span> = <span class=\"class\">SC</span>.<span class=\"class\">View</span>.<span class=\"variable\">extend</span>({\n <span class=\"variable\">touchStart</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>) {\n <span class=\"keyword\">var</span> <span class=\"variable\">f</span> = <span class=\"this\">this</span>.<span class=\"variable\">get</span>(<span class=\"string\">&quot;frame&quot;</span>);\n <span class=\"this\">this</span>.<span class=\"variable\">_touch</span> = {\n <span class=\"variable\">start</span>: { <span class=\"variable\">x</span>: <span class=\"variable\">touch</span>.<span class=\"variable\">pageX</span>, <span class=\"variable\">y</span>: <span class=\"variable\">touch</span>.<span class=\"variable\">pageY</span> },\n <span class=\"variable\">ourStart</span>: { <span class=\"variable\">x</span>: <span class=\"variable\">f</span>.<span class=\"variable\">x</span>, <span class=\"variable\">y</span>: <span class=\"variable\">f</span>.<span class=\"variable\">y</span>, <span class=\"variable\">width</span>: <span class=\"variable\">f</span>.<span class=\"variable\">width</span>, <span class=\"variable\">height</span>: <span class=\"variable\">f</span>.<span class=\"variable\">height</span> }\n };\n <span class=\"keyword\">return</span> <span class=\"class\">YES</span>; <span class=\"comment\">// or we won't get touchesDragged</span>\n },\n \n <span class=\"variable\">touchesDragged</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">evt</span>, <span class=\"variable\">touches</span>) {\n <span class=\"keyword\">var</span> <span class=\"variable\">t</span> = <span class=\"this\">this</span>.<span class=\"variable\">_touch</span>;\n <span class=\"this\">this</span>.<span class=\"variable\">set</span>(<span class=\"string\">&quot;layout&quot;</span>, { \n <span class=\"variable\">left</span>: <span class=\"variable\">t</span>.<span class=\"variable\">ourStart</span>.<span class=\"variable\">x</span> + <span class=\"variable\">evt</span>.<span class=\"variable\">pageX</span> - <span class=\"variable\">t</span>.<span class=\"variable\">start</span>.<span class=\"variable\">x</span>,\n <span class=\"variable\">top</span>: <span class=\"variable\">t</span>.<span class=\"variable\">ourStart</span>.<span class=\"variable\">y</span> + <span class=\"variable\">evt</span>.<span class=\"variable\">pageY</span> - <span class=\"variable\">t</span>.<span class=\"variable\">start</span>.<span class=\"variable\">y</span>,\n <span class=\"variable\">width</span>: <span class=\"variable\">t</span>.<span class=\"variable\">ourStart</span>.<span class=\"variable\">width</span>,\n <span class=\"variable\">height</span>: <span class=\"variable\">t</span>.<span class=\"variable\">ourStart</span>.<span class=\"variable\">height</span>\n });\n },\n \n <span class=\"variable\">touchEnd</span>: <span class=\"keyword\">function</span>() {\n <span class=\"comment\">// actually, we don't need to do anything here...</span>\n },\n \n <span class=\"comment\">// and now, redirect mouse events :)</span>\n <span class=\"variable\">mouseDown</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">evt</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">touchStart</span>(<span class=\"variable\">evt</span>);\n },\n \n <span class=\"variable\">mouseDragged</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">evt</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">touchesDragged</span>(<span class=\"variable\">evt</span>);\n },\n \n <span class=\"variable\">mouseUp</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">evt</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">touchEnd</span>(<span class=\"variable\">evt</span>);\n }\n});\n<span class=\"keyword\">var</span> <span class=\"class\">MyExampleView</span> = <span class=\"class\">SC</span>.<span class=\"class\">View</span>.<span class=\"variable\">extend</span>({\n <span class=\"variable\">backgroundColor</span>: <span class=\"string\">&quot;white&quot;</span>,\n <span class=\"variable\">childViews</span>: <span class=\"string\">&quot;dot1 dot2&quot;</span>.<span class=\"variable\">w</span>(),\n <span class=\"variable\">dot1</span>: <span class=\"class\">Dot</span>.<span class=\"variable\">design</span>({\n <span class=\"variable\">backgroundColor</span>: <span class=\"string\">&quot;red&quot;</span>,\n <span class=\"variable\">layout</span>: { <span class=\"variable\">left</span>: <span class=\"number integer\">10</span>, <span class=\"variable\">top</span>: <span class=\"number integer\">10</span>, <span class=\"variable\">width</span>: <span class=\"number integer\">100</span>, <span class=\"variable\">height</span>: <span class=\"number integer\">100</span> }\n }),\n <span class=\"variable\">dot2</span>: <span class=\"class\">Dot</span>.<span class=\"variable\">design</span>({\n <span class=\"variable\">backgroundColor</span>: <span class=\"string\">&quot;blue&quot;</span>,\n <span class=\"variable\">layout</span>: { <span class=\"variable\">right</span>: <span class=\"number integer\">10</span>, <span class=\"variable\">bottom</span>: <span class=\"number integer\">10</span>, <span class=\"variable\">width</span>: <span class=\"number integer\">100</span>, <span class=\"variable\">height</span>: <span class=\"number integer\">100</span> }\n })\n});\n\n<span class=\"comment\">// bootstrap code :)</span>\n<span class=\"variable\">exports</span>.<span class=\"variable\">getDemoView</span> = <span class=\"keyword\">function</span>() {\n <span class=\"keyword\">return</span> <span class=\"class\">MyExampleView</span>;\n};\n","original":"var Dot = SC.View.extend({\n touchStart: function(touch) {\n var f = this.get(\"frame\");\n this._touch = {\n start: { x: touch.pageX, y: touch.pageY },\n ourStart: { x: f.x, y: f.y, width: f.width, height: f.height }\n };\n return YES; // or we won't get touchesDragged\n },\n \n touchesDragged: function(evt, touches) {\n var t = this._touch;\n this.set(\"layout\", { \n left: t.ourStart.x + evt.pageX - t.start.x,\n top: t.ourStart.y + evt.pageY - t.start.y,\n width: t.ourStart.width,\n height: t.ourStart.height\n });\n },\n \n touchEnd: function() {\n // actually, we don't need to do anything here...\n },\n \n // and now, redirect mouse events :)\n mouseDown: function(evt) {\n this.touchStart(evt);\n },\n \n mouseDragged: function(evt) {\n this.touchesDragged(evt);\n },\n \n mouseUp: function(evt) {\n this.touchEnd(evt);\n }\n});\nvar MyExampleView = SC.View.extend({\n backgroundColor: \"white\",\n childViews: \"dot1 dot2\".w(),\n dot1: Dot.design({\n backgroundColor: \"red\",\n layout: { left: 10, top: 10, width: 100, height: 100 }\n }),\n dot2: Dot.design({\n backgroundColor: \"blue\",\n layout: { right: 10, bottom: 10, width: 100, height: 100 }\n })\n});\n\n// bootstrap code :)\nexports.getDemoView = function() {\n return MyExampleView;\n};\n"}},"articleDirectory":"articles/touch/","outputDirectory":"build/","title":"Touch Events"},{"content":"<h1>Multitouch</h1>\n\n<p>Handling single touches is pretty easy&emdash;not that much different from handling\nmouse events. But what about multiple touches?</p>\n\n<h2>Accepting Multiple Touches</h2>\n\n<p>First, you have to tell your view that you do, indeed want to receive multiple\ntouches. By default, views only receive single touches. This is because is easier \nto think in a single-touch model, and most controls only need to track a single touch.</p>\n\n<p>To accept multiple touches, just set the view's <code class='syntax js'><span class=\"variable\">acceptsMultitouch</span></code> property to\n<code class='syntax js'><span class=\"class\">YES</span></code>.</p>\n\n<pre><code class='syntax js'><span class=\"variable\">view</span> = <span class=\"class\">SC</span>.<span class=\"class\">View</span>.<span class=\"variable\">extend</span>({\n <span class=\"variable\">acceptsMultitouch</span>: <span class=\"class\">YES</span>\n});\n</code></pre>\n\n<h2>Processing the Individual Touches</h2>\n\n<p>Even without the supplied helper function, processing individual touches is relatively\nsimple:</p>\n\n<ul>\n<li>You get a separate <code class='syntax js'><span class=\"variable\">touchStart</span></code> for each individual touch.</li>\n<li>You get a separate <code class='syntax js'><span class=\"variable\">touchEnd</span></code> for each individual touch.</li>\n<li>You get one <code class='syntax js'><span class=\"variable\">touchesDragged</span></code> each event cycle for all of your touches put together.</li>\n</ul>\n\n<p>So, detecting individual touches starting and ending is simple. Detecting those touches\nmoving is not quite as simple, but still relatively easy.</p>\n\n<p>Remember how <code class='syntax js'><span class=\"variable\">touchesDragged</span></code> works:</p>\n\n<pre><code class='syntax js'><span class=\"variable\">touchesDragged</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">evt</span>, <span class=\"variable\">touches</span>)\n</code></pre>\n\n<p><code class='syntax js'><span class=\"variable\">touches</span></code> is an SC.CoreSet of SC.Touch objects. What can you do with a CoreSet? \nYou can do a couple of things:</p>\n\n<ul>\n<li>Turn it into an array and do whatever.</li>\n<li>Call .forEach to iterate.</li>\n</ul>\n\n<p>But you don't have to use the touches set at all. The <code class='syntax js'><span class=\"variable\">evt</span></code> has some useful properties and methods,\ntoo:</p>\n\n<ul>\n<li>pageX/pageY: the position of the first touch.</li>\n<li>averagedTouchesForView: a method which returns the averaged touch position\nand the average distance of the touches from that position.</li>\n</ul>\n\n<p><code class='syntax js'><span class=\"class\">SC</span>.<span class=\"class\">ScrollView</span></code>, for instance, makes heavy use of <code class='syntax js'><span class=\"variable\">averagedTouchesForView</span></code>, and never\ndirectly touches the <code class='syntax js'><span class=\"variable\">touches</span></code> set.</p>\n\n<h2>Averaging Touches</h2>\n\n<p>It is often <em>very</em> useful to average the touches. </p>\n\n<p><code class='syntax js'><span class=\"variable\">averagedTouchesForView</span></code> returns an object with four properties:</p>\n\n<ul>\n<li><strong><code class='syntax js'><span class=\"variable\">x</span></code></strong>: The average X position of the touch.</li>\n<li><strong><code class='syntax js'><span class=\"variable\">y</span></code></strong>: The average Y position of the touch.</li>\n<li><strong><code class='syntax js'><span class=\"variable\">d</span></code></strong>: average distance of the all touches from the average x/y position.</li>\n<li><strong><code class='syntax js'><span class=\"variable\">touchCount</span></code></strong> The number of touches averaged.</li>\n</ul>\n\n<p>You can call <code class='syntax js'><span class=\"variable\">averagedTouchesForView</span></code> on two separate objects: an <code class='syntax js'><span class=\"class\">SC</span>.<span class=\"class\">Event</span></code> object,\nor an <code class='syntax js'><span class=\"class\">SC</span>.<span class=\"class\">Touch</span></code> object.</p>\n\n<p>The two work identically but for one important difference: when you call it on <code class='syntax js'><span class=\"class\">SC</span>.<span class=\"class\">Touch</span></code>,\nyou <em>have the option</em> of telling the touch to add itself to the averaged set. Doing so makes no sense\nin most cases: the touch would just be counted twice! But what about <code class='syntax js'><span class=\"variable\">touchStart</span></code>?</p>\n\n<p>Recall that during <code class='syntax js'><span class=\"variable\">touchStart</span></code>, the view does not yet own the touch. So, <code class='syntax js'><span class=\"variable\">averagedTouchesForView</span></code>\nwould not, by default count it.</p>\n\n<pre><code class='syntax js'><span class=\"comment\">// on an event:</span>\n<span class=\"keyword\">var</span> <span class=\"variable\">a</span> = <span class=\"variable\">evt</span>.<span class=\"variable\">averagedTouchesForView</span>(<span class=\"this\">this</span>);\n\n<span class=\"comment\">// on a touch</span>\n<span class=\"keyword\">var</span> <span class=\"variable\">a</span> = <span class=\"variable\">touch</span>.<span class=\"variable\">averagedTouchesForView</span>(<span class=\"this\">this</span>);\n\n<span class=\"comment\">// on a touch, counting the touch itself</span>\n<span class=\"keyword\">var</span> <span class=\"variable\">a</span> = <span class=\"variable\">touch</span>.<span class=\"variable\">averagedTouchesForView</span>(<span class=\"this\">this</span>, <span class=\"class\">YES</span>);\n</code></pre>\n\n<h2>Thinking it Over</h2>\n\n<p>How might you use all of these to produce a good result?</p>\n\n<p>Let's take a simple example: moving and resizing something:</p>\n\n<p><a href='multitouch.js' class='demo'>multitouch.js</a></p>","errors":[],"demos":{"multitouch.js":{"ex":"var Box = SC.View.extend({\n _scale: 1,\n _translateX: 0,\n _translateY: 0,\n acceptsMultitouch: YES,\n touchStart: function(touch) {\n this.recomputeTouchStatus(touch, YES);\n return YES;\n },\n \n touchesDragged: function(evt, touches) {\n var t = this._touch;\n var avg = evt.averagedTouchesForView(this);\n \n // translation is easy:\n this._translateX = t.ourStart.x + avg.x - t.start.x;\n this._translateY = t.ourStart.y + avg.y - t.start.y;\n \n // mathematically speaking, scale *= the end distance / the start distance\n if (t.start.d > 1) { // but prevent divide-by-0\n this._scale = t.ourStart.scale * (avg.d / t.start.d);\n }\n \n // reposition\n this._reposition();\n },\n \n touchEnd: function(touch) {\n this.recomputeTouchStatus(touch, NO);\n },\n \n /**\n With this, we recompute our touch status--updating the start positioning and scale.\n */\n recomputeTouchStatus: function(touch, considerTouch) {\n var avg = touch.averagedTouchesForView(this, considerTouch);\n this._touch = {\n start: { x: avg.x, y: avg.y, d: avg.d },\n ourStart: { x: this._translateX, y: this._translateY, scale: this._scale }\n };\n },\n \n /**\n Repositions the view.\n */\n _reposition: function() {\n this.get(\"layer\").style.webkitTransform = \n \"translate3d(\" + this._translateX + \"px,\" + this._translateY + \"px, 0px) \" +\n \"scale3d(\" + this._scale + \",\" + this._scale + \",1)\";\n console.error(this._translateX + \" \" + this._translateY + \" \" + this._scale);\n },\n \n // and now, redirect mouse events :)\n mouseDown: function(evt) {\n this.touchStart(evt);\n },\n \n mouseDragged: function(evt) {\n this.touchesDragged(evt);\n },\n \n mouseUp: function(evt) {\n this.touchEnd(evt);\n }\n});\nvar MyExampleView = SC.View.extend({\n backgroundColor: \"white\",\n childViews: \"box\".w(),\n box: Box.design({\n backgroundColor: \"red\",\n layout: { left: 10, top: 10, width: 200, height: 200 }\n })\n});\n\n// bootstrap code :)\nexports.getDemoView = function() {\n return MyExampleView;\n};\n","highlighted":"<span class=\"keyword\">var</span> <span class=\"class\">Box</span> = <span class=\"class\">SC</span>.<span class=\"class\">View</span>.<span class=\"variable\">extend</span>({\n <span class=\"variable\">_scale</span>: <span class=\"number integer\">1</span>,\n <span class=\"variable\">_translateX</span>: <span class=\"number integer\">0</span>,\n <span class=\"variable\">_translateY</span>: <span class=\"number integer\">0</span>,\n <span class=\"variable\">acceptsMultitouch</span>: <span class=\"class\">YES</span>,\n <span class=\"variable\">touchStart</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">recomputeTouchStatus</span>(<span class=\"variable\">touch</span>, <span class=\"class\">YES</span>);\n <span class=\"keyword\">return</span> <span class=\"class\">YES</span>;\n },\n \n <span class=\"variable\">touchesDragged</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">evt</span>, <span class=\"variable\">touches</span>) {\n <span class=\"keyword\">var</span> <span class=\"variable\">t</span> = <span class=\"this\">this</span>.<span class=\"variable\">_touch</span>;\n <span class=\"keyword\">var</span> <span class=\"variable\">avg</span> = <span class=\"variable\">evt</span>.<span class=\"variable\">averagedTouchesForView</span>(<span class=\"this\">this</span>);\n \n <span class=\"comment\">// translation is easy:</span>\n <span class=\"this\">this</span>.<span class=\"variable\">_translateX</span> = <span class=\"variable\">t</span>.<span class=\"variable\">ourStart</span>.<span class=\"variable\">x</span> + <span class=\"variable\">avg</span>.<span class=\"variable\">x</span> - <span class=\"variable\">t</span>.<span class=\"variable\">start</span>.<span class=\"variable\">x</span>;\n <span class=\"this\">this</span>.<span class=\"variable\">_translateY</span> = <span class=\"variable\">t</span>.<span class=\"variable\">ourStart</span>.<span class=\"variable\">y</span> + <span class=\"variable\">avg</span>.<span class=\"variable\">y</span> - <span class=\"variable\">t</span>.<span class=\"variable\">start</span>.<span class=\"variable\">y</span>;\n \n <span class=\"comment\">// mathematically speaking, scale *= the end distance / the start distance</span>\n <span class=\"keyword\">if</span> (<span class=\"variable\">t</span>.<span class=\"variable\">start</span>.<span class=\"variable\">d</span> &gt; <span class=\"number integer\">1</span>) { <span class=\"comment\">// but prevent divide-by-0</span>\n <span class=\"this\">this</span>.<span class=\"variable\">_scale</span> = <span class=\"variable\">t</span>.<span class=\"variable\">ourStart</span>.<span class=\"variable\">scale</span> * (<span class=\"variable\">avg</span>.<span class=\"variable\">d</span> / <span class=\"variable\">t</span>.<span class=\"variable\">start</span>.<span class=\"variable\">d</span>);\n }\n \n <span class=\"comment\">// reposition</span>\n <span class=\"this\">this</span>.<span class=\"variable\">_reposition</span>();\n },\n \n <span class=\"variable\">touchEnd</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">recomputeTouchStatus</span>(<span class=\"variable\">touch</span>, <span class=\"class\">NO</span>);\n },\n \n <span class=\"multiline comment\">/**\n With this, we recompute our touch status--updating the start positioning and scale.\n */</span>\n <span class=\"variable\">recomputeTouchStatus</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>, <span class=\"variable\">considerTouch</span>) {\n <span class=\"keyword\">var</span> <span class=\"variable\">avg</span> = <span class=\"variable\">touch</span>.<span class=\"variable\">averagedTouchesForView</span>(<span class=\"this\">this</span>, <span class=\"variable\">considerTouch</span>);\n <span class=\"this\">this</span>.<span class=\"variable\">_touch</span> = {\n <span class=\"variable\">start</span>: { <span class=\"variable\">x</span>: <span class=\"variable\">avg</span>.<span class=\"variable\">x</span>, <span class=\"variable\">y</span>: <span class=\"variable\">avg</span>.<span class=\"variable\">y</span>, <span class=\"variable\">d</span>: <span class=\"variable\">avg</span>.<span class=\"variable\">d</span> },\n <span class=\"variable\">ourStart</span>: { <span class=\"variable\">x</span>: <span class=\"this\">this</span>.<span class=\"variable\">_translateX</span>, <span class=\"variable\">y</span>: <span class=\"this\">this</span>.<span class=\"variable\">_translateY</span>, <span class=\"variable\">scale</span>: <span class=\"this\">this</span>.<span class=\"variable\">_scale</span> }\n };\n },\n \n <span class=\"multiline comment\">/**\n Repositions the view.\n */</span>\n <span class=\"variable\">_reposition</span>: <span class=\"keyword\">function</span>() {\n <span class=\"this\">this</span>.<span class=\"variable\">get</span>(<span class=\"string\">&quot;layer&quot;</span>).<span class=\"variable\">style</span>.<span class=\"variable\">webkitTransform</span> = \n <span class=\"string\">&quot;translate3d(&quot;</span> + <span class=\"this\">this</span>.<span class=\"variable\">_translateX</span> + <span class=\"string\">&quot;px,&quot;</span> + <span class=\"this\">this</span>.<span class=\"variable\">_translateY</span> + <span class=\"string\">&quot;px, 0px) &quot;</span> +\n <span class=\"string\">&quot;scale3d(&quot;</span> + <span class=\"this\">this</span>.<span class=\"variable\">_scale</span> + <span class=\"string\">&quot;,&quot;</span> + <span class=\"this\">this</span>.<span class=\"variable\">_scale</span> + <span class=\"string\">&quot;,1)&quot;</span>;\n <span class=\"variable\">console</span>.<span class=\"variable\">error</span>(<span class=\"this\">this</span>.<span class=\"variable\">_translateX</span> + <span class=\"string\">&quot; &quot;</span> + <span class=\"this\">this</span>.<span class=\"variable\">_translateY</span> + <span class=\"string\">&quot; &quot;</span> + <span class=\"this\">this</span>.<span class=\"variable\">_scale</span>);\n },\n \n <span class=\"comment\">// and now, redirect mouse events :)</span>\n <span class=\"variable\">mouseDown</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">evt</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">touchStart</span>(<span class=\"variable\">evt</span>);\n },\n \n <span class=\"variable\">mouseDragged</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">evt</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">touchesDragged</span>(<span class=\"variable\">evt</span>);\n },\n \n <span class=\"variable\">mouseUp</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">evt</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">touchEnd</span>(<span class=\"variable\">evt</span>);\n }\n});\n<span class=\"keyword\">var</span> <span class=\"class\">MyExampleView</span> = <span class=\"class\">SC</span>.<span class=\"class\">View</span>.<span class=\"variable\">extend</span>({\n <span class=\"variable\">backgroundColor</span>: <span class=\"string\">&quot;white&quot;</span>,\n <span class=\"variable\">childViews</span>: <span class=\"string\">&quot;box&quot;</span>.<span class=\"variable\">w</span>(),\n <span class=\"variable\">box</span>: <span class=\"class\">Box</span>.<span class=\"variable\">design</span>({\n <span class=\"variable\">backgroundColor</span>: <span class=\"string\">&quot;red&quot;</span>,\n <span class=\"variable\">layout</span>: { <span class=\"variable\">left</span>: <span class=\"number integer\">10</span>, <span class=\"variable\">top</span>: <span class=\"number integer\">10</span>, <span class=\"variable\">width</span>: <span class=\"number integer\">200</span>, <span class=\"variable\">height</span>: <span class=\"number integer\">200</span> }\n })\n});\n\n<span class=\"comment\">// bootstrap code :)</span>\n<span class=\"variable\">exports</span>.<span class=\"variable\">getDemoView</span> = <span class=\"keyword\">function</span>() {\n <span class=\"keyword\">return</span> <span class=\"class\">MyExampleView</span>;\n};\n","original":"var Box = SC.View.extend({\n _scale: 1,\n _translateX: 0,\n _translateY: 0,\n acceptsMultitouch: YES,\n touchStart: function(touch) {\n this.recomputeTouchStatus(touch, YES);\n return YES;\n },\n \n touchesDragged: function(evt, touches) {\n var t = this._touch;\n var avg = evt.averagedTouchesForView(this);\n \n // translation is easy:\n this._translateX = t.ourStart.x + avg.x - t.start.x;\n this._translateY = t.ourStart.y + avg.y - t.start.y;\n \n // mathematically speaking, scale *= the end distance / the start distance\n if (t.start.d > 1) { // but prevent divide-by-0\n this._scale = t.ourStart.scale * (avg.d / t.start.d);\n }\n \n // reposition\n this._reposition();\n },\n \n touchEnd: function(touch) {\n this.recomputeTouchStatus(touch, NO);\n },\n \n /**\n With this, we recompute our touch status--updating the start positioning and scale.\n */\n recomputeTouchStatus: function(touch, considerTouch) {\n var avg = touch.averagedTouchesForView(this, considerTouch);\n this._touch = {\n start: { x: avg.x, y: avg.y, d: avg.d },\n ourStart: { x: this._translateX, y: this._translateY, scale: this._scale }\n };\n },\n \n /**\n Repositions the view.\n */\n _reposition: function() {\n this.get(\"layer\").style.webkitTransform = \n \"translate3d(\" + this._translateX + \"px,\" + this._translateY + \"px, 0px) \" +\n \"scale3d(\" + this._scale + \",\" + this._scale + \",1)\";\n console.error(this._translateX + \" \" + this._translateY + \" \" + this._scale);\n },\n \n // and now, redirect mouse events :)\n mouseDown: function(evt) {\n this.touchStart(evt);\n },\n \n mouseDragged: function(evt) {\n this.touchesDragged(evt);\n },\n \n mouseUp: function(evt) {\n this.touchEnd(evt);\n }\n});\nvar MyExampleView = SC.View.extend({\n backgroundColor: \"white\",\n childViews: \"box\".w(),\n box: Box.design({\n backgroundColor: \"red\",\n layout: { left: 10, top: 10, width: 200, height: 200 }\n })\n});\n\n// bootstrap code :)\nexports.getDemoView = function() {\n return MyExampleView;\n};\n"}},"articleDirectory":"articles/touch/","outputDirectory":"build/","title":"Multitouch"}]},{"title":"Built-In Support","articles":[{"content":"<h1>ButtonView Touch Support</h1>\n\n<p>ButtonView currently supports only a single touch (any other touches will be ignored). \nThis is fine: why would you want to consider two touches in a button press?</p>\n\n<p>However, it does not simply relay the touches to <code class='syntax js'><span class=\"variable\">mouseDown</span></code> and <code class='syntax js'><span class=\"variable\">mouseUp</span></code>.</p>\n\n<p>Instead, it calculates the distance of the main touch (<code class='syntax js'><span class=\"variable\">evt</span></code>'s <code class='syntax js'><span class=\"variable\">pageX</span></code> and <code class='syntax js'><span class=\"variable\">pageY</span></code>)\nfrom the button itself. This makes it easier to for a user to press a button while, for instance,\nmoving their finger.</p>\n\n<p>This is all done for you automatically. Here's a simple demo:\n<a href='touch-button.js' class='demo'>touch-button.js</a></p>\n\n<h2>Ace 2.0</h2>\n\n<p>Ace 2.0 supports several button sizes. In addition, it is capable of <em>automatically picking</em>\na size based on the size of your control. And best of all, it <em>centers</em> the button image\nvertically in the space you allocate. This allows you to, for instance, make a button 44px\ntall, but have the image only be 30px.</p>\n\n<p>You may use these options for <code class='syntax js'><span class=\"variable\">controlSize</span></code>:</p>\n\n<ul>\n<li>SC.SMALL_CONTROL_SIZE. 18px.</li>\n<li>SC.REGULAR_CONTROL_SIZE. 24px.</li>\n<li>SC.HUGE_CONTROL_SIZE. 30px.</li>\n<li>SC.JUMBO_CONTROL_SIZE. 44px.</li>\n<li>SC.AUTO_CONTROL_SIZE. Automatically figures a control size (largest that will fit), but\nthrows a warning if you don't have \"height\" set and it has to calculate the size.</li>\n<li>SC.CALCULATED_CONTROL_SIZE. Like AUTO_CONTROL_SIZE, but calculates it.</li>\n</ul>\n\n<p><a href='button-size.js' class='demo'>button-size.js</a></p>","errors":[],"demos":{"touch-button.js":{"ex":"var MyExampleView = SC.View.extend({\n backgroundColor: \"white\",\n childViews: \"button\".w(),\n button: SC.ButtonView.design({\n layout: { centerX: 0, centerY: 0, width: 200, height: 44 },\n title: \"Tap Here :)\",\n controlSize: SC.AUTO_CONTROL_SIZE\n })\n});\n\n// bootstrap code :)\nexports.getDemoView = function() {\n return MyExampleView;\n};\n","highlighted":"<span class=\"keyword\">var</span> <span class=\"class\">MyExampleView</span> = <span class=\"class\">SC</span>.<span class=\"class\">View</span>.<span class=\"variable\">extend</span>({\n <span class=\"variable\">backgroundColor</span>: <span class=\"string\">&quot;white&quot;</span>,\n <span class=\"variable\">childViews</span>: <span class=\"string\">&quot;button&quot;</span>.<span class=\"variable\">w</span>(),\n <span class=\"variable\">button</span>: <span class=\"class\">SC</span>.<span class=\"class\">ButtonView</span>.<span class=\"variable\">design</span>({\n <span class=\"variable\">layout</span>: { <span class=\"variable\">centerX</span>: <span class=\"number integer\">0</span>, <span class=\"variable\">centerY</span>: <span class=\"number integer\">0</span>, <span class=\"variable\">width</span>: <span class=\"number integer\">200</span>, <span class=\"variable\">height</span>: <span class=\"number integer\">44</span> },\n <span class=\"variable\">title</span>: <span class=\"string\">&quot;Tap Here :)&quot;</span>,\n <span class=\"variable\">controlSize</span>: <span class=\"class\">SC</span>.<span class=\"class\">AUTO_CONTROL_SIZE</span>\n })\n});\n\n<span class=\"comment\">// bootstrap code :)</span>\n<span class=\"variable\">exports</span>.<span class=\"variable\">getDemoView</span> = <span class=\"keyword\">function</span>() {\n <span class=\"keyword\">return</span> <span class=\"class\">MyExampleView</span>;\n};\n","original":"var MyExampleView = SC.View.extend({\n backgroundColor: \"white\",\n childViews: \"button\".w(),\n button: SC.ButtonView.design({\n layout: { centerX: 0, centerY: 0, width: 200, height: 44 },\n title: \"Tap Here :)\",\n controlSize: SC.AUTO_CONTROL_SIZE\n })\n});\n\n// bootstrap code :)\nexports.getDemoView = function() {\n return MyExampleView;\n};\n"},"button-size.js":{"ex":"var MyExampleView = SC.View.extend({\n backgroundColor: \"white\",\n childViews: \"form\".w(),\n \n form: SC.FormView.design({\n layout: {centerX: 0, centerY: 0, width: 400, height: 300 },\n childViews: \"small regular huge jumbo\".w(),\n small: SC.FormView.row(SC.ButtonView.design({\n layout: { width: 100, height: 18 },\n title: \"I'm TINY!\",\n controlSize: SC.SMALL_CONTROL_SIZE\n })),\n \n regular: SC.FormView.row(SC.ButtonView.design({\n layout: { width: 100, height: 24 },\n title: \"I'm Normal!\",\n controlSize: SC.REGULAR_CONTROL_SIZE\n })),\n \n huge: SC.FormView.row(SC.ButtonView.design({\n layout: { width: 100, height: 30 },\n title: \"I'm huge.\",\n controlSize: SC.HUGE_CONTROL_SIZE\n })),\n \n jumbo: SC.FormView.row(SC.ButtonView.design({\n layout: { width: 150, height: 44 },\n title: \"i'm jumbo.\",\n controlSize: SC.JUMBO_CONTROL_SIZE\n }))\n \n \n })\n});\n\n// bootstrap code :)\nexports.getDemoView = function() {\n return MyExampleView;\n};\n","highlighted":"<span class=\"keyword\">var</span> <span class=\"class\">MyExampleView</span> = <span class=\"class\">SC</span>.<span class=\"class\">View</span>.<span class=\"variable\">extend</span>({\n <span class=\"variable\">backgroundColor</span>: <span class=\"string\">&quot;white&quot;</span>,\n <span class=\"variable\">childViews</span>: <span class=\"string\">&quot;form&quot;</span>.<span class=\"variable\">w</span>(),\n \n <span class=\"variable\">form</span>: <span class=\"class\">SC</span>.<span class=\"class\">FormView</span>.<span class=\"variable\">design</span>({\n <span class=\"variable\">layout</span>: {<span class=\"variable\">centerX</span>: <span class=\"number integer\">0</span>, <span class=\"variable\">centerY</span>: <span class=\"number integer\">0</span>, <span class=\"variable\">width</span>: <span class=\"number integer\">400</span>, <span class=\"variable\">height</span>: <span class=\"number integer\">300</span> },\n <span class=\"variable\">childViews</span>: <span class=\"string\">&quot;small regular huge jumbo&quot;</span>.<span class=\"variable\">w</span>(),\n <span class=\"variable\">small</span>: <span class=\"class\">SC</span>.<span class=\"class\">FormView</span>.<span class=\"variable\">row</span>(<span class=\"class\">SC</span>.<span class=\"class\">ButtonView</span>.<span class=\"variable\">design</span>({\n <span class=\"variable\">layout</span>: { <span class=\"variable\">width</span>: <span class=\"number integer\">100</span>, <span class=\"variable\">height</span>: <span class=\"number integer\">18</span> },\n <span class=\"variable\">title</span>: <span class=\"string\">&quot;I'm TINY!&quot;</span>,\n <span class=\"variable\">controlSize</span>: <span class=\"class\">SC</span>.<span class=\"class\">SMALL_CONTROL_SIZE</span>\n })),\n \n <span class=\"variable\">regular</span>: <span class=\"class\">SC</span>.<span class=\"class\">FormView</span>.<span class=\"variable\">row</span>(<span class=\"class\">SC</span>.<span class=\"class\">ButtonView</span>.<span class=\"variable\">design</span>({\n <span class=\"variable\">layout</span>: { <span class=\"variable\">width</span>: <span class=\"number integer\">100</span>, <span class=\"variable\">height</span>: <span class=\"number integer\">24</span> },\n <span class=\"variable\">title</span>: <span class=\"string\">&quot;I'm Normal!&quot;</span>,\n <span class=\"variable\">controlSize</span>: <span class=\"class\">SC</span>.<span class=\"class\">REGULAR_CONTROL_SIZE</span>\n })),\n \n <span class=\"variable\">huge</span>: <span class=\"class\">SC</span>.<span class=\"class\">FormView</span>.<span class=\"variable\">row</span>(<span class=\"class\">SC</span>.<span class=\"class\">ButtonView</span>.<span class=\"variable\">design</span>({\n <span class=\"variable\">layout</span>: { <span class=\"variable\">width</span>: <span class=\"number integer\">100</span>, <span class=\"variable\">height</span>: <span class=\"number integer\">30</span> },\n <span class=\"variable\">title</span>: <span class=\"string\">&quot;I'm huge.&quot;</span>,\n <span class=\"variable\">controlSize</span>: <span class=\"class\">SC</span>.<span class=\"class\">HUGE_CONTROL_SIZE</span>\n })),\n \n <span class=\"variable\">jumbo</span>: <span class=\"class\">SC</span>.<span class=\"class\">FormView</span>.<span class=\"variable\">row</span>(<span class=\"class\">SC</span>.<span class=\"class\">ButtonView</span>.<span class=\"variable\">design</span>({\n <span class=\"variable\">layout</span>: { <span class=\"variable\">width</span>: <span class=\"number integer\">150</span>, <span class=\"variable\">height</span>: <span class=\"number integer\">44</span> },\n <span class=\"variable\">title</span>: <span class=\"string\">&quot;i'm jumbo.&quot;</span>,\n <span class=\"variable\">controlSize</span>: <span class=\"class\">SC</span>.<span class=\"class\">JUMBO_CONTROL_SIZE</span>\n }))\n \n \n })\n});\n\n<span class=\"comment\">// bootstrap code :)</span>\n<span class=\"variable\">exports</span>.<span class=\"variable\">getDemoView</span> = <span class=\"keyword\">function</span>() {\n <span class=\"keyword\">return</span> <span class=\"class\">MyExampleView</span>;\n};\n","original":"var MyExampleView = SC.View.extend({\n backgroundColor: \"white\",\n childViews: \"form\".w(),\n \n form: SC.FormView.design({\n layout: {centerX: 0, centerY: 0, width: 400, height: 300 },\n childViews: \"small regular huge jumbo\".w(),\n small: SC.FormView.row(SC.ButtonView.design({\n layout: { width: 100, height: 18 },\n title: \"I'm TINY!\",\n controlSize: SC.SMALL_CONTROL_SIZE\n })),\n \n regular: SC.FormView.row(SC.ButtonView.design({\n layout: { width: 100, height: 24 },\n title: \"I'm Normal!\",\n controlSize: SC.REGULAR_CONTROL_SIZE\n })),\n \n huge: SC.FormView.row(SC.ButtonView.design({\n layout: { width: 100, height: 30 },\n title: \"I'm huge.\",\n controlSize: SC.HUGE_CONTROL_SIZE\n })),\n \n jumbo: SC.FormView.row(SC.ButtonView.design({\n layout: { width: 150, height: 44 },\n title: \"i'm jumbo.\",\n controlSize: SC.JUMBO_CONTROL_SIZE\n }))\n \n \n })\n});\n\n// bootstrap code :)\nexports.getDemoView = function() {\n return MyExampleView;\n};\n"}},"articleDirectory":"articles/controls/button/","outputDirectory":"build/","title":"ButtonView Touch Support"},{"content":"<h1>ScrollView Touch Support</h1>\n\n<p>SproutCore's ScrollView comes with built-in support for touch-based\nscrolling, including momentum and bouncing. In addition, it has (somewhat experimental)\nsupport for scaling.</p>\n\n<p>For many cases, just putting a view inside a ScrollView will \"just work\". Still, you may want\nto set some settings.</p>\n\n<h2>Bouncing</h2>\n\n<p>By default, ScrollView will <em>always</em> bounce when scrolling vertically, regardless of the\ncontent's height, but only bounce horizontally <em>if</em> the content is wider than the ScrollView.\nThis is controlled by two properties:</p>\n\n<ul>\n<li>alwaysBounceHorizontal, which defaults to NO.</li>\n<li>alwaysBounceVertical, which defaults to YES.</li>\n</ul>\n\n<h2>Scaling</h2>\n\n<p>ScrollView has support for scaling, which you can use through a few properties:</p>\n\n<ul>\n<li>canScale. Specifies whether the content may be scaled. If YES, using two fingers\n(in that classic \"pinch gesture\") will zoom the content.</li>\n<li>minimumScale: The minimum scale value. Default: 0.25.</li>\n<li>maximumScale: The maximum scale value. Default: 2.0.</li>\n</ul>\n\n<p><a href='touch.js' class='demo'>touch.js</a></p>","errors":[],"demos":{"touch.js":{"ex":"/*globals Hedwig*/\nvar MyExampleView = SC.ScrollView.extend({\n horizontalAlign: SC.ALIGN_CENTER,\n verticalAlign: SC.ALIGN_MIDDLE,\n backgroundColor: \"#555\",\n \n canScale: YES,\n alwaysBounceVertical: NO,\n \n contentView: SC.ImageView.design({\n layout: { left: 0, top: 0, width: 1357, height: 2048 },\n value: Hedwig.SAMPLE_IMAGE\n })\n});\n\n// bootstrap code :)\nexports.getDemoView = function() {\n return MyExampleView;\n};\n","highlighted":"<span class=\"multiline comment\">/*globals Hedwig*/</span>\n<span class=\"keyword\">var</span> <span class=\"class\">MyExampleView</span> = <span class=\"class\">SC</span>.<span class=\"class\">ScrollView</span>.<span class=\"variable\">extend</span>({\n <span class=\"variable\">horizontalAlign</span>: <span class=\"class\">SC</span>.<span class=\"class\">ALIGN_CENTER</span>,\n <span class=\"variable\">verticalAlign</span>: <span class=\"class\">SC</span>.<span class=\"class\">ALIGN_MIDDLE</span>,\n <span class=\"variable\">backgroundColor</span>: <span class=\"string\">&quot;#555&quot;</span>,\n \n <span class=\"variable\">canScale</span>: <span class=\"class\">YES</span>,\n <span class=\"variable\">alwaysBounceVertical</span>: <span class=\"class\">NO</span>,\n \n <span class=\"variable\">contentView</span>: <span class=\"class\">SC</span>.<span class=\"class\">ImageView</span>.<span class=\"variable\">design</span>({\n <span class=\"variable\">layout</span>: { <span class=\"variable\">left</span>: <span class=\"number integer\">0</span>, <span class=\"variable\">top</span>: <span class=\"number integer\">0</span>, <span class=\"variable\">width</span>: <span class=\"number integer\">1357</span>, <span class=\"variable\">height</span>: <span class=\"number integer\">2048</span> },\n <span class=\"variable\">value</span>: <span class=\"class\">Hedwig</span>.<span class=\"class\">SAMPLE_IMAGE</span>\n })\n});\n\n<span class=\"comment\">// bootstrap code :)</span>\n<span class=\"variable\">exports</span>.<span class=\"variable\">getDemoView</span> = <span class=\"keyword\">function</span>() {\n <span class=\"keyword\">return</span> <span class=\"class\">MyExampleView</span>;\n};\n","original":"/*globals Hedwig*/\nvar MyExampleView = SC.ScrollView.extend({\n horizontalAlign: SC.ALIGN_CENTER,\n verticalAlign: SC.ALIGN_MIDDLE,\n backgroundColor: \"#555\",\n \n canScale: YES,\n alwaysBounceVertical: NO,\n \n contentView: SC.ImageView.design({\n layout: { left: 0, top: 0, width: 1357, height: 2048 },\n value: Hedwig.SAMPLE_IMAGE\n })\n});\n\n// bootstrap code :)\nexports.getDemoView = function() {\n return MyExampleView;\n};\n"}},"articleDirectory":"articles/controls/scroll/","outputDirectory":"build/","title":"ScrollView Touch Support"}]},{"title":"Advanced Concepts","articles":[{"content":"<h1>Capturing</h1>\n\n<p>There are many instances where you may have to capture touches. We'll consider scroll views,\nhowever, because it is very easy to explain <em>why</em> they need to be able to.</p>\n\n<p>If you are implementing a scroll view, you'll need to capture the touch before the target view gets it.</p>\n\n<p>This is because scroll views have some subtle quirks. For instance, a touch should not pass\nthrough to the actual target until a split-second has passed&emdash;this is to prevent flicker should\nthe user decide to scroll rather than touch the target. Also, it needs to add itself to what is\ncalled the \"touch responder stack\" <em>before</em> the target view, so that the target view can hand control back\nsimply as discussed above.</p>\n\n<h2>Touch Responder Stack</h2>\n\n<p>Very briefly mentioned in the \"Touch Events\" article, the <em>touch responder</em> is the view which\n\"owns\" a touch&emdash;the view which gets all touchesDragged events and the touchEnd for that touch.</p>\n\n<p>However, in our scroll view case, we want to pass control to the target view, but allow it\nto <em>transfer control back</em> (a process covered in \"Releasing\"). That means it needs to know\nwhat view to hand it back to. Also, what if you had a scroll view <em>within</em> a scroll view?</p>\n\n<p>To solve these issues, there is a \"stack\" of those views to which control can be passed back to.</p>\n\n<p>You generally work with it by either:</p>\n\n<ul>\n<li>Specifically telling it to \"stack\" your view when capturing a touch.</li>\n<li>Telling it to change touch responder to a touch responder in the stack (see Releasing)</li>\n</ul>\n\n<h2>Capturing</h2>\n\n<p>Capturing the touch is simple. Before starting at the target view and working its\nway up to the root calling touchStart (the same way all SproutCore events work), \nSproutCore's touch events go the opposite direction, starting at the root and working their way down\nto the target, calling a method named captureTouch:</p>\n\n<pre><code class='syntax js'><span class=\"variable\">captureTouch</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>) {\n</code></pre>\n\n<p>If the view returns YES, the touchStart event will be sent directly to it.</p>\n\n<p>You could then use invokeLater to wait that split-second. But then what? You don't actually\nknow what the target view should be. What you need is to start at the original target, and\ndo the whole working up to it calling captureTouch and work down from it calling touchStart\nthing&emdash;but this time, starting from your own view, rather than the root. </p>\n\n<p>Thankfully, you can do this in one line of code:</p>\n\n<pre><code class='syntax js'><span class=\"variable\">touch</span>.<span class=\"variable\">captureTouch</span>(<span class=\"this\">this</span>, <span class=\"class\">YES</span>); <span class=\"comment\">// the YES means stack, which I'm guessing you'd want to do</span>\n<span class=\"comment\">// so that the new view can easily pass control back to this...</span>\n<span class=\"comment\">// ... but you may know better than me.</span>\n</code></pre>\n\n<p>What happens next depends on whether or not you told it to stack your view:</p>\n\n<ul>\n<li>If stacked, you will receive a touchCancelled when the touch actually ends, unless the\nview which captures the touch hands control back to your view. If it does, you will <em>not</em>\nreceive another <code class='syntax js'><span class=\"variable\">touchStart</span></code>, but you <em>will</em> start receiving <code class='syntax js'><span class=\"variable\">touchesDragged</span></code> and \nwill receive a <code class='syntax js'><span class=\"variable\">touchEnd</span></code> when the touch ends.</li>\n<li>If not stacked, your view will receive <code class='syntax js'><span class=\"variable\">touchCancelled</span></code>.</li>\n</ul>\n\n<h2>What Does It Look Like?</h2>\n\n<p>In this example, we have two boxes, each containing an inner box. The outer boxes\ncapture touches, and only pass them to the inner box after a delay. The top box stacks,\nthe other one does not; this causes, as described above, a difference in when touchEnd/Cancelled\nis called on the outer boxes.</p>\n\n<p><a href='capturing.js' class='demo'>capturing.js</a></p>","errors":[],"demos":{"capturing.js":{"ex":"/**\n This is our test view. It will capture a touch, and, after one second,\n pass it through to the child view. Depending on the shouldStack property,\n it will stack while passing.\n \n In this example, the top view stacks, the bottom one does not.\n*/\nvar Tester = SC.View.extend({\n backgroundColor: \"white\",\n \n shouldStack: NO,\n captureTouch: function() {\n return YES;\n },\n \n touchStart: function(touch) {\n this._hasTouch = touch;\n this.get(\"layer\").style.backgroundColor = \"red\";\n \n // in one second, we'll pass the touch along.\n this.invokeLater(\"beginContentTouches\", 1000, touch);\n return YES;\n },\n \n beginContentTouches: function(touch) {\n // if our touch hasn't changed in the meantime\n if (touch === this._hasTouch) {\n // we'll pass the touch along.\n touch.captureTouch(this, this.get(\"shouldStack\"));\n }\n },\n \n touchEnd: function(touch) {\n this._hasTouch = NO;\n this.get(\"layer\").style.backgroundColor = \"white\";\n },\n \n touchCancelled: function(touch) {\n this._hasTouch = NO;\n this.get(\"layer\").style.backgroundColor = \"white\";\n },\n \n childViews: \"inner\".w(),\n inner: SC.View.design({\n layout: { left: 50, top: 50, right: 50, bottom: 50 },\n backgroundColor: \"gray\",\n touchStart: function() {\n this.get(\"layer\").style.backgroundColor = \"blue\";\n return YES;\n },\n \n touchEnd: function() {\n this.get(\"layer\").style.backgroundColor = \"gray\";\n }\n \n })\n \n});\n\nvar MyExampleView = SC.View.extend({\n backgroundColor: \"#aaa\",\n childViews: \"stacks doesNot\".w(),\n stacks: Tester.extend({\n layout: { top: 10, left: 10, width: 200, height: 200 },\n shouldStack: YES\n }),\n \n doesNot: Tester.extend({\n layout: { top: 230, left: 10, width: 200, height: 200 },\n shouldStack: NO \n })\n});\n\n// bootstrap code :)\nexports.getDemoView = function() {\n return MyExampleView;\n};\n","highlighted":"<span class=\"multiline comment\">/**\n This is our test view. It will capture a touch, and, after one second,\n pass it through to the child view. Depending on the shouldStack property,\n it will stack while passing.\n \n In this example, the top view stacks, the bottom one does not.\n*/</span>\n<span class=\"keyword\">var</span> <span class=\"class\">Tester</span> = <span class=\"class\">SC</span>.<span class=\"class\">View</span>.<span class=\"variable\">extend</span>({\n <span class=\"variable\">backgroundColor</span>: <span class=\"string\">&quot;white&quot;</span>,\n \n <span class=\"variable\">shouldStack</span>: <span class=\"class\">NO</span>,\n <span class=\"variable\">captureTouch</span>: <span class=\"keyword\">function</span>() {\n <span class=\"keyword\">return</span> <span class=\"class\">YES</span>;\n },\n \n <span class=\"variable\">touchStart</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">_hasTouch</span> = <span class=\"variable\">touch</span>;\n <span class=\"this\">this</span>.<span class=\"variable\">get</span>(<span class=\"string\">&quot;layer&quot;</span>).<span class=\"variable\">style</span>.<span class=\"variable\">backgroundColor</span> = <span class=\"string\">&quot;red&quot;</span>;\n \n <span class=\"comment\">// in one second, we'll pass the touch along.</span>\n <span class=\"this\">this</span>.<span class=\"variable\">invokeLater</span>(<span class=\"string\">&quot;beginContentTouches&quot;</span>, <span class=\"number integer\">1000</span>, <span class=\"variable\">touch</span>);\n <span class=\"keyword\">return</span> <span class=\"class\">YES</span>;\n },\n \n <span class=\"variable\">beginContentTouches</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>) {\n <span class=\"comment\">// if our touch hasn't changed in the meantime</span>\n <span class=\"keyword\">if</span> (<span class=\"variable\">touch</span> === <span class=\"this\">this</span>.<span class=\"variable\">_hasTouch</span>) {\n <span class=\"comment\">// we'll pass the touch along.</span>\n <span class=\"variable\">touch</span>.<span class=\"variable\">captureTouch</span>(<span class=\"this\">this</span>, <span class=\"this\">this</span>.<span class=\"variable\">get</span>(<span class=\"string\">&quot;shouldStack&quot;</span>));\n }\n },\n \n <span class=\"variable\">touchEnd</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">_hasTouch</span> = <span class=\"class\">NO</span>;\n <span class=\"this\">this</span>.<span class=\"variable\">get</span>(<span class=\"string\">&quot;layer&quot;</span>).<span class=\"variable\">style</span>.<span class=\"variable\">backgroundColor</span> = <span class=\"string\">&quot;white&quot;</span>;\n },\n \n <span class=\"variable\">touchCancelled</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">_hasTouch</span> = <span class=\"class\">NO</span>;\n <span class=\"this\">this</span>.<span class=\"variable\">get</span>(<span class=\"string\">&quot;layer&quot;</span>).<span class=\"variable\">style</span>.<span class=\"variable\">backgroundColor</span> = <span class=\"string\">&quot;white&quot;</span>;\n },\n \n <span class=\"variable\">childViews</span>: <span class=\"string\">&quot;inner&quot;</span>.<span class=\"variable\">w</span>(),\n <span class=\"variable\">inner</span>: <span class=\"class\">SC</span>.<span class=\"class\">View</span>.<span class=\"variable\">design</span>({\n <span class=\"variable\">layout</span>: { <span class=\"variable\">left</span>: <span class=\"number integer\">50</span>, <span class=\"variable\">top</span>: <span class=\"number integer\">50</span>, <span class=\"variable\">right</span>: <span class=\"number integer\">50</span>, <span class=\"variable\">bottom</span>: <span class=\"number integer\">50</span> },\n <span class=\"variable\">backgroundColor</span>: <span class=\"string\">&quot;gray&quot;</span>,\n <span class=\"variable\">touchStart</span>: <span class=\"keyword\">function</span>() {\n <span class=\"this\">this</span>.<span class=\"variable\">get</span>(<span class=\"string\">&quot;layer&quot;</span>).<span class=\"variable\">style</span>.<span class=\"variable\">backgroundColor</span> = <span class=\"string\">&quot;blue&quot;</span>;\n <span class=\"keyword\">return</span> <span class=\"class\">YES</span>;\n },\n \n <span class=\"variable\">touchEnd</span>: <span class=\"keyword\">function</span>() {\n <span class=\"this\">this</span>.<span class=\"variable\">get</span>(<span class=\"string\">&quot;layer&quot;</span>).<span class=\"variable\">style</span>.<span class=\"variable\">backgroundColor</span> = <span class=\"string\">&quot;gray&quot;</span>;\n }\n \n })\n \n});\n\n<span class=\"keyword\">var</span> <span class=\"class\">MyExampleView</span> = <span class=\"class\">SC</span>.<span class=\"class\">View</span>.<span class=\"variable\">extend</span>({\n <span class=\"variable\">backgroundColor</span>: <span class=\"string\">&quot;#aaa&quot;</span>,\n <span class=\"variable\">childViews</span>: <span class=\"string\">&quot;stacks doesNot&quot;</span>.<span class=\"variable\">w</span>(),\n <span class=\"variable\">stacks</span>: <span class=\"class\">Tester</span>.<span class=\"variable\">extend</span>({\n <span class=\"variable\">layout</span>: { <span class=\"variable\">top</span>: <span class=\"number integer\">10</span>, <span class=\"variable\">left</span>: <span class=\"number integer\">10</span>, <span class=\"variable\">width</span>: <span class=\"number integer\">200</span>, <span class=\"variable\">height</span>: <span class=\"number integer\">200</span> },\n <span class=\"variable\">shouldStack</span>: <span class=\"class\">YES</span>\n }),\n \n <span class=\"variable\">doesNot</span>: <span class=\"class\">Tester</span>.<span class=\"variable\">extend</span>({\n <span class=\"variable\">layout</span>: { <span class=\"variable\">top</span>: <span class=\"number integer\">230</span>, <span class=\"variable\">left</span>: <span class=\"number integer\">10</span>, <span class=\"variable\">width</span>: <span class=\"number integer\">200</span>, <span class=\"variable\">height</span>: <span class=\"number integer\">200</span> },\n <span class=\"variable\">shouldStack</span>: <span class=\"class\">NO</span> \n })\n});\n\n<span class=\"comment\">// bootstrap code :)</span>\n<span class=\"variable\">exports</span>.<span class=\"variable\">getDemoView</span> = <span class=\"keyword\">function</span>() {\n <span class=\"keyword\">return</span> <span class=\"class\">MyExampleView</span>;\n};\n","original":"/**\n This is our test view. It will capture a touch, and, after one second,\n pass it through to the child view. Depending on the shouldStack property,\n it will stack while passing.\n \n In this example, the top view stacks, the bottom one does not.\n*/\nvar Tester = SC.View.extend({\n backgroundColor: \"white\",\n \n shouldStack: NO,\n captureTouch: function() {\n return YES;\n },\n \n touchStart: function(touch) {\n this._hasTouch = touch;\n this.get(\"layer\").style.backgroundColor = \"red\";\n \n // in one second, we'll pass the touch along.\n this.invokeLater(\"beginContentTouches\", 1000, touch);\n return YES;\n },\n \n beginContentTouches: function(touch) {\n // if our touch hasn't changed in the meantime\n if (touch === this._hasTouch) {\n // we'll pass the touch along.\n touch.captureTouch(this, this.get(\"shouldStack\"));\n }\n },\n \n touchEnd: function(touch) {\n this._hasTouch = NO;\n this.get(\"layer\").style.backgroundColor = \"white\";\n },\n \n touchCancelled: function(touch) {\n this._hasTouch = NO;\n this.get(\"layer\").style.backgroundColor = \"white\";\n },\n \n childViews: \"inner\".w(),\n inner: SC.View.design({\n layout: { left: 50, top: 50, right: 50, bottom: 50 },\n backgroundColor: \"gray\",\n touchStart: function() {\n this.get(\"layer\").style.backgroundColor = \"blue\";\n return YES;\n },\n \n touchEnd: function() {\n this.get(\"layer\").style.backgroundColor = \"gray\";\n }\n \n })\n \n});\n\nvar MyExampleView = SC.View.extend({\n backgroundColor: \"#aaa\",\n childViews: \"stacks doesNot\".w(),\n stacks: Tester.extend({\n layout: { top: 10, left: 10, width: 200, height: 200 },\n shouldStack: YES\n }),\n \n doesNot: Tester.extend({\n layout: { top: 230, left: 10, width: 200, height: 200 },\n shouldStack: NO \n })\n});\n\n// bootstrap code :)\nexports.getDemoView = function() {\n return MyExampleView;\n};\n"}},"articleDirectory":"articles/touch/","outputDirectory":"build/","title":"Capturing"},{"content":"<h1>Releasing</h1>\n\n<p>Why would you want to give up a touch? Imagine that your control is inside a <code class='syntax js'><span class=\"class\">SC</span>.<span class=\"class\">ScrollView</span></code>:\nif the touch moves too much, perhaps it should be considered a scroll, rather than an\naction for your control.</p>\n\n<p>From touchesDragged, you would give up touch responder status through a line like this:</p>\n\n<pre><code class='syntax js'><span class=\"variable\">someTouch</span>.<span class=\"variable\">makeTouchResponder</span>(<span class=\"variable\">someTouch</span>.<span class=\"variable\">nextTouchResponder</span>);\n</code></pre>\n\n<p>The touch's nextTouchResponder is the responder that is the <em>parent</em> touch responder; through\ndevious trickery (see <em>Capturing Touches</em>), ScrollView receives touch responder status <em>before</em>\nother views; further, it doesn't just hand touch responder status to the target view (your view)--\nit adds the responder to a stack of touch responders for the touch, so the responders can easily\nreturn to their parent responder (which is what you do with the above line of code.)</p>\n\n<p>Remember, though, that touchesDragged is called with a set of touches. It is really easy\nto change the responder for all of the touches simultaneously, should you wish to do so:</p>\n\n<pre><code class='syntax js'><span class=\"variable\">touches</span>.<span class=\"variable\">forEach</span>(<span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>){\n <span class=\"variable\">touch</span>.<span class=\"variable\">makeTouchResponder</span>(<span class=\"variable\">touch</span>.<span class=\"variable\">nextTouchResponder</span>);\n});\n</code></pre>\n\n<p>Perhaps you want to pass control only if the responder is scrollable:</p>\n\n<pre><code class='syntax js'><span class=\"keyword\">if</span> (<span class=\"variable\">touch</span>.<span class=\"variable\">nextTouchResponder</span> &amp;&amp; <span class=\"variable\">touch</span>.<span class=\"variable\">nextTouchResponder</span>.<span class=\"variable\">isScrollable</span>) {\n <span class=\"variable\">touch</span>.<span class=\"variable\">makeTouchResponder</span>(<span class=\"variable\">touch</span>.<span class=\"variable\">nextTouchResponder</span>);\n}\n</code></pre>\n\n<p><code class='syntax js'><span class=\"variable\">touchCancelled</span></code> will be called on your view automatically.</p>\n\n<h2>What Does It Look Like?</h2>\n\n<p>In this example, there is a single white box, containing a gray inner box. When you press\non the inner box, the outer box will capture the touch first. After a delay, it re-captures\nby calling captureTouch, and the inner view receives it. This is just like the \"Capturing\" demo.</p>\n\n<p>However, the inner view, after a second, will release it back.</p>\n\n<p><a href='releasing.js' class='demo'>releasing.js</a></p>","errors":[],"demos":{"releasing.js":{"ex":"/**\n This is similar to the \"Capturing\" example.\n \n In fact, the outer view is identical. Only the inner view has changed.\n As we can't pass control back without stacking, this demo _only_ includes\n the stacking method.\n \n The inner view, just like the outer view, passes control back after a specific\n time period.\n*/\nvar Tester = SC.View.extend({\n backgroundColor: \"white\",\n \n captureTouch: function() {\n return YES;\n },\n \n touchStart: function(touch) {\n this._hasTouch = touch;\n this.get(\"layer\").style.backgroundColor = \"red\";\n \n // in one second, we'll pass the touch along.\n this.invokeLater(\"beginContentTouches\", 1000, touch);\n return YES;\n },\n \n beginContentTouches: function(touch) {\n // if our touch hasn't changed in the meantime\n if (touch === this._hasTouch) {\n // we'll pass the touch along.\n touch.captureTouch(this, YES);\n }\n },\n \n touchEnd: function(touch) {\n this._hasTouch = NO;\n this.get(\"layer\").style.backgroundColor = \"white\";\n },\n \n touchCancelled: function(touch) {\n this._hasTouch = NO;\n this.get(\"layer\").style.backgroundColor = \"white\";\n },\n \n childViews: \"inner\".w(),\n inner: SC.View.design({\n layout: { left: 50, top: 50, right: 50, bottom: 50 },\n backgroundColor: \"gray\",\n touchStart: function(touch) {\n this._touch = touch;\n this.get(\"layer\").style.backgroundColor = \"blue\";\n this.invokeLater(\"releaseTouch\", 1000, touch);\n return YES;\n },\n \n releaseTouch: function(touch) {\n if (touch === this._touch) {\n touch.makeTouchResponder(touch.nextTouchResponder);\n }\n },\n \n touchEnd: function(touch) {\n this._touch = NO;\n this.get(\"layer\").style.backgroundColor = \"gray\";\n },\n \n touchCancelled: function(touch) {\n this._touch = NO;\n this.get(\"layer\").style.backgroundColor = \"gray\";\n }\n \n })\n \n});\n\nvar MyExampleView = SC.View.extend({\n backgroundColor: \"#aaa\",\n childViews: \"demo\".w(),\n demo: Tester.extend({\n layout: { top: 10, left: 10, width: 200, height: 200 },\n shouldStack: YES\n })\n});\n\n// bootstrap code :)\nexports.getDemoView = function() {\n return MyExampleView;\n};\n","highlighted":"<span class=\"multiline comment\">/**\n This is similar to the &quot;Capturing&quot; example.\n \n In fact, the outer view is identical. Only the inner view has changed.\n As we can't pass control back without stacking, this demo _only_ includes\n the stacking method.\n \n The inner view, just like the outer view, passes control back after a specific\n time period.\n*/</span>\n<span class=\"keyword\">var</span> <span class=\"class\">Tester</span> = <span class=\"class\">SC</span>.<span class=\"class\">View</span>.<span class=\"variable\">extend</span>({\n <span class=\"variable\">backgroundColor</span>: <span class=\"string\">&quot;white&quot;</span>,\n \n <span class=\"variable\">captureTouch</span>: <span class=\"keyword\">function</span>() {\n <span class=\"keyword\">return</span> <span class=\"class\">YES</span>;\n },\n \n <span class=\"variable\">touchStart</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">_hasTouch</span> = <span class=\"variable\">touch</span>;\n <span class=\"this\">this</span>.<span class=\"variable\">get</span>(<span class=\"string\">&quot;layer&quot;</span>).<span class=\"variable\">style</span>.<span class=\"variable\">backgroundColor</span> = <span class=\"string\">&quot;red&quot;</span>;\n \n <span class=\"comment\">// in one second, we'll pass the touch along.</span>\n <span class=\"this\">this</span>.<span class=\"variable\">invokeLater</span>(<span class=\"string\">&quot;beginContentTouches&quot;</span>, <span class=\"number integer\">1000</span>, <span class=\"variable\">touch</span>);\n <span class=\"keyword\">return</span> <span class=\"class\">YES</span>;\n },\n \n <span class=\"variable\">beginContentTouches</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>) {\n <span class=\"comment\">// if our touch hasn't changed in the meantime</span>\n <span class=\"keyword\">if</span> (<span class=\"variable\">touch</span> === <span class=\"this\">this</span>.<span class=\"variable\">_hasTouch</span>) {\n <span class=\"comment\">// we'll pass the touch along.</span>\n <span class=\"variable\">touch</span>.<span class=\"variable\">captureTouch</span>(<span class=\"this\">this</span>, <span class=\"class\">YES</span>);\n }\n },\n \n <span class=\"variable\">touchEnd</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">_hasTouch</span> = <span class=\"class\">NO</span>;\n <span class=\"this\">this</span>.<span class=\"variable\">get</span>(<span class=\"string\">&quot;layer&quot;</span>).<span class=\"variable\">style</span>.<span class=\"variable\">backgroundColor</span> = <span class=\"string\">&quot;white&quot;</span>;\n },\n \n <span class=\"variable\">touchCancelled</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">_hasTouch</span> = <span class=\"class\">NO</span>;\n <span class=\"this\">this</span>.<span class=\"variable\">get</span>(<span class=\"string\">&quot;layer&quot;</span>).<span class=\"variable\">style</span>.<span class=\"variable\">backgroundColor</span> = <span class=\"string\">&quot;white&quot;</span>;\n },\n \n <span class=\"variable\">childViews</span>: <span class=\"string\">&quot;inner&quot;</span>.<span class=\"variable\">w</span>(),\n <span class=\"variable\">inner</span>: <span class=\"class\">SC</span>.<span class=\"class\">View</span>.<span class=\"variable\">design</span>({\n <span class=\"variable\">layout</span>: { <span class=\"variable\">left</span>: <span class=\"number integer\">50</span>, <span class=\"variable\">top</span>: <span class=\"number integer\">50</span>, <span class=\"variable\">right</span>: <span class=\"number integer\">50</span>, <span class=\"variable\">bottom</span>: <span class=\"number integer\">50</span> },\n <span class=\"variable\">backgroundColor</span>: <span class=\"string\">&quot;gray&quot;</span>,\n <span class=\"variable\">touchStart</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">_touch</span> = <span class=\"variable\">touch</span>;\n <span class=\"this\">this</span>.<span class=\"variable\">get</span>(<span class=\"string\">&quot;layer&quot;</span>).<span class=\"variable\">style</span>.<span class=\"variable\">backgroundColor</span> = <span class=\"string\">&quot;blue&quot;</span>;\n <span class=\"this\">this</span>.<span class=\"variable\">invokeLater</span>(<span class=\"string\">&quot;releaseTouch&quot;</span>, <span class=\"number integer\">1000</span>, <span class=\"variable\">touch</span>);\n <span class=\"keyword\">return</span> <span class=\"class\">YES</span>;\n },\n \n <span class=\"variable\">releaseTouch</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>) {\n <span class=\"keyword\">if</span> (<span class=\"variable\">touch</span> === <span class=\"this\">this</span>.<span class=\"variable\">_touch</span>) {\n <span class=\"variable\">touch</span>.<span class=\"variable\">makeTouchResponder</span>(<span class=\"variable\">touch</span>.<span class=\"variable\">nextTouchResponder</span>);\n }\n },\n \n <span class=\"variable\">touchEnd</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">_touch</span> = <span class=\"class\">NO</span>;\n <span class=\"this\">this</span>.<span class=\"variable\">get</span>(<span class=\"string\">&quot;layer&quot;</span>).<span class=\"variable\">style</span>.<span class=\"variable\">backgroundColor</span> = <span class=\"string\">&quot;gray&quot;</span>;\n },\n \n <span class=\"variable\">touchCancelled</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">_touch</span> = <span class=\"class\">NO</span>;\n <span class=\"this\">this</span>.<span class=\"variable\">get</span>(<span class=\"string\">&quot;layer&quot;</span>).<span class=\"variable\">style</span>.<span class=\"variable\">backgroundColor</span> = <span class=\"string\">&quot;gray&quot;</span>;\n }\n \n })\n \n});\n\n<span class=\"keyword\">var</span> <span class=\"class\">MyExampleView</span> = <span class=\"class\">SC</span>.<span class=\"class\">View</span>.<span class=\"variable\">extend</span>({\n <span class=\"variable\">backgroundColor</span>: <span class=\"string\">&quot;#aaa&quot;</span>,\n <span class=\"variable\">childViews</span>: <span class=\"string\">&quot;demo&quot;</span>.<span class=\"variable\">w</span>(),\n <span class=\"variable\">demo</span>: <span class=\"class\">Tester</span>.<span class=\"variable\">extend</span>({\n <span class=\"variable\">layout</span>: { <span class=\"variable\">top</span>: <span class=\"number integer\">10</span>, <span class=\"variable\">left</span>: <span class=\"number integer\">10</span>, <span class=\"variable\">width</span>: <span class=\"number integer\">200</span>, <span class=\"variable\">height</span>: <span class=\"number integer\">200</span> },\n <span class=\"variable\">shouldStack</span>: <span class=\"class\">YES</span>\n })\n});\n\n<span class=\"comment\">// bootstrap code :)</span>\n<span class=\"variable\">exports</span>.<span class=\"variable\">getDemoView</span> = <span class=\"keyword\">function</span>() {\n <span class=\"keyword\">return</span> <span class=\"class\">MyExampleView</span>;\n};\n","original":"/**\n This is similar to the \"Capturing\" example.\n \n In fact, the outer view is identical. Only the inner view has changed.\n As we can't pass control back without stacking, this demo _only_ includes\n the stacking method.\n \n The inner view, just like the outer view, passes control back after a specific\n time period.\n*/\nvar Tester = SC.View.extend({\n backgroundColor: \"white\",\n \n captureTouch: function() {\n return YES;\n },\n \n touchStart: function(touch) {\n this._hasTouch = touch;\n this.get(\"layer\").style.backgroundColor = \"red\";\n \n // in one second, we'll pass the touch along.\n this.invokeLater(\"beginContentTouches\", 1000, touch);\n return YES;\n },\n \n beginContentTouches: function(touch) {\n // if our touch hasn't changed in the meantime\n if (touch === this._hasTouch) {\n // we'll pass the touch along.\n touch.captureTouch(this, YES);\n }\n },\n \n touchEnd: function(touch) {\n this._hasTouch = NO;\n this.get(\"layer\").style.backgroundColor = \"white\";\n },\n \n touchCancelled: function(touch) {\n this._hasTouch = NO;\n this.get(\"layer\").style.backgroundColor = \"white\";\n },\n \n childViews: \"inner\".w(),\n inner: SC.View.design({\n layout: { left: 50, top: 50, right: 50, bottom: 50 },\n backgroundColor: \"gray\",\n touchStart: function(touch) {\n this._touch = touch;\n this.get(\"layer\").style.backgroundColor = \"blue\";\n this.invokeLater(\"releaseTouch\", 1000, touch);\n return YES;\n },\n \n releaseTouch: function(touch) {\n if (touch === this._touch) {\n touch.makeTouchResponder(touch.nextTouchResponder);\n }\n },\n \n touchEnd: function(touch) {\n this._touch = NO;\n this.get(\"layer\").style.backgroundColor = \"gray\";\n },\n \n touchCancelled: function(touch) {\n this._touch = NO;\n this.get(\"layer\").style.backgroundColor = \"gray\";\n }\n \n })\n \n});\n\nvar MyExampleView = SC.View.extend({\n backgroundColor: \"#aaa\",\n childViews: \"demo\".w(),\n demo: Tester.extend({\n layout: { top: 10, left: 10, width: 200, height: 200 },\n shouldStack: YES\n })\n});\n\n// bootstrap code :)\nexports.getDemoView = function() {\n return MyExampleView;\n};\n"}},"articleDirectory":"articles/touch/","outputDirectory":"build/","title":"Releasing"}]}],"file":"build/guides/touch"};
View
1  apps/hedwig/resources/guide/touch.json
@@ -1 +0,0 @@
-{"title":"Touch Application Guide","sections":[{"title":"Introduction","articles":[{"content":"<h1>A Brief Touch</h1>\n\n<p>It is very possible to build <em>awesome</em> touch-enabled applications in SproutCore.</p>\n\n<p>But, what makes an awesome touch-enabled application? Sure, it must accept touches,\nbut with SproutCore's (constantly growing) touch support, this is now pretty easy:\nmany existing interfaces, if built with newer SproutCore varieties, will function fine (or mostly fine),\non both larger-screened touch devices (such as iPad) and the traditional desktop environment.</p>\n\n<p>But there are many differences between desktop and touch platforms:</p>\n\n<ul>\n<li><strong>Precision.</strong> Touches are less precise than clicks. To compensate, controls should be larger.</li>\n<li><strong>Performance.</strong> Touch-based devices tend to be slow (for now). To get around this just takes \nsome elbow grease: there are many techniques to speed things up... many of which SproutCore will\nhandle for you.</li>\n<li><strong>Animation.</strong> Lack of animation looks okay on desktop (even if animation is cool)... but on\ntouch devices, non-animated interfaces look strange: touch is so much more realistic than mouse,\nbut sudden changes without transitions are not realistic at all.</li>\n<li><strong>Coolness.</strong> Touch-based interfaces are cool. That is all.</li>\n</ul>\n\n<p>In this guide, we go over each of these&emdash;except for the last, which is rather vague; you'll have to figure out\nyour own meaning of \"coolness\".</p>","errors":[],"demos":{},"articleDirectory":"articles/touch/","outputDirectory":"build/","title":"A Brief Touch","any":"metadata","goes":"Here","damn":"gruber","this":"is still eye-readable","and":"He is wrong about touch apps."},{"content":"<h1>Touch Events</h1>\n\n<p>SproutCore's touch events have a few great features:</p>\n\n<ul>\n<li>Multiple views can receive touches simultaneously.</li>\n<li>A single view can receive multiple touches.</li>\n<li>A view can capture touches before allowing them to pass through to children.</li>\n<li>Child views can release touches back to parent views that originally captured them.</li>\n</ul>\n\n<p>We won't get into the last two in this article&emdash;they're quite sophisticated!</p>\n\n<h1>Simple Single-Touch Handling</h1>\n\n<p>You may be familiar with this SC.View method signature if you are familiar with SproutCore:</p>\n\n<pre><code class='syntax js'><span class=\"variable\">mouseDown</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">evt</span>)\n</code></pre>\n\n<p>With <code class='syntax js'><span class=\"variable\">mouseDown</span></code>, you can decide whether or not to accept the mouse event by returning either\n<code class='syntax js'><span class=\"class\">YES</span></code> or <code class='syntax js'><span class=\"class\">NO</span></code>.</p>\n\n<p>Touch events are similar, but work a bit differently:</p>\n\n<pre><code class='syntax js'><span class=\"variable\">touchStart</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>)\n</code></pre>\n\n<p>Instead of being passed a raw event, <code class='syntax js'><span class=\"variable\">touchStart</span></code> is passed an <code class='syntax js'><span class=\"class\">SC</span>.<span class=\"class\">Touch</span></code> object.\nIf you return YES from touchStart, your view will \"own\" the touch&emdash;in SproutCore terms, your\nview will be the <em>touch responder</em>. For more information about what this entails, see\nthe \"Internals\" article. Your view will own the touch until the touch ends.</p>\n\n<p><code class='syntax js'><span class=\"variable\">touchStart</span></code> will be called once for every touch that touches the view.</p>\n\n<p><strong>Note:</strong> By default, views only receive <code class='syntax js'><span class=\"variable\">touchStart</span></code> and touchEnd for a single touch. This is\na feature intended to make it easier to handle such cases, very similar to Cocoa Touch's <code class='syntax js'><span class=\"variable\">acceptsMultitouch</span></code>\nproperty&emdash;actually, SC.View uses the same property name! See the \"Multitouch\" article.</p>\n\n<h2>Anatomy of an SC.Touch</h2>\n\n<p>SC.Touch represents the touch from the time the user puts their finger on the screen until the time they lift it.</p>\n\n<p>The touch object acts like an event object in many ways. It has many other useful things, as well:</p>\n\n<ul>\n<li><code class='syntax js'><span class=\"variable\">pageX</span></code> and <code class='syntax js'><span class=\"variable\">pageY</span></code> for the touch</li>\n<li><code class='syntax js'><span class=\"variable\">event</span></code>: if in an event cycle, this contains the event. Otherwise, it is <code class='syntax js'><span class=\"variable\">undefined</span></code>. \nYou will probably never need to access this.</li>\n<li><code class='syntax js'><span class=\"variable\">preventDefault</span></code>: if the touch is connected with an event, this calls <code class='syntax js'><span class=\"variable\">preventDefault</span>()</code> on the event.</li>\n<li><code class='syntax js'><span class=\"variable\">touchesForView</span>(<span class=\"variable\">view</span>)</code>: when supplied a view, will find all touches that the view is the\ntouch responder for. It is a CoreSet; to get an array, call <code class='syntax js'>.<span class=\"variable\">toArray</span></code> on the result.</li>\n<li><code class='syntax js'><span class=\"variable\">averagedTouchesForView</span>(<span class=\"variable\">view</span>)</code>: When supplied a view, averages all the touches on that view,\nreturning both an average position and an average distance from that position.</li>\n</ul>\n\n<p><strong>Note:</strong> If you call <code class='syntax js'><span class=\"variable\">touchesForView</span>(<span class=\"this\">this</span>)</code> from <code class='syntax js'><span class=\"variable\">touchStart</span></code>, the touch supplied will not be in the set\nreturned by <code class='syntax js'><span class=\"variable\">touchesForView</span>(<span class=\"this\">this</span>)</code>: you don't own the touch until you return YES.</p>\n\n<h2>touchEnd</h2>\n\n<p>Knowing when the touch starts is not very useful. At the very least, you will likely want to know when the touch\nends as well.</p>\n\n<p>It is quite simple:</p>\n\n<pre><code class='syntax js'><span class=\"variable\">touchEnd</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>)\n</code></pre>\n\n<p>It works exactly like <code class='syntax js'><span class=\"variable\">touchStart</span></code>. The touch will no longer be in the set of touches for the view,\nso if you call <code class='syntax js'><span class=\"variable\">touch</span>.<span class=\"variable\">touchesForView</span>(<span class=\"this\">this</span>)</code>, you'll only receive any other active touches. If your\nview does not accept multitouch, then the set is guaranteed to have no touches in it&emdash;you only receive\n<code class='syntax js'><span class=\"variable\">touchEnd</span></code> for the last touch that ends.</p>\n\n<h2>Tracking Touches</h2>\n\n<p>Tracking touch movement is simple:</p>\n\n<pre><code class='syntax js'><span class=\"variable\">touchesDragged</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">evt</span>, <span class=\"variable\">touches</span>)\n</code></pre>\n\n<p>The <code class='syntax js'><span class=\"variable\">touches</span></code> argument is the set of touches on the view&emdash;the same set you get by calling <code class='syntax js'><span class=\"variable\">touchesForView</span>(<span class=\"this\">this</span>)</code>.\nThis will have <em>all</em> touches, regardless of whether or not your view accepts multitouch.</p>\n\n<p>If your view does <em>not</em> accept multitouch, then it is even simpler:</p>\n\n<pre><code class='syntax js'><span class=\"variable\">x</span> = <span class=\"variable\">evt</span>.<span class=\"variable\">pageX</span>;\n<span class=\"variable\">y</span> = <span class=\"variable\">evt</span>.<span class=\"variable\">pageY</span>;\n</code></pre>\n\n<h2>Tip: Cross-Platform-iness</h2>\n\n<p>Did you realize that, assuming you don't use the set of view touches or other touch-specific API,\nyou can do this:</p>\n\n<pre><code class='syntax js'><span class=\"variable\">mouseDown</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">evt</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">touchStart</span>(<span class=\"variable\">evt</span>);\n},\n\n<span class=\"variable\">mouseDragged</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">evt</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">touchesDragged</span>(<span class=\"variable\">evt</span>);\n},\n\n<span class=\"variable\">mouseUp</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">evt</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">touchEnd</span>(<span class=\"variable\">evt</span>);\n}\n</code></pre>\n\n<p>Of course, you can also redirect touch events to mouse events, but that is not as fun.</p>\n\n<h2>Putting it All Together</h2>\n\n<p>Here is a very simple demo that uses the methods described above to allow the user to move two views\naround the screen:</p>\n\n<p><a href='touch-demo.js' class='demo'>touch-demo.js</a></p>","errors":[],"demos":{"touch-demo.js":{"ex":"var Dot = SC.View.extend({\n touchStart: function(touch) {\n var f = this.get(\"frame\");\n this._touch = {\n start: { x: touch.pageX, y: touch.pageY },\n ourStart: { x: f.x, y: f.y, width: f.width, height: f.height }\n };\n return YES; // or we won't get touchesDragged\n },\n \n touchesDragged: function(evt, touches) {\n var t = this._touch;\n this.set(\"layout\", { \n left: t.ourStart.x + evt.pageX - t.start.x,\n top: t.ourStart.y + evt.pageY - t.start.y,\n width: t.ourStart.width,\n height: t.ourStart.height\n });\n },\n \n touchEnd: function() {\n // actually, we don't need to do anything here...\n },\n \n // and now, redirect mouse events :)\n mouseDown: function(evt) {\n this.touchStart(evt);\n },\n \n mouseDragged: function(evt) {\n this.touchesDragged(evt);\n },\n \n mouseUp: function(evt) {\n this.touchEnd(evt);\n }\n});\nvar MyExampleView = SC.View.extend({\n backgroundColor: \"white\",\n childViews: \"dot1 dot2\".w(),\n dot1: Dot.design({\n backgroundColor: \"red\",\n layout: { left: 10, top: 10, width: 100, height: 100 }\n }),\n dot2: Dot.design({\n backgroundColor: \"blue\",\n layout: { right: 10, bottom: 10, width: 100, height: 100 }\n })\n});\n\n// bootstrap code :)\nexports.getDemoView = function() {\n return MyExampleView;\n};\n","highlighted":"<span class=\"keyword\">var</span> <span class=\"class\">Dot</span> = <span class=\"class\">SC</span>.<span class=\"class\">View</span>.<span class=\"variable\">extend</span>({\n <span class=\"variable\">touchStart</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>) {\n <span class=\"keyword\">var</span> <span class=\"variable\">f</span> = <span class=\"this\">this</span>.<span class=\"variable\">get</span>(<span class=\"string\">&quot;frame&quot;</span>);\n <span class=\"this\">this</span>.<span class=\"variable\">_touch</span> = {\n <span class=\"variable\">start</span>: { <span class=\"variable\">x</span>: <span class=\"variable\">touch</span>.<span class=\"variable\">pageX</span>, <span class=\"variable\">y</span>: <span class=\"variable\">touch</span>.<span class=\"variable\">pageY</span> },\n <span class=\"variable\">ourStart</span>: { <span class=\"variable\">x</span>: <span class=\"variable\">f</span>.<span class=\"variable\">x</span>, <span class=\"variable\">y</span>: <span class=\"variable\">f</span>.<span class=\"variable\">y</span>, <span class=\"variable\">width</span>: <span class=\"variable\">f</span>.<span class=\"variable\">width</span>, <span class=\"variable\">height</span>: <span class=\"variable\">f</span>.<span class=\"variable\">height</span> }\n };\n <span class=\"keyword\">return</span> <span class=\"class\">YES</span>; <span class=\"comment\">// or we won't get touchesDragged</span>\n },\n \n <span class=\"variable\">touchesDragged</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">evt</span>, <span class=\"variable\">touches</span>) {\n <span class=\"keyword\">var</span> <span class=\"variable\">t</span> = <span class=\"this\">this</span>.<span class=\"variable\">_touch</span>;\n <span class=\"this\">this</span>.<span class=\"variable\">set</span>(<span class=\"string\">&quot;layout&quot;</span>, { \n <span class=\"variable\">left</span>: <span class=\"variable\">t</span>.<span class=\"variable\">ourStart</span>.<span class=\"variable\">x</span> + <span class=\"variable\">evt</span>.<span class=\"variable\">pageX</span> - <span class=\"variable\">t</span>.<span class=\"variable\">start</span>.<span class=\"variable\">x</span>,\n <span class=\"variable\">top</span>: <span class=\"variable\">t</span>.<span class=\"variable\">ourStart</span>.<span class=\"variable\">y</span> + <span class=\"variable\">evt</span>.<span class=\"variable\">pageY</span> - <span class=\"variable\">t</span>.<span class=\"variable\">start</span>.<span class=\"variable\">y</span>,\n <span class=\"variable\">width</span>: <span class=\"variable\">t</span>.<span class=\"variable\">ourStart</span>.<span class=\"variable\">width</span>,\n <span class=\"variable\">height</span>: <span class=\"variable\">t</span>.<span class=\"variable\">ourStart</span>.<span class=\"variable\">height</span>\n });\n },\n \n <span class=\"variable\">touchEnd</span>: <span class=\"keyword\">function</span>() {\n <span class=\"comment\">// actually, we don't need to do anything here...</span>\n },\n \n <span class=\"comment\">// and now, redirect mouse events :)</span>\n <span class=\"variable\">mouseDown</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">evt</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">touchStart</span>(<span class=\"variable\">evt</span>);\n },\n \n <span class=\"variable\">mouseDragged</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">evt</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">touchesDragged</span>(<span class=\"variable\">evt</span>);\n },\n \n <span class=\"variable\">mouseUp</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">evt</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">touchEnd</span>(<span class=\"variable\">evt</span>);\n }\n});\n<span class=\"keyword\">var</span> <span class=\"class\">MyExampleView</span> = <span class=\"class\">SC</span>.<span class=\"class\">View</span>.<span class=\"variable\">extend</span>({\n <span class=\"variable\">backgroundColor</span>: <span class=\"string\">&quot;white&quot;</span>,\n <span class=\"variable\">childViews</span>: <span class=\"string\">&quot;dot1 dot2&quot;</span>.<span class=\"variable\">w</span>(),\n <span class=\"variable\">dot1</span>: <span class=\"class\">Dot</span>.<span class=\"variable\">design</span>({\n <span class=\"variable\">backgroundColor</span>: <span class=\"string\">&quot;red&quot;</span>,\n <span class=\"variable\">layout</span>: { <span class=\"variable\">left</span>: <span class=\"number integer\">10</span>, <span class=\"variable\">top</span>: <span class=\"number integer\">10</span>, <span class=\"variable\">width</span>: <span class=\"number integer\">100</span>, <span class=\"variable\">height</span>: <span class=\"number integer\">100</span> }\n }),\n <span class=\"variable\">dot2</span>: <span class=\"class\">Dot</span>.<span class=\"variable\">design</span>({\n <span class=\"variable\">backgroundColor</span>: <span class=\"string\">&quot;blue&quot;</span>,\n <span class=\"variable\">layout</span>: { <span class=\"variable\">right</span>: <span class=\"number integer\">10</span>, <span class=\"variable\">bottom</span>: <span class=\"number integer\">10</span>, <span class=\"variable\">width</span>: <span class=\"number integer\">100</span>, <span class=\"variable\">height</span>: <span class=\"number integer\">100</span> }\n })\n});\n\n<span class=\"comment\">// bootstrap code :)</span>\n<span class=\"variable\">exports</span>.<span class=\"variable\">getDemoView</span> = <span class=\"keyword\">function</span>() {\n <span class=\"keyword\">return</span> <span class=\"class\">MyExampleView</span>;\n};\n","original":"var Dot = SC.View.extend({\n touchStart: function(touch) {\n var f = this.get(\"frame\");\n this._touch = {\n start: { x: touch.pageX, y: touch.pageY },\n ourStart: { x: f.x, y: f.y, width: f.width, height: f.height }\n };\n return YES; // or we won't get touchesDragged\n },\n \n touchesDragged: function(evt, touches) {\n var t = this._touch;\n this.set(\"layout\", { \n left: t.ourStart.x + evt.pageX - t.start.x,\n top: t.ourStart.y + evt.pageY - t.start.y,\n width: t.ourStart.width,\n height: t.ourStart.height\n });\n },\n \n touchEnd: function() {\n // actually, we don't need to do anything here...\n },\n \n // and now, redirect mouse events :)\n mouseDown: function(evt) {\n this.touchStart(evt);\n },\n \n mouseDragged: function(evt) {\n this.touchesDragged(evt);\n },\n \n mouseUp: function(evt) {\n this.touchEnd(evt);\n }\n});\nvar MyExampleView = SC.View.extend({\n backgroundColor: \"white\",\n childViews: \"dot1 dot2\".w(),\n dot1: Dot.design({\n backgroundColor: \"red\",\n layout: { left: 10, top: 10, width: 100, height: 100 }\n }),\n dot2: Dot.design({\n backgroundColor: \"blue\",\n layout: { right: 10, bottom: 10, width: 100, height: 100 }\n })\n});\n\n// bootstrap code :)\nexports.getDemoView = function() {\n return MyExampleView;\n};\n"}},"articleDirectory":"articles/touch/","outputDirectory":"build/","title":"Touch Events"},{"content":"<h1>Multitouch</h1>\n\n<p>Handling single touches is pretty easy&emdash;not that much different from handling\nmouse events. But what about multiple touches?</p>\n\n<h2>Accepting Multiple Touches</h2>\n\n<p>First, you have to tell your view that you do, indeed want to receive multiple\ntouches. By default, views only receive single touches. This is because is easier \nto think in a single-touch model, and most controls only need to track a single touch.</p>\n\n<p>To accept multiple touches, just set the view's <code class='syntax js'><span class=\"variable\">acceptsMultitouch</span></code> property to\n<code class='syntax js'><span class=\"class\">YES</span></code>.</p>\n\n<pre><code class='syntax js'><span class=\"variable\">view</span> = <span class=\"class\">SC</span>.<span class=\"class\">View</span>.<span class=\"variable\">extend</span>({\n <span class=\"variable\">acceptsMultitouch</span>: <span class=\"class\">YES</span>\n});\n</code></pre>\n\n<h2>Processing the Individual Touches</h2>\n\n<p>Even without the supplied helper function, processing individual touches is relatively\nsimple:</p>\n\n<ul>\n<li>You get a separate <code class='syntax js'><span class=\"variable\">touchStart</span></code> for each individual touch.</li>\n<li>You get a separate <code class='syntax js'><span class=\"variable\">touchEnd</span></code> for each individual touch.</li>\n<li>You get one <code class='syntax js'><span class=\"variable\">touchesDragged</span></code> each event cycle for all of your touches put together.</li>\n</ul>\n\n<p>So, detecting individual touches starting and ending is simple. Detecting those touches\nmoving is not quite as simple, but still relatively easy.</p>\n\n<p>Remember how <code class='syntax js'><span class=\"variable\">touchesDragged</span></code> works:</p>\n\n<pre><code class='syntax js'><span class=\"variable\">touchesDragged</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">evt</span>, <span class=\"variable\">touches</span>)\n</code></pre>\n\n<p><code class='syntax js'><span class=\"variable\">touches</span></code> is an SC.CoreSet of SC.Touch objects. What can you do with a CoreSet? \nYou can do a couple of things:</p>\n\n<ul>\n<li>Turn it into an array and do whatever.</li>\n<li>Call .forEach to iterate.</li>\n</ul>\n\n<p>But you don't have to use the touches set at all. The <code class='syntax js'><span class=\"variable\">evt</span></code> has some useful properties and methods,\ntoo:</p>\n\n<ul>\n<li>pageX/pageY: the position of the first touch.</li>\n<li>averagedTouchesForView: a method which returns the averaged touch position\nand the average distance of the touches from that position.</li>\n</ul>\n\n<p><code class='syntax js'><span class=\"class\">SC</span>.<span class=\"class\">ScrollView</span></code>, for instance, makes heavy use of <code class='syntax js'><span class=\"variable\">averagedTouchesForView</span></code>, and never\ndirectly touches the <code class='syntax js'><span class=\"variable\">touches</span></code> set.</p>\n\n<h2>Averaging Touches</h2>\n\n<p>It is often <em>very</em> useful to average the touches. </p>\n\n<p><code class='syntax js'><span class=\"variable\">averagedTouchesForView</span></code> returns an object with four properties:</p>\n\n<ul>\n<li><strong><code class='syntax js'><span class=\"variable\">x</span></code></strong>: The average X position of the touch.</li>\n<li><strong><code class='syntax js'><span class=\"variable\">y</span></code></strong>: The average Y position of the touch.</li>\n<li><strong><code class='syntax js'><span class=\"variable\">d</span></code></strong>: average distance of the all touches from the average x/y position.</li>\n<li><strong><code class='syntax js'><span class=\"variable\">touchCount</span></code></strong> The number of touches averaged.</li>\n</ul>\n\n<p>You can call <code class='syntax js'><span class=\"variable\">averagedTouchesForView</span></code> on two separate objects: an <code class='syntax js'><span class=\"class\">SC</span>.<span class=\"class\">Event</span></code> object,\nor an <code class='syntax js'><span class=\"class\">SC</span>.<span class=\"class\">Touch</span></code> object.</p>\n\n<p>The two work identically but for one important difference: when you call it on <code class='syntax js'><span class=\"class\">SC</span>.<span class=\"class\">Touch</span></code>,\nyou <em>have the option</em> of telling the touch to add itself to the averaged set. Doing so makes no sense\nin most cases: the touch would just be counted twice! But what about <code class='syntax js'><span class=\"variable\">touchStart</span></code>?</p>\n\n<p>Recall that during <code class='syntax js'><span class=\"variable\">touchStart</span></code>, the view does not yet own the touch. So, <code class='syntax js'><span class=\"variable\">averagedTouchesForView</span></code>\nwould not, by default count it.</p>\n\n<pre><code class='syntax js'><span class=\"comment\">// on an event:</span>\n<span class=\"keyword\">var</span> <span class=\"variable\">a</span> = <span class=\"variable\">evt</span>.<span class=\"variable\">averagedTouchesForView</span>(<span class=\"this\">this</span>);\n\n<span class=\"comment\">// on a touch</span>\n<span class=\"keyword\">var</span> <span class=\"variable\">a</span> = <span class=\"variable\">touch</span>.<span class=\"variable\">averagedTouchesForView</span>(<span class=\"this\">this</span>);\n\n<span class=\"comment\">// on a touch, counting the touch itself</span>\n<span class=\"keyword\">var</span> <span class=\"variable\">a</span> = <span class=\"variable\">touch</span>.<span class=\"variable\">averagedTouchesForView</span>(<span class=\"this\">this</span>, <span class=\"class\">YES</span>);\n</code></pre>\n\n<h2>Thinking it Over</h2>\n\n<p>How might you use all of these to produce a good result?</p>\n\n<p>Let's take a simple example: moving and resizing something:</p>\n\n<p><a href='multitouch.js' class='demo'>multitouch.js</a></p>","errors":[],"demos":{"multitouch.js":{"ex":"var Box = SC.View.extend({\n _scale: 1,\n _translateX: 0,\n _translateY: 0,\n acceptsMultitouch: YES,\n touchStart: function(touch) {\n this.recomputeTouchStatus(touch, YES);\n return YES;\n },\n \n touchesDragged: function(evt, touches) {\n var t = this._touch;\n var avg = evt.averagedTouchesForView(this);\n \n // translation is easy:\n this._translateX = t.ourStart.x + avg.x - t.start.x;\n this._translateY = t.ourStart.y + avg.y - t.start.y;\n \n // mathematically speaking, scale *= the end distance / the start distance\n if (t.start.d > 1) { // but prevent divide-by-0\n this._scale = t.ourStart.scale * (avg.d / t.start.d);\n }\n \n // reposition\n this._reposition();\n },\n \n touchEnd: function(touch) {\n this.recomputeTouchStatus(touch, NO);\n },\n \n /**\n With this, we recompute our touch status--updating the start positioning and scale.\n */\n recomputeTouchStatus: function(touch, considerTouch) {\n var avg = touch.averagedTouchesForView(this, considerTouch);\n this._touch = {\n start: { x: avg.x, y: avg.y, d: avg.d },\n ourStart: { x: this._translateX, y: this._translateY, scale: this._scale }\n };\n },\n \n /**\n Repositions the view.\n */\n _reposition: function() {\n this.get(\"layer\").style.webkitTransform = \n \"translate3d(\" + this._translateX + \"px,\" + this._translateY + \"px, 0px) \" +\n \"scale3d(\" + this._scale + \",\" + this._scale + \",1)\";\n console.error(this._translateX + \" \" + this._translateY + \" \" + this._scale);\n },\n \n // and now, redirect mouse events :)\n mouseDown: function(evt) {\n this.touchStart(evt);\n },\n \n mouseDragged: function(evt) {\n this.touchesDragged(evt);\n },\n \n mouseUp: function(evt) {\n this.touchEnd(evt);\n }\n});\nvar MyExampleView = SC.View.extend({\n backgroundColor: \"white\",\n childViews: \"box\".w(),\n box: Box.design({\n backgroundColor: \"red\",\n layout: { left: 10, top: 10, width: 200, height: 200 }\n })\n});\n\n// bootstrap code :)\nexports.getDemoView = function() {\n return MyExampleView;\n};\n","highlighted":"<span class=\"keyword\">var</span> <span class=\"class\">Box</span> = <span class=\"class\">SC</span>.<span class=\"class\">View</span>.<span class=\"variable\">extend</span>({\n <span class=\"variable\">_scale</span>: <span class=\"number integer\">1</span>,\n <span class=\"variable\">_translateX</span>: <span class=\"number integer\">0</span>,\n <span class=\"variable\">_translateY</span>: <span class=\"number integer\">0</span>,\n <span class=\"variable\">acceptsMultitouch</span>: <span class=\"class\">YES</span>,\n <span class=\"variable\">touchStart</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">recomputeTouchStatus</span>(<span class=\"variable\">touch</span>, <span class=\"class\">YES</span>);\n <span class=\"keyword\">return</span> <span class=\"class\">YES</span>;\n },\n \n <span class=\"variable\">touchesDragged</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">evt</span>, <span class=\"variable\">touches</span>) {\n <span class=\"keyword\">var</span> <span class=\"variable\">t</span> = <span class=\"this\">this</span>.<span class=\"variable\">_touch</span>;\n <span class=\"keyword\">var</span> <span class=\"variable\">avg</span> = <span class=\"variable\">evt</span>.<span class=\"variable\">averagedTouchesForView</span>(<span class=\"this\">this</span>);\n \n <span class=\"comment\">// translation is easy:</span>\n <span class=\"this\">this</span>.<span class=\"variable\">_translateX</span> = <span class=\"variable\">t</span>.<span class=\"variable\">ourStart</span>.<span class=\"variable\">x</span> + <span class=\"variable\">avg</span>.<span class=\"variable\">x</span> - <span class=\"variable\">t</span>.<span class=\"variable\">start</span>.<span class=\"variable\">x</span>;\n <span class=\"this\">this</span>.<span class=\"variable\">_translateY</span> = <span class=\"variable\">t</span>.<span class=\"variable\">ourStart</span>.<span class=\"variable\">y</span> + <span class=\"variable\">avg</span>.<span class=\"variable\">y</span> - <span class=\"variable\">t</span>.<span class=\"variable\">start</span>.<span class=\"variable\">y</span>;\n \n <span class=\"comment\">// mathematically speaking, scale *= the end distance / the start distance</span>\n <span class=\"keyword\">if</span> (<span class=\"variable\">t</span>.<span class=\"variable\">start</span>.<span class=\"variable\">d</span> &gt; <span class=\"number integer\">1</span>) { <span class=\"comment\">// but prevent divide-by-0</span>\n <span class=\"this\">this</span>.<span class=\"variable\">_scale</span> = <span class=\"variable\">t</span>.<span class=\"variable\">ourStart</span>.<span class=\"variable\">scale</span> * (<span class=\"variable\">avg</span>.<span class=\"variable\">d</span> / <span class=\"variable\">t</span>.<span class=\"variable\">start</span>.<span class=\"variable\">d</span>);\n }\n \n <span class=\"comment\">// reposition</span>\n <span class=\"this\">this</span>.<span class=\"variable\">_reposition</span>();\n },\n \n <span class=\"variable\">touchEnd</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">recomputeTouchStatus</span>(<span class=\"variable\">touch</span>, <span class=\"class\">NO</span>);\n },\n \n <span class=\"multiline comment\">/**\n With this, we recompute our touch status--updating the start positioning and scale.\n */</span>\n <span class=\"variable\">recomputeTouchStatus</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>, <span class=\"variable\">considerTouch</span>) {\n <span class=\"keyword\">var</span> <span class=\"variable\">avg</span> = <span class=\"variable\">touch</span>.<span class=\"variable\">averagedTouchesForView</span>(<span class=\"this\">this</span>, <span class=\"variable\">considerTouch</span>);\n <span class=\"this\">this</span>.<span class=\"variable\">_touch</span> = {\n <span class=\"variable\">start</span>: { <span class=\"variable\">x</span>: <span class=\"variable\">avg</span>.<span class=\"variable\">x</span>, <span class=\"variable\">y</span>: <span class=\"variable\">avg</span>.<span class=\"variable\">y</span>, <span class=\"variable\">d</span>: <span class=\"variable\">avg</span>.<span class=\"variable\">d</span> },\n <span class=\"variable\">ourStart</span>: { <span class=\"variable\">x</span>: <span class=\"this\">this</span>.<span class=\"variable\">_translateX</span>, <span class=\"variable\">y</span>: <span class=\"this\">this</span>.<span class=\"variable\">_translateY</span>, <span class=\"variable\">scale</span>: <span class=\"this\">this</span>.<span class=\"variable\">_scale</span> }\n };\n },\n \n <span class=\"multiline comment\">/**\n Repositions the view.\n */</span>\n <span class=\"variable\">_reposition</span>: <span class=\"keyword\">function</span>() {\n <span class=\"this\">this</span>.<span class=\"variable\">get</span>(<span class=\"string\">&quot;layer&quot;</span>).<span class=\"variable\">style</span>.<span class=\"variable\">webkitTransform</span> = \n <span class=\"string\">&quot;translate3d(&quot;</span> + <span class=\"this\">this</span>.<span class=\"variable\">_translateX</span> + <span class=\"string\">&quot;px,&quot;</span> + <span class=\"this\">this</span>.<span class=\"variable\">_translateY</span> + <span class=\"string\">&quot;px, 0px) &quot;</span> +\n <span class=\"string\">&quot;scale3d(&quot;</span> + <span class=\"this\">this</span>.<span class=\"variable\">_scale</span> + <span class=\"string\">&quot;,&quot;</span> + <span class=\"this\">this</span>.<span class=\"variable\">_scale</span> + <span class=\"string\">&quot;,1)&quot;</span>;\n <span class=\"variable\">console</span>.<span class=\"variable\">error</span>(<span class=\"this\">this</span>.<span class=\"variable\">_translateX</span> + <span class=\"string\">&quot; &quot;</span> + <span class=\"this\">this</span>.<span class=\"variable\">_translateY</span> + <span class=\"string\">&quot; &quot;</span> + <span class=\"this\">this</span>.<span class=\"variable\">_scale</span>);\n },\n \n <span class=\"comment\">// and now, redirect mouse events :)</span>\n <span class=\"variable\">mouseDown</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">evt</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">touchStart</span>(<span class=\"variable\">evt</span>);\n },\n \n <span class=\"variable\">mouseDragged</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">evt</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">touchesDragged</span>(<span class=\"variable\">evt</span>);\n },\n \n <span class=\"variable\">mouseUp</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">evt</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">touchEnd</span>(<span class=\"variable\">evt</span>);\n }\n});\n<span class=\"keyword\">var</span> <span class=\"class\">MyExampleView</span> = <span class=\"class\">SC</span>.<span class=\"class\">View</span>.<span class=\"variable\">extend</span>({\n <span class=\"variable\">backgroundColor</span>: <span class=\"string\">&quot;white&quot;</span>,\n <span class=\"variable\">childViews</span>: <span class=\"string\">&quot;box&quot;</span>.<span class=\"variable\">w</span>(),\n <span class=\"variable\">box</span>: <span class=\"class\">Box</span>.<span class=\"variable\">design</span>({\n <span class=\"variable\">backgroundColor</span>: <span class=\"string\">&quot;red&quot;</span>,\n <span class=\"variable\">layout</span>: { <span class=\"variable\">left</span>: <span class=\"number integer\">10</span>, <span class=\"variable\">top</span>: <span class=\"number integer\">10</span>, <span class=\"variable\">width</span>: <span class=\"number integer\">200</span>, <span class=\"variable\">height</span>: <span class=\"number integer\">200</span> }\n })\n});\n\n<span class=\"comment\">// bootstrap code :)</span>\n<span class=\"variable\">exports</span>.<span class=\"variable\">getDemoView</span> = <span class=\"keyword\">function</span>() {\n <span class=\"keyword\">return</span> <span class=\"class\">MyExampleView</span>;\n};\n","original":"var Box = SC.View.extend({\n _scale: 1,\n _translateX: 0,\n _translateY: 0,\n acceptsMultitouch: YES,\n touchStart: function(touch) {\n this.recomputeTouchStatus(touch, YES);\n return YES;\n },\n \n touchesDragged: function(evt, touches) {\n var t = this._touch;\n var avg = evt.averagedTouchesForView(this);\n \n // translation is easy:\n this._translateX = t.ourStart.x + avg.x - t.start.x;\n this._translateY = t.ourStart.y + avg.y - t.start.y;\n \n // mathematically speaking, scale *= the end distance / the start distance\n if (t.start.d > 1) { // but prevent divide-by-0\n this._scale = t.ourStart.scale * (avg.d / t.start.d);\n }\n \n // reposition\n this._reposition();\n },\n \n touchEnd: function(touch) {\n this.recomputeTouchStatus(touch, NO);\n },\n \n /**\n With this, we recompute our touch status--updating the start positioning and scale.\n */\n recomputeTouchStatus: function(touch, considerTouch) {\n var avg = touch.averagedTouchesForView(this, considerTouch);\n this._touch = {\n start: { x: avg.x, y: avg.y, d: avg.d },\n ourStart: { x: this._translateX, y: this._translateY, scale: this._scale }\n };\n },\n \n /**\n Repositions the view.\n */\n _reposition: function() {\n this.get(\"layer\").style.webkitTransform = \n \"translate3d(\" + this._translateX + \"px,\" + this._translateY + \"px, 0px) \" +\n \"scale3d(\" + this._scale + \",\" + this._scale + \",1)\";\n console.error(this._translateX + \" \" + this._translateY + \" \" + this._scale);\n },\n \n // and now, redirect mouse events :)\n mouseDown: function(evt) {\n this.touchStart(evt);\n },\n \n mouseDragged: function(evt) {\n this.touchesDragged(evt);\n },\n \n mouseUp: function(evt) {\n this.touchEnd(evt);\n }\n});\nvar MyExampleView = SC.View.extend({\n backgroundColor: \"white\",\n childViews: \"box\".w(),\n box: Box.design({\n backgroundColor: \"red\",\n layout: { left: 10, top: 10, width: 200, height: 200 }\n })\n});\n\n// bootstrap code :)\nexports.getDemoView = function() {\n return MyExampleView;\n};\n"}},"articleDirectory":"articles/touch/","outputDirectory":"build/","title":"Multitouch"}]},{"title":"Built-In Support","articles":[{"content":"<h1>ButtonView Touch Support</h1>\n\n<p>ButtonView currently supports only a single touch (any other touches will be ignored). \nThis is fine: why would you want to consider two touches in a button press?</p>\n\n<p>However, it does not simply relay the touches to <code class='syntax js'><span class=\"variable\">mouseDown</span></code> and <code class='syntax js'><span class=\"variable\">mouseUp</span></code>.</p>\n\n<p>Instead, it calculates the distance of the main touch (<code class='syntax js'><span class=\"variable\">evt</span></code>'s <code class='syntax js'><span class=\"variable\">pageX</span></code> and <code class='syntax js'><span class=\"variable\">pageY</span></code>)\nfrom the button itself. This makes it easier to for a user to press a button while, for instance,\nmoving their finger.</p>\n\n<p>This is all done for you automatically. Here's a simple demo:\n<a href='touch-button.js' class='demo'>touch-button.js</a></p>\n\n<h2>Ace 2.0</h2>\n\n<p>Ace 2.0 supports several button sizes. In addition, it is capable of <em>automatically picking</em>\na size based on the size of your control. And best of all, it <em>centers</em> the button image\nvertically in the space you allocate. This allows you to, for instance, make a button 44px\ntall, but have the image only be 30px.</p>\n\n<p>You may use these options for <code class='syntax js'><span class=\"variable\">controlSize</span></code>:</p>\n\n<ul>\n<li>SC.SMALL_CONTROL_SIZE. 18px.</li>\n<li>SC.REGULAR_CONTROL_SIZE. 24px.</li>\n<li>SC.HUGE_CONTROL_SIZE. 30px.</li>\n<li>SC.JUMBO_CONTROL_SIZE. 44px.</li>\n<li>SC.AUTO_CONTROL_SIZE. Automatically figures a control size (largest that will fit), but\nthrows a warning if you don't have \"height\" set and it has to calculate the size.</li>\n<li>SC.CALCULATED_CONTROL_SIZE. Like AUTO_CONTROL_SIZE, but calculates it.</li>\n</ul>\n\n<p><a href='button-size.js' class='demo'>button-size.js</a></p>","errors":[],"demos":{"touch-button.js":{"ex":"var MyExampleView = SC.View.extend({\n backgroundColor: \"white\",\n childViews: \"button\".w(),\n button: SC.ButtonView.design({\n layout: { centerX: 0, centerY: 0, width: 200, height: 44 },\n title: \"Tap Here :)\",\n controlSize: SC.AUTO_CONTROL_SIZE\n })\n});\n\n// bootstrap code :)\nexports.getDemoView = function() {\n return MyExampleView;\n};\n","highlighted":"<span class=\"keyword\">var</span> <span class=\"class\">MyExampleView</span> = <span class=\"class\">SC</span>.<span class=\"class\">View</span>.<span class=\"variable\">extend</span>({\n <span class=\"variable\">backgroundColor</span>: <span class=\"string\">&quot;white&quot;</span>,\n <span class=\"variable\">childViews</span>: <span class=\"string\">&quot;button&quot;</span>.<span class=\"variable\">w</span>(),\n <span class=\"variable\">button</span>: <span class=\"class\">SC</span>.<span class=\"class\">ButtonView</span>.<span class=\"variable\">design</span>({\n <span class=\"variable\">layout</span>: { <span class=\"variable\">centerX</span>: <span class=\"number integer\">0</span>, <span class=\"variable\">centerY</span>: <span class=\"number integer\">0</span>, <span class=\"variable\">width</span>: <span class=\"number integer\">200</span>, <span class=\"variable\">height</span>: <span class=\"number integer\">44</span> },\n <span class=\"variable\">title</span>: <span class=\"string\">&quot;Tap Here :)&quot;</span>,\n <span class=\"variable\">controlSize</span>: <span class=\"class\">SC</span>.<span class=\"class\">AUTO_CONTROL_SIZE</span>\n })\n});\n\n<span class=\"comment\">// bootstrap code :)</span>\n<span class=\"variable\">exports</span>.<span class=\"variable\">getDemoView</span> = <span class=\"keyword\">function</span>() {\n <span class=\"keyword\">return</span> <span class=\"class\">MyExampleView</span>;\n};\n","original":"var MyExampleView = SC.View.extend({\n backgroundColor: \"white\",\n childViews: \"button\".w(),\n button: SC.ButtonView.design({\n layout: { centerX: 0, centerY: 0, width: 200, height: 44 },\n title: \"Tap Here :)\",\n controlSize: SC.AUTO_CONTROL_SIZE\n })\n});\n\n// bootstrap code :)\nexports.getDemoView = function() {\n return MyExampleView;\n};\n"},"button-size.js":{"ex":"var MyExampleView = SC.View.extend({\n backgroundColor: \"white\",\n childViews: \"form\".w(),\n \n form: SC.FormView.design({\n layout: {centerX: 0, centerY: 0, width: 400, height: 300 },\n childViews: \"small regular huge jumbo\".w(),\n small: SC.FormView.row(SC.ButtonView.design({\n layout: { width: 100, height: 18 },\n title: \"I'm TINY!\",\n controlSize: SC.SMALL_CONTROL_SIZE\n })),\n \n regular: SC.FormView.row(SC.ButtonView.design({\n layout: { width: 100, height: 24 },\n title: \"I'm Normal!\",\n controlSize: SC.REGULAR_CONTROL_SIZE\n })),\n \n huge: SC.FormView.row(SC.ButtonView.design({\n layout: { width: 100, height: 30 },\n title: \"I'm huge.\",\n controlSize: SC.HUGE_CONTROL_SIZE\n })),\n \n jumbo: SC.FormView.row(SC.ButtonView.design({\n layout: { width: 150, height: 44 },\n title: \"i'm jumbo.\",\n controlSize: SC.JUMBO_CONTROL_SIZE\n }))\n \n \n })\n});\n\n// bootstrap code :)\nexports.getDemoView = function() {\n return MyExampleView;\n};\n","highlighted":"<span class=\"keyword\">var</span> <span class=\"class\">MyExampleView</span> = <span class=\"class\">SC</span>.<span class=\"class\">View</span>.<span class=\"variable\">extend</span>({\n <span class=\"variable\">backgroundColor</span>: <span class=\"string\">&quot;white&quot;</span>,\n <span class=\"variable\">childViews</span>: <span class=\"string\">&quot;form&quot;</span>.<span class=\"variable\">w</span>(),\n \n <span class=\"variable\">form</span>: <span class=\"class\">SC</span>.<span class=\"class\">FormView</span>.<span class=\"variable\">design</span>({\n <span class=\"variable\">layout</span>: {<span class=\"variable\">centerX</span>: <span class=\"number integer\">0</span>, <span class=\"variable\">centerY</span>: <span class=\"number integer\">0</span>, <span class=\"variable\">width</span>: <span class=\"number integer\">400</span>, <span class=\"variable\">height</span>: <span class=\"number integer\">300</span> },\n <span class=\"variable\">childViews</span>: <span class=\"string\">&quot;small regular huge jumbo&quot;</span>.<span class=\"variable\">w</span>(),\n <span class=\"variable\">small</span>: <span class=\"class\">SC</span>.<span class=\"class\">FormView</span>.<span class=\"variable\">row</span>(<span class=\"class\">SC</span>.<span class=\"class\">ButtonView</span>.<span class=\"variable\">design</span>({\n <span class=\"variable\">layout</span>: { <span class=\"variable\">width</span>: <span class=\"number integer\">100</span>, <span class=\"variable\">height</span>: <span class=\"number integer\">18</span> },\n <span class=\"variable\">title</span>: <span class=\"string\">&quot;I'm TINY!&quot;</span>,\n <span class=\"variable\">controlSize</span>: <span class=\"class\">SC</span>.<span class=\"class\">SMALL_CONTROL_SIZE</span>\n })),\n \n <span class=\"variable\">regular</span>: <span class=\"class\">SC</span>.<span class=\"class\">FormView</span>.<span class=\"variable\">row</span>(<span class=\"class\">SC</span>.<span class=\"class\">ButtonView</span>.<span class=\"variable\">design</span>({\n <span class=\"variable\">layout</span>: { <span class=\"variable\">width</span>: <span class=\"number integer\">100</span>, <span class=\"variable\">height</span>: <span class=\"number integer\">24</span> },\n <span class=\"variable\">title</span>: <span class=\"string\">&quot;I'm Normal!&quot;</span>,\n <span class=\"variable\">controlSize</span>: <span class=\"class\">SC</span>.<span class=\"class\">REGULAR_CONTROL_SIZE</span>\n })),\n \n <span class=\"variable\">huge</span>: <span class=\"class\">SC</span>.<span class=\"class\">FormView</span>.<span class=\"variable\">row</span>(<span class=\"class\">SC</span>.<span class=\"class\">ButtonView</span>.<span class=\"variable\">design</span>({\n <span class=\"variable\">layout</span>: { <span class=\"variable\">width</span>: <span class=\"number integer\">100</span>, <span class=\"variable\">height</span>: <span class=\"number integer\">30</span> },\n <span class=\"variable\">title</span>: <span class=\"string\">&quot;I'm huge.&quot;</span>,\n <span class=\"variable\">controlSize</span>: <span class=\"class\">SC</span>.<span class=\"class\">HUGE_CONTROL_SIZE</span>\n })),\n \n <span class=\"variable\">jumbo</span>: <span class=\"class\">SC</span>.<span class=\"class\">FormView</span>.<span class=\"variable\">row</span>(<span class=\"class\">SC</span>.<span class=\"class\">ButtonView</span>.<span class=\"variable\">design</span>({\n <span class=\"variable\">layout</span>: { <span class=\"variable\">width</span>: <span class=\"number integer\">150</span>, <span class=\"variable\">height</span>: <span class=\"number integer\">44</span> },\n <span class=\"variable\">title</span>: <span class=\"string\">&quot;i'm jumbo.&quot;</span>,\n <span class=\"variable\">controlSize</span>: <span class=\"class\">SC</span>.<span class=\"class\">JUMBO_CONTROL_SIZE</span>\n }))\n \n \n })\n});\n\n<span class=\"comment\">// bootstrap code :)</span>\n<span class=\"variable\">exports</span>.<span class=\"variable\">getDemoView</span> = <span class=\"keyword\">function</span>() {\n <span class=\"keyword\">return</span> <span class=\"class\">MyExampleView</span>;\n};\n","original":"var MyExampleView = SC.View.extend({\n backgroundColor: \"white\",\n childViews: \"form\".w(),\n \n form: SC.FormView.design({\n layout: {centerX: 0, centerY: 0, width: 400, height: 300 },\n childViews: \"small regular huge jumbo\".w(),\n small: SC.FormView.row(SC.ButtonView.design({\n layout: { width: 100, height: 18 },\n title: \"I'm TINY!\",\n controlSize: SC.SMALL_CONTROL_SIZE\n })),\n \n regular: SC.FormView.row(SC.ButtonView.design({\n layout: { width: 100, height: 24 },\n title: \"I'm Normal!\",\n controlSize: SC.REGULAR_CONTROL_SIZE\n })),\n \n huge: SC.FormView.row(SC.ButtonView.design({\n layout: { width: 100, height: 30 },\n title: \"I'm huge.\",\n controlSize: SC.HUGE_CONTROL_SIZE\n })),\n \n jumbo: SC.FormView.row(SC.ButtonView.design({\n layout: { width: 150, height: 44 },\n title: \"i'm jumbo.\",\n controlSize: SC.JUMBO_CONTROL_SIZE\n }))\n \n \n })\n});\n\n// bootstrap code :)\nexports.getDemoView = function() {\n return MyExampleView;\n};\n"}},"articleDirectory":"articles/controls/button/","outputDirectory":"build/","title":"ButtonView Touch Support"},{"content":"<h1>ScrollView Touch Support</h1>\n\n<p>SproutCore's ScrollView comes with built-in support for touch-based\nscrolling, including momentum and bouncing. In addition, it has (somewhat experimental)\nsupport for scaling.</p>\n\n<p>For many cases, just putting a view inside a ScrollView will \"just work\". Still, you may want\nto set some settings.</p>\n\n<h2>Bouncing</h2>\n\n<p>By default, ScrollView will <em>always</em> bounce when scrolling vertically, regardless of the\ncontent's height, but only bounce horizontally <em>if</em> the content is wider than the ScrollView.\nThis is controlled by two properties:</p>\n\n<ul>\n<li>alwaysBounceHorizontal, which defaults to NO.</li>\n<li>alwaysBounceVertical, which defaults to YES.</li>\n</ul>\n\n<h2>Scaling</h2>\n\n<p>ScrollView has support for scaling, which you can use through a few properties:</p>\n\n<ul>\n<li>canScale. Specifies whether the content may be scaled. If YES, using two fingers\n(in that classic \"pinch gesture\") will zoom the content.</li>\n<li>minimumScale: The minimum scale value. Default: 0.25.</li>\n<li>maximumScale: The maximum scale value. Default: 2.0.</li>\n</ul>\n\n<p><a href='touch.js' class='demo'>touch.js</a></p>","errors":[],"demos":{"touch.js":{"ex":"/*globals Hedwig*/\nvar MyExampleView = SC.ScrollView.extend({\n horizontalAlign: SC.ALIGN_CENTER,\n verticalAlign: SC.ALIGN_MIDDLE,\n backgroundColor: \"#555\",\n \n canScale: YES,\n alwaysBounceVertical: NO,\n \n contentView: SC.ImageView.design({\n layout: { left: 0, top: 0, width: 1357, height: 2048 },\n value: Hedwig.SAMPLE_IMAGE\n })\n});\n\n// bootstrap code :)\nexports.getDemoView = function() {\n return MyExampleView;\n};\n","highlighted":"<span class=\"multiline comment\">/*globals Hedwig*/</span>\n<span class=\"keyword\">var</span> <span class=\"class\">MyExampleView</span> = <span class=\"class\">SC</span>.<span class=\"class\">ScrollView</span>.<span class=\"variable\">extend</span>({\n <span class=\"variable\">horizontalAlign</span>: <span class=\"class\">SC</span>.<span class=\"class\">ALIGN_CENTER</span>,\n <span class=\"variable\">verticalAlign</span>: <span class=\"class\">SC</span>.<span class=\"class\">ALIGN_MIDDLE</span>,\n <span class=\"variable\">backgroundColor</span>: <span class=\"string\">&quot;#555&quot;</span>,\n \n <span class=\"variable\">canScale</span>: <span class=\"class\">YES</span>,\n <span class=\"variable\">alwaysBounceVertical</span>: <span class=\"class\">NO</span>,\n \n <span class=\"variable\">contentView</span>: <span class=\"class\">SC</span>.<span class=\"class\">ImageView</span>.<span class=\"variable\">design</span>({\n <span class=\"variable\">layout</span>: { <span class=\"variable\">left</span>: <span class=\"number integer\">0</span>, <span class=\"variable\">top</span>: <span class=\"number integer\">0</span>, <span class=\"variable\">width</span>: <span class=\"number integer\">1357</span>, <span class=\"variable\">height</span>: <span class=\"number integer\">2048</span> },\n <span class=\"variable\">value</span>: <span class=\"class\">Hedwig</span>.<span class=\"class\">SAMPLE_IMAGE</span>\n })\n});\n\n<span class=\"comment\">// bootstrap code :)</span>\n<span class=\"variable\">exports</span>.<span class=\"variable\">getDemoView</span> = <span class=\"keyword\">function</span>() {\n <span class=\"keyword\">return</span> <span class=\"class\">MyExampleView</span>;\n};\n","original":"/*globals Hedwig*/\nvar MyExampleView = SC.ScrollView.extend({\n horizontalAlign: SC.ALIGN_CENTER,\n verticalAlign: SC.ALIGN_MIDDLE,\n backgroundColor: \"#555\",\n \n canScale: YES,\n alwaysBounceVertical: NO,\n \n contentView: SC.ImageView.design({\n layout: { left: 0, top: 0, width: 1357, height: 2048 },\n value: Hedwig.SAMPLE_IMAGE\n })\n});\n\n// bootstrap code :)\nexports.getDemoView = function() {\n return MyExampleView;\n};\n"}},"articleDirectory":"articles/controls/scroll/","outputDirectory":"build/","title":"ScrollView Touch Support"}]},{"title":"Advanced Concepts","articles":[{"content":"<h1>Capturing</h1>\n\n<p>There are many instances where you may have to capture touches. We'll consider scroll views,\nhowever, because it is very easy to explain <em>why</em> they need to be able to.</p>\n\n<p>If you are implementing a scroll view, you'll need to capture the touch before the target view gets it.</p>\n\n<p>This is because scroll views have some subtle quirks. For instance, a touch should not pass\nthrough to the actual target until a split-second has passed&emdash;this is to prevent flicker should\nthe user decide to scroll rather than touch the target. Also, it needs to add itself to what is\ncalled the \"touch responder stack\" <em>before</em> the target view, so that the target view can hand control back\nsimply as discussed above.</p>\n\n<h2>Touch Responder Stack</h2>\n\n<p>Very briefly mentioned in the \"Touch Events\" article, the <em>touch responder</em> is the view which\n\"owns\" a touch&emdash;the view which gets all touchesDragged events and the touchEnd for that touch.</p>\n\n<p>However, in our scroll view case, we want to pass control to the target view, but allow it\nto <em>transfer control back</em> (a process covered in \"Releasing\"). That means it needs to know\nwhat view to hand it back to. Also, what if you had a scroll view <em>within</em> a scroll view?</p>\n\n<p>To solve these issues, there is a \"stack\" of those views to which control can be passed back to.</p>\n\n<p>You generally work with it by either:</p>\n\n<ul>\n<li>Specifically telling it to \"stack\" your view when capturing a touch.</li>\n<li>Telling it to change touch responder to a touch responder in the stack (see Releasing)</li>\n</ul>\n\n<h2>Capturing</h2>\n\n<p>Capturing the touch is simple. Before starting at the target view and working its\nway up to the root calling touchStart (the same way all SproutCore events work), \nSproutCore's touch events go the opposite direction, starting at the root and working their way down\nto the target, calling a method named captureTouch:</p>\n\n<pre><code class='syntax js'><span class=\"variable\">captureTouch</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>) {\n</code></pre>\n\n<p>If the view returns YES, the touchStart event will be sent directly to it.</p>\n\n<p>You could then use invokeLater to wait that split-second. But then what? You don't actually\nknow what the target view should be. What you need is to start at the original target, and\ndo the whole working up to it calling captureTouch and work down from it calling touchStart\nthing&emdash;but this time, starting from your own view, rather than the root. </p>\n\n<p>Thankfully, you can do this in one line of code:</p>\n\n<pre><code class='syntax js'><span class=\"variable\">touch</span>.<span class=\"variable\">captureTouch</span>(<span class=\"this\">this</span>, <span class=\"class\">YES</span>); <span class=\"comment\">// the YES means stack, which I'm guessing you'd want to do</span>\n<span class=\"comment\">// so that the new view can easily pass control back to this...</span>\n<span class=\"comment\">// ... but you may know better than me.</span>\n</code></pre>\n\n<p>What happens next depends on whether or not you told it to stack your view:</p>\n\n<ul>\n<li>If stacked, you will receive a touchCancelled when the touch actually ends, unless the\nview which captures the touch hands control back to your view. If it does, you will <em>not</em>\nreceive another <code class='syntax js'><span class=\"variable\">touchStart</span></code>, but you <em>will</em> start receiving <code class='syntax js'><span class=\"variable\">touchesDragged</span></code> and \nwill receive a <code class='syntax js'><span class=\"variable\">touchEnd</span></code> when the touch ends.</li>\n<li>If not stacked, your view will receive <code class='syntax js'><span class=\"variable\">touchCancelled</span></code>.</li>\n</ul>\n\n<h2>What Does It Look Like?</h2>\n\n<p>In this example, we have two boxes, each containing an inner box. The outer boxes\ncapture touches, and only pass them to the inner box after a delay. The top box stacks,\nthe other one does not; this causes, as described above, a difference in when touchEnd/Cancelled\nis called on the outer boxes.</p>\n\n<p><a href='capturing.js' class='demo'>capturing.js</a></p>","errors":[],"demos":{"capturing.js":{"ex":"/**\n This is our test view. It will capture a touch, and, after one second,\n pass it through to the child view. Depending on the shouldStack property,\n it will stack while passing.\n \n In this example, the top view stacks, the bottom one does not.\n*/\nvar Tester = SC.View.extend({\n backgroundColor: \"white\",\n \n shouldStack: NO,\n captureTouch: function() {\n return YES;\n },\n \n touchStart: function(touch) {\n this._hasTouch = touch;\n this.get(\"layer\").style.backgroundColor = \"red\";\n \n // in one second, we'll pass the touch along.\n this.invokeLater(\"beginContentTouches\", 1000, touch);\n return YES;\n },\n \n beginContentTouches: function(touch) {\n // if our touch hasn't changed in the meantime\n if (touch === this._hasTouch) {\n // we'll pass the touch along.\n touch.captureTouch(this, this.get(\"shouldStack\"));\n }\n },\n \n touchEnd: function(touch) {\n this._hasTouch = NO;\n this.get(\"layer\").style.backgroundColor = \"white\";\n },\n \n touchCancelled: function(touch) {\n this._hasTouch = NO;\n this.get(\"layer\").style.backgroundColor = \"white\";\n },\n \n childViews: \"inner\".w(),\n inner: SC.View.design({\n layout: { left: 50, top: 50, right: 50, bottom: 50 },\n backgroundColor: \"gray\",\n touchStart: function() {\n this.get(\"layer\").style.backgroundColor = \"blue\";\n return YES;\n },\n \n touchEnd: function() {\n this.get(\"layer\").style.backgroundColor = \"gray\";\n }\n \n })\n \n});\n\nvar MyExampleView = SC.View.extend({\n backgroundColor: \"#aaa\",\n childViews: \"stacks doesNot\".w(),\n stacks: Tester.extend({\n layout: { top: 10, left: 10, width: 200, height: 200 },\n shouldStack: YES\n }),\n \n doesNot: Tester.extend({\n layout: { top: 230, left: 10, width: 200, height: 200 },\n shouldStack: NO \n })\n});\n\n// bootstrap code :)\nexports.getDemoView = function() {\n return MyExampleView;\n};\n","highlighted":"<span class=\"multiline comment\">/**\n This is our test view. It will capture a touch, and, after one second,\n pass it through to the child view. Depending on the shouldStack property,\n it will stack while passing.\n \n In this example, the top view stacks, the bottom one does not.\n*/</span>\n<span class=\"keyword\">var</span> <span class=\"class\">Tester</span> = <span class=\"class\">SC</span>.<span class=\"class\">View</span>.<span class=\"variable\">extend</span>({\n <span class=\"variable\">backgroundColor</span>: <span class=\"string\">&quot;white&quot;</span>,\n \n <span class=\"variable\">shouldStack</span>: <span class=\"class\">NO</span>,\n <span class=\"variable\">captureTouch</span>: <span class=\"keyword\">function</span>() {\n <span class=\"keyword\">return</span> <span class=\"class\">YES</span>;\n },\n \n <span class=\"variable\">touchStart</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">_hasTouch</span> = <span class=\"variable\">touch</span>;\n <span class=\"this\">this</span>.<span class=\"variable\">get</span>(<span class=\"string\">&quot;layer&quot;</span>).<span class=\"variable\">style</span>.<span class=\"variable\">backgroundColor</span> = <span class=\"string\">&quot;red&quot;</span>;\n \n <span class=\"comment\">// in one second, we'll pass the touch along.</span>\n <span class=\"this\">this</span>.<span class=\"variable\">invokeLater</span>(<span class=\"string\">&quot;beginContentTouches&quot;</span>, <span class=\"number integer\">1000</span>, <span class=\"variable\">touch</span>);\n <span class=\"keyword\">return</span> <span class=\"class\">YES</span>;\n },\n \n <span class=\"variable\">beginContentTouches</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>) {\n <span class=\"comment\">// if our touch hasn't changed in the meantime</span>\n <span class=\"keyword\">if</span> (<span class=\"variable\">touch</span> === <span class=\"this\">this</span>.<span class=\"variable\">_hasTouch</span>) {\n <span class=\"comment\">// we'll pass the touch along.</span>\n <span class=\"variable\">touch</span>.<span class=\"variable\">captureTouch</span>(<span class=\"this\">this</span>, <span class=\"this\">this</span>.<span class=\"variable\">get</span>(<span class=\"string\">&quot;shouldStack&quot;</span>));\n }\n },\n \n <span class=\"variable\">touchEnd</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">_hasTouch</span> = <span class=\"class\">NO</span>;\n <span class=\"this\">this</span>.<span class=\"variable\">get</span>(<span class=\"string\">&quot;layer&quot;</span>).<span class=\"variable\">style</span>.<span class=\"variable\">backgroundColor</span> = <span class=\"string\">&quot;white&quot;</span>;\n },\n \n <span class=\"variable\">touchCancelled</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">_hasTouch</span> = <span class=\"class\">NO</span>;\n <span class=\"this\">this</span>.<span class=\"variable\">get</span>(<span class=\"string\">&quot;layer&quot;</span>).<span class=\"variable\">style</span>.<span class=\"variable\">backgroundColor</span> = <span class=\"string\">&quot;white&quot;</span>;\n },\n \n <span class=\"variable\">childViews</span>: <span class=\"string\">&quot;inner&quot;</span>.<span class=\"variable\">w</span>(),\n <span class=\"variable\">inner</span>: <span class=\"class\">SC</span>.<span class=\"class\">View</span>.<span class=\"variable\">design</span>({\n <span class=\"variable\">layout</span>: { <span class=\"variable\">left</span>: <span class=\"number integer\">50</span>, <span class=\"variable\">top</span>: <span class=\"number integer\">50</span>, <span class=\"variable\">right</span>: <span class=\"number integer\">50</span>, <span class=\"variable\">bottom</span>: <span class=\"number integer\">50</span> },\n <span class=\"variable\">backgroundColor</span>: <span class=\"string\">&quot;gray&quot;</span>,\n <span class=\"variable\">touchStart</span>: <span class=\"keyword\">function</span>() {\n <span class=\"this\">this</span>.<span class=\"variable\">get</span>(<span class=\"string\">&quot;layer&quot;</span>).<span class=\"variable\">style</span>.<span class=\"variable\">backgroundColor</span> = <span class=\"string\">&quot;blue&quot;</span>;\n <span class=\"keyword\">return</span> <span class=\"class\">YES</span>;\n },\n \n <span class=\"variable\">touchEnd</span>: <span class=\"keyword\">function</span>() {\n <span class=\"this\">this</span>.<span class=\"variable\">get</span>(<span class=\"string\">&quot;layer&quot;</span>).<span class=\"variable\">style</span>.<span class=\"variable\">backgroundColor</span> = <span class=\"string\">&quot;gray&quot;</span>;\n }\n \n })\n \n});\n\n<span class=\"keyword\">var</span> <span class=\"class\">MyExampleView</span> = <span class=\"class\">SC</span>.<span class=\"class\">View</span>.<span class=\"variable\">extend</span>({\n <span class=\"variable\">backgroundColor</span>: <span class=\"string\">&quot;#aaa&quot;</span>,\n <span class=\"variable\">childViews</span>: <span class=\"string\">&quot;stacks doesNot&quot;</span>.<span class=\"variable\">w</span>(),\n <span class=\"variable\">stacks</span>: <span class=\"class\">Tester</span>.<span class=\"variable\">extend</span>({\n <span class=\"variable\">layout</span>: { <span class=\"variable\">top</span>: <span class=\"number integer\">10</span>, <span class=\"variable\">left</span>: <span class=\"number integer\">10</span>, <span class=\"variable\">width</span>: <span class=\"number integer\">200</span>, <span class=\"variable\">height</span>: <span class=\"number integer\">200</span> },\n <span class=\"variable\">shouldStack</span>: <span class=\"class\">YES</span>\n }),\n \n <span class=\"variable\">doesNot</span>: <span class=\"class\">Tester</span>.<span class=\"variable\">extend</span>({\n <span class=\"variable\">layout</span>: { <span class=\"variable\">top</span>: <span class=\"number integer\">230</span>, <span class=\"variable\">left</span>: <span class=\"number integer\">10</span>, <span class=\"variable\">width</span>: <span class=\"number integer\">200</span>, <span class=\"variable\">height</span>: <span class=\"number integer\">200</span> },\n <span class=\"variable\">shouldStack</span>: <span class=\"class\">NO</span> \n })\n});\n\n<span class=\"comment\">// bootstrap code :)</span>\n<span class=\"variable\">exports</span>.<span class=\"variable\">getDemoView</span> = <span class=\"keyword\">function</span>() {\n <span class=\"keyword\">return</span> <span class=\"class\">MyExampleView</span>;\n};\n","original":"/**\n This is our test view. It will capture a touch, and, after one second,\n pass it through to the child view. Depending on the shouldStack property,\n it will stack while passing.\n \n In this example, the top view stacks, the bottom one does not.\n*/\nvar Tester = SC.View.extend({\n backgroundColor: \"white\",\n \n shouldStack: NO,\n captureTouch: function() {\n return YES;\n },\n \n touchStart: function(touch) {\n this._hasTouch = touch;\n this.get(\"layer\").style.backgroundColor = \"red\";\n \n // in one second, we'll pass the touch along.\n this.invokeLater(\"beginContentTouches\", 1000, touch);\n return YES;\n },\n \n beginContentTouches: function(touch) {\n // if our touch hasn't changed in the meantime\n if (touch === this._hasTouch) {\n // we'll pass the touch along.\n touch.captureTouch(this, this.get(\"shouldStack\"));\n }\n },\n \n touchEnd: function(touch) {\n this._hasTouch = NO;\n this.get(\"layer\").style.backgroundColor = \"white\";\n },\n \n touchCancelled: function(touch) {\n this._hasTouch = NO;\n this.get(\"layer\").style.backgroundColor = \"white\";\n },\n \n childViews: \"inner\".w(),\n inner: SC.View.design({\n layout: { left: 50, top: 50, right: 50, bottom: 50 },\n backgroundColor: \"gray\",\n touchStart: function() {\n this.get(\"layer\").style.backgroundColor = \"blue\";\n return YES;\n },\n \n touchEnd: function() {\n this.get(\"layer\").style.backgroundColor = \"gray\";\n }\n \n })\n \n});\n\nvar MyExampleView = SC.View.extend({\n backgroundColor: \"#aaa\",\n childViews: \"stacks doesNot\".w(),\n stacks: Tester.extend({\n layout: { top: 10, left: 10, width: 200, height: 200 },\n shouldStack: YES\n }),\n \n doesNot: Tester.extend({\n layout: { top: 230, left: 10, width: 200, height: 200 },\n shouldStack: NO \n })\n});\n\n// bootstrap code :)\nexports.getDemoView = function() {\n return MyExampleView;\n};\n"}},"articleDirectory":"articles/touch/","outputDirectory":"build/","title":"Capturing"},{"content":"<h1>Releasing</h1>\n\n<p>Why would you want to give up a touch? Imagine that your control is inside a <code class='syntax js'><span class=\"class\">SC</span>.<span class=\"class\">ScrollView</span></code>:\nif the touch moves too much, perhaps it should be considered a scroll, rather than an\naction for your control.</p>\n\n<p>From touchesDragged, you would give up touch responder status through a line like this:</p>\n\n<pre><code class='syntax js'><span class=\"variable\">someTouch</span>.<span class=\"variable\">makeTouchResponder</span>(<span class=\"variable\">someTouch</span>.<span class=\"variable\">nextTouchResponder</span>);\n</code></pre>\n\n<p>The touch's nextTouchResponder is the responder that is the <em>parent</em> touch responder; through\ndevious trickery (see <em>Capturing Touches</em>), ScrollView receives touch responder status <em>before</em>\nother views; further, it doesn't just hand touch responder status to the target view (your view)--\nit adds the responder to a stack of touch responders for the touch, so the responders can easily\nreturn to their parent responder (which is what you do with the above line of code.)</p>\n\n<p>Remember, though, that touchesDragged is called with a set of touches. It is really easy\nto change the responder for all of the touches simultaneously, should you wish to do so:</p>\n\n<pre><code class='syntax js'><span class=\"variable\">touches</span>.<span class=\"variable\">forEach</span>(<span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>){\n <span class=\"variable\">touch</span>.<span class=\"variable\">makeTouchResponder</span>(<span class=\"variable\">touch</span>.<span class=\"variable\">nextTouchResponder</span>);\n});\n</code></pre>\n\n<p>Perhaps you want to pass control only if the responder is scrollable:</p>\n\n<pre><code class='syntax js'><span class=\"keyword\">if</span> (<span class=\"variable\">touch</span>.<span class=\"variable\">nextTouchResponder</span> &amp;&amp; <span class=\"variable\">touch</span>.<span class=\"variable\">nextTouchResponder</span>.<span class=\"variable\">isScrollable</span>) {\n <span class=\"variable\">touch</span>.<span class=\"variable\">makeTouchResponder</span>(<span class=\"variable\">touch</span>.<span class=\"variable\">nextTouchResponder</span>);\n}\n</code></pre>\n\n<p><code class='syntax js'><span class=\"variable\">touchCancelled</span></code> will be called on your view automatically.</p>\n\n<h2>What Does It Look Like?</h2>\n\n<p>In this example, there is a single white box, containing a gray inner box. When you press\non the inner box, the outer box will capture the touch first. After a delay, it re-captures\nby calling captureTouch, and the inner view receives it. This is just like the \"Capturing\" demo.</p>\n\n<p>However, the inner view, after a second, will release it back.</p>\n\n<p><a href='releasing.js' class='demo'>releasing.js</a></p>","errors":[],"demos":{"releasing.js":{"ex":"/**\n This is similar to the \"Capturing\" example.\n \n In fact, the outer view is identical. Only the inner view has changed.\n As we can't pass control back without stacking, this demo _only_ includes\n the stacking method.\n \n The inner view, just like the outer view, passes control back after a specific\n time period.\n*/\nvar Tester = SC.View.extend({\n backgroundColor: \"white\",\n \n captureTouch: function() {\n return YES;\n },\n \n touchStart: function(touch) {\n this._hasTouch = touch;\n this.get(\"layer\").style.backgroundColor = \"red\";\n \n // in one second, we'll pass the touch along.\n this.invokeLater(\"beginContentTouches\", 1000, touch);\n return YES;\n },\n \n beginContentTouches: function(touch) {\n // if our touch hasn't changed in the meantime\n if (touch === this._hasTouch) {\n // we'll pass the touch along.\n touch.captureTouch(this, YES);\n }\n },\n \n touchEnd: function(touch) {\n this._hasTouch = NO;\n this.get(\"layer\").style.backgroundColor = \"white\";\n },\n \n touchCancelled: function(touch) {\n this._hasTouch = NO;\n this.get(\"layer\").style.backgroundColor = \"white\";\n },\n \n childViews: \"inner\".w(),\n inner: SC.View.design({\n layout: { left: 50, top: 50, right: 50, bottom: 50 },\n backgroundColor: \"gray\",\n touchStart: function(touch) {\n this._touch = touch;\n this.get(\"layer\").style.backgroundColor = \"blue\";\n this.invokeLater(\"releaseTouch\", 1000, touch);\n return YES;\n },\n \n releaseTouch: function(touch) {\n if (touch === this._touch) {\n touch.makeTouchResponder(touch.nextTouchResponder);\n }\n },\n \n touchEnd: function(touch) {\n this._touch = NO;\n this.get(\"layer\").style.backgroundColor = \"gray\";\n },\n \n touchCancelled: function(touch) {\n this._touch = NO;\n this.get(\"layer\").style.backgroundColor = \"gray\";\n }\n \n })\n \n});\n\nvar MyExampleView = SC.View.extend({\n backgroundColor: \"#aaa\",\n childViews: \"demo\".w(),\n demo: Tester.extend({\n layout: { top: 10, left: 10, width: 200, height: 200 },\n shouldStack: YES\n })\n});\n\n// bootstrap code :)\nexports.getDemoView = function() {\n return MyExampleView;\n};\n","highlighted":"<span class=\"multiline comment\">/**\n This is similar to the &quot;Capturing&quot; example.\n \n In fact, the outer view is identical. Only the inner view has changed.\n As we can't pass control back without stacking, this demo _only_ includes\n the stacking method.\n \n The inner view, just like the outer view, passes control back after a specific\n time period.\n*/</span>\n<span class=\"keyword\">var</span> <span class=\"class\">Tester</span> = <span class=\"class\">SC</span>.<span class=\"class\">View</span>.<span class=\"variable\">extend</span>({\n <span class=\"variable\">backgroundColor</span>: <span class=\"string\">&quot;white&quot;</span>,\n \n <span class=\"variable\">captureTouch</span>: <span class=\"keyword\">function</span>() {\n <span class=\"keyword\">return</span> <span class=\"class\">YES</span>;\n },\n \n <span class=\"variable\">touchStart</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">_hasTouch</span> = <span class=\"variable\">touch</span>;\n <span class=\"this\">this</span>.<span class=\"variable\">get</span>(<span class=\"string\">&quot;layer&quot;</span>).<span class=\"variable\">style</span>.<span class=\"variable\">backgroundColor</span> = <span class=\"string\">&quot;red&quot;</span>;\n \n <span class=\"comment\">// in one second, we'll pass the touch along.</span>\n <span class=\"this\">this</span>.<span class=\"variable\">invokeLater</span>(<span class=\"string\">&quot;beginContentTouches&quot;</span>, <span class=\"number integer\">1000</span>, <span class=\"variable\">touch</span>);\n <span class=\"keyword\">return</span> <span class=\"class\">YES</span>;\n },\n \n <span class=\"variable\">beginContentTouches</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>) {\n <span class=\"comment\">// if our touch hasn't changed in the meantime</span>\n <span class=\"keyword\">if</span> (<span class=\"variable\">touch</span> === <span class=\"this\">this</span>.<span class=\"variable\">_hasTouch</span>) {\n <span class=\"comment\">// we'll pass the touch along.</span>\n <span class=\"variable\">touch</span>.<span class=\"variable\">captureTouch</span>(<span class=\"this\">this</span>, <span class=\"class\">YES</span>);\n }\n },\n \n <span class=\"variable\">touchEnd</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">_hasTouch</span> = <span class=\"class\">NO</span>;\n <span class=\"this\">this</span>.<span class=\"variable\">get</span>(<span class=\"string\">&quot;layer&quot;</span>).<span class=\"variable\">style</span>.<span class=\"variable\">backgroundColor</span> = <span class=\"string\">&quot;white&quot;</span>;\n },\n \n <span class=\"variable\">touchCancelled</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">_hasTouch</span> = <span class=\"class\">NO</span>;\n <span class=\"this\">this</span>.<span class=\"variable\">get</span>(<span class=\"string\">&quot;layer&quot;</span>).<span class=\"variable\">style</span>.<span class=\"variable\">backgroundColor</span> = <span class=\"string\">&quot;white&quot;</span>;\n },\n \n <span class=\"variable\">childViews</span>: <span class=\"string\">&quot;inner&quot;</span>.<span class=\"variable\">w</span>(),\n <span class=\"variable\">inner</span>: <span class=\"class\">SC</span>.<span class=\"class\">View</span>.<span class=\"variable\">design</span>({\n <span class=\"variable\">layout</span>: { <span class=\"variable\">left</span>: <span class=\"number integer\">50</span>, <span class=\"variable\">top</span>: <span class=\"number integer\">50</span>, <span class=\"variable\">right</span>: <span class=\"number integer\">50</span>, <span class=\"variable\">bottom</span>: <span class=\"number integer\">50</span> },\n <span class=\"variable\">backgroundColor</span>: <span class=\"string\">&quot;gray&quot;</span>,\n <span class=\"variable\">touchStart</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">_touch</span> = <span class=\"variable\">touch</span>;\n <span class=\"this\">this</span>.<span class=\"variable\">get</span>(<span class=\"string\">&quot;layer&quot;</span>).<span class=\"variable\">style</span>.<span class=\"variable\">backgroundColor</span> = <span class=\"string\">&quot;blue&quot;</span>;\n <span class=\"this\">this</span>.<span class=\"variable\">invokeLater</span>(<span class=\"string\">&quot;releaseTouch&quot;</span>, <span class=\"number integer\">1000</span>, <span class=\"variable\">touch</span>);\n <span class=\"keyword\">return</span> <span class=\"class\">YES</span>;\n },\n \n <span class=\"variable\">releaseTouch</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>) {\n <span class=\"keyword\">if</span> (<span class=\"variable\">touch</span> === <span class=\"this\">this</span>.<span class=\"variable\">_touch</span>) {\n <span class=\"variable\">touch</span>.<span class=\"variable\">makeTouchResponder</span>(<span class=\"variable\">touch</span>.<span class=\"variable\">nextTouchResponder</span>);\n }\n },\n \n <span class=\"variable\">touchEnd</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">_touch</span> = <span class=\"class\">NO</span>;\n <span class=\"this\">this</span>.<span class=\"variable\">get</span>(<span class=\"string\">&quot;layer&quot;</span>).<span class=\"variable\">style</span>.<span class=\"variable\">backgroundColor</span> = <span class=\"string\">&quot;gray&quot;</span>;\n },\n \n <span class=\"variable\">touchCancelled</span>: <span class=\"keyword\">function</span>(<span class=\"variable\">touch</span>) {\n <span class=\"this\">this</span>.<span class=\"variable\">_touch</span> = <span class=\"class\">NO</span>;\n <span class=\"this\">this</span>.<span class=\"variable\">get</span>(<span class=\"string\">&quot;layer&quot;</span>).<span class=\"variable\">style</span>.<span class=\"variable\">backgroundColor</span> = <span class=\"string\">&quot;gray&quot;</span>;\n }\n \n })\n \n});\n\n<span class=\"keyword\">var</span> <span class=\"class\">MyExampleView</span> = <span class=\"class\">SC</span>.<span class=\"class\">View</span>.<span class=\"variable\">extend</span>({\n <span class=\"variable\">backgroundColor</span>: <span class=\"string\">&quot;#aaa&quot;</span>,\n <span class=\"variable\">childViews</span>: <span class=\"string\">&quot;demo&quot;</span>.<span class=\"variable\">w</span>(),\n <span class=\"variable\">demo</span>: <span class=\"class\">Tester</span>.<span class=\"variable\">extend</span>({\n <span class=\"variable\">layout</span>: { <span class=\"variable\">top</span>: <span class=\"number integer\">10</span>, <span class=\"variable\">left</span>: <span class=\"number integer\">10</span>, <span class=\"variable\">width</span>: <span class=\"number integer\">200</span>, <span class=\"variable\">height</span>: <span class=\"number integer\">200</span> },\n <span class=\"variable\">shouldStack</span>: <span class=\"class\">YES</span>\n })\n});\n\n<span class=\"comment\">// bootstrap code :)</span>\n<span class=\"variable\">exports</span>.<span class=\"variable\">getDemoView</span> = <span class=\"keyword\">function</span>() {\n <span class=\"keyword\">return</span> <span class=\"class\">MyExampleView</span>;\n};\n","original":"/**\n This is similar to the \"Capturing\" example.\n \n In fact, the outer view is identical. Only the inner view has changed.\n As we can't pass control back without stacking, this demo _only_ includes\n the stacking method.\n \n The inner view, just like the outer view, passes control back after a specific\n time period.\n*/\nvar Tester = SC.View.extend({\n backgroundColor: \"white\",\n \n captureTouch: function() {\n return YES;\n },\n \n touchStart: function(touch) {\n this._hasTouch = touch;\n this.get(\"layer\").style.backgroundColor = \"red\";\n \n // in one second, we'll pass the touch along.\n this.invokeLater(\"beginContentTouches\", 1000, touch);\n return YES;\n },\n \n beginContentTouches: function(touch) {\n // if our touch hasn't changed in the meantime\n if (touch === this._hasTouch) {\n // we'll pass the touch along.\n touch.captureTouch(this, YES);\n }\n },\n \n touchEnd: function(touch) {\n this._hasTouch = NO;\n this.get(\"layer\").style.backgroundColor = \"white\";\n },\n \n touchCancelled: function(touch) {\n this._hasTouch = NO;\n this.get(\"layer\").style.backgroundColor = \"white\";\n },\n \n childViews: \"inner\".w(),\n inner: SC.View.design({\n layout: { left: 50, top: 50, right: 50, bottom: 50 },\n backgroundColor: \"gray\",\n touchStart: function(touch) {\n this._touch = touch;\n this.get(\"layer\").style.backgroundColor = \"blue\";\n this.invokeLater(\"releaseTouch\", 1000, touch);\n return YES;\n },\n \n releaseTouch: function(touch) {\n if (touch === this._touch) {\n touch.makeTouchResponder(touch.nextTouchResponder);\n }\n },\n \n touchEnd: function(touch) {\n this._touch = NO;\n this.get(\"layer\").style.backgroundColor = \"gray\";\n },\n \n touchCancelled: function(touch) {\n this._touch = NO;\n this.get(\"layer\").style.backgroundColor = \"gray\";\n }\n \n })\n \n});\n\nvar MyExampleView = SC.View.extend({\n backgroundColor: \"#aaa\",\n childViews: \"demo\".w(),\n demo: Tester.extend({\n layout: { top: 10, left: 10, width: 200, height: 200 },\n shouldStack: YES\n })\n});\n\n// bootstrap code :)\nexports.getDemoView = function() {\n return MyExampleView;\n};\n"}},"articleDirectory":"articles/touch/","outputDirectory":"build/","title":"Releasing"}]}],"file":"build/guides/touch"}
View
BIN  apps/hedwig/resources/icon-precomposed.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  apps/hedwig/resources/icon-precomposed.psd
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  apps/hedwig/resources/startup.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  apps/hedwig/resources/startup.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  apps/hedwig/resources/startup.psd
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
2  docs/build/articles/touch/a-brief-touch.html
@@ -110,6 +110,6 @@
<li><strong>Coolness.</strong> Touch-based interfaces are cool. That is all.</li>
</ul>
-<p>In this guide, we go over each of these&emdash;except for the last, which is rather vague; you'll have to figure out
+<p>In this guide, we go over each of these, except for the last, which is rather vague; you'll have to figure out
your own meaning of "coolness".</p>
</div><div class="footer"></div></body></html>
View
2  docs/build/articles/touch/a-brief-touch.json
@@ -1 +1 @@
-{"content":"<h1>A Brief Touch</h1>\n\n<p>It is very possible to build <em>awesome</em> touch-enabled applications in SproutCore.</p>\n\n<p>But, what makes an awesome touch-enabled application? Sure, it must accept touches,\nbut with SproutCore's (constantly growing) touch support, this is now pretty easy:\nmany existing interfaces, if built with newer SproutCore varieties, will function fine (or mostly fine),\non both larger-screened touch devices (such as iPad) and the traditional desktop environment.</p>\n\n<p>But there are many differences between desktop and touch platforms:</p>\n\n<ul>\n<li><strong>Precision.</strong> Touches are less precise than clicks. To compensate, controls should be larger.</li>\n<li><strong>Performance.</strong> Touch-based devices tend to be slow (for now). To get around this just takes \nsome elbow grease: there are many techniques to speed things up... many of which SproutCore will\nhandle for you.</li>\n<li><strong>Animation.</strong> Lack of animation looks okay on desktop (even if animation is cool)... but on\ntouch devices, non-animated interfaces look strange: touch is so much more realistic than mouse,\nbut sudden changes without transitions are not realistic at all.</li>\n<li><strong>Coolness.</strong> Touch-based interfaces are cool. That is all.</li>\n</ul>\n\n<p>In this guide, we go over each of these&emdash;except for the last, which is rather vague; you'll have to figure out\nyour own meaning of \"coolness\".</p>","errors":[],"demos":{},"articleDirectory":"articles/touch/","outputDirectory":"build/","title":"A Brief Touch","any":"metadata","goes":"Here","damn":"gruber","this":"is still eye-readable","and":"He is wrong about touch apps."}
+{"content":"<h1>A Brief Touch</h1>\n\n<p>It is very possible to build <em>awesome</em> touch-enabled applications in SproutCore.</p>\n\n<p>But, what makes an awesome touch-enabled application? Sure, it must accept touches,\nbut with SproutCore's (constantly growing) touch support, this is now pretty easy:\nmany existing interfaces, if built with newer SproutCore varieties, will function fine (or mostly fine),\non both larger-screened touch devices (such as iPad) and the traditional desktop environment.</p>\n\n<p>But there are many differences between desktop and touch platforms:</p>\n\n<ul>\n<li><strong>Precision.</strong> Touches are less precise than clicks. To compensate, controls should be larger.</li>\n<li><strong>Performance.</strong> Touch-based devices tend to be slow (for now). To get around this just takes \nsome elbow grease: there are many techniques to speed things up... many of which SproutCore will\nhandle for you.</li>\n<li><strong>Animation.</strong> Lack of animation looks okay on desktop (even if animation is cool)... but on\ntouch devices, non-animated interfaces look strange: touch is so much more realistic than mouse,\nbut sudden changes without transitions are not realistic at all.</li>\n<li><strong>Coolness.</strong> Touch-based interfaces are cool. That is all.</li>\n</ul>\n\n<p>In this guide, we go over each of these, except for the last, which is rather vague; you'll have to figure out\nyour own meaning of \"coolness\".</p>","errors":[],"demos":{},"articleDirectory":"articles/touch/","outputDirectory":"build/","title":"A Brief Touch","any":"metadata","goes":"Here","damn":"gruber","this":"is still eye-readable","and":"He is wrong about touch apps."}
View
2  docs/build/articles/touch/a-brief-touch.md
@@ -27,5 +27,5 @@ But there are many differences between desktop and touch platforms:
but sudden changes without transitions are not realistic at all.
- **Coolness.** Touch-based interfaces are cool. That is all.
-In this guide, we go over each of theseexcept for the last, which is rather vague; you'll have to figure out
+In this guide, we go over each of these, except for the last, which is rather vague; you'll have to figure out
your own meaning of "coolness".
View
2  docs/build/guides/touch.json
1 addition, 1 deletion not shown
View
2  docs/src/articles/touch/a-brief-touch.md
@@ -27,5 +27,5 @@ But there are many differences between desktop and touch platforms:
but sudden changes without transitions are not realistic at all.
- **Coolness.** Touch-based interfaces are cool. That is all.
-In this guide, we go over each of theseexcept for the last, which is rather vague; you'll have to figure out
+In this guide, we go over each of these, except for the last, which is rather vague; you'll have to figure out
your own meaning of "coolness".

0 comments on commit 60019be

Please sign in to comment.
Something went wrong with that request. Please try again.