Initial prototype of Frame + Page + Navigation.

This commit is contained in:
atanasovg
2014-06-12 17:37:55 +03:00
parent ef7c3ce677
commit 2c4781db01
26 changed files with 520 additions and 80 deletions

114
ui/frame/frame-common.ts Normal file
View File

@@ -0,0 +1,114 @@
import frame = require("ui/frame");
import view = require("ui/core/view");
import pages = require("ui/pages");
enum NavigationType {
New,
Back,
Forward
}
export class Frame extends view.View implements frame.Frame {
private _backStack: Array<frame.PageNavigationEntry>;
private _forwardStack: Array<frame.PageNavigationEntry>;
private _currentEntry: frame.PageNavigationEntry;
private _currentPage: pages.Page;
private _navigationType: NavigationType;
// TODO: Currently our navigation will not be synchronized in case users directly call native navigation methods like Activity.startActivity.
constructor() {
super();
this._backStack = new Array<frame.PageNavigationEntry>();
this._forwardStack = new Array<frame.PageNavigationEntry>();
this._navigationType = NavigationType.New;
}
public canGoBack(): boolean {
return this._backStack.length > 0;
}
public canGoForward(): boolean {
return this._forwardStack.length > 0;
}
public goBack() {
if (!this.canGoBack()) {
// TODO: Do we need to throw an error?
return;
}
var entry = this._backStack.pop();
this._navigationType = NavigationType.Back;
this.navigate(entry);
}
public goForward() {
if (!this.canGoForward()) {
// TODO: Do we need to throw an error?
return;
}
var entry = this._forwardStack.pop();
this._navigationType = NavigationType.Forward;
this.navigate(entry);
}
public navigate(entry: frame.PageNavigationEntry) {
if (this._currentPage) {
this._backStack.push(this._currentEntry);
}
// perform the actual navigation, depending on the requested navigation type
switch (this._navigationType) {
case NavigationType.New:
this.navigateCore(entry.context);
break;
case NavigationType.Back:
this.goBackCore();
if (this._currentPage) {
this._forwardStack.push(this._currentEntry);
}
break;
case NavigationType.Forward:
this.goForwardCore();
if (this._currentPage) {
this._backStack.push(this._currentEntry);
}
break;
}
// TODO: We assume here that there is a Page object in the exports of the required module. This should be well documented.
this._currentPage = require(entry.pageModuleName).Page;
this._currentPage.frame = this;
this._currentEntry = entry;
// notify the page
this._currentPage.onNavigatedTo(entry.context);
// reset the navigation type back to new
this._navigationType = NavigationType.New;
}
public goBackCore() {
}
public goForwardCore() {
}
public navigateCore(context: any) {
}
get backStack(): Array<frame.PageNavigationEntry> {
return this._backStack;
}
get forwardStack(): Array<frame.PageNavigationEntry> {
return this._forwardStack;
}
get currentPage(): pages.Page {
return this._currentPage;
}
}

35
ui/frame/frame.android.ts Normal file
View File

@@ -0,0 +1,35 @@
import frameCommon = require("ui/frame/frame-common");
import frame = require("ui/frame");
import pages = require("ui/pages");
import application = require("application");
export class Frame extends frameCommon.Frame {
public navigateCore(context: any) {
if (this.backStack.length === 0) {
// When navigating for the very first time we do not want to start an activity
// TODO: Revisit/polish this behavior
return;
}
var activity = this.currentPage.android.activity;
if (!activity) {
throw new Error("Current page does have an activity created.");
}
var intent = new android.content.Intent(activity, (<any>com).tns.NativeScriptActivity.class);
activity.startActivity(intent);
}
public goBackCore() {
var activity = this.currentPage.android.activity;
if (!activity) {
throw new Error("Current page does have an activity created.");
}
// TODO: This is not true in all cases, update once added support for parent activity in Android manifest
activity.finish();
}
public goForwardCore() {
}
}

24
ui/frame/frame.d.ts vendored Normal file
View File

@@ -0,0 +1,24 @@
declare module "ui/frame" {
import view = require("ui/core/view");
// There is a cyclic reference here (pages module requires frame) but it is intented and needed.
import pages = require("ui/pages");
export class Frame extends view.View {
goBack();
canGoBack(): boolean;
goForward();
canGoForward(): boolean;
navigate(entry: PageNavigationEntry);
currentPage: pages.Page;
backStack: Array<PageNavigationEntry>;
forwardStack: Array<PageNavigationEntry>;
}
export interface PageNavigationEntry {
pageModuleName: string;
context?: any;
}
}

1
ui/frame/frame.ios.ts Normal file
View File

@@ -0,0 +1 @@


2
ui/frame/index.ts Normal file
View File

@@ -0,0 +1,2 @@
declare var module, require;
module.exports = require("ui/frame/frame");