1 // ========================================================================== 2 // Project: SproutCore - JavaScript Application Framework 3 // Copyright: ©2006-2011 Strobe Inc. and contributors. 4 // Portions ©2008-2011 Apple Inc. All rights reserved. 5 // License: Licensed under MIT license (see license.js) 6 // ========================================================================== 7 8 9 /** 10 @namespace 11 NavigationBuilder is an implementation of the Builder protocol. It implements 12 `buildIn`/`Out` (though these only relay to `buildIn`/`OutNavigation, so feel free to 13 override if needed; the navigation builders will still be accessible). 14 15 Building in and out animates the view in and out to and from the left and right. 16 */ 17 SC.NavigationBuilder = { 18 19 /** 20 Walk like a duck. 21 22 @type Boolean 23 @default YES 24 @constant 25 */ 26 isNavigationBuilder: YES, 27 28 /** 29 The transitions to be used for navigation; these are mixed in to the existing 30 transitions hash if one exists, or become the transitions hash otherwise. 31 32 If NO, it uses the (hard-coded) defaults. 33 34 @type Boolean 35 @default NO 36 */ 37 navigationTransitions: NO, 38 39 initMixin: function() { 40 // force integrate SC.Animatable 41 var animatable = SC.Animatable; 42 if (animatable && !this.isAnimatable) { 43 // okay, let's mix it in! 44 this.mixin(animatable); 45 } else if (!animatable) { 46 // check that we actually have SC.Animatable 47 SC.Logger.error( 48 "SC.NavigationView and SC.NavigationBuilder require SC.Animatable " + 49 "to perform animations, but it is not present. Please ensure your app or framework " + 50 "references it." 51 ); 52 } 53 54 var navigationTransitions = this.get("navigationTransitions"); 55 if (!navigationTransitions && SC.Animatable) { 56 navigationTransitions = { 57 // these being identical helps us. 58 left: { duration: 0.25, timing: SC.Animatable.TRANSITION_EASE_IN_OUT, action: "navigationBuildDidFinish" }, 59 transform: { duration: 0.25, timing: SC.Animatable.TRANSITION_EASE_IN_OUT, action: "navigationBuildDidFinish" } 60 }; 61 } 62 63 // mix in transitions (a base set will have been added by SC.Animatable alrady) 64 if (SC.Animatable) SC.mixin(this.transitions, navigationTransitions); 65 }, 66 67 /** @private 68 Determines metrics of the view. This may be adapted to work with non-CSS transforms in future... 69 */ 70 metrics: function() { 71 var f = this.computeFrameWithParentFrame(); 72 return f; 73 }, 74 75 /** @private 76 Applies the supplied CSS transform. 77 */ 78 transform: function(pos) { 79 if (SC.platform.supportsCSS3DTransforms) { 80 this.adjust("transform", "translate3d(" + pos + "px,0px,0px)"); 81 } else { 82 this.adjust("transform", "translate(" + pos + "px,0px)"); 83 } 84 }, 85 86 buildInNavigation: function() { 87 // set initial state 88 var metrics = this.metrics(); 89 this.disableAnimation(); 90 this.transform(this.get("buildDirection") === SC.TO_LEFT ? metrics.width : -metrics.width); 91 this.enableAnimation(); 92 93 // now, (delayed) call transform to go to the correct spot 94 this.invokeLater("transform", 10, 0); 95 }, 96 97 buildOutNavigation: function() { 98 // we already have an initial state 99 var metrics = this.metrics(); 100 this.transform(this.get("buildDirection") === SC.TO_LEFT ? -metrics.width : metrics.width); 101 }, 102 103 /** 104 You may override this. If you do, call `buildInNavigation` to call the original functionality. 105 You may need to override `navigationBuildDidFinish` as well if you call `buildInNavigation`. 106 */ 107 buildIn: function() { 108 this.buildInNavigation(); 109 }, 110 111 /** 112 You may override this. If you do, call `buildOutNavigation` to call the original functionality. 113 You may need to override `navigationBuildDidFinish`as well if you call `buildOutNavigation`. 114 */ 115 buildOut: function() { 116 this.buildOutNavigation(); 117 }, 118 119 /** 120 This ensures that the view has a CSS transform set, even if it is added without build in, etc. 121 */ 122 resetBuild: function() { 123 this.transform(0); 124 }, 125 126 /** 127 Called when the transitions finish. 128 */ 129 navigationBuildDidFinish: function() { 130 if (this.isBuildingIn) { 131 this.buildInDidFinish(); 132 } else if (this.isBuildingOut) { 133 this.buildOutDidFinish(); 134 } 135 } 136 137 } ; 138 139