mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-17 04:41:36 +08:00
tabview-ios
This commit is contained in:
@ -26,6 +26,10 @@ export interface PropertyOptions<T, U> {
|
|||||||
valueConverter?: (value: any) => U
|
valueConverter?: (value: any) => U
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface CoerciblePropertyOptions<T, U> extends PropertyOptions<T, U> {
|
||||||
|
coerceValue(T, U): U
|
||||||
|
}
|
||||||
|
|
||||||
export interface ShorthandPropertyOptions {
|
export interface ShorthandPropertyOptions {
|
||||||
name: string,
|
name: string,
|
||||||
cssName: string;
|
cssName: string;
|
||||||
@ -40,9 +44,9 @@ export interface CssPropertyOptions<T extends Style, U> extends PropertyOptions<
|
|||||||
|
|
||||||
export class Property<T extends ViewBase, U> implements PropertyDescriptor {
|
export class Property<T extends ViewBase, U> implements PropertyDescriptor {
|
||||||
private registered: boolean;
|
private registered: boolean;
|
||||||
private name: string;
|
private readonly name: string;
|
||||||
public key: symbol;
|
public readonly key: symbol;
|
||||||
public native: symbol;
|
public readonly native: symbol;
|
||||||
|
|
||||||
public get: () => U;
|
public get: () => U;
|
||||||
public set: (value: U) => void;
|
public set: (value: U) => void;
|
||||||
@ -67,22 +71,137 @@ export class Property<T extends ViewBase, U> implements PropertyDescriptor {
|
|||||||
let valueConverter = options.valueConverter;
|
let valueConverter = options.valueConverter;
|
||||||
|
|
||||||
this.set = function (this: T, value: any): void {
|
this.set = function (this: T, value: any): void {
|
||||||
if (value === unsetValue) {
|
let reset = value === unsetValue;
|
||||||
value = defaultValue;
|
let unboxedValue: U;
|
||||||
}
|
let wrapped: boolean;
|
||||||
|
if (reset) {
|
||||||
|
unboxedValue = defaultValue;
|
||||||
|
} else {
|
||||||
|
wrapped = value && (<any>value).wrapped;
|
||||||
|
unboxedValue = wrapped ? WrappedValue.unwrap(value) : value;
|
||||||
|
|
||||||
let wrapped = value && value.wrapped;
|
if (valueConverter && typeof unboxedValue === "string") {
|
||||||
let unboxedValue: U = wrapped ? WrappedValue.unwrap(value) : value;
|
|
||||||
|
|
||||||
if (valueConverter) {
|
|
||||||
unboxedValue = valueConverter(unboxedValue);
|
unboxedValue = valueConverter(unboxedValue);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let currentValue = key in this ? this[key] : defaultValue;
|
let currentValue = key in this ? this[key] : defaultValue;
|
||||||
let changed: boolean = equalityComparer ? !equalityComparer(currentValue, unboxedValue) : currentValue !== unboxedValue;
|
let changed: boolean = equalityComparer ? !equalityComparer(currentValue, unboxedValue) : currentValue !== unboxedValue;
|
||||||
|
|
||||||
if (wrapped || changed) {
|
if (wrapped || changed) {
|
||||||
|
if (reset) {
|
||||||
|
delete this[key];
|
||||||
|
} else {
|
||||||
this[key] = unboxedValue;
|
this[key] = unboxedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valueChanged) {
|
||||||
|
valueChanged(this, currentValue, unboxedValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.hasListeners(eventName)) {
|
||||||
|
this.notify({
|
||||||
|
eventName: eventName,
|
||||||
|
propertyName: name,
|
||||||
|
object: this,
|
||||||
|
value: unboxedValue
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let nativeObject = this.nativeView;
|
||||||
|
if (nativeObject) {
|
||||||
|
this[native] = unboxedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (affectsLayout) {
|
||||||
|
this.requestLayout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.get = function (): U {
|
||||||
|
return key in this ? this[key] : defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
symbolPropertyMap[key] = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public register(cls: { prototype: T }): void {
|
||||||
|
if (this.registered) {
|
||||||
|
throw new Error(`Property ${this.name} already registered.`);
|
||||||
|
}
|
||||||
|
this.registered = true;
|
||||||
|
Object.defineProperty(cls.prototype, this.name, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CoercibleProperty<T extends ViewBase, U> implements PropertyDescriptor {
|
||||||
|
private registered: boolean;
|
||||||
|
private readonly name: string;
|
||||||
|
public readonly key: symbol;
|
||||||
|
public readonly native: symbol;
|
||||||
|
|
||||||
|
public get: () => U;
|
||||||
|
public set: (value: U) => void;
|
||||||
|
public enumerable: boolean = true;
|
||||||
|
public configurable: boolean = true;
|
||||||
|
|
||||||
|
public readonly coerce: (target: T) => void;
|
||||||
|
|
||||||
|
constructor(options: CoerciblePropertyOptions<T, U>) {
|
||||||
|
let name = options.name;
|
||||||
|
this.name = name;
|
||||||
|
|
||||||
|
let key = Symbol(name + ":propertyKey");
|
||||||
|
this.key = key;
|
||||||
|
|
||||||
|
let native: symbol = Symbol(name + ":nativeKey");
|
||||||
|
this.native = native;
|
||||||
|
|
||||||
|
let coerceKey = Symbol(name + ":coerceKey");
|
||||||
|
|
||||||
|
let eventName = name + "Change";
|
||||||
|
let defaultValue: U = options.defaultValue;
|
||||||
|
let affectsLayout: boolean = options.affectsLayout;
|
||||||
|
let equalityComparer = options.equalityComparer;
|
||||||
|
let valueChanged = options.valueChanged;
|
||||||
|
let valueConverter = options.valueConverter;
|
||||||
|
let coerceCallback = options.coerceValue;
|
||||||
|
|
||||||
|
this.coerce = function (target: T): void {
|
||||||
|
let originalValue: U = coerceKey in target ? target[coerceKey] : defaultValue;
|
||||||
|
target[key] = originalValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.set = function (this: T, value: U): void {
|
||||||
|
let reset = value === unsetValue;
|
||||||
|
let unboxedValue: U;
|
||||||
|
let wrapped: boolean;
|
||||||
|
if (reset) {
|
||||||
|
unboxedValue = defaultValue;
|
||||||
|
delete this[coerceKey];
|
||||||
|
} else {
|
||||||
|
wrapped = value && (<any>value).wrapped;
|
||||||
|
unboxedValue = wrapped ? WrappedValue.unwrap(value) : value;
|
||||||
|
|
||||||
|
if (valueConverter && typeof unboxedValue === "string") {
|
||||||
|
unboxedValue = valueConverter(unboxedValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
this[coerceKey] = unboxedValue;
|
||||||
|
unboxedValue = coerceCallback(this, unboxedValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
let currentValue = key in this ? this[key] : defaultValue;
|
||||||
|
let changed: boolean = equalityComparer ? !equalityComparer(currentValue, unboxedValue) : currentValue !== unboxedValue;
|
||||||
|
|
||||||
|
if (wrapped || changed) {
|
||||||
|
if (reset) {
|
||||||
|
delete this[key];
|
||||||
|
} else {
|
||||||
|
this[key] = unboxedValue;
|
||||||
|
}
|
||||||
|
|
||||||
if (valueChanged) {
|
if (valueChanged) {
|
||||||
valueChanged(this, currentValue, unboxedValue);
|
valueChanged(this, currentValue, unboxedValue);
|
||||||
}
|
}
|
||||||
@ -170,16 +289,16 @@ export class InheritedProperty<T extends ViewBase, U> extends Property<T, U> {
|
|||||||
that[sourceKey] = newValueSource;
|
that[sourceKey] = newValueSource;
|
||||||
|
|
||||||
if (currentValue !== newValue) {
|
if (currentValue !== newValue) {
|
||||||
let resetValue = newValueSource === ValueSource.Default;
|
let reset = newValueSource === ValueSource.Default;
|
||||||
that.eachChild((child) => {
|
that.eachChild((child) => {
|
||||||
let childValueSource = child[sourceKey];
|
let childValueSource = child[sourceKey];
|
||||||
if (resetValue) {
|
if (reset) {
|
||||||
if (childValueSource === ValueSource.Inherited) {
|
if (childValueSource === ValueSource.Inherited) {
|
||||||
setFunc.call(child, unsetValue);
|
setFunc.call(child, unsetValue);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (childValueSource <= ValueSource.Inherited) {
|
if (childValueSource <= ValueSource.Inherited) {
|
||||||
setInheritedValue.call(child, unboxedValue);
|
setInheritedValue.call(child, child.parent[key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -239,13 +358,14 @@ export class CssProperty<T extends Style, U> {
|
|||||||
let dependentPropertyNativeKey = dependentProperty ? dependentProperty.native : undefined;
|
let dependentPropertyNativeKey = dependentProperty ? dependentProperty.native : undefined;
|
||||||
|
|
||||||
function setLocalValue(this: T, value: U): void {
|
function setLocalValue(this: T, value: U): void {
|
||||||
if (value === unsetValue) {
|
let reset = value === unsetValue;
|
||||||
|
if (reset) {
|
||||||
value = defaultValue;
|
value = defaultValue;
|
||||||
this[sourceKey] = ValueSource.Default;
|
delete this[sourceKey];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this[sourceKey] = ValueSource.Local;
|
this[sourceKey] = ValueSource.Local;
|
||||||
if (valueConverter) {
|
if (valueConverter && typeof value === "string") {
|
||||||
value = valueConverter(value);
|
value = valueConverter(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -254,7 +374,12 @@ export class CssProperty<T extends Style, U> {
|
|||||||
let changed: boolean = equalityComparer ? !equalityComparer(currentValue, value) : currentValue !== value;
|
let changed: boolean = equalityComparer ? !equalityComparer(currentValue, value) : currentValue !== value;
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
|
if (reset) {
|
||||||
|
delete this[key];
|
||||||
|
} else {
|
||||||
this[key] = value;
|
this[key] = value;
|
||||||
|
}
|
||||||
|
|
||||||
if (valueChanged) {
|
if (valueChanged) {
|
||||||
valueChanged(this, currentValue, value);
|
valueChanged(this, currentValue, value);
|
||||||
}
|
}
|
||||||
@ -284,8 +409,7 @@ export class CssProperty<T extends Style, U> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setCssValue(this: T, value: U): void {
|
function setCssValue(this: T, value: U): void {
|
||||||
let resetValue = value === unsetValue;
|
let reset = value === unsetValue;
|
||||||
let newValueSource: ValueSource;
|
|
||||||
let currentValueSource: number = this[sourceKey] || ValueSource.Default;
|
let currentValueSource: number = this[sourceKey] || ValueSource.Default;
|
||||||
|
|
||||||
// We have localValueSource - NOOP.
|
// We have localValueSource - NOOP.
|
||||||
@ -293,22 +417,26 @@ export class CssProperty<T extends Style, U> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resetValue) {
|
if (reset) {
|
||||||
value = defaultValue;
|
value = defaultValue;
|
||||||
newValueSource = ValueSource.Default;
|
delete this[sourceKey];
|
||||||
} else {
|
} else {
|
||||||
newValueSource = ValueSource.Css;
|
this[sourceKey] = ValueSource.Css;
|
||||||
if (valueConverter) {
|
if (valueConverter && typeof value === "string") {
|
||||||
value = valueConverter(value);
|
value = valueConverter(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let currentValue: U = key in this ? this[key] : defaultValue;
|
let currentValue: U = key in this ? this[key] : defaultValue;
|
||||||
let changed: boolean = equalityComparer ? !equalityComparer(currentValue, value) : currentValue !== value;
|
let changed: boolean = equalityComparer ? !equalityComparer(currentValue, value) : currentValue !== value;
|
||||||
this[sourceKey] = newValueSource;
|
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
|
if (reset) {
|
||||||
|
delete this[key];
|
||||||
|
} else {
|
||||||
this[key] = value;
|
this[key] = value;
|
||||||
|
}
|
||||||
|
|
||||||
if (valueChanged) {
|
if (valueChanged) {
|
||||||
valueChanged(this, currentValue, value);
|
valueChanged(this, currentValue, value);
|
||||||
}
|
}
|
||||||
@ -395,9 +523,9 @@ export class InheritedCssProperty<T extends Style, U> extends CssProperty<T, U>
|
|||||||
let dependentPropertyNativeKey = dependentProperty ? dependentProperty.native : undefined;
|
let dependentPropertyNativeKey = dependentProperty ? dependentProperty.native : undefined;
|
||||||
|
|
||||||
let setFunc = (valueSource: ValueSource) => function (this: T, value: any): void {
|
let setFunc = (valueSource: ValueSource) => function (this: T, value: any): void {
|
||||||
let resetValue = value === unsetValue;
|
let reset = value === unsetValue;
|
||||||
let currentValueSource: number = this[sourceKey] || ValueSource.Default;
|
let currentValueSource: number = this[sourceKey] || ValueSource.Default;
|
||||||
if (resetValue) {
|
if (reset) {
|
||||||
// If we want to reset cssValue and we have localValue - return;
|
// If we want to reset cssValue and we have localValue - return;
|
||||||
if (valueSource === ValueSource.Css && currentValueSource === ValueSource.Local) {
|
if (valueSource === ValueSource.Css && currentValueSource === ValueSource.Local) {
|
||||||
return;
|
return;
|
||||||
@ -410,7 +538,7 @@ export class InheritedCssProperty<T extends Style, U> extends CssProperty<T, U>
|
|||||||
|
|
||||||
let view = this.view;
|
let view = this.view;
|
||||||
let newValue: U;
|
let newValue: U;
|
||||||
if (resetValue) {
|
if (reset) {
|
||||||
// If unsetValue - we want to reset this property.
|
// If unsetValue - we want to reset this property.
|
||||||
let parent = view.parent;
|
let parent = view.parent;
|
||||||
let style = parent ? parent.style : null
|
let style = parent ? parent.style : null
|
||||||
@ -421,11 +549,11 @@ export class InheritedCssProperty<T extends Style, U> extends CssProperty<T, U>
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
newValue = defaultValue;
|
newValue = defaultValue;
|
||||||
this[sourceKey] = ValueSource.Default;
|
delete this[sourceKey];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this[sourceKey] = valueSource;
|
this[sourceKey] = valueSource;
|
||||||
if (valueConverter) {
|
if (valueConverter && typeof value === "string") {
|
||||||
newValue = valueConverter(value);
|
newValue = valueConverter(value);
|
||||||
} else {
|
} else {
|
||||||
newValue = value;
|
newValue = value;
|
||||||
@ -436,7 +564,12 @@ export class InheritedCssProperty<T extends Style, U> extends CssProperty<T, U>
|
|||||||
let changed: boolean = equalityComparer ? !equalityComparer(currentValue, newValue) : currentValue !== newValue;
|
let changed: boolean = equalityComparer ? !equalityComparer(currentValue, newValue) : currentValue !== newValue;
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
|
if (reset) {
|
||||||
|
delete this[key];
|
||||||
|
} else {
|
||||||
this[key] = newValue;
|
this[key] = newValue;
|
||||||
|
}
|
||||||
|
|
||||||
if (valueChanged) {
|
if (valueChanged) {
|
||||||
valueChanged(this, currentValue, newValue);
|
valueChanged(this, currentValue, newValue);
|
||||||
}
|
}
|
||||||
@ -466,7 +599,7 @@ export class InheritedCssProperty<T extends Style, U> extends CssProperty<T, U>
|
|||||||
view.eachChild((child) => {
|
view.eachChild((child) => {
|
||||||
let childStyle = child.style;
|
let childStyle = child.style;
|
||||||
let childValueSource = childStyle[sourceKey] || ValueSource.Default;
|
let childValueSource = childStyle[sourceKey] || ValueSource.Default;
|
||||||
if (resetValue) {
|
if (reset) {
|
||||||
if (childValueSource === ValueSource.Inherited) {
|
if (childValueSource === ValueSource.Inherited) {
|
||||||
setDefaultFunc.call(childStyle, unsetValue);
|
setDefaultFunc.call(childStyle, unsetValue);
|
||||||
}
|
}
|
||||||
|
12
tns-core-modules/ui/definitions.d.ts
vendored
12
tns-core-modules/ui/definitions.d.ts
vendored
@ -62,6 +62,10 @@ declare module "ui/core/properties" {
|
|||||||
readonly valueConverter?: (value: any) => U
|
readonly valueConverter?: (value: any) => U
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface CoerciblePropertyOptions<T, U> extends PropertyOptions<T, U> {
|
||||||
|
coerceValue(T, U): U
|
||||||
|
}
|
||||||
|
|
||||||
interface CssPropertyOptions<T extends Style, U> extends PropertyOptions<T, U> {
|
interface CssPropertyOptions<T extends Style, U> extends PropertyOptions<T, U> {
|
||||||
readonly cssName: string;
|
readonly cssName: string;
|
||||||
}
|
}
|
||||||
@ -73,6 +77,14 @@ declare module "ui/core/properties" {
|
|||||||
public register(cls: { prototype: T }): void;
|
public register(cls: { prototype: T }): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CoercibleProperty<T extends ViewBase, U> implements TypedPropertyDescriptor<U> {
|
||||||
|
constructor(options: CoerciblePropertyOptions<T, U>);
|
||||||
|
|
||||||
|
public readonly native: symbol;
|
||||||
|
public readonly coerce: (target: T) => void;
|
||||||
|
public register(cls: { prototype: T }): void;
|
||||||
|
}
|
||||||
|
|
||||||
class InheritedProperty<T extends ViewBase, U> extends Property<T, U> {
|
class InheritedProperty<T extends ViewBase, U> extends Property<T, U> {
|
||||||
constructor(options: PropertyOptions<T, U>);
|
constructor(options: PropertyOptions<T, U>);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { TabView as TabViewDefinition, TabViewItem as TabViewItemDefinition } from "ui/tab-view";
|
import { TabView as TabViewDefinition, TabViewItem as TabViewItemDefinition } from "ui/tab-view";
|
||||||
import { Property } from "ui/core/properties";
|
import { Property, CoercibleProperty } from "ui/core/properties";
|
||||||
import { View, AddArrayFromBuilder } from "ui/core/view";
|
import { View, AddArrayFromBuilder } from "ui/core/view";
|
||||||
import { Bindable } from "ui/core/bindable";
|
import { Bindable } from "ui/core/bindable";
|
||||||
import { isIOS } from "platform";
|
import { isIOS } from "platform";
|
||||||
@ -122,20 +122,6 @@ export class TabViewBase extends View implements TabViewDefinition, AddArrayFrom
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public _onSelectedIndexPropertyChangedSetNativeValue() {
|
|
||||||
let index = this.selectedIndex;
|
|
||||||
if (index < 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.items) {
|
|
||||||
if (index >= this.items.length) {
|
|
||||||
this.selectedIndex = unsetValue;
|
|
||||||
throw new Error("SelectedIndex should be between [0, items.length)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get _selectedView(): View {
|
get _selectedView(): View {
|
||||||
let items = this.items;
|
let items = this.items;
|
||||||
let selectedIndex = this.selectedIndex;
|
let selectedIndex = this.selectedIndex;
|
||||||
@ -191,13 +177,6 @@ export class TabViewBase extends View implements TabViewDefinition, AddArrayFrom
|
|||||||
// iOS sepcific
|
// iOS sepcific
|
||||||
}
|
}
|
||||||
|
|
||||||
get [selectedIndexProperty.native](): number {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
set [selectedIndexProperty.native](value: number) {
|
|
||||||
this._onSelectedIndexPropertyChangedSetNativeValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
public onItemsPropertyChanged(oldValue: TabViewItemDefinition[], newValue: TabViewItemDefinition[]) {
|
public onItemsPropertyChanged(oldValue: TabViewItemDefinition[], newValue: TabViewItemDefinition[]) {
|
||||||
this.previousItems = oldValue;
|
this.previousItems = oldValue;
|
||||||
}
|
}
|
||||||
@ -206,11 +185,29 @@ export class TabViewBase extends View implements TabViewDefinition, AddArrayFrom
|
|||||||
export const itemsProperty = new Property<TabViewBase, TabViewItemBase[]>({
|
export const itemsProperty = new Property<TabViewBase, TabViewItemBase[]>({
|
||||||
name: "items", valueChanged: (target, oldValue, newValue) => {
|
name: "items", valueChanged: (target, oldValue, newValue) => {
|
||||||
target.onItemsPropertyChanged(oldValue, newValue);
|
target.onItemsPropertyChanged(oldValue, newValue);
|
||||||
|
selectedIndexProperty.coerce(target);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
itemsProperty.register(TabViewBase);
|
itemsProperty.register(TabViewBase);
|
||||||
|
|
||||||
export const selectedIndexProperty = new Property<TabViewBase, number>({ name: "selectedIndex", defaultValue: -1, affectsLayout: isIOS });
|
export const selectedIndexProperty = new CoercibleProperty<TabViewBase, number>({
|
||||||
|
name: "selectedIndex", defaultValue: -1, affectsLayout: isIOS, valueChanged: (target, oldValue, newValue) => {
|
||||||
|
let args = { eventName: TabViewBase.selectedIndexChangedEvent, object: this, oldIndex: oldValue, newIndex: newValue };
|
||||||
|
target.notify(args);
|
||||||
|
}, 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(TabViewBase);
|
selectedIndexProperty.register(TabViewBase);
|
||||||
|
|
||||||
export const selectedColorProperty = new Property<TabViewBase, Color>({ name: "selectedColor" });
|
export const selectedColorProperty = new Property<TabViewBase, Color>({ name: "selectedColor" });
|
||||||
|
@ -1,17 +1,16 @@
|
|||||||
import { TabViewBase, TabViewItemBase, itemsProperty, selectedIndexProperty, selectedColorProperty, tabsBackgroundColorProperty, traceCategory } from "./tab-view-common"
|
import { TabViewBase, TabViewItemBase, itemsProperty, selectedIndexProperty, selectedColorProperty, tabsBackgroundColorProperty, traceCategory } from "./tab-view-common"
|
||||||
import { View, colorProperty, fontInternalProperty } from "ui/core/view";
|
import { View, colorProperty, fontInternalProperty, layout } from "ui/core/view";
|
||||||
import { Property } from "ui/core/properties";
|
import { Property } from "ui/core/properties";
|
||||||
import { Bindable } from "ui/core/bindable";
|
import { Bindable } from "ui/core/bindable";
|
||||||
import { isIOS } from "platform";
|
import { isIOS } from "platform";
|
||||||
import { Color } from "color";
|
import { Color } from "color";
|
||||||
import { Font } from "ui/styling/font";
|
import { Font } from "ui/styling/font";
|
||||||
import { fromFileOrResource } from "image-source";
|
import { fromFileOrResource } from "image-source";
|
||||||
import trace = require("trace");
|
import { enabled as traceEnabled, write as traceWrite } from "trace";
|
||||||
|
import { RESOURCE_PREFIX, ad } from "utils/utils";
|
||||||
|
|
||||||
export * from "./tab-view-common";
|
export * from "./tab-view-common";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const VIEWS_STATES = "_viewStates";
|
const VIEWS_STATES = "_viewStates";
|
||||||
const ACCENT_COLOR = "colorAccent";
|
const ACCENT_COLOR = "colorAccent";
|
||||||
const PRIMARY_COLOR = "colorPrimary";
|
const PRIMARY_COLOR = "colorPrimary";
|
||||||
@ -59,8 +58,8 @@ function ensurePagerAdapterClass() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
instantiateItem(container: android.view.ViewGroup, index: number) {
|
instantiateItem(container: android.view.ViewGroup, index: number) {
|
||||||
if (trace.enabled) {
|
if (traceEnabled) {
|
||||||
trace.write("TabView.PagerAdapter.instantiateItem; container: " + container + "; index: " + index, traceCategory);
|
traceWrite("TabView.PagerAdapter.instantiateItem; container: " + container + "; index: " + index, traceCategory);
|
||||||
}
|
}
|
||||||
|
|
||||||
let item = this.items[index];
|
let item = this.items[index];
|
||||||
@ -69,8 +68,8 @@ function ensurePagerAdapterClass() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this[VIEWS_STATES]) {
|
if (this[VIEWS_STATES]) {
|
||||||
if (trace.enabled) {
|
if (traceEnabled) {
|
||||||
trace.write("TabView.PagerAdapter.instantiateItem; restoreHierarchyState: " + item.view, traceCategory);
|
traceWrite("TabView.PagerAdapter.instantiateItem; restoreHierarchyState: " + item.view, traceCategory);
|
||||||
}
|
}
|
||||||
item.view._nativeView.restoreHierarchyState(this[VIEWS_STATES]);
|
item.view._nativeView.restoreHierarchyState(this[VIEWS_STATES]);
|
||||||
}
|
}
|
||||||
@ -80,8 +79,8 @@ function ensurePagerAdapterClass() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
destroyItem(container: android.view.ViewGroup, index: number, _object: any) {
|
destroyItem(container: android.view.ViewGroup, index: number, _object: any) {
|
||||||
if (trace.enabled) {
|
if (traceEnabled) {
|
||||||
trace.write("TabView.PagerAdapter.destroyItem; container: " + container + "; index: " + index + "; _object: " + _object, traceCategory);
|
traceWrite("TabView.PagerAdapter.destroyItem; container: " + container + "; index: " + index + "; _object: " + _object, traceCategory);
|
||||||
}
|
}
|
||||||
let item = this.items[index];
|
let item = this.items[index];
|
||||||
let nativeView = item.view._nativeView;
|
let nativeView = item.view._nativeView;
|
||||||
@ -104,8 +103,8 @@ function ensurePagerAdapterClass() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
saveState(): android.os.Parcelable {
|
saveState(): android.os.Parcelable {
|
||||||
if (trace.enabled) {
|
if (traceEnabled) {
|
||||||
trace.write("TabView.PagerAdapter.saveState", traceCategory);
|
traceWrite("TabView.PagerAdapter.saveState", traceCategory);
|
||||||
}
|
}
|
||||||
|
|
||||||
let owner: TabView = this.owner;
|
let owner: TabView = this.owner;
|
||||||
@ -132,8 +131,8 @@ function ensurePagerAdapterClass() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
restoreState(state: android.os.Parcelable, loader: java.lang.ClassLoader) {
|
restoreState(state: android.os.Parcelable, loader: java.lang.ClassLoader) {
|
||||||
if (trace.enabled) {
|
if (traceEnabled) {
|
||||||
trace.write("TabView.PagerAdapter.restoreState", traceCategory);
|
traceWrite("TabView.PagerAdapter.restoreState", traceCategory);
|
||||||
}
|
}
|
||||||
let bundle: android.os.Bundle = <android.os.Bundle>state;
|
let bundle: android.os.Bundle = <android.os.Bundle>state;
|
||||||
bundle.setClassLoader(loader);
|
bundle.setClassLoader(loader);
|
||||||
@ -180,8 +179,8 @@ export class TabView extends TabViewBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public _createUI() {
|
public _createUI() {
|
||||||
if (trace.enabled) {
|
if (traceEnabled) {
|
||||||
trace.write("TabView._createUI(" + this + ");", traceCategory);
|
traceWrite("TabView._createUI(" + this + ");", traceCategory);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._grid = new org.nativescript.widgets.GridLayout(this._context);
|
this._grid = new org.nativescript.widgets.GridLayout(this._context);
|
||||||
@ -193,12 +192,12 @@ export class TabView extends TabViewBase {
|
|||||||
|
|
||||||
this.setElevation();
|
this.setElevation();
|
||||||
|
|
||||||
let accentColor = utils.ad.resources.getPalleteColor(ACCENT_COLOR, this._context);
|
let accentColor = ad.resources.getPalleteColor(ACCENT_COLOR, this._context);
|
||||||
if (accentColor) {
|
if (accentColor) {
|
||||||
this._tabLayout.setSelectedIndicatorColors([accentColor]);
|
this._tabLayout.setSelectedIndicatorColors([accentColor]);
|
||||||
}
|
}
|
||||||
|
|
||||||
let primaryColor = utils.ad.resources.getPalleteColor(PRIMARY_COLOR, this._context);
|
let primaryColor = ad.resources.getPalleteColor(PRIMARY_COLOR, this._context);
|
||||||
if (primaryColor) {
|
if (primaryColor) {
|
||||||
this._tabLayout.setBackgroundColor(primaryColor);
|
this._tabLayout.setBackgroundColor(primaryColor);
|
||||||
}
|
}
|
||||||
@ -225,7 +224,7 @@ export class TabView extends TabViewBase {
|
|||||||
private setElevation() {
|
private setElevation() {
|
||||||
let compat = <any>android.support.v4.view.ViewCompat;
|
let compat = <any>android.support.v4.view.ViewCompat;
|
||||||
if (compat.setElevation) {
|
if (compat.setElevation) {
|
||||||
let val = DEFAULT_ELEVATION * utils.layout.getDisplayDensity();
|
let val = DEFAULT_ELEVATION * layout.getDisplayDensity();
|
||||||
compat.setElevation(this._grid, val);
|
compat.setElevation(this._grid, val);
|
||||||
compat.setElevation(this._tabLayout, val);
|
compat.setElevation(this._tabLayout, val);
|
||||||
}
|
}
|
||||||
@ -271,7 +270,8 @@ export class TabView extends TabViewBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public _updateTabForItem(item: TabViewItem) {
|
public _updateTabForItem(item: TabViewItem) {
|
||||||
if (this.items && this.items.length > 0) {
|
let items = this.items;
|
||||||
|
if (items && items.length > 0) {
|
||||||
let index = this.items.indexOf(item);
|
let index = this.items.indexOf(item);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
this._tabLayout.updateItemAt(index, this.createTabItem(item));
|
this._tabLayout.updateItemAt(index, this.createTabItem(item));
|
||||||
@ -279,39 +279,17 @@ export class TabView extends TabViewBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public _onSelectedIndexPropertyChangedSetNativeValue() {
|
|
||||||
if (trace.enabled) {
|
|
||||||
trace.write("TabView._onSelectedIndexPropertyChangedSetNativeValue(" + data.oldValue + " ---> " + data.newValue + ");", traceCategory);
|
|
||||||
}
|
|
||||||
super._onSelectedIndexPropertyChangedSetNativeValue(data);
|
|
||||||
|
|
||||||
let index = data.newValue;
|
|
||||||
if (!types.isNullOrUndefined(index)) {
|
|
||||||
// Select the respective page in the ViewPager
|
|
||||||
let viewPagerSelectedIndex = this._viewPager.getCurrentItem();
|
|
||||||
if (viewPagerSelectedIndex !== index) {
|
|
||||||
if (trace.enabled) {
|
|
||||||
trace.write("TabView this._viewPager.setCurrentItem(" + index + ", true);", traceCategory);
|
|
||||||
}
|
|
||||||
this._viewPager.setCurrentItem(index, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let args = { eventName: TabView.selectedIndexChangedEvent, object: this, oldIndex: data.oldValue, newIndex: data.newValue };
|
|
||||||
this.notify(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
private createTabItem(item: TabViewItem): org.nativescript.widgets.TabItemSpec {
|
private createTabItem(item: TabViewItem): org.nativescript.widgets.TabItemSpec {
|
||||||
let result = new org.nativescript.widgets.TabItemSpec();
|
let result = new org.nativescript.widgets.TabItemSpec();
|
||||||
result.title = item.title;
|
result.title = item.title;
|
||||||
|
|
||||||
if (item.iconSource) {
|
if (item.iconSource) {
|
||||||
|
|
||||||
if (item.iconSource.indexOf(utils.RESOURCE_PREFIX) === 0) {
|
if (item.iconSource.indexOf(RESOURCE_PREFIX) === 0) {
|
||||||
result.iconId = utils.ad.resources.getDrawableId(item.iconSource.substr(utils.RESOURCE_PREFIX.length));
|
result.iconId = ad.resources.getDrawableId(item.iconSource.substr(RESOURCE_PREFIX.length));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let is = imageSource.fromFileOrResource(item.iconSource);
|
let is = fromFileOrResource(item.iconSource);
|
||||||
if (is) {
|
if (is) {
|
||||||
result.iconDrawable = new android.graphics.drawable.BitmapDrawable(is.android);
|
result.iconDrawable = new android.graphics.drawable.BitmapDrawable(is.android);
|
||||||
}
|
}
|
||||||
@ -321,6 +299,16 @@ export class TabView extends TabViewBase {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get [selectedIndexProperty.native](): number {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
set [selectedIndexProperty.native](value: number) {
|
||||||
|
if (traceEnabled) {
|
||||||
|
traceWrite("TabView this._viewPager.setCurrentItem(" + value + ", true);", traceCategory);
|
||||||
|
}
|
||||||
|
this._viewPager.setCurrentItem(value, true);
|
||||||
|
}
|
||||||
|
|
||||||
get [itemsProperty.native](): TabViewItemBase[] {
|
get [itemsProperty.native](): TabViewItemBase[] {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,15 @@
|
|||||||
import common = require("./tab-view-common");
|
import { TabViewBase, TabViewItemBase, itemsProperty, selectedIndexProperty, selectedColorProperty, tabsBackgroundColorProperty, traceCategory } from "./tab-view-common"
|
||||||
import definition = require("ui/tab-view");
|
import { View, colorProperty, fontInternalProperty, layout } from "ui/core/view";
|
||||||
import dependencyObservable = require("ui/core/dependency-observable");
|
import { Color } from "color";
|
||||||
import trace = require("trace");
|
import { Font } from "ui/styling/font";
|
||||||
import view = require("ui/core/view");
|
import { fromFileOrResource } from "image-source";
|
||||||
import types = require("utils/types");
|
|
||||||
import color = require("color");
|
|
||||||
import * as imageSourceModule from "image-source";
|
|
||||||
import style = require("ui/styling/style");
|
|
||||||
import { Page } from "ui/page";
|
import { Page } from "ui/page";
|
||||||
import * as utils from "utils/utils";
|
import { ios } from "utils/utils";
|
||||||
import getter = utils.ios.getter;
|
import { enabled as traceEnabled, write as traceWrite, categories as traceCategories } from "trace";
|
||||||
|
|
||||||
global.moduleMerge(common, exports);
|
import getter = ios.getter;
|
||||||
|
|
||||||
var imageSource: typeof imageSourceModule;
|
export * from "./tab-view-common";
|
||||||
function ensureImageSource() {
|
|
||||||
if (!imageSource) {
|
|
||||||
imageSource = require("image-source");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class UITabBarControllerImpl extends UITabBarController {
|
class UITabBarControllerImpl extends UITabBarController {
|
||||||
|
|
||||||
@ -31,8 +22,8 @@ class UITabBarControllerImpl extends UITabBarController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public viewDidLayoutSubviews(): void {
|
public viewDidLayoutSubviews(): void {
|
||||||
if (trace.enabled) {
|
if (traceEnabled) {
|
||||||
trace.write("TabView.UITabBarControllerClass.viewDidLayoutSubviews();", trace.categories.Debug);
|
traceWrite("TabView.UITabBarControllerClass.viewDidLayoutSubviews();", traceCategories.Debug);
|
||||||
}
|
}
|
||||||
super.viewDidLayoutSubviews();
|
super.viewDidLayoutSubviews();
|
||||||
let owner = this._owner.get();
|
let owner = this._owner.get();
|
||||||
@ -54,8 +45,8 @@ class UITabBarControllerDelegateImpl extends NSObject implements UITabBarControl
|
|||||||
}
|
}
|
||||||
|
|
||||||
public tabBarControllerShouldSelectViewController(tabBarController: UITabBarController, viewController: UIViewController): boolean {
|
public tabBarControllerShouldSelectViewController(tabBarController: UITabBarController, viewController: UIViewController): boolean {
|
||||||
if (trace.enabled) {
|
if (traceEnabled) {
|
||||||
trace.write("TabView.delegate.SHOULD_select(" + tabBarController + ", " + viewController + ");", trace.categories.Debug);
|
traceWrite("TabView.delegate.SHOULD_select(" + tabBarController + ", " + viewController + ");", traceCategories.Debug);
|
||||||
}
|
}
|
||||||
|
|
||||||
let owner = this._owner.get();
|
let owner = this._owner.get();
|
||||||
@ -69,8 +60,8 @@ class UITabBarControllerDelegateImpl extends NSObject implements UITabBarControl
|
|||||||
}
|
}
|
||||||
|
|
||||||
public tabBarControllerDidSelectViewController(tabBarController: UITabBarController, viewController: UIViewController): void {
|
public tabBarControllerDidSelectViewController(tabBarController: UITabBarController, viewController: UIViewController): void {
|
||||||
if (trace.enabled) {
|
if (traceEnabled) {
|
||||||
trace.write("TabView.delegate.DID_select(" + tabBarController + ", " + viewController + ");", trace.categories.Debug);
|
traceWrite("TabView.delegate.DID_select(" + tabBarController + ", " + viewController + ");", traceCategories.Debug);
|
||||||
}
|
}
|
||||||
|
|
||||||
let owner = this._owner.get();
|
let owner = this._owner.get();
|
||||||
@ -92,8 +83,8 @@ class UINavigationControllerDelegateImpl extends NSObject implements UINavigatio
|
|||||||
}
|
}
|
||||||
|
|
||||||
navigationControllerWillShowViewControllerAnimated(navigationController: UINavigationController, viewController: UIViewController, animated: boolean): void {
|
navigationControllerWillShowViewControllerAnimated(navigationController: UINavigationController, viewController: UIViewController, animated: boolean): void {
|
||||||
if (trace.enabled) {
|
if (traceEnabled) {
|
||||||
trace.write("TabView.moreNavigationController.WILL_show(" + navigationController + ", " + viewController + ", " + animated + ");", trace.categories.Debug);
|
traceWrite("TabView.moreNavigationController.WILL_show(" + navigationController + ", " + viewController + ", " + animated + ");", traceCategories.Debug);
|
||||||
}
|
}
|
||||||
|
|
||||||
let owner = this._owner.get();
|
let owner = this._owner.get();
|
||||||
@ -106,8 +97,8 @@ class UINavigationControllerDelegateImpl extends NSObject implements UINavigatio
|
|||||||
}
|
}
|
||||||
|
|
||||||
navigationControllerDidShowViewControllerAnimated(navigationController: UINavigationController, viewController: UIViewController, animated: boolean): void {
|
navigationControllerDidShowViewControllerAnimated(navigationController: UINavigationController, viewController: UIViewController, animated: boolean): void {
|
||||||
if (trace.enabled) {
|
if (traceEnabled) {
|
||||||
trace.write("TabView.moreNavigationController.DID_show(" + navigationController + ", " + viewController + ", " + animated + ");", trace.categories.Debug);
|
traceWrite("TabView.moreNavigationController.DID_show(" + navigationController + ", " + viewController + ", " + animated + ");", traceCategories.Debug);
|
||||||
}
|
}
|
||||||
// We don't need Edit button in More screen.
|
// We don't need Edit button in More screen.
|
||||||
navigationController.navigationBar.topItem.rightBarButtonItem = null;
|
navigationController.navigationBar.topItem.rightBarButtonItem = null;
|
||||||
@ -118,25 +109,29 @@ class UINavigationControllerDelegateImpl extends NSObject implements UINavigatio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TabViewItem extends common.TabViewItem {
|
function updateItemTitlePosition(tabBarItem: UITabBarItem): void {
|
||||||
public _controller: UIViewController;
|
if (typeof (<any>tabBarItem).setTitlePositionAdjustment === "function") {
|
||||||
public _parent: TabView;
|
|
||||||
|
|
||||||
public _update() {
|
|
||||||
if (this._parent && this._controller) {
|
|
||||||
var icon = this._parent._getIcon(this.iconSource);
|
|
||||||
//TODO: Implement initWithSystemItem to support standard system icons
|
|
||||||
var tabBarItem = UITabBarItem.alloc().initWithTitleImageTag((this.title || ""), icon, this._parent.items.indexOf(this));
|
|
||||||
if (!icon) {
|
|
||||||
if (types.isFunction((<any>tabBarItem).setTitlePositionAdjustment)) {
|
|
||||||
(<any>tabBarItem).setTitlePositionAdjustment({ horizontal: 0, vertical: -20 });
|
(<any>tabBarItem).setTitlePositionAdjustment({ horizontal: 0, vertical: -20 });
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
tabBarItem.titlePositionAdjustment = { horizontal: 0, vertical: -20 };
|
tabBarItem.titlePositionAdjustment = { horizontal: 0, vertical: -20 };
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TabViewItem extends TabViewItemBase {
|
||||||
|
public _controller: UIViewController;
|
||||||
|
public _parent: TabView;
|
||||||
|
|
||||||
|
public _update() {
|
||||||
|
if (this._parent && this._controller) {
|
||||||
|
const icon = this._parent._getIcon(this.iconSource);
|
||||||
|
//TODO: Implement initWithSystemItem to support standard system icons
|
||||||
|
const tabBarItem = UITabBarItem.alloc().initWithTitleImageTag((this.title || ""), icon, this._parent.items.indexOf(this));
|
||||||
|
if (!icon) {
|
||||||
|
updateItemTitlePosition(tabBarItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
var states = getTitleAttributesForStates(this._parent);
|
const states = getTitleAttributesForStates(this._parent);
|
||||||
tabBarItem.setTitleTextAttributesForState(states.normalState, UIControlState.Normal);
|
tabBarItem.setTitleTextAttributesForState(states.normalState, UIControlState.Normal);
|
||||||
tabBarItem.setTitleTextAttributesForState(states.selectedState, UIControlState.Selected);
|
tabBarItem.setTitleTextAttributesForState(states.selectedState, UIControlState.Selected);
|
||||||
this._controller.tabBarItem = tabBarItem;
|
this._controller.tabBarItem = tabBarItem;
|
||||||
@ -144,7 +139,21 @@ export class TabViewItem extends common.TabViewItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TabView extends common.TabView {
|
function selectedColorPropertyChanged(data: dependencyObservable.PropertyChangeData) {
|
||||||
|
const tabView = <TabView>data.object;
|
||||||
|
tabView._updateIOSTabBarColorsAndFonts();
|
||||||
|
}
|
||||||
|
(<proxy.PropertyMetadata>common.TabView.selectedColorProperty.metadata).onSetNativeValue = selectedColorPropertyChanged;
|
||||||
|
|
||||||
|
function tabsBackgroundColorPropertyChanged(data: dependencyObservable.PropertyChangeData) {
|
||||||
|
const tabView = <TabView>data.object;
|
||||||
|
if (data.newValue instanceof color.Color) {
|
||||||
|
tabView.ios.tabBar.barTintColor = data.newValue.ios;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(<proxy.PropertyMetadata>common.TabView.tabsBackgroundColorProperty.metadata).onSetNativeValue = tabsBackgroundColorPropertyChanged;
|
||||||
|
|
||||||
|
export class TabView extends TabViewBase {
|
||||||
public _ios: UITabBarControllerImpl;
|
public _ios: UITabBarControllerImpl;
|
||||||
private _delegate: UITabBarControllerDelegateImpl;
|
private _delegate: UITabBarControllerDelegateImpl;
|
||||||
private _moreNavigationControllerDelegate: UINavigationControllerDelegateImpl;
|
private _moreNavigationControllerDelegate: UINavigationControllerDelegateImpl;
|
||||||
@ -182,63 +191,60 @@ export class TabView extends common.TabView {
|
|||||||
|
|
||||||
public _onViewControllerShown(viewController: UIViewController) {
|
public _onViewControllerShown(viewController: UIViewController) {
|
||||||
// This method could be called with the moreNavigationController or its list controller, so we have to check.
|
// This method could be called with the moreNavigationController or its list controller, so we have to check.
|
||||||
if (trace.enabled) {
|
if (traceEnabled) {
|
||||||
trace.write("TabView._onViewControllerShown(" + viewController + ");", trace.categories.Debug);
|
traceWrite("TabView._onViewControllerShown(" + viewController + ");", traceCategories.Debug);
|
||||||
}
|
}
|
||||||
if (this._ios.viewControllers.containsObject(viewController)) {
|
if (this._ios.viewControllers.containsObject(viewController)) {
|
||||||
this.selectedIndex = this._ios.viewControllers.indexOfObject(viewController);
|
this.selectedIndex = this._ios.viewControllers.indexOfObject(viewController);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (trace.enabled) {
|
if (traceEnabled) {
|
||||||
trace.write("TabView._onViewControllerShown: viewController is not one of our viewControllers", trace.categories.Debug);
|
traceWrite("TabView._onViewControllerShown: viewController is not one of our viewControllers", traceCategories.Debug);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _actionBarHiddenByTabView: boolean;
|
private _actionBarHiddenByTabView: boolean;
|
||||||
public _handleTwoNavigationBars(backToMoreWillBeVisible: boolean){
|
public _handleTwoNavigationBars(backToMoreWillBeVisible: boolean) {
|
||||||
if (trace.enabled) {
|
if (traceEnabled) {
|
||||||
trace.write(`TabView._handleTwoNavigationBars(backToMoreWillBeVisible: ${backToMoreWillBeVisible})`, trace.categories.Debug);
|
traceWrite(`TabView._handleTwoNavigationBars(backToMoreWillBeVisible: ${backToMoreWillBeVisible})`, traceCategories.Debug);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The "< Back" and "< More" navigation bars should not be visible simultaneously.
|
// The "< Back" and "< More" navigation bars should not be visible simultaneously.
|
||||||
let page = <Page>this.page;
|
let page = <Page>this.page;
|
||||||
let actionBarVisible = page.frame._getNavBarVisible(page);
|
let actionBarVisible = page.frame._getNavBarVisible(page);
|
||||||
|
|
||||||
if (backToMoreWillBeVisible && actionBarVisible){
|
if (backToMoreWillBeVisible && actionBarVisible) {
|
||||||
page.frame.ios._disableNavBarAnimation = true;
|
page.frame.ios._disableNavBarAnimation = true;
|
||||||
page.actionBarHidden = true;
|
page.actionBarHidden = true;
|
||||||
page.frame.ios._disableNavBarAnimation = false;
|
page.frame.ios._disableNavBarAnimation = false;
|
||||||
this._actionBarHiddenByTabView = true;
|
this._actionBarHiddenByTabView = true;
|
||||||
if (trace.enabled) {
|
if (traceEnabled) {
|
||||||
trace.write(`TabView hid action bar`, trace.categories.Debug);
|
traceWrite(`TabView hid action bar`, traceCategories.Debug);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!backToMoreWillBeVisible && this._actionBarHiddenByTabView){
|
if (!backToMoreWillBeVisible && this._actionBarHiddenByTabView) {
|
||||||
page.frame.ios._disableNavBarAnimation = true;
|
page.frame.ios._disableNavBarAnimation = true;
|
||||||
page.actionBarHidden = false;
|
page.actionBarHidden = false;
|
||||||
page.frame.ios._disableNavBarAnimation = false;
|
page.frame.ios._disableNavBarAnimation = false;
|
||||||
this._actionBarHiddenByTabView = undefined;
|
this._actionBarHiddenByTabView = undefined;
|
||||||
if (trace.enabled) {
|
if (traceEnabled) {
|
||||||
trace.write(`TabView restored action bar`, trace.categories.Debug);
|
traceWrite(`TabView restored action bar`, traceCategories.Debug);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public _removeTabs(oldItems: Array<definition.TabViewItem>) {
|
public _removeTabs(oldItems: Array<TabViewItem>) {
|
||||||
if (trace.enabled) {
|
if (traceEnabled) {
|
||||||
trace.write("TabView._removeTabs(" + oldItems + ");", trace.categories.Debug);
|
traceWrite("TabView._removeTabs(" + oldItems + ");", traceCategories.Debug);
|
||||||
}
|
}
|
||||||
super._removeTabs(oldItems);
|
super._removeTabs(oldItems);
|
||||||
|
|
||||||
var i: number;
|
for (let i = 0, length = oldItems.length; i < length; i++) {
|
||||||
var length = oldItems.length;
|
let oldItem = oldItems[i];
|
||||||
var oldItem: TabViewItem;
|
|
||||||
for (i = 0; i < length; i++) {
|
|
||||||
oldItem = <TabViewItem>oldItems[i];
|
|
||||||
oldItem._parent = null;
|
oldItem._parent = null;
|
||||||
oldItem._controller = null;
|
oldItem._controller = null;
|
||||||
}
|
}
|
||||||
@ -246,22 +252,19 @@ export class TabView extends common.TabView {
|
|||||||
this._ios.viewControllers = null;
|
this._ios.viewControllers = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public _addTabs(newItems: Array<definition.TabViewItem>) {
|
public _addTabs(newItems: Array<TabViewItem>) {
|
||||||
if (trace.enabled) {
|
if (traceEnabled) {
|
||||||
trace.write("TabView._addTabs(" + newItems + ");", trace.categories.Debug);
|
traceWrite("TabView._addTabs(" + newItems + ");", traceCategories.Debug);
|
||||||
}
|
}
|
||||||
super._addTabs(newItems);
|
super._addTabs(newItems);
|
||||||
|
|
||||||
var i: number;
|
const length = newItems.length;
|
||||||
var length = newItems.length;
|
const newControllers: NSMutableArray<any> = NSMutableArray.alloc().initWithCapacity(length);
|
||||||
var item: TabViewItem;
|
const states = getTitleAttributesForStates(this);
|
||||||
var newControllers: NSMutableArray<any> = NSMutableArray.alloc().initWithCapacity(length);
|
|
||||||
var newController: UIViewController;
|
|
||||||
|
|
||||||
var states = getTitleAttributesForStates(this);
|
for (let i = 0; i < length; i++) {
|
||||||
|
const item = <TabViewItem>newItems[i];
|
||||||
for (i = 0; i < length; i++) {
|
let newController: UIViewController;
|
||||||
item = <TabViewItem>newItems[i];
|
|
||||||
|
|
||||||
if (item.view.ios instanceof UIViewController) {
|
if (item.view.ios instanceof UIViewController) {
|
||||||
newController = <UIViewController>item.view.ios;
|
newController = <UIViewController>item.view.ios;
|
||||||
@ -273,16 +276,11 @@ export class TabView extends common.TabView {
|
|||||||
item._parent = this;
|
item._parent = this;
|
||||||
item._controller = newController;
|
item._controller = newController;
|
||||||
|
|
||||||
var icon = this._getIcon(item.iconSource);
|
const icon = this._getIcon(item.iconSource);
|
||||||
|
|
||||||
var tabBarItem = UITabBarItem.alloc().initWithTitleImageTag((item.title || ""), icon, i);
|
const tabBarItem = UITabBarItem.alloc().initWithTitleImageTag((item.title || ""), icon, i);
|
||||||
if (!icon) {
|
if (!icon) {
|
||||||
if (types.isFunction((<any>tabBarItem).setTitlePositionAdjustment)) {
|
updateItemTitlePosition(tabBarItem);
|
||||||
(<any>tabBarItem).setTitlePositionAdjustment({ horizontal: 0, vertical: -20 });
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
(<any>tabBarItem).titlePositionAdjustment = { horizontal: 0, vertical: -20 };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
tabBarItem.setTitleTextAttributesForState(states.normalState, UIControlState.Normal);
|
tabBarItem.setTitleTextAttributesForState(states.normalState, UIControlState.Normal);
|
||||||
tabBarItem.setTitleTextAttributesForState(states.selectedState, UIControlState.Selected);
|
tabBarItem.setTitleTextAttributesForState(states.selectedState, UIControlState.Selected);
|
||||||
@ -337,14 +335,11 @@ export class TabView extends common.TabView {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var image: UIImage;
|
let image: UIImage = this._iconsCache[iconSource];
|
||||||
image = this._iconsCache[iconSource];
|
|
||||||
if (!image) {
|
if (!image) {
|
||||||
ensureImageSource();
|
const is = fromFileOrResource(iconSource);
|
||||||
|
|
||||||
var is = imageSource.fromFileOrResource(iconSource);
|
|
||||||
if (is && is.ios) {
|
if (is && is.ios) {
|
||||||
var originalRenderedImage = is.ios.imageWithRenderingMode(this._getIconRenderingMode());
|
const originalRenderedImage = is.ios.imageWithRenderingMode(this._getIconRenderingMode());
|
||||||
this._iconsCache[iconSource] = originalRenderedImage;
|
this._iconsCache[iconSource] = originalRenderedImage;
|
||||||
image = originalRenderedImage;
|
image = originalRenderedImage;
|
||||||
}
|
}
|
||||||
@ -357,8 +352,8 @@ export class TabView extends common.TabView {
|
|||||||
super._onSelectedIndexPropertyChangedSetNativeValue(data);
|
super._onSelectedIndexPropertyChangedSetNativeValue(data);
|
||||||
|
|
||||||
var newIndex = data.newValue;
|
var newIndex = data.newValue;
|
||||||
if (trace.enabled) {
|
if (traceEnabled) {
|
||||||
trace.write("TabView._onSelectedIndexPropertyChangedSetNativeValue(" + newIndex + ")", trace.categories.Debug);
|
traceWrite("TabView._onSelectedIndexPropertyChangedSetNativeValue(" + newIndex + ")", traceCategories.Debug);
|
||||||
}
|
}
|
||||||
if (types.isNullOrUndefined(newIndex)) {
|
if (types.isNullOrUndefined(newIndex)) {
|
||||||
return;
|
return;
|
||||||
@ -374,37 +369,38 @@ export class TabView extends common.TabView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public onMeasure(widthMeasureSpec: number, heightMeasureSpec: number): void {
|
public onMeasure(widthMeasureSpec: number, heightMeasureSpec: number): void {
|
||||||
var nativeView = this._nativeView;
|
const nativeView = this._nativeView;
|
||||||
if (nativeView) {
|
if (nativeView) {
|
||||||
|
|
||||||
var width = utils.layout.getMeasureSpecSize(widthMeasureSpec);
|
const width = layout.getMeasureSpecSize(widthMeasureSpec);
|
||||||
var widthMode = utils.layout.getMeasureSpecMode(widthMeasureSpec);
|
const widthMode = layout.getMeasureSpecMode(widthMeasureSpec);
|
||||||
|
|
||||||
var height = utils.layout.getMeasureSpecSize(heightMeasureSpec);
|
const height = layout.getMeasureSpecSize(heightMeasureSpec);
|
||||||
var heightMode = utils.layout.getMeasureSpecMode(heightMeasureSpec);
|
const heightMode = layout.getMeasureSpecMode(heightMeasureSpec);
|
||||||
|
|
||||||
this._tabBarHeight = TabView.measureHelper(this._ios.tabBar, width, widthMode, height, heightMode).height;
|
this._tabBarHeight = TabView.measureHelper(this._ios.tabBar, width, widthMode, height, heightMode).height;
|
||||||
let moreNavBarVisible = !!this._ios.moreNavigationController.navigationBar.window;
|
let moreNavBarVisible = !!this._ios.moreNavigationController.navigationBar.window;
|
||||||
this._navBarHeight = moreNavBarVisible ? TabView.measureHelper(this._ios.moreNavigationController.navigationBar, width, widthMode, height, heightMode).height : 0;
|
this._navBarHeight = moreNavBarVisible ? TabView.measureHelper(this._ios.moreNavigationController.navigationBar, width, widthMode, height, heightMode).height : 0;
|
||||||
|
|
||||||
var density = utils.layout.getDisplayDensity();
|
const density = layout.getDisplayDensity();
|
||||||
var measureWidth = 0;
|
let measureWidth = 0;
|
||||||
var measureHeight = 0;
|
let measureHeight = 0;
|
||||||
|
|
||||||
var child = this._selectedView;
|
const child = this._selectedView;
|
||||||
if (child) {
|
if (child) {
|
||||||
var childHeightMeasureSpec = utils.layout.makeMeasureSpec(height - this._navBarHeight - this._tabBarHeight, heightMode);
|
const childHeightMeasureSpec = layout.makeMeasureSpec(height - this._navBarHeight - this._tabBarHeight, heightMode);
|
||||||
var childSize = view.View.measureChild(this, child, widthMeasureSpec, childHeightMeasureSpec);
|
const childSize = View.measureChild(this, child, widthMeasureSpec, childHeightMeasureSpec);
|
||||||
|
|
||||||
measureHeight = childSize.measuredHeight;
|
measureHeight = childSize.measuredHeight;
|
||||||
measureWidth = childSize.measuredWidth;
|
measureWidth = childSize.measuredWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
measureWidth = Math.max(measureWidth, this.minWidth * density);
|
let style = this.style;
|
||||||
measureHeight = Math.max(measureHeight, this.minHeight * density);
|
measureWidth = Math.max(measureWidth, style.effectiveMinWidth * density);
|
||||||
|
measureHeight = Math.max(measureHeight, style.effectiveMinHeight * density);
|
||||||
|
|
||||||
var widthAndState = view.View.resolveSizeAndState(measureWidth, width, widthMode, 0);
|
const widthAndState = View.resolveSizeAndState(measureWidth, width, widthMode, 0);
|
||||||
var heightAndState = view.View.resolveSizeAndState(measureHeight, height, heightMode, 0);
|
const heightAndState = View.resolveSizeAndState(measureHeight, height, heightMode, 0);
|
||||||
|
|
||||||
this.setMeasuredDimension(widthAndState, heightAndState);
|
this.setMeasuredDimension(widthAndState, heightAndState);
|
||||||
}
|
}
|
||||||
@ -413,16 +409,16 @@ export class TabView extends common.TabView {
|
|||||||
public onLayout(left: number, top: number, right: number, bottom: number): void {
|
public onLayout(left: number, top: number, right: number, bottom: number): void {
|
||||||
super.onLayout(left, top, right, bottom);
|
super.onLayout(left, top, right, bottom);
|
||||||
|
|
||||||
var child = this._selectedView;
|
const child = this._selectedView;
|
||||||
if (child) {
|
if (child) {
|
||||||
view.View.layoutChild(this, child, 0, this._navBarHeight, right, (bottom - this._navBarHeight - this._tabBarHeight));
|
View.layoutChild(this, child, 0, this._navBarHeight, right, (bottom - this._navBarHeight - this._tabBarHeight));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static measureHelper(nativeView: UIView, width: number, widthMode: number, height: number, heightMode: number): CGSize {
|
private static measureHelper(nativeView: UIView, width: number, widthMode: number, height: number, heightMode: number): CGSize {
|
||||||
return nativeView.sizeThatFits(CGSizeMake(
|
return nativeView.sizeThatFits(CGSizeMake(
|
||||||
(widthMode === utils.layout.UNSPECIFIED) ? Number.POSITIVE_INFINITY : width,
|
(widthMode === layout.UNSPECIFIED) ? Number.POSITIVE_INFINITY : width,
|
||||||
(heightMode === utils.layout.UNSPECIFIED) ? Number.POSITIVE_INFINITY : height));
|
(heightMode === layout.UNSPECIFIED) ? Number.POSITIVE_INFINITY : height));
|
||||||
}
|
}
|
||||||
|
|
||||||
public _updateIOSTabBarColorsAndFonts(): void {
|
public _updateIOSTabBarColorsAndFonts(): void {
|
||||||
@ -430,10 +426,13 @@ export class TabView extends common.TabView {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var tabBar = this.ios.tabBar;
|
const tabBar = this.ios.tabBar;
|
||||||
var states = getTitleAttributesForStates(this);
|
|
||||||
for (var i = 0; i < tabBar.items.count; i++) {
|
tabBar.tintColor = this.selectedColor ? this.selectedColor.ios : null;
|
||||||
var item = <UITabBarItem>tabBar.items[i];
|
const states = getTitleAttributesForStates(this);
|
||||||
|
|
||||||
|
for (let i = 0; i < tabBar.items.count; i++) {
|
||||||
|
const item = <UITabBarItem>tabBar.items[i];
|
||||||
item.setTitleTextAttributesForState(states.normalState, UIControlState.Normal);
|
item.setTitleTextAttributesForState(states.normalState, UIControlState.Normal);
|
||||||
item.setTitleTextAttributesForState(states.selectedState, UIControlState.Selected);
|
item.setTitleTextAttributesForState(states.selectedState, UIControlState.Selected);
|
||||||
}
|
}
|
||||||
@ -459,21 +458,21 @@ export class TabView extends common.TabView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getTitleAttributesForStates(tabView: TabView): { normalState: any, selectedState: any } {
|
function getTitleAttributesForStates(tabView: TabView): { normalState: any, selectedState: any } {
|
||||||
var normalState = {};
|
const normalState = {};
|
||||||
if (tabView.tabTextColor instanceof color.Color) {
|
if (tabView.tabTextColor instanceof Color) {
|
||||||
normalState[UITextAttributeTextColor] = tabView.tabTextColor.ios;
|
normalState[UITextAttributeTextColor] = tabView.tabTextColor.ios;
|
||||||
}
|
}
|
||||||
|
|
||||||
var selectedState = {};
|
const selectedState = {};
|
||||||
if (tabView.selectedTabTextColor instanceof color.Color) {
|
if (tabView.selectedTabTextColor instanceof Color) {
|
||||||
selectedState[UITextAttributeTextColor] = tabView.selectedTabTextColor.ios;
|
selectedState[UITextAttributeTextColor] = tabView.selectedTabTextColor.ios;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
selectedState[UITextAttributeTextColor] = tabView.ios.tabBar.tintColor;
|
selectedState[UITextAttributeTextColor] = tabView.ios.tabBar.tintColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
var defaultFont = UIFont.systemFontOfSize(10);
|
const defaultFont = UIFont.systemFontOfSize(10);
|
||||||
var font = (<any>tabView.style)._fontInternal.getUIFont(defaultFont);
|
const font = (<any>tabView.style)._fontInternal.getUIFont(defaultFont);
|
||||||
normalState[NSFontAttributeName] = font;
|
normalState[NSFontAttributeName] = font;
|
||||||
selectedState[NSFontAttributeName] = font;
|
selectedState[NSFontAttributeName] = font;
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import dts = require("utils/utils");
|
import dts = require("utils/utils");
|
||||||
import common = require("./utils-common");
|
import common = require("./utils-common");
|
||||||
import {Color} from "color";
|
import { Color } from "color";
|
||||||
import enums = require("ui/enums");
|
import enums = require("ui/enums");
|
||||||
import * as fsModule from "file-system";
|
import * as fsModule from "file-system";
|
||||||
import * as traceModule from "trace";
|
import * as traceModule from "trace";
|
||||||
@ -56,9 +56,9 @@ export module ios {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getter<T>(_this: any, property: T | {(): T}): T {
|
export function getter<T>(_this: any, property: T | { (): T }): T {
|
||||||
if (typeof property === "function") {
|
if (typeof property === "function") {
|
||||||
return (<{(): T}>property).call(_this);
|
return (<{ (): T }>property).call(_this);
|
||||||
} else {
|
} else {
|
||||||
return <T>property;
|
return <T>property;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user