Move with arrows in ThemeColorPalette

This commit is contained in:
Julia Radzhabova 2021-07-09 11:42:19 +03:00
parent bce1ec7a56
commit a520792c55
5 changed files with 236 additions and 21 deletions

View file

@ -86,6 +86,8 @@ define([
if (this.options.auto)
this.autocolor = (typeof this.options.auto == 'object') ? this.options.auto.color || '000000' : '000000';
this.cmpEl.on('keydown.after.bs.dropdown', _.bind(this.onAfterKeydownMenu, this));
if (this.options.color!==undefined)
this.setColor(this.options.color);
},
@ -112,7 +114,8 @@ define([
el: this.cmpEl.find('#' + this.menu.id + '-color-menu'),
transparent: this.options.transparent,
value: color,
colors: colors
colors: colors,
parentMenu: (typeof this.menu == 'object') ? this.menu : undefined
});
this.colorPicker.on('select', _.bind(this.onColorSelect, this));
this.cmpEl.find('#' + this.menu.id + '-color-new').on('click', _.bind(this.addNewColor, this));
@ -121,6 +124,12 @@ define([
this.colorAuto = this.cmpEl.find('#' + this.menu.id + '-color-auto > a');
(color == 'auto') && this.setAutoColor(true);
}
var me = this;
(typeof this.menu == 'object') && this.menu.on('show:after', function(menu) {
_.delay(function() {
me.colorPicker.focus();
}, 10);
})
}
return this.colorPicker;
},
@ -150,6 +159,18 @@ define([
{ template: _.template('<a id="' + id + '-color-new" style="">' + this.textNewColor + '</a>') }
])
});
this.colorPicker && (this.colorPicker.parentMenu = menu);
var me = this;
menu.on('show:after', function(menu) {
me.colorPicker && _.delay(function() {
me.colorPicker.showLastSelected();
me.colorPicker.focus();
}, 10);
}).on('hide:after', function() {
if (me.options.takeFocusOnClose) {
setTimeout(function(){me.focus();}, 1);
}
});
return menu;
}
return this.menu;
@ -184,6 +205,21 @@ define([
return this.colorAuto && this.colorAuto.hasClass('selected');
},
focus: function() {
this.cmpEl && this.cmpEl.focus();
},
onAfterKeydownMenu: function(e) {
if ((e.keyCode == Common.UI.Keys.DOWN || e.keyCode == Common.UI.Keys.SPACE) && !this.isMenuOpen()) {
$('button', this.cmpEl).click();
return false;
}
},
isMenuOpen: function() {
return this.cmpEl.hasClass('open');
},
textNewColor: 'Add New Custom Color',
textAutoColor: 'Automatic'

View file

@ -71,6 +71,8 @@ Common.UI.FocusManager = new(function() {
item.selector = '.radiobox';
else if (field instanceof Common.UI.TreeView)
item.selector = '.treeview';
else if (field instanceof Common.UI.ColorButton)
item.selector = '.btn-group';
else if (field instanceof Common.UI.Button)
item.selector = 'button';
else

View file

@ -55,26 +55,28 @@ define([
effects: 5,
allowReselect: true,
transparent: false,
value: '000000'
value: '000000',
enableKeyEvents: true,
keyMoveDirection: 'both' // 'vertical', 'horizontal'
},
template :
_.template(
'<div style="padding: 8px 12px 12px;">' +
'<% var me = this; %>' +
'<% var me = this; var idx = 0; %>' +
'<% $(colors).each(function(num, item) { %>' +
'<% if (me.isBlankSeparator(item)) { %> <div class="palette-color-spacer" style="width:100%;height:8px;float:left;"></div>' +
'<% } else if (me.isSeparator(item)) { %> </div><div class="divider" style="width:100%;float:left;"></div><div style="padding: 12px;">' +
'<% } else if (me.isColor(item)) { %> ' +
'<a class="palette-color color-<%=item%>" style="background:#<%=item%>" hidefocus="on">' +
'<a class="palette-color color-<%=item%>" style="background:#<%=item%>" idx="<%=idx++%>">' +
'<em><span style="background:#<%=item%>;" unselectable="on">&#160;</span></em>' +
'</a>' +
'<% } else if (me.isTransparent(item)) { %>' +
'<a class="color-<%=item%>" hidefocus="on">' +
'<a class="color-<%=item%>" idx="<%=idx++%>">' +
'<em><span unselectable="on">&#160;</span></em>' +
'</a>' +
'<% } else if (me.isEffect(item)) { %>' +
'<a effectid="<%=item.effectId%>" effectvalue="<%=item.effectValue%>" class="palette-color-effect color-<%=item.color%>" style="background:#<%=item.color%>" hidefocus="on">' +
'<a effectid="<%=item.effectId%>" effectvalue="<%=item.effectValue%>" class="palette-color-effect color-<%=item.color%>" style="background:#<%=item.color%>" idx="<%=idx++%>">' +
'<em><span style="background:#<%=item.color%>;" unselectable="on">&#160;</span></em>' +
'</a>' +
'<% } else if (me.isCaption(item)) { %>' +
@ -85,7 +87,7 @@ define([
'<% if (me.options.dynamiccolors!==undefined) { %>' +
'<div class="palette-color-spacer" style="width:100%;height:8px;float:left;"></div><div style="padding: 12px;">' +
'<% for (var i=0; i<me.options.dynamiccolors; i++) { %>' +
'<a class="color-dynamic-<%=i%> dynamic-empty-color" style="background:#ffffff" color="" hidefocus="on">' +
'<a class="color-dynamic-<%=i%> dynamic-empty-color" style="background:#ffffff" color="" idx="<%=idx++%>">' +
'<em><span unselectable="on">&#160;</span></em></a>' +
'<% } %>' +
'<% } %>' +
@ -101,6 +103,18 @@ define([
el = me.$el || $(this.el);
this.colors = me.options.colors || this.generateColorData(me.options.themecolors, me.options.effects, me.options.standardcolors, me.options.transparent);
this.enableKeyEvents= me.options.enableKeyEvents;
this.tabindex = me.options.tabindex || 0;
this.parentMenu = me.options.parentMenu;
this.lastSelectedIdx = -1;
me.colorItems = [];
if (me.options.keyMoveDirection=='vertical')
me.moveKeys = [Common.UI.Keys.UP, Common.UI.Keys.DOWN];
else if (me.options.keyMoveDirection=='horizontal')
me.moveKeys = [Common.UI.Keys.LEFT, Common.UI.Keys.RIGHT];
else
me.moveKeys = [Common.UI.Keys.UP, Common.UI.Keys.DOWN, Common.UI.Keys.LEFT, Common.UI.Keys.RIGHT];
el.addClass('theme-colorpalette');
this.render();
@ -117,6 +131,12 @@ define([
render: function () {
this.$el.html(this.template({colors: this.colors}));
var me = this;
this.moveKeys && this.$el.find('a').each(function(num, item) {
me.colorItems.push({el: item, index: num});
});
this.attachKeyEvents();
return this;
},
@ -165,6 +185,7 @@ define([
});
if (colors[i] == color) {
colorEl.addClass(this.selectedCls);
this.lastSelectedIdx = parseInt(colorEl.attr('idx'));
color = undefined; //select only first found color
}
}
@ -181,20 +202,29 @@ define([
if (target.hasClass('color-transparent') ) {
$(me.el).find('a.' + me.selectedCls).removeClass(me.selectedCls);
target.addClass(me.selectedCls);
me.value = 'transparent';
me.trigger('select', me, 'transparent');
if (!e.suppressEvent) {
me.lastSelectedIdx = parseInt(target.attr('idx'));
me.value = 'transparent';
me.trigger('select', me, 'transparent');
}
} else if ( !(target[0].className.search('color-dynamic')<0) ) {
if (!/dynamic-empty-color/.test(target[0].className)) {
$(me.el).find('a.' + me.selectedCls).removeClass(me.selectedCls);
target.addClass(me.selectedCls);
color = target.attr('color');
if (color) me.trigger('select', me, color);
me.value = color.toUpperCase();
if (color && !e.suppressEvent) {
me.lastSelectedIdx = parseInt(target.attr('idx'));
color = target.attr('color');
me.trigger('select', me, color);
me.value = color.toUpperCase();
}
} else {
setTimeout(function(){
me.addNewColor();
}, 10);
if (e.suppressEvent) {
$(me.el).find('a.' + me.selectedCls).removeClass(me.selectedCls);
target.addClass(me.selectedCls);
} else
setTimeout(function(){
me.addNewColor();
}, 10);
}
} else {
if (!/^[a-fA-F0-9]{6}$/.test(me.value) || _.indexOf(me.colors, me.value)<0 )
@ -206,15 +236,19 @@ define([
color = target[0].className.match(me.colorRe)[1];
if ( target.hasClass('palette-color-effect') ) {
var effectId = parseInt(target.attr('effectid'));
if (color) {
if (color && !e.suppressEvent) {
me.value = color.toUpperCase();
me.trigger('select', me, {color: color, effectId: effectId});
me.lastSelectedIdx = parseInt(target.attr('idx'));
}
} else {
if (/#?[a-fA-F0-9]{6}/.test(color)) {
color = /#?([a-fA-F0-9]{6})/.exec(color)[1].toUpperCase();
me.value = color;
me.trigger('select', me, color);
if (color && !e.suppressEvent) {
me.value = color;
me.trigger('select', me, color);
me.lastSelectedIdx = parseInt(target.attr('idx'));
}
}
}
}
@ -281,6 +315,7 @@ define([
effectEl = el.find('a[effectid="'+color.effectId+'"]').first();
if (effectEl.length>0) {
effectEl.addClass(this.selectedCls);
this.lastSelectedIdx = parseInt(effectEl.attr('idx'));
this.value = effectEl[0].className.match(this.colorRe)[1].toUpperCase();
} else
this.value = false;
@ -288,6 +323,7 @@ define([
effectEl = el.find('a[effectvalue="'+color.effectValue+'"].color-' + color.color.toUpperCase()).first();
if (effectEl.length>0) {
effectEl.addClass(this.selectedCls);
this.lastSelectedIdx = parseInt(effectEl.attr('idx'));
this.value = effectEl[0].className.match(this.colorRe)[1].toUpperCase();
} else
this.value = false;
@ -302,8 +338,9 @@ define([
if (_.indexOf(this.colors, this.value)<0) this.value = false;
if (color != this.value || this.options.allowReselect) {
(color == 'transparent') ? el.find('a.color-transparent').addClass(this.selectedCls) : el.find('a.palette-color.color-' + color).first().addClass(this.selectedCls);
var co = (color == 'transparent') ? el.find('a.color-transparent').addClass(this.selectedCls) : el.find('a.palette-color.color-' + color).first().addClass(this.selectedCls);
this.value = color;
this.lastSelectedIdx = parseInt(co.attr('idx'));
if (suppressEvent !== true) {
this.fireEvent('select', this, color);
}
@ -314,6 +351,7 @@ define([
co = el.find('a[color="'+color+'"]').first();
if (co.length>0) {
co.addClass(this.selectedCls);
this.lastSelectedIdx = parseInt(co.attr('idx'));
this.value = color.toUpperCase();
}
}
@ -338,6 +376,7 @@ define([
co = el.find('a[color="'+color+'"]').first();
if (co.length>0) {
co.addClass(this.selectedCls);
this.lastSelectedIdx = parseInt(co.attr('idx'));
this.value = color;
}
if (suppressEvent !== true) {
@ -418,6 +457,26 @@ define([
clearSelection: function(suppressEvent) {
this.$el.find('a.' + this.selectedCls).removeClass(this.selectedCls);
this.value = undefined;
this.lastSelectedIdx = -1;
},
showLastSelected: function() {
this.selectByIndex(this.lastSelectedIdx, true);
},
getSelectedColor: function() {
var el = this.$el || $(this.el);
var idx = el.find('a.' + this.selectedCls).attr('idx');
return (idx!==undefined) ? this.colorItems[parseInt(idx)] : null;
},
selectByIndex: function(index, suppressEvent) {
var el = this.$el || $(this.el);
el.find('a.' + this.selectedCls).removeClass(this.selectedCls);
if (index>=0 && index<this.colorItems.length) {
this.handleClick({target: this.colorItems[index].el, suppressEvent: suppressEvent});
}
},
generateColorData: function(themecolors, effects, standardcolors, transparent) {
@ -449,6 +508,115 @@ define([
return arr;
},
onKeyDown: function (e, data) {
if (data===undefined) data = e;
if (_.indexOf(this.moveKeys, data.keyCode)>-1 || data.keyCode==Common.UI.Keys.RETURN) {
data.preventDefault();
data.stopPropagation();
var rec = this.getSelectedColor();
if (data.keyCode==Common.UI.Keys.RETURN) {
rec && this.selectByIndex(rec.index);
if (this.parentMenu)
this.parentMenu.hide();
} else {
var idx = rec ? rec.index : -1;
if (idx<0) {
idx = 0;
} else if (this.options.keyMoveDirection == 'both') {
if (this._layoutParams === undefined)
this.fillIndexesArray();
var topIdx = this.colorItems[idx].topIdx,
leftIdx = this.colorItems[idx].leftIdx;
idx = undefined;
if (data.keyCode==Common.UI.Keys.LEFT) {
while (idx===undefined) {
leftIdx--;
if (leftIdx<0) {
leftIdx = this._layoutParams.columns-1;
}
idx = this._layoutParams.itemsIndexes[topIdx][leftIdx];
}
} else if (data.keyCode==Common.UI.Keys.RIGHT) {
while (idx===undefined) {
leftIdx++;
if (leftIdx>this._layoutParams.columns-1) leftIdx = 0;
idx = this._layoutParams.itemsIndexes[topIdx][leftIdx];
}
} else if (data.keyCode==Common.UI.Keys.UP) {
while (idx===undefined) {
topIdx--;
if (topIdx<0) topIdx = this._layoutParams.rows-1;
idx = this._layoutParams.itemsIndexes[topIdx][leftIdx];
}
} else {
while (idx===undefined) {
topIdx++;
if (topIdx>this._layoutParams.rows-1) topIdx = 0;
idx = this._layoutParams.itemsIndexes[topIdx][leftIdx];
}
}
} else {
idx = (data.keyCode==Common.UI.Keys.UP || data.keyCode==Common.UI.Keys.LEFT)
? Math.max(0, idx-1)
: Math.min(this.colorItems.length - 1, idx + 1) ;
}
if (idx !== undefined && idx>=0) {
this._fromKeyDown = true;
this.selectByIndex(idx, true);
this._fromKeyDown = false;
}
}
}
},
fillIndexesArray: function() {
if (this.colorItems.length<=0) return;
this._layoutParams = {
itemsIndexes: [],
columns: 0,
rows: 0
};
var el = $(this.colorItems[0].el),
itemW = el.outerWidth() + parseInt(el.css('margin-left')) + parseInt(el.css('margin-right')),
offsetLeft = this.$el.offset().left,
offsetTop = el.offset().top,
prevtop = -1, topIdx = 0, leftIdx = 0;
for (var i=0; i<this.colorItems.length; i++) {
var top = $(this.colorItems[i].el).offset().top - offsetTop;
leftIdx = Math.floor(($(this.colorItems[i].el).offset().left - offsetLeft)/itemW);
if (top>prevtop) {
prevtop = top;
this._layoutParams.itemsIndexes.push([]);
topIdx = this._layoutParams.itemsIndexes.length-1;
}
this._layoutParams.itemsIndexes[topIdx][leftIdx] = i;
this.colorItems[i].topIdx = topIdx;
this.colorItems[i].leftIdx = leftIdx;
if (this._layoutParams.columns<leftIdx) this._layoutParams.columns = leftIdx;
}
this._layoutParams.rows = this._layoutParams.itemsIndexes.length;
this._layoutParams.columns++;
},
attachKeyEvents: function() {
if (this.enableKeyEvents) {
var el = this.$el || $(this.el);
el.addClass('canfocused');
el.attr('tabindex', this.tabindex.toString());
el.on('keydown', _.bind(this.onKeyDown, this));
}
},
focus: function() {
var el = this.$el || $(this.el);
el && el.focus();
},
textThemeColors : 'Theme Colors',
textStandartColors : 'Standart Colors'
}, Common.UI.ThemeColorPalette || {}));

View file

@ -681,6 +681,15 @@
}
}
.btn-group {
&:focus, &:active, &.open {
.btn-color:not(.disabled) {
border-color: @border-control-focus-ie;
border-color: @border-control-focus;
}
}
}
// for color button auto color
.dropdown-menu {
li > a.selected,

View file

@ -29,7 +29,7 @@
border: @scaled-one-px-value solid @border-color-shading;
}
&:hover, &.selected {
&:hover, &:focus, &.selected {
border-color: @icon-normal-ie;
border-color: @icon-normal;
em span {