blob: 752319c052e0daf4e679da91f17aa251aa757220 [file] [log] [blame]
/* Licensed under the Apache License, Version 2.0 (the "License") http://www.apache.org/licenses/LICENSE-2.0 */
const Role = require('./wb-role');
const WbUtils = require('./wb-utils');
const APointer = require('./wb-tool-apointer');
const Pointer = require('./wb-tool-pointer');
const Text = require('./wb-tool-text');
const Textbox = require('./wb-tool-textbox');
const Whiteout = require('./wb-tool-whiteout');
const Paint = require('./wb-tool-paint');
const Line = require('./wb-tool-line');
const ULine = require('./wb-tool-uline');
const Rect = require('./wb-tool-rect');
const Ellipse = require('./wb-tool-ellipse');
const Arrow = require('./wb-tool-arrow');
const Clipart = require('./wb-tool-clipart');
const StaticTMath = require('./wb-tool-stat-math');
const TMath = require('./wb-tool-math');
const ACTIVE = 'active';
function __validBtn(btn) {
return !!btn && btn.length === 1
&& typeof(btn.data) === 'function'
&& typeof(btn.data()) === 'object'
&& typeof(btn.data().deactivate) === 'function';
}
function _setCurrent(c, _cur) {
const hndl = c.find('a')
, cur = _cur || c.find('div.om-icon.big:first')
c.attr('title', cur.attr('title'));
hndl.find('.om-icon').remove();
hndl.prepend(cur.clone().addClass('stub').data('toolType', cur.data('toolType')));
}
function _initGroup(__id, e) {
const c = OmUtil.tmpl(__id);
e.after(c);
c.find('.om-icon').each(function() {
const cur = $(this);
cur.click(function() {
_setCurrent(c, cur);
});
});
return c;
}
function __destroySettings() {
$('#wb-settings').modal('dispose');
}
module.exports = class WbTools {
constructor(wbEl, wb) {
let mode, tools, settings, math;
function _initGroupHandle(c) {
c.find('a').off().click(function(e) {
e.stopImmediatePropagation()
const stub = $(this).find('.stub');
if (stub.hasClass(ACTIVE)) {
$(this).dropdown('toggle')
} else {
_btnClick(stub.data('toolType'));
stub.addClass(ACTIVE);
}
});
_setCurrent(c);
}
function _getBtn(m) {
return !!tools ? tools.find('.om-icon.' + (m || mode) + ':not(.stub)') : null;
}
function _cleanActive() {
!!tools && tools.find('.om-icon.' + ACTIVE).removeClass(ACTIVE);
}
function _setActive() {
!!tools && tools.find('.om-icon.' + mode).addClass(ACTIVE);
}
function _btnClick(toolType) {
const b = _getBtn();
if (__validBtn(b)) {
b.data().deactivate();
}
_cleanActive();
_getBtn('string' === typeof(toolType) && !!toolType ? toolType : $(this).data('toolType')).data().activate();
_setActive();
}
function _initToolBtn(m, def, obj) {
const btn = _getBtn(m);
if (!btn || btn.length === 0) {
return;
}
btn.data({
obj: obj
, toolType: m
, activate: function() {
if (!btn.hasClass(ACTIVE)) {
mode = m;
obj.activate();
}
}
, deactivate: function() {
obj.deactivate();
}
}).click(_btnClick);
if (def) {
btn.data().activate();
}
}
function _initTexts(sBtn) {
const c = _initGroup('#wb-area-texts', _getBtn('apointer'));
_initToolBtn('text', false, new Text(wb, settings, sBtn));
_initToolBtn('textbox', false, new Textbox(wb, settings, sBtn));
_initGroupHandle(c, tools);
}
function _initDrawings(sBtn) {
const c = _initGroup('#wb-area-drawings', tools.find('.texts'));
_initToolBtn('eraser', false, new Whiteout(wb, settings, sBtn));
_initToolBtn('paint', false, new Paint(wb, settings, sBtn));
_initToolBtn('line', false, new Line(wb, settings, sBtn));
_initToolBtn('uline', false, new ULine(wb, settings, sBtn));
_initToolBtn('rect', false, new Rect(wb, settings, sBtn));
_initToolBtn('ellipse', false, new Ellipse(wb, settings, sBtn));
_initToolBtn('arrow', false, new Arrow(wb, settings, sBtn));
_initGroupHandle(c, tools);
}
function _initCliparts(sBtn) {
const c = OmUtil.tmpl('#wb-area-cliparts');
tools.find('.drawings').after(c);
c.find('.om-icon.clipart').each(function() {
const cur = $(this);
cur.css('background-image', 'url(' + cur.data('image') + ')')
.click(function() {
_setCurrent(c, cur);
});
_initToolBtn(cur.data('mode'), false, new Clipart(wb, cur, settings, sBtn));
});
_initGroupHandle(c, tools);
}
function _initSettings() {
function setStyle(canvas, styleName, value) {
const o = canvas.getActiveObject();
if (!o) {
return;
}
if (o.setSelectionStyles && o.isEditing) {
const style = {};
style[styleName] = value;
o.setSelectionStyles(style);
} else {
o[styleName] = value;
}
canvas.requestRenderAll();
}
settings.find('.wb-prop-b, .wb-prop-i')
.button()
.click(function() {
$(this).toggleClass('ui-state-active selected');
const btn = _getBtn()
, isB = $(this).hasClass('wb-prop-b')
, style = isB ? 'bold' : 'italic'
, v = $(this).hasClass('selected')
, val = v ? style : '';
btn.data().obj.style[style] = v;
wb.eachCanvas(function(canvas) {
setStyle(canvas, isB ? 'fontWeight' : 'fontStyle', val)
});
});
settings.find('.wb-prop-lock-color, .wb-prop-lock-fill')
.button({icon: 'ui-icon-locked', showLabel: false})
.click(function() {
const btn = _getBtn()
, isColor = $(this).hasClass('wb-prop-lock-color')
, c = settings.find(isColor ? '.wb-prop-color' : '.wb-prop-fill')
, enabled = $(this).button('option', 'icon') === 'ui-icon-locked';
$(this).button('option', 'icon', enabled ? 'ui-icon-unlocked' : 'ui-icon-locked');
c.prop('disabled', !enabled);
btn.data().obj[isColor ? 'stroke' : 'fill'].enabled = enabled;
});
settings.find('.wb-prop-color').change(function() {
const btn = _getBtn();
if (btn.length === 1) {
const v = $(this).val();
btn.data().obj.stroke.color = v;
wb.eachCanvas(function(canvas) {
if ('paint' === mode) {
canvas.freeDrawingBrush.color = v;
} else {
setStyle(canvas, 'stroke', v)
}
});
}
});
settings.find('.wb-prop-width').change(function() {
const btn = _getBtn();
if (btn.length === 1) {
const v = 1 * $(this).val();
btn.data().obj.stroke.width = v;
wb.eachCanvas(function(canvas) {
if ('paint' === mode) {
canvas.freeDrawingBrush.width = v;
} else {
setStyle(canvas, 'strokeWidth', v)
}
});
}
});
settings.find('.wb-prop-fill').change(function() {
const btn = _getBtn();
if (btn.length === 1) {
const v = $(this).val();
btn.data().obj.fill.color = v;
wb.eachCanvas(function(canvas) {
setStyle(canvas, 'fill', v)
});
}
});
settings.find('.wb-prop-opacity').change(function() {
const btn = _getBtn();
if (btn.length === 1) {
const v = (1 * $(this).val()) / 100;
btn.data().obj.opacity = v;
wb.eachCanvas(function(canvas) {
if ('paint' === mode) {
canvas.freeDrawingBrush.opacity = v;
} else {
setStyle(canvas, 'opacity', v)
}
});
}
});
settings.find('.ui-dialog-titlebar-close').click(function() {
settings.hide();
});
settings.draggable({
scroll: false
, handle: '.ui-dialog-titlebar'
, containment: 'body'
, start: function() {
if (!!settings.css('bottom')) {
settings.css('bottom', '').css(Settings.isRtl ? 'left' : 'right', '');
}
}
, drag: function() {
if (settings.position().x + settings.width() >= settings.parent().width()) {
return false;
}
}
});
}
function _initMath() {
math.find('.ui-dialog-titlebar-close').click(function() {
math.hide();
});
math.find('.update-btn').button().click(function() {
const o = wb._findObject({
uid: $(this).data('uid')
, slide: $(this).data('slide')
});
const json = wb._toOmJson(o);
json.formula = math.find('textarea').val();
const cnvs = wb.getCanvas(o.slide);
StaticTMath.create(json, cnvs
, function(obj) {
wb.removeObj([o]);
cnvs.fire('object:modified', {target: obj});
}
, function(msg) {
const err = math.find('.status');
err.text(msg);
StaticTMath.highlight(err);
});
}).parent().css('text-align', Settings.isRtl ? 'left' : 'right');
math.draggable({
scroll: false
, handle: '.ui-dialog-titlebar'
, containment: 'body'
, start: function() {
if (!!math.css('bottom')) {
math.css('bottom', '').css(Settings.isRtl ? 'left' : 'right', '');
}
}
, drag: function() {
if (math.position().x + math.width() >= math.parent().width()) {
return false;
}
}
});
math.resizable({
minHeight: 140
, minWidth: 255
});
}
this.setRole = (role) => {
const btn = _getBtn();
if (__validBtn(btn)) {
btn.data().deactivate();
}
wbEl.find('.tools>div').remove();
wbEl.find('.wb-tool-settings').remove();
WbUtils.safeRemove(tools);
WbUtils.safeRemove(settings);
WbUtils.safeRemove(math);
if (role === Role.NONE) {
__destroySettings();
tools = !!Room.getOptions().questions ? OmUtil.tmpl('#wb-tools-readonly') : wbEl.find('invalid-wb-element');
} else {
tools = OmUtil.tmpl('#wb-tools');
settings = OmUtil.tmpl('#wb-tool-settings');
settings[0].style.display = 'none';
settings[0].style.bottom = '100px';
settings[0].style[(Settings.isRtl ? 'left' : 'right')] = '100px';
math = OmUtil.tmpl('#wb-formula');
math[0].style.display = 'none';
math[0].style.bottom = '100px';
math[0].style[(Settings.isRtl ? 'left' : 'right')] = '100px';
wbEl.append(settings, math);
}
wbEl.find('.tools').append(tools);
tools = wbEl.find('.tools>div');
settings = wbEl.find('.wb-tool-settings');
const clearAll = tools.find('.om-icon.clear-all')
, sBtn = tools.find('.om-icon.settings');;
let _firstToolItem = true;
switch (role) {
case Role.PRESENTER:
clearAll.confirmation({
confirmationEvent: 'om-clear-all'
, onConfirm: () => OmUtil.wbAction({action: 'clearAll', data: {wbId: wb.getId()}})
}).removeClass('disabled');
case Role.WHITEBOARD:
if (role === Role.WHITEBOARD) {
clearAll.addClass('disabled');
}
_initToolBtn('pointer', _firstToolItem, new Pointer(wb, settings, sBtn));
_firstToolItem = false;
_initTexts(sBtn);
_initDrawings(sBtn);
_initToolBtn('math', _firstToolItem, new TMath(wb, settings, sBtn));
_initCliparts(sBtn);
tools.find('.om-icon.settings').click(function() {
settings.show();
});
tools.find('.om-icon.math').click(function() {
math.show();
});
tools.find('.om-icon.clear-slide')
.confirmation({
confirmationEvent: 'om-clear-slide'
, onConfirm: function() {
OmUtil.wbAction({action: 'clearSlide', data: {wbId: wb.getId(), slide: wb.slide}});
}
});
tools.find('.om-icon.save').click(function() {
OmUtil.wbAction({action: 'save', data: {wbId: wb.getId()}});
});
tools.find('.om-icon.undo').click(function() {
OmUtil.wbAction({action: 'undo', data: {wbId: wb.getId()}});
});
_initSettings();
_initMath();
case Role.NONE:
_initToolBtn('apointer', _firstToolItem, new APointer(wb, settings, sBtn));
default:
//no-op
}
};
this.reactivateBtn = () => {
const b = _getBtn();
if (__validBtn(b)) {
b.data().deactivate();
b.data().activate();
}
};
this.updateCoordinates = (o) => {
settings.find('.wb-dim-x').val(o.left);
settings.find('.wb-dim-y').val(o.top);
settings.find('.wb-dim-w').val(o.width);
settings.find('.wb-dim-h').val(o.height);
};
this.destroy = () => {
__destroySettings();
};
this.getMode = () => {
return mode;
};
this.getMath = () => {
return math;
};
}
};