This repository has been archived on 2024-07-22. You can view files and clone it, but cannot push or open issues or pull requests.
Doric/js-framework/ui/view.ts
2019-07-17 10:33:08 +08:00

192 lines
3.5 KiB
TypeScript

import { Color, GradientColor } from "../util/color"
import { Modeling, Model } from "../util/types";
import "reflect-metadata"
export function Property(target: Object, propKey: string) {
Reflect.defineMetadata(propKey, true, target)
}
export abstract class View implements Modeling {
@Property
width: number = 0
@Property
height: number = 0
@Property
x: number = 0
@Property
y: number = 0
@Property
bgColor?: Color | GradientColor
@Property
corners?: number | { leftTop?: number; rightTop?: number; leftBottom?: number; rightBottom?: number }
@Property
border?: { width: number; color: Color; }
@Property
shadow?: { color: Color; opacity: number; radius: number; offset: { width: number; height: number; }; }
@Property
alpha?: number
constructor() {
return new Proxy(this, {
get: (target, p) => {
return Reflect.get(target, p)
},
set: (target, p, v) => {
const oldV = Reflect.get(target, p)
const ret = Reflect.set(target, p, v)
if (Reflect.getMetadata(p, target)) {
this.onPropertyChanged(p.toString(), oldV, v)
}
return ret
}
})
}
/** Anchor start*/
get left() {
return this.x
}
set left(v: number) {
this.x = v
}
get right() {
return this.x + this.width
}
set right(v: number) {
this.x = v - this.width
}
get top() {
return this.y
}
set top(v: number) {
this.y = v
}
get bottom() {
return this.y + this.height
}
set bottom(v: number) {
this.y = v - this.height
}
/** Anchor end*/
__dirty_props__: { [index: string]: Model | undefined } = {}
onPropertyChanged(propKey: string, oldV: Model, newV: Model): void {
if (newV instanceof Object
&& Reflect.has(newV, 'toModel')
&& Reflect.get(newV, 'toModel') instanceof Function) {
newV = Reflect.apply(Reflect.get(newV, 'toModel'), newV, [])
}
this.__dirty_props__[propKey] = newV
}
toModel() {
return this.__dirty_props__ || {}
}
@Property
padding?: {
left?: number,
right?: number,
top?: number,
bottom?: number,
}
@Property
config?: Config
}
export enum Alignment {
center = 0,
start,
end,
}
export enum Gravity {
center = 0,
left,
right,
top,
bottom,
}
export interface Config {
margin?: {
left?: number,
right?: number,
top?: number,
bottom?: number,
}
alignment?: Alignment
}
export interface StackConfig extends Config {
}
export interface LayoutConfig extends Config {
weight?: number
}
export abstract class Group extends View {
@Property
children: View[] = []
}
export class Stack extends Group {
@Property
gravity?: number
}
class LinearLayout extends Group {
@Property
space?: number
@Property
gravity?: number
}
export class VLayout extends LinearLayout {
}
export class HLayout extends LinearLayout {
}
export class Text extends View {
@Property
text?: string
@Property
textColor?: Color
@Property
textSize?: number
@Property
maxLines?: number
}
export class Image extends View {
@Property
imageUrl?: string
}
export class List extends View {
}
export class Slide extends View {
}