Merge pull request #361 from NativeScript/feature/css-fonts

CSS font properties
This commit is contained in:
Alexander Vakrilov
2015-06-26 17:18:32 +03:00
28 changed files with 1164 additions and 330 deletions

View File

@ -211,6 +211,10 @@
<TypeScriptCompile Include="apps\ui-tests-app\pages\listview_binding.ts" />
<TypeScriptCompile Include="apps\ui-tests-app\modal-view\login-page.ts" />
<TypeScriptCompile Include="apps\ui-tests-app\modal-view\modal-view.ts" />
<TypeScriptCompile Include="apps\ui-tests-app\pages\text\text-field.ts" />
<TypeScriptCompile Include="apps\ui-tests-app\pages\text\text-view.ts" />
<TypeScriptCompile Include="apps\ui-tests-app\pages\text\label.ts" />
<TypeScriptCompile Include="apps\ui-tests-app\pages\text\button.ts" />
<TypeScriptCompile Include="es-collections.d.ts" />
<TypeScriptCompile Include="es6-promise.d.ts" />
<TypeScriptCompile Include="file-system\file-name-resolver.d.ts" />
@ -440,7 +444,19 @@
<DependentUpon>wrap-layout.d.ts</DependentUpon>
</TypeScriptCompile>
<TypeScriptCompile Include="ui\styling\css-selector.d.ts" />
<TypeScriptCompile Include="ui\styling\css-selector.ts" />
<TypeScriptCompile Include="ui\styling\css-selector.ts">
<DependentUpon>css-selector.d.ts</DependentUpon>
</TypeScriptCompile>
<TypeScriptCompile Include="ui\styling\font.android.ts">
<DependentUpon>font.d.ts</DependentUpon>
</TypeScriptCompile>
<TypeScriptCompile Include="ui\styling\font.ios.ts">
<DependentUpon>font.d.ts</DependentUpon>
</TypeScriptCompile>
<TypeScriptCompile Include="ui\styling\font.d.ts" />
<TypeScriptCompile Include="ui\styling\font-common.ts">
<DependentUpon>font.d.ts</DependentUpon>
</TypeScriptCompile>
<TypeScriptCompile Include="ui\styling\style-property.d.ts" />
<TypeScriptCompile Include="ui\styling\style.ts" />
<TypeScriptCompile Include="ui\styling\visual-state.ts" />
@ -604,6 +620,7 @@
<Content Include="apps\template-master-detail\main-page.minWH600.xml" />
<Content Include="apps\template-settings\app.css" />
<Content Include="apps\tests\app\location-example.xml" />
<TypeScriptCompile Include="apps\tests\pages\fonts-test.ts" />
<Content Include="apps\tests\pages\page-load-performance\start.xml">
<SubType>Designer</SubType>
</Content>
@ -611,6 +628,7 @@
<SubType>Designer</SubType>
</Content>
<Content Include="apps\tests\pages\page-load-performance\test-small.xml" />
<Content Include="apps\tests\pages\fonts-test.xml" />
<Content Include="apps\tests\pages\page18.xml" />
<Content Include="apps\tests\ui\bindingContext_testPage.xml" />
<Content Include="apps\tests\ui\bindingContext_testPage1.xml" />
@ -646,6 +664,10 @@
<Content Include="apps\template-tab-navigation\app.css" />
<Content Include="apps\ui-tests-app\modal-view\login-page.xml" />
<Content Include="apps\ui-tests-app\modal-view\modal-view.xml" />
<Content Include="apps\ui-tests-app\pages\text\text-field.xml" />
<Content Include="apps\ui-tests-app\pages\text\text-view.xml" />
<Content Include="apps\ui-tests-app\pages\text\label.xml" />
<Content Include="apps\ui-tests-app\pages\text\button.xml" />
<Content Include="ui\layouts\stack-layout\package.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

View File

@ -0,0 +1,18 @@
import stack = require("ui/layouts/stack-layout");
import style = require("ui/styling/style");
export function buttonTap(args) {
var stackLayout = <stack.StackLayout>args.object.parent;
for (var i = 0; i < stackLayout.getChildrenCount(); i++){
var v = stackLayout.getChildAt(i);
v.style._resetValue(style.fontFamilyProperty);
v.style._resetValue(style.fontSizeProperty);
v.style._resetValue(style.fontStyleProperty);
v.style._resetValue(style.fontWeightProperty);
v.style._resetValue(style.fontProperty);
v.style._resetValue(style.colorProperty);
v.style._resetValue(style.textAlignmentProperty);
}
}

View File

@ -0,0 +1,84 @@
<Page>
<ScrollView>
<StackLayout id="stack">
<Button text="RESET" tap="buttonTap"/>
<Label text="Fallback: times or serif" style="font-family: invalid, 'one more invalid font', , Times New Roman, serif"/>
<Label text="Fallback: monospace" style="font-family: invalid, Courier New, monospace"/>
<Label text="Fallback: monospace bold italic" style="font-family: invalid, CourierNewPS-BoldItalicMT, monospace; font-weight: bold; font-style: italic;"/>
<Label text="GREEN" style="color: green" />
<Button text="GREEN" style="color: green"/>c
<TextView text="GREEN" style="color: green"/>
<TextField text="GREEN" style="color: green"/>
<Label text="no align" />
<Label text="left" style="text-align: left" />
<Label text="center" style="text-align: center" />
<Label text="right" style="text-align: right" />
<Button text="no align" />
<Button text="left" style="text-align: left" />
<Button text="center" style="text-align: center" />
<Button text="right" style="text-align: right" />
<TextView text="no align" />
<TextView text="left" style="text-align: left" />
<TextView text="center" style="text-align: center" />
<TextView text="right" style="text-align: right" />
<TextField text="no align" />
<TextField text="left" style="text-align: left" />
<TextField text="center" style="text-align: center" />
<TextField text="right" style="text-align: right" />
<Label text="Label: normal" />
<Label text="Label: size" style="font-size: 32" />
<Label text="Label: italic" style="font-style: italic" />
<Label text="Label: bold" style="font-weight: bold"/>
<Label text="Label: bold-italic" style="font-weight: bold; font-style: italic"/>
<Label text="Label: times new" style="font-family: Times New Roman"/>
<Label text="Label: serif" style="font-family: serif"/>
<Label text="Label: sans-serif" style="font-family: sans-serif"/>
<Label text="Label: monospace" style="font-family: monospace"/>
<Label text="Label: all in one" style="font-family: Times New Roman; font-weight: bold; font-style: italic; font-size: 32" />
<Button text="Button: normal" />
<Button text="Button: size" style="font-size: 32" />
<Button text="Button: italic" style="font-style: italic" />
<Button text="Button: bold" style="font-weight: bold"/>
<Button text="Button: bold-italic" style="font-weight: bold; font-style: italic"/>
<Button text="Button: times new" style="font-family: Times New Roman"/>
<Button text="Button: serif" style="font-family: serif"/>
<Button text="Button: sans-serif" style="font-family: sans-serif"/>
<Button text="Button: monospace" style="font-family: monospace"/>
<Button text="Button: all in one" style="font-family: Times New Roman; font-weight: bold; font-style: italic; font-size: 32" />
<TextView text="TextView: normal" />
<TextView text="TextView: size" style="font-size: 32" />
<TextView text="TextView: italic" style="font-style: italic" />
<TextView text="TextView: bold" style="font-weight: bold"/>
<TextView text="TextView: bold-italic" style="font-weight: bold; font-style: italic"/>
<TextView text="TextView: times new" style="font-family: Times New Roman"/>
<TextView text="TextView: serif" style="font-family: serif"/>
<TextView text="TextView: sans-serif" style="font-family: sans-serif"/>
<TextView text="TextView: monospace" style="font-family: monospace"/>
<TextView text="TextView: all in one" style="font-family: Times New Roman; font-weight: bold; font-style: italic; font-size: 32" />
<TextField text="TextField: normal" />
<TextField text="TextField: size" style="font-size: 32" />
<TextField text="TextField: italic" style="font-style: italic" />
<TextField text="TextField: bold" style="font-weight: bold"/>
<TextField text="TextField: bold-italic" style="font-weight: bold; font-style: italic"/>
<TextField text="TextField: times new" style="font-family: Times New Roman"/>
<TextField text="TextField: serif" style="font-family: serif"/>
<TextField text="TextField: sans-serif" style="font-family: sans-serif"/>
<TextField text="TextField: monospace" style="font-family: monospace"/>
<TextField text="TextField: all in one" style="font-family: Times New Roman; font-weight: bold; font-style: italic; font-size: 32" />
</StackLayout>
</ScrollView>
</Page>

