diff --git a/Android/doric/src/main/java/pub/doric/shader/StackNode.java b/Android/doric/src/main/java/pub/doric/shader/StackNode.java index f57acf7f..4e235a75 100644 --- a/Android/doric/src/main/java/pub/doric/shader/StackNode.java +++ b/Android/doric/src/main/java/pub/doric/shader/StackNode.java @@ -51,13 +51,7 @@ public class StackNode extends GroupNode { @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); - } + super.blend(view, name, prop); } @Override diff --git a/Android/doric/src/main/java/pub/doric/shader/TextNode.java b/Android/doric/src/main/java/pub/doric/shader/TextNode.java index ecdedf60..b83b8d27 100644 --- a/Android/doric/src/main/java/pub/doric/shader/TextNode.java +++ b/Android/doric/src/main/java/pub/doric/shader/TextNode.java @@ -16,6 +16,7 @@ package pub.doric.shader; import android.util.TypedValue; +import android.view.Gravity; import android.widget.TextView; import pub.doric.DoricContext; @@ -52,7 +53,7 @@ public class TextNode extends ViewNode { view.setTextColor(prop.asNumber().toInt()); break; case "textAlignment": - view.setGravity(prop.asNumber().toInt()); + view.setGravity(prop.asNumber().toInt() | Gravity.CENTER_VERTICAL); break; default: super.blend(view, name, prop); diff --git a/Android/doric/src/main/java/pub/doric/shader/ViewNode.java b/Android/doric/src/main/java/pub/doric/shader/ViewNode.java index 3faae261..3c26cecf 100644 --- a/Android/doric/src/main/java/pub/doric/shader/ViewNode.java +++ b/Android/doric/src/main/java/pub/doric/shader/ViewNode.java @@ -19,6 +19,7 @@ import android.content.Context; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; +import android.widget.LinearLayout; import pub.doric.DoricContext; import pub.doric.DoricRegistry; @@ -66,7 +67,7 @@ public abstract class ViewNode extends DoricContextHolder { this.mId = id; } - public String getType(){ + public String getType() { return mType; } @@ -93,32 +94,30 @@ public abstract class ViewNode extends DoricContextHolder { } else { params = mLayoutParams; } + if (mLayoutParams instanceof LinearLayout.LayoutParams && ((LinearLayout.LayoutParams) mLayoutParams).weight > 0) { + if (mSuperNode instanceof VLayoutNode) { + params.height = ViewGroup.LayoutParams.MATCH_PARENT; + } else if (mSuperNode instanceof HLayoutNode) { + params.width = ViewGroup.LayoutParams.MATCH_PARENT; + } + } + mView.setLayoutParams(params); } protected void blend(T view, String name, JSValue prop) { switch (name) { case "width": - if (mLayoutParams.width >= 0) { - mLayoutParams.width = DoricUtils.dp2px(prop.asNumber().toFloat()); - } + setWidth(prop.asNumber().toFloat()); break; case "height": - if (mLayoutParams.height >= 0) { - mLayoutParams.height = DoricUtils.dp2px(prop.asNumber().toFloat()); - } + setHeight(prop.asNumber().toFloat()); break; case "x": - if (mLayoutParams instanceof ViewGroup.MarginLayoutParams) { - float x = prop.asNumber().toFloat(); - ((ViewGroup.MarginLayoutParams) mLayoutParams).leftMargin = DoricUtils.dp2px(x); - } + setX(prop.asNumber().toFloat()); break; case "y": - if (mLayoutParams instanceof ViewGroup.MarginLayoutParams) { - float y = prop.asNumber().toFloat(); - ((ViewGroup.MarginLayoutParams) mLayoutParams).topMargin = DoricUtils.dp2px(y); - } + setY(prop.asNumber().toFloat()); break; case "bgColor": view.setBackgroundColor(prop.asNumber().toInt()); @@ -133,9 +132,7 @@ public abstract class ViewNode extends DoricContextHolder { }); break; case "layoutConfig": - if (prop.isObject() && mSuperNode != null) { - mSuperNode.blendSubLayoutConfig(this, prop.asObject()); - } + setLayoutConfig(prop.asObject()); break; case "border": if (prop.isObject() && doricLayer != null) { @@ -216,4 +213,34 @@ public abstract class ViewNode extends DoricContextHolder { public String getId() { return mId; } + + protected void setWidth(float width) { + if (mLayoutParams.width >= 0) { + mLayoutParams.width = DoricUtils.dp2px(width); + } + } + + protected void setHeight(float height) { + if (mLayoutParams.height >= 0) { + mLayoutParams.height = DoricUtils.dp2px(height); + } + } + + protected void setX(float x) { + if (mLayoutParams instanceof ViewGroup.MarginLayoutParams) { + ((ViewGroup.MarginLayoutParams) mLayoutParams).leftMargin = DoricUtils.dp2px(x); + } + } + + protected void setY(float y) { + if (mLayoutParams instanceof ViewGroup.MarginLayoutParams) { + ((ViewGroup.MarginLayoutParams) mLayoutParams).topMargin = DoricUtils.dp2px(y); + } + } + + protected void setLayoutConfig(JSObject layoutConfig) { + if (mSuperNode != null) { + mSuperNode.blendSubLayoutConfig(this, layoutConfig); + } + } } diff --git a/Android/doric/src/main/java/pub/doric/shader/list/ListItemNode.java b/Android/doric/src/main/java/pub/doric/shader/list/ListItemNode.java index 8ce9fcf6..4aabf847 100644 --- a/Android/doric/src/main/java/pub/doric/shader/list/ListItemNode.java +++ b/Android/doric/src/main/java/pub/doric/shader/list/ListItemNode.java @@ -17,6 +17,7 @@ package pub.doric.shader.list; import android.widget.FrameLayout; +import com.github.pengfeizhou.jscore.JSObject; import com.github.pengfeizhou.jscore.JSValue; import pub.doric.DoricContext; @@ -45,4 +46,11 @@ public class ListItemNode extends StackNode { super.blend(view, name, prop); } } + + @Override + public void blend(JSObject jsObject) { + super.blend(jsObject); + getDoricLayer().getLayoutParams().width = getLayoutParams().width; + getDoricLayer().getLayoutParams().height = getLayoutParams().height; + } } diff --git a/demo/src/ListDemo.ts b/demo/src/ListDemo.ts index 843ab12c..77a692e6 100644 --- a/demo/src/ListDemo.ts +++ b/demo/src/ListDemo.ts @@ -1,4 +1,4 @@ -import { Group, Panel, List, text, gravity, Color, Stack, LayoutSpec, list, NativeCall, listItem, log, vlayout } from "doric"; +import { Group, Panel, List, text, gravity, Color, Stack, LayoutSpec, list, NativeCall, listItem, log, vlayout, Gravity, hlayout } from "doric"; const colors = [ "#f0932b", "#eb4d4b", @@ -26,23 +26,44 @@ class ListPanel extends Panel { list({ itemCount: 1000, renderItem: (idx: number) => { - return listItem(text({ - layoutConfig: { - widthSpec: LayoutSpec.AT_MOST, - heightSpec: LayoutSpec.WRAP_CONTENT, - margin: { - left: 10, - right: 50, - top: 50, - bottom: 10, - }, - }, - text: `Cell At Line ${idx}`, - textAlignment: gravity().center(), - textColor: Color.parse("#ffffff"), - textSize: 20, - })).also(it => { - it.gravity = gravity().center() + return listItem( + hlayout([ + text({ + layoutConfig: { + widthSpec: LayoutSpec.WRAP_CONTENT, + heightSpec: LayoutSpec.EXACTLY, + alignment: gravity().center(), + }, + text: `Cell At Line ${idx}`, + textAlignment: gravity().center(), + textColor: Color.parse("#ffffff"), + textSize: 20, + height: 50, + bgColor: Color.parse('#00ff00'), + }), + text({ + layoutConfig: { + widthSpec: LayoutSpec.EXACTLY, + heightSpec: LayoutSpec.EXACTLY, + alignment: gravity().center(), + weight: 1, + }, + text: `Right`, + textAlignment: gravity().right(), + textColor: Color.parse("#ffffff"), + textSize: 20, + height: 50, + bgColor: Color.parse('#00ffff'), + }), + ]).also(it => { + it.layoutConfig = { + widthSpec: LayoutSpec.AT_MOST, + heightSpec: LayoutSpec.WRAP_CONTENT, + alignment: gravity().center(), + } + it.bgColor = Color.parse('#ffffff') + }) + ).also(it => { it.bgColor = Color.parse(colors[idx % colors.length]) it.layoutConfig = { widthSpec: LayoutSpec.AT_MOST, @@ -51,8 +72,7 @@ class ListPanel extends Panel { it.height = 100 it.onClick = () => { log(`Click item at ${idx}`) - it.bgColor = Color.parse('#000000') - log(`bgcolor is ${Color.parse('#000000').toModel()}`) + it.height += 10 } }) }, diff --git a/demo/src/Snake.ts b/demo/src/Snake.ts index ec45d7f4..6b438750 100644 --- a/demo/src/Snake.ts +++ b/demo/src/Snake.ts @@ -189,6 +189,10 @@ class SnakeView extends ViewHolder { textSize: 30, textAlignment: new Gravity().center(), bgColor: Color.parse('#ffff00'), + layoutConfig: { + widthSpec: LayoutSpec.EXACTLY, + heightSpec: LayoutSpec.EXACTLY, + }, }).also(it => this.up = it) ]).also(it => { it.layoutConfig = { @@ -204,6 +208,10 @@ class SnakeView extends ViewHolder { textSize: 30, textAlignment: new Gravity().center(), bgColor: Color.parse('#ffff00'), + layoutConfig: { + widthSpec: LayoutSpec.EXACTLY, + heightSpec: LayoutSpec.EXACTLY, + }, }).also(it => this.left = it), text({ width: 50, @@ -212,6 +220,10 @@ class SnakeView extends ViewHolder { textSize: 30, textAlignment: new Gravity().center(), bgColor: Color.parse('#ffff00'), + layoutConfig: { + widthSpec: LayoutSpec.EXACTLY, + heightSpec: LayoutSpec.EXACTLY, + }, }).also(it => this.down = it), text({ width: 50, @@ -220,6 +232,10 @@ class SnakeView extends ViewHolder { textSize: 30, textAlignment: new Gravity().center(), bgColor: Color.parse('#ffff00'), + layoutConfig: { + widthSpec: LayoutSpec.EXACTLY, + heightSpec: LayoutSpec.EXACTLY, + }, }).also(it => this.right = it), ]).also(it => { it.layoutConfig = { @@ -248,16 +264,6 @@ class SnakeView extends ViewHolder { }).in(root) } - buildController(text: string) { - const ret = new Text - ret.width = ret.height = 50 - ret.bgColor = Color.parse('#ffff00') - ret.text = text - ret.textSize = 30 - ret.textAlignment = new Gravity().center() - return ret - } - bind(state: SnakeModel): void { log('build', state) this.panel.width = state.width * 10 diff --git a/iOS/Pod/Classes/Shader/DoricLayouts.m b/iOS/Pod/Classes/Shader/DoricLayouts.m index fca3fe87..bf238368 100644 --- a/iOS/Pod/Classes/Shader/DoricLayouts.m +++ b/iOS/Pod/Classes/Shader/DoricLayouts.m @@ -530,23 +530,3 @@ - (UIView *)viewWithTagString:(NSString *)tagString { layout.layoutConfig = [[DoricLayoutConfig alloc] initWithWidth:DoricLayoutWrapContent height:DoricLayoutWrapContent]; return layout; } - -DoricVLayoutView *vLayoutWithBlock(NSArray *blocks) { - DoricVLayoutView *layout = [[DoricVLayoutView alloc] initWithFrame:CGRectZero]; - UIView *(^block)(); - for (block in blocks) { - [layout addSubview:block()]; - } - layout.layoutConfig = [[DoricLayoutConfig alloc] initWithWidth:DoricLayoutWrapContent height:DoricLayoutWrapContent]; - return layout; -} - -DoricHLayoutView *hLayoutWithBlock(NSArray *blocks) { - DoricHLayoutView *layout = [[DoricHLayoutView alloc] initWithFrame:CGRectZero]; - UIView *(^block)(); - for (block in blocks) { - [layout addSubview:block()]; - } - layout.layoutConfig = [[DoricLayoutConfig alloc] initWithWidth:DoricLayoutWrapContent height:DoricLayoutWrapContent]; - return layout; -} diff --git a/iOS/Pod/Classes/Shader/DoricStackNode.m b/iOS/Pod/Classes/Shader/DoricStackNode.m index 9e2f7569..7b0ea338 100644 --- a/iOS/Pod/Classes/Shader/DoricStackNode.m +++ b/iOS/Pod/Classes/Shader/DoricStackNode.m @@ -29,10 +29,6 @@ - (DoricStackView *)build { } - (void)blendView:(DoricStackView *)view forPropName:(NSString *)name propValue:(id)prop { - if ([name isEqualToString:@"gravity"]) { - view.gravity = (DoricGravity) [(NSNumber *) prop integerValue]; - } else { - [super blendView:view forPropName:name propValue:prop]; - } + [super blendView:view forPropName:name propValue:prop]; } @end diff --git a/iOS/Pod/Classes/Shader/DoricSuperNode.m b/iOS/Pod/Classes/Shader/DoricSuperNode.m index b06ee2db..ac1827d4 100644 --- a/iOS/Pod/Classes/Shader/DoricSuperNode.m +++ b/iOS/Pod/Classes/Shader/DoricSuperNode.m @@ -93,7 +93,10 @@ - (void)blendSubNode:(DoricViewNode *)subNode layoutConfig:(NSDictionary *)layou if (alignment) { params.alignment = (DoricGravity) [alignment integerValue]; } - + NSNumber *weight = layoutConfig[@"weight"]; + if (weight) { + params.weight = (DoricGravity) [weight integerValue]; + } } - (void)blendSubNode:(NSDictionary *)subModel { diff --git a/iOS/Pod/Classes/Shader/DoricTextNode.m b/iOS/Pod/Classes/Shader/DoricTextNode.m index 5dd22fc5..9f386205 100644 --- a/iOS/Pod/Classes/Shader/DoricTextNode.m +++ b/iOS/Pod/Classes/Shader/DoricTextNode.m @@ -39,15 +39,10 @@ - (void)blendView:(UILabel *)view forPropName:(NSString *)name propValue:(id)pro } else if ([name isEqualToString:@"textAlignment"]) { DoricGravity gravity = (DoricGravity) [(NSNumber *) prop integerValue]; NSTextAlignment alignment = NSTextAlignmentCenter; - switch (gravity) { - case LEFT: - alignment = NSTextAlignmentLeft; - break; - case RIGHT: - alignment = NSTextAlignmentRight; - break; - default: - break; + if ((gravity & LEFT) == LEFT) { + alignment = NSTextAlignmentLeft; + } else if ((gravity & RIGHT) == RIGHT) { + alignment = NSTextAlignmentRight; } view.textAlignment = alignment; } else { diff --git a/js-framework/src/ui/declarative.ts b/js-framework/src/ui/declarative.ts index 69b8a454..13ce2903 100644 --- a/js-framework/src/ui/declarative.ts +++ b/js-framework/src/ui/declarative.ts @@ -20,6 +20,10 @@ import { IList, List } from './listview' export function text(config: IText) { const ret = new Text + ret.layoutConfig = { + widthSpec: LayoutSpec.WRAP_CONTENT, + heightSpec: LayoutSpec.WRAP_CONTENT, + } for (let key in config) { Reflect.set(ret, key, Reflect.get(config, key, config), ret) } @@ -28,6 +32,10 @@ export function text(config: IText) { export function image(config: IImage) { const ret = new Image + ret.layoutConfig = { + widthSpec: LayoutSpec.WRAP_CONTENT, + heightSpec: LayoutSpec.WRAP_CONTENT, + } for (let key in config) { Reflect.set(ret, key, Reflect.get(config, key, config), ret) } diff --git a/js-framework/src/ui/layout.ts b/js-framework/src/ui/layout.ts index bfeb246a..0dd19eac 100644 --- a/js-framework/src/ui/layout.ts +++ b/js-framework/src/ui/layout.ts @@ -17,12 +17,9 @@ import { LayoutConfig, Group, Property, IView } from "./view"; import { Gravity } from "../util/gravity"; export interface IStack extends IView { - gravity?: Gravity } export class Stack extends Group implements IStack { - @Property - gravity?: Gravity }