/** * Silex, live web creation * http://projects.silexlabs.org/?/silex/ * * Copyright (c) 2012 Silex Labs * http://www.silexlabs.org/ * * Silex is available under the GPL license * http://www.silexlabs.org/silex/silex-licensing/ */ /** * @fileoverview Property pane, displayed in the property tool box. * Controls the borders params * */ import { SelectableState } from 'drag-drop-stage-component/src/ts/Types'; import { Controller, Model } from '../../types'; import { ColorPicker } from '../ColorPicker'; import { PaneBase } from './pane-base'; /** * on of Silex Editors class * const user edit style of components * @param element container to render the UI * @param model model class which holds * the model instances - views use it for read * operation only * @param controller structure which holds * the controller instances */ export class BorderPane extends PaneBase { /** * input element */ borderWidthInput: HTMLInputElement; /** * input element */ borderStyleComboBox: HTMLSelectElement; /** * input element */ borderRadiusInput: HTMLInputElement; /** * color picker for border color */ colorPicker: ColorPicker; /** * input element */ borderPlacementCheckBoxes: HTMLInputElement[] = null; /** * input element */ cornerPlacementCheckBoxes: HTMLInputElement[] = null; constructor(element: HTMLElement, model: Model, controller: Controller) { super(element, model, controller); // init the component this.buildUi(); } /** * build the UI */ buildUi() { this.colorPicker = new ColorPicker(this.element.querySelector('.color-edit-container'), () => this.onBorderColorChanged()); this.borderPlacementCheckBoxes = [ '.border-placement-container .top', '.border-placement-container .right', '.border-placement-container .bottom', '.border-placement-container .left', ].map((selector) => this.initCheckBox(selector, (e) => this.onBorderWidthChanged())); this.cornerPlacementCheckBoxes = [ '.border-radius-container .top-left', '.border-radius-container .top-right', '.border-radius-container .bottom-right', '.border-radius-container .bottom-left', ].map((selector) => this.initCheckBox(selector, () => this.onBorderCornerChanged())); this.borderWidthInput = this.initInput('.border-width-input', (e) => this.onBorderWidthChanged()); this.borderStyleComboBox = this.initComboBox('.border-type-combo-box', (e) => this.onBorderStyleChanged()); this.borderRadiusInput = this.initInput('.corner-radius-input', (e) => this.onBorderCornerChanged()); } /** * redraw the properties */ redraw(states: SelectableState[], pageNames: string[], currentPageName: string) { super.redraw(states, pageNames, currentPageName); // border width, this builds a string like "0px 1px 2px 3px" // FIXME: should not build a string which is then split in redrawBorderWidth const borderWidth = this.getCommonProperty(states, (state) => { const w = this.model.element.getStyle(state.el, 'border-width'); if (w && w !== '') { return w; } else { return null; } }); // display width or reset borders if width is null if (borderWidth) { this.redrawBorderWidth(borderWidth); this.redrawBorderColor(states); } else { this.resetBorder(); } // border style const borderStyle = this.getCommonProperty(states, (state) => this.model.element.getStyle(state.el, 'border-style')); if (borderStyle) { this.borderStyleComboBox.value = borderStyle; } else { this.borderStyleComboBox.selectedIndex = 0; } // border radius const borderRadiusStr = this.getCommonProperty(states, (state) => this.model.element.getStyle(state.el, 'border-radius')); if (borderRadiusStr) { this.redrawBorderRadius(borderRadiusStr); } else { this.resetBorderRadius(); } } /** * redraw border color UI */ redrawBorderColor(states) { if (states.length > 0) { this.colorPicker.setDisabled(false); const color = this.getCommonProperty(states, (state) => this.model.element.getStyle(state.el, 'border-color') || 'rgba(0,0,0,1)'); // indeterminate state this.colorPicker.setIndeterminate(color == null); // display color if (color != null ) { this.colorPicker.setColor(color); } } else { this.colorPicker.setDisabled(true); } } /** * redraw border radius UI */ redrawBorderRadius(borderWidth) { const values = borderWidth.split(' '); // get corner radius value, get the first non-zero value let val = values[0]; if (values[1] != null && val === '0' || val === '0px') { val = values[1]; } if (values[2] != null && val === '0' || val === '0px') { val = values[2]; } if (values[3] != null && val === '0' || val === '0px') { val = values[3]; } // remove unit when needed if (val != null && val !== '0' && val !== '0px') { this.borderRadiusInput.value = val.substr(0, val.indexOf('px')); // corner placement let idx; const len = this.cornerPlacementCheckBoxes.length; for (idx = 0; idx < len; idx++) { const checkBox = this.cornerPlacementCheckBoxes[idx]; if (values[idx] !== '0' && values[idx] !== '0px') { checkBox.checked = true; } else { checkBox.checked = false; } } } else { this.resetBorderRadius(); } } /** * redraw border width UI */ redrawBorderWidth(borderWidth) { // top, right, bottom, left const values = borderWidth.split(' '); // get the first non-zero value let val = values[0]; if (values[1] != null && val === '0' || val === '0px') { val = values[1]; } if (values[2] != null && val === '0' || val === '0px') { val = values[2]; } if (values[3] != null && val === '0' || val === '0px') { val = values[3]; } // if there is a non-zero value if (val !== '0' && val !== '0px') { this.borderWidthInput.value = val.substr(0, val.indexOf('px')); // border placement const len = this.borderPlacementCheckBoxes.length; for (let idx = 0; idx < len; idx++) { const checkBox = this.borderPlacementCheckBoxes[idx]; if (values.length > idx && values[idx] !== '0' && values[idx] !== '0px') { checkBox.checked = true; } else { checkBox.checked = false; } } } else { this.resetBorder(); } } /** * reset UI */ resetBorderRadius() { this.borderRadiusInput.value = ''; // corner placement let idx; const len = this.cornerPlacementCheckBoxes.length; for (idx = 0; idx < len; idx++) { const checkBox = this.cornerPlacementCheckBoxes[idx]; checkBox.checked = true; } } /** * reset UI */ resetBorder() { this.borderWidthInput.value = ''; // border placement let idx; const len = this.borderPlacementCheckBoxes.length; for (idx = 0; idx < len; idx++) { const checkBox = this.borderPlacementCheckBoxes[idx]; checkBox.checked = true; } // border color this.colorPicker.setColor(''); this.colorPicker.setDisabled(true); } /** * property changed * callback for number inputs */ onBorderWidthChanged() { if (this.borderWidthInput.value && this.borderWidthInput.value !== '' && this.borderWidthInput.value !== '0') { // border color this.colorPicker.setDisabled(false); if (this.colorPicker.getColor() == null || this.colorPicker.getColor() === '') { this.colorPicker.setColor('rgba(0,0,0,1)'); } // border placement let borderWidthStr = ''; let idx; const len = this.borderPlacementCheckBoxes.length; for (idx = 0; idx < len; idx++) { const checkBox = this.borderPlacementCheckBoxes[idx]; if (checkBox.checked) { borderWidthStr += this.borderWidthInput.value + 'px '; } else { borderWidthStr += '0 '; } } // reset indeterminate state (because all selected elements will be // changed the same value) this.colorPicker.setIndeterminate(false); // border width this.styleChanged('border-width', borderWidthStr); // border style this.onBorderStyleChanged(); } else { this.styleChanged('border-width', ''); this.styleChanged('border-style', ''); this.colorPicker.setDisabled(true); } } /** * property changed * callback for number inputs * border style */ onBorderStyleChanged() { this.styleChanged('border-style', this.borderStyleComboBox.value); } /** * property changed * callback for number inputs */ onBorderColorChanged() { this.styleChanged('border-color', this.colorPicker.getColor()); } /** * property changed * callback for number inputs */ onBorderCornerChanged() { // corner radius if (this.borderRadiusInput.value != null && this.borderRadiusInput.value !== '') { // corner placement let borderWidthStr = ''; let idx; const len = this.cornerPlacementCheckBoxes.length; for (idx = 0; idx < len; idx++) { const checkBox = this.cornerPlacementCheckBoxes[idx]; if (checkBox.checked) { borderWidthStr += this.borderRadiusInput.value + 'px '; } else { borderWidthStr += '0 '; } } this.styleChanged('border-radius', borderWidthStr); } else { this.styleChanged('border-radius', ''); } } }