blossom
Version:
Modern, Cross-Platform Application Framework
296 lines (233 loc) • 11.8 kB
JavaScript
// ==========================================================================
// Project: SproutCore - JavaScript Application Framework
// Copyright: ©2006-2011 Strobe Inc. and contributors.
// Portions ©2008-2010 Apple Inc. All rights reserved.
// License: Licensed under MIT license (see license.js)
// ==========================================================================
/**
@namespace
A Collection View Delegate is consulted by a SC.CollectionView's to make
policy decisions about certain behaviors such as selection control and
drag and drop. If you need to control other aspects of your data, you may
also want to add the SC.CollectionContent mixin.
To act as a Collection Delegate, just apply this mixin to your class. You
must then set the "delegate" property on the CollectionView to your object.
Alternatively, if no delegate is set on a CollectionView, but the content
implements this mixin, the content object will be used as the delegate
instead.
If you set an ArrayController or its arrangedObjects property as the content
of a CollectionView, the ArrayController will automatically act as the
delegate for the view.
@since SproutCore 1.0
*/
SC.CollectionViewDelegate = {
/**
Used to detect the mixin by SC.CollectionView
*/
isCollectionViewDelegate: true,
// ..........................................................
// SELECTION
//
/**
This method will be called anytime the collection view is about to
change the selection in response to user mouse clicks or keyboard events.
You can use this method to adjust the proposed selection, eliminating any
selected objects that cannot be selected. The default implementation of
this method simply returns the proposed selection.
@param {SC.CollectionView} view the collection view
@param {SC.IndexSet} sel Proposed array of selected objects.
@returns {SC.IndexSet} Actual allow selection index set
*/
collectionViewSelectionForProposedSelection: function(view, sel) {
return sel ;
},
/**
Called by the collection when attempting to select an item. Return the
actual indexes you want to allow to be selected. Return null to disallow
the change. The default allows all selection.
@param {SC.CollectionView} view the view collection view
@param {SC.IndexSet} indexes the indexes to be selected
@param {Boolean} extend true if the indexes will extend existing sel
@returns {SC.IndexSet} allowed index set
*/
collectionViewShouldSelectIndexes: function (view, indexes, extend) {
return indexes;
},
/**
Called by the collection when attempting to deselect an item. Return the
actual indexes you want to allow to be deselected. Return null to
disallow the change. The default allows all selection.
Note that you should not modify the passed in IndexSet. clone it instead.
@param {SC.CollectionView} view the view collection view
@param {SC.IndexSet} indexes the indexes to be selected
@returns {SC.IndexSet} allowed index set
*/
collectionViewShouldDeselectIndexes: function (view, indexes) {
return indexes;
},
// ..........................................................
// EDIT OPERATIONS
//
/**
Called by the collection view whenever the deleteSelection() method is
called. You can implement this method to get fine-grained control over
which items can be deleted. To prevent deletion, return null.
This method is only called if canDeleteContent is true on the collection
view.
@param {SC.CollectionView} view the collection view
@param {SC.IndexSet} indexes proposed index set of items to delete.
@returns {SC.IndexSet} index set allowed to delete or null.
*/
collectionViewShouldDeleteIndexes: function(view, indexes) {
return indexes;
},
/**
Called by the collection view to actually delete the selected items.
The default behavior will use standard array operators to delete the
indexes from the array. You can implement this method to provide your own
deletion method.
If you simply want to control the items to be deleted, you should instead
implement collectionViewShouldDeleteItems(). This method will only be
called if canDeleteContent is true and collectionViewShouldDeleteIndexes()
returns a non-empty index set
@param {SC.CollectionView} view collection view
@param {SC.IndexSet} indexes the items to delete
@returns {Boolean} true if the deletion was a success.
*/
collectionViewDeleteContent: function(view, content, indexes) {
if (!content) return false ;
if (SC.typeOf(content.destroyAt) === SC.T_FUNCTION) {
content.destroyAt(indexes);
view.selectPreviousItem(false, 1) ;
return true ;
} else if (SC.typeOf(content.removeAt) === SC.T_FUNCTION) {
content.removeAt(indexes);
view.selectPreviousItem(false, 1) ;
return true;
} else return false ;
},
// ..........................................................
// DRAGGING
//
/**
Called by the collection view just before it starts a drag to give you
an opportunity to decide if the drag should be allowed.
You can use this method to implement fine-grained control over when a
drag will be allowed and when it will not be allowed. For example, you
may enable content reordering but then implement this method to prevent
reordering of certain items in the view.
The default implementation always returns true.
@param view {SC.CollectionView} the collection view
@returns {Boolean} true to alow, false to prevent it
*/
collectionViewShouldBeginDrag: function(view) { return true; },
/**
Called by the collection view just before it starts a drag so that
you can provide the data types you would like to support in the data.
You can implement this method to return an array of the data types you
will provide for the drag data.
If you return null or an empty array, can you have set canReorderContent
to true on the CollectionView, then the drag will go ahead but only
reordering will be allowed. If canReorderContent is false, then the drag
will not be allowed to start.
If you simply want to control whether a drag is allowed or not, you
should instead implement collectionViewShouldBeginDrag().
The default returns an empty array.
@param view {SC.CollectionView} the collection view to begin dragging.
@returns {Array} array of supported data types.
*/
collectionViewDragDataTypes: function(view) { return []; },
/**
Called by a collection view when a drag concludes to give you the option
to provide the drag data for the drop.
This method should be implemented essentially as you would implement the
dragDataForType() if you were a drag data source. You will never be asked
to provide drag data for a reorder event, only for other types of data.
The default implementation returns null.
@param view {SC.CollectionView}
the collection view that initiated the drag
@param dataType {String} the data type to provide
@param drag {SC.Drag} the drag object
@returns {Object} the data object or null if the data could not be provided.
*/
collectionViewDragDataForType: function(view, drag, dataType) {
return null ;
},
/**
Called once during a drag the first time view is entered. Return all
possible drag operations OR'd together.
@param {SC.CollectionView} view
the collection view that initiated the drag
@param {SC.Drag} drag
the drag object
@param {Number} proposedDragOperations
proposed logical OR of allowed drag operations.
@returns {Number} the allowed drag operations. Defaults to op
*/
collectionViewComputeDragOperations: function(view, drag, proposedDragOperations) {
return proposedDragOperations ;
},
/**
Called by the collection view during a drag to let you determine the
kind and location of a drop you might want to accept.
You can override this method to implement fine-grained control over how
and when a dragged item is allowed to be dropped into a collection view.
This method will be called by the collection view both to determine in
general which operations you might support and specifically the operations
you would support if the user dropped an item over a specific location.
If the proposedDropOperation parameter is SC.DROP_ON or SC.DROP_BEFORE,
then the proposedInsertionPoint will be a non-negative value and you
should determine the specific operations you will support if the user
dropped the drag item at that point.
If you do not like the proposed drop operation or insertion point, you
can override these properties as well by setting the proposedDropOperation
and proposedInsertionIndex properties on the collection view during this
method. These properties are ignored all other times.
@param view {SC.CollectionView} the collection view
@param drag {SC.Drag} the current drag object
@param op {Number} proposed logical OR of allowed drag operations.
@param proposedInsertionIndex {Number} an index into the content array
representing the proposed insertion point.
@param proposedDropOperation {String} the proposed drop operation. Will be one of SC.DROP_ON, SC.DROP_BEFORE, or SC.DROP_ANY.
@returns the allowed drag operation. Defaults to op
*/
collectionViewValidateDragOperation: function(view, drag, op, proposedInsertionIndex, proposedDropOperation) {
// don't allow dropping on by default
return (proposedDropOperation & SC.DROP_ON) ? SC.DRAG_NONE : op ;
},
/**
Called by the collection view to actually accept a drop. This method will
only be invoked AFTER your validateDrop method has been called to
determine if you want to even allow the drag operation to go through.
You should actually make changes to the data model if needed here and
then return the actual drag operation that was performed. If you return
SC.DRAG_NONE and the dragOperation was SC.DRAG_REORDER, then the default
reorder behavior will be provided by the collection view.
@param view {SC.CollectionView}
@param drag {SC.Drag} the current drag object
@param op {Number} proposed logical OR of allowed drag operations.
@param proposedInsertionIndex {Number} an index into the content array representing the proposed insertion point.
@param proposedDropOperation {String} the proposed drop operation. Will be one of SC.DROP_ON, SC.DROP_BEFORE, or SC.DROP_ANY.
@returns the allowed drag operation. Defaults to proposedDragOperation
*/
collectionViewPerformDragOperation: function(view, drag, op, proposedInsertionIndex, proposedDropOperation) {
return SC.DRAG_NONE ;
},
/**
Renders a drag view for the passed content indexes. If you return null
from this, then a default drag view will be generated for you.
@param {SC.CollectionView} view
@param {SC.IndexSet} dragContent
@returns {SC.View} view or null
*/
collectionViewDragViewFor: function(view, dragContent) {
return null;
},
/**
Allows the ghost view created in collectionViewDragViewFor to be displayed
like a cursor instead of the default implementation. This sets the view
origin to be the location of the mouse cursor.
@property {Boolean} ghost view acts like a cursor
*/
ghostActsLikeCursor: false
};