mirror of
				https://github.com/blanking003/cx-cocos.git
				synced 2025-10-30 19:05:30 +00:00 
			
		
		
		
	init
This commit is contained in:
		
							
								
								
									
										105
									
								
								cx3-demo/assets/cx/core/cx.adapt.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								cx3-demo/assets/cx/core/cx.adapt.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,105 @@ | ||||
| import * as cc from 'cc'; | ||||
|  | ||||
| cc.Node.prototype.pro = function() | ||||
| { | ||||
| 	if (!this._pro) | ||||
| 		this._pro = {}; | ||||
| 	return this._pro; | ||||
| }; | ||||
|  | ||||
| cc.Node.prototype.getWidth = function() | ||||
| { | ||||
| 	return (this.getComponent(cc.UITransform) || this.addComponent(cc.UITransform)).width; | ||||
| }; | ||||
|  | ||||
| cc.Node.prototype.getHeight = function() | ||||
| { | ||||
| 	return (this.getComponent(cc.UITransform) || this.addComponent(cc.UITransform)).height; | ||||
| }; | ||||
|  | ||||
| cc.Node.prototype.getContentSize = function() | ||||
| { | ||||
| 	return (this.getComponent(cc.UITransform) || this.addComponent(cc.UITransform)).contentSize; | ||||
| }; | ||||
|  | ||||
| cc.Node.prototype.setTouchCallback = function(target:any, callback?:Function, ...params:any) | ||||
| { | ||||
| 	if (!callback) | ||||
| 	{ | ||||
| 		this.off(cc.Node.EventType.TOUCH_END); | ||||
| 		return; | ||||
| 	} | ||||
| 	this.on(cc.Node.EventType.TOUCH_END, (event: cc.EventTouch) => | ||||
| 	{ | ||||
| 		if (Math.abs(event.getLocation().x - event.getStartLocation().x) > 15 || Math.abs(event.getLocation().y - event.getStartLocation().y) > 15) | ||||
| 			return; | ||||
| 		if (cx.touchLockTimelen < 0) | ||||
| 			return; | ||||
| 		var t = cx.utils.getCurrSecond(true); | ||||
| 		if (t - cx.touchPriorSecond >= cx.touchLockTimelen) | ||||
| 		{ | ||||
| 			cx.touchPriorSecond = t; | ||||
| 			cx.touchLockTimelen = 250; | ||||
| 			callback && callback.apply(target, params != undefined ? [this].concat(params) : params); | ||||
| 		} | ||||
| 	}); | ||||
| }; | ||||
|  | ||||
| var prototype: any = cc.ScrollView.prototype; | ||||
| prototype.startAutoScroll = prototype._startAutoScroll; | ||||
|  | ||||
| //将ScrollView的content最小高度设置为ScrollView的高度,且初始位置定位到顶部 | ||||
| prototype._adjustContentOutOfBoundaryOrigin = prototype._adjustContentOutOfBoundary; | ||||
| prototype._adjustContentOutOfBoundary = function()  | ||||
| { | ||||
| 	////blank | ||||
| 	var that: any = this; | ||||
| 	if (!that._content) | ||||
| 		return; | ||||
| 	var contentTransform = that._content.getComponent(cc.UITransform); | ||||
| 	if (contentTransform.contentSize.height < that.view.contentSize.height) | ||||
| 	{ | ||||
| 		that.view.getComponent(cc.Widget)?.updateAlignment(); | ||||
| 		contentTransform.setContentSize(contentTransform.contentSize.width, that.view.contentSize.height); | ||||
| 	} | ||||
|  | ||||
| 	this._adjustContentOutOfBoundaryOrigin(); | ||||
| }; | ||||
|  | ||||
| //下拉刷新时,顶部回弹到cx_refreshTopGap位置 cx_refreshTopGap=120 | ||||
| prototype._flattenVectorByDirection = function(vector: cc.Vec3)  | ||||
| { | ||||
| 	const result = vector; | ||||
| 	result.x = this.horizontal ? result.x : 0; | ||||
| 	result.y = this.vertical ? result.y : 0; | ||||
| 	 | ||||
| 	////blank | ||||
| 	var that: any = this; | ||||
| 	if (that.cx_refreshTopGap && result.y > that.cx_refreshTopGap) | ||||
| 		result.y -= that.cx_refreshTopGap; | ||||
|  | ||||
| 	return result; | ||||
| }; | ||||
|  | ||||
| //PageView指示器优先按Page.dataIndex值指示,且page数量为1时不显示 | ||||
| cc.PageViewIndicator.prototype._changedState = function ()  | ||||
| { | ||||
| 	var that: any = this; | ||||
| 	var indicators = that._indicators; | ||||
| 	if (indicators.length === 0)  | ||||
| 		return; | ||||
| 	var page = that._pageView.getPages()[that._pageView.curPageIdx]; | ||||
| 	var dataIndex = page && page.pro().dataIndex; | ||||
| 	var idx = dataIndex != undefined ? dataIndex : that._pageView.curPageIdx; | ||||
| 	if (idx >= indicators.length) return; | ||||
| 	var uiComp; | ||||
| 	for (var i = 0; i < indicators.length; ++i)  | ||||
| 	{ | ||||
| 		var node = indicators[i]; | ||||
| 		uiComp = node._uiProps.uiComp; | ||||
| 		if (uiComp)  | ||||
| 			uiComp.color = cc.color(uiComp.color.r, uiComp.color.g, uiComp.color.b, i != idx ? 255/2 : 255); | ||||
| 	} | ||||
| }; | ||||
|  | ||||
|  | ||||
							
								
								
									
										9
									
								
								cx3-demo/assets/cx/core/cx.adapt.ts.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								cx3-demo/assets/cx/core/cx.adapt.ts.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "4.0.22", | ||||
|   "importer": "typescript", | ||||
|   "imported": true, | ||||
|   "uuid": "bf4f5efb-16d9-4df5-9888-f51aa81eaa26", | ||||
|   "files": [], | ||||
|   "subMetas": {}, | ||||
|   "userData": {} | ||||
| } | ||||
							
								
								
									
										44
									
								
								cx3-demo/assets/cx/core/cx.define.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								cx3-demo/assets/cx/core/cx.define.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| import * as cc from 'cc'; | ||||
