mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
up to segmented-bar.ios
This commit is contained in:
11
tns-core-modules/ui/border/border.d.ts
vendored
11
tns-core-modules/ui/border/border.d.ts
vendored
@@ -2,7 +2,6 @@
|
||||
* Contains the Border class, which represents a UI border component.
|
||||
*/
|
||||
declare module "ui/border" {
|
||||
import { Color } from "color";
|
||||
import { ContentView } from "ui/content-view";
|
||||
|
||||
/**
|
||||
@@ -13,15 +12,5 @@ declare module "ui/border" {
|
||||
* Gets or sets the corner radius of the border component.
|
||||
*/
|
||||
cornerRadius: number;
|
||||
|
||||
/**
|
||||
* Gets or sets the border width of the border component.
|
||||
*/
|
||||
borderWidth: string | number;
|
||||
|
||||
/**
|
||||
* Gets or sets the border color of the border component.
|
||||
*/
|
||||
borderColor: string | Color;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
import { ButtonBase, textProperty, formattedTextProperty } from "./button-common";
|
||||
import { FormattedString } from "text/formatted-string";
|
||||
import {
|
||||
ButtonBase, textProperty, formattedTextProperty, TouchGestureEventData, FormattedString, GestureTypes, TouchAction,
|
||||
PseudoClassHandler
|
||||
} from "./button-common";
|
||||
|
||||
export * from "./button-common";
|
||||
|
||||
@@ -17,32 +19,11 @@ class ClickListener implements android.view.View.OnClickListener {
|
||||
}
|
||||
}
|
||||
|
||||
@Interfaces([android.view.View.OnTouchListener])
|
||||
class TouchListener implements android.view.View.OnTouchListener {
|
||||
constructor(public owner: WeakRef<Button>) {
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
public onTouch(v: android.view.View, event: android.view.MotionEvent): boolean {
|
||||
let btn = this.owner.get();
|
||||
if (!btn) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (event.getAction() === 0) { // down
|
||||
btn._goToVisualState("highlighted");
|
||||
}
|
||||
else if (event.getAction() === 1) { // up
|
||||
btn._goToVisualState("normal");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export class Button extends ButtonBase {
|
||||
nativeView: android.widget.Button;
|
||||
private _isPressed: boolean = false;
|
||||
private _isPressed: boolean;
|
||||
private _transformationMethod;
|
||||
private _highlightedHandler: (args: TouchGestureEventData) => void;
|
||||
|
||||
get android(): android.widget.Button {
|
||||
return this.nativeView;
|
||||
@@ -52,7 +33,6 @@ export class Button extends ButtonBase {
|
||||
let weakRef = new WeakRef(this);
|
||||
this.nativeView = new android.widget.Button(this._context);
|
||||
this.nativeView.setOnClickListener(new ClickListener(weakRef));
|
||||
this.nativeView.setOnTouchListener(new TouchListener(weakRef));
|
||||
}
|
||||
|
||||
public _setFormattedTextPropertyToNative(value: FormattedString) {
|
||||
@@ -70,7 +50,6 @@ export class Button extends ButtonBase {
|
||||
|
||||
this.nativeView.setText(newText);
|
||||
}
|
||||
}
|
||||
|
||||
@PseudoClassHandler("normal", "highlighted", "pressed", "active")
|
||||
_updateHandler(subscribe: boolean) {
|
||||
@@ -91,4 +70,3 @@ export class Button extends ButtonBase {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
3
tns-core-modules/ui/button/button.d.ts
vendored
3
tns-core-modules/ui/button/button.d.ts
vendored
@@ -2,8 +2,7 @@
|
||||
* Contains the Button class, which represents a standard button widget.
|
||||
*/
|
||||
declare module "ui/button" {
|
||||
import { TextBase, Property, EventData } from "ui/text-base";
|
||||
import { FormattedString, FormattedStringView } from "text/formatted-string";
|
||||
import { TextBase, Property, EventData, FormattedString, FormattedStringView } from "ui/text-base";
|
||||
|
||||
/**
|
||||
* Represents a standard Button widget.
|
||||
|
||||
@@ -27,7 +27,7 @@ export interface PropertyOptions<T, U> {
|
||||
}
|
||||
|
||||
export interface CoerciblePropertyOptions<T, U> extends PropertyOptions<T, U> {
|
||||
coerceValue(T, U): U
|
||||
readonly coerceValue: (T, U) => U;
|
||||
}
|
||||
|
||||
export interface ShorthandPropertyOptions {
|
||||
@@ -95,6 +95,10 @@ export class Property<T extends ViewBase, U> implements PropertyDescriptor {
|
||||
this[key] = unboxedValue;
|
||||
}
|
||||
|
||||
if (this.nativeView) {
|
||||
this[native] = unboxedValue;
|
||||
}
|
||||
|
||||
if (valueChanged) {
|
||||
valueChanged(this, currentValue, unboxedValue);
|
||||
}
|
||||
@@ -108,10 +112,6 @@ export class Property<T extends ViewBase, U> implements PropertyDescriptor {
|
||||
});
|
||||
}
|
||||
|
||||
if (this.nativeView) {
|
||||
this[native] = unboxedValue;
|
||||
}
|
||||
|
||||
if (affectsLayout) {
|
||||
this.requestLayout();
|
||||
}
|
||||
@@ -201,6 +201,10 @@ export class CoercibleProperty<T extends ViewBase, U> implements PropertyDescrip
|
||||
this[key] = unboxedValue;
|
||||
}
|
||||
|
||||
if (this.nativeView) {
|
||||
this[native] = unboxedValue;
|
||||
}
|
||||
|
||||
if (valueChanged) {
|
||||
valueChanged(this, currentValue, unboxedValue);
|
||||
}
|
||||
@@ -214,10 +218,6 @@ export class CoercibleProperty<T extends ViewBase, U> implements PropertyDescrip
|
||||
});
|
||||
}
|
||||
|
||||
if (this.nativeView) {
|
||||
this[native] = unboxedValue;
|
||||
}
|
||||
|
||||
if (affectsLayout) {
|
||||
this.requestLayout();
|
||||
}
|
||||
@@ -378,6 +378,15 @@ export class CssProperty<T extends Style, U> {
|
||||
this[key] = value;
|
||||
}
|
||||
|
||||
let view = this.view;
|
||||
if (view.nativeView) {
|
||||
view[native] = value;
|
||||
if (dependentPropertyNativeKey) {
|
||||
// Call the native setter for dependent property.
|
||||
view[dependentPropertyNativeKey] = this[dependentPropertyKey];
|
||||
}
|
||||
}
|
||||
|
||||
if (valueChanged) {
|
||||
valueChanged(this, currentValue, value);
|
||||
}
|
||||
@@ -391,15 +400,6 @@ export class CssProperty<T extends Style, U> {
|
||||
});
|
||||
}
|
||||
|
||||
let view = this.view;
|
||||
if (view.nativeView) {
|
||||
view[native] = value;
|
||||
if (dependentPropertyNativeKey) {
|
||||
// Call the native setter for dependent property.
|
||||
view[dependentPropertyNativeKey] = this[dependentPropertyKey];
|
||||
}
|
||||
}
|
||||
|
||||
if (affectsLayout) {
|
||||
view.requestLayout();
|
||||
}
|
||||
@@ -435,6 +435,15 @@ export class CssProperty<T extends Style, U> {
|
||||
this[key] = value;
|
||||
}
|
||||
|
||||
let view = this.view;
|
||||
if (view.nativeView) {
|
||||
view[native] = value;
|
||||
if (dependentPropertyNativeKey) {
|
||||
// Call the native setter for dependent property.
|
||||
view[dependentPropertyNativeKey] = this[dependentPropertyKey];
|
||||
}
|
||||
}
|
||||
|
||||
if (valueChanged) {
|
||||
valueChanged(this, currentValue, value);
|
||||
}
|
||||
@@ -448,15 +457,6 @@ export class CssProperty<T extends Style, U> {
|
||||
});
|
||||
}
|
||||
|
||||
let view = this.view;
|
||||
if (view.nativeView) {
|
||||
view[native] = value;
|
||||
if (dependentPropertyNativeKey) {
|
||||
// Call the native setter for dependent property.
|
||||
view[dependentPropertyNativeKey] = this[dependentPropertyKey];
|
||||
}
|
||||
}
|
||||
|
||||
if (affectsLayout) {
|
||||
view.requestLayout();
|
||||
}
|
||||
@@ -568,6 +568,15 @@ export class InheritedCssProperty<T extends Style, U> extends CssProperty<T, U>
|
||||
this[key] = newValue;
|
||||
}
|
||||
|
||||
let nativeView = view.nativeView;
|
||||
if (nativeView) {
|
||||
view[native] = value;
|
||||
if (dependentPropertyNativeKey) {
|
||||
// Call the native setter for dependent property.
|
||||
view[dependentPropertyNativeKey] = this[dependentPropertyKey];
|
||||
}
|
||||
}
|
||||
|
||||
if (valueChanged) {
|
||||
valueChanged(this, currentValue, newValue);
|
||||
}
|
||||
@@ -581,15 +590,6 @@ export class InheritedCssProperty<T extends Style, U> extends CssProperty<T, U>
|
||||
});
|
||||
}
|
||||
|
||||
let nativeView = view.nativeView;
|
||||
if (nativeView) {
|
||||
view[native] = value;
|
||||
if (dependentPropertyNativeKey) {
|
||||
// Call the native setter for dependent property.
|
||||
view[dependentPropertyNativeKey] = this[dependentPropertyKey];
|
||||
}
|
||||
}
|
||||
|
||||
if (affectsLayout) {
|
||||
view.requestLayout();
|
||||
}
|
||||
@@ -752,7 +752,7 @@ function inheritableCssPropertiesOn(style: Object): Array<InheritedCssProperty<a
|
||||
}
|
||||
|
||||
export function applyNativeSetters(view: ViewBase): void {
|
||||
let symbols = Object.getOwnPropertySymbols(view);
|
||||
let symbols = (<any>Object).getOwnPropertySymbols(view);
|
||||
for (let symbol of symbols) {
|
||||
let property: Property<any, any> = symbolPropertyMap[symbol];
|
||||
if (!property) {
|
||||
@@ -767,7 +767,7 @@ export function applyNativeSetters(view: ViewBase): void {
|
||||
}
|
||||
|
||||
let style = view.style;
|
||||
symbols = Object.getOwnPropertySymbols(style);
|
||||
symbols = (<any>Object).getOwnPropertySymbols(style);
|
||||
for (let symbol of symbols) {
|
||||
let property: CssProperty<any, any> = cssSymbolPropertyMap[symbol];
|
||||
if (!property) {
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
import { ViewBase as ViewBaseDefinition } from "ui/core/view-base";
|
||||
import { Observable, EventData } from "data/observable";
|
||||
import { Property, InheritedProperty, CssProperty, Style } from "./properties";
|
||||
import { Property, InheritedProperty, CssProperty, Style, clearInheritedProperties, propagateInheritedProperties } from "./properties";
|
||||
import { Binding, BindingOptions, Bindable } from "ui/core/bindable";
|
||||
import { isIOS } from "platform";
|
||||
import { fromString as gestureFromString } from "ui/gestures";
|
||||
import { CssState, StyleScope, applyInlineSyle } from "ui/styling/style-scope";
|
||||
import { KeyframeAnimation } from "ui/animation/keyframe-animation";
|
||||
|
||||
export { Observable, EventData, Binding, BindingOptions, Bindable, isIOS, gestureFromString };
|
||||
import { enabled as traceEnabled, write as traceWrite, categories as traceCategories, notifyEvent as traceNotifyEvent } from "trace";
|
||||
|
||||
export { KeyframeAnimation, Observable, EventData, Binding, BindingOptions, Bindable, isIOS, gestureFromString, traceEnabled, traceWrite, traceCategories, traceNotifyEvent };
|
||||
export * from "./properties";
|
||||
|
||||
let defaultBindingSource = {};
|
||||
@@ -46,12 +50,19 @@ export function isEventOrGesture(name: string, view: ViewBaseDefinition): boolea
|
||||
export class ViewBase extends Observable implements ViewBaseDefinition {
|
||||
private _updatingJSPropertiesDict = {};
|
||||
private _style: Style;
|
||||
private _isLoaded: boolean;
|
||||
private _registeredAnimations: Array<KeyframeAnimation>;
|
||||
private _visualState: string;
|
||||
|
||||
public bindingContext: any;
|
||||
public nativeView: any;
|
||||
public parent: ViewBase;
|
||||
public isCollapsed;
|
||||
|
||||
public id: string;
|
||||
public className: string;
|
||||
|
||||
public _cssState: CssState;
|
||||
constructor() {
|
||||
super();
|
||||
this._style = new Style(this);
|
||||
@@ -69,6 +80,200 @@ export class ViewBase extends Observable implements ViewBaseDefinition {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
get isLoaded(): boolean {
|
||||
return this._isLoaded;
|
||||
}
|
||||
|
||||
get page(): ViewBaseDefinition {
|
||||
if (this.parent) {
|
||||
return this.parent.page;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected onLoaded() {
|
||||
this._isLoaded = true;
|
||||
this._loadEachChildView();
|
||||
this._applyStyleFromScope();
|
||||
this._emit("loaded");
|
||||
}
|
||||
|
||||
get _childrenCount(): number {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public _loadEachChildView() {
|
||||
if (this._childrenCount > 0) {
|
||||
this.eachChild((child) => {
|
||||
child.onLoaded();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
protected onUnloaded() {
|
||||
this._setCssState(null);
|
||||
this._unloadEachChildView();
|
||||
this._isLoaded = false;
|
||||
this._emit("unloaded");
|
||||
}
|
||||
|
||||
private _unloadEachChildView() {
|
||||
if (this._childrenCount > 0) {
|
||||
this.eachChild((child) => {
|
||||
if (child.isLoaded) {
|
||||
child.onUnloaded();
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private _applyStyleFromScope() {
|
||||
let rootPage = this.page;
|
||||
if (!rootPage || !rootPage.isLoaded) {
|
||||
return;
|
||||
}
|
||||
let scope: StyleScope = (<any>rootPage)._getStyleScope();
|
||||
scope.applySelectors(this);
|
||||
}
|
||||
|
||||
// TODO: Make sure the state is set to null and this is called on unloaded to clean up change listeners...
|
||||
_setCssState(next: CssState): void {
|
||||
const previous = this._cssState;
|
||||
this._cssState = next;
|
||||
|
||||
if (!this._invalidateCssHandler) {
|
||||
this._invalidateCssHandler = () => {
|
||||
if (this._invalidateCssHandlerSuspended) {
|
||||
return;
|
||||
}
|
||||
this.applyCssState();
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
this._invalidateCssHandlerSuspended = true;
|
||||
|
||||
if (next) {
|
||||
next.changeMap.forEach((changes, view) => {
|
||||
if (changes.attributes) {
|
||||
changes.attributes.forEach(attribute => {
|
||||
view.addEventListener(attribute + "Change", this._invalidateCssHandler)
|
||||
});
|
||||
}
|
||||
if (changes.pseudoClasses) {
|
||||
changes.pseudoClasses.forEach(pseudoClass => {
|
||||
let eventName = ":" + pseudoClass;
|
||||
view.addEventListener(":" + pseudoClass, this._invalidateCssHandler);
|
||||
if (view[eventName]) {
|
||||
view[eventName](+1);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (previous) {
|
||||
previous.changeMap.forEach((changes, view) => {
|
||||
if (changes.attributes) {
|
||||
changes.attributes.forEach(attribute => {
|
||||
view.removeEventListener("onPropertyChanged:" + attribute, this._invalidateCssHandler)
|
||||
});
|
||||
}
|
||||
if (changes.pseudoClasses) {
|
||||
changes.pseudoClasses.forEach(pseudoClass => {
|
||||
let eventName = ":" + pseudoClass;
|
||||
view.removeEventListener(eventName, this._invalidateCssHandler)
|
||||
if (view[eventName]) {
|
||||
view[eventName](-1);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
} finally {
|
||||
this._invalidateCssHandlerSuspended = false;
|
||||
}
|
||||
|
||||
this.applyCssState();
|
||||
}
|
||||
|
||||
private notifyPseudoClassChanged(pseudoClass: string): void {
|
||||
this.notify({ eventName: ":" + pseudoClass, object: this });
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify that some attributes or pseudo classes that may affect the current CssState had changed.
|
||||
*/
|
||||
private _invalidateCssHandler;
|
||||
private _invalidateCssHandlerSuspended: boolean;
|
||||
|
||||
private applyCssState(): void {
|
||||
if (!this._cssState) {
|
||||
return;
|
||||
}
|
||||
|
||||
// this.style._beginUpdate();
|
||||
this._cssState.apply();
|
||||
// this.style._endUpdate();
|
||||
}
|
||||
|
||||
private pseudoClassAliases = {
|
||||
'highlighted': [
|
||||
'active',
|
||||
'pressed'
|
||||
]
|
||||
};
|
||||
|
||||
public cssClasses: Set<string> = new Set();
|
||||
public cssPseudoClasses: Set<string> = new Set();
|
||||
|
||||
private getAllAliasedStates(name: string): Array<string> {
|
||||
let allStates = [];
|
||||
allStates.push(name);
|
||||
if (name in this.pseudoClassAliases) {
|
||||
for (let i = 0; i < this.pseudoClassAliases[name].length; i++) {
|
||||
allStates.push(this.pseudoClassAliases[name][i]);
|
||||
}
|
||||
}
|
||||
return allStates;
|
||||
}
|
||||
|
||||
public addPseudoClass(name: string): void {
|
||||
let allStates = this.getAllAliasedStates(name);
|
||||
for (let i = 0; i < allStates.length; i++) {
|
||||
if (!this.cssPseudoClasses.has(allStates[i])) {
|
||||
this.cssPseudoClasses.add(allStates[i]);
|
||||
this.notifyPseudoClassChanged(allStates[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public deletePseudoClass(name: string): void {
|
||||
let allStates = this.getAllAliasedStates(name);
|
||||
for (let i = 0; i < allStates.length; i++) {
|
||||
if (this.cssPseudoClasses.has(allStates[i])) {
|
||||
this.cssPseudoClasses.delete(allStates[i]);
|
||||
this.notifyPseudoClassChanged(allStates[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private _applyInlineStyle(inlineStyle) {
|
||||
if (typeof inlineStyle === "string") {
|
||||
try {
|
||||
// this.style._beginUpdate();
|
||||
applyInlineSyle(this, inlineStyle);
|
||||
} finally {
|
||||
// this.style._endUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bindings = new Map<string, Binding>();
|
||||
public bind(options: BindingOptions, source: Object = defaultBindingSource): void {
|
||||
let binding: Binding = this.bindings.get(options.targetProperty);
|
||||
@@ -126,6 +331,125 @@ export class ViewBase extends Observable implements ViewBaseDefinition {
|
||||
public eachChild(callback: (child: ViewBase) => boolean) {
|
||||
//
|
||||
}
|
||||
|
||||
public _addView(view: ViewBase, atIndex?: number) {
|
||||
if (traceEnabled) {
|
||||
traceWrite(`${this}._addView(${view}, ${atIndex})`, traceCategories.ViewHierarchy);
|
||||
}
|
||||
|
||||
if (!view) {
|
||||
throw new Error("Expecting a valid View instance.");
|
||||
}
|
||||
if (!(view instanceof ViewBase)) {
|
||||
throw new Error(view + " is not a valid View instance.");
|
||||
}
|
||||
if (view.parent) {
|
||||
throw new Error("View already has a parent. View: " + view + " Parent: " + view.parent);
|
||||
}
|
||||
|
||||
view.parent = this;
|
||||
this._addViewCore(view, atIndex);
|
||||
view._parentChanged(null);
|
||||
}
|
||||
|
||||
protected _addViewCore(view: ViewBase, atIndex?: number) {
|
||||
// TODO: Discuss this.
|
||||
if (this._isLoaded) {
|
||||
view.onLoaded();
|
||||
}
|
||||
|
||||
propagateInheritedProperties(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Core logic for removing a child view from this instance. Used by the framework to handle lifecycle events more centralized. Do not outside the UI Stack implementation.
|
||||
*/
|
||||
public _removeView(view: ViewBase) {
|
||||
if (traceEnabled) {
|
||||
traceWrite(`${this}._removeView(${view})`, traceCategories.ViewHierarchy);
|
||||
}
|
||||
if (view.parent !== this) {
|
||||
throw new Error("View not added to this instance. View: " + view + " CurrentParent: " + view.parent + " ExpectedParent: " + this);
|
||||
}
|
||||
|
||||
this._removeViewCore(view);
|
||||
view.parent = undefined;
|
||||
view._parentChanged(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method is intended to be overridden by inheritors and used as "protected"
|
||||
*/
|
||||
public _removeViewCore(view: ViewBase) {
|
||||
// TODO: Discuss this.
|
||||
if (view.isLoaded) {
|
||||
view.onUnloaded();
|
||||
}
|
||||
|
||||
// view.unsetInheritedProperties();
|
||||
}
|
||||
|
||||
public _goToVisualState(state: string) {
|
||||
if (traceEnabled) {
|
||||
traceWrite(this + " going to state: " + state, traceCategories.Style);
|
||||
}
|
||||
if (state === this._visualState) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.deletePseudoClass(this._visualState);
|
||||
this._visualState = state;
|
||||
this.addPseudoClass(state);
|
||||
}
|
||||
|
||||
public _applyXmlAttribute(attribute, value): boolean {
|
||||
if (attribute === "style") {
|
||||
this._applyInlineStyle(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public setInlineStyle(style: string): void {
|
||||
if (typeof style !== "string") {
|
||||
throw new Error("Parameter should be valid CSS string!");
|
||||
}
|
||||
|
||||
this._applyInlineStyle(style);
|
||||
}
|
||||
|
||||
public _parentChanged(oldParent: ViewBase): void {
|
||||
//Overridden
|
||||
if (oldParent) {
|
||||
// Move these method in property class.
|
||||
clearInheritedProperties(this);
|
||||
}
|
||||
}
|
||||
|
||||
public _registerAnimation(animation: KeyframeAnimation) {
|
||||
if (this._registeredAnimations === undefined) {
|
||||
this._registeredAnimations = new Array<KeyframeAnimation>();
|
||||
}
|
||||
this._registeredAnimations.push(animation);
|
||||
}
|
||||
|
||||
public _unregisterAnimation(animation: KeyframeAnimation) {
|
||||
if (this._registeredAnimations) {
|
||||
let index = this._registeredAnimations.indexOf(animation);
|
||||
if (index >= 0) {
|
||||
this._registeredAnimations.splice(index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public _cancelAllAnimations() {
|
||||
if (this._registeredAnimations) {
|
||||
for (let animation of this._registeredAnimations) {
|
||||
animation.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const visibilityProperty = new CssProperty<Style, "visible" | "hidden" | "collapse" | "collapsed">({
|
||||
@@ -139,5 +463,30 @@ export const visibilityProperty = new CssProperty<Style, "visible" | "hidden" |
|
||||
});
|
||||
visibilityProperty.register(Style);
|
||||
|
||||
export let bindingContextProperty = new InheritedProperty<ViewBase, any>({ name: "bindingContext" });
|
||||
export const bindingContextProperty = new InheritedProperty<ViewBase, any>({ name: "bindingContext" });
|
||||
bindingContextProperty.register(ViewBase);
|
||||
|
||||
|
||||
function onCssClassPropertyChanged(view: ViewBase, oldValue: string, newValue: string) {
|
||||
let classes = view.cssClasses;
|
||||
classes.clear();
|
||||
if (typeof newValue === "string") {
|
||||
newValue.split(" ").forEach(c => classes.add(c));
|
||||
}
|
||||
}
|
||||
|
||||
export const classNameProperty = new Property<ViewBase, string>({ name: "className", valueChanged: onCssClassPropertyChanged });
|
||||
classNameProperty.register(ViewBase);
|
||||
|
||||
function resetStyles(view: ViewBase): void {
|
||||
// view.style._resetCssValues();
|
||||
// view._applyStyleFromScope();
|
||||
view.eachChild((child) => {
|
||||
// TODO.. Check old implementation....
|
||||
resetStyles(child);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
export const idProperty = new Property<ViewBase, string>({ name: "id", valueChanged: (view, oldValue, newValue) => resetStyles(view) });
|
||||
idProperty.register(ViewBase);
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
import { View as ViewDefinition, Point, Size } from "ui/core/view";
|
||||
import { CssState, StyleScope, applyInlineSyle } from "ui/styling/style-scope";
|
||||
import { Color } from "color";
|
||||
import { Animation, AnimationPromise } from "ui/animation";
|
||||
import { KeyframeAnimation } from "ui/animation/keyframe-animation";
|
||||
import { Source } from "utils/debug";
|
||||
import { Background } from "ui/styling/background";
|
||||
import {
|
||||
ViewBase, getEventOrGestureName, Observable, EventData, Style, propagateInheritedProperties, clearInheritedProperties,
|
||||
ViewBase, getEventOrGestureName, Observable, EventData, Style,
|
||||
Property, InheritedProperty, CssProperty, ShorthandProperty, InheritedCssProperty,
|
||||
gestureFromString, isIOS
|
||||
gestureFromString, isIOS, traceEnabled, traceWrite, traceCategories, traceNotifyEvent
|
||||
} from "./view-base";
|
||||
import { observe as gestureObserve, GesturesObserver, GestureTypes, GestureEventData } from "ui/gestures";
|
||||
import { Font, parseFont } from "ui/styling/font";
|
||||
@@ -16,15 +14,14 @@ import { fontSizeConverter } from "../styling/converters";
|
||||
|
||||
// TODO: Remove this and start using string as source (for android).
|
||||
import { fromFileOrResource, fromBase64, fromUrl } from "image-source";
|
||||
|
||||
import { enabled as traceEnabled, write as traceWrite, categories as traceCategories, notifyEvent as traceNotifyEvent } from "trace";
|
||||
import { isDataURI, isFileOrResourcePath } from "utils/utils";
|
||||
|
||||
export * from "./view-base";
|
||||
|
||||
export {
|
||||
Color, GestureTypes, GesturesObserver, GestureEventData, Animation, AnimationPromise, KeyframeAnimation,
|
||||
Background, Font, traceEnabled, traceWrite, traceCategories, traceNotifyEvent
|
||||
GestureTypes, GesturesObserver, GestureEventData,
|
||||
Animation, AnimationPromise,
|
||||
Background, Font, Color
|
||||
}
|
||||
|
||||
// registerSpecialProperty("class", (instance: ViewDefinition, propertyValue: string) => {
|
||||
@@ -192,22 +189,17 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
|
||||
|
||||
private _parent: ViewCommon;
|
||||
|
||||
private _visualState: string;
|
||||
private _isLoaded: boolean;
|
||||
|
||||
private _isLayoutValid: boolean;
|
||||
private _cssType: string;
|
||||
|
||||
private _updatingInheritedProperties: boolean;
|
||||
private _registeredAnimations: Array<KeyframeAnimation>;
|
||||
|
||||
|
||||
public _domId: number;
|
||||
public _isAddedToNativeVisualTree: boolean;
|
||||
public _gestureObservers = {};
|
||||
|
||||
public cssClasses: Set<string> = new Set();
|
||||
public cssPseudoClasses: Set<string> = new Set();
|
||||
|
||||
public _cssState: CssState;
|
||||
public parent: ViewCommon;
|
||||
|
||||
constructor() {
|
||||
@@ -560,22 +552,12 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
|
||||
|
||||
//END Style property shortcuts
|
||||
|
||||
|
||||
get page(): ViewDefinition {
|
||||
if (this.parent) {
|
||||
return this.parent.page;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public id: string;
|
||||
public automationText: string;
|
||||
public originX: number;
|
||||
public originY: number;
|
||||
public isEnabled: boolean;
|
||||
public isUserInteractionEnabled: boolean;
|
||||
public className: string;
|
||||
|
||||
|
||||
get isLayoutValid(): boolean {
|
||||
return this._isLayoutValid;
|
||||
@@ -592,49 +574,6 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
|
||||
return true;
|
||||
}
|
||||
|
||||
get isLoaded(): boolean {
|
||||
return this._isLoaded;
|
||||
}
|
||||
|
||||
public onLoaded() {
|
||||
this._isLoaded = true;
|
||||
this._loadEachChildView();
|
||||
this._applyStyleFromScope();
|
||||
this._emit("loaded");
|
||||
}
|
||||
|
||||
public _loadEachChildView() {
|
||||
if (this._childrenCount > 0) {
|
||||
// iterate all children and call onLoaded on them first
|
||||
let eachChild = function (child: ViewCommon): boolean {
|
||||
child.onLoaded();
|
||||
return true;
|
||||
}
|
||||
this._eachChildView(eachChild);
|
||||
}
|
||||
}
|
||||
|
||||
public onUnloaded() {
|
||||
this._setCssState(null);
|
||||
|
||||
this._unloadEachChildView();
|
||||
|
||||
this._isLoaded = false;
|
||||
this._emit("unloaded");
|
||||
}
|
||||
|
||||
public _unloadEachChildView() {
|
||||
if (this._childrenCount > 0) {
|
||||
this._eachChildView((child: ViewCommon) => {
|
||||
if (child.isLoaded) {
|
||||
child.onUnloaded();
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// public _onPropertyChanged(property: Property, oldValue: any, newValue: any) {
|
||||
// super._onPropertyChanged(property, oldValue, newValue);
|
||||
|
||||
@@ -721,44 +660,6 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
|
||||
public abstract onLayout(left: number, top: number, right: number, bottom: number): void;
|
||||
public abstract layoutNativeView(left: number, top: number, right: number, bottom: number): void;
|
||||
|
||||
private pseudoClassAliases = {
|
||||
'highlighted': [
|
||||
'active',
|
||||
'pressed'
|
||||
]
|
||||
};
|
||||
|
||||
private getAllAliasedStates(name: string): Array<string> {
|
||||
let allStates = [];
|
||||
allStates.push(name);
|
||||
if (name in this.pseudoClassAliases) {
|
||||
for (let i = 0; i < this.pseudoClassAliases[name].length; i++) {
|
||||
allStates.push(this.pseudoClassAliases[name][i]);
|
||||
}
|
||||
}
|
||||
return allStates;
|
||||
}
|
||||
|
||||
public addPseudoClass(name: string): void {
|
||||
let allStates = this.getAllAliasedStates(name);
|
||||
for (let i = 0; i < allStates.length; i++) {
|
||||
if (!this.cssPseudoClasses.has(allStates[i])) {
|
||||
this.cssPseudoClasses.add(allStates[i]);
|
||||
this.notifyPseudoClassChanged(allStates[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public deletePseudoClass(name: string): void {
|
||||
let allStates = this.getAllAliasedStates(name);
|
||||
for (let i = 0; i < allStates.length; i++) {
|
||||
if (this.cssPseudoClasses.has(allStates[i])) {
|
||||
this.cssPseudoClasses.delete(allStates[i]);
|
||||
this.notifyPseudoClassChanged(allStates[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static resolveSizeAndState(size: number, specSize: number, specMode: number, childMeasuredState: number): number {
|
||||
let result = size;
|
||||
switch (specMode) {
|
||||
@@ -975,26 +876,6 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
|
||||
return { boundsChanged, sizeChanged };
|
||||
}
|
||||
|
||||
private _applyStyleFromScope() {
|
||||
let rootPage = this.page;
|
||||
if (!rootPage || !rootPage.isLoaded) {
|
||||
return;
|
||||
}
|
||||
let scope: StyleScope = (<any>rootPage)._getStyleScope();
|
||||
scope.applySelectors(this);
|
||||
}
|
||||
|
||||
private _applyInlineStyle(inlineStyle) {
|
||||
if (typeof inlineStyle === "string") {
|
||||
try {
|
||||
// this.style._beginUpdate();
|
||||
applyInlineSyle(this, inlineStyle);
|
||||
} finally {
|
||||
// this.style._endUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: We need to implement some kind of build step that includes these members only when building for Android
|
||||
//@android
|
||||
public _context: android.content.Context;
|
||||
@@ -1019,9 +900,7 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
|
||||
// TODO: We need to implement some kind of build step that includes these members only when building for iOS
|
||||
|
||||
//@endios
|
||||
get _childrenCount(): number {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public _eachChildView(callback: (view: ViewCommon) => boolean) {
|
||||
//
|
||||
@@ -1047,113 +926,39 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
|
||||
// IOS specific
|
||||
}
|
||||
|
||||
/**
|
||||
* Core logic for adding a child view to this instance. Used by the framework to handle lifecycle events more centralized. Do not outside the UI Stack implementation.
|
||||
* // TODO: Think whether we need the base Layout routine.
|
||||
*/
|
||||
public _addView(view: ViewDefinition, atIndex?: number) {
|
||||
if (traceEnabled) {
|
||||
traceWrite(`${this}._addView(${view}, ${atIndex})`, traceCategories.ViewHierarchy);
|
||||
}
|
||||
|
||||
if (!view) {
|
||||
throw new Error("Expecting a valid View instance.");
|
||||
}
|
||||
if (!(view instanceof ViewBase)) {
|
||||
throw new Error(view + " is not a valid View instance.");
|
||||
}
|
||||
if (view.parent) {
|
||||
throw new Error("View already has a parent. View: " + view + " Parent: " + view.parent);
|
||||
}
|
||||
|
||||
view.parent = this;
|
||||
this._addViewCore(view, atIndex);
|
||||
view._parentChanged(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method is intended to be overridden by inheritors and used as "protected"
|
||||
*/
|
||||
public _addViewCore(view: ViewDefinition, atIndex?: number) {
|
||||
this._propagateInheritableProperties(view);
|
||||
|
||||
public _addViewCore(view: ViewCommon, atIndex?: number) {
|
||||
if (!view._isAddedToNativeVisualTree) {
|
||||
let nativeIndex = this._childIndexToNativeChildIndex(atIndex);
|
||||
view._isAddedToNativeVisualTree = this._addViewToNativeVisualTree(view, nativeIndex);
|
||||
}
|
||||
|
||||
// TODO: Discuss this.
|
||||
if (this._isLoaded) {
|
||||
view.onLoaded();
|
||||
}
|
||||
}
|
||||
|
||||
public _propagateInheritableProperties(view: ViewDefinition) {
|
||||
propagateInheritedProperties(this);
|
||||
// view._inheritProperties(this);
|
||||
// view.style._inheritStyleProperties(this);
|
||||
}
|
||||
|
||||
// public _inheritProperties(parentView: ViewDefinition) {
|
||||
// parentView._eachSetProperty((property) => {
|
||||
// if (!(property instanceof styling.Property) && property.inheritable) {
|
||||
// let baseValue = parentView._getValue(property);
|
||||
// this._setValue(property, baseValue, ValueSource.Inherited);
|
||||
// }
|
||||
// return true;
|
||||
// });
|
||||
// }
|
||||
|
||||
/**
|
||||
* Core logic for removing a child view from this instance. Used by the framework to handle lifecycle events more centralized. Do not outside the UI Stack implementation.
|
||||
*/
|
||||
public _removeView(view: ViewDefinition) {
|
||||
if (traceEnabled) {
|
||||
traceWrite(`${this}._removeView(${view})`, traceCategories.ViewHierarchy);
|
||||
}
|
||||
if (view.parent !== this) {
|
||||
throw new Error("View not added to this instance. View: " + view + " CurrentParent: " + view.parent + " ExpectedParent: " + this);
|
||||
}
|
||||
|
||||
this._removeViewCore(view);
|
||||
view.parent = undefined;
|
||||
view._parentChanged(this);
|
||||
super._addViewCore(view, atIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method is intended to be overridden by inheritors and used as "protected"
|
||||
*/
|
||||
public _removeViewCore(view: ViewDefinition) {
|
||||
public _removeViewCore(view: ViewCommon) {
|
||||
// TODO: Change type from ViewCommon to ViewBase. Probably this
|
||||
// method will need to go to ViewBase class.
|
||||
// Remove the view from the native visual scene first
|
||||
this._removeViewFromNativeVisualTree(view);
|
||||
|
||||
// TODO: Discuss this.
|
||||
if (view.isLoaded) {
|
||||
view.onUnloaded();
|
||||
super._removeViewCore(view);
|
||||
}
|
||||
|
||||
// view.unsetInheritedProperties();
|
||||
}
|
||||
|
||||
public unsetInheritedProperties(): void {
|
||||
// this._setValue(ProxyObject.bindingContextProperty, undefined, ValueSource.Inherited);
|
||||
// this._eachSetProperty((property) => {
|
||||
// if (!(property instanceof styling.Property) && property.inheritable) {
|
||||
// this._resetValue(property, ValueSource.Inherited);
|
||||
// public unsetInheritedProperties(): void {
|
||||
// // this._setValue(ProxyObject.bindingContextProperty, undefined, ValueSource.Inherited);
|
||||
// // this._eachSetProperty((property) => {
|
||||
// // if (!(property instanceof styling.Property) && property.inheritable) {
|
||||
// // this._resetValue(property, ValueSource.Inherited);
|
||||
// // }
|
||||
// // return true;
|
||||
// // });
|
||||
// }
|
||||
// return true;
|
||||
// });
|
||||
}
|
||||
|
||||
public _parentChanged(oldParent: ViewDefinition): void {
|
||||
//Overridden
|
||||
if (oldParent) {
|
||||
// Move these method in property class.
|
||||
clearInheritedProperties(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method is intended to be overridden by inheritors and used as "protected".
|
||||
@@ -1173,36 +978,6 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
|
||||
view._isAddedToNativeVisualTree = false;
|
||||
}
|
||||
|
||||
public _goToVisualState(state: string) {
|
||||
if (traceEnabled) {
|
||||
traceWrite(this + " going to state: " + state, traceCategories.Style);
|
||||
}
|
||||
if (state === this._visualState) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.deletePseudoClass(this._visualState);
|
||||
this._visualState = state;
|
||||
this.addPseudoClass(state);
|
||||
}
|
||||
|
||||
public _applyXmlAttribute(attribute, value): boolean {
|
||||
if (attribute === "style") {
|
||||
this._applyInlineStyle(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public setInlineStyle(style: string): void {
|
||||
if (typeof style !== "string") {
|
||||
throw new Error("Parameter should be valid CSS string!");
|
||||
}
|
||||
|
||||
this._applyInlineStyle(style);
|
||||
}
|
||||
|
||||
public _updateLayout() {
|
||||
// needed for iOS.
|
||||
}
|
||||
@@ -1253,30 +1028,6 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
|
||||
return new Animation([animation]);
|
||||
}
|
||||
|
||||
public _registerAnimation(animation: KeyframeAnimation) {
|
||||
if (this._registeredAnimations === undefined) {
|
||||
this._registeredAnimations = new Array<KeyframeAnimation>();
|
||||
}
|
||||
this._registeredAnimations.push(animation);
|
||||
}
|
||||
|
||||
public _unregisterAnimation(animation: KeyframeAnimation) {
|
||||
if (this._registeredAnimations) {
|
||||
let index = this._registeredAnimations.indexOf(animation);
|
||||
if (index >= 0) {
|
||||
this._registeredAnimations.splice(index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public _unregisterAllAnimations() {
|
||||
if (this._registeredAnimations) {
|
||||
for (let animation of this._registeredAnimations) {
|
||||
animation.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public toString(): string {
|
||||
let str = this.typeName;
|
||||
if (this.id) {
|
||||
@@ -1304,88 +1055,6 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
|
||||
// // Check for a valid _nativeView instance
|
||||
// return !!this._nativeView;
|
||||
// }
|
||||
|
||||
private notifyPseudoClassChanged(pseudoClass: string): void {
|
||||
this.notify({ eventName: ":" + pseudoClass, object: this });
|
||||
}
|
||||
|
||||
// TODO: Make sure the state is set to null and this is called on unloaded to clean up change listeners...
|
||||
_setCssState(next: CssState): void {
|
||||
const previous = this._cssState;
|
||||
this._cssState = next;
|
||||
|
||||
if (!this._invalidateCssHandler) {
|
||||
this._invalidateCssHandler = () => {
|
||||
if (this._invalidateCssHandlerSuspended) {
|
||||
return;
|
||||
}
|
||||
this.applyCssState();
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
this._invalidateCssHandlerSuspended = true;
|
||||
|
||||
if (next) {
|
||||
next.changeMap.forEach((changes, view) => {
|
||||
if (changes.attributes) {
|
||||
changes.attributes.forEach(attribute => {
|
||||
view.addEventListener(attribute + "Change", this._invalidateCssHandler)
|
||||
});
|
||||
}
|
||||
if (changes.pseudoClasses) {
|
||||
changes.pseudoClasses.forEach(pseudoClass => {
|
||||
let eventName = ":" + pseudoClass;
|
||||
view.addEventListener(":" + pseudoClass, this._invalidateCssHandler);
|
||||
if (view[eventName]) {
|
||||
view[eventName](+1);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (previous) {
|
||||
previous.changeMap.forEach((changes, view) => {
|
||||
if (changes.attributes) {
|
||||
changes.attributes.forEach(attribute => {
|
||||
view.removeEventListener("onPropertyChanged:" + attribute, this._invalidateCssHandler)
|
||||
});
|
||||
}
|
||||
if (changes.pseudoClasses) {
|
||||
changes.pseudoClasses.forEach(pseudoClass => {
|
||||
let eventName = ":" + pseudoClass;
|
||||
view.removeEventListener(eventName, this._invalidateCssHandler)
|
||||
if (view[eventName]) {
|
||||
view[eventName](-1);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
} finally {
|
||||
this._invalidateCssHandlerSuspended = false;
|
||||
}
|
||||
|
||||
this.applyCssState();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify that some attributes or pseudo classes that may affect the current CssState had changed.
|
||||
*/
|
||||
private _invalidateCssHandler;
|
||||
private _invalidateCssHandlerSuspended: boolean;
|
||||
|
||||
private applyCssState(): void {
|
||||
if (!this._cssState) {
|
||||
return;
|
||||
}
|
||||
|
||||
// this.style._beginUpdate();
|
||||
this._cssState.apply();
|
||||
// this.style._endUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
function getLengthEffectiveValue(density: number, param: Length): number {
|
||||
@@ -1512,39 +1181,6 @@ export namespace Length {
|
||||
}
|
||||
}
|
||||
|
||||
function onCssClassPropertyChanged(view: ViewCommon, oldValue: string, newValue: string) {
|
||||
let classes = view.cssClasses;
|
||||
classes.clear();
|
||||
if (typeof newValue === "string") {
|
||||
newValue.split(" ").forEach(c => classes.add(c));
|
||||
}
|
||||
}
|
||||
|
||||
export const classNameProperty = new Property<ViewCommon, string>({ name: "className", valueChanged: onCssClassPropertyChanged });
|
||||
classNameProperty.register(ViewCommon);
|
||||
|
||||
function resetStyles(view: ViewCommon): void {
|
||||
// view.style._resetCssValues();
|
||||
// view._applyStyleFromScope();
|
||||
view._eachChildView((child) => {
|
||||
// TODO.. Check old implementation....
|
||||
resetStyles(child);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
export const idProperty = new Property<ViewCommon, string>({ name: "id", valueChanged: (view, oldValue, newValue) => resetStyles(view) });
|
||||
idProperty.register(ViewCommon);
|
||||
|
||||
export const automationTextProperty = new Property<ViewCommon, string>({ name: "automationText" });
|
||||
automationTextProperty.register(ViewCommon);
|
||||
|
||||
export const originXProperty = new Property<ViewCommon, number>({ name: "originX", defaultValue: 0.5, valueConverter: (v) => parseFloat(v) });
|
||||
originXProperty.register(ViewCommon);
|
||||
|
||||
export const originYProperty = new Property<ViewCommon, number>({ name: "originY", defaultValue: 0.5, valueConverter: (v) => parseFloat(v) });
|
||||
originYProperty.register(ViewCommon);
|
||||
|
||||
export function booleanConverter(v: string): boolean {
|
||||
let lowercase = (v + '').toLowerCase();
|
||||
if (lowercase === "true") {
|
||||
@@ -1556,6 +1192,15 @@ export function booleanConverter(v: string): boolean {
|
||||
throw new Error(`Invalid boolean: ${v}`);
|
||||
}
|
||||
|
||||
export const automationTextProperty = new Property<ViewCommon, string>({ name: "automationText" });
|
||||
automationTextProperty.register(ViewCommon);
|
||||
|
||||
export const originXProperty = new Property<ViewCommon, number>({ name: "originX", defaultValue: 0.5, valueConverter: (v) => parseFloat(v) });
|
||||
originXProperty.register(ViewCommon);
|
||||
|
||||
export const originYProperty = new Property<ViewCommon, number>({ name: "originY", defaultValue: 0.5, valueConverter: (v) => parseFloat(v) });
|
||||
originYProperty.register(ViewCommon);
|
||||
|
||||
export const isEnabledProperty = new Property<ViewCommon, boolean>({ name: "isEnabled", defaultValue: true, valueConverter: booleanConverter });
|
||||
isEnabledProperty.register(ViewCommon);
|
||||
|
||||
|
||||
@@ -76,15 +76,18 @@ export class View extends ViewCommon {
|
||||
}
|
||||
}
|
||||
|
||||
public onLoaded() {
|
||||
protected onLoaded() {
|
||||
super.onLoaded();
|
||||
this.setOnTouchListener();
|
||||
}
|
||||
|
||||
public onUnloaded() {
|
||||
if (this.touchListenerIsSet) {
|
||||
this._nativeView.setOnTouchListener(null);
|
||||
this.touchListenerIsSet = false;
|
||||
this._unregisterAllAnimations();
|
||||
}
|
||||
|
||||
this._cancelAllAnimations();
|
||||
super.onUnloaded();
|
||||
}
|
||||
|
||||
@@ -99,12 +102,12 @@ export class View extends ViewCommon {
|
||||
this._nativeView.setClickable(true);
|
||||
}
|
||||
|
||||
let touchListener = this.touchListener || new TouchListener(new WeakRef(this));
|
||||
this._nativeView.setOnTouchListener(touchListener);
|
||||
this.touchListener = this.touchListener || new TouchListener(new WeakRef(this));
|
||||
this._nativeView.setOnTouchListener(this.touchListener);
|
||||
}
|
||||
}
|
||||
|
||||
public _addViewCore(view: View, atIndex?: number) {
|
||||
public _addViewCore(view: ViewCommon, atIndex?: number) {
|
||||
if (this._context) {
|
||||
view._onAttached(this._context);
|
||||
}
|
||||
@@ -127,6 +130,7 @@ export class View extends ViewCommon {
|
||||
if (traceEnabled) {
|
||||
traceWrite(`${this}._onAttached(context)`, traceCategories.VisualTreeEvents);
|
||||
}
|
||||
|
||||
if (this._context === context) {
|
||||
return;
|
||||
}
|
||||
@@ -158,6 +162,9 @@ export class View extends ViewCommon {
|
||||
return true;
|
||||
}
|
||||
this._eachChildView(eachChild);
|
||||
} else if (this._nativeView) {
|
||||
// copy all the locally cached values to the native android widget
|
||||
applyNativeSetters(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
54
tns-core-modules/ui/core/view.d.ts
vendored
54
tns-core-modules/ui/core/view.d.ts
vendored
@@ -1,18 +1,17 @@
|
||||
declare module "ui/core/view" {
|
||||
import { GestureTypes, GesturesObserver, GestureEventData } from "ui/gestures";
|
||||
import { GestureTypes, GesturesObserver, GestureEventData, TouchGestureEventData, TouchAction } from "ui/gestures";
|
||||
import { Animation, AnimationDefinition, AnimationPromise } from "ui/animation";
|
||||
import { KeyframeAnimation } from "ui/animation/keyframe-animation";
|
||||
import {
|
||||
ViewBase, Property, CssProperty, InheritedCssProperty, ShorthandProperty, Style,
|
||||
BindingOptions, Observable, EventData,
|
||||
ViewBase, Property, CssProperty, InheritedCssProperty, Style,
|
||||
BindingOptions, Observable, EventData
|
||||
} from "ui/core/view-base";
|
||||
import { Background } from "ui/styling/background";
|
||||
import { Font } from "ui/styling/font";
|
||||
import { Color } from "color";
|
||||
|
||||
export {
|
||||
GestureTypes, GesturesObserver, GestureEventData,
|
||||
Animation, AnimationDefinition, AnimationPromise, KeyframeAnimation,
|
||||
GestureTypes, GesturesObserver, GestureEventData, TouchGestureEventData, TouchAction,
|
||||
Animation, AnimationDefinition, AnimationPromise,
|
||||
Background, Font, Color
|
||||
}
|
||||
|
||||
@@ -356,16 +355,6 @@ declare module "ui/core/view" {
|
||||
cssClasses: Set<string>;
|
||||
cssPseudoClasses: Set<string>;
|
||||
|
||||
/**
|
||||
* Gets the parent view. This property is read-only.
|
||||
*/
|
||||
public parent: View;
|
||||
|
||||
/**
|
||||
* Gets owner page. This is a read-only property.
|
||||
*/
|
||||
page: View;
|
||||
|
||||
/**
|
||||
* This is called to find out how big a view should be. The parent supplies constraint information in the width and height parameters.
|
||||
* The actual measurement work of a view is performed in onMeasure(int, int), called by this method. Therefore, only onMeasure(int, int) can and must be overridden by subclasses.
|
||||
@@ -550,29 +539,9 @@ declare module "ui/core/view" {
|
||||
*/
|
||||
public getActualSize(): Size;
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @unstable
|
||||
* A widget can call this method to add a matching css pseudo class.
|
||||
*/
|
||||
public addPseudoClass(name: string): void;
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @unstable
|
||||
* A widget can call this method to discard mathing css pseudo class.
|
||||
*/
|
||||
public deletePseudoClass(name: string): void;
|
||||
|
||||
// Lifecycle events
|
||||
onLoaded(): void;
|
||||
onUnloaded(): void;
|
||||
isLoaded: boolean;
|
||||
|
||||
_addView(view: View, atIndex?: number);
|
||||
_propagateInheritableProperties(view: View);
|
||||
// _inheritProperties(parentView: View);
|
||||
_removeView(view: View);
|
||||
|
||||
_context: any /* android.content.Context */;
|
||||
|
||||
_childIndexToNativeChildIndex(index?: number): number;
|
||||
@@ -595,18 +564,11 @@ declare module "ui/core/view" {
|
||||
|
||||
isCollapsed: boolean;
|
||||
isLayoutRequired: boolean;
|
||||
_parentChanged(oldParent: View): void;
|
||||
|
||||
_gestureObservers: any;
|
||||
// _isInheritedChange(): boolean;
|
||||
_domId: number;
|
||||
|
||||
_cssState: any /* "ui/styling/style-scope" */;
|
||||
_setCssState(next: any /* "ui/styling/style-scope" */);
|
||||
|
||||
_registerAnimation(animation: KeyframeAnimation);
|
||||
_unregisterAnimation(animation: KeyframeAnimation);
|
||||
_unregisterAllAnimations();
|
||||
|
||||
_isAddedToNativeVisualTree: boolean;
|
||||
|
||||
/**
|
||||
@@ -740,8 +702,6 @@ declare module "ui/core/view" {
|
||||
export function measureSpecToString(measureSpec: number): string;
|
||||
}
|
||||
|
||||
export const classNameProperty: Property<View, string>;
|
||||
export const idProperty: Property<View, string>;
|
||||
export const automationTextProperty: Property<View, string>;
|
||||
export const originXProperty: Property<View, number>;
|
||||
export const originYProperty: Property<View, number>;
|
||||
|
||||
@@ -49,12 +49,9 @@ export class DatePicker extends DatePickerBase {
|
||||
}
|
||||
|
||||
public _createUI() {
|
||||
if (!this._listener) {
|
||||
this._listener = new DateChangedListener(new WeakRef(this));
|
||||
}
|
||||
|
||||
this._android = new android.widget.DatePicker(this._context);
|
||||
this._android.setCalendarViewShown(false);
|
||||
this._listener = this._listener = new DateChangedListener(new WeakRef(this));
|
||||
this._android.init(0, 0, 0, this._listener);
|
||||
}
|
||||
|
||||
|
||||
51
tns-core-modules/ui/definitions.d.ts
vendored
51
tns-core-modules/ui/definitions.d.ts
vendored
@@ -9,9 +9,10 @@ declare module "ui/core/view-base" {
|
||||
import { Style } from "ui/styling/style";
|
||||
import { isIOS } from "platform";
|
||||
import { fromString as gestureFromString } from "ui/gestures";
|
||||
import { KeyframeAnimation } from "ui/animation/keyframe-animation";
|
||||
|
||||
export {
|
||||
Observable, EventData,
|
||||
Observable, EventData, KeyframeAnimation,
|
||||
Binding, BindingOptions, Bindable, Style, isIOS, gestureFromString
|
||||
};
|
||||
|
||||
@@ -41,10 +42,17 @@ declare module "ui/core/view-base" {
|
||||
public android: any;
|
||||
public nativeView: any;
|
||||
public bindingContext: any;
|
||||
|
||||
/**
|
||||
* Gets the parent view. This property is read-only.
|
||||
*/
|
||||
public parent: ViewBase;
|
||||
public readonly parent: ViewBase;
|
||||
|
||||
/**
|
||||
* Gets owner page. This is a read-only property.
|
||||
*/
|
||||
public readonly page: ViewBase;
|
||||
|
||||
/**
|
||||
* Gets the style object associated to this view.
|
||||
*/
|
||||
@@ -52,15 +60,50 @@ declare module "ui/core/view-base" {
|
||||
|
||||
/**
|
||||
* Returns true if visibility is set to 'collapse'.
|
||||
* Readonly property
|
||||
*/
|
||||
public isCollapsed: boolean;
|
||||
public readonly isLoaded: boolean;
|
||||
|
||||
// public onLoaded(): void;
|
||||
// public onUnloaded(): void;
|
||||
|
||||
public bind(options: BindingOptions, source: Object): void;
|
||||
public unbind(property: string): void;
|
||||
|
||||
public requestLayout(): void;
|
||||
public eachChild(callback: (child: ViewBase) => boolean): void;
|
||||
|
||||
public _addView(view: ViewBase, atIndex?: number): void;
|
||||
public _removeView(view: ViewBase): void;
|
||||
public _parentChanged(oldParent: ViewBase): void;
|
||||
|
||||
_childrenCount: number;
|
||||
|
||||
_cssState: any /* "ui/styling/style-scope" */;
|
||||
_setCssState(next: any /* "ui/styling/style-scope" */);
|
||||
_registerAnimation(animation: KeyframeAnimation);
|
||||
_unregisterAnimation(animation: KeyframeAnimation);
|
||||
_cancelAllAnimations();
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @unstable
|
||||
* A widget can call this method to add a matching css pseudo class.
|
||||
*/
|
||||
public addPseudoClass(name: string): void;
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @unstable
|
||||
* A widget can call this method to discard mathing css pseudo class.
|
||||
*/
|
||||
public deletePseudoClass(name: string): void;
|
||||
}
|
||||
|
||||
export const idProperty: Property<ViewBase, string>;
|
||||
export const classNameProperty: Property<ViewBase, string>;
|
||||
export const bindingContextProperty: InheritedProperty<ViewBase, any>;
|
||||
}
|
||||
|
||||
declare module "ui/core/properties" {
|
||||
@@ -80,7 +123,7 @@ declare module "ui/core/properties" {
|
||||
}
|
||||
|
||||
export interface CoerciblePropertyOptions<T, U> extends PropertyOptions<T, U> {
|
||||
coerceValue(T, U): U
|
||||
readonly coerceValue: (t: T, u: U) => U;
|
||||
}
|
||||
|
||||
export interface CssPropertyOptions<T extends Style, U> extends PropertyOptions<T, U> {
|
||||
@@ -134,4 +177,6 @@ declare module "ui/core/properties" {
|
||||
public readonly cssName: string;
|
||||
public register(cls: { prototype: T }): void;
|
||||
}
|
||||
|
||||
export function applyNativeSetters(view: ViewBase): void;
|
||||
}
|
||||
@@ -4,15 +4,14 @@ import { Button } from "ui/button";
|
||||
import { TextField } from "ui/text-field";
|
||||
import { Label } from "ui/label";
|
||||
import { View, Color } from "ui/core/view";
|
||||
import * as types from "utils/types";
|
||||
|
||||
export let STRING = "string",
|
||||
PROMPT = "Prompt",
|
||||
CONFIRM = "Confirm",
|
||||
ALERT = "Alert",
|
||||
LOGIN = "Login",
|
||||
OK = "OK",
|
||||
CANCEL = "Cancel";
|
||||
export const STRING = "string";
|
||||
export const PROMPT = "Prompt";
|
||||
export const CONFIRM = "Confirm";
|
||||
export const ALERT = "Alert";
|
||||
export const LOGIN = "Login";
|
||||
export const OK = "OK";
|
||||
export const CANCEL = "Cancel";
|
||||
|
||||
/**
|
||||
* Defines the input type for prompt dialog.
|
||||
@@ -65,7 +64,7 @@ let buttonBackgroundColor: Color;
|
||||
// NOTE: This will fail if app.css is changed.
|
||||
export function getButtonBackgroundColor(): Color {
|
||||
if (!buttonBackgroundColor) {
|
||||
let btn = new button.Button();
|
||||
let btn = new Button();
|
||||
applySelectors(btn);
|
||||
buttonBackgroundColor = btn.backgroundColor;
|
||||
btn.onUnloaded();
|
||||
@@ -100,5 +99,5 @@ export function getLabelColor(): Color {
|
||||
}
|
||||
|
||||
export function isDialogOptions(arg): boolean {
|
||||
return !types.isNullOrUndefined(arg) && (arg.message || arg.title);
|
||||
return arg && (arg.message || arg.title);
|
||||
}
|
||||
@@ -7,15 +7,6 @@
|
||||
|
||||
import { ad } from "utils/utils";
|
||||
|
||||
export class EditableTextBase extends common.EditableTextBase {
|
||||
private _android: android.widget.EditText;
|
||||
private _textWatcher: android.text.TextWatcher;
|
||||
private _keyListenerCache: android.text.method.IKeyListener;
|
||||
/* tslint:disable */
|
||||
private _dirtyTextAccumulator: string;
|
||||
/* tslint:enable */
|
||||
|
||||
|
||||
@Interfaces([android.text.TextWatcher])
|
||||
class TextWatcher implements android.text.TextWatcher {
|
||||
constructor(private owner: WeakRef<EditableTextBase>) {
|
||||
@@ -61,6 +52,9 @@ class TextWatcher implements android.text.TextWatcher {
|
||||
}
|
||||
}
|
||||
|
||||
//https://github.com/NativeScript/NativeScript/issues/2942
|
||||
let dismissKeyboardTimeoutId: number;
|
||||
|
||||
@Interfaces([android.view.View.OnFocusChangeListener])
|
||||
class FocusChangeListener implements android.view.View.OnFocusChangeListener {
|
||||
constructor(private owner: WeakRef<EditableTextBase>) {
|
||||
@@ -73,7 +67,7 @@ class FocusChangeListener implements android.view.View.OnFocusChangeListener {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hasFocus) {
|
||||
if (hasFocus) {
|
||||
if (dismissKeyboardTimeoutId) {
|
||||
// https://github.com/NativeScript/NativeScript/issues/2942
|
||||
// Don't hide the keyboard since another (or the same) EditText has gained focus.
|
||||
@@ -118,6 +112,7 @@ class EditorActionListener implements android.widget.TextView.OnEditorActionList
|
||||
}
|
||||
owner._onReturnPress();
|
||||
}
|
||||
|
||||
// If action is ACTION_NEXT then do not close keyboard
|
||||
if (actionId === android.view.inputmethod.EditorInfo.IME_ACTION_NEXT) {
|
||||
owner._onReturnPress();
|
||||
@@ -126,6 +121,7 @@ class EditorActionListener implements android.widget.TextView.OnEditorActionList
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class EditableTextBase extends EditableTextBaseCommon {
|
||||
_textWatcher: android.text.TextWatcher;
|
||||
|
||||
@@ -3,14 +3,11 @@
|
||||
NavigationTransition, AndroidFragmentCallbacks, AndroidActivityCallbacks
|
||||
} from "ui/frame";
|
||||
import { FrameBase, NavigationContext, stack, goBack } from "./frame-common";
|
||||
import { Page } from "ui/page";
|
||||
import { View } from "ui/core/view";
|
||||
import { Observable } from "data/observable";
|
||||
import { Page, View, Observable } from "ui/page";
|
||||
import { DIALOG_FRAGMENT_TAG } from "../page/constants";
|
||||
import * as transitionModule from "ui/transition";
|
||||
import * as trace from "trace";
|
||||
import * as application from "application";
|
||||
import * as types from "utils/types";
|
||||
|
||||
export * from "./frame-common";
|
||||
|
||||
|
||||
3
tns-core-modules/ui/frame/frame.d.ts
vendored
3
tns-core-modules/ui/frame/frame.d.ts
vendored
@@ -2,8 +2,7 @@
|
||||
* Contains the Frame class, which represents the logical View unit that is responsible for navigation within an application.
|
||||
*/
|
||||
declare module "ui/frame" {
|
||||
import { View, Observable, EventData } from "ui/core/view";
|
||||
import { Page } from "ui/page";
|
||||
import { Page, View, Observable, EventData } from "ui/page";
|
||||
import { Transition } from "ui/transition";
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { iOSFrame as iOSFrameDefinition, BackstackEntry, NavigationTransition } from "ui/frame";
|
||||
import { FrameBase } from "./frame-common";
|
||||
import { Page } from "ui/page";
|
||||
import { View } from "ui/core/view";
|
||||
import { Page, View } from "ui/page";
|
||||
|
||||
import * as transitionModule from "ui/transition";
|
||||
import * as trace from "trace";
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { GestureTypes as GestureTypesDefinition, GestureEventData, GesturesObserver as GesturesObserverDefinition } from "ui/gestures";
|
||||
import { View, EventData } from "ui/core/view";
|
||||
import { View } from "ui/core/view";
|
||||
|
||||
export { View, EventData, layout } from "ui/core/view";
|
||||
|
||||
export enum GestureTypes {
|
||||
tap = 1 << 0,
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import { GestureEventData, SwipeGestureEventData, PanGestureEventData, RotationGestureEventData } from "ui/gestures";
|
||||
import { GesturesObserverBase, toString, TouchAction, GestureStateTypes, GestureTypes, SwipeDirection } from "./gestures-common";
|
||||
import { View, layout } from "ui/core/view";
|
||||
import { EventData } from "data/observable";
|
||||
import { GesturesObserverBase, toString, TouchAction, GestureStateTypes, GestureTypes, SwipeDirection, View, layout, EventData } from "./gestures-common";
|
||||
import * as trace from "trace";
|
||||
|
||||
export * from "./gestures-common";
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
import { GestureEventData, SwipeGestureEventData, PanGestureEventData, RotationGestureEventData, PinchGestureEventData } from "ui/gestures";
|
||||
import { GesturesObserverBase, toString, TouchAction, GestureStateTypes, GestureTypes, SwipeDirection } from "./gestures-common";
|
||||
import { View } from "ui/core/view";
|
||||
import { EventData } from "data/observable";
|
||||
import { GesturesObserverBase, toString, TouchAction, GestureStateTypes, GestureTypes, SwipeDirection, View, EventData } from "./gestures-common";
|
||||
import * as trace from "trace";
|
||||
import * as utils from "utils/utils";
|
||||
import types = require("utils/types");
|
||||
import getter = utils.ios.getter;
|
||||
import { ios } from "utils/utils";
|
||||
import getter = ios.getter;
|
||||
|
||||
export * from "./gestures-common";
|
||||
|
||||
@@ -451,7 +448,7 @@ class TouchGestureEventData implements TouchGestureEventData {
|
||||
}
|
||||
|
||||
private getMainPointer(): UITouch {
|
||||
if (types.isUndefined(this._mainPointer)) {
|
||||
if (this._mainPointer === undefined) {
|
||||
this._mainPointer = this.ios.touches.anyObject();
|
||||
}
|
||||
return this._mainPointer;
|
||||
|
||||
@@ -89,7 +89,7 @@ export class Image extends ImageBase {
|
||||
let owner = new WeakRef<Image>(this);
|
||||
this._imageLoadedListener = this._imageLoadedListener || new ImageLoadedListener(new WeakRef(this));
|
||||
|
||||
this.imageSource = unsetValue;
|
||||
this.imageSource = <any>unsetValue;
|
||||
if (typeof value === "string") {
|
||||
value = value.trim();
|
||||
this.isLoading = true;
|
||||
@@ -98,8 +98,8 @@ export class Image extends ImageBase {
|
||||
// TODO: Check with runtime what should we do in case of base64 string.
|
||||
super._createImageSourceFromSrc();
|
||||
}
|
||||
else if (imageSource.isFileOrResourcePath(value)) {
|
||||
if (value.indexOf(utils.RESOURCE_PREFIX) === 0) {
|
||||
else if (isFileOrResourcePath(value)) {
|
||||
if (value.indexOf(RESOURCE_PREFIX) === 0) {
|
||||
imageView.setUri(value, this.decodeWidth, this.decodeHeight, this.useCache, async, this._imageLoadedListener);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -65,10 +65,10 @@ export class ListPicker extends ListPickerBase {
|
||||
return this._android;
|
||||
}
|
||||
|
||||
|
||||
public _createUI() {
|
||||
this._android = new android.widget.NumberPicker(this._context);
|
||||
this._editText = getEditText(this._android);
|
||||
let editText = getEditText(this._android);
|
||||
this._editText = editText;
|
||||
this._selectorWheelPaint = getSelectorWheelPaint(this._android);
|
||||
|
||||
this._android.setDescendantFocusability(android.widget.NumberPicker.FOCUS_BLOCK_DESCENDANTS);
|
||||
@@ -77,36 +77,24 @@ export class ListPicker extends ListPickerBase {
|
||||
this._android.setMaxValue(0);
|
||||
this._android.setValue(0);
|
||||
|
||||
let formatter = this._formatter || new Formatter(new WeakRef(this));
|
||||
this._formatter = this._formatter || new Formatter(new WeakRef(this));
|
||||
this._android.setFormatter(this._formatter);
|
||||
|
||||
this._valueChangedListener = this._valueChangedListener || new ValueChangeListener(new WeakRef(this));
|
||||
this._android.setOnValueChangedListener(this._valueChangedListener);
|
||||
|
||||
if (editText) {
|
||||
//Fix the disappearing selected item.
|
||||
//HACK: http://stackoverflow.com/questions/17708325/android-numberpicker-with-formatter-does-not-format-on-first-rendering/26797732
|
||||
this._editText.setFilters([]);
|
||||
editText.setFilters([]);
|
||||
|
||||
//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);
|
||||
editText.setText(" ", android.widget.TextView.BufferType.NORMAL);
|
||||
}
|
||||
|
||||
this._android.setWrapSelectorWheel(false);
|
||||
}
|
||||
|
||||
private updateSelectedValue(): void {
|
||||
let selectedIndex = this.selectedIndex;
|
||||
this.android.setValue(selectedIndex);
|
||||
}
|
||||
|
||||
private onItemsPropertyChanged(items: any[] | ItemsSource) {
|
||||
let maxValue = items && items.length > 0 ? items.length - 1 : 0;
|
||||
|
||||
this.android.setMaxValue(maxValue);
|
||||
this.updateSelectedValue();
|
||||
|
||||
this._fixNumberPickerRendering();
|
||||
}
|
||||
|
||||
private _fixNumberPickerRendering() {
|
||||
//HACK: Force the stubborn NumberPicker to render correctly when we have 0 or 1 items.
|
||||
this._android.setFormatter(null);
|
||||
@@ -122,8 +110,8 @@ export class ListPicker extends ListPickerBase {
|
||||
return -1;
|
||||
}
|
||||
set [selectedIndexProperty.native](value: number) {
|
||||
if (this.itemsSet) {
|
||||
this.updateSelectedValue();
|
||||
if (value >= 0) {
|
||||
this.android.setValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,23 +119,15 @@ export class ListPicker extends ListPickerBase {
|
||||
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;
|
||||
}
|
||||
let maxValue = value && value.length > 0 ? value.length - 1 : 0;
|
||||
this.android.setMaxValue(maxValue);
|
||||
this._fixNumberPickerRendering();
|
||||
}
|
||||
|
||||
get [colorProperty.native](): { wheelColor: number, textColor: number } {
|
||||
return {
|
||||
wheelColor: this._selectorWheelPaint.getColor(),
|
||||
textColor: this._editText.getTextColors().getDefaultColor()
|
||||
textColor: this._editText ? this._editText.getTextColors().getDefaultColor() : -1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,6 +142,8 @@ export class ListPicker extends ListPickerBase {
|
||||
}
|
||||
|
||||
this._selectorWheelPaint.setColor(wheelColor);
|
||||
if (this._editText) {
|
||||
this._editText.setTextColor(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ListPickerBase, selectedIndexProperty, itemsProperty } from "./list-picker-common";
|
||||
import { ListPickerBase, Color, selectedIndexProperty, itemsProperty, backgroundColorProperty, colorProperty } from "./list-picker-common";
|
||||
import { ItemsSource } from "ui/list-picker";
|
||||
|
||||
export * from "./list-picker-common";
|
||||
@@ -30,24 +30,12 @@ export class ListPicker extends ListPickerBase {
|
||||
return this._ios;
|
||||
}
|
||||
|
||||
private updateSelectedValue(): void {
|
||||
let selectedIndex = this.selectedIndex;
|
||||
if (selectedIndex >= 0) {
|
||||
this.ios.selectRowInComponentAnimated(selectedIndex, 0, false);
|
||||
}
|
||||
}
|
||||
|
||||
private onItemsPropertyChanged(items: any[] | ItemsSource) {
|
||||
this.ios.reloadAllComponents();
|
||||
this.updateSelectedValue();
|
||||
}
|
||||
|
||||
get [selectedIndexProperty.native](): number {
|
||||
return -1;
|
||||
}
|
||||
set [selectedIndexProperty.native](value: number) {
|
||||
if (this.itemsSet) {
|
||||
this.updateSelectedValue();
|
||||
if (value >= 0) {
|
||||
this.ios.selectRowInComponentAnimated(value, 0, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,17 +43,21 @@ export class ListPicker extends ListPickerBase {
|
||||
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;
|
||||
this.ios.reloadAllComponents();
|
||||
}
|
||||
|
||||
get [backgroundColorProperty.native](): UIColor {
|
||||
return this._ios.backgroundColor;
|
||||
}
|
||||
set [backgroundColorProperty.native](value: UIColor | Color) {
|
||||
this._ios.backgroundColor = value instanceof Color ? value.ios : value;
|
||||
}
|
||||
|
||||
get [colorProperty.native](): UIColor {
|
||||
return this._ios.tintColor;
|
||||
}
|
||||
set [colorProperty.native](value: UIColor | Color) {
|
||||
this._ios.tintColor = value instanceof Color ? value.ios : value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,51 +109,3 @@ class ListPickerDelegateImpl extends NSObject implements UIPickerViewDelegate {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class ListPickerStyler implements Styler {
|
||||
// background-color
|
||||
private static setBackgroundColorProperty(view: View, newValue: any) {
|
||||
var picker = <UIPickerView>view._nativeView;
|
||||
picker.backgroundColor = newValue;
|
||||
}
|
||||
|
||||
private static resetBackgroundColorProperty(view: View, nativeValue: any) {
|
||||
var picker = <UIPickerView>view._nativeView;
|
||||
picker.backgroundColor = nativeValue;
|
||||
}
|
||||
|
||||
private static getBackgroundColorProperty(view: View): any {
|
||||
var picker = <UIPickerView>view._nativeView;
|
||||
return picker.backgroundColor;
|
||||
}
|
||||
|
||||
// color
|
||||
private static setColorProperty(view: View, newValue: any) {
|
||||
var picker = <UIPickerView>view._nativeView;
|
||||
picker.tintColor = newValue;
|
||||
}
|
||||
|
||||
private static resetColorProperty(view: View, nativeValue: any) {
|
||||
var picker = <UIPickerView>view._nativeView;
|
||||
picker.tintColor = nativeValue;
|
||||
}
|
||||
|
||||
private static getColorProperty(view: View): any {
|
||||
var picker = <UIPickerView>view._nativeView;
|
||||
return picker.tintColor;
|
||||
}
|
||||
|
||||
public static registerHandlers() {
|
||||
registerHandler(backgroundColorProperty, new StylePropertyChangedHandler(
|
||||
ListPickerStyler.setBackgroundColorProperty,
|
||||
ListPickerStyler.resetBackgroundColorProperty,
|
||||
ListPickerStyler.getBackgroundColorProperty), "ListPicker");
|
||||
|
||||
registerHandler(colorProperty, new StylePropertyChangedHandler(
|
||||
ListPickerStyler.setColorProperty,
|
||||
ListPickerStyler.resetColorProperty,
|
||||
ListPickerStyler.getColorProperty), "ListPicker");
|
||||
}
|
||||
}
|
||||
|
||||
ListPickerStyler.registerHandlers();
|
||||
|
||||
@@ -131,17 +131,21 @@ export class ListView extends ListViewBase {
|
||||
this._realizedTemplates.clear();
|
||||
}
|
||||
|
||||
get [separatorColor.native](): number {
|
||||
return null;
|
||||
}
|
||||
set [separatorColor.native](value: Color) {
|
||||
get [separatorColor.native](): { dividerHeight: number, divider: android.graphics.drawable.Drawable } {
|
||||
let nativeView = this._android;
|
||||
if (value) {
|
||||
return {
|
||||
dividerHeight: nativeView.getDividerHeight(),
|
||||
divider: nativeView.getDivider()
|
||||
};
|
||||
}
|
||||
set [separatorColor.native](value: Color | { dividerHeight: number, divider: android.graphics.drawable.Drawable }) {
|
||||
let nativeView = this._android;
|
||||
if (value instanceof Color) {
|
||||
nativeView.setDivider(new android.graphics.drawable.ColorDrawable(value.android));
|
||||
nativeView.setDividerHeight(1);
|
||||
} else {
|
||||
nativeView.setDivider(null);
|
||||
nativeView.setDividerHeight(0);
|
||||
nativeView.setDivider(value.divider);
|
||||
nativeView.setDividerHeight(value.dividerHeight);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,26 +287,3 @@ function ensureListViewAdapterClass() {
|
||||
|
||||
ListViewAdapterClass = ListViewAdapter;
|
||||
}
|
||||
|
||||
export class ListViewStyler implements Styler {
|
||||
// separator-color
|
||||
private static setSeparatorColorProperty(view: viewModule.View, newValue: any) {
|
||||
let listView = <android.widget.ListView>view._nativeView;
|
||||
listView.setDivider(new android.graphics.drawable.ColorDrawable(newValue));
|
||||
listView.setDividerHeight(1);
|
||||
}
|
||||
|
||||
private static resetSeparatorColorProperty(view: viewModule.View, nativeValue: any) {
|
||||
let listView = <android.widget.ListView>view._nativeView;
|
||||
listView.setDivider(new android.graphics.drawable.ColorDrawable(nativeValue));
|
||||
listView.setDividerHeight(1);
|
||||
}
|
||||
|
||||
public static registerHandlers() {
|
||||
registerHandler(separatorColorProperty, new StylePropertyChangedHandler(
|
||||
ListViewStyler.setSeparatorColorProperty,
|
||||
ListViewStyler.resetSeparatorColorProperty), "ListView");
|
||||
}
|
||||
}
|
||||
|
||||
ListViewStyler.registerHandlers();
|
||||
|
||||
@@ -46,10 +46,10 @@ export class PageBase extends ContentView implements PageDefinition {
|
||||
this.style[backgroundColorProperty.cssName] = new Color("white");
|
||||
}
|
||||
|
||||
public onLoaded() {
|
||||
this._applyCss();
|
||||
super.onLoaded();
|
||||
}
|
||||
// public onLoaded() {
|
||||
// this._applyCss();
|
||||
// super.onLoaded();
|
||||
// }
|
||||
|
||||
|
||||
get navigationContext(): any {
|
||||
|
||||
@@ -3,6 +3,8 @@ import { ActionBar } from "ui/action-bar";
|
||||
import { GridLayout } from "ui/layouts/grid-layout";
|
||||
import { DIALOG_FRAGMENT_TAG } from "./constants";
|
||||
import { device } from "platform";
|
||||
import { applyNativeSetters } from "ui/core/properties";
|
||||
|
||||
import * as trace from "trace";
|
||||
|
||||
export * from "./page-common";
|
||||
@@ -14,7 +16,7 @@ const STATUS_BAR_DARK_BCKG = 1711276032;
|
||||
interface DialogFragmentClass {
|
||||
new (owner: Page, fullscreen: boolean, shownCallback: () => void, dismissCallback: () => void): android.app.DialogFragment;
|
||||
}
|
||||
var DialogFragmentClass: DialogFragmentClass;
|
||||
let DialogFragmentClass: DialogFragmentClass;
|
||||
|
||||
function ensureDialogFragmentClass() {
|
||||
if (DialogFragmentClass) {
|
||||
@@ -32,7 +34,7 @@ function ensureDialogFragmentClass() {
|
||||
}
|
||||
|
||||
public onCreateDialog(savedInstanceState: android.os.Bundle): android.app.Dialog {
|
||||
var dialog = new android.app.Dialog(this._owner._context);
|
||||
const dialog = new android.app.Dialog(this._owner._context);
|
||||
dialog.requestWindowFeature(android.view.Window.FEATURE_NO_TITLE);
|
||||
|
||||
// Hide actionBar and adjust alignment based on _fullscreen value.
|
||||
@@ -42,7 +44,7 @@ function ensureDialogFragmentClass() {
|
||||
|
||||
dialog.setContentView(this._owner._nativeView, this._owner._nativeView.getLayoutParams());
|
||||
|
||||
var window = dialog.getWindow();
|
||||
const window = dialog.getWindow();
|
||||
window.setBackgroundDrawable(new android.graphics.drawable.ColorDrawable(android.graphics.Color.TRANSPARENT));
|
||||
|
||||
if (this._fullscreen) {
|
||||
@@ -124,7 +126,7 @@ export class Page extends PageBase {
|
||||
}
|
||||
|
||||
public _onDetached(force?: boolean) {
|
||||
var skipDetached = !force && this.frame.android.cachePagesOnNavigate && !this._isBackNavigation;
|
||||
const skipDetached = !force && this.frame.android.cachePagesOnNavigate && !this._isBackNavigation;
|
||||
|
||||
if (skipDetached) {
|
||||
// Do not detach the context and android reference.
|
||||
@@ -153,7 +155,7 @@ export class Page extends PageBase {
|
||||
|
||||
this._onAttached(parent._context);
|
||||
this._isAddedToNativeVisualTree = true;
|
||||
this._syncNativeProperties();
|
||||
applyNativeSetters(this);
|
||||
|
||||
ensureDialogFragmentClass();
|
||||
|
||||
|
||||
2
tns-core-modules/ui/page/page.d.ts
vendored
2
tns-core-modules/ui/page/page.d.ts
vendored
@@ -11,6 +11,8 @@ declare module "ui/page" {
|
||||
import styleScope = require("ui/styling/style-scope");
|
||||
//@endprivate
|
||||
|
||||
export * from "ui/content-view";
|
||||
|
||||
/**
|
||||
* Defines the data for the page navigation events.
|
||||
*/
|
||||
|
||||
@@ -1,17 +1,9 @@
|
||||
import { Progress as ProgressDefinition } from "ui/progress";
|
||||
import { View, Property } from "ui/core/view";
|
||||
import { View, Property, CoercibleProperty } from "ui/core/view";
|
||||
|
||||
export * from "ui/core/view";
|
||||
|
||||
export class ProgressBase extends View implements ProgressDefinition {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
// This calls make both platforms have default values from 0 to 100.
|
||||
this.maxValue = 100;
|
||||
this.value = 0;
|
||||
}
|
||||
|
||||
public value: number;
|
||||
public maxValue: number;
|
||||
// get maxValue(): number {
|
||||
@@ -38,11 +30,11 @@ export class ProgressBase extends View implements ProgressDefinition {
|
||||
/**
|
||||
* Represents the observable property backing the value property of each Progress instance.
|
||||
*/
|
||||
export const valueProperty = new Property<ProgressBase, number>({ name: "value", defaultValue: 0 });
|
||||
export const valueProperty = new CoercibleProperty<ProgressBase, number>({ name: "value", defaultValue: 0, coerceValue: (t, v) => v < 0 ? 0 : Math.min(v, t.maxValue) });
|
||||
valueProperty.register(ProgressBase);
|
||||
|
||||
/**
|
||||
* Represents the observable property backing the maxValue property of each Progress instance.
|
||||
*/
|
||||
export const maxValueProperty = new Property<ProgressBase, number>({ name: "maxValue", defaultValue: 100 });
|
||||
export const maxValueProperty = new Property<ProgressBase, number>({ name: "maxValue", defaultValue: 100, valueChanged: (target, oldValue, newValue) => valueProperty.coerce(target) });
|
||||
maxValueProperty.register(ProgressBase);
|
||||
@@ -1,5 +1,7 @@
|
||||
import { ProgressBase, valueProperty, maxValueProperty } from "./progress-common";
|
||||
import { View, Color, colorProperty, backgroundColorProperty, backgroundInternalProperty } from "ui/core/view";
|
||||
import {
|
||||
View, Color, ProgressBase, valueProperty, maxValueProperty,
|
||||
colorProperty, backgroundColorProperty, backgroundInternalProperty
|
||||
} from "./progress-common";
|
||||
|
||||
export * from "./progress-common";
|
||||
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
import { ProgressBase, valueProperty, maxValueProperty } from "./progress-common";
|
||||
import { View, Color, colorProperty, backgroundColorProperty, backgroundInternalProperty } from "ui/core/view";
|
||||
import {
|
||||
ProgressBase, View, Color, valueProperty, maxValueProperty,
|
||||
colorProperty, backgroundColorProperty, backgroundInternalProperty
|
||||
} from "./progress-common";
|
||||
|
||||
export * from "./progress-common";
|
||||
|
||||
export class Progress extends ProgressBase {
|
||||
private _ios: UIProgressView;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this._ios = UIProgressView.new();
|
||||
}
|
||||
private _ios = UIProgressView.new();
|
||||
|
||||
get ios(): UIProgressView {
|
||||
return this._ios;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import types = require("utils/types");
|
||||
import { ProxyViewContainer as ProxyViewContainerDefinition } from "ui/proxy-view-container";
|
||||
import { enabled as traceEnabled, write as traceWrite, categories as traceCategories } from "trace";
|
||||
import { LayoutBase, View } from "ui/layouts/layout-base";
|
||||
import { enabled as traceEnabled, write as traceWrite, categories as traceCategories } from "trace";
|
||||
/**
|
||||
* Proxy view container that adds all its native children directly to the parent.
|
||||
* To be used as a logical grouping container of views.
|
||||
@@ -50,7 +50,7 @@ export class ProxyViewContainer extends LayoutBase implements ProxyViewContainer
|
||||
|
||||
public _eachLayoutView(callback: (View) => void): void {
|
||||
this._eachChildView((cv) => {
|
||||
if (cv._isVisible) {
|
||||
if (!cv.isCollapsed) {
|
||||
cv._eachLayoutView(callback);
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { SegmentedBar as SegmentedBarDefinition, SegmentedBarItem as SegmentedBarItemDefinition } from "ui/segmented-bar";
|
||||
import { SegmentedBar as SegmentedBarDefinition, SegmentedBarItem as SegmentedBarItemDefinition, SelectedIndexChangedEventData } from "ui/segmented-bar";
|
||||
import {
|
||||
View, AddChildFromBuilder, AddArrayFromBuilder,
|
||||
Property, EventData, Color, Bindable
|
||||
ViewBase, View, AddChildFromBuilder, AddArrayFromBuilder,
|
||||
Property, CoercibleProperty, EventData, Color
|
||||
} from "ui/core/view";
|
||||
|
||||
export * from "ui/core/view";
|
||||
@@ -10,9 +10,7 @@ export module knownCollections {
|
||||
export var items = "items";
|
||||
}
|
||||
|
||||
var CHILD_SEGMENTED_BAR_ITEM = "SegmentedBarItem";
|
||||
|
||||
export abstract class SegmentedBarItemBase extends Bindable implements SegmentedBarItemDefinition {
|
||||
export abstract class SegmentedBarItemBase extends ViewBase implements SegmentedBarItemDefinition {
|
||||
private _title: string = "";
|
||||
public _parent: SegmentedBarBase;
|
||||
|
||||
@@ -32,11 +30,9 @@ export abstract class SegmentedBarItemBase extends Bindable implements Segmented
|
||||
export abstract class SegmentedBarBase extends View implements SegmentedBarDefinition, AddChildFromBuilder, AddArrayFromBuilder {
|
||||
public static selectedIndexChangedEvent = "selectedIndexChanged";
|
||||
|
||||
protected previousSelectedIndex: number;
|
||||
|
||||
public selectedIndex: number;
|
||||
public items: Array<SegmentedBarItemDefinition>;
|
||||
public selectedBackgroundColor: Color;
|
||||
public items: Array<SegmentedBarItemDefinition>;
|
||||
|
||||
public _addArrayFromBuilder(name: string, value: Array<any>): void {
|
||||
if (name === "items") {
|
||||
@@ -45,7 +41,7 @@ export abstract class SegmentedBarBase extends View implements SegmentedBarDefin
|
||||
}
|
||||
|
||||
public _addChildFromBuilder(name: string, value: any): void {
|
||||
if (name === CHILD_SEGMENTED_BAR_ITEM) {
|
||||
if (name === "SegmentedBarItem") {
|
||||
if (!this.items) {
|
||||
this.items = new Array<SegmentedBarItemBase>();
|
||||
}
|
||||
@@ -53,58 +49,52 @@ export abstract class SegmentedBarBase extends View implements SegmentedBarDefin
|
||||
}
|
||||
}
|
||||
|
||||
public _adjustSelectedIndex(items: Array<SegmentedBarItemDefinition>) {
|
||||
if (this.items) {
|
||||
if (this.items.length > 0) {
|
||||
if (this.selectedIndex === undefined || (this.selectedIndex > this.items.length - 1)) {
|
||||
this.selectedIndex = 0;
|
||||
}
|
||||
} else {
|
||||
this.selectedIndex = undefined;
|
||||
}
|
||||
} else {
|
||||
this.selectedIndex = undefined;
|
||||
// public _onBindingContextChanged(oldValue: any, newValue: any) {
|
||||
// super._onBindingContextChanged(oldValue, newValue);
|
||||
// if (this.items && this.items.length > 0) {
|
||||
// var i = 0;
|
||||
// var length = this.items.length;
|
||||
// for (; i < length; i++) {
|
||||
// this.items[i].bindingContext = newValue;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
public onItemsChanged(oldItems: SegmentedBarItemDefinition[], newItems: SegmentedBarItemDefinition[]): void {
|
||||
if (oldItems) {
|
||||
for (let i = 0, count = oldItems.length; i < count; i++) {
|
||||
this._removeView(oldItems[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public _onBindingContextChanged(oldValue: any, newValue: any) {
|
||||
super._onBindingContextChanged(oldValue, newValue);
|
||||
if (this.items && this.items.length > 0) {
|
||||
var i = 0;
|
||||
var length = this.items.length;
|
||||
for (; i < length; i++) {
|
||||
this.items[i].bindingContext = newValue;
|
||||
if (newItems) {
|
||||
for (let i = 0, count = newItems.length; i < count; i++) {
|
||||
this._addView(newItems[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract insertTab(tabItem: SegmentedBarItemBase, index?: number): void;
|
||||
|
||||
public getValidIndex(index?: number): number {
|
||||
let idx: number;
|
||||
let itemsLength = this.items ? this.items.length : 0;
|
||||
if (index === null || index === undefined) {
|
||||
idx = itemsLength - 1;
|
||||
} else {
|
||||
if (index < 0 || index > itemsLength) {
|
||||
idx = itemsLength - 1;
|
||||
} else {
|
||||
idx = index;
|
||||
}
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
public onSelectedIndexChanged(oldValue: number, newValue: number): void {
|
||||
this.previousSelectedIndex = oldValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets or sets the selected index dependency property of the SegmentedBar.
|
||||
*/
|
||||
export const selectedIndexProperty = new Property<SegmentedBarBase, number>({
|
||||
name: "selectedIndex", defaultValue: -1, valueConverter: (v) => parseInt(v), valueChanged: (target, oldValue, newValue) => target.onSelectedIndexChanged(oldValue, newValue)
|
||||
export const selectedIndexProperty = new CoercibleProperty<SegmentedBarBase, number>({
|
||||
name: "selectedIndex", defaultValue: -1, valueConverter: (v) => parseInt(v), valueChanged: (target, oldValue, newValue) => {
|
||||
target.notify(<SelectedIndexChangedEventData>{ eventName: SegmentedBarBase.selectedIndexChangedEvent, object: target, oldIndex: oldValue, newIndex: newValue });
|
||||
},
|
||||
coerceValue: (target, value) => {
|
||||
let items = target.items;
|
||||
if (items) {
|
||||
let max = items.length - 1;
|
||||
if (value > max) {
|
||||
value = max;
|
||||
}
|
||||
} else {
|
||||
value = -1;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
});
|
||||
selectedIndexProperty.register(SegmentedBarBase);
|
||||
|
||||
@@ -117,5 +107,10 @@ selectedBackgroundColorProperty.register(SegmentedBarBase);
|
||||
/**
|
||||
* Gets or sets the items dependency property of the SegmentedBar.
|
||||
*/
|
||||
export const itemsProperty = new Property<SegmentedBarBase, SegmentedBarItemDefinition[]>({ name: "items" });
|
||||
export const itemsProperty = new Property<SegmentedBarBase, SegmentedBarItemDefinition[]>({
|
||||
name: "items", valueChanged: (target, oldValue, newValue) => {
|
||||
target.onItemsChanged(oldValue, newValue);
|
||||
selectedIndexProperty.coerce(target);
|
||||
}
|
||||
});
|
||||
itemsProperty.register(SegmentedBarBase);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {
|
||||
SegmentedBarItemBase, SegmentedBarBase, selectedIndexProperty, itemsProperty, selectedBackgroundColorProperty,
|
||||
colorProperty, fontInternalProperty, Color, Font
|
||||
colorProperty, fontInternalProperty, Color, Font, applyNativeSetters
|
||||
} from "./segmented-bar-common";
|
||||
|
||||
export * from "./segmented-bar-common";
|
||||
@@ -15,6 +15,7 @@ const R_ATTR_STATE_SELECTED = 0x010100a1;
|
||||
// TODO: Use addView instead of _parent property. This way
|
||||
// bindingContext and style propagation will work out fo the box.
|
||||
|
||||
let apiLevel: number;
|
||||
// TODO: Move this into widgets.
|
||||
let SegmentedBarColorDrawableClass;
|
||||
function ensureSegmentedBarColorDrawableClass() {
|
||||
@@ -22,6 +23,8 @@ function ensureSegmentedBarColorDrawableClass() {
|
||||
return;
|
||||
}
|
||||
|
||||
apiLevel = android.os.Build.VERSION.SDK_INT;
|
||||
|
||||
class SegmentedBarColorDrawable extends android.graphics.drawable.ColorDrawable {
|
||||
constructor(arg: any) {
|
||||
super(arg);
|
||||
@@ -40,15 +43,95 @@ function ensureSegmentedBarColorDrawableClass() {
|
||||
SegmentedBarColorDrawableClass = SegmentedBarColorDrawable;
|
||||
}
|
||||
|
||||
function setBackground(view: android.view.View, background: android.graphics.drawable.Drawable): void {
|
||||
if (apiLevel >= 16) {
|
||||
view.setBackground(background);
|
||||
} else {
|
||||
view.setBackgroundDrawable(background);
|
||||
}
|
||||
}
|
||||
|
||||
export class SegmentedBarItem extends SegmentedBarItemBase {
|
||||
public _update() {
|
||||
if (this._parent && this._parent.android) {
|
||||
// TabHost.TabSpec.setIndicator DOES NOT WORK once the title has been set.
|
||||
// http://stackoverflow.com/questions/2935781/modify-tab-indicator-dynamically-in-android
|
||||
const tabIndex = this._parent.items.indexOf(this);
|
||||
const titleTextViewId = 16908310; // http://developer.android.com/reference/android/R.id.html#title
|
||||
const titleTextView = <android.widget.TextView>this._parent.android.getTabWidget().getChildAt(tabIndex).findViewById(titleTextViewId);
|
||||
titleTextView.setText(this.title || "");
|
||||
private _nativeView: android.widget.TextView;
|
||||
|
||||
public setNativeView(textView: android.widget.TextView): void {
|
||||
this._nativeView = textView;
|
||||
applyNativeSetters(this);
|
||||
if (this.titleDirty) {
|
||||
this._update();
|
||||
}
|
||||
}
|
||||
|
||||
private titleDirty: boolean;
|
||||
public _update(): void {
|
||||
// if (this._parent && this._parent.android) {
|
||||
// // TabHost.TabSpec.setIndicator DOES NOT WORK once the title has been set.
|
||||
// // http://stackoverflow.com/questions/2935781/modify-tab-indicator-dynamically-in-android
|
||||
// const tabIndex = this._parent.items.indexOf(this);
|
||||
// const titleTextViewId = 16908310; // http://developer.android.com/reference/android/R.id.html#title
|
||||
// const titleTextView = <android.widget.TextView>this._parent.android.getTabWidget().getChildAt(tabIndex).findViewById(titleTextViewId);
|
||||
// titleTextView.setText(this.title || "");
|
||||
// }
|
||||
|
||||
let tv = this._nativeView;
|
||||
if (tv) {
|
||||
tv.setText(this.title || "");
|
||||
this.titleDirty = false;
|
||||
} else {
|
||||
this.titleDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
get [colorProperty.native](): number {
|
||||
return this._nativeView.getCurrentTextColor();
|
||||
}
|
||||
set [colorProperty.native](value: Color | number) {
|
||||
let color = typeof value === "Color" ? value.android : value;
|
||||
this._nativeView.setTextColor(color);
|
||||
}
|
||||
|
||||
get [fontInternalProperty.native](): { typeface: android.graphics.Typeface, fontSize: number } {
|
||||
let textView = this._nativeView;
|
||||
return {
|
||||
typeface: textView.getTypeface(),
|
||||
fontSize: textView.getTextSize()
|
||||
};
|
||||
}
|
||||
set [fontInternalProperty.native](value: Font | { typeface: android.graphics.Typeface, fontSize: number }) {
|
||||
let tv = this._nativeView;
|
||||
if (value instanceof Font) {
|
||||
tv.setTypeface(value.getAndroidTypeface());
|
||||
tv.setTextSize(value.fontSize);
|
||||
} else {
|
||||
tv.setTypeface(value.typeface);
|
||||
tv.setTextSize(android.util.TypedValue.COMPLEX_UNIT_PX, value.fontSize);
|
||||
}
|
||||
}
|
||||
|
||||
get [selectedBackgroundColorProperty.native](): android.graphics.drawable.Drawable {
|
||||
let viewGroup = <android.view.ViewGroup>this._nativeView.getParent();
|
||||
return viewGroup.getBackground();
|
||||
}
|
||||
set [selectedBackgroundColorProperty.native](value: Color | android.graphics.drawable.Drawable) {
|
||||
let viewGroup = <android.view.ViewGroup>this._nativeView.getParent();
|
||||
if (value instanceof Color) {
|
||||
let color = value.android;
|
||||
let backgroundDrawable = viewGroup.getBackground();
|
||||
if (apiLevel > 21 && backgroundDrawable && typeof backgroundDrawable.setColorFilter === "function") {
|
||||
backgroundDrawable.setColorFilter(color, android.graphics.PorterDuff.Mode.SRC_IN);
|
||||
} else {
|
||||
let stateDrawable = new android.graphics.drawable.StateListDrawable();
|
||||
|
||||
let arr = Array.create("int", 1);
|
||||
arr[0] = R_ATTR_STATE_SELECTED;
|
||||
let colorDrawable: android.graphics.drawable.ColorDrawable = new SegmentedBarColorDrawableClass(color);
|
||||
stateDrawable.addState(arr, colorDrawable);
|
||||
stateDrawable.setBounds(0, 15, viewGroup.getRight(), viewGroup.getBottom());
|
||||
|
||||
setBackground(viewGroup, stateDrawable);
|
||||
}
|
||||
} else {
|
||||
setBackground(viewGroup, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -77,8 +160,15 @@ class TabContentFactory implements android.widget.TabHost.TabContentFactory {
|
||||
let owner = this.owner.get();
|
||||
if (owner) {
|
||||
let tv = new android.widget.TextView(owner._context);
|
||||
// TODO: Why do we set it to collapse???
|
||||
let index = parseInt(tag);
|
||||
// This is collapsed by default and made visibile
|
||||
// by android when TabItem becomes visible/selected.
|
||||
// TODO: Try commenting visigility change.
|
||||
tv.setVisibility(android.view.View.GONE);
|
||||
tv.setMaxLines(1);
|
||||
tv.setEllipsize(android.text.TextUtils.TruncateAt.END);
|
||||
|
||||
(<SegmentedBarItem>owner.items[index]).setNativeView(tv);
|
||||
return tv;
|
||||
} else {
|
||||
throw new Error(`Invalid owner: ${this.owner}`);
|
||||
@@ -95,9 +185,6 @@ export class SegmentedBar extends SegmentedBarBase {
|
||||
public _createUI() {
|
||||
ensureTabHostClass();
|
||||
ensureSegmentedBarColorDrawableClass();
|
||||
if (this.apiLevel === undefined) {
|
||||
this.apiLevel = android.os.Build.VERSION.SDK_INT;
|
||||
}
|
||||
|
||||
let weakRef = new WeakRef(this);
|
||||
this._android = new TabHostClass(this._context, null);
|
||||
@@ -128,14 +215,14 @@ export class SegmentedBar extends SegmentedBarBase {
|
||||
return this._android;
|
||||
}
|
||||
|
||||
public insertTab(tabItem: SegmentedBarItem, index?: number): void {
|
||||
tabItem._parent = this;
|
||||
|
||||
const tab = this.android.newTabSpec(this.getValidIndex(index) + "");
|
||||
public insertTab(tabItem: SegmentedBarItem, index: number): void {
|
||||
const tab = this.android.newTabSpec(index + "");
|
||||
tab.setIndicator(tabItem.title);
|
||||
tab.setContent(this.tabContentFactory);
|
||||
|
||||
this.android.addTab(tab);
|
||||
let tabHost = this.android;
|
||||
tabHost.addTab(tab);
|
||||
|
||||
// TODO: Why do we need to call this for every added tab?
|
||||
this.resetNativeListener();
|
||||
}
|
||||
@@ -149,155 +236,24 @@ export class SegmentedBar extends SegmentedBarBase {
|
||||
return -1;
|
||||
}
|
||||
set [selectedIndexProperty.native](value: number) {
|
||||
let items = this.items;
|
||||
if (!items) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (value >= 0 && value <= (items.length - 1)) {
|
||||
this._android.setCurrentTab(value);
|
||||
this.notify({ eventName: SegmentedBar.selectedIndexChangedEvent, object: this, oldIndex: this.previousSelectedIndex, newIndex: value });
|
||||
}
|
||||
}
|
||||
|
||||
private previousItems: SegmentedBarItem[];
|
||||
get [itemsProperty.native](): SegmentedBarItem[] {
|
||||
return null;
|
||||
}
|
||||
set [itemsProperty.native](value: SegmentedBarItem[]) {
|
||||
const oldItems = this.previousItems;
|
||||
if (oldItems) {
|
||||
for (let i = 0, length = oldItems.length; i < length; i++) {
|
||||
oldItems[i]._parent = null;
|
||||
}
|
||||
}
|
||||
|
||||
this._android.clearAllTabs();
|
||||
|
||||
const newItems = value;
|
||||
this._adjustSelectedIndex(newItems);
|
||||
|
||||
let tabHost = this._android;
|
||||
if (newItems && newItems.length) {
|
||||
for (let i = 0; i < newItems.length; i++) {
|
||||
this.insertTab(newItems[i], i);
|
||||
}
|
||||
|
||||
if (this.selectedIndex !== undefined && tabHost.getCurrentTab() !== this.selectedIndex) {
|
||||
tabHost.setCurrentTab(this.selectedIndex);
|
||||
}
|
||||
|
||||
let color = this.color ? this.color.android : -1;
|
||||
for (let i = 0, count = tabHost.getTabWidget().getTabCount(); i < count; i++) {
|
||||
let vg = <android.view.ViewGroup>tabHost.getTabWidget().getChildTabViewAt(i);
|
||||
let t = <android.widget.TextView>vg.getChildAt(1);
|
||||
if (color > -1) {
|
||||
t.setTextColor(color);
|
||||
}
|
||||
|
||||
t.setMaxLines(1);
|
||||
t.setEllipsize(android.text.TextUtils.TruncateAt.END);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get [selectedBackgroundColorProperty.native](): android.graphics.drawable.Drawable[] {
|
||||
let tabHost = this._android;
|
||||
let result = [];
|
||||
for (let i = 0, count = tabHost.getTabWidget().getTabCount(); i < count; i++) {
|
||||
let background = tabHost.getTabWidget().getChildTabViewAt(i).getBackground();
|
||||
result.push(background);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
set [selectedBackgroundColorProperty.native](value: Color | android.graphics.drawable.Drawable[]) {
|
||||
let setValue: boolean;
|
||||
let color: number;
|
||||
if (value instanceof Color) {
|
||||
setValue = true;
|
||||
color = value.android;
|
||||
}
|
||||
|
||||
let tabHost = this._android;
|
||||
let apiLevel = this.apiLevel;
|
||||
for (let i = 0, count = tabHost.getTabWidget().getTabCount(); i < count; i++) {
|
||||
let vg = <android.view.ViewGroup>tabHost.getTabWidget().getChildTabViewAt(i);
|
||||
if (setValue) {
|
||||
let backgroundDrawable = vg.getBackground();
|
||||
if (apiLevel > 21 && backgroundDrawable && typeof backgroundDrawable.setColorFilter === "function") {
|
||||
backgroundDrawable.setColorFilter(color, android.graphics.PorterDuff.Mode.SRC_IN);
|
||||
} else {
|
||||
let stateDrawable = new android.graphics.drawable.StateListDrawable();
|
||||
|
||||
let arr = Array.create("int", 1);
|
||||
arr[0] = R_ATTR_STATE_SELECTED;
|
||||
let colorDrawable: android.graphics.drawable.ColorDrawable = new SegmentedBarColorDrawableClass(color);
|
||||
stateDrawable.addState(arr, colorDrawable);
|
||||
stateDrawable.setBounds(0, 15, vg.getRight(), vg.getBottom());
|
||||
|
||||
if (android.os.Build.VERSION.SDK_INT >= 16) {
|
||||
vg.setBackground(stateDrawable);
|
||||
} else {
|
||||
vg.setBackgroundDrawable(stateDrawable);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (apiLevel >= 16) {
|
||||
vg.setBackground(value[i]);
|
||||
} else {
|
||||
vg.setBackgroundDrawable(value[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get [colorProperty.native](): number {
|
||||
let textView = new android.widget.TextView(this._context);
|
||||
return textView.getCurrentTextColor();
|
||||
}
|
||||
set [colorProperty.native](value: Color | number) {
|
||||
let tabHost = this._android;
|
||||
let color = typeof value === "number" ? value : value.android;
|
||||
for (let i = 0, count = tabHost.getTabWidget().getTabCount(); i < count; i++) {
|
||||
let tab = <android.view.ViewGroup>tabHost.getTabWidget().getChildTabViewAt(i);
|
||||
let t = <android.widget.TextView>tab.getChildAt(1);
|
||||
t.setTextColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
get [fontInternalProperty.native](): { typeface: android.graphics.Typeface, fontSize: number } {
|
||||
let textView = new android.widget.TextView(this._context);
|
||||
return {
|
||||
typeface: textView.getTypeface(),
|
||||
fontSize: textView.getTextSize()
|
||||
};
|
||||
}
|
||||
set [fontInternalProperty.native](value: Font | { typeface: android.graphics.Typeface, fontSize: number }) {
|
||||
let typeface: android.graphics.Typeface;
|
||||
let fontSize: number;
|
||||
let isFont: boolean;
|
||||
if (value instanceof Font) {
|
||||
isFont = true;
|
||||
typeface = value.getAndroidTypeface();
|
||||
fontSize = value.fontSize;
|
||||
} else {
|
||||
typeface = value.typeface;
|
||||
fontSize = value.fontSize;
|
||||
}
|
||||
|
||||
let tabHost = this._android;
|
||||
for (let i = 0, count = tabHost.getTabWidget().getTabCount(); i < count; i++) {
|
||||
let tab = <android.view.ViewGroup>tabHost.getTabWidget().getChildTabViewAt(i);
|
||||
let t = <android.widget.TextView>tab.getChildAt(1);
|
||||
|
||||
t.setTypeface(typeface);
|
||||
|
||||
if (isFont) {
|
||||
t.setTextSize(fontSize);
|
||||
}
|
||||
else {
|
||||
t.setTextSize(android.util.TypedValue.COMPLEX_UNIT_PX, fontSize);
|
||||
if (this.selectedIndex < 0) {
|
||||
this.selectedIndex = tabHost.getCurrentTab();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
*/
|
||||
declare module "ui/segmented-bar" {
|
||||
import {
|
||||
View, AddChildFromBuilder, AddArrayFromBuilder,
|
||||
Property, EventData, Color, Bindable
|
||||
ViewBase, View, AddChildFromBuilder, AddArrayFromBuilder,
|
||||
Property, CoercibleProperty, EventData, Color
|
||||
} from "ui/core/view";
|
||||
|
||||
/**
|
||||
* Represents a SegmentedBar item.
|
||||
*/
|
||||
class SegmentedBarItem extends Bindable {
|
||||
class SegmentedBarItem extends ViewBase {
|
||||
/**
|
||||
* Gets or sets the title of the SegmentedBarItem.
|
||||
*/
|
||||
@@ -76,15 +76,12 @@ declare module "ui/segmented-bar" {
|
||||
*/
|
||||
public _addChildFromBuilder(name: string, value: any): void;
|
||||
public _addArrayFromBuilder(name: string, value: Array<any>): void;
|
||||
public insertTab(tabItem: SegmentedBarItem, index?: number): void;
|
||||
|
||||
public getValidIndex(index?: number): number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets or sets the selected index dependency property of the SegmentedBar.
|
||||
*/
|
||||
export const selectedIndexProperty: Property<SegmentedBar, number>;
|
||||
export const selectedIndexProperty: CoercibleProperty<SegmentedBar, number>;
|
||||
|
||||
/**
|
||||
* Gets or sets the selected background color property of the SegmentedBar.
|
||||
|
||||
@@ -32,9 +32,9 @@ export class SegmentedBar extends SegmentedBarBase {
|
||||
return this._ios;
|
||||
}
|
||||
|
||||
public insertTab(tabItem: SegmentedBarItem, index?: number): void {
|
||||
public insertTab(tabItem: SegmentedBarItem, index: number): void {
|
||||
tabItem._parent = this;
|
||||
this.ios.insertSegmentWithTitleAtIndexAnimated(tabItem.title, this.getValidIndex(index), false);
|
||||
this.ios.insertSegmentWithTitleAtIndexAnimated(tabItem.title, index, false);
|
||||
}
|
||||
|
||||
get [selectedIndexProperty.native](): number {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { View } from "./background-common";
|
||||
import { isNullOrUndefined, isFunction, getClass } from "utils/types";
|
||||
import { CacheLayerType } from "utils/utils";
|
||||
import { Button } from "ui/button";
|
||||
import cssValue = require("css-value");
|
||||
|
||||
export * from "./background-common"
|
||||
|
||||
// TODO: Change this implementation to use
|
||||
// We are using "ad" here to avoid namespace collision with the global android object
|
||||
export module ad {
|
||||
let SDK: number;
|
||||
@@ -40,25 +40,25 @@ export module ad {
|
||||
let cache = <CacheLayerType>v._nativeView;
|
||||
|
||||
if (isSetColorFilterOnlyWidget(nativeView)
|
||||
&& !types.isNullOrUndefined(backgroundDrawable)
|
||||
&& types.isFunction(backgroundDrawable.setColorFilter)
|
||||
&& !isNullOrUndefined(backgroundDrawable)
|
||||
&& isFunction(backgroundDrawable.setColorFilter)
|
||||
&& !background.hasBorderWidth()
|
||||
&& !background.hasBorderRadius()
|
||||
&& !background.clipPath
|
||||
&& types.isNullOrUndefined(background.image)
|
||||
&& !types.isNullOrUndefined(background.color)) {
|
||||
&& isNullOrUndefined(background.image)
|
||||
&& !isNullOrUndefined(background.color)) {
|
||||
let backgroundColor = (<any>backgroundDrawable).backgroundColor = background.color.android;
|
||||
backgroundDrawable.setColorFilter(backgroundColor, android.graphics.PorterDuff.Mode.SRC_IN);
|
||||
(<any>backgroundDrawable).backgroundColor = backgroundColor;
|
||||
}
|
||||
else if (!background.isEmpty()) {
|
||||
if (!(backgroundDrawable instanceof org.nativescript.widgets.BorderDrawable)) {
|
||||
let viewClass = types.getClass(v);
|
||||
let viewClass = getClass(v);
|
||||
if (!isSetColorFilterOnlyWidget(nativeView) && !_defaultBackgrounds.has(viewClass)) {
|
||||
_defaultBackgrounds.set(viewClass, nativeView.getBackground());
|
||||
}
|
||||
|
||||
backgroundDrawable = new org.nativescript.widgets.BorderDrawable(1, v.toString());
|
||||
backgroundDrawable = new org.nativescript.widgets.BorderDrawable(v.toString());
|
||||
refreshBorderDrawable(v, <org.nativescript.widgets.BorderDrawable>backgroundDrawable);
|
||||
|
||||
if (getSDK() >= 16) {
|
||||
@@ -80,7 +80,7 @@ export module ad {
|
||||
}
|
||||
else {
|
||||
// reset the value with the default native value
|
||||
if (v instanceof Button) {
|
||||
if (nativeView instanceof android.widget.Button) {
|
||||
let nativeButton = new android.widget.Button(nativeView.getContext());
|
||||
|
||||
if (getSDK() >= 16) {
|
||||
|
||||
@@ -40,11 +40,6 @@ export module ios {
|
||||
(<CAShapeLayer>nativeView["leftBorderLayer"]).removeFromSuperlayer();
|
||||
}
|
||||
|
||||
let background = <common.Background>view.style._getValue(style.backgroundInternalProperty);
|
||||
if (!background || background.isEmpty()) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Clip-path
|
||||
if (background.clipPath) {
|
||||
drawClipPath(nativeView, background);
|
||||
@@ -297,8 +292,8 @@ function drawClipPath(nativeView: UIView, background: Background) {
|
||||
}
|
||||
|
||||
let top = cssValueToDevicePixels(topString, bounds.bottom);
|
||||
let right = cssValueToDevicePixels("100%", bounds.right) - common.cssValueToDevicePixels(rightString, bounds.right);
|
||||
let bottom = cssValueToDevicePixels("100%", bounds.bottom) - common.cssValueToDevicePixels(bottomString, bounds.bottom);
|
||||
let right = cssValueToDevicePixels("100%", bounds.right) - cssValueToDevicePixels(rightString, bounds.right);
|
||||
let bottom = cssValueToDevicePixels("100%", bounds.bottom) - cssValueToDevicePixels(bottomString, bounds.bottom);
|
||||
let left = cssValueToDevicePixels(leftString, bounds.right);
|
||||
|
||||
path = UIBezierPath.bezierPathWithRect(CGRectMake(left, top, right - left, bottom - top)).CGPath;
|
||||
|
||||
@@ -9,12 +9,14 @@ const FONTS_BASE_PATH = "/fonts/";
|
||||
const typefaceCache = new Map<string, android.graphics.Typeface>();
|
||||
let appAssets: android.content.res.AssetManager;
|
||||
|
||||
type fontWeight = "100" | "200" | "300" | "normal" | "400" | "500" | "600" | "bold" | "700" | "800" | "900";
|
||||
|
||||
export class Font extends FontBase {
|
||||
public static default = new Font(undefined, undefined, "normal", "normal");
|
||||
|
||||
private _typeface: android.graphics.Typeface;
|
||||
|
||||
constructor(family: string, size: number, style: "normal" | "italic", weight: "100" | "200" | "300" | "normal" | "400" | "500" | "600" | "bold" | "700" | "800" | "900") {
|
||||
constructor(family: string, size: number, style: "normal" | "italic", weight: fontWeight) {
|
||||
super(family, size, style, weight);
|
||||
}
|
||||
|
||||
@@ -26,7 +28,7 @@ export class Font extends FontBase {
|
||||
return new Font(this.fontFamily, this.fontSize, style, this.fontWeight);
|
||||
}
|
||||
|
||||
public withFontWeight(weight: "100" | "200" | "300" | "normal" | "400" | "500" | "600" | "bold" | "700" | "800" | "900"): Font {
|
||||
public withFontWeight(weight: fontWeight): Font {
|
||||
return new Font(this.fontFamily, this.fontSize, this.fontStyle, weight);
|
||||
}
|
||||
|
||||
|
||||
8
tns-core-modules/ui/styling/style-scope.d.ts
vendored
8
tns-core-modules/ui/styling/style-scope.d.ts
vendored
@@ -1,6 +1,6 @@
|
||||
//@private
|
||||
declare module "ui/styling/style-scope" {
|
||||
import { View } from "ui/core/view";
|
||||
import { ViewBase } from "ui/core/view-base";
|
||||
import { SyntaxTree } from "css";
|
||||
import { RuleSet, Node, SelectorCore, ChangeMap } from "ui/styling/css-selector";
|
||||
import { KeyframeAnimationInfo } from "ui/animation/keyframe-animation";
|
||||
@@ -14,7 +14,7 @@ declare module "ui/styling/style-scope" {
|
||||
/**
|
||||
* Gets the static selectors that match the view and the dynamic selectors that may potentially match the view.
|
||||
*/
|
||||
public changeMap: ChangeMap<View>;
|
||||
public changeMap: ChangeMap<ViewBase>;
|
||||
}
|
||||
|
||||
export class StyleScope {
|
||||
@@ -25,7 +25,7 @@ declare module "ui/styling/style-scope" {
|
||||
public static createSelectorsFromImports(tree: SyntaxTree, keyframes: Object): RuleSet[];
|
||||
public ensureSelectors(): boolean;
|
||||
|
||||
public applySelectors(view: View): void
|
||||
public applySelectors(view: ViewBase): void
|
||||
public query(options: Node): SelectorCore[];
|
||||
|
||||
public getKeyframeAnimationWithName(animationName: string): KeyframeAnimationInfo;
|
||||
@@ -33,5 +33,5 @@ declare module "ui/styling/style-scope" {
|
||||
}
|
||||
|
||||
export function resolveFileNameFromUrl(url: string, appDirectory: string, fileExists: (string) => boolean): string;
|
||||
export function applyInlineSyle(view: View, style: string): void;
|
||||
export function applyInlineSyle(view: ViewBase, style: string): void;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { View } from "ui/core/view";
|
||||
import { ViewBase } from "ui/core/view-base";
|
||||
import { SyntaxTree, Keyframes, parse as parseCss, Rule, Declaration, Node } from "css";
|
||||
import { RuleSet, SelectorsMap, SelectorCore, SelectorsMatch, ChangeMap, fromAstNodes } from "ui/styling/css-selector";
|
||||
import { KeyframeAnimationInfo, KeyframeAnimation } from "ui/animation/keyframe-animation";
|
||||
@@ -15,10 +15,10 @@ const animationsSymbol: symbol = Symbol("animations");
|
||||
let pattern: RegExp = /('|")(.*?)\1/;
|
||||
|
||||
export class CssState {
|
||||
constructor(private view: View, private match: SelectorsMatch<View>) {
|
||||
constructor(private view: ViewBase, private match: SelectorsMatch<ViewBase>) {
|
||||
}
|
||||
|
||||
public get changeMap(): ChangeMap<View> {
|
||||
public get changeMap(): ChangeMap<ViewBase> {
|
||||
return this.match.changeMap;
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ export class StyleScope {
|
||||
return true;
|
||||
}
|
||||
|
||||
public applySelectors(view: View): void {
|
||||
public applySelectors(view: ViewBase): void {
|
||||
this.ensureSelectors();
|
||||
|
||||
let state = this._selectors.query(view);
|
||||
@@ -229,7 +229,7 @@ export function resolveFileNameFromUrl(url: string, appDirectory: string, fileEx
|
||||
return null;
|
||||
}
|
||||
|
||||
export function applyInlineSyle(view: View, style: string) {
|
||||
export function applyInlineSyle(view: ViewBase, style: string) {
|
||||
try {
|
||||
let syntaxTree = parseCss("local { " + style + " }", undefined);
|
||||
let filteredDeclarations = <Declaration[]>(<Rule[]>syntaxTree.stylesheet.rules.filter(isRule))[0].declarations.filter(isDeclaration);
|
||||
@@ -249,7 +249,7 @@ function isKeyframe(node: Node): node is Keyframes {
|
||||
return node.type === "keyframes";
|
||||
}
|
||||
|
||||
function applyDescriptors(view: View, ruleset: RuleSet): void {
|
||||
function applyDescriptors(view: ViewBase, ruleset: RuleSet): void {
|
||||
let style = view.style;
|
||||
ruleset.declarations.forEach(d => {
|
||||
let name = `css-${d.property}`;
|
||||
@@ -301,7 +301,7 @@ function applyDescriptors(view: View, ruleset: RuleSet): void {
|
||||
}
|
||||
}
|
||||
|
||||
function applyInlineStyle(view: View, declarations: Declaration[]): void {
|
||||
function applyInlineStyle(view: ViewBase, declarations: Declaration[]): void {
|
||||
let style = view.style;
|
||||
declarations.forEach(d => {
|
||||
let name = d.property;
|
||||
|
||||
@@ -133,10 +133,10 @@ export class Style extends Observable implements StyleDefinition {
|
||||
// }
|
||||
// }
|
||||
|
||||
// public _resetCssValues() {
|
||||
// this.view._unregisterAllAnimations();
|
||||
// this._resetValues(ValueSource.Css);
|
||||
// }
|
||||
public _resetCssValues() {
|
||||
this.view._cancelAllAnimations();
|
||||
this._resetValues(ValueSource.Css);
|
||||
}
|
||||
|
||||
// public _resetLocalValues() {
|
||||
// this._resetValues(ValueSource.Local);
|
||||
@@ -230,11 +230,11 @@ export class Style extends Observable implements StyleDefinition {
|
||||
// shouldReset = (newValue === property.defaultValue);
|
||||
// }
|
||||
|
||||
public _updateTextDecoration() {
|
||||
if (this._getValue(textDecorationProperty) !== enums.TextDecoration.none) {
|
||||
this._applyProperty(textDecorationProperty, this._getValue(textDecorationProperty));
|
||||
}
|
||||
}
|
||||
// public _updateTextDecoration() {
|
||||
// if (this._getValue(textDecorationProperty) !== enums.TextDecoration.none) {
|
||||
// this._applyProperty(textDecorationProperty, this._getValue(textDecorationProperty));
|
||||
// }
|
||||
// }
|
||||
|
||||
// this._view._onStylePropertyChanged(property);
|
||||
// }
|
||||
|
||||
5
tns-core-modules/ui/text-base/text-base.d.ts
vendored
5
tns-core-modules/ui/text-base/text-base.d.ts
vendored
@@ -2,6 +2,9 @@
|
||||
import { View, AddChildFromBuilder, Property, CssProperty, InheritedCssProperty, Style } from "ui/core/view";
|
||||
import { FormattedString, FormattedStringView } from "text/formatted-string";
|
||||
|
||||
export * from "ui/core/view";
|
||||
export { FormattedString, FormattedStringView } from "text/formatted-string";
|
||||
|
||||
/**
|
||||
* Represents the base class for all text views.
|
||||
*/
|
||||
@@ -73,6 +76,4 @@
|
||||
export const textTransformProperty: CssProperty<Style, "none" | "capitalize" | "uppercase" | "lowercase">;
|
||||
export const whiteSpaceProperty: CssProperty<Style, "normal" | "nowrap">;
|
||||
export const letterSpacingProperty: CssProperty<Style, number>;
|
||||
|
||||
export * from "ui/core/view";
|
||||
}
|
||||
@@ -24,7 +24,7 @@ export class TimePicker extends TimePickerBase {
|
||||
|
||||
public _createUI() {
|
||||
this.nativeView = new android.widget.TimePicker(this._context);
|
||||
this._listener = new TimeChangedListener(new WeakRef(this));
|
||||
this._listener = this._listener || new TimeChangedListener(new WeakRef(this));
|
||||
this.nativeView.setOnTimeChangedListener(this._listener);
|
||||
|
||||
let c = java.util.Calendar.getInstance();
|
||||
|
||||
Reference in New Issue
Block a user