From ba56bb983fc727c42dfbd02d98b9aeadd10ea5c8 Mon Sep 17 00:00:00 2001 From: MGMsystems Date: Wed, 4 Jun 2014 13:41:56 +0200 Subject: [PATCH] feat(ionSideMenu): add `edge-drag-threshold`, delegate `edgeDragThreshold()` Closes #1570 --- js/angular/controller/sideMenuController.js | 14 +++++++++++++ js/angular/directive/sideMenuContent.js | 14 ++++++++++++- js/angular/service/sideMenuDelegate.js | 12 ++++++++++- js/controllers/sideMenuController.js | 22 +++++++++++++++++++-- test/html/sideMenu.html | 2 +- 5 files changed, 59 insertions(+), 5 deletions(-) diff --git a/js/angular/controller/sideMenuController.js b/js/angular/controller/sideMenuController.js index c75bfe8010..9e4bdfc80d 100644 --- a/js/angular/controller/sideMenuController.js +++ b/js/angular/controller/sideMenuController.js @@ -9,6 +9,7 @@ function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform) { extend(this, ionic.controllers.SideMenuController.prototype); this.$scope = $scope; + this.dragThreshold = 25; ionic.controllers.SideMenuController.call(this, { left: { width: 275 }, @@ -22,6 +23,19 @@ function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform) { return $scope.dragContent; }; + this.dragThreshold = 25; + this.edgeDragThreshold = function(value) { + if (arguments.length) { + if (angular.isNumber(value) && value > 0) { + this.dragThreshold = value; + this.dragOnlyEdge = true; + } else { + this.dragOnlyEdge = !!value; + } + } + return this.dragOnlyEdge; + }; + this.isDraggableTarget = function(e) { return $scope.dragContent && (!e.gesture.srcEvent.defaultPrevented && diff --git a/js/angular/directive/sideMenuContent.js b/js/angular/directive/sideMenuContent.js index 168d15cb5c..3bdccf64ca 100644 --- a/js/angular/directive/sideMenuContent.js +++ b/js/angular/directive/sideMenuContent.js @@ -12,6 +12,7 @@ * @usage * ```html * * * ``` @@ -19,6 +20,10 @@ * {@link ionic.directive:ionSideMenus} documentation. * * @param {boolean=} drag-content Whether the content can be dragged. Default true. + * @param {boolean|number=} edge-drag-threshold Whether the content drag can only start if it is below a certain threshold distance from the edge of the screen. Default false. Accepts three types of values: + * - If a non-zero number is given, that many pixels is used as the maximum allowed distance from the edge that starts dragging the side menu. + * - If true is given, the default number of pixels (25) is used as the maximum allowed distance. + * - If false or 0 is given, the edge drag threshold is disabled, and dragging from anywhere on the content is allowed. * */ IonicModule @@ -37,7 +42,7 @@ function($timeout, $ionicGesture) { $element.addClass('menu-content pane'); - if (angular.isDefined(attr.dragContent)) { + if (isDefined(attr.dragContent)) { $scope.$watch(attr.dragContent, function(value) { sideMenuCtrl.canDragContent(value); }); @@ -45,6 +50,12 @@ function($timeout, $ionicGesture) { sideMenuCtrl.canDragContent(true); } + if (isDefined(attr.edgeDragThreshold)) { + $scope.$watch(attr.edgeDragThreshold, function(value) { + sideMenuCtrl.edgeDragThreshold(value); + }); + } + var defaultPrevented = false; var isDragging = false; @@ -87,6 +98,7 @@ function($timeout, $ionicGesture) { var releaseGesture = $ionicGesture.on('release', dragReleaseFn, $element); sideMenuCtrl.setContent({ + element: element[0], onDrag: function(e) {}, endDrag: function(e) {}, getTranslateX: function() { diff --git a/js/angular/service/sideMenuDelegate.js b/js/angular/service/sideMenuDelegate.js index 728833592e..6bbfee97c4 100644 --- a/js/angular/service/sideMenuDelegate.js +++ b/js/angular/service/sideMenuDelegate.js @@ -89,7 +89,17 @@ IonicModule * side menus. * @returns {boolean} Whether the content can be dragged to open side menus. */ - 'canDragContent' + 'canDragContent', + /** + * @ngdoc method + * @name $ionicSideMenuDelegate#edgeDragThreshold + * @param {boolean|number=} value Set whether the content drag can only start if it is below a certain threshold distance from the edge of the screen. Accepts three different values: + * - If a non-zero number is given, that many pixels is used as the maximum allowed distance from the edge that starts dragging the side menu. + * - If true is given, the default number of pixels (25) is used as the maximum allowed distance. + * - If false or 0 is given, the edge drag threshold is disabled, and dragging from anywhere on the content is allowed. + * @returns {boolean} Whether the drag can start only from within the edge of screen threshold. + */ + 'edgeDragThreshold', /** * @ngdoc method * @name $ionicSideMenuDelegate#$getByHandle diff --git a/js/controllers/sideMenuController.js b/js/controllers/sideMenuController.js index 36978afd84..4174f2b65e 100644 --- a/js/controllers/sideMenuController.js +++ b/js/controllers/sideMenuController.js @@ -1,7 +1,7 @@ (function(ionic) { 'use strict'; - /** +/** * The SideMenuController is a controller with a left and/or right menu that * can be slid out and toggled. Seen on many an app. * @@ -278,10 +278,28 @@ this._startX = null; this._lastX = null; this._offsetX = null; + this._firstX = null; + this._doDrag = false; }, // Handle a drag event _handleDrag: function(e) { + + //Get the start position of the drag + if (!this._firstX) { + this._firstX = e.gesture.touches[0].pageX; + this.content._cachedWidth = this.content.element.offsetWidth; + } + + //Allow the drag to affect the side if: + // - the side menu is already opened, or + // - there is no edge drag threshold enabled, or + // - the drag is within the edge drag threshold + this._doDrag = this.isOpen() || + !this.edgeDragThreshold() || + this._firstX <= this.dragThreshold || + this._firstX >= this.content._cachedWidth - this.dragThreshold; + // If we don't have start coords, grab and store them if(!this._startX) { this._startX = e.gesture.touches[0].pageX; @@ -292,7 +310,7 @@ } // Calculate difference from the tap points - if(!this._isDragging && Math.abs(this._lastX - this._startX) > this.dragThresholdX) { + if(!this._isDragging && this._doDrag && Math.abs(this._lastX - this._startX) > this.dragThresholdX) { // if the difference is greater than threshold, start dragging using the current // point as the starting point this._startX = this._lastX; diff --git a/test/html/sideMenu.html b/test/html/sideMenu.html index 0dc93dacd4..4e6dab7a75 100644 --- a/test/html/sideMenu.html +++ b/test/html/sideMenu.html @@ -13,7 +13,7 @@ - +

Slide me