|  | ||||
| import native from "./cx.native"; | ||||
| import picker from "./cx.picker"; | ||||
| import res from "./cx.res"; | ||||
| import script from "./cx.script"; | ||||
| import serv from "./cx.serv"; | ||||
| import sys from "./cx.sys"; | ||||
| import ui from "./cx.ui"; | ||||
| import utils from "./cx.utils"; | ||||
|  | ||||
| class cx extends ui | ||||
| { | ||||
| 	static native = native; | ||||
| 	static picker = picker; | ||||
| 	static res = res; | ||||
| 	static script = script; | ||||
| 	static serv = serv; | ||||
| 	static sys = sys; | ||||
| 	static utils = utils; | ||||
|  | ||||
| 	static config = sys.config; | ||||
| 	static os = sys.os; | ||||
| 	 | ||||
| 	static log = console.log; | ||||
|  | ||||
| 	static init(mainScene: cc.Component) | ||||
| 	{ | ||||
| 		console.log("..... cx init (framework: " + sys.version + ") ....."); | ||||
|  | ||||
| 		sys.init(); | ||||
| 		ui.init(mainScene); | ||||
|  | ||||
| 		if (!sys.config.debug) | ||||
| 			this.log = function(){}; | ||||
|  | ||||
| 		console.log("..... cx init success (sw:" + ui.sw + ", sh:" + ui.sh + ") ....."); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| window.cx = window.cx || cx; | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										9
									
								
								cx3-demo/assets/cx/core/cx.define.ts.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								cx3-demo/assets/cx/core/cx.define.ts.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "4.0.22", | ||||
|   "importer": "typescript", | ||||
|   "imported": true, | ||||
|   "uuid": "09fe4b13-8d70-477f-9e93-1b76c37ba3cb", | ||||
|   "files": [], | ||||
|   "subMetas": {}, | ||||
|   "userData": {} | ||||
| } | ||||
							
								
								
									
										44
									
								
								cx3-demo/assets/cx/core/cx.native.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								cx3-demo/assets/cx/core/cx.native.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| import sys from './cx.sys'; | ||||
|  | ||||
| export default class native | ||||
| { | ||||
| 	static androidIntf: any = {}; | ||||
| 	static undefinedIns = {call:function(){return "";}}; | ||||
|  | ||||
| 	static ins (name: string): any | ||||
| 	{ | ||||
| 		if (!sys.os.native) | ||||
| 			return this.undefinedIns; | ||||
|  | ||||
| 		//非android使用jsb c++ | ||||
| 		if (!sys.os.android || name == "cx") | ||||
| 			return typeof cxnative != "undefined" && cxnative.NativeCreator.createNativeClass(name) || this.undefinedIns; | ||||
|  | ||||
| 		//android使用jsb.reflection | ||||
| 		if (!jsb.reflection) | ||||
| 		{ | ||||
| 			console.log("!!!!! error: jsb.reflection is undefined !!!!!"); | ||||
| 			return this.undefinedIns; | ||||
| 		} | ||||
| 		 | ||||
| 		var intf = this.androidIntf[name]; | ||||
| 		if (!intf) | ||||
| 		{ | ||||
| 			intf = this.androidIntf[name] = {}; | ||||
| 			intf.name = name, | ||||
| 			intf.call = (function(fname: string, params: any[], callback?: Function) | ||||
| 			{ | ||||
| 				intf.callback = callback; | ||||
| 				return jsb.reflection.callStaticMethod("cx/NativeIntf", "call", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",  | ||||
| 					intf.name, fname, params && params.join("#@#") || ""); | ||||
| 			}).bind(intf); | ||||
| 		} | ||||
| 		return intf; | ||||
| 	} | ||||
|  | ||||
| 	static androidCallback (name: string, v1: number, v2: string) | ||||
| 	{ | ||||
| 		var intf = native.androidIntf[name]; | ||||
| 		intf && intf.callback && intf.callback(v1, v2); | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										9
									
								
								cx3-demo/assets/cx/core/cx.native.ts.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								cx3-demo/assets/cx/core/cx.native.ts.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "4.0.22", | ||||
|   "importer": "typescript", | ||||
|   "imported": true, | ||||
|   "uuid": "b97ea3bc-cb32-4fc9-bfb4-a52dab76bdf9", | ||||
|   "files": [], | ||||
|   "subMetas": {}, | ||||
|   "userData": {} | ||||
| } | ||||
							
								
								
									
										326
									
								
								cx3-demo/assets/cx/core/cx.picker.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										326
									
								
								cx3-demo/assets/cx/core/cx.picker.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,326 @@ | ||||
| import * as cc from 'cc'; | ||||
| import res from './cx.res'; | ||||
| import ui from './cx.ui'; | ||||
|  | ||||
| export default class picker  | ||||
| { | ||||
| 	//dataList数组对象属性包括:  | ||||
| 	//data:数据列表,[""或{}],如果是{},需指定显示字段display | ||||
| 	//index: 默认初始定位index | ||||
| 	//suffix: 在数据后加上该字串 | ||||
| 	//ex: (callback, [{data:["a", "b"], index:0, suffix:""}, {...}]) | ||||
| 	//ex: (callback, [{data:[{id:"a", name:"b"}], display:"name", index:0, suffix:"年"}, {...}]) | ||||
| 	static create (page: cc.Component, callback: Function | undefined, dataList: any[]) | ||||
| 	{ | ||||
| 		return new OptionPicker(page, callback, dataList); | ||||
| 	} | ||||
|  | ||||
| 	//创建年月日选择,默认值:yearData:当前年,year:当前年,monthData:所有月,month:当前月,dayData:1~31天,dy:当前天 | ||||
| 	//ex: (this, callback) | ||||
| 	static createYearMonthDay (page: cc.Component, callback: Function | undefined, yearData?: any[], year?: number, monthData?: any[], month?: number, dayData?: any[], day?: number) | ||||
| 	{ | ||||
| 		var d = new Date(); | ||||
| 		yearData = yearData ? yearData : this.year(); | ||||
| 		monthData = monthData ? monthData : this.month(); | ||||
| 		dayData = dayData ? dayData : this.day(); | ||||
| 		var yearIndex = yearData.indexOf(year ? year : d.getFullYear()); | ||||
| 		var monthIndex = monthData.indexOf(month ? month : (d.getMonth() + 1)); | ||||
| 		var dayIndex = dayData.indexOf(day ? day : d.getDate()); | ||||
| 		return new OptionPickerYearMonthDay(page, callback, [ | ||||
| 			{data: yearData, index: yearIndex, suffix: "年"}, | ||||
| 			{data: monthData, index: monthIndex, suffix: "月"}, | ||||
| 			{data: dayData, index: dayIndex, suffix: "日"}]); | ||||
| 	} | ||||
|  | ||||
| 	//创建年月选择,默认值:yearData:当前年,year:当前年,monthData:所有月,month:当前月 | ||||
| 	//返回值,选中年、月值:callback(2016, 7)----非索引,以下年月日相关的,都是如此 | ||||
| 	//ex: (callback, cx.picker.year(-3, 0), null, cx.picker.month(1, 0), null) | ||||
| 	static createYearMonth (page: cc.Component, callback: Function | undefined, yearData?: any[], year?: number, monthData?: any[], month?: number) | ||||
| 	{ | ||||
| 		var d = new Date(); | ||||
| 		yearData = yearData ? yearData : this.year(); | ||||
| 		monthData = monthData ? monthData : this.month(); | ||||
| 		var yearIndex = yearData.indexOf(year ? year : d.getFullYear()); | ||||
| 		var monthIndex = monthData.indexOf(month ? month : (d.getMonth() + 1)); | ||||
| 		return new OptionPicker(page, callback, [ | ||||
| 			{data: yearData, index: yearIndex, suffix: "年"},  | ||||
| 			{data: monthData, index: monthIndex, suffix: "月"}]); | ||||
| 	} | ||||
|  | ||||
| 	//创建月日选择, 默认值:monthData:所有月,month:当前月,dayData:1~31天,day:当前天 | ||||
| 	static createMonthDay (page: cc.Component, callback: Function | undefined, monthData?: any[], month?: number, dayData?: any[], day?: number) | ||||
| 	{ | ||||
| 		var d = new Date(); | ||||
| 		monthData = monthData ? monthData : this.month(); | ||||
| 		dayData = dayData ? dayData : this.day(); | ||||
| 		var dayIndex = dayData.indexOf(day ? day : d.getDate()); | ||||
| 		var monthIndex = monthData.indexOf(month ? month : (d.getMonth() + 1)); | ||||
| 		return new OptionPickerMonthDay(page, callback, [ | ||||
| 			{data: monthData, index: monthIndex, suffix: "月"},  | ||||
| 			{data: dayData, index: dayIndex, suffix: "日"}]); | ||||
| 	} | ||||
|  | ||||
| 	//创建时分选择 | ||||
| 	static createHourMinute (page: cc.Component, callback: Function | undefined, hourData?: any[], hour?: number, minuteData?: any[], minute?: number) | ||||
| 	{ | ||||
| 		hourData = hourData ? hourData : this.number(0, 23); | ||||
| 		minuteData = minuteData ? minuteData : this.number(0, 59); | ||||
| 		var hourIndex = hourData.indexOf(hour ? hour : 0); | ||||
| 		var minuIndex = minuteData.indexOf(minute ? minute : 0); | ||||
| 		return new OptionPicker(page, callback, [ | ||||
| 			{data: hourData, index: hourIndex, suffix: "时"}, | ||||
| 			{data: minuteData, index: minuIndex, suffix: "分"}]); | ||||
| 	} | ||||
|  | ||||
| 	//生成from至to之间的数值数组,label为后缀,默认值:label:undefined | ||||
| 	//ex: (10, 100, "万") | ||||
| 	static number (from?: number, to?: number, label?: string): any[] | ||||
| 	{ | ||||
| 		var d = []; | ||||
| 		if (from != undefined && to != undefined) | ||||
| 			for (var i = from; i <= to; i++) | ||||
| 				d.push(label ? i + "" + label : i); | ||||
| 		return d; | ||||
| 	} | ||||
|  | ||||
| 	//生成form至to之间的年数组,默认值:from:undefined -- 当前年 | ||||
| 	//ex: (2010, 2016) | ||||
| 	//ex: (-3, 0) //当前年-3 至 当前年 | ||||
| 	static year (from?: number, to?: number): any[] | ||||
| 	{ | ||||
| 		from = from || 0; | ||||
| 		to = to || 0; | ||||
| 		var y = new Date().getFullYear(); | ||||
| 		if (Math.abs(from) < 1000) from += y; | ||||
| 		if (Math.abs(to) < 1000) to += y; | ||||
| 		return this.number(from, to); | ||||
| 	} | ||||
|  | ||||
| 	//生成from至to之间的月数组,from=0则为当前月,to=0则为当前月,默认值:from=1,to=12 | ||||
| 	//ex: (1, 0)、(0, 12)、() | ||||
| 	static month (from?: number, to?: number): any[] | ||||
| 	{ | ||||
| 		from = from == undefined ? 1 : (from == 0 ? new Date().getMonth() + 1 : from); | ||||
| 		to = to == undefined ? 12 : (to == 0 ? new Date().getMonth() + 1 : to); | ||||
| 		return this.number(from, to); | ||||
| 	} | ||||
|  | ||||
| 	//生成from至to之间的月数组,默认值:from=1,to=31 | ||||
| 	//ex: (1, 15) | ||||
| 	static day (from?: number, to?: number): any[] | ||||
| 	{ | ||||
| 		return this.number(from ? from : 1, to ? to : 31); | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| //选择器ScrollView | ||||
| class OptionPickerScrollView | ||||
| { | ||||
| 	itemHeight = 80; | ||||
| 	scrollView!: cc.ScrollView; | ||||
| 	checkValidHandler?: Function; | ||||
| 	tweenAdjust?: cc.Tween<any>; | ||||
| 	lastY?: number; | ||||
|  | ||||
| 	constructor (view: cc.Node, data:[], defaultIndex: number, displayProperty:string, labelSuffix?: string) | ||||
| 	{ | ||||
| 		var width = view.getWidth(); | ||||
| 		var height = this.itemHeight = 80; | ||||
| 		this.scrollView = view.getComponent(cc.ScrollView)!; | ||||
| 		this.scrollView.content!.getComponent(cc.UITransform)?.setContentSize(view.getContentSize()); | ||||
| 		 | ||||
| 		var node = new cc.Node(); | ||||
| 		node.addComponent(cc.UITransform).setContentSize(width, height*2); | ||||
| 		this.scrollView.content!.addChild(node); | ||||
|  | ||||
| 		for (var i in data) | ||||
| 		{ | ||||
| 			var text = displayProperty ? data[i][displayProperty] : data[i]; | ||||
| 			var itemNode = new cc.Node(); | ||||
| 			itemNode.addComponent(cc.UITransform).setContentSize(width, height); | ||||
| 			itemNode.addChild(ui.createLabelNode(labelSuffix ? text + labelSuffix : text, 32, "000000")); | ||||
| 			this.scrollView.content!.addChild(itemNode); | ||||
| 		} | ||||
|  | ||||
| 		node = new cc.Node(); | ||||
| 		node.addComponent(cc.UITransform).setContentSize(width, height*2); | ||||
| 		this.scrollView.content!.addChild(node); | ||||
|  | ||||
| 		this.scrollView.content!.getComponent(cc.Layout)!.updateLayout(); | ||||
| 		this.setIndex(defaultIndex); | ||||
|  | ||||
| 		view.on(cc.ScrollView.EventType.SCROLL_ENDED, this.onScrollEnded, this); | ||||
| 		view.on(cc.ScrollView.EventType.SCROLLING, this.onScrolling, this); | ||||
| 		view.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this); | ||||
| 	} | ||||
|  | ||||
| 	getIndex (): number | ||||
| 	{ | ||||
| 		return Math.round(this.scrollView.getScrollOffset().y / this.itemHeight); | ||||
| 	} | ||||
|  | ||||
| 	setIndex (index: number) | ||||
| 	{ | ||||
| 		this.scrollView.content!.setPosition(this.scrollView.content!.getPosition().x, index * this.itemHeight + this.scrollView.node.getHeight()); | ||||
| 	} | ||||
|  | ||||
| 	getPosition (index: number): number | ||||
| 	{ | ||||
| 		return index * this.itemHeight; | ||||
| 	} | ||||
|  | ||||
| 	onScrollEnded (scrollView: cc.ScrollView) | ||||
| 	{ | ||||
| 		//如果在滚动中又按下,isAutoScrolling=true | ||||
| 		//自动滚动结束,或无自动滚动,isAutoScrolling=false | ||||
| 		if (scrollView.isAutoScrolling()) | ||||
| 			return; | ||||
|  | ||||
| 		var p = Math.round(scrollView.getScrollOffset().y / this.itemHeight) + 1; | ||||
| 		if (this.checkValidHandler && !this.checkValidHandler(this)) | ||||
| 			return; | ||||
|  | ||||
| 		//滚动停止时没有在label上,则调整位置 | ||||
| 		var py = (p - 1) * this.itemHeight; | ||||
| 		if (Math.abs(scrollView.getScrollOffset().y - py) < 1) | ||||
| 			scrollView.content!.setPosition(scrollView.content!.getPosition().x, py + scrollView.node.getHeight()); | ||||
| 		else | ||||
| 			this.tweenAdjust = cc.tween(scrollView.content).to(0.5, {position:cc.v3(undefined, py + scrollView.node.getHeight())}).start(); | ||||
| 	} | ||||
|  | ||||
| 	onScrolling (scrollView: cc.ScrollView) | ||||
| 	{ | ||||
| 		if (scrollView.isAutoScrolling()) | ||||
| 		{ | ||||
| 			if (this.lastY != undefined && Math.abs(scrollView.getScrollOffset().y - this.lastY) < 1) | ||||
| 			{ | ||||
| 				this.lastY = undefined; | ||||
| 					scrollView.stopAutoScroll(); | ||||
| 			} | ||||
| 			else | ||||
| 				this.lastY = scrollView.getScrollOffset().y; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	onTouchStart () | ||||
| 	{ | ||||
| 		if (this.tweenAdjust) | ||||
| 		{ | ||||
| 			this.tweenAdjust.stop(); | ||||
| 			this.tweenAdjust = undefined; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| //选择器界面 | ||||
| class OptionPicker  | ||||
| { | ||||
| 	callback?: Function; | ||||
| 	dataList!: any[]; | ||||
| 	viewList!: any[]; | ||||
| 	node?: cc.Node; | ||||
| 	page!: cc.Component; | ||||
|  | ||||
| 	constructor (page: cc.Component, callback: Function | undefined, dataList: any[]) | ||||
| 	{ | ||||
| 		this.page = page; | ||||
| 		this.callback = callback; | ||||
| 		this.dataList = []; | ||||
| 		this.viewList = []; | ||||
|  | ||||
| 		res.loadBundleRes(["cx.prefab/cx.picker", "cx.prefab/cx.pickerScrollView"], (assets: any[]) => | ||||
| 		{ | ||||
| 			var node = this.node = cc.instantiate(assets[0].data); | ||||
| 			ui.makeNodeMap(node); | ||||
| 			ui.setAndroidBackHandler(this.close.bind(this)); | ||||
| 			ui.gn(node, "spCancel").setTouchCallback(this, this.close, 0); | ||||
| 			ui.gn(node, "layerMask").setTouchCallback(this, this.close, 0); | ||||
| 			ui.gn(node, "spOk").setTouchCallback(this, this.close, 1); | ||||
|  | ||||
| 			ui.mainScene.node.addChild(node); | ||||
| 			node.getComponent(cc.Widget).updateAlignment(); | ||||
| 			cc.tween(node).by(0.55, {position: cc.v3(undefined, 480)}, {easing: "expoOut"}).start(); | ||||
| 			cc.tween(ui.gn(node, "layerMask").getComponent(cc.UIOpacity)).to(0.25, {opacity: 100}).start(); | ||||
|  | ||||
| 			var viewParent = ui.gn(node, "layerBox"); | ||||
| 			var viewWidth = ui.sw / dataList.length; | ||||
| 			for (var i in dataList) | ||||
| 			{ | ||||
| 				var obj = dataList[i]; | ||||
| 				this.dataList.push(obj.data); | ||||
|  | ||||
| 				var view: cc.Node = cc.instantiate(assets[1].data); | ||||
| 				view.getComponent(cc.UITransform)?.setContentSize(viewWidth, view.getHeight()); | ||||
| 				viewParent.addChild(view); | ||||
|  | ||||
| 				var pickerView: OptionPickerScrollView = new OptionPickerScrollView(view, obj.data, obj.index, obj.display, obj.suffix); | ||||
| 				if (this.checkValidHandler) | ||||
| 					pickerView.checkValidHandler = this.checkValidHandler.bind(this); | ||||
| 				this.viewList.push(pickerView); | ||||
| 			} | ||||
| 			 | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	close (sender: cc.Node, flag: any) | ||||
| 	{ | ||||
| 		if (flag && this.callback) | ||||
| 		{ | ||||
| 			var params = []; | ||||
| 			for (var i in this.viewList) | ||||
| 			{ | ||||
| 				var index = this.viewList[i].getIndex(); | ||||
| 				params.push({index: index, value: this.dataList[i][index]}); | ||||
| 			} | ||||
| 			this.callback.apply(this.page, params); | ||||
| 		} | ||||
| 		ui.gn(this.node, "layerMask").setTouchCallback(); | ||||
| 		cc.tween(this.node).by(0.55, {position: cc.v3(0, -480)}, {easing: "expoOut"}).call(()=>{this.node?.destroy();}).start(); | ||||
| 		cc.tween(ui.gn(this.node, "layerMask").getComponent(cc.UIOpacity)).to(0.25, {opacity: 0}).start(); | ||||
| 		ui.setAndroidBackHandler(); | ||||
| 	} | ||||
|  | ||||
| 	checkValidHandler (scrollView: cc.ScrollView): boolean | ||||
| 	{ | ||||
| 		return true; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| class OptionPickerMonthDay extends OptionPicker | ||||
| { | ||||
| 	checkValidHandler (scrollView: cc.ScrollView) | ||||
| 	{ | ||||
| 		var month = this.dataList[0][this.viewList[0].getIndex()]; | ||||
| 		var dayIndex = this.viewList[1].getIndex(); | ||||
| 		var day = this.dataList[1][dayIndex]; | ||||
| 		var c = new Date(new Date().getFullYear(), month, 0).getDate(); | ||||
| 		var d = c - day; | ||||
| 		if (d < 0) | ||||
| 		{ | ||||
| 			var p = this.viewList[1].getPosition(dayIndex + d); | ||||
| 			this.viewList[1].view.scrollToOffset(cc.v2(0, p), 0.4); | ||||
| 			return scrollView != this.viewList[1]; | ||||
| 		} | ||||
| 		return true; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| class OptionPickerYearMonthDay extends OptionPicker | ||||
| { | ||||
| 	checkValidHandler (scrollView: cc.ScrollView) | ||||
| 	{ | ||||
| 		var year = this.dataList[0][this.viewList[0].getIndex()]; | ||||
| 		var month = this.dataList[1][this.viewList[1].getIndex()]; | ||||
| 		var dayIndex = this.viewList[2].getIndex(); | ||||
| 		var day = this.dataList[2][dayIndex]; | ||||
| 		var c = new Date(year, month, 0).getDate(); | ||||
| 		var d = c - day; | ||||
| 		if (d < 0) | ||||
| 		{ | ||||
| 			var p = this.viewList[2].getPosition(dayIndex + d); | ||||
| 			this.viewList[2].view.scrollToOffset(cc.v2(0, p), 0.4); | ||||
| 			return scrollView != this.viewList[2]; | ||||
| 		} | ||||
| 		return true; | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										9
									
								
								cx3-demo/assets/cx/core/cx.picker.ts.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								cx3-demo/assets/cx/core/cx.picker.ts.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "4.0.22", | ||||
|   "importer": "typescript", | ||||
|   "imported": true, | ||||
|   "uuid": "9cbbf9f1-7d7e-42bf-a933-8313aa01f1f4", | ||||
|   "files": [], | ||||
|   "subMetas": {}, | ||||
|   "userData": {} | ||||
| } | ||||
							
								
								
									
										95
									
								
								cx3-demo/assets/cx/core/cx.res.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								cx3-demo/assets/cx/core/cx.res.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,95 @@ | ||||
| import * as cc from 'cc'; | ||||
| import serv from './cx.serv'; | ||||
|  | ||||
| export default  | ||||
| { | ||||
| 	//从resources目录取图片 | ||||
| 	//sizeMode:  | ||||
| 	//	cc.Sprite.SizeMode.CUSTOM - 图片适应Node尺寸 | ||||
| 	//	cc.Sprite.SizeMode.TRIMMED - 图片裁剪后的尺寸 | ||||
| 	//	cc.Sprite.SizeMode.RAW - 图片原始尺寸 | ||||
| 	setImageFromRes (spriteOrNode: any, img: string, sizeMode?: number, callback?: Function) | ||||
| 	{ | ||||
| 		var sprite: cc.Sprite = spriteOrNode instanceof cc.Sprite ? spriteOrNode : (spriteOrNode.getComponent(cc.Sprite) || spriteOrNode.addComponent(cc.Sprite)); | ||||
| 		cc.resources.load(img, (err: Error | null, asset: cc.ImageAsset) => | ||||
| 		{ | ||||
| 			if (err) | ||||
| 				cc.log("cx.serv.setImageFromRes error", err); | ||||
| 			else | ||||
| 			{ | ||||
| 				sprite.sizeMode = sizeMode != null ? sizeMode : cc.Sprite.SizeMode.CUSTOM; | ||||
| 				var spriteFrame = new cc.SpriteFrame(); | ||||
| 				spriteFrame.texture = asset._texture; | ||||
| 				sprite.spriteFrame = spriteFrame; | ||||
| 				callback && callback(sprite); | ||||
| 			} | ||||
| 		}); | ||||
| 	}, | ||||
|  | ||||
| 	//从bundle目录取图片 | ||||
| 	setImageFromBundle (spriteOrNode: cc.Sprite | cc.Node, path: string, sizeMode?: number, callback?:Function) | ||||
| 	{ | ||||
| 		var sprite: cc.Sprite = spriteOrNode instanceof cc.Sprite ? spriteOrNode : (spriteOrNode.getComponent(cc.Sprite) || spriteOrNode.addComponent(cc.Sprite)); | ||||
| 		this.loadBundleRes(path, (asset: cc.ImageAsset) => | ||||
| 		{ | ||||
| 			sprite.sizeMode = sizeMode ? sizeMode : cc.Sprite.SizeMode.CUSTOM; | ||||
| 			var spriteFrame = new cc.SpriteFrame(); | ||||
| 			spriteFrame.texture = asset._texture; | ||||
| 			sprite.spriteFrame = spriteFrame; | ||||
| 			callback && callback(sprite); | ||||
| 		}); | ||||
| 	}, | ||||
|  | ||||
| 	//从远程取图片, localPath: 保存到本地路径,并优先从该路径取图片 | ||||
| 	setImageFromRemote (spriteOrNode: cc.Sprite | cc.Node, url: string, localPath?: string, sizeMode?: number, callback?:Function) | ||||
| 	{ | ||||
| 		serv.loadFile(url, localPath, function(asset: cc.ImageAsset) | ||||
| 		{ | ||||
| 			var sprite: cc.Sprite = spriteOrNode instanceof cc.Sprite ? spriteOrNode : (spriteOrNode.getComponent(cc.Sprite) || spriteOrNode.addComponent(cc.Sprite)); | ||||
| 			sprite.sizeMode = sizeMode != null ? sizeMode : cc.Sprite.SizeMode.CUSTOM; | ||||
| 			var spriteFrame = new cc.SpriteFrame(); | ||||
| 			spriteFrame.texture = asset._texture; | ||||
| 			sprite.spriteFrame = spriteFrame; | ||||
| 			callback && callback(sprite); | ||||
| 		}); | ||||
| 	}, | ||||
|  | ||||
| 	//加载prefab,callback(类对象) | ||||
| 	//ex: ("page/page1", this.xx.bind(this)) | ||||
| 	//ex: (["page/page1", "page/page2"], this.xx.bind(this)) | ||||
| 	//ex: ({p1:"page/page1", p2:"page/page2"}, this.xx.bind(this)) | ||||
| 	loadBundleRes (prefab: string | string[], callback?:Function) | ||||
| 	{ | ||||
| 		var load = function(fab: string, index?: number) | ||||
| 		{ | ||||
| 			var p = fab.indexOf("/");                      //prefab = ui/path1/page1 | ||||
| 			var ui = p ? fab.substr(0, p) : "ui";          //ui = ui | ||||
| 			var res = p ? fab.substr(p + 1) : fab;         //res = path1/page1 | ||||
| 			cc.assetManager.loadBundle(ui, (err, bundle) =>  | ||||
| 			{ | ||||
| 				bundle.load(res, (err, asset) => | ||||
| 				{ | ||||
| 					if (err) | ||||
| 						cc.log("cx.serv.loadBundleRes error", err); | ||||
| 					else if (index == undefined) | ||||
| 						callback && callback(asset); | ||||
| 					else | ||||
| 					{ | ||||
| 						assets[index] = asset; | ||||
| 						if (++loadedCount == assets.length) | ||||
| 							callback && callback(assets.length == 1 ? assets[0] : assets); | ||||
| 					} | ||||
| 				}); | ||||
| 			}); | ||||
| 		}; | ||||
| 		if (typeof prefab === "string") | ||||
| 			load(prefab); | ||||
| 		else | ||||
| 		{ | ||||
| 			var assets = new Array(prefab.length); | ||||
| 			var loadedCount = 0; | ||||
| 			for (var i in prefab) | ||||
| 				load(prefab[i], +i); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										9
									
								
								cx3-demo/assets/cx/core/cx.res.ts.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								cx3-demo/assets/cx/core/cx.res.ts.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "4.0.22", | ||||
|   "importer": "typescript", | ||||
|   "imported": true, | ||||
|   "uuid": "6d1e5209-0e30-42db-bd36-eff1ab6988eb", | ||||
|   "files": [], | ||||
|   "subMetas": {}, | ||||
|   "userData": {} | ||||
| } | ||||
							
								
								
									
										54
									
								
								cx3-demo/assets/cx/core/cx.script.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								cx3-demo/assets/cx/core/cx.script.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | ||||
| import * as cc from 'cc'; | ||||
|  | ||||
| export default | ||||
| { | ||||
| 	pageView: | ||||
| 	{ | ||||
| 		initAutoScroll(page: cc.Component, viewName: string, autoScrollSeconds: number, loop: boolean, callback?: Function) | ||||
| 		{ | ||||
| 			var script: any = page.getComponent("cxui.pageView") || page.addComponent("cxui.pageView"); | ||||
| 			script.initAutoScroll.apply(script, arguments); | ||||
| 		} | ||||
| 	}, | ||||
|  | ||||
| 	scrollView: | ||||
| 	{ | ||||
| 		//添加增量加载数据功能 | ||||
| 		initDeltaInsert (page: cc.Component, viewName: string, queryHandler: Function) | ||||
| 		{ | ||||
| 			var script: any = page.getComponent("cxui.scrollView") || page.addComponent("cxui.scrollView"); | ||||
| 			script.initDeltaInsert.apply(script, arguments); | ||||
| 		}, | ||||
|  | ||||
| 		//增量加载数据完成时调用 | ||||
| 		overDeltaInsert (page: cc.Component, noMoreData: boolean) | ||||
| 		{ | ||||
| 			var script: any = page.getComponent("cxui.scrollView"); | ||||
| 			script && script.overDeltaInsert.call(script, noMoreData); | ||||
| 		}, | ||||
|  | ||||
| 		//添加下拉刷新功能 | ||||
| 		initDropRefresh (page: cc.Component, viewName: string, refreshHandler: Function) | ||||
| 		{ | ||||
| 			var script: any = page.getComponent("cxui.scrollView") || page.addComponent("cxui.scrollView"); | ||||
| 			script.initDropRefresh.apply(script, arguments); | ||||
| 		}, | ||||
|  | ||||
| 		//下拉刷新结束时调用 | ||||
| 		overDropRefresh (page: cc.Component) | ||||
| 		{ | ||||
| 			var script: any = page.getComponent("cxui.scrollView"); | ||||
| 			script && script.overDropRefresh.call(script); | ||||
| 		} | ||||
| 	}, | ||||
|  | ||||
| 	nativeMask: | ||||
| 	{ | ||||
| 		init (page: cc.Component, node: Node, x: number, y: number, width: number, height: number): string | ||||
| 		{ | ||||
| 			var script: any = page.getComponent("cxui.nativeMask") || page.addComponent("cxui.nativeMask"); | ||||
| 			return script.init.apply(script, arguments); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
							
								
								
									
										9
									
								
								cx3-demo/assets/cx/core/cx.script.ts.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								cx3-demo/assets/cx/core/cx.script.ts.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "4.0.22", | ||||
|   "importer": "typescript", | ||||
|   "imported": true, | ||||
|   "uuid": "5e9f4376-ed55-457b-89dc-0ae3be5c97d3", | ||||
|   "files": [], | ||||
|   "subMetas": {}, | ||||
|   "userData": {} | ||||
| } | ||||
							
								
								
									
										92
									
								
								cx3-demo/assets/cx/core/cx.serv.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								cx3-demo/assets/cx/core/cx.serv.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,92 @@ | ||||
| import * as cc from 'cc'; | ||||
| import sys from './cx.sys'; | ||||
|  | ||||
| let _commonHeaders: string[]; | ||||
|  | ||||
| export default  | ||||
| { | ||||
| 	//取远程文件并保存到本地localPath,如果是JS,localPath无效 | ||||
| 	loadFile (url: string, localPath?: string, callback?: Function) | ||||
| 	{ | ||||
| 		if (!sys.os.native || !localPath) | ||||
| 		{ | ||||
| 			this.loadAsset(url, callback); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		if (jsb.fileUtils.isFileExist(localPath)) | ||||
| 		{ | ||||
| 			this.loadAsset(localPath, callback); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		this.internalRequest("GET", url, null, (ret: any) => | ||||
| 		{ | ||||
| 			var path = localPath.substr(0, localPath.lastIndexOf("/")); | ||||
| 			if (!jsb.fileUtils.isDirectoryExist(path)) | ||||
| 				jsb.fileUtils.createDirectory(path); | ||||
| 			// 3.0和3.1版本的writeDataToFile有bug,报参数错误,因此使用NativeUtils | ||||
| 			// jsb.fileUtils.writeDataToFile(new Uint8Array(ret.data), localPath); | ||||
| 			cxnative.NativeUtils.writeDataToFile(new Uint8Array(ret.data), localPath); | ||||
| 			this.loadAsset(localPath, callback); | ||||
| 		}, undefined, {responseType:'arraybuffer'}); | ||||
| 	}, | ||||
|  | ||||
| 	//取本地或远程资源文件: 图片、mp3、视频等 | ||||
| 	loadAsset (url: string, callback?: Function) | ||||
| 	{ | ||||
| 		cc.assetManager.loadRemote(url, function(err, asset) | ||||
| 		{ | ||||
| 			if (err) | ||||
| 				cc.log("cx.serv.loadAsset error", err); | ||||
| 			else | ||||
| 				callback && callback(asset); | ||||
| 		}); | ||||
| 	}, | ||||
|  | ||||
| 	call (url: string, callback?: Function, context?: any) | ||||
| 	{ | ||||
| 		this.internalRequest("GET", url, undefined, callback, context); | ||||
| 	}, | ||||
|  | ||||
| 	post (url: string, data?: any, callback?: Function, context?: any) | ||||
| 	{ | ||||
| 		this.internalRequest("POST", url, data, callback, context); | ||||
| 	}, | ||||
|  | ||||
| 	upload (url: string, filePath: string, callback?: Function) | ||||
| 	{ | ||||
| 		if (sys.os.native) | ||||
| 			this.internalRequest("POST", url, jsb.fileUtils.getValueMapFromFile(filePath), callback, undefined, {headers: ['Content-Type', 'application/octet-stream']}); | ||||
| 	}, | ||||
|  | ||||
| 	setCommonHeaders (headers: string[]) | ||||
| 	{ | ||||
| 		_commonHeaders = headers; | ||||
| 	}, | ||||
|  | ||||
| 	internalRequest (method: string, url: string, data?: any, callback?: Function, context?: any, option?: any) | ||||
| 	{ | ||||
| 		var xhr = new XMLHttpRequest(); | ||||
| 		xhr.onreadystatechange = function()  | ||||
| 		{ | ||||
| 			if (xhr.readyState === 4 && xhr.status === 200) | ||||
| 				callback && callback({data:xhr.response, context:context}); | ||||
| 		}; | ||||
| 		if (option) | ||||
| 		{ | ||||
| 			if (option.responseType) | ||||
| 			{ | ||||
| 				xhr.responseType = option.responseType; | ||||
| 			} | ||||
| 			if (option.headers) | ||||
| 				for (var i=0; i<option.headers.length; i+=2) | ||||
| 					xhr.setRequestHeader(option.headers[i], option.headers[i+1]); | ||||
| 		} | ||||
| 		if (_commonHeaders) | ||||
| 			for (var i=0; i<_commonHeaders.length; i+=2) | ||||
| 				xhr.setRequestHeader(_commonHeaders[i], _commonHeaders[i+1]); | ||||
| 		xhr.open(method, url); | ||||
| 		xhr.send(data); | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										9
									
								
								cx3-demo/assets/cx/core/cx.serv.ts.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								cx3-demo/assets/cx/core/cx.serv.ts.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "4.0.22", | ||||
|   "importer": "typescript", | ||||
|   "imported": true, | ||||
|   "uuid": "fed014af-56c5-416f-bbfb-22589be96888", | ||||
|   "files": [], | ||||
|   "subMetas": {}, | ||||
|   "userData": {} | ||||
| } | ||||
							
								
								
									
										79
									
								
								cx3-demo/assets/cx/core/cx.sys.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								cx3-demo/assets/cx/core/cx.sys.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,79 @@ | ||||
| import * as cc from 'cc'; | ||||
|  | ||||
| class config | ||||
| { | ||||
| 	[key: string]:any | ||||
| } | ||||
|  | ||||
| (function() | ||||
| { | ||||
| 	//creator3.0 | ||||
| 	if (!cc.sys.OS) | ||||
| 	{ | ||||
| 		cc.sys.OS = {OSX:cc.sys.OS_OSX, IOS:cc.sys.OS_IOS, ANDROID:cc.sys.OS_ANDROID, WINDOWS:cc.sys.OS_WINDOWS}; | ||||
| 	} | ||||
| 	else if (cc.sys.os == cc.sys.OS.ANDROID) | ||||
| 		cc.sys.OS_ANDROID = cc.sys.OS.ANDROID; | ||||
| })(); | ||||
|  | ||||
| export default class sys  | ||||
| { | ||||
| 	static version: string = "v1.0.0"; | ||||
| 	static userPath: string = "__user"; | ||||
| 	static cachePath: string = "__cache"; | ||||
|  | ||||
| 	static os = | ||||
| 	{ | ||||
| 		native: cc.sys.isNative, //mac or ios or android | ||||
|  | ||||
| 		mac: cc.sys.isNative && cc.sys.os == cc.sys.OS.OSX, | ||||
| 		ios: cc.sys.isNative && cc.sys.os == cc.sys.OS.IOS, | ||||
| 		android: cc.sys.isNative && cc.sys.os == cc.sys.OS.ANDROID, | ||||
|  | ||||
| 		wxgame: cc.sys.platform == "WECHAT_GAME", | ||||
| 		wxpub: cc.sys.platform != "WECHAT_GAME" && cc.sys.browserType == "wechat", | ||||
| 		web: cc.sys.isBrowser | ||||
| 	} | ||||
|  | ||||
| 	static config: config = | ||||
| 	{ | ||||
| 		debug: false, | ||||
| 		startPage: "ui/start",        //开始页 | ||||
| 		autoRemoveLaunchImage: true,  //自动移除启动屏 | ||||
|  | ||||
| 		designSizeMinWidth: 0,        //最小设计宽度 | ||||
| 		designSizeMinHeight: 750,     //最小设计高度 | ||||
| 		 | ||||
| 		slideEventDisabled: false,    //禁止子页面右划 | ||||
| 		pageActionDisabled: false,    //禁止页面显示和退出动画 | ||||
| 		androidkeyDisabled: false,    //禁止android返回键 | ||||
|  | ||||
| 		hintFontSize: 36,                //cx.hint 文字尺寸 | ||||
| 		hintFontColor: "ff0000",         //cx.hint 文字颜色 | ||||
| 		hintFontOutlineWidth: 1,         //cx.hint 文字描边宽度 | ||||
| 		hintFontOutlineColor: "777777",  //cx.hint 文字描边颜色 | ||||
|  | ||||
| 		safeLayerTitleHeight: 170,             //ios刘海屏标题栏高度 | ||||
| 		safeLayerTitleName: "layerSafeTitle",  //ios刘海屏标题栏名称 | ||||
| 		safeLayerTabHeight: 162,               //ios刘海屏底栏高度 | ||||
| 		safeLayerTabName: "layerSafeTab",      //ios刘海屏底栏名称 | ||||
| 	} | ||||
|  | ||||
| 	static init() | ||||
| 	{ | ||||
| 		for (var i in cc.game.appConfig) | ||||
| 			this.config[i] = cc.game.appConfig[i]; | ||||
|  | ||||
| 		cc.game.config.debugMode = this.config.debug ? 1 : 3; | ||||
|  | ||||
| 		if (this.os.native) | ||||
| 		{ | ||||
| 			var path = jsb.fileUtils.getWritablePath(); | ||||
| 			if (this.os.mac && typeof cxnative != "undefined") | ||||
| 				path += "_cxcache/" + cxnative.NativeCreator.createNativeClass("cx.sys").call("getPackageName", []) + "/"; | ||||
| 			this.userPath = path + this.userPath + "/"; | ||||
| 			this.cachePath = path + this.cachePath + "/"; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
							
								
								
									
										9
									
								
								cx3-demo/assets/cx/core/cx.sys.ts.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								cx3-demo/assets/cx/core/cx.sys.ts.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "4.0.22", | ||||
|   "importer": "typescript", | ||||
|   "imported": true, | ||||
|   "uuid": "f6d0649e-e9e2-4656-a22e-f20c516aabc3", | ||||
|   "files": [], | ||||
|   "subMetas": {}, | ||||
|   "userData": {} | ||||
| } | ||||
							
								
								
									
										529
									
								
								cx3-demo/assets/cx/core/cx.ui.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										529
									
								
								cx3-demo/assets/cx/core/cx.ui.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,529 @@ | ||||
| import * as cc from 'cc'; | ||||
|  | ||||
| import res from "./cx.res"; | ||||
| import sys from "./cx.sys"; | ||||
| import native from "./cx.native"; | ||||
|  | ||||
| export default class ui  | ||||
| { | ||||
| 	static sw: number = 0; | ||||
| 	static sh: number = 0; | ||||
|  | ||||
| 	static mainScene: cc.Component; | ||||
| 	static rootNode: RootNode; | ||||
| 	static uid: number = 0; | ||||
|  | ||||
|     // 在页面组件脚本中,设置页面的以下参数可以改变出入场动画 | ||||
| 	// initPx: cx.sw, | ||||
| 	// initPy: 0, | ||||
| 	// moveInAction: null, | ||||
| 	// moveOutAction: null, | ||||
| 	// nextInAction: null, | ||||
| 	// nextOutAction: null, | ||||
|  | ||||
|     static defaultInitPx: number = 0; | ||||
|     static defaultInitPy: number = 0; | ||||
|     static defaultMoveInAction: cc.Tween<any>; | ||||
|     static defaultMoveOutAction: cc.Tween<any>; | ||||
|     static defaultNextInAction: cc.Tween<any>; | ||||
|     static defaultNextOutAction: cc.Tween<any>; | ||||
|     static touchLockTimelen = 250; //ms | ||||
|     static touchPriorSecond = 0; | ||||
|  | ||||
| 	static androidKeyBackHandler: any; | ||||
|  | ||||
| 	static init (mainScene: cc.Component) | ||||
| 	{ | ||||
| 		var size = cc.view.getCanvasSize(); | ||||
| 		if (Math.ceil(size.height) < sys.config.designSizeMinHeight) | ||||
| 			cc.view.setDesignResolutionSize(cc.view.getDesignResolutionSize().width, cc.view.getDesignResolutionSize().height, cc.ResolutionPolicy.FIXED_HEIGHT); | ||||
| 		else if (Math.ceil(size.width) < sys.config.designSizeMinWidth) | ||||
| 			cc.view.setDesignResolutionSize(cc.view.getDesignResolutionSize().width, cc.view.getDesignResolutionSize().height, cc.ResolutionPolicy.FIXED_WIDTH); | ||||
| 		size = cc.view.getVisibleSize(); | ||||
|  | ||||
| 		this.sw = Math.round(size.width); | ||||
| 		this.sh = Math.round(size.height); | ||||
| 		 | ||||
| 		this.defaultInitPx = this.sw; | ||||
| 		this.defaultInitPy = 0; | ||||
| 		this.defaultMoveInAction = cc.tween(this.rootNode).delay(0.1).to(0.55, {position:cc.v3(0, undefined)}, {easing: "expoOut"}); | ||||
| 		this.defaultMoveOutAction = cc.tween().to(0.55, {position:cc.v3(ui.sw)}, {easing: "expoOut"}); | ||||
| 		this.defaultNextInAction = cc.tween().delay(0.1).to(0.55, {position:cc.v3(-this.sw*0.3, undefined)}, {easing:"expoOut"}); | ||||
| 		this.defaultNextOutAction = cc.tween().to(0.55, {position:cc.v3(0)}, {easing:"expoOut"}); | ||||
|  | ||||
| 		this.mainScene = mainScene; | ||||
| 		this.rootNode = new RootNode(); | ||||
| 		mainScene.node.addChild(this.rootNode); | ||||
| 		this.addPage(this.rootNode, sys.config.startPage, undefined, !sys.config.autoRemoveLaunchImage ? undefined : this.removeLaunchImage); | ||||
| 		cc.assetManager.loadBundle("cx.prefab"); | ||||
| 	} | ||||
|  | ||||
| 	static removeLaunchImage () | ||||
| 	{ | ||||
| 		sys.os.native && native.ins("cx.sys").call("removeLaunchImage", []); | ||||
| 	} | ||||
|  | ||||
| 	//将节点放入map | ||||
| 	static makeNodeMap (node: any) | ||||
| 	{ | ||||
| 		node._nodeMap = {}; | ||||
| 		var f = function(e: any) | ||||
| 		{ | ||||
| 			node._nodeMap[e.name] = e; | ||||
| 			for (var i in e.children) | ||||
| 				f(e.children[i]); | ||||
| 		}; | ||||
| 		f(node); | ||||
| 	} | ||||
|  | ||||
| 	//从map取出节点 | ||||
| 	static gn (pageOrNode: any, name: string) | ||||
| 	{ | ||||
| 		var node = (pageOrNode instanceof cc.Component) && pageOrNode.node ? pageOrNode.node : pageOrNode; | ||||
| 		return node && node._nodeMap && node._nodeMap[name]; | ||||
| 	} | ||||
|  | ||||
|     static hint (content: string) | ||||
| 	{ | ||||
| 		res.loadBundleRes("cx.prefab/cx.hint", (asset: any) => | ||||
| 		{ | ||||
| 			var page = cc.instantiate(asset.data); | ||||
| 			page.name = "cx.hint"; | ||||
| 			ui.makeNodeMap(page); | ||||
| 			var lblHint: cc.Node = ui.gn(page, "lblHint"); | ||||
| 			var priorHint; | ||||
| 			for (var i in ui.mainScene.node.children) | ||||
| 			{ | ||||
| 				var n = ui.mainScene.node.children[i]; | ||||
| 				if (n.name == "cx.hint") | ||||
| 				{ | ||||
| 					n.name = "cx.hint.prior"; | ||||
| 					priorHint = n; | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 			lblHint.getComponent(cc.Label)!.color = cc.color(sys.config.hintFontColor); | ||||
| 			lblHint.getComponent(cc.Label)!.fontSize = sys.config.hintFontSize; | ||||
| 			lblHint.getComponent(cc.LabelOutline)!.width = sys.config.hintFontOutlineWidth; | ||||
| 			lblHint.getComponent(cc.LabelOutline)!.color = cc.color(sys.config.hintFontOutlineColor); | ||||
| 			lblHint.getComponent(cc.Label)!.string = content; | ||||
| 			lblHint.setScale(0.5, 0.5); | ||||
| 			if (priorHint) | ||||
| 				lblHint.setPosition(lblHint.getPosition().x, Math.min(-30, ui.gn(priorHint, "lblHint").getPosition().y - 50)); | ||||
| 			ui.mainScene.node.addChild(page); | ||||
| 			cc.tween(lblHint).to(0.1, {scale:cc.v3(1,1,1)}).by(1.5, {position:cc.v3(undefined,30)}).by(0.2, {position: cc.v3(undefined, 20)}).call(()=>{page.destroy();}).start(); | ||||
| 			cc.tween(lblHint.getComponent(cc.UIOpacity)).delay(1.5).to(0.2, {opacity: 0}).start(); | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	static alert (content: string, callback?: Function, labelOk?: string) | ||||
| 	{ | ||||
| 		ui.setAndroidBackHandler(true); | ||||
| 		res.loadBundleRes("cx.prefab/cx.alert", function(asset: any) | ||||
| 		{ | ||||
| 			var page = cc.instantiate(asset.data); | ||||
| 			page.name = "cx.alert"; | ||||
| 			page.content = content; | ||||
| 			page.callback = callback; | ||||
| 			ui.makeNodeMap(page); | ||||
| 			page.on(cc.Node.EventType.TOUCH_START, (event: cc.EventTouch) => | ||||
| 			{ | ||||
| 				event.propagationStopped = true; | ||||
| 			}); | ||||
|  | ||||
| 			if (labelOk) | ||||
| 				ui.gn(page, "lblOk").getComponent(cc.Label).string = labelOk; | ||||
|  | ||||
| 			var lblContent: cc.Node = ui.gn(page, "lblContent"); | ||||
| 			lblContent.getComponent(cc.Label)!.string = content; | ||||
| 			lblContent.getComponent(cc.Label)!.updateRenderData(true); //更新Label高度 | ||||
| 			var contentHeight = Math.max(400, lblContent.getComponent(cc.UITransform)!.height + 140); | ||||
| 			var nodeContent: cc.Node = ui.gn(page, "nodeContent"); | ||||
| 			nodeContent.getComponent(cc.UITransform)!.height = contentHeight; | ||||
| 			nodeContent.setScale(1.2, 1.2); | ||||
| 			ui.mainScene.node.addChild(page); | ||||
| 			 | ||||
| 			cc.tween(nodeContent).to(0.15, {scale:cc.v3(1,1,1)}).start(); | ||||
| 			cc.tween(ui.gn(page, "mask").getComponent(cc.UIOpacity)).to(0.15, {opacity:90}).start(); | ||||
| 			ui.setNativeMaskMask((ui.sw-600)/2, (ui.sh+contentHeight)/2, 600, contentHeight, 14); | ||||
| 			ui.gn(page, "spOk").setTouchCallback(page, function() | ||||
| 			{ | ||||
| 				ui.clearNativeMaskMask(); | ||||
| 				ui.setAndroidBackHandler(); | ||||
| 				page.destroy(); | ||||
| 				callback && callback(); | ||||
| 			}); | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	static confirm (content: string, callback?: Function, labelOk?: string, labelCancel?: string) | ||||
| 	{ | ||||
| 		ui.setAndroidBackHandler(true); | ||||
| 		res.loadBundleRes("cx.prefab/cx.confirm", function(asset: any) | ||||
| 		{ | ||||
| 			var page = cc.instantiate(asset.data); | ||||
| 			page.name = "cx.confirm"; | ||||
| 			page.content = content; | ||||
| 			page.callback = callback; | ||||
| 			ui.makeNodeMap(page); | ||||
| 			page.on(cc.Node.EventType.TOUCH_START, (event: cc.EventTouch) => | ||||
| 			{ | ||||
| 				event.propagationStopped = true; | ||||
| 			}); | ||||
|  | ||||
| 			if (labelOk) | ||||
| 				ui.gn(page, "lblOk").getComponent(cc.Label).string = labelOk; | ||||
|  | ||||
| 			if (labelCancel) | ||||
| 				ui.gn(page, "lblCancel").getComponent(cc.Label).string = labelCancel; | ||||
|  | ||||
| 			var lblContent = ui.gn(page, "lblContent"); | ||||
| 			lblContent.getComponent(cc.Label)!.string = content; | ||||
| 			lblContent.getComponent(cc.Label)!.updateRenderData(true); //更新Label高度 | ||||
| 			ui.gn(page, "nodeContent").getComponent(cc.UITransform)!.height = Math.max(400, lblContent.getComponent(cc.UITransform)!.height + 140); | ||||
| 			ui.mainScene.node.addChild(page); | ||||
|  | ||||
| 			var nodeContent = ui.gn(page, "nodeContent"); | ||||
| 			nodeContent.setScale(1.2, 1.2); | ||||
| 			cc.tween(nodeContent).to(0.15, {scale:cc.v3(1, 1, 1)}).start(); | ||||
| 			cc.tween(ui.gn(page, "mask").getComponent(cc.UIOpacity)).to(0.15, {opacity:90}).start(); | ||||
| 			ui.gn(page, "spOk").setTouchCallback(page, function() | ||||
| 			{ | ||||
| 				ui.setAndroidBackHandler(); | ||||
| 				page.destroy(); | ||||
| 				callback && callback(true); | ||||
| 			}); | ||||
| 			ui.gn(page, "spCancel").setTouchCallback(page, function() | ||||
| 			{ | ||||
| 				ui.setAndroidBackHandler(); | ||||
| 				page.destroy(); | ||||
| 				callback && callback(false); | ||||
| 			}); | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	static showLoading (page: cc.Component, parentNode: any, delayShowSeconds: number = 0) | ||||
| 	{ | ||||
| 		if (parentNode._loadingInDelay || parentNode.getChildByName("cx.loadingNode")) | ||||
| 			return; | ||||
| 		var createLoading = function(dt?: number) | ||||
| 		{ | ||||
| 			if (dt && !parentNode._loadingInDelay) | ||||
| 				return; | ||||
| 			var imageNode = new cc.Node(); | ||||
| 			imageNode.name = "cx.loadingNode"; | ||||
| 			imageNode.setScale(0.45, 0.45); | ||||
| 			res.setImageFromBundle(imageNode, "cx.prefab/s_loading", cc.Sprite.SizeMode.TRIMMED); | ||||
| 			parentNode.addChild(imageNode); | ||||
| 			cc.tween(imageNode).repeatForever(cc.tween().by(0, {angle: -30}).delay(0.07)).start(); | ||||
| 		}; | ||||
| 		parentNode._loadingEnabled = true; | ||||
| 		if (delayShowSeconds > 0) | ||||
| 		{ | ||||
| 			parentNode._loadingInDelay = true; | ||||
| 			page.scheduleOnce(createLoading, delayShowSeconds); | ||||
| 		} | ||||
| 		else | ||||
| 			createLoading(); | ||||
| 	} | ||||
|  | ||||
| 	static removeLoading (parentNode: any) | ||||
| 	{ | ||||
| 		var loadingNode = parentNode.getChildByName("cx.loadingNode"); | ||||
| 		if (loadingNode) | ||||
| 			loadingNode.removeFromParent(); | ||||
| 		if (parentNode._loadingInDelay) | ||||
| 			delete parentNode._loadingInDelay; | ||||
| 	} | ||||
|  | ||||
| 	static getTopPage (fromLast?: number): any | ||||
| 	{ | ||||
| 		fromLast = fromLast || 0; | ||||
| 		var match = 0; | ||||
| 		for (var i = this.rootNode.children.length - 1; i>=0; i--) | ||||
| 		{ | ||||
| 			var page = this.rootNode.children[i]; | ||||
| 			if (page.active && !page.ignoreTopPage) | ||||
| 			{ | ||||
| 				if (++match > -fromLast) | ||||
| 					return page; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	static addPage (parent:cc.Node, prefab:string, scripts?:string[], callbackOrParams?:any, runAction?:boolean) | ||||
| 	{ | ||||
| 		ui.touchLockTimelen = -1; | ||||
| 		res.loadBundleRes(prefab, (asset: any) => | ||||
| 		{ | ||||
| 			var p = prefab.indexOf("/"); | ||||
| 			var script = p ? prefab.substr(prefab.lastIndexOf("/") + 1) : prefab; //script = page1(.ts) | ||||
| 			scripts = scripts || [script]; | ||||
| 			var node = cc.instantiate(asset.data); | ||||
| 			var cxuiPageScript = node.addComponent("cxui.page"); | ||||
| 			for (var i in scripts) | ||||
| 				if (cc.js.getClassByName(scripts[i])) | ||||
| 					node.addComponent(scripts[i]); | ||||
| 			node.mainComponent = script && node.getComponent(script); | ||||
| 			parent.addChild(node); | ||||
| 			if (callbackOrParams != null) | ||||
| 			{ | ||||
| 				if (typeof callbackOrParams == "function") | ||||
| 					callbackOrParams(node); | ||||
| 				else if (node.mainComponent) | ||||
| 					node.mainComponent.contextParams = callbackOrParams; | ||||
| 			} | ||||
| 			if (runAction) | ||||
| 				cxuiPageScript.runActionShow(); | ||||
| 			ui.touchLockTimelen = 500; | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	static showPage (prefab:string, scripts?:string[], callbackOrParams?:any) | ||||
| 	{ | ||||
| 		if (arguments.length == 1 || typeof arguments[0] == "string") | ||||
| 			ui.addPage(ui.rootNode, prefab, scripts, callbackOrParams, true); | ||||
| 		else //for touchCallback | ||||
| 			ui.addPage(ui.rootNode, arguments[1], undefined, undefined, true); | ||||
| 	} | ||||
|  | ||||
| 	static closePage (sender: any) | ||||
| 	{ | ||||
| 		var node: any = sender instanceof cc.Component ? sender.node : (this instanceof cc.Component ? this.node : sender); | ||||
| 		node.getComponent("cxui.page").runActionClose(); | ||||
| 	} | ||||
|  | ||||
| 	//设置android返回键处理函数 | ||||
| 	static setAndroidBackHandler(handler?: any) | ||||
| 	{ | ||||
| 		if (sys.os.android) | ||||
| 			this.androidKeyBackHandler = handler; | ||||
| 	} | ||||
|  | ||||
| 	static setNativeMaskMask (x: number, y: number, width: number, height: number, radius: number) | ||||
| 	{ | ||||
| 		if (!sys.os.native) | ||||
| 			return; | ||||
| 		var mask = ui.getTopPage(); | ||||
| 		mask = mask && mask.getComponent("cxui.nativeMask"); | ||||
| 		if (mask) | ||||
| 		{ | ||||
| 			var rect = ui.convertToDeviceSize(undefined, x, y, width, height); | ||||
| 			mask.setMaskMask(rect.x, rect.y, rect.width, rect.height, radius); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	static clearNativeMaskMask () | ||||
| 	{ | ||||
| 		if (!sys.os.native) | ||||
| 			return; | ||||
| 		var mask = ui.getTopPage(); | ||||
| 		mask = mask && mask.getComponent("cxui.nativeMask"); | ||||
| 		if (mask) | ||||
| 			mask.clearMaskMask(); | ||||
| 	} | ||||
|  | ||||
| 	static createPanel (color4: string, width: number, height: number): cc.Node | ||||
| 	{ | ||||
| 		var panel = new cc.Node(); | ||||
| 		panel.addComponent(cc.UITransform).setContentSize(width, height); | ||||
| 		panel.addComponent(cc.Sprite).color = cc.color(color4 || "ffffffff"); | ||||
| 		res.setImageFromBundle(panel, "cx.prefab/s_color"); | ||||
| 		return panel; | ||||
| 	} | ||||
|  | ||||
| 	static createLabelNode (text: string, fontSize: number, fontColor: string): cc.Node | ||||
| 	{ | ||||
| 		var node = new cc.Node(); | ||||
| 		var label = node.addComponent(cc.Label); | ||||
| 		label.string = text; | ||||
| 		label.fontSize = fontSize; | ||||
| 		label.color = cc.color(fontColor); | ||||
| 		return node; | ||||
| 	} | ||||
|  | ||||
| 	//将一个node节点中相对于节点左下角的坐标转换为屏幕坐标 | ||||
| 	static convertToDeviceSize (node:cc.Node | undefined, x:number, y:number, width?:number, height?:number): cc.Rect | ||||
| 	{ | ||||
| 		let frameSize = cc.view.getFrameSize(); | ||||
| 		width = width ? frameSize.width * width / this.sw : 0; | ||||
| 		height = height ? frameSize.height * height / this.sh : 0; | ||||
| 		let r: cc.Vec3 | undefined = node ? node.getComponent(cc.UITransform)?.convertToWorldSpaceAR(cc.v3(x, y, 0)) : cc.v3(x, y, 0); | ||||
| 		if (r) | ||||
| 		{ | ||||
| 			x = frameSize.width * r.x / this.sw; | ||||
| 			y = frameSize.height * (this.sh - r.y) / this.sh; | ||||
| 		} | ||||
| 		return new cc.Rect(x, y, width, height); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| class RootNode extends cc.Node | ||||
| { | ||||
| 	constructor () | ||||
| 	{ | ||||
| 		super(); | ||||
| 		// this.setPosition(0, -ui.sh/2); | ||||
| 		// this.addComponent(cc.UITransform)?.setAnchorPoint(0.5, 0.5); | ||||
| 		this.addComponent(cc.UITransform).setContentSize(ui.sw, ui.sh); | ||||
| 		var widget = this.addComponent(cc.Widget); | ||||
| 		widget.isAlignTop = widget.isAlignBottom = true; widget.isAlignLeft = widget.isAlignRight = true; | ||||
| 			 | ||||
| 		//if (sys.os.android) | ||||
| 		//	cc.systemEvent.on(cc.SystemEventType.KEY_UP, this.onAndroidKeyUp, this); | ||||
| 		if (!sys.config.slideEventDisabled) | ||||
| 			this.addSlideEvent(); | ||||
| 	} | ||||
|  | ||||
| 	onBackPressed() | ||||
| 	//onAndroidKeyUp (event: cc.EventKeyboard) | ||||
| 	{ | ||||
| 		// console.log(".................event..." + event.keyCode + "," + cc.macro.KEY.back); | ||||
| 		//if (event.keyCode == cc.macro.KEY.back || event.keyCode == cc.macro.KEY.backspace || event.keyCode == cc.macro.KEY.escape) | ||||
| 		{ | ||||
| 			if (ui.androidKeyBackHandler) | ||||
| 			{ | ||||
| 				if (typeof ui.androidKeyBackHandler == "function") | ||||
| 					ui.androidKeyBackHandler(); | ||||
| 				return; | ||||
| 			} | ||||
| 			var topPage = ui.getTopPage(); | ||||
| 			var handler = topPage.androidBackHandler; | ||||
| 			if (handler) | ||||
| 			{ | ||||
| 				if (handler == "closePage") | ||||
| 					ui.closePage(topPage); | ||||
| 				else if (handler == "closeApp") | ||||
| 					native.ins("cx.sys").call("moveTaskToBack"); | ||||
| 				else | ||||
| 					handler(); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	slideState = 0; | ||||
| 	slideShadow: cc.Node | undefined; | ||||
| 	slidePage: cc.Node | undefined; | ||||
| 	slideRelatePage: cc.Node | undefined; | ||||
| 	slideMoveDeltaX = 0; | ||||
|  | ||||
| 	addSlideEvent () | ||||
| 	{ | ||||
| 		this.on(cc.Node.EventType.TOUCH_START, (event: cc.EventTouch) => | ||||
| 		{ | ||||
| 			if (event.getLocationX() > ui.sw/2) | ||||
| 				return; | ||||
| 			this.slideState = 0; | ||||
| 			var slidePage = ui.getTopPage(); | ||||
| 			if (slidePage && slidePage.slideEventDisabled) | ||||
| 				return; | ||||
| 			this.slidePage = slidePage; | ||||
| 			this.slideRelatePage = ui.getTopPage(-1); | ||||
| 			// console.log("slide start...", this.slidePage && this.slidePage.name, this.slideRelatePage && this.slideRelatePage.name); | ||||
| 		}, this, true); | ||||
|  | ||||
| 		this.on(cc.Node.EventType.TOUCH_MOVE, (event: cc.EventTouch) => | ||||
| 		{ | ||||
| 			if (!this.slidePage || !this.slidePage.active || this.slidePage.slideEventDisabled) | ||||
| 				return; | ||||
| 			var delta = event.getUIDelta(); | ||||
| 			if (this.slideState < 2) | ||||
| 			{ | ||||
| 				if (Math.abs(delta.x) > 0.05 || Math.abs(delta.y) > 0.05) | ||||
| 				{ | ||||
| 					if (Math.abs(delta.x) > Math.abs(delta.y) && Math.abs(event.getLocation().y - event.getStartLocation().y) < 35) | ||||
| 					{ | ||||
| 						if (event.getLocation().x - event.getStartLocation().x >= 20) | ||||
| 						{ | ||||
| 							this.slideState++; | ||||
| 							if (!this.slideShadow) | ||||
| 							{ | ||||
| 								var node: cc.Node = this.slideShadow = new cc.Node(); | ||||
| 								node.name = "cx.slideShadow"; | ||||
| 								node.ignoreTopPage = true; | ||||
| 								this.addChild(node); | ||||
| 								node.setSiblingIndex(10000000 - 1000); | ||||
|  | ||||
| 								var imgNode = new cc.Node(); | ||||
| 								res.setImageFromBundle(imgNode, "cx.prefab/s_shadow", cc.Sprite.SizeMode.CUSTOM, (sprite: cc.Sprite) => | ||||
| 								{ | ||||
| 									imgNode.getComponent(cc.UITransform)!.setContentSize(sprite.spriteFrame!.width, sprite.spriteFrame!.height); | ||||
| 									imgNode.setScale(1, ui.sh / sprite.spriteFrame!.height); | ||||
| 									imgNode.setPosition(-ui.sw/2-sprite.spriteFrame!.width/2, 0); | ||||
| 									node.addChild(imgNode); | ||||
| 								}); | ||||
| 							} | ||||
| 						} | ||||
| 					} | ||||
| 					else | ||||
| 						this.slideState = 3; | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			if (this.slideState == 2) | ||||
| 			{ | ||||
| 				// console.log("slide move..." + delta.x); | ||||
| 				event.propagationStopped = true; | ||||
| 				this.slideMoveDeltaX = delta.x; | ||||
| 				var p = this.slidePage.getPosition(); | ||||
| 				p.x = Math.max(p.x + this.slideMoveDeltaX, 0); | ||||
| 				this.slidePage.setPosition(p); | ||||
| 				this.slideShadow?.setPosition(p); | ||||
| 				if (this.slideRelatePage) | ||||
| 				{ | ||||
| 					p = this.slideRelatePage.getPosition(); | ||||
| 					p.x += this.slideMoveDeltaX * (this.slideRelatePage.nextInPercentX != undefined ? this.slideRelatePage.nextInPercentX : 0.3); | ||||
| 					if (p.x > 0) | ||||
| 						p.x = 0; | ||||
| 					this.slideRelatePage.setPosition(p); | ||||
| 				} | ||||
| 			} | ||||
| 		}, this, true); | ||||
|  | ||||
| 		let touchEnd = (event: cc.EventTouch) => | ||||
| 		{ | ||||
| 			if (!this.slidePage || !this.slidePage.active || this.slidePage.slideEventDisabled) | ||||
| 				return; | ||||
|  | ||||
| 			if (this.slideState == 2) | ||||
| 			{ | ||||
| 				event.propagationStopped = true; | ||||
| 				if (this.slideMoveDeltaX > 19 || this.slidePage.getPosition().x > ui.sw * 0.33) | ||||
| 				{ | ||||
| 					ui.closePage.call(null, this.slidePage); | ||||
| 					this.slideShadow && cc.tween(this.slideShadow).to(0.55, {position: cc.v3(ui.sw + 12, undefined)}, {easing: "expoOut"}).start(); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					ui.defaultNextOutAction.clone(this.slidePage).start(); | ||||
| 					if (this.slideRelatePage) | ||||
| 					{ | ||||
| 						var tx = -ui.sw * (this.slideRelatePage.nextInPercentX != undefined ? this.slideRelatePage.nextInPercentX : 0.3); | ||||
| 						cc.tween(this.slideRelatePage).to(0.55, {position: cc.v3(tx, undefined)}, {easing: "expoOut"}).start(); | ||||
| 					} | ||||
| 					this.slideShadow && ui.defaultNextOutAction.clone(this.slideShadow).start(); | ||||
| 				} | ||||
| 				this.slidePage = undefined; | ||||
| 			} | ||||
| 			this.slideState = 0; | ||||
| 		}; | ||||
|  | ||||
| 		this.on(cc.Node.EventType.TOUCH_END, touchEnd, this, true); | ||||
| 		this.on(cc.Node.EventType.TOUCH_CANCEL, touchEnd, this, true); | ||||
|  | ||||
| 		// this.on(cc.Node.EventType.TOUCH_CANCEL, (event: cc.EventTouch) => | ||||
| 		// { | ||||
| 		// 	if (this.slideState == 2) | ||||
| 		// 	{ | ||||
| 		// 		event.propagationStopped = true; | ||||
| 		// 		if (this.slidePage) | ||||
| 		// 		{ | ||||
| 		// 			ui.defaultNextOutAction.clone(this.slidePage).start(); | ||||
| 		// 			this.slideShadow && ui.defaultNextOutAction.clone(this.slideShadow).start(); | ||||
| 		// 			this.slidePage = undefined; | ||||
| 		// 		} | ||||
| 		// 	} | ||||
| 		// 	this.slideState = 0; | ||||
| 		// }, this, true); | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										9
									
								
								cx3-demo/assets/cx/core/cx.ui.ts.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								cx3-demo/assets/cx/core/cx.ui.ts.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "4.0.22", | ||||
|   "importer": "typescript", | ||||
|   "imported": true, | ||||
|   "uuid": "65f94526-5d8d-4385-a552-f58a5c951f3f", | ||||
|   "files": [], | ||||
|   "subMetas": {}, | ||||
|   "userData": {} | ||||
| } | ||||
							
								
								
									
										270
									
								
								cx3-demo/assets/cx/core/cx.utils.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										270
									
								
								cx3-demo/assets/cx/core/cx.utils.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,270 @@ | ||||
|  | ||||
| export default  | ||||
| { | ||||
| 	//在str前补充0,补充至长度len | ||||
| 	prefix: function(str: string | number, len?: number): string | ||||
| 	{ | ||||
| 		if (len == undefined) | ||||
| 			len = 2; | ||||
| 		var ret = str + ''; | ||||
| 		while (ret.length < len) | ||||
| 			ret = "0" + ret; | ||||
| 		return ret; | ||||
| 	}, | ||||
|  | ||||
| 	formatTime: function(time: Date, format?: string): string | ||||
| 	{ | ||||
| 		var s = (format || "%Y-%m-%d %X").replace("%Y", time.getFullYear()+""); | ||||
| 		s = s.replace("%m", this.prefix(time.getMonth()+1)); | ||||
| 		s = s.replace("%d", this.prefix(time.getDate())); | ||||
| 		s = s.replace("%X", this.prefix(time.getHours())+":"+this.prefix(time.getMinutes())+":"+this.prefix(time.getSeconds())); | ||||
| 		s = s.replace("%x", this.prefix(time.getHours())+""+this.prefix(time.getMinutes())+""+this.prefix(time.getSeconds())); | ||||
| 		return s; | ||||
| 	}, | ||||
|  | ||||
|     getCurrSecond(ms?:boolean): number | ||||
| 	{ | ||||
| 		return Math.floor(new Date().getTime()*(ms ? 1 : 0.001)); | ||||
| 	}, | ||||
|  | ||||
| 	strToSecond: function(stime: string): number | ||||
| 	{ | ||||
| 		return Date.parse(stime.replace(/[^0-9: ]/mg, '/')).valueOf()*0.001; | ||||
| 	}, | ||||
| 	secondToStr: function(second: number, format?: string): string | ||||
| 	{ | ||||
| 		var date = new Date(); | ||||
| 		date.setTime(second * 1000); | ||||
| 		return this.formatTime(date, format); | ||||
| 	}, | ||||
| 	getCurrDate: function(format?: string): string | ||||
| 	{ | ||||
| 		return this.formatTime(new Date(), format || "%Y-%m-%d"); | ||||
| 	}, | ||||
| 	getCurrTime: function(format?: string): string | ||||
| 	{ | ||||
| 		return this.formatTime(new Date(), format); | ||||
| 	}, | ||||
| 	getDiffDate: function(diff: number, format?: string): string | ||||
| 	{ | ||||
| 		return this.secondToStr(this.getCurrSecond() + diff, format || "%Y-%m-%d"); | ||||
| 	}, | ||||
| 	getDiffTime: function(diff: number, format?: string): string | ||||
| 	{ | ||||
| 		return this.secondToStr(this.getCurrSecond() + diff, format); | ||||
| 	}, | ||||
|  | ||||
| 	//对象相关 | ||||
| 	getObject: function(arr: any[], key: string, value: any): any | ||||
| 	{ | ||||
| 		for (var i in arr) | ||||
| 		{ | ||||
| 			var same = true; | ||||
| 			for (var j=1; j<arguments.length-1; j+=2) | ||||
| 				if (arr[i][arguments[j]] != arguments[j+1]) | ||||
| 				{ | ||||
| 					same = false; | ||||
| 					break; | ||||
| 				} | ||||
| 			if (same) | ||||
| 				return arr[i]; | ||||
| 		} | ||||
| 		return null; | ||||
| 	}, | ||||
|  | ||||
| 	getObjects: function(arr: any[]): any[] | ||||
| 	{ | ||||
| 		var data = [], same; | ||||
| 		for (var i in arr) | ||||
| 		{ | ||||
| 			same = true; | ||||
| 			for (var j=1; j<arguments.length-1; j+=2) | ||||
| 				if (arr[i][arguments[j]] != arguments[j+1]) | ||||
| 				{ | ||||
| 					same = false; | ||||
| 					break; | ||||
| 				} | ||||
| 			if (same) | ||||
| 				data.push(arr[i]); | ||||
| 		} | ||||
| 		return data; | ||||
| 	}, | ||||
| 	getObjectIndex: function(arr: any[]): number | ||||
| 	{ | ||||
| 		for (var i in arr) | ||||
| 		{ | ||||
| 			var same = true; | ||||
| 			for (var j=1; j<arguments.length-1; j+=2) | ||||
| 				if (arr[i][arguments[j]] != arguments[j+1]) | ||||
| 				{ | ||||
| 					same = false; | ||||
| 					break; | ||||
| 				} | ||||
| 			if (same) | ||||
| 				return +i; | ||||
| 		} | ||||
| 		return -1; | ||||
| 	}, | ||||
| 	getObjectValues: function(obj: any): any | ||||
| 	{ | ||||
| 		var s = ""; | ||||
| 		for (var i in obj) | ||||
| 			if (i.charAt(0) != "$") | ||||
| 				s += "," + obj[i]; | ||||
| 		return s && s.substr(1); | ||||
| 	}, | ||||
|  | ||||
| 	copyObject: function(obj: any): any | ||||
| 	{ | ||||
| 		var ret: any; | ||||
| 		if (Array.isArray(obj)) | ||||
| 		{ | ||||
| 			ret = []; | ||||
| 			for (var i in obj) | ||||
| 				ret.push(this.copyObject(obj[i])); | ||||
| 		} | ||||
| 		else if (typeof obj == "object") | ||||
| 		{ | ||||
| 			ret = {}; | ||||
| 			for (var i in obj) | ||||
| 				ret[i] = this.copyObject(obj[i]); | ||||
| 		} | ||||
| 		else  | ||||
| 			ret = obj; | ||||
| 		return ret; | ||||
| 	}, | ||||
| 	updateObject: function(obj: any, newObj: any) | ||||
| 	{ | ||||
| 		if (newObj) | ||||
| 			for (var i in obj) | ||||
| 				if (newObj[i] != undefined) | ||||
| 					obj[i] = newObj[i]; | ||||
| 	}, | ||||
| 	extendObject: function(obj: any, newObj: any, ignoreExist?: boolean) | ||||
| 	{ | ||||
| 		for (var i in newObj) | ||||
| 			if (!ignoreExist || ignoreExist && obj[i] != undefined) | ||||
| 				obj[i] = newObj[i]; | ||||
| 	}, | ||||
| 	updateObjectValue: function(arr: any[], key: string, newValue: any) | ||||
| 	{ | ||||
| 		for (var i in arr) | ||||
| 			arr[i][key] = newValue; | ||||
| 	}, | ||||
| 	dict2Object: function(dictList: any[]): any | ||||
| 	{ | ||||
| 		var o, obj: any = {}; | ||||
| 		for (var i in dictList) | ||||
| 		{ | ||||
| 			o = dictList[i]; | ||||
| 			obj[o.dict_field] = obj[o.dict_field] || {obj:{}, list:[]}; | ||||
| 			obj[o.dict_field].obj[o.dict_code+""] = o.dict_value; | ||||
| 			obj[o.dict_field].list.push({id:o.dict_code, name:o.dict_value}); | ||||
| 		} | ||||
| 		return obj; | ||||
| 	}, | ||||
|  | ||||
| 	//数据类型相关 | ||||
| 	isInteger: function(num: string, min?: number | undefined, max?: number | undefined): boolean | ||||
| 	{ | ||||
| 		if (min == undefined) | ||||
| 			min = -2147483648; | ||||
| 		if (max == undefined) | ||||
| 			max = 2147483647; | ||||
| 		var exp = /^-?\d+$/; | ||||
| 		return exp.test(num) && (min == undefined || +num>=min) && (max == undefined || +num<max); | ||||
| 	}, | ||||
| 	isNumber: function(num: string, min?: number | undefined, max?: number | undefined): boolean | ||||
| 	{ | ||||
| 		var exp = /^(([1-9]\d*)|\d)(\.\d{1,6})?$/; | ||||
| 		return exp.test(num) && (min == undefined || +num>=min) && (max == undefined || +num<max); | ||||
| 	}, | ||||
| 	isNumber2: function(num: string, min?: number | undefined, max?: number | undefined): boolean | ||||
| 	{ | ||||
| 		var exp = /^(([0-9]\d*)|\d)(\.\d{1,6})?$/; | ||||
| 		return exp.test(num) && (min == undefined || +num>=min) && (max == undefined || +num<max); | ||||
| 	}, | ||||
| 	isCurrency: function(num: string, min?: number | undefined, max?: number | undefined): boolean | ||||
| 	{ | ||||
| 		var exp = /^(([1-9]\d*)|\d)(\.\d{1,2})?$/; | ||||
| 		return exp.test(num) && (min == undefined || +num>=min) && (max == undefined || +num<max); | ||||
| 	}, | ||||
| 	isCurrency4: function(num: string, min?: number | undefined, max?: number | undefined): boolean | ||||
| 	{ | ||||
| 		var exp = /^(([1-9]\d*)|\d)(\.\d{1,4})?$/; | ||||
| 		return exp.test(num) && (min == undefined || +num>=min) && (max == undefined || +num<max); | ||||
| 	}, | ||||
| 	isIdCard:function(value: string): boolean | ||||
| 	{ | ||||
| 		if (value.length != 18) | ||||
| 			return false; | ||||
| 		var IDCARD_18 = /^\d{17}[0-9|x|X]$/; | ||||
| 		if (!value.match(IDCARD_18)) | ||||
| 			return false; | ||||
| 		if (+value.substr(6,4)<1900 || +value.substr(6,4)>2100 || | ||||
| 			+value.substr(10,2)>12 || +value.substr(10,2)<1 || | ||||
| 			+value.substr(12,2)>31 || +value.substr(12,2)<1) | ||||
| 			return false; | ||||
| 		var Wi = new Array(7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2,1); | ||||
| 		var Ai = new Array('1','0','X','9','8','7','6','5','4','3','2'); | ||||
| 		if (value.charAt(17) == 'x') | ||||
| 			value = value.replace("x","X"); | ||||
| 		var strSum = 0; | ||||
| 		for (var i=0; i<value.length-1; i++) | ||||
| 			strSum = strSum + +value.charAt(i)*Wi[i]; | ||||
| 		return value.charAt(17) == Ai[strSum%11]; | ||||
| 	}, | ||||
|  | ||||
| 	//字符函数 | ||||
| 	formatFloat: function(value: number): number | ||||
| 	{ | ||||
| 		return Math.round(value*100)/100; | ||||
| 	}, | ||||
| 	encode: function(content: string, key?: string): string | ||||
| 	{ | ||||
| 		return cx.os.native ? cx.native.ins("cx").call("encode", [content, key || ""]) : content; | ||||
| 	}, | ||||
| 	decode: function(content: string, key?: string): string | ||||
| 	{ | ||||
| 		return cx.os.native ? cx.native.ins("cx").call("decode", [content, key || ""]) : content; | ||||
| 	}, | ||||
| 	md5: function(content: string, key?: string): string | ||||
| 	{ | ||||
| 		return cx.os.native ? cx.native.ins("cx").call("md5", [content, key || ""]) : content; | ||||
| 	}, | ||||
| 	randomRange: function(min: number, max: number): number | ||||
| 	{ | ||||
| 		if (min >= max) | ||||
| 			return min; | ||||
| 		return Math.floor(Math.random() * (max - min + 1)) + min; | ||||
| 	}, | ||||
| 	randomArray: function(arr: any[]) | ||||
| 	{ | ||||
| 		var len = arr.length; | ||||
| 		for (var i=0; i<arr.length; i++) | ||||
| 		{ | ||||
| 			var r = this.randomRange(0, len-1); | ||||
| 			var t = arr[i]; | ||||
| 			arr[i] = arr[r]; | ||||
| 			arr[r] = t; | ||||
| 		} | ||||
| 		return arr; | ||||
| 	}, | ||||
| 	//删除str中的指定字符 | ||||
| 	strDelete: function(str: string | undefined, c?: string): string | ||||
| 	{ | ||||
| 		if (!str) | ||||
| 			return ""; | ||||
| 		c = c ? c : '"'; | ||||
| 		while (str.indexOf(c) >= 0) | ||||
| 			str = str.replace(c, ""); | ||||
| 		return str; | ||||
| 	}, | ||||
| 	//按len长度截断str,之后显示为... | ||||
| 	strTruncate: function(str: string | undefined, len: number): string | ||||
| 	{ | ||||
| 		if (!str || str.length <= len) | ||||
| 			return str || ""; | ||||
| 		return str.substr(0, len-1) + "..."; | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										9
									
								
								cx3-demo/assets/cx/core/cx.utils.ts.meta
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								cx3-demo/assets/cx/core/cx.utils.ts.meta
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| { | ||||
|   "ver": "4.0.22", | ||||
|   "importer": "typescript", | ||||
|   "imported": true, | ||||
|   "uuid": "55c7bd0f-7a87-4083-bc6c-5b37f6f384f9", | ||||
|   "files": [], | ||||
|   "subMetas": {}, | ||||
|   "userData": {} | ||||
| } | ||||
		Reference in New Issue
	
	Block a user