Browse Source

Add toolbar to the component

pull/36/head
Artur Arseniev 9 years ago
parent
commit
be8bfa1ebf
  1. 34
      src/canvas/main.js
  2. 38
      src/canvas/view/CanvasView.js
  3. 3
      src/commands/view/MoveComponent.js
  4. 48
      src/commands/view/SelectComponent.js
  5. 11
      src/dom_components/model/Component.js
  6. 3
      src/dom_components/view/ComponentView.js
  7. 3
      src/editor/config/config.js
  8. 10
      styles/css/main.css
  9. 12
      styles/scss/main.scss

34
src/canvas/main.js

@ -136,6 +136,14 @@ define(function(require) {
return CanvasView.ghostEl; return CanvasView.ghostEl;
}, },
/**
* Returns toolbar element
* @return {HTMLElement}
*/
getToolbarEl: function(){
return CanvasView.toolbarEl;
},
/** /**
* Render canvas * Render canvas
* */ * */
@ -158,18 +166,18 @@ define(function(require) {
}, },
/** /**
* Get the offset of the element * Get the offset of the element
* @param {HTMLElement} el * @param {HTMLElement} el
* @return {Object} * @return {Object}
* @private * @private
*/ */
offset: function(el){ offset: function(el){
var rect = el.getBoundingClientRect(); var rect = el.getBoundingClientRect();
return { return {
top: rect.top + document.body.scrollTop, top: rect.top + document.body.scrollTop,
left: rect.left + document.body.scrollLeft left: rect.left + document.body.scrollLeft
}; };
}, },
/** /**
* Returns wrapper element * Returns wrapper element
@ -182,4 +190,4 @@ define(function(require) {
}; };
}; };
}); });

38
src/canvas/view/CanvasView.js

@ -36,17 +36,18 @@ function(Backbone, FrameView) {
renderBody: function(){ renderBody: function(){
var wrap = this.model.get('frame').get('wrapper'); var wrap = this.model.get('frame').get('wrapper');
if(wrap){ if(wrap){
var ppfx = this.ppfx;
var body = this.frame.$el.contents().find('body'); var body = this.frame.$el.contents().find('body');
var cssc = this.config.em.get('CssComposer'); var cssc = this.config.em.get('CssComposer');
var conf = this.config.em.get('Config'); var conf = this.config.em.get('Config');
body.append(wrap.render()).append(cssc.render()); body.append(wrap.render()).append(cssc.render());
var protCss = conf.protectedCss; var protCss = conf.protectedCss;
var frameCss = '.' + this.ppfx + 'dashed *{outline: 1px dashed rgba(170,170,170,0.7); outline-offset: -2px}' + var frameCss = '.' + ppfx + 'dashed *{outline: 1px dashed rgba(170,170,170,0.7); outline-offset: -2px}' +
'.' + this.ppfx + 'comp-selected{outline: 3px solid #3b97e3 !important}' + '.' + ppfx + 'comp-selected{outline: 3px solid #3b97e3 !important}' +
'.' + this.ppfx + 'no-select{user-select: none; -webkit-user-select:none; -moz-user-select: none}'+ '.' + ppfx + 'no-select{user-select: none; -webkit-user-select:none; -moz-user-select: none}'+
'.' + this.ppfx + 'freezed{opacity: 0.5; pointer-events: none}' + '.' + ppfx + 'freezed{opacity: 0.5; pointer-events: none}' +
'.' + this.ppfx + 'no-pointer{pointer-events: none}' + '.' + ppfx + 'no-pointer{pointer-events: none}' +
'.' + this.ppfx + 'plh-image{background:#f5f5f5; border:none; height:50px; width:50px; display:block; outline:3px solid #ffca6f; cursor:pointer}'; '.' + ppfx + 'plh-image{background:#f5f5f5; border:none; height:50px; width:50px; display:block; outline:3px solid #ffca6f; cursor:pointer}';
if(protCss) if(protCss)
body.append('<style>' + frameCss + protCss + '</style>'); body.append('<style>' + frameCss + protCss + '</style>');
this.config.em.trigger('loaded'); this.config.em.trigger('loaded');
@ -135,17 +136,20 @@ function(Backbone, FrameView) {
var frame = this.frame; var frame = this.frame;
frame.el.onload = this.renderBody; frame.el.onload = this.renderBody;
} }
this.toolsEl = $('<div>', { id: this.ppfx + 'tools' }).get(0); var ppfx = this.ppfx;
this.hlEl = $('<div>', { class: this.ppfx + 'highlighter' }).get(0); this.toolsEl = $('<div>', { id: ppfx + 'tools' }).get(0);
this.badgeEl = $('<div>', {class: this.ppfx + 'badge'}).get(0); this.hlEl = $('<div>', { class: ppfx + 'highlighter' }).get(0);
this.placerEl = $('<div>', {class: this.ppfx + 'placeholder'}).get(0); this.badgeEl = $('<div>', {class: ppfx + 'badge'}).get(0);
this.placerIntEl = $('<div>', {class: this.ppfx + 'placeholder-int'}).get(0); this.placerEl = $('<div>', {class: ppfx + 'placeholder'}).get(0);
this.ghostEl = $('<div>', {class: this.ppfx + 'ghost'}).get(0); this.placerIntEl = $('<div>', {class: ppfx + 'placeholder-int'}).get(0);
this.placerEl.appendChild(this.placerIntEl); this.ghostEl = $('<div>', {class: ppfx + 'ghost'}).get(0);
this.toolsEl.appendChild(this.hlEl); this.toolbarEl = $('<div>', {class: ppfx + 'toolbar'}).get(0);
this.toolsEl.appendChild(this.badgeEl); this.placerEl.appendChild(this.placerIntEl);
this.toolsEl.appendChild(this.placerEl); this.toolsEl.appendChild(this.hlEl);
this.toolsEl.appendChild(this.ghostEl); this.toolsEl.appendChild(this.badgeEl);
this.toolsEl.appendChild(this.placerEl);
this.toolsEl.appendChild(this.ghostEl);
this.toolsEl.appendChild(this.toolbarEl);
this.$el.append(this.toolsEl); this.$el.append(this.toolsEl);
var rte = this.em.get('rte'); var rte = this.em.get('rte');

3
src/commands/view/MoveComponent.js

@ -12,7 +12,7 @@ define(['backbone', './SelectComponent','./SelectPosition'],
this.noSelClass = this.ppfx + 'no-select'; this.noSelClass = this.ppfx + 'no-select';
}, },
enable: function(){ enable: function() {
SelectComponent.enable.apply(this, arguments); SelectComponent.enable.apply(this, arguments);
this.getBadgeEl().addClass(this.badgeClass); this.getBadgeEl().addClass(this.badgeClass);
this.getHighlighterEl().addClass(this.hoverClass); this.getHighlighterEl().addClass(this.hoverClass);
@ -40,6 +40,7 @@ define(['backbone', './SelectComponent','./SelectPosition'],
var drag = el.get('draggable'); var drag = el.get('draggable');
if(!drag) if(!drag)
return; return;
// Avoid badge showing on move // Avoid badge showing on move
this.cacheEl = null; this.cacheEl = null;
this.startSelectPosition(e.target, this.frameEl.contentDocument); this.startSelectPosition(e.target, this.frameEl.contentDocument);

48
src/commands/view/SelectComponent.js

@ -232,7 +232,7 @@ define(function() {
m.set('open', 0); m.set('open', 0);
} }
var parent = nMd.collection ? nMd.collection.parent : null; var parent = nMd.collection ? nMd.collection.parent : null;
while(parent){ while(parent) {
parent.set('open', 1); parent.set('open', 1);
opened[parent.cid] = parent; opened[parent.cid] = parent;
parent = parent.collection ? parent.collection.parent : null; parent = parent.collection ? parent.collection.parent : null;
@ -240,9 +240,54 @@ define(function() {
this.editorModel.set('selectedComponent', nMd); this.editorModel.set('selectedComponent', nMd);
nMd.set('status','selected'); nMd.set('status','selected');
this.updateToolbar(nMd);
} }
}, },
/**
* Update toolbar if the component has one
* @param {Object} model
*/
updateToolbar: function(model) {
var toolbar = model.get('toolbar');
var ppfx = this.ppfx;
var showToolbar = this.config.em.get('Config').showToolbar;
// TODO to refactor
if (showToolbar && toolbar && toolbar.length) {
var toolbarEl = this.canvas.getToolbarEl();
toolbarEl.innerHTML = '';
toolbar.forEach(function (item) {
var className = ppfx + 'toolbar-item';
var addClass = item.className || '';
toolbarEl.innerHTML += '<div class="' + ppfx + 'toolbar-item ' + addClass + '" onClick="alert(\'TODO\')"></div>';
});
var view = model.get('view');
if(view) {
var canvasPos = this.getCanvasPosition();
var pos = this.getElementPos(view.el);
var toolbarStyle = toolbarEl.style;
var unit = 'px';
// TODO Fix toolbar over the canvas (the problem is with the fisrt top el)
var topPos = (pos.top - toolbarEl.offsetHeight) < canvasPos.top ?
canvasPos.top : pos.top - toolbarEl.offsetHeight;
//var left = pos.left + badgeW < canvasPos.left ? canvasPos.left : pos.left;
toolbarStyle.display = 'flex';
toolbarStyle.left = (pos.left + pos.width - toolbarEl.offsetWidth) + unit; //
toolbarStyle.top = (pos.top - toolbarEl.offsetHeight) + unit;
}
}
},
/**
* Return canvas dimensions and positions
* @return {Object}
*/
getCanvasPosition: function () {
return this.canvas.getCanvasView().getPosition();
},
/** /**
* Removes all highlighting effects on components * Removes all highlighting effects on components
* @private * @private
@ -323,6 +368,7 @@ define(function() {
this.em.set('selectedComponent', null); this.em.set('selectedComponent', null);
this.toggleClipboard(); this.toggleClipboard();
this.hideBadge(); this.hideBadge();
this.canvas.getToolbarEl().style.display = 'none';
} }
}; };
}); });

11
src/dom_components/model/Component.js

@ -41,6 +41,16 @@ define(['backbone','./Components', 'SelectorManager/model/Selectors', 'TraitMana
attributes: {}, attributes: {},
classes: '', classes: '',
traits: ['id', 'title'], traits: ['id', 'title'],
toolbar: [{
className: 'fa fa-arrows',
command: 'tlb-move',
},{
className: 'fa fa-clone',
command: 'tlb-clone',
},{
className: 'fa fa-trash-o',
command: 'tlb-delete',
}],
}, },
initialize: function(o, opt) { initialize: function(o, opt) {
@ -132,6 +142,7 @@ define(['backbone','./Components', 'SelectorManager/model/Selectors', 'TraitMana
}); });
} }
attr.status = ''; attr.status = '';
attr.view = '';
return new this.constructor(attr, {sm: this.sm}); return new this.constructor(attr, {sm: this.sm});
}, },

3
src/dom_components/view/ComponentView.js

@ -25,7 +25,8 @@ define(['backbone', './ComponentsView'],
this.listenTo(this.model, 'change:status', this.updateStatus); this.listenTo(this.model, 'change:status', this.updateStatus);
this.listenTo(this.model, 'change:state', this.updateState); this.listenTo(this.model, 'change:state', this.updateState);
this.listenTo(this.model.get('classes'), 'add remove change', this.updateClasses); this.listenTo(this.model.get('classes'), 'add remove change', this.updateClasses);
this.$el.data("model", this.model); this.$el.data('model', this.model);
this.model.set('view', this);
this.$el.data("collection", this.components); this.$el.data("collection", this.components);
if(this.model.get('classes').length) if(this.model.get('classes').length)

3
src/editor/config/config.js

@ -26,6 +26,9 @@ define(function () {
// Default command // Default command
defaultCommand: 'select-comp', defaultCommand: 'select-comp',
// Show a toolbar when the component is selected
showToolbar: 1,
// If true render a select of available devices // If true render a select of available devices
showDevices: 1, showDevices: 1,

10
styles/css/main.css

@ -2801,6 +2801,16 @@ div.gjs-select {
.gjs-frame { .gjs-frame {
transition: width 0.35s ease; } transition: width 0.35s ease; }
.gjs-toolbar {
position: absolute;
background-color: #3b97e3;
color: white; }
.gjs-toolbar-item {
padding: 5px 7px;
font-size: 0.8rem;
cursor: pointer; }
.btn-cl, .gjs-mdl-dialog .gjs-mdl-btn-close, .gjs-am-assets-cont #gjs-am-close { .btn-cl, .gjs-mdl-dialog .gjs-mdl-btn-close, .gjs-am-assets-cont #gjs-am-close {
font-size: 25px; font-size: 25px;
opacity: 0.3; opacity: 0.3;

12
styles/scss/main.scss

@ -330,6 +330,18 @@ div.#{$app-prefix}select {
transition: width 0.35s ease; transition: width 0.35s ease;
} }
.#{$app-prefix}toolbar {
position: absolute;
background-color: $colorBlue;
color: white;
}
.#{$app-prefix}toolbar-item {
padding: 5px 7px;
font-size: 0.8rem;
cursor: pointer;
}
.btn-cl { .btn-cl {
font-size: 25px; font-size: 25px;
@include opacity(0.3); @include opacity(0.3);

Loading…
Cancel
Save