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
JSX
/* ***** 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;
}