src/dialogs/font.js
/*
* OS.js - JavaScript Cloud/Web Desktop Platform
*
* Copyright (c) Anders Evenrud <andersevenrud@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @author Anders Evenrud <andersevenrud@gmail.com>
* @licence Simplified BSD License
*/
import {h, app} from 'hyperapp';
import Dialog from '../dialog';
import {
Toolbar,
SelectField,
TextareaField
} from '@osjs/gui';
/**
* Default OS.js Font Dialog
*/
export default class FontDialog extends Dialog {
/**
* Constructor
* @param {Core} core OS.js Core reference
* @param {Object} args Arguments given from service creation
* @param {number} [args.minSize=6] Minimum size
* @param {number} [args.maxSize] Maximum size
* @param {string} [args.unit=px] Unit
* @param {string} [args.name] Initial font name
* @param {number} [args.size] Initial font size
* @param {string} [args.text] What text to preview
* @param {string[]} [args.controls] What controls to show
* @param {string[]} [args.fonts] List of fonts
* @param {Function} callback The callback function
*/
constructor(core, args, callback) {
args = Object.assign({}, {
title: 'Choose Font',
minSize: 6,
maxSize: 48,
unit: 'px',
name: 'Roboto',
size: 10,
style: 'regular',
text: 'The quick brown fox jumps over the lazy dog',
controls: ['size', 'name', 'style'],
fonts: [
'Roboto',
'arial',
'sans-serif',
'monospace'
]
}, args);
super(core, args, {
className: 'info',
window: {
title: args.title,
attributes: {
minDimension: {
width: 400,
height: 200
}
}
},
buttons: ['ok', 'cancel']
}, callback);
this.value = {
name: this.args.name,
size: this.args.size,
style: this.args.style
};
}
render(options) {
const fontSizes = Array(this.args.maxSize - this.args.minSize)
.fill(0)
.map((v, i) => this.args.minSize + i)
.reduce((o, i) => Object.assign(o, {[i]: i}), {});
const fontNames = this.args.fonts
.reduce((o, i) => {
const k = i.toLowerCase();
return Object.assign(o, {[k]: i});
}, {});
const fontStyles = {
'regular': 'Regular',
'bold': 'Bold',
'italic': 'Italic'
};
const initialState = Object.assign({}, this.value);
const initialActions = {
setSize: size => state => {
this.value.size = size;
return {size};
},
setFont: name => state => {
this.value.name = name;
return {name};
},
setStyle: style => state => {
this.value.style = style;
return {style};
}
};
super.render(options, ($content) => {
app(initialState, initialActions, (state, actions) => this.createView([
h(Toolbar, {}, [
h(SelectField, {
box: {grow: 1, style: {display: this.args.controls.indexOf('size') !== -1 ? 'flex' : 'none'}},
value: state.size,
choices: fontSizes,
onchange: (ev, v) => actions.setSize(v)
}),
h(SelectField, {
box: {grow: 1, style: {display: this.args.controls.indexOf('name') !== -1 ? 'flex' : 'none'}},
value: state.name.toLowerCase(),
choices: fontNames,
onchange: (ev, v) => actions.setFont(v)
}),
h(SelectField, {
box: {grow: 1, style: {display: this.args.controls.indexOf('style') !== -1 ? 'flex' : 'none'}},
value: state.size,
choices: fontStyles,
onchange: (ev, v) => actions.setStyle(v)
})
]),
h(TextareaField, {
box: {grow: 1},
value: this.args.text,
style: {
fontFamily: state.name,
fontSize: `${state.size}${this.args.unit}`,
fontWeight: state.style === 'bold' ? 'bold' : 'normal',
fontStyle: state.style !== 'bold' ? state.style : 'normal',
height: '4rem',
overflow: 'hidden',
whiteSpace: 'nowrap'
}
})
]), $content);
});
}
}