DIR : /home/kozerus/public_html/pn/uize/site-source/js/Uize/Widget/Collection/Dynamic.js
/home/kozerus/public_html/pn/uize/site-source/js/Uize/Widget/Collection
/*______________
| ______ | U I Z E J A V A S C R I P T F R A M E W O R K
| / / | ---------------------------------------------------
| / O / | MODULE : Uize.Widget.Collection.Dynamic Class
| / / / |
| / / / /| | ONLINE : http://www.uize.com
| /____/ /__/_| | COPYRIGHT : (c)2007-2016 UIZE
| /___ | LICENSE : Available under MIT License or GNU General Public License
|_______________| http://www.uize.com/license.html
*/
/* Module Meta Data
type: Class
importance: 4
codeCompleteness: 80
docCompleteness: 3
*/
/*?
Introduction
The =Uize.Widget.Collection.Dynamic= class extends =Uize.Widget.Collection= by adding dynamic adding, removing, and drag-and-drop re-ordering of items.
*DEVELOPERS:* `Chris van Rensburg`, `Jan Borgersen`, `Rich Bean`, `Tim Carter`, `Vinson Chuong`
*/
Uize.module ({
name:'Uize.Widget.Collection.Dynamic',
required:[
'Uize.Dom.Basics',
'Uize.Dom.Pos',
'Uize.Widget.Drag',
'Uize.Tooltip'
],
builder:function (_superclass) {
'use strict';
var
/*** Variables for Scruncher Optimization ***/
_true = true,
_false = false,
_null = null,
_Uize_Dom = Uize.Dom,
_Uize_Dom_Basics = _Uize_Dom.Basics,
_Uize_Dom_Pos = _Uize_Dom.Pos,
_Uize_Tooltip = Uize.Tooltip,
/*** General Variables ***/
_selectedProperty = {selected:_true}
;
/*** Private Instance Methods ***/
function _addItem (m,_widgetProperties) {
var
_propertiesProperty = _widgetProperties.properties,
_itemWidgetName = m.makeItemWidgetName (_propertiesProperty)
;
m.get ('items').push (_propertiesProperty);
return m.addItemWidget (_itemWidgetName,_widgetProperties);
}
function _fireItemsChangedEvent (m) {m.fire ('Items Changed')};
return _superclass.subclass ({
omegastructor:function () {
var m = this;
/*** watch for dragging of items ***/
var
_itemInitiatingDrag,
_itemDisplayOrderNo, // 0 is normal, 1 is reverse
_itemsDragged,
_itemsDraggedLength,
_itemsCoords,
_itemWidgetOver,
_itemWidgetOverCoords,
_insertPointItem,
_insertPointModeNo, // 0 is before, 1 is after
_insertPointCoords,
_lastInsertPointItem,
_lastInsertPointModeNo,
_orientationNo,
_insertionMarkerNode,
_insertionMarkerDims,
_axisPosName,
_axisDimName,
_drag = m.addChild ('drag',Uize.Widget.Drag,{nodeMap:{'':_null}}),
_ignoreDrag = _false
;
// one way operation
_drag.wire (
'Changed.inDrag',
function (_event) {m.set ({_inDrag:_event.newValue})}
);
function _setInDrag (_inDrag) {
var
_opacity = _inDrag ? m._itemVestigeOpacity : 1,
_draggingTooltip = m.getNode ('tooltipDragging')
;
for (var _itemDraggedNo = _itemsDraggedLength; --_itemDraggedNo > -1;)
_itemsDragged [_itemDraggedNo].setNodeOpacity ('',_opacity)
;
_inDrag &&
_Uize_Dom_Basics.setInnerHtml (
_draggingTooltip,
m.localize (
'draggingToReorder' + (_itemsDraggedLength > 1 ? 'Plural' : 'Singular'),
{totalItems:_itemsDraggedLength}
)
)
;
_Uize_Tooltip.showTooltip (_draggingTooltip,_inDrag,_true);
}
_drag.wire ({
'Drag Start':
function () {
_itemDisplayOrderNo = m._itemDisplayOrder == 'reverse' ? 1 : 0;
_itemInitiatingDrag.set ({over:_false});
/*** determine items being dragged ***/
var _itemInitiatingDragIsSelected = _itemInitiatingDrag.get ('selected');
if (!_itemInitiatingDragIsSelected) {
m.selectAll (_false);
m._ensureItemDraggedIsSelected && _itemInitiatingDrag.set ({selected:_true});
}
if (!m._dragIgnoresLocked) {
// if drag obeys the locked property, the locked objects are not draggable.
if (_itemInitiatingDragIsSelected) {
for (
var
_itemsSelectedIdx = -1,
_itemsToDrag = m.getSelected (),
_itemsToDragLength = _itemsToDrag.length
;
++_itemsSelectedIdx < _itemsToDragLength;
)
_itemsToDrag[_itemsSelectedIdx].get ('locked') &&
_itemsToDrag[_itemsSelectedIdx].set ({selected:_false})
;
// cancel drag if nothing is selected
_ignoreDrag = !m.get ('totalSelected');
}
else if (_itemInitiatingDrag.get ('locked'))
_ignoreDrag = _true
;
}
_itemsDragged =
_itemInitiatingDragIsSelected ? m.getSelected () : [_itemInitiatingDrag]
;
_itemsDraggedLength = _itemsDragged.length;
/*** capture coords for item widgets (for performance during drag) ***/
_itemsCoords = [];
m.forAll (
function (_itemWidget) {
_itemsCoords.push (_Uize_Dom_Pos.getCoords (_itemWidget.getNode ()));
}
);
/*** initialize ***/
var
_itemsCoordsLength = _itemsCoords.length,
_totalItemsMinus1 = _itemsCoordsLength - 1,
_itemsCoords0 = _itemsCoords [_itemDisplayOrderNo ? _totalItemsMinus1 : 0],
_itemsCoords1 = _itemsCoords [_itemDisplayOrderNo ? _totalItemsMinus1 - 1 : 1]
;
_orientationNo =
_totalItemsMinus1 && _itemsCoords1.top >= _itemsCoords0.bottom
? 1 /* 1 = items layed out vertically */
: 0 /* 0 = items layed out horizontally */
;
_axisPosName = _orientationNo ? 'top' : 'left';
_axisDimName = _orientationNo ? 'height' : 'width';
_insertPointItem = _insertPointModeNo = _insertPointCoords = _lastInsertPointItem = _lastInsertPointModeNo = _null;
_insertionMarkerNode = m.getNode ('insertionMarker');
_insertionMarkerDims = _Uize_Dom_Pos.getDimensions (_insertionMarkerNode);
/*** expand drop coordinates for item widgets (performance optimization) ***/
for (
var
_itemWidgetNo = -1,
_itemWidgetSpacing = _totalItemsMinus1
?
_itemsCoords1 [_axisPosName] -
(_itemsCoords0 [_axisPosName] + _itemsCoords0 [_axisDimName] - 1)
: 0
,
_itemWidgetSpacingDiv2 = _itemWidgetSpacing / 2
;
++_itemWidgetNo < _itemsCoordsLength;
) {
var _itemWidgetCoords = _itemsCoords [_itemWidgetNo];
_itemWidgetCoords [_axisPosName] -= _itemWidgetSpacingDiv2;
_itemWidgetCoords [_axisDimName] += _itemWidgetSpacing;
}
_setInDrag (_true);
},
'Drag Update':
function () {
var
_dragEventPos = _drag.eventPos
;
_Uize_Tooltip.positionTooltip (
m.getNode ('tooltipDragging'),
{pageX:_dragEventPos [0],pageY:_dragEventPos [1]}
);
function _pointWithinCoords (_coords) {
return (
_coords &&
_Uize_Dom_Pos.doRectanglesOverlap (
_coords.left,_coords.top,_coords.width,_coords.height,
_dragEventPos [0],_dragEventPos [1],1,1
)
);
}
if (!_pointWithinCoords (_itemWidgetOverCoords)) {
_itemWidgetOver = _itemWidgetOverCoords = _null;
m.forAll (
function (_itemWidget,_itemWidgetNo) {
var _itemWidgetCoords = _itemsCoords [_itemWidgetNo];
if (_pointWithinCoords (_itemWidgetCoords)) {
_itemWidgetOver = _itemWidget;
_itemWidgetOverCoords = _itemWidgetCoords;
}
return !_itemWidgetOver;
}
);
}
if (!_pointWithinCoords (_insertPointCoords)) {
_insertPointItem = _insertPointCoords = _null;
if (_itemWidgetOver && !Uize.isIn (_itemsDragged,_itemWidgetOver)) {
var
_axisDim = _itemWidgetOverCoords [_axisDimName],
_axisDimDiv2 = _axisDim / 2,
_axisLower = _itemWidgetOverCoords [_axisPosName],
_axisCenter = _axisLower + _axisDimDiv2
;
_insertPointItem = _itemWidgetOver;
_insertPointModeNo = _dragEventPos [_orientationNo] < _axisCenter ? 0 : 1;
_insertPointCoords = Uize.clone (_itemWidgetOverCoords);
_insertPointCoords [_axisPosName] = _insertPointModeNo ? _axisCenter : _axisLower;
_insertPointCoords [_axisDimName] = _axisDimDiv2;
}
}
if (
_insertPointItem != _lastInsertPointItem ||
_insertPointModeNo != _lastInsertPointModeNo
) {
m.displayNode (_insertionMarkerNode,!!_insertPointItem);
if (_insertPointItem) {
var _insertionMarkerCoords = Uize.clone (_insertPointCoords);
_insertionMarkerCoords [_axisPosName] +=
(_insertPointModeNo ? _insertPointCoords [_axisDimName] : 0)
- _insertionMarkerDims [_axisDimName] / 2
;
delete _insertionMarkerCoords [_axisDimName];
_Uize_Dom_Pos.setCoords (_insertionMarkerNode,_insertionMarkerCoords);
}
_lastInsertPointItem = _insertPointItem;
_lastInsertPointModeNo = _insertPointModeNo;
}
_drag.set ({cursor:_insertPointItem || _itemWidgetOver ? m._dragCursor : 'not-allowed'});
},
'Drag Done':
function () {
if (_drag.get ('dragStarted')) {
_setInDrag (_false);
m.displayNode ('insertionMarker',_false);
var _finishDrag = function () {
if (_insertPointItem && !_ignoreDrag && !_drag.get ('dragCancelled')) {
var _itemWidgets = m.itemWidgets;
/*** handle the 'after' insert mode ***/
if (_insertPointModeNo ^ _itemDisplayOrderNo) {
var
_itemWidgetsLength = _itemWidgets.length,
_insertionIndex = Uize.indexIn (_itemWidgets,_insertPointItem) + 1
;
_insertPointItem = _null;
while (_insertionIndex < _itemWidgetsLength) {
var _itemWidget = _itemWidgets [_insertionIndex];
if (!Uize.isIn (_itemsDragged,_itemWidget)) {
_insertPointItem = _itemWidget;
break;
} else {
_insertionIndex++;
}
}
}
/*** perform the move ***/
for (var _itemDraggedNo = -1; ++_itemDraggedNo < _itemsDraggedLength;)
m.move (_itemsDragged [_itemDraggedNo],_insertPointItem)
;
/*** fire events informing of move ***/
m.fire ('Items Reordered');
_fireItemsChangedEvent (m);
}
};
m._confirmToDrag
? m.confirm ({
state:'warning',
title:m.localize ('confirmDragToReorderTitle'),
message:m.localize ('confirmDragToReorderPrompt'),
yesHandler:function () {
m._confirmToDrag = _false;
m.fire ('Drag Confirmed');
_finishDrag ();
},
noHandler:function () {
_drag.set ({dragCancelled:true});
}
})
: _finishDrag ()
;
}
}
});
/*** initiate drag using the drag widget, and let it do the rest ***/
m.wire (
'Item Mouse Down',
function (_event) {
if (m._dragToReorder) {
setTimeout(
function() {
_itemInitiatingDrag = _event.source;
_drag.initiate (_event.domEvent);
},
0
);
}
_event.bubble = _false;
}
);
},
instanceMethods:{
add:function (_itemsToAdd) {
var
m = this,
_itemWidgetsAdded = []
;
if (!Uize.isArray (_itemsToAdd)) _itemsToAdd = [_itemsToAdd];
var _itemsToAddLength = _itemsToAdd.length;
if (_itemsToAddLength) {
m._makeNewlyAddedSelected && m.selectAll (_false);
var _commonProperties = m._makeNewlyAddedSelected ? _selectedProperty : _null;
for (var _itemToAddNo = -1; ++_itemToAddNo < _itemsToAddLength;)
_itemWidgetsAdded.push (
_addItem (m,Uize.copyInto (_itemsToAdd [_itemToAddNo],_commonProperties))
)
;
}
_fireItemsChangedEvent (m);
return _itemWidgetsAdded;
},
getItemWidgetProperties:function () {
var m = this;
return (
Uize.copyInto (
{
previewTooltip:
function () {return m._dragToReorder ? m.getNode ('tooltipDragToReorder') : _null}
},
m.get ('itemWidgetProperties')
)
);
},
move:function (_itemWidgetToMove, _insertionPointItem) {
var
m = this,
_insertAfter = m._itemDisplayOrder == 'reverse',
_insertionPointNode = _insertionPointItem ? _insertionPointItem.getNode () : _null,
_items = m.get ('items'),
_itemWidgets = m.itemWidgets,
_rootNode = _itemWidgetToMove.getNode().parentNode,
_node = _itemWidgetToMove.getNode (),
_nodeToInsertBefore = _insertAfter
? (_insertionPointNode ? _insertionPointNode.nextSibling : _rootNode.childNodes[0])
: _insertionPointNode
;
// reorder the DOM element
_nodeToInsertBefore ? _rootNode.insertBefore (_node, _nodeToInsertBefore) : _rootNode.appendChild(_node);
/*** reorder itemWidget in the itemWidgets, and item in items ***/
/*** splice out item being dragged ***/
var
_spliceOutPos = Uize.indexIn (_itemWidgets,_itemWidgetToMove),
_item = _items [_spliceOutPos]
;
_itemWidgets.splice (_spliceOutPos,1);
_items.splice (_spliceOutPos,1);
/*** splice item into new position ***/
var _spliceInPos = _insertionPointItem
? Uize.indexIn (_itemWidgets,_insertionPointItem)
: _itemWidgets.length
;
_itemWidgets.splice (_spliceInPos,0,_itemWidgetToMove);
_items.splice (_spliceInPos,0,_item);
},
getTemplateHtml: function (_templateNode) { /* virtual hook method */
return _templateNode.innerHTML;
},
processItemTemplate:function (_templateNode) {
// NOTE: This code is pretty much identical to the code in buildHtml (of Uize.Widget), but there's no
// easy way to get the template into the markup so that it can do what it does.
var _nodeInnerHtml = this.getTemplateHtml(_templateNode);
return Uize.Template &&_templateNode.tagName == 'SCRIPT' && _templateNode.type == 'text/jst'
? Uize.Template.compile(_nodeInnerHtml, this._templateTokens || { openerToken: '[%', closerToken: '%]' })
: function (_input) {return _nodeInnerHtml.replace (/ITEMWIDGETNAME/g, _input.name)}
;
},
afterWireUi:function () {},
wireUi:function () {
var m = this;
if (!m.isWired) {
var
_docBody = document.body,
_insertionMarkerNode = m.getNode ('insertionMarker'),
_itemWidgetProperties = {},
_itemTemplateNode = m.getNode ('itemTemplate')
;
// Pull insertion marker to root
if (_insertionMarkerNode && _insertionMarkerNode.parentNode != _docBody) {
_docBody.insertBefore (_insertionMarkerNode, _docBody.childNodes[0]);
m.setNodeStyle (
_insertionMarkerNode,
{
display:'none',
position:'absolute',
zIndex:10000,
left:'',
top:'',
right:'',
bottom:''
}
);
}
if (_itemTemplateNode)
_itemWidgetProperties.html = m.processItemTemplate (_itemTemplateNode)
;
_itemWidgetProperties.built = _false;
_itemWidgetProperties.container = m.getNode ('items');
_itemWidgetProperties.insertionMode = m._itemDisplayOrder == 'reverse' ? 'inner top' : 'inner bottom';
// Update the already created item widgets if the UI hasn't been built yet
m.get('built')
|| m.forAll( function (_itemWidget) { _itemWidget.set(_itemWidgetProperties) } );
// For future creation of item widgets we need to update the item widget properties to have all the UI building stuff
m.set({itemWidgetProperties:Uize.copyInto(_itemWidgetProperties, m.get('itemWidgetProperties') || {})});
_superclass.doMy (m,'wireUi');
m.afterWireUi();
}
}
},
stateProperties:{
_confirmToDrag:{
name:'confirmToDrag',
value:_false
},
_dragCursor:{
name: 'dragCursor',
value: 'move'
},
_dragIgnoresLocked:{
name:'dragIgnoresLocked',
value:_true
/*
If true, then drag will drag locked CollectionItem widgets. If false, then drag will de-select any locked CollectionItem widgets prior to carrying out the drag.
*/
},
_dragToReorder:{
name:'dragToReorder',
value:_false
},
_ensureItemDraggedIsSelected:{
name:'ensureItemDraggedIsSelected',
value:_false
/*
If true, an unselected item that is dragged will be selected. If false, an unselected item that is dragged will remain unselected.
*/
},
_inDrag:'inDrag', // get only
_itemDisplayOrder:{
name:'itemDisplayOrder',
value:'normal' // normal | reverse
},
_makeNewlyAddedSelected:{
name:'makeNewlyAddedSelected',
value:_true
},
_itemVestigeOpacity:{
name:'itemVestigeOpacity',
value:.2
},
_templateTokens: 'templateTokens'
}
});
}
});
//
koh5_pano
Drag mouse to navigate.
Navigation
- Left/Right Mouse drag: Changes camera heading.
- Up/Sown Mouse drag: Changes camera pitch.
- Scroll wheel: Changes camera field of view.
- I-Key: Displays Info panel with canvas size, image size and FPS.
17.Aug.2010, Martin Wengenmayer