diff --git a/apps/TelerikNEXT/main-page.xml b/apps/TelerikNEXT/main-page.xml index e61b14caa..dbf50f5bc 100644 --- a/apps/TelerikNEXT/main-page.xml +++ b/apps/TelerikNEXT/main-page.xml @@ -27,9 +27,9 @@ - - - + + + diff --git a/apps/tests/xml-declaration/mainPage.xml b/apps/tests/xml-declaration/mainPage.xml index 0a175108d..240ea464a 100644 --- a/apps/tests/xml-declaration/mainPage.xml +++ b/apps/tests/xml-declaration/mainPage.xml @@ -6,6 +6,15 @@ + + + + + + + + + diff --git a/color/color.d.ts b/color/color.d.ts index 742f806ce..6e31ddd03 100644 --- a/color/color.d.ts +++ b/color/color.d.ts @@ -6,53 +6,54 @@ declare module "color" { * Represents a color object. Stores all color components (alpha (opacity), red, green, blue) in a [0..255] range. */ class Color { + constructor(knownColor: string); constructor(hex: string); constructor(argb: number); constructor(alpha: number, red: number, green: number, blue: number); - /** - * Gets the Alpha component (in the [0, 255] range) of this color. This is a read-only property. - */ + /** + * Gets the Alpha component (in the [0, 255] range) of this color. This is a read-only property. + */ public a: number; - /** - * Gets the Red component (in the [0, 255] range) of this color. This is a read-only property. - */ + /** + * Gets the Red component (in the [0, 255] range) of this color. This is a read-only property. + */ public r: number; - /** - * Gets the Green component (in the [0, 255] range) of this color. This is a read-only property. - */ + /** + * Gets the Green component (in the [0, 255] range) of this color. This is a read-only property. + */ public g: number; - /** - * Gets the Blue component (in the [0, 255] range) of this color. This is a read-only property. - */ + /** + * Gets the Blue component (in the [0, 255] range) of this color. This is a read-only property. + */ public b: number; - /** - * Gets the Hexadecimal string representation of this color. This is a read-only property. - */ + /** + * Gets the Hexadecimal string representation of this color. This is a read-only property. + */ public hex: string; - /** - * Gets the Argb Number representation of this color where each 8 bits represent a single color component. This is a read-only property. - */ + /** + * Gets the Argb Number representation of this color where each 8 bits represent a single color component. This is a read-only property. + */ public argb: number; - /** - * Gets the known name of this instance. Defined only if it has been constructed from a known color name - e.g. "red". This is a read-only property. - */ + /** + * Gets the known name of this instance. Defined only if it has been constructed from a known color name - e.g. "red". This is a read-only property. + */ public name: string; - /** - * Gets the android-specific integer value representation. Same as the Argb one. This is a read-only property. - */ + /** + * Gets the android-specific integer value representation. Same as the Argb one. This is a read-only property. + */ android: number; - /** - * Gets the iOS-specific UIColor value representation. This is a read-only property. - */ + /** + * Gets the iOS-specific UIColor value representation. This is a read-only property. + */ ios: UIColor; /** diff --git a/ui/builder/component-builder.ts b/ui/builder/component-builder.ts index e0c86e84a..94bd620bc 100644 --- a/ui/builder/component-builder.ts +++ b/ui/builder/component-builder.ts @@ -30,7 +30,7 @@ var MODULES = { "Span": "text/span", "WebView": "ui/web-view", "SegmentedBar": "ui/segmented-bar", - "SegmentedBarEntry": "ui/segmented-bar", + "SegmentedBarItem": "ui/segmented-bar", "TimePicker": "ui/time-picker", "DatePicker": "ui/date-picker", "ListPicker": "ui/list-picker", diff --git a/ui/segmented-bar/segmented-bar-common.ts b/ui/segmented-bar/segmented-bar-common.ts index 75829594d..f6309a8a3 100644 --- a/ui/segmented-bar/segmented-bar-common.ts +++ b/ui/segmented-bar/segmented-bar-common.ts @@ -2,6 +2,7 @@ import view = require("ui/core/view"); import proxy = require("ui/core/proxy"); import dependencyObservable = require("ui/core/dependency-observable"); +import color = require("color"); export module knownCollections { export var items = "items"; @@ -10,7 +11,13 @@ export module knownCollections { export class SegmentedBar extends view.View implements definition.SegmentedBar { public _addArrayFromBuilder(name: string, value: Array) { if (name === "items") { - this.items = value; + this._setValue(SegmentedBar.itemsProperty, value); + } + } + + public _adjustSelectedIndex() { + if (this.selectedIndex > this.items.length - 1) { + this._setValue(SegmentedBar.selectedIndexProperty, this.items.length - 1); } } @@ -21,14 +28,22 @@ export class SegmentedBar extends view.View implements definition.SegmentedBar { this._setValue(SegmentedBar.selectedIndexProperty, value); } - get items(): Array { + get items(): Array { return this._getValue(SegmentedBar.itemsProperty); } - set items(value: Array) { + set items(value: Array) { this._setValue(SegmentedBar.itemsProperty, value); } - public static selectedIndexProperty = new dependencyObservable.Property("selectedIndex", "SegmentedBar", new proxy.PropertyMetadata(0)) + get selectedBackgroundColor(): color.Color { + return this._getValue(SegmentedBar.selectedBackgroundColorProperty); + } + set selectedBackgroundColor(value: color.Color) { + this._setValue(SegmentedBar.selectedBackgroundColorProperty, + value instanceof color.Color ? value : new color.Color(value)); + } + public static selectedBackgroundColorProperty = new dependencyObservable.Property("selectedBackgroundColor", "SegmentedBar", new proxy.PropertyMetadata(undefined)) + public static selectedIndexProperty = new dependencyObservable.Property("selectedIndex", "SegmentedBar", new proxy.PropertyMetadata(0)) public static itemsProperty = new dependencyObservable.Property("items", "SegmentedBar", new proxy.PropertyMetadata(undefined)) } \ No newline at end of file diff --git a/ui/segmented-bar/segmented-bar.android.ts b/ui/segmented-bar/segmented-bar.android.ts index 004d813ff..dcfe550d9 100644 --- a/ui/segmented-bar/segmented-bar.android.ts +++ b/ui/segmented-bar/segmented-bar.android.ts @@ -9,11 +9,12 @@ require("utils/module-merge").merge(common, exports); function onSelectedIndexPropertyChanged(data: dependencyObservable.PropertyChangeData) { var view = data.object; - if (!view.android) { + if (!view.android || !view.items) { return; } var index = data.newValue; + if (types.isNumber(index) && index >= 0 && index <= view.items.length - 1) { view.android.setCurrentTab(index); } @@ -28,41 +29,97 @@ function onItemsPropertyChanged(data: dependencyObservable.PropertyChangeData) { view.android.clearAllTabs(); - for (var i = 0; i < view.items.length; i++) { - var title = view.items[i].title; - var tab = view.android.newTabSpec(i + ""); + var newItems = >data.newValue; - tab.setIndicator(title); + if (newItems && newItems.length) { + for (var i = 0; i < newItems.length; i++) { + var title = newItems[i].title; + var tab = view.android.newTabSpec(i + ""); - tab.setContent(new android.widget.TabHost.TabContentFactory({ - createTabContent: function (tag: string): android.view.View { - var tv = new android.widget.TextView(view._context); - tv.setVisibility(android.view.View.GONE); - return tv; + tab.setIndicator(title); + + tab.setContent(new android.widget.TabHost.TabContentFactory({ + createTabContent: function (tag: string): android.view.View { + var tv = new android.widget.TextView(view._context); + tv.setVisibility(android.view.View.GONE); + return tv; + } + })); + + view.android.addTab(tab); + } + + view._adjustSelectedIndex(); + + if (view.android.getCurrentTab() !== view.selectedIndex) { + view.android.setCurrentTab(view.selectedIndex); + } + + view.android.setOnTabChangedListener(null); + view.android.setOnTabChangedListener(view._listener); + + if (view.selectedBackgroundColor) { + var tabHost = view.android; + + for (var tabIndex = 0; tabIndex < tabHost.getTabWidget().getTabCount(); tabIndex++) { + var vg = tabHost.getTabWidget().getChildTabViewAt(tabIndex); + + var stateDrawable = new android.graphics.drawable.StateListDrawable(); + + var arr = java.lang.reflect.Array.newInstance(java.lang.Integer.class.getField("TYPE").get(null), 1); + arr[0] = (android).R.attr.state_selected; + + var colorDrawable = new SegmentedBarColorDrawable(view.selectedBackgroundColor.android) + stateDrawable.addState(arr, colorDrawable); + stateDrawable.setBounds(0, 15, vg.getRight(), vg.getBottom()); + + vg.setBackgroundDrawable(stateDrawable); } - })); - - view.android.addTab(tab); + } } } (common.SegmentedBar.itemsProperty.metadata).onSetNativeValue = onItemsPropertyChanged; +class SegmentedBarColorDrawable extends android.graphics.drawable.ColorDrawable { + constructor(arg: any) { + super(arg); + + return global.__native(this); + } + + public draw(canvas: android.graphics.Canvas): void { + var p = new android.graphics.Paint(); + p.setColor(this.Color); + p.setStyle(android.graphics.Paint.Style.FILL); + canvas.drawRect(0, this.Bounds.height() - 15, this.Bounds.width(), this.Bounds.height(), p); + } +} + export class SegmentedBar extends common.SegmentedBar { private _android: OurTabHost; + public _listener: android.widget.TabHost.OnTabChangeListener; public _createUI() { this._android = new OurTabHost(this._context, null); + if (this._android.getCurrentTab() !== this.selectedIndex) { + this._android.setCurrentTab(this.selectedIndex); + } var that = new WeakRef(this); - this._android.setOnTabChangedListener(new android.widget.TabHost.OnTabChangeListener({ + this._listener = new android.widget.TabHost.OnTabChangeListener({ onTabChanged: function (id: string) { var bar = that.get(); if (bar) { - bar.selectedIndex = parseInt(id); + var oldIndex = bar.selectedIndex; + var newIndex = parseInt(id); + + if (oldIndex !== newIndex) { + bar._onPropertyChangedFromNative(SegmentedBar.selectedIndexProperty, newIndex); + } } } - })); + }); var tabHostLayout = new android.widget.LinearLayout(this._context); tabHostLayout.setOrientation(android.widget.LinearLayout.VERTICAL); diff --git a/ui/segmented-bar/segmented-bar.d.ts b/ui/segmented-bar/segmented-bar.d.ts index 75d5c34ee..4af62a85d 100644 --- a/ui/segmented-bar/segmented-bar.d.ts +++ b/ui/segmented-bar/segmented-bar.d.ts @@ -4,13 +4,14 @@ declare module "ui/segmented-bar" { import view = require("ui/core/view"); import dependencyObservable = require("ui/core/dependency-observable"); + import color = require("color"); /** - * Represents a SegmentedBar entry. + * Represents a SegmentedBar item. */ - interface SegmentedBarEntry { + interface SegmentedBarItem { /** - * Gets or sets the title of the SegmentedBarEntry. + * Gets or sets the title of the SegmentedBarItem. */ title: string; } @@ -24,10 +25,15 @@ declare module "ui/segmented-bar" { */ selectedIndex: number; + /** + * Gets or sets the selected background color of the SegmentedBar component. + */ + selectedBackgroundColor: color.Color; + /** * Gets or sets the items of the SegmentedBar. */ - items: Array; + items: Array; /** * Gets or sets the selected index dependency property of the SegmentedBar. diff --git a/ui/segmented-bar/segmented-bar.ios.ts b/ui/segmented-bar/segmented-bar.ios.ts index 3832b3f01..1996e7c3f 100644 --- a/ui/segmented-bar/segmented-bar.ios.ts +++ b/ui/segmented-bar/segmented-bar.ios.ts @@ -2,6 +2,7 @@ import dependencyObservable = require("ui/core/dependency-observable"); import proxy = require("ui/core/proxy"); import types = require("utils/types"); +import color = require("color"); // merge the exports of the common file with the exports of this file declare var exports; @@ -9,7 +10,7 @@ require("utils/module-merge").merge(common, exports); function onSelectedIndexPropertyChanged(data: dependencyObservable.PropertyChangeData) { var view = data.object; - if (!view.ios) { + if (!view.ios || !view.items) { return; } @@ -31,9 +32,27 @@ function onItemsPropertyChanged(data: dependencyObservable.PropertyChangeData) { for (var i = 0; i < view.items.length; i++) { view.ios.insertSegmentWithTitleAtIndexAnimated(view.items[i].title, i, false); } + + view._adjustSelectedIndex(); + + if (view.ios.selectedSegmentIndex !== view.selectedIndex) { + view.ios.selectedSegmentIndex = view.selectedIndex; + } } (common.SegmentedBar.itemsProperty.metadata).onSetNativeValue = onItemsPropertyChanged; +function onSelectedBackgroundColorPropertyChanged(data: dependencyObservable.PropertyChangeData) { + var view = data.object; + if (!view.ios) { + return; + } + + if (data.newValue instanceof color.Color) { + view.ios.tintColor = (data.newValue).ios; + } +} +(common.SegmentedBar.selectedBackgroundColorProperty.metadata).onSetNativeValue = onSelectedBackgroundColorPropertyChanged; + export class SegmentedBar extends common.SegmentedBar { private _ios: UISegmentedControl; private _selectionHandler: NSObject; diff --git a/ui/styling/stylers.android.ts b/ui/styling/stylers.android.ts index ebe346b04..5a203952d 100644 --- a/ui/styling/stylers.android.ts +++ b/ui/styling/stylers.android.ts @@ -210,10 +210,40 @@ export class ActivityIndicatorStyler implements definition.stylers.Styler { } } +export class SegmentedBarStyler implements definition.stylers.Styler { + //Text color methods + private static setColorProperty(view: view.View, newValue: any) { + var tabHost = view.android; + + for (var tabIndex = 0; tabIndex < tabHost.getTabWidget().getTabCount(); tabIndex++) { + var tab = tabHost.getTabWidget().getChildTabViewAt(tabIndex); + var t = tab.getChildAt(1); + t.setTextColor(newValue); + } + } + + private static resetColorProperty(view: view.View, nativeValue: any) { + var tabHost = view.android; + + for (var tabIndex = 0; tabIndex < tabHost.getTabWidget().getTabCount(); tabIndex++) { + var tab = tabHost.getTabWidget().getChildTabViewAt(tabIndex); + var t = tab.getChildAt(1); + t.setTextColor(constants.btn_default); + } + } + + public static registerHandlers() { + style.registerHandler(style.colorProperty, new stylersCommon.StylePropertyChangedHandler( + SegmentedBarStyler.setColorProperty, + SegmentedBarStyler.resetColorProperty), "SegmentedBar"); + } +} + export function _registerDefaultStylers() { style.registerNoStylingClass("Frame"); DefaultStyler.registerHandlers(); ButtonStyler.registerHandlers(); TextViewStyler.registerHandlers(); ActivityIndicatorStyler.registerHandlers(); + SegmentedBarStyler.registerHandlers(); } diff --git a/ui/styling/stylers.ios.ts b/ui/styling/stylers.ios.ts index 1e86f99d6..25f783d53 100644 --- a/ui/styling/stylers.ios.ts +++ b/ui/styling/stylers.ios.ts @@ -466,6 +466,29 @@ export class TextViewStyler implements definition.stylers.Styler { } } +export class SegmentedBarStyler implements definition.stylers.Styler { + //Text color methods + private static setColorProperty(view: view.View, newValue: any) { + var bar = view.ios; + var attrs = NSMutableDictionary.new(); + attrs.setValueForKey(newValue, NSForegroundColorAttributeName); + bar.setTitleTextAttributesForState(attrs, UIControlState.UIControlStateNormal); + } + + private static resetColorProperty(view: view.View, nativeValue: any) { + var bar = view.ios; + var attrs = NSMutableDictionary.new(); + attrs.setValueForKey(nativeValue, NSForegroundColorAttributeName); + bar.setTitleTextAttributesForState(attrs, UIControlState.UIControlStateNormal); + } + + public static registerHandlers() { + style.registerHandler(style.colorProperty, new stylersCommon.StylePropertyChangedHandler( + SegmentedBarStyler.setColorProperty, + SegmentedBarStyler.resetColorProperty), "SegmentedBar"); + } +} + export function _registerDefaultStylers() { style.registerNoStylingClass("Frame"); DefaultStyler.registerHandlers(); @@ -473,4 +496,5 @@ export function _registerDefaultStylers() { LabelStyler.registerHandlers(); TextFieldStyler.registerHandlers(); TextViewStyler.registerHandlers(); + SegmentedBarStyler.registerHandlers(); }