From e90bac1d32e855b1e374448ef4989a57dcc8c965 Mon Sep 17 00:00:00 2001 From: "pengfei.zhou" Date: Tue, 22 Oct 2019 16:04:40 +0800 Subject: [PATCH 1/9] feat:add config to generate map file --- demo/rollup.config.js | 1 + demo/tsconfig.json | 5 ++--- doric-cli/contents/_rollup.config.js | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/demo/rollup.config.js b/demo/rollup.config.js index 3e8b4c13..e267034d 100644 --- a/demo/rollup.config.js +++ b/demo/rollup.config.js @@ -8,6 +8,7 @@ export default bundles.map(bundle => { output: { format: "cjs", file: `bundle/${bundle}.js`, + sourcemap: true, }, plugins: [ resolve({ jsnext: true, main: true }), diff --git a/demo/tsconfig.json b/demo/tsconfig.json index d511f6a0..4d880db4 100644 --- a/demo/tsconfig.json +++ b/demo/tsconfig.json @@ -1,6 +1,5 @@ { "compilerOptions": { - "experimentalDecorators": true, /* Basic Options */ // "incremental": true, /* Enable incremental compilation */ "target": "ES2015", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ @@ -11,7 +10,7 @@ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ // "declaration": true, /* Generates corresponding '.d.ts' file. */ // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ - // "sourceMap": true, /* Generates corresponding '.map' file. */ + "sourceMap": true, /* Generates corresponding '.map' file. */ // "outFile": "./", /* Concatenate and emit output to single file. */ "outDir": "build/", /* Redirect output structure to the directory. */ // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ @@ -53,7 +52,7 @@ // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ /* Experimental Options */ - // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */ }, "include": [ diff --git a/doric-cli/contents/_rollup.config.js b/doric-cli/contents/_rollup.config.js index 3e8b4c13..e267034d 100644 --- a/doric-cli/contents/_rollup.config.js +++ b/doric-cli/contents/_rollup.config.js @@ -8,6 +8,7 @@ export default bundles.map(bundle => { output: { format: "cjs", file: `bundle/${bundle}.js`, + sourcemap: true, }, plugins: [ resolve({ jsnext: true, main: true }), From 42b03d52a37af770768f9985d7e47cbdc7db2ecc Mon Sep 17 00:00:00 2001 From: "pengfei.zhou" Date: Wed, 23 Oct 2019 09:54:40 +0800 Subject: [PATCH 2/9] add api of list and sectionList --- js-framework/src/ui/view.ts | 51 +++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/js-framework/src/ui/view.ts b/js-framework/src/ui/view.ts index 06e36705..0e7fccea 100644 --- a/js-framework/src/ui/view.ts +++ b/js-framework/src/ui/view.ts @@ -61,6 +61,26 @@ export abstract class View implements Modeling { @Property viewId = uniqueId('ViewId') + @Property + padding?: { + left?: number, + right?: number, + top?: number, + bottom?: number, + } + + @Property + layoutConfig?: Config + + @Property + onClick?: Function + + /** + * Set to reuse native view + */ + @Property + identifier?: string + parent?: Group callbacks: Map = new Map @@ -188,19 +208,6 @@ export abstract class View implements Modeling { return this.nativeViewModel } - @Property - padding?: { - left?: number, - right?: number, - top?: number, - bottom?: number, - } - - @Property - layoutConfig?: Config - - @Property - onClick?: Function } export interface Config { @@ -323,7 +330,25 @@ export class Image extends View { } export class List extends View { + @Property + itemCount = 0 + @Property + renderItem?: (index: number) => View +} + +export class SectionList extends View { + @Property + sectionRowsCount: number[] = [] + + @Property + renderSectionHeader?: (section: number) => View + + @Property + renderItem?: (item: number, section: number) => View + + @Property + sectionHeaderSticky = true } export class Slide extends View { From b4e41192c001d84c0608f45139da8e995bb4dfe0 Mon Sep 17 00:00:00 2001 From: "pengfei.zhou" Date: Wed, 23 Oct 2019 11:25:28 +0800 Subject: [PATCH 3/9] add getItem cache logic --- js-framework/src/ui/panel.ts | 4 +-- js-framework/src/ui/view.ts | 70 +++++++++++++++++++++++++++++++++--- 2 files changed, 68 insertions(+), 6 deletions(-) diff --git a/js-framework/src/ui/panel.ts b/js-framework/src/ui/panel.ts index 6c675f66..5c3708de 100644 --- a/js-framework/src/ui/panel.ts +++ b/js-framework/src/ui/panel.ts @@ -98,8 +98,8 @@ export abstract class Panel { private retrospectView(ids: string[]): View { return ids.reduce((acc: View, cur) => { - if (acc instanceof Group) { - return acc.children.filter(e => e.viewId === cur)[0] + if (Reflect.has(acc, "subViewById")) { + return Reflect.get(acc, "subViewById")(cur) } return acc }, this.__root__) diff --git a/js-framework/src/ui/view.ts b/js-framework/src/ui/view.ts index 0e7fccea..45e08476 100644 --- a/js-framework/src/ui/view.ts +++ b/js-framework/src/ui/view.ts @@ -228,7 +228,20 @@ export interface LinearConfig extends Config { weight?: number } -export abstract class Group extends View { +export interface SuperView { + subViewById(id: string): View | undefined +} + +export abstract class Group extends View implements SuperView { + + subViewById(id: string): View | undefined { + for (let view of this.children) { + if (view.viewId === id) { + return view + } + } + return undefined + } @Property readonly children: View[] = new Proxy([], { @@ -330,25 +343,74 @@ export class Image extends View { } export class List extends View { + private cachedViews: Map = new Map @Property itemCount = 0 @Property - renderItem?: (index: number) => View + renderItem!: (index: number) => View + + + private getItem(itemIdx: number) { + let view = this.cachedViews.get(`${itemIdx}`) + if (view === undefined) { + view = this.renderItem(itemIdx) + this.cachedViews.set(`${itemIdx}`, view) + } + return view + } + + @Property + private renderBunchedItems(items: number[]): View[] { + return items.map(e => this.getItem(e)) + } } export class SectionList extends View { + private cachedViews: Map = new Map + @Property sectionRowsCount: number[] = [] @Property - renderSectionHeader?: (section: number) => View + renderSectionHeader!: (sectionIdx: number) => View @Property - renderItem?: (item: number, section: number) => View + renderItem!: (sectionIdx: number, itemIdx: number) => View @Property sectionHeaderSticky = true + + setupSectionRows(sectionCount: number, numberOfSection: (section: number) => number) { + this.sectionRowsCount = [...Array(sectionCount).keys()].map(e => numberOfSection(e)) + } + + private getItem(sectionIdx: number, itemIdx: number) { + let view = this.cachedViews.get(`${sectionIdx}:${itemIdx}`) + if (view === undefined) { + view = this.renderItem(sectionIdx, itemIdx) + this.cachedViews.set(`${sectionIdx}:${itemIdx}`, view) + } + return view + } + + private getSectionHeader(sectionIdx: number) { + let view = this.cachedViews.get(`${sectionIdx}:`) + if (view === undefined) { + view = this.renderSectionHeader(sectionIdx) + this.cachedViews.set(`${sectionIdx}:`, view) + } + return view + } + + @Property + private renderBunchedItems(items: Array<{ itemIdx: number, sectionIdx: number }>, + headers: number[]): { items: View[], headers: View[] } { + return { + items: items.map(e => this.getItem(e.sectionIdx, e.itemIdx)), + headers: headers.map(e => this.getSectionHeader(e)) + } + } } export class Slide extends View { From da8cf72a0d85ae14922328fa1c8125981c0360d1 Mon Sep 17 00:00:00 2001 From: "pengfei.zhou" Date: Wed, 23 Oct 2019 14:14:33 +0800 Subject: [PATCH 4/9] add Slide api --- js-framework/src/ui/view.ts | 44 +++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/js-framework/src/ui/view.ts b/js-framework/src/ui/view.ts index 45e08476..4a27e971 100644 --- a/js-framework/src/ui/view.ts +++ b/js-framework/src/ui/view.ts @@ -207,7 +207,13 @@ export abstract class View implements Modeling { toModel() { return this.nativeViewModel } - + let(block: (it: this) => void) { + block(this) + } + also(block: (it: this) => void) { + block(this) + return this + } } export interface Config { @@ -342,8 +348,13 @@ export class Image extends View { imageUrl?: string } -export class List extends View { +export class List extends View implements SuperView { private cachedViews: Map = new Map + + subViewById(id: string): View | undefined { + return this.cachedViews.get(id) + } + @Property itemCount = 0 @@ -366,9 +377,12 @@ export class List extends View { } } -export class SectionList extends View { +export class SectionList extends View implements SuperView { private cachedViews: Map = new Map + subViewById(id: string): View | undefined { + return this.cachedViews.get(id) + } @Property sectionRowsCount: number[] = [] @@ -413,8 +427,30 @@ export class SectionList extends View { } } -export class Slide extends View { +export class Slide extends View implements SuperView { + @Property + pageCount = 0 + @Property + renderPage!: (pageIdx: number) => View + + private cachedViews: Map = new Map + subViewById(id: string): View | undefined { + return this.cachedViews.get(id) + } + private getPage(pageIdx: number) { + let view = this.cachedViews.get(`${pageIdx}`) + if (view === undefined) { + view = this.renderPage(pageIdx) + this.cachedViews.set(`${pageIdx}`, view) + } + return view + } + + @Property + private renderBunchedPages(pages: number[]): View[] { + return pages.map(e => this.getPage(e)) + } } export function stack() { From eeed67b57a1a073cbea280e9b34662e4cd9c7771 Mon Sep 17 00:00:00 2001 From: "pengfei.zhou" Date: Wed, 23 Oct 2019 14:18:50 +0800 Subject: [PATCH 5/9] add Scroller api --- js-framework/src/ui/view.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/js-framework/src/ui/view.ts b/js-framework/src/ui/view.ts index 4a27e971..9a8d5959 100644 --- a/js-framework/src/ui/view.ts +++ b/js-framework/src/ui/view.ts @@ -309,6 +309,16 @@ export class Stack extends Group { @Property gravity?: Gravity } + +export class Scroller extends View implements SuperView { + @Property + contentView?: View + + subViewById(id: string): View | undefined { + return this.contentView + } +} + export class Root extends Stack { } @@ -453,6 +463,8 @@ export class Slide extends View implements SuperView { } } + + export function stack() { } From f78f3ed7d840bc5f2e36449d8f22fdc1ccf0d622 Mon Sep 17 00:00:00 2001 From: "pengfei.zhou" Date: Wed, 23 Oct 2019 15:59:55 +0800 Subject: [PATCH 6/9] feat:complete defination of LayoutConfig --- Android/doric/build.gradle | 2 +- .../java/pub/doric/engine/DoricJSEngine.java | 4 +- .../main/java/pub/doric/shader/GroupNode.java | 32 ++++++- .../java/pub/doric/shader/LinearNode.java | 2 +- .../main/java/pub/doric/shader/StackNode.java | 2 +- .../main/java/pub/doric/shader/ViewNode.java | 8 +- demo/src/Counter.ts | 6 +- demo/src/Snake.ts | 39 +++++++-- js-framework/src/ui/panel.ts | 2 +- js-framework/src/ui/view.ts | 83 +++++++------------ 10 files changed, 107 insertions(+), 73 deletions(-) diff --git a/Android/doric/build.gradle b/Android/doric/build.gradle index 06e6b084..43aa1284 100644 --- a/Android/doric/build.gradle +++ b/Android/doric/build.gradle @@ -26,7 +26,7 @@ android { afterEvaluate { buildJSBundle.exec() buildDemo.exec() - buildDebugger.exec() + //buildDebugger.exec() } task buildJSBundle(type: Exec) { diff --git a/Android/doric/src/main/java/pub/doric/engine/DoricJSEngine.java b/Android/doric/src/main/java/pub/doric/engine/DoricJSEngine.java index 20acbb84..c7cc65e0 100644 --- a/Android/doric/src/main/java/pub/doric/engine/DoricJSEngine.java +++ b/Android/doric/src/main/java/pub/doric/engine/DoricJSEngine.java @@ -67,8 +67,8 @@ public class DoricJSEngine implements Handler.Callback, DoricTimerExtension.Time private void initJSExecutor() { -// mDoricJSE = new DoricNativeJSExecutor(); - mDoricJSE = new DoricRemoteJSExecutor(); + mDoricJSE = new DoricNativeJSExecutor(); +// mDoricJSE = new DoricRemoteJSExecutor(); mDoricJSE.injectGlobalJSFunction(DoricConstant.INJECT_LOG, new JavaFunction() { @Override public JavaValue exec(JSDecoder[] args) { diff --git a/Android/doric/src/main/java/pub/doric/shader/GroupNode.java b/Android/doric/src/main/java/pub/doric/shader/GroupNode.java index bfe28c75..81cd53b5 100644 --- a/Android/doric/src/main/java/pub/doric/shader/GroupNode.java +++ b/Android/doric/src/main/java/pub/doric/shader/GroupNode.java @@ -116,12 +116,42 @@ public abstract class GroupNode extends ViewNode { } protected ViewGroup.LayoutParams generateDefaultLayoutParams() { - return new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + return new ViewGroup.LayoutParams(0, 0); } protected void blendChild(ViewNode viewNode, JSObject jsObject) { + + JSValue jsValue = jsObject.getProperty("margin"); + JSValue widthSpec = jsObject.getProperty("widthSpec"); + JSValue heightSpec = jsObject.getProperty("widthSpec"); + ViewGroup.LayoutParams layoutParams = viewNode.getLayoutParams(); + if (widthSpec.isNumber()) { + switch (widthSpec.asNumber().toInt()) { + case 1: + layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT; + break; + case 2: + layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT; + break; + default: + break; + + } + } + if (heightSpec.isNumber()) { + switch (heightSpec.asNumber().toInt()) { + case 1: + layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT; + break; + case 2: + layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT; + break; + default: + break; + } + } if (jsValue.isObject() && layoutParams instanceof ViewGroup.MarginLayoutParams) { JSValue topVal = jsValue.asObject().getProperty("top"); if (topVal.isNumber()) { diff --git a/Android/doric/src/main/java/pub/doric/shader/LinearNode.java b/Android/doric/src/main/java/pub/doric/shader/LinearNode.java index 2a54cd00..80e7bb24 100644 --- a/Android/doric/src/main/java/pub/doric/shader/LinearNode.java +++ b/Android/doric/src/main/java/pub/doric/shader/LinearNode.java @@ -50,7 +50,7 @@ public class LinearNode extends GroupNode { @Override protected ViewGroup.LayoutParams generateDefaultLayoutParams() { - return new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + return new LinearLayout.LayoutParams(0, 0); } @Override 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 ff5417d6..4c781889 100644 --- a/Android/doric/src/main/java/pub/doric/shader/StackNode.java +++ b/Android/doric/src/main/java/pub/doric/shader/StackNode.java @@ -62,6 +62,6 @@ public class StackNode extends GroupNode { @Override protected ViewGroup.LayoutParams generateDefaultLayoutParams() { - return new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + return new FrameLayout.LayoutParams(0, 0); } } 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 e03d3ad6..6f3bda4d 100644 --- a/Android/doric/src/main/java/pub/doric/shader/ViewNode.java +++ b/Android/doric/src/main/java/pub/doric/shader/ViewNode.java @@ -86,16 +86,12 @@ public abstract class ViewNode extends DoricContextHolder { protected void blend(T view, ViewGroup.LayoutParams layoutParams, String name, JSValue prop) { switch (name) { case "width": - if (prop.asNumber().toInt() < 0) { - layoutParams.width = prop.asNumber().toInt(); - } else { + if (layoutParams.width >= 0) { layoutParams.width = DoricUtils.dp2px(prop.asNumber().toFloat()); } break; case "height": - if (prop.asNumber().toInt() < 0) { - layoutParams.height = prop.asNumber().toInt(); - } else { + if (layoutParams.height >= 0) { layoutParams.height = DoricUtils.dp2px(prop.asNumber().toFloat()); } break; diff --git a/demo/src/Counter.ts b/demo/src/Counter.ts index 8107b065..5da84dc6 100644 --- a/demo/src/Counter.ts +++ b/demo/src/Counter.ts @@ -1,4 +1,4 @@ -import { Image, ViewHolder, VMPanel, ViewModel, Gravity, NativeCall, Text, Color, VLayout, log, logw, loge, Group, } from "doric" +import { Image, ViewHolder, VMPanel, ViewModel, Gravity, NativeCall, Text, Color, VLayout, log, logw, loge, Group, LayoutSpec, } from "doric" interface CountModel { @@ -57,6 +57,10 @@ class CounterView extends ViewHolder { // iv.width = iv.height = 100 iv.imageUrl = "https://misc.aotu.io/ONE-SUNDAY/SteamEngine.png" //iv.bgColor = Color.parse('#00ff00') + iv.layoutConfig = { + widthSpec: LayoutSpec.WRAP_CONTENT, + heightSpec: LayoutSpec.WRAP_CONTENT, + } root.addChild(iv) } diff --git a/demo/src/Snake.ts b/demo/src/Snake.ts index 68e6bde8..617d0306 100644 --- a/demo/src/Snake.ts +++ b/demo/src/Snake.ts @@ -1,4 +1,4 @@ -import { loge, log, ViewHolder, Stack, ViewModel, Gravity, Text, Color, HLayout, VLayout, Group, VMPanel } from "doric"; +import { loge, log, ViewHolder, Stack, ViewModel, Gravity, Text, Color, HLayout, VLayout, Group, VMPanel, LayoutSpec } from "doric"; type SnakeNode = { x: number @@ -154,10 +154,14 @@ class SnakeView extends ViewHolder { margin: { top: 20 }, + widthSpec: LayoutSpec.WRAP_CONTENT, + heightSpec: LayoutSpec.WRAP_CONTENT, } vlayout.space = 20 vlayout.layoutConfig = { - alignment: new Gravity().centerX().top() + alignment: new Gravity().centerX().top(), + widthSpec: LayoutSpec.WRAP_CONTENT, + heightSpec: LayoutSpec.WRAP_CONTENT, } this.panel.bgColor = Color.parse('#00ff00') vlayout.addChild(title) @@ -165,11 +169,20 @@ class SnakeView extends ViewHolder { root.addChild(vlayout) const hlayout = new HLayout - this.start.text = "Start" - this.start.textSize = 30 - this.start.textColor = Color.parse("#ffffff") - - hlayout.addChild(this.start) + hlayout.layoutConfig = { + widthSpec: LayoutSpec.WRAP_CONTENT, + heightSpec: LayoutSpec.WRAP_CONTENT, + } + hlayout.addChild(this.start.also( + it => { + it.text = "Start" + it.textSize = 30 + it.textColor = Color.parse("#ffffff") + it.layoutConfig = { + widthSpec: LayoutSpec.WRAP_CONTENT, + heightSpec: LayoutSpec.WRAP_CONTENT, + } + })) vlayout.addChild(hlayout) @@ -182,7 +195,9 @@ class SnakeView extends ViewHolder { controlArea.gravity = new Gravity().centerX() controlArea.space = 10 controlArea.layoutConfig = { - alignment: new Gravity().centerX() + alignment: new Gravity().centerX(), + widthSpec: LayoutSpec.WRAP_CONTENT, + heightSpec: LayoutSpec.WRAP_CONTENT, } const line1 = new HLayout const line2 = new HLayout @@ -191,6 +206,14 @@ class SnakeView extends ViewHolder { line2.addChild(this.left) line2.addChild(this.down) line2.addChild(this.right) + line1.layoutConfig = { + widthSpec: LayoutSpec.WRAP_CONTENT, + heightSpec: LayoutSpec.WRAP_CONTENT, + } + line2.layoutConfig = { + widthSpec: LayoutSpec.WRAP_CONTENT, + heightSpec: LayoutSpec.WRAP_CONTENT, + } controlArea.addChild(line1) controlArea.addChild(line2) vlayout.addChild(controlArea) diff --git a/js-framework/src/ui/panel.ts b/js-framework/src/ui/panel.ts index 5c3708de..e2abef1e 100644 --- a/js-framework/src/ui/panel.ts +++ b/js-framework/src/ui/panel.ts @@ -99,7 +99,7 @@ export abstract class Panel { private retrospectView(ids: string[]): View { return ids.reduce((acc: View, cur) => { if (Reflect.has(acc, "subViewById")) { - return Reflect.get(acc, "subViewById")(cur) + return Reflect.apply(Reflect.get(acc, "subViewById"), acc, [cur]) } return acc }, this.__root__) diff --git a/js-framework/src/ui/view.ts b/js-framework/src/ui/view.ts index 9a8d5959..b222309e 100644 --- a/js-framework/src/ui/view.ts +++ b/js-framework/src/ui/view.ts @@ -19,9 +19,25 @@ import { uniqueId } from "../util/uniqueId"; import { Gravity } from "../util/gravity"; import { loge } from "../util/log"; -export const MATCH_PARENT = -1 +export enum LayoutSpec { + EXACTLY = 0, + WRAP_CONTENT = 1, + AT_MOST = 2, +} + +export interface LayoutConfig { + widthSpec?: LayoutSpec + heightSpec?: LayoutSpec + margin?: { + left?: number, + right?: number, + top?: number, + bottom?: number, + } + alignment?: Gravity +} + -export const WRAP_CONTENT = -2 export function Property(target: Object, propKey: string) { Reflect.defineMetadata(propKey, true, target) @@ -29,10 +45,10 @@ export function Property(target: Object, propKey: string) { export abstract class View implements Modeling { @Property - width: number = WRAP_CONTENT + width: number = 0 @Property - height: number = WRAP_CONTENT + height: number = 0 @Property x: number = 0 @@ -70,7 +86,7 @@ export abstract class View implements Modeling { } @Property - layoutConfig?: Config + layoutConfig?: LayoutConfig @Property onClick?: Function @@ -216,21 +232,11 @@ export abstract class View implements Modeling { } } -export interface Config { - margin?: { - left?: number, - right?: number, - top?: number, - bottom?: number, - } - alignment?: Gravity -} - -export interface StackConfig extends Config { +export interface StackConfig extends LayoutConfig { } -export interface LinearConfig extends Config { +export interface LinearConfig extends LayoutConfig { weight?: number } @@ -239,16 +245,6 @@ export interface SuperView { } export abstract class Group extends View implements SuperView { - - subViewById(id: string): View | undefined { - for (let view of this.children) { - if (view.viewId === id) { - return view - } - } - return undefined - } - @Property readonly children: View[] = new Proxy([], { set: (target, index, value) => { @@ -269,6 +265,14 @@ export abstract class Group extends View implements SuperView { } }) + subViewById(id: string): View | undefined { + for (let view of this.children) { + if (view.viewId === id) { + return view + } + } + return undefined + } addChild(view: View) { this.children.push(view) } @@ -461,27 +465,4 @@ export class Slide extends View implements SuperView { private renderBunchedPages(pages: number[]): View[] { return pages.map(e => this.getPage(e)) } -} - - - -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 -} +} \ No newline at end of file From c2e3ef4f7e7ab17caaf7b336b0e3a83034c97078 Mon Sep 17 00:00:00 2001 From: "pengfei.zhou" Date: Wed, 23 Oct 2019 19:37:06 +0800 Subject: [PATCH 7/9] feat:iOS LinearLayout and adapt new layoutconfig --- iOS/Example/Example/ViewController.m | 13 +- iOS/Example/Podfile.lock | 2 +- iOS/Pod/Classes/DoricContext.h | 2 +- iOS/Pod/Classes/DoricContext.m | 9 +- iOS/Pod/Classes/Shader/DoricGroupNode.h | 6 +- iOS/Pod/Classes/Shader/DoricGroupNode.m | 41 +- iOS/Pod/Classes/Shader/DoricHLayoutNode.h | 8 +- iOS/Pod/Classes/Shader/DoricHLayoutNode.m | 110 +---- iOS/Pod/Classes/Shader/DoricImageNode.m | 8 - iOS/Pod/Classes/Shader/DoricLinearLayout.h | 117 +++++ iOS/Pod/Classes/Shader/DoricLinearLayout.m | 505 ++++++++++++++++++++ iOS/Pod/Classes/Shader/DoricRootNode.h | 2 +- iOS/Pod/Classes/Shader/DoricRootNode.m | 8 +- iOS/Pod/Classes/Shader/DoricStackNode.h | 7 +- iOS/Pod/Classes/Shader/DoricStackNode.m | 92 +--- iOS/Pod/Classes/Shader/DoricTextNode.m | 10 +- iOS/Pod/Classes/Shader/DoricVLayoutNode.h | 8 +- iOS/Pod/Classes/Shader/DoricVLayoutNode.m | 101 +--- iOS/Pod/Classes/Shader/DoricViewContainer.h | 101 ---- iOS/Pod/Classes/Shader/DoricViewContainer.m | 108 ----- iOS/Pod/Classes/Shader/DoricViewNode.h | 23 +- iOS/Pod/Classes/Shader/DoricViewNode.m | 151 +----- iOS/Pod/Classes/{ => Shader}/UIView+Doric.h | 0 iOS/Pod/Classes/{ => Shader}/UIView+Doric.m | 0 iOS/Pod/Classes/Util/DoricExtensions.h | 29 ++ iOS/Pod/Classes/Util/DoricExtensions.m | 35 ++ 26 files changed, 813 insertions(+), 683 deletions(-) create mode 100644 iOS/Pod/Classes/Shader/DoricLinearLayout.h create mode 100644 iOS/Pod/Classes/Shader/DoricLinearLayout.m delete mode 100644 iOS/Pod/Classes/Shader/DoricViewContainer.h delete mode 100644 iOS/Pod/Classes/Shader/DoricViewContainer.m rename iOS/Pod/Classes/{ => Shader}/UIView+Doric.h (100%) rename iOS/Pod/Classes/{ => Shader}/UIView+Doric.m (100%) create mode 100644 iOS/Pod/Classes/Util/DoricExtensions.h create mode 100644 iOS/Pod/Classes/Util/DoricExtensions.m diff --git a/iOS/Example/Example/ViewController.m b/iOS/Example/Example/ViewController.m index dabf77b3..806bc11d 100644 --- a/iOS/Example/Example/ViewController.m +++ b/iOS/Example/Example/ViewController.m @@ -13,21 +13,26 @@ #import "DoricNativePlugin.h" #import "DoricRootNode.h" #import "DoricLocalServer.h" +#import "DoricLinearLayout.h" +#import "DoricExtensions.h" @interface ViewController () -@property (nonatomic,strong) DoricContext *doricContext; -@property (nonatomic,strong) DoricLocalServer *localServer; +@property(nonatomic, strong) DoricContext *doricContext; +@property(nonatomic, strong) DoricLocalServer *localServer; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; - + NSString *path = [[NSBundle bundleForClass:[self class]] pathForResource:@"Snake" ofType:@"js"]; NSString *jsContent = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil]; self.doricContext = [[DoricContext alloc] initWithScript:jsContent source:@"test.js"]; - self.doricContext.rootNode.view = self.view; + [self.doricContext.rootNode setupRootView:[[Stack new] also:^(Stack *it) { + it.layoutConfig = [[StackLayoutConfig alloc] initWithWidth:LayoutParamAtMost height:LayoutParamAtMost]; + [self.view addSubview:it]; + }]]; [self.doricContext initContextWithWidth:self.view.width height:self.view.height]; [self.doricContext.driver connectDevKit:@"ws://192.168.11.38:7777"]; self.localServer = [[DoricLocalServer alloc] init]; diff --git a/iOS/Example/Podfile.lock b/iOS/Example/Podfile.lock index 9c0eaa93..a41b13c0 100644 --- a/iOS/Example/Podfile.lock +++ b/iOS/Example/Podfile.lock @@ -25,7 +25,7 @@ EXTERNAL SOURCES: :path: "../" SPEC CHECKSUMS: - Doric: 1dae6e8a19a32a27af975f787509cc0658dde095 + Doric: f96b77d435e836e88cf02319e3c9ebc08cab65f6 GCDWebServer: ead88cd14596dd4eae4f5830b8877c87c8728990 SDWebImage: 920f1a2ff1ca8296ad34f6e0510a1ef1d70ac965 SocketRocket: d57c7159b83c3c6655745cd15302aa24b6bae531 diff --git a/iOS/Pod/Classes/DoricContext.h b/iOS/Pod/Classes/DoricContext.h index 0829fff0..6607ba4b 100644 --- a/iOS/Pod/Classes/DoricContext.h +++ b/iOS/Pod/Classes/DoricContext.h @@ -35,7 +35,7 @@ NS_ASSUME_NONNULL_BEGIN @property(nonatomic, strong) DoricRootNode *rootNode; @property(nonatomic, strong) NSString *source; @property(nonatomic, strong) NSString *script;; -@property(nonatomic, strong) NSDictionary *initialParams; +@property(nonatomic, strong) NSMutableDictionary *initialParams; - (instancetype)initWithScript:(NSString *)script source:(NSString *)source; diff --git a/iOS/Pod/Classes/DoricContext.m b/iOS/Pod/Classes/DoricContext.m index 222b131d..fa07d1df 100644 --- a/iOS/Pod/Classes/DoricContext.m +++ b/iOS/Pod/Classes/DoricContext.m @@ -24,6 +24,7 @@ #import "DoricContextManager.h" #import "DoricRootNode.h" #import "DoricConstant.h" +#import "DoricExtensions.h" @implementation DoricContext @@ -35,7 +36,7 @@ - (instancetype)initWithScript:(NSString *)script source:(NSString *)source { _rootNode = [[DoricRootNode alloc] initWithContext:self]; _script = script; _source = source; - _initialParams = [@{@"width": @(LAYOUT_MATCH_PARENT), @"height": @(LAYOUT_MATCH_PARENT)} mutableCopy]; + _initialParams = [@{@"width": @(0), @"height": @(0)} mutableCopy]; [self callEntity:DORIC_ENTITY_CREATE, nil]; } return self; @@ -63,8 +64,10 @@ - (DoricAsyncResult *)callEntity:(NSString *)method withArgumentsArray:(NSArray } - (void)initContextWithWidth:(CGFloat)width height:(CGFloat)height { - [self.initialParams setValue:@(width) forKey:@"width"]; - [self.initialParams setValue:@(height) forKey:@"height"]; + [self.initialParams also:^(NSMutableDictionary *it) { + it[@"width"] = @(width); + it[@"height"] = @(height); + }]; [self callEntity:DORIC_ENTITY_INIT, self.initialParams, nil]; } diff --git a/iOS/Pod/Classes/Shader/DoricGroupNode.h b/iOS/Pod/Classes/Shader/DoricGroupNode.h index cd15a6bc..fe717a3a 100644 --- a/iOS/Pod/Classes/Shader/DoricGroupNode.h +++ b/iOS/Pod/Classes/Shader/DoricGroupNode.h @@ -24,15 +24,13 @@ NS_ASSUME_NONNULL_BEGIN -@interface DoricGroupNode : DoricViewNode +@interface DoricGroupNode : DoricViewNode @property(nonatomic, strong) NSMutableDictionary *children; @property(nonatomic, strong) NSMutableArray *indexedChildren; -@property(nonatomic) CGFloat desiredWidth; -@property(nonatomic) CGFloat desiredHeight; -- (void)blendChild:(DoricViewNode *)child layoutConfig:(NSDictionary *)layoutconfig; +- (void)blendChild:(DoricViewNode *)child layoutConfig:(NSDictionary *)layoutConfig; - (P)generateDefaultLayoutParams; @end diff --git a/iOS/Pod/Classes/Shader/DoricGroupNode.m b/iOS/Pod/Classes/Shader/DoricGroupNode.m index 0aefa8dc..ba5c6764 100644 --- a/iOS/Pod/Classes/Shader/DoricGroupNode.m +++ b/iOS/Pod/Classes/Shader/DoricGroupNode.m @@ -20,6 +20,7 @@ // Created by pengfei.zhou on 2019/7/30. // +#import #import "DoricGroupNode.h" @implementation DoricGroupNode @@ -72,10 +73,10 @@ - (void)blendView:(UIView *)view forPropName:(NSString *)name propValue:(id)prop [tobeRemoved addObject:old]; } - LayoutParams *params = node.layoutParams; + LayoutConfig *params = node.layoutConfig; if (params == nil) { params = [self generateDefaultLayoutParams]; - node.layoutParams = params; + node.layoutConfig = params; } [node blend:val[@"props"]]; if (self.indexedChildren.count <= i) { @@ -108,21 +109,35 @@ - (void)blendView:(UIView *)view forPropName:(NSString *)name propValue:(id)prop } } -- (LayoutParams *)generateDefaultLayoutParams { - LayoutParams *params = [[LayoutParams alloc] init]; +- (LayoutConfig *)generateDefaultLayoutParams { + LayoutConfig *params = [[LayoutConfig alloc] init]; return params; } -- (void)blendChild:(DoricViewNode *)child layoutConfig:(NSDictionary *)layoutconfig { - LayoutParams *params = child.layoutParams; - if ([params isKindOfClass:MarginLayoutParams.class]) { - MarginLayoutParams *marginParams = (MarginLayoutParams *) params; - NSDictionary *margin = layoutconfig[@"margin"]; +- (void)blendChild:(DoricViewNode *)child layoutConfig:(NSDictionary *)layoutConfig { + LayoutConfig *params = child.layoutConfig; + + [layoutConfig[@"widthSpec"] also:^(NSNumber *it) { + if (it) { + params.widthSpec = (LayoutParam) [it integerValue]; + } + }]; + + [layoutConfig[@"heightSpec"] also:^(NSNumber *it) { + if (it) { + params.heightSpec = (LayoutParam) [it integerValue]; + } + }]; + + if ([params isKindOfClass:MarginLayoutConfig.class]) { + MarginLayoutConfig *marginParams = (MarginLayoutConfig *) params; + NSDictionary *margin = layoutConfig[@"margin"]; if (margin) { - marginParams.margin.top = [(NSNumber *) margin[@"top"] floatValue]; - marginParams.margin.left = [(NSNumber *) margin[@"left"] floatValue]; - marginParams.margin.right = [(NSNumber *) margin[@"right"] floatValue]; - marginParams.margin.bottom = [(NSNumber *) margin[@"bottom"] floatValue]; + marginParams.margin = MarginMake( + [(NSNumber *) margin[@"left"] floatValue], + [(NSNumber *) margin[@"top"] floatValue], + [(NSNumber *) margin[@"right"] floatValue], + [(NSNumber *) margin[@"bottom"] floatValue]); } } diff --git a/iOS/Pod/Classes/Shader/DoricHLayoutNode.h b/iOS/Pod/Classes/Shader/DoricHLayoutNode.h index 458546f7..d429f102 100644 --- a/iOS/Pod/Classes/Shader/DoricHLayoutNode.h +++ b/iOS/Pod/Classes/Shader/DoricHLayoutNode.h @@ -22,11 +22,5 @@ #import "DoricGroupNode.h" -NS_ASSUME_NONNULL_BEGIN - -@interface DoricHLayoutNode : DoricGroupNode -@property(nonatomic) CGFloat space; -@property(nonatomic) DoricGravity gravity; +@interface DoricHLayoutNode : DoricGroupNode @end - -NS_ASSUME_NONNULL_END diff --git a/iOS/Pod/Classes/Shader/DoricHLayoutNode.m b/iOS/Pod/Classes/Shader/DoricHLayoutNode.m index 26fb4d06..29d6a639 100644 --- a/iOS/Pod/Classes/Shader/DoricHLayoutNode.m +++ b/iOS/Pod/Classes/Shader/DoricHLayoutNode.m @@ -24,114 +24,42 @@ #import "DoricUtil.h" @implementation DoricHLayoutNode -- (instancetype)init { - if (self = [super init]) { - _space = 0; - _gravity = 0; - } - return self; +- (HLayout *)build:(NSDictionary *)props { + return [HLayout new]; } -- (void)blendView:(id)view forPropName:(NSString *)name propValue:(id)prop { +- (void)blendView:(HLayout *)view forPropName:(NSString *)name propValue:(id)prop { if ([name isEqualToString:@"gravity"]) { - self.gravity = [(NSNumber *)prop integerValue]; + view.gravity = (DoricGravity) [(NSNumber *) prop integerValue]; } else if ([name isEqualToString:@"space"]) { - self.space = [(NSNumber *)prop floatValue]; + view.space = [(NSNumber *) prop floatValue]; } else { [super blendView:view forPropName:name propValue:prop]; } } -- (void)blendChild:(DoricViewNode *)child layoutConfig:(NSDictionary *)layoutconfig { - [super blendChild:child layoutConfig:layoutconfig]; - if (![child.layoutParams isKindOfClass:VHLayoutParams.class]) { +- (void)blendChild:(DoricViewNode *)child layoutConfig:(NSDictionary *)layoutConfig { + [super blendChild:child layoutConfig:layoutConfig]; + if (![child.layoutConfig isKindOfClass:LinearLayoutConfig.class]) { DoricLog(@"blend HLayout child error,layout params not match"); return; } - VHLayoutParams *params = (VHLayoutParams *)child.layoutParams; - NSDictionary *margin = [layoutconfig objectForKey:@"margin"]; + LinearLayoutConfig *params = (LinearLayoutConfig *) child.layoutConfig; + NSDictionary *margin = layoutConfig[@"margin"]; if (margin) { - params.margin.top = [(NSNumber *)[margin objectForKey:@"top"] floatValue]; - params.margin.left = [(NSNumber *)[margin objectForKey:@"left"] floatValue]; - params.margin.right = [(NSNumber *)[margin objectForKey:@"right"] floatValue]; - params.margin.bottom = [(NSNumber *)[margin objectForKey:@"bottom"] floatValue]; + params.margin = MarginMake( + [(NSNumber *) margin[@"left"] floatValue], + [(NSNumber *) margin[@"top"] floatValue], + [(NSNumber *) margin[@"right"] floatValue], + [(NSNumber *) margin[@"bottom"] floatValue]); } - NSNumber *alignment = [layoutconfig objectForKey:@"alignment"]; + NSNumber *alignment = layoutConfig[@"alignment"]; if (alignment) { - params.alignment = [alignment integerValue]; + params.alignment = (DoricGravity) [alignment integerValue]; } } -- (VHLayoutParams *)generateDefaultLayoutParams { - return [[VHLayoutParams alloc] init]; +- (LinearLayoutConfig *)generateDefaultLayoutParams { + return [[LinearLayoutConfig alloc] init]; } - -- (void)measureByParent:(DoricGroupNode *)parent { - DoricLayoutDesc widthSpec = self.layoutParams.width; - DoricLayoutDesc heightSpec = self.layoutParams.height; - CGFloat maxWidth = 0,maxHeight = 0; - for (DoricViewNode *child in self.indexedChildren) { - [child measureByParent:self]; - CGFloat placeWidth = child.measuredWidth; - CGFloat placeHeight = child.measuredHeight; - maxWidth += placeWidth + self.space; - maxHeight = MAX(maxHeight, placeHeight); - } - - maxWidth -= self.space; - - self.desiredWidth = maxWidth; - self.desiredHeight = maxHeight; - - if (widthSpec == LAYOUT_WRAP_CONTENT) { - self.width = maxWidth; - } - - if (heightSpec == LAYOUT_WRAP_CONTENT) { - self.height = maxHeight; - } -} - -- (void)layoutByParent:(DoricGroupNode *)parent { - if (self.layoutParams.width == LAYOUT_MATCH_PARENT) { - self.width = parent.width; - } - if (self.layoutParams.height == LAYOUT_MATCH_PARENT) { - self.height = parent.height; - } - // layout child - CGFloat xStart = 0; - if ((self.gravity & LEFT) == LEFT) { - xStart = 0; - } else if ((self.gravity & RIGHT) == RIGHT) { - xStart = self.width - self.desiredWidth; - } else if ((self.gravity & CENTER_X) == CENTER_X) { - xStart = (self.width -self.desiredWidth)/2; - } - - for (DoricViewNode *child in self.indexedChildren) { - if (child.layoutParams.width == LAYOUT_MATCH_PARENT) { - child.width = self.width; - } - if (child.layoutParams.height == LAYOUT_MATCH_PARENT) { - child.height = self.height; - } - - if ([child.layoutParams isKindOfClass:VHLayoutParams.class]) { - VHLayoutParams *layoutParams = (VHLayoutParams *)child.layoutParams; - DoricGravity gravity = layoutParams.alignment | self.gravity; - if ((gravity & TOP) == TOP) { - child.top = 0; - } else if ((gravity & BOTTOM) == BOTTOM) { - child.bottom = self.height; - } else if ((gravity & CENTER_Y) == CENTER_Y) { - child.centerY = self.height/2; - } - } - child.left = xStart; - xStart = child.right + self.space; - [child layoutByParent:self]; - } -} - @end diff --git a/iOS/Pod/Classes/Shader/DoricImageNode.m b/iOS/Pod/Classes/Shader/DoricImageNode.m index 28c28195..470d8477 100644 --- a/iOS/Pod/Classes/Shader/DoricImageNode.m +++ b/iOS/Pod/Classes/Shader/DoricImageNode.m @@ -40,12 +40,4 @@ - (void)blendView:(UIImageView *)view forPropName:(NSString *)name propValue:(id [super blendView:view forPropName:name propValue:prop]; } } - -- (void)measureByParent:(DoricGroupNode *)parent { - DoricLayoutDesc widthSpec = self.layoutParams.width; - DoricLayoutDesc heightSpec = self.layoutParams.height; - if (widthSpec == LAYOUT_WRAP_CONTENT || heightSpec == LAYOUT_WRAP_CONTENT) { - [self.view sizeToFit]; - } -} @end diff --git a/iOS/Pod/Classes/Shader/DoricLinearLayout.h b/iOS/Pod/Classes/Shader/DoricLinearLayout.h new file mode 100644 index 00000000..300cd46d --- /dev/null +++ b/iOS/Pod/Classes/Shader/DoricLinearLayout.h @@ -0,0 +1,117 @@ +/* + * 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. + */ +// +// Created by pengfei.zhou on 2019/10/23. +// + +#import + + +struct Margin { + CGFloat left; + CGFloat right; + CGFloat top; + CGFloat bottom; +}; +typedef struct Margin Margin; + +Margin MarginMake(CGFloat left, CGFloat top, CGFloat right, CGFloat bottom); + +typedef NS_ENUM(NSInteger, LayoutParam) { + LayoutParamExact, + LayoutParamWrapContent, + LayoutParamAtMost, +}; + +typedef NS_ENUM(NSInteger, DoricGravity) { + SPECIFIED = 1, + START = 1 << 1, + END = 1 << 2, + SHIFT_X = 0, + SHIFT_Y = 4, + LEFT = (START | SPECIFIED) << SHIFT_X, + RIGHT = (END | SPECIFIED) << SHIFT_X, + TOP = (START | SPECIFIED) << SHIFT_Y, + BOTTOM = (END | SPECIFIED) << SHIFT_Y, + CENTER_X = SPECIFIED << SHIFT_X, + CENTER_Y = SPECIFIED << SHIFT_Y, + CENTER = CENTER_X | CENTER_Y, +}; + +@interface LayoutConfig : NSObject +@property(nonatomic, assign) LayoutParam widthSpec; +@property(nonatomic, assign) LayoutParam heightSpec; +@property(nonatomic, assign) DoricGravity alignment; + +- (instancetype)init; + +- (instancetype)initWithWidth:(LayoutParam)width height:(LayoutParam)height; + +@end + +@interface StackLayoutConfig : LayoutConfig +@end + +@interface MarginLayoutConfig : LayoutConfig +@property(nonatomic) Margin margin; + +- (instancetype)initWithWidth:(LayoutParam)width height:(LayoutParam)height margin:(Margin)margin; +@end + +@interface LinearLayoutConfig : MarginLayoutConfig +@property(nonatomic, assign) NSUInteger weight; +@end + + +@interface LayoutContainer : UIView + +- (T)configForChild:(__kindof UIView *)child; + +- (void)layout; + +- (void)requestLayout; +@end + +@interface Stack : LayoutContainer +@property(nonatomic, assign) DoricGravity gravity; +@end + +@interface LinearLayout : LayoutContainer +@property(nonatomic, assign) DoricGravity gravity; +@property(nonatomic, assign) CGFloat space; +@end + + +@interface VLayout : LinearLayout +@end + +@interface HLayout : LinearLayout +@end + +@interface UIView (LayoutConfig) +@property(nonatomic, strong) LayoutConfig *layoutConfig; +@property(nonatomic, copy) NSString *tagString; + +- (UIView *)viewWithTagString:(NSString *)tagString; +@end + +VLayout *vLayout(NSArray <__kindof UIView *> *views); + +HLayout *hLayout(NSArray <__kindof UIView *> *views); + +VLayout *vLayoutWithBlock(NSArray *blocks); + +HLayout *hLayoutWithBlock(NSArray *blocks); diff --git a/iOS/Pod/Classes/Shader/DoricLinearLayout.m b/iOS/Pod/Classes/Shader/DoricLinearLayout.m new file mode 100644 index 00000000..7ddc1db8 --- /dev/null +++ b/iOS/Pod/Classes/Shader/DoricLinearLayout.m @@ -0,0 +1,505 @@ +/* + * 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. + */ +// +// Created by pengfei.zhou on 2019/10/23. +// + +#import "DoricLinearLayout.h" +#import +#import "UIView+Doric.h" + +Margin MarginMake(CGFloat left, CGFloat top, CGFloat right, CGFloat bottom) { + Margin margin; + margin.left = left; + margin.top = top; + margin.right = right; + margin.bottom = bottom; + return margin; +} + +@implementation LayoutConfig +- (instancetype)init { + if (self = [super init]) { + _widthSpec = LayoutParamExact; + _heightSpec = LayoutParamExact; + } + return self; +} + +- (instancetype)initWithWidth:(LayoutParam)width height:(LayoutParam)height { + if (self = [super init]) { + _widthSpec = width; + _heightSpec = height; + } + return self; +} +@end + +@implementation MarginLayoutConfig +- (instancetype)init { + if (self = [super init]) { + _margin = MarginMake(0, 0, 0, 0); + } + return self; +} + +- (instancetype)initWithWidth:(LayoutParam)width height:(LayoutParam)height margin:(Margin)margin { + if (self = [super initWithWidth:width height:height]) { + _margin = margin; + } + return self; +} +@end + +@implementation StackLayoutConfig +@end + +@implementation LinearLayoutConfig +@end + + +@interface LayoutContainer () +@property(nonatomic, assign) BOOL waitingLayout; +@end + +@implementation LayoutContainer +- (instancetype)init { + if (self = [super init]) { + _waitingLayout = NO; + } + return self; +} + +- (instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + _waitingLayout = NO; + } + return self; +} + +- (instancetype)initWithCoder:(NSCoder *)coder { + if (self = [super initWithCoder:coder]) { + _waitingLayout = NO; + } + return self; +} + + +- (LayoutConfig *)configForChild:(UIView *)child { + LayoutConfig *config = child.layoutConfig; + if (!config) { + config = [[LayoutConfig alloc] init]; + } + return config; +} + +- (void)requestLayout { + if ([self.superview isKindOfClass:[LinearLayout class]]) { + [(LinearLayout *) self.superview requestLayout]; + return; + } + if (self.waitingLayout) { + return; + } + self.waitingLayout = YES; + dispatch_async(dispatch_get_main_queue(), ^{ + self.waitingLayout = NO; + [self sizeToFit]; + [self layout]; + }); +} + +- (void)layoutSubviews { + [super layoutSubviews]; + [self requestLayout]; +} + +- (void)layout { + [self.subviews enumerateObjectsUsingBlock:^(__kindof UIView *child, NSUInteger idx, BOOL *stop) { + if ([child isKindOfClass:[LayoutContainer class]]) { + [(LayoutContainer *) child layout]; + } + }]; +} + +@end + + +@interface Stack () + +@property(nonatomic, assign) CGFloat contentWidth; +@property(nonatomic, assign) CGFloat contentHeight; +@end + +@implementation Stack +- (StackLayoutConfig *)configForChild:(UIView *)child { + StackLayoutConfig *config = (StackLayoutConfig *) child.layoutConfig; + if (!config) { + config = [[StackLayoutConfig alloc] init]; + } + return config; +} + + +- (void)sizeToFit { + LayoutConfig *config = self.layoutConfig; + self.contentWidth = 0; + self.contentHeight = 0; + for (UIView *child in self.subviews) { + if (child.isHidden) { + continue; + } + StackLayoutConfig *childConfig = [self configForChild:child]; + if ([child isKindOfClass:[LayoutContainer class]] + || childConfig.widthSpec == LayoutParamWrapContent + || childConfig.heightSpec == LayoutParamWrapContent) { + [child sizeToFit]; + } + self.contentWidth = MAX(self.contentWidth, child.width); + self.contentHeight = MAX(self.contentHeight, child.height); + } + if (config.widthSpec == LayoutParamWrapContent) { + self.width = self.contentWidth; + } else if (config.widthSpec == LayoutParamAtMost) { + self.width = self.superview.width; + } + if (config.heightSpec == LayoutParamWrapContent) { + self.height = self.contentHeight; + } else if (config.heightSpec == LayoutParamAtMost) { + self.height = self.superview.height; + } +} + +- (void)layout { + for (UIView *child in self.subviews) { + if (child.isHidden) { + continue; + } + StackLayoutConfig *childConfig = [self configForChild:child]; + DoricGravity gravity = childConfig.alignment | self.gravity; + if ((gravity & LEFT) == LEFT) { + child.left = 0; + } else if ((gravity & RIGHT) == RIGHT) { + child.right = self.width; + } else if ((gravity & CENTER_X) == CENTER_X) { + child.centerX = self.width / 2; + } + if ((gravity & TOP) == TOP) { + child.top = 0; + } else if ((gravity & BOTTOM) == BOTTOM) { + child.bottom = self.height; + } else if ((gravity & CENTER_Y) == CENTER_Y) { + child.centerY = self.height / 2; + } + if (childConfig.widthSpec == LayoutParamAtMost) { + child.width = self.width; + } + if (childConfig.heightSpec == LayoutParamAtMost) { + child.height = self.height; + } + + if ([child isKindOfClass:[LayoutContainer class]]) { + [(LayoutContainer *) child layout]; + } + } +} +@end + +@interface LinearLayout () +@property(nonatomic, assign) CGFloat contentWidth; +@property(nonatomic, assign) CGFloat contentHeight; +@property(nonatomic, assign) NSUInteger contentWeight; +@end + +@implementation LinearLayout +- (LinearLayoutConfig *)configForChild:(UIView *)child { + LinearLayoutConfig *config = (LinearLayoutConfig *) child.layoutConfig; + if (!config) { + config = [[LinearLayoutConfig alloc] init]; + } + return config; +} +@end + +@implementation VLayout + +- (void)sizeToFit { + LayoutConfig *config = self.layoutConfig; + self.contentWidth = 0; + self.contentHeight = 0; + self.contentWeight = 0; + for (UIView *child in self.subviews) { + if (child.isHidden) { + continue; + } + LinearLayoutConfig *childConfig = [self configForChild:child]; + if ([child isKindOfClass:[LayoutContainer class]] + || childConfig.widthSpec == LayoutParamWrapContent + || childConfig.heightSpec == LayoutParamWrapContent) { + [child sizeToFit]; + } + self.contentWidth = MAX(self.contentWidth, child.width + childConfig.margin.left + childConfig.margin.right); + self.contentHeight += child.height + self.space + childConfig.margin.top + childConfig.margin.bottom; + self.contentWeight += childConfig.weight; + } + self.contentHeight -= self.space; + if (config.widthSpec == LayoutParamWrapContent) { + self.width = self.contentWidth; + } else if (config.widthSpec == LayoutParamAtMost) { + self.width = self.superview.width; + } + if (config.heightSpec == LayoutParamWrapContent) { + self.height = self.contentHeight; + } else if (config.heightSpec == LayoutParamAtMost) { + self.height = self.superview.height; + } + if (self.contentWeight) { + CGFloat remain = self.height - self.contentHeight; + for (UIView *child in self.subviews) { + if (child.isHidden) { + continue; + } + LinearLayoutConfig *childConfig = [self configForChild:child]; + if (childConfig.weight) { + child.height += remain / self.contentWeight * childConfig.weight; + } + } + self.contentHeight = self.height; + } +} + +- (void)layout { + CGFloat yStart = 0; + if ((self.gravity & TOP) == TOP) { + yStart = 0; + } else if ((self.gravity & BOTTOM) == BOTTOM) { + yStart = self.height - self.contentHeight; + } else if ((self.gravity & CENTER_Y) == CENTER_Y) { + yStart = (self.height - self.contentHeight) / 2; + } + for (UIView *child in self.subviews) { + if (child.isHidden) { + continue; + } + LinearLayoutConfig *childConfig = [self configForChild:child]; + DoricGravity gravity = childConfig.alignment | self.gravity; + if ((gravity & LEFT) == LEFT) { + child.left = 0; + } else if ((gravity & RIGHT) == RIGHT) { + child.right = self.width; + } else if ((gravity & CENTER_X) == CENTER_X) { + child.centerX = self.width / 2; + } else { + if (childConfig.margin.left) { + child.left = childConfig.margin.left; + } else if (childConfig.margin.right) { + child.right = self.width - childConfig.margin.right; + } + } + if (childConfig.widthSpec == LayoutParamAtMost) { + child.width = self.width; + } + if (childConfig.heightSpec == LayoutParamAtMost) { + child.height = self.height - yStart - childConfig.margin.top - childConfig.margin.bottom - self.space; + } + if (childConfig.margin.top) { + yStart += childConfig.margin.top; + } + child.top = yStart; + yStart = child.bottom + self.space; + if (childConfig.margin.bottom) { + yStart += childConfig.margin.bottom; + } + if ([child isKindOfClass:[LayoutContainer class]]) { + [(LayoutContainer *) child layout]; + } + } +} +@end + +@implementation HLayout +- (void)sizeToFit { + LinearLayoutConfig *config; + if ([self.superview isKindOfClass:[LinearLayout class]]) { + config = [(LinearLayout *) self.superview configForChild:self]; + } else { + config = (LinearLayoutConfig *) self.layoutConfig; + if (!config) { + config = [[LinearLayoutConfig alloc] init]; + } + } + self.contentWidth = 0; + self.contentHeight = 0; + self.contentWeight = 0; + for (UIView *child in self.subviews) { + if (child.isHidden) { + continue; + } + LinearLayoutConfig *childConfig = [self configForChild:child]; + if ([child isKindOfClass:[LayoutContainer class]] + || childConfig.widthSpec == LayoutParamWrapContent + || childConfig.heightSpec == LayoutParamWrapContent) { + [child sizeToFit]; + } + self.contentHeight = MAX(self.contentHeight, child.height + childConfig.margin.top + childConfig.margin.bottom); + self.contentWidth += child.width + self.space + childConfig.margin.left + childConfig.margin.right; + self.contentWeight += childConfig.weight; + } + self.contentWidth -= self.space; + if (config.widthSpec == LayoutParamWrapContent) { + self.width = self.contentWidth; + } else if (config.widthSpec == LayoutParamAtMost) { + self.width = self.superview.width; + } + if (config.heightSpec == LayoutParamWrapContent) { + self.height = self.contentHeight; + } else if (config.heightSpec == LayoutParamAtMost) { + self.height = self.superview.height; + } + if (self.contentWeight) { + CGFloat remain = self.width - self.contentWidth; + for (UIView *child in self.subviews) { + if (child.isHidden) { + continue; + } + LinearLayoutConfig *childConfig = [self configForChild:child]; + if (childConfig.weight) { + child.width += remain / self.contentWeight * childConfig.weight; + } + } + self.contentWidth = self.width; + } +} + +- (void)layout { + CGFloat xStart = 0; + if ((self.gravity & LEFT) == LEFT) { + xStart = 0; + } else if ((self.gravity & RIGHT) == RIGHT) { + xStart = self.width - self.contentWidth; + } else if ((self.gravity & CENTER_X) == CENTER_X) { + xStart = (self.width - self.contentWidth) / 2; + } + for (UIView *child in self.subviews) { + if (child.isHidden) { + continue; + } + LinearLayoutConfig *childConfig = [self configForChild:child]; + DoricGravity gravity = childConfig.alignment | self.gravity; + if ((gravity & TOP) == TOP) { + child.top = 0; + } else if ((gravity & BOTTOM) == BOTTOM) { + child.bottom = self.height; + } else if ((gravity & CENTER_Y) == CENTER_Y) { + child.centerY = self.height / 2; + } else { + if (childConfig.margin.top) { + child.top = childConfig.margin.top; + } else if (childConfig.margin.bottom) { + child.bottom = self.height - childConfig.margin.bottom; + } + } + + if (childConfig.heightSpec == LayoutParamAtMost) { + child.height = self.height; + } + if (childConfig.widthSpec == LayoutParamAtMost) { + child.width = self.width - xStart - childConfig.margin.right - childConfig.margin.left - self.space; + } + + if (childConfig.margin.left) { + xStart += childConfig.margin.left; + } + child.left = xStart; + xStart = child.right + self.space; + if (childConfig.margin.right) { + xStart += childConfig.margin.right; + } + if ([child isKindOfClass:[LayoutContainer class]]) { + [(LayoutContainer *) child layout]; + } + } +} +@end + +static const void *kLayoutConfig = &kLayoutConfig; +static const void *kTagString = &kTagString; + +@implementation UIView (LayoutConfig) +@dynamic layoutConfig; + +- (void)setLayoutConfig:(LayoutConfig *)layoutConfig { + objc_setAssociatedObject(self, kLayoutConfig, layoutConfig, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +- (LayoutConfig *)layoutConfig { + return objc_getAssociatedObject(self, kLayoutConfig); +} + +- (void)setTagString:(NSString *)tagString { + objc_setAssociatedObject(self, kTagString, tagString, OBJC_ASSOCIATION_COPY_NONATOMIC); + self.tag = [tagString hash]; +} + +- (NSString *)tagString { + return objc_getAssociatedObject(self, kTagString); +} + + +- (UIView *)viewWithTagString:(NSString *)tagString { + // notice the potential hash collision + return [self viewWithTag:[tagString hash]]; +} + +@end + +VLayout *vLayout(NSArray <__kindof UIView *> *views) { + VLayout *layout = [[VLayout alloc] initWithFrame:CGRectZero]; + for (__kindof UIView *uiView in views) { + [layout addSubview:uiView]; + } + layout.layoutConfig = [[LayoutConfig alloc] initWithWidth:LayoutParamWrapContent height:LayoutParamWrapContent]; + return layout; +} + +HLayout *hLayout(NSArray <__kindof UIView *> *views) { + HLayout *layout = [[HLayout alloc] initWithFrame:CGRectZero]; + for (__kindof UIView *uiView in views) { + [layout addSubview:uiView]; + } + layout.layoutConfig = [[LayoutConfig alloc] initWithWidth:LayoutParamWrapContent height:LayoutParamWrapContent]; + return layout; +} + +VLayout *vLayoutWithBlock(NSArray *blocks) { + VLayout *layout = [[VLayout alloc] initWithFrame:CGRectZero]; + UIView *(^block)(); + for (block in blocks) { + [layout addSubview:block()]; + } + layout.layoutConfig = [[LayoutConfig alloc] initWithWidth:LayoutParamWrapContent height:LayoutParamWrapContent]; + return layout; +} + +HLayout *hLayoutWithBlock(NSArray *blocks) { + HLayout *layout = [[HLayout alloc] initWithFrame:CGRectZero]; + UIView *(^block)(); + for (block in blocks) { + [layout addSubview:block()]; + } + layout.layoutConfig = [[LayoutConfig alloc] initWithWidth:LayoutParamWrapContent height:LayoutParamWrapContent]; + return layout; +} \ No newline at end of file diff --git a/iOS/Pod/Classes/Shader/DoricRootNode.h b/iOS/Pod/Classes/Shader/DoricRootNode.h index 9fa950b6..cc945e8c 100644 --- a/iOS/Pod/Classes/Shader/DoricRootNode.h +++ b/iOS/Pod/Classes/Shader/DoricRootNode.h @@ -26,7 +26,7 @@ NS_ASSUME_NONNULL_BEGIN @interface DoricRootNode : DoricStackNode -- (void)setupRootView:(UIView *)view; +- (void)setupRootView:(Stack *)view; - (void)render:(NSDictionary *)props; @end diff --git a/iOS/Pod/Classes/Shader/DoricRootNode.m b/iOS/Pod/Classes/Shader/DoricRootNode.m index 6df879d9..69f2ad28 100644 --- a/iOS/Pod/Classes/Shader/DoricRootNode.m +++ b/iOS/Pod/Classes/Shader/DoricRootNode.m @@ -23,17 +23,15 @@ #import "DoricRootNode.h" @implementation DoricRootNode -- (void)setupRootView:(UIView *)view { +- (void)setupRootView:(Stack *)view { self.view = view; + self.layoutConfig = view.layoutConfig; } - (void)render:(NSDictionary *)props { [self blend:props]; - [self requestLayout]; } - - (void)requestLayout { - [self measureByParent:self]; - [self layoutByParent:self]; + [self.view requestLayout]; } @end diff --git a/iOS/Pod/Classes/Shader/DoricStackNode.h b/iOS/Pod/Classes/Shader/DoricStackNode.h index 71719c10..9d6cbe98 100644 --- a/iOS/Pod/Classes/Shader/DoricStackNode.h +++ b/iOS/Pod/Classes/Shader/DoricStackNode.h @@ -22,10 +22,5 @@ #import "DoricGroupNode.h" -NS_ASSUME_NONNULL_BEGIN - -@interface DoricStackNode : DoricGroupNode -@property(nonatomic) DoricGravity gravity; +@interface DoricStackNode : DoricGroupNode @end - -NS_ASSUME_NONNULL_END diff --git a/iOS/Pod/Classes/Shader/DoricStackNode.m b/iOS/Pod/Classes/Shader/DoricStackNode.m index 50491d08..4023605a 100644 --- a/iOS/Pod/Classes/Shader/DoricStackNode.m +++ b/iOS/Pod/Classes/Shader/DoricStackNode.m @@ -25,93 +25,33 @@ @implementation DoricStackNode -- (instancetype)init { - if (self = [super init]) { - _gravity = 0; - } - return self; +- (Stack *)build:(NSDictionary *)props { + return [Stack new]; } -- (void)measureByParent:(DoricGroupNode *)parent { - DoricLayoutDesc widthSpec = self.layoutParams.width; - DoricLayoutDesc heightSpec = self.layoutParams.height; - CGFloat maxWidth = 0, maxHeight = 0; - for (DoricViewNode *child in self.indexedChildren) { - [child measureByParent:self]; - CGFloat placeWidth = child.measuredWidth; - CGFloat placeHeight = child.measuredHeight; - maxWidth = MAX(maxWidth, placeWidth); - maxHeight = MAX(maxHeight, placeHeight); - } - self.desiredWidth = maxWidth; - self.desiredHeight = maxHeight; - - if (widthSpec == LAYOUT_WRAP_CONTENT) { - self.width = maxWidth; - } - - if (heightSpec == LAYOUT_WRAP_CONTENT) { - self.height = maxHeight; +- (void)blendView:(Stack *)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]; } } -- (LayoutParams *)generateDefaultLayoutParams { - return [[StackLayoutParams alloc] init]; +- (StackLayoutConfig *)generateDefaultLayoutParams { + return [[StackLayoutConfig alloc] init]; } -- (void)blendChild:(DoricViewNode *)child layoutConfig:(NSDictionary *)layoutconfig { - [super blendChild:child layoutConfig:layoutconfig]; - if (![child.layoutParams isKindOfClass:StackLayoutParams.class]) { - DoricLog(@"blend Stack child error,layout params not match"); +- (void)blendChild:(DoricViewNode *)child layoutConfig:(NSDictionary *)layoutConfig { + [super blendChild:child layoutConfig:layoutConfig]; + if (![child.layoutConfig isKindOfClass:StackLayoutConfig.class]) { + DoricLog(@"blend HLayout child error,layout params not match"); return; } - StackLayoutParams *params = (StackLayoutParams *) child.layoutParams; -// NSDictionary *margin = [layoutconfig objectForKey:@"margin"]; -// if (margin) { -// params.margin.top = [(NSNumber *)[margin objectForKey:@"top"] floatValue]; -// params.margin.left = [(NSNumber *)[margin objectForKey:@"left"] floatValue]; -// params.margin.right = [(NSNumber *)[margin objectForKey:@"right"] floatValue]; -// params.margin.bottom = [(NSNumber *)[margin objectForKey:@"bottom"] floatValue]; -// } - NSNumber *alignment = layoutconfig[@"alignment"]; + StackLayoutConfig *params = (StackLayoutConfig *) child.layoutConfig; + NSNumber *alignment = layoutConfig[@"alignment"]; if (alignment) { - params.alignment = [alignment integerValue]; + params.alignment = (DoricGravity) [alignment integerValue]; } } -- (void)layoutByParent:(DoricGroupNode *)parent { - for (DoricViewNode *child in self.indexedChildren) { - if (child.layoutParams.width == LAYOUT_MATCH_PARENT) { - child.width = self.width; - } - if (child.layoutParams.height == LAYOUT_MATCH_PARENT) { - child.height = self.height; - } - DoricGravity gravity = self.gravity; - if ([child.layoutParams isKindOfClass:StackLayoutParams.class]) { - StackLayoutParams *layoutParams = (StackLayoutParams *) child.layoutParams; - gravity |= layoutParams.alignment; - } - - if ((gravity & LEFT) == LEFT) { - child.left = self.left; - } - if ((gravity & RIGHT) == RIGHT) { - child.right = self.right; - } - if ((gravity & TOP) == TOP) { - child.top = self.top; - } - if ((gravity & BOTTOM) == BOTTOM) { - child.bottom = self.bottom; - } - if ((gravity & CENTER_X) == CENTER_X) { - child.centerX = self.centerX; - } - if ((gravity & CENTER_Y) == CENTER_Y) { - child.centerY = self.centerY; - } - [child layoutByParent:self]; - } -} @end diff --git a/iOS/Pod/Classes/Shader/DoricTextNode.m b/iOS/Pod/Classes/Shader/DoricTextNode.m index 8c7dbd02..d723c4ad 100644 --- a/iOS/Pod/Classes/Shader/DoricTextNode.m +++ b/iOS/Pod/Classes/Shader/DoricTextNode.m @@ -37,7 +37,7 @@ - (void)blendView:(UILabel *)view forPropName:(NSString *)name propValue:(id)pro } else if ([name isEqualToString:@"textColor"]) { view.textColor = DoricColor(prop); } else if ([name isEqualToString:@"textAlignment"]) { - DoricGravity gravity = [(NSNumber *) prop integerValue]; + DoricGravity gravity = (DoricGravity) [(NSNumber *) prop integerValue]; NSTextAlignment alignment = NSTextAlignmentCenter; switch (gravity) { case LEFT: @@ -54,12 +54,4 @@ - (void)blendView:(UILabel *)view forPropName:(NSString *)name propValue:(id)pro [super blendView:view forPropName:name propValue:prop]; } } - -- (void)measureByParent:(DoricGroupNode *)parent { - DoricLayoutDesc widthSpec = self.layoutParams.width; - DoricLayoutDesc heightSpec = self.layoutParams.height; - if (widthSpec == LAYOUT_WRAP_CONTENT || heightSpec == LAYOUT_WRAP_CONTENT) { - [self.view sizeToFit]; - } -} @end diff --git a/iOS/Pod/Classes/Shader/DoricVLayoutNode.h b/iOS/Pod/Classes/Shader/DoricVLayoutNode.h index 54c15fa3..2ed3bfbd 100644 --- a/iOS/Pod/Classes/Shader/DoricVLayoutNode.h +++ b/iOS/Pod/Classes/Shader/DoricVLayoutNode.h @@ -22,11 +22,5 @@ #import "DoricGroupNode.h" -NS_ASSUME_NONNULL_BEGIN - -@interface DoricVLayoutNode : DoricGroupNode -@property(nonatomic) CGFloat space; -@property(nonatomic) DoricGravity gravity; +@interface DoricVLayoutNode : DoricGroupNode @end - -NS_ASSUME_NONNULL_END diff --git a/iOS/Pod/Classes/Shader/DoricVLayoutNode.m b/iOS/Pod/Classes/Shader/DoricVLayoutNode.m index 3ce2cacf..94b00765 100644 --- a/iOS/Pod/Classes/Shader/DoricVLayoutNode.m +++ b/iOS/Pod/Classes/Shader/DoricVLayoutNode.m @@ -24,19 +24,16 @@ #import "DoricUtil.h" @implementation DoricVLayoutNode -- (instancetype)init { - if (self = [super init]) { - _space = 0; - _gravity = 0; - } - return self; + +- (VLayout *)build:(NSDictionary *)props { + return [VLayout new]; } -- (void)blendView:(id)view forPropName:(NSString *)name propValue:(id)prop { +- (void)blendView:(VLayout *)view forPropName:(NSString *)name propValue:(id)prop { if ([name isEqualToString:@"gravity"]) { - self.gravity = [(NSNumber *) prop integerValue]; + view.gravity = (DoricGravity) [(NSNumber *) prop integerValue]; } else if ([name isEqualToString:@"space"]) { - self.space = [(NSNumber *) prop floatValue]; + view.space = [(NSNumber *) prop floatValue]; } else { [super blendView:view forPropName:name propValue:prop]; } @@ -44,92 +41,26 @@ - (void)blendView:(id)view forPropName:(NSString *)name propValue:(id)prop { - (void)blendChild:(DoricViewNode *)child layoutConfig:(NSDictionary *)layoutconfig { [super blendChild:child layoutConfig:layoutconfig]; - if (![child.layoutParams isKindOfClass:VHLayoutParams.class]) { + if (![child.layoutConfig isKindOfClass:LinearLayoutConfig.class]) { DoricLog(@"blend VLayout child error,layout params not match"); return; } - VHLayoutParams *params = (VHLayoutParams *) child.layoutParams; + LinearLayoutConfig *params = (LinearLayoutConfig *) child.layoutConfig; NSDictionary *margin = layoutconfig[@"margin"]; if (margin) { - params.margin.top = [(NSNumber *) margin[@"top"] floatValue]; - params.margin.left = [(NSNumber *) margin[@"left"] floatValue]; - params.margin.right = [(NSNumber *) margin[@"right"] floatValue]; - params.margin.bottom = [(NSNumber *) margin[@"bottom"] floatValue]; + params.margin = MarginMake( + [(NSNumber *) margin[@"left"] floatValue], + [(NSNumber *) margin[@"top"] floatValue], + [(NSNumber *) margin[@"right"] floatValue], + [(NSNumber *) margin[@"bottom"] floatValue]); } NSNumber *alignment = layoutconfig[@"alignment"]; if (alignment) { - params.alignment = [alignment integerValue]; + params.alignment = (DoricGravity) [alignment integerValue]; } } -- (LayoutParams *)generateDefaultLayoutParams { - return [[VHLayoutParams alloc] init]; -} - -- (void)measureByParent:(DoricGroupNode *)parent { - DoricLayoutDesc widthSpec = self.layoutParams.width; - DoricLayoutDesc heightSpec = self.layoutParams.height; - CGFloat maxWidth = 0, maxHeight = 0; - for (DoricViewNode *child in self.indexedChildren) { - [child measureByParent:self]; - CGFloat placeWidth = child.measuredWidth; - CGFloat placeHeight = child.measuredHeight; - maxWidth = MAX(maxWidth, placeWidth); - maxHeight += placeHeight + self.space; - } - maxHeight -= self.space; - - self.desiredWidth = maxWidth; - self.desiredHeight = maxHeight; - - if (widthSpec == LAYOUT_WRAP_CONTENT) { - self.width = maxWidth; - } - - if (heightSpec == LAYOUT_WRAP_CONTENT) { - self.height = maxHeight; - } -} - -- (void)layoutByParent:(DoricGroupNode *)parent { - if (self.layoutParams.width == LAYOUT_MATCH_PARENT) { - self.width = parent.width; - } - if (self.layoutParams.height == LAYOUT_MATCH_PARENT) { - self.height = parent.height; - } - // layout child - CGFloat yStart = 0; - if ((self.gravity & TOP) == TOP) { - yStart = 0; - } else if ((self.gravity & BOTTOM) == BOTTOM) { - yStart = self.height - self.desiredHeight; - } else if ((self.gravity & CENTER_Y) == CENTER_Y) { - yStart = (self.height - self.desiredHeight) / 2; - } - - - for (DoricViewNode *child in self.indexedChildren) { - if (child.layoutParams.width == LAYOUT_MATCH_PARENT) { - child.width = self.width; - } - if (child.layoutParams.height == LAYOUT_MATCH_PARENT) { - child.height = self.height; - } - if ([child.layoutParams isKindOfClass:VHLayoutParams.class]) { - VHLayoutParams *layoutParams = (VHLayoutParams *) child.layoutParams; - DoricGravity gravity = layoutParams.alignment | self.gravity; - if ((gravity & LEFT) == LEFT) { - child.left = 0; - } else if ((gravity & RIGHT) == RIGHT) { - child.right = self.width; - } else if ((gravity & CENTER_X) == CENTER_X) { - child.centerX = self.width / 2; - } - } - child.top = yStart; - yStart = child.bottom + self.space; - [child layoutByParent:self]; - } +- (LinearLayoutConfig *)generateDefaultLayoutParams { + return [[LinearLayoutConfig alloc] init]; } @end diff --git a/iOS/Pod/Classes/Shader/DoricViewContainer.h b/iOS/Pod/Classes/Shader/DoricViewContainer.h deleted file mode 100644 index d15eb2f1..00000000 --- a/iOS/Pod/Classes/Shader/DoricViewContainer.h +++ /dev/null @@ -1,101 +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. - */ -// -// DoricViewContainer.h -// Doric -// -// Created by pengfei.zhou on 2019/7/30. -// - -#import "UIView+Doric.h" - -typedef NS_ENUM(NSInteger, DoricGravity) { - SPECIFIED = 1, - START = 1 << 1, - END = 1 << 2, - SHIFT_X = 0, - SHIFT_Y = 4, - LEFT = (START | SPECIFIED) << SHIFT_X, - RIGHT = (END | SPECIFIED) << SHIFT_X, - TOP = (START | SPECIFIED) << SHIFT_Y, - BOTTOM = (END | SPECIFIED) << SHIFT_Y, - CENTER_X = SPECIFIED << SHIFT_X, - CENTER_Y = SPECIFIED << SHIFT_Y, - CENTER = CENTER_X | CENTER_Y, -}; - -typedef NS_ENUM(NSInteger, DoricLayoutDesc) { - LAYOUT_ABSOLUTE = 0, - LAYOUT_MATCH_PARENT = -1, - LAYOUT_WRAP_CONTENT = -2, -}; - -NS_ASSUME_NONNULL_BEGIN - -@interface DoricRect : NSObject -@property(nonatomic) CGFloat left; -@property(nonatomic) CGFloat right; -@property(nonatomic) CGFloat top; -@property(nonatomic) CGFloat bottom; -@end - - -@interface LayoutParams : NSObject -@property(nonatomic) DoricLayoutDesc width; -@property(nonatomic) DoricLayoutDesc height; -@end - -@interface MarginLayoutParams : LayoutParams -@property(nonatomic, strong) DoricRect *margin; -@end - -@interface StackLayoutParams : LayoutParams -@property(nonatomic) DoricGravity alignment; -@end - -@interface VHLayoutParams : MarginLayoutParams -@property(nonatomic) DoricGravity alignment; -@property(nonatomic) NSInteger weight; -@end - - -@interface UIView (DoricContainer) - -@property(nonatomic, strong) LayoutParams *layoutParams; - -- (void)layout; - -- (void)measure; - -@end - -@interface Stack : UIView -@property(nonatomic) DoricGravity gravity; -@end - -@interface LinearLayout : UIView -@property(nonatomic) DoricGravity gravity; -@property(nonatomic) CGFloat space; -@end - - -@interface VLayout : LinearLayout -@end - -@interface HLayout : LinearLayout -@end - -NS_ASSUME_NONNULL_END diff --git a/iOS/Pod/Classes/Shader/DoricViewContainer.m b/iOS/Pod/Classes/Shader/DoricViewContainer.m deleted file mode 100644 index 8abbcdac..00000000 --- a/iOS/Pod/Classes/Shader/DoricViewContainer.m +++ /dev/null @@ -1,108 +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. - */ -// -// DoricViewContainer.m -// Doric -// -// Created by pengfei.zhou on 2019/7/30. -// - -#import "DoricViewContainer.h" -#import - -@implementation DoricRect -- (instancetype)init { - if (self = [super init]) { - _left = 0; - _right = 0; - _top = 0; - _bottom = 0; - } - return self; -} -@end - -@implementation LayoutParams -- (instancetype)init { - if (self = [super init]) { - _width = LAYOUT_WRAP_CONTENT; - _height = LAYOUT_WRAP_CONTENT; - } - return self; -} -@end - -@implementation MarginLayoutParams -- (instancetype)init { - if (self = [super init]) { - _margin = [[DoricRect alloc] init]; - } - return self; -} -@end - -@implementation StackLayoutParams -- (instancetype)init { - if (self = [super init]) { - _alignment = 0; - } - return self; -} -@end - -@implementation VHLayoutParams -- (instancetype)init { - if (self = [super init]) { - _alignment = 0; - _weight = 0; - } - return self; -} -@end - - -@implementation UIView (DoricContainer) - -- (LayoutParams *)layoutParams { - return objc_getAssociatedObject(self, _cmd); -} - -- (void)setLayoutParams:(LayoutParams *)layoutParams { - objc_setAssociatedObject(self, @selector(layoutParams), layoutParams, OBJC_ASSOCIATION_RETAIN_NONATOMIC); -} - -- (void)layout { - -} - -- (void)measure { - if (self.layoutParams) { - - } -} -@end - -@implementation Stack -@end - -@implementation LinearLayout -@end - -@implementation VLayout -@end - -@implementation HLayout -@end diff --git a/iOS/Pod/Classes/Shader/DoricViewNode.h b/iOS/Pod/Classes/Shader/DoricViewNode.h index 543f87c0..36dcc378 100644 --- a/iOS/Pod/Classes/Shader/DoricViewNode.h +++ b/iOS/Pod/Classes/Shader/DoricViewNode.h @@ -21,8 +21,7 @@ // #import "DoricContextHolder.h" -#import "DoricViewContainer.h" - +#import "DoricLinearLayout.h" #import "UIView+Doric.h" NS_ASSUME_NONNULL_BEGIN @@ -37,24 +36,10 @@ NS_ASSUME_NONNULL_BEGIN @property(nonatomic, strong) NSString *viewId; -@property(nonatomic, strong) LayoutParams *layoutParams; +@property(nonatomic, strong) LayoutConfig *layoutConfig; @property(nonatomic, strong, readonly) NSArray *idList; - -@property(nonatomic) CGFloat x; -@property(nonatomic) CGFloat y; -@property(nonatomic) CGFloat width; -@property(nonatomic) CGFloat height; -@property(nonatomic) CGFloat centerX; -@property(nonatomic) CGFloat centerY; -@property(nonatomic) CGFloat top; -@property(nonatomic) CGFloat left; -@property(nonatomic) CGFloat right; -@property(nonatomic) CGFloat bottom; -@property(nonatomic, readonly) CGFloat measuredWidth; -@property(nonatomic, readonly) CGFloat measuredHeight; - - (V)build:(NSDictionary *)props; - (void)blend:(NSDictionary *)props; @@ -63,10 +48,6 @@ NS_ASSUME_NONNULL_BEGIN - (void)callJSResponse:(NSString *)funcId, ...; -- (void)measureByParent:(DoricGroupNode *)parent; - -- (void)layoutByParent:(DoricGroupNode *)parent; - + (DoricViewNode *)create:(DoricContext *)context withType:(NSString *)type; - (void)requestLayout; diff --git a/iOS/Pod/Classes/Shader/DoricViewNode.m b/iOS/Pod/Classes/Shader/DoricViewNode.m index de219bd2..e4d4b214 100644 --- a/iOS/Pod/Classes/Shader/DoricViewNode.m +++ b/iOS/Pod/Classes/Shader/DoricViewNode.m @@ -85,6 +85,7 @@ - (void)blend:(NSDictionary *)props { if (self.view == nil) { self.view = [self build:props]; } + self.view.layoutConfig = self.layoutConfig; for (NSString *key in props) { id value = props[key]; [self blendView:self.view forPropName:key propValue:value]; @@ -94,18 +95,12 @@ - (void)blend:(NSDictionary *)props { - (void)blendView:(UIView *)view forPropName:(NSString *)name propValue:(id)prop { if ([name isEqualToString:@"width"]) { NSNumber *width = (NSNumber *) prop; - if ([width integerValue] < 0) { - self.layoutParams.width = [width integerValue]; - } else { - self.layoutParams.width = LAYOUT_ABSOLUTE; + if ([width floatValue] >= 0) { view.width = [width floatValue]; } } else if ([name isEqualToString:@"height"]) { NSNumber *height = (NSNumber *) prop; - if ([height integerValue] < 0) { - self.layoutParams.height = [height integerValue]; - } else { - self.layoutParams.height = LAYOUT_ABSOLUTE; + if ([height floatValue] >= 0) { view.height = [height floatValue]; } } else if ([name isEqualToString:@"x"]) { @@ -119,14 +114,14 @@ - (void)blendView:(UIView *)view forPropName:(NSString *)name propValue:(id)prop [self.parent blendChild:self layoutConfig:prop]; } } else if ([name isEqualToString:@"onClick"]) { - [self.callbackIds setObject:prop forKey:@"onClick"]; + self.callbackIds[@"onClick"] = prop; view.userInteractionEnabled = YES; - UITapGestureRecognizer *tapGesturRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onClick:)]; - [view addGestureRecognizer:tapGesturRecognizer]; + UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onClick:)]; + [view addGestureRecognizer:tapGestureRecognizer]; } else if ([name isEqualToString:@"border"]) { NSDictionary *dic = prop; - CGFloat width = [(NSNumber *) [dic objectForKey:@"width"] floatValue]; - UIColor *color = DoricColor((NSNumber *) [dic objectForKey:@"color"]); + CGFloat width = [(NSNumber *) dic[@"width"] floatValue]; + UIColor *color = DoricColor((NSNumber *) dic[@"color"]); view.layer.borderWidth = width; view.layer.borderColor = color.CGColor; } else if ([name isEqualToString:@"corners"]) { @@ -134,10 +129,10 @@ - (void)blendView:(UIView *)view forPropName:(NSString *)name propValue:(id)prop view.layer.cornerRadius = [(NSNumber *) prop floatValue]; } else if ([prop isKindOfClass:NSDictionary.class]) { NSDictionary *dic = prop; - CGFloat leftTop = [(NSNumber *) [dic objectForKey:@"leftTop"] floatValue]; - CGFloat rightTop = [(NSNumber *) [dic objectForKey:@"rightTop"] floatValue]; - CGFloat rightBottom = [(NSNumber *) [dic objectForKey:@"rightBottom"] floatValue]; - CGFloat leftBottom = [(NSNumber *) [dic objectForKey:@"leftBottom"] floatValue]; + CGFloat leftTop = [(NSNumber *) dic[@"leftTop"] floatValue]; + CGFloat rightTop = [(NSNumber *) dic[@"rightTop"] floatValue]; + CGFloat rightBottom = [(NSNumber *) dic[@"rightBottom"] floatValue]; + CGFloat leftBottom = [(NSNumber *) dic[@"leftBottom"] floatValue]; CALayer *mask = nil; if (ABS(leftTop - rightTop) > CGFLOAT_MIN || ABS(leftTop - rightBottom) > CGFLOAT_MIN @@ -155,14 +150,14 @@ - (void)blendView:(UIView *)view forPropName:(NSString *)name propValue:(id)prop } } else if ([name isEqualToString:@"shadow"]) { NSDictionary *dic = prop; - CGFloat opacity = [(NSNumber *) [dic objectForKey:@"opacity"] floatValue]; + CGFloat opacity = [(NSNumber *) dic[@"opacity"] floatValue]; if (opacity > CGFLOAT_MIN) { view.clipsToBounds = NO; - UIColor *color = DoricColor((NSNumber *) [dic objectForKey:@"color"]); + UIColor *color = DoricColor((NSNumber *) dic[@"color"]); view.layer.shadowColor = color.CGColor; - view.layer.shadowRadius = [(NSNumber *) [dic objectForKey:@"radius"] floatValue]; - view.layer.shadowOffset = CGSizeMake([(NSNumber *) [dic objectForKey:@"offsetX"] floatValue], [(NSNumber *) [dic objectForKey:@"offsetY"] floatValue]); - view.layer.shadowOpacity = opacity; + view.layer.shadowRadius = [(NSNumber *) dic[@"radius"] floatValue]; + view.layer.shadowOffset = CGSizeMake([(NSNumber *) dic[@"offsetX"] floatValue], [(NSNumber *) dic[@"offsetY"] floatValue]); + view.layer.shadowOpacity = (float) opacity; } else { view.clipsToBounds = YES; } @@ -173,35 +168,7 @@ - (void)blendView:(UIView *)view forPropName:(NSString *)name propValue:(id)prop } - (void)onClick:(UIView *)view { - [self callJSResponse:[self.callbackIds objectForKey:@"onClick"], nil]; -} - -- (CGFloat)measuredWidth { - if ([self.layoutParams isKindOfClass:MarginLayoutParams.class]) { - MarginLayoutParams *marginParams = (MarginLayoutParams *) self.layoutParams; - return self.width + marginParams.margin.left + marginParams.margin.right; - } - return self.width; -} - -- (CGFloat)measuredHeight { - if ([self.layoutParams isKindOfClass:MarginLayoutParams.class]) { - MarginLayoutParams *marginParams = (MarginLayoutParams *) self.layoutParams; - return self.height + marginParams.margin.top + marginParams.margin.bottom; - } - return self.height; -} - -- (void)measureByParent:(DoricGroupNode *)parent { - DoricLayoutDesc widthSpec = self.layoutParams.width; - DoricLayoutDesc heightSpec = self.layoutParams.height; - if (widthSpec == LAYOUT_WRAP_CONTENT || heightSpec == LAYOUT_WRAP_CONTENT) { - [self.view sizeToFit]; - } -} - -- (void)layoutByParent:(DoricGroupNode *)parent { - + [self callJSResponse:self.callbackIds[@"onClick"], nil]; } - (NSArray *)idList { @@ -232,87 +199,7 @@ - (void)callJSResponse:(NSString *)funcId, ... { + (DoricViewNode *)create:(DoricContext *)context withType:(NSString *)type { DoricRegistry *registry = context.driver.registry; Class clz = [registry acquireViewNode:type]; - return [[clz alloc] initWithContext:context]; -} - -- (CGFloat)x { - return ((UIView *) self.view).x; -} - -- (CGFloat)y { - return ((UIView *) self.view).y; -} - -- (CGFloat)width { - return ((UIView *) self.view).width; -} - -- (CGFloat)height { - return ((UIView *) self.view).height; -} - -- (CGFloat)top { - return ((UIView *) self.view).top; -} - -- (CGFloat)bottom { - return ((UIView *) self.view).bottom; -} - -- (CGFloat)left { - return ((UIView *) self.view).left; -} - -- (CGFloat)right { - return ((UIView *) self.view).right; -} - -- (CGFloat)centerX { - return ((UIView *) self.view).centerX; -} - -- (CGFloat)centerY { - return ((UIView *) self.view).centerY; -} - -- (void)setX:(CGFloat)x { - ((UIView *) self.view).x = x; -} - -- (void)setY:(CGFloat)y { - ((UIView *) self.view).y = y; -} - -- (void)setWidth:(CGFloat)width { - ((UIView *) self.view).width = width; -} - -- (void)setHeight:(CGFloat)height { - ((UIView *) self.view).height = height; -} - -- (void)setLeft:(CGFloat)left { - ((UIView *) self.view).left = left; -} - -- (void)setRight:(CGFloat)right { - ((UIView *) self.view).right = right; -} - -- (void)setTop:(CGFloat)top { - ((UIView *) self.view).top = top; -} - -- (void)setBottom:(CGFloat)bottom { - ((UIView *) self.view).bottom = bottom; -} - -- (void)setCenterX:(CGFloat)centerX { - ((UIView *) self.view).centerX = centerX; -} - -- (void)setCenterY:(CGFloat)centerY { - ((UIView *) self.view).centerY = centerY; + return [(DoricViewNode *) [clz alloc] initWithContext:context]; } - (void)requestLayout { diff --git a/iOS/Pod/Classes/UIView+Doric.h b/iOS/Pod/Classes/Shader/UIView+Doric.h similarity index 100% rename from iOS/Pod/Classes/UIView+Doric.h rename to iOS/Pod/Classes/Shader/UIView+Doric.h diff --git a/iOS/Pod/Classes/UIView+Doric.m b/iOS/Pod/Classes/Shader/UIView+Doric.m similarity index 100% rename from iOS/Pod/Classes/UIView+Doric.m rename to iOS/Pod/Classes/Shader/UIView+Doric.m diff --git a/iOS/Pod/Classes/Util/DoricExtensions.h b/iOS/Pod/Classes/Util/DoricExtensions.h new file mode 100644 index 00000000..aba09103 --- /dev/null +++ b/iOS/Pod/Classes/Util/DoricExtensions.h @@ -0,0 +1,29 @@ +/* + * 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. + */ +// +// Created by pengfei.zhou on 2019/10/23. +// + +#import + + +@interface NSObject (Doric) +- (id)apply:(id (^)(id it))block; + +- (instancetype)also:(void (^)(id it))block; + +- (void)let:(void (^)(id it))block; +@end diff --git a/iOS/Pod/Classes/Util/DoricExtensions.m b/iOS/Pod/Classes/Util/DoricExtensions.m new file mode 100644 index 00000000..b3b92987 --- /dev/null +++ b/iOS/Pod/Classes/Util/DoricExtensions.m @@ -0,0 +1,35 @@ +/* + * 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. + */ +// +// Created by pengfei.zhou on 2019/10/23. +// + +#import "DoricExtensions.h" + +@implementation NSObject (Doric) +- (id)apply:(id (^)(id it))block { + return block(self); +} + +- (instancetype)also:(void (^)(id it))block { + block(self); + return self; +} + +- (void)let:(void (^)(id it))block { + block(self); +} +@end From 4b1a982e8566370f5dac430d3017768ea94bddc1 Mon Sep 17 00:00:00 2001 From: "pengfei.zhou" Date: Wed, 23 Oct 2019 20:06:21 +0800 Subject: [PATCH 8/9] rename add doric prefix --- iOS/Example/Example/ViewController.m | 6 +- iOS/Pod/Classes/Shader/DoricGroupNode.h | 2 +- iOS/Pod/Classes/Shader/DoricGroupNode.m | 18 +- iOS/Pod/Classes/Shader/DoricHLayoutNode.h | 2 +- iOS/Pod/Classes/Shader/DoricHLayoutNode.m | 10 +- .../{DoricLinearLayout.h => DoricLayouts.h} | 40 ++--- .../{DoricLinearLayout.m => DoricLayouts.m} | 160 +++++++++--------- iOS/Pod/Classes/Shader/DoricRootNode.h | 2 +- iOS/Pod/Classes/Shader/DoricRootNode.m | 2 +- iOS/Pod/Classes/Shader/DoricStackNode.h | 2 +- iOS/Pod/Classes/Shader/DoricStackNode.m | 14 +- iOS/Pod/Classes/Shader/DoricVLayoutNode.h | 2 +- iOS/Pod/Classes/Shader/DoricVLayoutNode.m | 10 +- iOS/Pod/Classes/Shader/DoricViewNode.h | 4 +- 14 files changed, 137 insertions(+), 137 deletions(-) rename iOS/Pod/Classes/Shader/{DoricLinearLayout.h => DoricLayouts.h} (65%) rename iOS/Pod/Classes/Shader/{DoricLinearLayout.m => DoricLayouts.m} (70%) diff --git a/iOS/Example/Example/ViewController.m b/iOS/Example/Example/ViewController.m index 806bc11d..e638a42a 100644 --- a/iOS/Example/Example/ViewController.m +++ b/iOS/Example/Example/ViewController.m @@ -13,7 +13,7 @@ #import "DoricNativePlugin.h" #import "DoricRootNode.h" #import "DoricLocalServer.h" -#import "DoricLinearLayout.h" +#import "DoricLayouts.h" #import "DoricExtensions.h" @interface ViewController () @@ -29,8 +29,8 @@ - (void)viewDidLoad { NSString *path = [[NSBundle bundleForClass:[self class]] pathForResource:@"Snake" ofType:@"js"]; NSString *jsContent = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil]; self.doricContext = [[DoricContext alloc] initWithScript:jsContent source:@"test.js"]; - [self.doricContext.rootNode setupRootView:[[Stack new] also:^(Stack *it) { - it.layoutConfig = [[StackLayoutConfig alloc] initWithWidth:LayoutParamAtMost height:LayoutParamAtMost]; + [self.doricContext.rootNode setupRootView:[[DoricStackView new] also:^(DoricStackView *it) { + it.layoutConfig = [[DoricStackConfig alloc] initWithWidth:DoricLayoutAtMost height:DoricLayoutAtMost]; [self.view addSubview:it]; }]]; [self.doricContext initContextWithWidth:self.view.width height:self.view.height]; diff --git a/iOS/Pod/Classes/Shader/DoricGroupNode.h b/iOS/Pod/Classes/Shader/DoricGroupNode.h index fe717a3a..413de989 100644 --- a/iOS/Pod/Classes/Shader/DoricGroupNode.h +++ b/iOS/Pod/Classes/Shader/DoricGroupNode.h @@ -24,7 +24,7 @@ NS_ASSUME_NONNULL_BEGIN -@interface DoricGroupNode : DoricViewNode +@interface DoricGroupNode : DoricViewNode @property(nonatomic, strong) NSMutableDictionary *children; @property(nonatomic, strong) NSMutableArray *indexedChildren; diff --git a/iOS/Pod/Classes/Shader/DoricGroupNode.m b/iOS/Pod/Classes/Shader/DoricGroupNode.m index ba5c6764..7cf1d71e 100644 --- a/iOS/Pod/Classes/Shader/DoricGroupNode.m +++ b/iOS/Pod/Classes/Shader/DoricGroupNode.m @@ -73,7 +73,7 @@ - (void)blendView:(UIView *)view forPropName:(NSString *)name propValue:(id)prop [tobeRemoved addObject:old]; } - LayoutConfig *params = node.layoutConfig; + DoricLayoutConfig *params = node.layoutConfig; if (params == nil) { params = [self generateDefaultLayoutParams]; node.layoutConfig = params; @@ -109,31 +109,31 @@ - (void)blendView:(UIView *)view forPropName:(NSString *)name propValue:(id)prop } } -- (LayoutConfig *)generateDefaultLayoutParams { - LayoutConfig *params = [[LayoutConfig alloc] init]; +- (DoricLayoutConfig *)generateDefaultLayoutParams { + DoricLayoutConfig *params = [[DoricLayoutConfig alloc] init]; return params; } - (void)blendChild:(DoricViewNode *)child layoutConfig:(NSDictionary *)layoutConfig { - LayoutConfig *params = child.layoutConfig; + DoricLayoutConfig *params = child.layoutConfig; [layoutConfig[@"widthSpec"] also:^(NSNumber *it) { if (it) { - params.widthSpec = (LayoutParam) [it integerValue]; + params.widthSpec = (DoricLayoutSpec) [it integerValue]; } }]; [layoutConfig[@"heightSpec"] also:^(NSNumber *it) { if (it) { - params.heightSpec = (LayoutParam) [it integerValue]; + params.heightSpec = (DoricLayoutSpec) [it integerValue]; } }]; - if ([params isKindOfClass:MarginLayoutConfig.class]) { - MarginLayoutConfig *marginParams = (MarginLayoutConfig *) params; + if ([params isKindOfClass:DoricMarginConfig.class]) { + DoricMarginConfig *marginParams = (DoricMarginConfig *) params; NSDictionary *margin = layoutConfig[@"margin"]; if (margin) { - marginParams.margin = MarginMake( + marginParams.margin = DoricMarginMake( [(NSNumber *) margin[@"left"] floatValue], [(NSNumber *) margin[@"top"] floatValue], [(NSNumber *) margin[@"right"] floatValue], diff --git a/iOS/Pod/Classes/Shader/DoricHLayoutNode.h b/iOS/Pod/Classes/Shader/DoricHLayoutNode.h index d429f102..4e754d28 100644 --- a/iOS/Pod/Classes/Shader/DoricHLayoutNode.h +++ b/iOS/Pod/Classes/Shader/DoricHLayoutNode.h @@ -22,5 +22,5 @@ #import "DoricGroupNode.h" -@interface DoricHLayoutNode : DoricGroupNode +@interface DoricHLayoutNode : DoricGroupNode @end diff --git a/iOS/Pod/Classes/Shader/DoricHLayoutNode.m b/iOS/Pod/Classes/Shader/DoricHLayoutNode.m index 29d6a639..de2f0c00 100644 --- a/iOS/Pod/Classes/Shader/DoricHLayoutNode.m +++ b/iOS/Pod/Classes/Shader/DoricHLayoutNode.m @@ -40,14 +40,14 @@ - (void)blendView:(HLayout *)view forPropName:(NSString *)name propValue:(id)pro - (void)blendChild:(DoricViewNode *)child layoutConfig:(NSDictionary *)layoutConfig { [super blendChild:child layoutConfig:layoutConfig]; - if (![child.layoutConfig isKindOfClass:LinearLayoutConfig.class]) { + if (![child.layoutConfig isKindOfClass:DoricLinearConfig.class]) { DoricLog(@"blend HLayout child error,layout params not match"); return; } - LinearLayoutConfig *params = (LinearLayoutConfig *) child.layoutConfig; + DoricLinearConfig *params = (DoricLinearConfig *) child.layoutConfig; NSDictionary *margin = layoutConfig[@"margin"]; if (margin) { - params.margin = MarginMake( + params.margin = DoricMarginMake( [(NSNumber *) margin[@"left"] floatValue], [(NSNumber *) margin[@"top"] floatValue], [(NSNumber *) margin[@"right"] floatValue], @@ -59,7 +59,7 @@ - (void)blendChild:(DoricViewNode *)child layoutConfig:(NSDictionary *)layoutCon } } -- (LinearLayoutConfig *)generateDefaultLayoutParams { - return [[LinearLayoutConfig alloc] init]; +- (DoricLinearConfig *)generateDefaultLayoutParams { + return [[DoricLinearConfig alloc] init]; } @end diff --git a/iOS/Pod/Classes/Shader/DoricLinearLayout.h b/iOS/Pod/Classes/Shader/DoricLayouts.h similarity index 65% rename from iOS/Pod/Classes/Shader/DoricLinearLayout.h rename to iOS/Pod/Classes/Shader/DoricLayouts.h index 300cd46d..421b27b3 100644 --- a/iOS/Pod/Classes/Shader/DoricLinearLayout.h +++ b/iOS/Pod/Classes/Shader/DoricLayouts.h @@ -20,20 +20,20 @@ #import -struct Margin { +struct DoricMargin { CGFloat left; CGFloat right; CGFloat top; CGFloat bottom; }; -typedef struct Margin Margin; +typedef struct DoricMargin DoricMargin; -Margin MarginMake(CGFloat left, CGFloat top, CGFloat right, CGFloat bottom); +DoricMargin DoricMarginMake(CGFloat left, CGFloat top, CGFloat right, CGFloat bottom); -typedef NS_ENUM(NSInteger, LayoutParam) { - LayoutParamExact, - LayoutParamWrapContent, - LayoutParamAtMost, +typedef NS_ENUM(NSInteger, DoricLayoutSpec) { + DoricLayoutExact, + DoricLayoutWrapContent, + DoricLayoutAtMost, }; typedef NS_ENUM(NSInteger, DoricGravity) { @@ -51,32 +51,32 @@ typedef NS_ENUM(NSInteger, DoricGravity) { CENTER = CENTER_X | CENTER_Y, }; -@interface LayoutConfig : NSObject -@property(nonatomic, assign) LayoutParam widthSpec; -@property(nonatomic, assign) LayoutParam heightSpec; +@interface DoricLayoutConfig : NSObject +@property(nonatomic, assign) DoricLayoutSpec widthSpec; +@property(nonatomic, assign) DoricLayoutSpec heightSpec; @property(nonatomic, assign) DoricGravity alignment; - (instancetype)init; -- (instancetype)initWithWidth:(LayoutParam)width height:(LayoutParam)height; +- (instancetype)initWithWidth:(DoricLayoutSpec)width height:(DoricLayoutSpec)height; @end -@interface StackLayoutConfig : LayoutConfig +@interface DoricStackConfig : DoricLayoutConfig @end -@interface MarginLayoutConfig : LayoutConfig -@property(nonatomic) Margin margin; +@interface DoricMarginConfig : DoricLayoutConfig +@property(nonatomic) DoricMargin margin; -- (instancetype)initWithWidth:(LayoutParam)width height:(LayoutParam)height margin:(Margin)margin; +- (instancetype)initWithWidth:(DoricLayoutSpec)width height:(DoricLayoutSpec)height margin:(DoricMargin)margin; @end -@interface LinearLayoutConfig : MarginLayoutConfig +@interface DoricLinearConfig : DoricMarginConfig @property(nonatomic, assign) NSUInteger weight; @end -@interface LayoutContainer : UIView +@interface DoricLayoutContainer : UIView - (T)configForChild:(__kindof UIView *)child; @@ -85,11 +85,11 @@ typedef NS_ENUM(NSInteger, DoricGravity) { - (void)requestLayout; @end -@interface Stack : LayoutContainer +@interface DoricStackView : DoricLayoutContainer @property(nonatomic, assign) DoricGravity gravity; @end -@interface LinearLayout : LayoutContainer +@interface LinearLayout : DoricLayoutContainer @property(nonatomic, assign) DoricGravity gravity; @property(nonatomic, assign) CGFloat space; @end @@ -102,7 +102,7 @@ typedef NS_ENUM(NSInteger, DoricGravity) { @end @interface UIView (LayoutConfig) -@property(nonatomic, strong) LayoutConfig *layoutConfig; +@property(nonatomic, strong) DoricLayoutConfig *layoutConfig; @property(nonatomic, copy) NSString *tagString; - (UIView *)viewWithTagString:(NSString *)tagString; diff --git a/iOS/Pod/Classes/Shader/DoricLinearLayout.m b/iOS/Pod/Classes/Shader/DoricLayouts.m similarity index 70% rename from iOS/Pod/Classes/Shader/DoricLinearLayout.m rename to iOS/Pod/Classes/Shader/DoricLayouts.m index 7ddc1db8..f8d67ce3 100644 --- a/iOS/Pod/Classes/Shader/DoricLinearLayout.m +++ b/iOS/Pod/Classes/Shader/DoricLayouts.m @@ -17,12 +17,12 @@ // Created by pengfei.zhou on 2019/10/23. // -#import "DoricLinearLayout.h" +#import "DoricLayouts.h" #import #import "UIView+Doric.h" -Margin MarginMake(CGFloat left, CGFloat top, CGFloat right, CGFloat bottom) { - Margin margin; +DoricMargin DoricMarginMake(CGFloat left, CGFloat top, CGFloat right, CGFloat bottom) { + DoricMargin margin; margin.left = left; margin.top = top; margin.right = right; @@ -30,16 +30,16 @@ Margin MarginMake(CGFloat left, CGFloat top, CGFloat right, CGFloat bottom) { return margin; } -@implementation LayoutConfig +@implementation DoricLayoutConfig - (instancetype)init { if (self = [super init]) { - _widthSpec = LayoutParamExact; - _heightSpec = LayoutParamExact; + _widthSpec = DoricLayoutExact; + _heightSpec = DoricLayoutExact; } return self; } -- (instancetype)initWithWidth:(LayoutParam)width height:(LayoutParam)height { +- (instancetype)initWithWidth:(DoricLayoutSpec)width height:(DoricLayoutSpec)height { if (self = [super init]) { _widthSpec = width; _heightSpec = height; @@ -48,15 +48,15 @@ - (instancetype)initWithWidth:(LayoutParam)width height:(LayoutParam)height { } @end -@implementation MarginLayoutConfig +@implementation DoricMarginConfig - (instancetype)init { if (self = [super init]) { - _margin = MarginMake(0, 0, 0, 0); + _margin = DoricMarginMake(0, 0, 0, 0); } return self; } -- (instancetype)initWithWidth:(LayoutParam)width height:(LayoutParam)height margin:(Margin)margin { +- (instancetype)initWithWidth:(DoricLayoutSpec)width height:(DoricLayoutSpec)height margin:(DoricMargin)margin { if (self = [super initWithWidth:width height:height]) { _margin = margin; } @@ -64,18 +64,18 @@ - (instancetype)initWithWidth:(LayoutParam)width height:(LayoutParam)height marg } @end -@implementation StackLayoutConfig +@implementation DoricStackConfig @end -@implementation LinearLayoutConfig +@implementation DoricLinearConfig @end -@interface LayoutContainer () +@interface DoricLayoutContainer () @property(nonatomic, assign) BOOL waitingLayout; @end -@implementation LayoutContainer +@implementation DoricLayoutContainer - (instancetype)init { if (self = [super init]) { _waitingLayout = NO; @@ -98,10 +98,10 @@ - (instancetype)initWithCoder:(NSCoder *)coder { } -- (LayoutConfig *)configForChild:(UIView *)child { - LayoutConfig *config = child.layoutConfig; +- (DoricLayoutConfig *)configForChild:(UIView *)child { + DoricLayoutConfig *config = child.layoutConfig; if (!config) { - config = [[LayoutConfig alloc] init]; + config = [[DoricLayoutConfig alloc] init]; } return config; } @@ -129,8 +129,8 @@ - (void)layoutSubviews { - (void)layout { [self.subviews enumerateObjectsUsingBlock:^(__kindof UIView *child, NSUInteger idx, BOOL *stop) { - if ([child isKindOfClass:[LayoutContainer class]]) { - [(LayoutContainer *) child layout]; + if ([child isKindOfClass:[DoricLayoutContainer class]]) { + [(DoricLayoutContainer *) child layout]; } }]; } @@ -138,47 +138,47 @@ - (void)layout { @end -@interface Stack () +@interface DoricStackView () @property(nonatomic, assign) CGFloat contentWidth; @property(nonatomic, assign) CGFloat contentHeight; @end -@implementation Stack -- (StackLayoutConfig *)configForChild:(UIView *)child { - StackLayoutConfig *config = (StackLayoutConfig *) child.layoutConfig; +@implementation DoricStackView +- (DoricStackConfig *)configForChild:(UIView *)child { + DoricStackConfig *config = (DoricStackConfig *) child.layoutConfig; if (!config) { - config = [[StackLayoutConfig alloc] init]; + config = [[DoricStackConfig alloc] init]; } return config; } - (void)sizeToFit { - LayoutConfig *config = self.layoutConfig; + DoricLayoutConfig *config = self.layoutConfig; self.contentWidth = 0; self.contentHeight = 0; for (UIView *child in self.subviews) { if (child.isHidden) { continue; } - StackLayoutConfig *childConfig = [self configForChild:child]; - if ([child isKindOfClass:[LayoutContainer class]] - || childConfig.widthSpec == LayoutParamWrapContent - || childConfig.heightSpec == LayoutParamWrapContent) { + DoricStackConfig *childConfig = [self configForChild:child]; + if ([child isKindOfClass:[DoricLayoutContainer class]] + || childConfig.widthSpec == DoricLayoutWrapContent + || childConfig.heightSpec == DoricLayoutWrapContent) { [child sizeToFit]; } self.contentWidth = MAX(self.contentWidth, child.width); self.contentHeight = MAX(self.contentHeight, child.height); } - if (config.widthSpec == LayoutParamWrapContent) { + if (config.widthSpec == DoricLayoutWrapContent) { self.width = self.contentWidth; - } else if (config.widthSpec == LayoutParamAtMost) { + } else if (config.widthSpec == DoricLayoutAtMost) { self.width = self.superview.width; } - if (config.heightSpec == LayoutParamWrapContent) { + if (config.heightSpec == DoricLayoutWrapContent) { self.height = self.contentHeight; - } else if (config.heightSpec == LayoutParamAtMost) { + } else if (config.heightSpec == DoricLayoutAtMost) { self.height = self.superview.height; } } @@ -188,7 +188,7 @@ - (void)layout { if (child.isHidden) { continue; } - StackLayoutConfig *childConfig = [self configForChild:child]; + DoricStackConfig *childConfig = [self configForChild:child]; DoricGravity gravity = childConfig.alignment | self.gravity; if ((gravity & LEFT) == LEFT) { child.left = 0; @@ -204,15 +204,15 @@ - (void)layout { } else if ((gravity & CENTER_Y) == CENTER_Y) { child.centerY = self.height / 2; } - if (childConfig.widthSpec == LayoutParamAtMost) { + if (childConfig.widthSpec == DoricLayoutAtMost) { child.width = self.width; } - if (childConfig.heightSpec == LayoutParamAtMost) { + if (childConfig.heightSpec == DoricLayoutAtMost) { child.height = self.height; } - if ([child isKindOfClass:[LayoutContainer class]]) { - [(LayoutContainer *) child layout]; + if ([child isKindOfClass:[DoricLayoutContainer class]]) { + [(DoricLayoutContainer *) child layout]; } } } @@ -225,10 +225,10 @@ @interface LinearLayout () @end @implementation LinearLayout -- (LinearLayoutConfig *)configForChild:(UIView *)child { - LinearLayoutConfig *config = (LinearLayoutConfig *) child.layoutConfig; +- (DoricLinearConfig *)configForChild:(UIView *)child { + DoricLinearConfig *config = (DoricLinearConfig *) child.layoutConfig; if (!config) { - config = [[LinearLayoutConfig alloc] init]; + config = [[DoricLinearConfig alloc] init]; } return config; } @@ -237,7 +237,7 @@ - (LinearLayoutConfig *)configForChild:(UIView *)child { @implementation VLayout - (void)sizeToFit { - LayoutConfig *config = self.layoutConfig; + DoricLayoutConfig *config = self.layoutConfig; self.contentWidth = 0; self.contentHeight = 0; self.contentWeight = 0; @@ -245,10 +245,10 @@ - (void)sizeToFit { if (child.isHidden) { continue; } - LinearLayoutConfig *childConfig = [self configForChild:child]; - if ([child isKindOfClass:[LayoutContainer class]] - || childConfig.widthSpec == LayoutParamWrapContent - || childConfig.heightSpec == LayoutParamWrapContent) { + DoricLinearConfig *childConfig = [self configForChild:child]; + if ([child isKindOfClass:[DoricLayoutContainer class]] + || childConfig.widthSpec == DoricLayoutWrapContent + || childConfig.heightSpec == DoricLayoutWrapContent) { [child sizeToFit]; } self.contentWidth = MAX(self.contentWidth, child.width + childConfig.margin.left + childConfig.margin.right); @@ -256,14 +256,14 @@ - (void)sizeToFit { self.contentWeight += childConfig.weight; } self.contentHeight -= self.space; - if (config.widthSpec == LayoutParamWrapContent) { + if (config.widthSpec == DoricLayoutWrapContent) { self.width = self.contentWidth; - } else if (config.widthSpec == LayoutParamAtMost) { + } else if (config.widthSpec == DoricLayoutAtMost) { self.width = self.superview.width; } - if (config.heightSpec == LayoutParamWrapContent) { + if (config.heightSpec == DoricLayoutWrapContent) { self.height = self.contentHeight; - } else if (config.heightSpec == LayoutParamAtMost) { + } else if (config.heightSpec == DoricLayoutAtMost) { self.height = self.superview.height; } if (self.contentWeight) { @@ -272,7 +272,7 @@ - (void)sizeToFit { if (child.isHidden) { continue; } - LinearLayoutConfig *childConfig = [self configForChild:child]; + DoricLinearConfig *childConfig = [self configForChild:child]; if (childConfig.weight) { child.height += remain / self.contentWeight * childConfig.weight; } @@ -294,7 +294,7 @@ - (void)layout { if (child.isHidden) { continue; } - LinearLayoutConfig *childConfig = [self configForChild:child]; + DoricLinearConfig *childConfig = [self configForChild:child]; DoricGravity gravity = childConfig.alignment | self.gravity; if ((gravity & LEFT) == LEFT) { child.left = 0; @@ -309,10 +309,10 @@ - (void)layout { child.right = self.width - childConfig.margin.right; } } - if (childConfig.widthSpec == LayoutParamAtMost) { + if (childConfig.widthSpec == DoricLayoutAtMost) { child.width = self.width; } - if (childConfig.heightSpec == LayoutParamAtMost) { + if (childConfig.heightSpec == DoricLayoutAtMost) { child.height = self.height - yStart - childConfig.margin.top - childConfig.margin.bottom - self.space; } if (childConfig.margin.top) { @@ -323,8 +323,8 @@ - (void)layout { if (childConfig.margin.bottom) { yStart += childConfig.margin.bottom; } - if ([child isKindOfClass:[LayoutContainer class]]) { - [(LayoutContainer *) child layout]; + if ([child isKindOfClass:[DoricLayoutContainer class]]) { + [(DoricLayoutContainer *) child layout]; } } } @@ -332,13 +332,13 @@ - (void)layout { @implementation HLayout - (void)sizeToFit { - LinearLayoutConfig *config; + DoricLinearConfig *config; if ([self.superview isKindOfClass:[LinearLayout class]]) { config = [(LinearLayout *) self.superview configForChild:self]; } else { - config = (LinearLayoutConfig *) self.layoutConfig; + config = (DoricLinearConfig *) self.layoutConfig; if (!config) { - config = [[LinearLayoutConfig alloc] init]; + config = [[DoricLinearConfig alloc] init]; } } self.contentWidth = 0; @@ -348,10 +348,10 @@ - (void)sizeToFit { if (child.isHidden) { continue; } - LinearLayoutConfig *childConfig = [self configForChild:child]; - if ([child isKindOfClass:[LayoutContainer class]] - || childConfig.widthSpec == LayoutParamWrapContent - || childConfig.heightSpec == LayoutParamWrapContent) { + DoricLinearConfig *childConfig = [self configForChild:child]; + if ([child isKindOfClass:[DoricLayoutContainer class]] + || childConfig.widthSpec == DoricLayoutWrapContent + || childConfig.heightSpec == DoricLayoutWrapContent) { [child sizeToFit]; } self.contentHeight = MAX(self.contentHeight, child.height + childConfig.margin.top + childConfig.margin.bottom); @@ -359,14 +359,14 @@ - (void)sizeToFit { self.contentWeight += childConfig.weight; } self.contentWidth -= self.space; - if (config.widthSpec == LayoutParamWrapContent) { + if (config.widthSpec == DoricLayoutWrapContent) { self.width = self.contentWidth; - } else if (config.widthSpec == LayoutParamAtMost) { + } else if (config.widthSpec == DoricLayoutAtMost) { self.width = self.superview.width; } - if (config.heightSpec == LayoutParamWrapContent) { + if (config.heightSpec == DoricLayoutWrapContent) { self.height = self.contentHeight; - } else if (config.heightSpec == LayoutParamAtMost) { + } else if (config.heightSpec == DoricLayoutAtMost) { self.height = self.superview.height; } if (self.contentWeight) { @@ -375,7 +375,7 @@ - (void)sizeToFit { if (child.isHidden) { continue; } - LinearLayoutConfig *childConfig = [self configForChild:child]; + DoricLinearConfig *childConfig = [self configForChild:child]; if (childConfig.weight) { child.width += remain / self.contentWeight * childConfig.weight; } @@ -397,7 +397,7 @@ - (void)layout { if (child.isHidden) { continue; } - LinearLayoutConfig *childConfig = [self configForChild:child]; + DoricLinearConfig *childConfig = [self configForChild:child]; DoricGravity gravity = childConfig.alignment | self.gravity; if ((gravity & TOP) == TOP) { child.top = 0; @@ -413,10 +413,10 @@ - (void)layout { } } - if (childConfig.heightSpec == LayoutParamAtMost) { + if (childConfig.heightSpec == DoricLayoutAtMost) { child.height = self.height; } - if (childConfig.widthSpec == LayoutParamAtMost) { + if (childConfig.widthSpec == DoricLayoutAtMost) { child.width = self.width - xStart - childConfig.margin.right - childConfig.margin.left - self.space; } @@ -428,8 +428,8 @@ - (void)layout { if (childConfig.margin.right) { xStart += childConfig.margin.right; } - if ([child isKindOfClass:[LayoutContainer class]]) { - [(LayoutContainer *) child layout]; + if ([child isKindOfClass:[DoricLayoutContainer class]]) { + [(DoricLayoutContainer *) child layout]; } } } @@ -441,11 +441,11 @@ - (void)layout { @implementation UIView (LayoutConfig) @dynamic layoutConfig; -- (void)setLayoutConfig:(LayoutConfig *)layoutConfig { +- (void)setLayoutConfig:(DoricLayoutConfig *)layoutConfig { objc_setAssociatedObject(self, kLayoutConfig, layoutConfig, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } -- (LayoutConfig *)layoutConfig { +- (DoricLayoutConfig *)layoutConfig { return objc_getAssociatedObject(self, kLayoutConfig); } @@ -471,7 +471,7 @@ - (UIView *)viewWithTagString:(NSString *)tagString { for (__kindof UIView *uiView in views) { [layout addSubview:uiView]; } - layout.layoutConfig = [[LayoutConfig alloc] initWithWidth:LayoutParamWrapContent height:LayoutParamWrapContent]; + layout.layoutConfig = [[DoricLayoutConfig alloc] initWithWidth:DoricLayoutWrapContent height:DoricLayoutWrapContent]; return layout; } @@ -480,7 +480,7 @@ - (UIView *)viewWithTagString:(NSString *)tagString { for (__kindof UIView *uiView in views) { [layout addSubview:uiView]; } - layout.layoutConfig = [[LayoutConfig alloc] initWithWidth:LayoutParamWrapContent height:LayoutParamWrapContent]; + layout.layoutConfig = [[DoricLayoutConfig alloc] initWithWidth:DoricLayoutWrapContent height:DoricLayoutWrapContent]; return layout; } @@ -490,7 +490,7 @@ - (UIView *)viewWithTagString:(NSString *)tagString { for (block in blocks) { [layout addSubview:block()]; } - layout.layoutConfig = [[LayoutConfig alloc] initWithWidth:LayoutParamWrapContent height:LayoutParamWrapContent]; + layout.layoutConfig = [[DoricLayoutConfig alloc] initWithWidth:DoricLayoutWrapContent height:DoricLayoutWrapContent]; return layout; } @@ -500,6 +500,6 @@ - (UIView *)viewWithTagString:(NSString *)tagString { for (block in blocks) { [layout addSubview:block()]; } - layout.layoutConfig = [[LayoutConfig alloc] initWithWidth:LayoutParamWrapContent height:LayoutParamWrapContent]; + layout.layoutConfig = [[DoricLayoutConfig alloc] initWithWidth:DoricLayoutWrapContent height:DoricLayoutWrapContent]; return layout; -} \ No newline at end of file +} diff --git a/iOS/Pod/Classes/Shader/DoricRootNode.h b/iOS/Pod/Classes/Shader/DoricRootNode.h index cc945e8c..58bff00a 100644 --- a/iOS/Pod/Classes/Shader/DoricRootNode.h +++ b/iOS/Pod/Classes/Shader/DoricRootNode.h @@ -26,7 +26,7 @@ NS_ASSUME_NONNULL_BEGIN @interface DoricRootNode : DoricStackNode -- (void)setupRootView:(Stack *)view; +- (void)setupRootView:(DoricStackView *)view; - (void)render:(NSDictionary *)props; @end diff --git a/iOS/Pod/Classes/Shader/DoricRootNode.m b/iOS/Pod/Classes/Shader/DoricRootNode.m index 69f2ad28..ed0ae8db 100644 --- a/iOS/Pod/Classes/Shader/DoricRootNode.m +++ b/iOS/Pod/Classes/Shader/DoricRootNode.m @@ -23,7 +23,7 @@ #import "DoricRootNode.h" @implementation DoricRootNode -- (void)setupRootView:(Stack *)view { +- (void)setupRootView:(DoricStackView *)view { self.view = view; self.layoutConfig = view.layoutConfig; } diff --git a/iOS/Pod/Classes/Shader/DoricStackNode.h b/iOS/Pod/Classes/Shader/DoricStackNode.h index 9d6cbe98..375cafad 100644 --- a/iOS/Pod/Classes/Shader/DoricStackNode.h +++ b/iOS/Pod/Classes/Shader/DoricStackNode.h @@ -22,5 +22,5 @@ #import "DoricGroupNode.h" -@interface DoricStackNode : DoricGroupNode +@interface DoricStackNode : DoricGroupNode @end diff --git a/iOS/Pod/Classes/Shader/DoricStackNode.m b/iOS/Pod/Classes/Shader/DoricStackNode.m index 4023605a..ec1e37af 100644 --- a/iOS/Pod/Classes/Shader/DoricStackNode.m +++ b/iOS/Pod/Classes/Shader/DoricStackNode.m @@ -25,11 +25,11 @@ @implementation DoricStackNode -- (Stack *)build:(NSDictionary *)props { - return [Stack new]; +- (DoricStackView *)build:(NSDictionary *)props { + return [DoricStackView new]; } -- (void)blendView:(Stack *)view forPropName:(NSString *)name propValue:(id)prop { +- (void)blendView:(DoricStackView *)view forPropName:(NSString *)name propValue:(id)prop { if ([name isEqualToString:@"gravity"]) { view.gravity = (DoricGravity) [(NSNumber *) prop integerValue]; } else { @@ -37,17 +37,17 @@ - (void)blendView:(Stack *)view forPropName:(NSString *)name propValue:(id)prop } } -- (StackLayoutConfig *)generateDefaultLayoutParams { - return [[StackLayoutConfig alloc] init]; +- (DoricStackConfig *)generateDefaultLayoutParams { + return [[DoricStackConfig alloc] init]; } - (void)blendChild:(DoricViewNode *)child layoutConfig:(NSDictionary *)layoutConfig { [super blendChild:child layoutConfig:layoutConfig]; - if (![child.layoutConfig isKindOfClass:StackLayoutConfig.class]) { + if (![child.layoutConfig isKindOfClass:DoricStackConfig.class]) { DoricLog(@"blend HLayout child error,layout params not match"); return; } - StackLayoutConfig *params = (StackLayoutConfig *) child.layoutConfig; + DoricStackConfig *params = (DoricStackConfig *) child.layoutConfig; NSNumber *alignment = layoutConfig[@"alignment"]; if (alignment) { params.alignment = (DoricGravity) [alignment integerValue]; diff --git a/iOS/Pod/Classes/Shader/DoricVLayoutNode.h b/iOS/Pod/Classes/Shader/DoricVLayoutNode.h index 2ed3bfbd..28cde7d3 100644 --- a/iOS/Pod/Classes/Shader/DoricVLayoutNode.h +++ b/iOS/Pod/Classes/Shader/DoricVLayoutNode.h @@ -22,5 +22,5 @@ #import "DoricGroupNode.h" -@interface DoricVLayoutNode : DoricGroupNode +@interface DoricVLayoutNode : DoricGroupNode @end diff --git a/iOS/Pod/Classes/Shader/DoricVLayoutNode.m b/iOS/Pod/Classes/Shader/DoricVLayoutNode.m index 94b00765..243b04fd 100644 --- a/iOS/Pod/Classes/Shader/DoricVLayoutNode.m +++ b/iOS/Pod/Classes/Shader/DoricVLayoutNode.m @@ -41,14 +41,14 @@ - (void)blendView:(VLayout *)view forPropName:(NSString *)name propValue:(id)pro - (void)blendChild:(DoricViewNode *)child layoutConfig:(NSDictionary *)layoutconfig { [super blendChild:child layoutConfig:layoutconfig]; - if (![child.layoutConfig isKindOfClass:LinearLayoutConfig.class]) { + if (![child.layoutConfig isKindOfClass:DoricLinearConfig.class]) { DoricLog(@"blend VLayout child error,layout params not match"); return; } - LinearLayoutConfig *params = (LinearLayoutConfig *) child.layoutConfig; + DoricLinearConfig *params = (DoricLinearConfig *) child.layoutConfig; NSDictionary *margin = layoutconfig[@"margin"]; if (margin) { - params.margin = MarginMake( + params.margin = DoricMarginMake( [(NSNumber *) margin[@"left"] floatValue], [(NSNumber *) margin[@"top"] floatValue], [(NSNumber *) margin[@"right"] floatValue], @@ -60,7 +60,7 @@ - (void)blendChild:(DoricViewNode *)child layoutConfig:(NSDictionary *)layoutcon } } -- (LinearLayoutConfig *)generateDefaultLayoutParams { - return [[LinearLayoutConfig alloc] init]; +- (DoricLinearConfig *)generateDefaultLayoutParams { + return [[DoricLinearConfig alloc] init]; } @end diff --git a/iOS/Pod/Classes/Shader/DoricViewNode.h b/iOS/Pod/Classes/Shader/DoricViewNode.h index 36dcc378..f7333e42 100644 --- a/iOS/Pod/Classes/Shader/DoricViewNode.h +++ b/iOS/Pod/Classes/Shader/DoricViewNode.h @@ -21,7 +21,7 @@ // #import "DoricContextHolder.h" -#import "DoricLinearLayout.h" +#import "DoricLayouts.h" #import "UIView+Doric.h" NS_ASSUME_NONNULL_BEGIN @@ -36,7 +36,7 @@ NS_ASSUME_NONNULL_BEGIN @property(nonatomic, strong) NSString *viewId; -@property(nonatomic, strong) LayoutConfig *layoutConfig; +@property(nonatomic, strong) DoricLayoutConfig *layoutConfig; @property(nonatomic, strong, readonly) NSArray *idList; From c9f1f099ae5318c719258487487f7c1c83a4f342 Mon Sep 17 00:00:00 2001 From: "pengfei.zhou" Date: Wed, 23 Oct 2019 20:11:24 +0800 Subject: [PATCH 9/9] feat:rename vlayout and hlayout --- iOS/Pod/Classes/Shader/DoricHLayoutNode.h | 2 +- iOS/Pod/Classes/Shader/DoricHLayoutNode.m | 8 +++--- iOS/Pod/Classes/Shader/DoricLayouts.h | 16 +++-------- iOS/Pod/Classes/Shader/DoricLayouts.m | 34 +++++++++++------------ iOS/Pod/Classes/Shader/DoricStackNode.m | 2 +- iOS/Pod/Classes/Shader/DoricVLayoutNode.h | 2 +- iOS/Pod/Classes/Shader/DoricVLayoutNode.m | 8 +++--- 7 files changed, 32 insertions(+), 40 deletions(-) diff --git a/iOS/Pod/Classes/Shader/DoricHLayoutNode.h b/iOS/Pod/Classes/Shader/DoricHLayoutNode.h index 4e754d28..4f6d6086 100644 --- a/iOS/Pod/Classes/Shader/DoricHLayoutNode.h +++ b/iOS/Pod/Classes/Shader/DoricHLayoutNode.h @@ -22,5 +22,5 @@ #import "DoricGroupNode.h" -@interface DoricHLayoutNode : DoricGroupNode +@interface DoricHLayoutNode : DoricGroupNode @end diff --git a/iOS/Pod/Classes/Shader/DoricHLayoutNode.m b/iOS/Pod/Classes/Shader/DoricHLayoutNode.m index de2f0c00..5292ae4d 100644 --- a/iOS/Pod/Classes/Shader/DoricHLayoutNode.m +++ b/iOS/Pod/Classes/Shader/DoricHLayoutNode.m @@ -24,11 +24,11 @@ #import "DoricUtil.h" @implementation DoricHLayoutNode -- (HLayout *)build:(NSDictionary *)props { - return [HLayout new]; +- (DoricHLayoutView *)build:(NSDictionary *)props { + return [DoricHLayoutView new]; } -- (void)blendView:(HLayout *)view forPropName:(NSString *)name propValue:(id)prop { +- (void)blendView:(DoricHLayoutView *)view forPropName:(NSString *)name propValue:(id)prop { if ([name isEqualToString:@"gravity"]) { view.gravity = (DoricGravity) [(NSNumber *) prop integerValue]; } else if ([name isEqualToString:@"space"]) { @@ -41,7 +41,7 @@ - (void)blendView:(HLayout *)view forPropName:(NSString *)name propValue:(id)pro - (void)blendChild:(DoricViewNode *)child layoutConfig:(NSDictionary *)layoutConfig { [super blendChild:child layoutConfig:layoutConfig]; if (![child.layoutConfig isKindOfClass:DoricLinearConfig.class]) { - DoricLog(@"blend HLayout child error,layout params not match"); + DoricLog(@"blend DoricHLayoutView child error,layout params not match"); return; } DoricLinearConfig *params = (DoricLinearConfig *) child.layoutConfig; diff --git a/iOS/Pod/Classes/Shader/DoricLayouts.h b/iOS/Pod/Classes/Shader/DoricLayouts.h index 421b27b3..8b825e6f 100644 --- a/iOS/Pod/Classes/Shader/DoricLayouts.h +++ b/iOS/Pod/Classes/Shader/DoricLayouts.h @@ -89,29 +89,21 @@ typedef NS_ENUM(NSInteger, DoricGravity) { @property(nonatomic, assign) DoricGravity gravity; @end -@interface LinearLayout : DoricLayoutContainer +@interface DoricLinearView : DoricLayoutContainer @property(nonatomic, assign) DoricGravity gravity; @property(nonatomic, assign) CGFloat space; @end -@interface VLayout : LinearLayout +@interface DoricVLayoutView : DoricLinearView @end -@interface HLayout : LinearLayout +@interface DoricHLayoutView : DoricLinearView @end -@interface UIView (LayoutConfig) +@interface UIView (DoricLayoutConfig) @property(nonatomic, strong) DoricLayoutConfig *layoutConfig; @property(nonatomic, copy) NSString *tagString; - (UIView *)viewWithTagString:(NSString *)tagString; @end - -VLayout *vLayout(NSArray <__kindof UIView *> *views); - -HLayout *hLayout(NSArray <__kindof UIView *> *views); - -VLayout *vLayoutWithBlock(NSArray *blocks); - -HLayout *hLayoutWithBlock(NSArray *blocks); diff --git a/iOS/Pod/Classes/Shader/DoricLayouts.m b/iOS/Pod/Classes/Shader/DoricLayouts.m index f8d67ce3..2a6777d6 100644 --- a/iOS/Pod/Classes/Shader/DoricLayouts.m +++ b/iOS/Pod/Classes/Shader/DoricLayouts.m @@ -107,8 +107,8 @@ - (DoricLayoutConfig *)configForChild:(UIView *)child { } - (void)requestLayout { - if ([self.superview isKindOfClass:[LinearLayout class]]) { - [(LinearLayout *) self.superview requestLayout]; + if ([self.superview isKindOfClass:[DoricLinearView class]]) { + [(DoricLinearView *) self.superview requestLayout]; return; } if (self.waitingLayout) { @@ -218,13 +218,13 @@ - (void)layout { } @end -@interface LinearLayout () +@interface DoricLinearView () @property(nonatomic, assign) CGFloat contentWidth; @property(nonatomic, assign) CGFloat contentHeight; @property(nonatomic, assign) NSUInteger contentWeight; @end -@implementation LinearLayout +@implementation DoricLinearView - (DoricLinearConfig *)configForChild:(UIView *)child { DoricLinearConfig *config = (DoricLinearConfig *) child.layoutConfig; if (!config) { @@ -234,7 +234,7 @@ - (DoricLinearConfig *)configForChild:(UIView *)child { } @end -@implementation VLayout +@implementation DoricVLayoutView - (void)sizeToFit { DoricLayoutConfig *config = self.layoutConfig; @@ -330,11 +330,11 @@ - (void)layout { } @end -@implementation HLayout +@implementation DoricHLayoutView - (void)sizeToFit { DoricLinearConfig *config; - if ([self.superview isKindOfClass:[LinearLayout class]]) { - config = [(LinearLayout *) self.superview configForChild:self]; + if ([self.superview isKindOfClass:[DoricLinearView class]]) { + config = [(DoricLinearView *) self.superview configForChild:self]; } else { config = (DoricLinearConfig *) self.layoutConfig; if (!config) { @@ -438,7 +438,7 @@ - (void)layout { static const void *kLayoutConfig = &kLayoutConfig; static const void *kTagString = &kTagString; -@implementation UIView (LayoutConfig) +@implementation UIView (DoricLayoutConfig) @dynamic layoutConfig; - (void)setLayoutConfig:(DoricLayoutConfig *)layoutConfig { @@ -466,8 +466,8 @@ - (UIView *)viewWithTagString:(NSString *)tagString { @end -VLayout *vLayout(NSArray <__kindof UIView *> *views) { - VLayout *layout = [[VLayout alloc] initWithFrame:CGRectZero]; +DoricVLayoutView *vLayout(NSArray <__kindof UIView *> *views) { + DoricVLayoutView *layout = [[DoricVLayoutView alloc] initWithFrame:CGRectZero]; for (__kindof UIView *uiView in views) { [layout addSubview:uiView]; } @@ -475,8 +475,8 @@ - (UIView *)viewWithTagString:(NSString *)tagString { return layout; } -HLayout *hLayout(NSArray <__kindof UIView *> *views) { - HLayout *layout = [[HLayout alloc] initWithFrame:CGRectZero]; +DoricHLayoutView *hLayout(NSArray <__kindof UIView *> *views) { + DoricHLayoutView *layout = [[DoricHLayoutView alloc] initWithFrame:CGRectZero]; for (__kindof UIView *uiView in views) { [layout addSubview:uiView]; } @@ -484,8 +484,8 @@ - (UIView *)viewWithTagString:(NSString *)tagString { return layout; } -VLayout *vLayoutWithBlock(NSArray *blocks) { - VLayout *layout = [[VLayout alloc] initWithFrame:CGRectZero]; +DoricVLayoutView *vLayoutWithBlock(NSArray *blocks) { + DoricVLayoutView *layout = [[DoricVLayoutView alloc] initWithFrame:CGRectZero]; UIView *(^block)(); for (block in blocks) { [layout addSubview:block()]; @@ -494,8 +494,8 @@ - (UIView *)viewWithTagString:(NSString *)tagString { return layout; } -HLayout *hLayoutWithBlock(NSArray *blocks) { - HLayout *layout = [[HLayout alloc] initWithFrame:CGRectZero]; +DoricHLayoutView *hLayoutWithBlock(NSArray *blocks) { + DoricHLayoutView *layout = [[DoricHLayoutView alloc] initWithFrame:CGRectZero]; UIView *(^block)(); for (block in blocks) { [layout addSubview:block()]; diff --git a/iOS/Pod/Classes/Shader/DoricStackNode.m b/iOS/Pod/Classes/Shader/DoricStackNode.m index ec1e37af..c260248f 100644 --- a/iOS/Pod/Classes/Shader/DoricStackNode.m +++ b/iOS/Pod/Classes/Shader/DoricStackNode.m @@ -44,7 +44,7 @@ - (DoricStackConfig *)generateDefaultLayoutParams { - (void)blendChild:(DoricViewNode *)child layoutConfig:(NSDictionary *)layoutConfig { [super blendChild:child layoutConfig:layoutConfig]; if (![child.layoutConfig isKindOfClass:DoricStackConfig.class]) { - DoricLog(@"blend HLayout child error,layout params not match"); + DoricLog(@"blend DoricHLayoutView child error,layout params not match"); return; } DoricStackConfig *params = (DoricStackConfig *) child.layoutConfig; diff --git a/iOS/Pod/Classes/Shader/DoricVLayoutNode.h b/iOS/Pod/Classes/Shader/DoricVLayoutNode.h index 28cde7d3..6024eaa2 100644 --- a/iOS/Pod/Classes/Shader/DoricVLayoutNode.h +++ b/iOS/Pod/Classes/Shader/DoricVLayoutNode.h @@ -22,5 +22,5 @@ #import "DoricGroupNode.h" -@interface DoricVLayoutNode : DoricGroupNode +@interface DoricVLayoutNode : DoricGroupNode @end diff --git a/iOS/Pod/Classes/Shader/DoricVLayoutNode.m b/iOS/Pod/Classes/Shader/DoricVLayoutNode.m index 243b04fd..7b586e4c 100644 --- a/iOS/Pod/Classes/Shader/DoricVLayoutNode.m +++ b/iOS/Pod/Classes/Shader/DoricVLayoutNode.m @@ -25,11 +25,11 @@ @implementation DoricVLayoutNode -- (VLayout *)build:(NSDictionary *)props { - return [VLayout new]; +- (DoricVLayoutView *)build:(NSDictionary *)props { + return [DoricVLayoutView new]; } -- (void)blendView:(VLayout *)view forPropName:(NSString *)name propValue:(id)prop { +- (void)blendView:(DoricVLayoutView *)view forPropName:(NSString *)name propValue:(id)prop { if ([name isEqualToString:@"gravity"]) { view.gravity = (DoricGravity) [(NSNumber *) prop integerValue]; } else if ([name isEqualToString:@"space"]) { @@ -42,7 +42,7 @@ - (void)blendView:(VLayout *)view forPropName:(NSString *)name propValue:(id)pro - (void)blendChild:(DoricViewNode *)child layoutConfig:(NSDictionary *)layoutconfig { [super blendChild:child layoutConfig:layoutconfig]; if (![child.layoutConfig isKindOfClass:DoricLinearConfig.class]) { - DoricLog(@"blend VLayout child error,layout params not match"); + DoricLog(@"blend DoricVLayoutView child error,layout params not match"); return; } DoricLinearConfig *params = (DoricLinearConfig *) child.layoutConfig;