add vh layout
This commit is contained in:
parent
341692f319
commit
9592e9ed3d
@ -3,10 +3,12 @@ package com.github.penfeizhou.doric;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.github.penfeizhou.doric.plugin.ShaderPlugin;
|
||||
import com.github.penfeizhou.doric.shader.HLayoutNode;
|
||||
import com.github.penfeizhou.doric.shader.ImageNode;
|
||||
import com.github.penfeizhou.doric.shader.RootNode;
|
||||
import com.github.penfeizhou.doric.shader.StackNode;
|
||||
import com.github.penfeizhou.doric.shader.TextNode;
|
||||
import com.github.penfeizhou.doric.shader.VLayoutNode;
|
||||
import com.github.penfeizhou.doric.shader.ViewNode;
|
||||
import com.github.penfeizhou.doric.utils.DoricMetaInfo;
|
||||
import com.github.penfeizhou.doric.plugin.DoricJavaPlugin;
|
||||
@ -47,6 +49,8 @@ public class DoricRegistry {
|
||||
this.registerViewNode(TextNode.class);
|
||||
this.registerViewNode(ImageNode.class);
|
||||
this.registerViewNode(StackNode.class);
|
||||
this.registerViewNode(VLayoutNode.class);
|
||||
this.registerViewNode(HLayoutNode.class);
|
||||
initRegistry(this);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,26 @@
|
||||
package com.github.penfeizhou.doric.shader;
|
||||
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.github.penfeizhou.doric.DoricContext;
|
||||
import com.github.penfeizhou.doric.extension.bridge.DoricPlugin;
|
||||
import com.github.pengfeizhou.jscore.JSObject;
|
||||
|
||||
/**
|
||||
* @Description: com.github.penfeizhou.doric.shader
|
||||
* @Author: pengfei.zhou
|
||||
* @CreateDate: 2019-07-23
|
||||
*/
|
||||
@DoricPlugin(name = "HLayout")
|
||||
public class HLayoutNode extends LinearNode {
|
||||
public HLayoutNode(DoricContext doricContext) {
|
||||
super(doricContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LinearLayout build(JSObject jsObject) {
|
||||
LinearLayout linearLayout = super.build(jsObject);
|
||||
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
|
||||
return linearLayout;
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package com.github.penfeizhou.doric.shader;
|
||||
|
||||
import android.graphics.drawable.ShapeDrawable;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.github.penfeizhou.doric.DoricContext;
|
||||
import com.github.penfeizhou.doric.utils.DoricUtils;
|
||||
import com.github.pengfeizhou.jscore.JSObject;
|
||||
import com.github.pengfeizhou.jscore.JSValue;
|
||||
|
||||
/**
|
||||
* @Description: com.github.penfeizhou.doric.shader
|
||||
* @Author: pengfei.zhou
|
||||
* @CreateDate: 2019-07-23
|
||||
*/
|
||||
public class LinearNode extends GroupNode<LinearLayout> {
|
||||
public LinearNode(DoricContext doricContext) {
|
||||
super(doricContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LinearLayout build(JSObject jsObject) {
|
||||
return new LinearLayout(getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void blend(LinearLayout view, String name, JSValue prop) {
|
||||
switch (name) {
|
||||
case "space":
|
||||
ShapeDrawable shapeDrawable;
|
||||
if (view.getDividerDrawable() == null) {
|
||||
shapeDrawable = new ShapeDrawable();
|
||||
shapeDrawable.setAlpha(0);
|
||||
view.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE);
|
||||
} else {
|
||||
shapeDrawable = (ShapeDrawable) view.getDividerDrawable();
|
||||
view.setDividerDrawable(null);
|
||||
}
|
||||
if (view.getOrientation() == LinearLayout.VERTICAL) {
|
||||
shapeDrawable.setIntrinsicHeight(DoricUtils.dp2px(prop.asNumber().toFloat()));
|
||||
} else {
|
||||
shapeDrawable.setIntrinsicWidth(DoricUtils.dp2px(prop.asNumber().toFloat()));
|
||||
}
|
||||
view.setDividerDrawable(shapeDrawable);
|
||||
break;
|
||||
case "gravity":
|
||||
view.setGravity(prop.asNumber().toInt());
|
||||
break;
|
||||
default:
|
||||
super.blend(view, name, prop);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ import android.widget.FrameLayout;
|
||||
import com.github.penfeizhou.doric.DoricContext;
|
||||
import com.github.penfeizhou.doric.extension.bridge.DoricPlugin;
|
||||
import com.github.pengfeizhou.jscore.JSObject;
|
||||
import com.github.pengfeizhou.jscore.JSValue;
|
||||
|
||||
/**
|
||||
* @Description: com.github.penfeizhou.doric.widget
|
||||
@ -21,4 +22,15 @@ public class StackNode extends GroupNode<FrameLayout> {
|
||||
public FrameLayout build(JSObject jsObject) {
|
||||
return new FrameLayout(getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void blend(FrameLayout view, String name, JSValue prop) {
|
||||
switch (name) {
|
||||
case "gravity":
|
||||
view.setForegroundGravity(prop.asNumber().toInt());
|
||||
break;
|
||||
default:
|
||||
super.blend(view, name, prop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,27 @@
|
||||
package com.github.penfeizhou.doric.shader;
|
||||
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.github.penfeizhou.doric.DoricContext;
|
||||
import com.github.penfeizhou.doric.extension.bridge.DoricPlugin;
|
||||
import com.github.pengfeizhou.jscore.JSObject;
|
||||
|
||||
/**
|
||||
* @Description: com.github.penfeizhou.doric.shader
|
||||
* @Author: pengfei.zhou
|
||||
* @CreateDate: 2019-07-23
|
||||
*/
|
||||
@DoricPlugin(name = "VLayout")
|
||||
public class VLayoutNode extends LinearNode {
|
||||
public VLayoutNode(DoricContext doricContext) {
|
||||
super(doricContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LinearLayout build(JSObject jsObject) {
|
||||
LinearLayout linearLayout = super.build(jsObject);
|
||||
linearLayout.setOrientation(LinearLayout.VERTICAL);
|
||||
return linearLayout;
|
||||
}
|
||||
|
||||
}
|
@ -58,10 +58,18 @@ public abstract class ViewNode<T extends View> extends DoricComponent {
|
||||
protected void blend(T view, String name, JSValue prop) {
|
||||
switch (name) {
|
||||
case "width":
|
||||
view.getLayoutParams().width = DoricUtils.dp2px(prop.asNumber().toFloat());
|
||||
if (prop.asNumber().toInt() < 0) {
|
||||
view.getLayoutParams().width = prop.asNumber().toInt();
|
||||
} else {
|
||||
view.getLayoutParams().width = DoricUtils.dp2px(prop.asNumber().toFloat());
|
||||
}
|
||||
break;
|
||||
case "height":
|
||||
view.getLayoutParams().height = DoricUtils.dp2px(prop.asNumber().toFloat());
|
||||
if (prop.asNumber().toInt() < 0) {
|
||||
view.getLayoutParams().height = prop.asNumber().toInt();
|
||||
} else {
|
||||
view.getLayoutParams().height = DoricUtils.dp2px(prop.asNumber().toFloat());
|
||||
}
|
||||
break;
|
||||
case "x":
|
||||
if (view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
|
||||
|
@ -1,35 +1,52 @@
|
||||
import { NativeCall, Text, Alignment, Color, VLayout, Panel, log, logw, loge } from "./index"
|
||||
import { Group } from "./src/ui/view";
|
||||
|
||||
import { Gravity, Mutable, NativeCall, Text, Color, VLayout, Panel, log, logw, loge, Group, Stack, } from "./index"
|
||||
|
||||
|
||||
@Entry
|
||||
export class MyPage extends Panel {
|
||||
state = {
|
||||
count: 0
|
||||
}
|
||||
|
||||
build(rootView: Group): void {
|
||||
const state = Mutable.of(1)
|
||||
const numberView = new Text
|
||||
numberView.width = 100
|
||||
numberView.height = 200
|
||||
numberView.top = 50
|
||||
numberView.text = this.state.count.toString()
|
||||
state.bind((v) => {
|
||||
numberView.text = v.toString()
|
||||
})
|
||||
numberView.textSize = 40
|
||||
numberView.centerX = rootView.width / 2
|
||||
rootView.addChild(numberView)
|
||||
const click = new Text
|
||||
click.width = click.height = 100
|
||||
click.textSize = 20
|
||||
click.text = '点击计数'
|
||||
click.onClick = () => {
|
||||
this.state.count++
|
||||
numberView.text = this.state.count.toString()
|
||||
state.set(state.get() + 1)
|
||||
}
|
||||
click.centerX = rootView.width / 2
|
||||
click.top = numberView.bottom + 20
|
||||
rootView.addChild(click)
|
||||
rootView.bgColor = Color.safeParse('#00ff00')
|
||||
|
||||
const vlayout = new VLayout
|
||||
vlayout.width = this.getRootView().width
|
||||
vlayout.height = 500
|
||||
|
||||
vlayout.top = 50
|
||||
vlayout.centerX = this.getRootView().width / 2
|
||||
vlayout.space = 0
|
||||
vlayout.gravity = (new Gravity()).bottom()
|
||||
const v = [1, 2, 3,].map(e => {
|
||||
const stack = new Stack
|
||||
stack.width = stack.height = 50
|
||||
stack.bgColor = Color.safeParse('#00ff00')
|
||||
vlayout.addChild(stack)
|
||||
stack.onClick = () => {
|
||||
loge('stack:onClick')
|
||||
if (vlayout.space !== undefined) {
|
||||
loge('change space')
|
||||
vlayout.space += 10
|
||||
}
|
||||
}
|
||||
})
|
||||
rootView.addChild(vlayout)
|
||||
}
|
||||
|
||||
@NativeCall
|
||||
|
@ -2,4 +2,6 @@ export * from "./src/ui/view"
|
||||
export * from "./src/ui/panel"
|
||||
export * from "./src/util/color"
|
||||
export * from './src/util/log'
|
||||
export * from './src/util/types'
|
||||
export * from './src/util/gravity'
|
||||
export * from './src/runtime/global'
|
@ -5,6 +5,8 @@ function from(obj: Object) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
class Wrapper {
|
||||
val: any
|
||||
constructor(val: any) {
|
||||
|
@ -1,18 +1,23 @@
|
||||
import { Color, GradientColor } from "../util/color"
|
||||
import { Modeling, Model, obj2Model } from "../util/types";
|
||||
import { uniqueId } from "../util/uniqueId";
|
||||
import { Gravity } from "../util/gravity";
|
||||
import { loge } from "../util/log";
|
||||
|
||||
export const MATCH_PARENT = -1
|
||||
|
||||
export const WRAP_CONTENT = -2
|
||||
|
||||
export function Property(target: Object, propKey: string) {
|
||||
Reflect.defineMetadata(propKey, true, target)
|
||||
}
|
||||
|
||||
export abstract class View implements Modeling {
|
||||
@Property
|
||||
width: number = 0
|
||||
width: number = WRAP_CONTENT
|
||||
|
||||
@Property
|
||||
height: number = 0
|
||||
height: number = WRAP_CONTENT
|
||||
|
||||
@Property
|
||||
x: number = 0
|
||||
@ -146,9 +151,11 @@ export abstract class View implements Modeling {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
isDirty() {
|
||||
return Reflect.ownKeys(this.__dirty_props__).length !== 0
|
||||
}
|
||||
|
||||
responseCallback(id: string, ...args: any) {
|
||||
const f = this.id2Callback(id)
|
||||
if (f instanceof Function) {
|
||||
@ -176,20 +183,9 @@ export abstract class View implements Modeling {
|
||||
|
||||
@Property
|
||||
config?: Config
|
||||
}
|
||||
|
||||
export enum Alignment {
|
||||
center = 0,
|
||||
start,
|
||||
end,
|
||||
}
|
||||
|
||||
export enum Gravity {
|
||||
center = 0,
|
||||
left,
|
||||
right,
|
||||
top,
|
||||
bottom,
|
||||
@Property
|
||||
onClick?: Function
|
||||
}
|
||||
|
||||
export interface Config {
|
||||
@ -199,14 +195,14 @@ export interface Config {
|
||||
top?: number,
|
||||
bottom?: number,
|
||||
}
|
||||
alignment?: Alignment
|
||||
alignment?: Gravity
|
||||
}
|
||||
|
||||
export interface StackConfig extends Config {
|
||||
|
||||
}
|
||||
|
||||
export interface LayoutConfig extends Config {
|
||||
export interface LinearConfig extends Config {
|
||||
weight?: number
|
||||
}
|
||||
|
||||
@ -257,7 +253,7 @@ export abstract class Group extends View {
|
||||
|
||||
export class Stack extends Group {
|
||||
@Property
|
||||
gravity?: number
|
||||
gravity?: Gravity
|
||||
}
|
||||
export class Root extends Stack {
|
||||
|
||||
@ -267,7 +263,7 @@ class LinearLayout extends Group {
|
||||
space?: number
|
||||
|
||||
@Property
|
||||
gravity?: number
|
||||
gravity?: Gravity
|
||||
}
|
||||
|
||||
export class VLayout extends LinearLayout {
|
||||
@ -288,9 +284,6 @@ export class Text extends View {
|
||||
|
||||
@Property
|
||||
maxLines?: number
|
||||
|
||||
@Property
|
||||
onClick?: Function
|
||||
}
|
||||
|
||||
export class Image extends View {
|
||||
@ -305,3 +298,24 @@ export class List extends View {
|
||||
export class Slide extends View {
|
||||
|
||||
}
|
||||
|
||||
export function stack() {
|
||||
|
||||
}
|
||||
|
||||
export function vlayout(providers: Array<() => View>, config: {
|
||||
width: number
|
||||
height: number
|
||||
space?: number
|
||||
}) {
|
||||
const vlayout = new VLayout
|
||||
vlayout.width = config.width
|
||||
vlayout.height = config.height
|
||||
if (config.space !== undefined) {
|
||||
vlayout.space = config.space
|
||||
}
|
||||
providers.forEach(e => {
|
||||
vlayout.addChild(e())
|
||||
})
|
||||
return vlayout
|
||||
}
|
||||
|
64
js-framework/src/util/gravity.ts
Normal file
64
js-framework/src/util/gravity.ts
Normal file
@ -0,0 +1,64 @@
|
||||
import { Modeling } from "./types";
|
||||
|
||||
const SPECIFIED = 1
|
||||
const START = 1 << 1
|
||||
const END = 1 << 2
|
||||
|
||||
const SHIFT_X = 0
|
||||
const SHIFT_Y = 4
|
||||
|
||||
export const LEFT = (START | SPECIFIED) << SHIFT_X
|
||||
export const RIGHT = (END | SPECIFIED) << SHIFT_X
|
||||
|
||||
export const TOP = (START | SPECIFIED) << SHIFT_Y
|
||||
export const BOTTOM = (END | SPECIFIED) << SHIFT_Y
|
||||
|
||||
export const CENTER_X = SPECIFIED << SHIFT_X
|
||||
export const CENTER_Y = SPECIFIED << SHIFT_Y
|
||||
|
||||
export const CENTER = CENTER_X | CENTER_Y
|
||||
|
||||
export class Gravity implements Modeling {
|
||||
val = 0
|
||||
|
||||
left() {
|
||||
this.val |= LEFT
|
||||
return this
|
||||
}
|
||||
|
||||
right() {
|
||||
this.val |= RIGHT
|
||||
return this
|
||||
}
|
||||
|
||||
top() {
|
||||
this.val |= TOP
|
||||
return this
|
||||
}
|
||||
|
||||
bottom() {
|
||||
this.val |= BOTTOM
|
||||
return this
|
||||
}
|
||||
|
||||
center() {
|
||||
this.val |= CENTER
|
||||
return this
|
||||
}
|
||||
|
||||
centerX() {
|
||||
this.val |= CENTER_X
|
||||
return this
|
||||
}
|
||||
|
||||
centerY() {
|
||||
this.val |= CENTER_Y
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
toModel() {
|
||||
return this.val
|
||||
}
|
||||
|
||||
}
|
@ -15,4 +15,36 @@ export function obj2Model(obj: Model): Model {
|
||||
}
|
||||
|
||||
type _M = string | number | boolean | Modeling | { [index: string]: Model | undefined }
|
||||
export type Model = _M | Array<_M>
|
||||
export type Model = _M | Array<_M>
|
||||
|
||||
export type Binder<T> = (v: T) => void
|
||||
|
||||
export class Mutable<T>{
|
||||
private val: T
|
||||
|
||||
private binders: Set<Binder<T>> = new Set
|
||||
|
||||
get = () => {
|
||||
return this.val
|
||||
}
|
||||
|
||||
set = (v: T) => {
|
||||
this.val = v
|
||||
this.binders.forEach(e => {
|
||||
Reflect.apply(e, undefined, [this.val])
|
||||
})
|
||||
}
|
||||
|
||||
private constructor(v: T) {
|
||||
this.val = v
|
||||
}
|
||||
|
||||
bind(binder: Binder<T>) {
|
||||
this.binders.add(binder)
|
||||
Reflect.apply(binder, undefined, [this.val])
|
||||
}
|
||||
|
||||
static of<E>(v: E) {
|
||||
return new Mutable(v)
|
||||
}
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
let __uniqueId__: number = 0
|
||||
|
||||
let __uniqueId__ = 0
|
||||
export function uniqueId(prefix: string) {
|
||||
return `__${prefix}_${__uniqueId__++}__`;
|
||||
}
|
Reference in New Issue
Block a user