UNPKG

ngui-tools

Version:

A GUI typesetting display engine and cross platform GUI application development framework based on NodeJS/OpenGL

335 lines (294 loc) 8.59 kB
/* ***** BEGIN LICENSE BLOCK ***** * Distributed under the BSD license: * * Copyright (c) 2015-2017, xuewen.chu * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 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. * * Neither the name of xuewen.chu nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * 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 xuewen.chu 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. * * ***** END LICENSE BLOCK ***** */ import './util'; import { CSS, New, Indep, Hybrid, Clip, Input, Span, LimitIndep, Div, Limit, Text, Button, Panel, atomPixel, ngui } from './ngui'; import { Navigation } from './nav'; CSS({ '.x_dialog': { minWidth: 380, maxWidth: '40!', maxHeight: '40!', alignX: 'center', alignY: 'center', backgroundColor: '#fff', borderRadius: 12, }, '.x_dialog .title': { width: 'full', margin: 10, marginTop: 18, marginBottom: 0, textAlign: 'center', textStyle: 'bold', textSize: 18, textOverflow: 'ellipsis', textWhiteSpace: 'no_wrap', }, '.x_dialog .content': { width: 'full', margin: 10, marginTop: 2, marginBottom: 20, textAlign: 'center', textSize: 14, }, '.x_dialog .buttons': { width: 'full', borderRadiusLeftBottom: 12, borderRadiusRightBottom: 12, }, '.x_dialog .button': { height: 43, borderTop: `${atomPixel*0.7} #9da1a0`, textSize: 18, textLineHeight: 43, textColor:"#0079ff", }, '.x_dialog .button:normal': { backgroundColor: '#fff0', time: 180 }, '.x_dialog .button:hover': { backgroundColor: '#E1E4E455', time: 50 }, '.x_dialog .button:down': { backgroundColor: '#E1E4E4', time: 50 }, '.x_dialog .prompt': { marginTop: 10, width: "full", height: 30, backgroundColor: "#eee", borderRadius: 8, }, }) function compute_buttons_width(self) { var btns = self.buttons; if ( btns.length == 1 ) { btns[0].width = 'full'; } else { var main_width = self.find('m_main').finalWidth; if ( main_width ) { for ( var btn of btns ) { btn.width = (main_width / btns.length) - ((btns.length - 1) * atomPixel); btn.borderLeft = `${atomPixel} #9da1a0`; } btns[0].borderLeftWidth = 0; } } } function close(self) { if ( self.defaultClose ) self.close(); } /** * @class Dialog */ export class Dialog extends Navigation { m_btns_count = 0; /** * @event onClickButton */ event onClickButton; /** * @defaultClose */ defaultClose = true; /** * @get length btns */ get length() { return this.m_btns_count; } /** * @overwrite */ loadView(vx) { super.loadView( <Indep width="full" height="full" backgroundColor="#0005" receive=1 visible=0 opacity=0> <LimitIndep id="m_main" class="x_dialog" alignX="center" alignY="center"> <Hybrid id="m_title" class="title" /> <Hybrid id="m_con" class="content">${vx}</Hybrid> <Clip id="m_btns" class="buttons" /> </LimitIndep> </Indep> ); this.view.appendTo(ngui.root); } get title() { return this.find('m_title').innerText } get content() { return this.find('m_con').innerText } set title(value) { this.find('m_title').removeAllChild(); this.find('m_title').appendText(value || ''); } set content(value) { this.find('m_con').removeAllChild(); this.find('m_con').appendText(value || ''); } get buttons() { var btns = this.find('m_btns'); var count = btns.childrenCount; var rv = []; for ( var i = 0; i < count; i++ ) { rv.push( btns.children(i) ); } return rv; } set buttons(btns) { if ( Array.isArray(btns) ) { this.find('m_btns').removeAllChild(); this.m_btns_count = btns.length; for ( var i = 0; i < btns.length; i++ ) { var btn = New( <Button index=i class="button" width="full" onClick="triggerClickButton" defaultHighlighted=0>${btns[i]}</Button>, this.find('m_btns') ); } if ( this.visible ) { compute_buttons_width(this); } } } show() { if (!this.visible) { this.view.appendTo(ngui.root); this.visible = 1; ngui.nextFrame(()=>{ compute_buttons_width(this); var main = this.find('m_main'); main.originX = main.finalWidth / 2; main.originY = main.finalHeight / 2; main.scale = '0.3 0.3'; main.transition({ scale : '1 1', time: 200 }); this.view.opacity = 0.3; this.transition({ opacity : 1, time: 200 }); }); this.registerNavigation(0); } } close() { if ( this.visible ) { var main = this.find('m_main'); main.originX = main.finalWidth / 2; main.originY = main.finalHeight / 2; main.transition({ scale : '0.5 0.5', time: 200 }); this.transition({ opacity : 0.15, time: 200 }, ()=>{ this.remove() }); this.unregisterNavigation(0, null); } else { this.unregisterNavigation(0, null); this.remove(); } } triggerClickButton(evt) { this.trigger('ClickButton', evt.sender.index); close(this); } /** * @overwrite */ navigationBack() { if ( this.length ) { this.trigger('ClickButton', 0); } close(this); return true; } /** * @overwrite */ navigationEnter(focus) { if ( !this.view.hasChild(focus) ) { if ( this.length ) { this.trigger('ClickButton', this.length - 1); } close(this); } } } export const CONSTS = { OK: 'OK', Cancel: 'Cancel', placeholder: 'Please enter..', }; export function alert(msg, cb = util.noop) { var dag = New( <Dialog buttons=[CONSTS.OK] onClickButton=(e=>cb(e.data))>${msg}</Dialog> ); dag.show(); return dag; } export function confirm(msg, cb = util.noop) { var dag = New( <Dialog buttons=[CONSTS.Cancel, CONSTS.OK] onClickButton=(e=>cb(e.data))>${msg}</Dialog> ); dag.show(); return dag; } function handle_prompt_enter(ev) { var dag = ev.sender.topCtr; dag.trigger('ClickButton', 1); close(dag); } export function prompt(msg, text = '', cb = util.noop) { if ( typeof text == 'function' ) { cb = text; text = ''; } var dag = New( <Dialog buttons=[CONSTS.Cancel, CONSTS.OK] onClickButton=(e=>cb(e.data, e.data ? dag.find('m_input').value: ''))> <Span> ${msg} <Input id="m_input" class="prompt" returnType="done" onKeyEnter=handle_prompt_enter value=text placeholder=CONSTS.placeholder /> </Span> </Dialog> ); dag.show(); dag.find('m_input').focus(); return dag; } export function show(title, msg, buttons, cb = ()=>{ }) { var dag = New( <Dialog title=title buttons=buttons onClickButton=(e=>cb(e.data))>${msg}</Dialog> ); dag.show(); return dag; }