From f5cc51ee6d627931e869edd505268fee4abc4e9b Mon Sep 17 00:00:00 2001 From: Martin Yankov Date: Fri, 2 Aug 2019 17:43:13 +0300 Subject: [PATCH 01/10] wip: support font icons from image element --- .../app/bottom-navigation/font-icons-page.css | 18 +++++++++++++++--- .../app/bottom-navigation/font-icons-page.xml | 14 ++++++++++++-- .../bottom-navigation.android.ts | 11 ++++++----- .../bottom-navigation/bottom-navigation.ios.ts | 17 ++++++++++++++--- .../tab-strip-item/tab-strip-item.ts | 12 +++++++++++- 5 files changed, 58 insertions(+), 14 deletions(-) diff --git a/e2e/ui-tests-app/app/bottom-navigation/font-icons-page.css b/e2e/ui-tests-app/app/bottom-navigation/font-icons-page.css index ee183523d2..f2a3fa4683 100644 --- a/e2e/ui-tests-app/app/bottom-navigation/font-icons-page.css +++ b/e2e/ui-tests-app/app/bottom-navigation/font-icons-page.css @@ -6,6 +6,18 @@ font-size: 36; } -.color { - color: blue; -} \ No newline at end of file +TabStripItem.special Image { + color: teal; +} + +TabStripItem.special:active Image { + color: purple; +} + +TabStripItem.special Label { + color: gold; +} + +TabStripItem.special:active Label { + color: olive; +} \ No newline at end of file diff --git a/e2e/ui-tests-app/app/bottom-navigation/font-icons-page.xml b/e2e/ui-tests-app/app/bottom-navigation/font-icons-page.xml index 644cdb121a..d843f8f021 100644 --- a/e2e/ui-tests-app/app/bottom-navigation/font-icons-page.xml +++ b/e2e/ui-tests-app/app/bottom-navigation/font-icons-page.xml @@ -3,10 +3,20 @@ - + - + + + + + + + + diff --git a/tns-core-modules/ui/bottom-navigation/bottom-navigation.android.ts b/tns-core-modules/ui/bottom-navigation/bottom-navigation.android.ts index 2051ad123c..eae0adaee7 100644 --- a/tns-core-modules/ui/bottom-navigation/bottom-navigation.android.ts +++ b/tns-core-modules/ui/bottom-navigation/bottom-navigation.android.ts @@ -188,13 +188,14 @@ function createTabItemSpec(tabStripItem: TabStripItem): org.nativescript.widgets } } else { let is = new ImageSource(); - if (isFontIconURI(tabStripItem.iconSource)) { - const fontIconCode = tabStripItem.iconSource.split("//")[1]; - const font = tabStripItem.style.fontInternal; - const color = tabStripItem.style.color; + if (isFontIconURI(iconSource)) { + const fontIconCode = iconSource.split("//")[1]; + const target = tabStripItem.image ? tabStripItem.image : tabStripItem; + const font = target.style.fontInternal; + const color = target.style.color; is = fromFontIconCode(fontIconCode, font, color); } else { - is = fromFileOrResource(tabStripItem.iconSource); + is = fromFileOrResource(iconSource); } if (is) { diff --git a/tns-core-modules/ui/bottom-navigation/bottom-navigation.ios.ts b/tns-core-modules/ui/bottom-navigation/bottom-navigation.ios.ts index 8f8918d309..e7233cbe57 100644 --- a/tns-core-modules/ui/bottom-navigation/bottom-navigation.ios.ts +++ b/tns-core-modules/ui/bottom-navigation/bottom-navigation.ios.ts @@ -259,6 +259,8 @@ export class BottomNavigation extends TabNavigationBase { public onLoaded() { super.onLoaded(); + this.setViewControllers(this.items); + const selectedIndex = this.selectedIndex; const selectedView = this.items && this.items[selectedIndex] && this.items[selectedIndex].content; if (selectedView instanceof Frame) { @@ -554,13 +556,16 @@ export class BottomNavigation extends TabNavigationBase { return null; } - let image: UIImage = this._iconsCache[iconSource]; + const target = tabStripItem.image ? tabStripItem.image : tabStripItem; + const font = target.style.fontInternal; + const color = target.style.color; + const iconTag = [iconSource, font.fontStyle, font.fontWeight, font.fontSize, font.fontFamily, color].join(";"); + + let image: UIImage = this._iconsCache[iconTag]; if (!image) { let is = new ImageSource; if (isFontIconURI(iconSource)) { const fontIconCode = iconSource.split("//")[1]; - const font = tabStripItem.style.fontInternal; - const color = tabStripItem.style.color; is = fromFontIconCode(fontIconCode, font, color); } else { is = fromFileOrResource(iconSource); @@ -615,6 +620,12 @@ export class BottomNavigation extends TabNavigationBase { return null; } [itemsProperty.setNative](value: TabContentItem[]) { + if (value) { + value.forEach((item: TabContentItem, i) => { + (item).index = i; + }); + } + this.setViewControllers(value); selectedIndexProperty.coerce(this); } diff --git a/tns-core-modules/ui/tab-navigation-base/tab-strip-item/tab-strip-item.ts b/tns-core-modules/ui/tab-navigation-base/tab-strip-item/tab-strip-item.ts index 9d81137f90..c334346b09 100644 --- a/tns-core-modules/ui/tab-navigation-base/tab-strip-item/tab-strip-item.ts +++ b/tns-core-modules/ui/tab-navigation-base/tab-strip-item/tab-strip-item.ts @@ -9,7 +9,7 @@ import { AddChildFromBuilder } from "../../core/view"; // Requires import { - View, CSSType, backgroundColorProperty, backgroundInternalProperty, colorProperty, + View, ViewBase, CSSType, backgroundColorProperty, backgroundInternalProperty, colorProperty, fontSizeProperty, fontInternalProperty, PseudoClassHandler } from "../../core/view"; import { textTransformProperty, TextTransform } from "../../text-base"; @@ -31,6 +31,16 @@ export class TabStripItem extends View implements TabStripItemDefinition, AddChi private _highlightedHandler: () => void; private _normalHandler: () => void; + public eachChild(callback: (child: ViewBase) => boolean) { + if (this.label) { + callback(this.label); + } + + if (this.image) { + callback(this.image); + } + } + public _addChildFromBuilder(name: string, value: any): void { if (name === "Image") { this.image = value; From 327c761a36df922e2f954674a806ab9160456805 Mon Sep 17 00:00:00 2001 From: Martin Yankov Date: Tue, 6 Aug 2019 17:27:41 +0300 Subject: [PATCH 02/10] wip: add bottom navigation custom font icons --- .../app/bottom-navigation/font-icons-page.css | 14 ++++- .../app/bottom-navigation/font-icons-page.xml | 59 ++++++++++++------- .../bottom-navigation.ios.ts | 38 +++++------- .../tab-strip-item/tab-strip-item.ts | 46 +++++++++++---- 4 files changed, 97 insertions(+), 60 deletions(-) diff --git a/e2e/ui-tests-app/app/bottom-navigation/font-icons-page.css b/e2e/ui-tests-app/app/bottom-navigation/font-icons-page.css index f2a3fa4683..4c7b99d2aa 100644 --- a/e2e/ui-tests-app/app/bottom-navigation/font-icons-page.css +++ b/e2e/ui-tests-app/app/bottom-navigation/font-icons-page.css @@ -6,12 +6,20 @@ font-size: 36; } +TabStripItem { + color: skyblue; +} + +TabStripItem:active { + color: darkblue; +} + TabStripItem.special Image { - color: teal; + color: lightgreen; } TabStripItem.special:active Image { - color: purple; + color: darkgreen; } TabStripItem.special Label { @@ -19,5 +27,5 @@ TabStripItem.special Label { } TabStripItem.special:active Label { - color: olive; + color: darkgoldenrod; } \ No newline at end of file diff --git a/e2e/ui-tests-app/app/bottom-navigation/font-icons-page.xml b/e2e/ui-tests-app/app/bottom-navigation/font-icons-page.xml index d843f8f021..c72f3320f4 100644 --- a/e2e/ui-tests-app/app/bottom-navigation/font-icons-page.xml +++ b/e2e/ui-tests-app/app/bottom-navigation/font-icons-page.xml @@ -5,40 +5,59 @@ - - - - - - - - + + - - + + - - + + \ No newline at end of file diff --git a/tns-core-modules/ui/bottom-navigation/bottom-navigation.ios.ts b/tns-core-modules/ui/bottom-navigation/bottom-navigation.ios.ts index e7233cbe57..565b4418af 100644 --- a/tns-core-modules/ui/bottom-navigation/bottom-navigation.ios.ts +++ b/tns-core-modules/ui/bottom-navigation/bottom-navigation.ios.ts @@ -322,23 +322,6 @@ export class BottomNavigation extends TabNavigationBase { this._ios.tabBar.barTintColor = value instanceof Color ? value.ios : value; } - public getTabBarColor(): UIColor { - return this._ios.tabBar.tintColor; - } - - public setTabBarColor(value: UIColor | Color): void { - this._ios.tabBar.tintColor = value instanceof Color ? value.ios : value; - - if (!this.tabStrip) { - return; - } - - const states = getTitleAttributesForStates(this.tabStrip); - this.tabStrip.items.forEach((tabStripItem) => { - applyStatesToItem(tabStripItem.nativeView, states); - }); - } - public setTabBarItemBackgroundColor(tabStripItem: TabStripItem, value: UIColor | Color): void { if (!this.tabStrip) { return; @@ -362,10 +345,17 @@ export class BottomNavigation extends TabNavigationBase { } public setTabBarItemColor(tabStripItem: TabStripItem, value: UIColor | Color): void { - const states = getTitleAttributesForStates(tabStripItem); + const states = getTitleAttributesForStates(tabStripItem.label); applyStatesToItem(tabStripItem.nativeView, states); } + public setTabBarIconColor(tabStripItem: TabStripItem, value: UIColor | Color): void { + const image = this._getIcon(tabStripItem); + + tabStripItem.nativeView.image = image; + tabStripItem.nativeView.selectedImage = image; + } + public getTabBarItemFontSize(tabStripItem: TabStripItem): number { return null; } @@ -501,7 +491,6 @@ export class BottomNavigation extends TabNavigationBase { items = items.slice(0, maxTabsCount); const controllers = NSMutableArray.alloc().initWithCapacity(length); - const states = getTitleAttributesForStates(this); if (this.tabStrip) { this.tabStrip.setNativeView(this._ios.tabBar); @@ -515,6 +504,7 @@ export class BottomNavigation extends TabNavigationBase { const tabBarItem = this.createTabBarItem(tabStripItem, i); updateTitleAndIconPositions(tabStripItem, tabBarItem, controller); + const states = getTitleAttributesForStates(tabStripItem.label); applyStatesToItem(tabBarItem, states); controller.tabBarItem = tabBarItem; @@ -536,8 +526,8 @@ export class BottomNavigation extends TabNavigationBase { let image: UIImage; let title: string; - image = this._getIcon(item); - title = item.label ? item.label.text : item.title; + image = item.isLoaded && this._getIcon(item); + title = item.label && item.label.text; const tabBarItem = UITabBarItem.alloc().initWithTitleImageTag(title, image, index); @@ -551,12 +541,12 @@ export class BottomNavigation extends TabNavigationBase { public _getIcon(tabStripItem: TabStripItem): UIImage { // Image and Label children of TabStripItem // take priority over its `iconSource` and `title` properties - const iconSource = tabStripItem.image ? tabStripItem.image.src : tabStripItem.iconSource; + const iconSource = tabStripItem.image && tabStripItem.image.src; if (!iconSource) { return null; } - const target = tabStripItem.image ? tabStripItem.image : tabStripItem; + const target = tabStripItem.image; const font = target.style.fontInternal; const color = target.style.color; const iconTag = [iconSource, font.fontStyle, font.fontWeight, font.fontSize, font.fontFamily, color].join(";"); @@ -573,7 +563,7 @@ export class BottomNavigation extends TabNavigationBase { if (is && is.ios) { const originalRenderedImage = is.ios.imageWithRenderingMode(this._getIconRenderingMode()); - this._iconsCache[iconSource] = originalRenderedImage; + this._iconsCache[iconTag] = originalRenderedImage; image = originalRenderedImage; } else { // TODO diff --git a/tns-core-modules/ui/tab-navigation-base/tab-strip-item/tab-strip-item.ts b/tns-core-modules/ui/tab-navigation-base/tab-strip-item/tab-strip-item.ts index c334346b09..55f7876bf7 100644 --- a/tns-core-modules/ui/tab-navigation-base/tab-strip-item/tab-strip-item.ts +++ b/tns-core-modules/ui/tab-navigation-base/tab-strip-item/tab-strip-item.ts @@ -1,5 +1,6 @@ // Types import { TabStripItem as TabStripItemDefinition } from "."; +import { PropertyChangeData } from "../../../data/observable"; import { TabNavigationBase } from "../tab-navigation-base"; import { TabStrip } from "../tab-strip"; import { Image } from "../../image/image"; @@ -31,6 +32,38 @@ export class TabStripItem extends View implements TabStripItemDefinition, AddChi private _highlightedHandler: () => void; private _normalHandler: () => void; + public onLoaded() { + if (!this.image) { + const image = new Image(); + image.src = this.iconSource; + this.image = image; + this._addView(this.image); + } + + if (!this.label) { + const label = new Label(); + label.text = this.title; + this.label = label; + this._addView(this.label); + } + + super.onLoaded(); + + this.label.style.addEventListener("colorChange", (args: PropertyChangeData) => { + const parent = this.parent; + const tabStripParent = parent && parent.parent; + + return tabStripParent && tabStripParent.setTabBarItemColor(this, args.value); + }); + + this.image.style.addEventListener("colorChange", (args: PropertyChangeData) => { + const parent = this.parent; + const tabStripParent = parent && parent.parent; + + return tabStripParent && (tabStripParent).setTabBarIconColor(this, args.value); + }); + } + public eachChild(callback: (child: ViewBase) => boolean) { if (this.label) { callback(this.label); @@ -110,19 +143,6 @@ export class TabStripItem extends View implements TabStripItemDefinition, AddChi // disable the background CSS properties } - [colorProperty.getDefault](): Color { - const parent = this.parent; - const tabStripParent = parent && parent.parent; - - return tabStripParent && tabStripParent.getTabBarItemColor(this); - } - [colorProperty.setNative](value: Color) { - const parent = this.parent; - const tabStripParent = parent && parent.parent; - - return tabStripParent && tabStripParent.setTabBarItemColor(this, value); - } - [fontSizeProperty.getDefault](): { nativeSize: number } { const parent = this.parent; const tabStripParent = parent && parent.parent; From ae894bbf4dfa0a2edb5e1991f378b79f7223a5a8 Mon Sep 17 00:00:00 2001 From: MartoYankov Date: Wed, 7 Aug 2019 16:54:49 +0300 Subject: [PATCH 03/10] wip: implement color for all tabs --- .../app/bottom-navigation/font-icons-page.css | 4 ++ e2e/ui-tests-app/app/tabs/font-icons-page.css | 30 +++++++- e2e/ui-tests-app/app/tabs/font-icons-page.xml | 57 +++++++++++---- .../widgets/BottomNavigationBar.java | 4 ++ .../org/nativescript/widgets/TabItemSpec.java | 1 + .../bottom-navigation.android.ts | 71 ++++++++++--------- tns-core-modules/ui/tabs/tabs.android.ts | 61 +++++++++++----- tns-core-modules/ui/tabs/tabs.ios.ts | 25 ++++--- .../android/org.nativescript.widgets.d.ts | 1 + 9 files changed, 173 insertions(+), 81 deletions(-) diff --git a/e2e/ui-tests-app/app/bottom-navigation/font-icons-page.css b/e2e/ui-tests-app/app/bottom-navigation/font-icons-page.css index 4c7b99d2aa..3c1767b852 100644 --- a/e2e/ui-tests-app/app/bottom-navigation/font-icons-page.css +++ b/e2e/ui-tests-app/app/bottom-navigation/font-icons-page.css @@ -6,6 +6,10 @@ font-size: 36; } +TabStrip { + color: mediumvioletred; +} + TabStripItem { color: skyblue; } diff --git a/e2e/ui-tests-app/app/tabs/font-icons-page.css b/e2e/ui-tests-app/app/tabs/font-icons-page.css index ee183523d2..3c1767b852 100644 --- a/e2e/ui-tests-app/app/tabs/font-icons-page.css +++ b/e2e/ui-tests-app/app/tabs/font-icons-page.css @@ -6,6 +6,30 @@ font-size: 36; } -.color { - color: blue; -} \ No newline at end of file +TabStrip { + color: mediumvioletred; +} + +TabStripItem { + color: skyblue; +} + +TabStripItem:active { + color: darkblue; +} + +TabStripItem.special Image { + color: lightgreen; +} + +TabStripItem.special:active Image { + color: darkgreen; +} + +TabStripItem.special Label { + color: gold; +} + +TabStripItem.special:active Label { + color: darkgoldenrod; +} \ No newline at end of file diff --git a/e2e/ui-tests-app/app/tabs/font-icons-page.xml b/e2e/ui-tests-app/app/tabs/font-icons-page.xml index 317d5def4d..0a31a8d761 100644 --- a/e2e/ui-tests-app/app/tabs/font-icons-page.xml +++ b/e2e/ui-tests-app/app/tabs/font-icons-page.xml @@ -3,32 +3,61 @@ - + - - + + + + - + + + - + + - - + + - - + + - - + + \ No newline at end of file diff --git a/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/BottomNavigationBar.java b/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/BottomNavigationBar.java index 29a5c04920..e6a01f822c 100644 --- a/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/BottomNavigationBar.java +++ b/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/BottomNavigationBar.java @@ -205,6 +205,10 @@ private void setupItem(LinearLayout ll, TextView textView,ImageView imgView, Tab textView.setVisibility(GONE); } + if (tabItem.color != 0) { + textView.setTextColor(tabItem.color); + } + if (tabItem.backgroundColor != 0) { ll.setBackgroundColor(tabItem.backgroundColor); } diff --git a/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabItemSpec.java b/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabItemSpec.java index 2aa6ff08b7..fc581db76d 100644 --- a/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabItemSpec.java +++ b/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabItemSpec.java @@ -7,4 +7,5 @@ public class TabItemSpec { public int iconId; public Drawable iconDrawable; public int backgroundColor; + public int color; } \ No newline at end of file diff --git a/tns-core-modules/ui/bottom-navigation/bottom-navigation.android.ts b/tns-core-modules/ui/bottom-navigation/bottom-navigation.android.ts index eae0adaee7..ce2d1b4dd2 100644 --- a/tns-core-modules/ui/bottom-navigation/bottom-navigation.android.ts +++ b/tns-core-modules/ui/bottom-navigation/bottom-navigation.android.ts @@ -170,15 +170,17 @@ function createTabItemSpec(tabStripItem: TabStripItem): org.nativescript.widgets let iconSource; const tabItemSpec = new org.nativescript.widgets.TabItemSpec(); - // Image and Label children of TabStripItem - // take priority over its `iconSource` and `title` properties - iconSource = tabStripItem.image ? tabStripItem.image.src : tabStripItem.iconSource; - tabItemSpec.title = tabStripItem.label ? tabStripItem.label.text : tabStripItem.title; - + tabItemSpec.title = tabStripItem.label && tabStripItem.label.text; + if (tabStripItem.backgroundColor instanceof Color) { tabItemSpec.backgroundColor = tabStripItem.backgroundColor.android; } - + + if (tabStripItem.label && tabStripItem.label.style.color instanceof Color) { + tabItemSpec.color = tabStripItem.label.style.color.android; + } + + iconSource = tabStripItem.image && tabStripItem.image.src; if (iconSource) { if (iconSource.indexOf(RESOURCE_PREFIX) === 0) { tabItemSpec.iconId = ad.resources.getDrawableId(iconSource.substr(RESOURCE_PREFIX.length)); @@ -187,21 +189,12 @@ function createTabItemSpec(tabStripItem: TabStripItem): org.nativescript.widgets // traceMissingIcon(iconSource); } } else { - let is = new ImageSource(); - if (isFontIconURI(iconSource)) { - const fontIconCode = iconSource.split("//")[1]; - const target = tabStripItem.image ? tabStripItem.image : tabStripItem; - const font = target.style.fontInternal; - const color = target.style.color; - is = fromFontIconCode(fontIconCode, font, color); - } else { - is = fromFileOrResource(iconSource); - } + const icon = _getIcon(tabStripItem); - if (is) { + if (icon) { // TODO: Make this native call that accepts string so that we don't load Bitmap in JS. // tslint:disable-next-line:deprecation - tabItemSpec.iconDrawable = new android.graphics.drawable.BitmapDrawable(application.android.context.getResources(), is.android); + tabItemSpec.iconDrawable = icon; } else { // TODO: // traceMissingIcon(iconSource); @@ -212,6 +205,25 @@ function createTabItemSpec(tabStripItem: TabStripItem): org.nativescript.widgets return tabItemSpec; } +function _getIcon(tabStripItem: TabStripItem): android.graphics.drawable.BitmapDrawable { + const iconSource = tabStripItem.image && tabStripItem.image.src; + + let is = new ImageSource(); + if (isFontIconURI(iconSource)) { + const fontIconCode = iconSource.split("//")[1]; + const target = tabStripItem.image ? tabStripItem.image : tabStripItem; + const font = target.style.fontInternal; + const color = target.style.color; + is = fromFontIconCode(fontIconCode, font, color); + } else { + is = fromFileOrResource(iconSource); + } + + const image = new android.graphics.drawable.BitmapDrawable(application.android.context.getResources(), is.android); + + return image; +} + function setElevation(bottomNavigationBar: org.nativescript.widgets.BottomNavigationBar) { const compat = androidx.core.view.ViewCompat; if (compat.setElevation) { @@ -562,20 +574,6 @@ export class BottomNavigation extends TabNavigationBase { } } - public getTabBarColor(): number { - return this._bottomNavigationBar.getTabTextColor(); - } - - public setTabBarColor(value: number | Color): void { - if (value instanceof Color) { - this._bottomNavigationBar.setTabTextColor(value.android); - this._bottomNavigationBar.setSelectedTabTextColor(value.android); - } else { - this._bottomNavigationBar.setTabTextColor(value); - this._bottomNavigationBar.setSelectedTabTextColor(value); - } - } - public setTabBarItemBackgroundColor(tabStripItem: TabStripItem, value: android.graphics.drawable.Drawable | Color): void { // TODO: Should figure out a way to do it directly with the the nativeView const tabStripItemIndex = this.tabStrip.items.indexOf(tabStripItem); @@ -595,6 +593,15 @@ export class BottomNavigation extends TabNavigationBase { } } + public setTabBarIconColor(tabStripItem: TabStripItem, value: number | Color): void { + const index = (tabStripItem).index; + const tabBarItem = this._bottomNavigationBar.getViewForItemAt(index); + const imgView = tabBarItem.getChildAt(0); + const drawable = _getIcon(tabStripItem); + + imgView.setImageDrawable(drawable); + } + public getTabBarItemFontSize(tabStripItem: TabStripItem): { nativeSize: number } { return { nativeSize: tabStripItem.nativeViewProtected.getTextSize() }; } diff --git a/tns-core-modules/ui/tabs/tabs.android.ts b/tns-core-modules/ui/tabs/tabs.android.ts index fbfa0929bb..53ce34f284 100644 --- a/tns-core-modules/ui/tabs/tabs.android.ts +++ b/tns-core-modules/ui/tabs/tabs.android.ts @@ -287,38 +287,33 @@ function createTabItemSpec(tabStripItem: TabStripItem): org.nativescript.widgets let iconSource; const tabItemSpec = new org.nativescript.widgets.TabItemSpec(); + tabItemSpec.title = tabStripItem.label && tabStripItem.label.text; + if (tabStripItem.backgroundColor instanceof Color) { tabItemSpec.backgroundColor = tabStripItem.backgroundColor.android; } - - // Image and Label children of TabStripItem - // take priority over its `iconSource` and `title` properties - iconSource = tabStripItem.image ? tabStripItem.image.src : tabStripItem.iconSource; - tabItemSpec.title = tabStripItem.label ? tabStripItem.label.text : tabStripItem.title; - + + if (tabStripItem.label && tabStripItem.label.style.color instanceof Color) { + tabItemSpec.color = tabStripItem.label.style.color.android; + } + + iconSource = tabStripItem.image && tabStripItem.image.src; if (iconSource) { if (iconSource.indexOf(RESOURCE_PREFIX) === 0) { tabItemSpec.iconId = ad.resources.getDrawableId(iconSource.substr(RESOURCE_PREFIX.length)); if (tabItemSpec.iconId === 0) { - // TODO + // TODO: // traceMissingIcon(iconSource); } } else { - let is = new ImageSource(); - if (isFontIconURI(tabStripItem.iconSource)) { - const fontIconCode = tabStripItem.iconSource.split("//")[1]; - const font = tabStripItem.style.fontInternal; - const color = tabStripItem.style.color; - is = fromFontIconCode(fontIconCode, font, color); - } else { - is = fromFileOrResource(tabStripItem.iconSource); - } + const icon = _getIcon(tabStripItem); - if (is) { + if (icon) { // TODO: Make this native call that accepts string so that we don't load Bitmap in JS. - tabItemSpec.iconDrawable = new android.graphics.drawable.BitmapDrawable(application.android.context.getResources(), is.android); + // tslint:disable-next-line:deprecation + tabItemSpec.iconDrawable = icon; } else { - // TODO + // TODO: // traceMissingIcon(iconSource); } } @@ -327,6 +322,25 @@ function createTabItemSpec(tabStripItem: TabStripItem): org.nativescript.widgets return tabItemSpec; } +function _getIcon(tabStripItem: TabStripItem): android.graphics.drawable.BitmapDrawable { + const iconSource = tabStripItem.image && tabStripItem.image.src; + + let is = new ImageSource(); + if (isFontIconURI(iconSource)) { + const fontIconCode = iconSource.split("//")[1]; + const target = tabStripItem.image ? tabStripItem.image : tabStripItem; + const font = target.style.fontInternal; + const color = target.style.color; + is = fromFontIconCode(fontIconCode, font, color); + } else { + is = fromFileOrResource(iconSource); + } + + const image = new android.graphics.drawable.BitmapDrawable(application.android.context.getResources(), is.android); + + return image; +} + let defaultAccentColor: number = undefined; function getDefaultAccentColor(context: android.content.Context): number { if (defaultAccentColor === undefined) { @@ -707,6 +721,15 @@ export class Tabs extends TabsBase { } } + public setTabBarIconColor(tabStripItem: TabStripItem, value: number | Color): void { + const index = (tabStripItem).index; + const tabBarItem = this._tabLayout.getViewForItemAt(index); + const imgView = tabBarItem.getChildAt(0); + const drawable = _getIcon(tabStripItem); + + imgView.setImageDrawable(drawable); + } + public getTabBarItemFontSize(tabStripItem: TabStripItem): { nativeSize: number } { return { nativeSize: tabStripItem.nativeViewProtected.getTextSize() }; } diff --git a/tns-core-modules/ui/tabs/tabs.ios.ts b/tns-core-modules/ui/tabs/tabs.ios.ts index d278ac4c6f..2bceb236d0 100644 --- a/tns-core-modules/ui/tabs/tabs.ios.ts +++ b/tns-core-modules/ui/tabs/tabs.ios.ts @@ -528,10 +528,8 @@ export class Tabs extends TabsBase { this._ios.dataSource = this._dataSource; this._ios.delegate = this._delegate; - if (!this.tabBarItems) { - const tabStripItems = this.tabStrip ? this.tabStrip.items : null; - this.setTabStripItems(tabStripItems); - } + const tabStripItems = this.tabStrip ? this.tabStrip.items : null; + this.setTabStripItems(tabStripItems); } public onUnloaded() { @@ -838,8 +836,8 @@ export class Tabs extends TabsBase { let image: UIImage; let title: string; - image = this._getIcon(item); - title = item.label ? item.label.text : item.title; + image = item.isLoaded && this._getIcon(item); + title = item.label && item.label.text; if (!this.tabStrip._hasImage) { this.tabStrip._hasImage = !!image; @@ -872,20 +870,21 @@ export class Tabs extends TabsBase { } public _getIcon(tabStripItem: TabStripItem): UIImage { - // Image and Label children of TabStripItem - // take priority over its `iconSource` and `title` properties - const iconSource = tabStripItem.image ? tabStripItem.image.src : tabStripItem.iconSource; + const iconSource = tabStripItem.image && tabStripItem.image.src; if (!iconSource) { return null; } - let image: UIImage = this._iconsCache[iconSource]; + const target = tabStripItem.image; + const font = target.style.fontInternal; + const color = target.style.color; + const iconTag = [iconSource, font.fontStyle, font.fontWeight, font.fontSize, font.fontFamily, color].join(";"); + + let image: UIImage = this._iconsCache[iconTag]; if (!image) { let is = new ImageSource; if (isFontIconURI(iconSource)) { const fontIconCode = iconSource.split("//")[1]; - const font = tabStripItem.style.fontInternal; - const color = tabStripItem.style.color; is = fromFontIconCode(fontIconCode, font, color); } else { is = fromFileOrResource(iconSource); @@ -893,7 +892,7 @@ export class Tabs extends TabsBase { if (is && is.ios) { const originalRenderedImage = is.ios.imageWithRenderingMode(this._getIconRenderingMode()); - this._iconsCache[iconSource] = originalRenderedImage; + this._iconsCache[iconTag] = originalRenderedImage; image = originalRenderedImage; } else { // TODO diff --git a/tns-platform-declarations/android/org.nativescript.widgets.d.ts b/tns-platform-declarations/android/org.nativescript.widgets.d.ts index b78e57aa25..333e4a6b9d 100644 --- a/tns-platform-declarations/android/org.nativescript.widgets.d.ts +++ b/tns-platform-declarations/android/org.nativescript.widgets.d.ts @@ -455,6 +455,7 @@ iconId: number; iconDrawable: android.graphics.drawable.Drawable; backgroundColor: number; + color: number; } export namespace image { From 4e16c039fba394d2fb58ffec7f10ee9334294131 Mon Sep 17 00:00:00 2001 From: MartoYankov Date: Thu, 8 Aug 2019 11:04:35 +0300 Subject: [PATCH 04/10] chore: merge master --- tns-core-modules/ui/tabs/tabs.android.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tns-core-modules/ui/tabs/tabs.android.ts b/tns-core-modules/ui/tabs/tabs.android.ts index 53ce34f284..fa11bc11ae 100644 --- a/tns-core-modules/ui/tabs/tabs.android.ts +++ b/tns-core-modules/ui/tabs/tabs.android.ts @@ -723,7 +723,7 @@ export class Tabs extends TabsBase { public setTabBarIconColor(tabStripItem: TabStripItem, value: number | Color): void { const index = (tabStripItem).index; - const tabBarItem = this._tabLayout.getViewForItemAt(index); + const tabBarItem = this._tabsBar.getViewForItemAt(index); const imgView = tabBarItem.getChildAt(0); const drawable = _getIcon(tabStripItem); From ef6c6eb3996b6b1eae6819a16bec1bb843949b49 Mon Sep 17 00:00:00 2001 From: MartoYankov Date: Fri, 9 Aug 2019 17:41:09 +0300 Subject: [PATCH 05/10] wip: implement listeners for nested label --- .../app/bottom-navigation/color-page.css | 8 + .../app/bottom-navigation/color-page.xml | 15 +- .../app/bottom-navigation/font-page.css | 8 + .../app/bottom-navigation/font-page.xml | 17 ++- .../bottom-navigation/text-transform-page.css | 8 + .../bottom-navigation/text-transform-page.xml | 13 +- e2e/ui-tests-app/app/tabs/color-page.css | 8 + e2e/ui-tests-app/app/tabs/color-page.xml | 17 ++- e2e/ui-tests-app/app/tabs/font-page.css | 8 + e2e/ui-tests-app/app/tabs/font-page.xml | 15 +- .../app/tabs/text-transform-page.css | 8 + .../app/tabs/text-transform-page.xml | 13 +- tests/package.json | 4 +- .../widgets/BottomNavigationBar.java | 11 +- .../org/nativescript/widgets/TabItemSpec.java | 3 + .../org/nativescript/widgets/TabStrip.java | 28 ++-- .../org/nativescript/widgets/TabsBar.java | 14 +- tns-core-modules/package.json | 2 +- .../bottom-navigation.android.ts | 123 +++++++--------- .../bottom-navigation.ios.ts | 36 ++--- .../tab-strip-item/tab-strip-item.ts | 77 +++++----- tns-core-modules/ui/tabs/tabs.android.ts | 137 +++++++----------- .../android/org.nativescript.widgets.d.ts | 2 + 23 files changed, 327 insertions(+), 248 deletions(-) diff --git a/e2e/ui-tests-app/app/bottom-navigation/color-page.css b/e2e/ui-tests-app/app/bottom-navigation/color-page.css index 17d688073f..3b7744d0d1 100644 --- a/e2e/ui-tests-app/app/bottom-navigation/color-page.css +++ b/e2e/ui-tests-app/app/bottom-navigation/color-page.css @@ -17,3 +17,11 @@ TabStripItem.special { TabStripItem.special:active { color: yellowgreen; } + +TabStripItem.nested Label { + color: teal; +} + +TabStripItem.nested:active Label { + color: yellowgreen; +} diff --git a/e2e/ui-tests-app/app/bottom-navigation/color-page.xml b/e2e/ui-tests-app/app/bottom-navigation/color-page.xml index b8c3e9d4ef..b63d6c8c47 100644 --- a/e2e/ui-tests-app/app/bottom-navigation/color-page.xml +++ b/e2e/ui-tests-app/app/bottom-navigation/color-page.xml @@ -3,10 +3,13 @@ - + - - + + + + @@ -20,5 +23,11 @@ + + + + + \ No newline at end of file diff --git a/e2e/ui-tests-app/app/bottom-navigation/font-page.css b/e2e/ui-tests-app/app/bottom-navigation/font-page.css index 22a3ce46c1..57b0eda891 100644 --- a/e2e/ui-tests-app/app/bottom-navigation/font-page.css +++ b/e2e/ui-tests-app/app/bottom-navigation/font-page.css @@ -17,3 +17,11 @@ TabStripItem.special { TabStripItem.special:active { font: 16 monospace; } + +TabStripItem.nested Label { + font: 12 monospace; +} + +TabStripItem.nested:active Label { + font: 16 monospace; +} diff --git a/e2e/ui-tests-app/app/bottom-navigation/font-page.xml b/e2e/ui-tests-app/app/bottom-navigation/font-page.xml index 6da1c62334..b59f818d80 100644 --- a/e2e/ui-tests-app/app/bottom-navigation/font-page.xml +++ b/e2e/ui-tests-app/app/bottom-navigation/font-page.xml @@ -1,12 +1,15 @@ - + - + - - + + + + @@ -20,5 +23,11 @@ + + + + + \ No newline at end of file diff --git a/e2e/ui-tests-app/app/bottom-navigation/text-transform-page.css b/e2e/ui-tests-app/app/bottom-navigation/text-transform-page.css index 80b3649d42..539c8c8172 100644 --- a/e2e/ui-tests-app/app/bottom-navigation/text-transform-page.css +++ b/e2e/ui-tests-app/app/bottom-navigation/text-transform-page.css @@ -17,3 +17,11 @@ TabStripItem.special { TabStripItem.special:active { text-transform: uppercase; } + +TabStripItem.nested Label { + text-transform: lowercase; +} + +TabStripItem.nested:active Label { + text-transform: uppercase; +} diff --git a/e2e/ui-tests-app/app/bottom-navigation/text-transform-page.xml b/e2e/ui-tests-app/app/bottom-navigation/text-transform-page.xml index 33db487c6d..dcddb8bd62 100644 --- a/e2e/ui-tests-app/app/bottom-navigation/text-transform-page.xml +++ b/e2e/ui-tests-app/app/bottom-navigation/text-transform-page.xml @@ -1,12 +1,15 @@ - + - + + + @@ -20,5 +23,11 @@ + + + + + \ No newline at end of file diff --git a/e2e/ui-tests-app/app/tabs/color-page.css b/e2e/ui-tests-app/app/tabs/color-page.css index b417cfecf7..97c0d950b2 100644 --- a/e2e/ui-tests-app/app/tabs/color-page.css +++ b/e2e/ui-tests-app/app/tabs/color-page.css @@ -17,3 +17,11 @@ TabStripItem.special { TabStripItem.special:active { color: yellowgreen; } + +TabStripItem.nested Label { + color: teal; +} + +TabStripItem.nested:active Label { + color: yellowgreen; +} diff --git a/e2e/ui-tests-app/app/tabs/color-page.xml b/e2e/ui-tests-app/app/tabs/color-page.xml index be732a6c3e..5741956f52 100644 --- a/e2e/ui-tests-app/app/tabs/color-page.xml +++ b/e2e/ui-tests-app/app/tabs/color-page.xml @@ -1,12 +1,15 @@ - + - + - - + + + + @@ -20,5 +23,11 @@ + + + + + \ No newline at end of file diff --git a/e2e/ui-tests-app/app/tabs/font-page.css b/e2e/ui-tests-app/app/tabs/font-page.css index 1e28cb2a52..d2473e4d7e 100644 --- a/e2e/ui-tests-app/app/tabs/font-page.css +++ b/e2e/ui-tests-app/app/tabs/font-page.css @@ -17,3 +17,11 @@ TabStripItem.special { TabStripItem.special:active { font: 16 monospace; } + +TabStripItem.nested Label { + font: 12 monospace; +} + +TabStripItem.nested:active Label { + font: 16 monospace; +} diff --git a/e2e/ui-tests-app/app/tabs/font-page.xml b/e2e/ui-tests-app/app/tabs/font-page.xml index a0c8bfa60c..ee9003d981 100644 --- a/e2e/ui-tests-app/app/tabs/font-page.xml +++ b/e2e/ui-tests-app/app/tabs/font-page.xml @@ -1,12 +1,15 @@ - + - - + + + + @@ -20,5 +23,11 @@ + + + + + \ No newline at end of file diff --git a/e2e/ui-tests-app/app/tabs/text-transform-page.css b/e2e/ui-tests-app/app/tabs/text-transform-page.css index db5fd0e50d..ebbc005bd2 100644 --- a/e2e/ui-tests-app/app/tabs/text-transform-page.css +++ b/e2e/ui-tests-app/app/tabs/text-transform-page.css @@ -17,3 +17,11 @@ TabStripItem.special { TabStripItem.special:active { text-transform: uppercase; } + +TabStripItem.nested Label { + text-transform: lowercase; +} + +TabStripItem.nested:active Label { + text-transform: uppercase; +} diff --git a/e2e/ui-tests-app/app/tabs/text-transform-page.xml b/e2e/ui-tests-app/app/tabs/text-transform-page.xml index c80979319a..aa9ea5bf31 100644 --- a/e2e/ui-tests-app/app/tabs/text-transform-page.xml +++ b/e2e/ui-tests-app/app/tabs/text-transform-page.xml @@ -1,12 +1,15 @@ - + - + + + @@ -20,5 +23,11 @@ + + + + + \ No newline at end of file diff --git a/tests/package.json b/tests/package.json index b1a3a76c68..fee500327e 100644 --- a/tests/package.json +++ b/tests/package.json @@ -2,10 +2,10 @@ "nativescript": { "id": "org.nativescript.UnitTestApp", "tns-android": { - "version": "next" + "version": "6.1.0-2019-07-29-182447-01" }, "tns-ios": { - "version": "next" + "version": "6.1.0-2019-08-01-122621-01" } }, "main": "app.js", diff --git a/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/BottomNavigationBar.java b/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/BottomNavigationBar.java index e6a01f822c..80d05ab74b 100644 --- a/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/BottomNavigationBar.java +++ b/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/BottomNavigationBar.java @@ -205,8 +205,17 @@ private void setupItem(LinearLayout ll, TextView textView,ImageView imgView, Tab textView.setVisibility(GONE); } + if (tabItem.typeFace != null) { + textView.setTypeface(tabItem.typeFace); + } + + if (tabItem.fontSize != 0) { + textView.setTextSize(tabItem.fontSize); + } + if (tabItem.color != 0) { - textView.setTextColor(tabItem.color); + textView.setTextColor(tabItem.color); + mTabStrip.setShouldUpdateTabsTextColor(false); } if (tabItem.backgroundColor != 0) { diff --git a/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabItemSpec.java b/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabItemSpec.java index fc581db76d..1494e407f3 100644 --- a/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabItemSpec.java +++ b/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabItemSpec.java @@ -1,9 +1,12 @@ package org.nativescript.widgets; import android.graphics.drawable.Drawable; +import android.graphics.Typeface; public class TabItemSpec { public String title; + public int fontSize; + public Typeface typeFace; public int iconId; public Drawable iconDrawable; public int backgroundColor; diff --git a/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabStrip.java b/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabStrip.java index 557be52a1e..37cb21c133 100644 --- a/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabStrip.java +++ b/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabStrip.java @@ -52,6 +52,8 @@ class TabStrip extends LinearLayout { private int mSelectedTabTextColor; private float mTabTextFontSize; + private boolean mShouldUpdateTabsTextColor; + TabStrip(Context context) { this(context, null); } @@ -87,6 +89,8 @@ class TabStrip extends LinearLayout { // Default selected color is the same as mTabTextColor mSelectedTabTextColor = mTabTextColor; + mShouldUpdateTabsTextColor = true; + setMeasureWithLargestChildEnabled(true); } @@ -120,16 +124,22 @@ int getSelectedTabTextColor(){ return mSelectedTabTextColor; } + void setShouldUpdateTabsTextColor(boolean value) { + mShouldUpdateTabsTextColor = value; + } + private void updateTabsTextColor(){ - final int childCount = getChildCount(); - for (int i = 0; i < childCount; i++){ - LinearLayout linearLayout = (LinearLayout)getChildAt(i); - TextView textView = (TextView)linearLayout.getChildAt(1); - if (i == mSelectedPosition){ - textView.setTextColor(mSelectedTabTextColor); - } - else { - textView.setTextColor(mTabTextColor); + if (mShouldUpdateTabsTextColor) { + final int childCount = getChildCount(); + for (int i = 0; i < childCount; i++){ + LinearLayout linearLayout = (LinearLayout)getChildAt(i); + TextView textView = (TextView)linearLayout.getChildAt(1); + if (i == mSelectedPosition){ + textView.setTextColor(mSelectedTabTextColor); + } + else { + textView.setTextColor(mTabTextColor); + } } } } diff --git a/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabsBar.java b/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabsBar.java index c53661cc75..783c3d17ba 100644 --- a/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabsBar.java +++ b/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabsBar.java @@ -252,7 +252,6 @@ protected View createDefaultTabView(Context context, TabItemSpec tabItem) { textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, TAB_VIEW_TEXT_SIZE_SP); textView.setTypeface(Typeface.DEFAULT_BOLD); textView.setEllipsize(TextUtils.TruncateAt.END); - textView.setAllCaps(true); textView.setMaxLines(2); textView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); textView.setPadding(padding, 0, padding, 0); @@ -288,6 +287,19 @@ private void setupItem(LinearLayout ll, TextView textView,ImageView imgView, Tab ll.setBackgroundColor(tabItem.backgroundColor); } + if (tabItem.typeFace != null) { + textView.setTypeface(tabItem.typeFace); + } + + if (tabItem.fontSize != 0) { + textView.setTextSize(tabItem.fontSize); + } + + if (tabItem.color != 0) { + textView.setTextColor(tabItem.color); + mTabStrip.setShouldUpdateTabsTextColor(false); + } + if (imgView.getVisibility() == VISIBLE && textView.getVisibility() == VISIBLE) { ll.setMinimumHeight((int) (LARGE_MIN_HEIGHT * density)); } else { diff --git a/tns-core-modules/package.json b/tns-core-modules/package.json index 91325f8966..b92f0c306f 100644 --- a/tns-core-modules/package.json +++ b/tns-core-modules/package.json @@ -26,7 +26,7 @@ "license": "Apache-2.0", "typings": "tns-core-modules.d.ts", "dependencies": { - "tns-core-modules-widgets": "next", + "tns-core-modules-widgets": "file:../tns-core-modules-widgets/dist/package", "tslib": "^1.9.3" }, "devDependencies": { diff --git a/tns-core-modules/ui/bottom-navigation/bottom-navigation.android.ts b/tns-core-modules/ui/bottom-navigation/bottom-navigation.android.ts index ce2d1b4dd2..e2bbfdbc5b 100644 --- a/tns-core-modules/ui/bottom-navigation/bottom-navigation.android.ts +++ b/tns-core-modules/ui/bottom-navigation/bottom-navigation.android.ts @@ -167,37 +167,58 @@ function initializeNativeClasses() { } function createTabItemSpec(tabStripItem: TabStripItem): org.nativescript.widgets.TabItemSpec { - let iconSource; const tabItemSpec = new org.nativescript.widgets.TabItemSpec(); - tabItemSpec.title = tabStripItem.label && tabStripItem.label.text; - - if (tabStripItem.backgroundColor instanceof Color) { - tabItemSpec.backgroundColor = tabStripItem.backgroundColor.android; - } - - if (tabStripItem.label && tabStripItem.label.style.color instanceof Color) { - tabItemSpec.color = tabStripItem.label.style.color.android; - } - - iconSource = tabStripItem.image && tabStripItem.image.src; - if (iconSource) { - if (iconSource.indexOf(RESOURCE_PREFIX) === 0) { - tabItemSpec.iconId = ad.resources.getDrawableId(iconSource.substr(RESOURCE_PREFIX.length)); - if (tabItemSpec.iconId === 0) { - // TODO: - // traceMissingIcon(iconSource); - } - } else { - const icon = _getIcon(tabStripItem); + if (tabStripItem.isLoaded) { + const nestedLabel = tabStripItem.label; + let title = nestedLabel.text; + + // TEXT-TRANSFORM + const textTransform = nestedLabel.style.textTransform; + if (textTransform) { + title = getTransformedText(title, textTransform); + } + tabItemSpec.title = title; - if (icon) { - // TODO: Make this native call that accepts string so that we don't load Bitmap in JS. - // tslint:disable-next-line:deprecation - tabItemSpec.iconDrawable = icon; + // BACKGROUND-COLOR + const backgroundColor = tabStripItem.style.backgroundColor; + if (backgroundColor) { + tabItemSpec.backgroundColor = backgroundColor.android; + } + + // COLOR + const color = nestedLabel.style.color; + if (color) { + tabItemSpec.color = color.android; + } + + // FONT + const fontInternal = nestedLabel.style.fontInternal; + if (fontInternal) { + tabItemSpec.fontSize = fontInternal.fontSize; + tabItemSpec.typeFace = fontInternal.getAndroidTypeface(); + } + + // ICON + const iconSource = tabStripItem.image && tabStripItem.image.src; + if (iconSource) { + if (iconSource.indexOf(RESOURCE_PREFIX) === 0) { + tabItemSpec.iconId = ad.resources.getDrawableId(iconSource.substr(RESOURCE_PREFIX.length)); + if (tabItemSpec.iconId === 0) { + // TODO: + // traceMissingIcon(iconSource); + } } else { - // TODO: - // traceMissingIcon(iconSource); + const icon = _getIcon(tabStripItem); + + if (icon) { + // TODO: Make this native call that accepts string so that we don't load Bitmap in JS. + // tslint:disable-next-line:deprecation + tabItemSpec.iconDrawable = icon; + } else { + // TODO: + // traceMissingIcon(iconSource); + } } } } @@ -581,10 +602,6 @@ export class BottomNavigation extends TabNavigationBase { this.updateAndroidItemAt(tabStripItemIndex, tabItemSpec); } - public getTabBarItemColor(tabStripItem: TabStripItem): number { - return tabStripItem.nativeViewProtected.getCurrentTextColor(); - } - public setTabBarItemColor(tabStripItem: TabStripItem, value: number | Color): void { if (typeof value === "number") { tabStripItem.nativeViewProtected.setTextColor(value); @@ -602,45 +619,15 @@ export class BottomNavigation extends TabNavigationBase { imgView.setImageDrawable(drawable); } - public getTabBarItemFontSize(tabStripItem: TabStripItem): { nativeSize: number } { - return { nativeSize: tabStripItem.nativeViewProtected.getTextSize() }; + public setTabBarItemFontInternal(tabStripItem: TabStripItem, value: Font): void { + tabStripItem.nativeViewProtected.setTextSize(value.fontSize); + tabStripItem.nativeViewProtected.setTypeface(value.getAndroidTypeface()); } - public setTabBarItemFontSize(tabStripItem: TabStripItem, value: number | { nativeSize: number }): void { - if (typeof value === "number") { - tabStripItem.nativeViewProtected.setTextSize(value); - } else { - tabStripItem.nativeViewProtected.setTextSize(android.util.TypedValue.COMPLEX_UNIT_PX, value.nativeSize); - } - } - - public getTabBarItemFontInternal(tabStripItem: TabStripItem): android.graphics.Typeface { - return tabStripItem.nativeViewProtected.getTypeface(); - } - - public setTabBarItemFontInternal(tabStripItem: TabStripItem, value: Font | android.graphics.Typeface): void { - tabStripItem.nativeViewProtected.setTypeface(value instanceof Font ? value.getAndroidTypeface() : value); - } - - private _defaultTransformationMethod: android.text.method.TransformationMethod; - - public getTabBarItemTextTransform(tabStripItem: TabStripItem): "default" { - return "default"; - } - - public setTabBarItemTextTransform(tabStripItem: TabStripItem, value: TextTransform | "default"): void { - const tv = tabStripItem.nativeViewProtected; - - this._defaultTransformationMethod = this._defaultTransformationMethod || tv.getTransformationMethod(); - - if (value === "default") { - tv.setTransformationMethod(this._defaultTransformationMethod); - tv.setText(tabStripItem.title); - } else { - const result = getTransformedText(tabStripItem.title, value); - tv.setText(result); - tv.setTransformationMethod(null); - } + public setTabBarItemTextTransform(tabStripItem: TabStripItem, value: TextTransform): void { + const nestedLabel = tabStripItem.label; + const title = getTransformedText(nestedLabel.text, value); + tabStripItem.nativeViewProtected.setText(title); } [selectedIndexProperty.setNative](value: number) { diff --git a/tns-core-modules/ui/bottom-navigation/bottom-navigation.ios.ts b/tns-core-modules/ui/bottom-navigation/bottom-navigation.ios.ts index 565b4418af..35f4c0f9a3 100644 --- a/tns-core-modules/ui/bottom-navigation/bottom-navigation.ios.ts +++ b/tns-core-modules/ui/bottom-navigation/bottom-navigation.ios.ts @@ -340,10 +340,6 @@ export class BottomNavigation extends TabNavigationBase { bgView.backgroundColor = value instanceof Color ? value.ios : value; } - public getTabBarItemColor(tabStripItem: TabStripItem): UIColor { - return this._ios.tabBar.tintColor; - } - public setTabBarItemColor(tabStripItem: TabStripItem, value: UIColor | Color): void { const states = getTitleAttributesForStates(tabStripItem.label); applyStatesToItem(tabStripItem.nativeView, states); @@ -356,30 +352,13 @@ export class BottomNavigation extends TabNavigationBase { tabStripItem.nativeView.selectedImage = image; } - public getTabBarItemFontSize(tabStripItem: TabStripItem): number { - return null; - } - - public setTabBarItemFontSize(tabStripItem: TabStripItem, value: number | { nativeSize: number }): void { - const states = getTitleAttributesForStates(tabStripItem); - applyStatesToItem(tabStripItem.nativeView, states); - } - - public getTabBarItemFontInternal(tabStripItem: TabStripItem): Font { - return null; - } - public setTabBarItemFontInternal(tabStripItem: TabStripItem, value: Font): void { - const states = getTitleAttributesForStates(tabStripItem); + const states = getTitleAttributesForStates(tabStripItem.label); applyStatesToItem(tabStripItem.nativeView, states); } - public getTabBarItemTextTransform(tabStripItem: TabStripItem): TextTransform { - return null; - } - public setTabBarItemTextTransform(tabStripItem: TabStripItem, value: TextTransform): void { - const title = getTransformedText(tabStripItem.title, value); + const title = getTransformedText(tabStripItem.label.text, value); tabStripItem.nativeView.title = title; } @@ -526,8 +505,15 @@ export class BottomNavigation extends TabNavigationBase { let image: UIImage; let title: string; - image = item.isLoaded && this._getIcon(item); - title = item.label && item.label.text; + if (item.isLoaded) { + image = this._getIcon(item); + title = item.label.text; + + const textTransform = item.label.style.textTransform; + if (textTransform) { + title = getTransformedText(title, textTransform); + } + } const tabBarItem = UITabBarItem.alloc().initWithTitleImageTag(title, image, index); diff --git a/tns-core-modules/ui/tab-navigation-base/tab-strip-item/tab-strip-item.ts b/tns-core-modules/ui/tab-navigation-base/tab-strip-item/tab-strip-item.ts index 55f7876bf7..8acf5b4c62 100644 --- a/tns-core-modules/ui/tab-navigation-base/tab-strip-item/tab-strip-item.ts +++ b/tns-core-modules/ui/tab-navigation-base/tab-strip-item/tab-strip-item.ts @@ -32,6 +32,12 @@ export class TabStripItem extends View implements TabStripItemDefinition, AddChi private _highlightedHandler: () => void; private _normalHandler: () => void; + private _labelColorHandler: (args: PropertyChangeData) => void; + private _labelFontHandler: (args: PropertyChangeData) => void; + private _labelTextTransformHandler: (args: PropertyChangeData) => void; + + private _imageColorHandler: (args: PropertyChangeData) => void; + public onLoaded() { if (!this.image) { const image = new Image(); @@ -49,19 +55,47 @@ export class TabStripItem extends View implements TabStripItemDefinition, AddChi super.onLoaded(); - this.label.style.addEventListener("colorChange", (args: PropertyChangeData) => { + this._labelColorHandler = this._labelColorHandler || ((args: PropertyChangeData) => { const parent = this.parent; const tabStripParent = parent && parent.parent; return tabStripParent && tabStripParent.setTabBarItemColor(this, args.value); }); + this.label.style.on("colorChange", this._labelColorHandler); + + this._labelFontHandler = this._labelFontHandler || ((args: PropertyChangeData) => { + const parent = this.parent; + const tabStripParent = parent && parent.parent; + + return tabStripParent && tabStripParent.setTabBarItemFontInternal(this, args.value); + }); + this.label.style.on("fontInternalChange", this._labelFontHandler); + + this._labelTextTransformHandler = this._labelTextTransformHandler || ((args: PropertyChangeData) => { + const parent = this.parent; + const tabStripParent = parent && parent.parent; + + return tabStripParent && tabStripParent.setTabBarItemTextTransform(this, args.value); + }); + this.label.style.on("textTransformChange", this._labelTextTransformHandler); - this.image.style.addEventListener("colorChange", (args: PropertyChangeData) => { + this._imageColorHandler = this._imageColorHandler || ((args: PropertyChangeData) => { const parent = this.parent; const tabStripParent = parent && parent.parent; return tabStripParent && (tabStripParent).setTabBarIconColor(this, args.value); }); + this.image.style.on("colorChange", this._imageColorHandler); + } + + public onUnloaded() { + super.onUnloaded(); + + this.label.style.off("colorChange", this._labelColorHandler); + this.label.style.off("fontInternalChange", this._labelFontHandler); + this.label.style.off("textTransformChange", this._labelTextTransformHandler); + + this.image.style.off("colorChange", this._imageColorHandler); } public eachChild(callback: (child: ViewBase) => boolean) { @@ -142,43 +176,4 @@ export class TabStripItem extends View implements TabStripItemDefinition, AddChi [backgroundInternalProperty.setNative](value: any) { // disable the background CSS properties } - - [fontSizeProperty.getDefault](): { nativeSize: number } { - const parent = this.parent; - const tabStripParent = parent && parent.parent; - - return tabStripParent && tabStripParent.getTabBarItemFontSize(this); - } - [fontSizeProperty.setNative](value: number | { nativeSize: number }) { - const parent = this.parent; - const tabStripParent = parent && parent.parent; - - return tabStripParent && tabStripParent.setTabBarItemFontSize(this, value); - } - - [fontInternalProperty.getDefault](): any { - const parent = this.parent; - const tabStripParent = parent && parent.parent; - - return tabStripParent && tabStripParent.getTabBarItemFontInternal(this); - } - [fontInternalProperty.setNative](value: any) { - const parent = this.parent; - const tabStripParent = parent && parent.parent; - - return tabStripParent && tabStripParent.setTabBarItemFontInternal(this, value); - } - - [textTransformProperty.getDefault](): any { - const parent = this.parent; - const tabStripParent = parent && parent.parent; - - return tabStripParent && tabStripParent.getTabBarItemTextTransform(this); - } - [textTransformProperty.setNative](value: any) { - const parent = this.parent; - const tabStripParent = parent && parent.parent; - - return tabStripParent && tabStripParent.setTabBarItemTextTransform(this, value); - } } diff --git a/tns-core-modules/ui/tabs/tabs.android.ts b/tns-core-modules/ui/tabs/tabs.android.ts index fa11bc11ae..cc6ade86df 100644 --- a/tns-core-modules/ui/tabs/tabs.android.ts +++ b/tns-core-modules/ui/tabs/tabs.android.ts @@ -284,37 +284,58 @@ function initializeNativeClasses() { } function createTabItemSpec(tabStripItem: TabStripItem): org.nativescript.widgets.TabItemSpec { - let iconSource; const tabItemSpec = new org.nativescript.widgets.TabItemSpec(); - tabItemSpec.title = tabStripItem.label && tabStripItem.label.text; - - if (tabStripItem.backgroundColor instanceof Color) { - tabItemSpec.backgroundColor = tabStripItem.backgroundColor.android; - } - - if (tabStripItem.label && tabStripItem.label.style.color instanceof Color) { - tabItemSpec.color = tabStripItem.label.style.color.android; - } - - iconSource = tabStripItem.image && tabStripItem.image.src; - if (iconSource) { - if (iconSource.indexOf(RESOURCE_PREFIX) === 0) { - tabItemSpec.iconId = ad.resources.getDrawableId(iconSource.substr(RESOURCE_PREFIX.length)); - if (tabItemSpec.iconId === 0) { - // TODO: - // traceMissingIcon(iconSource); - } - } else { - const icon = _getIcon(tabStripItem); + if (tabStripItem.isLoaded) { + const nestedLabel = tabStripItem.label; + let title = nestedLabel.text; + + // TEXT-TRANSFORM + const textTransform = nestedLabel.style.textTransform; + if (textTransform) { + title = getTransformedText(title, textTransform); + } + tabItemSpec.title = title; + + // BACKGROUND-COLOR + const backgroundColor = tabStripItem.style.backgroundColor; + if (backgroundColor) { + tabItemSpec.backgroundColor = backgroundColor.android; + } - if (icon) { - // TODO: Make this native call that accepts string so that we don't load Bitmap in JS. - // tslint:disable-next-line:deprecation - tabItemSpec.iconDrawable = icon; + // COLOR + const color = nestedLabel.style.color; + if (color) { + tabItemSpec.color = color.android; + } + + // FONT + const fontInternal = nestedLabel.style.fontInternal; + if (fontInternal) { + tabItemSpec.fontSize = fontInternal.fontSize; + tabItemSpec.typeFace = fontInternal.getAndroidTypeface(); + } + + // ICON + const iconSource = tabStripItem.image && tabStripItem.image.src; + if (iconSource) { + if (iconSource.indexOf(RESOURCE_PREFIX) === 0) { + tabItemSpec.iconId = ad.resources.getDrawableId(iconSource.substr(RESOURCE_PREFIX.length)); + if (tabItemSpec.iconId === 0) { + // TODO: + // traceMissingIcon(iconSource); + } } else { - // TODO: - // traceMissingIcon(iconSource); + const icon = _getIcon(tabStripItem); + + if (icon) { + // TODO: Make this native call that accepts string so that we don't load Bitmap in JS. + // tslint:disable-next-line:deprecation + tabItemSpec.iconDrawable = icon; + } else { + // TODO: + // traceMissingIcon(iconSource); + } } } } @@ -679,20 +700,6 @@ export class Tabs extends TabsBase { } } - public getTabBarColor(): number { - return this._tabsBar.getTabTextColor(); - } - - public setTabBarColor(value: number | Color): void { - if (value instanceof Color) { - this._tabsBar.setTabTextColor(value.android); - this._tabsBar.setSelectedTabTextColor(value.android); - } else { - this._tabsBar.setTabTextColor(value); - this._tabsBar.setSelectedTabTextColor(value); - } - } - public getTabBarHighlightColor(): number { return getDefaultAccentColor(this._context); } @@ -709,10 +716,6 @@ export class Tabs extends TabsBase { this.updateAndroidItemAt(tabStripItemIndex, tabItemSpec); } - public getTabBarItemColor(tabStripItem: TabStripItem): number { - return tabStripItem.nativeViewProtected.getCurrentTextColor(); - } - public setTabBarItemColor(tabStripItem: TabStripItem, value: number | Color): void { if (typeof value === "number") { tabStripItem.nativeViewProtected.setTextColor(value); @@ -730,45 +733,15 @@ export class Tabs extends TabsBase { imgView.setImageDrawable(drawable); } - public getTabBarItemFontSize(tabStripItem: TabStripItem): { nativeSize: number } { - return { nativeSize: tabStripItem.nativeViewProtected.getTextSize() }; + public setTabBarItemFontInternal(tabStripItem: TabStripItem, value: Font): void { + tabStripItem.nativeViewProtected.setTextSize(value.fontSize); + tabStripItem.nativeViewProtected.setTypeface(value.getAndroidTypeface()); } - public setTabBarItemFontSize(tabStripItem: TabStripItem, value: number | { nativeSize: number }): void { - if (typeof value === "number") { - tabStripItem.nativeViewProtected.setTextSize(value); - } else { - tabStripItem.nativeViewProtected.setTextSize(android.util.TypedValue.COMPLEX_UNIT_PX, value.nativeSize); - } - } - - public getTabBarItemFontInternal(tabStripItem: TabStripItem): android.graphics.Typeface { - return tabStripItem.nativeViewProtected.getTypeface(); - } - - public setTabBarItemFontInternal(tabStripItem: TabStripItem, value: Font | android.graphics.Typeface): void { - tabStripItem.nativeViewProtected.setTypeface(value instanceof Font ? value.getAndroidTypeface() : value); - } - - private _defaultTransformationMethod: android.text.method.TransformationMethod; - - public getTabBarItemTextTransform(tabStripItem: TabStripItem): "default" { - return "default"; - } - - public setTabBarItemTextTransform(tabStripItem: TabStripItem, value: TextTransform | "default"): void { - const tv = tabStripItem.nativeViewProtected; - - this._defaultTransformationMethod = this._defaultTransformationMethod || tv.getTransformationMethod(); - - if (value === "default") { - tv.setTransformationMethod(this._defaultTransformationMethod); - tv.setText(tabStripItem.title); - } else { - const result = getTransformedText(tabStripItem.title, value); - tv.setText(result); - tv.setTransformationMethod(null); - } + public setTabBarItemTextTransform(tabStripItem: TabStripItem, value: TextTransform): void { + const nestedLabel = tabStripItem.label; + const title = getTransformedText(nestedLabel.text, value); + tabStripItem.nativeViewProtected.setText(title); } [selectedIndexProperty.setNative](value: number) { diff --git a/tns-platform-declarations/android/org.nativescript.widgets.d.ts b/tns-platform-declarations/android/org.nativescript.widgets.d.ts index 333e4a6b9d..dc17e76389 100644 --- a/tns-platform-declarations/android/org.nativescript.widgets.d.ts +++ b/tns-platform-declarations/android/org.nativescript.widgets.d.ts @@ -452,6 +452,8 @@ export class TabItemSpec { title: string; + fontSize: number; + typeFace: android.graphics.Typeface; iconId: number; iconDrawable: android.graphics.drawable.Drawable; backgroundColor: number; From 915125bbd8f86c2e3df51d7da44b9e5b1300792d Mon Sep 17 00:00:00 2001 From: MartoYankov Date: Sat, 10 Aug 2019 23:06:08 +0300 Subject: [PATCH 06/10] wip: add title getter and setter --- .../app/bottom-navigation/font-icons-page.css | 6 +- .../app/bottom-navigation/icon-change-page.ts | 2 + .../bottom-navigation/icon-change-page.xml | 4 +- e2e/ui-tests-app/app/tabs/font-icons-page.css | 6 +- e2e/ui-tests-app/app/tabs/icon-change-page.ts | 2 + .../app/tabs/icon-change-page.xml | 4 +- .../bottom-navigation.android.ts | 7 ++ .../bottom-navigation.ios.ts | 4 ++ .../tab-navigation-base.d.ts | 12 ++++ .../tab-navigation-base.ts | 8 +++ .../tab-strip-item/tab-strip-item.ts | 64 ++++++++++++++++++- tns-core-modules/ui/tabs/tabs.android.ts | 7 ++ 12 files changed, 118 insertions(+), 8 deletions(-) diff --git a/e2e/ui-tests-app/app/bottom-navigation/font-icons-page.css b/e2e/ui-tests-app/app/bottom-navigation/font-icons-page.css index 3c1767b852..57076da817 100644 --- a/e2e/ui-tests-app/app/bottom-navigation/font-icons-page.css +++ b/e2e/ui-tests-app/app/bottom-navigation/font-icons-page.css @@ -32,4 +32,8 @@ TabStripItem.special Label { TabStripItem.special:active Label { color: darkgoldenrod; -} \ No newline at end of file +} + +TabStripItem:active .font-size { + font-size: 10; +} diff --git a/e2e/ui-tests-app/app/bottom-navigation/icon-change-page.ts b/e2e/ui-tests-app/app/bottom-navigation/icon-change-page.ts index 199c5c5663..bfb016431f 100644 --- a/e2e/ui-tests-app/app/bottom-navigation/icon-change-page.ts +++ b/e2e/ui-tests-app/app/bottom-navigation/icon-change-page.ts @@ -6,10 +6,12 @@ export function onSelectedIndexChanged(args: SelectedIndexChangedEventData) { const newItem = bottomNav.tabStrip.items[args.newIndex]; if (newItem) { newItem.iconSource = "res://icon"; + newItem.title = "selected"; } const oldItem = bottomNav.tabStrip.items[args.oldIndex]; if (oldItem) { oldItem.iconSource = "res://testlogo"; + oldItem.title = "unselected"; } } diff --git a/e2e/ui-tests-app/app/bottom-navigation/icon-change-page.xml b/e2e/ui-tests-app/app/bottom-navigation/icon-change-page.xml index 40bf3afac8..1305f2a062 100644 --- a/e2e/ui-tests-app/app/bottom-navigation/icon-change-page.xml +++ b/e2e/ui-tests-app/app/bottom-navigation/icon-change-page.xml @@ -4,8 +4,8 @@ - - + + diff --git a/e2e/ui-tests-app/app/tabs/font-icons-page.css b/e2e/ui-tests-app/app/tabs/font-icons-page.css index 3c1767b852..57076da817 100644 --- a/e2e/ui-tests-app/app/tabs/font-icons-page.css +++ b/e2e/ui-tests-app/app/tabs/font-icons-page.css @@ -32,4 +32,8 @@ TabStripItem.special Label { TabStripItem.special:active Label { color: darkgoldenrod; -} \ No newline at end of file +} + +TabStripItem:active .font-size { + font-size: 10; +} diff --git a/e2e/ui-tests-app/app/tabs/icon-change-page.ts b/e2e/ui-tests-app/app/tabs/icon-change-page.ts index 1a466d6a65..cf4e24af11 100644 --- a/e2e/ui-tests-app/app/tabs/icon-change-page.ts +++ b/e2e/ui-tests-app/app/tabs/icon-change-page.ts @@ -6,10 +6,12 @@ export function onSelectedIndexChanged(args: SelectedIndexChangedEventData) { const newItem = tabsNav.tabStrip.items[args.newIndex]; if (newItem) { newItem.iconSource = "res://icon"; + newItem.title = "selected"; } const oldItem = tabsNav.tabStrip.items[args.oldIndex]; if (oldItem) { oldItem.iconSource = "res://testlogo"; + oldItem.title = "unselected"; } } diff --git a/e2e/ui-tests-app/app/tabs/icon-change-page.xml b/e2e/ui-tests-app/app/tabs/icon-change-page.xml index 28f78dc9f3..9dc1ede306 100644 --- a/e2e/ui-tests-app/app/tabs/icon-change-page.xml +++ b/e2e/ui-tests-app/app/tabs/icon-change-page.xml @@ -4,8 +4,8 @@ - - + + diff --git a/tns-core-modules/ui/bottom-navigation/bottom-navigation.android.ts b/tns-core-modules/ui/bottom-navigation/bottom-navigation.android.ts index e2bbfdbc5b..755ec6b68d 100644 --- a/tns-core-modules/ui/bottom-navigation/bottom-navigation.android.ts +++ b/tns-core-modules/ui/bottom-navigation/bottom-navigation.android.ts @@ -595,6 +595,13 @@ export class BottomNavigation extends TabNavigationBase { } } + public setTabBarItemTitle(tabStripItem: TabStripItem, value: string): void { + // TODO: Should figure out a way to do it directly with the the nativeView + const tabStripItemIndex = this.tabStrip.items.indexOf(tabStripItem); + const tabItemSpec = createTabItemSpec(tabStripItem); + this.updateAndroidItemAt(tabStripItemIndex, tabItemSpec); + } + public setTabBarItemBackgroundColor(tabStripItem: TabStripItem, value: android.graphics.drawable.Drawable | Color): void { // TODO: Should figure out a way to do it directly with the the nativeView const tabStripItemIndex = this.tabStrip.items.indexOf(tabStripItem); diff --git a/tns-core-modules/ui/bottom-navigation/bottom-navigation.ios.ts b/tns-core-modules/ui/bottom-navigation/bottom-navigation.ios.ts index 35f4c0f9a3..62d0c26d73 100644 --- a/tns-core-modules/ui/bottom-navigation/bottom-navigation.ios.ts +++ b/tns-core-modules/ui/bottom-navigation/bottom-navigation.ios.ts @@ -322,6 +322,10 @@ export class BottomNavigation extends TabNavigationBase { this._ios.tabBar.barTintColor = value instanceof Color ? value.ios : value; } + public setTabBarItemTitle(tabStripItem: TabStripItem, value: string): void { + tabStripItem.nativeView.title = value; + } + public setTabBarItemBackgroundColor(tabStripItem: TabStripItem, value: UIColor | Color): void { if (!this.tabStrip) { return; diff --git a/tns-core-modules/ui/tab-navigation-base/tab-navigation-base/tab-navigation-base.d.ts b/tns-core-modules/ui/tab-navigation-base/tab-navigation-base/tab-navigation-base.d.ts index 400b158a50..6a11acd77c 100644 --- a/tns-core-modules/ui/tab-navigation-base/tab-navigation-base/tab-navigation-base.d.ts +++ b/tns-core-modules/ui/tab-navigation-base/tab-navigation-base/tab-navigation-base.d.ts @@ -144,6 +144,12 @@ export class TabNavigationBase extends View { */ setTabBarHighlightColor(value: any) + /** + * @private + * Method is intended to be overridden by inheritors and used as "protected" + */ + setTabBarItemTitle(tabStripItem: TabStripItem, value: any): any + /** * @private * Method is intended to be overridden by inheritors and used as "protected" @@ -168,6 +174,12 @@ export class TabNavigationBase extends View { */ setTabBarItemColor(tabStripItem: TabStripItem, value: any): void + /** + * @private + * Method is intended to be overridden by inheritors and used as "protected" + */ + setTabBarIconColor(tabStripItem: TabStripItem, value: any): void + /** * @private * Method is intended to be overridden by inheritors and used as "protected" diff --git a/tns-core-modules/ui/tab-navigation-base/tab-navigation-base/tab-navigation-base.ts b/tns-core-modules/ui/tab-navigation-base/tab-navigation-base/tab-navigation-base.ts index f18c5b8def..b72d5640de 100644 --- a/tns-core-modules/ui/tab-navigation-base/tab-navigation-base/tab-navigation-base.ts +++ b/tns-core-modules/ui/tab-navigation-base/tab-navigation-base/tab-navigation-base.ts @@ -152,6 +152,10 @@ export class TabNavigationBase extends View implements TabNavigationBaseDefiniti // overridden by inheritors } + public setTabBarItemTitle(tabStripItem: TabStripItem, value: any): void { + // overridden by inheritors + } + public getTabBarItemBackgroundColor(tabStripItem: TabStripItem): any { // overridden by inheritors return null; @@ -170,6 +174,10 @@ export class TabNavigationBase extends View implements TabNavigationBaseDefiniti // overridden by inheritors } + public setTabBarIconColor(tabStripItem: TabStripItem, value: any): void { + // overridden by inheritors + } + public getTabBarItemFontSize(tabStripItem: TabStripItem): any { // overridden by inheritors return null; diff --git a/tns-core-modules/ui/tab-navigation-base/tab-strip-item/tab-strip-item.ts b/tns-core-modules/ui/tab-navigation-base/tab-strip-item/tab-strip-item.ts index 8acf5b4c62..08126d9ab9 100644 --- a/tns-core-modules/ui/tab-navigation-base/tab-strip-item/tab-strip-item.ts +++ b/tns-core-modules/ui/tab-navigation-base/tab-strip-item/tab-strip-item.ts @@ -24,19 +24,55 @@ export class TabStripItem extends View implements TabStripItemDefinition, AddChi public static selectEvent = "select"; public static unselectEvent = "unselect"; - public title: string; - public iconSource: string; public image: Image; public label: Label; + private _title: string; + private _iconSource: string; + private _highlightedHandler: () => void; private _normalHandler: () => void; private _labelColorHandler: (args: PropertyChangeData) => void; private _labelFontHandler: (args: PropertyChangeData) => void; private _labelTextTransformHandler: (args: PropertyChangeData) => void; + private _labelTextHandler: (args: PropertyChangeData) => void; private _imageColorHandler: (args: PropertyChangeData) => void; + private _imageFontHandler: (args: PropertyChangeData) => void; + private _imageSrcHandler: (args: PropertyChangeData) => void; + + get title(): string { + if (this.isLoaded) { + return this.label.text; + } + + return this._title; + } + + set title(value: string) { + this._title = value; + + if (this.isLoaded) { + this.label.text = value; + } + } + + get iconSource(): string { + if (this.isLoaded) { + return this.image.src; + } + + return this._iconSource; + } + + set iconSource(value: string) { + this._iconSource = value; + + if (this.isLoaded) { + this.image.src = value; + } + } public onLoaded() { if (!this.image) { @@ -79,6 +115,14 @@ export class TabStripItem extends View implements TabStripItemDefinition, AddChi }); this.label.style.on("textTransformChange", this._labelTextTransformHandler); + this._labelTextHandler = this._labelTextHandler || ((args: PropertyChangeData) => { + const parent = this.parent; + const tabStripParent = parent && parent.parent; + + return tabStripParent && tabStripParent.setTabBarItemTitle(this, args.value); + }); + this.label.on("textChange", this._labelTextHandler); + this._imageColorHandler = this._imageColorHandler || ((args: PropertyChangeData) => { const parent = this.parent; const tabStripParent = parent && parent.parent; @@ -86,6 +130,22 @@ export class TabStripItem extends View implements TabStripItemDefinition, AddChi return tabStripParent && (tabStripParent).setTabBarIconColor(this, args.value); }); this.image.style.on("colorChange", this._imageColorHandler); + + this._imageFontHandler = this._imageFontHandler || ((args: PropertyChangeData) => { + const parent = this.parent; + const tabStripParent = parent && parent.parent; + + return tabStripParent && (tabStripParent).setTabBarIconColor(this, args.value); + }); + this.image.style.on("fontInternalChange", this._imageFontHandler); + + this._imageSrcHandler = this._imageSrcHandler || ((args: PropertyChangeData) => { + const parent = this.parent; + const tabStripParent = parent && parent.parent; + + return tabStripParent && (tabStripParent).setTabBarIconColor(this, args.value); + }); + this.image.on("srcChange", this._imageSrcHandler); } public onUnloaded() { diff --git a/tns-core-modules/ui/tabs/tabs.android.ts b/tns-core-modules/ui/tabs/tabs.android.ts index cc6ade86df..9fa203fb49 100644 --- a/tns-core-modules/ui/tabs/tabs.android.ts +++ b/tns-core-modules/ui/tabs/tabs.android.ts @@ -709,6 +709,13 @@ export class Tabs extends TabsBase { this._tabsBar.setSelectedIndicatorColors([color]); } + public setTabBarItemTitle(tabStripItem: TabStripItem, value: string): void { + // TODO: Should figure out a way to do it directly with the the nativeView + const tabStripItemIndex = this.tabStrip.items.indexOf(tabStripItem); + const tabItemSpec = createTabItemSpec(tabStripItem); + this.updateAndroidItemAt(tabStripItemIndex, tabItemSpec); + } + public setTabBarItemBackgroundColor(tabStripItem: TabStripItem, value: android.graphics.drawable.Drawable | Color): void { // TODO: Should figure out a way to do it directly with the the nativeView const tabStripItemIndex = this.tabStrip.items.indexOf(tabStripItem); From 143ac8d2f81fcac5cb2f080a9a176a6bcb7b1692 Mon Sep 17 00:00:00 2001 From: Martin Yankov Date: Mon, 12 Aug 2019 09:29:51 +0300 Subject: [PATCH 07/10] wip: remove additional listeners --- .../ui/tab-navigation-base/tab-strip-item/tab-strip-item.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tns-core-modules/ui/tab-navigation-base/tab-strip-item/tab-strip-item.ts b/tns-core-modules/ui/tab-navigation-base/tab-strip-item/tab-strip-item.ts index 08126d9ab9..45272af3bb 100644 --- a/tns-core-modules/ui/tab-navigation-base/tab-strip-item/tab-strip-item.ts +++ b/tns-core-modules/ui/tab-navigation-base/tab-strip-item/tab-strip-item.ts @@ -154,8 +154,11 @@ export class TabStripItem extends View implements TabStripItemDefinition, AddChi this.label.style.off("colorChange", this._labelColorHandler); this.label.style.off("fontInternalChange", this._labelFontHandler); this.label.style.off("textTransformChange", this._labelTextTransformHandler); + this.label.style.off("textChange", this._labelTextHandler); this.image.style.off("colorChange", this._imageColorHandler); + this.image.style.off("fontInternalChange", this._imageFontHandler); + this.image.style.off("srcChange", this._imageSrcHandler); } public eachChild(callback: (child: ViewBase) => boolean) { From e40783bee6f1d7b7b044984b2a04e0ff272a729d Mon Sep 17 00:00:00 2001 From: Martin Yankov Date: Mon, 12 Aug 2019 09:37:14 +0300 Subject: [PATCH 08/10] wip: fix dep version tags --- tests/package.json | 4 ++-- tns-core-modules/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/package.json b/tests/package.json index fee500327e..b1a3a76c68 100644 --- a/tests/package.json +++ b/tests/package.json @@ -2,10 +2,10 @@ "nativescript": { "id": "org.nativescript.UnitTestApp", "tns-android": { - "version": "6.1.0-2019-07-29-182447-01" + "version": "next" }, "tns-ios": { - "version": "6.1.0-2019-08-01-122621-01" + "version": "next" } }, "main": "app.js", diff --git a/tns-core-modules/package.json b/tns-core-modules/package.json index b92f0c306f..91325f8966 100644 --- a/tns-core-modules/package.json +++ b/tns-core-modules/package.json @@ -26,7 +26,7 @@ "license": "Apache-2.0", "typings": "tns-core-modules.d.ts", "dependencies": { - "tns-core-modules-widgets": "file:../tns-core-modules-widgets/dist/package", + "tns-core-modules-widgets": "next", "tslib": "^1.9.3" }, "devDependencies": { From 38a1b66f3e420123c4a7e733eb671e3c2d84b4ac Mon Sep 17 00:00:00 2001 From: Martin Yankov Date: Thu, 15 Aug 2019 13:27:01 +0300 Subject: [PATCH 09/10] wip: fix tabstrip items binding --- .../widgets/BottomNavigationBar.java | 26 +++++++++---------- .../org/nativescript/widgets/TabsBar.java | 26 +++++++++---------- .../bottom-navigation.android.ts | 16 ++++++------ .../tab-strip-item/tab-strip-item.ts | 4 +-- .../tab-strip/tab-strip.ts | 21 ++++++++++++++- 5 files changed, 55 insertions(+), 38 deletions(-) diff --git a/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/BottomNavigationBar.java b/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/BottomNavigationBar.java index 80d05ab74b..4e2cd7eeba 100644 --- a/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/BottomNavigationBar.java +++ b/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/BottomNavigationBar.java @@ -201,23 +201,23 @@ private void setupItem(LinearLayout ll, TextView textView,ImageView imgView, Tab if (tabItem.title != null && !tabItem.title.isEmpty()) { textView.setText(tabItem.title); textView.setVisibility(VISIBLE); + + if (tabItem.typeFace != null) { + textView.setTypeface(tabItem.typeFace); + } + + if (tabItem.fontSize != 0) { + textView.setTextSize(tabItem.fontSize); + } + + if (tabItem.color != 0) { + textView.setTextColor(tabItem.color); + mTabStrip.setShouldUpdateTabsTextColor(false); + } } else { textView.setVisibility(GONE); } - if (tabItem.typeFace != null) { - textView.setTypeface(tabItem.typeFace); - } - - if (tabItem.fontSize != 0) { - textView.setTextSize(tabItem.fontSize); - } - - if (tabItem.color != 0) { - textView.setTextColor(tabItem.color); - mTabStrip.setShouldUpdateTabsTextColor(false); - } - if (tabItem.backgroundColor != 0) { ll.setBackgroundColor(tabItem.backgroundColor); } diff --git a/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabsBar.java b/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabsBar.java index 783c3d17ba..20dfdfd0c8 100644 --- a/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabsBar.java +++ b/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/TabsBar.java @@ -279,6 +279,19 @@ private void setupItem(LinearLayout ll, TextView textView,ImageView imgView, Tab if (tabItem.title != null && !tabItem.title.isEmpty()) { textView.setText(tabItem.title); textView.setVisibility(VISIBLE); + + if (tabItem.typeFace != null) { + textView.setTypeface(tabItem.typeFace); + } + + if (tabItem.fontSize != 0) { + textView.setTextSize(tabItem.fontSize); + } + + if (tabItem.color != 0) { + textView.setTextColor(tabItem.color); + mTabStrip.setShouldUpdateTabsTextColor(false); + } } else { textView.setVisibility(GONE); } @@ -287,19 +300,6 @@ private void setupItem(LinearLayout ll, TextView textView,ImageView imgView, Tab ll.setBackgroundColor(tabItem.backgroundColor); } - if (tabItem.typeFace != null) { - textView.setTypeface(tabItem.typeFace); - } - - if (tabItem.fontSize != 0) { - textView.setTextSize(tabItem.fontSize); - } - - if (tabItem.color != 0) { - textView.setTextColor(tabItem.color); - mTabStrip.setShouldUpdateTabsTextColor(false); - } - if (imgView.getVisibility() == VISIBLE && textView.getVisibility() == VISIBLE) { ll.setMinimumHeight((int) (LARGE_MIN_HEIGHT * density)); } else { diff --git a/tns-core-modules/ui/bottom-navigation/bottom-navigation.android.ts b/tns-core-modules/ui/bottom-navigation/bottom-navigation.android.ts index 755ec6b68d..e229ce2022 100644 --- a/tns-core-modules/ui/bottom-navigation/bottom-navigation.android.ts +++ b/tns-core-modules/ui/bottom-navigation/bottom-navigation.android.ts @@ -170,11 +170,11 @@ function createTabItemSpec(tabStripItem: TabStripItem): org.nativescript.widgets const tabItemSpec = new org.nativescript.widgets.TabItemSpec(); if (tabStripItem.isLoaded) { - const nestedLabel = tabStripItem.label; - let title = nestedLabel.text; + const titleLabel = tabStripItem.label; + let title = titleLabel.text; // TEXT-TRANSFORM - const textTransform = nestedLabel.style.textTransform; + const textTransform = titleLabel.style.textTransform; if (textTransform) { title = getTransformedText(title, textTransform); } @@ -187,13 +187,13 @@ function createTabItemSpec(tabStripItem: TabStripItem): org.nativescript.widgets } // COLOR - const color = nestedLabel.style.color; + const color = titleLabel.style.color; if (color) { tabItemSpec.color = color.android; } // FONT - const fontInternal = nestedLabel.style.fontInternal; + const fontInternal = titleLabel.style.fontInternal; if (fontInternal) { tabItemSpec.fontSize = fontInternal.fontSize; tabItemSpec.typeFace = fontInternal.getAndroidTypeface(); @@ -229,7 +229,7 @@ function createTabItemSpec(tabStripItem: TabStripItem): org.nativescript.widgets function _getIcon(tabStripItem: TabStripItem): android.graphics.drawable.BitmapDrawable { const iconSource = tabStripItem.image && tabStripItem.image.src; - let is = new ImageSource(); + let is: ImageSource; if (isFontIconURI(iconSource)) { const fontIconCode = iconSource.split("//")[1]; const target = tabStripItem.image ? tabStripItem.image : tabStripItem; @@ -632,8 +632,8 @@ export class BottomNavigation extends TabNavigationBase { } public setTabBarItemTextTransform(tabStripItem: TabStripItem, value: TextTransform): void { - const nestedLabel = tabStripItem.label; - const title = getTransformedText(nestedLabel.text, value); + const titleLabel = tabStripItem.label; + const title = getTransformedText(titleLabel.text, value); tabStripItem.nativeViewProtected.setText(title); } diff --git a/tns-core-modules/ui/tab-navigation-base/tab-strip-item/tab-strip-item.ts b/tns-core-modules/ui/tab-navigation-base/tab-strip-item/tab-strip-item.ts index 45272af3bb..79753759df 100644 --- a/tns-core-modules/ui/tab-navigation-base/tab-strip-item/tab-strip-item.ts +++ b/tns-core-modules/ui/tab-navigation-base/tab-strip-item/tab-strip-item.ts @@ -10,10 +10,8 @@ import { AddChildFromBuilder } from "../../core/view"; // Requires import { - View, ViewBase, CSSType, backgroundColorProperty, backgroundInternalProperty, colorProperty, - fontSizeProperty, fontInternalProperty, PseudoClassHandler + View, ViewBase, CSSType, backgroundColorProperty, backgroundInternalProperty, PseudoClassHandler } from "../../core/view"; -import { textTransformProperty, TextTransform } from "../../text-base"; export * from "../../core/view"; export const traceCategory = "TabView"; diff --git a/tns-core-modules/ui/tab-navigation-base/tab-strip/tab-strip.ts b/tns-core-modules/ui/tab-navigation-base/tab-strip/tab-strip.ts index 774af491df..bd2280d125 100644 --- a/tns-core-modules/ui/tab-navigation-base/tab-strip/tab-strip.ts +++ b/tns-core-modules/ui/tab-navigation-base/tab-strip/tab-strip.ts @@ -51,6 +51,18 @@ export class TabStrip extends View implements TabStripDefinition, AddChildFromBu } } + public onItemsChanged(oldItems: TabStripItem[], newItems: TabStripItem[]): void { + if (oldItems) { + oldItems.forEach(item => this._removeView(item)); + } + + if (newItems) { + newItems.forEach(item => { + this._addView(item); + }); + } + } + [backgroundColorProperty.getDefault](): Color { const parent = this.parent; @@ -112,7 +124,14 @@ export class TabStrip extends View implements TabStripDefinition, AddChildFromBu return parent && parent.setTabBarHighlightColor(value); } -} +} + +export const itemsProperty = new Property({ + name: "items", valueChanged: (target, oldValue, newValue) => { + target.onItemsChanged(oldValue, newValue); + } +}); +itemsProperty.register(TabStrip); export const iosIconRenderingModeProperty = new Property({ name: "iosIconRenderingMode", defaultValue: "automatic" }); iosIconRenderingModeProperty.register(TabStrip); From e440eeb7de93d6e0c5d1c73c1826236922ee2db6 Mon Sep 17 00:00:00 2001 From: Martin Yankov Date: Thu, 15 Aug 2019 15:25:19 +0300 Subject: [PATCH 10/10] wip: remove default white color for tabcontentitem --- .../tab-content-item/tab-content-item.android.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/tns-core-modules/ui/tab-navigation-base/tab-content-item/tab-content-item.android.ts b/tns-core-modules/ui/tab-navigation-base/tab-content-item/tab-content-item.android.ts index 1c81bfa0c8..73aba71b0c 100644 --- a/tns-core-modules/ui/tab-navigation-base/tab-content-item/tab-content-item.android.ts +++ b/tns-core-modules/ui/tab-navigation-base/tab-content-item/tab-content-item.android.ts @@ -27,7 +27,6 @@ export class TabContentItem extends TabContentItemBase { public initNativeView(): void { super.initNativeView(); - this.nativeViewProtected.setBackgroundColor(-1); // White color. } public _addViewToNativeVisualTree(child: View, atIndex?: number): boolean {