Browse Source

Update sorte and make it work

pull/36/head
Artur Arseniev 11 years ago
parent
commit
af5bf1abb5
  1. 14
      src/editor/model/Editor.js
  2. 2
      src/style_manager/model/Layer.js
  3. 16
      src/style_manager/model/Layers.js
  4. 13
      src/style_manager/view/LayerView.js
  5. 49
      src/style_manager/view/LayersView.js
  6. 4
      src/style_manager/view/PropertyStackView.js
  7. 108
      src/utils/Sorter.js
  8. 9
      styles/css/main.css
  9. 7
      styles/scss/main.scss
  10. 23
      test/specs/style_manager/model/Models.js
  11. 6
      test/specs/utils/Sorter.js

14
src/editor/model/Editor.js

@ -12,7 +12,8 @@ define([
'RichTextEditor', 'RichTextEditor',
'DomComponents', 'DomComponents',
'ClassManager', 'ClassManager',
'Panels'], 'Panels',
'Utils'],
function( function(
Backbone, Backbone,
UndoManager, UndoManager,
@ -27,7 +28,8 @@ define([
RichTextEditor, RichTextEditor,
DomComponents, DomComponents,
ClassManager, ClassManager,
Panels Panels,
Utils
){ ){
return Backbone.Model.extend({ return Backbone.Model.extend({
@ -58,10 +60,18 @@ define([
this.initCanvas(); this.initCanvas();
this.initUndoManager(); this.initUndoManager();
this.initCssComposer(); this.initCssComposer();
this.initUtils();
this.on('change:selectedComponent', this.componentSelected, this); this.on('change:selectedComponent', this.componentSelected, this);
}, },
/**
* Initialize Utils
* */
initUtils: function() {
this.set('Utils', new Utils());
},
/** /**
* Initialize Css Composer * Initialize Css Composer
* */ * */

2
src/style_manager/model/Layer.js

@ -4,7 +4,7 @@ define(['backbone'],
return Backbone.Model.extend({ return Backbone.Model.extend({
defaults: { defaults: {
name: '', index: '',
active: true, active: true,
value: '', value: '',
preview: false, preview: false,

16
src/style_manager/model/Layers.js

@ -5,5 +5,21 @@ define([ 'backbone', './Layer'],
model: Layer, model: Layer,
initialize: function(){
this.idx = 1;
this.on('add', this.onAdd);
this.on('reset', this.onReset);
},
onAdd: function(model, c, opts){
//console.log(opts);
if(!opts.noIncrement)
model.set('index', this.idx++);
},
onReset: function(){
this.idx = 1;
},
}); });
}); });

13
src/style_manager/view/LayerView.js

@ -16,16 +16,17 @@ define(['backbone', 'text!./../templates/layer.html'],
this.config = o.config || {}; this.config = o.config || {};
this.pfx = this.config.stylePrefix || ''; this.pfx = this.config.stylePrefix || '';
this.className = this.pfx + 'layer'; this.className = this.pfx + 'layer';
this.sorter = o.sorter || null;
this.listenTo(this.model, 'destroy remove', this.remove); this.listenTo(this.model, 'destroy remove', this.remove);
this.listenTo(this.model, 'change:value', this.valueChanged); this.listenTo(this.model, 'change:value', this.valueChanged);
this.listenTo(this.model, 'change:props', this.showProps); this.listenTo(this.model, 'change:props', this.showProps);
this.events['click #' + this.pfx + 'close-layer'] = 'remove'; this.events['click #' + this.pfx + 'close-layer'] = 'remove';
//this.events['mousedown > #' + this.pfx + 'move'] = 'initSorter'; this.events['mousedown > #' + this.pfx + 'move'] = 'initSorter';
if( !this.model.get('preview') ){ if( !this.model.get('preview') ){
this.$el.addClass(this.pfx + 'no-preview'); this.$el.addClass(this.pfx + 'no-preview');
} }
this.$el.data('model', this.model);
this.delegateEvents(); this.delegateEvents();
}, },
@ -35,7 +36,7 @@ define(['backbone', 'text!./../templates/layer.html'],
* */ * */
initSorter: function(e){ initSorter: function(e){
if(this.sorter) if(this.sorter)
this.sorter.startMove(this); this.sorter.startSort(this.el);
}, },
/** /**
@ -121,7 +122,8 @@ define(['backbone', 'text!./../templates/layer.html'],
Backbone.View.prototype.remove.apply(this, arguments); Backbone.View.prototype.remove.apply(this, arguments);
if(this.model.collection) //---
if(this.model.collection.contains(this.model))
this.model.collection.remove(this.model); this.model.collection.remove(this.model);
if(this.stackModel && this.stackModel.set){ if(this.stackModel && this.stackModel.set){
@ -162,8 +164,7 @@ define(['backbone', 'text!./../templates/layer.html'],
render : function(){ render : function(){
var i = this.getIndex(); var i = this.getIndex();
this.$el.html( this.template({ this.$el.html( this.template({
label: 'Layer ' + i, label: 'Layer ' + this.model.get('index'),
name: this.model.get('name'),
pfx: this.pfx, pfx: this.pfx,
})); }));
this.$el.attr('class', this.className); this.$el.attr('class', this.className);

49
src/style_manager/view/LayersView.js

@ -6,14 +6,26 @@ define(['backbone','./LayerView'],
return Backbone.View.extend({ return Backbone.View.extend({
initialize: function(o) { initialize: function(o) {
this.config = o.config; this.config = o.config || {};
this.stackModel = o.stackModel; this.stackModel = o.stackModel;
this.preview = o.preview; this.preview = o.preview;
this.pfx = this.config.stylePrefix; this.pfx = this.config.stylePrefix || '';
this.className = this.pfx + 'layers'; this.className = this.pfx + 'layers';
this.listenTo( this.collection, 'add', this.addTo ); this.listenTo( this.collection, 'add', this.addTo);
this.listenTo( this.collection, 'deselectAll', this.deselectAll ); this.listenTo( this.collection, 'deselectAll', this.deselectAll );
this.listenTo( this.collection, 'reset', this.render ); this.listenTo( this.collection, 'reset', this.render);
var em = this.config.target || '';
var utils = em ? em.get('Utils') : '';
this.sorter = utils ? new utils.Sorter({
container: this.el,
containerSel: '.' + this.pfx + 'layers',
itemSel: '.' + this.pfx + 'layer',
pfx: 'wte-',
}) : '';
this.$el.data('collection', this.collection);
}, },
/** /**
@ -23,19 +35,21 @@ define(['backbone','./LayerView'],
* @return Object * @return Object
* */ * */
addTo: function(model){ addTo: function(model){
this.addToCollection(model); var i = this.collection.indexOf(model);
this.addToCollection(model, null, i);
}, },
/** /**
* Add new object to collection * Add new object to collection
* @param Object Model * @param Object Model
* @param Object Fragment collection * @param Object Fragment collection
* @param {number} index Index of append
* *
* @return Object Object created * @return Object Object created
* */ * */
addToCollection: function(model, fragmentEl){ addToCollection: function(model, fragmentEl, index){
var fragment = fragmentEl || null; var fragment = fragmentEl || null;
var viewObject = LayerView; var viewObject = LayerView;
if(typeof this.preview !== 'undefined'){ if(typeof this.preview !== 'undefined'){
model.set('preview', this.preview); model.set('preview', this.preview);
@ -45,13 +59,28 @@ define(['backbone','./LayerView'],
model: model, model: model,
stackModel: this.stackModel, stackModel: this.stackModel,
config: this.config, config: this.config,
sorter: this.sorter
}); });
var rendered = view.render().el; var rendered = view.render().el;
if(fragment){ if(fragment){
fragment.appendChild( rendered ); fragment.appendChild( rendered );
}else{ }else{
this.$el.append(rendered); if(typeof index != 'undefined'){
var method = 'before';
// If the added model is the last of collection
// need to change the logic of append
if(this.$el.children().length == index){
index--;
method = 'after';
}
// In case the added is new in the collection index will be -1
if(index < 0){
this.$el.append(rendered);
}else
this.$el.children().eq(index)[method](rendered);
}else
this.$el.append(rendered);
} }
return rendered; return rendered;

4
src/style_manager/view/PropertyStackView.js

@ -163,7 +163,9 @@ define(['backbone','./PropertyCompositeView', 'text!./../templates/propertyStack
},this); },this);
} }
this.$props.detach(); this.$props.detach();
this.getLayers().reset(n); var layers = this.getLayers();
layers.reset();
layers.add(n);
this.refreshValue(); this.refreshValue();
this.model.set({stackIndex: null}, {silent: true}); this.model.set({stackIndex: null}, {silent: true});
}, },

108
src/utils/Sorter.js

@ -6,21 +6,18 @@ define(['backbone'],
initialize: function(opt) { initialize: function(opt) {
_.bindAll(this,'startSort','onMove','endMove','rollback'); _.bindAll(this,'startSort','onMove','endMove','rollback');
var o = opt || {}; var o = opt || {};
this.config = o.config || {};
this.pfx = this.config.stylePrefix || '';
this.itemClass = '.' + this.pfx + this.config.itemClass;
this.itemsClass = '.' + this.pfx + this.config.itemsClass;
this.setElement('.'+this.pfx+this.config.containerId);
this.elT = 0; this.elT = 0;
this.elL = 0; this.elL = 0;
this.borderOffset = o.borderOffset || 10; this.borderOffset = o.borderOffset || 10;
this.freezeClass = o.freezeClass || 'freezed'; this.freezeClass = o.freezeClass || 'freezed';
this.el = document.querySelector(o.container); var el = o.container;
this.el = typeof el === 'string' ? document.querySelector(o.container) : el;
this.$el = $(this.el); this.$el = $(this.el);
this.containerSel = 'div'; this.containerSel = o.containerSel || 'div';
this.itemSel = 'div'; this.itemSel = o.itemSel || 'div';
this.nested = o.nested || 0;
this.pfx = o.pfx || '';
}, },
/** /**
@ -44,6 +41,8 @@ define(['backbone'],
* @return {Element|null} * @return {Element|null}
*/ */
closest: function(el, selector){ closest: function(el, selector){
if(!el)
return;
var elem = el.parentNode; var elem = el.parentNode;
while (elem && elem.nodeType === 1) { while (elem && elem.nodeType === 1) {
if (this.matches(elem, selector)) if (this.matches(elem, selector))
@ -74,10 +73,10 @@ define(['backbone'],
var pfx = this.pfx; var pfx = this.pfx;
var el = document.createElement('div'); var el = document.createElement('div');
var ins = document.createElement('div'); var ins = document.createElement('div');
el.id = pfx + 'placeholder'; el.className = pfx + 'placeholder';
el.style.display = 'none'; el.style.display = 'none';
el.style['pointer-events'] = 'none'; el.style['pointer-events'] = 'none';
ins.id = pfx + "plh-int"; ins.className = pfx + "placeholder-int";
el.appendChild(ins); el.appendChild(ins);
return el; return el;
}, },
@ -88,16 +87,16 @@ define(['backbone'],
* */ * */
startSort: function(trg){ startSort: function(trg){
this.moved = 0; this.moved = 0;
this.eV = trg.el || trg; this.eV = trg;
if(!this.matches(trg, this.itemSel + ',' + this.containerSel))
this.eV = this.closest(trg, this.itemSel);
// Create placeholder if not exists // Create placeholder if not exists
if(!this.plh){ if(!this.plh){
this.plh = this.createPlaceholder(); this.plh = this.createPlaceholder();
this.el.appendChild(this.plh); this.el.appendChild(this.plh);
} }
//freeze el.. add this.freezeClass
//callback onStart
this.$el.on('mousemove',this.onMove); this.$el.on('mousemove',this.onMove);
$(document).on('mouseup',this.endMove); $(document).on('mouseup',this.endMove);
@ -126,12 +125,12 @@ define(['backbone'],
var dims = this.dimsFromTarget(e.target, this.rX, this.rY); var dims = this.dimsFromTarget(e.target, this.rX, this.rY);
var pos = this.findPosition(dims, this.rX, this.rY); var pos = this.findPosition(dims, this.rX, this.rY);
var actualPos = pos.index + ':' + pos.method;
// If there is a significant changes with the pointer // If there is a significant changes with the pointer
if(!this.lastPos || (this.lastPos != actualPos)){ if( !this.lastPos ||
(this.lastPos.index != pos.index || this.lastPos.method != pos.method)){
this.movePlaceholder(this.plh, dims, pos, this.prevTargetDim); this.movePlaceholder(this.plh, dims, pos, this.prevTargetDim);
this.lastPos = actualPos; this.lastPos = pos;
} }
//callback onMove //callback onMove
@ -144,9 +143,13 @@ define(['backbone'],
* */ * */
getChildrenDim: function(elem){ getChildrenDim: function(elem){
var dims = []; var dims = [];
if(!elem)
return dims;
var ch = elem.children; //TODO filter match var ch = elem.children; //TODO filter match
for (var i = 0, len = ch.length; i < len; i++) { for (var i = 0, len = ch.length; i < len; i++) {
var el = ch[i]; var el = ch[i];
if(!this.matches(el, this.itemSel))
continue;
var dim = this.getDim(el); var dim = this.getDim(el);
dim.push(true); //TODO check if in flow, now only for vertical elements dim.push(true); //TODO check if in flow, now only for vertical elements
dim.push(el); dim.push(el);
@ -175,9 +178,12 @@ define(['backbone'],
dimsFromTarget: function(target, rX, rY){ dimsFromTarget: function(target, rX, rY){
var dims = []; var dims = [];
if(!this.matches(target, this.itemSel)) if(!this.matches(target, this.itemSel + ',' + this.containerSel))
target = this.closest(target, this.itemSel); target = this.closest(target, this.itemSel);
if(!target)
return dims;
// Check if the target is different from the previous one // Check if the target is different from the previous one
if(this.prevTarget){ if(this.prevTarget){
if(this.prevTarget != target){ if(this.prevTarget != target){
@ -187,10 +193,10 @@ define(['backbone'],
// New target encountered // New target encountered
if(!this.prevTarget){ if(!this.prevTarget){
var parent = this.closest(target, this.containerSel); this.targetP = this.closest(target, this.containerSel);
this.prevTarget = target; this.prevTarget = target;
this.prevTargetDim = this.getDim(target); this.prevTargetDim = this.getDim(target);
this.cacheDimsP = this.getChildrenDim(parent); this.cacheDimsP = this.getChildrenDim(this.targetP);
this.cacheDims = this.getChildrenDim(target); this.cacheDims = this.getChildrenDim(target);
} }
@ -198,10 +204,15 @@ define(['backbone'],
if(this.prevTarget == target) if(this.prevTarget == target)
dims = this.cacheDims; dims = this.cacheDims;
// Target when I will drop element to sort
this.target = this.prevTarget;
// Generally also on every new target the poiner enters near // Generally also on every new target the poiner enters near
// to borders, so have to to check always // to borders, so have to to check always
if(this.nearBorders(this.prevTargetDim, rX, rY)) if(this.nearBorders(this.prevTargetDim, rX, rY) ||
(!this.nested && !this.cacheDims.length)){
dims = this.cacheDimsP; dims = this.cacheDimsP;
this.target = this.targetP;
}
return dims; return dims;
}, },
@ -310,6 +321,10 @@ define(['backbone'],
l = elDim[1]; l = elDim[1];
} }
}else{ }else{
if(!this.nested){
plh.style.display = 'none';
return;
}
if(trgDim){ if(trgDim){
t = trgDim[0] + margI + 17; t = trgDim[0] + margI + 17;
l = trgDim[1] + margI * 7; l = trgDim[1] + margI * 7;
@ -334,12 +349,9 @@ define(['backbone'],
this.$el.off('mousemove', this.onMove); this.$el.off('mousemove', this.onMove);
$(document).off('mouseup', this.endMove); $(document).off('mouseup', this.endMove);
$(document).off('keypress', this.rollback); $(document).off('keypress', this.rollback);
//this.eV.unfreeze(); this.plh.style.display = 'none';
//this.$plh.hide();
if(this.moved) if(this.moved)
this.move(this.$targetEl, this.$sel, this.posIndex, this.posMethod); this.move(this.target, this.eV, this.lastPos);
//this.itemLeft(); // Do I need to reset all cached stuff?
//callback onMove
}, },
/** /**
@ -351,26 +363,17 @@ define(['backbone'],
* *
* @return void * @return void
* */ * */
move: function(target, el, posIndex, method){ move: function(dst, src, pos){
//this.eV var index = pos.index;
var trg = target|| this.$targetEl; var model = $(src).data('model');
trg = trg || this.$backupEl; var collection = model.collection;
if(!trg) var targetCollection = $(dst).data('collection');
return;
var index = posIndex || 0; if(targetCollection){// && targetModel.get('droppable')
var model = el.data("model"); index = pos.method === 'after' ? index + 1 : index;
var collection = model.collection; var modelTemp = targetCollection.add({}, {at: index, noIncrement: 1});
var targetModel = trg.data('model'); var modelRemoved = model.collection.remove(model);
var targetCollection = targetModel.collection; targetCollection.add(modelRemoved, {at: index, noIncrement: 1});
if(!this.cDim.length)
targetCollection = targetModel.get('components');
if(targetCollection && targetModel.get('droppable')){
index = method == 'after' ? index + 1 : index;
var modelTemp = targetCollection.add({style:{}}, { at: index});
var modelRemoved = collection.remove(model, { silent:false });
targetCollection.add(modelRemoved, { at: index, silent:false });
targetCollection.remove(modelTemp); targetCollection.remove(modelTemp);
}else }else
console.warn("Invalid target position"); console.warn("Invalid target position");
@ -378,16 +381,13 @@ define(['backbone'],
/** /**
* Rollback to previous situation * Rollback to previous situation
* @param Event * @param {Event}
* @param Bool Indicates if rollback in anycase * @param {Bool} Indicates if rollback in anycase
* @return void
* */ * */
rollback: function(e, force){ rollback: function(e){
var key = e.which || e.keyCode; var key = e.which || e.keyCode;
if(key == 27 || force){ if(key == 27)
this.moved = false;
this.endMove(); this.endMove();
}
return; return;
}, },

9
styles/css/main.css

@ -2720,10 +2720,11 @@ ol.example li.placeholder:before {
.wte-com-badge-yellow { .wte-com-badge-yellow {
background-color: #ffca6f; } background-color: #ffca6f; }
.wte-com-placeholder { .wte-placeholder, .wte-com-placeholder {
position: absolute; } position: absolute;
z-index: 10; }
.wte-com-placeholder-int { .wte-placeholder-int, .wte-com-placeholder-int {
background-color: #62c462; background-color: #62c462;
height: 100%; height: 100%;
width: 100%; width: 100%;
@ -3218,7 +3219,7 @@ ol.example li.placeholder:before {
.wte-sm-layer > #wte-sm-move { .wte-sm-layer > #wte-sm-move {
opacity: 0.3; opacity: 0.3;
filter: alpha(opacity=30); filter: alpha(opacity=30);
cursor: pointer; cursor: move;
font-size: 12px; font-size: 12px;
float: left; float: left;
margin: 0 5px 0 0; } margin: 0 5px 0 0; }

7
styles/scss/main.scss

@ -188,10 +188,11 @@ ol.example li.placeholder:before {position: absolute;}
@extend .#{$com-prefix}badge; @extend .#{$com-prefix}badge;
background-color: $colorYell; background-color: $colorYell;
} }
.#{$com-prefix}placeholder{ .#{$app-prefix}placeholder, .#{$com-prefix}placeholder{
position: absolute; position: absolute;
z-index: 10;
} }
.#{$com-prefix}placeholder-int{ .#{$app-prefix}placeholder-int, .#{$com-prefix}placeholder-int{
background-color: $colorGreen; background-color: $colorGreen;
height: 100%; width: 100%; height: 100%; width: 100%;
pointer-events: 'none'; pointer-events: 'none';
@ -742,7 +743,7 @@ $arrowColor: darken($fontColor,24%); /*b1b1b1*/
} }
.#{$sm-prefix}layer > ##{$sm-prefix}move { .#{$sm-prefix}layer > ##{$sm-prefix}move {
@include opacity(0.3); @include opacity(0.3);
cursor: pointer; cursor: move;
font-size: 12px; font-size: 12px;
float: left; float: left;
margin: 0 5px 0 0; margin: 0 5px 0 0;

23
test/specs/style_manager/model/Models.js

@ -118,8 +118,8 @@ define([path + 'Sector',
delete obj; delete obj;
}); });
it('Has name property', function() { it('Has index property', function() {
obj.has('name').should.equal(true); obj.has('index').should.equal(true);
}); });
it('Is active', function() { it('Is active', function() {
@ -144,6 +144,25 @@ define([path + 'Sector',
obj.should.be.ok; obj.should.be.ok;
}); });
it('Init index on add', function() {
var model = obj.add({});
model.get('index').should.equal(1);
});
it('Increment index', function() {
var model = obj.add({});
var model2 = obj.add({});
model2.get('index').should.equal(2);
});
it('Cache index', function() {
var model = obj.add({});
var model2 = obj.add({});
obj.remove(model2);
var model3 = obj.add({});
model3.get('index').should.equal(3);
});
}); });
} }

6
test/specs/utils/Sorter.js

@ -47,7 +47,7 @@ define([path + 'Sorter',],
}); });
it('Creates placeholder', function() { it('Creates placeholder', function() {
obj.createPlaceholder().id.should.equal('placeholder'); obj.createPlaceholder().className.should.equal('placeholder');
}); });
describe('Closest method', function() { describe('Closest method', function() {
@ -267,6 +267,10 @@ define([path + 'Sorter',],
it.skip('movePlaceholder', function() { it.skip('movePlaceholder', function() {
}); });
it.skip('move', function() {
obj.move(el).should.equal('test');
});
}); });
}); });

Loading…
Cancel
Save