Fix flexbox-layout properties

This commit is contained in:
Panayot Cankov
2017-01-04 11:53:24 +02:00
parent fb4ab6cdb0
commit d8db6a2484
6 changed files with 113 additions and 96 deletions

View File

@@ -62,7 +62,7 @@ allTests["WRAPLAYOUT"] = require("./ui/layouts/wrap-layout-tests");
allTests["ABSOLUTELAYOUT"] = require("./ui/layouts/absolute-layout-tests");
allTests["GRIDLAYOUT"] = require("./ui/layouts/grid-layout-tests");
allTests["STACKLAYOUT"] = require("./ui/layouts/stack-layout-tests");
// allTests["FLEXBOXLAYOUT"] = require("./ui/layouts/flexbox-layout-tests");
allTests["FLEXBOXLAYOUT"] = require("./ui/layouts/flexbox-layout-tests");
// allTests["STYLE-PROPERTIES"] = require("./ui/styling/style-properties-tests");
// allTests["FRAME"] = require("./ui/frame/frame-tests");
// allTests["VIEW"] = require("./ui/view/view-tests");

View File

@@ -12,6 +12,9 @@ import { observe as gestureObserve, GesturesObserver, GestureTypes, GestureEvent
import { Font, parseFont, FontStyle, FontWeight } from "ui/styling/font";
import { fontSizeConverter } from "../styling/converters";
// Only types:
import { Order, FlexGrow, FlexShrink, FlexWrapBefore, AlignSelf } from "ui/layouts/flexbox-layout"
// TODO: Remove this and start using string as source (for android).
import { fromFileOrResource, fromBase64, fromUrl } from "image-source";
import { isDataURI, isFileOrResourcePath, layout } from "utils/utils";
@@ -61,6 +64,12 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
rowSpan: number;
colSpan: number;
order: Order;
flexGrow: FlexGrow;
flexShrink: FlexShrink;
flexWrapBefore: FlexWrapBefore;
alignSelf: AlignSelf;
public static loadedEvent = "loaded";
public static unloadedEvent = "unloaded";
@@ -69,10 +78,11 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
_currentWidthMeasureSpec: number;
_currentHeightMeasureSpec: number;
private _oldLeft: number;
private _oldTop: number;
private _oldRight: number;
private _oldBottom: number;
_oldLeft: number;
_oldTop: number;
_oldRight: number;
_oldBottom: number;
private _isLayoutValid: boolean;
private _cssType: string;
@@ -662,14 +672,13 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
let measureHeight = 0;
if (child && !child.isCollapsed) {
let density = layout.getDisplayDensity();
let width = layout.getMeasureSpecSize(widthMeasureSpec);
let widthMode = layout.getMeasureSpecMode(widthMeasureSpec);
let height = layout.getMeasureSpecSize(heightMeasureSpec);
let heightMode = layout.getMeasureSpecMode(heightMeasureSpec);
updateChildLayoutParams(child, parent, density);
child._updateEffectiveLayoutValues(parent);
let style = child.style;
let horizontalMargins = child.effectiveMarginLeft + child.effectiveMarginRight;
@@ -871,8 +880,36 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
public _setValue(): never {
throw new Error("The View._setValue is obsolete. There is a new property system.")
}
_updateEffectiveLayoutValues(parent: ViewCommon): void {
const density = layout.getDisplayDensity();
const style = this.style;
let parentWidthMeasureSpec = parent._currentWidthMeasureSpec;
let parentWidthMeasureSize = layout.getMeasureSpecSize(parentWidthMeasureSpec);
let parentWidthMeasureMode = layout.getMeasureSpecMode(parentWidthMeasureSpec);
let parentAvailableWidth = parentWidthMeasureMode === layout.UNSPECIFIED ? -1 : parentWidthMeasureSize;
this.effectiveWidth = PercentLength.toDevicePixels(style.width, -2, parentAvailableWidth)
this.effectiveMarginLeft = PercentLength.toDevicePixels(style.marginLeft, 0, parentAvailableWidth);
this.effectiveMarginRight = PercentLength.toDevicePixels(style.marginRight, 0, parentAvailableWidth);
let parentHeightMeasureSpec = parent._currentHeightMeasureSpec;
let parentHeightMeasureSize = layout.getMeasureSpecSize(parentHeightMeasureSpec);
let parentHeightMeasureMode = layout.getMeasureSpecMode(parentHeightMeasureSpec);
let parentAvailableHeight = parentHeightMeasureMode === layout.UNSPECIFIED ? -1 : parentHeightMeasureSize;
this.effectiveHeight = PercentLength.toDevicePixels(style.height, -2, parentAvailableHeight);
this.effectiveMarginTop = PercentLength.toDevicePixels(style.marginTop, 0, parentAvailableHeight);
this.effectiveMarginBottom = PercentLength.toDevicePixels(style.marginBottom, 0, parentAvailableHeight);
}
}
ViewCommon.prototype._oldLeft = 0;
ViewCommon.prototype._oldTop = 0;
ViewCommon.prototype._oldRight = 0;
ViewCommon.prototype._oldBottom = 0;
ViewCommon.prototype.effectiveMinWidth = 0;
ViewCommon.prototype.effectiveMinHeight = 0;
ViewCommon.prototype.effectiveWidth = 0;
@@ -890,28 +927,6 @@ ViewCommon.prototype.effectiveBorderRightWidth = 0;
ViewCommon.prototype.effectiveBorderBottomWidth = 0;
ViewCommon.prototype.effectiveBorderLeftWidth = 0;
function updateChildLayoutParams(child: ViewCommon, parent: ViewCommon, density: number): void {
let style = child.style;
let parentWidthMeasureSpec = parent._currentWidthMeasureSpec;
let parentWidthMeasureSize = layout.getMeasureSpecSize(parentWidthMeasureSpec);
let parentWidthMeasureMode = layout.getMeasureSpecMode(parentWidthMeasureSpec);
let parentAvailableWidth = parentWidthMeasureMode === layout.UNSPECIFIED ? -1 : parentWidthMeasureSize;
child.effectiveWidth = PercentLength.toDevicePixels(style.width, -2, parentAvailableWidth)
child.effectiveMarginLeft = PercentLength.toDevicePixels(style.marginLeft, 0, parentAvailableWidth);
child.effectiveMarginRight = PercentLength.toDevicePixels(style.marginRight, 0, parentAvailableWidth);
let parentHeightMeasureSpec = parent._currentHeightMeasureSpec;
let parentHeightMeasureSize = layout.getMeasureSpecSize(parentHeightMeasureSpec);
let parentHeightMeasureMode = layout.getMeasureSpecMode(parentHeightMeasureSpec);
let parentAvailableHeight = parentHeightMeasureMode === layout.UNSPECIFIED ? -1 : parentHeightMeasureSize;
child.effectiveHeight = PercentLength.toDevicePixels(style.height, -2, parentAvailableHeight);
child.effectiveMarginTop = PercentLength.toDevicePixels(style.marginTop, 0, parentAvailableHeight);
child.effectiveMarginBottom = PercentLength.toDevicePixels(style.marginBottom, 0, parentAvailableHeight);
}
function equalsCommon(a: Length, b: Length): boolean;
function equalsCommon(a: PercentLength, b: PercentLength): boolean;
function equalsCommon(a: PercentLength, b: PercentLength): boolean {

View File

@@ -569,6 +569,8 @@ declare module "ui/core/view" {
_nativeView: any;
_setNativeViewFrame(nativeView: any, frame: any): void;
// _onStylePropertyChanged(property: dependencyObservable.Property): void;
_updateEffectiveLayoutValues(parent: View): void;
//@endprivate
public effectiveMinWidth: number;

View File

@@ -231,7 +231,7 @@ export abstract class FlexboxLayoutBase extends LayoutBase {
export const flexDirectionProperty = new CssProperty<Style, FlexDirection>({ name: "flexDirection", cssName: "flex-direction", defaultValue: FlexDirection.ROW, affectsLayout: isIOS, valueConverter: FlexDirection.parse });
flexDirectionProperty.register(Style);
export const flexWrapProperty = new CssProperty<Style, FlexWrap>({ name: "flexWrap", cssName: "flex-wrap", defaultValue: FlexWrap.NOWRAP, affectsLayout: isIOS, valueConverter: FlexWrap.parse });
export const flexWrapProperty = new CssProperty<Style, FlexWrap>({ name: "flexWrap", cssName: "flex-wrap", defaultValue: "nowrap", affectsLayout: isIOS, valueConverter: FlexWrap.parse });
flexWrapProperty.register(Style);
export const justifyContentProperty = new CssProperty<Style, JustifyContent>({ name: "justifyContent", cssName: "justify-content", defaultValue: JustifyContent.FLEX_START, affectsLayout: isIOS, valueConverter: JustifyContent.parse });
@@ -245,84 +245,68 @@ alignContentProperty.register(Style);
export const orderProperty = new CssProperty<Style, Order>({ name: "order", cssName: "order", defaultValue: ORDER_DEFAULT, valueConverter: Order.parse });
orderProperty.register(Style);
Object.defineProperty(View.prototype, "order", {
get(this: View): Order {
return this.style.order;
},
set(this: View, value: Order) {
this.style.order = value;
},
enumerable: true,
configurable: true
});
export const flexGrowProperty = new CssProperty<Style, FlexGrow>({ name: "flexGrow", cssName: "flex-grow", defaultValue: FLEX_GROW_DEFAULT, valueConverter: FlexGrow.parse });
flexGrowProperty.register(Style);
Object.defineProperty(View.prototype, "flexGrow", {
get(this: View): FlexGrow {
return this.style.flexGrow;
},
set(this: View, value: FlexGrow) {
this.style.flexGrow = value;
},
enumerable: true,
configurable: true
});
export const flexShrinkProperty = new CssProperty<Style, FlexShrink>({ name: "flexShrink", cssName: "flex-shrink", defaultValue: FLEX_SHRINK_DEFAULT, valueConverter: FlexShrink.parse });
flexShrinkProperty.register(Style);
Object.defineProperty(View.prototype, "flexShrink", {
get(this: View): FlexShrink {
return this.style.flexShrink;
},
set(this: View, value: FlexShrink) {
this.style.flexShrink = value;
},
enumerable: true,
configurable: true
});
export const flexWrapBeforeProperty = new CssProperty<Style, FlexWrapBefore>({ name: "flexWrapBefore", cssName: "flex-wrap-before", defaultValue: false, valueConverter: FlexWrapBefore.parse });
flexWrapBeforeProperty.register(Style);
Object.defineProperty(View.prototype, "flexWrapBefore", {
get(this: View): FlexWrapBefore {
return this.style.flexWrapBefore;
},
set(this: View, value: FlexWrapBefore) {
this.style.flexWrapBefore = value;
},
enumerable: true,
configurable: true
});
export const alignSelfProperty = new CssProperty<Style, AlignSelf>({ name: "alignSelf", cssName: "align-self", defaultValue: AlignSelf.AUTO, valueConverter: AlignSelf.parse });
alignSelfProperty.register(Style);
// These support setting attached properties through XML. Delete if we stop supporting them.
// they could be set in XML through style -- <button style.order="1" />
const orderProperty1 = new Property<View, Order>({ name: "order", defaultValue: ORDER_DEFAULT, valueConverter: Order.parse });
orderProperty1.register(View);
const flexGrowProperty1 = new Property<View, FlexGrow>({ name: "flexGrow", defaultValue: FLEX_GROW_DEFAULT, valueConverter: FlexGrow.parse });
flexGrowProperty1.register(View);
const flexShrinkProperty1 = new Property<View, FlexShrink>({ name: "flexShrink", defaultValue: FLEX_SHRINK_DEFAULT, valueConverter: FlexShrink.parse });
flexShrinkProperty1.register(View);
const flexWrapBeforeProperty1 = new Property<View, FlexWrapBefore>({ name: "flexWrapBefore", defaultValue: false, valueConverter: FlexWrapBefore.parse });
flexWrapBeforeProperty1.register(View);
const alignSelfProperty1 = new Property<View, AlignSelf>({ name: "alignSelf", defaultValue: AlignSelf.AUTO, valueConverter: AlignSelf.parse });
alignSelfProperty1.register(View);
// registerSpecialProperty("order", (instance, propertyValue) => {
// FlexboxLayoutBase.setOrder(instance, !isNaN(+propertyValue) && +propertyValue);
// });
// registerSpecialProperty("flexGrow", (instance, propertyValue) => {
// FlexboxLayoutBase.setFlexGrow(instance, !isNaN(+propertyValue) && +propertyValue);
// });
// registerSpecialProperty("flexShrink", (instance, propertyValue) => {
// FlexboxLayoutBase.setFlexShrink(instance, !isNaN(+propertyValue) && +propertyValue);
// });
// registerSpecialProperty("alignSelf", (instance, propertyValue) => {
// FlexboxLayoutBase.setAlignSelf(instance, propertyValue);
// });
// registerSpecialProperty("flexWrapBefore", (instance, propertyValue) => {
// FlexboxLayoutBase.setFlexWrapBefore(instance, isString(propertyValue) ? FlexWrapBefore.parse(propertyValue) : propertyValue);
// });
// const flexboxGuard = <T>(handler: (flexbox: FlexboxLayoutBase, newValue: any) => void) => (view: View, newValue: any) => view instanceof FlexboxLayoutBase ? handler(view, newValue) : void 0;
// style.registerHandler(flexDirectionProperty, new style.StylePropertyChangedHandler(
// flexboxGuard((flexbox, newValue) => flexbox._setNativeFlexDirection(newValue)),
// flexboxGuard((flexbox, newValue) => flexbox._setNativeFlexDirection(FlexDirection.ROW))), "FlexboxLayout");
// style.registerHandler(flexWrapProperty, new style.StylePropertyChangedHandler(
// flexboxGuard((flexbox, newValue) => flexbox._setNativeFlexWrap(newValue)),
// flexboxGuard((flexbox, newValue) => flexbox._setNativeFlexWrap(FlexWrap.NOWRAP))), "FlexboxLayout");
// style.registerHandler(justifyContentProperty, new style.StylePropertyChangedHandler(
// flexboxGuard((flexbox, newValue) => flexbox._setNativeJustifyContent(newValue)),
// flexboxGuard((flexbox, newValue) => flexbox._setNativeJustifyContent(JustifyContent.FLEX_START))), "FlexboxLayout");
// style.registerHandler(alignItemsProperty, new style.StylePropertyChangedHandler(
// flexboxGuard((flexbox, newValue) => flexbox._setNativeAlignItems(newValue)),
// flexboxGuard((flexbox, newValue) => flexbox._setNativeAlignItems(AlignItems.STRETCH))), "FlexboxLayout");
// style.registerHandler(alignContentProperty, new style.StylePropertyChangedHandler(
// flexboxGuard((flexbox, newValue) => flexbox._setNativeAlignContent(newValue)),
// flexboxGuard((flexbox, newValue) => flexbox._setNativeAlignContent(AlignContent.STRETCH))), "FlexboxLayout");
// style.registerHandler(orderProperty, new style.StylePropertyChangedHandler(
// (view, value) => flexbox._onNativeOrderPropertyChanged(view, value),
// (view, value) => flexbox._onNativeOrderPropertyChanged(view, 1)), "View");
// style.registerHandler(flexGrowProperty, new style.StylePropertyChangedHandler(
// (view, value) => flexbox._onNativeFlexGrowPropertyChanged(view, value),
// (view, value) => flexbox._onNativeFlexGrowPropertyChanged(view, 0)), "View");
// style.registerHandler(flexShrinkProperty, new style.StylePropertyChangedHandler(
// (view, value) => flexbox._onNativeFlexShrinkPropertyChanged(view, value),
// (view, value) => flexbox._onNativeFlexShrinkPropertyChanged(view, 1)), "View");
// style.registerHandler(flexWrapBeforeProperty, new style.StylePropertyChangedHandler(
// (view, value) => flexbox._onNativeFlexWrapBeforePropertyChanged(view, value),
// (view, value) => flexbox._onNativeFlexWrapBeforePropertyChanged(view, false)), "View");
// style.registerHandler(alignSelfProperty, new style.StylePropertyChangedHandler(
// (view, value) => flexbox._onNativeAlignSelfPropertyChanged(view, value),
// (view, value) => flexbox._onNativeAlignSelfPropertyChanged(view, AlignSelf.AUTO)), "View");
Object.defineProperty(View.prototype, "alignSelf", {
get(this: View): AlignSelf {
return this.style.alignSelf;
},
set(this: View, value: AlignSelf) {
this.style.alignSelf = value;
},
enumerable: true,
configurable: true
});
// flex-flow: <flex-direction> || <flex-wrap>
const flexFlowProperty = new ShorthandProperty<Style, string>({

View File

@@ -18,6 +18,20 @@ declare module "ui/styling/style" {
}
}
declare module "ui/core/view" {
import {
Order, FlexGrow, FlexShrink, FlexWrapBefore, AlignSelf
} from "ui/layouts/flexbox-layout"
interface View {
order: Order;
flexGrow: FlexGrow;
flexShrink: FlexShrink;
flexWrapBefore: FlexWrapBefore;
alignSelf: AlignSelf;
}
}
declare module "ui/layouts/flexbox-layout" {
import { LayoutBase, View, Style, CssProperty } from "ui/layouts/layout-base";

View File

@@ -263,6 +263,7 @@ export class FlexboxLayout extends FlexboxLayoutBase {
continue;
}
child._updateEffectiveLayoutValues(this);
let lp = child; // child.style;
if (FlexboxLayout.getAlignSelf(child) === AlignSelf.STRETCH) {
flexLine._indicesAlignSelfStretch.push(i);
@@ -377,6 +378,7 @@ export class FlexboxLayout extends FlexboxLayoutBase {
continue;
}
child._updateEffectiveLayoutValues(this);
const lp = child; // .style;
if (FlexboxLayout.getAlignSelf(child) === AlignSelf.STRETCH) {
flexLine._indicesAlignSelfStretch.push(i);