mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
Merge pull request #205 from NativeScript/platform-specific-files
Platform specific files
This commit is contained in:
@@ -82,6 +82,7 @@
|
||||
<TypeScriptCompile Include="apps\template-blank\main-page.ts">
|
||||
<DependentUpon>main-page.xml</DependentUpon>
|
||||
</TypeScriptCompile>
|
||||
<TypeScriptCompile Include="apps\template-master-detail\main-page.ts" />
|
||||
<TypeScriptCompile Include="apps\template-settings\app.ts" />
|
||||
<TypeScriptCompile Include="apps\template-settings\main-page.ts">
|
||||
<DependentUpon>main-page.xml</DependentUpon>
|
||||
@@ -96,19 +97,18 @@
|
||||
<TypeScriptCompile Include="apps\template-master-detail\details-page.ts">
|
||||
<DependentUpon>details-page.xml</DependentUpon>
|
||||
</TypeScriptCompile>
|
||||
<TypeScriptCompile Include="apps\template-master-detail\main-page.ts">
|
||||
<DependentUpon>main-page.xml</DependentUpon>
|
||||
</TypeScriptCompile>
|
||||
<TypeScriptCompile Include="apps\tests\app\binding_tests.ts">
|
||||
<DependentUpon>binding_tests.xml</DependentUpon>
|
||||
</TypeScriptCompile>
|
||||
<TypeScriptCompile Include="apps\tests\app\location-example.ts" />
|
||||
<TypeScriptCompile Include="apps\tests\app\style_props.ts" />
|
||||
<TypeScriptCompile Include="apps\tests\console-tests.ts" />
|
||||
<TypeScriptCompile Include="apps\tests\file-name-resolver-tests\file-name-resolver-tests.ts" />
|
||||
<TypeScriptCompile Include="apps\tests\frame-tests.ts" />
|
||||
<TypeScriptCompile Include="apps\tests\gestures-tests.ts" />
|
||||
<TypeScriptCompile Include="apps\tests\layouts\dock-layout-tests.ts" />
|
||||
<TypeScriptCompile Include="apps\tests\pages\app.ts" />
|
||||
<TypeScriptCompile Include="apps\tests\pages\file-load-test.ts" />
|
||||
<TypeScriptCompile Include="apps\tests\pages\page12.ts" />
|
||||
<TypeScriptCompile Include="apps\tests\layouts\absolute-layout-tests.ts" />
|
||||
<TypeScriptCompile Include="apps\tests\layouts\layout-helper.ts" />
|
||||
@@ -167,6 +167,10 @@
|
||||
<TypeScriptCompile Include="apps\ui-tests-app\pages\i61.ts" />
|
||||
<TypeScriptCompile Include="apps\ui-tests-app\pages\i73.ts" />
|
||||
<TypeScriptCompile Include="apps\ui-tests-app\pages\gestures.ts" />
|
||||
<TypeScriptCompile Include="file-system\file-name-resolver.d.ts" />
|
||||
<TypeScriptCompile Include="file-system\file-name-resolver.ts">
|
||||
<DependentUpon>file-name-resolver.d.ts</DependentUpon>
|
||||
</TypeScriptCompile>
|
||||
<TypeScriptCompile Include="image-source\image-source-common.ts">
|
||||
<DependentUpon>image-source.d.ts</DependentUpon>
|
||||
</TypeScriptCompile>
|
||||
@@ -537,9 +541,22 @@
|
||||
<SubType>Designer</SubType>
|
||||
</Content>
|
||||
<Content Include="apps\gallery-app\layouts\dock-layout.xml" />
|
||||
<Content Include="apps\template-master-detail\details-view.xml" />
|
||||
<Content Include="apps\template-master-detail\main-page.minWH600.xml" />
|
||||
<Content Include="apps\template-settings\app.css" />
|
||||
<Content Include="apps\tests\app\binding_tests.xml" />
|
||||
<Content Include="apps\tests\ui\label\label-tests-wrong.css" />
|
||||
<Content Include="apps\tests\pages\files\other.xml" />
|
||||
<Content Include="apps\tests\pages\files\test.android.phone.xml" />
|
||||
<Content Include="apps\tests\pages\files\test.android.xml" />
|
||||
<Content Include="apps\tests\pages\files\test.minWH300.xml" />
|
||||
<Content Include="apps\tests\pages\files\test.minWH450.xml" />
|
||||
<Content Include="apps\tests\pages\files\test.xml" />
|
||||
<Content Include="apps\tests\file-name-resolver-tests\files\other.xml" />
|
||||
<Content Include="apps\tests\file-name-resolver-tests\files\test.android.xml" />
|
||||
<Content Include="apps\tests\file-name-resolver-tests\files\test.ios.land.xml" />
|
||||
<Content Include="apps\tests\file-name-resolver-tests\files\test.android.minWH600.xml" />
|
||||
<Content Include="apps\tests\file-name-resolver-tests\files\test.xml" />
|
||||
<Content Include="apps\ui-tests-app\pages\i86.xml" />
|
||||
<Content Include="apps\template-blank\app.css" />
|
||||
<Content Include="apps\template-hello-world\app.css" />
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import application = require("application");
|
||||
application.mainModule = "app/main-page";
|
||||
application.start();
|
||||
application.start();
|
||||
|
||||
3
apps/platform-specific-template/app.ts
Normal file
3
apps/platform-specific-template/app.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import application = require("application");
|
||||
application.mainModule = "app/main-page";
|
||||
application.start();
|
||||
5
apps/platform-specific-template/main-page.android.xml
Normal file
5
apps/platform-specific-template/main-page.android.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<Page loaded="onPageLoaded">
|
||||
<StackLayout id="stack">
|
||||
<Label id="label" text="Hello, Android!" />
|
||||
</StackLayout>
|
||||
</Page>
|
||||
5
apps/platform-specific-template/main-page.ios.xml
Normal file
5
apps/platform-specific-template/main-page.ios.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<Page loaded="onPageLoaded">
|
||||
<StackLayout id="stack">
|
||||
<Label id="label" text="Hello, iOS!" />
|
||||
</StackLayout>
|
||||
</Page>
|
||||
1
apps/platform-specific-template/main-page.ts
Normal file
1
apps/platform-specific-template/main-page.ts
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
2
apps/platform-specific-template/package.json
Normal file
2
apps/platform-specific-template/package.json
Normal file
@@ -0,0 +1,2 @@
|
||||
{ "name" : "platform-specific-template",
|
||||
"main" : "app.js" }
|
||||
@@ -13,15 +13,22 @@ ListView {
|
||||
horizontal-align: center;
|
||||
}
|
||||
|
||||
.detail-title {
|
||||
margin: 10;
|
||||
font-size: 26;
|
||||
color: #3c3c3c;
|
||||
horizontal-align: center;
|
||||
}
|
||||
|
||||
.listItem {
|
||||
margin: 10;
|
||||
horizontal-align: center;
|
||||
color: #808080;
|
||||
font-size: 24;
|
||||
font-size: 20;
|
||||
}
|
||||
|
||||
.info {
|
||||
margin: 10;
|
||||
font-size: 24;
|
||||
font-size: 20;
|
||||
color: #808080;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import pages = require("ui/page");
|
||||
import observable = require("data/observable");
|
||||
|
||||
import vmModule = require("./main-view-model");
|
||||
// Event handler for Page "navigatedTo" event attached in details-page.xml
|
||||
export function pageNavigatedTo(args: observable.EventData) {
|
||||
var page = <pages.Page>args.object;
|
||||
page.bindingContext = page.navigationContext;
|
||||
page.bindingContext = vmModule.mainViewModel.get("selectedItem");
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<Page xmlns="http://www.nativescript.org/tns.xsd" navigatedTo="pageNavigatedTo">
|
||||
<StackLayout>
|
||||
<Label text="{{ title }}" cssClass="title"/>
|
||||
<Label text="{{ info }}" cssClass="info" textWrap="true"/>
|
||||
</StackLayout>
|
||||
<Page xmlns="http://www.nativescript.org/tns.xsd"
|
||||
xmlns:app="app"
|
||||
navigatedTo="pageNavigatedTo">
|
||||
<app:details-view />
|
||||
</Page>
|
||||
4
apps/template-master-detail/details-view.xml
Normal file
4
apps/template-master-detail/details-view.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<StackLayout xmlns="http://www.nativescript.org/tns.xsd">
|
||||
<Label text="{{ title }}" cssClass="detail-title"/>
|
||||
<Label text="{{ info }}" cssClass="info" textWrap="true"/>
|
||||
</StackLayout>
|
||||
17
apps/template-master-detail/main-page.minWH600.xml
Normal file
17
apps/template-master-detail/main-page.minWH600.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<Page xmlns="http://www.nativescript.org/tns.xsd"
|
||||
xmlns:app="app"
|
||||
loaded="pageLoaded">
|
||||
<GridLayout rows="auto, *" columns="300, *">
|
||||
<Label text="Master Details Page" cssClass="title" colSpan="2" />
|
||||
|
||||
<ListView items="{{ items }}" itemTap="listViewItemTap" row="1">
|
||||
<ListView.itemTemplate>
|
||||
<Label text="{{ title }}" cssClass="listItem" />
|
||||
</ListView.itemTemplate>
|
||||
</ListView>
|
||||
|
||||
<GridLayout row="1" col="1" bindingContext="{{ selectedItem }}">
|
||||
<app:details-view/>
|
||||
</GridLayout>
|
||||
</GridLayout>
|
||||
</Page>
|
||||
@@ -1,9 +1,12 @@
|
||||
import observable = require("data/observable");
|
||||
import pages = require("ui/page");
|
||||
import frames = require("ui/frame");
|
||||
import platform = require("platform");
|
||||
import listView = require("ui/list-view");
|
||||
import vmModule = require("./main-view-model");
|
||||
|
||||
var twoPaneLayout = Math.min(platform.screen.mainScreen.widthDIPs, platform.screen.mainScreen.heightDIPs) > 600;
|
||||
|
||||
// Event handler for Page "loaded" event attached in main-page.xml
|
||||
export function pageLoaded(args: observable.EventData) {
|
||||
var page = <pages.Page>args.object;
|
||||
@@ -12,8 +15,9 @@ export function pageLoaded(args: observable.EventData) {
|
||||
|
||||
export function listViewItemTap(args: listView.ItemEventData) {
|
||||
// Navigate to the details page with context set to the current data item
|
||||
frames.topmost().navigate({
|
||||
moduleName: "app/details-page",
|
||||
context: args.view.bindingContext
|
||||
});
|
||||
if (!twoPaneLayout) {
|
||||
frames.topmost().navigate("app/details-page");
|
||||
}
|
||||
|
||||
vmModule.mainViewModel.set("selectedItem", args.view.bindingContext);
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
<Page xmlns="http://www.nativescript.org/tns.xsd" loaded="pageLoaded">
|
||||
<Page xmlns="http://www.nativescript.org/tns.xsd"
|
||||
loaded="pageLoaded">
|
||||
<GridLayout rows="auto, *">
|
||||
<Label text="Items Page" cssClass="title" />
|
||||
|
||||
|
||||
245
apps/tests/file-name-resolver-tests/file-name-resolver-tests.ts
Normal file
245
apps/tests/file-name-resolver-tests/file-name-resolver-tests.ts
Normal file
@@ -0,0 +1,245 @@
|
||||
import TKUnit = require("../TKUnit");
|
||||
import fs = require("file-system");
|
||||
import enums = require("ui/enums");
|
||||
import resolver = require("file-system/file-name-resolver");
|
||||
|
||||
var androidPhonePortraitContext: resolver.PlatformContext = {
|
||||
width: 360,
|
||||
height: 640,
|
||||
deviceType: enums.DeviceType.Phone,
|
||||
os: "android"
|
||||
}
|
||||
|
||||
var androidPhoneLandsacpeContext: resolver.PlatformContext = {
|
||||
width: 640,
|
||||
height: 360,
|
||||
deviceType: enums.DeviceType.Phone,
|
||||
os: "android"
|
||||
}
|
||||
|
||||
var androidTabletPortraitContext: resolver.PlatformContext = {
|
||||
width: 600,
|
||||
height: 960,
|
||||
deviceType: enums.DeviceType.Tablet,
|
||||
os: "android"
|
||||
}
|
||||
|
||||
var iPhonePortraitContext: resolver.PlatformContext = {
|
||||
width: 320,
|
||||
height: 480,
|
||||
deviceType: enums.DeviceType.Phone,
|
||||
os: "ios"
|
||||
}
|
||||
|
||||
var iPhoneLandscapeContext: resolver.PlatformContext = {
|
||||
width: 480,
|
||||
height: 320,
|
||||
deviceType: enums.DeviceType.Phone,
|
||||
os: "ios"
|
||||
}
|
||||
|
||||
export function test_findFileMatch_fileName() {
|
||||
var candidates: Array<string> = [
|
||||
"test.xml",
|
||||
"test2.xml",
|
||||
"other.xml"
|
||||
];
|
||||
|
||||
testTemplate(candidates, androidPhonePortraitContext, "test.xml")
|
||||
};
|
||||
|
||||
export function test_findFileMatch_os_android() {
|
||||
var candidates: Array<string> = [
|
||||
"test.xml",
|
||||
"test.ios.xml",
|
||||
"test.android.xml",
|
||||
"other.xml"
|
||||
];
|
||||
|
||||
testTemplate(candidates, androidPhonePortraitContext, "test.android.xml")
|
||||
};
|
||||
|
||||
export function test_findFileMatch_os_ios() {
|
||||
var candidates: Array<string> = [
|
||||
"test.xml",
|
||||
"test.ios.xml",
|
||||
"test.android.xml",
|
||||
"other.xml"
|
||||
];
|
||||
|
||||
testTemplate(candidates, iPhonePortraitContext, "test.ios.xml")
|
||||
};
|
||||
|
||||
export function test_findFileMatch_os_fallback() {
|
||||
var candidates: Array<string> = [
|
||||
"test.xml",
|
||||
"test.ios.xml",
|
||||
"other.xml"
|
||||
];
|
||||
|
||||
testTemplate(candidates, androidPhonePortraitContext, "test.xml")
|
||||
};
|
||||
|
||||
export function test_findFileMatch_minWH_fallback() {
|
||||
var candidates: Array<string> = [
|
||||
"test.xml",
|
||||
"test.minWH600.xml",
|
||||
"other.xml"
|
||||
];
|
||||
|
||||
testTemplate(candidates, androidPhonePortraitContext, "test.xml")
|
||||
}
|
||||
|
||||
export function test_findFileMatch_minWH_best_value() {
|
||||
var candidates: Array<string> = [
|
||||
"test.xml",
|
||||
"test.minWH400.xml",
|
||||
"test.minWH500.xml",
|
||||
"test.minWH600.xml",
|
||||
"test.minWH700.xml",
|
||||
"other.xml"
|
||||
];
|
||||
|
||||
testTemplate(candidates, androidTabletPortraitContext, "test.minWH600.xml")
|
||||
}
|
||||
|
||||
export function test_findFileMatch_minW_fallback() {
|
||||
var candidates: Array<string> = [
|
||||
"test.xml",
|
||||
"test.minW600.xml",
|
||||
"other.xml"
|
||||
];
|
||||
|
||||
testTemplate(candidates, androidPhonePortraitContext, "test.xml")
|
||||
}
|
||||
|
||||
export function test_findFileMatch_minW_best_value() {
|
||||
var candidates: Array<string> = [
|
||||
"test.xml",
|
||||
"test.minW400.xml",
|
||||
"test.minW500.xml",
|
||||
"test.minW600.xml",
|
||||
"test.minW700.xml",
|
||||
"other.xml"
|
||||
];
|
||||
|
||||
testTemplate(candidates, androidTabletPortraitContext, "test.minW600.xml")
|
||||
}
|
||||
|
||||
export function test_findFileMatch_minH_fallback() {
|
||||
var candidates: Array<string> = [
|
||||
"test.xml",
|
||||
"test.minH600.xml",
|
||||
"other.xml"
|
||||
];
|
||||
|
||||
testTemplate(candidates, androidPhoneLandsacpeContext, "test.xml")
|
||||
}
|
||||
|
||||
export function test_findFileMatch_minH_best_value() {
|
||||
var candidates: Array<string> = [
|
||||
"test.xml",
|
||||
"test.minH400.xml",
|
||||
"test.minH500.xml",
|
||||
"test.minH600.xml",
|
||||
"test.minH700.xml",
|
||||
"other.xml"
|
||||
];
|
||||
|
||||
testTemplate(candidates, androidPhonePortraitContext, "test.minH600.xml")
|
||||
}
|
||||
|
||||
export function test_findFileMatch_orienation_fallback() {
|
||||
var candidates: Array<string> = [
|
||||
"test.xml",
|
||||
"test.land.xml",
|
||||
"other.xml"
|
||||
];
|
||||
|
||||
testTemplate(candidates, androidTabletPortraitContext, "test.xml")
|
||||
}
|
||||
|
||||
export function test_findFileMatch_orienation_portrait() {
|
||||
var candidates: Array<string> = [
|
||||
"test.xml",
|
||||
"test.land.xml",
|
||||
"test.port.xml",
|
||||
"other.xml"
|
||||
];
|
||||
|
||||
testTemplate(candidates, androidTabletPortraitContext, "test.port.xml")
|
||||
}
|
||||
|
||||
export function test_findFileMatch_orienation_landscape() {
|
||||
var candidates: Array<string> = [
|
||||
"test.xml",
|
||||
"test.land.xml",
|
||||
"test.port.xml",
|
||||
"other.xml"
|
||||
];
|
||||
|
||||
testTemplate(candidates, androidPhoneLandsacpeContext, "test.land.xml")
|
||||
}
|
||||
|
||||
export function test_findFileMatch_choose_most_specific_file() {
|
||||
var candidates: Array<string> = [
|
||||
"test.xml",
|
||||
"test.android.xml",
|
||||
"test.android.port.xml",
|
||||
"other.xml"
|
||||
];
|
||||
|
||||
testTemplate(candidates, androidPhonePortraitContext, "test.android.port.xml")
|
||||
}
|
||||
|
||||
export function test_findFileMatch_with_multiple_matches_loads_by_priority() {
|
||||
var candidates: Array<string> = [
|
||||
"test.xml",
|
||||
"test.android.xml",
|
||||
"test.tablet.xml",
|
||||
"test.land.xml",
|
||||
"test.minH600.xml",
|
||||
"test.minW600.xml",
|
||||
"test.minWH600.xml",
|
||||
"other.xml"
|
||||
];
|
||||
|
||||
testTemplate(candidates, androidTabletPortraitContext, "test.minWH600.xml")
|
||||
}
|
||||
|
||||
function testTemplate(candidates: Array<string>, context: resolver.PlatformContext, expected: string) {
|
||||
var result = resolver.findFileMatch("test", ".xml", candidates, context);
|
||||
TKUnit.assertEqual(result, expected, "File path");
|
||||
}
|
||||
|
||||
var testFilePath = fs.path.join(fs.knownFolders.currentApp().path, "app/tests/file-name-resolver-tests/files/test");
|
||||
|
||||
export function test_file_resolver_with_andorid_phone_portratit() {
|
||||
var fileResolver = new resolver.FileNameResolver(androidPhonePortraitContext);
|
||||
var result = fileResolver.resolveFileName(testFilePath, "xml");
|
||||
TKUnit.assertEqual(result, testFilePath + ".android.xml", "File path");
|
||||
}
|
||||
|
||||
export function test_file_resolver_with_andorid_phone_landscape() {
|
||||
var fileResolver = new resolver.FileNameResolver(androidPhoneLandsacpeContext);
|
||||
var result = fileResolver.resolveFileName(testFilePath, "xml");
|
||||
TKUnit.assertEqual(result, testFilePath + ".android.xml", "File path");
|
||||
}
|
||||
|
||||
export function test_file_resolver_with_andorid_tablet_portrait() {
|
||||
var fileResolver = new resolver.FileNameResolver(androidTabletPortraitContext);
|
||||
var result = fileResolver.resolveFileName(testFilePath, "xml");
|
||||
TKUnit.assertEqual(result, testFilePath + ".android.minWH600.xml", "File path");
|
||||
}
|
||||
|
||||
export function test_file_resolver_with_ios_phone_landscape() {
|
||||
var fileResolver = new resolver.FileNameResolver(iPhoneLandscapeContext);
|
||||
var result = fileResolver.resolveFileName(testFilePath, "xml");
|
||||
TKUnit.assertEqual(result, testFilePath + ".ios.land.xml", "File path");
|
||||
}
|
||||
|
||||
export function test_file_resolver_with_ios_phone_portrait() {
|
||||
var fileResolver = new resolver.FileNameResolver(iPhonePortraitContext);
|
||||
var result = fileResolver.resolveFileName(testFilePath, "xml");
|
||||
TKUnit.assertEqual(result, testFilePath + ".xml", "File path");
|
||||
}
|
||||
1
apps/tests/file-name-resolver-tests/files/other.xml
Normal file
1
apps/tests/file-name-resolver-tests/files/other.xml
Normal file
@@ -0,0 +1 @@
|
||||
other.xml
|
||||
@@ -0,0 +1 @@
|
||||
test.monWH450.xml
|
||||
@@ -0,0 +1 @@
|
||||
test.android.xml
|
||||
@@ -0,0 +1 @@
|
||||
test.minWH300.xml
|
||||
1
apps/tests/file-name-resolver-tests/files/test.xml
Normal file
1
apps/tests/file-name-resolver-tests/files/test.xml
Normal file
@@ -0,0 +1 @@
|
||||
test.xml
|
||||
29
apps/tests/pages/file-load-test.ts
Normal file
29
apps/tests/pages/file-load-test.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import label = require("ui/label");
|
||||
import pages = require("ui/page");
|
||||
import fs = require("file-system");
|
||||
import fileResolverModule = require("file-system/file-name-resolver");
|
||||
|
||||
export function createPage() {
|
||||
var page = new pages.Page();
|
||||
var lbl = new label.Label();
|
||||
|
||||
var moduleName = "app/tests/pages/files/test";
|
||||
|
||||
var resolver = new fileResolverModule.FileNameResolver({
|
||||
width: 400,
|
||||
height: 600,
|
||||
os: "android",
|
||||
deviceType: "phone"
|
||||
});
|
||||
|
||||
// Current app full path.
|
||||
var currentAppPath = fs.knownFolders.currentApp().path;
|
||||
var moduleNamePath = fs.path.join(currentAppPath, moduleName);
|
||||
|
||||
var fileName = resolver.resolveFileName(moduleNamePath, "xml");
|
||||
lbl.text = fileName;
|
||||
lbl.textWrap = true;;
|
||||
|
||||
page.content = lbl;
|
||||
return page;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import btns = require("ui/button");
|
||||
import gridModule = require("ui/layouts/grid-layout");
|
||||
import gridModule = require("ui/layouts/grid-layout");
|
||||
import pages = require("ui/page");
|
||||
import buttons = require("ui/button");
|
||||
import app = require("application");
|
||||
import platform = require("platform");
|
||||
|
||||
@@ -12,7 +12,6 @@ function printDeviceInfoAndroid() {
|
||||
console.log("android.os.Build.VERSION.RELEASE = " + android.os.Build.VERSION.RELEASE); //android.os.Build.VERSION.RELEASE = 4.4.4
|
||||
android.os.Build.MANUFACTURER
|
||||
var metrics: android.util.DisplayMetrics = app.android.context.getResources().getDisplayMetrics();
|
||||
|
||||
console.log("metrics.density = " + metrics.density); //metrics.density = 3
|
||||
console.log("metrics.scaledDensity = " + metrics.scaledDensity); //metrics.scaledDensity = 3
|
||||
console.log("metrics.densityDpi = " + metrics.densityDpi); //metrics.densityDpi = 480
|
||||
@@ -20,6 +19,12 @@ function printDeviceInfoAndroid() {
|
||||
console.log("metrics.yxdpi = " + metrics.ydpi); //metrics.yxdpi = 443.3450012207031
|
||||
console.log("metrics.widthPixels = " + metrics.widthPixels); //metrics.widthPixels = 1080
|
||||
console.log("metrics.heightPixels = " + metrics.heightPixels); //metrics.heightPixels = 1776
|
||||
|
||||
var config = app.android.context.getResources().getConfiguration();
|
||||
console.log("config.screenWidthDp = " + config.screenWidthDp);
|
||||
console.log("config.screenHeightDp = " + config.screenHeightDp);
|
||||
console.log("config.smallestScreenWidthDp = " + config.smallestScreenWidthDp);
|
||||
console.log("config.orientation = " + (config.orientation === android.content.res.Configuration.ORIENTATION_PORTRAIT ? "portrait" : "ladscape"));
|
||||
}
|
||||
|
||||
function printDeviceInfoIOS() {
|
||||
@@ -45,45 +50,35 @@ function printTNSInfo() {
|
||||
console.log("platform.device.sdkVersion = " + platform.device.sdkVersion);
|
||||
console.log("platform.device.deviceType = " + platform.device.deviceType);
|
||||
|
||||
console.log("platform.screen.mainScreen.widthDIPs = " + platform.screen.mainScreen.widthDIPs);
|
||||
console.log("platform.screen.mainScreen.heightDIPs = " + platform.screen.mainScreen.heightDIPs);
|
||||
console.log("platform.screen.mainScreen.scale = " + platform.screen.mainScreen.scale);
|
||||
console.log("platform.screen.mainScreen.widthPixels = " + platform.screen.mainScreen.widthPixels);
|
||||
console.log("platform.screen.mainScreen.heightPixels = " + platform.screen.mainScreen.heightPixels);
|
||||
console.log("platform.screen.mainScreen.scale = " + platform.screen.mainScreen.scale);
|
||||
}
|
||||
|
||||
if (app.android) {
|
||||
printDeviceInfoAndroid();
|
||||
function print() {
|
||||
if (app.android) {
|
||||
printDeviceInfoAndroid();
|
||||
}
|
||||
else {
|
||||
printDeviceInfoIOS();
|
||||
}
|
||||
printTNSInfo();
|
||||
}
|
||||
else {
|
||||
printDeviceInfoIOS();
|
||||
}
|
||||
printTNSInfo();
|
||||
print();
|
||||
|
||||
export function createPage() {
|
||||
var page = new pages.Page();
|
||||
var grid = new gridModule.GridLayout();
|
||||
|
||||
var rows = 100;
|
||||
var cols = 3;
|
||||
var row;
|
||||
var col;
|
||||
var btn = new buttons.Button();
|
||||
btn.text = "print";
|
||||
btn.on("tap", (d) => {
|
||||
print();
|
||||
});
|
||||
|
||||
for (row = 0; row < rows; row++) {
|
||||
grid.addRow(new gridModule.ItemSpec(1, gridModule.GridUnitType.auto));
|
||||
}
|
||||
|
||||
for (col = 0; col < cols; col++) {
|
||||
grid.addColumn(new gridModule.ItemSpec(1, gridModule.GridUnitType.auto));
|
||||
}
|
||||
|
||||
for (col = 0; col < cols; col++) {
|
||||
for (row = 0; row < rows; row++) {
|
||||
var btn = new btns.Button();
|
||||
btn.text = "Col: " + col + ", Row: " + row;
|
||||
gridModule.GridLayout.setColumn(btn, col);
|
||||
gridModule.GridLayout.setRow(btn, row);
|
||||
grid.addChild(btn);
|
||||
}
|
||||
}
|
||||
grid.addChild(btn);
|
||||
|
||||
page.content = grid;
|
||||
return page;
|
||||
|
||||
@@ -46,6 +46,7 @@ allTests["TEXT-FIELD"] = require("./ui/text-field/text-field-tests");
|
||||
allTests["TEXT-VIEW"] = require("./ui/text-view/text-view-tests");
|
||||
allTests["FORMATTEDSTRING"] = require("./text/formatted-string-tests");
|
||||
allTests["FILE-SYSTEM-ACCESS"] = require("./file-system-access-tests/file-system-access-tests");
|
||||
allTests["FILE-NAME-RESOLVER"] = require("./file-name-resolver-tests/file-name-resolver-tests");
|
||||
allTests["XML-DECLARATION"] = require("./xml-declaration/xml-declaration-tests");
|
||||
allTests["LIST-PICKER"] = require("./ui/list-picker/list-picker-tests");
|
||||
allTests["DATE-PICKER"] = require("./ui/date-picker/date-picker-tests");
|
||||
|
||||
20
file-system/file-name-resolver.d.ts
vendored
Normal file
20
file-system/file-name-resolver.d.ts
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Provides FileNameResolver class used for loading files based on device capabilities.
|
||||
*/
|
||||
declare module "file-system/file-name-resolver" {
|
||||
export interface PlatformContext {
|
||||
width: number;
|
||||
height: number;
|
||||
os: string;
|
||||
deviceType: string;
|
||||
}
|
||||
|
||||
export class FileNameResolver {
|
||||
constructor(context: PlatformContext);
|
||||
resolveFileName(path: string, ext: string): string;
|
||||
}
|
||||
|
||||
//@private
|
||||
export function findFileMatch(path: string, ext: string, candidates: Array<string>, context: PlatformContext): string
|
||||
//@endprivate
|
||||
}
|
||||
215
file-system/file-name-resolver.ts
Normal file
215
file-system/file-name-resolver.ts
Normal file
@@ -0,0 +1,215 @@
|
||||
import definition = require("file-system/file-name-resolver");
|
||||
import fs = require("file-system");
|
||||
import types = require("utils/types");
|
||||
import trace = require("trace");
|
||||
|
||||
var MIN_WH: string = "minWH";
|
||||
var MIN_W: string = "minW";
|
||||
var MIN_H: string = "minH";
|
||||
var PRIORITY_STEP = 10000;
|
||||
|
||||
interface QualifierSpec {
|
||||
isMatch(value: string): boolean;
|
||||
getMatchValue(value: string, context: definition.PlatformContext): number;
|
||||
}
|
||||
|
||||
var minWidthHeightQualifier: QualifierSpec = {
|
||||
isMatch: function (value: string): boolean {
|
||||
return value.indexOf(MIN_WH) === 0;
|
||||
|
||||
},
|
||||
getMatchValue(value: string, context: definition.PlatformContext): number {
|
||||
var numVal = parseInt(value.substr(MIN_WH.length));
|
||||
if (isNaN(numVal)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
var actualLength = Math.min(context.width, context.height);
|
||||
if (actualLength < numVal) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return PRIORITY_STEP - (actualLength - numVal);
|
||||
}
|
||||
}
|
||||
|
||||
var minWidthQualifier: QualifierSpec = {
|
||||
isMatch: function (value: string): boolean {
|
||||
return value.indexOf(MIN_W) === 0 && value.indexOf(MIN_WH) < 0;
|
||||
|
||||
},
|
||||
getMatchValue(value: string, context: definition.PlatformContext): number {
|
||||
var numVal = parseInt(value.substr(MIN_W.length));
|
||||
if (isNaN(numVal)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
var actualWidth = context.width;
|
||||
if (actualWidth < numVal) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return PRIORITY_STEP - (actualWidth - numVal);
|
||||
}
|
||||
}
|
||||
|
||||
var minHeightQualifier: QualifierSpec = {
|
||||
isMatch: function (value: string): boolean {
|
||||
return value.indexOf(MIN_H) === 0 && value.indexOf(MIN_WH) < 0;
|
||||
|
||||
},
|
||||
getMatchValue(value: string, context: definition.PlatformContext): number {
|
||||
var numVal = parseInt(value.substr(MIN_H.length));
|
||||
if (isNaN(numVal)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
var actualHeight = context.height;
|
||||
if (actualHeight < numVal) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return PRIORITY_STEP - (actualHeight - numVal)
|
||||
}
|
||||
}
|
||||
|
||||
var paltformQualifier: QualifierSpec = {
|
||||
isMatch: function (value: string): boolean {
|
||||
return value === "android" ||
|
||||
value === "ios";
|
||||
|
||||
},
|
||||
getMatchValue(value: string, context: definition.PlatformContext): number{
|
||||
return value === context.os.toLowerCase() ? 1 : -1;
|
||||
}
|
||||
}
|
||||
|
||||
var orientationQualifier: QualifierSpec = {
|
||||
isMatch: function (value: string): boolean {
|
||||
return value === "land" ||
|
||||
value === "port";
|
||||
|
||||
},
|
||||
getMatchValue(value: string, context: definition.PlatformContext): number{
|
||||
var isLandscape: number = (context.width > context.height) ? 1 : -1;
|
||||
return (value === "land") ? isLandscape : -isLandscape;
|
||||
}
|
||||
}
|
||||
|
||||
// List of supported qualifiers ordered by priority
|
||||
var supportedQualifiers: Array<QualifierSpec> = [
|
||||
minWidthHeightQualifier,
|
||||
minWidthQualifier,
|
||||
minHeightQualifier,
|
||||
orientationQualifier,
|
||||
paltformQualifier
|
||||
];
|
||||
|
||||
export class FileNameResolver implements definition.FileNameResolver {
|
||||
private _context: definition.PlatformContext;
|
||||
private _cache = {};
|
||||
|
||||
constructor(context: definition.PlatformContext) {
|
||||
this._context = context;
|
||||
}
|
||||
|
||||
public resolveFileName(path: string, ext: string): string {
|
||||
var key = path + ext;
|
||||
var result: string = this._cache[key];
|
||||
if (types.isUndefined(result)) {
|
||||
result = this.resolveFileNameImpl(path, ext);
|
||||
this._cache[key] = result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private resolveFileNameImpl(path: string, ext: string): string {
|
||||
var result: string = null;
|
||||
path = fs.path.normalize(path);
|
||||
ext = "." + ext;
|
||||
|
||||
var candidates = this.getFileCandidatesFromFolder(path, ext);
|
||||
result = findFileMatch(path, ext, candidates, this._context);
|
||||
|
||||
trace.write("Resolved file name for \"" + path + ext + "\" result: " + (result ? result : "no match found"), trace.categories.Navigation);
|
||||
return result;
|
||||
}
|
||||
|
||||
private getFileCandidatesFromFolder(path: string, ext: string): Array<string> {
|
||||
var candidates = new Array<string>();
|
||||
var folderPath = path.substring(0, path.lastIndexOf(fs.path.separator) + 1);
|
||||
|
||||
if (fs.Folder.exists(folderPath)) {
|
||||
var folder = fs.Folder.fromPath(folderPath);
|
||||
folder.eachEntity((e) => {
|
||||
if (e instanceof fs.File) {
|
||||
var file = <fs.File>e;
|
||||
if (file.path.indexOf(path) === 0 && file.extension === ext) {
|
||||
candidates.push(file.path);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
else {
|
||||
trace.write("Could not find folder " + folderPath + " when loading " + path + ext, trace.categories.Navigation);
|
||||
}
|
||||
|
||||
return candidates;
|
||||
}
|
||||
}
|
||||
|
||||
export function findFileMatch(path: string, ext: string, candidates: Array<string>, context: definition.PlatformContext): string {
|
||||
var bestValue = -1
|
||||
var result: string = null;
|
||||
|
||||
trace.write("Candidates for " + path + ext + ": " + candidates.join(", "), trace.categories.Navigation);
|
||||
for (var i = 0; i < candidates.length; i++) {
|
||||
var filePath = candidates[i];
|
||||
var qualifiersStr: string = filePath.substr(path.length, filePath.length - path.length - ext.length);
|
||||
|
||||
var qualifiers = qualifiersStr.split(".");
|
||||
|
||||
var value = checkQualifiers(qualifiers, context);
|
||||
|
||||
if (value >= 0 && value > bestValue) {
|
||||
bestValue = value;
|
||||
result = candidates[i];
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function checkQualifiers(qualifiers: Array<string>, context: definition.PlatformContext): number {
|
||||
var result = 0;
|
||||
for (var i = 0; i < qualifiers.length; i++) {
|
||||
if (qualifiers[i]) {
|
||||
var value = checkQualifier(qualifiers[i], context);
|
||||
if (value < 0) {
|
||||
// Non of the supported qualifiers matched this or the match was not satisified
|
||||
return -1;
|
||||
}
|
||||
|
||||
result += value;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function checkQualifier(value: string, context: definition.PlatformContext) {
|
||||
for (var i = 0; i < supportedQualifiers.length; i++) {
|
||||
if (supportedQualifiers[i].isMatch(value)) {
|
||||
var result = supportedQualifiers[i].getMatchValue(value, context);
|
||||
if (result > 0) {
|
||||
result += (supportedQualifiers.length - i) * PRIORITY_STEP;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -73,7 +73,9 @@ export class screen implements definition.screen {
|
||||
mainScreenInfo = {
|
||||
widthPixels: metrics.widthPixels,
|
||||
heightPixels: metrics.heightPixels,
|
||||
scale: metrics.density
|
||||
scale: metrics.density,
|
||||
widthDIPs: metrics.widthPixels / metrics.density,
|
||||
heightDIPs: metrics.heightPixels / metrics.density
|
||||
}
|
||||
}
|
||||
return mainScreenInfo;
|
||||
|
||||
10
platform/platform.d.ts
vendored
10
platform/platform.d.ts
vendored
@@ -61,6 +61,16 @@ declare module "platform" {
|
||||
*/
|
||||
heightPixels: number;
|
||||
|
||||
/**
|
||||
* Gets the absolute width of the screen in density independent pixels.
|
||||
*/
|
||||
widthDIPs: number;
|
||||
|
||||
/**
|
||||
* Gets the absolute height of the screen in density independent pixels.
|
||||
*/
|
||||
heightDIPs: number;
|
||||
|
||||
/**
|
||||
* The logical density of the display. This is a scaling factor for the Density Independent Pixel unit.
|
||||
*/
|
||||
|
||||
@@ -71,7 +71,9 @@ export class screen implements definition.screen {
|
||||
mainScreenInfo = {
|
||||
widthPixels: size.width * scale,
|
||||
heightPixels: size.height * scale,
|
||||
scale: scale
|
||||
scale: scale,
|
||||
widthDIPs: size.width,
|
||||
heightDIPs: size.height
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import trace = require("trace");
|
||||
import builder = require("ui/builder");
|
||||
import fs = require("file-system");
|
||||
import utils = require("utils/utils");
|
||||
import platform = require("platform");
|
||||
import fileResolverModule = require("file-system/file-name-resolver");
|
||||
|
||||
var frameStack: Array<Frame> = [];
|
||||
|
||||
@@ -39,7 +41,7 @@ function resolvePageFromEntry(entry: definition.NavigationEntry): pages.Page {
|
||||
}
|
||||
}
|
||||
else if (entry.moduleName) {
|
||||
// Current app full path.
|
||||
// Current app full path.
|
||||
var currentAppPath = fs.knownFolders.currentApp().path;
|
||||
//Full path of the module = current app full path + module name.
|
||||
var moduleNamePath = fs.path.join(currentAppPath, entry.moduleName);
|
||||
@@ -67,14 +69,26 @@ function resolvePageFromEntry(entry: definition.NavigationEntry): pages.Page {
|
||||
return page;
|
||||
}
|
||||
|
||||
var fileNameResolver: fileResolverModule.FileNameResolver;
|
||||
function resolveFilePath(path, ext) {
|
||||
if (!fileNameResolver) {
|
||||
fileNameResolver = new fileResolverModule.FileNameResolver({
|
||||
width: platform.screen.mainScreen.widthDIPs,
|
||||
height: platform.screen.mainScreen.heightDIPs,
|
||||
os: platform.device.os,
|
||||
deviceType: platform.device.deviceType
|
||||
});
|
||||
}
|
||||
return fileNameResolver.resolveFileName(path, ext);
|
||||
}
|
||||
|
||||
function pageFromBuilder(moduleNamePath: string, moduleName: string, moduleExports: any): pages.Page {
|
||||
var page: pages.Page;
|
||||
var element: view.View;
|
||||
|
||||
// Possible XML file path.
|
||||
var fileName = moduleNamePath + ".xml";
|
||||
|
||||
if (fs.File.exists(fileName)) {
|
||||
var fileName = resolveFilePath(moduleNamePath, "xml");
|
||||
if (fileName) {
|
||||
trace.write("Loading XML file: " + fileName, trace.categories.Navigation);
|
||||
|
||||
// Or check if the file exists in the app modules and load the page from XML.
|
||||
@@ -83,8 +97,10 @@ function pageFromBuilder(moduleNamePath: string, moduleName: string, moduleExpor
|
||||
page = <pages.Page>element;
|
||||
|
||||
// Possible CSS file path.
|
||||
var cssFileName = moduleName + ".css";
|
||||
page.addCssFile(cssFileName);
|
||||
var cssFileName = resolveFilePath(moduleName, "css");
|
||||
if (cssFileName) {
|
||||
page.addCssFile(cssFileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -61,10 +61,13 @@ export class Page extends contentView.ContentView implements dts.Page {
|
||||
}
|
||||
|
||||
public addCssFile(cssFileName: string) {
|
||||
if (cssFileName.indexOf(fs.knownFolders.currentApp().path) !== 0) {
|
||||
cssFileName = fs.path.join(fs.knownFolders.currentApp().path, cssFileName);
|
||||
}
|
||||
|
||||
var cssString;
|
||||
var realCssFileName = fs.path.join(fs.knownFolders.currentApp().path, cssFileName);
|
||||
if (fs.File.exists(realCssFileName)) {
|
||||
new fileSystemAccess.FileSystemAccess().readText(realCssFileName, r => { cssString = r; });
|
||||
if (fs.File.exists(cssFileName)) {
|
||||
new fileSystemAccess.FileSystemAccess().readText(cssFileName, r => { cssString = r; });
|
||||
this._addCssInternal(cssString, cssFileName);
|
||||
}
|
||||
}
|
||||
@@ -104,18 +107,18 @@ export class Page extends contentView.ContentView implements dts.Page {
|
||||
return;
|
||||
}
|
||||
|
||||
this._styleScope.ensureSelectors();
|
||||
this._styleScope.ensureSelectors();
|
||||
|
||||
var scope = this._styleScope;
|
||||
var checkSelectors = (view: view.View): boolean => {
|
||||
scope.applySelectors(view);
|
||||
return true;
|
||||
}
|
||||
var scope = this._styleScope;
|
||||
var checkSelectors = (view: view.View): boolean => {
|
||||
scope.applySelectors(view);
|
||||
return true;
|
||||
}
|
||||
|
||||
checkSelectors(this);
|
||||
view.eachDescendant(this, checkSelectors);
|
||||
checkSelectors(this);
|
||||
view.eachDescendant(this, checkSelectors);
|
||||
|
||||
this._cssApplied = true;
|
||||
this._cssApplied = true;
|
||||
}
|
||||
|
||||
private _resetCssValues() {
|
||||
|
||||
Reference in New Issue
Block a user