mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
OptionsMenu XML support
This commit is contained in:
@@ -37,6 +37,7 @@ var MODULES = {
|
||||
"TimePicker": "ui/time-picker",
|
||||
"DatePicker": "ui/date-picker",
|
||||
"ListPicker": "ui/list-picker",
|
||||
"MenuItem": "ui/page",
|
||||
};
|
||||
|
||||
var ROW = "row";
|
||||
|
||||
@@ -370,6 +370,10 @@ export class Frame extends view.CustomLayoutView implements definition.Frame {
|
||||
public _removeViewFromNativeVisualTree(child: view.View): void {
|
||||
child._isAddedToNativeVisualTree = false;
|
||||
}
|
||||
|
||||
public _invalidateOptionsMenu() {
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
var _topmost = function (): Frame {
|
||||
|
||||
@@ -6,6 +6,7 @@ import observable = require("data/observable");
|
||||
import utils = require("utils/utils");
|
||||
import view = require("ui/core/view");
|
||||
import application = require("application");
|
||||
import imageSource = require("image-source");
|
||||
|
||||
declare var exports;
|
||||
require("utils/module-merge").merge(frameCommon, exports);
|
||||
@@ -37,6 +38,7 @@ class PageFragmentBody extends android.app.Fragment {
|
||||
onCreate(savedInstanceState: android.os.Bundle) {
|
||||
super.onCreate(savedInstanceState);
|
||||
trace.write(this.getTag() + ".onCreate(); savedInstanceState: " + savedInstanceState, trace.categories.NativeLifecycle);
|
||||
super.setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
onCreateView(inflater: android.view.LayoutInflater, container: android.view.ViewGroup, savedInstanceState: android.os.Bundle): android.view.View {
|
||||
@@ -132,6 +134,38 @@ class PageFragmentBody extends android.app.Fragment {
|
||||
super.onDetach();
|
||||
trace.write(this.getTag() + ".onDetach();", trace.categories.NativeLifecycle);
|
||||
}
|
||||
|
||||
onCreateOptionsMenu(menu: android.view.IMenu, inflater: android.view.MenuInflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
|
||||
var page: pages.Page = this.entry.resolvedPage;
|
||||
var items = page.optionsMenu.getItems();
|
||||
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
var item = items[i];
|
||||
var menuItem = menu.add(android.view.Menu.NONE, i, item.priority, item.text);
|
||||
if (item.icon) {
|
||||
var img = imageSource.fromFile(item.icon);
|
||||
var drawable = new android.graphics.drawable.BitmapDrawable(img.android);
|
||||
menuItem.setIcon(drawable);
|
||||
}
|
||||
|
||||
menuItem.setShowAsAction(android.view.MenuItem.SHOW_AS_ACTION_ALWAYS);
|
||||
}
|
||||
}
|
||||
|
||||
onOptionsItemSelected(item: android.view.IMenuItem) {
|
||||
var page: pages.Page = this.entry.resolvedPage;
|
||||
var itemId = item.getItemId();
|
||||
|
||||
var menuItem = page.optionsMenu.getItemAt(itemId);
|
||||
if (menuItem) {
|
||||
menuItem._raiseTap();
|
||||
return true;
|
||||
}
|
||||
|
||||
super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
function onFragmentShown(fragment: PageFragmentBody) {
|
||||
@@ -314,6 +348,12 @@ export class Frame extends frameCommon.Frame {
|
||||
public _clearAndroidReference() {
|
||||
// we should keep the reference to underlying native object, since frame can contain many pages.
|
||||
}
|
||||
|
||||
public _invalidateOptionsMenu() {
|
||||
if (this.android && this.android.activity) {
|
||||
this.android.activity.invalidateOptionsMenu();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
declare module com {
|
||||
|
||||
1
ui/frame/frame.d.ts
vendored
1
ui/frame/frame.d.ts
vendored
@@ -84,6 +84,7 @@ declare module "ui/frame" {
|
||||
|
||||
//@private
|
||||
_processNavigationQueue(page: pages.Page);
|
||||
_invalidateOptionsMenu();
|
||||
//@endprivate
|
||||
}
|
||||
|
||||
|
||||
@@ -5,19 +5,30 @@ import frame = require("ui/frame");
|
||||
import styleScope = require("ui/styling/style-scope");
|
||||
import fs = require("file-system");
|
||||
import fileSystemAccess = require("file-system/file-system-access");
|
||||
import trace = require("trace");
|
||||
import observable = require("data/observable");
|
||||
|
||||
var OPTIONS_MENU = "optionsMenu";
|
||||
|
||||
export module knownEvents {
|
||||
export var navigatedTo = "navigatedTo";
|
||||
export var tap = "tap";
|
||||
}
|
||||
|
||||
export class Page extends contentView.ContentView implements dts.Page {
|
||||
export module knownCollections {
|
||||
export var optionsMenu = "optionsMenu";
|
||||
}
|
||||
|
||||
export class Page extends contentView.ContentView implements dts.Page, view.AddArrayFromBuilder {
|
||||
private _navigationContext: any;
|
||||
|
||||
private _cssApplied: boolean;
|
||||
private _styleScope: styleScope.StyleScope = new styleScope.StyleScope();
|
||||
private _optionsMenu: OptionsMenu;
|
||||
|
||||
constructor(options?: dts.Options) {
|
||||
super(options);
|
||||
this._optionsMenu = new OptionsMenu(this);
|
||||
}
|
||||
|
||||
public onLoaded() {
|
||||
@@ -40,6 +51,13 @@ export class Page extends contentView.ContentView implements dts.Page {
|
||||
this._refreshCss();
|
||||
}
|
||||
|
||||
get optionsMenu(): OptionsMenu {
|
||||
return this._optionsMenu;
|
||||
}
|
||||
set optionsMenu(value: OptionsMenu) {
|
||||
throw new Error("optionsMenu property is read-only");
|
||||
}
|
||||
|
||||
private _refreshCss(): void {
|
||||
if (this._cssApplied) {
|
||||
this._resetCssValues();
|
||||
@@ -131,4 +149,71 @@ export class Page extends contentView.ContentView implements dts.Page {
|
||||
view.eachDescendant(this, resetCssValuesFunc);
|
||||
|
||||
}
|
||||
|
||||
public _addArrayFromBuilder(name: string, value: Array<any>) {
|
||||
if (name === OPTIONS_MENU) {
|
||||
this.optionsMenu.setItems(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class OptionsMenu implements dts.OptionsMenu {
|
||||
private _items: Array<MenuItem> = new Array<MenuItem>();
|
||||
private _page: Page;
|
||||
|
||||
constructor(page: Page) {
|
||||
this._page = page;
|
||||
}
|
||||
|
||||
public addItem(item: MenuItem): void {
|
||||
if (!item) {
|
||||
throw new Error("Cannot add empty item");
|
||||
}
|
||||
|
||||
this._items.push(item);
|
||||
this.invalidate();
|
||||
}
|
||||
|
||||
public removeItem(item: MenuItem): void {
|
||||
if (!item) {
|
||||
throw new Error("Cannot remove empty item");
|
||||
}
|
||||
|
||||
var itemIndex = this._items.indexOf(item);
|
||||
if (itemIndex < 0) {
|
||||
throw new Error("Cannot find item to remove");
|
||||
}
|
||||
|
||||
this._items.splice(itemIndex, 1);
|
||||
this.invalidate();
|
||||
}
|
||||
|
||||
public getItems(): Array<MenuItem> {
|
||||
return this._items.slice();
|
||||
}
|
||||
|
||||
public getItemAt(index: number): MenuItem {
|
||||
return this._items[index];
|
||||
}
|
||||
|
||||
public setItems(items: Array<MenuItem>) {
|
||||
this._items = items;
|
||||
this.invalidate();
|
||||
}
|
||||
|
||||
private invalidate() {
|
||||
if (this._page.frame) {
|
||||
this._page.frame._invalidateOptionsMenu();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class MenuItem extends observable.Observable implements dts.MenuItem {
|
||||
public text: string = "";
|
||||
public icon: string;
|
||||
public priority: number = 0;
|
||||
|
||||
public _raiseTap() {
|
||||
this._emit(knownEvents.tap);
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,8 @@
|
||||
import definition = require("ui/page");
|
||||
import trace = require("trace");
|
||||
|
||||
module.exports.knownEvents = pageCommon.knownEvents;
|
||||
declare var exports;
|
||||
require("utils/module-merge").merge(pageCommon, exports);
|
||||
|
||||
export class Page extends pageCommon.Page {
|
||||
private _isBackNavigation = false;
|
||||
|
||||
37
ui/page/page.d.ts
vendored
37
ui/page/page.d.ts
vendored
@@ -30,10 +30,14 @@ declare module "ui/page" {
|
||||
export var navigatedTo: string;
|
||||
}
|
||||
|
||||
export module knownCollections {
|
||||
export var optionsMenu: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a logical unit for navigation (inside Frame).
|
||||
*/
|
||||
export class Page extends contentView.ContentView {
|
||||
export class Page extends contentView.ContentView implements view.AddArrayFromBuilder {
|
||||
|
||||
constructor(options?: Options)
|
||||
|
||||
@@ -64,6 +68,11 @@ declare module "ui/page" {
|
||||
*/
|
||||
frame: frame.Frame;
|
||||
|
||||
/**
|
||||
* Gets the OptionsMenu for this page.
|
||||
*/
|
||||
optionsMenu: OptionsMenu;
|
||||
|
||||
/**
|
||||
* A method called before navigating to the page.
|
||||
* @param context - The data passed to the page through the NavigationEntry.context property.
|
||||
@@ -88,7 +97,8 @@ declare module "ui/page" {
|
||||
onNavigatedFrom(isBackNavigation: boolean): void;
|
||||
|
||||
//@private
|
||||
_getStyleScope(): styleScope.StyleScope
|
||||
_getStyleScope(): styleScope.StyleScope;
|
||||
_addArrayFromBuilder(name: string, value: Array<any>): void;
|
||||
//@endprivate
|
||||
|
||||
on(event: string, callback: (data: observable.EventData) => void);
|
||||
@@ -118,4 +128,25 @@ declare module "ui/page" {
|
||||
*/
|
||||
exports?: any;
|
||||
}
|
||||
}
|
||||
|
||||
export class OptionsMenu {
|
||||
addItem(item: MenuItem): void;
|
||||
removeItem(item: MenuItem): void;
|
||||
getItems(): Array<MenuItem>;
|
||||
getItemAt(index: number): MenuItem;
|
||||
}
|
||||
|
||||
export class MenuItem extends observable.Observable {
|
||||
text: string;
|
||||
icon: string;
|
||||
priority: number;
|
||||
|
||||
on(event: string, callback: (data: observable.EventData) => void);
|
||||
on(event: "tap", callback: (args: observable.EventData) => void);
|
||||
|
||||
//@private
|
||||
_raiseTap();
|
||||
//@endprivate
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user