mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-15 19:26:42 +08:00
alpha2
This commit is contained in:
@ -11,6 +11,7 @@ import { ViewBase, getEventOrGestureName } from "./view-base";
|
||||
import { propagateInheritedProperties, clearInheritedProperties, Property, InheritedProperty, CssProperty, ShorthandProperty, InheritedCssProperty } from "./properties";
|
||||
import { observe, fromString as gestureFromString, GesturesObserver, GestureTypes, GestureEventData } from "ui/gestures";
|
||||
import { isIOS } from "platform";
|
||||
import { Font } from "ui/styling/font";
|
||||
|
||||
// TODO: Remove this and start using string as source (for android).
|
||||
import { fromFileOrResource, fromBase64, fromUrl } from "image-source";
|
||||
@ -2171,3 +2172,134 @@ opacityProperty.register(Style);
|
||||
|
||||
export const colorProperty = new InheritedCssProperty<Style, Color>({ name: "color", cssName: "color", equalityComparer: Color.equals, valueConverter: (v: string) => new Color(v) });
|
||||
colorProperty.register(Style);
|
||||
|
||||
|
||||
export let fontInternalProperty = new CssProperty<Style, Font>({ name: "fontInternal", cssName: "_fontInternal", defaultValue: Font.default });
|
||||
|
||||
export let fontFamilyProperty = new InheritedCssProperty<Style, string>({
|
||||
name: "fontFamily", cssName: "font-family", valueChanged: (target, newValue) => {
|
||||
let currentFont = target.fontInternal;
|
||||
if (currentFont.fontFamily !== newValue) {
|
||||
target.fontInternal = currentFont.withFontFamily(newValue);
|
||||
}
|
||||
}
|
||||
});
|
||||
fontFamilyProperty.register(Style);
|
||||
|
||||
export let fontSizeProperty = new InheritedCssProperty<Style, number>({
|
||||
name: "fontSize", cssName: "font-size", valueChanged: (target, newValue) => {
|
||||
let currentFont = target.fontInternal;
|
||||
if (currentFont.fontSize !== newValue) {
|
||||
target.fontInternal = currentFont.withFontSize(newValue);
|
||||
}
|
||||
},
|
||||
valueConverter: (v) => parseFloat(v)
|
||||
});
|
||||
fontSizeProperty.register(Style);
|
||||
|
||||
export let fontStyleProperty = new InheritedCssProperty<Style, "normal" | "italic">({
|
||||
name: "fontStyle", cssName: "font-style", defaultValue: "normal", valueChanged: (target, newValue) => {
|
||||
if (!(newValue === "normal" || newValue === "italic")) {
|
||||
throw new Error(`font-style should be 'normal' or 'italic'. value: ${newValue}`)
|
||||
}
|
||||
|
||||
let currentFont = target.fontInternal;
|
||||
if (currentFont.fontStyle !== newValue) {
|
||||
target.fontInternal = currentFont.withFontStyle(newValue);
|
||||
}
|
||||
}
|
||||
});
|
||||
fontStyleProperty.register(Style);
|
||||
|
||||
export let fontWeightProperty = new InheritedCssProperty<Style, "100" | "200" | "300" | "normal" | "400" | "500" | "600" | "bold" | "700" | "800" | "900">({
|
||||
name: "fontWeight", cssName: "font-weight", defaultValue: "normal", valueChanged: (target, newValue) => {
|
||||
if (!newValue) {
|
||||
console.trace();
|
||||
}
|
||||
|
||||
// TODO: Console.log errors or throw error?
|
||||
if (!(newValue === "normal" || newValue === "bold"
|
||||
|| newValue === "100" || newValue === "200" || newValue === "300"
|
||||
|| newValue === "400" || newValue === "500" || newValue === "600"
|
||||
|| newValue === "700" || newValue === "800" || newValue === "900")) {
|
||||
throw new Error(`Invalid font-weight value: ${newValue}`);
|
||||
}
|
||||
|
||||
let currentFont = target.fontInternal;
|
||||
if (currentFont.fontWeight !== newValue) {
|
||||
target.fontInternal = currentFont.withFontWeight(newValue);
|
||||
}
|
||||
}
|
||||
});
|
||||
fontWeightProperty.register(Style);
|
||||
|
||||
export let fontProperty = new ShorthandProperty<Style>({
|
||||
name: "font", cssName: "font",
|
||||
getter: function (this: Style) {
|
||||
return `${this.fontStyle} ${this.fontWeight} ${this.fontSize} ${this.fontFamily}`;
|
||||
},
|
||||
converter: function (value: string) {
|
||||
return parseFont(value);
|
||||
}
|
||||
})
|
||||
fontProperty.register(Style);
|
||||
|
||||
function parseFont(font: string): [CssProperty<any, any>, any][] {
|
||||
let fontSize: number;
|
||||
let fontFamily: string;
|
||||
let fontStyle: "normal" | "italic" = "normal";
|
||||
let fontWeight: string = "normal";
|
||||
|
||||
let elements = font.split(/\s+/);
|
||||
let element: string;
|
||||
while (element = elements.shift()) {
|
||||
switch (element) {
|
||||
case "normal":
|
||||
break;
|
||||
|
||||
// TODO: add support for oblique font style.
|
||||
case "italic":
|
||||
// case "oblique":
|
||||
fontStyle = "italic";
|
||||
break;
|
||||
|
||||
case "100":
|
||||
case "200":
|
||||
case "300":
|
||||
case "normal":
|
||||
case "400":
|
||||
case "500":
|
||||
case "600":
|
||||
case "bold":
|
||||
case "700":
|
||||
case "800":
|
||||
case "900":
|
||||
fontWeight = element;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!fontSize) {
|
||||
let parts = element.split("/");
|
||||
// TODO: add support for px support.
|
||||
fontSize = parseFloat(parts[0]);
|
||||
// TODO: add support for lineHeight.
|
||||
// if (parts.length > 1) {
|
||||
// lineHeight = parts[1];
|
||||
// }
|
||||
break;
|
||||
}
|
||||
|
||||
fontFamily = element;
|
||||
// if (elements.length) {
|
||||
// fontFamily += " " + elements.join(" ");
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
[fontStyleProperty, fontStyle],
|
||||
[fontWeightProperty, fontWeight],
|
||||
[fontSizeProperty, fontSize],
|
||||
[fontFamilyProperty, fontFamily]
|
||||
]
|
||||
}
|
||||
|
9
tns-core-modules/ui/core/view.d.ts
vendored
9
tns-core-modules/ui/core/view.d.ts
vendored
@ -5,10 +5,11 @@ declare module "ui/core/view" {
|
||||
import { Color } from "color";
|
||||
import { Animation, AnimationDefinition, AnimationPromise } from "ui/animation";
|
||||
import { KeyframeAnimation } from "ui/animation/keyframe-animation";
|
||||
import { Property, CssProperty, InheritedCssProperty } from "ui/core/properties";
|
||||
import { Property, CssProperty, InheritedCssProperty, ShorthandProperty } from "ui/core/properties";
|
||||
import { BindingOptions } from "ui/core/bindable";
|
||||
import { ViewBase } from "ui/core/view-base";
|
||||
import { Background } from "ui/styling/background";
|
||||
import { Font } from "ui/styling/font";
|
||||
|
||||
/**
|
||||
* Gets a child view by id.
|
||||
@ -771,5 +772,11 @@ declare module "ui/core/view" {
|
||||
export const verticalAlignmentProperty: CssProperty<Style, string>;
|
||||
export const horizontalAlignmentProperty: CssProperty<Style, string>;
|
||||
|
||||
export const fontSizeProperty: InheritedCssProperty<Style, number>;
|
||||
export const fontFamilyProperty: InheritedCssProperty<Style, string>;
|
||||
export const fontStyleProperty: InheritedCssProperty<Style, string>;
|
||||
export const fontWeightProperty: InheritedCssProperty<Style, string>;
|
||||
|
||||
export const backgroundInternalProperty: CssProperty<Style, Background>;
|
||||
export const fontInternalProperty: InheritedCssProperty<Style, Font>;
|
||||
}
|
1204
tns-core-modules/ui/enums/enums.d.ts
vendored
1204
tns-core-modules/ui/enums/enums.d.ts
vendored
File diff suppressed because it is too large
Load Diff
2
tns-core-modules/ui/frame/frame.d.ts
vendored
2
tns-core-modules/ui/frame/frame.d.ts
vendored
@ -350,7 +350,7 @@ declare module "ui/frame" {
|
||||
* Gets or sets the visibility of navigationBar.
|
||||
* Use NavBarVisibility enumeration - auto, never, always
|
||||
*/
|
||||
navBarVisibility: string;
|
||||
navBarVisibility: "auto" | "never" | "always";
|
||||
|
||||
//@private
|
||||
_disableNavBarAnimation: boolean;
|
||||
|
@ -2,7 +2,6 @@
|
||||
import { FrameBase } from "./frame-common";
|
||||
import { Page } from "ui/page";
|
||||
import { View } from "ui/core/view";
|
||||
import { NavigationBarVisibility, AnimationCurve } from "ui/enums";
|
||||
|
||||
import * as transitionModule from "ui/transition";
|
||||
import * as trace from "trace";
|
||||
@ -206,13 +205,13 @@ export class Frame extends FrameBase {
|
||||
|
||||
public _getNavBarVisible(page: Page): boolean {
|
||||
switch (this._ios.navBarVisibility) {
|
||||
case NavigationBarVisibility.always:
|
||||
case "always":
|
||||
return true;
|
||||
|
||||
case NavigationBarVisibility.never:
|
||||
case "never":
|
||||
return false;
|
||||
|
||||
case NavigationBarVisibility.auto:
|
||||
case "auto":
|
||||
let newValue: boolean;
|
||||
|
||||
if (page && page.actionBarHidden !== undefined) {
|
||||
@ -637,26 +636,30 @@ function _getNativeTransition(navigationTransition: NavigationTransition, push:
|
||||
export function _getNativeCurve(transition: NavigationTransition): UIViewAnimationCurve {
|
||||
if (transition.curve) {
|
||||
switch (transition.curve) {
|
||||
case AnimationCurve.easeIn:
|
||||
case "easeIn":
|
||||
if (trace.enabled) {
|
||||
trace.write("Transition curve resolved to UIViewAnimationCurve.EaseIn.", trace.categories.Transition);
|
||||
}
|
||||
return UIViewAnimationCurve.EaseIn;
|
||||
case AnimationCurve.easeOut:
|
||||
|
||||
case "easeOut":
|
||||
if (trace.enabled) {
|
||||
trace.write("Transition curve resolved to UIViewAnimationCurve.EaseOut.", trace.categories.Transition);
|
||||
}
|
||||
return UIViewAnimationCurve.EaseOut;
|
||||
case AnimationCurve.easeInOut:
|
||||
|
||||
case "easeInOut":
|
||||
if (trace.enabled) {
|
||||
trace.write("Transition curve resolved to UIViewAnimationCurve.EaseInOut.", trace.categories.Transition);
|
||||
}
|
||||
return UIViewAnimationCurve.EaseInOut;
|
||||
case AnimationCurve.linear:
|
||||
|
||||
case "linear":
|
||||
if (trace.enabled) {
|
||||
trace.write("Transition curve resolved to UIViewAnimationCurve.Linear.", trace.categories.Transition);
|
||||
}
|
||||
return UIViewAnimationCurve.Linear;
|
||||
|
||||
default:
|
||||
if (trace.enabled) {
|
||||
trace.write("Transition curve resolved to original: " + transition.curve, trace.categories.Transition);
|
||||
@ -673,7 +676,7 @@ class iOSFrame implements iOSFrameDefinition {
|
||||
/* tslint:enable */
|
||||
private _controller: UINavigationControllerImpl;
|
||||
private _showNavigationBar: boolean;
|
||||
private _navBarVisibility: string;
|
||||
private _navBarVisibility: "auto" | "never" | "always" = "auto";
|
||||
private _frame: Frame;
|
||||
|
||||
// TabView uses this flag to disable animation while showing/hiding the navigation bar because of the "< More" bar.
|
||||
@ -684,8 +687,6 @@ class iOSFrame implements iOSFrameDefinition {
|
||||
this._frame = frame;
|
||||
this._controller = UINavigationControllerImpl.initWithOwner(new WeakRef(frame));
|
||||
this._controller.automaticallyAdjustsScrollViewInsets = false;
|
||||
//this.showNavigationBar = false;
|
||||
this._navBarVisibility = NavigationBarVisibility.auto;
|
||||
}
|
||||
|
||||
public get controller() {
|
||||
@ -708,10 +709,10 @@ class iOSFrame implements iOSFrameDefinition {
|
||||
}
|
||||
}
|
||||
|
||||
public get navBarVisibility(): string {
|
||||
public get navBarVisibility(): "auto" | "never" | "always" {
|
||||
return this._navBarVisibility;
|
||||
}
|
||||
public set navBarVisibility(value: string) {
|
||||
public set navBarVisibility(value: "auto" | "never" | "always") {
|
||||
this._navBarVisibility = value;
|
||||
}
|
||||
}
|
@ -8,12 +8,6 @@ import types = require("utils/types");
|
||||
import getter = utils.ios.getter;
|
||||
|
||||
export * from "./gestures-common";
|
||||
// import common = require("./gestures-common");
|
||||
// import definition = require("ui/gestures");
|
||||
// import view = require("ui/core/view");
|
||||
// import observable = require("data/observable");
|
||||
// import trace = require("trace");
|
||||
|
||||
|
||||
export function observe(target: View, type: GestureTypes, callback: (args: GestureEventData) => void, context?: any): GesturesObserver {
|
||||
let observer = new GesturesObserver(target, callback, context);
|
||||
|
@ -123,5 +123,5 @@ isLoadingProperty.register(ImageBase);
|
||||
export const stretchProperty = new Property<ImageBase, "none" | "aspectFill" | "aspectFit" | "fill">({ name: "stretch", defaultValue: "aspectFit", affectsLayout: isIOS })
|
||||
stretchProperty.register(ImageBase);
|
||||
|
||||
export const tintColorProperty = new CssProperty<Style, Color>({ name: "tintColor", cssName: "tint-color", equalityComparer: Color.equals, valueConverter: (value) => new Color(value) });
|
||||
export const tintColorProperty = new InheritedCssProperty<Style, Color>({ name: "tintColor", cssName: "tint-color", equalityComparer: Color.equals, valueConverter: (value) => new Color(value) });
|
||||
tintColorProperty.register(Style);
|
4
tns-core-modules/ui/image/image.d.ts
vendored
4
tns-core-modules/ui/image/image.d.ts
vendored
@ -3,7 +3,7 @@
|
||||
*/
|
||||
declare module "ui/image" {
|
||||
import { View } from "ui/core/view";
|
||||
import { Property, CssProperty } from "ui/core/properties";
|
||||
import { Property, InheritedCssProperty } from "ui/core/properties";
|
||||
import { Color } from "color";
|
||||
import { ImageSource } from "image-source";
|
||||
import { Style } from "ui/styling/style";
|
||||
@ -61,5 +61,5 @@ declare module "ui/image" {
|
||||
export const isLoadingProperty: Property<Image, string>;
|
||||
export const loadMode: Property<Image, "sync" | "async">;
|
||||
export const stretchProperty: Property<Image, "none" | "aspectFill" | "aspectFit" | "fill">;
|
||||
export const tintColorProperty: CssProperty<Style, Color>;
|
||||
export const tintColorProperty: InheritedCssProperty<Style, Color>;
|
||||
}
|
@ -3,7 +3,7 @@ import { TextBase } from "ui/text-base";
|
||||
|
||||
export * from "ui/text-base";
|
||||
|
||||
export class LabelBase extends TextBase implements LabelDefinition {
|
||||
export class Label extends TextBase implements LabelDefinition {
|
||||
private _android: android.widget.TextView;
|
||||
|
||||
get textWrap(): boolean {
|
||||
|
@ -1,6 +1,11 @@
|
||||
import { Label as LabelDefinition } from "ui/label";
|
||||
import { TextBase, View, whiteSpaceProperty, layout } from "ui/text-base";
|
||||
import { Background } from "ui/styling/background";
|
||||
import { TextBase, whiteSpaceProperty } from "ui/text-base";
|
||||
import {
|
||||
View, layout, backgroundInternalProperty,
|
||||
borderTopWidthProperty, borderRightWidthProperty, borderBottomWidthProperty, borderLeftWidthProperty,
|
||||
paddingTopProperty, paddingRightProperty, paddingBottomProperty, paddingLeftProperty
|
||||
} from "ui/core/view";
|
||||
import { Background, ios } from "ui/styling/background";
|
||||
|
||||
export * from "ui/text-base";
|
||||
|
||||
@ -11,8 +16,8 @@ enum FixedSize {
|
||||
BOTH = 3
|
||||
}
|
||||
|
||||
export class LabelBase extends TextBase implements LabelDefinition {
|
||||
private _ios: UILabel;
|
||||
export class Label extends TextBase implements LabelDefinition {
|
||||
private _ios: TNSLabel;
|
||||
private _fixedSize: FixedSize;
|
||||
|
||||
constructor() {
|
||||
@ -22,11 +27,11 @@ export class LabelBase extends TextBase implements LabelDefinition {
|
||||
this._ios.userInteractionEnabled = true;
|
||||
}
|
||||
|
||||
get ios(): UILabel {
|
||||
get ios(): TNSLabel {
|
||||
return this._ios;
|
||||
}
|
||||
|
||||
get _nativeView(): UILabel {
|
||||
get _nativeView(): TNSLabel {
|
||||
return this._ios;
|
||||
}
|
||||
|
||||
@ -53,13 +58,13 @@ export class LabelBase extends TextBase implements LabelDefinition {
|
||||
}
|
||||
|
||||
public onMeasure(widthMeasureSpec: number, heightMeasureSpec: number): void {
|
||||
var nativeView = this._nativeView;
|
||||
let nativeView = this._nativeView;
|
||||
if (nativeView) {
|
||||
var width = layout.getMeasureSpecSize(widthMeasureSpec);
|
||||
var widthMode = layout.getMeasureSpecMode(widthMeasureSpec);
|
||||
let width = layout.getMeasureSpecSize(widthMeasureSpec);
|
||||
let widthMode = layout.getMeasureSpecMode(widthMeasureSpec);
|
||||
|
||||
var height = layout.getMeasureSpecSize(heightMeasureSpec);
|
||||
var heightMode = layout.getMeasureSpecMode(heightMeasureSpec);
|
||||
let height = layout.getMeasureSpecSize(heightMeasureSpec);
|
||||
let heightMode = layout.getMeasureSpecMode(heightMeasureSpec);
|
||||
|
||||
if (widthMode === layout.UNSPECIFIED) {
|
||||
width = Number.POSITIVE_INFINITY;
|
||||
@ -72,30 +77,30 @@ export class LabelBase extends TextBase implements LabelDefinition {
|
||||
this._fixedSize = (widthMode === layout.EXACTLY ? FixedSize.WIDTH : FixedSize.NONE)
|
||||
| (heightMode === layout.EXACTLY ? FixedSize.HEIGHT : FixedSize.NONE);
|
||||
|
||||
var nativeSize = nativeView.sizeThatFits(CGSizeMake(width, height));
|
||||
var labelWidth = nativeSize.width;
|
||||
let nativeSize = nativeView.sizeThatFits(CGSizeMake(width, height));
|
||||
let labelWidth = nativeSize.width;
|
||||
|
||||
if (!this.textWrap && this.style.whiteSpace !== "nowrap") {
|
||||
labelWidth = Math.min(labelWidth, width);
|
||||
}
|
||||
|
||||
let style = this.sltye;
|
||||
var measureWidth = Math.max(labelWidth, style.effectiveMinWidth);
|
||||
var measureHeight = Math.max(nativeSize.height, style.effectiveMinHeight);
|
||||
let style = this.style;
|
||||
let measureWidth = Math.max(labelWidth, style.effectiveMinWidth);
|
||||
let measureHeight = Math.max(nativeSize.height, style.effectiveMinHeight);
|
||||
|
||||
var widthAndState = View.resolveSizeAndState(measureWidth, width, widthMode, 0);
|
||||
var heightAndState = View.resolveSizeAndState(measureHeight, height, heightMode, 0);
|
||||
let widthAndState = View.resolveSizeAndState(measureWidth, width, widthMode, 0);
|
||||
let heightAndState = View.resolveSizeAndState(measureHeight, height, heightMode, 0);
|
||||
|
||||
this.setMeasuredDimension(widthAndState, heightAndState);
|
||||
}
|
||||
}
|
||||
|
||||
get [whiteSpaceProperty.native](): string {
|
||||
return WhiteSpace.normal;
|
||||
get [whiteSpaceProperty.native](): "nowrap" | "normal" {
|
||||
return "normal";
|
||||
}
|
||||
set [whiteSpaceProperty.native](value: string) {
|
||||
let nativeView = this.nativeView;
|
||||
if (value === WhiteSpace.normal) {
|
||||
if (value === "normal") {
|
||||
nativeView.lineBreakMode = NSLineBreakMode.ByWordWrapping;
|
||||
nativeView.numberOfLines = 0;
|
||||
}
|
||||
@ -104,204 +109,138 @@ export class LabelBase extends TextBase implements LabelDefinition {
|
||||
nativeView.numberOfLines = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let zeroInsets = UIEdgeInsetsZero;
|
||||
|
||||
export class LabelStyler implements style.Styler {
|
||||
//Background methods
|
||||
private static setBackgroundInternalProperty(view: View, newValue: any) {
|
||||
var uiLabel: UILabel = <UILabel>view._nativeView;
|
||||
if (uiLabel && uiLabel.layer) {
|
||||
var flipImage = true;
|
||||
ensureBackground();
|
||||
var uiColor = <UIColor>background.ios.createBackgroundUIColor(view, flipImage);
|
||||
var cgColor = uiColor ? uiColor.CGColor : null;
|
||||
uiLabel.layer.backgroundColor = cgColor;
|
||||
}
|
||||
}
|
||||
|
||||
private static resetBackgroundInternalProperty(view: View, nativeValue: any) {
|
||||
var uiLabel: UILabel = <UILabel>view._nativeView;
|
||||
if (uiLabel && uiLabel.layer) {
|
||||
var uiColor = <UIColor>nativeValue;
|
||||
var cgColor = uiColor ? uiColor.CGColor : null;
|
||||
uiLabel.layer.backgroundColor = cgColor;
|
||||
}
|
||||
}
|
||||
|
||||
private static getNativeBackgroundInternalValue(view: View): any {
|
||||
var uiLabel: UILabel = <UILabel>view._nativeView;
|
||||
if (uiLabel && uiLabel.layer && uiLabel.layer.backgroundColor) {
|
||||
return UIColor.colorWithCGColor(uiLabel.layer.backgroundColor);
|
||||
get [backgroundInternalProperty.native](): UIColor {
|
||||
let nativeView = this._nativeView;
|
||||
if (nativeView.layer && nativeView.layer.backgroundColor) {
|
||||
return UIColor.colorWithCGColor(nativeView.layer.backgroundColor);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
set [backgroundInternalProperty.native](value: UIColor | Background) {
|
||||
let nativeView = this._nativeView;
|
||||
|
||||
private static setBorderTopWidthProperty(view: View, newValue: number) {
|
||||
LabelStyler.setNativeBorderTopWidth(view, newValue);
|
||||
}
|
||||
|
||||
private static resetBorderTopWidthProperty(view: View, nativeValue: number) {
|
||||
LabelStyler.setNativeBorderTopWidth(view, nativeValue);
|
||||
}
|
||||
|
||||
private static setNativeBorderTopWidth(view: View, newValue: number) {
|
||||
let nativeView = <UIView>view._nativeView;
|
||||
if (nativeView instanceof TNSLabel) {
|
||||
nativeView.borderThickness = {
|
||||
top: newValue,
|
||||
right: nativeView.borderThickness.right,
|
||||
bottom: nativeView.borderThickness.bottom,
|
||||
left: nativeView.borderThickness.left
|
||||
};
|
||||
let cgColor = null;
|
||||
if (value instanceof UIColor) {
|
||||
cgColor = value.CGColor;
|
||||
} else {
|
||||
let uiColor = <UIColor>ios.createBackgroundUIColor(this, true);
|
||||
cgColor = uiColor ? uiColor.CGColor : null;
|
||||
}
|
||||
|
||||
nativeView.layer.backgroundColor = cgColor;
|
||||
}
|
||||
|
||||
private static getBorderTopWidthProperty(view: View): number {
|
||||
let nativeView = <UIView>view._nativeView;
|
||||
if (nativeView instanceof TNSLabel) {
|
||||
return nativeView.borderThickness.top;
|
||||
}
|
||||
get [borderTopWidthProperty.native](): number {
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static setBorderRightWidthProperty(view: View, newValue: number) {
|
||||
LabelStyler.setNativeBorderRightWidth(view, newValue);
|
||||
set [borderTopWidthProperty.native](value: number) {
|
||||
let nativeView = this._nativeView;
|
||||
let border = nativeView.borderThickness;
|
||||
nativeView.borderThickness = {
|
||||
top: value,
|
||||
right: border.right,
|
||||
bottom: border.bottom,
|
||||
left: border.left
|
||||
};
|
||||
}
|
||||
|
||||
private static resetBorderRightWidthProperty(view: View, nativeValue: number) {
|
||||
LabelStyler.setNativeBorderRightWidth(view, nativeValue);
|
||||
}
|
||||
|
||||
private static setNativeBorderRightWidth(view: View, newValue: number) {
|
||||
let nativeView = <UIView>view._nativeView;
|
||||
if (nativeView instanceof TNSLabel) {
|
||||
nativeView.borderThickness = {
|
||||
top: nativeView.borderThickness.top,
|
||||
right: newValue,
|
||||
bottom: nativeView.borderThickness.bottom,
|
||||
left: nativeView.borderThickness.left
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private static getBorderRightWidthProperty(view: View): number {
|
||||
let nativeView = <UIView>view._nativeView;
|
||||
if (nativeView instanceof TNSLabel) {
|
||||
return nativeView.borderThickness.right;
|
||||
}
|
||||
get [borderRightWidthProperty.native](): number {
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static setBorderBottomWidthProperty(view: View, newValue: number) {
|
||||
LabelStyler.setNativeBorderBottomWidth(view, newValue);
|
||||
set [borderRightWidthProperty.native](value: number) {
|
||||
let nativeView = this._nativeView;
|
||||
let border = nativeView.borderThickness;
|
||||
nativeView.borderThickness = {
|
||||
top: border.top,
|
||||
right: value,
|
||||
bottom: border.bottom,
|
||||
left: border.left
|
||||
};
|
||||
}
|
||||
|
||||
private static resetBorderBottomWidthProperty(view: View, nativeValue: number) {
|
||||
LabelStyler.setNativeBorderBottomWidth(view, nativeValue);
|
||||
}
|
||||
|
||||
private static setNativeBorderBottomWidth(view: View, newValue: number) {
|
||||
let nativeView = <UIView>view._nativeView;
|
||||
if (nativeView instanceof TNSLabel) {
|
||||
nativeView.borderThickness = {
|
||||
top: nativeView.borderThickness.top,
|
||||
right: nativeView.borderThickness.right,
|
||||
bottom: newValue,
|
||||
left: nativeView.borderThickness.left
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private static getBorderBottomWidthProperty(view: View): number {
|
||||
let nativeView = <UIView>view._nativeView;
|
||||
if (nativeView instanceof TNSLabel) {
|
||||
return nativeView.borderThickness.bottom;
|
||||
}
|
||||
get [borderBottomWidthProperty.native](): number {
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static setBorderLeftWidthProperty(view: View, newValue: number) {
|
||||
LabelStyler.setNativeBorderLeftWidth(view, newValue);
|
||||
set [borderBottomWidthProperty.native](value: number) {
|
||||
let nativeView = this._nativeView;
|
||||
let border = nativeView.borderThickness;
|
||||
nativeView.borderThickness = {
|
||||
top: border.top,
|
||||
right: border.right,
|
||||
bottom: value,
|
||||
left: border.left
|
||||
};
|
||||
}
|
||||
|
||||
private static resetBorderLeftWidthProperty(view: View, nativeValue: number) {
|
||||
LabelStyler.setNativeBorderLeftWidth(view, nativeValue);
|
||||
}
|
||||
|
||||
private static setNativeBorderLeftWidth(view: View, newValue: number) {
|
||||
let nativeView = <UIView>view._nativeView;
|
||||
if (nativeView instanceof TNSLabel) {
|
||||
nativeView.borderThickness = {
|
||||
top: nativeView.borderThickness.top,
|
||||
right: nativeView.borderThickness.right,
|
||||
bottom: nativeView.borderThickness.bottom,
|
||||
left: newValue
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private static getBorderLeftWidthProperty(view: View): number {
|
||||
let nativeView = <UIView>view._nativeView;
|
||||
if (nativeView instanceof TNSLabel) {
|
||||
return nativeView.borderThickness.left;
|
||||
}
|
||||
get [borderLeftWidthProperty.native](): number {
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static setPaddingProperty(view: View, newValue: UIEdgeInsets) {
|
||||
LabelStyler.setNativePadding(view, newValue);
|
||||
set [borderLeftWidthProperty.native](value: number) {
|
||||
let nativeView = this._nativeView;
|
||||
let border = nativeView.borderThickness;
|
||||
nativeView.borderThickness = {
|
||||
top: border.top,
|
||||
right: border.right,
|
||||
bottom: border.bottom,
|
||||
left: value
|
||||
};
|
||||
}
|
||||
|
||||
private static resetPaddingProperty(view: View, nativeValue: UIEdgeInsets) {
|
||||
LabelStyler.setNativePadding(view, nativeValue);
|
||||
get [paddingTopProperty.native](): number {
|
||||
return 0;
|
||||
}
|
||||
set [paddingTopProperty.native](value: number) {
|
||||
let nativeView = this._nativeView;
|
||||
let padding = nativeView.padding;
|
||||
nativeView.padding = {
|
||||
top: value,
|
||||
right: padding.right,
|
||||
bottom: padding.bottom,
|
||||
left: padding.left
|
||||
};
|
||||
}
|
||||
|
||||
private static setNativePadding(view: View, padding: UIEdgeInsets) {
|
||||
let nativeView = <UIView>view._nativeView;
|
||||
if (nativeView instanceof TNSLabel) {
|
||||
nativeView.padding = { top: padding.top, left: padding.left, bottom: padding.bottom, right: padding.right };
|
||||
}
|
||||
get [paddingRightProperty.native](): number {
|
||||
return 0;
|
||||
}
|
||||
set [paddingRightProperty.native](value: number) {
|
||||
let nativeView = this._nativeView;
|
||||
let padding = nativeView.padding;
|
||||
nativeView.padding = {
|
||||
top: padding.top,
|
||||
right: value,
|
||||
bottom: padding.bottom,
|
||||
left: padding.left
|
||||
};
|
||||
}
|
||||
|
||||
private static getPaddingProperty(view: View): UIEdgeInsets {
|
||||
let nativeView = <UIView>view._nativeView;
|
||||
if (nativeView instanceof TNSLabel) {
|
||||
return nativeView.padding;
|
||||
}
|
||||
return zeroInsets;
|
||||
get [paddingBottomProperty.native](): number {
|
||||
return 0;
|
||||
}
|
||||
set [paddingBottomProperty.native](value: number) {
|
||||
let nativeView = this._nativeView;
|
||||
let padding = nativeView.padding;
|
||||
nativeView.padding = {
|
||||
top: padding.top,
|
||||
right: padding.right,
|
||||
bottom: value,
|
||||
left: padding.left
|
||||
};
|
||||
}
|
||||
|
||||
public static registerHandlers() {
|
||||
style.registerHandler(style.backgroundInternalProperty, new style.StylePropertyChangedHandler(
|
||||
LabelStyler.setBackgroundInternalProperty,
|
||||
LabelStyler.resetBackgroundInternalProperty,
|
||||
LabelStyler.getNativeBackgroundInternalValue), "Label");
|
||||
|
||||
style.registerHandler(style.borderTopWidthProperty, new style.StylePropertyChangedHandler(
|
||||
LabelStyler.setBorderTopWidthProperty,
|
||||
LabelStyler.resetBorderTopWidthProperty,
|
||||
LabelStyler.getBorderTopWidthProperty), "Label");
|
||||
style.registerHandler(style.borderRightWidthProperty, new style.StylePropertyChangedHandler(
|
||||
LabelStyler.setBorderRightWidthProperty,
|
||||
LabelStyler.resetBorderRightWidthProperty,
|
||||
LabelStyler.getBorderRightWidthProperty), "Label");
|
||||
style.registerHandler(style.borderBottomWidthProperty, new style.StylePropertyChangedHandler(
|
||||
LabelStyler.setBorderBottomWidthProperty,
|
||||
LabelStyler.resetBorderBottomWidthProperty,
|
||||
LabelStyler.getBorderBottomWidthProperty), "Label");
|
||||
style.registerHandler(style.borderLeftWidthProperty, new style.StylePropertyChangedHandler(
|
||||
LabelStyler.setBorderLeftWidthProperty,
|
||||
LabelStyler.resetBorderLeftWidthProperty,
|
||||
LabelStyler.getBorderLeftWidthProperty), "Label");
|
||||
|
||||
style.registerHandler(style.nativePaddingsProperty, new style.StylePropertyChangedHandler(
|
||||
LabelStyler.setPaddingProperty,
|
||||
LabelStyler.resetPaddingProperty,
|
||||
LabelStyler.getPaddingProperty), "Label");
|
||||
get [paddingLeftProperty.native](): number {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
LabelStyler.registerHandlers();
|
||||
set [paddingLeftProperty.native](value: number) {
|
||||
let nativeView = this._nativeView;
|
||||
let padding = nativeView.padding;
|
||||
nativeView.padding = {
|
||||
top: padding.top,
|
||||
right: padding.right,
|
||||
bottom: padding.bottom,
|
||||
left: value
|
||||
};
|
||||
}
|
||||
}
|
@ -1,92 +1,32 @@
|
||||
import definition = require("ui/list-picker");
|
||||
import dependencyObservable = require("ui/core/dependency-observable");
|
||||
import proxy = require("ui/core/proxy");
|
||||
import view = require("ui/core/view");
|
||||
import types = require("utils/types");
|
||||
import trace = require("trace");
|
||||
import { ListPicker as ListPickerDefinition, ItemsSource } from "ui/list-picker";
|
||||
import { View } from "ui/core/view";
|
||||
import { Property } from "ui/core/properties";
|
||||
|
||||
export var traceCategory = "ListPicker";
|
||||
export class ListPickerBase extends View implements ListPickerDefinition {
|
||||
|
||||
export class ListPicker extends view.View implements definition.ListPicker {
|
||||
public static selectedIndexProperty = new dependencyObservable.Property("selectedIndex", "ListPicker", new proxy.PropertyMetadata(undefined));
|
||||
public static itemsProperty = new dependencyObservable.Property("items", "ListPicker", new proxy.PropertyMetadata(undefined));
|
||||
|
||||
get selectedIndex(): number {
|
||||
return this._getValue(ListPicker.selectedIndexProperty);
|
||||
}
|
||||
set selectedIndex(value: number) {
|
||||
this._setValue(ListPicker.selectedIndexProperty, value);
|
||||
}
|
||||
|
||||
get items(): any {
|
||||
return this._getValue(ListPicker.itemsProperty);
|
||||
}
|
||||
set items(value: any) {
|
||||
this._setValue(ListPicker.itemsProperty, value);
|
||||
}
|
||||
public selectedIndex: number;
|
||||
public items: any[] | ItemsSource;
|
||||
|
||||
public _getItemAsString(index: number): any {
|
||||
if (!this.items || !this.items.length) {
|
||||
if (!this.items) {
|
||||
return " ";
|
||||
}
|
||||
|
||||
if (types.isDefined(this.items)) {
|
||||
var item = this.items.getItem ? this.items.getItem(index) : this.items[index];
|
||||
|
||||
return types.isString(item) ? item : (types.isDefined(item) ? item.toString() : index.toString());
|
||||
}
|
||||
|
||||
return index.toString();
|
||||
let getItem = (<ItemsSource>this.items).getItem;
|
||||
let item = typeof getItem === "function" ? getItem(index) : this.items[index];
|
||||
return item === undefined || item === null ? index + "" : item + "";
|
||||
}
|
||||
|
||||
public _onSelectedIndexPropertyChanged(data: dependencyObservable.PropertyChangeData) {
|
||||
if (trace.enabled) {
|
||||
trace.write("ListPicker._onSelectedIndexPropertyChanged("+data.oldValue+" => "+data.newValue+");", traceCategory);
|
||||
}
|
||||
var index = this.selectedIndex;
|
||||
if (types.isUndefined(index)) {
|
||||
return;
|
||||
protected getSelectedIndex(items: any[] | ItemsSource): number {
|
||||
let maxValue = items && items.length > 0 ? items.length - 1 : 0;
|
||||
let selectedIndex = this.selectedIndex;
|
||||
if (selectedIndex < 0 || selectedIndex > maxValue) {
|
||||
selectedIndex = 0;
|
||||
}
|
||||
|
||||
if (types.isDefined(this.items)) {
|
||||
if (index < 0 || index >= this.items.length) {
|
||||
this.selectedIndex = undefined;
|
||||
throw new Error("selectedIndex should be between [0, items.length - 1]");
|
||||
}
|
||||
}
|
||||
return selectedIndex;
|
||||
}
|
||||
|
||||
public _onItemsPropertyChanged(data: dependencyObservable.PropertyChangeData) {
|
||||
//trace.write("ListPicker._onItemsPropertyChanged(" + data.oldValue + " => " + data.newValue + ");", traceCategory);
|
||||
}
|
||||
|
||||
public _updateSelectedIndexOnItemsPropertyChanged(newItems) {
|
||||
if (trace.enabled) {
|
||||
trace.write("ListPicker._updateSelectedIndexOnItemsPropertyChanged(" + newItems + ");", traceCategory);
|
||||
}
|
||||
var newItemsCount = 0;
|
||||
if (newItems && newItems.length) {
|
||||
newItemsCount = newItems.length;
|
||||
}
|
||||
|
||||
if (newItemsCount === 0) {
|
||||
this.selectedIndex = undefined;
|
||||
}
|
||||
else if (types.isUndefined(this.selectedIndex) || this.selectedIndex >= newItemsCount) {
|
||||
this.selectedIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onSelectedIndexPropertyChanged(data: dependencyObservable.PropertyChangeData) {
|
||||
var picker = <ListPicker>data.object;
|
||||
picker._onSelectedIndexPropertyChanged(data);
|
||||
}
|
||||
|
||||
function onItemsPropertyChanged(data: dependencyObservable.PropertyChangeData) {
|
||||
var picker = <ListPicker>data.object;
|
||||
picker._onItemsPropertyChanged(data);
|
||||
}
|
||||
|
||||
(<proxy.PropertyMetadata>ListPicker.selectedIndexProperty.metadata).onSetNativeValue = onSelectedIndexPropertyChanged;
|
||||
(<proxy.PropertyMetadata>ListPicker.itemsProperty.metadata).onSetNativeValue = onItemsPropertyChanged;
|
||||
export const selectedIndexProperty = new Property<ListPickerBase, number>({ name: "selectedIndex", defaultValue: -1 });
|
||||
export const itemsProperty = new Property<ListPickerBase, any[] | ItemsSource>({ name: "items" });
|
@ -1,17 +1,44 @@
|
||||
import common = require("./list-picker-common");
|
||||
import dependencyObservable = require("ui/core/dependency-observable");
|
||||
import utils = require("utils/utils")
|
||||
import * as types from "utils/types";
|
||||
import { Styler, colorProperty, registerHandler, StylePropertyChangedHandler } from "ui/styling/style";
|
||||
import { View } from "ui/core/view";
|
||||
import { ListPickerBase, selectedIndexProperty, itemsProperty } from "./list-picker-common";
|
||||
import { ItemsSource } from "ui/list-picker";
|
||||
|
||||
global.moduleMerge(common, exports);
|
||||
export * from "./list-picker-common";
|
||||
|
||||
export class ListPicker extends common.ListPicker {
|
||||
@Interfaces([android.widget.NumberPicker.Formatter])
|
||||
class Formatter implements android.widget.NumberPicker.Formatter {
|
||||
constructor(private owner: WeakRef<ListPicker>) {
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
format(index: number): string {
|
||||
let owner = this.owner.get();
|
||||
if (owner) {
|
||||
return owner._getItemAsString(index);
|
||||
}
|
||||
|
||||
return " ";
|
||||
}
|
||||
}
|
||||
|
||||
@Interfaces([android.widget.NumberPicker.OnValueChangeListener])
|
||||
class ValueChangeListener implements android.widget.NumberPicker.OnValueChangeListener {
|
||||
constructor(private owner: WeakRef<ListPicker>) {
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
onValueChange(picker: android.widget.NumberPicker, oldVal: number, newVal: number): void {
|
||||
let owner = this.owner.get();
|
||||
if (owner) {
|
||||
owner.nativePropertyChanged(selectedIndexProperty, newVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class ListPicker extends ListPickerBase {
|
||||
private _android: android.widget.NumberPicker;
|
||||
private _valueChangedListener: android.widget.NumberPicker.OnValueChangeListener;
|
||||
private _formatter: android.widget.NumberPicker.Formatter;
|
||||
private _editText: android.widget.EditText;
|
||||
private itemsSet: boolean;
|
||||
|
||||
get android(): android.widget.NumberPicker {
|
||||
return this._android;
|
||||
@ -25,35 +52,10 @@ export class ListPicker extends common.ListPicker {
|
||||
this._android.setMaxValue(0);
|
||||
this._android.setValue(0);
|
||||
|
||||
var that = new WeakRef(this);
|
||||
|
||||
this._formatter = new android.widget.NumberPicker.Formatter(
|
||||
<utils.Owned & android.widget.NumberPicker.IFormatter>{
|
||||
get owner(): ListPicker {
|
||||
return that.get();
|
||||
},
|
||||
|
||||
format: function (index: number) {
|
||||
if (this.owner) {
|
||||
return this.owner._getItemAsString(index);
|
||||
}
|
||||
|
||||
return " ";
|
||||
}
|
||||
});
|
||||
let formatter = this._formatter || new Formatter(new WeakRef(this));
|
||||
this._android.setFormatter(this._formatter);
|
||||
|
||||
this._valueChangedListener = new android.widget.NumberPicker.OnValueChangeListener(<utils.Owned & android.widget.NumberPicker.IOnValueChangeListener>{
|
||||
get owner() {
|
||||
return that.get();
|
||||
},
|
||||
|
||||
onValueChange: function (picker: android.widget.NumberPicker, oldVal: number, newVal: number) {
|
||||
if (this.owner) {
|
||||
this.owner._onPropertyChangedFromNative(common.ListPicker.selectedIndexProperty, newVal);
|
||||
}
|
||||
}
|
||||
});
|
||||
let valueChangedListener = this._valueChangedListener || new ValueChangeListener(new WeakRef(this));
|
||||
this._android.setOnValueChangedListener(this._valueChangedListener);
|
||||
|
||||
//Fix the disappearing selected item.
|
||||
@ -65,37 +67,25 @@ export class ListPicker extends common.ListPicker {
|
||||
|
||||
//Since the Android NumberPicker has to always have at least one item, i.e. minValue=maxValue=value=0, we don't want this zero showing up when this.items is empty.
|
||||
this._editText.setText(" ", android.widget.TextView.BufferType.NORMAL);
|
||||
|
||||
this.android.setWrapSelectorWheel(false);
|
||||
}
|
||||
|
||||
public _onSelectedIndexPropertyChanged(data: dependencyObservable.PropertyChangeData) {
|
||||
super._onSelectedIndexPropertyChanged(data);
|
||||
if (this.android && types.isNumber(data.newValue)) {
|
||||
this.android.setValue(data.newValue);
|
||||
}
|
||||
private updateSelectedValue(): void {
|
||||
let selectedIndex = this.getSelectedIndex(this.items);
|
||||
this.android.setValue(selectedIndex);
|
||||
}
|
||||
|
||||
public _onItemsPropertyChanged(data: dependencyObservable.PropertyChangeData) {
|
||||
if (this.android) {
|
||||
if (!data.newValue || !data.newValue.length) {
|
||||
this.android.setMaxValue(0);
|
||||
}
|
||||
else {
|
||||
this.android.setMaxValue(data.newValue.length - 1);
|
||||
}
|
||||
private onItemsPropertyChanged(items: any[] | ItemsSource) {
|
||||
let maxValue = items && items.length > 0 ? items.length - 1 : 0;
|
||||
|
||||
this.android.setWrapSelectorWheel(false);
|
||||
}
|
||||
|
||||
this._updateSelectedIndexOnItemsPropertyChanged(data.newValue);
|
||||
this.android.setMaxValue(maxValue);
|
||||
this.updateSelectedValue();
|
||||
|
||||
this._fixNumberPickerRendering();
|
||||
}
|
||||
|
||||
private _fixNumberPickerRendering() {
|
||||
if (!this.android) {
|
||||
return;
|
||||
}
|
||||
|
||||
//HACK: Force the stubborn NumberPicker to render correctly when we have 0 or 1 items.
|
||||
this.android.setFormatter(null);
|
||||
this.android.setFormatter(this._formatter); //Force the NumberPicker to call our Formatter
|
||||
@ -105,40 +95,30 @@ export class ListPicker extends common.ListPicker {
|
||||
this._editText.invalidate(); //Force the EditText to redraw
|
||||
this.android.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
export class ListPickerStyler implements Styler {
|
||||
// color
|
||||
private static setColorProperty(view: View, newValue: any) {
|
||||
var picker = <android.widget.NumberPicker>view._nativeView;
|
||||
ListPickerStyler._setNumberPickerTextColor(picker, newValue);
|
||||
get [selectedIndexProperty.native](): number {
|
||||
return -1;
|
||||
}
|
||||
set [selectedIndexProperty.native](value: number) {
|
||||
if (this.itemsSet) {
|
||||
this.updateSelectedValue();
|
||||
}
|
||||
}
|
||||
|
||||
private static resetColorProperty(view: View, nativeValue: any) {
|
||||
var picker = <android.widget.NumberPicker>view._nativeView;
|
||||
ListPickerStyler._setNumberPickerTextColor(picker, nativeValue);
|
||||
get [itemsProperty.native](): any[] {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static registerHandlers() {
|
||||
registerHandler(colorProperty, new StylePropertyChangedHandler(
|
||||
ListPickerStyler.setColorProperty,
|
||||
ListPickerStyler.resetColorProperty), "ListPicker");
|
||||
}
|
||||
|
||||
private static _setNumberPickerTextColor(picker: android.widget.NumberPicker, newValue: any) {
|
||||
let childrenCount = picker.getChildCount();
|
||||
|
||||
for (let i = 0; i < childrenCount; i++) {
|
||||
let child = picker.getChildAt(i);
|
||||
if (child instanceof android.widget.EditText) {
|
||||
let selectorWheelPaintField = picker.getClass().getDeclaredField("mSelectorWheelPaint");
|
||||
selectorWheelPaintField.setAccessible(true);
|
||||
|
||||
selectorWheelPaintField.get(picker).setColor(newValue);
|
||||
(<android.widget.EditText>picker.getChildAt(i)).setTextColor(newValue);
|
||||
}
|
||||
set [itemsProperty.native](value: any[] | ItemsSource) {
|
||||
this.onItemsPropertyChanged(value);
|
||||
// items are cleared - set selectedIndex to -1
|
||||
if (!value) {
|
||||
this.itemsSet = false;
|
||||
this.selectedIndex = -1;
|
||||
} else if (this.selectedIndex < 0) {
|
||||
// items are set and selectedIndex is set - update maxValue & value.
|
||||
this.selectedIndex = 0;
|
||||
// set this flag later so no native call happens
|
||||
this.itemsSet = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListPickerStyler.registerHandlers();
|
21
tns-core-modules/ui/list-picker/list-picker.d.ts
vendored
21
tns-core-modules/ui/list-picker/list-picker.d.ts
vendored
@ -2,18 +2,13 @@
|
||||
* Contains the ListPicker class.
|
||||
*/
|
||||
declare module "ui/list-picker" {
|
||||
import view = require("ui/core/view");
|
||||
import dependencyObservable = require("ui/core/dependency-observable");
|
||||
import { View } from "ui/core/view";
|
||||
import { Property } from "ui/core/properties";
|
||||
|
||||
/**
|
||||
* Represents an list picker.
|
||||
*/
|
||||
export class ListPicker extends view.View {
|
||||
public static selectedIndexProperty: dependencyObservable.Property;
|
||||
public static itemsProperty: dependencyObservable.Property;
|
||||
|
||||
constructor();
|
||||
|
||||
export class ListPicker extends View {
|
||||
/**
|
||||
* Gets the native [android.widget.NumberPicker](http://developer.android.com/reference/android/widget/NumberPicker.html) that represents the user interface for this component. Valid only when running on Android OS.
|
||||
*/
|
||||
@ -35,4 +30,12 @@ declare module "ui/list-picker" {
|
||||
*/
|
||||
items: any;
|
||||
}
|
||||
}
|
||||
|
||||
export interface ItemsSource {
|
||||
length: number;
|
||||
getItem(index: number): any;
|
||||
}
|
||||
|
||||
export const selectedIndexProperty: Property<ListPicker, number>;
|
||||
export const itemsProperty: Property<ListPicker, any[] | ItemsSource>;
|
||||
}
|
@ -1,15 +1,13 @@
|
||||
import common = require("./list-picker-common");
|
||||
import dependencyObservable = require("ui/core/dependency-observable");
|
||||
import * as types from "utils/types";
|
||||
import { backgroundColorProperty, colorProperty, registerHandler, Styler, StylePropertyChangedHandler } from "ui/styling/style";
|
||||
import { View } from "ui/core/view";
|
||||
import { ListPickerBase, selectedIndexProperty, itemsProperty } from "./list-picker-common";
|
||||
import { ItemsSource } from "ui/list-picker";
|
||||
|
||||
global.moduleMerge(common, exports);
|
||||
export * from "./list-picker-common";
|
||||
|
||||
export class ListPicker extends common.ListPicker {
|
||||
export class ListPicker extends ListPickerBase {
|
||||
private _ios: UIPickerView;
|
||||
private _dataSource: ListPickerDataSource;
|
||||
private _delegate: ListPickerDelegateImpl;
|
||||
private itemsSet: boolean;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@ -33,19 +31,42 @@ export class ListPicker extends common.ListPicker {
|
||||
return this._ios;
|
||||
}
|
||||
|
||||
public _onSelectedIndexPropertyChanged(data: dependencyObservable.PropertyChangeData) {
|
||||
super._onSelectedIndexPropertyChanged(data);
|
||||
if (this.ios && types.isNumber(data.newValue)) {
|
||||
this.ios.selectRowInComponentAnimated(data.newValue, 0, false);
|
||||
private updateSelectedValue(): void {
|
||||
let selectedIndex = this.getSelectedIndex(this.items);
|
||||
if (selectedIndex >= 0) {
|
||||
this.ios.selectRowInComponentAnimated(selectedIndex, 0, false);
|
||||
}
|
||||
}
|
||||
|
||||
public _onItemsPropertyChanged(data: dependencyObservable.PropertyChangeData) {
|
||||
if (this.ios) {
|
||||
this.ios.reloadAllComponents();
|
||||
}
|
||||
private onItemsPropertyChanged(items: any[] | ItemsSource) {
|
||||
this.ios.reloadAllComponents();
|
||||
this.updateSelectedValue();
|
||||
}
|
||||
|
||||
this._updateSelectedIndexOnItemsPropertyChanged(data.newValue);
|
||||
get [selectedIndexProperty.native](): number {
|
||||
return -1;
|
||||
}
|
||||
set [selectedIndexProperty.native](value: number) {
|
||||
if (this.itemsSet) {
|
||||
this.updateSelectedValue();
|
||||
}
|
||||
}
|
||||
|
||||
get [itemsProperty.native](): any[] {
|
||||
return null;
|
||||
}
|
||||
set [itemsProperty.native](value: any[] | ItemsSource) {
|
||||
this.onItemsPropertyChanged(value);
|
||||
// items are cleared - set selectedIndex to -1
|
||||
if (!value) {
|
||||
this.itemsSet = false;
|
||||
this.selectedIndex = -1;
|
||||
} else if (this.selectedIndex < 0) {
|
||||
// items are set and selectedIndex is set - update maxValue & value.
|
||||
this.selectedIndex = 0;
|
||||
// set this flag later so no native call happens
|
||||
this.itemsSet = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,7 +114,7 @@ class ListPickerDelegateImpl extends NSObject implements UIPickerViewDelegate {
|
||||
public pickerViewDidSelectRowInComponent(pickerView: UIPickerView, row: number, component: number): void {
|
||||
let owner = this._owner.get();
|
||||
if (owner) {
|
||||
owner._onPropertyChangedFromNative(common.ListPicker.selectedIndexProperty, row);
|
||||
owner.nativePropertyChanged(selectedIndexProperty, row);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -144,4 +165,4 @@ export class ListPickerStyler implements Styler {
|
||||
}
|
||||
}
|
||||
|
||||
ListPickerStyler.registerHandlers();
|
||||
ListPickerStyler.registerHandlers();
|
||||
|
18
tns-core-modules/ui/styling/style.d.ts
vendored
18
tns-core-modules/ui/styling/style.d.ts
vendored
@ -2,7 +2,6 @@ declare module "ui/styling/style" {
|
||||
import { Observable } from "data/observable";
|
||||
import { ViewBase } from "ui/core/view-base";
|
||||
import { Color } from "color";
|
||||
import { CssProperty, InheritedCssProperty } from "ui/core/properties";
|
||||
import { Font } from "ui/styling/font";
|
||||
import { Background } from "ui/styling/background";
|
||||
import { Length } from "ui/core/view";
|
||||
@ -83,7 +82,7 @@ declare module "ui/styling/style" {
|
||||
public fontSize: number;
|
||||
public fontFamily: string;
|
||||
public fontStyle: "normal" | "italic";
|
||||
public fontWeight: string;
|
||||
public fontWeight: "100" | "200" | "300" | "normal" | "400" | "500" | "600" | "bold" | "700" | "800" | "900";
|
||||
public font: string;
|
||||
|
||||
public zIndex: number;
|
||||
@ -141,21 +140,6 @@ declare module "ui/styling/style" {
|
||||
// export function getHandler(property: Property, view: View): StylePropertyChangedHandler;
|
||||
// Property registration
|
||||
|
||||
export let tintColorProperty: InheritedCssProperty<Style, Color>;
|
||||
export let placeholderColorProperty: InheritedCssProperty<Style, Color>;
|
||||
|
||||
export let fontSizeProperty: InheritedCssProperty<Style, number>;
|
||||
export let fontFamilyProperty: InheritedCssProperty<Style, string>;
|
||||
export let fontStyleProperty: InheritedCssProperty<Style, string>;
|
||||
export let fontWeightProperty: InheritedCssProperty<Style, string>;
|
||||
export let fontProperty: InheritedCssProperty<Style, Font>;
|
||||
|
||||
export let textAlignmentProperty: InheritedCssProperty<Style, string>;
|
||||
export let textDecorationProperty: CssProperty<Style, string>;
|
||||
export let textTransformProperty: CssProperty<Style, string>;
|
||||
export let letterSpacingProperty: CssProperty<Style, number>;
|
||||
export let whiteSpaceProperty: CssProperty<Style, string>;
|
||||
|
||||
// /**
|
||||
// * Represents an object that defines how style property should be applied on a native view/widget.
|
||||
// */
|
||||
|
@ -284,149 +284,6 @@ Style.prototype.effectiveBorderBottomWidth = 0;
|
||||
Style.prototype.effectiveBorderLeftWidth = 0;
|
||||
// Property registration
|
||||
|
||||
export let fontInternalProperty = new CssProperty<Style, Font>({ name: "fontInternal", cssName: "_fontInternal", defaultValue: Font.default });
|
||||
|
||||
export let fontFamilyProperty = new InheritedCssProperty<Style, string>({
|
||||
name: "fontFamily", cssName: "font-family", valueChanged: (target, newValue) => {
|
||||
let currentFont = target.fontInternal;
|
||||
if (currentFont.fontFamily !== newValue) {
|
||||
target.fontInternal = currentFont.withFontFamily(newValue);
|
||||
}
|
||||
}
|
||||
});
|
||||
fontFamilyProperty.register(Style);
|
||||
|
||||
export let fontSizeProperty = new InheritedCssProperty<Style, number>({
|
||||
name: "fontSize", cssName: "font-size", valueChanged: (target, newValue) => {
|
||||
let currentFont = target.fontInternal;
|
||||
if (currentFont.fontSize !== newValue) {
|
||||
target.fontInternal = currentFont.withFontSize(newValue);
|
||||
}
|
||||
},
|
||||
valueConverter: (v) => parseFloat(v)
|
||||
});
|
||||
fontSizeProperty.register(Style);
|
||||
|
||||
export let fontStyleProperty = new InheritedCssProperty<Style, string>({
|
||||
name: "fontStyle", cssName: "font-style", defaultValue: FontStyle.normal, valueChanged: (target, newValue) => {
|
||||
if (newValue !== FontStyle.normal && newValue !== FontStyle.italic) {
|
||||
throw new Error(`font-style should be 'normal' or 'italic'. value: ${newValue}`)
|
||||
}
|
||||
|
||||
let currentFont = target.fontInternal;
|
||||
if (currentFont.fontStyle !== newValue) {
|
||||
target.fontInternal = currentFont.withFontStyle(newValue);
|
||||
}
|
||||
}
|
||||
});
|
||||
fontStyleProperty.register(Style);
|
||||
|
||||
export let fontWeightProperty = new InheritedCssProperty<Style, string>({
|
||||
name: "fontWeight", cssName: "font-weight", defaultValue: FontWeight.normal, valueChanged: (target, newValue) => {
|
||||
if (!newValue) {
|
||||
console.trace();
|
||||
}
|
||||
|
||||
if (!(newValue === FontWeight.thin
|
||||
|| newValue === FontWeight.extraLight
|
||||
|| newValue === FontWeight.light
|
||||
|| newValue === FontWeight.normal || newValue === "400"
|
||||
|| newValue === FontWeight.medium
|
||||
|| newValue === FontWeight.semiBold
|
||||
|| newValue === FontWeight.bold || newValue === "700"
|
||||
|| newValue === FontWeight.extraBold
|
||||
|| newValue === FontWeight.black)) {
|
||||
throw new Error(`Invalid font-weight value: ${newValue}`);
|
||||
}
|
||||
|
||||
let currentFont = target.fontInternal;
|
||||
if (currentFont.fontWeight !== newValue) {
|
||||
target.fontInternal = currentFont.withFontWeight(newValue);
|
||||
}
|
||||
}
|
||||
});
|
||||
fontWeightProperty.register(Style);
|
||||
|
||||
function onFontChanged(style: Style, oldValue: Font, newValue: Font): void {
|
||||
// TODO: Do we need these here?
|
||||
style.fontFamily = newValue.fontFamily;
|
||||
style.fontStyle = newValue.fontStyle;
|
||||
style.fontWeight = newValue.fontWeight;
|
||||
style.fontSize = newValue.fontSize;
|
||||
}
|
||||
|
||||
export let fontProperty = new ShorthandProperty<Style>({
|
||||
name: "font", cssName: "font",
|
||||
getter: function (this: Style) {
|
||||
return `${this.fontStyle} ${this.fontWeight} ${this.fontSize} ${this.fontFamily}`;
|
||||
},
|
||||
converter: function (value: string) {
|
||||
return parseFont(value);
|
||||
}
|
||||
})
|
||||
fontProperty.register(Style);
|
||||
|
||||
function parseFont(font: string): [CssProperty<any, any>, any][] {
|
||||
let fontSize: number;
|
||||
let fontFamily: string;
|
||||
let fontStyle: "normal" | "italic" = "normal";
|
||||
let fontWeight = "normal";
|
||||
|
||||
let elements = font.split(/\s+/);
|
||||
let element: string;
|
||||
while (element = elements.shift()) {
|
||||
switch (element) {
|
||||
case "normal":
|
||||
break;
|
||||
|
||||
// TODO: add support for oblique font style.
|
||||
case "italic":
|
||||
// case "oblique":
|
||||
fontStyle = "italic";
|
||||
break;
|
||||
|
||||
case FontWeight.thin:
|
||||
case FontWeight.extraLight:
|
||||
case FontWeight.light:
|
||||
case FontWeight.normal:
|
||||
case "400":
|
||||
case FontWeight.medium:
|
||||
case FontWeight.semiBold:
|
||||
case FontWeight.bold:
|
||||
case "700":
|
||||
case FontWeight.extraBold:
|
||||
case FontWeight.black:
|
||||
fontWeight = element;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!fontSize) {
|
||||
let parts = element.split("/");
|
||||
// TODO: add support for px support.
|
||||
fontSize = parseFloat(parts[0]);
|
||||
// TODO: add support for lineHeight.
|
||||
// if (parts.length > 1) {
|
||||
// lineHeight = parts[1];
|
||||
// }
|
||||
break;
|
||||
}
|
||||
|
||||
fontFamily = element;
|
||||
// if (elements.length) {
|
||||
// fontFamily += " " + elements.join(" ");
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
[fontStyleProperty, fontStyle],
|
||||
[fontWeightProperty, fontWeight],
|
||||
[fontSizeProperty, fontSize],
|
||||
[fontFamilyProperty, fontFamily]
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
// register default shorthand callbacks.
|
||||
// styleProperty.registerShorthandCallback("font", onFontChanged);
|
||||
// styleProperty.registerShorthandCallback("margin", onMarginChanged);
|
||||
|
@ -122,8 +122,8 @@ textProperty.register(TextBaseCommon);
|
||||
export let formattedTextProperty = new Property<TextBaseCommon, FormattedString>({ name: "formattedText", affectsLayout: isIOS, valueChanged: onFormattedTextPropertyChanged });
|
||||
formattedTextProperty.register(TextBaseCommon);
|
||||
|
||||
export let textAlignmentProperty = new InheritedCssProperty<Style, string>({
|
||||
name: "textAlignment", cssName: "text-align", valueConverter: (value: string) => {
|
||||
export let textAlignmentProperty = new InheritedCssProperty<Style, "left" | "center" | "right">({
|
||||
name: "textAlignment", cssName: "text-align", valueConverter: (value) => {
|
||||
switch (value) {
|
||||
case "left":
|
||||
case "center":
|
||||
@ -131,27 +131,27 @@ export let textAlignmentProperty = new InheritedCssProperty<Style, string>({
|
||||
return value;
|
||||
|
||||
default:
|
||||
throw new Error("CSS text-align \"" + value + "\" is not supported.");
|
||||
throw new Error(`CSS text-align ${value} is not supported.`);
|
||||
}
|
||||
}
|
||||
});
|
||||
textAlignmentProperty.register(Style);
|
||||
|
||||
export let textDecorationProperty = new CssProperty<Style, string>({
|
||||
name: "textDecoration", cssName: "text-decoration", defaultValue: "none", valueConverter: (value: string) => {
|
||||
export let textDecorationProperty = new CssProperty<Style, "none" | "underline" | "line-through">({
|
||||
name: "textDecoration", cssName: "text-decoration", defaultValue: "none", valueConverter: (value) => {
|
||||
let values = (value + "").split(" ");
|
||||
|
||||
if (values.indexOf("none") !== -1 || values.indexOf("underline") !== -1 || values.indexOf("lineThrough") !== -1) {
|
||||
return value;
|
||||
} else {
|
||||
throw new Error("CSS text-decoration \"" + value + "\" is not supported.");
|
||||
throw new Error(`CSS text-decoration ${value} is not supported.`);
|
||||
}
|
||||
}
|
||||
});
|
||||
textDecorationProperty.register(Style);
|
||||
|
||||
export let textTransformProperty = new CssProperty<Style, string>({
|
||||
name: "textTransform", cssName: "text-transform", defaultValue: "none", valueConverter: (value: string) => {
|
||||
export let textTransformProperty = new CssProperty<Style, "none" | "capitalize" | "uppercase" | "lowercase">({
|
||||
name: "textTransform", cssName: "text-transform", defaultValue: "none", valueConverter: (value) => {
|
||||
switch (value) {
|
||||
case "none":
|
||||
case "uppercase":
|
||||
@ -160,7 +160,7 @@ export let textTransformProperty = new CssProperty<Style, string>({
|
||||
return value;
|
||||
|
||||
default:
|
||||
throw new Error("CSS text-transform \"" + value + "\" is not supported.");
|
||||
throw new Error(`CSS text-transform ${value} is not supported.`);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -173,7 +173,7 @@ export let whiteSpaceProperty = new CssProperty<Style, "normal" | "nowrap">({
|
||||
case "nowrap":
|
||||
return value;
|
||||
default:
|
||||
throw new Error("CSS white-space \"" + value + "\" is not supported.");
|
||||
throw new Error(`CSS white-space ${value} is not supported.`);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
14
tns-core-modules/ui/text-base/text-base.d.ts
vendored
14
tns-core-modules/ui/text-base/text-base.d.ts
vendored
@ -67,12 +67,12 @@
|
||||
//@endprivate
|
||||
}
|
||||
|
||||
export let textProperty: Property<TextBase, string>;
|
||||
export let formattedTextProperty: Property<TextBase, FormattedString>;
|
||||
export const textProperty: Property<TextBase, string>;
|
||||
export const formattedTextProperty: Property<TextBase, FormattedString>;
|
||||
|
||||
export let textAlignmentProperty: InheritedCssProperty<Style, string>;
|
||||
export let textDecorationProperty: CssProperty<Style, string>;
|
||||
export let textTransformProperty: CssProperty<Style, string>;
|
||||
export let whiteSpaceProperty: CssProperty<Style, string>;
|
||||
export let letterSpacingProperty: CssProperty<Style, number>;
|
||||
export const textAlignmentProperty: InheritedCssProperty<Style, "left" | "center" | "right">;
|
||||
export const textDecorationProperty: CssProperty<Style, "none" | "underline" | "line-through">;
|
||||
export const textTransformProperty: CssProperty<Style, "none" | "capitalize" | "uppercase" | "lowercase">;
|
||||
export const whiteSpaceProperty: CssProperty<Style, "normal" | "nowrap">;
|
||||
export const letterSpacingProperty: CssProperty<Style, number>;
|
||||
}
|
@ -1,10 +1,9 @@
|
||||
import { TextBaseCommon, textProperty, formattedTextProperty } from "./text-base-common";
|
||||
import { FormattedString } from "text/formatted-string";
|
||||
import {
|
||||
colorProperty, fontInternalProperty, textAlignmentProperty, textDecorationProperty,
|
||||
import {
|
||||
TextBaseCommon, textProperty, formattedTextProperty, textAlignmentProperty, textDecorationProperty,
|
||||
textTransformProperty, whiteSpaceProperty, letterSpacingProperty
|
||||
} from "ui/styling/style";
|
||||
import { TextAlignment, TextDecoration, TextTransform, WhiteSpace } from "ui/enums";
|
||||
} from "./text-base-common";
|
||||
import { FormattedString } from "text/formatted-string";
|
||||
import { colorProperty, fontInternalProperty } from "ui/core/view";
|
||||
import { toUIString, isNumber } from "utils/types";
|
||||
import { Font } from "ui/styling/font";
|
||||
import { Color } from "color";
|
||||
@ -15,18 +14,18 @@ function NSStringFromNSAttributedString(source: NSAttributedString | string): NS
|
||||
return NSString.stringWithString(source instanceof NSAttributedString && source.string || <string>source);
|
||||
}
|
||||
|
||||
function getTransformedText(text: string, transform: string): string {
|
||||
function getTransformedText(text: string, transform: "none" | "capitalize" | "uppercase" | "lowercase"): string {
|
||||
switch (transform) {
|
||||
case TextTransform.uppercase:
|
||||
case "uppercase":
|
||||
return NSStringFromNSAttributedString(text).uppercaseString;
|
||||
|
||||
case TextTransform.lowercase:
|
||||
case "lowercase":
|
||||
return NSStringFromNSAttributedString(text).lowercaseString;
|
||||
|
||||
case TextTransform.capitalize:
|
||||
case "capitalize":
|
||||
return NSStringFromNSAttributedString(text).capitalizedString;
|
||||
|
||||
case TextTransform.none:
|
||||
case "none":
|
||||
default:
|
||||
return text;
|
||||
}
|
||||
|
Reference in New Issue
Block a user