declarative ui

This commit is contained in:
pengfei.zhou 2019-10-28 11:28:46 +08:00 committed by unknown
parent b1a2211dcf
commit 042a1dbf17
7 changed files with 224 additions and 196 deletions

View File

@ -1,4 +1,4 @@
import { vlayout, Image, ViewHolder, VMPanel, ViewModel, Gravity, NativeCall, Text, Color, log, logw, loge, Group, LayoutSpec, } from "doric"
import { text, vlayout, Image, ViewHolder, VMPanel, ViewModel, Gravity, NativeCall, Text, Color, log, logw, loge, Group, LayoutSpec, } from "doric"
interface CountModel {
count: number
@ -10,39 +10,31 @@ class CounterView extends ViewHolder<CountModel> {
counter!: Text
build(root: Group) {
root.addChild(vlayout([
() => {
return (new Text).also(it => {
it.textSize = 40
it.layoutConfig = {
text({
textSize: 40,
layoutConfig: {
alignment: new Gravity().center()
}
this.number = it
})
},
() => {
return (new Text).also(it => {
it.text = "点击计数"
it.textSize = 20
it.border = {
}).also(it => { this.number = it }),
text({
text: "点击计数",
textSize: 20,
border: {
width: 1,
color: Color.parse('#000000'),
}
it.corners = 5
it.layoutConfig = {
},
corners: 5,
layoutConfig: {
alignment: new Gravity().center()
}
it.shadow = {
},
shadow: {
color: Color.parse("#00ff00"),
opacity: 0.5,
radius: 20,
offsetX: 10,
offsetY: 10,
}
this.counter = it
})
},
}).also(it => { this.counter = it }),
]).also(it => {
it.width = 200
it.height = 200

View File

@ -1,4 +1,4 @@
import { loge, log, ViewHolder, Stack, ViewModel, Gravity, Text, Color, HLayout, VLayout, Group, VMPanel, LayoutSpec, vlayout, hlayout, takeNonNull } from "doric";
import { text, loge, log, ViewHolder, Stack, ViewModel, Gravity, Text, Color, HLayout, VLayout, Group, VMPanel, LayoutSpec, vlayout, hlayout, takeNonNull, stack } from "doric";
type SnakeNode = {
x: number
@ -146,91 +146,89 @@ class SnakeView extends ViewHolder<SnakeModel> {
build(root: Group): void {
root.bgColor = Color.parse('#000000')
vlayout([
() => {
return (new Text).also(title => {
title.text = "Snake"
title.textSize = 20
title.textColor = Color.parse("#ffffff")
title.layoutConfig = {
text({
text: "Snake",
textSize: 20,
textColor: Color.parse("#ffffff"),
layoutConfig: {
alignment: new Gravity().centerX(),
margin: {
top: 20
},
widthSpec: LayoutSpec.WRAP_CONTENT,
heightSpec: LayoutSpec.WRAP_CONTENT,
}
})
},
() => {
return (new Stack).also(panel => {
}),
(new Stack).also(panel => {
panel.bgColor = Color.parse('#00ff00')
this.panel = panel
})
},
() => {
return hlayout([
() => {
return (new Text).also(it => {
it.text = "Start"
it.textSize = 30
it.textColor = Color.parse("#ffffff")
it.layoutConfig = {
}),
hlayout([
text({
text: "Start",
textSize: 30,
textColor: Color.parse("#ffffff"),
layoutConfig: {
widthSpec: LayoutSpec.WRAP_CONTENT,
heightSpec: LayoutSpec.WRAP_CONTENT,
}
this.start = it
})
},
}).also(it => this.start = it),
]).also(it => {
it.layoutConfig = {
widthSpec: LayoutSpec.WRAP_CONTENT,
heightSpec: LayoutSpec.WRAP_CONTENT,
}
})
},
() => {
return vlayout([
() => {
return hlayout([
() => {
return this.buildController("↑").also(it => {
this.up = it
})
}
}),
vlayout([
hlayout([
text({
width: 50,
height: 50,
text: "↑",
textSize: 30,
textAlignment: new Gravity().center(),
bgColor: Color.parse('#ffff00'),
}).also(it => this.up = it)
]).also(it => {
it.layoutConfig = {
widthSpec: LayoutSpec.WRAP_CONTENT,
heightSpec: LayoutSpec.WRAP_CONTENT,
}
})
},
() => {
return hlayout([
() => {
return this.buildController("←").also(it => {
this.left = it
})
},
() => {
return this.buildController("↓").also(it => {
this.down = it
})
},
() => {
return this.buildController("→").also(it => {
this.right = it
})
},
}),
hlayout([
text({
width: 50,
height: 50,
text: "←",
textSize: 30,
textAlignment: new Gravity().center(),
bgColor: Color.parse('#ffff00'),
}).also(it => this.left = it),
text({
width: 50,
height: 50,
text: "↓",
textSize: 30,
textAlignment: new Gravity().center(),
bgColor: Color.parse('#ffff00'),
}).also(it => this.down = it),
text({
width: 50,
height: 50,
text: "→",
textSize: 30,
textAlignment: new Gravity().center(),
bgColor: Color.parse('#ffff00'),
}).also(it => this.right = it),
]).also(it => {
it.layoutConfig = {
widthSpec: LayoutSpec.WRAP_CONTENT,
heightSpec: LayoutSpec.WRAP_CONTENT,
}
it.space = 10
})
},
])
.also(controlArea => {
}),
]).also(controlArea => {
controlArea.gravity = new Gravity().centerX()
controlArea.space = 10
controlArea.layoutConfig = {
@ -238,8 +236,7 @@ class SnakeView extends ViewHolder<SnakeModel> {
widthSpec: LayoutSpec.WRAP_CONTENT,
heightSpec: LayoutSpec.WRAP_CONTENT,
}
})
}
}),
]).also(it => {
it.space = 20
it.layoutConfig = {

View File

@ -15,6 +15,7 @@
*/
export * from "./src/ui/view"
export * from "./src/ui/panel"
export * from "./src/ui/declarative"
export * from "./src/util/color"
export * from './src/util/log'
export * from './src/util/types'

View File

@ -0,0 +1,87 @@
import { Text, Image, HLayout, VLayout, Stack, LayoutConfig, View } from './view'
import { Color, GradientColor } from '../util/color'
import { Gravity } from '../util/gravity'
export interface IView {
width?: number
height?: number
bgColor?: 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
padding?: {
left?: number,
right?: number,
top?: number,
bottom?: number,
}
layoutConfig?: LayoutConfig
onClick?: Function
identifier?: string
}
export interface IText extends IView {
text?: string
textColor?: Color
textSize?: number
maxLines?: number
textAlignment?: Gravity
}
export interface IImage extends IView {
imageUrl?: string
}
export interface IStack extends IView {
gravity?: Gravity
}
export interface IVLayout extends IView {
space?: number
gravity?: Gravity
}
export interface IHLayout extends IView {
space?: number
gravity?: Gravity
}
export function text(config: IText) {
const ret = new Text
for (let key in config) {
Reflect.set(ret, key, Reflect.get(config, key, config), ret)
}
return ret
}
export function image(config: IImage) {
const ret = new Image
for (let key in config) {
Reflect.set(ret, key, Reflect.get(config, key, config), ret)
}
return ret
}
export function stack(views: View[]) {
const ret = new Stack
for (let v of views) {
ret.addChild(v)
}
return ret
}
export function hlayout(views: View[]) {
const ret = new HLayout
for (let v of views) {
ret.addChild(v)
}
return ret
}
export function vlayout(views: View[]) {
const ret = new VLayout
for (let v of views) {
ret.addChild(v)
}
return ret
}

View File

@ -1,47 +0,0 @@
/*
* 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.
*/
function from(obj: Object) {
return new Proxy(obj, {
set: (target, prop, value, receiver) => {
return Reflect.set(target, prop, value, receiver)
}
})
}
class Wrapper {
val: any
constructor(val: any) {
this.val = val
}
toVal(): any {
return this.val
}
}
export class State {
static of<T extends Object>(obj: T): T {
return new Proxy(obj, {
get: (target, prop) => {
const ret = Reflect.get(target, prop)
if (ret instanceof Object) {
return State.of(ret)
} else {
return new Wrapper(ret)
}
}
})
}
}

View File

@ -37,8 +37,6 @@ export interface LayoutConfig {
alignment?: Gravity
}
export function Property(target: Object, propKey: string) {
Reflect.defineMetadata(propKey, true, target)
}

View File

@ -13,36 +13,36 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { View, Stack, VLayout, HLayout } from "../ui/view"
// import { View, Stack, VLayout, HLayout } from "../ui/view"
export type ViewBlock = () => View
// export type ViewBlock = () => View
export function stack(blocks: ViewBlock[]) {
return takeAlso(new Stack)(
it => {
for (let block of blocks) {
it.addChild(block())
}
})
}
// export function stack(blocks: ViewBlock[]) {
// return takeAlso(new Stack)(
// it => {
// for (let block of blocks) {
// it.addChild(block())
// }
// })
// }
export function vlayout(blocks: ViewBlock[]) {
return takeAlso(new VLayout)(
it => {
for (let block of blocks) {
it.addChild(block())
}
})
}
// export function vlayout(blocks: ViewBlock[]) {
// return takeAlso(new VLayout)(
// it => {
// for (let block of blocks) {
// it.addChild(block())
// }
// })
// }
export function hlayout(blocks: ViewBlock[]) {
return takeAlso(new HLayout)(
it => {
for (let block of blocks) {
it.addChild(block())
}
})
}
// export function hlayout(blocks: ViewBlock[]) {
// return takeAlso(new HLayout)(
// it => {
// for (let block of blocks) {
// it.addChild(block())
// }
// })
// }
export function take<T>(target: T) {
return (block: (p: T) => void) => {