js:add lib and .d.ts
This commit is contained in:
127
doric-js/lib/src/ui/animation.d.ts
vendored
Normal file
127
doric-js/lib/src/ui/animation.d.ts
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
import { Modeling, Model } from "../util/types";
|
||||
export declare type AnimatedKey = "translationX" | "translationY" | "scaleX" | "scaleY" | "rotation" | "pivotX" | "pivotY";
|
||||
export declare enum RepeatMode {
|
||||
RESTART = 1,
|
||||
REVERSE = 2
|
||||
}
|
||||
export interface IAnimation extends Modeling {
|
||||
duration: number;
|
||||
delay?: number;
|
||||
}
|
||||
export interface Changeable {
|
||||
fromValue: number;
|
||||
toValue: number;
|
||||
key: AnimatedKey;
|
||||
repeatCount?: number;
|
||||
repeatMode?: RepeatMode;
|
||||
}
|
||||
export declare enum FillMode {
|
||||
/**
|
||||
* The receiver is removed from the presentation when the animation is completed.
|
||||
*/
|
||||
Removed = 0,
|
||||
/**
|
||||
* The receiver remains visible in its final state when the animation is completed.
|
||||
*/
|
||||
Forward = 1,
|
||||
/**
|
||||
* The receiver clamps values before zero to zero when the animation is completed.
|
||||
*/
|
||||
Backward = 2,
|
||||
/**
|
||||
* The receiver clamps values at both ends of the object’s time space
|
||||
*/
|
||||
Both = 3
|
||||
}
|
||||
export declare enum TimingFunction {
|
||||
/**
|
||||
* The system default timing function. Use this function to ensure that the timing of your animations matches that of most system animations.
|
||||
*/
|
||||
Default = 0,
|
||||
/**
|
||||
* Linear pacing, which causes an animation to occur evenly over its duration.
|
||||
*/
|
||||
Linear = 1,
|
||||
/**
|
||||
* Ease-in pacing, which causes an animation to begin slowly and then speed up as it progresses.
|
||||
*/
|
||||
EaseIn = 2,
|
||||
/**
|
||||
* Ease-out pacing, which causes an animation to begin quickly and then slow as it progresses.
|
||||
*/
|
||||
EaseOut = 3,
|
||||
/**
|
||||
* Ease-in-ease-out pacing, which causes an animation to begin slowly, accelerate through the middle of its duration, and then slow again before completing.
|
||||
*/
|
||||
EaseInEaseOut = 4
|
||||
}
|
||||
declare abstract class Animation implements IAnimation {
|
||||
changeables: Map<AnimatedKey, Changeable>;
|
||||
duration: number;
|
||||
repeatCount?: number;
|
||||
repeatMode?: RepeatMode;
|
||||
delay?: number;
|
||||
fillMode: FillMode;
|
||||
timingFunction?: TimingFunction;
|
||||
toModel(): {
|
||||
type: string;
|
||||
delay: number | undefined;
|
||||
duration: number;
|
||||
changeables: {
|
||||
key: AnimatedKey;
|
||||
fromValue: number;
|
||||
toValue: number;
|
||||
}[];
|
||||
repeatCount: number | undefined;
|
||||
repeatMode: RepeatMode | undefined;
|
||||
fillMode: FillMode;
|
||||
timingFunction: TimingFunction | undefined;
|
||||
};
|
||||
}
|
||||
export declare class ScaleAnimation extends Animation {
|
||||
private scaleXChangeable;
|
||||
private scaleYChangeable;
|
||||
constructor();
|
||||
set fromScaleX(v: number);
|
||||
get fromScaleX(): number;
|
||||
set toScaleX(v: number);
|
||||
get toScaleX(): number;
|
||||
set fromScaleY(v: number);
|
||||
get fromScaleY(): number;
|
||||
set toScaleY(v: number);
|
||||
get toScaleY(): number;
|
||||
}
|
||||
export declare class TranslationAnimation extends Animation {
|
||||
private translationXChangeable;
|
||||
private translationYChangeable;
|
||||
constructor();
|
||||
set fromTranslationX(v: number);
|
||||
get fromTranslationX(): number;
|
||||
set toTranslationX(v: number);
|
||||
get toTranslationX(): number;
|
||||
set fromTranslationY(v: number);
|
||||
get fromTranslationY(): number;
|
||||
set toTranslationY(v: number);
|
||||
get toTranslationY(): number;
|
||||
}
|
||||
export declare class RotationAnimation extends Animation {
|
||||
private rotationChaneable;
|
||||
constructor();
|
||||
set fromRotation(v: number);
|
||||
get fromRotation(): number;
|
||||
set toRotation(v: number);
|
||||
get toRotation(): number;
|
||||
}
|
||||
export declare class AnimationSet implements IAnimation {
|
||||
private animations;
|
||||
_duration: number;
|
||||
delay?: number;
|
||||
addAnimation(anim: IAnimation): void;
|
||||
get duration(): number;
|
||||
set duration(v: number);
|
||||
toModel(): {
|
||||
animations: Model;
|
||||
delay: number | undefined;
|
||||
};
|
||||
}
|
||||
export {};
|
||||
218
doric-js/lib/src/ui/animation.js
Normal file
218
doric-js/lib/src/ui/animation.js
Normal file
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright [2019] [Doric.Pub]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export var RepeatMode;
|
||||
(function (RepeatMode) {
|
||||
RepeatMode[RepeatMode["RESTART"] = 1] = "RESTART";
|
||||
RepeatMode[RepeatMode["REVERSE"] = 2] = "REVERSE";
|
||||
})(RepeatMode || (RepeatMode = {}));
|
||||
export var FillMode;
|
||||
(function (FillMode) {
|
||||
/**
|
||||
* The receiver is removed from the presentation when the animation is completed.
|
||||
*/
|
||||
FillMode[FillMode["Removed"] = 0] = "Removed";
|
||||
/**
|
||||
* The receiver remains visible in its final state when the animation is completed.
|
||||
*/
|
||||
FillMode[FillMode["Forward"] = 1] = "Forward";
|
||||
/**
|
||||
* The receiver clamps values before zero to zero when the animation is completed.
|
||||
*/
|
||||
FillMode[FillMode["Backward"] = 2] = "Backward";
|
||||
/**
|
||||
* The receiver clamps values at both ends of the object’s time space
|
||||
*/
|
||||
FillMode[FillMode["Both"] = 3] = "Both";
|
||||
})(FillMode || (FillMode = {}));
|
||||
export var TimingFunction;
|
||||
(function (TimingFunction) {
|
||||
/**
|
||||
* The system default timing function. Use this function to ensure that the timing of your animations matches that of most system animations.
|
||||
*/
|
||||
TimingFunction[TimingFunction["Default"] = 0] = "Default";
|
||||
/**
|
||||
* Linear pacing, which causes an animation to occur evenly over its duration.
|
||||
*/
|
||||
TimingFunction[TimingFunction["Linear"] = 1] = "Linear";
|
||||
/**
|
||||
* Ease-in pacing, which causes an animation to begin slowly and then speed up as it progresses.
|
||||
*/
|
||||
TimingFunction[TimingFunction["EaseIn"] = 2] = "EaseIn";
|
||||
/**
|
||||
* Ease-out pacing, which causes an animation to begin quickly and then slow as it progresses.
|
||||
*/
|
||||
TimingFunction[TimingFunction["EaseOut"] = 3] = "EaseOut";
|
||||
/**
|
||||
* Ease-in-ease-out pacing, which causes an animation to begin slowly, accelerate through the middle of its duration, and then slow again before completing.
|
||||
*/
|
||||
TimingFunction[TimingFunction["EaseInEaseOut"] = 4] = "EaseInEaseOut";
|
||||
})(TimingFunction || (TimingFunction = {}));
|
||||
class Animation {
|
||||
constructor() {
|
||||
this.changeables = new Map;
|
||||
this.duration = 0;
|
||||
this.fillMode = FillMode.Forward;
|
||||
}
|
||||
toModel() {
|
||||
const changeables = [];
|
||||
for (let e of this.changeables.values()) {
|
||||
changeables.push({
|
||||
key: e.key,
|
||||
fromValue: e.fromValue,
|
||||
toValue: e.toValue,
|
||||
});
|
||||
}
|
||||
return {
|
||||
type: this.constructor.name,
|
||||
delay: this.delay,
|
||||
duration: this.duration,
|
||||
changeables,
|
||||
repeatCount: this.repeatCount,
|
||||
repeatMode: this.repeatMode,
|
||||
fillMode: this.fillMode,
|
||||
timingFunction: this.timingFunction
|
||||
};
|
||||
}
|
||||
}
|
||||
export class ScaleAnimation extends Animation {
|
||||
constructor() {
|
||||
super();
|
||||
this.scaleXChangeable = {
|
||||
key: "scaleX",
|
||||
fromValue: 1,
|
||||
toValue: 1,
|
||||
};
|
||||
this.scaleYChangeable = {
|
||||
key: "scaleY",
|
||||
fromValue: 1,
|
||||
toValue: 1,
|
||||
};
|
||||
this.changeables.set("scaleX", this.scaleXChangeable);
|
||||
this.changeables.set("scaleY", this.scaleYChangeable);
|
||||
}
|
||||
set fromScaleX(v) {
|
||||
this.scaleXChangeable.fromValue = v;
|
||||
}
|
||||
get fromScaleX() {
|
||||
return this.scaleXChangeable.fromValue;
|
||||
}
|
||||
set toScaleX(v) {
|
||||
this.scaleXChangeable.toValue = v;
|
||||
}
|
||||
get toScaleX() {
|
||||
return this.scaleXChangeable.toValue;
|
||||
}
|
||||
set fromScaleY(v) {
|
||||
this.scaleYChangeable.fromValue = v;
|
||||
}
|
||||
get fromScaleY() {
|
||||
return this.scaleYChangeable.fromValue;
|
||||
}
|
||||
set toScaleY(v) {
|
||||
this.scaleYChangeable.toValue = v;
|
||||
}
|
||||
get toScaleY() {
|
||||
return this.scaleYChangeable.toValue;
|
||||
}
|
||||
}
|
||||
export class TranslationAnimation extends Animation {
|
||||
constructor() {
|
||||
super();
|
||||
this.translationXChangeable = {
|
||||
key: "translationX",
|
||||
fromValue: 1,
|
||||
toValue: 1,
|
||||
};
|
||||
this.translationYChangeable = {
|
||||
key: "translationY",
|
||||
fromValue: 1,
|
||||
toValue: 1,
|
||||
};
|
||||
this.changeables.set("translationX", this.translationXChangeable);
|
||||
this.changeables.set("translationY", this.translationYChangeable);
|
||||
}
|
||||
set fromTranslationX(v) {
|
||||
this.translationXChangeable.fromValue = v;
|
||||
}
|
||||
get fromTranslationX() {
|
||||
return this.translationXChangeable.fromValue;
|
||||
}
|
||||
set toTranslationX(v) {
|
||||
this.translationXChangeable.toValue = v;
|
||||
}
|
||||
get toTranslationX() {
|
||||
return this.translationXChangeable.toValue;
|
||||
}
|
||||
set fromTranslationY(v) {
|
||||
this.translationYChangeable.fromValue = v;
|
||||
}
|
||||
get fromTranslationY() {
|
||||
return this.translationYChangeable.fromValue;
|
||||
}
|
||||
set toTranslationY(v) {
|
||||
this.translationYChangeable.toValue = v;
|
||||
}
|
||||
get toTranslationY() {
|
||||
return this.translationYChangeable.toValue;
|
||||
}
|
||||
}
|
||||
export class RotationAnimation extends Animation {
|
||||
constructor() {
|
||||
super();
|
||||
this.rotationChaneable = {
|
||||
key: "rotation",
|
||||
fromValue: 1,
|
||||
toValue: 1,
|
||||
};
|
||||
this.changeables.set("rotation", this.rotationChaneable);
|
||||
}
|
||||
set fromRotation(v) {
|
||||
this.rotationChaneable.fromValue = v;
|
||||
}
|
||||
get fromRotation() {
|
||||
return this.rotationChaneable.fromValue;
|
||||
}
|
||||
set toRotation(v) {
|
||||
this.rotationChaneable.toValue = v;
|
||||
}
|
||||
get toRotation() {
|
||||
return this.rotationChaneable.toValue;
|
||||
}
|
||||
}
|
||||
export class AnimationSet {
|
||||
constructor() {
|
||||
this.animations = [];
|
||||
this._duration = 0;
|
||||
}
|
||||
addAnimation(anim) {
|
||||
this.animations.push(anim);
|
||||
}
|
||||
get duration() {
|
||||
return this._duration;
|
||||
}
|
||||
set duration(v) {
|
||||
this._duration = v;
|
||||
this.animations.forEach(e => e.duration = v);
|
||||
}
|
||||
toModel() {
|
||||
return {
|
||||
animations: this.animations.map(e => {
|
||||
return e.toModel();
|
||||
}),
|
||||
delay: this.delay,
|
||||
};
|
||||
}
|
||||
}
|
||||
3
doric-js/lib/src/ui/index.ui.d.ts
vendored
Normal file
3
doric-js/lib/src/ui/index.ui.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
export * from './view';
|
||||
export * from './panel';
|
||||
export * from './animation';
|
||||
18
doric-js/lib/src/ui/index.ui.js
Normal file
18
doric-js/lib/src/ui/index.ui.js
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright [2019] [Doric.Pub]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export * from './view';
|
||||
export * from './panel';
|
||||
export * from './animation';
|
||||
32
doric-js/lib/src/ui/panel.d.ts
vendored
Normal file
32
doric-js/lib/src/ui/panel.d.ts
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
import { View, Group } from "./view";
|
||||
import { Root } from '../widget/layouts';
|
||||
import { BridgeContext } from '../runtime/global';
|
||||
export declare function NativeCall(target: Panel, propertyKey: string, descriptor: PropertyDescriptor): PropertyDescriptor;
|
||||
export declare abstract class Panel {
|
||||
context: BridgeContext;
|
||||
onCreate(): void;
|
||||
onDestroy(): void;
|
||||
onShow(): void;
|
||||
onHidden(): void;
|
||||
abstract build(rootView: Group): void;
|
||||
private __data__?;
|
||||
private __root__;
|
||||
private headviews;
|
||||
addHeadView(v: View): void;
|
||||
allHeadViews(): IterableIterator<View>;
|
||||
removeHeadView(v: View | string): void;
|
||||
clearHeadViews(): void;
|
||||
getRootView(): Root;
|
||||
getInitData(): object | undefined;
|
||||
private __init__;
|
||||
private __onCreate__;
|
||||
private __onDestroy__;
|
||||
private __onShow__;
|
||||
private __onHidden__;
|
||||
private __build__;
|
||||
private __response__;
|
||||
private retrospectView;
|
||||
private nativeRender;
|
||||
private hookBeforeNativeCall;
|
||||
private hookAfterNativeCall;
|
||||
}
|
||||
206
doric-js/lib/src/ui/panel.js
Normal file
206
doric-js/lib/src/ui/panel.js
Normal file
@@ -0,0 +1,206 @@
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
/*
|
||||
* Copyright [2019] [Doric.Pub]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { View } from "./view";
|
||||
import { loge } from '../util/log';
|
||||
import { Root } from '../widget/layouts';
|
||||
export function NativeCall(target, propertyKey, descriptor) {
|
||||
const originVal = descriptor.value;
|
||||
descriptor.value = function () {
|
||||
const ret = Reflect.apply(originVal, this, arguments);
|
||||
return ret;
|
||||
};
|
||||
return descriptor;
|
||||
}
|
||||
export class Panel {
|
||||
constructor() {
|
||||
this.__root__ = new Root;
|
||||
this.headviews = new Map;
|
||||
}
|
||||
onCreate() { }
|
||||
onDestroy() { }
|
||||
onShow() { }
|
||||
onHidden() { }
|
||||
addHeadView(v) {
|
||||
this.headviews.set(v.viewId, v);
|
||||
}
|
||||
allHeadViews() {
|
||||
return this.headviews.values();
|
||||
}
|
||||
removeHeadView(v) {
|
||||
if (v instanceof View) {
|
||||
this.headviews.delete(v.viewId);
|
||||
}
|
||||
else {
|
||||
this.headviews.delete(v);
|
||||
}
|
||||
}
|
||||
clearHeadViews() {
|
||||
this.headviews.clear();
|
||||
}
|
||||
getRootView() {
|
||||
return this.__root__;
|
||||
}
|
||||
getInitData() {
|
||||
return this.__data__;
|
||||
}
|
||||
__init__(frame, data) {
|
||||
if (data) {
|
||||
this.__data__ = JSON.parse(data);
|
||||
}
|
||||
this.__root__.width = frame.width;
|
||||
this.__root__.height = frame.height;
|
||||
this.__root__.children.length = 0;
|
||||
this.build(this.__root__);
|
||||
}
|
||||
__onCreate__() {
|
||||
this.onCreate();
|
||||
}
|
||||
__onDestroy__() {
|
||||
this.onDestroy();
|
||||
}
|
||||
__onShow__() {
|
||||
this.onShow();
|
||||
}
|
||||
__onHidden__() {
|
||||
this.onHidden();
|
||||
}
|
||||
__build__() {
|
||||
this.build(this.__root__);
|
||||
}
|
||||
__response__(viewIds, callbackId) {
|
||||
const v = this.retrospectView(viewIds);
|
||||
if (v === undefined) {
|
||||
loge(`Cannot find view for ${viewIds}`);
|
||||
}
|
||||
else {
|
||||
const argumentsList = [callbackId];
|
||||
for (let i = 2; i < arguments.length; i++) {
|
||||
argumentsList.push(arguments[i]);
|
||||
}
|
||||
return Reflect.apply(v.responseCallback, v, argumentsList);
|
||||
}
|
||||
}
|
||||
retrospectView(ids) {
|
||||
return ids.reduce((acc, cur) => {
|
||||
if (acc === undefined) {
|
||||
if (cur === this.__root__.viewId) {
|
||||
return this.__root__;
|
||||
}
|
||||
return this.headviews.get(cur);
|
||||
}
|
||||
else {
|
||||
if (Reflect.has(acc, "subviewById")) {
|
||||
return Reflect.apply(Reflect.get(acc, "subviewById"), acc, [cur]);
|
||||
}
|
||||
return acc;
|
||||
}
|
||||
}, undefined);
|
||||
}
|
||||
nativeRender(model) {
|
||||
this.context.shader.render(model);
|
||||
}
|
||||
hookBeforeNativeCall() {
|
||||
if (Environment.platform !== 'h5') {
|
||||
this.__root__.clean();
|
||||
for (let v of this.headviews.values()) {
|
||||
v.clean();
|
||||
}
|
||||
}
|
||||
}
|
||||
hookAfterNativeCall() {
|
||||
if (Environment.platform !== 'h5') {
|
||||
//Here insert a native call to ensure the promise is resolved done.
|
||||
nativeEmpty();
|
||||
if (this.__root__.isDirty()) {
|
||||
const model = this.__root__.toModel();
|
||||
this.nativeRender(model);
|
||||
}
|
||||
for (let v of this.headviews.values()) {
|
||||
if (v.isDirty()) {
|
||||
const model = v.toModel();
|
||||
this.nativeRender(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
Promise.resolve().then(() => {
|
||||
if (this.__root__.isDirty()) {
|
||||
const model = this.__root__.toModel();
|
||||
this.nativeRender(model);
|
||||
this.__root__.clean();
|
||||
}
|
||||
for (let v of this.headviews.values()) {
|
||||
if (v.isDirty()) {
|
||||
const model = v.toModel();
|
||||
this.nativeRender(model);
|
||||
v.clean();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
__decorate([
|
||||
NativeCall,
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Object, String]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], Panel.prototype, "__init__", null);
|
||||
__decorate([
|
||||
NativeCall,
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", []),
|
||||
__metadata("design:returntype", void 0)
|
||||
], Panel.prototype, "__onCreate__", null);
|
||||
__decorate([
|
||||
NativeCall,
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", []),
|
||||
__metadata("design:returntype", void 0)
|
||||
], Panel.prototype, "__onDestroy__", null);
|
||||
__decorate([
|
||||
NativeCall,
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", []),
|
||||
__metadata("design:returntype", void 0)
|
||||
], Panel.prototype, "__onShow__", null);
|
||||
__decorate([
|
||||
NativeCall,
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", []),
|
||||
__metadata("design:returntype", void 0)
|
||||
], Panel.prototype, "__onHidden__", null);
|
||||
__decorate([
|
||||
NativeCall,
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", []),
|
||||
__metadata("design:returntype", void 0)
|
||||
], Panel.prototype, "__build__", null);
|
||||
__decorate([
|
||||
NativeCall,
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [Array, String]),
|
||||
__metadata("design:returntype", void 0)
|
||||
], Panel.prototype, "__response__", null);
|
||||
174
doric-js/lib/src/ui/view.d.ts
vendored
Normal file
174
doric-js/lib/src/ui/view.d.ts
vendored
Normal file
@@ -0,0 +1,174 @@
|
||||
import { Color, GradientColor } from "../util/color";
|
||||
import { Modeling, Model } from "../util/types";
|
||||
import { BridgeContext } from "../runtime/global";
|
||||
import { LayoutConfig } from '../util/layoutconfig';
|
||||
import { IAnimation } from "./animation";
|
||||
export declare function Property(target: Object, propKey: string): void;
|
||||
export interface IView {
|
||||
width?: number;
|
||||
height?: number;
|
||||
backgroundColor?: Color | GradientColor;
|
||||
corners?: number | {
|
||||
leftTop?: number;
|
||||
rightTop?: number;
|
||||
leftBottom?: number;
|
||||
rightBottom?: number;
|
||||
};
|
||||
border?: {
|
||||
width: number;
|
||||
color: Color;
|
||||
};
|
||||
shadow?: {
|
||||
color: Color;
|
||||
opacity: number;
|
||||
radius: number;
|
||||
offsetX: number;
|
||||
offsetY: number;
|
||||
};
|
||||
/**
|
||||
* float [0,..1]
|
||||
*/
|
||||
alpha?: number;
|
||||
hidden?: boolean;
|
||||
padding?: {
|
||||
left?: number;
|
||||
right?: number;
|
||||
top?: number;
|
||||
bottom?: number;
|
||||
};
|
||||
layoutConfig?: LayoutConfig;
|
||||
onClick?: Function;
|
||||
identifier?: string;
|
||||
/**++++++++++transform++++++++++*/
|
||||
translationX?: number;
|
||||
translationY?: number;
|
||||
scaleX?: number;
|
||||
scaleY?: number;
|
||||
/**
|
||||
* float [0,..1]
|
||||
*/
|
||||
pivotX?: number;
|
||||
/**
|
||||
* float [0,..1]
|
||||
*/
|
||||
pivotY?: number;
|
||||
/**
|
||||
* rotation*PI
|
||||
*/
|
||||
rotation?: number;
|
||||
}
|
||||
export declare abstract class View implements Modeling, IView {
|
||||
width: number;
|
||||
height: number;
|
||||
x: number;
|
||||
y: number;
|
||||
backgroundColor?: Color | GradientColor;
|
||||
corners?: number | {
|
||||
leftTop?: number;
|
||||
rightTop?: number;
|
||||
leftBottom?: number;
|
||||
rightBottom?: number;
|
||||
};
|
||||
border?: {
|
||||
width: number;
|
||||
color: Color;
|
||||
};
|
||||
shadow?: {
|
||||
color: Color;
|
||||
opacity: number;
|
||||
radius: number;
|
||||
offsetX: number;
|
||||
offsetY: number;
|
||||
};
|
||||
alpha?: number;
|
||||
hidden?: boolean;
|
||||
viewId: string;
|
||||
padding?: {
|
||||
left?: number;
|
||||
right?: number;
|
||||
top?: number;
|
||||
bottom?: number;
|
||||
};
|
||||
layoutConfig?: LayoutConfig;
|
||||
onClick?: Function;
|
||||
superview?: Superview;
|
||||
callbacks: Map<String, Function>;
|
||||
private callback2Id;
|
||||
private id2Callback;
|
||||
constructor();
|
||||
/** Anchor start*/
|
||||
get left(): number;
|
||||
set left(v: number);
|
||||
get right(): number;
|
||||
set right(v: number);
|
||||
get top(): number;
|
||||
set top(v: number);
|
||||
get bottom(): number;
|
||||
set bottom(v: number);
|
||||
get centerX(): number;
|
||||
get centerY(): number;
|
||||
set centerX(v: number);
|
||||
set centerY(v: number);
|
||||
/** Anchor end*/
|
||||
private __dirty_props__;
|
||||
get dirtyProps(): {
|
||||
[index: string]: Model;
|
||||
};
|
||||
nativeViewModel: {
|
||||
id: string;
|
||||
type: string;
|
||||
props: {
|
||||
[index: string]: Model;
|
||||
};
|
||||
};
|
||||
onPropertyChanged(propKey: string, oldV: Model, newV: Model): void;
|
||||
clean(): void;
|
||||
isDirty(): boolean;
|
||||
responseCallback(id: string, ...args: any): any;
|
||||
toModel(): {
|
||||
id: string;
|
||||
type: string;
|
||||
props: {
|
||||
[index: string]: Model;
|
||||
};
|
||||
};
|
||||
let(block: (it: this) => void): void;
|
||||
also(block: (it: this) => void): this;
|
||||
apply(config: IView): this;
|
||||
in(group: Group): this;
|
||||
nativeChannel(context: any, name: string): (args?: any) => Promise<any>;
|
||||
getWidth(context: BridgeContext): Promise<number>;
|
||||
getHeight(context: BridgeContext): Promise<number>;
|
||||
getLocationOnScreen(context: BridgeContext): Promise<{
|
||||
x: number;
|
||||
y: number;
|
||||
}>;
|
||||
/**++++++++++transform++++++++++*/
|
||||
translationX?: number;
|
||||
translationY?: number;
|
||||
scaleX?: number;
|
||||
scaleY?: number;
|
||||
pivotX?: number;
|
||||
pivotY?: number;
|
||||
rotation?: number;
|
||||
/**----------transform----------*/
|
||||
doAnimation(context: BridgeContext, animation: IAnimation): Promise<void>;
|
||||
}
|
||||
export declare abstract class Superview extends View {
|
||||
subviewById(id: string): View | undefined;
|
||||
abstract allSubviews(): Iterable<View>;
|
||||
isDirty(): boolean;
|
||||
clean(): void;
|
||||
toModel(): {
|
||||
id: string;
|
||||
type: string;
|
||||
props: {
|
||||
[index: string]: Model;
|
||||
};
|
||||
};
|
||||
}
|
||||
export declare abstract class Group extends Superview {
|
||||
readonly children: View[];
|
||||
allSubviews(): View[];
|
||||
addChild(view: View): void;
|
||||
}
|
||||
328
doric-js/lib/src/ui/view.js
Normal file
328
doric-js/lib/src/ui/view.js
Normal file
@@ -0,0 +1,328 @@
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
import { obj2Model } from "../util/types";
|
||||
import { uniqueId } from "../util/uniqueId";
|
||||
import { loge } from "../util/log";
|
||||
export function Property(target, propKey) {
|
||||
Reflect.defineMetadata(propKey, true, target);
|
||||
}
|
||||
export class View {
|
||||
constructor() {
|
||||
this.width = 0;
|
||||
this.height = 0;
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
this.viewId = uniqueId('ViewId');
|
||||
this.callbacks = new Map;
|
||||
/** Anchor end*/
|
||||
this.__dirty_props__ = {};
|
||||
this.nativeViewModel = {
|
||||
id: this.viewId,
|
||||
type: this.constructor.name,
|
||||
props: this.__dirty_props__,
|
||||
};
|
||||
return new Proxy(this, {
|
||||
get: (target, p, receiver) => {
|
||||
return Reflect.get(target, p, receiver);
|
||||
},
|
||||
set: (target, p, v, receiver) => {
|
||||
const oldV = Reflect.get(target, p, receiver);
|
||||
const ret = Reflect.set(target, p, v, receiver);
|
||||
if (Reflect.getMetadata(p, target) && oldV !== v) {
|
||||
receiver.onPropertyChanged(p.toString(), oldV, v);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
});
|
||||
}
|
||||
callback2Id(f) {
|
||||
const id = uniqueId('Function');
|
||||
this.callbacks.set(id, f);
|
||||
return id;
|
||||
}
|
||||
id2Callback(id) {
|
||||
let f = this.callbacks.get(id);
|
||||
if (f === undefined) {
|
||||
f = Reflect.get(this, id);
|
||||
}
|
||||
return f;
|
||||
}
|
||||
/** Anchor start*/
|
||||
get left() {
|
||||
return this.x;
|
||||
}
|
||||
set left(v) {
|
||||
this.x = v;
|
||||
}
|
||||
get right() {
|
||||
return this.x + this.width;
|
||||
}
|
||||
set right(v) {
|
||||
this.x = v - this.width;
|
||||
}
|
||||
get top() {
|
||||
return this.y;
|
||||
}
|
||||
set top(v) {
|
||||
this.y = v;
|
||||
}
|
||||
get bottom() {
|
||||
return this.y + this.height;
|
||||
}
|
||||
set bottom(v) {
|
||||
this.y = v - this.height;
|
||||
}
|
||||
get centerX() {
|
||||
return this.x + this.width / 2;
|
||||
}
|
||||
get centerY() {
|
||||
return this.y + this.height / 2;
|
||||
}
|
||||
set centerX(v) {
|
||||
this.x = v - this.width / 2;
|
||||
}
|
||||
set centerY(v) {
|
||||
this.y = v - this.height / 2;
|
||||
}
|
||||
get dirtyProps() {
|
||||
return this.__dirty_props__;
|
||||
}
|
||||
onPropertyChanged(propKey, oldV, newV) {
|
||||
if (newV instanceof Function) {
|
||||
newV = this.callback2Id(newV);
|
||||
}
|
||||
else {
|
||||
newV = obj2Model(newV);
|
||||
}
|
||||
this.__dirty_props__[propKey] = newV;
|
||||
}
|
||||
clean() {
|
||||
for (const key in this.__dirty_props__) {
|
||||
if (Reflect.has(this.__dirty_props__, key)) {
|
||||
Reflect.deleteProperty(this.__dirty_props__, key);
|
||||
}
|
||||
}
|
||||
}
|
||||
isDirty() {
|
||||
return Reflect.ownKeys(this.__dirty_props__).length !== 0;
|
||||
}
|
||||
responseCallback(id, ...args) {
|
||||
const f = this.id2Callback(id);
|
||||
if (f instanceof Function) {
|
||||
const argumentsList = [];
|
||||
for (let i = 1; i < arguments.length; i++) {
|
||||
argumentsList.push(arguments[i]);
|
||||
}
|
||||
return Reflect.apply(f, this, argumentsList);
|
||||
}
|
||||
else {
|
||||
loge(`Cannot find callback:${id} for ${JSON.stringify(this.toModel())}`);
|
||||
}
|
||||
}
|
||||
toModel() {
|
||||
return this.nativeViewModel;
|
||||
}
|
||||
let(block) {
|
||||
block(this);
|
||||
}
|
||||
also(block) {
|
||||
block(this);
|
||||
return this;
|
||||
}
|
||||
apply(config) {
|
||||
for (let key in config) {
|
||||
Reflect.set(this, key, Reflect.get(config, key, config), this);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
in(group) {
|
||||
group.addChild(this);
|
||||
return this;
|
||||
}
|
||||
nativeChannel(context, name) {
|
||||
let thisView = this;
|
||||
return function (args = undefined) {
|
||||
const func = context.shader.command;
|
||||
const viewIds = [];
|
||||
while (thisView != undefined) {
|
||||
viewIds.push(thisView.viewId);
|
||||
thisView = thisView.superview;
|
||||
}
|
||||
const params = {
|
||||
viewIds: viewIds.reverse(),
|
||||
name,
|
||||
args,
|
||||
};
|
||||
return Reflect.apply(func, undefined, [params]);
|
||||
};
|
||||
}
|
||||
getWidth(context) {
|
||||
return this.nativeChannel(context, 'getWidth')();
|
||||
}
|
||||
getHeight(context) {
|
||||
return this.nativeChannel(context, 'getHeight')();
|
||||
}
|
||||
getLocationOnScreen(context) {
|
||||
return this.nativeChannel(context, "getLocationOnScreen")();
|
||||
}
|
||||
/**----------transform----------*/
|
||||
doAnimation(context, animation) {
|
||||
return this.nativeChannel(context, "doAnimation")(animation.toModel()).then((args) => {
|
||||
for (let key in args) {
|
||||
Reflect.set(this, key, Reflect.get(args, key, args), this);
|
||||
Reflect.deleteProperty(this.__dirty_props__, key);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Number)
|
||||
], View.prototype, "width", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Number)
|
||||
], View.prototype, "height", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Number)
|
||||
], View.prototype, "x", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Number)
|
||||
], View.prototype, "y", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Object)
|
||||
], View.prototype, "backgroundColor", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Object)
|
||||
], View.prototype, "corners", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Object)
|
||||
], View.prototype, "border", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Object)
|
||||
], View.prototype, "shadow", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Number)
|
||||
], View.prototype, "alpha", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Boolean)
|
||||
], View.prototype, "hidden", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Object)
|
||||
], View.prototype, "viewId", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Object)
|
||||
], View.prototype, "padding", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Object)
|
||||
], View.prototype, "layoutConfig", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Function)
|
||||
], View.prototype, "onClick", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Number)
|
||||
], View.prototype, "translationX", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Number)
|
||||
], View.prototype, "translationY", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Number)
|
||||
], View.prototype, "scaleX", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Number)
|
||||
], View.prototype, "scaleY", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Number)
|
||||
], View.prototype, "pivotX", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Number)
|
||||
], View.prototype, "pivotY", void 0);
|
||||
__decorate([
|
||||
Property,
|
||||
__metadata("design:type", Number)
|
||||
], View.prototype, "rotation", void 0);
|
||||
export class Superview extends View {
|
||||
subviewById(id) {
|
||||
for (let v of this.allSubviews()) {
|
||||
if (v.viewId === id) {
|
||||
return v;
|
||||
}
|
||||
}
|
||||
}
|
||||
isDirty() {
|
||||
if (super.isDirty()) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
for (const v of this.allSubviews()) {
|
||||
if (v.isDirty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
clean() {
|
||||
for (let v of this.allSubviews()) {
|
||||
v.clean();
|
||||
}
|
||||
super.clean();
|
||||
}
|
||||
toModel() {
|
||||
const subviews = [];
|
||||
for (let v of this.allSubviews()) {
|
||||
if (v != undefined) {
|
||||
v.superview = this;
|
||||
if (v.isDirty()) {
|
||||
subviews.push(v.toModel());
|
||||
}
|
||||
}
|
||||
}
|
||||
this.dirtyProps.subviews = subviews;
|
||||
return super.toModel();
|
||||
}
|
||||
}
|
||||
export class Group extends Superview {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.children = new Proxy([], {
|
||||
set: (target, index, value) => {
|
||||
const ret = Reflect.set(target, index, value);
|
||||
// Let getDirty return true
|
||||
this.dirtyProps.children = this.children.map(e => e.viewId);
|
||||
return ret;
|
||||
}
|
||||
});
|
||||
}
|
||||
allSubviews() {
|
||||
return this.children;
|
||||
}
|
||||
addChild(view) {
|
||||
this.children.push(view);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user