use css flex and box to implement stack and vlayout and hlayout

This commit is contained in:
pengfei.zhou 2019-12-21 11:09:27 +08:00
parent ef88d9c092
commit c8f3b5db00
11 changed files with 729 additions and 793 deletions

423
dist/Counter.js vendored
View File

@ -8,118 +8,337 @@ var __decorate = (undefined && undefined.__decorate) || function (decorators, ta
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (undefined && undefined.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
class CounterView extends doric.ViewHolder {
build(root) {
root.addChild(doric.vlayout([
doric.text({
textSize: 40,
layoutConfig: {
alignment: doric.Gravity.Center,
widthSpec: doric.LayoutSpec.FIT,
heightSpec: doric.LayoutSpec.FIT,
},
}).also(it => { this.number = it; }),
doric.text({
text: "点击计数",
textSize: 20,
border: {
width: 1,
color: doric.Color.parse('#000000'),
},
corners: 5,
layoutConfig: {
alignment: doric.Gravity.Center,
widthSpec: doric.LayoutSpec.FIT,
heightSpec: doric.LayoutSpec.FIT,
},
padding: {
left: 10,
right: 10,
top: 10,
bottom: 10,
},
shadow: {
color: doric.Color.parse("#00ff00"),
opacity: 0.5,
radius: 20,
offsetX: 10,
offsetY: 10,
}
}).also(it => { this.counter = it; }),
]).also(it => {
it.width = 200;
it.height = 200;
it.space = 20;
it.gravity = doric.Gravity.Center;
it.layoutConfig = {
alignment: doric.Gravity.Center
};
it.border = {
width: 1,
color: doric.Color.parse("#000000"),
};
it.shadow = {
color: doric.Color.parse("#ffff00"),
opacity: 0.5,
radius: 20,
offsetX: 10,
offsetY: 10,
};
it.corners = 20;
it.backgroundColor = doric.Color.parse('#ff00ff');
}));
// root.addChild((new doric.Image).also(iv => {
// iv.imageUrl = "https://misc.aotu.io/ONE-SUNDAY/SteamEngine.png";
// iv.layoutConfig = {
// widthSpec: doric.LayoutSpec.FIT,
// heightSpec: doric.LayoutSpec.FIT,
// };
// }));
var Direction;
(function (Direction) {
Direction[Direction["left"] = 0] = "left";
Direction[Direction["right"] = 1] = "right";
Direction[Direction["up"] = 2] = "up";
Direction[Direction["down"] = 3] = "down";
})(Direction || (Direction = {}));
var State;
(function (State) {
State[State["idel"] = 0] = "idel";
State[State["run"] = 1] = "run";
State[State["fail"] = 2] = "fail";
})(State || (State = {}));
class SnakeModel {
constructor(w, h) {
this.state = State.idel;
this.direction = Direction.right;
this.food = { x: -1, y: -1 };
this.head = {
x: 0,
y: 0,
};
this.width = w;
this.height = h;
}
refreshFood() {
this.food.x = Math.floor(Math.random() * (this.width - 1));
this.food.y = Math.floor(Math.random() * (this.height - 1));
}
get tail() {
let node = this.head;
while (node.next !== undefined) {
node = node.next;
}
return node;
}
get score() {
let node = this.head;
let n = 0;
while (node.next !== undefined) {
n++;
node = node.next;
}
return n;
}
forward(node) {
switch (this.direction) {
case Direction.left:
node.x -= 1;
break;
case Direction.right:
node.x += 1;
break;
case Direction.up:
node.y -= 1;
break;
case Direction.down:
node.y += 1;
break;
}
}
step() {
if (this.state !== State.run) {
return;
}
let tail = this.tail;
while (tail.prev != undefined) {
tail.x = tail.prev.x;
tail.y = tail.prev.y;
tail = tail.prev;
}
this.forward(this.head);
if (this.head.x < 0 || this.head.x >= this.width
|| this.head.y < 0 || this.head.y >= this.height) {
//If out of bound
doric.loge('out of bound');
this.state = State.fail;
}
else if (this.head.x == this.food.x && this.head.y == this.food.y) {
//If eat food
let head = { x: this.food.x, y: this.food.y };
doric.log('eat food', head);
this.forward(head);
this.head.prev = head;
head.next = this.head;
this.head = head;
this.refreshFood();
}
if (this.crashAtSelf()) {
//If crash at self
doric.loge('crash at self');
this.state = State.fail;
}
}
crashAtSelf() {
let cur = this.head.next;
while (cur !== undefined) {
if (cur.x == this.head.x && cur.y == this.head.y) {
return true;
}
cur = cur.next;
}
return false;
}
reset() {
this.direction = Direction.right;
this.state = State.run;
this.head.x = 0;
this.head.y = 0;
this.head.next = undefined;
this.refreshFood();
}
}
class CounterVM extends doric.ViewModel {
onAttached(s, vh) {
vh.counter.onClick = () => {
this.updateState(state => {
state.count++;
});
class SnakeView extends doric.ViewHolder {
build(root) {
root.backgroundColor = doric.Color.parse('#000000');
doric.vlayout([
doric.text({
text: "Snake",
textSize: 20,
textColor: doric.Color.parse("#ffffff"),
layoutConfig: {
alignment: new doric.Gravity().centerX(),
margin: {
top: 20
},
widthSpec: doric.LayoutSpec.FIT,
heightSpec: doric.LayoutSpec.FIT,
},
}),
(new doric.Stack).also(panel => {
panel.backgroundColor = doric.Color.parse('#00ff00');
this.panel = panel;
}),
doric.hlayout([
doric.text({
text: "Start",
textSize: 30,
textColor: doric.Color.parse("#ffffff"),
layoutConfig: {
widthSpec: doric.LayoutSpec.FIT,
heightSpec: doric.LayoutSpec.FIT,
},
}).also(it => this.start = it),
]).also(it => {
it.layoutConfig = {
widthSpec: doric.LayoutSpec.FIT,
heightSpec: doric.LayoutSpec.FIT,
};
}),
doric.vlayout([
doric.hlayout([
doric.text({
width: 50,
height: 50,
text: "↑",
textSize: 30,
textAlignment: new doric.Gravity().center(),
backgroundColor: doric.Color.parse('#ffff00'),
layoutConfig: {
widthSpec: doric.LayoutSpec.JUST,
heightSpec: doric.LayoutSpec.JUST,
},
}).also(it => this.up = it)
]).also(it => {
it.layoutConfig = {
widthSpec: doric.LayoutSpec.FIT,
heightSpec: doric.LayoutSpec.FIT,
};
}),
doric.hlayout([
doric.text({
width: 50,
height: 50,
text: "←",
textSize: 30,
textAlignment: new doric.Gravity().center(),
backgroundColor: doric.Color.parse('#ffff00'),
layoutConfig: {
widthSpec: doric.LayoutSpec.JUST,
heightSpec: doric.LayoutSpec.JUST,
},
}).also(it => this.left = it),
doric.text({
width: 50,
height: 50,
text: "↓",
textSize: 30,
textAlignment: new doric.Gravity().center(),
backgroundColor: doric.Color.parse('#ffff00'),
layoutConfig: {
widthSpec: doric.LayoutSpec.JUST,
heightSpec: doric.LayoutSpec.JUST,
},
}).also(it => this.down = it),
doric.text({
width: 50,
height: 50,
text: "→",
textSize: 30,
textAlignment: new doric.Gravity().center(),
backgroundColor: doric.Color.parse('#ffff00'),
layoutConfig: {
widthSpec: doric.LayoutSpec.JUST,
heightSpec: doric.LayoutSpec.JUST,
},
}).also(it => this.right = it),
]).also(it => {
it.layoutConfig = {
widthSpec: doric.LayoutSpec.FIT,
heightSpec: doric.LayoutSpec.FIT,
};
it.space = 10;
}),
]).also(controlArea => {
controlArea.gravity = new doric.Gravity().centerX();
controlArea.space = 10;
controlArea.layoutConfig = {
alignment: new doric.Gravity().centerX(),
widthSpec: doric.LayoutSpec.FIT,
heightSpec: doric.LayoutSpec.FIT,
};
}),
]).also(it => {
it.space = 20;
it.layoutConfig = {
alignment: new doric.Gravity().centerX().top(),
widthSpec: doric.LayoutSpec.MOST,
heightSpec: doric.LayoutSpec.MOST,
};
it.gravity = new doric.Gravity().centerX();
}).in(root);
}
bind(state) {
doric.log('build', state);
this.panel.width = state.width * 10;
this.panel.height = state.height * 10;
let node = state.head;
let nodes = [];
while (node != undefined) {
nodes.push(node);
node = node.next;
}
nodes.push(state.food);
nodes.forEach((e, index) => {
let item = this.panel.children[index];
if (item === undefined) {
item = new doric.Stack;
item.width = item.height = 10;
item.corners = 5;
item.shadow = {
color: doric.Color.GRAY,
opacity: 1,
radius: 3,
offsetX: 3,
offsetY: 3,
};
this.panel.addChild(item);
}
if (index === nodes.length - 1) {
item.backgroundColor = doric.Color.parse('#ffff00');
}
else {
item.backgroundColor = doric.Color.parse('#ff0000');
}
item.x = e.x * 10;
item.y = e.y * 10;
});
if (nodes.length < this.panel.children.length) {
this.panel.children.length = nodes.length;
}
}
}
class SnakeVM extends doric.ViewModel {
constructor() {
super(...arguments);
this.start = () => {
if (this.timerId !== undefined) {
clearInterval(this.timerId);
}
this.updateState(it => it.reset());
this.timerId = setInterval(() => {
this.updateState(it => it.step());
if (this.getState().state === State.fail) {
doric.loge('Game Over');
this.stop();
}
}, 500);
};
this.stop = () => {
if (this.timerId !== undefined) {
clearInterval(this.timerId);
this.timerId = undefined;
}
};
this.left = () => {
this.updateState(it => it.direction = Direction.left);
};
this.right = () => {
this.updateState(it => it.direction = Direction.right);
};
this.up = () => {
this.updateState(it => it.direction = Direction.up);
};
this.down = () => {
this.updateState(it => it.direction = Direction.down);
};
}
onBind(s, vh) {
vh.number.text = `${s.count}`;
onAttached(state, v) {
doric.takeNonNull(v.start)(it => it.onClick = this.start);
doric.takeNonNull(v.left)(it => it.onClick = this.left);
doric.takeNonNull(v.right)(it => it.onClick = this.right);
doric.takeNonNull(v.up)(it => it.onClick = this.up);
doric.takeNonNull(v.down)(it => it.onClick = this.down);
}
onBind(state, v) {
v.bind(state);
}
}
let MyPage = class MyPage extends doric.VMPanel {
getViewHolderClass() {
return CounterView;
}
let SnakePanel = class SnakePanel extends doric.VMPanel {
getViewModelClass() {
return CounterVM;
return SnakeVM;
}
getState() {
return {
count: 0
};
return new SnakeModel(35, 35);
}
log() {
doric.log("Hello.HEGO");
doric.logw("Hello.HEGO");
doric.loge("Hello.HEGO");
context.modal.toast('This is a toast.').then((r) => {
doric.loge(r);
});
getViewHolderClass() {
return SnakeView;
}
};
__decorate([
doric.NativeCall,
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", void 0)
], MyPage.prototype, "log", null);
MyPage = __decorate([
SnakePanel = __decorate([
Entry
], MyPage);
//# sourceMappingURL=Counter.js.map
], SnakePanel);
//# sourceMappingURL=Snake.js.map

622
dist/index.js vendored
View File

@ -1330,11 +1330,12 @@ var doric = (function (exports) {
}
function jsReleaseContext(id) {
const context = gContexts.get(id);
const args = arguments;
if (context) {
timerInfos.forEach((v, k) => {
if (v.context === context) {
if (global$1.nativeClearTimer === undefined) {
return Reflect.apply(_clearTimeout, undefined, arguments);
return Reflect.apply(_clearTimeout, undefined, args);
}
timerInfos.delete(k);
nativeClearTimer(k);
@ -1765,6 +1766,9 @@ class View {
getHeight(context) {
return this.nativeChannel(context, 'getHeight')();
}
getLocationOnScreen(context) {
return this.nativeChannel(context, "getLocationOnScreen")();
}
/**----------transform----------*/
doAnimation(context, animation) {
return this.nativeChannel(context, "doAnimation")(animation.toModel()).then((args) => {
@ -1889,9 +1893,11 @@ class Superview extends View {
toModel() {
const subviews = [];
for (let v of this.allSubviews()) {
v.superview = this;
if (v.isDirty()) {
subviews.push(v.toModel());
if (v != undefined) {
v.superview = this;
if (v.isDirty()) {
subviews.push(v.toModel());
}
}
}
this.dirtyProps.subviews = subviews;
@ -1991,43 +1997,52 @@ function gravity() {
}
(function (LayoutSpec) {
LayoutSpec[LayoutSpec["EXACTLY"] = 0] = "EXACTLY";
LayoutSpec[LayoutSpec["WRAP_CONTENT"] = 1] = "WRAP_CONTENT";
LayoutSpec[LayoutSpec["AT_MOST"] = 2] = "AT_MOST";
/**
* Depends on what's been set on width or height.
*/
LayoutSpec[LayoutSpec["JUST"] = 0] = "JUST";
/**
* Depends on it's content.
*/
LayoutSpec[LayoutSpec["FIT"] = 1] = "FIT";
/**
* Extend as much as parent let it take.
*/
LayoutSpec[LayoutSpec["MOST"] = 2] = "MOST";
})(exports.LayoutSpec || (exports.LayoutSpec = {}));
class LayoutConfigImpl {
wrap() {
this.widthSpec = exports.LayoutSpec.WRAP_CONTENT;
this.heightSpec = exports.LayoutSpec.WRAP_CONTENT;
fit() {
this.widthSpec = exports.LayoutSpec.FIT;
this.heightSpec = exports.LayoutSpec.FIT;
return this;
}
atmost() {
this.widthSpec = exports.LayoutSpec.AT_MOST;
this.heightSpec = exports.LayoutSpec.AT_MOST;
most() {
this.widthSpec = exports.LayoutSpec.MOST;
this.heightSpec = exports.LayoutSpec.MOST;
return this;
}
exactly() {
this.widthSpec = exports.LayoutSpec.EXACTLY;
this.heightSpec = exports.LayoutSpec.EXACTLY;
just() {
this.widthSpec = exports.LayoutSpec.JUST;
this.heightSpec = exports.LayoutSpec.JUST;
return this;
}
w(w) {
configWidth(w) {
this.widthSpec = w;
return this;
}
h(h) {
configHeight(h) {
this.heightSpec = h;
return this;
}
m(m) {
configMargin(m) {
this.margin = m;
return this;
}
a(a) {
configAligmnet(a) {
this.alignment = a;
return this;
}
wg(w) {
configWeight(w) {
this.weight = w;
return this;
}
@ -2074,7 +2089,7 @@ class HLayout extends LinearLayout {
}
function stack(views) {
const ret = new Stack;
ret.layoutConfig = layoutConfig().wrap();
ret.layoutConfig = layoutConfig().fit();
for (let v of views) {
ret.addChild(v);
}
@ -2082,7 +2097,7 @@ function stack(views) {
}
function hlayout(views) {
const ret = new HLayout;
ret.layoutConfig = layoutConfig().wrap();
ret.layoutConfig = layoutConfig().fit();
for (let v of views) {
ret.addChild(v);
}
@ -2090,7 +2105,7 @@ function hlayout(views) {
}
function vlayout(views) {
const ret = new VLayout;
ret.layoutConfig = layoutConfig().wrap();
ret.layoutConfig = layoutConfig().fit();
for (let v of views) {
ret.addChild(v);
}
@ -2268,6 +2283,21 @@ __decorate$2([
__metadata$2("design:returntype", void 0)
], Panel.prototype, "__response__", null);
/*
* Copyright [2019] [Doric.Pub]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function (RepeatMode) {
RepeatMode[RepeatMode["RESTART"] = 1] = "RESTART";
RepeatMode[RepeatMode["REVERSE"] = 2] = "REVERSE";
@ -2575,7 +2605,7 @@ __decorate$3([
], Text.prototype, "textAlignment", void 0);
function text(config) {
const ret = new Text;
ret.layoutConfig = layoutConfig().wrap();
ret.layoutConfig = layoutConfig().fit();
for (let key in config) {
Reflect.set(ret, key, Reflect.get(config, key, config), ret);
}
@ -2610,13 +2640,17 @@ __decorate$4([
Property,
__metadata$4("design:type", Number)
], Image.prototype, "scaleType", void 0);
__decorate$4([
Property,
__metadata$4("design:type", Boolean)
], Image.prototype, "isBlur", void 0);
__decorate$4([
Property,
__metadata$4("design:type", Function)
], Image.prototype, "loadCallback", void 0);
function image(config) {
const ret = new Image;
ret.layoutConfig = layoutConfig().wrap();
ret.layoutConfig = layoutConfig().fit();
for (let key in config) {
Reflect.set(ret, key, Reflect.get(config, key, config), ret);
}
@ -2737,7 +2771,7 @@ function list(config) {
}
function listItem(item) {
return (new ListItem).also((it) => {
it.layoutConfig = layoutConfig().atmost().h(exports.LayoutSpec.WRAP_CONTENT);
it.layoutConfig = layoutConfig().most().configHeight(exports.LayoutSpec.FIT);
it.addChild(item);
});
}
@ -2817,7 +2851,7 @@ __decorate$6([
], Slider.prototype, "onPageSlided", void 0);
function slideItem(item) {
return (new SlideItem).also((it) => {
it.layoutConfig = layoutConfig().wrap();
it.layoutConfig = layoutConfig().fit();
it.addChild(item);
});
}
@ -2846,7 +2880,7 @@ function slider(config) {
*/
function scroller(content) {
return (new Scroller).also(v => {
v.layoutConfig = layoutConfig().wrap();
v.layoutConfig = layoutConfig().fit();
v.content = content;
});
}
@ -2901,7 +2935,7 @@ __decorate$7([
], Refreshable.prototype, "onRefresh", void 0);
function refreshable(config) {
const ret = new Refreshable;
ret.layoutConfig = layoutConfig().wrap();
ret.layoutConfig = layoutConfig().fit();
for (let key in config) {
Reflect.set(ret, key, Reflect.get(config, key, config), ret);
}
@ -2939,7 +2973,12 @@ class FlowLayout extends Superview {
this.batchCount = 15;
}
allSubviews() {
return this.cachedViews.values();
if (this.loadMoreView) {
return [...this.cachedViews.values(), this.loadMoreView];
}
else {
return this.cachedViews.values();
}
}
reset() {
this.cachedViews.clear();
@ -2966,6 +3005,12 @@ class FlowLayout extends Superview {
return listItem.toModel();
});
}
toModel() {
if (this.loadMoreView) {
this.dirtyProps['loadMoreView'] = this.loadMoreView.viewId;
}
return super.toModel();
}
}
__decorate$8([
Property,
@ -2991,6 +3036,18 @@ __decorate$8([
Property,
__metadata$8("design:type", Object)
], FlowLayout.prototype, "batchCount", void 0);
__decorate$8([
Property,
__metadata$8("design:type", Function)
], FlowLayout.prototype, "onLoadMore", void 0);
__decorate$8([
Property,
__metadata$8("design:type", Boolean)
], FlowLayout.prototype, "loadMore", void 0);
__decorate$8([
Property,
__metadata$8("design:type", FlowLayoutItem)
], FlowLayout.prototype, "loadMoreView", void 0);
function flowlayout(config) {
const ret = new FlowLayout;
for (let key in config) {
@ -3000,7 +3057,7 @@ function flowlayout(config) {
}
function flowItem(item) {
return (new FlowLayoutItem).also((it) => {
it.layoutConfig = layoutConfig().wrap();
it.layoutConfig = layoutConfig().fit();
it.addChild(item);
});
}
@ -3334,36 +3391,60 @@ function repeat(action) {
};
}
/*
* 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.
*/
/**
* Only supports x,y,width,height,corner(just for four corners),rotation,bgColor,
* @param panel @see Panel
*/
function animate(panel) {
return (args) => {
return takeLet(panel.context.animate)(it => {
return it.submit().then(() => {
args.animations();
return takeLet(panel.getRootView())(root => {
if (root.isDirty()) {
const model = root.toModel();
model.duration = args.duration;
const ret = it.animateRender(model);
root.clean();
return ret;
}
for (let v of panel.allHeadViews()) {
if (v.isDirty()) {
const model = v.toModel();
function animate(context) {
const entity = context.entity;
if (entity instanceof Panel) {
let panel = entity;
return (args) => {
return takeLet(panel.context.animate)(it => {
return it.submit().then(() => {
args.animations();
return takeLet(panel.getRootView())(root => {
if (root.isDirty()) {
const model = root.toModel();
model.duration = args.duration;
const ret = it.animateRender(model);
it.clean();
root.clean();
return ret;
}
}
throw new Error('Cannot find any animated elements');
for (let v of panel.allHeadViews()) {
if (v.isDirty()) {
const model = v.toModel();
const ret = it.animateRender(model);
it.clean();
return ret;
}
}
throw new Error('Cannot find any animated elements');
});
});
});
});
};
};
}
else {
return (args) => {
return Promise.reject(`Cannot find panel in Context:${context.id}`);
};
}
}
class Observable {
@ -3547,7 +3628,6 @@ return __module.exports;
render(ret) {
this.context.rootNode.viewId = ret.id;
this.context.rootNode.blend(ret.props);
this.context.rootNode.layout();
}
}
@ -3640,26 +3720,72 @@ return __module.exports;
for (let key in props) {
this.blendProps(this.view, key, props[key]);
}
this.onBlended();
this.layout();
}
onBlended() {
}
configBorder() {
if (this.border) {
this.view.style.borderStyle = "solid";
this.view.style.borderWidth = toPixelString(this.border.width);
this.view.style.borderColor = toRGBAString(this.border.color);
}
}
configWidth() {
switch (this.layoutConfig.widthSpec) {
case LayoutSpec.WRAP_CONTENT:
this.view.style.width = "auto";
break;
case LayoutSpec.AT_MOST:
this.view.style.width = "100%";
break;
case LayoutSpec.EXACTLY:
default:
this.view.style.width = toPixelString(this.frameWidth
- this.paddingLeft - this.paddingRight
- this.borderWidth * 2);
break;
}
}
configHeight() {
switch (this.layoutConfig.heightSpec) {
case LayoutSpec.WRAP_CONTENT:
this.view.style.height = "auto";
break;
case LayoutSpec.AT_MOST:
this.view.style.height = "100%";
break;
case LayoutSpec.EXACTLY:
default:
this.view.style.height = toPixelString(this.frameHeight
- this.paddingTop - this.paddingBottom
- this.borderWidth * 2);
break;
}
}
configMargin() {
if (this.layoutConfig.margin) {
this.view.style.marginLeft = toPixelString(this.layoutConfig.margin.left || 0);
this.view.style.marginRight = toPixelString(this.layoutConfig.margin.right || 0);
this.view.style.marginTop = toPixelString(this.layoutConfig.margin.top || 0);
this.view.style.marginBottom = toPixelString(this.layoutConfig.margin.bottom || 0);
}
}
configPadding() {
if (this.padding) {
this.view.style.paddingLeft = toPixelString(this.paddingLeft);
this.view.style.paddingRight = toPixelString(this.paddingRight);
this.view.style.paddingTop = toPixelString(this.paddingTop);
this.view.style.paddingBottom = toPixelString(this.paddingBottom);
}
this.x = this.offsetX;
this.y = this.offsetY;
}
layout() {
this.layoutSelf({ width: this.frameWidth, height: this.frameHeight });
}
layoutSelf(targetSize) {
this.width = targetSize.width;
this.height = targetSize.height;
this.configMargin();
this.configBorder();
this.configPadding();
this.configWidth();
this.configHeight();
}
blendProps(v, propName, prop) {
switch (propName) {
@ -3697,32 +3823,6 @@ return __module.exports;
break;
}
}
set width(v) {
this.view.style.width = toPixelString(v - this.paddingLeft - this.paddingRight - this.borderWidth * 2);
}
get width() {
return this.view.offsetWidth;
}
set height(v) {
this.view.style.height = toPixelString(v - this.paddingTop - this.paddingBottom - this.borderWidth * 2);
}
get height() {
return this.view.offsetHeight;
}
set x(v) {
var _a;
this.view.style.left = toPixelString(v + (((_a = this.superNode) === null || _a === void 0 ? void 0 : _a.paddingLeft) || 0));
}
get x() {
return this.view.offsetLeft;
}
set y(v) {
var _a;
this.view.style.top = toPixelString(v + (((_a = this.superNode) === null || _a === void 0 ? void 0 : _a.paddingTop) || 0));
}
get y() {
return this.view.offsetTop;
}
set backgroundColor(v) {
this.view.style.backgroundColor = toRGBAString(v);
}
@ -3817,6 +3917,9 @@ return __module.exports;
}
blend(props) {
super.blend(props);
}
onBlended() {
super.onBlended();
this.configChildNode();
}
configChildNode() {
@ -3922,94 +4025,15 @@ return __module.exports;
build() {
return document.createElement('div');
}
blend(props) {
super.blend(props);
layout() {
super.layout();
this.configOffset();
}
configOffset() {
this.childNodes.forEach(e => {
e.view.style.position = "absolute";
});
}
measureContentSize(targetSize) {
let width = this.frameWidth;
let height = this.frameHeight;
let contentSize = { width: 0, height: 0 };
let limitSize = {
width: targetSize.width - this.paddingLeft - this.paddingRight,
height: targetSize.height - this.paddingTop - this.paddingBottom,
};
if (this.layoutConfig.widthSpec === LayoutSpec.WRAP_CONTENT
|| this.layoutConfig.heightSpec === LayoutSpec.WRAP_CONTENT) {
contentSize = this.childNodes.reduce((prev, current) => {
const size = current.measureContentSize(limitSize);
return {
width: Math.max(prev.width, size.width),
height: Math.max(prev.height, size.height),
};
}, contentSize);
}
switch (this.layoutConfig.widthSpec) {
case LayoutSpec.AT_MOST:
width = targetSize.width;
break;
case LayoutSpec.WRAP_CONTENT:
width = contentSize.width;
break;
}
switch (this.layoutConfig.heightSpec) {
case LayoutSpec.AT_MOST:
height = targetSize.height;
break;
case LayoutSpec.WRAP_CONTENT:
height = contentSize.height;
break;
}
return { width, height };
}
layoutSelf(targetSize) {
const { width, height } = this.measureContentSize(targetSize);
this.width = width;
this.height = height;
const limitSize = {
width: width - this.paddingLeft - this.paddingRight,
height: height - this.paddingTop - this.paddingBottom,
};
this.childNodes.forEach(e => {
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
e.layoutSelf(limitSize);
let gravity = ((_a = e.layoutConfig) === null || _a === void 0 ? void 0 : _a.alignment) || 0;
if ((gravity & LEFT) === LEFT) {
e.x = 0;
}
else if ((gravity & RIGHT) === RIGHT) {
e.x = width - e.width + this.paddingLeft - this.paddingRight;
}
else if ((gravity & CENTER_X) === CENTER_X) {
e.x = width / 2 - e.width / 2 - this.paddingLeft;
}
else {
if ((_b = e.layoutConfig.margin) === null || _b === void 0 ? void 0 : _b.left) {
e.x = (_c = e.layoutConfig.margin) === null || _c === void 0 ? void 0 : _c.left;
}
else if ((_d = e.layoutConfig.margin) === null || _d === void 0 ? void 0 : _d.right) {
e.x = width - e.width + this.paddingLeft - this.paddingRight - ((_e = e.layoutConfig.margin) === null || _e === void 0 ? void 0 : _e.right);
}
}
if ((gravity & TOP) === TOP) {
e.y = 0;
}
else if ((gravity & BOTTOM) === BOTTOM) {
e.y = height - e.height + this.paddingTop - this.paddingBottom;
}
else if ((gravity & CENTER_Y) === CENTER_Y) {
e.y = height / 2 - e.height / 2 - this.paddingTop;
}
else {
if ((_f = e.layoutConfig.margin) === null || _f === void 0 ? void 0 : _f.top) {
e.y = (_g = e.layoutConfig.margin) === null || _g === void 0 ? void 0 : _g.top;
}
else if ((_h = e.layoutConfig.margin) === null || _h === void 0 ? void 0 : _h.bottom) {
e.y = height - e.height + this.paddingTop - this.paddingBottom - ((_j = e.layoutConfig.margin) === null || _j === void 0 ? void 0 : _j.bottom);
}
}
e.view.style.left = toPixelString(e.offsetX + this.paddingLeft);
e.view.style.top = toPixelString(e.offsetY + this.paddingTop);
});
}
}
@ -4019,11 +4043,6 @@ return __module.exports;
super(...arguments);
this.space = 0;
this.gravity = 0;
this.contentSize = {
width: 0,
height: 0,
weight: 0,
};
}
build() {
const ret = document.createElement('div');
@ -4037,6 +4056,66 @@ return __module.exports;
this.space = prop;
}
else if (propName === 'gravity') {
this.gravity = prop;
if ((this.gravity & LEFT) === LEFT) {
this.view.style.alignItems = "flex-start";
}
else if ((this.gravity & RIGHT) === RIGHT) {
this.view.style.alignItems = "flex-end";
}
else if ((this.gravity & CENTER_X) === CENTER_X) {
this.view.style.alignItems = "center";
}
if ((this.gravity & TOP) === TOP) {
this.view.style.justifyContent = "flex-start";
}
else if ((this.gravity & BOTTOM) === BOTTOM) {
this.view.style.justifyContent = "flex-end";
}
else if ((this.gravity & CENTER_Y) === CENTER_Y) {
this.view.style.justifyContent = "center";
}
}
else {
super.blendProps(v, propName, prop);
}
}
layout() {
super.layout();
this.childNodes.forEach((e, idx) => {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
e.view.style.flexShrink = "0";
if ((_a = e.layoutConfig) === null || _a === void 0 ? void 0 : _a.weight) {
e.view.style.flex = `${(_b = e.layoutConfig) === null || _b === void 0 ? void 0 : _b.weight}`;
}
e.view.style.marginTop = toPixelString(((_d = (_c = e.layoutConfig) === null || _c === void 0 ? void 0 : _c.margin) === null || _d === void 0 ? void 0 : _d.top) || 0);
e.view.style.marginBottom = toPixelString((idx === this.childNodes.length - 1) ? 0 : this.space
+ (((_f = (_e = e.layoutConfig) === null || _e === void 0 ? void 0 : _e.margin) === null || _f === void 0 ? void 0 : _f.bottom) || 0));
e.view.style.marginLeft = toPixelString(((_h = (_g = e.layoutConfig) === null || _g === void 0 ? void 0 : _g.margin) === null || _h === void 0 ? void 0 : _h.left) || 0);
e.view.style.marginRight = toPixelString(((_k = (_j = e.layoutConfig) === null || _j === void 0 ? void 0 : _j.margin) === null || _k === void 0 ? void 0 : _k.right) || 0);
});
}
}
class DoricHLayoutNode extends DoricGroupViewNode {
constructor() {
super(...arguments);
this.space = 0;
this.gravity = 0;
}
build() {
const ret = document.createElement('div');
ret.style.display = "flex";
ret.style.flexDirection = "row";
ret.style.flexWrap = "nowrap";
return ret;
}
blendProps(v, propName, prop) {
if (propName === 'space') {
this.space = prop;
}
else if (propName === 'gravity') {
this.gravity = prop;
this.gravity = prop;
if ((this.gravity & LEFT) === LEFT) {
this.view.style.justifyContent = "flex-start";
@ -4061,179 +4140,19 @@ return __module.exports;
super.blendProps(v, propName, prop);
}
}
measureContentSize(targetSize) {
let width = this.frameWidth;
let height = this.frameHeight;
let contentSize = { width: 0, height: 0, weight: 0 };
let limitSize = {
width: targetSize.width - this.paddingLeft - this.paddingRight,
height: targetSize.height - this.paddingTop - this.paddingBottom,
};
contentSize = this.childNodes.reduce((prev, current) => {
var _a, _b, _c, _d, _e;
const size = current.measureContentSize(limitSize);
return {
width: Math.max(prev.width, size.width),
height: prev.height + size.height + this.space
+ ((_b = (_a = current.layoutConfig) === null || _a === void 0 ? void 0 : _a.margin) === null || _b === void 0 ? void 0 : _b.top) || 0
+ ((_d = (_c = current.layoutConfig) === null || _c === void 0 ? void 0 : _c.margin) === null || _d === void 0 ? void 0 : _d.bottom) || 0,
weight: prev.weight + ((_e = current.layoutConfig) === null || _e === void 0 ? void 0 : _e.weight) || 0
};
}, contentSize);
contentSize.height -= this.space;
switch (this.layoutConfig.widthSpec) {
case LayoutSpec.AT_MOST:
width = targetSize.width;
break;
case LayoutSpec.WRAP_CONTENT:
width = contentSize.width;
break;
}
switch (this.layoutConfig.heightSpec) {
case LayoutSpec.AT_MOST:
height = targetSize.height;
break;
case LayoutSpec.WRAP_CONTENT:
height = contentSize.height;
break;
}
if (contentSize.weight > 0) {
contentSize.height = targetSize.height;
}
this.contentSize = contentSize;
return { width, height };
}
layoutSelf(targetSize) {
const { width, height } = this.measureContentSize(targetSize);
this.width = width;
this.height = height;
}
}
class DoricHLayoutNode extends DoricGroupViewNode {
constructor() {
super(...arguments);
this.space = 0;
this.gravity = 0;
this.contentSize = {
width: 0,
height: 0,
weight: 0,
};
}
build() {
return document.createElement('div');
}
blendProps(v, propName, prop) {
if (propName === 'space') {
this.space = prop;
}
else if (propName === 'gravity') {
this.gravity = prop;
}
else {
super.blendProps(v, propName, prop);
}
}
blend(props) {
super.blend(props);
this.childNodes.forEach(e => {
e.view.style.position = "absolute";
});
}
measureContentSize(targetSize) {
let width = this.frameWidth;
let height = this.frameHeight;
let contentSize = { width: 0, height: 0, weight: 0 };
let limitSize = {
width: targetSize.width - this.paddingLeft - this.paddingRight,
height: targetSize.height - this.paddingTop - this.paddingBottom,
};
contentSize = this.childNodes.reduce((prev, current) => {
var _a, _b, _c, _d, _e;
const size = current.measureContentSize(limitSize);
return {
width: prev.width + size.width + this.space
+ ((_b = (_a = current.layoutConfig) === null || _a === void 0 ? void 0 : _a.margin) === null || _b === void 0 ? void 0 : _b.left) || 0
+ ((_d = (_c = current.layoutConfig) === null || _c === void 0 ? void 0 : _c.margin) === null || _d === void 0 ? void 0 : _d.right) || 0,
height: Math.max(prev.height, size.height),
weight: prev.weight + ((_e = current.layoutConfig) === null || _e === void 0 ? void 0 : _e.weight) || 0
};
}, contentSize);
contentSize.width -= this.space;
switch (this.layoutConfig.widthSpec) {
case LayoutSpec.AT_MOST:
width = targetSize.width;
break;
case LayoutSpec.WRAP_CONTENT:
width = contentSize.width;
break;
}
switch (this.layoutConfig.heightSpec) {
case LayoutSpec.AT_MOST:
height = targetSize.height;
break;
case LayoutSpec.WRAP_CONTENT:
height = contentSize.height;
break;
}
if (contentSize.weight > 0) {
contentSize.width = targetSize.width;
}
this.contentSize = contentSize;
return { width, height };
}
layoutSelf(targetSize) {
const { width, height } = this.measureContentSize(targetSize);
this.width = width;
this.height = height;
let xStart = this.paddingLeft;
if ((this.gravity & LEFT) == LEFT) {
xStart = this.paddingLeft;
}
else if ((this.gravity & RIGHT) == RIGHT) {
xStart = targetSize.width - this.contentSize.width - this.paddingRight;
}
else if ((this.gravity & CENTER_X) == CENTER_X) {
xStart = (targetSize.width - this.contentSize.width - this.paddingLeft - this.paddingRight) / 2 + this.paddingLeft;
}
let remain = targetSize.width - this.contentSize.width - this.paddingLeft - this.paddingRight;
this.childNodes.forEach(e => {
var _a, _b, _c, _d, _e, _f, _g, _h;
const childTargetSize = {
width: width - xStart - this.paddingRight,
height: height - this.paddingTop - this.paddingBottom,
};
if (((_a = e.layoutConfig) === null || _a === void 0 ? void 0 : _a.weight) > 0) {
childTargetSize.width += remain / this.contentSize.weight * e.layoutConfig.weight;
}
e.layoutSelf(childTargetSize);
let gravity = ((_b = e.layoutConfig) === null || _b === void 0 ? void 0 : _b.alignment) | this.gravity;
if ((gravity & TOP) === TOP) {
e.y = 0;
}
else if ((gravity & BOTTOM) === BOTTOM) {
e.y = height - e.height + this.paddingTop - this.paddingBottom;
}
else if ((gravity & CENTER_Y) === CENTER_Y) {
e.x = height / 2 - e.height / 2 - this.paddingTop;
}
else {
if ((_c = e.layoutConfig.margin) === null || _c === void 0 ? void 0 : _c.left) {
e.x = (_d = e.layoutConfig.margin) === null || _d === void 0 ? void 0 : _d.left;
}
else if ((_e = e.layoutConfig.margin) === null || _e === void 0 ? void 0 : _e.right) {
e.x = width - e.width + this.paddingLeft - this.paddingRight - ((_f = e.layoutConfig.margin) === null || _f === void 0 ? void 0 : _f.right);
}
}
if (((_g = e.layoutConfig.margin) === null || _g === void 0 ? void 0 : _g.left) !== undefined) {
xStart += e.layoutConfig.margin.left;
}
e.x = xStart - this.paddingLeft;
xStart += e.width + this.space;
if (((_h = e.layoutConfig.margin) === null || _h === void 0 ? void 0 : _h.right) !== undefined) {
xStart += e.layoutConfig.margin.right;
layout() {
super.layout();
this.childNodes.forEach((e, idx) => {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
e.view.style.flexShrink = "0";
if ((_a = e.layoutConfig) === null || _a === void 0 ? void 0 : _a.weight) {
e.view.style.flex = `${(_b = e.layoutConfig) === null || _b === void 0 ? void 0 : _b.weight}`;
}
e.view.style.marginLeft = toPixelString(((_d = (_c = e.layoutConfig) === null || _c === void 0 ? void 0 : _c.margin) === null || _d === void 0 ? void 0 : _d.left) || 0);
e.view.style.marginRight = toPixelString((idx === this.childNodes.length - 1) ? 0 : this.space
+ (((_f = (_e = e.layoutConfig) === null || _e === void 0 ? void 0 : _e.margin) === null || _f === void 0 ? void 0 : _f.right) || 0));
e.view.style.marginTop = toPixelString(((_h = (_g = e.layoutConfig) === null || _g === void 0 ? void 0 : _g.margin) === null || _h === void 0 ? void 0 : _h.top) || 0);
e.view.style.marginBottom = toPixelString(((_k = (_j = e.layoutConfig) === null || _j === void 0 ? void 0 : _j.margin) === null || _k === void 0 ? void 0 : _k.bottom) || 0);
});
}
}
@ -4242,9 +4161,6 @@ return __module.exports;
build() {
return document.createElement('p');
}
measureContentSize(targetSize) {
return targetSize;
}
blendProps(v, propName, prop) {
switch (propName) {
case 'text':

2
dist/index.js.map vendored

File diff suppressed because one or more lines are too long

52
package-lock.json generated
View File

@ -4,11 +4,6 @@
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@types/estree": {
"version": "0.0.40",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.40.tgz",
"integrity": "sha512-p3KZgMto/JyxosKGmnLDJ/dG5wf+qTRMUjHJcspC2oQKa4jP7mz+tv0ND56lLBu3ojHlhzY33Ol+khLyNmilkA=="
},
"@types/node": {
"version": "12.12.20",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.20.tgz",
@ -22,19 +17,6 @@
"@types/node": "*"
}
},
"@types/ws": {
"version": "6.0.4",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-6.0.4.tgz",
"integrity": "sha512-PpPrX7SZW9re6+Ha8ojZG4Se8AZXgf0GK6zmfqEuCsY49LFDNXO3SByp44X3dFEqtB73lkCDAdUazhAjVPiNwg==",
"requires": {
"@types/node": "*"
}
},
"acorn": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz",
"integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ=="
},
"axios": {
"version": "0.19.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.19.0.tgz",
@ -58,13 +40,11 @@
}
},
"doric": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/doric/-/doric-0.1.3.tgz",
"integrity": "sha512-LChTWodhBAWmIamafGo5DbdV2QKJKxYOBQcwfIBFegheiBQeiNUB25izK4+DmDSHhR/VoAre0kykcxUKbi0h6g==",
"version": "file:../doric/doric-js",
"requires": {
"@types/ws": "^6.0.4",
"reflect-metadata": "^0.1.13",
"rollup": "^1.27.8",
"rollup": "^1.27.12",
"rollup-plugin-node-resolve": "^5.2.0",
"tslib": "^1.10.0",
"typescript": "^3.7.3",
@ -127,11 +107,6 @@
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw=="
},
"reflect-metadata": {
"version": "0.1.13",
"resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz",
"integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg=="
},
"resolve": {
"version": "1.14.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.14.0.tgz",
@ -140,16 +115,6 @@
"path-parse": "^1.0.6"
}
},
"rollup": {
"version": "1.27.13",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-1.27.13.tgz",
"integrity": "sha512-hDi7M07MpmNSDE8YVwGVFA8L7n8jTLJ4lG65nMAijAyqBe//rtu4JdxjUBE7JqXfdpqxqDTbCDys9WcqdpsQvw==",
"requires": {
"@types/estree": "*",
"@types/node": "*",
"acorn": "^7.1.0"
}
},
"rollup-plugin-commonjs": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-10.1.0.tgz",
@ -195,20 +160,15 @@
"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.6.tgz",
"integrity": "sha512-1ZooVLYFxC448piVLBbtOxFcXwnymH9oUF8nRd3CuYDVvkRBxRl6pB4Mtas5a4drtL+E8LDgFkQNcgIw6tc8Hg=="
},
"tslib": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz",
"integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ=="
"tsc": {
"version": "1.20150623.0",
"resolved": "https://registry.npmjs.org/tsc/-/tsc-1.20150623.0.tgz",
"integrity": "sha1-Trw8d04WkUjLx2inNCUz8ILHpuU="
},
"typescript": {
"version": "3.7.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.3.tgz",
"integrity": "sha512-Mcr/Qk7hXqFBXMN7p7Lusj1ktCBydylfQM/FZCk5glCNQJrCUKPkMHdo9R0MTFWsC/4kPFvDS0fDPvukfCkFsw=="
},
"ws": {
"version": "7.2.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.2.1.tgz",
"integrity": "sha512-sucePNSafamSKoOqoNfBd8V0StlkzJKL2ZAhGQinCfNQ+oacw+Pk7lcdAElecBF2VkLNZRiIb5Oi1Q5lVUVt2A=="
}
}
}

View File

@ -19,9 +19,11 @@
"homepage": "https://github.com/doric-pub/doric-h5#readme",
"dependencies": {
"axios": "^0.19.0",
"doric": "^0.1.3",
"doric": "file:../doric/doric-js",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-json": "^4.0.0",
"rollup-plugin-node-resolve": "^5.2.0"
"rollup-plugin-node-resolve": "^5.2.0",
"tsc": "^1.20150623.0",
"typescript": "^3.7.3"
}
}

View File

@ -5,6 +5,5 @@ export class ShaderPlugin extends DoricPlugin {
render(ret: DVModel) {
this.context.rootNode.viewId = ret.id
this.context.rootNode.blend(ret.props)
this.context.rootNode.layout()
}
}

View File

@ -1,122 +1,53 @@
import { DoricGroupViewNode, LayoutSpec, FrameSize, LEFT, RIGHT, CENTER_X, CENTER_Y, TOP, BOTTOM } from "./DoricViewNode";
import { DoricGroupViewNode, LEFT, RIGHT, CENTER_X, CENTER_Y, TOP, BOTTOM, toPixelString } from "./DoricViewNode";
export class DoricHLayoutNode extends DoricGroupViewNode {
space = 0
gravity = 0
contentSize = {
width: 0,
height: 0,
weight: 0,
}
build() {
return document.createElement('div')
const ret = document.createElement('div')
ret.style.display = "flex"
ret.style.flexDirection = "row"
ret.style.flexWrap = "nowrap"
return ret
}
blendProps(v: HTMLElement, propName: string, prop: any) {
if (propName === 'space') {
this.space = prop
} else if (propName === 'gravity') {
this.gravity = prop
this.gravity = prop
if ((this.gravity & LEFT) === LEFT) {
this.view.style.justifyContent = "flex-start"
} else if ((this.gravity & RIGHT) === RIGHT) {
this.view.style.justifyContent = "flex-end"
} else if ((this.gravity & CENTER_X) === CENTER_X) {
this.view.style.justifyContent = "center"
}
if ((this.gravity & TOP) === TOP) {
this.view.style.alignItems = "flex-start"
} else if ((this.gravity & BOTTOM) === BOTTOM) {
this.view.style.alignItems = "flex-end"
} else if ((this.gravity & CENTER_Y) === CENTER_Y) {
this.view.style.alignItems = "center"
}
} else {
super.blendProps(v, propName, prop)
}
}
blend(props: { [index: string]: any }) {
super.blend(props)
this.childNodes.forEach(e => {
e.view.style.position = "absolute"
})
}
measureContentSize(targetSize: { width: number, height: number }) {
let width = this.frameWidth
let height = this.frameHeight
let contentSize = { width: 0, height: 0, weight: 0 }
let limitSize = {
width: targetSize.width - this.paddingLeft - this.paddingRight,
height: targetSize.height - this.paddingTop - this.paddingBottom,
}
contentSize = this.childNodes.reduce((prev, current) => {
const size = current.measureContentSize(limitSize)
return {
width: prev.width + size.width + this.space
+ current.layoutConfig?.margin?.left || 0
+ current.layoutConfig?.margin?.right || 0,
height: Math.max(prev.height, size.height),
weight: prev.weight + current.layoutConfig?.weight || 0
}
}, contentSize)
contentSize.width -= this.space
switch (this.layoutConfig.widthSpec) {
case LayoutSpec.AT_MOST:
width = targetSize.width
break
case LayoutSpec.WRAP_CONTENT:
width = contentSize.width
break
default:
break
}
switch (this.layoutConfig.heightSpec) {
case LayoutSpec.AT_MOST:
height = targetSize.height
break
case LayoutSpec.WRAP_CONTENT:
height = contentSize.height
break
default:
break
}
if (contentSize.weight > 0) {
contentSize.width = targetSize.width
}
this.contentSize = contentSize
return { width, height }
}
layoutSelf(targetSize: FrameSize) {
const { width, height } = this.measureContentSize(targetSize)
this.width = width
this.height = height
let xStart = this.paddingLeft;
if ((this.gravity & LEFT) == LEFT) {
xStart = this.paddingLeft
} else if ((this.gravity & RIGHT) == RIGHT) {
xStart = targetSize.width - this.contentSize.width - this.paddingRight;
} else if ((this.gravity & CENTER_X) == CENTER_X) {
xStart = (targetSize.width - this.contentSize.width - this.paddingLeft - this.paddingRight) / 2 + this.paddingLeft
}
let remain = targetSize.width - this.contentSize.width - this.paddingLeft - this.paddingRight
this.childNodes.forEach(e => {
const childTargetSize = {
width: width - xStart - this.paddingRight,
height: height - this.paddingTop - this.paddingBottom,
}
if (e.layoutConfig?.weight > 0) {
childTargetSize.width += remain / this.contentSize.weight * e.layoutConfig.weight
}
e.layoutSelf(childTargetSize)
let gravity = e.layoutConfig?.alignment | this.gravity
if ((gravity & TOP) === TOP) {
e.y = 0
} else if ((gravity & BOTTOM) === BOTTOM) {
e.y = height - e.height + this.paddingTop - this.paddingBottom
} else if ((gravity & CENTER_Y) === CENTER_Y) {
e.x = height / 2 - e.height / 2 - this.paddingTop
} else {
if (e.layoutConfig.margin?.left) {
e.x = e.layoutConfig.margin?.left
} else if (e.layoutConfig.margin?.right) {
e.x = width - e.width + this.paddingLeft - this.paddingRight - e.layoutConfig.margin?.right
}
}
if (e.layoutConfig.margin?.left !== undefined) {
xStart += e.layoutConfig.margin.left
}
e.x = xStart - this.paddingLeft
xStart += e.width + this.space
if (e.layoutConfig.margin?.right !== undefined) {
xStart += e.layoutConfig.margin.right
layout() {
super.layout()
this.childNodes.forEach((e, idx) => {
e.view.style.flexShrink = "0"
if (e.layoutConfig?.weight) {
e.view.style.flex = `${e.layoutConfig?.weight}`
}
e.view.style.marginLeft = toPixelString(e.layoutConfig?.margin?.left || 0)
e.view.style.marginRight = toPixelString(
(idx === this.childNodes.length - 1) ? 0 : this.space
+ (e.layoutConfig?.margin?.right || 0))
e.view.style.marginTop = toPixelString(e.layoutConfig?.margin?.top || 0)
e.view.style.marginBottom = toPixelString(e.layoutConfig?.margin?.bottom || 0)
})
}
}

View File

@ -1,4 +1,4 @@
import { DoricGroupViewNode, LayoutSpec, FrameSize, LEFT, RIGHT, CENTER_X, CENTER_Y, TOP, BOTTOM } from "./DoricViewNode";
import { DoricGroupViewNode, LayoutSpec, FrameSize, LEFT, RIGHT, CENTER_X, CENTER_Y, TOP, BOTTOM, toPixelString } from "./DoricViewNode";
export class DoricStackNode extends DoricGroupViewNode {
@ -6,92 +6,16 @@ export class DoricStackNode extends DoricGroupViewNode {
return document.createElement('div')
}
blend(props: { [index: string]: any }) {
super.blend(props)
layout() {
super.layout()
this.configOffset()
}
configOffset() {
this.childNodes.forEach(e => {
e.view.style.position = "absolute"
})
}
measureContentSize(targetSize: { width: number, height: number }) {
let width = this.frameWidth
let height = this.frameHeight
let contentSize = { width: 0, height: 0 }
let limitSize = {
width: targetSize.width - this.paddingLeft - this.paddingRight,
height: targetSize.height - this.paddingTop - this.paddingBottom,
}
if (this.layoutConfig.widthSpec === LayoutSpec.WRAP_CONTENT
|| this.layoutConfig.heightSpec === LayoutSpec.WRAP_CONTENT) {
contentSize = this.childNodes.reduce((prev, current) => {
const size = current.measureContentSize(limitSize)
return {
width: Math.max(prev.width, size.width),
height: Math.max(prev.height, size.height),
}
}, contentSize)
}
switch (this.layoutConfig.widthSpec) {
case LayoutSpec.AT_MOST:
width = targetSize.width
break
case LayoutSpec.WRAP_CONTENT:
width = contentSize.width
break
default:
break
}
switch (this.layoutConfig.heightSpec) {
case LayoutSpec.AT_MOST:
height = targetSize.height
break
case LayoutSpec.WRAP_CONTENT:
height = contentSize.height
break
default:
break
}
return { width, height }
}
layoutSelf(targetSize: FrameSize) {
const { width, height } = this.measureContentSize(targetSize)
this.width = width
this.height = height
const limitSize = {
width: width - this.paddingLeft - this.paddingRight,
height: height - this.paddingTop - this.paddingBottom,
}
this.childNodes.forEach(e => {
e.layoutSelf(limitSize)
let gravity = e.layoutConfig?.alignment || 0
if ((gravity & LEFT) === LEFT) {
e.x = 0
} else if ((gravity & RIGHT) === RIGHT) {
e.x = width - e.width + this.paddingLeft - this.paddingRight
} else if ((gravity & CENTER_X) === CENTER_X) {
e.x = width / 2 - e.width / 2 - this.paddingLeft
} else {
if (e.layoutConfig.margin?.left) {
e.x = e.layoutConfig.margin?.left
} else if (e.layoutConfig.margin?.right) {
e.x = width - e.width + this.paddingLeft - this.paddingRight - e.layoutConfig.margin?.right
}
}
if ((gravity & TOP) === TOP) {
e.y = 0
} else if ((gravity & BOTTOM) === BOTTOM) {
e.y = height - e.height + this.paddingTop - this.paddingBottom
} else if ((gravity & CENTER_Y) === CENTER_Y) {
e.y = height / 2 - e.height / 2 - this.paddingTop
} else {
if (e.layoutConfig.margin?.top) {
e.y = e.layoutConfig.margin?.top
} else if (e.layoutConfig.margin?.bottom) {
e.y = height - e.height + this.paddingTop - this.paddingBottom - e.layoutConfig.margin?.bottom
}
}
e.view.style.left = toPixelString(e.offsetX + this.paddingLeft)
e.view.style.top = toPixelString(e.offsetY + this.paddingTop)
})
}
}

View File

@ -6,9 +6,6 @@ export class DoricTextNode extends DoricViewNode {
return document.createElement('p')
}
measureContentSize(targetSize: FrameSize) {
return targetSize
}
blendProps(v: HTMLParagraphElement, propName: string, prop: any) {
switch (propName) {
case 'text':

View File

@ -1,13 +1,9 @@
import { DoricGroupViewNode, LayoutSpec, FrameSize, LEFT, RIGHT, CENTER_X, CENTER_Y, TOP, BOTTOM } from "./DoricViewNode";
import { DoricGroupViewNode, LayoutSpec, FrameSize, LEFT, RIGHT, CENTER_X, CENTER_Y, TOP, BOTTOM, toPixelString } from "./DoricViewNode";
export class DoricVLayoutNode extends DoricGroupViewNode {
space = 0
gravity = 0
contentSize = {
width: 0,
height: 0,
weight: 0,
}
build() {
const ret = document.createElement('div')
ret.style.display = "flex"
@ -21,73 +17,37 @@ export class DoricVLayoutNode extends DoricGroupViewNode {
} else if (propName === 'gravity') {
this.gravity = prop
if ((this.gravity & LEFT) === LEFT) {
this.view.style.justifyContent = "flex-start"
this.view.style.alignItems = "flex-start"
} else if ((this.gravity & RIGHT) === RIGHT) {
this.view.style.justifyContent = "flex-end"
this.view.style.alignItems = "flex-end"
} else if ((this.gravity & CENTER_X) === CENTER_X) {
this.view.style.justifyContent = "center"
this.view.style.alignItems = "center"
}
if ((this.gravity & TOP) === TOP) {
this.view.style.alignItems = "flex-start"
this.view.style.justifyContent = "flex-start"
} else if ((this.gravity & BOTTOM) === BOTTOM) {
this.view.style.alignItems = "flex-end"
this.view.style.justifyContent = "flex-end"
} else if ((this.gravity & CENTER_Y) === CENTER_Y) {
this.view.style.alignItems = "center"
this.view.style.justifyContent = "center"
}
} else {
super.blendProps(v, propName, prop)
}
}
measureContentSize(targetSize: { width: number, height: number }) {
let width = this.frameWidth
let height = this.frameHeight
let contentSize = { width: 0, height: 0, weight: 0 }
let limitSize = {
width: targetSize.width - this.paddingLeft - this.paddingRight,
height: targetSize.height - this.paddingTop - this.paddingBottom,
}
contentSize = this.childNodes.reduce((prev, current) => {
const size = current.measureContentSize(limitSize)
return {
width: Math.max(prev.width, size.width),
height: prev.height + size.height + this.space
+ current.layoutConfig?.margin?.top || 0
+ current.layoutConfig?.margin?.bottom || 0,
weight: prev.weight + current.layoutConfig?.weight || 0
layout() {
super.layout()
this.childNodes.forEach((e, idx) => {
e.view.style.flexShrink = "0"
if (e.layoutConfig?.weight) {
e.view.style.flex = `${e.layoutConfig?.weight}`
}
}, contentSize)
contentSize.height -= this.space
switch (this.layoutConfig.widthSpec) {
case LayoutSpec.AT_MOST:
width = targetSize.width
break
case LayoutSpec.WRAP_CONTENT:
width = contentSize.width
break
default:
break
}
switch (this.layoutConfig.heightSpec) {
case LayoutSpec.AT_MOST:
height = targetSize.height
break
case LayoutSpec.WRAP_CONTENT:
height = contentSize.height
break
default:
break
}
if (contentSize.weight > 0) {
contentSize.height = targetSize.height
}
this.contentSize = contentSize
return { width, height }
}
layoutSelf(targetSize: FrameSize) {
const { width, height } = this.measureContentSize(targetSize)
this.width = width
this.height = height
e.view.style.marginTop = toPixelString(e.layoutConfig?.margin?.top || 0)
e.view.style.marginBottom = toPixelString(
(idx === this.childNodes.length - 1) ? 0 : this.space
+ (e.layoutConfig?.margin?.bottom || 0))
e.view.style.marginLeft = toPixelString(e.layoutConfig?.margin?.left || 0)
e.view.style.marginRight = toPixelString(e.layoutConfig?.margin?.right || 0)
})
}
}

View File

@ -138,28 +138,81 @@ export abstract class DoricViewNode {
for (let key in props) {
this.blendProps(this.view, key, props[key])
}
this.onBlended()
this.layout()
}
onBlended() {
}
configBorder() {
if (this.border) {
this.view.style.borderStyle = "solid"
this.view.style.borderWidth = toPixelString(this.border.width)
this.view.style.borderColor = toRGBAString(this.border.color)
}
}
configWidth() {
switch (this.layoutConfig.widthSpec) {
case LayoutSpec.WRAP_CONTENT:
this.view.style.width = "auto"
break
case LayoutSpec.AT_MOST:
this.view.style.width = "100%"
break
case LayoutSpec.EXACTLY:
default:
this.view.style.width = toPixelString(this.frameWidth
- this.paddingLeft - this.paddingRight
- this.borderWidth * 2)
break
}
}
configHeight() {
switch (this.layoutConfig.heightSpec) {
case LayoutSpec.WRAP_CONTENT:
this.view.style.height = "auto"
break
case LayoutSpec.AT_MOST:
this.view.style.height = "100%"
break
case LayoutSpec.EXACTLY:
default:
this.view.style.height = toPixelString(this.frameHeight
- this.paddingTop - this.paddingBottom
- this.borderWidth * 2)
break
}
}
configMargin() {
if (this.layoutConfig.margin) {
this.view.style.marginLeft = toPixelString(this.layoutConfig.margin.left || 0)
this.view.style.marginRight = toPixelString(this.layoutConfig.margin.right || 0)
this.view.style.marginTop = toPixelString(this.layoutConfig.margin.top || 0)
this.view.style.marginBottom = toPixelString(this.layoutConfig.margin.bottom || 0)
}
}
configPadding() {
if (this.padding) {
this.view.style.paddingLeft = toPixelString(this.paddingLeft)
this.view.style.paddingRight = toPixelString(this.paddingRight)
this.view.style.paddingTop = toPixelString(this.paddingTop)
this.view.style.paddingBottom = toPixelString(this.paddingBottom)
}
this.x = this.offsetX
this.y = this.offsetY
}
layout() {
this.layoutSelf({ width: this.frameWidth, height: this.frameHeight })
}
layoutSelf(targetSize: FrameSize) {
this.width = targetSize.width
this.height = targetSize.height
this.configMargin()
this.configBorder()
this.configPadding()
this.configWidth()
this.configHeight()
}
blendProps(v: HTMLElement, propName: string, prop: any) {
@ -199,31 +252,6 @@ export abstract class DoricViewNode {
}
}
set width(v: number) {
this.view.style.width = toPixelString(v - this.paddingLeft - this.paddingRight - this.borderWidth * 2)
}
get width() {
return this.view.offsetWidth
}
set height(v: number) {
this.view.style.height = toPixelString(v - this.paddingTop - this.paddingBottom - this.borderWidth * 2)
}
get height() {
return this.view.offsetHeight
}
set x(v: number) {
this.view.style.left = toPixelString(v + (this.superNode?.paddingLeft || 0))
}
get x() {
return this.view.offsetLeft
}
set y(v: number) {
this.view.style.top = toPixelString(v + (this.superNode?.paddingTop || 0))
}
get y() {
return this.view.offsetTop
}
set backgroundColor(v: number) {
this.view.style.backgroundColor = toRGBAString(v)
}
@ -239,8 +267,6 @@ export abstract class DoricViewNode {
return ret
}
abstract measureContentSize(targetSize: FrameSize): FrameSize
getIdList() {
const ids: string[] = []
let viewNode: DoricViewNode | undefined = this
@ -329,9 +355,11 @@ export abstract class DoricGroupViewNode extends DoricSuperViewNode {
blend(props: { [index: string]: any }) {
super.blend(props)
}
onBlended() {
super.onBlended()
this.configChildNode()
}
configChildNode() {
this.childViewIds.forEach((childViewId, index) => {
const model = this.getSubModel(childViewId)