View File

@ -81,6 +81,18 @@ export function test_setting_opacity_property_from_CSS_is_applied_to_Style() {
test_property_from_CSS_is_applied_to_style("opacity", "opacity", 0.5);
}
export function test_setting_fontFamily_property_from_CSS_is_applied_to_Style() {
test_property_from_CSS_is_applied_to_style("fontFamily", "font-family", "Helvetica");
}
export function test_setting_fontWeight_property_from_CSS_is_applied_to_Style() {
test_property_from_CSS_is_applied_to_style("fontWeight", "font-weight", "bold");
}
export function test_setting_fontStyle_property_from_CSS_is_applied_to_Style() {
test_property_from_CSS_is_applied_to_style("fontStyle", "font-style", "italic");
}
function test_property_from_CSS_is_applied_to_style(propName: string, cssName: string, value: any, cssValue?: string) {
if (!cssValue) {
cssValue = value + "";
@ -231,7 +243,7 @@ export function test_setting_margin_shorthand_property_sets_all_margins() {
test_margin_shorthand_property("10 20 30 40", 10, 20, 30, 40);
}
function test_margin_shorthand_property(short: string, top:number, right:number, bottom:number, left:number) {
function test_margin_shorthand_property(short: string, top: number, right: number, bottom: number, left: number) {
var testView = new buttonModule.Button();
testView.style.margin = short;
@ -257,3 +269,23 @@ function test_padding_shorthand_property(short: string, top: number, right: numb
TKUnit.assertEqual(testView.style.paddingLeft, left, "left");
}
export function test_setting_font_shorthand_property() {
test_font_shorthand_property("15px Arial", "Arial", 15, "normal", "normal");
test_font_shorthand_property("bold 15px Arial", "Arial", 15, "normal", "bold");
test_font_shorthand_property("italic 15px Arial", "Arial", 15, "italic", "normal");
test_font_shorthand_property("bold italic 15px Arial", "Arial", 15, "italic", "bold");
test_font_shorthand_property("italic normal bold 15px Arial, serif", "Arial, serif", 15, "italic", "bold");
test_font_shorthand_property("small-caps normal bold 15px Arial", "Arial", 15, "normal", "bold");
test_font_shorthand_property("normal normal normal 15px Arial", "Arial", 15, "normal", "normal");
test_font_shorthand_property("normal normal normal 15px/30px Arial", "Arial", 15, "normal", "normal");
}
function test_font_shorthand_property(short: string, family: string, size: number, style: string, weight:string) {
var testView = new buttonModule.Button();
(<any>testView).style = "font: " + short;
TKUnit.assertEqual(testView.style.fontFamily, family, "style.fontFamily");
TKUnit.assertEqual(testView.style.fontStyle, style, "style.fontStyle");
TKUnit.assertEqual(testView.style.fontWeight, weight, "style.fontWeight");
TKUnit.assertEqual(testView.style.fontSize, size, "style.fontSize");
}

View File

@ -12,6 +12,8 @@ trace.setCategories(trace.categories.Test);
var list: string[] = ["pages", "layouts", "modal-view"];
// basePath is auto-changed when building multiple apps
var basePath = "";
export function createPage() {
var txtInput = new text.TextView();
var btn = new button.Button();
@ -21,7 +23,7 @@ export function createPage() {
while (i < list.length) {
filePath = fs.path.join(__dirname, list[i], txtInput.text);
if ((fs.File.exists(filePath + ".xml") || (fs.File.exists(filePath + ".js")))) {
fileName = list[i] + "/" + txtInput.text;
fileName = basePath + list[i] + "/" + txtInput.text;
break;
}
i++;

View File

@ -0,0 +1,16 @@
import stack = require("ui/layouts/stack-layout");
import style = require("ui/styling/style");
import view = require("ui/core/view");
export function resetStyles(args) {
var stackLayout = <stack.StackLayout>args.object.parent;
view.eachDescendant(stackLayout, function (v: view.View) {
v.style._resetValue(style.fontFamilyProperty);
v.style._resetValue(style.fontSizeProperty);
v.style._resetValue(style.fontStyleProperty);
v.style._resetValue(style.fontWeightProperty);
v.style._resetValue(style.fontProperty);
v.style._resetValue(style.colorProperty);
v.style._resetValue(style.textAlignmentProperty);
return true;
});
}

View File

@ -0,0 +1,25 @@
<Page>
<StackLayout>
<Button text="RESET" tap="resetStyles"/>
<Button text="no align" />
<Button text="left" style="text-align: left" />
<Button text="center" style="text-align: center" />
<Button text="right" style="text-align: right" />
<WrapLayout>
<Button text="normal" />
<Button text="color" style="color: green"/>
<Button text="size" style="font-size: 32" />
<Button text="italic" style="font-style: italic" />
<Button text="bold" style="font-weight: bold"/>
<Button text="bold-italic" style="font-weight: bold; font-style: italic"/>
<Button text="serif" style="font-family: serif"/>
<Button text="sans-serif" style="font-family: sans-serif"/>
<Button text="monospace" style="font-family: monospace"/>
<Button text="Times New Roman" style="font-family: Times New Roman"/>
<Button text="invalid font" style="font-family: InvalidFont"/>
<Button text="all in one" style="font-family: serif; font-weight: bold; font-style: italic; font-size: 32; color: green" />
</WrapLayout>
</StackLayout>
</Page>

View File

@ -0,0 +1,16 @@
import stack = require("ui/layouts/stack-layout");
import style = require("ui/styling/style");
import view = require("ui/core/view");
export function resetStyles(args) {
var stackLayout = <stack.StackLayout>args.object.parent;
view.eachDescendant(stackLayout, function (v: view.View) {
v.style._resetValue(style.fontFamilyProperty);
v.style._resetValue(style.fontSizeProperty);
v.style._resetValue(style.fontStyleProperty);
v.style._resetValue(style.fontWeightProperty);
v.style._resetValue(style.fontProperty);
v.style._resetValue(style.colorProperty);
v.style._resetValue(style.textAlignmentProperty);
return true;
});
}

View File

@ -0,0 +1,25 @@
<Page>
<StackLayout>
<Button text="RESET" tap="resetStyles"/>
<Label text="no align" />
<Label text="left" style="text-align: left" />
<Label text="center" style="text-align: center" />
<Label text="right" style="text-align: right" />
<WrapLayout>
<Label text="normal" />
<Label text="color" style="color: green"/>
<Label text="size" style="font-size: 32" />
<Label text="italic" style="font-style: italic" />
<Label text="bold" style="font-weight: bold"/>
<Label text="bold-italic" style="font-weight: bold; font-style: italic"/>
<Label text="serif" style="font-family: serif"/>
<Label text="sans-serif" style="font-family: sans-serif"/>
<Label text="monospace" style="font-family: monospace"/>
<Label text="Times New Roman" style="font-family: Times New Roman"/>
<Label text="invalid font" style="font-family: InvalidFont"/>
<Label text="all in one" style="font-family: serif; font-weight: bold; font-style: italic; font-size: 32; color: green" />
</WrapLayout>
</StackLayout>
</Page>

View File

@ -0,0 +1,16 @@
import stack = require("ui/layouts/stack-layout");
import style = require("ui/styling/style");
import view = require("ui/core/view");
export function resetStyles(args) {
var stackLayout = <stack.StackLayout>args.object.parent;
view.eachDescendant(stackLayout, function (v: view.View) {
v.style._resetValue(style.fontFamilyProperty);
v.style._resetValue(style.fontSizeProperty);
v.style._resetValue(style.fontStyleProperty);
v.style._resetValue(style.fontWeightProperty);
v.style._resetValue(style.fontProperty);
v.style._resetValue(style.colorProperty);
v.style._resetValue(style.textAlignmentProperty);
return true;
});
}

View File

@ -0,0 +1,25 @@
<Page>
<StackLayout>
<Button text="RESET" tap="resetStyles"/>
<TextField text="no align" />
<TextField text="left" style="text-align: left" />
<TextField text="center" style="text-align: center" />
<TextField text="right" style="text-align: right" />
<WrapLayout>
<TextField text="normal" />
<TextField text="color" style="color: green"/>
<TextField text="size" style="font-size: 32" />
<TextField text="italic" style="font-style: italic" />
<TextField text="bold" style="font-weight: bold"/>
<TextField text="bold-italic" style="font-weight: bold; font-style: italic"/>
<TextField text="serif" style="font-family: serif"/>
<TextField text="sans-serif" style="font-family: sans-serif"/>
<TextField text="monospace" style="font-family: monospace"/>
<TextField text="Times New Roman" style="font-family: Times New Roman"/>
<TextField text="invalid font" style="font-family: InvalidFont"/>
<TextField text="all in one" style="font-family: serif; font-weight: bold; font-style: italic; font-size: 32; color: green" />
</WrapLayout>
</StackLayout>
</Page>

View File

@ -0,0 +1,16 @@
import stack = require("ui/layouts/stack-layout");
import style = require("ui/styling/style");
import view = require("ui/core/view");
export function resetStyles(args) {
var stackLayout = <stack.StackLayout>args.object.parent;
view.eachDescendant(stackLayout, function (v: view.View) {
v.style._resetValue(style.fontFamilyProperty);
v.style._resetValue(style.fontSizeProperty);
v.style._resetValue(style.fontStyleProperty);
v.style._resetValue(style.fontWeightProperty);
v.style._resetValue(style.fontProperty);
v.style._resetValue(style.colorProperty);
v.style._resetValue(style.textAlignmentProperty);
return true;
});
}

View File

@ -0,0 +1,25 @@
<Page>
<StackLayout>
<Button text="RESET" tap="resetStyles"/>
<TextView text="no align" />
<TextView text="left" style="text-align: left" />
<TextView text="center" style="text-align: center" />
<TextView text="right" style="text-align: right" />
<WrapLayout>
<TextView text="normal" />
<TextView text="color" style="color: green"/>
<TextView text="size" style="font-size: 32" />
<TextView text="italic" style="font-style: italic" />
<TextView text="bold" style="font-weight: bold"/>
<TextView text="bold-italic" style="font-weight: bold; font-style: italic"/>
<TextView text="serif" style="font-family: serif"/>
<TextView text="sans-serif" style="font-family: sans-serif"/>
<TextView text="monospace" style="font-family: monospace"/>
<TextView text="Times New Roman" style="font-family: Times New Roman"/>
<TextView text="invalid font" style="font-family: InvalidFont"/>
<TextView text="all in one" style="font-family: serif; font-weight: bold; font-style: italic; font-size: 32; color: green" />
</WrapLayout>
</StackLayout>
</Page>

View File

@ -94,6 +94,12 @@ export class Color implements definition.Color {
}
public static equals(value1: definition.Color, value2: definition.Color): boolean {
// both values are falsy
if (!value1 && !value2) {
return true;
}
// only one is falsy
if (!value1 || !value2) {
return false;
}

View File

@ -9,8 +9,8 @@ export class Span extends spanCommon.Span {
public updateSpanModifiers(parent: formattedString.FormattedString) {
super.updateSpanModifiers(parent);
var realFontFamily = this.fontFamily || (parent ? parent.fontFamily : undefined);
var realFontSize = this.fontSize ||
(parent ? parent.fontSize : undefined) ||
var realFontSize = this.fontSize ||
(parent ? parent.fontSize : undefined) ||
(parent && parent.parent ? parent.parent.style.fontSize : undefined);
var realFontAttributes = this.fontAttributes || (parent ? parent.fontAttributes : undefined);
@ -25,10 +25,10 @@ export class Span extends spanCommon.Span {
else {
var fontDescriptor = UIFontDescriptor.new();
var symbolicTraits;
if (realFontAttributes & enums.FontAttributes.Bold) {
if (realFontAttributes & enums.FontAttributes.Bold) {
symbolicTraits |= UIFontDescriptorSymbolicTraits.UIFontDescriptorTraitBold;
}
if (realFontAttributes & enums.FontAttributes.Italic) {
if (realFontAttributes & enums.FontAttributes.Italic) {
symbolicTraits |= UIFontDescriptorSymbolicTraits.UIFontDescriptorTraitItalic;
}
font = UIFont.fontWithDescriptorSize(fontDescriptor.fontDescriptorWithSymbolicTraits(symbolicTraits), realFontSize);
@ -41,7 +41,7 @@ export class Span extends spanCommon.Span {
}
}
var realForegroundColor = this.foregroundColor ||
var realForegroundColor = this.foregroundColor ||
(parent ? parent.foregroundColor : undefined) ||
(parent && parent.parent ? parent.parent.style.color : undefined);
if (realForegroundColor) {
@ -51,7 +51,7 @@ export class Span extends spanCommon.Span {
});
}
var realBackgroundColor = this.backgroundColor ||
var realBackgroundColor = this.backgroundColor ||
(parent ? parent.backgroundColor : undefined) ||
(parent && parent.parent ? parent.parent.style.backgroundColor : undefined);
if (realBackgroundColor) {

View File

@ -73,6 +73,10 @@ declare module "ui/core/dependency-observable" {
* Gets or sets the callback to be raised whenever the associated property is about to change for any DependencyObservable instance that uses the property to store a value.
*/
onValidateValue: PropertyValidationCallback;
/**
* Gets function that used to compare if two property values are equal.
*/
equalityComparer: PropertyEqualityComparer;
/**
* Checks whether the PropertyMetadataSettings.affectsLayout bit is present in the options value.
*/

32
ui/enums/enums.d.ts vendored
View File

@ -370,4 +370,36 @@
*/
export var popup: string;
}
/**
* Specifies different font styles.
*/
export module FontStyle {
/**
* Normal font style.
*/
export var normal: string;
/**
* Italic font style.
*/
export var italic: string;
}
/**
* Specifies different font weights.
*/
export module FontWeight {
/**
* Normal font weight.
*/
export var normal: string;
/**
* Bold font weight.
*/
export var bold: string;
}
}

View File

@ -102,4 +102,14 @@ export module MenuItemPosition {
export module ImageFormat {
export var png: string = "png";
export var jpeg: string = "jpeg";
}
}
export module FontStyle {
export var normal: string = "normal";
export var italic: string = "italic";
}
export module FontWeight {
export var normal: string = "normal";
export var bold: string = "bold";
}

186
ui/styling/font-common.ts Normal file
View File

@ -0,0 +1,186 @@
import enums = require("ui/enums");
import definitios = require("ui/styling/font");
import converters = require("ui/styling/converters");
export class Font implements definitios.Font {
public static default = undefined;
private _fontFamily: string;
private _fontStyle: string;
private _fontWeight: string;
private _fontSize: number;
get fontFamily(): string {
return this._fontFamily;
}
set fontFamily(value: string) {
throw new Error("fontFamily is read-only");
}
get fontStyle(): string {
return this._fontStyle;
}
set fontStyle(value: string) {
throw new Error("fontStyle is read-only");
}
get fontWeight(): string {
return this._fontWeight;
}
set fontWeight(value: string) {
throw new Error("fontWeight is read-only");
}
get fontSize(): number {
return this._fontSize;
}
set fontSize(value: number) {
throw new Error("fontSize is read-only");
}
get isBold(): boolean {
return this._fontWeight.toLowerCase() === enums.FontWeight.bold;;
}
set isBold(value: boolean) {
throw new Error("isBold is read-only");
}
get isItalic(): boolean {
return this._fontStyle.toLowerCase() === enums.FontStyle.italic;;
}
set isItalic(value: boolean) {
throw new Error("isItalic is read-only");
}
constructor(family: string, size: number, style: string, weight: string) {
this._fontFamily = family;
this._fontSize = size;
this._fontStyle = style;
this._fontWeight = weight;
}
public getAndroidTypeface(): android.graphics.Typeface {
return undefined;
}
public getUIFont(defaultFont: UIFont): UIFont {
return undefined;
}
public withFontFamily(family: string): Font {
throw new Error("This should be called on the derived class");
}
public withFontStyle(style: string): Font {
throw new Error("This should be called on the derived class");
}
public withFontWeight(weight: string): Font {
throw new Error("This should be called on the derived class");
}
public withFontSize(size: number): Font {
throw new Error("This should be called on the derived class");
}
public static equals(value1: Font, value2: Font): boolean {
// both values are falsy
if (!value1 && !value2) {
return true;
}
// only one is falsy
if (!value1 || !value2) {
return false;
}
return value1.fontFamily === value2.fontFamily &&
value1.fontSize === value2.fontSize &&
value1.fontStyle === value2.fontStyle &&
value1.fontWeight === value2.fontWeight;
}
public static parse(cssValue: string): Font {
var parsed = parseFont(cssValue);
var size = converters.fontSizeConverter(parsed.fontSize);
size = !!size ? size : undefined;
return new Font(parsed.fontFamily, size, parsed.fontStyle, parsed.fontWeight);
}
}
export function parseFontFamily(value: string): Array<string> {
var result = new Array<string>();
if (!value) {
return result;
}
var split = value.split(",");
for (var i = 0; i < split.length; i++) {
var str = split[i].trim().replace(/['"]+/g, '');
if (str) {
result.push(str);
}
}
return result;
}
export module genericFontFamilies {
export var serif = "serif";
export var sansSerif = "sans-serif";
export var monospace = "monospace";
}
var styles = new Set();
["italic", "oblique"].forEach((val, i, a) => styles.add(val));
var weights = new Set();
["bold", "bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900"].forEach((val, i, a) => weights.add(val));
interface ParsedFont {
fontStyle?: string;
fontVariant?: string;
fontWeight?: string,
lineHeight?: string,
fontSize?: string,
fontFamily?: string
}
function parseFont(fontValue: string): ParsedFont {
var result: ParsedFont = {
fontStyle: "normal",
fontVariant: "normal",
fontWeight: "normal",
}
var parts = fontValue.split(/\s+/);
var part: string;
while (part = parts.shift()) {
if (part === "normal") {
// nothing to do here
}
else if (part === "small-caps") {
// The only supported font variant in shorthand font
result.fontVariant = part;
}
else if (styles.has(part)) {
result.fontStyle = part
}
else if (weights.has(part)) {
result.fontWeight = part;
}
else if (!result.fontSize) {
var sizes = part.split("/");
result.fontSize = sizes[0];
result.lineHeight = sizes.length > 1 ? sizes[1] : undefined;
}
else {
result.fontFamily = part;
if (parts.length) {
result.fontFamily += " " + parts.join(" ");
}
break;
}
}
return result;
}

124
ui/styling/font.android.ts Normal file
View File

@ -0,0 +1,124 @@
import enums = require("ui/enums");
import common = require("ui/styling/font-common");
import application = require("application");
import trace = require("trace");
import types = require("utils/types");
import fs = require("file-system");
var typefaceCache = new Map<string, android.graphics.Typeface>();
var appAssets: android.content.res.AssetManager;
var FONTS_BASE_PATH = "app/fonts/";
export class Font extends common.Font {
public static default = new Font(undefined, undefined, enums.FontStyle.normal, enums.FontWeight.normal);
private _typeface: android.graphics.Typeface;
constructor(family: string, size: number, style: string, weight: string) {
super(family, size, style, weight);
}
public withFontFamily(family: string): Font {
return new Font(family, this.fontSize, this.fontStyle, this.fontWeight);
}
public withFontStyle(style: string): Font {
return new Font(this.fontFamily, this.fontSize, style, this.fontWeight);
}
public withFontWeight(weight: string): Font {
return new Font(this.fontFamily, this.fontSize, this.fontStyle, weight);
}
public withFontSize(size: number): Font {
return new Font(this.fontFamily, size, this.fontStyle, this.fontWeight);
}
public getAndroidTypeface(): android.graphics.Typeface {
if (!this._typeface) {
var style: number = 0;
if (this.isBold) {
style |= android.graphics.Typeface.BOLD;
}
if (this.isItalic) {
style |= android.graphics.Typeface.ITALIC;
}
var typeFace = this.getTypeFace(this.fontFamily);
this._typeface = android.graphics.Typeface.create(typeFace, style);
}
return this._typeface;
}
private getTypeFace(fontFamily: string): android.graphics.Typeface {
var fonts = common.parseFontFamily(fontFamily);
var result = null;
if (fonts.length === 0) {
return null;
}
for (var i = 0; i < fonts.length; i++) {
switch (fonts[i].toLowerCase()) {
case common.genericFontFamilies.serif:
result = android.graphics.Typeface.SERIF;
break;
case common.genericFontFamilies.sansSerif:
result = android.graphics.Typeface.SANS_SERIF;
break;
case common.genericFontFamilies.monospace:
result = android.graphics.Typeface.MONOSPACE;
break;
default:
result = this.loadFontFromAsset(fonts[i]);
break;
}
if (result) {
return result;
}
}
return null;
}
private loadFontFromAsset(fontFamily: string): android.graphics.Typeface {
appAssets = appAssets || application.android.context.getAssets();
if (!appAssets) {
return null;
}
var result = typefaceCache.get(fontFamily);
// Check for undefined explicitly as null mean we tried to load the font, but failed.
if (types.isUndefined(result)) {
result = null;
var fontAssetPath: string;
var basePath = fs.path.join(fs.knownFolders.currentApp().path, "fonts", fontFamily);
if (fs.File.exists(basePath + ".ttf")) {
fontAssetPath = FONTS_BASE_PATH + fontFamily + ".ttf";
}
else if (fs.File.exists(basePath + ".otf")) {
fontAssetPath = FONTS_BASE_PATH + fontFamily + ".otf";
}
else {
trace.write("Could not find font file for " + fontFamily, trace.categories.Error, trace.messageType.error);
}
if (fontAssetPath) {
try {
result = android.graphics.Typeface.createFromAsset(appAssets, fontAssetPath);
} catch (e) {
trace.write("Error loading font asset: " + fontAssetPath, trace.categories.Error, trace.messageType.error);
}
}
typefaceCache.set(fontFamily, result);
}
return result;
}
}

30
ui/styling/font.d.ts vendored Normal file
View File

@ -0,0 +1,30 @@
declare module "ui/styling/font" {
export class Font {
public static default: Font;
public fontFamily: string;
public fontStyle: string;
public fontWeight: string;
public fontSize: number;
public isBold: boolean;
public isItalic: boolean;
constructor(family: string, size: number, style: string, weight: string);
public getAndroidTypeface(): android.graphics.Typeface;
public getUIFont(defaultFont: UIFont): UIFont;
public withFontFamily(family: string): Font;
public withFontStyle(style: string): Font;
public withFontWeight(weight: string): Font;
public withFontSize(size: number): Font;
public static equals(value1: Font, value2: Font): boolean;
public static parse(cssValue: string): Font;
}
export module ios {
export function registerFont(fontFile: string);
}
}

152
ui/styling/font.ios.ts Normal file
View File

@ -0,0 +1,152 @@
import enums = require("ui/enums");
import common = require("ui/styling/font-common");
import fs = require("file-system");
var DEFAULT_SERIF = "Times New Roman";
var DEFAULT_SANS_SERIF = "Helvetica";
var DEFAULT_MONOSPACE = "Courier New";
export class Font extends common.Font {
public static default = new Font(undefined, undefined, enums.FontStyle.normal, enums.FontWeight.normal);
private _uiFont: UIFont;
constructor(family: string, size: number, style: string, weight: string) {
super(family, size, style, weight);
}
public getUIFont(defaultFont: UIFont): UIFont {
if (!this._uiFont) {
var symbolicTraits: number = 0;
if (this.isBold) {
symbolicTraits |= UIFontDescriptorSymbolicTraits.UIFontDescriptorTraitBold;
}
if (this.isItalic) {
symbolicTraits |= UIFontDescriptorSymbolicTraits.UIFontDescriptorTraitItalic;
}
var descriptor = resolveFontDescriptor(this.fontFamily, symbolicTraits);
if (!descriptor) {
descriptor = defaultFont.fontDescriptor().fontDescriptorWithSymbolicTraits(symbolicTraits);
}
var size = this.fontSize || defaultFont.pointSize;
this._uiFont = UIFont.fontWithDescriptorSize(descriptor, size);
}
return this._uiFont;
}
public withFontFamily(family: string): Font {
return new Font(family, this.fontSize, this.fontStyle, this.fontWeight);
}
public withFontStyle(style: string): Font {
return new Font(this.fontFamily, this.fontSize, style, this.fontWeight);
}
public withFontWeight(weight: string): Font {
return new Font(this.fontFamily, this.fontSize, this.fontStyle, weight);
}
public withFontSize(size: number): Font {
return new Font(this.fontFamily, size, this.fontStyle, this.fontWeight);
}
}
var areSystemFontSetsValid: boolean = false;
var systemFontFamilies = new Set();
var systemFonts = new Set();
function assureSystemFontSets() {
if (!areSystemFontSetsValid) {
var nsFontFamilies = UIFont.familyNames();
for (var i = 0; i < nsFontFamilies.count; i++) {
var family = nsFontFamilies.objectAtIndex(i);
systemFontFamilies.add(family);
var nsFonts = UIFont.fontNamesForFamilyName(family);
for (var j = 0; j < nsFonts.count; j++) {
var font = nsFonts.objectAtIndex(j);
systemFonts.add(font);
}
}
areSystemFontSetsValid = true;
}
}
function resolveFontDescriptor(fontFamilyValue: string, symbolicTraits: number): UIFontDescriptor {
var fonts = common.parseFontFamily(fontFamilyValue);
var result: UIFontDescriptor = null;
if (fonts.length === 0) {
return null;
}
assureSystemFontSets();
for (var i = 0; i < fonts.length; i++) {
var fontFamily = getFontFamilyRespectingGenericFonts(fonts[i]);
if (systemFontFamilies.has(fontFamily)) {
// This is a font family - we should apply symbolic traits if there are such
result = UIFontDescriptor.fontDescriptorWithNameSize(fontFamily, 0);
if (symbolicTraits) {
result = result.fontDescriptorWithSymbolicTraits(symbolicTraits);
}
}
else if (systemFonts.has(fontFamily)) {
// This is an actual font - don't apply symbolic traits
result = UIFontDescriptor.fontDescriptorWithNameSize(fontFamily, 0);
}
else {
// TODO: Handle custom fonts when they are supported.
}
if (result) {
return result;
}
}
return null;
}
function getFontFamilyRespectingGenericFonts(fontFamily: string): string {
if (!fontFamily) {
return fontFamily;
}
switch (fontFamily.toLowerCase()) {
case common.genericFontFamilies.serif:
return DEFAULT_SERIF;
case common.genericFontFamilies.sansSerif:
return DEFAULT_SANS_SERIF;
case common.genericFontFamilies.monospace:
return DEFAULT_MONOSPACE;
default:
return fontFamily;
}
}
export module ios {
export function registerFont(fontFile: string) {
var filePath = fs.path.join(fs.knownFolders.currentApp().path, "fonts", fontFile);
var fontData = NSFileManager.defaultManager().contentsAtPath(filePath);
if (!fontData) {
throw new Error("Could not load font from: " + fontFile);
}
var provider = CGDataProviderCreateWithCFData(fontData);
var font = CGFontCreateWithDataProvider(provider);
if (!font) {
throw new Error("Could not load font from: " + fontFile);
}
var error = NSError.alloc().init();
if (!CTFontManagerRegisterGraphicsFont(font, error)) {
throw new Error(error.localizedDescription);
}
areSystemFontSetsValid = false;
}
}

View File

@ -11,6 +11,7 @@ import converters = require("ui/styling/converters");
import enums = require("ui/enums");
import imageSource = require("image-source");
import utils = require("utils/utils");
import font = require("ui/styling/font");
// key is the property id and value is Dictionary<string, StylePropertyChangedHandler>;
var _registeredHandlers = Array<Object>();
@ -75,6 +76,34 @@ export class Style extends observable.DependencyObservable implements styling.St
this._setValue(fontSizeProperty, value, observable.ValueSource.Local);
}
get fontFamily(): string {
return this._getValue(fontFamilyProperty);
}
set fontFamily(value: string) {
this._setValue(fontFamilyProperty, value, observable.ValueSource.Local);
}
get fontStyle(): string {
return this._getValue(fontStyleProperty);
}
set fontStyle(value: string) {
this._setValue(fontStyleProperty, value, observable.ValueSource.Local);
}
get fontWeight(): string {
return this._getValue(fontWeightProperty);
}
set fontWeight(value: string) {
this._setValue(fontWeightProperty, value, observable.ValueSource.Local);
}
get font(): string {
return this._getValue(fontProperty);
}
set font(value: string) {
this._setValue(fontProperty, value, observable.ValueSource.Local);
}
get textAlignment(): string {
return this._getValue(textAlignmentProperty);
}
@ -288,8 +317,16 @@ export class Style extends observable.DependencyObservable implements styling.St
}
else {
trace.write("Found handler for property: " + property.name + ", view:" + this._view, trace.categories.Style);
var shouldReset = false;
if (property.metadata.equalityComparer) {
shouldReset = property.metadata.equalityComparer(newValue, property.metadata.defaultValue);
}
else {
shouldReset = (newValue === property.metadata.defaultValue);
}
if (types.isUndefined(newValue)) {
if (shouldReset) {
(<any>handler).resetProperty(property, this._view);
} else {
(<any>handler).applyProperty(property, this._view, newValue);
@ -440,9 +477,78 @@ export var backgroundColorProperty = new styleProperty.Property("backgroundColor
new observable.PropertyMetadata(undefined, observable.PropertyMetadataSettings.None, undefined, undefined, color.Color.equals),
converters.colorConverter);
export var fontProperty = new styleProperty.Property("font", "font",
new observable.PropertyMetadata(undefined, observable.PropertyMetadataSettings.None, onFontChanged));
export var fontSizeProperty = new styleProperty.Property("fontSize", "font-size",
new observable.PropertyMetadata(undefined, observable.PropertyMetadataSettings.AffectsLayout | observable.PropertyMetadataSettings.Inheritable),
converters.fontSizeConverter);
new observable.PropertyMetadata(undefined, observable.PropertyMetadataSettings.Inheritable, onFontSizeChanged),converters.fontSizeConverter);
export var fontFamilyProperty = new styleProperty.Property("fontFamily", "font-family",
new observable.PropertyMetadata(undefined, observable.PropertyMetadataSettings.Inheritable, onFontFamilyChanged));
export var fontStyleProperty = new styleProperty.Property("fontStyle", "font-style",
new observable.PropertyMetadata(enums.FontStyle.normal, observable.PropertyMetadataSettings.Inheritable, onFontStyleChanged, isFontStyleValid));
export var fontWeightProperty = new styleProperty.Property("fontWeight", "font-weight",
new observable.PropertyMetadata(enums.FontWeight.normal, observable.PropertyMetadataSettings.Inheritable, onFontWeightChanged, isFontWeightValid));
export var fontInternalProperty = new styleProperty.Property("_fontInternal", "_fontInternal",
new observable.PropertyMetadata(font.Font.default, observable.PropertyMetadataSettings.AffectsLayout, null, null, font.Font.equals), font.Font.parse);
function isFontWeightValid(value: string): boolean {
return value === enums.FontWeight.normal || value === enums.FontWeight.bold;
}
function isFontStyleValid(value: string): boolean {
return value === enums.FontStyle.normal || value === enums.FontStyle.italic;
}
function onFontFamilyChanged(data: observable.PropertyChangeData) {
var style = <Style>data.object;
var currentFont = <font.Font>style._getValue(fontInternalProperty);
if (currentFont.fontFamily !== data.newValue) {
style._setValue(fontInternalProperty, currentFont.withFontFamily(data.newValue));
}
}
function onFontStyleChanged(data: observable.PropertyChangeData) {
var style = <Style>data.object;
var currentFont = <font.Font>style._getValue(fontInternalProperty);
if (currentFont.fontStyle !== data.newValue) {
style._setValue(fontInternalProperty, currentFont.withFontStyle(data.newValue));
}
}
function onFontWeightChanged(data: observable.PropertyChangeData) {
var style = <Style>data.object;
var currentFont = <font.Font>style._getValue(fontInternalProperty);
if (currentFont.fontWeight !== data.newValue) {
style._setValue(fontInternalProperty, currentFont.withFontWeight(data.newValue));
}
}
function onFontSizeChanged(data: observable.PropertyChangeData) {
var style = <Style>data.object;
var currentFont = <font.Font>style._getValue(fontInternalProperty);
if (currentFont.fontSize !== data.newValue) {
style._setValue(fontInternalProperty, currentFont.withFontSize(data.newValue));
}
}
function onFontChanged(data: observable.PropertyChangeData) {
var style = <Style>data.object;
var newFont = font.Font.parse(data.newValue);
var valueSource = style._getValueSource(fontProperty);
style._setValue(fontFamilyProperty, newFont.fontFamily, valueSource);
style._setValue(fontStyleProperty, newFont.fontStyle, valueSource);
style._setValue(fontWeightProperty, newFont.fontWeight, valueSource);
style._setValue(fontSizeProperty, newFont.fontSize, valueSource);
}
export var textAlignmentProperty = new styleProperty.Property("textAlignment", "text-align",
new observable.PropertyMetadata(undefined, observable.PropertyMetadataSettings.AffectsLayout | observable.PropertyMetadataSettings.Inheritable),

View File

@ -6,12 +6,12 @@ import types = require("utils/types");
var _defaultNativeValuesCache = {};
export class StylePropertyChangedHandler {
private _applyProperty: (view: view.View, newValue: any) => void;
private _applyProperty: (view: view.View, newValue: any, defaultValue?: any) => void;
private _resetProperty: (view: view.View, nativeValue: any) => void;
private _getNativeValue: (view: view.View) => any;
constructor(
applyCallback: (view: view.View, newValue: any) => void,
applyCallback: (view: view.View, newValue: any, defaultValue?: any) => void,
resetCallback: (view: view.View, nativeValue: any) => void,
getNativeValue?: (view: view.View) => any) {
@ -33,7 +33,7 @@ export class StylePropertyChangedHandler {
newValue = newValue.ios ? newValue.ios : newValue;
}
this._applyProperty(view, newValue);
this._applyProperty(view, newValue, _defaultNativeValuesCache[className + property.id]);
}
public resetProperty(property: dependencyObservable.Property, view: view.View) {

View File

@ -10,6 +10,7 @@ import enums = require("ui/enums");
import utils = require("utils/utils");
import styleModule = require("ui/styling/style");
import imageSource = require("image-source");
import font = require("ui/styling/font");
// merge the exports of the common file with the exports of this file
declare var exports;
@ -289,17 +290,39 @@ export class TextViewStyler implements definition.stylers.Styler {
return (<android.widget.TextView>view.android).getTextColors().getDefaultColor();
}
// font-size
private static setFontSizeProperty(view: view.View, newValue: any) {
(<android.widget.TextView>view.android).setTextSize(newValue);
// font
private static setFontInternalProperty(view: view.View, newValue: any, nativeValue: any) {
var tv = <android.widget.TextView>view.android;
var fontValue = <font.Font>newValue;
var typeface = fontValue.getAndroidTypeface();
if (typeface) {
tv.setTypeface(typeface);
}
else {
tv.setTypeface(nativeValue.typeface);
}
if (fontValue.fontSize) {
tv.setTextSize(fontValue.fontSize);
}
else {
tv.setTextSize(android.util.TypedValue.COMPLEX_UNIT_PX, nativeValue.size);
}
}
private static resetFontSizeProperty(view: view.View, nativeValue: any) {
(<android.widget.TextView>view.android).setTextSize(android.util.TypedValue.COMPLEX_UNIT_PX, nativeValue);
private static resetFontInternalProperty(view: view.View, nativeValue: any) {
var tv: android.widget.TextView = <android.widget.TextView>view.android;
tv.setTypeface(nativeValue.typeface);
tv.setTextSize(android.util.TypedValue.COMPLEX_UNIT_PX, nativeValue.size);
}
private static getNativeFontSizeValue(view: view.View): any {
return (<android.widget.TextView>view.android).getTextSize();
private static getNativeFontInternalValue(view: view.View): any {
var tv: android.widget.TextView = <android.widget.TextView>view.android;
return {
typeface: tv.getTypeface(),
size: tv.getTextSize()
};
}
// text-align
@ -332,17 +355,35 @@ export class TextViewStyler implements definition.stylers.Styler {
style.registerHandler(style.colorProperty, new stylersCommon.StylePropertyChangedHandler(
TextViewStyler.setColorProperty,
TextViewStyler.resetColorProperty,
TextViewStyler.getNativeColorValue));
TextViewStyler.getNativeColorValue), "TextBase");
style.registerHandler(style.fontSizeProperty, new stylersCommon.StylePropertyChangedHandler(
TextViewStyler.setFontSizeProperty,
TextViewStyler.resetFontSizeProperty,
TextViewStyler.getNativeFontSizeValue));
style.registerHandler(style.fontInternalProperty, new stylersCommon.StylePropertyChangedHandler(
TextViewStyler.setFontInternalProperty,
TextViewStyler.resetFontInternalProperty,
TextViewStyler.getNativeFontInternalValue), "TextBase");
style.registerHandler(style.textAlignmentProperty, new stylersCommon.StylePropertyChangedHandler(
TextViewStyler.setTextAlignmentProperty,
TextViewStyler.resetTextAlignmentProperty,
TextViewStyler.getNativeTextAlignmentValue));
TextViewStyler.getNativeTextAlignmentValue), "TextBase");
// Register the same stylers for Button.
// It also derives from TextView but is not under TextBase in our View hierarchy.
style.registerHandler(style.colorProperty, new stylersCommon.StylePropertyChangedHandler(
TextViewStyler.setColorProperty,
TextViewStyler.resetColorProperty,
TextViewStyler.getNativeColorValue), "Button");
style.registerHandler(style.fontInternalProperty, new stylersCommon.StylePropertyChangedHandler(
TextViewStyler.setFontInternalProperty,
TextViewStyler.resetFontInternalProperty,
TextViewStyler.getNativeFontInternalValue), "Button");
style.registerHandler(style.textAlignmentProperty, new stylersCommon.StylePropertyChangedHandler(
TextViewStyler.setTextAlignmentProperty,
TextViewStyler.resetTextAlignmentProperty,
TextViewStyler.getNativeTextAlignmentValue), "Button");
}
}
@ -493,6 +534,7 @@ export class BorderStyler implements definition.stylers.Styler {
}
}
// Register all styler at the end.
export function _registerDefaultStylers() {
style.registerNoStylingClass("Frame");
DefaultStyler.registerHandlers();

View File

@ -3,11 +3,18 @@ import style = require("ui/styling/style");
import definition = require("ui/styling");
import stylersCommon = require("ui/styling/stylers-common");
import enums = require("ui/enums");
import font = require("ui/styling/font");
// merge the exports of the common file with the exports of this file
declare var exports;
require("utils/module-merge").merge(stylersCommon, exports);
interface TextUIView {
font: UIFont;
textAlignment: number;
textColor: UIColor;
}
export class DefaultStyler implements definition.stylers.Styler {
//Background methods
private static setBackgroundProperty(view: view.View, newValue: any) {
@ -158,88 +165,70 @@ export class DefaultStyler implements definition.stylers.Styler {
}
export class ButtonStyler implements definition.stylers.Styler {
// Color methods
// color
private static setColorProperty(view: view.View, newValue: any) {
var btn: UIButton = <UIButton>view._nativeView;
if (btn) {
btn.setTitleColorForState(newValue, UIControlState.UIControlStateNormal);
}
btn.setTitleColorForState(newValue, UIControlState.UIControlStateNormal);
}
private static resetColorProperty(view: view.View, nativeValue: any) {
var btn: UIButton = <UIButton>view._nativeView;
if (btn) {
btn.setTitleColorForState(nativeValue, UIControlState.UIControlStateNormal);
}
btn.setTitleColorForState(nativeValue, UIControlState.UIControlStateNormal);
}
private static getNativeColorValue(view: view.View): any {
var btn: UIButton = <UIButton>view._nativeView;
if (btn) {
return btn.titleColorForState(UIControlState.UIControlStateNormal);
}
return btn.titleColorForState(UIControlState.UIControlStateNormal);
}
// Font size
private static setFontSizeProperty(view: view.View, newValue: any) {
// font
private static setFontInternalProperty(view: view.View, newValue: any, nativeValue: any) {
var btn: UIButton = <UIButton>view._nativeView;
if (btn) {
btn.titleLabel.font = btn.titleLabel.font.fontWithSize(newValue);
}
btn.titleLabel.font = (<font.Font>newValue).getUIFont(nativeValue);
}
private static resetFontSizeProperty(view: view.View, nativeValue: any) {
private static resetFontInternalProperty(view: view.View, nativeValue: any) {
var btn: UIButton = <UIButton>view._nativeView;
if (btn) {
btn.font = btn.titleLabel.font.fontWithSize(nativeValue);
}
btn.titleLabel.font = nativeValue;
}
private static getNativeFontSizeValue(view: view.View): any {
private static getNativeFontInternalValue(view: view.View): any {
var btn: UIButton = <UIButton>view._nativeView;
if (btn) {
return btn.titleLabel.font.pointSize;
}
return btn.titleLabel.font;
}
// text-align
private static setTextAlignmentProperty(view: view.View, newValue: any) {
var ios: UIButton = <UIButton>view._nativeView;
if (ios) {
switch (newValue) {
case enums.TextAlignment.left:
ios.titleLabel.textAlignment = NSTextAlignment.NSTextAlignmentLeft;
ios.contentHorizontalAlignment = UIControlContentHorizontalAlignment.UIControlContentHorizontalAlignmentLeft;
break;
case enums.TextAlignment.center:
ios.titleLabel.textAlignment = NSTextAlignment.NSTextAlignmentCenter;
ios.contentHorizontalAlignment = UIControlContentHorizontalAlignment.UIControlContentHorizontalAlignmentCenter;
break;
case enums.TextAlignment.right:
ios.titleLabel.textAlignment = NSTextAlignment.NSTextAlignmentRight;
ios.contentHorizontalAlignment = UIControlContentHorizontalAlignment.UIControlContentHorizontalAlignmentRight;
break;
default:
break;
}
var btn: UIButton = <UIButton>view._nativeView;
setTextAlignment(btn.titleLabel, newValue);
// Also set the contentHorizontalAlignment
switch (newValue) {
case enums.TextAlignment.left:
btn.contentHorizontalAlignment = UIControlContentHorizontalAlignment.UIControlContentHorizontalAlignmentLeft;
break;
case enums.TextAlignment.center:
btn.contentHorizontalAlignment = UIControlContentHorizontalAlignment.UIControlContentHorizontalAlignmentCenter;
break;
case enums.TextAlignment.right:
btn.contentHorizontalAlignment = UIControlContentHorizontalAlignment.UIControlContentHorizontalAlignmentRight;
break;
default:
break;
}
}
private static resetTextAlignmentProperty(view: view.View, nativeValue: any) {
var ios: UIButton = <UIButton>view._nativeView;
if (ios) {
ios.titleLabel.textAlignment = nativeValue.textAlign;
ios.contentHorizontalAlignment = nativeValue.contentAlign;
}
var btn: UIButton = <UIButton>view._nativeView;
btn.titleLabel.textAlignment = nativeValue.textAlign;
btn.contentHorizontalAlignment = nativeValue.contentAlign;
}
private static getNativeTextAlignmentValue(view: view.View): any {
var ios: UIButton = <UIButton>view._nativeView;
if (ios) {
return {
textAlign: ios.titleLabel.textAlignment,
contentAlign: ios.contentHorizontalAlignment
}
var btn: UIButton = <UIButton>view._nativeView;
return {
textAlign: btn.titleLabel.textAlignment,
contentAlign: btn.contentHorizontalAlignment
}
}
@ -249,10 +238,10 @@ export class ButtonStyler implements definition.stylers.Styler {
ButtonStyler.resetColorProperty,
ButtonStyler.getNativeColorValue), "Button");
style.registerHandler(style.fontSizeProperty, new stylersCommon.StylePropertyChangedHandler(
ButtonStyler.setFontSizeProperty,
ButtonStyler.resetFontSizeProperty,
ButtonStyler.getNativeFontSizeValue), "Button");
style.registerHandler(style.fontInternalProperty, new stylersCommon.StylePropertyChangedHandler(
ButtonStyler.setFontInternalProperty,
ButtonStyler.resetFontInternalProperty,
ButtonStyler.getNativeFontInternalValue), "Button");
style.registerHandler(style.textAlignmentProperty, new stylersCommon.StylePropertyChangedHandler(
ButtonStyler.setTextAlignmentProperty,
@ -261,197 +250,69 @@ export class ButtonStyler implements definition.stylers.Styler {
}
}
export class LabelStyler implements definition.stylers.Styler {
// Color methods
private static setColorProperty(view: view.View, newValue: any) {
var label: UILabel = <UILabel>view._nativeView;
if (label) {
label.textColor = newValue;
}
export class TextBaseStyler implements definition.stylers.Styler {
// font
private static setFontInternalProperty(view: view.View, newValue: any, nativeValue: any) {
var ios: TextUIView = <TextUIView>view._nativeView;
ios.font = (<font.Font>newValue).getUIFont(nativeValue);
}
private static resetColorProperty(view: view.View, nativeValue: any) {
var label: UILabel = <UILabel>view._nativeView;
if (label) {
label.textColor = nativeValue;
}
private static resetFontInternalProperty(view: view.View, nativeValue: any) {
var ios: TextUIView = <TextUIView>view._nativeView;
ios.font = nativeValue;
}
private static getNativeColorValue(view: view.View): any {
var label: UILabel = <UILabel>view._nativeView;
if (label) {
return label.textColor;
}
}
// Font size
private static setFontSizeProperty(view: view.View, newValue: any) {
var label: UILabel = <UILabel>view._nativeView;
if (label) {
label.font = label.font.fontWithSize(newValue);
}
}
private static resetFontSizeProperty(view: view.View, nativeValue: any) {
var label: UILabel = <UILabel>view._nativeView;
if (label) {
label.font = label.font.fontWithSize(nativeValue);
}
}
private static getNativeFontSizeValue(view: view.View): any {
var label: UILabel = <UILabel>view._nativeView;
if (label) {
return label.font.pointSize;
}
private static getNativeFontInternalValue(view: view.View): any {
var ios: TextUIView = <TextUIView>view._nativeView;
return ios.font;
}
// text-align
private static setTextAlignmentProperty(view: view.View, newValue: any) {
var ios: UILabel = <UILabel>view._nativeView;
if (ios) {
switch (newValue) {
case enums.TextAlignment.left:
ios.textAlignment = NSTextAlignment.NSTextAlignmentLeft;
break;
case enums.TextAlignment.center:
ios.textAlignment = NSTextAlignment.NSTextAlignmentCenter;
break;
case enums.TextAlignment.right:
ios.textAlignment = NSTextAlignment.NSTextAlignmentRight;
break;
default:
break;
}
}
setTextAlignment(view._nativeView, newValue);
}
private static resetTextAlignmentProperty(view: view.View, nativeValue: any) {
var ios: UILabel = <UILabel>view._nativeView;
if (ios) {
ios.textAlignment = nativeValue;
}
var ios: TextUIView = <TextUIView>view._nativeView;
ios.textAlignment = nativeValue;
}
private static getNativeTextAlignmentValue(view: view.View): any {
var ios: UILabel = <UILabel>view._nativeView;
if (ios) {
return ios.textAlignment;
}
var ios: TextUIView = <TextUIView>view._nativeView;
return ios.textAlignment;
}
public static registerHandlers() {
style.registerHandler(style.colorProperty, new stylersCommon.StylePropertyChangedHandler(
LabelStyler.setColorProperty,
LabelStyler.resetColorProperty,
LabelStyler.getNativeColorValue), "Label");
style.registerHandler(style.fontSizeProperty, new stylersCommon.StylePropertyChangedHandler(
LabelStyler.setFontSizeProperty,
LabelStyler.resetFontSizeProperty,
LabelStyler.getNativeFontSizeValue), "Label");
style.registerHandler(style.textAlignmentProperty, new stylersCommon.StylePropertyChangedHandler(
LabelStyler.setTextAlignmentProperty,
LabelStyler.resetTextAlignmentProperty,
LabelStyler.getNativeTextAlignmentValue), "Label");
}
}
export class TextFieldStyler implements definition.stylers.Styler {
// Color methods
// color
private static setColorProperty(view: view.View, newValue: any) {
var textField: UITextField = <UITextField>view._nativeView;
if (textField) {
textField.textColor = newValue;
}
var ios: TextUIView = <TextUIView>view._nativeView;
ios.textColor = newValue;
}
private static resetColorProperty(view: view.View, nativeValue: any) {
var textField: UITextField = <UITextField>view._nativeView;
if (textField) {
textField.textColor = nativeValue;
}
var ios: TextUIView = <TextUIView>view._nativeView;
ios.textColor = nativeValue;
}
private static getNativeColorValue(view: view.View): any {
var textField: UITextField = <UITextField>view._nativeView;
if (textField) {
return textField.textColor;
}
}
// Font size
private static setFontSizeProperty(view: view.View, newValue: any) {
var textField: UITextField = <UITextField>view._nativeView;
if (textField) {
textField.font = textField.font.fontWithSize(newValue);
}
}
private static resetFontSizeProperty(view: view.View, nativeValue: any) {
var textField: UITextField = <UITextField>view._nativeView;
if (textField) {
textField.font = textField.font.fontWithSize(nativeValue);
}
}
private static getNativeFontSizeValue(view: view.View): any {
var textField: UITextField = <UITextField>view._nativeView;
if (textField) {
return textField.font.pointSize;
}
}
// text-align
private static setTextAlignmentProperty(view: view.View, newValue: any) {
var ios: UITextField = <UITextField>view._nativeView;
if (ios) {
switch (newValue) {
case enums.TextAlignment.left:
ios.textAlignment = NSTextAlignment.NSTextAlignmentLeft;
break;
case enums.TextAlignment.center:
ios.textAlignment = NSTextAlignment.NSTextAlignmentCenter;
break;
case enums.TextAlignment.right:
ios.textAlignment = NSTextAlignment.NSTextAlignmentRight;
break;
default:
break;
}
}
}
private static resetTextAlignmentProperty(view: view.View, nativeValue: any) {
var ios: UITextField = <UITextField>view._nativeView;
if (ios) {
ios.textAlignment = nativeValue;
}
}
private static getNativeTextAlignmentValue(view: view.View): any {
var ios: UITextField = <UITextField>view._nativeView;
if (ios) {
return ios.textAlignment;
}
var ios: TextUIView = <TextUIView>view._nativeView;
return ios.textColor;
}
public static registerHandlers() {
style.registerHandler(style.colorProperty, new stylersCommon.StylePropertyChangedHandler(
TextFieldStyler.setColorProperty,
TextFieldStyler.resetColorProperty,
TextFieldStyler.getNativeColorValue), "TextField");
style.registerHandler(style.fontSizeProperty, new stylersCommon.StylePropertyChangedHandler(
TextFieldStyler.setFontSizeProperty,
TextFieldStyler.resetFontSizeProperty,
TextFieldStyler.getNativeFontSizeValue), "TextField");
style.registerHandler(style.fontInternalProperty, new stylersCommon.StylePropertyChangedHandler(
TextBaseStyler.setFontInternalProperty,
TextBaseStyler.resetFontInternalProperty,
TextBaseStyler.getNativeFontInternalValue), "TextBase");
style.registerHandler(style.textAlignmentProperty, new stylersCommon.StylePropertyChangedHandler(
TextFieldStyler.setTextAlignmentProperty,
TextFieldStyler.resetTextAlignmentProperty,
TextFieldStyler.getNativeTextAlignmentValue), "TextField");
TextBaseStyler.setTextAlignmentProperty,
TextBaseStyler.resetTextAlignmentProperty,
TextBaseStyler.getNativeTextAlignmentValue), "TextBase");
style.registerHandler(style.colorProperty, new stylersCommon.StylePropertyChangedHandler(
TextBaseStyler.setColorProperty,
TextBaseStyler.resetColorProperty,
TextBaseStyler.getNativeColorValue), "TextBase");
}
}
@ -459,16 +320,12 @@ export class TextViewStyler implements definition.stylers.Styler {
// Color methods
private static setColorProperty(view: view.View, newValue: any) {
var textView: UITextView = <UITextView>view._nativeView;
if (textView) {
TextViewStyler._setTextViewColor(textView, newValue);
}
TextViewStyler._setTextViewColor(textView, newValue);
}
private static resetColorProperty(view: view.View, nativeValue: any) {
var textView: UITextView = <UITextView>view._nativeView;
if (textView) {
TextViewStyler._setTextViewColor(textView, nativeValue);
}
TextViewStyler._setTextViewColor(textView, nativeValue);
}
private static _setTextViewColor(textView: UITextView, newValue: any) {
@ -483,69 +340,11 @@ export class TextViewStyler implements definition.stylers.Styler {
private static getNativeColorValue(view: view.View): any {
var textView: UITextView = <UITextView>view._nativeView;
if (textView) {
if ((<any>textView).isShowingHint && textView.textColor) {
return textView.textColor.colorWithAlphaComponent(1);
}
else {
return textView.textColor;
}
if ((<any>textView).isShowingHint && textView.textColor) {
return textView.textColor.colorWithAlphaComponent(1);
}
}
// Font size
private static setFontSizeProperty(view: view.View, newValue: any) {
var textView: UITextView = <UITextView>view._nativeView;
if (textView) {
textView.font = textView.font.fontWithSize(newValue);
}
}
private static resetFontSizeProperty(view: view.View, nativeValue: any) {
var textView: UITextView = <UITextView>view._nativeView;
if (textView) {
textView.font = textView.font.fontWithSize(nativeValue);
}
}
private static getNativeFontSizeValue(view: view.View): any {
var textView: UITextView = <UITextView>view._nativeView;
if (textView) {
return textView.font.pointSize;
}
}
// text-align
private static setTextAlignmentProperty(view: view.View, newValue: any) {
var ios: UITextView = <UITextView>view._nativeView;
if (ios) {
switch (newValue) {
case enums.TextAlignment.left:
ios.textAlignment = NSTextAlignment.NSTextAlignmentLeft;
break;
case enums.TextAlignment.center:
ios.textAlignment = NSTextAlignment.NSTextAlignmentCenter;
break;
case enums.TextAlignment.right:
ios.textAlignment = NSTextAlignment.NSTextAlignmentRight;
break;
default:
break;
}
}
}
private static resetTextAlignmentProperty(view: view.View, nativeValue: any) {
var ios: UITextView = <UITextView>view._nativeView;
if (ios) {
ios.textAlignment = nativeValue;
}
}
private static getNativeTextAlignmentValue(view: view.View): any {
var ios: UITextView = <UITextView>view._nativeView;
if (ios) {
return ios.textAlignment;
else {
return textView.textColor;
}
}
@ -554,16 +353,6 @@ export class TextViewStyler implements definition.stylers.Styler {
TextViewStyler.setColorProperty,
TextViewStyler.resetColorProperty,
TextViewStyler.getNativeColorValue), "TextView");
style.registerHandler(style.fontSizeProperty, new stylersCommon.StylePropertyChangedHandler(
TextViewStyler.setFontSizeProperty,
TextViewStyler.resetFontSizeProperty,
TextViewStyler.getNativeFontSizeValue), "TextView");
style.registerHandler(style.textAlignmentProperty, new stylersCommon.StylePropertyChangedHandler(
TextViewStyler.setTextAlignmentProperty,
TextViewStyler.resetTextAlignmentProperty,
TextViewStyler.getNativeTextAlignmentValue), "TextView");
}
}
@ -649,13 +438,29 @@ export class SearchBarStyler implements definition.stylers.Styler {
}
}
function setTextAlignment(view: TextUIView, value: string) {
switch (value) {
case enums.TextAlignment.left:
view.textAlignment = NSTextAlignment.NSTextAlignmentLeft;
break;
case enums.TextAlignment.center:
view.textAlignment = NSTextAlignment.NSTextAlignmentCenter;
break;
case enums.TextAlignment.right:
view.textAlignment = NSTextAlignment.NSTextAlignmentRight;
break;
default:
break;
}
}
// Register all styler at the end.
export function _registerDefaultStylers() {
style.registerNoStylingClass("Frame");
DefaultStyler.registerHandlers();
TextBaseStyler.registerHandlers();
ButtonStyler.registerHandlers();
LabelStyler.registerHandlers();
TextFieldStyler.registerHandlers();
TextViewStyler.registerHandlers();
SegmentedBarStyler.registerHandlers();
SearchBarStyler.registerHandlers();
}
}

View File

@ -53,6 +53,21 @@
*/
fontSize: number;
/**
* Gets or sets font-family style property.
*/
fontFamily: string;
/**
* Gets or sets font-style style property.
*/
fontStyle: string;
/**
* Gets or sets font-weight style property.
*/
fontWeight: string;
/**
* Gets or sets text-alignment style property.
*/

View File

@ -39,7 +39,7 @@ export module ios {
export function nsArrayToJSArray(a: any): string[] {
var arr = [];
if ("undefined" !== typeof a) {
for (var i = 0; i < a.count(); i++) {
for (var i = 0; i < a.count; i++) {
arr.push(a.objectAtIndex(i));
}
}