/*
* Copyright 2018 Anyware Services
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* This UI helper provides a dialog box to choose a glyph from a given store.
* See #open method.
*/
Ext.define('Ametys.helper.ChooseGlyph', {
singleton: true,
/**
* @property {Ametys.window.DialogBox} _box The dialog box
* @private
*/
/**
* @property {Ext.form.field.Text} _filterField The filter field for glyph
* @private
*/
/**
* @property {Ext.view.View} _dataView The data view for glyph
* @private
*/
/**
* @private
* @property {Function} _cbFn The callback function invoked when glyph are selected
*/
/**
* Configure and open the dialog box
* @param {Object} config The configuration options :
* @param {Object} config.storeCfg (required) The store configuration
* @param {Object} config.storeCfg.proxy (required) The proxy to use for the store
* @param {Object} [config.storeCfg.model=Ametys.helper.ChooseGlyph.Model] The name of the model associated to this store
* @param {String} [config.iconCls] The CSS class for the icon of the dialog box.
* @param {String} [config.title] The title of the dialog box.
* @param {String} [config.helpMessage] The help message to display on top of dialog box.
* @param {Function} config.callback The callback function invoked when a glyph is selected. The callback function will received the following parameters:
* @param {Object} config.callback.glyph The name of selected glyph
*/
open: function (config)
{
this._cbFn = config.callback;
this._createDialogBox(config.title, config.iconCls, config.helpMessage);
this._initDialog(config.storeCfg);
this._box.show();
},
/**
* @private
* Creates the dialog box
* @param {String} [title] The title of the dialog box.
* @param {String} [iconCls] The CSS class for the icon of the dialog box.
* @param {String} [helpMessage] The help message to display on top of dialog box.
*/
_createDialogBox: function(title, iconCls, helpMessage)
{
if (!this._initialized)
{
this._dataView = this._createDataView();
this._filterField = this._createFilterField();
this._box = Ext.create('Ametys.window.DialogBox', {
title: title || "{{i18n PLUGINS_CORE_UI_WIDGET_HELPER_CHOOSEGLYPH_DIALOG_TITLE}}",
width: 450,
height: 350,
layout: {
type: 'vbox',
align: 'stretch'
},
scrollable: false,
alwaysOnTop: true,
referenceHolder: true,
closeAction: 'hide',
iconCls: iconCls || 'ametysicon-puzzle33',
cls: 'choose-glyph-helper',
items: [
{
xtype: "component",
cls: "a-text",
html: helpMessage || "{{i18n PLUGINS_CORE_UI_WIDGET_HELPER_CHOOSEGLYPH_DIALOG_HINT}}"
},
this._filterField,
this._dataView
],
buttons: [{
reference: 'validate',
text: "{{i18n PLUGINS_CORE_UI_WIDGET_HELPER_CHOOSEGLYPH_OK_BUTTON}}",
handler: this._validate,
scope: this
}, {
text: "{{i18n PLUGINS_CORE_UI_WIDGET_HELPER_CHOOSEGLYPH_CANCEL_BUTTON}}",
handler: this._cancel,
scope: this
}]
});
this._initialized = true;
}
},
/**
* @private
* Create a filter for glyph
* @return {Ext.form.field.Text} the glyph filter field
*/
_createFilterField: function()
{
return Ext.create('Ext.form.field.Text', {
cls: 'ametys',
width: '100%',
hideLabel: true,
emptyText: "{{i18n PLUGINS_CORE_UI_WIDGET_HELPER_CHOOSEGLYPH_DIALOG_SEARCH}}",
listeners: {change: Ext.Function.createBuffered(this._searchFilter, 500, this)}
});
},
/**
* @private
* This listener is called on 'keyup' event on filter input field.
* Filters the glyphs on store.
* @param {Ext.form.Field} field The field
*/
_searchFilter: function (field)
{
var value = new String(field.getValue()).trim();
this._dataView.getStore().filter('cssClassNamesAsString', new RegExp(value));
},
/**
* @private
* Create the data view for glyph
* @return {Ext.view.View} the glyph data view
*/
_createDataView: function()
{
var dataView = Ext.create ('Ext.view.View',
{
itemSelector: 'div.data-view-glyph-icon',
cls: "data-view-glyph-icons",
border: false,
overItemCls: 'x-view-over',
selectedItemCls: 'x-view-over',
scrollable: true,
flex: 1,
tpl: new Ext.XTemplate(
'<tpl for=".">',
'<div class="data-view-glyph-icon">',
'<div class="glyph-icon-class {[values.cssClassNames[0]]}" title="{[values.cssClassNames.join(\'\\n\')]}"></div>',
'</div>',
'</tpl>'
)
});
return dataView;
},
/**
* @private
* Initialize the dialog
* @param {Object} storeCfg The store configuration
*/
_initDialog: function(storeCfg)
{
if (!storeCfg)
{
this.getLogger().error('Missing store configuration #storeCfg is missing. Unable to load available glyphs.');
return;
}
var store = Ext.create('Ext.data.Store', Ext.applyIf(storeCfg, {
autoDestroy: true,
model: 'Ametys.helper.ChooseGlyph.Model'
}));
this._dataView.setStore(store);
this._dataView.getStore().load();
this._filterField.setValue("");
store.clearFilter();
store.filter('cssClassNamesAsString', "");
},
/**
* @private
* Function invoked when clicking the 'ok' button, saving the selected glyph
*/
_validate: function ()
{
if (Ext.isFunction(this._cbFn))
{
var glyphNodes = this._dataView.getSelectedNodes();
if (glyphNodes && glyphNodes.length > 0)
{
var glyph = this._dataView.getRecord(glyphNodes[0]);
this._cbFn (glyph.get('cssClassNames')[0]);
}
else
{
this._cbFn (null);
}
}
this._box.hide();
},
/**
* @private
* Fonction invoked when clicking the 'cancel' button
*/
_cancel: function()
{
this._cbFn (null);
this._box.hide();
}
});
/**
* @private
* The model used in the {@link Ametys.helper.ChooseGlyph} store
*/
Ext.define('Ametys.helper.ChooseGlyph.Model', {
extend: 'Ext.data.Model',
fields: [
{ name:'cssClassNames' },
{ name:'cssClassNamesAsString', mapping: 'cssClassNames', compute: function(v) { return v.join(" "); } }
]
});