Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Updated component to work with Sencha Touch 2.1.

This also includes a number of enhancements such as:

  * event support - see app/controller for example
  * automatic CSS styling be default

Note: This will no longer work as-is with older versions of
Sencha Touch.
  • Loading branch information...
commit e00c77f548510cb615f0bde2547ad1f28368de14 1 parent e6695f7
@wnielson authored
View
14 README.rst
@@ -36,6 +36,20 @@ or simply extend the 'Ext.ux.slidenavigation.View' class.
For a more complete example, see `app/view/Main.js`.
+Building with Sencha Command
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In order for the ``sencha build`` command to work properly, you need to let it know where
+to find the component. This can be done easily by opening the following file::
+
+ .sencha/app/sencha.cfg
+
+Update the ``app.classpath`` variable to point to the ``ux`` directory, like so::
+
+ app.classpath=${app.dir}/app.js,${app.dir}/app,path/to/ux
+
+
+
Building the Example Application
--------------------------------
View
30 app.js
@@ -1,6 +1,6 @@
//<debug>
Ext.Loader.setPath({
- 'Ext': 'sdk/src',
+ 'Ext': 'touch/src',
'Ext.ux': './ux'
});
//</debug>
@@ -9,22 +9,34 @@ Ext.application({
name: 'SlideNavigationExample',
requires: [
- 'Ext.Msg'
+ 'Ext.MessageBox'
],
views: [
'Main'
],
+ controllers: [
+ 'Main'
+ ],
+
icon: {
- 57: 'resources/icons/Icon.png',
- 72: 'resources/icons/Icon~ipad.png',
- 114: 'resources/icons/Icon@2x.png',
- 144: 'resources/icons/Icon~ipad@2x.png'
+ '57': 'resources/icons/Icon.png',
+ '72': 'resources/icons/Icon~ipad.png',
+ '114': 'resources/icons/Icon@2x.png',
+ '144': 'resources/icons/Icon~ipad@2x.png'
+ },
+
+ isIconPrecomposed: true,
+
+ startupImage: {
+ '320x460': 'resources/startup/320x460.jpg',
+ '640x920': 'resources/startup/640x920.png',
+ '768x1004': 'resources/startup/768x1004.png',
+ '748x1024': 'resources/startup/748x1024.png',
+ '1536x2008': 'resources/startup/1536x2008.png',
+ '1496x2048': 'resources/startup/1496x2048.png'
},
-
- phoneStartupScreen: 'resources/loading/Homescreen.jpg',
- tabletStartupScreen: 'resources/loading/Homescreen~ipad.jpg',
launch: function() {
// Destroy the #appLoadingIndicator element
View
47 app.json
@@ -5,10 +5,27 @@
"name": "SlideNavigationExample",
/**
+ * The file path to this application's front HTML document, relative to this app.json file
+ */
+ "indexHtmlPath": "index.html",
+
+ /**
+ * The absolute URL to this application in development environment, i.e: the URL to run this application
+ * on your web browser during development, e.g: "http://localhost/myapp/index.html".
+ *
+ * This value is needed when build to resolve your application's dependencies if it requires server-side resources
+ * that are not accessible via file system protocol.
+ */
+ "url": null,
+
+ /**
* List of all JavaScript assets in the right execution order.
* Each item is an object with the following format:
* {
- * "path": "path/to/script.js" // Relative path to this app.json file
+ * "path": "path/to/script.js" // Path to file, if local file it must be relative to this app.json file
+ * "remote": true // (Optional)
+ * // - Defaults to undefined (falsey) to signal a local file which will be copied
+ * // - Specify true if this file is a remote file which will not to be copied
* "update": "delta" // (Optional)
* // - If not specified, this file will only be loaded once, and
* // cached inside localStorage until this value is changed.
@@ -19,10 +36,11 @@
*/
"js": [
{
- "path": "sdk/sencha-touch.js"
+ "path": "touch/sencha-touch.js"
},
{
"path": "app.js",
+ "bundle": true, /* Indicates that all class dependencies are concatenated into this file when build */
"update": "delta"
}
],
@@ -31,7 +49,10 @@
* List of all CSS assets in the right inclusion order.
* Each item is an object with the following format:
* {
- * "path": "path/to/item.css" // Relative path to this app.json file
+ * "path": "path/to/item.css" // Path to file, if local file it must be relative to this app.json file
+ * "remote": true // (Optional)
+ * // - Defaults to undefined (falsey) to signal a local file which will be copied
+ * // - Specify true if this file is a remote file which will not to be copied
* "update": "delta" // (Optional)
* // - If not specified, this file will only be loaded once, and
* // cached inside localStorage until this value is changed to either one below
@@ -55,8 +76,7 @@
* List of items in the CACHE MANIFEST section
*/
"cache": [
- "index.html",
- "resources/images/guide.jpg"
+ "index.html"
],
/**
* List of items in the NETWORK section
@@ -73,15 +93,22 @@
/**
* Extra resources to be copied along when build
*/
- "extras": [
+ "resources": [
"resources/images",
"resources/icons",
- "resources/loading"
+ "resources/startup"
+ ],
+
+ /**
+ * File / directory name matchers to ignore when copying to the builds, must be valid regular expressions
+ */
+ "ignore": [
+ "\.svn$"
],
/**
* Directory path to store all previous production builds. Note that the content generated inside this directory
- * must be kept intact for proper generation of delta between updates
+ * must be kept intact for proper generation of deltas between updates
*/
"archivePath": "archive",
@@ -102,12 +129,12 @@
"product": "touch",
"minVersion": 3,
"debug": false,
- "logger": "no"
+ "logger": false
},
/**
* Uniquely generated id for this application, used as prefix for localStorage keys.
* Normally you should never change this value.
*/
- "id": "152440a0-7772-11e1-aa1c-bf802d67caea"
+ "id": "cfdd6666-d48b-4834-9e2d-6ae8ef18cd19"
}
View
49 app/controller/Main.js
@@ -0,0 +1,49 @@
+Ext.define("SlideNavigationExample.controller.Main", {
+ extend: 'Ext.app.Controller',
+
+ config: {
+ refs: {
+ slideNav: 'slidenavigationview'
+ },
+
+ control: {
+ slideNav: {
+ open: function(nav, position, duration) {
+ console.log('Container open (position='+position+',duration='+duration+')');
+ },
+
+ close: function(nav, position, duration) {
+ console.log('Container close (position='+position+',duration='+duration+')');
+ },
+
+ select: function(nav, item, index) {
+ console.log('Selected item (index='+index+')');
+ },
+
+ opened: function(nav) {
+ console.log('Container opened');
+ },
+
+ closed: function(nav) {
+ console.log('Container closed');
+ },
+
+ slideend: function(nav) {
+ console.log('Container slideend');
+ },
+
+ slidestart: function(nav) {
+ console.log('Container slidestart');
+ },
+
+ dragstart: function(nav) {
+ console.log('Container dragstart');
+ },
+
+ dragend: function(nav) {
+ console.log('Container dragend');
+ }
+ }
+ }
+ }
+});
View
2  app/view/Main.js
@@ -42,7 +42,7 @@ Ext.define("SlideNavigationExample.view.Main", {
centered: false,
width: 200,
left: 0
- },
+ }
/**
* Here's an example of how to add a different type of
View
74 index.html
@@ -3,88 +3,54 @@
<head>
<meta charset="UTF-8">
<title>SlideNavigationExample</title>
-
- <!-- Android debug -->
- <!--<script src="http://10.0.2.2:8080/target/target-script-min.js#anonymous"></script>-->
-
<style type="text/css">
- /**
- * Example CSS for adding a drop shadow to the main container.
- */
- .x-slidenavigation-container.x-dragging,
- .x-slidenavigation-container.open {
- /**
- * The performance of this now seem acceptable. If you
- * are experiencing a laggy sliding animation you can either
- * a) Turn off the slide animation (set duration to 0), or
- * b) Use the border-image method below
- */
- box-shadow: 0 0 4px 1px #999;
- -webkit-box-shadow: 0 0 4px 1px #999;
- }
-
-
- /**
+ /**
* Example of an initial loading indicator.
* It is recommended to keep this as minimal as possible to provide instant feedback
* while other resources are still being loaded for the first time
*/
html, body {
height: 100%;
+ background-color: #1985D0
}
#appLoadingIndicator {
position: absolute;
top: 50%;
- left: 50%;
- margin-top: -10px;
- margin-left: -50px;
- width: 100px;
- height: 20px;
- }
-
- #appLoadingIndicator > * {
- background-color: #FFFFFF;
- float: left;
- height: 20px;
- margin-left: 11px;
- width: 20px;
+ margin-top: -15px;
+ text-align: center;
+ width: 100%;
+ height: 30px;
-webkit-animation-name: appLoadingIndicator;
- -webkit-border-radius: 13px;
- -webkit-animation-duration: 0.8s;
+ -webkit-animation-duration: 0.5s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-direction: linear;
- opacity: 0.3
- }
-
- #appLoadingIndicator > :nth-child(1) {
- -webkit-animation-delay: 0.18s;
- }
-
- #appLoadingIndicator > :nth-child(2) {
- -webkit-animation-delay: 0.42s;
}
- #appLoadingIndicator > :nth-child(3) {
- -webkit-animation-delay: 0.54s;
+ #appLoadingIndicator > * {
+ background-color: #FFFFFF;
+ display: inline-block;
+ height: 30px;
+ -webkit-border-radius: 15px;
+ margin: 0 5px;
+ width: 30px;
+ opacity: 0.8;
}
@-webkit-keyframes appLoadingIndicator{
0% {
- opacity: 0.3
+ opacity: 0.8
}
-
50% {
- opacity: 1;
- background-color:#1985D0
+ opacity: 0
}
-
100% {
- opacity:0.3
+ opacity: 0.8
}
}
</style>
- <script id="microloader" type="text/javascript" src="sdk/microloader/development.js"></script>
+ <!-- The line below must be kept intact for Sencha Command to build your application -->
+ <script id="microloader" type="text/javascript" src="touch/microloader/development.js"></script>
</head>
<body>
<div id="appLoadingIndicator">
View
72 packager.json
@@ -5,13 +5,19 @@
* This is the name of your application, which is displayed on the device when the app is installed. On IOS, this should match
* the name of your application in the Apple Provisioning Portal.
*/
- "applicationName":"SlideNavigationExample",
+ "applicationName":"My Application",
/**
* @cfg {String} applicationId
* This is the name namespace for your application. On IOS, this should match the name of your application in the Apple Provisioning Portal.
*/
- "applicationId":"com.wnielson.slideNavigationExample",
+ "applicationId":"com.mycompany.myAppID",
+
+ /**
+ * @cfg {String} bundleSeedId
+ * A ten character string which stands before aplication ID in Apple Provisioning Portal
+ */
+ "bundleSeedId":"KPXFEPZ6EF",
/**
* @cfg {String} versionString
@@ -21,30 +27,40 @@
"versionString":"1.0",
/**
- * @cfg {String} iconName
- * This is file name of your icon. This should be in the same directory of this configuration file.
- *
+ * @cfg {Integer} versionCode
+ * @required
+ * This is the integer version code of your application, or you can refer to it as a build number. Used only for Android builds.
+ */
+ "versionCode":"1",
+
+ /**
+ * @cfg {Object} icon
* For iOS, please refer to their documentation about icon sizes:
* https://developer.apple.com/library/ios/#documentation/userexperience/conceptual/mobilehig/IconsImages/IconsImages.html
*
* For Android, please refer to the Google Launcher icons guide:
* http://developer.android.com/guide/practices/ui_guidelines/icon_design_launcher.html
*/
- "iconName":"resources/icons/Icon~ipad.png",
+ "icon": {
+ "57":"resources/icons/Icon.png",
+ "72":"resources/icons/Icon~ipad.png",
+ "114":"resources/icons/Icon@2x.png",
+ "144":"resources/icons/Icon~ipad@2x.png"
+ },
/**
* @cfg {String} inputPath
* @required
* This is location of your Sencha Touch 2 application, relative to this configuration file.
*/
- "inputPath":"build/native",
+ "inputPath":"./",
/**
* @cfg {String} outputPath
* @required
- * This is where the built application file with be saved.
+ * This is where the built application file with be saved. Make sure that output path is not in your input path, you may get into endless recursive copying
*/
- "outputPath":"build/",
+ "outputPath":"../build/",
/**
* @cfg {String} configuration
@@ -97,23 +113,49 @@
*
* When using a certificatePath on Windows, you do not need to specify this.
*/
- "certificateAlias":"",
-
+ "certificatePassword":"",
+ /**
+ * @cfg {String} certificatePassword
+ * The password which was specified during certificate export
+ */
+ "provisionProfile":"",
+ /**
+ * @cfg {String} provisionProfile
+ * The path to the provision profile (APP_NAME.mobileprovision) which you can create and then download from Apple's provisioning portal
+ */
+ "sdkPath":"/path/to/android-sdk",
+
/**
* @cfg {String} sdkPath
* This is the path to the Android SDK, if you are developing an Android application.
*/
"sdkPath":"/path/to/android-sdk",
-
+
/**
- * @cfg androidAPILevel
+ /**
+ * @cfg {String} androidAPILevel
* This is android API level, the version of Android SDK to use, you can read more about it here: http://developer.android.com/guide/appendix/api-levels.html.
* Be sure to install corresponding platform API in android SDK manager (android_sdk/tools/android)
*/
- "androidAPILevel":"15",
+ "androidAPILevel":"8",
+
+ /**
+ /**
+ * @cfg {Array[String]} permissions
+ * Array of permissions that is used by an application (Android only)
+ * Full list of permissions for Android application can be found here: http://developer.android.com/reference/android/Manifest.permission.html#ACCESS_CHECKIN_PROPERTIES
+ */
+ "permissions":[
+ "INTERNET",
+ "ACCESS_NETWORK_STATE",
+ "CAMERA",
+ "VIBRATE",
+ "ACCESS_FINE_LOCATION",
+ "ACCESS_COARSE_LOCATION",
+ "CALL_PHONE"],
/**
- * @cfg orientations
+ * @cfg {Array[String]} orientations
* @required
* This is orientations that this application can run.
*/
View
6,756 resources/css/app.css
1 addition, 6,755 deletions not shown
View
BIN  resources/loading/Default-LandscapeLeft~ipad.png
Deleted file not rendered
View
BIN  resources/loading/Default-LandscapeRight~ipad.png
Deleted file not rendered
View
BIN  resources/loading/Default-Landscape~ipad.png
Deleted file not rendered
View
BIN  resources/loading/Default-PortraitUpsideDown~ipad.png
Deleted file not rendered
View
BIN  resources/loading/Default-Portrait~ipad.png
Deleted file not rendered
View
BIN  resources/loading/Default.png
Deleted file not rendered
View
BIN  resources/loading/Default@2x.png
Deleted file not rendered
View
BIN  resources/loading/Default~ipad.png
Deleted file not rendered
View
BIN  resources/loading/Homescreen~ipad.jpg
Deleted file not rendered
View
2  resources/sass/config.rb
@@ -2,7 +2,7 @@
dir = File.dirname(__FILE__)
# Load the sencha-touch framework automatically.
-load File.join(dir, '..', '..', 'sdk', 'resources', 'themes')
+load File.join(dir, '..', '..', 'touch', 'resources', 'themes')
# Compass configurations
sass_path = dir
View
BIN  resources/startup/1496x2048.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  resources/startup/1536x2008.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
0  resources/loading/Homescreen.jpg → resources/startup/320x460.jpg
File renamed without changes
View
BIN  resources/startup/640x920.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  resources/startup/748x1024.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  resources/startup/768x1004.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
224 ux/slidenavigation/View.js
@@ -12,14 +12,67 @@ Ext.define('Ext.ux.slidenavigation.View', {
'Ext.Button',
'Ext.Container',
'Ext.Function',
- 'Ext.ModelManager',
'Ext.Toolbar',
'Ext.data.Model',
+ 'Ext.data.ModelManager',
'Ext.data.Store',
- 'Ext.dataview.List',
+ 'Ext.dataview.List'
],
xtype: 'slidenavigationview',
+
+ /**
+ * @event close
+ * @preventable moveContainer
+ * Fires whenever the container is closed
+ * @param {Ext.ux.slidenavigation.View} this The navigation View instance
+ * @param {Number} position The x-coordinate to which the container will be moved to
+ * @param {Number} duration The duration of the slide event
+ */
+
+ /**
+ * @event open
+ * @preventable moveContainer
+ * Fires whenever the container is opened
+ * @param {Ext.ux.slidenavigation.View} this The navigation View instance
+ * @param {Number} position The x-coordinate to which the container will be moved to
+ * @param {Number} duration The duration of the slide event
+ */
+
+ /**
+ * @event select
+ * @preventable setContainerItem
+ * Fires whenever an item in the menu is selected
+ * @param {Ext.ux.slidenavigation.View} this The navigation View instance
+ * @param {Ext.Component} item The selected item
+ * @param {Integer} index The index of the selected item
+ */
+
+ /**
+ * @event slideend
+ * Fires whenever the user has finished sliding the container. This is fired once the
+ * animation is complete.
+ * @param {Ext.ux.slidenavigation.View} this The navigation View instance
+ */
+
+ /**
+ * @event slidestart
+ * Fires whenever the user has started sliding the container. This is fired once the
+ * animation is complete.
+ * @param {Ext.ux.slidenavigation.View} this The navigation View instance
+ */
+
+ /**
+ * @event opened
+ * Fires after the container is fully opened.
+ * @param {Ext.ux.slidenavigation.View} this The navigation View instance
+ */
+
+ /**
+ * @event closed
+ * Fires after the container is fully closed.
+ * @param {Ext.ux.slidenavigation.View} this The navigation View instance
+ */
config: {
/**
@@ -88,7 +141,7 @@ Ext.define('Ext.ux.slidenavigation.View', {
* of the container when "flicked". By default the animation is disable on
* Android.
*/
- slideDuration: Ext.os.is.Android ? 0 : 100,
+ slideDuration: Ext.os.is('Android') ? 0 : 100,
/**
* @cfg {Integer} selectSlideDuration Number of miliseconds to animate the sliding
@@ -96,13 +149,20 @@ Ext.define('Ext.ux.slidenavigation.View', {
* value here of 300 gives a much nicer feel. By default the animation is disable on
* Android.
*/
- selectSlideDuration: Ext.os.is.Android ? 0 : 300,
+ selectSlideDuration: Ext.os.is('Android') ? 0 : 300,
/**
* @cfg {Boolean} closeOnSelect Whether or not to automatically close the container
* when an item in the list is selected. Default is true.
*/
- closeOnSelect: true
+ closeOnSelect: true,
+
+ /**
+ * @cfg {String} shadowStyle CSS to use for styling the shadow when the container is
+ * open. This should be a valid CSS 'box-shadow' argument. Set to false to disable
+ * it.
+ */
+ shadowStyle: '0 0 4px 1px #999'
},
initConfig: function() {
@@ -148,7 +208,8 @@ Ext.define('Ext.ux.slidenavigation.View', {
listeners: {
release: me.toggleContainer,
scope: me
- },
+ }
+
/**
* To add the button into a toolbar, you can add the following
* to any item in your navigation list.
@@ -161,6 +222,8 @@ Ext.define('Ext.ux.slidenavigation.View', {
},
initialize: function() {
+ this.__init = false;
+
this.callParent();
this.addCls('x-slidenavigation');
@@ -172,10 +235,14 @@ Ext.define('Ext.ux.slidenavigation.View', {
this.list,
this.container
]);
+
+ this.createContainerCSS();
// TODO: Make this optional, perhaps by defining
// "selected: true" in the items list
this.list.select(0);
+
+ this.__init = true;
},
/**
@@ -194,8 +261,31 @@ Ext.define('Ext.ux.slidenavigation.View', {
me.store.add(item);
});
},
+
+ /**
+ * @private
+ * Construct style element for container shadow and insert into the DOM.
+ */
+ createContainerCSS: function() {
+ var shadowStyle = this.getShadowStyle(),
+ id = this.getId();
+
+ if (shadowStyle) {
+ if (!document.getElementById(id)) {
+ style = document.createElement('style');
+ style.type = 'text/css';
+ style.id = id;
+ style.innerHTML = '.x-slidenavigation-container.x-dragging, '+
+ '.x-slidenavigation-container.open { '+
+ 'box-shadow: '+shadowStyle+';'+
+ '-webkit-box-shadow:'+shadowStyle+';';
+ document.getElementsByTagName('head')[0].appendChild(style);
+ }
+ }
+ },
/**
+ * @private
* Creates a button that can toggle the navigation menu. For an example
* config, see ``slideButtonDefaults``.
*/
@@ -217,7 +307,8 @@ Ext.define('Ext.ux.slidenavigation.View', {
var me = this,
store = list.getStore(),
index = item.raw.index,
- container = me.container;
+ container = me.container,
+ func = Ext.emptyFn;
if (me._cache[index] == undefined) {
//container = this.down('container[cls="x-slidenavigation-container"]');
@@ -234,18 +325,27 @@ Ext.define('Ext.ux.slidenavigation.View', {
me.createSlideButton(me._cache[index], item.raw.slideButton);
}
}
- }
-
- if (Ext.isFunction(this._cache[index])) {
- this._cache[index]();
+ }
+
+ if (Ext.isFunction(me._cache[index])) {
+ func = me._cache[index];
} else {
- container.setActiveItem(this._cache[index]);
+ func = me.setContainerItem;
+ }
+
+ if (me.__init) {
+ me.fireAction('select', [me , me._cache[index], index], func, me);
}
- if (this.config.closeOnSelect) {
- this.closeContainer(this.config.selectSlideDuration);
+ if (me.config.closeOnSelect) {
+ me.closeContainer(this.config.selectSlideDuration);
}
},
+
+ setContainerItem: function(nav, item) {
+ var container = nav.container;
+ container.setActiveItem(item);
+ },
onContainerDrag: function(draggable, e, offset, eOpts) {
if (offset.x < 1) {
@@ -264,6 +364,7 @@ Ext.define('Ext.ux.slidenavigation.View', {
node = e.target;
while (node = node.parentNode) {
if (node.className && node.className.indexOf(this.config.slideSelector) > -1) {
+ this.fireEvent('dragstart', this);
return true;
}
}
@@ -276,18 +377,20 @@ Ext.define('Ext.ux.slidenavigation.View', {
var velocity = Math.abs(e.deltaX / e.deltaTime),
direction = (e.deltaX > 0) ? "right" : "left",
offset = Ext.clone(draggable.offset),
- threshold = parseInt(this.config.list.width * .70);
+ threshold = parseInt(this.config.list.minWidth * .70);
switch (direction) {
case "right":
- offset.x = (velocity > 0.75 || offset.x > threshold) ? this.config.list.width : 0;
+ offset.x = (velocity > 0.75 || offset.x > threshold) ? this.config.list.minWidth : 0;
break;
case "left":
- offset.x = (velocity > 0.75 || offset.x < threshold) ? 0 : this.config.list.width;
+ offset.x = (velocity > 0.75 || offset.x < threshold) ? 0 : this.config.list.minWidth;
break;
}
+
+ this.fireEvent('dragend', this);
- this.moveContainer(offset.x);
+ this.moveContainer(this, offset.x);
},
/**
@@ -328,17 +431,25 @@ Ext.define('Ext.ux.slidenavigation.View', {
* Closes the container. See ``moveContainer`` for more details.
*/
closeContainer: function(duration) {
- var duration = duration || this.config.slideDuration;
- this.moveContainer(0, duration);
+ var me = this,
+ duration = duration || this.config.slideDuration;
+
+ if (me.__init) {
+ me.fireAction('close', [me, 0, duration], 'moveContainer', me);
+ }
},
/**
* Opens the container. See ``moveContainer`` for more details.
*/
openContainer: function(duration) {
- var duration = duration || this.config.slideDuration;
- this.container.addCls('open');
- this.moveContainer(this.config.list.width, duration);
+ var me = this,
+ duration = duration || this.config.slideDuration,
+ offsetX = this.config.list.minWidth;
+
+ if (me.__init) {
+ me.fireAction('open', [me, offsetX, duration], 'moveContainer', me);
+ }
},
toggleContainer: function(duration) {
@@ -357,10 +468,14 @@ Ext.define('Ext.ux.slidenavigation.View', {
* number of milliseconds to animate the slide effect. If no duration is
* provided, the default in ``config.slideDuration`` is used.
*/
- moveContainer: function(offsetX, duration) {
- var duration = duration || this.config.slideDuration,
+ moveContainer: function(nav, offsetX, duration) {
+ var duration = duration || this.config.slideDuration,
draggable = this.container.draggableBehavior.draggable;
+ if (offsetX > 0) {
+ this.container.addCls('open');
+ }
+
draggable.setOffset(offsetX, 0, {
duration: duration
});
@@ -373,6 +488,10 @@ Ext.define('Ext.ux.slidenavigation.View', {
isClosed: function() {
return (this.container.draggableBehavior.draggable.offset.x == 0);
},
+
+ isOpened: function() {
+ return (this.container.draggableBehavior.draggable.offset.x == this.config.list.minWidth);
+ },
/**
* Sets the container as being closed. This shouldn't ever be called
@@ -389,7 +508,7 @@ Ext.define('Ext.ux.slidenavigation.View', {
if (closed) {
this.container.removeCls('open');
-
+
/*
Ext.each(this.container.getActiveItem().getItems().items, function(item) {
if (item.maskOnSlide) {
@@ -399,6 +518,7 @@ Ext.define('Ext.ux.slidenavigation.View', {
*/
} else {
this.container.addCls('open');
+
/*
Ext.each(this.container.getActiveItem().getItems().items, function(item) {
if (item.maskOnSlide) {
@@ -414,12 +534,24 @@ Ext.define('Ext.ux.slidenavigation.View', {
* the navigation items.
*/
createNavigationList: function(store) {
- return Ext.create('Ext.dataview.List', Ext.merge({}, this.config.list, {
+ var listConfig = this.getList();
+
+ // The width of the list needs to be set to 100%, so we copy
+ // the width value (if set) to minWidth and then delete it.
+ if (listConfig.width) {
+ if (!listConfig.minWidth) {
+ listConfig.minWidth = listConfig.width;
+ }
+ delete listConfig.width;
+ }
+
+ return Ext.create('Ext.dataview.List', Ext.merge({}, listConfig, {
store: this.store,
docked: 'left',
cls: 'x-slidenavigation-list',
style: 'position: absolute; top: 0; left: 0; height: 100%;' +
- 'width: 100% !important; z-index: 2',
+ 'z-index: 2',
+ width: '100%',
listeners: {
select: this.onSelect,
scope: this
@@ -433,7 +565,9 @@ Ext.define('Ext.ux.slidenavigation.View', {
* the navigation list.
*/
createContainer: function() {
- return Ext.create('Ext.Container', Ext.merge({}, this.config.container, {
+ var me = this;
+
+ return Ext.create('Ext.Container', Ext.merge({}, me.config.container, {
docked: 'left',
cls: 'x-slidenavigation-container',
style: 'width: 100%; height: 100%; position: absolute; opacity: 1; z-index: 5',
@@ -442,26 +576,42 @@ Ext.define('Ext.ux.slidenavigation.View', {
direction: 'horizontal',
constraint: {
min: { x: 0, y: 0 },
- max: { x: this.config.list.maxDrag || Math.max(screen.width, screen.height), y: 0 }
+ max: { x: me.config.list.maxDrag || Math.max(screen.width, screen.height), y: 0 }
},
listeners: {
dragstart: {
- fn: this.onContainerDragstart,
+ fn: me.onContainerDragstart,
order: 'before',
- scope: this
+ scope: me
},
- drag: Ext.Function.createThrottled(this.onContainerDrag, 100, this),
- dragend: this.onContainerDragend,
- scope: this
+ drag: Ext.Function.createThrottled(me.onContainerDrag, 100, me),
+ dragend: me.onContainerDragend,
+ scope: me
},
translatable: {
listeners: {
+ animationstart: function() {
+ me.fireEvent('slidestart', me);
+ },
animationend: function(translatable, b, c) {
+ // Fire the event now that the animation is done.
+ if (me.__init) {
+ me.fireEvent('slideend', me);
+ }
+
+ if (me.isOpened()) {
+ me.fireEvent('opened', me);
+ }
+
+ else if (me.isClosed()) {
+ me.fireEvent('closed', me);
+ }
+
// Remove the class when the animation is finished, but only
// if we're "closed"
- this.setClosed(this.isClosed());
+ me.setClosed(me.isClosed());
},
- scope: this // The "x-slidenavigation" container
+ scope: me // The "x-slidenavigation" container
}
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.