2016-04-01 13:17:09 +00:00
|
|
|
/*
|
|
|
|
*
|
2019-01-17 13:05:03 +00:00
|
|
|
* (c) Copyright Ascensio System SIA 2010-2019
|
2016-04-01 13:17:09 +00:00
|
|
|
*
|
|
|
|
* This program is a free software product. You can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
|
|
|
* version 3 as published by the Free Software Foundation. In accordance with
|
|
|
|
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
|
|
|
|
* that Ascensio System SIA expressly excludes the warranty of non-infringement
|
|
|
|
* of any third-party rights.
|
|
|
|
*
|
|
|
|
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
|
|
|
|
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
|
|
|
|
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
|
|
|
*
|
2019-01-17 13:00:34 +00:00
|
|
|
* You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha
|
|
|
|
* street, Riga, Latvia, EU, LV-1050.
|
2016-04-01 13:17:09 +00:00
|
|
|
*
|
|
|
|
* The interactive user interfaces in modified source and object code versions
|
|
|
|
* of the Program must display Appropriate Legal Notices, as required under
|
|
|
|
* Section 5 of the GNU AGPL version 3.
|
|
|
|
*
|
|
|
|
* Pursuant to Section 7(b) of the License you must retain the original Product
|
|
|
|
* logo when distributing the program. Pursuant to Section 7(e) we decline to
|
|
|
|
* grant you any rights under trademark law for use of our trademarks.
|
|
|
|
*
|
|
|
|
* All the Product's GUI elements, including illustrations and icon sets, as
|
|
|
|
* well as technical writing content are licensed under the terms of the
|
|
|
|
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
|
|
|
|
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
|
|
|
*
|
|
|
|
*/
|
2016-03-11 00:48:53 +00:00
|
|
|
/**
|
|
|
|
* ComboBoxFonts.js
|
|
|
|
*
|
|
|
|
* Created by Alexander Yuzhin on 2/11/14
|
2018-03-01 12:16:38 +00:00
|
|
|
* Copyright (c) 2018 Ascensio System SIA. All rights reserved.
|
2016-03-11 00:48:53 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (Common === undefined)
|
|
|
|
var Common = {};
|
|
|
|
|
|
|
|
var FONT_TYPE_RECENT = 4;
|
|
|
|
|
|
|
|
define([
|
|
|
|
'common/main/lib/component/ComboBox'
|
|
|
|
], function () {
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
Common.UI.ComboBoxFonts = Common.UI.ComboBox.extend((function() {
|
2021-08-13 14:08:16 +00:00
|
|
|
var iconWidth = 300,
|
|
|
|
iconHeight = Asc.FONT_THUMBNAIL_HEIGHT || 28,
|
2016-03-11 00:48:53 +00:00
|
|
|
thumbCanvas = document.createElement('canvas'),
|
|
|
|
thumbContext = thumbCanvas.getContext('2d'),
|
2021-09-24 10:22:40 +00:00
|
|
|
postfix = (/^(zh|ja|ko)$/i.test(Common.Locale.getCurrentLanguage())) ? '_ea' : '',
|
2021-03-29 19:33:40 +00:00
|
|
|
thumbs = [
|
2021-09-24 10:22:40 +00:00
|
|
|
{ratio: 1, path: '../../../../sdkjs/common/Images/fonts_thumbnail' + postfix + '.png', width: iconWidth, height: iconHeight},
|
|
|
|
{ratio: 1.25, path: '../../../../sdkjs/common/Images/fonts_thumbnail' + postfix + '@1.25x.png', width: iconWidth * 1.25, height: iconHeight * 1.25},
|
|
|
|
{ratio: 1.5, path: '../../../../sdkjs/common/Images/fonts_thumbnail' + postfix + '@1.5x.png', width: iconWidth * 1.5, height: iconHeight * 1.5},
|
|
|
|
{ratio: 1.75, path: '../../../../sdkjs/common/Images/fonts_thumbnail' + postfix + '@1.75x.png', width: iconWidth * 1.75, height: iconHeight * 1.75},
|
|
|
|
{ratio: 2, path: '../../../../sdkjs/common/Images/fonts_thumbnail' + postfix + '@2x.png', width: iconWidth * 2, height: iconHeight * 2}
|
2021-03-29 19:33:40 +00:00
|
|
|
],
|
|
|
|
thumbIdx = 0,
|
2021-08-13 14:08:16 +00:00
|
|
|
listItemHeight = 28,
|
2021-03-29 19:33:40 +00:00
|
|
|
spriteCols = 1,
|
|
|
|
applicationPixelRatio = Common.Utils.applicationPixelRatio();
|
2016-03-11 00:48:53 +00:00
|
|
|
|
2022-05-17 14:07:01 +00:00
|
|
|
if ( Common.Controllers.Desktop.isActive() ) {
|
|
|
|
thumbs[0].path = Common.Controllers.Desktop.call('getFontsSprite');
|
|
|
|
thumbs[1].path = Common.Controllers.Desktop.call('getFontsSprite', '@1.25x');
|
|
|
|
thumbs[2].path = Common.Controllers.Desktop.call('getFontsSprite', '@1.5x');
|
|
|
|
thumbs[3].path = Common.Controllers.Desktop.call('getFontsSprite', '@1.75x');
|
|
|
|
thumbs[4].path = Common.Controllers.Desktop.call('getFontsSprite', '@2x');
|
2016-03-11 00:48:53 +00:00
|
|
|
}
|
|
|
|
|
2021-03-29 19:33:40 +00:00
|
|
|
var bestDistance = Math.abs(applicationPixelRatio-thumbs[0].ratio);
|
|
|
|
var currentDistance = 0;
|
|
|
|
for (var i=1; i<thumbs.length; i++) {
|
|
|
|
currentDistance = Math.abs(applicationPixelRatio-thumbs[i].ratio);
|
|
|
|
if (currentDistance < (bestDistance - 0.0001))
|
|
|
|
{
|
|
|
|
bestDistance = currentDistance;
|
|
|
|
thumbIdx = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
thumbCanvas.height = thumbs[thumbIdx].height;
|
|
|
|
thumbCanvas.width = thumbs[thumbIdx].width;
|
2016-03-11 00:48:53 +00:00
|
|
|
|
2022-05-13 17:44:32 +00:00
|
|
|
function CThumbnailLoader() {
|
2022-05-25 13:48:17 +00:00
|
|
|
this.supportBinaryFormat = !(Common.Controllers.Desktop.isActive() && !Common.Controllers.isFeatureAvailable('isSupportBinaryFontsSprite'));
|
2022-05-13 17:44:32 +00:00
|
|
|
|
|
|
|
this.image = null;
|
2022-05-14 14:36:18 +00:00
|
|
|
this.binaryFormat = null;
|
2022-05-13 17:44:32 +00:00
|
|
|
this.data = null;
|
|
|
|
this.width = 0;
|
|
|
|
this.height = 0;
|
|
|
|
this.heightOne = 0;
|
|
|
|
this.count = 0;
|
|
|
|
|
|
|
|
this.load = function(url, callback) {
|
|
|
|
if (!callback)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!this.supportBinaryFormat) {
|
|
|
|
this.width = thumbs[thumbIdx].width;
|
|
|
|
this.heightOne = thumbs[thumbIdx].height;
|
|
|
|
|
|
|
|
this.image = new Image();
|
|
|
|
this.image.onload = callback;
|
|
|
|
this.image.src = thumbs[thumbIdx].path;
|
|
|
|
} else {
|
|
|
|
var me = this;
|
|
|
|
var xhr = new XMLHttpRequest();
|
|
|
|
xhr.open('GET', url + ".bin", true);
|
|
|
|
xhr.responseType = 'arraybuffer';
|
|
|
|
|
|
|
|
if (xhr.overrideMimeType)
|
|
|
|
xhr.overrideMimeType('text/plain; charset=x-user-defined');
|
|
|
|
else
|
|
|
|
xhr.setRequestHeader('Accept-Charset', 'x-user-defined');
|
|
|
|
|
|
|
|
xhr.onload = function() {
|
|
|
|
// TODO: check errors
|
2022-05-14 14:36:18 +00:00
|
|
|
me.binaryFormat = this.response;
|
2022-05-13 17:44:32 +00:00
|
|
|
callback();
|
|
|
|
};
|
|
|
|
|
|
|
|
xhr.send(null);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
this.openBinary = function(arrayBuffer) {
|
2022-05-14 13:34:00 +00:00
|
|
|
//var t1 = performance.now();
|
|
|
|
|
2022-05-13 17:44:32 +00:00
|
|
|
var binaryAlpha = new Uint8Array(arrayBuffer);
|
2022-05-14 13:34:00 +00:00
|
|
|
this.width = (binaryAlpha[0] << 24) | (binaryAlpha[1] << 16) | (binaryAlpha[2] << 8) | (binaryAlpha[3] << 0);
|
|
|
|
this.heightOne = (binaryAlpha[4] << 24) | (binaryAlpha[5] << 16) | (binaryAlpha[6] << 8) | (binaryAlpha[7] << 0);
|
|
|
|
this.count = (binaryAlpha[8] << 24) | (binaryAlpha[9] << 16) | (binaryAlpha[10] << 8) | (binaryAlpha[11] << 0);
|
|
|
|
this.height = this.count * this.heightOne;
|
2022-05-13 17:44:32 +00:00
|
|
|
|
|
|
|
this.data = new Uint8ClampedArray(4 * this.width * this.height);
|
|
|
|
|
|
|
|
var binaryIndex = 12;
|
|
|
|
var binaryLen = binaryAlpha.length;
|
|
|
|
var imagePixels = this.data;
|
2022-05-14 13:34:00 +00:00
|
|
|
var index = 0;
|
2022-05-13 17:44:32 +00:00
|
|
|
|
|
|
|
var len0 = 0;
|
2022-05-14 13:34:00 +00:00
|
|
|
var tmpValue = 0;
|
2022-05-13 17:44:32 +00:00
|
|
|
while (binaryIndex < binaryLen) {
|
2022-05-14 13:34:00 +00:00
|
|
|
tmpValue = binaryAlpha[binaryIndex++];
|
|
|
|
if (0 == tmpValue) {
|
|
|
|
len0 = binaryAlpha[binaryIndex++];
|
2022-05-13 17:44:32 +00:00
|
|
|
while (len0 > 0) {
|
|
|
|
len0--;
|
2022-05-14 13:34:00 +00:00
|
|
|
imagePixels[index] = imagePixels[index + 1] = imagePixels[index + 2] = 255;
|
|
|
|
imagePixels[index + 3] = 0; // this value is already 0.
|
|
|
|
index += 4;
|
2022-05-13 17:44:32 +00:00
|
|
|
}
|
2022-05-14 13:34:00 +00:00
|
|
|
} else {
|
|
|
|
imagePixels[index] = imagePixels[index + 1] = imagePixels[index + 2] = 255 - tmpValue;
|
|
|
|
imagePixels[index + 3] = tmpValue;
|
|
|
|
index += 4;
|
2022-05-13 17:44:32 +00:00
|
|
|
}
|
|
|
|
}
|
2022-05-14 13:34:00 +00:00
|
|
|
|
|
|
|
//var t2 = performance.now();
|
|
|
|
//console.log(t2 - t1);
|
2022-05-13 17:44:32 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
this.getImage = function(index, canvas, ctx) {
|
|
|
|
|
|
|
|
//var t1 = performance.now();
|
|
|
|
if (!canvas)
|
|
|
|
{
|
|
|
|
canvas = document.createElement("canvas");
|
|
|
|
canvas.width = this.width;
|
|
|
|
canvas.height = this.heightOne;
|
|
|
|
canvas.style.width = iconWidth + "px";
|
|
|
|
canvas.style.height = iconHeight + "px";
|
|
|
|
|
|
|
|
ctx = canvas.getContext("2d");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.supportBinaryFormat) {
|
2022-05-14 14:36:18 +00:00
|
|
|
if (!this.data) {
|
|
|
|
this.openBinary(this.binaryFormat);
|
|
|
|
delete this.binaryFormat;
|
|
|
|
}
|
|
|
|
|
2022-05-13 17:44:32 +00:00
|
|
|
var dataTmp = ctx.createImageData(this.width, this.heightOne);
|
|
|
|
var sizeImage = 4 * this.width * this.heightOne;
|
|
|
|
dataTmp.data.set(new Uint8ClampedArray(this.data.buffer, index * sizeImage, sizeImage));
|
|
|
|
ctx.putImageData(dataTmp, 0, 0);
|
|
|
|
} else {
|
|
|
|
ctx.clearRect(0, 0, this.width, this.heightOne);
|
|
|
|
ctx.drawImage(this.image, 0, -this.heightOne * index);
|
|
|
|
}
|
|
|
|
|
|
|
|
//var t2 = performance.now();
|
|
|
|
//console.log(t2 - t1);
|
|
|
|
|
|
|
|
return canvas;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2016-03-11 00:48:53 +00:00
|
|
|
return {
|
|
|
|
template: _.template([
|
|
|
|
'<div class="input-group combobox fonts <%= cls %>" id="<%= id %>" style="<%= style %>">',
|
2021-05-30 11:16:33 +00:00
|
|
|
'<input type="text" class="form-control" spellcheck="false" data-hint="<%= dataHint %>" data-hint-direction="<%= dataHintDirection %>"> ',
|
2016-03-11 00:48:53 +00:00
|
|
|
'<div style="display: table-cell;"></div>',
|
2021-05-30 11:16:33 +00:00
|
|
|
'<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></button>',
|
2016-03-11 00:48:53 +00:00
|
|
|
'<ul class="dropdown-menu <%= menuCls %>" style="<%= menuStyle %>" role="menu">',
|
|
|
|
'<li class="divider">',
|
|
|
|
'<% _.each(items, function(item) { %>',
|
|
|
|
'<li id="<%= item.id %>">',
|
2020-06-05 13:10:48 +00:00
|
|
|
'<a class="font-item" tabindex="-1" type="menuitem" style="height:<%=scope.getListItemHeight()%>px;"></a>',
|
2016-03-11 00:48:53 +00:00
|
|
|
'</li>',
|
|
|
|
'<% }); %>',
|
|
|
|
'</ul>',
|
|
|
|
'</div>'
|
|
|
|
].join('')),
|
|
|
|
|
|
|
|
initialize : function(options) {
|
|
|
|
Common.UI.ComboBox.prototype.initialize.call(this, _.extend(options, {
|
2016-08-12 12:04:12 +00:00
|
|
|
displayField: 'name',
|
|
|
|
scroller: {
|
2017-06-01 14:00:38 +00:00
|
|
|
wheelSpeed: 20,
|
2016-08-03 12:58:47 +00:00
|
|
|
alwaysVisibleY: true,
|
|
|
|
onChange: this.updateVisibleFontsTiles.bind(this)
|
|
|
|
}
|
2016-03-11 00:48:53 +00:00
|
|
|
}));
|
|
|
|
|
2019-05-31 14:55:04 +00:00
|
|
|
this.recent = _.isNumber(options.recent) ? options.recent : 5;
|
2016-03-11 00:48:53 +00:00
|
|
|
|
2019-06-04 12:27:54 +00:00
|
|
|
var filter = Common.localStorage.getKeysFilter();
|
|
|
|
this.appPrefix = (filter && filter.length) ? filter.split(',')[0] : '';
|
|
|
|
|
2019-02-01 10:13:44 +00:00
|
|
|
// Common.NotificationCenter.on('fonts:change', _.bind(this.onApiChangeFont, this));
|
2016-03-11 00:48:53 +00:00
|
|
|
Common.NotificationCenter.on('fonts:load', _.bind(this.fillFonts, this));
|
|
|
|
},
|
|
|
|
|
|
|
|
render : function(parentEl) {
|
|
|
|
var oldRawValue = null;
|
2020-10-02 11:55:27 +00:00
|
|
|
var oldTabindex = '';
|
2016-03-11 00:48:53 +00:00
|
|
|
|
|
|
|
if (!_.isUndefined(this._input)) {
|
|
|
|
oldRawValue = this._input.val();
|
2020-10-02 11:55:27 +00:00
|
|
|
oldTabindex = this._input.attr('tabindex');
|
2016-03-11 00:48:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Common.UI.ComboBox.prototype.render.call(this, parentEl);
|
|
|
|
|
|
|
|
this.setRawValue(oldRawValue);
|
2020-10-02 11:55:27 +00:00
|
|
|
this._input.attr('tabindex', oldTabindex);
|
2016-03-11 00:48:53 +00:00
|
|
|
|
|
|
|
this._input.on('keyup', _.bind(this.onInputKeyUp, this));
|
|
|
|
this._input.on('keydown', _.bind(this.onInputKeyDown, this));
|
2018-03-15 12:30:58 +00:00
|
|
|
this._input.on('focus', _.bind(function() {this.inFormControl = true;}, this));
|
|
|
|
this._input.on('blur', _.bind(function() {this.inFormControl = false;}, this));
|
2016-03-11 00:48:53 +00:00
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
onAfterKeydownMenu: function(e) {
|
|
|
|
var me = this;
|
|
|
|
if (e.keyCode == Common.UI.Keys.RETURN) {
|
|
|
|
if ($(e.target).closest('input').length) { // enter in input field
|
|
|
|
if (this.lastValue !== this._input.val())
|
|
|
|
this._input.trigger('change');
|
2021-01-16 16:00:17 +00:00
|
|
|
else
|
|
|
|
return true;
|
2016-03-11 00:48:53 +00:00
|
|
|
} else { // enter in dropdown list
|
|
|
|
$(e.target).click();
|
|
|
|
if (this.rendered) {
|
|
|
|
if (Common.Utils.isIE)
|
|
|
|
this._input.trigger('change', { onkeydown: true });
|
|
|
|
else
|
|
|
|
this._input.blur();
|
|
|
|
}
|
2021-01-15 13:02:21 +00:00
|
|
|
}
|
2016-03-11 00:48:53 +00:00
|
|
|
return false;
|
|
|
|
} else if (e.keyCode == Common.UI.Keys.ESC && this.isMenuOpen()) {
|
|
|
|
this._input.val(this.lastValue);
|
|
|
|
setTimeout(function() {
|
|
|
|
me.closeMenu();
|
|
|
|
me.onAfterHideMenu(e);
|
|
|
|
}, 10);
|
|
|
|
return false;
|
2017-12-04 13:30:30 +00:00
|
|
|
} else if ((e.keyCode == Common.UI.Keys.HOME && !e.shiftKey || e.keyCode == Common.UI.Keys.END && !e.shiftKey || e.keyCode == Common.UI.Keys.BACKSPACE && !me._input.is(':focus')) && this.isMenuOpen()) {
|
2016-07-27 12:05:52 +00:00
|
|
|
me._input.focus();
|
2016-03-11 00:48:53 +00:00
|
|
|
setTimeout(function() {
|
2016-07-27 12:05:52 +00:00
|
|
|
me._input[0].selectionStart = me._input[0].selectionEnd = (e.keyCode == Common.UI.Keys.HOME) ? 0 : me._input[0].value.length;
|
2016-03-11 00:48:53 +00:00
|
|
|
}, 10);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.updateVisibleFontsTiles();
|
|
|
|
},
|
|
|
|
|
|
|
|
onInputKeyUp: function(e) {
|
2021-11-12 11:30:51 +00:00
|
|
|
if (!this._isKeyDown) return;
|
2016-03-11 00:48:53 +00:00
|
|
|
if (e.keyCode != Common.UI.Keys.RETURN && e.keyCode !== Common.UI.Keys.SHIFT &&
|
|
|
|
e.keyCode !== Common.UI.Keys.CTRL && e.keyCode !== Common.UI.Keys.ALT &&
|
|
|
|
e.keyCode !== Common.UI.Keys.LEFT && e.keyCode !== Common.UI.Keys.RIGHT &&
|
|
|
|
e.keyCode !== Common.UI.Keys.HOME && e.keyCode !== Common.UI.Keys.END &&
|
|
|
|
e.keyCode !== Common.UI.Keys.ESC &&
|
|
|
|
e.keyCode !== Common.UI.Keys.INSERT && e.keyCode !== Common.UI.Keys.TAB){
|
|
|
|
e.stopPropagation();
|
|
|
|
this.selectCandidate(e.keyCode == Common.UI.Keys.DELETE || e.keyCode == Common.UI.Keys.BACKSPACE);
|
|
|
|
if (this._selectedItem) {
|
|
|
|
var me = this;
|
2016-07-27 12:08:34 +00:00
|
|
|
if (me._timerSelection===undefined)
|
|
|
|
me._timerSelection = setInterval(function(){
|
|
|
|
if ((new Date()) - me._inInputKeyDown<100 || !me._selectedItem) return;
|
|
|
|
|
|
|
|
clearInterval(me._timerSelection);
|
|
|
|
me._timerSelection = undefined;
|
|
|
|
var input = me._input[0],
|
|
|
|
text = me._selectedItem.get(me.displayField),
|
|
|
|
inputVal = input.value;
|
|
|
|
if (me.rendered) {
|
|
|
|
if (document.selection) { // IE
|
|
|
|
document.selection.createRange().text = text;
|
|
|
|
} else if (input.selectionStart || input.selectionStart == '0') { //FF и Webkit
|
|
|
|
input.value = text;
|
|
|
|
input.selectionStart = inputVal.length;
|
|
|
|
input.selectionEnd = text.length;
|
|
|
|
}
|
2016-03-11 00:48:53 +00:00
|
|
|
}
|
2016-07-27 12:08:34 +00:00
|
|
|
}, 10);
|
2016-03-11 00:48:53 +00:00
|
|
|
}
|
|
|
|
}
|
2021-11-12 11:30:51 +00:00
|
|
|
this._isKeyDown = false;
|
2016-03-11 00:48:53 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
onInputKeyDown: function(e) {
|
2021-11-12 11:30:51 +00:00
|
|
|
this._isKeyDown = true;
|
2016-07-27 12:08:34 +00:00
|
|
|
this._inInputKeyDown = (new Date());
|
2016-03-11 00:48:53 +00:00
|
|
|
var me = this;
|
|
|
|
|
|
|
|
if (e.keyCode == Common.UI.Keys.ESC){
|
|
|
|
this._input.val(this.lastValue);
|
|
|
|
setTimeout(function() {
|
|
|
|
me.closeMenu();
|
|
|
|
me.onAfterHideMenu(e);
|
|
|
|
}, 10);
|
2020-10-02 11:55:27 +00:00
|
|
|
} else if (e.keyCode != Common.UI.Keys.RETURN && e.keyCode != Common.UI.Keys.CTRL && e.keyCode != Common.UI.Keys.SHIFT && e.keyCode != Common.UI.Keys.ALT && e.keyCode != Common.UI.Keys.TAB){
|
2021-12-05 22:50:14 +00:00
|
|
|
if (!this.isMenuOpen() && !e.ctrlKey) {
|
2016-03-11 00:48:53 +00:00
|
|
|
this.openMenu();
|
2021-12-05 22:50:14 +00:00
|
|
|
(this.recent > 0) && this.flushVisibleFontsTiles();
|
|
|
|
}
|
2016-03-11 00:48:53 +00:00
|
|
|
|
|
|
|
if (e.keyCode == Common.UI.Keys.UP || e.keyCode == Common.UI.Keys.DOWN) {
|
|
|
|
_.delay(function() {
|
2016-03-16 12:48:39 +00:00
|
|
|
var selected = (e.keyCode == Common.UI.Keys.DOWN) ? me.cmpEl.find('ul li.selected').nextAll('li:not(.divider)') : me.cmpEl.find('ul li.selected').prevAll('li:not(.divider)');
|
|
|
|
selected = (selected.length>0) ? selected.eq(0) : ((e.keyCode == Common.UI.Keys.DOWN) ? me.cmpEl.find('ul li:not(.divider):first') : me.cmpEl.find('ul li:not(.divider):last'));
|
|
|
|
selected = selected.find('a');
|
2016-03-11 00:48:53 +00:00
|
|
|
|
|
|
|
me._skipInputChange = true;
|
|
|
|
selected.focus();
|
|
|
|
me.updateVisibleFontsTiles();
|
|
|
|
}, 10);
|
|
|
|
} else
|
|
|
|
me._skipInputChange = false;
|
2018-04-11 09:15:27 +00:00
|
|
|
} else if (e.keyCode == Common.UI.Keys.RETURN && this._input.val() === me.lastValue){
|
|
|
|
this._input.trigger('change', { reapply: true });
|
2016-03-11 00:48:53 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
onInputChanged: function(e, extra) {
|
|
|
|
// skip processing for internally-generated synthetic event
|
|
|
|
// to avoid double processing
|
|
|
|
if (extra && extra.synthetic)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (this._skipInputChange) {
|
|
|
|
this._skipInputChange = false; return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this._isMouseDownMenu) {
|
|
|
|
this._isMouseDownMenu = false; return;
|
|
|
|
}
|
|
|
|
|
|
|
|
var val = $(e.target).val(),
|
|
|
|
record = {};
|
|
|
|
|
2018-04-11 09:15:27 +00:00
|
|
|
if (this.lastValue === val && !(extra && extra.reapply)) {
|
2016-03-11 00:48:53 +00:00
|
|
|
if (extra && extra.onkeydown)
|
|
|
|
this.trigger('combo:blur', this, e);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
record[this.valueField] = val;
|
|
|
|
record[this.displayField] = val;
|
|
|
|
|
|
|
|
this.trigger('changed:before', this, record, e);
|
|
|
|
|
|
|
|
if (e.isDefaultPrevented())
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (this._selectedItem) {
|
|
|
|
record[this.valueField] = this._selectedItem.get(this.displayField);
|
|
|
|
this.setRawValue(record[this.valueField]);
|
|
|
|
this.trigger('selected', this, _.extend({}, this._selectedItem.toJSON()), e);
|
|
|
|
this.addItemToRecent(this._selectedItem);
|
|
|
|
this.closeMenu();
|
|
|
|
} else {
|
|
|
|
this.setRawValue(record[this.valueField]);
|
|
|
|
record['isNewFont'] = true;
|
|
|
|
this.trigger('selected', this, record, e);
|
|
|
|
this.closeMenu();
|
|
|
|
}
|
|
|
|
|
|
|
|
// trigger changed event
|
|
|
|
this.trigger('changed:after', this, record, e);
|
|
|
|
},
|
|
|
|
|
|
|
|
getImageUri: function(opts) {
|
|
|
|
if (opts.cloneid) {
|
|
|
|
var img = $(this.el).find('ul > li#'+opts.cloneid + ' img');
|
|
|
|
return img != null ? img[0].src : undefined;
|
|
|
|
}
|
|
|
|
|
2022-05-13 17:44:32 +00:00
|
|
|
var index = Math.floor(opts.imgidx/spriteCols);
|
|
|
|
return this.spriteThumbs.getImage(index, thumbCanvas, thumbContext).toDataURL();
|
2016-03-11 00:48:53 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
getImageWidth: function() {
|
|
|
|
return iconWidth;
|
|
|
|
},
|
|
|
|
|
|
|
|
getImageHeight: function() {
|
|
|
|
return iconHeight;
|
|
|
|
},
|
|
|
|
|
|
|
|
getListItemHeight: function() {
|
|
|
|
return listItemHeight;
|
|
|
|
},
|
|
|
|
|
|
|
|
loadSprite: function(callback) {
|
2022-05-13 17:44:32 +00:00
|
|
|
this.spriteThumbs = new CThumbnailLoader();
|
|
|
|
this.spriteThumbs.load(thumbs[thumbIdx].path, callback);
|
2016-03-11 00:48:53 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
fillFonts: function(store, select) {
|
|
|
|
var me = this;
|
|
|
|
|
|
|
|
this.loadSprite(function() {
|
2021-03-29 19:33:40 +00:00
|
|
|
spriteCols = Math.floor(me.spriteThumbs.width / (thumbs[thumbIdx].width)) || 1;
|
2016-03-11 00:48:53 +00:00
|
|
|
me.store.set(store.toJSON());
|
|
|
|
|
|
|
|
me.rendered = false;
|
2019-04-24 14:39:20 +00:00
|
|
|
if (!_.isUndefined(me.scroller)) {
|
|
|
|
me.scroller.destroy();
|
|
|
|
delete me.scroller;
|
|
|
|
}
|
|
|
|
me._scrollerIsInited = false;
|
2016-03-11 00:48:53 +00:00
|
|
|
me.render($(me.el));
|
|
|
|
|
|
|
|
me._fontsArray = me.store.toJSON();
|
|
|
|
|
|
|
|
if (me.recent > 0) {
|
|
|
|
me.store.on('add', me.onInsertItem, me);
|
|
|
|
me.store.on('remove', me.onRemoveItem, me);
|
2019-06-04 12:27:54 +00:00
|
|
|
|
|
|
|
Common.Utils.InternalSettings.set(me.appPrefix + "-settings-recent-fonts", Common.localStorage.getItem(me.appPrefix + "-settings-recent-fonts"));
|
|
|
|
var arr = Common.Utils.InternalSettings.get(me.appPrefix + "-settings-recent-fonts");
|
|
|
|
arr = arr ? arr.split(';') : [];
|
|
|
|
arr.reverse().forEach(function(item) {
|
|
|
|
item && me.addItemToRecent(me.store.findWhere({name: item}), true);
|
|
|
|
});
|
2016-03-11 00:48:53 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
onApiChangeFont: function(font) {
|
2018-03-15 14:14:09 +00:00
|
|
|
var me = this;
|
2020-11-11 12:32:19 +00:00
|
|
|
var name = (_.isFunction(font.get_Name) ? font.get_Name() : font.asc_getFontName());
|
|
|
|
if (this.__name !== name) {
|
2021-04-20 12:29:32 +00:00
|
|
|
this.__name = name;
|
2020-11-11 12:32:19 +00:00
|
|
|
if (!this.__nameId) {
|
|
|
|
this.__nameId = setTimeout(function () {
|
2021-04-20 12:29:32 +00:00
|
|
|
me.onApiChangeFontInternal(me.__name);
|
2020-11-11 12:32:19 +00:00
|
|
|
me.__nameId = null;
|
|
|
|
}, 100);
|
|
|
|
}
|
2021-04-20 12:29:32 +00:00
|
|
|
|
2020-11-11 12:32:19 +00:00
|
|
|
}
|
2018-03-15 14:14:09 +00:00
|
|
|
},
|
|
|
|
|
2020-11-11 12:32:19 +00:00
|
|
|
onApiChangeFontInternal: function(name) {
|
2018-03-15 12:30:58 +00:00
|
|
|
if (this.inFormControl) return;
|
|
|
|
|
2016-03-11 00:48:53 +00:00
|
|
|
if (this.getRawValue() !== name) {
|
|
|
|
var record = this.store.findWhere({
|
|
|
|
name: name
|
|
|
|
});
|
|
|
|
|
|
|
|
$('.selected', $(this.el)).removeClass('selected');
|
|
|
|
|
|
|
|
if (record) {
|
|
|
|
this.setRawValue(record.get(this.displayField));
|
|
|
|
var itemNode = $('#' + record.get('id'), $(this.el)),
|
|
|
|
menuNode = $('ul.dropdown-menu', this.cmpEl);
|
|
|
|
|
|
|
|
if (itemNode && menuNode) {
|
|
|
|
itemNode.addClass('selected');
|
|
|
|
if (this.recent<=0)
|
|
|
|
menuNode.scrollTop(itemNode.offset().top - menuNode.offset().top);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
this.setRawValue(name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
itemClicked: function (e) {
|
2021-02-10 13:06:02 +00:00
|
|
|
this.__name = undefined;
|
2021-02-10 14:00:47 +00:00
|
|
|
if (this.__nameId) {
|
2021-02-10 13:06:02 +00:00
|
|
|
clearTimeout(this.__nameId);
|
|
|
|
this.__nameId = undefined;
|
|
|
|
}
|
|
|
|
|
2019-06-04 12:27:54 +00:00
|
|
|
Common.UI.ComboBox.prototype.itemClicked.apply(this, arguments);
|
|
|
|
|
2016-03-11 00:48:53 +00:00
|
|
|
var el = $(e.target).closest('li');
|
|
|
|
var record = this.store.findWhere({id: el.attr('id')});
|
|
|
|
this.addItemToRecent(record);
|
|
|
|
},
|
|
|
|
|
|
|
|
onInsertItem: function(item) {
|
|
|
|
$(this.el).find('ul').prepend(_.template([
|
|
|
|
'<li id="<%= item.id %>">',
|
2020-06-05 13:10:48 +00:00
|
|
|
'<a class="font-item" tabindex="-1" type="menuitem" style="height:<%=scope.getListItemHeight()%>px;"></a>',
|
2016-03-11 00:48:53 +00:00
|
|
|
'</li>'
|
2017-04-21 08:10:07 +00:00
|
|
|
].join(''))({
|
2016-03-11 00:48:53 +00:00
|
|
|
item: item.attributes,
|
|
|
|
scope: this
|
|
|
|
}));
|
|
|
|
},
|
|
|
|
|
|
|
|
onRemoveItem: function(item, store, opts) {
|
|
|
|
$(this.el).find('ul > li#'+item.id).remove();
|
|
|
|
},
|
|
|
|
|
|
|
|
onBeforeShowMenu: function(e) {
|
2019-05-31 08:45:02 +00:00
|
|
|
if (this.store.length<1) {
|
|
|
|
e.preventDefault();
|
|
|
|
return;
|
|
|
|
}
|
2016-03-11 00:48:53 +00:00
|
|
|
Common.UI.ComboBox.prototype.onBeforeShowMenu.apply(this, arguments);
|
|
|
|
|
|
|
|
if (!this.getSelectedRecord() && !!this.getRawValue()) {
|
|
|
|
var record = this.store.where({name: this.getRawValue()});
|
|
|
|
if (record && record.length) {
|
|
|
|
this.selectRecord(record[record.length - 1]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
onAfterShowMenu: function(e) {
|
|
|
|
if (this.recent > 0) {
|
|
|
|
if (this.scroller && !this._scrollerIsInited) {
|
|
|
|
this.scroller.update();
|
|
|
|
this._scrollerIsInited = true;
|
|
|
|
}
|
|
|
|
$(this.el).find('ul').scrollTop(0);
|
|
|
|
this.trigger('show:after', this, e);
|
2017-05-24 12:04:06 +00:00
|
|
|
this.flushVisibleFontsTiles();
|
|
|
|
this.updateVisibleFontsTiles(null, 0);
|
2022-03-31 17:29:11 +00:00
|
|
|
Common.Utils.isGecko && this.scroller && this.scroller.update();
|
2016-03-11 00:48:53 +00:00
|
|
|
} else {
|
|
|
|
Common.UI.ComboBox.prototype.onAfterShowMenu.apply(this, arguments);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
onAfterHideMenu: function(e) {
|
|
|
|
if (this.lastValue !== this._input.val())
|
|
|
|
this._input.val(this.lastValue);
|
|
|
|
|
|
|
|
Common.UI.ComboBox.prototype.onAfterHideMenu.apply(this, arguments);
|
|
|
|
},
|
|
|
|
|
2019-06-04 12:27:54 +00:00
|
|
|
addItemToRecent: function(record, silent) {
|
2019-10-10 09:03:30 +00:00
|
|
|
if (!record || this.recent<1) return;
|
2017-05-24 12:04:06 +00:00
|
|
|
|
2019-06-04 12:27:54 +00:00
|
|
|
var font = this.store.findWhere({name: record.get('name'),type:FONT_TYPE_RECENT});
|
|
|
|
font && this.store.remove(font);
|
|
|
|
|
|
|
|
var fonts = this.store.where({type:FONT_TYPE_RECENT});
|
|
|
|
if (!(fonts.length < this.recent)) {
|
|
|
|
this.store.remove(fonts[this.recent - 1]);
|
|
|
|
}
|
2016-03-11 00:48:53 +00:00
|
|
|
|
2019-06-04 12:27:54 +00:00
|
|
|
var new_record = record.clone();
|
|
|
|
new_record.set({'type': FONT_TYPE_RECENT, 'id': Common.UI.getId(), cloneid: record.id});
|
|
|
|
this.store.add(new_record, {at:0});
|
|
|
|
|
|
|
|
if (!silent) {
|
|
|
|
var arr = [];
|
|
|
|
this.store.where({type:FONT_TYPE_RECENT}).forEach(function(item){
|
|
|
|
arr.push(item.get('name'));
|
|
|
|
});
|
|
|
|
arr = arr.join(';');
|
|
|
|
Common.localStorage.setItem(this.appPrefix + "-settings-recent-fonts", arr);
|
|
|
|
Common.Utils.InternalSettings.set(this.appPrefix + "-settings-recent-fonts", arr);
|
2016-03-11 00:48:53 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
selectCandidate: function(full) {
|
|
|
|
var me = this,
|
|
|
|
inputVal = this._input.val().toLowerCase();
|
|
|
|
|
|
|
|
if (!this._fontsArray)
|
|
|
|
this._fontsArray = this.store.toJSON();
|
|
|
|
|
|
|
|
var font = _.find(this._fontsArray, function(font) {
|
|
|
|
return (full) ? (font[me.displayField].toLowerCase() == inputVal) : (font[me.displayField].toLowerCase().indexOf(inputVal) == 0)
|
|
|
|
});
|
|
|
|
|
|
|
|
if (font) {
|
|
|
|
this._selectedItem = this.store.findWhere({
|
|
|
|
id: font.id
|
|
|
|
});
|
|
|
|
} else
|
|
|
|
this._selectedItem = null;
|
|
|
|
|
|
|
|
$('.selected', $(this.el)).removeClass('selected');
|
|
|
|
|
|
|
|
if (this._selectedItem) {
|
|
|
|
var itemNode = $('#' + this._selectedItem.get('id'), $(this.el)),
|
|
|
|
menuEl = $('ul[role=menu]', $(this.el));
|
|
|
|
|
|
|
|
if (itemNode.length > 0 && menuEl.length > 0) {
|
|
|
|
itemNode.addClass('selected');
|
|
|
|
|
|
|
|
var itemTop = itemNode.position().top,
|
|
|
|
menuTop = menuEl.scrollTop();
|
|
|
|
|
|
|
|
if (itemTop != 0)
|
|
|
|
menuEl.scrollTop(menuTop + itemTop);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
updateVisibleFontsTiles: function(e, scrollY) {
|
|
|
|
var me = this, j = 0, storeCount = me.store.length, index = 0;
|
|
|
|
|
|
|
|
if (!me.tiles) me.tiles = [];
|
|
|
|
if (storeCount !== me.tiles.length) {
|
|
|
|
for (j = me.tiles.length; j < storeCount; ++j) {
|
2016-11-07 14:52:07 +00:00
|
|
|
me.tiles.unshift(null);
|
2016-03-11 00:48:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_.isUndefined(scrollY)) scrollY = parseInt($(me.el).find('.ps-scrollbar-x-rail').css('bottom'));
|
|
|
|
|
|
|
|
var scrollH = $(me.el).find('.dropdown-menu').height(),
|
|
|
|
count = Math.max(Math.floor(scrollH / listItemHeight) + 3, 0),
|
|
|
|
from = Math.max(Math.floor(-(scrollY / listItemHeight)) - 1, 0),
|
|
|
|
to = from + count;
|
|
|
|
|
|
|
|
var listItems = $(me.el).find('a');
|
|
|
|
|
|
|
|
for (j = 0; j < storeCount; ++j) {
|
|
|
|
if (from <= j && j < to) {
|
|
|
|
if (null === me.tiles[j]) {
|
2020-09-09 15:58:34 +00:00
|
|
|
index = Math.floor(me.store.at(j).get('imgidx')/spriteCols);
|
2022-05-13 17:44:32 +00:00
|
|
|
var fontImage = me.spriteThumbs.getImage(index);
|
2016-03-11 00:48:53 +00:00
|
|
|
|
|
|
|
me.tiles[j] = fontImage;
|
|
|
|
$(listItems[j]).get(0).appendChild(fontImage);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (me.tiles[j]) {
|
|
|
|
me.tiles[j].parentNode.removeChild(me.tiles[j]);
|
|
|
|
me.tiles[j] = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
flushVisibleFontsTiles: function() {
|
|
|
|
for (var j = this.tiles.length - 1; j >= 0; --j) {
|
|
|
|
if (this.tiles[j]) {
|
|
|
|
this.tiles[j].parentNode.removeChild(this.tiles[j]);
|
|
|
|
this.tiles[j] = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})());
|
|
|
|
});
|