ngui-tools
Version:
A GUI typesetting display engine and cross platform GUI application development framework based on NodeJS/OpenGL
1,141 lines (1,012 loc) • 32.1 kB
JSX
/* ***** BEGIN LICENSE BLOCK *****
* Distributed under the BSD license:
*
* Copyright (c) 2015, 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 './sys';
import { List, KEYCODE_MENU } from './event';
import {
ViewController, View, Div, Indep,
Limit, Button, Text, TextNode, Clip,
New, isViewXml, Panel, ngui, isEmptyViewXml
} from './ngui';
export const FOREGROUND_ACTION_INIT = 0;
export const FOREGROUND_ACTION_RESUME = 1;
const DEFAULT_TRANSITION_TIME = 400;
const navigationStack = new List();
var navigationInit_ok = false;
function get_valid_focus(nav, focus_move) {
var view = nav.view;
return view.hasChild(focus_move) ? view.firstButton() : focus_move;
}
function navigationInit(root) {
// initialize
navigationInit_ok = true;
root.onBack.on(function(ev) {
var last = navigationStack.last;
while(last) {
if ( last.value.navigationBack() ) {
ev.cancelDefault(); // 取消默认动作
break;
}
last = last.prev;
}
});
root.onClick.on(function(ev) {
// console.log('onClick--', ev.keyboard );
if ( ev.keyboard ) { // 需要键盘产生的事件
var last = navigationStack.last;
if ( last ) {
last.value.navigationEnter(ev.sender);
}
}
});
root.onKeyDown.on(function(ev) {
var last = navigationStack.last;
if ( last ) {
var focus_move = ev.focusMove;
var nav = last.value;
switch(ev.keycode) {
case 37: // left
focus_move = nav.navigationLeft(focus_move);
break;
case 38: // up
focus_move = nav.navigationTop(focus_move);
break;
case 39: // right
focus_move = nav.navigationRight(focus_move);
break;
case 40: // down
focus_move = nav.navigationDown(focus_move);
break;
case KEYCODE_MENU:
nav.navigationMenu();
default: return;
}
ev.focusMove = focus_move;
}
});
}
/**
* @class Basic
*/
class Basic extends ViewController {
m_status = -1; // 1=background,0=foreground,-1=init or exit
// @public
get status() { return this.m_status }
intoBackground(time) { this.m_status = 1 }
intoForeground(time, action, data) { this.m_status = 0 }
intoLeave(time) { this.m_status = -1 }
}
/**
* @class Navigation
*/
export class Navigation extends Basic {
m_iterator = null;
m_focus_resume = null;
/**
* @event onBackground
*/
event onBackground;
/**
* @event onForeground
*/
event onForeground;
intoBackground(time) {
super.intoBackground(time);
this.triggerBackground();
}
intoForeground(time, action, data) {
super.intoForeground(time, action, data);
this.triggerForeground({ action: action, data: data });
}
/**
* @func defaultFocus()
*/
defaultFocus() {
// var view = this.view;
// if ( view ) {
// return view.firstButton();
// }
return null;
}
triggerRemoveView(ev) {
if ( this.m_iterator ) {
navigationStack.del(this.m_iterator);
this.m_iterator = null;
}
super.triggerRemoveView(ev);
}
/**
* @func registerNavigation()
*/
registerNavigation(time) {
if ( !this.m_iterator ) { // No need to repeat it
if ( !navigationInit_ok ) { // init
var r = ngui.root;
if ( r ) {
navigationInit(r);
}
}
this.m_iterator = navigationStack.push(this);
// console.log('push_navigation()-----', navigationStack.length);
ngui.lock(()=>{
var prev = this.m_iterator.prev;
if ( prev ) {
var focus = ngui.app.focusView;
prev.m_focus_resume = prev.value.view.hasChild(focus) ? focus : null;
prev.value.intoBackground(time);
}
var view = this.defaultFocus();
if ( view ) {
view.focus();
}
this.intoForeground(time, FOREGROUND_ACTION_INIT, null);
});
}
}
/**
* @func unregisterNavigation(time, data)
*/
unregisterNavigation(time, data) {
if ( this.m_iterator ) {
// util.assert(this.m_iterator, 'Bad iterator!');
navigationStack.del(this.m_iterator);
this.m_iterator = null;
ngui.lock(()=>{
this.intoLeave(time);
var last = navigationStack.last;
if ( last ) {
if (last.value.m_focus_resume) {
last.value.m_focus_resume.focus();
}
last.value.intoForeground(time, FOREGROUND_ACTION_RESUME, data);
}
});
}
}
/* 导航事件产生时系统会首先将事件发送给焦点视图,事件如果能成功传递到root,
* 那么事件最终将发送到达当前导航列表栈最顶端
*/
navigationBack() {
/* 这里如果返回true会继续往导航列表栈底端传递,直到返回true或到达栈底退出应用程序 */
return true;
}
navigationEnter(focus) {
// Rewrite this function to implement your logic
}
/**
* navigationTop()
* navigationDown()
* navigationLeft()
* navigationRight()
* 返回null时焦点不会发生任何改变
*/
navigationTop(focus_move) {
return get_valid_focus(this, focus_move);
}
navigationDown(focus_move) {
return get_valid_focus(this, focus_move);
}
navigationLeft(focus_move) {
return get_valid_focus(this, focus_move);
}
navigationRight(focus_move) {
return get_valid_focus(this, focus_move);
}
/* 按下menu按键时会调用 */
navigationMenu() {
// Rewrite this function to implement your logic
}
}
/**
* @func refresh_bar_style
*/
function refresh_bar_style(self, time) {
if ( self.m_navbar_panel && self.current ) {
time = self.enableAnimate && time;
var navbar = self.navbar || {
height: 0, border: 0, backgroundColor: '#0000', borderColor: '#0000'
};
var toolbar = self.toolbar || {
height: 0, border: 0, backgroundColor: '#0000', borderColor: '#0000'
};
var navbarHidden = self.$navbarHidden || self.navbar.$hidden;
var toolbarHidden = self.$toolbarHidden || self.toolbar.$hidden
var navbar_height = navbarHidden ? 0 : navbar.height + self.m_padding + navbar.border;
var toolbar_height = toolbarHidden ? 0 : toolbar.height + toolbar.border;
if ( time ) {
if ( !navbarHidden ) self.m_navbar_panel.show();
if ( !toolbarHidden ) self.m_toolbar_panel.show();
ngui.lock(()=>{
self.m_navbar_panel.transition({
height: Math.max(0, navbar_height - navbar.border),
borderBottom: `${navbar.border} ${navbar.borderColor}`,
backgroundColor: navbar.backgroundColor,
time: time,
});
//console.log(navbar.backgroundColor, 'OKOK1', time);
self.m_toolbar_panel.transition({
height: Math.max(0, toolbar_height - toolbar.border),
borderTop: `${toolbar.border} ${toolbar.borderColor}`,
backgroundColor: toolbar.backgroundColor,
time: time,
});
self.m_page_panel.transition({ height: navbar_height + toolbar_height + '!', time: time }, ()=>{
if ( navbarHidden ) self.m_navbar_panel.hide();
if ( toolbarHidden ) self.m_toolbar_panel.hide();
});
});
} else {
var style = {
height: Math.max(0, navbar_height - navbar.border),
borderBottom: `${navbar.border} ${navbar.borderColor}`,
backgroundColor: navbar.backgroundColor,
visible: !navbarHidden,
};
self.m_navbar_panel.style = style;
//console.log(navbar.backgroundColor, 'OKOK2', time);
self.m_toolbar_panel.style = {
height: Math.max(0, toolbar_height - toolbar.border),
borderTop: `${toolbar.border} ${toolbar.borderColor}`,
backgroundColor: toolbar.backgroundColor,
visible: !toolbarHidden,
};
self.m_page_panel.style = { height: navbar_height + toolbar_height + '!' };
}
}
}
/**
* @class NavpageCollection
*/
export class NavpageCollection extends ViewController {
m_padding = 20;
m_pages = null;
m_default_toolbar = null;
m_navbar_panel = null;
m_page_panel = null;
m_toolbar_panel = null;
m_animating = false;
$navbarHidden = false;
$toolbarHidden = false;
/**
* @field enableAnimate
*/
enableAnimate = true;
event onPush;
event onPop;
get padding() { return this.m_padding }
get navbarHidden() { return this.$navbarHidden }
get toolbarHidden() { return this.$toolbarHidden }
set navbarHidden(value) { this.setNavbarHidden(value, false) }
set toolbarHidden(value) { this.setToolbarHidden(value, false) }
get length() { return this.m_pages.length }
get pages() { return this.m_pages.slice() }
get current() { return this.m_pages.last(0) || null }
get navbar() { return this.length ? this.current.navbar : null }
get toolbar() { return this.length ? this.current.toolbar : null }
get defaultToolbar() { return this.m_default_toolbar }
set padding(value) {
util.assert(typeof value == 'number');
this.m_padding = Math.max(value, 0);
refresh_bar_style(this, 0);
}
/**
* @func setNavbarHidden
*/
setNavbarHidden(value, time) {
this.$navbarHidden = !!value;
refresh_bar_style(this, time ? DEFAULT_TRANSITION_TIME : 0);
}
/**
* @func setToolbarHidden
*/
setToolbarHidden(value, time) {
this.$toolbarHidden = !!value;
refresh_bar_style(this, time ? DEFAULT_TRANSITION_TIME : 0);
}
/**
* @set defaultToolbar {Toolbar} # Set default toolbar
*/
set defaultToolbar(value) {
if (value) {
if (isViewXml(value)) // view xml
value = New(value);
util.assert(value instanceof Toolbar, 'Type not correct');
util.assert(!value.m_collection || value.m_collection !== this);
if ( value !== this.m_default_toolbar ) {
if ( this.m_default_toolbar ) {
this.m_default_toolbar.remove();
}
this.m_default_toolbar = value;
this.m_default_toolbar.m_collection = this;
}
} else { // cancel
if ( this.m_default_toolbar ) {
this.m_default_toolbar.remove();
this.m_default_toolbar = null;
}
}
}
constructor() {
super();
this.m_pages = [];
}
loadView(vx) {
super.loadView(
<Clip width="100%" height="100%">
<Div id="navbar" width="100%" />
<Div id="page" width="100%" />
<Div id="toolbar" width="100%" />
</Clip>
);
this.m_navbar_panel = this.find('navbar');
this.m_page_panel = this.find('page');
this.m_toolbar_panel = this.find('toolbar');
if ( !isEmptyViewXml(vx) ) {
/* delay 因为是第一次加载,布局系统还未初始化
* 无法正确的获取数值来进行title bar的排版计算
* 所以这里延时一帧画面
*/
ngui.nextFrame(()=>{ this.push(vx) });
}
}
push(page, animate, ...args) {
if ( this.m_animating ) {
return;
}
var time = this.enableAnimate && animate && this.length ? DEFAULT_TRANSITION_TIME : 0;
var prev = this.current;
if ( page ) {
if ( page instanceof Navpage ) {
util.assert(!page.view.parent && !page.collection,
'Navpage can only be a new entity');
page.view.appendTo(this.m_page_panel);
} else {
if ( isViewXml(page, Navpage) ) {
page = New(page, this.m_page_panel, ...args);
} else if ( isViewXml(page, View) ) {
page = New(<Navpage>${page}</Navpage>, this.m_page_panel, ...args);
}
}
}
util.assert(page instanceof Navpage,
'The argument navpage is not of the correct type, '+
'Only for Navpage entities or Navpage VX data.');
// set page
page.m_collection = this;
page.m_prevPage = prev;
if (prev) { // set next page
prev.m_nextPage = page;
}
if (!page.m_navbar) { // Create default navbar
page.navbar = <Navbar />;
}
if (!page.m_toolbar) { // use default toolbar
if (this.defaultToolbar) {
page.toolbar = this.defaultToolbar;
} else {
page.toolbar = <Toolbar />;
}
}
this.m_pages.push(page);
page.navbar.m_collection = this;
page.toolbar.m_collection = this;
page.navbar.view.appendTo(this.m_navbar_panel);
page.toolbar.view.appendTo(this.m_toolbar_panel);
this.m_animating = time;
if ( time ) {
setTimeout(()=>{ this.m_animating = false }, time);
}
page.navbar.$setBackText(prev ? prev.title : '');
refresh_bar_style(this, time);
// switch and animate
this.triggerPush(page);
page.registerNavigation(time);
}
pop(animate) {
this.pops(1, animate);
}
pops(count, animate) {
count = Math.min(this.length - 1, count);
if ( count <= 0 ) {
return;
}
if ( this.m_animating ) {
return;
}
var time = this.enableAnimate && animate ? DEFAULT_TRANSITION_TIME : 0;
var page = this.m_pages[this.length - 1 - count];
var arr = this.m_pages.splice(this.length - count);
var next = arr.pop();
arr.forEach(function (page) {
page.intoLeave(false);
});
this.m_animating = time;
if ( time ) {
setTimeout(()=>{ this.m_animating = false }, time);
}
refresh_bar_style(this, time);
// switch and animate
this.triggerPop(next);
next.unregisterNavigation(time, null);
}
}
/**
* @class Bar
*/
class Bar extends Basic {
$height = 44;
$hidden = false;
$border = ngui.atomPixel;
$borderColor = '#b3b3b3';
$backgroundColor = '#f9f9f9';
m_page = null;
m_collection = null;
get height() { return this.$height }
get hidden() { return this.$hidden }
get border() { return this.$border }
get borderColor() { return this.$borderColor }
get backgroundColor() { return this.$backgroundColor }
get collection() { return this.m_collection }
get page() { return this.m_page }
get isCurrent() { return this.m_page && this.m_page.isCurrent }
set height(value) {
util.assert(typeof value == 'number');
this.$height = value;
this.refreshStyle(0);
}
set hidden(value) {
this.$hidden = !!value;
this.refreshStyle(0);
}
set border(value) {
util.assert(typeof value == 'number');
this.$border = value;
this.refreshStyle(0);
}
set borderColor(value) {
this.$border = value;
this.refreshStyle(0);
}
set backgroundColor(value) {
this.$backgroundColor = value;
this.refreshStyle(0);
}
setHidden(value, time) {
this.$hidden = !!value;
this.refreshStyle(time ? DEFAULT_TRANSITION_TIME : 0);
}
/**
* @fun refreshStyle
*/
refreshStyle(time) {
if (this.isCurrent) {
refresh_bar_style(this.m_page.collection, time);
}
}
get visible() {
return super.visible;
}
set visible(value) {
if ( value ) {
if (this.isCurrent) {
super.visible = 1;
}
} else {
if (!this.isCurrent) {
super.visible = 0;
}
}
}
}
/**
* @func navbar_compute_title_layout
*/
function navbar_compute_title_layout(self) {
if ( self.$defaultStyle ) {
var back_text_btn = self.find('m_back_text_btn');
var back_text = self.find('m_back_text1').value;
var title_text = self.m_title_text_panel.value;
var backIconVisible = self.$backIconVisible;
if ( self.page && self.page.m_prevPage ) {
back_text_btn.visible = true;
} else {
back_text_btn.visible = false;
back_text = '';
backIconVisible = false;
}
var nav_width = self.collection ? self.collection.view.finalWidth : 0;
// console.log('----------------------nav_width', nav_width);
var back_width = self.find('m_back_text1').simpleLayoutWidth(back_text) + 3; // 3间隔
var title_width = self.m_title_text_panel.simpleLayoutWidth(title_text);
var menu_width = Math.min(nav_width / 3, Math.max(self.$titleMenuWidth, 0));
var marginLeft = 0;
var min_back_width = 6;
if ( backIconVisible ) {
min_back_width += self.find('m_back_text0').simpleLayoutWidth('\uedc5');
back_width += min_back_width;
}
self.m_title_panel.marginLeft = marginLeft;
self.m_title_panel.marginRight = menu_width;
self.m_title_panel.show();
self.find('m_back_text0').visible = backIconVisible;
if ( nav_width ) {
var title_x = nav_width / 2 - title_width / 2 - marginLeft;
if ( back_width <= title_x ) {
back_width = title_x;
} else { // back 的宽度超过title-x位置
//console.log(back_width, (nav_width - menu_width - marginLeft) - title_width);
back_width = Math.min(back_width, (nav_width - menu_width - marginLeft) - title_width);
back_width = Math.max(min_back_width, back_width);
}
title_width = nav_width - back_width - menu_width - marginLeft;
self.m_back_panel_width = back_width;// - min_back_width;
self.m_title_panel_width = title_width;
} else {
self.m_back_panel_width = 0;
self.m_title_panel_width = 0;
back_width = 30;
title_width = 70;
}
var back_text_num = back_width / (back_width + title_width);
var titl_text_num = title_width / (back_width + title_width);
// 为保证浮点数在转换后之和不超过100,向下保留三位小数
self.m_back_text_panel.width = Math.floor(back_text_num * 100000) / 1000 + '%';
self.m_title_text_panel.width = Math.floor(titl_text_num * 100000) / 1000 + '%';
} else {
self.m_title_panel.hide(); // hide title text and back text
}
}
/**
* @class Navbar
*/
export class Navbar extends Bar {
m_back_text = '';
m_title_text = '';
m_title_panel = null;
m_back_text_panel = null;
m_title_text_panel = null;
m_back_panel_width = 0;
m_title_panel_width = 0;
$defaultStyle = true;
$backIconVisible = true;
$titleMenuWidth = 40; // display right menu button width
$backgroundColor = '#2c86e5'; // 3c89fb
// @public
get backIconVisible() { return this.$backIconVisible }
get defaultStyle() { return this.$defaultStyle }
get titleMenuWidth() { return this.$titleMenuWidth }
get backTextColor() { return this.m_back_text_btn.textColor }
get titleTextColor() { return this.m_title_text_panel.textColor }
set backIconVisible(value) {
this.$backIconVisible = !!value;
navbar_compute_title_layout(this);
}
set defaultStyle(value) {
this.$defaultStyle = !!value;
navbar_compute_title_layout(this);
}
set titleMenuWidth(value) {
util.assert(typeof value == 'number');
this.$titleMenuWidth = value;
navbar_compute_title_layout(this);
}
set backTextColor(value) { this.find('m_back_text_btn').textColor = value }
set titleTextColor(value) { this.m_title_text_panel.textColor = value }
refreshStyle(time) {
if (this.isCurrent) {
this.view.alignY = 'bottom';
this.view.height = this.height;
this.m_title_text_panel.textLineHeight = this.height;
this.find('m_back_text_btn').textLineHeight = this.height;
super.refreshStyle(time);
}
}
/**
* @overwrite
*/
loadView(vx) {
super.loadView(
<Indep width="100%" height=44 visible=0 alignY="bottom">
${vx}
<Indep id="m_title_panel" width="full" height="100%" visible=0>
<Div id="m_back_text_panel" height="full">
<Limit maxWidth="100%">
<!--textColor="#0079ff"-->
<Button id="m_back_text_btn"
textColor="#fff"
width="full"
textLineHeight=44
textSize=16
textWhiteSpace="no_wrap" textOverflow="ellipsis">
<Div width=6 />
<TextNode id="m_back_text0"
textLineHeight="auto"
textSize=20
height=26 y=2
textColor="inherit"
textFamily="icon" value='\uedc5' />
<TextNode id="m_back_text1" />
</Button>
</Limit>
</Div>
<Text id="m_title_text_panel"
height="full"
textColor="#fff"
textLineHeight=44
textSize=16
textWhiteSpace="no_wrap"
textStyle="bold" textOverflow="ellipsis" />
</Indep>
</Indep>
);
this.m_title_panel = this.find('m_title_panel');
this.m_back_text_panel = this.find('m_back_text_panel');
this.m_title_text_panel = this.find('m_title_text_panel');
var back_text_btn = this.find('m_back_text_btn');
back_text_btn.onClick.on(()=>{ this.collection.pop(true) });
}
/**
* @fun setBackText # set navbar back text
*/
$setBackText(value) {
this.find('m_back_text1').value = value;
navbar_compute_title_layout(this);
}
/**
* @fun $setTitleText # set navbar title text
*/
$setTitleText(value) {
this.m_title_text_panel.value = value;
navbar_compute_title_layout(this);
}
intoBackground(time) {
if ( time ) {
if ( this.$defaultStyle ) {
var m_back_text0 = this.find('m_back_text0');
var m_back_text1 = this.find('m_back_text1');
var m_title_text_panel = this.m_title_text_panel;
var back_icon_width = m_back_text0.visible ? m_back_text0.clientWidth : 0;
m_back_text1.transition({
x: -m_back_text1.clientWidth, time: time,
});
m_title_text_panel.transition({
x: -this.m_back_panel_width + back_icon_width, time: time,
});
}
this.transition({ opacity: 0, time: time }, ()=>{ this.hide() });
} else {
this.view.opacity = 0;
this.hide();
}
super.intoBackground(time);
}
intoForeground(time, action, data) {
var m_back_text0 = this.find('m_back_text0');
var m_back_text1 = this.find('m_back_text1');
var m_title_text_panel = this.m_title_text_panel;
this.show();
if ( time ) { // TODO
if ( this.$defaultStyle ) {
var back_icon_width = 0;//m_back_text0.visible ? 20 : 0;
if ( this.status == -1 ) {
m_back_text1.x = this.m_back_panel_width - back_icon_width;
m_title_text_panel.x = this.m_title_panel_width + this.$titleMenuWidth;
}
m_back_text1.transition({ x: 0, time: time });
m_title_text_panel.transition({ x: 0, time: time });
} else {
m_back_text1.x = 0;
m_title_text_panel.x = 0;
}
this.view.opacity = 0;
this.transition({ opacity: 1, time: time });
} else {
this.view.opacity = 1;
m_back_text1.x = 0;
m_title_text_panel.x = 0;
}
super.intoForeground(time, action, data);
}
intoLeave(time) {
if ( this.status == 0 && time ) { // TODO
if ( this.$defaultStyle ) {
var m_back_text0 = this.find('m_back_text0');
var m_back_text1 = this.find('m_back_text1');
var m_title_text_panel = this.m_title_text_panel;
var back_icon_width = m_back_text0.visible ? m_back_text0.clientWidth : 0;
m_back_text1.transition({ x: this.m_back_panel_width - back_icon_width, time: time });
m_title_text_panel.transition({
x: this.m_title_panel_width + this.$titleMenuWidth, time: time,
});
}
this.transition({ opacity: 0, time: time }, ()=>{ this.remove() });
} else {
this.remove();
}
super.intoLeave(time);
}
}
/**
* @class Toolbar
*/
export class Toolbar extends Bar {
$height = 49;
/**
* @overwrite
*/
loadView(vx) {
super.loadView(
<Indep width="100%" height="full" visible=0>${vx}</Indep>
);
}
intoForeground(time, action, data) {
if ( this.isDefault ) {
this.m_page = this.collection.current;
}
if ( time ) {
var page = (this.page.nextPage || this.page.prevPage);
if (!page || page.toolbar !== this) {
this.show();
this.view.opacity = 0;
this.transition({ opacity: 1, time: time });
}
} else {
this.show();
this.view.opacity = 1;
}
super.intoForeground(time, action, data);
}
intoBackground(time) {
if ( this.collection.current.toolbar !== this ) {
if ( time ) {
this.transition({ opacity: 0, time: time }, ()=>{ this.hide() });
} else {
this.view.opacity = 0;
this.hide();
}
}
super.intoBackground(time);
}
intoLeave(time) {
if ( this.collection.current.toolbar !== this ) {
if ( this.status == 0 && time ) {
this.transition({ opacity: 0, time: time }, ()=>{
if ( this.collection.defaultToolbar !== this ) {
this.remove();
} else {
this.hide();
}
});
} else {
if ( this.collection.defaultToolbar !== this ) {
this.remove();
} else {
this.hide();
}
}
}
super.intoLeave(time);
}
get isDefault() {
return this.collection && this.collection.defaultToolbar === this;
}
}
/**
* @func backgroundColorReverse
*/
function backgroundColorReverse(self) {
var color = self.backgroundColor.reverse();
color.a = 255 * 0.6;
return color;
}
// Basic
/**
* @class Navpage
*/
export class Navpage extends Navigation {
m_title = '';
m_navbar = null;
m_toolbar = null;
m_collection = null;
m_prevPage = null;
m_nextPage = null;
// @public
get title() { return this.m_title }
get collection() { return this.m_collection }
get navbar() {
if ( this.m_navbar ) {
return this.m_navbar;
} else {
this.navbar = <Navbar />;
return this.m_navbar;
}
}
get toolbar() {
if ( this.m_toolbar ) {
return this.m_toolbar;
} else {
this.toolbar = <Toolbar />;
return this.m_toolbar;
}
}
get prevPage() { return this.m_prevPage }
get nextPage() { return this.m_nextPage }
get isCurrent() { return this.m_collection && this.m_collection.current === this }
get backgroundColor() { return this.view.backgroundColor }
set backgroundColor(value) {
this.view.backgroundColor = value;
}
set title(value) {
this.m_title = String(value);
if (this.m_navbar) {
this.m_navbar.$setTitleText(this.m_title);
}
if (this.m_nextPage && this.m_nextPage.navbar) {
this.m_nextPage.navbar.$setBackText(value);
}
}
set navbar(value) {
if (value) {
if ( isViewXml(value) ) {
value = New(value);
}
util.assert(value instanceof Navbar, 'Type not correct');
if (value !== this.m_navbar) {
util.assert(!value.m_page);
if (this.m_navbar) {
this.navbar.remove();
}
this.m_navbar = value;
this.m_navbar.m_page = this;
this.m_navbar.$setTitleText(this.m_title);
this.m_navbar.$setBackText(this.m_prevPage ? this.m_prevPage.m_title : '');
this.m_navbar.refreshStyle(false);
}
}
}
set toolbar(value) {
if (value) {
if ( isViewXml(value) ) {
value = New(value);
}
util.assert(value instanceof Toolbar, 'Type not correct');
if (value !== this.m_toolbar) {
util.assert(!value.m_page || value.isDefault);
if (this.m_toolbar) {
if ( !this.m_toolbar.isDefault ) {
this.m_toolbar.remove();
}
}
this.m_toolbar = value;
this.m_toolbar.m_page = this;
this.m_toolbar.refreshStyle(false);
} else {
this.m_toolbar.m_page = this;
}
}
}
// @overwrite
loadView(vx) {
super.loadView(
<Indep width="100%" height="full" backgroundColor="#fff" visible=0>${vx}</Indep>
);
}
// @overwrite
intoBackground(time) {
//console.log( this.nextPage == null ? 'null' : 'no null' )
if ( this.nextPage == null ) return;
//console.log( 'natpage intoBackground' )
this.navbar.intoBackground(time);
this.toolbar.intoBackground(time);
if ( this.status != 1 ) {
if ( time && this.view.parent.finalVisible ) {
this.transition({ x: this.view.parent.finalWidth / -3, visible: false, time: time });
} else {
this.style = { x: (this.view.parent.finalWidth || 100) / -3, visible: false };
}
}
super.intoBackground(time);
}
// @overwrite
intoForeground(time, action, data) {
if ( this.status == 0 ) return;
this.navbar.intoForeground(time, action, data);
this.toolbar.intoForeground(time, action, data);
this.m_nextPage = null;
if ( this.status == -1 ) {
if ( time && this.view.parent.finalVisible ) {
this.style = {
borderLeftColor: backgroundColorReverse(this),
borderLeftWidth: ngui.atomPixel,
x: this.view.parent.finalWidth,
visible: 1,
};
this.transition({ x: 0, time: time }, ()=>{
this.view.borderLeftWidth = 0;
});
} else {
this.style = { x: 0, borderLeftWidth: 0, visible: 1 };
}
this.m_toolbar.m_page = this;
}
else if ( this.status == 1 ) {
if ( time && this.view.parent.finalVisible ) {
this.visible = 1;
this.transition({ x: 0, time: time });
} else {
this.style = { x: 0, visible: 1 };
}
this.m_toolbar.m_page = this;
}
super.intoForeground(time, action, data);
}
// @overwrite
intoLeave(time) {
this.navbar.intoLeave(time);
this.toolbar.intoLeave(time);
if ( this.status == 0 ) {
if ( time && this.view.parent.finalVisible ) {
this.style = {
borderLeftColor: backgroundColorReverse(this),
borderLeftWidth: ngui.atomPixel,
};
this.transition({ x: this.view.parent.finalWidth, visible: 0, time: time }, ()=>{
this.remove();
});
super.intoLeave(time);
return;
}
}
super.intoLeave(time);
this.remove();
}
// @overwrite
triggerRemoveView(ev) {
if (this.m_navbar) {
this.m_navbar.remove();
}
if (this.m_toolbar && !this.m_toolbar.isDefault) {
this.m_toolbar.remove();
}
super.triggerRemoveView(ev);
}
// @overwrite
navigationBack() {
if ( this.m_prevPage ) {
this.m_collection.pop(true);
return true;
} else {
return false;
}
}
}
export {
NavPage: Navpage,
};