diff --git a/apps/tests/pages/tab-view.ts b/apps/tests/pages/tab-view.ts index 33fb3694f..56de943f9 100644 --- a/apps/tests/pages/tab-view.ts +++ b/apps/tests/pages/tab-view.ts @@ -1,15 +1,15 @@ var observableModule = require("data/observable"); var vm = new observableModule.Observable(); -function onPageLoaded(args) { +export function onPageLoaded(args) { var page = args.object; vm.set("firstTitle", "fiiiirst"); vm.set("secondTitle", "secondTitle"); vm.set("secondIcon", "res://icon"); page.bindingContext = vm; } -exports.onPageLoaded = onPageLoaded; var i = 0; -function onTap() { + +export function onTap() { i++; vm.set("firstTitle", "changed " + i); if (i === 3) { @@ -19,5 +19,15 @@ function onTap() { vm.set("firstIcon", ""); } } -exports.onTap = onTap; -//# sourceMappingURL=tab-view.js.map \ No newline at end of file + +export function setStyle(args) { + var page = args.object.actionBar.page; + + page.css = "TabView { color: red; }"; +} + +export function clearStyle(args) { + var page = args.object.actionBar.page; + + page.css = "Page { background-color: red; }"; +} diff --git a/apps/tests/pages/tab-view.xml b/apps/tests/pages/tab-view.xml index fe8700ffd..9a5306e93 100644 --- a/apps/tests/pages/tab-view.xml +++ b/apps/tests/pages/tab-view.xml @@ -1,6 +1,14 @@ - + + + + + + + + + diff --git a/org.nativescript.widgets.d.ts b/org.nativescript.widgets.d.ts index ee122f956..da1b342d8 100644 --- a/org.nativescript.widgets.d.ts +++ b/org.nativescript.widgets.d.ts @@ -152,6 +152,9 @@ setItems(items: Array, viewPager: android.support.v4.view.ViewPager): void; updateItemAt(position: number, itemSpec: TabItemSpec): void; + + getTextViewForItemAt(index: number): android.widget.TextView; + getViewForItemAt(index: number): android.widget.LinearLayout; } export class TabItemSpec { diff --git a/ui/styling/stylers.android.ts b/ui/styling/stylers.android.ts index 0efdeb45c..a7243fcec 100644 --- a/ui/styling/stylers.android.ts +++ b/ui/styling/stylers.android.ts @@ -8,6 +8,7 @@ import utils = require("utils/utils"); import styleModule = require("./style"); import font = require("ui/styling/font"); import background = require("ui/styling/background"); +import tabView = require("ui/tab-view"); var btn; global.moduleMerge(stylersCommon, exports); @@ -63,7 +64,7 @@ function onBackgroundOrBorderPropertyChanged(v: view.View) { (borderWidth + v.style.paddingTop) * density, (borderWidth + v.style.paddingRight) * density, (borderWidth + v.style.paddingBottom) * density - ); + ); } export class DefaultStyler implements definition.stylers.Styler { @@ -125,7 +126,7 @@ export class DefaultStyler implements definition.stylers.Styler { private static setNativeLayoutParamsProperty(view: view.View, params: style.CommonLayoutParams): void { var nativeView: android.view.View = view._nativeView; var lp = DefaultStyler.getNativeLayoutParams(nativeView); - + lp.leftMargin = params.leftMargin * utils.layout.getDisplayDensity(); lp.topMargin = params.topMargin * utils.layout.getDisplayDensity(); lp.rightMargin = params.rightMargin * utils.layout.getDisplayDensity(); @@ -160,7 +161,7 @@ export class DefaultStyler implements definition.stylers.Styler { case enums.HorizontalAlignment.stretch: gravity |= android.view.Gravity.FILL_HORIZONTAL; - // If width is not specified set it as MATCH_PARENT + // If width is not specified set it as MATCH_PARENT if (width < 0) { width = -1; } @@ -198,7 +199,7 @@ export class DefaultStyler implements definition.stylers.Styler { lp.gravity = gravity; lp.width = width; lp.height = height; - + nativeView.setLayoutParams(lp); } @@ -602,7 +603,7 @@ export class SearchBarStyler implements definition.stylers.Styler { private static _getSearchViewTextView(bar: android.widget.SearchView): android.widget.TextView { var id = bar.getContext().getResources().getIdentifier("android:id/search_src_text", null, null); - return bar.findViewById(id); + return bar.findViewById(id); } private static _changeSearchViewTextColor(bar: android.widget.SearchView, color: number) { @@ -614,7 +615,7 @@ export class SearchBarStyler implements definition.stylers.Styler { private static _changeSearchViewPlateBackgroundColor(bar: android.widget.SearchView, color: number) { var id = bar.getContext().getResources().getIdentifier("android:id/search_plate", null, null); - var textView = bar.findViewById(id); + var textView = bar.findViewById(id); if (textView) { textView.setBackgroundColor(color); } @@ -643,6 +644,51 @@ export class ActionBarStyler implements definition.stylers.Styler { } } +export class TabViewStyler implements definition.stylers.Styler { + // color + private static setColorProperty(view: view.View, newValue: any) { + var tab = view; + var count = tab.items ? tab.items.length : 0; + var tabLayout = tab._getAndroidTabView(); + + for (var i = 0; i < count; i++) { + tabLayout.getTextViewForItemAt(i).setTextColor(newValue); + } + } + + private static resetColorProperty(view: view.View, nativeValue: any) { + if (types.isNullOrUndefined(nativeValue)) { + return; + } + + var tab = view; + var count = tab.items ? tab.items.length : 0; + var tabLayout = tab._getAndroidTabView(); + + for (var i = 0; i < count; i++) { + tabLayout.getTextViewForItemAt(i).setTextColor(nativeValue); + } + } + + private static getColorProperty(view: view.View): any { + var tab = view; + var tv: android.widget.TextView = tab._getAndroidTabView().getTextViewForItemAt(0); + if (tv) { + return tv.getTextColors().getDefaultColor(); + } + else { + return null; + } + } + + public static registerHandlers() { + style.registerHandler(style.colorProperty, new stylersCommon.StylePropertyChangedHandler( + TabViewStyler.setColorProperty, + TabViewStyler.resetColorProperty, + TabViewStyler.getColorProperty), "TabView"); + } +} + // Register all styler at the end. export function _registerDefaultStylers() { style.registerNoStylingClass("Frame"); @@ -653,4 +699,5 @@ export function _registerDefaultStylers() { SegmentedBarStyler.registerHandlers(); SearchBarStyler.registerHandlers(); ActionBarStyler.registerHandlers(); + TabViewStyler.registerHandlers(); } diff --git a/ui/styling/stylers.ios.ts b/ui/styling/stylers.ios.ts index 4b9702134..7f7684e76 100644 --- a/ui/styling/stylers.ios.ts +++ b/ui/styling/stylers.ios.ts @@ -6,6 +6,7 @@ import enums = require("ui/enums"); import font = require("ui/styling/font"); import background = require("ui/styling/background"); import frame = require("ui/frame"); +import tabView = require("ui/tab-view"); global.moduleMerge(stylersCommon, exports); @@ -83,7 +84,7 @@ export class DefaultStyler implements definition.stylers.Styler { } private static getBorderWidthProperty(view: view.View): any { - if (view._nativeView instanceof UIView){ + if (view._nativeView instanceof UIView) { return (view._nativeView).layer.borderWidth; } return 0; @@ -500,6 +501,25 @@ export class ActionBarStyler implements definition.stylers.Styler { } } +export class TabViewStyler implements definition.stylers.Styler { + // color + private static setColorProperty(view: view.View, newValue: any) { + var tab = view; + tab._updateIOSTabBarColors(); + } + + private static resetColorProperty(view: view.View, nativeValue: any) { + var tab = view; + tab._updateIOSTabBarColors(); + } + + public static registerHandlers() { + style.registerHandler(style.colorProperty, new stylersCommon.StylePropertyChangedHandler( + TabViewStyler.setColorProperty, + TabViewStyler.resetColorProperty), "TabView"); + } +} + function setTextAlignment(view: TextUIView, value: string) { switch (value) { case enums.TextAlignment.left: @@ -526,4 +546,5 @@ export function _registerDefaultStylers() { SegmentedBarStyler.registerHandlers(); SearchBarStyler.registerHandlers(); ActionBarStyler.registerHandlers(); + TabViewStyler.registerHandlers(); } diff --git a/ui/tab-view/tab-view-common.ts b/ui/tab-view/tab-view-common.ts index 20b5a2128..e7092aac0 100644 --- a/ui/tab-view/tab-view-common.ts +++ b/ui/tab-view/tab-view-common.ts @@ -5,6 +5,7 @@ import proxy = require("ui/core/proxy"); import types = require("utils/types"); import trace = require("trace"); import bindable = require("ui/core/bindable"); +import color = require("color"); export var traceCategory = "TabView"; @@ -56,6 +57,7 @@ export class TabViewItem extends bindable.Bindable implements definition.TabView var TAB_VIEW = "TabView"; var ITEMS = "items"; var SELECTED_INDEX = "selectedIndex"; +var SELECTED_COLOR = "selectedColor"; export module knownCollections { export var items = "items"; @@ -74,6 +76,13 @@ var selectedIndexProperty = new dependencyObservable.Property( undefined, dependencyObservable.PropertyMetadataSettings.AffectsLayout)); +var selectedColorProperty = new dependencyObservable.Property( + SELECTED_COLOR, + TAB_VIEW, + new proxy.PropertyMetadata( + undefined, + dependencyObservable.PropertyMetadataSettings.None)); + (selectedIndexProperty.metadata).onSetNativeValue = function (data: dependencyObservable.PropertyChangeData) { var tabView = data.object; tabView._onSelectedIndexPropertyChangedSetNativeValue(data); @@ -87,6 +96,7 @@ var selectedIndexProperty = new dependencyObservable.Property( export class TabView extends view.View implements definition.TabView, view.AddArrayFromBuilder { public static itemsProperty = itemsProperty; public static selectedIndexProperty = selectedIndexProperty; + public static selectedColorProperty = selectedColorProperty; public static selectedIndexChangedEvent = "selectedIndexChanged"; public _addArrayFromBuilder(name: string, value: Array) { @@ -159,6 +169,14 @@ export class TabView extends view.View implements definition.TabView, view.AddAr this._setValue(TabView.selectedIndexProperty, value); } + get selectedColor(): color.Color { + return this._getValue(TabView.selectedColorProperty); + } + set selectedColor(value: color.Color) { + this._setValue(TabView.selectedColorProperty, + value instanceof color.Color ? value : new color.Color(value)); + } + public _onSelectedIndexPropertyChangedSetNativeValue(data: dependencyObservable.PropertyChangeData) { var index = this.selectedIndex; if (types.isUndefined(index)) { @@ -233,4 +251,13 @@ export class TabView extends view.View implements definition.TabView, view.AddAr } } } + + public _getAndroidTabView(): org.nativescript.widgets.TabLayout { + // Android specific + return undefined; + } + + public _updateIOSTabBarColors() { + // iOS sepcific + } } \ No newline at end of file diff --git a/ui/tab-view/tab-view.android.ts b/ui/tab-view/tab-view.android.ts index 2d86354cc..4f9515217 100644 --- a/ui/tab-view/tab-view.android.ts +++ b/ui/tab-view/tab-view.android.ts @@ -6,6 +6,8 @@ import trace = require("trace"); import types = require("utils/types"); import utils = require("utils/utils"); import imageSource = require("image-source"); +import proxy = require("ui/core/proxy"); +import color = require("color"); var VIEWS_STATES = "_viewStates"; var ACCENT_COLOR = "colorAccent"; @@ -140,6 +142,14 @@ class PageChangedListener extends android.support.v4.view.ViewPager.SimpleOnPage } } +function selectedColorPropertyChanged(data: dependencyObservable.PropertyChangeData) { + var tabLayout = (data.object)._getAndroidTabView(); + if (tabLayout && data.newValue instanceof color.Color) { + tabLayout.setSelectedIndicatorColors([data.newValue.android]); + } +} +(common.TabView.selectedColorProperty.metadata).onSetNativeValue = selectedColorPropertyChanged; + export class TabView extends common.TabView { private _grid: org.nativescript.widgets.GridLayout; private _tabLayout: org.nativescript.widgets.TabLayout; @@ -278,4 +288,8 @@ export class TabView extends common.TabView { return result; } + + public _getAndroidTabView(): org.nativescript.widgets.TabLayout { + return this._tabLayout; + } } diff --git a/ui/tab-view/tab-view.d.ts b/ui/tab-view/tab-view.d.ts index ec7fa6fec..46be5c9b2 100644 --- a/ui/tab-view/tab-view.d.ts +++ b/ui/tab-view/tab-view.d.ts @@ -6,6 +6,7 @@ declare module "ui/tab-view" { import dependencyObservable = require("ui/core/dependency-observable"); import observable = require("data/observable"); import bindable = require("ui/core/bindable"); + import color = require("color"); /** * Represents a tab view entry. @@ -48,6 +49,7 @@ declare module "ui/tab-view" { class TabView extends view.View { public static itemsProperty: dependencyObservable.Property; public static selectedIndexProperty: dependencyObservable.Property; + public static selectedColorProperty: dependencyObservable.Property; /** * Gets or sets the items of the TabView. @@ -59,6 +61,11 @@ declare module "ui/tab-view" { */ selectedIndex: number; + /** + * Gets or sets the color used for selected item. + */ + selectedColor: color.Color; + /** * Gets the native [android widget](http://developer.android.com/reference/android/support/v4/view/ViewPager.html) that represents the user interface for this component. Valid only when running on Android OS. */ @@ -86,5 +93,10 @@ declare module "ui/tab-view" { * Raised when the selected index changes. */ on(event: "selectedIndexChanged", callback: (args: SelectedIndexChangedEventData) => void, thisArg?: any); + + //@private + _getAndroidTabView(): org.nativescript.widgets.TabLayout; + _updateIOSTabBarColors(); + //@endprivate } -} \ No newline at end of file +} \ No newline at end of file diff --git a/ui/tab-view/tab-view.ios.ts b/ui/tab-view/tab-view.ios.ts index 89d460851..d73408764 100644 --- a/ui/tab-view/tab-view.ios.ts +++ b/ui/tab-view/tab-view.ios.ts @@ -7,6 +7,8 @@ import uiUtils = require("ui/utils"); import view = require("ui/core/view"); import imageSource = require("image-source"); import types = require("utils/types"); +import proxy = require("ui/core/proxy"); +import color = require("color"); global.moduleMerge(common, exports); @@ -89,11 +91,21 @@ export class TabViewItem extends common.TabViewItem { (tabBarItem).titlePositionAdjustment = { horizontal: 0, vertical: -20 }; } } + + var states = getTitleAttributesForStates(this._parent); + tabBarItem.setTitleTextAttributesForState(states.normalState, UIControlState.UIControlStateNormal); + tabBarItem.setTitleTextAttributesForState(states.selectedState, UIControlState.UIControlStateSelected); this._controller.tabBarItem = tabBarItem; } } } +function selectedColorPropertyChanged(data: dependencyObservable.PropertyChangeData) { + var tabView = data.object; + tabView._updateIOSTabBarColors(); +} +(common.TabView.selectedColorProperty.metadata).onSetNativeValue = selectedColorPropertyChanged; + export class TabView extends common.TabView { private _ios: UITabBarControllerImpl; private _delegate: UITabBarControllerDelegateImpl; @@ -124,7 +136,7 @@ export class TabView extends common.TabView { super.onUnloaded(); } - get ios(): UIViewController { + get ios(): UITabBarController { return this._ios; } @@ -295,4 +307,39 @@ export class TabView extends common.TabView { (widthMode === utils.layout.UNSPECIFIED) ? Number.POSITIVE_INFINITY : width, (heightMode === utils.layout.UNSPECIFIED) ? Number.POSITIVE_INFINITY : height)); } -} \ No newline at end of file + + public _updateIOSTabBarColors() { + if (!this.items) { + return; + } + + var tabBar = this.ios.tabBar; + var states = getTitleAttributesForStates(this); + + for (var i = 0; i < this.items.length; i++) { + var item = tabBar.items[i]; + item.setTitleTextAttributesForState(states.normalState, UIControlState.UIControlStateNormal); + item.setTitleTextAttributesForState(states.selectedState, UIControlState.UIControlStateSelected); + } + } +} + +function getTitleAttributesForStates(tabView: TabView): { normalState: any, selectedState: any } { + var normalState = {}; + if (tabView.color instanceof color.Color) { + normalState[UITextAttributeTextColor] = tabView.color.ios; + } + + var selectedState = {}; + if (tabView.selectedColor instanceof color.Color) { + selectedState[UITextAttributeTextColor] = tabView.selectedColor.ios; + } + else { + selectedState[UITextAttributeTextColor] = tabView.ios.tabBar.tintColor; + } + + return { + normalState: normalState, + selectedState: selectedState + }; +}