Sfoglia il codice sorgente

interaction classes for EventDragging/EventResizing

Adam Shaw 8 anni fa
parent
commit
14b0d7b52c

+ 1 - 1
src.json

@@ -22,11 +22,11 @@
     "common/MouseFollower.js",
     "common/ChronoComponent.js",
     "common/EventPointing.js",
-    "common/CoordChronoComponentMixin.js",
     "common/CoordChronoComponentMixin.day-click.js",
     "common/CoordChronoComponentMixin.day-selection.js",
     "common/CoordChronoComponentMixin.event-dragging.js",
     "common/CoordChronoComponentMixin.event-resizing.js",
+    "common/CoordChronoComponentMixin.js",
     "common/CoordChronoComponentMixin.external-dropping.js",
     "common/FillSystem.js",
     "common/EventRenderUtils.js",

+ 6 - 8
src/common/CoordChronoComponentMixin.day-click.js

@@ -8,7 +8,7 @@ var DateClicking = Class.extend({
 
 	/*
 	component must implement:
-		- bindDayHandler
+		- bindDateHandlerToEl
 		- registerDragListener
 		- getSafeHitFootprint
 		- getHitEl
@@ -16,9 +16,9 @@ var DateClicking = Class.extend({
 	constructor: function(component) {
 		this.view = component.view;
 		this.component = component;
-		this.dragListener = this.buildDragListener();
 
-		this.bind();
+		this.dragListener = this.buildDragListener();
+		component.registerDragListener(this.dragListener);
 	},
 
 
@@ -27,23 +27,21 @@ var DateClicking = Class.extend({
 	},
 
 
-	bind: function() {
+	bindToEl: function(el) {
 		var component = this.component;
 		var dragListener = this.dragListener;
 
-		component.bindDayHandler('mousedown', function(ev) {
+		component.bindDateHandlerToEl(el, 'mousedown', function(ev) {
 			if (!component.shouldIgnoreMouse()) {
 				dragListener.startInteraction(ev);
 			}
 		});
 
-		component.bindDayHandler('touchstart', function(ev) {
+		component.bindDateHandlerToEl(el, 'touchstart', function(ev) {
 			if (!component.shouldIgnoreTouch()) {
 				dragListener.startInteraction(ev);
 			}
 		});
-
-		component.registerDragListener(dragListener);
 	},
 
 

+ 7 - 9
src/common/CoordChronoComponentMixin.day-selection.js

@@ -8,7 +8,7 @@ var DateSelecting = Class.extend({
 
 	/*
 	component must implement:
-		- bindDayHandler
+		- bindDateHandlerToEl
 		- registerDragListener
 		- getSafeHitFootprint
 		- renderHighlight
@@ -17,9 +17,9 @@ var DateSelecting = Class.extend({
 	constructor: function(component) {
 		this.component = component;
 		this.view = component.view;
-		this.dragListener = this.buildDragListener();
 
-		this.bind();
+		this.dragListener = this.buildDragListener();
+		component.registerDragListener(this.dragListener);
 	},
 
 
@@ -39,12 +39,12 @@ var DateSelecting = Class.extend({
 	},
 
 
-	bind: function() {
+	bindToEl: function(el) {
 		var _this = this;
 		var component = this.component;
 		var dragListener = this.dragListener;
 
-		component.bindDayHandler('mousedown', function(ev) {
+		component.bindDateHandlerToEl(el, 'mousedown', function(ev) {
 			if (_this.opt('selectable') && !component.shouldIgnoreMouse()) {
 				dragListener.startInteraction(ev, {
 					distance: _this.opt('selectMinDistance')
@@ -52,7 +52,7 @@ var DateSelecting = Class.extend({
 			}
 		});
 
-		component.bindDayHandler('touchstart', function(ev) {
+		component.bindDateHandlerToEl(el, 'touchstart', function(ev) {
 			if (_this.opt('selectable') && !component.shouldIgnoreTouch()) {
 				dragListener.startInteraction(ev, {
 					delay: _this.getDelay()
@@ -60,9 +60,7 @@ var DateSelecting = Class.extend({
 			}
 		});
 
-		preventSelection(component.el);
-
-		component.registerDragListener(dragListener);
+		preventSelection(el);
 	},
 
 

+ 125 - 21
src/common/CoordChronoComponentMixin.event-dragging.js

@@ -1,18 +1,118 @@
 
-/*
-Wired up by calling
-buildSegDragListener
-*/
-$.extend(CoordChronoComponentMixin, {
+var EventDragging = Class.extend({
+
+	view: null,
+	component: null,
+	dragListener: null,
+	isDragging: false,
+
+
+	/*
+	component impements:
+		- bindSegHandlerToEl
+		- registerDragListener
+		- unregisterDragListener
+		- publiclyTrigger
+		- diffDates
+		- eventRangesToEventFootprints
+		- isEventInstanceGroupAllowed
+		- eventPointing (!)
+	*/
+	constructor: function(component) {
+		this.view = component._getView();
+		this.component = component;
+	},
+
+
+	opt: function(name) {
+		return this.view.opt(name);
+	},
+
+
+	getSelectionDelay: function() {
+		var delay = this.opt('eventLongPressDelay');
+
+		if (delay == null) {
+			delay = this.opt('longPressDelay'); // fallback
+		}
+
+		return delay;
+	},
+
+
+	bindToEl: function(el) {
+		var component = this.component;
+
+		component.bindSegHandlerToEl(el, 'mousedown', this.handleMousedown.bind(this));
+		component.bindSegHandlerToEl(el, 'touchstart', this.handleTouchStart.bind(this));
+	},
+
 
-	isDraggingSeg: false, // is a segment being dragged? boolean
+	handleMousedown: function(seg, ev) {
+		if (this.component.canStartDrag(seg, ev)) {
+			this.buildDragListener(seg).startInteraction(ev, { distance: 5 });
+		}
+	},
+
+
+	handleTouchStart: function(seg, ev) {
+		var component = this.component;
+		var settings = {
+			delay: this.view.isEventDefSelected(seg.footprint.eventDef) ? // already selected?
+				0 : this.getSelectionDelay()
+		};
+
+		if (component.canStartDrag(seg, ev)) {
+			this.buildDragListener(seg).startInteraction(ev, settings);
+		}
+		else if (component.canStartSelection(seg, ev)) {
+			this.buildSelectListener(seg).startInteraction(ev, settings);
+		}
+	},
+
+
+	// seg isn't draggable, but let's use a generic DragListener
+	// simply for the delay, so it can be selected.
+	// Has side effect of setting/unsetting `dragListener`
+	buildSelectListener: function(seg) {
+		var _this = this;
+		var view = this.view;
+		var eventDef = seg.footprint.eventDef;
+		var eventInstance = seg.footprint.eventInstance; // null for inverse-background events
+
+		if (this.dragListener) {
+			return this.dragListener;
+		}
+
+		var dragListener = this.dragListener = new DragListener({
+			dragStart: function(ev) {
+				if (
+					dragListener.isTouch &&
+					!view.isEventDefSelected(eventDef) &&
+					eventInstance
+				) {
+					// if not previously selected, will fire after a delay. then, select the event
+					view.selectEventInstance(eventInstance);
+				}
+			},
+			interactionEnd: function(ev) {
+				_this.dragListener = null;
+				_this.component.unregisterDragListener(dragListener);
+			}
+		});
+
+		this.component.registerDragListener(dragListener);
+
+		return dragListener;
+	},
 
 
 	// Builds a listener that will track user-dragging on an event segment.
 	// Generic enough to work with any type of Grid.
-	// Has side effect of setting/unsetting `segDragListener`
-	buildSegDragListener: function(seg) {
+	// Has side effect of setting/unsetting `dragListener`
+	buildDragListener: function(seg) {
 		var _this = this;
+		var component = this.component;
 		var view = this.view;
 		var calendar = view.calendar;
 		var eventManager = calendar.eventManager;
@@ -23,18 +123,18 @@ $.extend(CoordChronoComponentMixin, {
 		var mouseFollower; // A clone of the original element that will move with the mouse
 		var eventDefMutation;
 
-		if (this.segDragListener) {
-			return this.segDragListener;
+		if (this.dragListener) {
+			return this.dragListener;
 		}
 
 		// Tracks mouse movement over the *view's* coordinate map. Allows dragging and dropping between subcomponents
 		// of the view.
-		var dragListener = this.segDragListener = new HitDragListener(view, {
+		var dragListener = this.dragListener = new HitDragListener(view, {
 			scroll: this.opt('dragScroll'),
 			subjectEl: el,
 			subjectCenter: true,
 			interactionStart: function(ev) {
-				seg.component = _this; // for renderDrag
+				seg.component = component; // for renderDrag
 				isDragging = false;
 				mouseFollower = new MouseFollower(seg.el, {
 					additionalClass: 'fc-dragging',
@@ -59,7 +159,7 @@ $.extend(CoordChronoComponentMixin, {
 
 				// ensure a mouseout on the manipulated event has been reported
 				// TODO: okay to call this?
-				_this.eventPointing.handleMouseout(seg, ev);
+				component.eventPointing.handleMouseout(seg, ev);
 
 				_this.segDragStart(seg, ev);
 				view.hideEventsWithId(eventDef.id); // hide all event segments. our mouseFollower will take over
@@ -88,7 +188,7 @@ $.extend(CoordChronoComponentMixin, {
 							eventDef.id,
 							eventDefMutation
 						);
-						isAllowed = _this.isEventInstanceGroupAllowed(mutatedEventInstanceGroup);
+						isAllowed = component.isEventInstanceGroupAllowed(mutatedEventInstanceGroup);
 					}
 					else {
 						isAllowed = false;
@@ -107,7 +207,7 @@ $.extend(CoordChronoComponentMixin, {
 				if (
 					eventDefMutation &&
 					(dragHelperEls = view.renderDrag(
-						_this.eventRangesToEventFootprints(
+						component.eventRangesToEventFootprints(
 							mutatedEventInstanceGroup.sliceRenderRanges(view.renderUnzonedRange, calendar)
 						),
 						seg
@@ -155,18 +255,22 @@ $.extend(CoordChronoComponentMixin, {
 						view.showEventsWithId(eventDef.id);
 					}
 				});
-				_this.segDragListener = null;
+
+				_this.dragListener = null;
+				component.unregisterDragListener(dragListener);
 			}
 		});
 
+		component.registerDragListener(dragListener);
+
 		return dragListener;
 	},
 
 
 	// Called before event segment dragging starts
 	segDragStart: function(seg, ev) {
-		this.isDraggingSeg = true;
-		this.publiclyTrigger('eventDragStart', {
+		this.isDragging = true;
+		this.component.publiclyTrigger('eventDragStart', {
 			context: seg.el[0],
 			args: [
 				seg.footprint.getEventLegacy(),
@@ -180,8 +284,8 @@ $.extend(CoordChronoComponentMixin, {
 
 	// Called after event segment dragging stops
 	segDragStop: function(seg, ev) {
-		this.isDraggingSeg = false;
-		this.publiclyTrigger('eventDragStop', {
+		this.isDragging = false;
+		this.component.publiclyTrigger('eventDragStop', {
 			context: seg.el[0],
 			args: [
 				seg.footprint.getEventLegacy(),
@@ -216,7 +320,7 @@ $.extend(CoordChronoComponentMixin, {
 			}
 		}
 
-		dateDelta = this.diffDates(date1, date0);
+		dateDelta = this.component.diffDates(date1, date0);
 
 		dateMutation = new EventDefDateMutation();
 		dateMutation.clearEnd = clearEnd;

+ 72 - 47
src/common/CoordChronoComponentMixin.event-resizing.js

@@ -1,30 +1,64 @@
 
-/*
-Wired up by calling
-startSegResize
-*/
-$.extend(CoordChronoComponentMixin, {
-
-	isResizingSeg: false, // is a segment being resized? boolean
-
-
-	// returns boolean whether resizing actually started or not.
-	// assumes the seg allows resizing.
-	// `dragOptions` are optional.
-	startSegResize: function(seg, ev, dragOptions) {
-		if ($(ev.target).is('.fc-resizer')) {
-			this.buildSegResizeListener(seg, $(ev.target).is('.fc-start-resizer'))
-				.startInteraction(ev, dragOptions);
-			return true;
+var EventResizing = Class.extend({
+
+	view: null,
+	component: null,
+	dragListener: null,
+	isResizing: false,
+
+
+	/*
+	component impements:
+		- bindSegHandlerToEl
+		- registerDragListener
+		- unregisterDragListener
+		- publiclyTrigger
+		- diffDates
+		- eventRangesToEventFootprints
+		- isEventInstanceGroupAllowed
+		- getSafeHitFootprint
+		- eventPointing (!)
+	*/
+	constructor: function(component) {
+		this.view = component._getView();
+		this.component = component;
+	},
+
+
+	opt: function(name) {
+		return this.view.opt(name);
+	},
+
+
+	bindToEl: function(el) {
+		var component = this.component;
+
+		component.bindSegHandlerToEl(el, 'mousedown', this.handleMouseDown.bind(this));
+		component.bindSegHandlerToEl(el, 'touchstart', this.handleTouchStart.bind(this));
+	},
+
+
+	handleMouseDown: function(seg, ev) {
+		if (this.component.canStartResize(seg, ev)) {
+			this.buildDragListener(seg, $(ev.target).is('.fc-start-resizer'))
+				.startInteraction(ev, { distance: 5 });
+		}
+	},
+
+
+	handleTouchStart: function(seg, ev) {
+		if (this.component.canStartResize(seg, ev)) {
+			this.buildDragListener(seg, $(ev.target).is('.fc-start-resizer'))
+				.startInteraction(ev);
 		}
-		return false;
 	},
 
 
 	// Creates a listener that tracks the user as they resize an event segment.
 	// Generic enough to work with any type of Grid.
-	buildSegResizeListener: function(seg, isStart) {
+	buildDragListener: function(seg, isStart) {
 		var _this = this;
+		var component = this.component;
 		var view = this.view;
 		var calendar = view.calendar;
 		var eventManager = calendar.eventManager;
@@ -35,7 +69,7 @@ $.extend(CoordChronoComponentMixin, {
 		var resizeMutation; // zoned event date properties. falsy if invalid resize
 
 		// Tracks mouse movement over the *grid's* coordinate map
-		var dragListener = this.segResizeListener = new HitDragListener(this, {
+		var dragListener = this.dragListener = new HitDragListener(component, {
 			scroll: this.opt('dragScroll'),
 			subjectEl: el,
 			interactionStart: function() {
@@ -46,14 +80,14 @@ $.extend(CoordChronoComponentMixin, {
 
 				// ensure a mouseout on the manipulated event has been reported
 				// TODO: okay to call this?
-				_this.eventPointing.handleMouseout(seg, ev);
+				component.eventPointing.handleMouseout(seg, ev);
 
 				_this.segResizeStart(seg, ev);
 			},
 			hitOver: function(hit, isOrig, origHit) {
 				var isAllowed = true;
-				var origHitFootprint = _this.getSafeHitFootprint(origHit);
-				var hitFootprint = _this.getSafeHitFootprint(hit);
+				var origHitFootprint = component.getSafeHitFootprint(origHit);
+				var hitFootprint = component.getSafeHitFootprint(hit);
 				var mutatedEventInstanceGroup;
 
 				if (origHitFootprint && hitFootprint) {
@@ -66,7 +100,7 @@ $.extend(CoordChronoComponentMixin, {
 							eventDef.id,
 							resizeMutation
 						);
-						isAllowed = _this.isEventInstanceGroupAllowed(mutatedEventInstanceGroup);
+						isAllowed = component.isEventInstanceGroupAllowed(mutatedEventInstanceGroup);
 					}
 					else {
 						isAllowed = false;
@@ -88,8 +122,8 @@ $.extend(CoordChronoComponentMixin, {
 				if (resizeMutation) {
 					view.hideEventsWithId(eventDef.id);
 
-					_this.renderEventResize(
-						_this.eventRangesToEventFootprints(
+					component.renderEventResize(
+						component.eventRangesToEventFootprints(
 							mutatedEventInstanceGroup.sliceRenderRanges(view.renderUnzonedRange, calendar)
 						),
 						seg
@@ -101,7 +135,7 @@ $.extend(CoordChronoComponentMixin, {
 				view.showEventsWithId(eventDef.id); // for when out-of-bounds. show original
 			},
 			hitDone: function() { // resets the rendering to show the original event
-				_this.unrenderEventResize();
+				component.unrenderEventResize();
 				enableCursor();
 			},
 			interactionEnd: function(ev) {
@@ -116,18 +150,22 @@ $.extend(CoordChronoComponentMixin, {
 				else {
 					view.showEventsWithId(eventDef.id);
 				}
-				_this.segResizeListener = null;
+
+				_this.dragListener = null;
+				component.unregisterDragListener(dragListener);
 			}
 		});
 
+		component.registerDragListener(dragListener);
+
 		return dragListener;
 	},
 
 
 	// Called before event segment resizing starts
 	segResizeStart: function(seg, ev) {
-		this.isResizingSeg = true;
-		this.publiclyTrigger('eventResizeStart', {
+		this.isResizing = true;
+		this.component.publiclyTrigger('eventResizeStart', {
 			context: seg.el[0],
 			args: [
 				seg.footprint.getEventLegacy(),
@@ -141,8 +179,8 @@ $.extend(CoordChronoComponentMixin, {
 
 	// Called after event segment resizing stops
 	segResizeStop: function(seg, ev) {
-		this.isResizingSeg = false;
-		this.publiclyTrigger('eventResizeStop', {
+		this.isResizing = false;
+		this.component.publiclyTrigger('eventResizeStop', {
 			context: seg.el[0],
 			args: [
 				seg.footprint.getEventLegacy(),
@@ -157,7 +195,7 @@ $.extend(CoordChronoComponentMixin, {
 	// Returns new date-information for an event segment being resized from its start
 	computeEventStartResizeMutation: function(startFootprint, endFootprint, origEventFootprint) {
 		var origRange = origEventFootprint.componentFootprint.unzonedRange;
-		var startDelta = this.diffDates(
+		var startDelta = this.component.diffDates(
 			endFootprint.unzonedRange.getStart(),
 			startFootprint.unzonedRange.getStart()
 		);
@@ -182,7 +220,7 @@ $.extend(CoordChronoComponentMixin, {
 	// Returns new date-information for an event segment being resized from its end
 	computeEventEndResizeMutation: function(startFootprint, endFootprint, origEventFootprint) {
 		var origRange = origEventFootprint.componentFootprint.unzonedRange;
-		var endDelta = this.diffDates(
+		var endDelta = this.component.diffDates(
 			endFootprint.unzonedRange.getEnd(),
 			startFootprint.unzonedRange.getEnd()
 		);
@@ -201,19 +239,6 @@ $.extend(CoordChronoComponentMixin, {
 		}
 
 		return false;
-	},
-
-
-	// Renders a visual indication of an event being resized.
-	// Must return elements used for any mock events.
-	renderEventResize: function(eventFootprints, seg) {
-		// subclasses must implement
-	},
-
-
-	// Unrenders a visual indication of an event being resized.
-	unrenderEventResize: function() {
-		// subclasses must implement
 	}
 
 });

+ 64 - 97
src/common/CoordChronoComponentMixin.js

@@ -9,8 +9,6 @@ var CoordChronoComponentMixin = {
 	// TODO: port isTimeScale into same system?
 	largeUnit: null,
 
-	segDragListener: null,
-	segResizeListener: null,
 	externalDragListener: null,
 
 	hitsNeededDepth: 0, // necessary because multiple callers might need the same hits
@@ -23,6 +21,12 @@ var CoordChronoComponentMixin = {
 	eventPointingClass: EventPointing,
 	eventPointing: null,
 
+	eventDraggingClass: EventDragging,
+	eventDragging: null,
+
+	eventResizingClass: EventResizing,
+	eventResizing: null,
+
 
 	initCoordChronoComponent: function() {
 		this.dragListeners = [];
@@ -53,12 +57,6 @@ var CoordChronoComponentMixin = {
 		}
 
 		// TODO: get these to start using registerDragListener()
-		if (this.segDragListener) {
-			this.segDragListener.endInteraction(); // will clear this.segDragListener
-		}
-		if (this.segResizeListener) {
-			this.segResizeListener.endInteraction(); // will clear this.segResizeListener
-		}
 		if (this.externalDragListener) {
 			this.externalDragListener.endInteraction(); // will clear this.externalDragListener
 		}
@@ -75,16 +73,15 @@ var CoordChronoComponentMixin = {
 		ChronoComponent.prototype.setElement.apply(this, arguments);
 
 		if (this.hasDayInteractions) {
-			new DateClicking(this);
-			new DateSelecting(this);
+			new DateClicking(this).bindToEl(this.el);
+			new DateSelecting(this).bindToEl(this.el);
 		}
 
 		this.eventPointing = new this.eventPointingClass(this);
+		this.eventDragging = new this.eventDraggingClass(this);
+		this.eventResizing = new this.eventResizingClass(this);
 
-		// for NON-EventPointing interactions.....
-		// attach event-element-related handlers. in Grid.events
-		// same garbage collection note as above.
-		this.bindSegHandlersToEl(this.el);
+		this.bindAllSegHandlersToEl(this.el);
 	},
 
 
@@ -127,8 +124,7 @@ var CoordChronoComponentMixin = {
 	},
 
 
-	// TODO: move this into Day*Pointing* ?
-	bindDayHandler: function(name, handler) {
+	bindDateHandlerToEl: function(el, name, handler) {
 		var _this = this;
 
 		// attach a handler to the grid's root element.
@@ -148,13 +144,6 @@ var CoordChronoComponentMixin = {
 	},
 
 
-	// Attaches event-element-related handlers to an arbitrary container element. leverages bubbling.
-	bindSegHandlersToEl: function(el) {
-		this.bindSegHandlerToEl(el, 'touchstart', this.handleSegTouchStart);
-		this.bindSegHandlerToEl(el, 'mousedown', this.handleSegMousedown);
-	},
-
-
 	bindSegHandlerToEl: function(el, name, handler) {
 		var _this = this;
 
@@ -168,80 +157,73 @@ var CoordChronoComponentMixin = {
 	},
 
 
+	bindAllSegHandlersToEl: function(el) {
+		this.eventPointing.bindToEl(el);
+		this.eventDragging.bindToEl(el);
+		this.eventResizing.bindToEl(el);
+	},
+
+
 	shouldIgnoreMouse: function() {
 		// HACK
-		// This will still work even though bindDayHandler doesn't use GlobalEmitter.
+		// This will still work even though bindDateHandlerToEl doesn't use GlobalEmitter.
 		return GlobalEmitter.get().shouldIgnoreMouse();
 	},
 
 
 	shouldIgnoreTouch: function() {
+		var view = this._getView();
+
 		// On iOS (and Android?) when a new selection is initiated overtop another selection,
 		// the touchend never fires because the elements gets removed mid-touch-interaction (my theory).
 		// HACK: simply don't allow this to happen.
 		// ALSO: prevent selection when an *event* is already raised.
-		return this.view.isSelected || this.view.selectedEvent;
+		return view.isSelected || view.selectedEvent;
 	},
 
 
 	shouldIgnoreEventPointing: function() {
 		// only call the handlers if there is not a drag/resize in progress
-		return this.isDraggingSeg || this.isResizingSeg;
-	},
 
-
-	registerDragListener: function(dragListener) {
-		this.dragListeners.push(dragListener);
+		return this.eventDragging.isDragging || this.eventResizing.isResizing;
 	},
 
 
-	/* Handlers
-	------------------------------------------------------------------------------------------------------------------*/
+	canStartSelection: function(seg, ev) {
+		var view = this._getView();
+
+		return getEvIsTouch(ev) &&
+			!this.canStartResize(seg, ev) &&
+			(view.isEventDefDraggable(seg.footprint.eventDef) ||
+			 view.isEventDefResizable(seg.footprint.eventDef));
+	},
 
 
-	handleSegMousedown: function(seg, ev) {
+	canStartDrag: function(seg, ev) {
 		var view = this._getView();
-		var isResizing = this.startSegResize(seg, ev, { distance: 5 });
 
-		if (!isResizing && view.isEventDefDraggable(seg.footprint.eventDef)) {
-			this.buildSegDragListener(seg)
-				.startInteraction(ev, {
-					distance: 5
-				});
-		}
+		return !this.canStartResize(seg, ev) &&
+			view.isEventDefDraggable(seg.footprint.eventDef);
 	},
 
 
-	handleSegTouchStart: function(seg, ev) {
+	canStartResize: function(seg, ev) {
 		var view = this._getView();
 		var eventDef = seg.footprint.eventDef;
-		var isSelected = view.isEventDefSelected(eventDef);
-		var isDraggable = view.isEventDefDraggable(eventDef);
-		var isResizable = view.isEventDefResizable(eventDef);
-		var isResizing = false;
-		var dragListener;
-		var eventLongPressDelay;
-
-		if (isSelected && isResizable) {
-			// only allow resizing of the event is selected
-			isResizing = this.startSegResize(seg, ev);
-		}
 
-		if (!isResizing && (isDraggable || isResizable)) { // allowed to be selected?
+		return (!getEvIsTouch(ev) || view.isEventDefSelected(eventDef)) &&
+			view.isEventDefResizable(eventDef) &&
+			$(ev.target).is('.fc-resizer');
+	},
 
-			eventLongPressDelay = this.opt('eventLongPressDelay');
-			if (eventLongPressDelay == null) {
-				eventLongPressDelay = this.opt('longPressDelay'); // fallback
-			}
 
-			dragListener = isDraggable ?
-				this.buildSegDragListener(seg) :
-				this.buildSegSelectListener(seg); // seg isn't draggable, but still needs to be selected
+	registerDragListener: function(dragListener) {
+		this.dragListeners.push(dragListener);
+	},
 
-			dragListener.startInteraction(ev, { // won't start if already started
-				delay: isSelected ? 0 : eventLongPressDelay // do delay if not already selected
-			});
-		}
+
+	unregisterDragListener: function(dragListener) {
+		removeExact(this.dragListeners, dragListener);
 	},
 
 
@@ -249,39 +231,6 @@ var CoordChronoComponentMixin = {
 	------------------------------------------------------------------------------------------------------------------*/
 
 
-	// seg isn't draggable, but let's use a generic DragListener
-	// simply for the delay, so it can be selected.
-	// Has side effect of setting/unsetting `segDragListener`
-	buildSegSelectListener: function(seg) {
-		var _this = this;
-		var view = this._getView();
-		var eventDef = seg.footprint.eventDef;
-		var eventInstance = seg.footprint.eventInstance; // null for inverse-background events
-
-		if (this.segDragListener) {
-			return this.segDragListener;
-		}
-
-		var dragListener = this.segDragListener = new DragListener({
-			dragStart: function(ev) {
-				if (
-					dragListener.isTouch &&
-					!view.isEventDefSelected(eventDef) &&
-					eventInstance
-				) {
-					// if not previously selected, will fire after a delay. then, select the event
-					view.selectEventInstance(eventInstance);
-				}
-			},
-			interactionEnd: function(ev) {
-				_this.segDragListener = null;
-			}
-		});
-
-		return dragListener;
-	},
-
-
 	// is it allowed, in relation to the view's validRange?
 	// NOTE: very similar to isExternalInstanceGroupAllowed
 	isEventInstanceGroupAllowed: function(eventInstanceGroup) {
@@ -365,6 +314,24 @@ var CoordChronoComponentMixin = {
 	},
 
 
+	// Event Resizing
+	// ---------------------------------------------------------------------------------------------------------------
+	// TODO: why not move this to ChronoComponent
+
+
+	// Renders a visual indication of an event being resized.
+	// Must return elements used for any mock events.
+	renderEventResize: function(eventFootprints, seg) {
+		// subclasses must implement
+	},
+
+
+	// Unrenders a visual indication of an event being resized.
+	unrenderEventResize: function() {
+		// subclasses must implement
+	},
+
+
 	/* Selection
 	------------------------------------------------------------------------------------------------------------------*/
 

+ 1 - 2
src/common/DayGrid.limit.js

@@ -290,8 +290,7 @@ DayGrid.mixin({
 
 		// the popover doesn't live within the grid's container element, and thus won't get the event
 		// delegated-handlers for free. attach event-related handlers to the popover.
-		this.bindSegHandlersToEl(this.segPopover.el); // TODO: eventually remove!
-		this.eventPointing.bindToEl(this.segPopover.el);
+		this.bindAllSegHandlersToEl(this.segPopover.el);
 	},