mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
Add support for snapshot
Fix Layout class getMeasuredWidth & getMeasuredHeight Move some classes to widgets Fix API17 tests
This commit is contained in:
@@ -15,6 +15,33 @@ function generateItemId(): number {
|
||||
return actionItemIdGenerator;
|
||||
}
|
||||
|
||||
interface MenuItemClickListener {
|
||||
new (owner: ActionBar): android.support.v7.widget.Toolbar.OnMenuItemClickListener;
|
||||
}
|
||||
|
||||
let MenuItemClickListener: MenuItemClickListener;
|
||||
|
||||
function initializeMenuItemClickListener(): void {
|
||||
if (MenuItemClickListener) {
|
||||
return;
|
||||
}
|
||||
|
||||
@Interfaces([android.support.v7.widget.Toolbar.OnMenuItemClickListener])
|
||||
class MenuItemClickListenerImpl extends java.lang.Object implements android.support.v7.widget.Toolbar.OnMenuItemClickListener {
|
||||
constructor(public owner: ActionBar) {
|
||||
super();
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
onMenuItemClick(item: android.view.IMenuItem): boolean {
|
||||
let itemId = item.getItemId();
|
||||
return this.owner._onAndroidItemSelected(itemId);
|
||||
}
|
||||
}
|
||||
|
||||
MenuItemClickListener = MenuItemClickListenerImpl;
|
||||
}
|
||||
|
||||
export class ActionItem extends ActionItemBase {
|
||||
private _androidPosition: AndroidActionItemSettings = {
|
||||
position: "actionBar",
|
||||
@@ -73,24 +100,6 @@ export class NavigationButton extends ActionItem {
|
||||
|
||||
}
|
||||
|
||||
@Interfaces([android.support.v7.widget.Toolbar.OnMenuItemClickListener])
|
||||
class MenuItemClickListener extends java.lang.Object implements android.support.v7.widget.Toolbar.OnMenuItemClickListener {
|
||||
constructor(public owner: WeakRef<ActionBar>) {
|
||||
super();
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
onMenuItemClick(item: android.view.IMenuItem): boolean {
|
||||
let owner = this.owner.get();
|
||||
if (!owner) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let itemId = item.getItemId();
|
||||
return owner._onAndroidItemSelected(itemId);
|
||||
}
|
||||
}
|
||||
|
||||
export class ActionBar extends ActionBarBase {
|
||||
private _appResources: android.content.res.Resources;
|
||||
private _android: AndroidActionBarSettings;
|
||||
@@ -116,8 +125,9 @@ export class ActionBar extends ActionBarBase {
|
||||
}
|
||||
|
||||
public _createNativeView() {
|
||||
initializeMenuItemClickListener();
|
||||
this._toolbar = new android.support.v7.widget.Toolbar(this._context);
|
||||
this._menuItemClickListener = this._menuItemClickListener || new MenuItemClickListener(new WeakRef(this));
|
||||
this._menuItemClickListener = this._menuItemClickListener || new MenuItemClickListener(this);
|
||||
this._toolbar.setOnMenuItemClickListener(this._menuItemClickListener);
|
||||
}
|
||||
|
||||
@@ -342,7 +352,7 @@ export class ActionBar extends ActionBarBase {
|
||||
return defaultTitleTextColor;
|
||||
}
|
||||
set [colorProperty.native](value: number | Color) {
|
||||
let color = value instanceof Color ? value.android : value;
|
||||
let color = value instanceof Color ? value.android : value;
|
||||
this.nativeView.setTitleTextColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ declare module "ui/action-bar" {
|
||||
update();
|
||||
|
||||
//@private
|
||||
_isEmpty(): boolean
|
||||
_isEmpty(): boolean;
|
||||
//@endprivate
|
||||
|
||||
_addArrayFromBuilder(name: string, value: Array<any>): void;
|
||||
|
||||
@@ -6,34 +6,45 @@
|
||||
|
||||
export * from "./button-common";
|
||||
|
||||
@Interfaces([android.view.View.OnClickListener])
|
||||
class ClickListener extends java.lang.Object implements android.view.View.OnClickListener {
|
||||
constructor(public owner: WeakRef<Button>) {
|
||||
super();
|
||||
return global.__native(this);
|
||||
interface ClickListener {
|
||||
new (owner: Button): android.view.View.OnClickListener;
|
||||
}
|
||||
|
||||
let ClickListener: ClickListener;
|
||||
|
||||
function initializeClickListener(): void {
|
||||
if (ClickListener) {
|
||||
return;
|
||||
}
|
||||
|
||||
public onClick(v: android.view.View): void {
|
||||
let btn = this.owner.get();
|
||||
if (btn) {
|
||||
btn._emit(ButtonBase.tapEvent);
|
||||
@Interfaces([android.view.View.OnClickListener])
|
||||
class ClickListenerImpl extends java.lang.Object implements android.view.View.OnClickListener {
|
||||
constructor(public owner: Button) {
|
||||
super();
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
public onClick(v: android.view.View): void {
|
||||
this.owner._emit(ButtonBase.tapEvent);
|
||||
}
|
||||
}
|
||||
|
||||
ClickListener = ClickListenerImpl;
|
||||
}
|
||||
|
||||
export class Button extends ButtonBase {
|
||||
_button: android.widget.Button;
|
||||
private _highlightedHandler: (args: TouchGestureEventData) => void;
|
||||
private _defaultNativePadding: android.graphics.Rect;
|
||||
|
||||
|
||||
get android(): android.widget.Button {
|
||||
return this._button;
|
||||
}
|
||||
|
||||
public _createNativeView() {
|
||||
let weakRef = new WeakRef(this);
|
||||
initializeClickListener();
|
||||
this._button = new android.widget.Button(this._context);
|
||||
this._button.setOnClickListener(new ClickListener(weakRef));
|
||||
this._button.setOnClickListener(new ClickListener(this));
|
||||
|
||||
// Unlike all other widgets, the Button has padding 30 36 30 36 in device pixels.
|
||||
let result = new android.graphics.Rect();
|
||||
@@ -67,7 +78,7 @@ export class Button extends ButtonBase {
|
||||
|
||||
//PaddingTop
|
||||
get [paddingTopProperty.native](): Length {
|
||||
return { value: this._defaultNativePadding.top, unit: "px" }
|
||||
return { value: this._defaultNativePadding.top, unit: "px" }
|
||||
}
|
||||
set [paddingTopProperty.native](value: Length) {
|
||||
org.nativescript.widgets.ViewHelper.setPaddingTop(this.nativeView, Length.toDevicePixels(value, 0) + Length.toDevicePixels(this.style.borderTopWidth, 0));
|
||||
@@ -75,7 +86,7 @@ export class Button extends ButtonBase {
|
||||
|
||||
//PaddingRight
|
||||
get [paddingRightProperty.native](): Length {
|
||||
return { value: this._defaultNativePadding.right, unit: "px" }
|
||||
return { value: this._defaultNativePadding.right, unit: "px" }
|
||||
}
|
||||
set [paddingRightProperty.native](value: Length) {
|
||||
org.nativescript.widgets.ViewHelper.setPaddingRight(this.nativeView, Length.toDevicePixels(value, 0) + Length.toDevicePixels(this.style.borderRightWidth, 0));
|
||||
@@ -83,7 +94,7 @@ export class Button extends ButtonBase {
|
||||
|
||||
//PaddingBottom
|
||||
get [paddingBottomProperty.native](): Length {
|
||||
return { value: this._defaultNativePadding.bottom, unit: "px" }
|
||||
return { value: this._defaultNativePadding.bottom, unit: "px" }
|
||||
}
|
||||
set [paddingBottomProperty.native](value: Length) {
|
||||
org.nativescript.widgets.ViewHelper.setPaddingBottom(this.nativeView, Length.toDevicePixels(value, 0) + Length.toDevicePixels(this.style.borderBottomWidth, 0));
|
||||
@@ -91,7 +102,7 @@ export class Button extends ButtonBase {
|
||||
|
||||
//PaddingLeft
|
||||
get [paddingLeftProperty.native](): Length {
|
||||
return { value: this._defaultNativePadding.left, unit: "px" }
|
||||
return { value: this._defaultNativePadding.left, unit: "px" }
|
||||
}
|
||||
set [paddingLeftProperty.native](value: Length) {
|
||||
org.nativescript.widgets.ViewHelper.setPaddingLeft(this.nativeView, Length.toDevicePixels(value, 0) + Length.toDevicePixels(this.style.borderLeftWidth, 0));
|
||||
@@ -103,8 +114,8 @@ export class Button extends ButtonBase {
|
||||
set [zIndexProperty.native](value: number) {
|
||||
org.nativescript.widgets.ViewHelper.setZIndex(this.nativeView, value);
|
||||
// API >= 21
|
||||
if (this.nativeView.setStateListAnimator){
|
||||
if (this.nativeView.setStateListAnimator) {
|
||||
this.nativeView.setStateListAnimator(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -108,8 +108,6 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
|
||||
|
||||
public _gestureObservers = {};
|
||||
|
||||
// public parent: ViewCommon;
|
||||
|
||||
public effectiveMinWidth: number;
|
||||
public effectiveMinHeight: number;
|
||||
public effectiveWidth: number;
|
||||
@@ -127,11 +125,6 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
|
||||
public effectiveBorderBottomWidth: number;
|
||||
public effectiveBorderLeftWidth: number;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._goToVisualState("normal");
|
||||
}
|
||||
|
||||
observe(type: GestureTypes, callback: (args: GestureEventData) => void, thisArg?: any): void {
|
||||
if (!this._gestureObservers[type]) {
|
||||
this._gestureObservers[type] = [];
|
||||
|
||||
@@ -17,49 +17,53 @@ const ANDROID = "_android";
|
||||
const NATIVE_VIEW = "_nativeView";
|
||||
const VIEW_GROUP = "_viewGroup";
|
||||
|
||||
// TODO: Move this class into widgets.
|
||||
@Interfaces([android.view.View.OnTouchListener])
|
||||
class DisableUserInteractionListener extends java.lang.Object implements android.view.View.OnTouchListener {
|
||||
constructor() {
|
||||
super();
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
onTouch(view: android.view.View, event: android.view.MotionEvent): boolean {
|
||||
return true;
|
||||
}
|
||||
interface TouchListener {
|
||||
new (owner: View): android.view.View.OnTouchListener;
|
||||
}
|
||||
|
||||
@Interfaces([android.view.View.OnTouchListener])
|
||||
class TouchListener extends java.lang.Object implements android.view.View.OnTouchListener {
|
||||
constructor(private owner: WeakRef<View>) {
|
||||
super();
|
||||
return global.__native(this);
|
||||
let TouchListener: TouchListener;
|
||||
let disableUserInteractionListener: org.nativescript.widgets.DisableUserInteractionListener;
|
||||
|
||||
function initializeDisabledListener(): void {
|
||||
if (disableUserInteractionListener) {
|
||||
return;
|
||||
}
|
||||
|
||||
onTouch(view: android.view.View, event: android.view.MotionEvent): boolean {
|
||||
let owner = this.owner.get();
|
||||
if (!owner) {
|
||||
return false;
|
||||
disableUserInteractionListener = new org.nativescript.widgets.DisableUserInteractionListener();
|
||||
}
|
||||
|
||||
function initializeTouchListener(): void {
|
||||
if (TouchListener) {
|
||||
return;
|
||||
}
|
||||
|
||||
@Interfaces([android.view.View.OnTouchListener])
|
||||
class TouchListenerImpl extends java.lang.Object implements android.view.View.OnTouchListener {
|
||||
constructor(private owner: View) {
|
||||
super();
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
for (let type in owner._gestureObservers) {
|
||||
let list = owner._gestureObservers[type];
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
list[i].androidOnTouchEvent(event);
|
||||
onTouch(view: android.view.View, event: android.view.MotionEvent): boolean {
|
||||
const owner = this.owner;
|
||||
for (let type in owner._gestureObservers) {
|
||||
let list = owner._gestureObservers[type];
|
||||
list.forEach(element => {
|
||||
element.androidOnTouchEvent(event);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let nativeView = owner._nativeView;
|
||||
if (!nativeView || !nativeView.onTouchEvent) {
|
||||
return false;
|
||||
}
|
||||
let nativeView = owner._nativeView;
|
||||
if (!nativeView || !nativeView.onTouchEvent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return nativeView.onTouchEvent(event);
|
||||
return nativeView.onTouchEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const disableUserInteractionListener = new DisableUserInteractionListener();
|
||||
TouchListener = TouchListenerImpl;
|
||||
}
|
||||
|
||||
export class View extends ViewCommon {
|
||||
private touchListenerIsSet: boolean;
|
||||
@@ -101,7 +105,8 @@ export class View extends ViewCommon {
|
||||
this._nativeView.setClickable(true);
|
||||
}
|
||||
|
||||
this.touchListener = this.touchListener || new TouchListener(new WeakRef(this));
|
||||
initializeTouchListener();
|
||||
this.touchListener = this.touchListener || new TouchListener(this);
|
||||
this._nativeView.setOnTouchListener(this.touchListener);
|
||||
}
|
||||
}
|
||||
@@ -311,6 +316,7 @@ export class View extends ViewCommon {
|
||||
}
|
||||
set [isUserInteractionEnabledProperty.native](value: boolean) {
|
||||
if (!value) {
|
||||
initializeDisabledListener();
|
||||
// User interaction is disabled -- we stop it and we do not care whether someone wants to listen for gestures.
|
||||
this._nativeView.setOnTouchListener(disableUserInteractionListener);
|
||||
} else {
|
||||
@@ -480,62 +486,60 @@ function createNativePercentLengthProperty({key, auto = 0, getPixels, setPixels,
|
||||
});
|
||||
}
|
||||
|
||||
const ViewHelper = org.nativescript.widgets.ViewHelper;
|
||||
|
||||
createNativePercentLengthProperty({
|
||||
key: marginTopProperty.native,
|
||||
getPixels: ViewHelper.getMarginTop,
|
||||
setPixels: ViewHelper.setMarginTop,
|
||||
setPercent: ViewHelper.setMarginTopPercent
|
||||
getPixels: org.nativescript.widgets.ViewHelper.getMarginTop,
|
||||
setPixels: org.nativescript.widgets.ViewHelper.setMarginTop,
|
||||
setPercent: org.nativescript.widgets.ViewHelper.setMarginTopPercent
|
||||
});
|
||||
|
||||
createNativePercentLengthProperty({
|
||||
key: marginRightProperty.native,
|
||||
getPixels: ViewHelper.getMarginRight,
|
||||
setPixels: ViewHelper.setMarginRight,
|
||||
setPercent: ViewHelper.setMarginRightPercent
|
||||
getPixels: org.nativescript.widgets.ViewHelper.getMarginRight,
|
||||
setPixels: org.nativescript.widgets.ViewHelper.setMarginRight,
|
||||
setPercent: org.nativescript.widgets.ViewHelper.setMarginRightPercent
|
||||
});
|
||||
|
||||
createNativePercentLengthProperty({
|
||||
key: marginBottomProperty.native,
|
||||
getPixels: ViewHelper.getMarginBottom,
|
||||
setPixels: ViewHelper.setMarginBottom,
|
||||
setPercent: ViewHelper.setMarginBottomPercent
|
||||
getPixels: org.nativescript.widgets.ViewHelper.getMarginBottom,
|
||||
setPixels: org.nativescript.widgets.ViewHelper.setMarginBottom,
|
||||
setPercent: org.nativescript.widgets.ViewHelper.setMarginBottomPercent
|
||||
});
|
||||
|
||||
createNativePercentLengthProperty({
|
||||
key: marginLeftProperty.native,
|
||||
getPixels: ViewHelper.getMarginLeft,
|
||||
setPixels: ViewHelper.setMarginLeft,
|
||||
setPercent: ViewHelper.setMarginLeftPercent
|
||||
getPixels: org.nativescript.widgets.ViewHelper.getMarginLeft,
|
||||
setPixels: org.nativescript.widgets.ViewHelper.setMarginLeft,
|
||||
setPercent: org.nativescript.widgets.ViewHelper.setMarginLeftPercent
|
||||
});
|
||||
|
||||
createNativePercentLengthProperty({
|
||||
key: widthProperty.native,
|
||||
auto: android.view.ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
getPixels: ViewHelper.getWidth,
|
||||
setPixels: ViewHelper.setWidth,
|
||||
setPercent: ViewHelper.setWidthPercent
|
||||
getPixels: org.nativescript.widgets.ViewHelper.getWidth,
|
||||
setPixels: org.nativescript.widgets.ViewHelper.setWidth,
|
||||
setPercent: org.nativescript.widgets.ViewHelper.setWidthPercent
|
||||
});
|
||||
|
||||
createNativePercentLengthProperty({
|
||||
key: heightProperty.native,
|
||||
auto: android.view.ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
getPixels: ViewHelper.getHeight,
|
||||
setPixels: ViewHelper.setHeight,
|
||||
setPercent: ViewHelper.setHeightPercent
|
||||
getPixels: org.nativescript.widgets.ViewHelper.getHeight,
|
||||
setPixels: org.nativescript.widgets.ViewHelper.setHeight,
|
||||
setPercent: org.nativescript.widgets.ViewHelper.setHeightPercent
|
||||
});
|
||||
|
||||
createNativePercentLengthProperty({
|
||||
key: "_minWidthNative",
|
||||
getPixels: ViewHelper.getMinWidth,
|
||||
setPixels: ViewHelper.setMinWidth
|
||||
getPixels: org.nativescript.widgets.ViewHelper.getMinWidth,
|
||||
setPixels: org.nativescript.widgets.ViewHelper.setMinWidth
|
||||
});
|
||||
|
||||
createNativePercentLengthProperty({
|
||||
key: "_minHeightNative",
|
||||
getPixels: ViewHelper.getMinHeight,
|
||||
setPixels: ViewHelper.setMinHeight
|
||||
getPixels: org.nativescript.widgets.ViewHelper.getMinHeight,
|
||||
setPixels: org.nativescript.widgets.ViewHelper.setMinHeight
|
||||
});
|
||||
|
||||
export class CustomLayoutView extends View implements CustomLayoutViewDefinition {
|
||||
|
||||
@@ -5,39 +5,49 @@
|
||||
|
||||
export * from "./date-picker-common";
|
||||
|
||||
@Interfaces([android.widget.DatePicker.OnDateChangedListener])
|
||||
class DateChangedListener extends java.lang.Object implements android.widget.DatePicker.OnDateChangedListener {
|
||||
constructor(public owner: WeakRef<DatePicker>) {
|
||||
super()
|
||||
return global.__native(this);
|
||||
interface DateChangedListener {
|
||||
new (owner: DatePicker): android.widget.DatePicker.OnDateChangedListener;
|
||||
}
|
||||
|
||||
let DateChangedListener: DateChangedListener;
|
||||
|
||||
function initializeDateChangedListener(): void {
|
||||
if (DateChangedListener) {
|
||||
return;
|
||||
}
|
||||
|
||||
onDateChanged(picker: android.widget.DatePicker, year: number, month: number, day: number) {
|
||||
let owner = this.owner.get();
|
||||
if (!owner) {
|
||||
return;
|
||||
@Interfaces([android.widget.DatePicker.OnDateChangedListener])
|
||||
class DateChangedListenerImpl extends java.lang.Object implements android.widget.DatePicker.OnDateChangedListener {
|
||||
constructor(public owner: DatePicker) {
|
||||
super()
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
let dateIsChanged = false;
|
||||
if (year !== owner.year) {
|
||||
yearProperty.nativeValueChange(owner, year);
|
||||
dateIsChanged = true;
|
||||
}
|
||||
onDateChanged(picker: android.widget.DatePicker, year: number, month: number, day: number) {
|
||||
const owner = this.owner;
|
||||
let dateIsChanged = false;
|
||||
if (year !== owner.year) {
|
||||
yearProperty.nativeValueChange(owner, year);
|
||||
dateIsChanged = true;
|
||||
}
|
||||
|
||||
if ((month + 1) !== owner.month) {
|
||||
monthProperty.nativeValueChange(owner, month + 1);
|
||||
dateIsChanged = true;
|
||||
}
|
||||
if ((month + 1) !== owner.month) {
|
||||
monthProperty.nativeValueChange(owner, month + 1);
|
||||
dateIsChanged = true;
|
||||
}
|
||||
|
||||
if (day !== owner.day) {
|
||||
dayProperty.nativeValueChange(owner, day);
|
||||
dateIsChanged = true;
|
||||
}
|
||||
if (day !== owner.day) {
|
||||
dayProperty.nativeValueChange(owner, day);
|
||||
dateIsChanged = true;
|
||||
}
|
||||
|
||||
if (dateIsChanged) {
|
||||
dateProperty.nativeValueChange(owner, new Date(year, month, day));
|
||||
if (dateIsChanged) {
|
||||
dateProperty.nativeValueChange(owner, new Date(year, month, day));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DateChangedListener = DateChangedListenerImpl;
|
||||
}
|
||||
|
||||
export class DatePicker extends DatePickerBase {
|
||||
@@ -49,9 +59,10 @@ export class DatePicker extends DatePickerBase {
|
||||
}
|
||||
|
||||
public _createNativeView() {
|
||||
initializeDateChangedListener();
|
||||
this._android = new android.widget.DatePicker(this._context);
|
||||
this._android.setCalendarViewShown(false);
|
||||
this._listener = this._listener = new DateChangedListener(new WeakRef(this));
|
||||
this._listener = this._listener = new DateChangedListener(this);
|
||||
this._android.init(0, 0, 0, this._listener);
|
||||
}
|
||||
|
||||
@@ -120,4 +131,4 @@ export class DatePicker extends DatePickerBase {
|
||||
picker.setMinDate(newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,102 +9,86 @@ import { ad } from "utils/utils";
|
||||
|
||||
export * from "./editable-text-base-common";
|
||||
|
||||
@Interfaces([android.text.TextWatcher])
|
||||
class TextWatcher extends java.lang.Object implements android.text.TextWatcher {
|
||||
constructor(private owner: WeakRef<EditableTextBase>) {
|
||||
super();
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
public beforeTextChanged(text: string, start: number, count: number, after: number) {
|
||||
//
|
||||
}
|
||||
|
||||
public onTextChanged(text: string, start: number, before: number, count: number) {
|
||||
let owner = this.owner.get();
|
||||
if (!owner) {
|
||||
return;
|
||||
}
|
||||
let selectionStart = owner.android.getSelectionStart();
|
||||
owner.android.removeTextChangedListener(owner._textWatcher);
|
||||
|
||||
// //RemoveThisDoubleCall
|
||||
// owner.style._updateTextDecoration();
|
||||
// owner.style._updateTextTransform();
|
||||
|
||||
owner.android.addTextChangedListener(owner._textWatcher);
|
||||
owner.android.setSelection(selectionStart);
|
||||
}
|
||||
|
||||
public afterTextChanged(editable: android.text.IEditable) {
|
||||
let owner = this.owner.get();
|
||||
if (!owner) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (owner.updateTextTrigger) {
|
||||
case "focusLost":
|
||||
owner._dirtyTextAccumulator = editable.toString();
|
||||
break;
|
||||
case "textChanged":
|
||||
textProperty.nativeValueChange(owner, editable.toString());
|
||||
break;
|
||||
default:
|
||||
throw new Error("Invalid updateTextTrigger: " + owner.updateTextTrigger);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//https://github.com/NativeScript/NativeScript/issues/2942
|
||||
let dismissKeyboardTimeoutId: any;
|
||||
|
||||
@Interfaces([android.view.View.OnFocusChangeListener])
|
||||
class FocusChangeListener extends java.lang.Object implements android.view.View.OnFocusChangeListener {
|
||||
constructor(private owner: WeakRef<EditableTextBase>) {
|
||||
super();
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
public onFocusChange(view: android.view.View, hasFocus: boolean) {
|
||||
let owner = this.owner.get();
|
||||
if (!owner) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasFocus) {
|
||||
if (dismissKeyboardTimeoutId) {
|
||||
// https://github.com/NativeScript/NativeScript/issues/2942
|
||||
// Don't hide the keyboard since another (or the same) EditText has gained focus.
|
||||
clearTimeout(dismissKeyboardTimeoutId);
|
||||
dismissKeyboardTimeoutId = undefined;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (owner._dirtyTextAccumulator) {
|
||||
textProperty.nativeValueChange(owner, owner._dirtyTextAccumulator);
|
||||
owner._dirtyTextAccumulator = undefined;
|
||||
}
|
||||
|
||||
dismissKeyboardTimeoutId = setTimeout(() => {
|
||||
// https://github.com/NativeScript/NativeScript/issues/2942
|
||||
// Dismiss the keyboard if focus goes to something different from EditText.
|
||||
owner.dismissSoftInput();
|
||||
dismissKeyboardTimeoutId = null;
|
||||
}, 1);
|
||||
}
|
||||
}
|
||||
interface EditTextListeners extends android.text.TextWatcher, android.view.View.OnFocusChangeListener, android.widget.TextView.OnEditorActionListener {
|
||||
}
|
||||
|
||||
@Interfaces([android.widget.TextView.OnEditorActionListener])
|
||||
class EditorActionListener extends java.lang.Object implements android.widget.TextView.OnEditorActionListener {
|
||||
constructor(private owner: WeakRef<EditableTextBase>) {
|
||||
super();
|
||||
return global.__native(this);
|
||||
interface EditTextListenersClass {
|
||||
prototype: EditTextListeners;
|
||||
new (owner: EditableTextBase): EditTextListeners;
|
||||
}
|
||||
|
||||
let EditTextListeners: EditTextListenersClass;
|
||||
|
||||
function initializeEditTextListeners(): void {
|
||||
if (EditTextListeners) {
|
||||
return;
|
||||
}
|
||||
|
||||
public onEditorAction(textView: android.widget.TextView, actionId: number, event: android.view.KeyEvent): boolean {
|
||||
let owner = this.owner.get();
|
||||
if (owner) {
|
||||
@Interfaces([android.text.TextWatcher, android.view.View.OnFocusChangeListener, android.widget.TextView.OnEditorActionListener])
|
||||
class EditTextListenersImpl extends java.lang.Object implements android.text.TextWatcher, android.view.View.OnFocusChangeListener, android.widget.TextView.OnEditorActionListener {
|
||||
constructor(private owner: EditableTextBase) {
|
||||
super();
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
public beforeTextChanged(text: string, start: number, count: number, after: number) {
|
||||
//
|
||||
}
|
||||
|
||||
public onTextChanged(text: string, start: number, before: number, count: number) {
|
||||
const owner = this.owner;
|
||||
let selectionStart = owner.android.getSelectionStart();
|
||||
owner.android.removeTextChangedListener(owner._editTextListeners);
|
||||
owner.android.addTextChangedListener(owner._editTextListeners);
|
||||
owner.android.setSelection(selectionStart);
|
||||
}
|
||||
|
||||
public afterTextChanged(editable: android.text.IEditable) {
|
||||
const owner = this.owner;
|
||||
switch (owner.updateTextTrigger) {
|
||||
case "focusLost":
|
||||
owner._dirtyTextAccumulator = editable.toString();
|
||||
break;
|
||||
case "textChanged":
|
||||
textProperty.nativeValueChange(owner, editable.toString());
|
||||
break;
|
||||
default:
|
||||
throw new Error("Invalid updateTextTrigger: " + owner.updateTextTrigger);
|
||||
}
|
||||
}
|
||||
|
||||
public onFocusChange(view: android.view.View, hasFocus: boolean) {
|
||||
const owner = this.owner;
|
||||
|
||||
if (hasFocus) {
|
||||
if (dismissKeyboardTimeoutId) {
|
||||
// https://github.com/NativeScript/NativeScript/issues/2942
|
||||
// Don't hide the keyboard since another (or the same) EditText has gained focus.
|
||||
clearTimeout(dismissKeyboardTimeoutId);
|
||||
dismissKeyboardTimeoutId = undefined;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (owner._dirtyTextAccumulator) {
|
||||
textProperty.nativeValueChange(owner, owner._dirtyTextAccumulator);
|
||||
owner._dirtyTextAccumulator = undefined;
|
||||
}
|
||||
|
||||
dismissKeyboardTimeoutId = setTimeout(() => {
|
||||
// https://github.com/NativeScript/NativeScript/issues/2942
|
||||
// Dismiss the keyboard if focus goes to something different from EditText.
|
||||
owner.dismissSoftInput();
|
||||
dismissKeyboardTimeoutId = null;
|
||||
}, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public onEditorAction(textView: android.widget.TextView, actionId: number, event: android.view.KeyEvent): boolean {
|
||||
const owner = this.owner;
|
||||
|
||||
if (actionId === android.view.inputmethod.EditorInfo.IME_ACTION_DONE ||
|
||||
actionId === android.view.inputmethod.EditorInfo.IME_ACTION_GO ||
|
||||
actionId === android.view.inputmethod.EditorInfo.IME_ACTION_SEARCH ||
|
||||
@@ -126,18 +110,19 @@ class EditorActionListener extends java.lang.Object implements android.widget.Te
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
EditTextListeners = EditTextListenersImpl;
|
||||
}
|
||||
|
||||
export abstract class EditableTextBase extends EditableTextBaseCommon {
|
||||
_textWatcher: android.text.TextWatcher;
|
||||
/* tslint:disable */
|
||||
_dirtyTextAccumulator: string;
|
||||
/* tslint:enable */
|
||||
|
||||
_editTextListeners: EditTextListeners;
|
||||
|
||||
private _android: android.widget.EditText;
|
||||
private _keyListenerCache: android.text.method.KeyListener;
|
||||
private _focusChangeListener: android.view.View.OnFocusChangeListener;
|
||||
private _editorActionListener: android.widget.TextView.OnEditorActionListener;
|
||||
|
||||
get android(): android.widget.EditText {
|
||||
return this._android;
|
||||
@@ -148,34 +133,24 @@ export abstract class EditableTextBase extends EditableTextBaseCommon {
|
||||
public abstract _onReturnPress(): void;
|
||||
|
||||
public _createNativeView() {
|
||||
initializeEditTextListeners();
|
||||
this._android = new android.widget.EditText(this._context);
|
||||
this._configureEditText();
|
||||
this._keyListenerCache = this.android.getKeyListener();
|
||||
|
||||
let weakRef = new WeakRef(this);
|
||||
|
||||
this._textWatcher = this._textWatcher || new TextWatcher(weakRef);
|
||||
this._android.addTextChangedListener(this._textWatcher);
|
||||
|
||||
this._focusChangeListener = this._focusChangeListener || new FocusChangeListener(weakRef);
|
||||
this._android.setOnFocusChangeListener(this._focusChangeListener);
|
||||
|
||||
this._editorActionListener = this._editorActionListener || new EditorActionListener(weakRef);
|
||||
this._android.setOnEditorActionListener(this._editorActionListener);
|
||||
this._editTextListeners = this._editTextListeners || new EditTextListeners(this);
|
||||
this._android.addTextChangedListener(this._editTextListeners);
|
||||
this._android.setOnFocusChangeListener(this._editTextListeners);
|
||||
this._android.setOnEditorActionListener(this._editTextListeners);
|
||||
}
|
||||
|
||||
public _resetNativeView(force?: boolean) {
|
||||
if (this._android) {
|
||||
if (this._textWatcher) {
|
||||
this._android.removeTextChangedListener(this._textWatcher);
|
||||
}
|
||||
this._android.setOnFocusChangeListener(null);
|
||||
this._android.setOnEditorActionListener(null);
|
||||
|
||||
if (this._focusChangeListener) {
|
||||
this._android.setOnFocusChangeListener(null);
|
||||
}
|
||||
|
||||
if (this._editorActionListener) {
|
||||
this._android.setOnEditorActionListener(null);
|
||||
if (this._editTextListeners) {
|
||||
this._android.removeTextChangedListener(this._editTextListeners);
|
||||
}
|
||||
}
|
||||
super._resetNativeView();
|
||||
@@ -436,4 +411,4 @@ export abstract class EditableTextBase extends EditableTextBaseCommon {
|
||||
this._android.setHintTextColor(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,226 @@
|
||||
import { GestureEventData, SwipeGestureEventData, PanGestureEventData, RotationGestureEventData } from "ui/gestures";
|
||||
import { GesturesObserverBase, toString, TouchAction, GestureStateTypes, GestureTypes, SwipeDirection,
|
||||
View, EventData } from "./gestures-common";
|
||||
import {
|
||||
GesturesObserverBase, toString, TouchAction, GestureStateTypes, GestureTypes, SwipeDirection,
|
||||
View, EventData
|
||||
} from "./gestures-common";
|
||||
|
||||
// Import layout from utils directly to avoid circular references
|
||||
import { layout } from "utils/utils";
|
||||
|
||||
export * from "./gestures-common";
|
||||
|
||||
interface TapAndDoubleTapGestureListener {
|
||||
new (observer: GesturesObserver, target: View, type: number): android.view.GestureDetector.SimpleOnGestureListener;
|
||||
}
|
||||
|
||||
let TapAndDoubleTapGestureListener: TapAndDoubleTapGestureListener;
|
||||
function initializeTapAndDoubleTapGestureListener() {
|
||||
if (TapAndDoubleTapGestureListener) {
|
||||
return;
|
||||
}
|
||||
|
||||
class TapAndDoubleTapGestureListenerImpl extends android.view.GestureDetector.SimpleOnGestureListener {
|
||||
private _observer: GesturesObserver;
|
||||
private _target: View;
|
||||
private _type: number;
|
||||
|
||||
constructor(observer: GesturesObserver, target: View, type: number) {
|
||||
super();
|
||||
|
||||
this._observer = observer;
|
||||
this._target = target;
|
||||
this._type = type;
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
public onSingleTapUp(motionEvent: android.view.MotionEvent): boolean {
|
||||
if (this._type & GestureTypes.tap) {
|
||||
let args = _getArgs(GestureTypes.tap, this._target, motionEvent);
|
||||
_executeCallback(this._observer, args);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public onDoubleTap(motionEvent: android.view.MotionEvent): boolean {
|
||||
if (this._type & GestureTypes.doubleTap) {
|
||||
let args = _getArgs(GestureTypes.doubleTap, this._target, motionEvent);
|
||||
_executeCallback(this._observer, args);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public onDown(motionEvent: android.view.MotionEvent): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
public onLongPress(motionEvent: android.view.MotionEvent): void {
|
||||
if (this._type & GestureTypes.longPress) {
|
||||
let args = _getArgs(GestureTypes.longPress, this._target, motionEvent);
|
||||
_executeCallback(this._observer, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TapAndDoubleTapGestureListener = TapAndDoubleTapGestureListenerImpl;
|
||||
}
|
||||
|
||||
interface PinchGestureListener {
|
||||
new (observer: GesturesObserver, target: View): android.view.ScaleGestureDetector.SimpleOnScaleGestureListener;
|
||||
}
|
||||
|
||||
let PinchGestureListener: PinchGestureListener;
|
||||
function initializePinchGestureListener() {
|
||||
if (PinchGestureListener) {
|
||||
return;
|
||||
}
|
||||
|
||||
class PinchGestureListenerImpl extends android.view.ScaleGestureDetector.SimpleOnScaleGestureListener {
|
||||
private _observer: GesturesObserver;
|
||||
private _target: View;
|
||||
private _scale: number;
|
||||
private _density: number;
|
||||
|
||||
constructor(observer: GesturesObserver, target: View) {
|
||||
super();
|
||||
|
||||
this._observer = observer;
|
||||
this._target = target;
|
||||
this._density = layout.getDisplayDensity();
|
||||
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
public onScaleBegin(detector: android.view.ScaleGestureDetector): boolean {
|
||||
this._scale = detector.getScaleFactor();
|
||||
|
||||
let args = new PinchGestureEventData(
|
||||
this._target,
|
||||
detector,
|
||||
this._scale,
|
||||
this._target,
|
||||
GestureStateTypes.began);
|
||||
|
||||
_executeCallback(this._observer, args);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public onScale(detector: android.view.ScaleGestureDetector): boolean {
|
||||
this._scale *= detector.getScaleFactor();
|
||||
|
||||
let args = new PinchGestureEventData(
|
||||
this._target,
|
||||
detector,
|
||||
this._scale,
|
||||
this._target,
|
||||
GestureStateTypes.changed);
|
||||
|
||||
_executeCallback(this._observer, args);
|
||||
return true;
|
||||
}
|
||||
|
||||
public onScaleEnd(detector: android.view.ScaleGestureDetector): void {
|
||||
this._scale *= detector.getScaleFactor();
|
||||
|
||||
let args = new PinchGestureEventData(
|
||||
this._target,
|
||||
detector,
|
||||
this._scale,
|
||||
this._target,
|
||||
GestureStateTypes.ended);
|
||||
|
||||
_executeCallback(this._observer, args);
|
||||
}
|
||||
}
|
||||
|
||||
PinchGestureListener = PinchGestureListenerImpl;
|
||||
}
|
||||
|
||||
interface SwipeGestureListener {
|
||||
new (observer: GesturesObserver, target: View): android.view.GestureDetector.SimpleOnGestureListener;
|
||||
}
|
||||
|
||||
let SwipeGestureListener: SwipeGestureListener;
|
||||
function initializeSwipeGestureListener() {
|
||||
if (SwipeGestureListener) {
|
||||
return;
|
||||
}
|
||||
|
||||
class SwipeGestureListenerImpl extends android.view.GestureDetector.SimpleOnGestureListener {
|
||||
private _observer: GesturesObserver;
|
||||
private _target: View;
|
||||
|
||||
constructor(observer: GesturesObserver, target: View) {
|
||||
super();
|
||||
|
||||
this._observer = observer;
|
||||
this._target = target;
|
||||
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
public onDown(motionEvent: android.view.MotionEvent): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
public onFling(initialEvent: android.view.MotionEvent, currentEvent: android.view.MotionEvent, velocityX: number, velocityY: number): boolean {
|
||||
let result = false;
|
||||
let args: SwipeGestureEventData;
|
||||
try {
|
||||
let deltaY = currentEvent.getY() - initialEvent.getY();
|
||||
let deltaX = currentEvent.getX() - initialEvent.getX();
|
||||
|
||||
if (Math.abs(deltaX) > Math.abs(deltaY)) {
|
||||
|
||||
if (Math.abs(deltaX) > SWIPE_THRESHOLD
|
||||
&& Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
|
||||
|
||||
if (deltaX > 0) {
|
||||
|
||||
args = _getSwipeArgs(SwipeDirection.right, this._target, initialEvent, currentEvent);
|
||||
_executeCallback(this._observer, args);
|
||||
|
||||
result = true;
|
||||
} else {
|
||||
|
||||
args = _getSwipeArgs(SwipeDirection.left, this._target, initialEvent, currentEvent);
|
||||
_executeCallback(this._observer, args);
|
||||
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (Math.abs(deltaY) > SWIPE_THRESHOLD
|
||||
&& Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
|
||||
|
||||
if (deltaY > 0) {
|
||||
|
||||
args = _getSwipeArgs(SwipeDirection.down, this._target, initialEvent, currentEvent);
|
||||
_executeCallback(this._observer, args);
|
||||
|
||||
result = true;
|
||||
} else {
|
||||
|
||||
args = _getSwipeArgs(SwipeDirection.up, this._target, initialEvent, currentEvent);
|
||||
_executeCallback(this._observer, args);
|
||||
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ex) {
|
||||
//
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
SwipeGestureListener = SwipeGestureListenerImpl;
|
||||
}
|
||||
|
||||
const SWIPE_THRESHOLD = 100;
|
||||
const SWIPE_VELOCITY_THRESHOLD = 100;
|
||||
const INVALID_POINTER_ID = -1;
|
||||
@@ -78,18 +292,18 @@ export class GesturesObserver extends GesturesObserverBase {
|
||||
this._detach();
|
||||
|
||||
if (type & GestureTypes.tap || type & GestureTypes.doubleTap || type & GestureTypes.longPress) {
|
||||
ensureTapAndDoubleTapGestureListenerClass();
|
||||
this._simpleGestureDetector = new android.support.v4.view.GestureDetectorCompat(target._context, new TapAndDoubleTapGestureListenerClass(this, this.target, type));
|
||||
initializeTapAndDoubleTapGestureListener();
|
||||
this._simpleGestureDetector = new android.support.v4.view.GestureDetectorCompat(target._context, new TapAndDoubleTapGestureListener(this, this.target, type));
|
||||
}
|
||||
|
||||
if (type & GestureTypes.pinch) {
|
||||
ensurePinchGestureListenerClass();
|
||||
this._scaleGestureDetector = new android.view.ScaleGestureDetector(target._context, new PinchGestureListenerClass(this, this.target));
|
||||
initializePinchGestureListener();
|
||||
this._scaleGestureDetector = new android.view.ScaleGestureDetector(target._context, new PinchGestureListener(this, this.target));
|
||||
}
|
||||
|
||||
if (type & GestureTypes.swipe) {
|
||||
ensureSwipeGestureListenerClass();
|
||||
this._swipeGestureDetector = new android.support.v4.view.GestureDetectorCompat(target._context, new SwipeGestureListenerClass(this, this.target));
|
||||
initializeSwipeGestureListener();
|
||||
this._swipeGestureDetector = new android.support.v4.view.GestureDetectorCompat(target._context, new SwipeGestureListener(this, this.target));
|
||||
}
|
||||
|
||||
if (type & GestureTypes.pan) {
|
||||
@@ -182,57 +396,6 @@ function _executeCallback(observer: GesturesObserver, args: GestureEventData) {
|
||||
}
|
||||
}
|
||||
|
||||
let TapAndDoubleTapGestureListenerClass;
|
||||
function ensureTapAndDoubleTapGestureListenerClass() {
|
||||
if (TapAndDoubleTapGestureListenerClass) {
|
||||
return;
|
||||
}
|
||||
|
||||
class TapAndDoubleTapGestureListener extends android.view.GestureDetector.SimpleOnGestureListener {
|
||||
private _observer: GesturesObserver;
|
||||
private _target: View;
|
||||
private _type: number;
|
||||
|
||||
constructor(observer: GesturesObserver, target: View, type: number) {
|
||||
super();
|
||||
|
||||
this._observer = observer;
|
||||
this._target = target;
|
||||
this._type = type;
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
public onSingleTapUp(motionEvent: android.view.MotionEvent): boolean {
|
||||
if (this._type & GestureTypes.tap) {
|
||||
let args = _getArgs(GestureTypes.tap, this._target, motionEvent);
|
||||
_executeCallback(this._observer, args);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public onDoubleTap(motionEvent: android.view.MotionEvent): boolean {
|
||||
if (this._type & GestureTypes.doubleTap) {
|
||||
let args = _getArgs(GestureTypes.doubleTap, this._target, motionEvent);
|
||||
_executeCallback(this._observer, args);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public onDown(motionEvent: android.view.MotionEvent): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
public onLongPress(motionEvent: android.view.MotionEvent): void {
|
||||
if (this._type & GestureTypes.longPress) {
|
||||
let args = _getArgs(GestureTypes.longPress, this._target, motionEvent);
|
||||
_executeCallback(this._observer, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TapAndDoubleTapGestureListenerClass = TapAndDoubleTapGestureListener;
|
||||
}
|
||||
|
||||
class PinchGestureEventData implements PinchGestureEventData {
|
||||
public type = GestureTypes.pinch;
|
||||
public eventName = toString(GestureTypes.pinch);
|
||||
@@ -255,155 +418,6 @@ class PinchGestureEventData implements PinchGestureEventData {
|
||||
}
|
||||
}
|
||||
|
||||
let PinchGestureListenerClass;
|
||||
function ensurePinchGestureListenerClass() {
|
||||
if (PinchGestureListenerClass) {
|
||||
return;
|
||||
}
|
||||
|
||||
class PinchGestureListener extends android.view.ScaleGestureDetector.SimpleOnScaleGestureListener {
|
||||
private _observer: GesturesObserver;
|
||||
private _target: View;
|
||||
private _scale: number;
|
||||
private _density: number;
|
||||
|
||||
constructor(observer: GesturesObserver, target: View) {
|
||||
super();
|
||||
|
||||
this._observer = observer;
|
||||
this._target = target;
|
||||
this._density = layout.getDisplayDensity();
|
||||
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
public onScaleBegin(detector: android.view.ScaleGestureDetector): boolean {
|
||||
this._scale = detector.getScaleFactor();
|
||||
|
||||
let args = new PinchGestureEventData(
|
||||
this._target,
|
||||
detector,
|
||||
this._scale,
|
||||
this._target,
|
||||
GestureStateTypes.began);
|
||||
|
||||
_executeCallback(this._observer, args);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public onScale(detector: android.view.ScaleGestureDetector): boolean {
|
||||
this._scale *= detector.getScaleFactor();
|
||||
|
||||
let args = new PinchGestureEventData(
|
||||
this._target,
|
||||
detector,
|
||||
this._scale,
|
||||
this._target,
|
||||
GestureStateTypes.changed);
|
||||
|
||||
_executeCallback(this._observer, args);
|
||||
return true;
|
||||
}
|
||||
|
||||
public onScaleEnd(detector: android.view.ScaleGestureDetector): void {
|
||||
this._scale *= detector.getScaleFactor();
|
||||
|
||||
let args = new PinchGestureEventData(
|
||||
this._target,
|
||||
detector,
|
||||
this._scale,
|
||||
this._target,
|
||||
GestureStateTypes.ended);
|
||||
|
||||
_executeCallback(this._observer, args);
|
||||
}
|
||||
}
|
||||
|
||||
PinchGestureListenerClass = PinchGestureListener;
|
||||
}
|
||||
|
||||
let SwipeGestureListenerClass;
|
||||
function ensureSwipeGestureListenerClass() {
|
||||
if (SwipeGestureListenerClass) {
|
||||
return;
|
||||
}
|
||||
|
||||
class SwipeGestureListener extends android.view.GestureDetector.SimpleOnGestureListener {
|
||||
private _observer: GesturesObserver;
|
||||
private _target: View;
|
||||
|
||||
constructor(observer: GesturesObserver, target: View) {
|
||||
super();
|
||||
|
||||
this._observer = observer;
|
||||
this._target = target;
|
||||
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
public onDown(motionEvent: android.view.MotionEvent): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
public onFling(initialEvent: android.view.MotionEvent, currentEvent: android.view.MotionEvent, velocityX: number, velocityY: number): boolean {
|
||||
let result = false;
|
||||
let args: SwipeGestureEventData;
|
||||
try {
|
||||
let deltaY = currentEvent.getY() - initialEvent.getY();
|
||||
let deltaX = currentEvent.getX() - initialEvent.getX();
|
||||
|
||||
if (Math.abs(deltaX) > Math.abs(deltaY)) {
|
||||
|
||||
if (Math.abs(deltaX) > SWIPE_THRESHOLD
|
||||
&& Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
|
||||
|
||||
if (deltaX > 0) {
|
||||
|
||||
args = _getSwipeArgs(SwipeDirection.right, this._target, initialEvent, currentEvent);
|
||||
_executeCallback(this._observer, args);
|
||||
|
||||
result = true;
|
||||
} else {
|
||||
|
||||
args = _getSwipeArgs(SwipeDirection.left, this._target, initialEvent, currentEvent);
|
||||
_executeCallback(this._observer, args);
|
||||
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (Math.abs(deltaY) > SWIPE_THRESHOLD
|
||||
&& Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
|
||||
|
||||
if (deltaY > 0) {
|
||||
|
||||
args = _getSwipeArgs(SwipeDirection.down, this._target, initialEvent, currentEvent);
|
||||
_executeCallback(this._observer, args);
|
||||
|
||||
result = true;
|
||||
} else {
|
||||
|
||||
args = _getSwipeArgs(SwipeDirection.up, this._target, initialEvent, currentEvent);
|
||||
_executeCallback(this._observer, args);
|
||||
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ex) {
|
||||
//
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
SwipeGestureListenerClass = SwipeGestureListener;
|
||||
}
|
||||
|
||||
class CustomPanGestureDetector {
|
||||
private observer: GesturesObserver;
|
||||
private target: View;
|
||||
|
||||
@@ -60,6 +60,7 @@ export class Image extends ImageBase {
|
||||
}
|
||||
|
||||
public _createNativeView() {
|
||||
initializeImageLoadedListener();
|
||||
if (!imageFetcher) {
|
||||
initImageCache(this._context);
|
||||
}
|
||||
@@ -77,7 +78,7 @@ export class Image extends ImageBase {
|
||||
|
||||
let value = this.src;
|
||||
let async = this.loadMode === ASYNC;
|
||||
this._imageLoadedListener = this._imageLoadedListener || new ImageLoadedListener(new WeakRef(this));
|
||||
this._imageLoadedListener = this._imageLoadedListener || new ImageLoadedListener(this);
|
||||
|
||||
if (typeof value === "string") {
|
||||
value = value.trim();
|
||||
@@ -163,17 +164,27 @@ export class Image extends ImageBase {
|
||||
}
|
||||
}
|
||||
|
||||
@Interfaces([org.nativescript.widgets.image.Worker.OnImageLoadedListener])
|
||||
class ImageLoadedListener extends java.lang.Object implements org.nativescript.widgets.image.Worker.OnImageLoadedListener {
|
||||
constructor(private owner: WeakRef<Image>) {
|
||||
super();
|
||||
return global.__native(this);
|
||||
interface ImageLoadedListener {
|
||||
new (owner: Image): org.nativescript.widgets.image.Worker.OnImageLoadedListener;
|
||||
}
|
||||
|
||||
let ImageLoadedListener: ImageLoadedListener;
|
||||
function initializeImageLoadedListener() {
|
||||
if (ImageLoadedListener) {
|
||||
return;
|
||||
}
|
||||
|
||||
onImageLoaded(success: boolean): void {
|
||||
let owner = this.owner.get();
|
||||
if (owner) {
|
||||
owner.isLoading = false;
|
||||
@Interfaces([org.nativescript.widgets.image.Worker.OnImageLoadedListener])
|
||||
class ImageLoadedListenerImpl extends java.lang.Object implements org.nativescript.widgets.image.Worker.OnImageLoadedListener {
|
||||
constructor(private owner: Image) {
|
||||
super();
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
onImageLoaded(success: boolean): void {
|
||||
this.owner.isLoading = false;
|
||||
}
|
||||
}
|
||||
|
||||
ImageLoadedListener = ImageLoadedListenerImpl;
|
||||
}
|
||||
@@ -77,64 +77,62 @@ function setLayoutParamsProperty(view: View, setter: (lp: org.nativescript.widge
|
||||
}
|
||||
}
|
||||
|
||||
import FlexboxLayoutWidget = org.nativescript.widgets.FlexboxLayout;
|
||||
|
||||
const flexDirectionMap = {
|
||||
[FlexDirection.ROW]: FlexboxLayoutWidget.FLEX_DIRECTION_ROW,
|
||||
[FlexDirection.ROW_REVERSE]: FlexboxLayoutWidget.FLEX_DIRECTION_ROW_REVERSE,
|
||||
[FlexDirection.COLUMN]: FlexboxLayoutWidget.FLEX_DIRECTION_COLUMN,
|
||||
[FlexDirection.COLUMN_REVERSE]: FlexboxLayoutWidget.FLEX_DIRECTION_COLUMN_REVERSE
|
||||
}
|
||||
[FlexDirection.ROW]: 0, //FlexboxLayoutWidget.FLEX_DIRECTION_ROW,
|
||||
[FlexDirection.ROW_REVERSE]: 1, //FlexboxLayoutWidget.FLEX_DIRECTION_ROW_REVERSE,
|
||||
[FlexDirection.COLUMN]: 2, //FlexboxLayoutWidget.FLEX_DIRECTION_COLUMN,
|
||||
[FlexDirection.COLUMN_REVERSE]: 3 //FlexboxLayoutWidget.FLEX_DIRECTION_COLUMN_REVERSE
|
||||
};
|
||||
|
||||
const flexWrapMap = {
|
||||
[FlexWrap.NOWRAP]: FlexboxLayoutWidget.FLEX_WRAP_NOWRAP,
|
||||
[FlexWrap.WRAP]: FlexboxLayoutWidget.FLEX_WRAP_WRAP,
|
||||
[FlexWrap.WRAP_REVERSE]: FlexboxLayoutWidget.FLEX_WRAP_WRAP_REVERSE
|
||||
[FlexWrap.NOWRAP]: 0, //FlexboxLayoutWidget.FLEX_WRAP_NOWRAP,
|
||||
[FlexWrap.WRAP]: 1, //FlexboxLayoutWidget.FLEX_WRAP_WRAP,
|
||||
[FlexWrap.WRAP_REVERSE]: 2 //FlexboxLayoutWidget.FLEX_WRAP_WRAP_REVERSE
|
||||
}
|
||||
|
||||
const justifyContentMap = {
|
||||
[JustifyContent.CENTER]: FlexboxLayoutWidget.JUSTIFY_CONTENT_CENTER,
|
||||
[JustifyContent.FLEX_END]: FlexboxLayoutWidget.JUSTIFY_CONTENT_FLEX_END,
|
||||
[JustifyContent.FLEX_START]: FlexboxLayoutWidget.JUSTIFY_CONTENT_FLEX_START,
|
||||
[JustifyContent.SPACE_AROUND]: FlexboxLayoutWidget.JUSTIFY_CONTENT_SPACE_AROUND,
|
||||
[JustifyContent.SPACE_BETWEEN]: FlexboxLayoutWidget.JUSTIFY_CONTENT_SPACE_BETWEEN
|
||||
[JustifyContent.FLEX_START]: 0, //FlexboxLayoutWidget.JUSTIFY_CONTENT_FLEX_START,
|
||||
[JustifyContent.FLEX_END]: 1, //FlexboxLayoutWidget.JUSTIFY_CONTENT_FLEX_END,
|
||||
[JustifyContent.CENTER]: 2, //FlexboxLayoutWidget.JUSTIFY_CONTENT_CENTER,
|
||||
[JustifyContent.SPACE_BETWEEN]: 3, //FlexboxLayoutWidget.JUSTIFY_CONTENT_SPACE_BETWEEN
|
||||
[JustifyContent.SPACE_AROUND]: 4 //FlexboxLayoutWidget.JUSTIFY_CONTENT_SPACE_AROUND,
|
||||
}
|
||||
|
||||
const alignItemsMap = {
|
||||
[AlignItems.BASELINE]: FlexboxLayoutWidget.ALIGN_ITEMS_BASELINE,
|
||||
[AlignItems.CENTER]: FlexboxLayoutWidget.ALIGN_ITEMS_CENTER,
|
||||
[AlignItems.FLEX_END]: FlexboxLayoutWidget.ALIGN_ITEMS_FLEX_END,
|
||||
[AlignItems.FLEX_START]: FlexboxLayoutWidget.ALIGN_ITEMS_FLEX_START,
|
||||
[AlignItems.STRETCH]: FlexboxLayoutWidget.ALIGN_ITEMS_STRETCH
|
||||
[AlignItems.FLEX_START]: 0, //FlexboxLayoutWidget.ALIGN_ITEMS_FLEX_START,
|
||||
[AlignItems.FLEX_END]: 1, //FlexboxLayoutWidget.ALIGN_ITEMS_FLEX_END,
|
||||
[AlignItems.CENTER]: 2, //FlexboxLayoutWidget.ALIGN_ITEMS_CENTER,
|
||||
[AlignItems.BASELINE]: 3, //FlexboxLayoutWidget.ALIGN_ITEMS_BASELINE,
|
||||
[AlignItems.STRETCH]: 4 //FlexboxLayoutWidget.ALIGN_ITEMS_STRETCH
|
||||
}
|
||||
|
||||
const alignContentMap = {
|
||||
[AlignContent.CENTER]: FlexboxLayoutWidget.ALIGN_CONTENT_CENTER,
|
||||
[AlignContent.FLEX_END]: FlexboxLayoutWidget.ALIGN_CONTENT_FLEX_END,
|
||||
[AlignContent.FLEX_START]: FlexboxLayoutWidget.ALIGN_CONTENT_FLEX_START,
|
||||
[AlignContent.SPACE_AROUND]: FlexboxLayoutWidget.ALIGN_CONTENT_SPACE_AROUND,
|
||||
[AlignContent.SPACE_BETWEEN]: FlexboxLayoutWidget.ALIGN_CONTENT_SPACE_BETWEEN,
|
||||
[AlignContent.STRETCH]: FlexboxLayoutWidget.ALIGN_CONTENT_STRETCH
|
||||
[AlignContent.FLEX_START]: 0, //FlexboxLayoutWidget.ALIGN_CONTENT_FLEX_START,
|
||||
[AlignContent.FLEX_END]: 1, //FlexboxLayoutWidget.ALIGN_CONTENT_FLEX_END,
|
||||
[AlignContent.CENTER]: 2, //FlexboxLayoutWidget.ALIGN_CONTENT_CENTER,
|
||||
[AlignContent.SPACE_BETWEEN]: 3, //FlexboxLayoutWidget.ALIGN_CONTENT_SPACE_BETWEEN,
|
||||
[AlignContent.SPACE_AROUND]: 4, //FlexboxLayoutWidget.ALIGN_CONTENT_SPACE_AROUND,
|
||||
[AlignContent.STRETCH]: 5 //FlexboxLayoutWidget.ALIGN_CONTENT_STRETCH
|
||||
}
|
||||
|
||||
const alignSelfMap = {
|
||||
[AlignSelf.AUTO]: FlexboxLayoutWidget.LayoutParams.ALIGN_SELF_AUTO,
|
||||
[AlignSelf.FLEX_START]: FlexboxLayoutWidget.LayoutParams.ALIGN_SELF_FLEX_START,
|
||||
[AlignSelf.FLEX_END]: FlexboxLayoutWidget.LayoutParams.ALIGN_SELF_FLEX_END,
|
||||
[AlignSelf.CENTER]: FlexboxLayoutWidget.LayoutParams.ALIGN_SELF_CENTER,
|
||||
[AlignSelf.BASELINE]: FlexboxLayoutWidget.LayoutParams.ALIGN_SELF_BASELINE,
|
||||
[AlignSelf.STRETCH]: FlexboxLayoutWidget.LayoutParams.ALIGN_SELF_STRETCH
|
||||
[AlignSelf.AUTO]: -1, //FlexboxLayoutWidget.LayoutParams.ALIGN_SELF_AUTO,
|
||||
[AlignSelf.FLEX_START]: 0, //FlexboxLayoutWidget.LayoutParams.ALIGN_SELF_FLEX_START,
|
||||
[AlignSelf.FLEX_END]: 1, //FlexboxLayoutWidget.LayoutParams.ALIGN_SELF_FLEX_END,
|
||||
[AlignSelf.CENTER]: 2, //FlexboxLayoutWidget.LayoutParams.ALIGN_SELF_CENTER,
|
||||
[AlignSelf.BASELINE]: 3, //FlexboxLayoutWidget.LayoutParams.ALIGN_SELF_BASELINE,
|
||||
[AlignSelf.STRETCH]: 4 //FlexboxLayoutWidget.LayoutParams.ALIGN_SELF_STRETCH
|
||||
}
|
||||
|
||||
export class FlexboxLayout extends FlexboxLayoutBase {
|
||||
private _layout: FlexboxLayoutWidget;
|
||||
private _layout: org.nativescript.widgets.FlexboxLayout;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
get android(): FlexboxLayoutWidget { return this._layout; }
|
||||
get _nativeView(): FlexboxLayoutWidget { return this._layout; }
|
||||
get android(): org.nativescript.widgets.FlexboxLayout { return this._layout; }
|
||||
get _nativeView(): org.nativescript.widgets.FlexboxLayout { return this._layout; }
|
||||
|
||||
public _createNativeView() {
|
||||
this._layout = new org.nativescript.widgets.FlexboxLayout(this._context);
|
||||
@@ -161,7 +159,7 @@ export class FlexboxLayout extends FlexboxLayoutBase {
|
||||
this.android.setJustifyContent(justifyContentMap[justifyContent]);
|
||||
}
|
||||
|
||||
get [alignItemsProperty.native](): AlignItems{
|
||||
get [alignItemsProperty.native](): AlignItems {
|
||||
return alignItemsProperty.defaultValue;
|
||||
}
|
||||
set [alignItemsProperty.native](alignItems: AlignItems) {
|
||||
|
||||
@@ -5,27 +5,41 @@ export * from "ui/layouts/layout-base";
|
||||
|
||||
const OWNER = Symbol("_owner");
|
||||
|
||||
var NativeViewGroupClass;
|
||||
function ensureNativeViewGroupClass() {
|
||||
if (NativeViewGroupClass) {
|
||||
interface NativeViewGroup {
|
||||
new (context: android.content.Context): android.view.ViewGroup;
|
||||
}
|
||||
|
||||
let NativeViewGroup: NativeViewGroup;
|
||||
function initializeNativeViewGroup() {
|
||||
if (NativeViewGroup) {
|
||||
return;
|
||||
}
|
||||
|
||||
NativeViewGroupClass = (<any>android.view.ViewGroup).extend({
|
||||
onMeasure: function (widthMeasureSpec, heightMeasureSpec) {
|
||||
class NativeViewGroupImpl extends android.view.ViewGroup {
|
||||
constructor(context: android.content.Context) {
|
||||
super(context);
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
onMeasure(widthMeasureSpec: number, heightMeasureSpec: number): void {
|
||||
const owner: View = this[OWNER];
|
||||
owner.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
this.setMeasuredDimension(owner.getMeasuredWidth(), owner.getMeasuredHeight());
|
||||
},
|
||||
onLayout: function (changed: boolean, left: number, top: number, right: number, bottom: number): void {
|
||||
}
|
||||
|
||||
onLayout(changed: boolean, left: number, top: number, right: number, bottom: number): void {
|
||||
const owner: View = this[OWNER];
|
||||
owner.onLayout(left, top, right, bottom);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
NativeViewGroup = NativeViewGroupImpl;
|
||||
}
|
||||
|
||||
export class Layout extends LayoutBase implements LayoutDefinition {
|
||||
private _viewGroup: android.view.ViewGroup;
|
||||
_measuredWidth: number;
|
||||
_measuredHeight: number;
|
||||
|
||||
get android(): android.view.ViewGroup {
|
||||
return this._viewGroup;
|
||||
@@ -36,8 +50,8 @@ export class Layout extends LayoutBase implements LayoutDefinition {
|
||||
}
|
||||
|
||||
public _createNativeView() {
|
||||
ensureNativeViewGroupClass();
|
||||
this._viewGroup = new NativeViewGroupClass(this._context);
|
||||
initializeNativeViewGroup();
|
||||
this._viewGroup = new NativeViewGroup(this._context);
|
||||
this._viewGroup[OWNER] = this;
|
||||
}
|
||||
|
||||
@@ -77,4 +91,23 @@ export class Layout extends LayoutBase implements LayoutDefinition {
|
||||
public onLayout(left: number, top: number, right: number, bottom: number): void {
|
||||
// Don't call super because it will trigger layout again.
|
||||
}
|
||||
|
||||
// NOTE: overriden so we cache measuredWidth & measuredHeight.
|
||||
public setMeasuredDimension(measuredWidth: number, measuredHeight: number): void {
|
||||
super.setMeasuredDimension(measuredWidth, measuredHeight);
|
||||
this._measuredWidth = measuredWidth;
|
||||
this._measuredHeight = measuredHeight;
|
||||
}
|
||||
|
||||
// NOTE: base implementation use the nativeView.getMeasuredWidth which should
|
||||
// not be called while we are in onMeasure.
|
||||
public getMeasuredWidth(): number {
|
||||
return this._measuredWidth;
|
||||
}
|
||||
|
||||
// NOTE: base implementation use the nativeView.getMeasuredWidth which should
|
||||
// not be called while we are in onMeasure.
|
||||
public getMeasuredHeight(): number {
|
||||
return this._measuredHeight;
|
||||
}
|
||||
}
|
||||
@@ -3,36 +3,48 @@ import { ItemsSource } from "ui/list-picker";
|
||||
|
||||
export * from "./list-picker-common";
|
||||
|
||||
@Interfaces([android.widget.NumberPicker.Formatter])
|
||||
class Formatter extends java.lang.Object implements android.widget.NumberPicker.Formatter {
|
||||
constructor(private owner: WeakRef<ListPicker>) {
|
||||
super();
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
format(index: number): string {
|
||||
let owner = this.owner.get();
|
||||
if (owner) {
|
||||
return owner._getItemAsString(index);
|
||||
}
|
||||
|
||||
return " ";
|
||||
}
|
||||
interface Formatter {
|
||||
new (owner: ListPicker): android.widget.NumberPicker.Formatter;
|
||||
}
|
||||
|
||||
@Interfaces([android.widget.NumberPicker.OnValueChangeListener])
|
||||
class ValueChangeListener extends java.lang.Object implements android.widget.NumberPicker.OnValueChangeListener {
|
||||
constructor(private owner: WeakRef<ListPicker>) {
|
||||
super();
|
||||
return global.__native(this);
|
||||
interface ValueChangeListener {
|
||||
new (owner: ListPicker): android.widget.NumberPicker.OnValueChangeListener;
|
||||
}
|
||||
|
||||
let Formatter: Formatter;
|
||||
let ValueChangeListener: ValueChangeListener;
|
||||
|
||||
function initializeNativeClasses(): void {
|
||||
if (Formatter) {
|
||||
return;
|
||||
}
|
||||
|
||||
onValueChange(picker: android.widget.NumberPicker, oldValue: number, newValue: number): void {
|
||||
let owner = this.owner.get();
|
||||
if (owner) {
|
||||
selectedIndexProperty.nativeValueChange(owner, newValue);
|
||||
@Interfaces([android.widget.NumberPicker.Formatter])
|
||||
class FormatterImpl extends java.lang.Object implements android.widget.NumberPicker.Formatter {
|
||||
constructor(private owner: ListPicker) {
|
||||
super();
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
format(index: number): string {
|
||||
return this.owner._getItemAsString(index);
|
||||
}
|
||||
}
|
||||
|
||||
@Interfaces([android.widget.NumberPicker.OnValueChangeListener])
|
||||
class ValueChangeListenerImpl extends java.lang.Object implements android.widget.NumberPicker.OnValueChangeListener {
|
||||
constructor(private owner: ListPicker) {
|
||||
super();
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
onValueChange(picker: android.widget.NumberPicker, oldValue: number, newValue: number): void {
|
||||
selectedIndexProperty.nativeValueChange(this.owner, newValue);
|
||||
}
|
||||
}
|
||||
|
||||
Formatter = FormatterImpl;
|
||||
ValueChangeListener = ValueChangeListenerImpl;
|
||||
}
|
||||
|
||||
function getEditText(picker: android.widget.NumberPicker): android.widget.EditText {
|
||||
@@ -68,6 +80,7 @@ export class ListPicker extends ListPickerBase {
|
||||
}
|
||||
|
||||
public _createNativeView() {
|
||||
initializeNativeClasses();
|
||||
this._android = new android.widget.NumberPicker(this._context);
|
||||
let editText = getEditText(this._android);
|
||||
this._editText = editText;
|
||||
@@ -79,10 +92,10 @@ export class ListPicker extends ListPickerBase {
|
||||
this._android.setMaxValue(0);
|
||||
this._android.setValue(0);
|
||||
|
||||
this._formatter = this._formatter || new Formatter(new WeakRef(this));
|
||||
this._formatter = this._formatter || new Formatter(this);
|
||||
this._android.setFormatter(this._formatter);
|
||||
|
||||
this._valueChangedListener = this._valueChangedListener || new ValueChangeListener(new WeakRef(this));
|
||||
this._valueChangedListener = this._valueChangedListener || new ValueChangeListener(this);
|
||||
this._android.setOnValueChangedListener(this._valueChangedListener);
|
||||
|
||||
if (editText) {
|
||||
|
||||
@@ -13,20 +13,32 @@ const ITEMLOADING = ListViewBase.itemLoadingEvent;
|
||||
const LOADMOREITEMS = ListViewBase.loadMoreItemsEvent;
|
||||
const ITEMTAP = ListViewBase.itemTapEvent;
|
||||
|
||||
@Interfaces([android.widget.AdapterView.OnItemClickListener])
|
||||
class ItemClickListener extends java.lang.Object implements android.widget.AdapterView.OnItemClickListener {
|
||||
constructor(private owner: WeakRef<ListView>) {
|
||||
super();
|
||||
return global.__native(this);
|
||||
interface ItemClickListener {
|
||||
new (owner: ListView): android.widget.AdapterView.OnItemClickListener;
|
||||
}
|
||||
|
||||
let ItemClickListener: ItemClickListener;
|
||||
|
||||
function initializeItemClickListener(): void {
|
||||
if (ItemClickListener) {
|
||||
return;
|
||||
}
|
||||
|
||||
onItemClick<T extends android.widget.Adapter>(parent: android.widget.AdapterView<T>, convertView: android.view.View, index: number, id: number) {
|
||||
let owner = this.owner.get();
|
||||
if (owner) {
|
||||
let view = owner._realizedTemplates.get(owner._getItemTemplate(index).key).get(convertView);
|
||||
@Interfaces([android.widget.AdapterView.OnItemClickListener])
|
||||
class ItemClickListenerImpl extends java.lang.Object implements android.widget.AdapterView.OnItemClickListener {
|
||||
constructor(private owner: ListView) {
|
||||
super();
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
onItemClick<T extends android.widget.Adapter>(parent: android.widget.AdapterView<T>, convertView: android.view.View, index: number, id: number) {
|
||||
const owner = this.owner;
|
||||
const view = owner._realizedTemplates.get(owner._getItemTemplate(index).key).get(convertView);
|
||||
owner.notify({ eventName: ITEMTAP, object: owner, index: index, view: view });
|
||||
}
|
||||
}
|
||||
|
||||
ItemClickListener = ItemClickListenerImpl;
|
||||
}
|
||||
|
||||
export class ListView extends ListViewBase {
|
||||
@@ -37,6 +49,7 @@ export class ListView extends ListViewBase {
|
||||
public _realizedTemplates = new Map<string, Map<android.view.View, View>>();
|
||||
|
||||
public _createNativeView() {
|
||||
initializeItemClickListener();
|
||||
this._android = new android.widget.ListView(this._context);
|
||||
this._android.setDescendantFocusability(android.view.ViewGroup.FOCUS_AFTER_DESCENDANTS);
|
||||
this.updateEffectiveRowHeight();
|
||||
@@ -51,7 +64,7 @@ export class ListView extends ListViewBase {
|
||||
ensureListViewAdapterClass();
|
||||
this._android.setAdapter(new ListViewAdapterClass(this));
|
||||
|
||||
this._itemClickListener = this._itemClickListener || new ItemClickListener(new WeakRef(this));
|
||||
this._itemClickListener = this._itemClickListener || new ItemClickListener(this);
|
||||
this.android.setOnItemClickListener(this._itemClickListener);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,17 +10,17 @@ const SYSTEM_UI_FLAG_LIGHT_STATUS_BAR = 0x00002000;
|
||||
const STATUS_BAR_LIGHT_BCKG = -657931;
|
||||
const STATUS_BAR_DARK_BCKG = 1711276032;
|
||||
|
||||
interface DialogFragmentClass {
|
||||
interface DialogFragment {
|
||||
new (owner: Page, fullscreen: boolean, shownCallback: () => void, dismissCallback: () => void): android.app.DialogFragment;
|
||||
}
|
||||
let DialogFragmentClass: DialogFragmentClass;
|
||||
let DialogFragment: DialogFragment;
|
||||
|
||||
function ensureDialogFragmentClass() {
|
||||
if (DialogFragmentClass) {
|
||||
function initializeDialogFragment() {
|
||||
if (DialogFragment) {
|
||||
return;
|
||||
}
|
||||
|
||||
class DialogFragmentClassInner extends android.app.DialogFragment {
|
||||
class DialogFragmentImpl extends android.app.DialogFragment {
|
||||
constructor(
|
||||
private _owner: Page,
|
||||
private _fullscreen: boolean,
|
||||
@@ -83,7 +83,7 @@ function ensureDialogFragmentClass() {
|
||||
|
||||
};
|
||||
|
||||
DialogFragmentClass = DialogFragmentClassInner;
|
||||
DialogFragment = DialogFragmentImpl;
|
||||
}
|
||||
|
||||
export class Page extends PageBase {
|
||||
@@ -158,9 +158,9 @@ export class Page extends PageBase {
|
||||
this._setupUI(parent._context);
|
||||
this._isAddedToNativeVisualTree = true;
|
||||
|
||||
ensureDialogFragmentClass();
|
||||
initializeDialogFragment();
|
||||
|
||||
this._dialogFragment = new DialogFragmentClass(this, !!fullscreen, () => this._raiseShownModallyEvent(), () => this.closeModal());
|
||||
this._dialogFragment = new DialogFragment(this, !!fullscreen, () => this._raiseShownModallyEvent(), () => this.closeModal());
|
||||
|
||||
super._raiseShowingModallyEvent();
|
||||
|
||||
|
||||
@@ -9,16 +9,31 @@ export * from "./search-bar-common";
|
||||
const SEARCHTEXT = Symbol("searchText");
|
||||
const QUERY = Symbol("query");
|
||||
|
||||
@Interfaces([android.widget.SearchView.OnQueryTextListener])
|
||||
class QueryTextListener extends java.lang.Object implements android.widget.SearchView.OnQueryTextListener {
|
||||
constructor(private owner: WeakRef<SearchBar>) {
|
||||
super();
|
||||
return global.__native(this);
|
||||
interface QueryTextListener {
|
||||
new (owner: SearchBar): android.widget.SearchView.OnQueryTextListener;
|
||||
}
|
||||
|
||||
interface CloseListener {
|
||||
new (owner: SearchBar): android.widget.SearchView.OnCloseListener;
|
||||
}
|
||||
|
||||
let QueryTextListener: QueryTextListener;
|
||||
let CloseListener: CloseListener;
|
||||
|
||||
function initializeNativeClasses(): void {
|
||||
if (QueryTextListener) {
|
||||
return;
|
||||
}
|
||||
|
||||
onQueryTextChange(newText: string): boolean {
|
||||
let owner = this.owner.get();
|
||||
if (owner) {
|
||||
@Interfaces([android.widget.SearchView.OnQueryTextListener])
|
||||
class QueryTextListenerImpl extends java.lang.Object implements android.widget.SearchView.OnQueryTextListener {
|
||||
constructor(private owner: SearchBar) {
|
||||
super();
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
onQueryTextChange(newText: string): boolean {
|
||||
const owner = this.owner;
|
||||
textProperty.nativeValueChange(owner, newText);
|
||||
|
||||
// This code is needed since sometimes OnCloseListener is not called!
|
||||
@@ -27,37 +42,36 @@ class QueryTextListener extends java.lang.Object implements android.widget.Searc
|
||||
}
|
||||
|
||||
this[SEARCHTEXT] = newText;
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
onQueryTextSubmit(query: string): boolean {
|
||||
let owner = this.owner.get();
|
||||
if (owner) {
|
||||
onQueryTextSubmit(query: string): boolean {
|
||||
const owner = this.owner;
|
||||
// This code is needed since onQueryTextSubmit is called twice with same query!
|
||||
if (query !== "" && this[QUERY] !== query) {
|
||||
owner._emit(SearchBarBase.submitEvent);
|
||||
}
|
||||
|
||||
this[QUERY] = query;
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Interfaces([android.widget.SearchView.OnCloseListener])
|
||||
class CloseListener extends java.lang.Object implements android.widget.SearchView.OnCloseListener {
|
||||
constructor(private owner: WeakRef<SearchBar>) {
|
||||
super();
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
onClose(): boolean {
|
||||
let owner = this.owner.get();
|
||||
if (owner) {
|
||||
owner._emit(SearchBarBase.clearEvent);
|
||||
@Interfaces([android.widget.SearchView.OnCloseListener])
|
||||
class CloseListenerImpl extends java.lang.Object implements android.widget.SearchView.OnCloseListener {
|
||||
constructor(private owner: SearchBar) {
|
||||
super();
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
onClose(): boolean {
|
||||
this.owner._emit(SearchBarBase.clearEvent);
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
QueryTextListener = QueryTextListenerImpl;
|
||||
CloseListener = CloseListenerImpl;
|
||||
}
|
||||
|
||||
export class SearchBar extends SearchBarBase {
|
||||
@@ -79,14 +93,15 @@ export class SearchBar extends SearchBarBase {
|
||||
}
|
||||
|
||||
public _createNativeView() {
|
||||
initializeNativeClasses();
|
||||
this._android = new android.widget.SearchView(this._context);
|
||||
|
||||
this._android.setIconified(false);
|
||||
|
||||
this._queryTextListener = this._queryTextListener || new QueryTextListener(new WeakRef(this));
|
||||
this._queryTextListener = this._queryTextListener || new QueryTextListener(this);
|
||||
this._android.setOnQueryTextListener(this._queryTextListener);
|
||||
|
||||
this._closeListener = this._closeListener || new CloseListener(new WeakRef(this));
|
||||
this._closeListener = this._closeListener || new CloseListener(this);
|
||||
this._android.setOnCloseListener(this._closeListener);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,40 +10,77 @@ const R_ID_TABCONTENT = 0x01020011;
|
||||
const R_ATTR_STATE_SELECTED = 0x010100a1;
|
||||
const TITLE_TEXT_VIEW_ID = 16908310; // http://developer.android.com/reference/android/R.id.html#title
|
||||
|
||||
interface TabChangeListener {
|
||||
new (owner: SegmentedBar): android.widget.TabHost.OnTabChangeListener;
|
||||
}
|
||||
|
||||
interface TabContentFactory {
|
||||
new (owner: SegmentedBar): android.widget.TabHost.TabContentFactory;
|
||||
}
|
||||
|
||||
interface TabHost {
|
||||
new (context: android.content.Context, attrs: android.util.AttributeSet): android.widget.TabHost;
|
||||
}
|
||||
|
||||
let apiLevel: number;
|
||||
// TODO: Move this into widgets.
|
||||
let SegmentedBarColorDrawableClass;
|
||||
function ensureSegmentedBarColorDrawableClass() {
|
||||
if (SegmentedBarColorDrawableClass) {
|
||||
|
||||
let TabHost: TabHost;
|
||||
let TabChangeListener: TabChangeListener;
|
||||
let TabContentFactory: TabContentFactory;
|
||||
|
||||
function initializeNativeClasses(): void {
|
||||
if (TabChangeListener) {
|
||||
return;
|
||||
}
|
||||
|
||||
apiLevel = android.os.Build.VERSION.SDK_INT;
|
||||
|
||||
class SegmentedBarColorDrawable extends android.graphics.drawable.ColorDrawable {
|
||||
constructor(arg: any) {
|
||||
super(arg);
|
||||
|
||||
@Interfaces([android.widget.TabHost.OnTabChangeListener])
|
||||
class TabChangeListenerImpl extends java.lang.Object implements android.widget.TabHost.OnTabChangeListener {
|
||||
constructor(private owner: SegmentedBar) {
|
||||
super();
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
public draw(canvas: android.graphics.Canvas): void {
|
||||
let p = new android.graphics.Paint();
|
||||
p.setColor(this.getColor());
|
||||
p.setStyle(android.graphics.Paint.Style.FILL);
|
||||
canvas.drawRect(0, this.getBounds().height() - 15, this.getBounds().width(), this.getBounds().height(), p);
|
||||
onTabChanged(id: string): void {
|
||||
const owner = this.owner;
|
||||
if (owner.shouldChangeSelectedIndex()) {
|
||||
owner.selectedIndex = parseInt(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SegmentedBarColorDrawableClass = SegmentedBarColorDrawable;
|
||||
}
|
||||
@Interfaces([android.widget.TabHost.TabContentFactory])
|
||||
class TabContentFactoryImpl extends java.lang.Object implements android.widget.TabHost.TabContentFactory {
|
||||
constructor(private owner: SegmentedBar) {
|
||||
super();
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
function setBackground(view: android.view.View, background: android.graphics.drawable.Drawable): void {
|
||||
if (apiLevel >= 16) {
|
||||
view.setBackground(background);
|
||||
} else {
|
||||
view.setBackgroundDrawable(background);
|
||||
createTabContent(tag: string): android.view.View {
|
||||
const tv = new android.widget.TextView(this.owner._context);
|
||||
// This is collapsed by default and made visible
|
||||
// by android when TabItem becomes visible/selected.
|
||||
// TODO: Try commenting visibility change.
|
||||
tv.setVisibility(android.view.View.GONE);
|
||||
tv.setMaxLines(1);
|
||||
tv.setEllipsize(android.text.TextUtils.TruncateAt.END);
|
||||
return tv;
|
||||
}
|
||||
}
|
||||
|
||||
class TabHostImpl extends android.widget.TabHost {
|
||||
constructor(context: android.content.Context, attrs: android.util.AttributeSet) {
|
||||
super(context, attrs);
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
protected onAttachedToWindow(): void {
|
||||
// overriden to remove the code that will steal the focus from edit fields.
|
||||
}
|
||||
}
|
||||
|
||||
TabHost = TabHostImpl;
|
||||
TabChangeListener = TabChangeListenerImpl;
|
||||
TabContentFactory = TabContentFactoryImpl;
|
||||
}
|
||||
|
||||
export class SegmentedBarItem extends SegmentedBarItemBase {
|
||||
@@ -122,59 +159,20 @@ export class SegmentedBarItem extends SegmentedBarItemBase {
|
||||
if (apiLevel > 21 && backgroundDrawable && typeof backgroundDrawable.setColorFilter === "function") {
|
||||
const newDrawable = backgroundDrawable.getConstantState().newDrawable();
|
||||
newDrawable.setColorFilter(color, android.graphics.PorterDuff.Mode.SRC_IN);
|
||||
setBackground(viewGroup, newDrawable);
|
||||
org.nativescript.widgets.ViewHelper.setBackground(viewGroup, newDrawable);
|
||||
} else {
|
||||
const stateDrawable = new android.graphics.drawable.StateListDrawable();
|
||||
|
||||
let arr = Array.create("int", 1);
|
||||
arr[0] = R_ATTR_STATE_SELECTED;
|
||||
let colorDrawable: android.graphics.drawable.ColorDrawable = new SegmentedBarColorDrawableClass(color);
|
||||
let colorDrawable: android.graphics.drawable.ColorDrawable = new org.nativescript.widgets.SegmentedBarColorDrawable(color);
|
||||
stateDrawable.addState(arr, colorDrawable);
|
||||
stateDrawable.setBounds(0, 15, viewGroup.getRight(), viewGroup.getBottom());
|
||||
|
||||
setBackground(viewGroup, stateDrawable);
|
||||
|
||||
org.nativescript.widgets.ViewHelper.setBackground(viewGroup, stateDrawable);
|
||||
}
|
||||
} else {
|
||||
setBackground(viewGroup, value.newDrawable());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Interfaces([android.widget.TabHost.OnTabChangeListener])
|
||||
class TabChangeListener extends java.lang.Object implements android.widget.TabHost.OnTabChangeListener {
|
||||
constructor(private owner: WeakRef<SegmentedBar>) {
|
||||
super();
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
onTabChanged(id: string): void {
|
||||
let owner = this.owner.get();
|
||||
if (owner && owner.shouldChangeSelectedIndex()) {
|
||||
owner.selectedIndex = parseInt(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Interfaces([android.widget.TabHost.TabContentFactory])
|
||||
class TabContentFactory extends java.lang.Object implements android.widget.TabHost.TabContentFactory {
|
||||
constructor(private owner: WeakRef<SegmentedBar>) {
|
||||
super();
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
createTabContent(tag: string): android.view.View {
|
||||
let owner = this.owner.get();
|
||||
if (owner) {
|
||||
let tv = new android.widget.TextView(owner._context);
|
||||
// This is collapsed by default and made visible
|
||||
// by android when TabItem becomes visible/selected.
|
||||
// TODO: Try commenting visibility change.
|
||||
tv.setVisibility(android.view.View.GONE);
|
||||
tv.setMaxLines(1);
|
||||
tv.setEllipsize(android.text.TextUtils.TruncateAt.END);
|
||||
return tv;
|
||||
} else {
|
||||
throw new Error(`Invalid owner: ${this.owner}`);
|
||||
org.nativescript.widgets.ViewHelper.setBackground(viewGroup, value.newDrawable());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -190,14 +188,12 @@ export class SegmentedBar extends SegmentedBarBase {
|
||||
}
|
||||
|
||||
public _createNativeView() {
|
||||
ensureTabHostClass();
|
||||
ensureSegmentedBarColorDrawableClass();
|
||||
initializeNativeClasses();
|
||||
|
||||
let weakRef = new WeakRef(this);
|
||||
this._android = new TabHostClass(this._context, null);
|
||||
this._android = new TabHost(this._context, null);
|
||||
|
||||
this.listener = this.listener || new TabChangeListener(weakRef);
|
||||
this.tabContentFactory = this.tabContentFactory || new TabContentFactory(weakRef);
|
||||
this.listener = this.listener || new TabChangeListener(this);
|
||||
this.tabContentFactory = this.tabContentFactory || new TabContentFactory(this);
|
||||
|
||||
const tabHostLayout = new android.widget.LinearLayout(this._context);
|
||||
tabHostLayout.setOrientation(android.widget.LinearLayout.VERTICAL);
|
||||
@@ -251,24 +247,3 @@ export class SegmentedBar extends SegmentedBarBase {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let TabHostClass;
|
||||
function ensureTabHostClass() {
|
||||
if (TabHostClass) {
|
||||
return;
|
||||
}
|
||||
|
||||
class OurTabHost extends android.widget.TabHost {
|
||||
constructor(context: any, attrs: any) {
|
||||
super(context, attrs);
|
||||
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
protected onAttachedToWindow(): void {
|
||||
// overriden to remove the code that will steal the focus from edit fields.
|
||||
}
|
||||
}
|
||||
|
||||
TabHostClass = OurTabHost;
|
||||
}
|
||||
|
||||
@@ -6,30 +6,42 @@
|
||||
|
||||
export * from "./slider-common";
|
||||
|
||||
@Interfaces([android.widget.SeekBar.OnSeekBarChangeListener])
|
||||
class SeekBarChangeListener extends java.lang.Object implements android.widget.SeekBar.OnSeekBarChangeListener {
|
||||
constructor(private owner: WeakRef<Slider>) {
|
||||
super();
|
||||
return global.__native(this);
|
||||
interface SeekBarChangeListener {
|
||||
new (owner: Slider): android.widget.SeekBar.OnSeekBarChangeListener;
|
||||
}
|
||||
|
||||
let SeekBarChangeListener: SeekBarChangeListener;
|
||||
|
||||
function initializeSeekBarChangeListener(): void {
|
||||
if (SeekBarChangeListener) {
|
||||
return;
|
||||
}
|
||||
|
||||
onProgressChanged(seekBar: android.widget.SeekBar, progress: number, fromUser: boolean): void {
|
||||
let owner = this.owner.get();
|
||||
if (owner) {
|
||||
if (!owner._supressNativeValue) {
|
||||
let newValue: number = seekBar.getProgress() + owner.minValue;
|
||||
valueProperty.nativeValueChange(owner, newValue);
|
||||
}
|
||||
@Interfaces([android.widget.SeekBar.OnSeekBarChangeListener])
|
||||
class SeekBarChangeListenerImpl extends java.lang.Object implements android.widget.SeekBar.OnSeekBarChangeListener {
|
||||
constructor(private owner: Slider) {
|
||||
super();
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
onProgressChanged(seekBar: android.widget.SeekBar, progress: number, fromUser: boolean): void {
|
||||
const owner = this.owner;
|
||||
if (!owner._supressNativeValue) {
|
||||
let newValue: number = seekBar.getProgress() + owner.minValue;
|
||||
valueProperty.nativeValueChange(owner, newValue);
|
||||
}
|
||||
}
|
||||
|
||||
onStartTrackingTouch(seekBar: android.widget.SeekBar): void {
|
||||
//
|
||||
}
|
||||
|
||||
onStopTrackingTouch(seekBar: android.widget.SeekBar): void {
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
onStartTrackingTouch(seekBar: android.widget.SeekBar): void {
|
||||
//
|
||||
}
|
||||
|
||||
onStopTrackingTouch(seekBar: android.widget.SeekBar): void {
|
||||
//
|
||||
}
|
||||
SeekBarChangeListener = SeekBarChangeListenerImpl;
|
||||
}
|
||||
|
||||
export class Slider extends SliderBase {
|
||||
@@ -38,7 +50,8 @@ export class Slider extends SliderBase {
|
||||
private changeListener: android.widget.SeekBar.OnSeekBarChangeListener;
|
||||
|
||||
public _createNativeView() {
|
||||
this.changeListener = this.changeListener || new SeekBarChangeListener(new WeakRef(this));
|
||||
initializeSeekBarChangeListener();
|
||||
this.changeListener = this.changeListener || new SeekBarChangeListener(this);
|
||||
this._android = new android.widget.SeekBar(this._context);
|
||||
this._android.setOnSeekBarChangeListener(this.changeListener);
|
||||
}
|
||||
|
||||
@@ -72,32 +72,26 @@ export module ad {
|
||||
refreshBorderDrawable(view, <org.nativescript.widgets.BorderDrawable>backgroundDrawable);
|
||||
}
|
||||
|
||||
// This should be done only when backgroundImage is set!!!
|
||||
if ((background.hasBorderWidth() || background.hasBorderRadius() || background.clipPath) && getSDK() < 18) {
|
||||
// Switch to software because of unsupported canvas methods if hardware acceleration is on:
|
||||
// http://developer.android.com/guide/topics/graphics/hardware-accel.html
|
||||
cache.layerType = cache.getLayerType();
|
||||
cache.setLayerType(android.view.View.LAYER_TYPE_SOFTWARE, null);
|
||||
if (cache.layerType === undefined) {
|
||||
cache.layerType = cache.getLayerType();
|
||||
cache.setLayerType(android.view.View.LAYER_TYPE_SOFTWARE, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// reset the value with the default native value
|
||||
if (nativeView instanceof android.widget.Button) {
|
||||
let nativeButton = new android.widget.Button(nativeView.getContext());
|
||||
|
||||
if (getSDK() >= 16) {
|
||||
nativeView.setBackground(nativeButton.getBackground());
|
||||
} else {
|
||||
nativeView.setBackgroundDrawable(nativeButton.getBackground());
|
||||
}
|
||||
org.nativescript.widgets.ViewHelper.setBackground(nativeView, nativeButton.getBackground());
|
||||
}
|
||||
else {
|
||||
let viewClass = getClass(view);
|
||||
if (_defaultBackgrounds.has(viewClass)) {
|
||||
if (getSDK() >= 16) {
|
||||
nativeView.setBackground(_defaultBackgrounds.get(viewClass));
|
||||
} else {
|
||||
nativeView.setBackgroundDrawable(_defaultBackgrounds.get(viewClass));
|
||||
}
|
||||
org.nativescript.widgets.ViewHelper.setBackground(nativeView, _defaultBackgrounds.get(viewClass));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,19 +4,31 @@
|
||||
|
||||
export * from "./switch-common";
|
||||
|
||||
@Interfaces([android.widget.CompoundButton.OnCheckedChangeListener])
|
||||
class CheckedChangeListener extends java.lang.Object implements android.widget.CompoundButton.OnCheckedChangeListener {
|
||||
constructor(private owner: WeakRef<Switch>) {
|
||||
super();
|
||||
return global.__native(this);
|
||||
interface CheckedChangeListener {
|
||||
new (owner: Switch): android.widget.CompoundButton.OnCheckedChangeListener;
|
||||
}
|
||||
|
||||
let CheckedChangeListener: CheckedChangeListener;
|
||||
|
||||
function initializeCheckedChangeListener(): void {
|
||||
if (CheckedChangeListener) {
|
||||
return;
|
||||
}
|
||||
|
||||
onCheckedChanged(buttonView: android.widget.CompoundButton, isChecked: boolean): void {
|
||||
let owner = this.owner.get();
|
||||
if (owner) {
|
||||
@Interfaces([android.widget.CompoundButton.OnCheckedChangeListener])
|
||||
class CheckedChangeListenerImpl extends java.lang.Object implements android.widget.CompoundButton.OnCheckedChangeListener {
|
||||
constructor(private owner: Switch) {
|
||||
super();
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
onCheckedChanged(buttonView: android.widget.CompoundButton, isChecked: boolean): void {
|
||||
const owner = this.owner;
|
||||
checkedProperty.nativeValueChange(owner, isChecked);
|
||||
}
|
||||
}
|
||||
|
||||
CheckedChangeListener = CheckedChangeListenerImpl;
|
||||
}
|
||||
|
||||
export class Switch extends SwitchBase {
|
||||
@@ -29,8 +41,9 @@ export class Switch extends SwitchBase {
|
||||
}
|
||||
|
||||
public _createNativeView() {
|
||||
initializeCheckedChangeListener();
|
||||
this._android = new android.widget.Switch(this._context);
|
||||
this.listener = this.listener || new CheckedChangeListener(new WeakRef(this));
|
||||
this.listener = this.listener || new CheckedChangeListener(this);
|
||||
this._android.setOnCheckedChangeListener(this.listener);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,70 +16,23 @@ const ACCENT_COLOR = "colorAccent";
|
||||
const PRIMARY_COLOR = "colorPrimary";
|
||||
const DEFAULT_ELEVATION = 4;
|
||||
|
||||
let defaultAccentColor: number = undefined;
|
||||
function getDefaultAccentColor(context: android.content.Context): number {
|
||||
if (defaultAccentColor === undefined) {
|
||||
//Fallback color: https://developer.android.com/samples/SlidingTabsColors/src/com.example.android.common/view/SlidingTabStrip.html
|
||||
defaultAccentColor = ad.resources.getPalleteColor(ACCENT_COLOR, context) || 0xFF33B5E5;
|
||||
}
|
||||
return defaultAccentColor;
|
||||
interface PagerAdapter {
|
||||
new (owner: TabView, items: Array<TabViewItem>): android.support.v4.view.PagerAdapter;
|
||||
}
|
||||
|
||||
export class TabViewItem extends TabViewItemBase {
|
||||
public nativeView: android.widget.TextView;
|
||||
public tabItemSpec: org.nativescript.widgets.TabItemSpec;
|
||||
public index: number;
|
||||
|
||||
public setNativeView(textView: android.widget.TextView): void {
|
||||
this.nativeView = textView;
|
||||
if (textView) {
|
||||
initNativeView(this);
|
||||
}
|
||||
}
|
||||
|
||||
public _update(): void {
|
||||
const tv = this.nativeView;
|
||||
if (tv) {
|
||||
const tabLayout = <org.nativescript.widgets.TabLayout>tv.getParent();
|
||||
tabLayout.updateItemAt(this.index, this.tabItemSpec);
|
||||
}
|
||||
}
|
||||
|
||||
get [fontSizeProperty.native](): { nativeSize: number } {
|
||||
return { nativeSize: this.nativeView.getTextSize() };
|
||||
}
|
||||
set [fontSizeProperty.native](value: number | { nativeSize: number }) {
|
||||
if (typeof value === "number") {
|
||||
this.nativeView.setTextSize(value);
|
||||
} else {
|
||||
this.nativeView.setTextSize(android.util.TypedValue.COMPLEX_UNIT_PX, value.nativeSize);
|
||||
}
|
||||
}
|
||||
|
||||
get [fontInternalProperty.native](): android.graphics.Typeface {
|
||||
return this.nativeView.getTypeface();
|
||||
}
|
||||
set [fontInternalProperty.native](value: Font | android.graphics.Typeface) {
|
||||
this.nativeView.setTypeface(value instanceof Font ? value.getAndroidTypeface() : value);
|
||||
}
|
||||
|
||||
get [textTransformProperty.native](): TextTransform {
|
||||
return "none";
|
||||
}
|
||||
set [textTransformProperty.native](value: TextTransform) {
|
||||
const tv = this.nativeView;
|
||||
const result = getTransformedText(this.title, value);
|
||||
tv.setText(result);
|
||||
}
|
||||
interface PageChangedListener {
|
||||
new (owner: TabView): android.support.v4.view.ViewPager.SimpleOnPageChangeListener;
|
||||
}
|
||||
|
||||
let PagerAdapterClass;
|
||||
function ensurePagerAdapterClass() {
|
||||
if (PagerAdapterClass) {
|
||||
let PagerAdapter: PagerAdapter;
|
||||
let PageChangedListener: PageChangedListener;
|
||||
|
||||
function initializeNativeClasses() {
|
||||
if (PagerAdapter) {
|
||||
return;
|
||||
}
|
||||
|
||||
class PagerAdapterClassInner extends android.support.v4.view.PagerAdapter {
|
||||
class PagerAdapterImpl extends android.support.v4.view.PagerAdapter {
|
||||
private owner: TabView;
|
||||
private items: Array<TabViewItem>;
|
||||
|
||||
@@ -160,8 +113,8 @@ function ensurePagerAdapterClass() {
|
||||
traceWrite("TabView.PagerAdapter.saveState", traceCategory);
|
||||
}
|
||||
|
||||
let owner: TabView = this.owner;
|
||||
if (!owner || owner._childrenCount === 0) {
|
||||
const owner: TabView = this.owner;
|
||||
if (owner._childrenCount === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -194,16 +147,7 @@ function ensurePagerAdapterClass() {
|
||||
}
|
||||
};
|
||||
|
||||
PagerAdapterClass = PagerAdapterClassInner;
|
||||
}
|
||||
|
||||
let PageChangedListenerClass;
|
||||
function ensurePageChangedListenerClass() {
|
||||
if (PageChangedListenerClass) {
|
||||
return;
|
||||
}
|
||||
|
||||
class PageChangedListener extends android.support.v4.view.ViewPager.SimpleOnPageChangeListener {
|
||||
class PageChangedListenerImpl extends android.support.v4.view.ViewPager.SimpleOnPageChangeListener {
|
||||
private _owner: TabView;
|
||||
constructor(owner: TabView) {
|
||||
super();
|
||||
@@ -216,7 +160,8 @@ function ensurePageChangedListenerClass() {
|
||||
}
|
||||
}
|
||||
|
||||
PageChangedListenerClass = PageChangedListener;
|
||||
PagerAdapter = PagerAdapterImpl;
|
||||
PageChangedListener = PageChangedListenerImpl;
|
||||
}
|
||||
|
||||
function createTabItemSpec(item: TabViewItem): org.nativescript.widgets.TabItemSpec {
|
||||
@@ -238,6 +183,63 @@ function createTabItemSpec(item: TabViewItem): org.nativescript.widgets.TabItemS
|
||||
return result;
|
||||
}
|
||||
|
||||
let defaultAccentColor: number = undefined;
|
||||
function getDefaultAccentColor(context: android.content.Context): number {
|
||||
if (defaultAccentColor === undefined) {
|
||||
//Fallback color: https://developer.android.com/samples/SlidingTabsColors/src/com.example.android.common/view/SlidingTabStrip.html
|
||||
defaultAccentColor = ad.resources.getPalleteColor(ACCENT_COLOR, context) || 0xFF33B5E5;
|
||||
}
|
||||
return defaultAccentColor;
|
||||
}
|
||||
|
||||
export class TabViewItem extends TabViewItemBase {
|
||||
public nativeView: android.widget.TextView;
|
||||
public tabItemSpec: org.nativescript.widgets.TabItemSpec;
|
||||
public index: number;
|
||||
|
||||
public setNativeView(textView: android.widget.TextView): void {
|
||||
this.nativeView = textView;
|
||||
if (textView) {
|
||||
initNativeView(this);
|
||||
}
|
||||
}
|
||||
|
||||
public _update(): void {
|
||||
const tv = this.nativeView;
|
||||
if (tv) {
|
||||
const tabLayout = <org.nativescript.widgets.TabLayout>tv.getParent();
|
||||
tabLayout.updateItemAt(this.index, this.tabItemSpec);
|
||||
}
|
||||
}
|
||||
|
||||
get [fontSizeProperty.native](): { nativeSize: number } {
|
||||
return { nativeSize: this.nativeView.getTextSize() };
|
||||
}
|
||||
set [fontSizeProperty.native](value: number | { nativeSize: number }) {
|
||||
if (typeof value === "number") {
|
||||
this.nativeView.setTextSize(value);
|
||||
} else {
|
||||
this.nativeView.setTextSize(android.util.TypedValue.COMPLEX_UNIT_PX, value.nativeSize);
|
||||
}
|
||||
}
|
||||
|
||||
get [fontInternalProperty.native](): android.graphics.Typeface {
|
||||
return this.nativeView.getTypeface();
|
||||
}
|
||||
set [fontInternalProperty.native](value: Font | android.graphics.Typeface) {
|
||||
this.nativeView.setTypeface(value instanceof Font ? value.getAndroidTypeface() : value);
|
||||
}
|
||||
|
||||
get [textTransformProperty.native](): TextTransform {
|
||||
return "none";
|
||||
}
|
||||
set [textTransformProperty.native](value: TextTransform) {
|
||||
const tv = this.nativeView;
|
||||
const result = getTransformedText(this.title, value);
|
||||
tv.setText(result);
|
||||
}
|
||||
}
|
||||
|
||||
export class TabView extends TabViewBase {
|
||||
private _grid: org.nativescript.widgets.GridLayout;
|
||||
private _tabLayout: org.nativescript.widgets.TabLayout;
|
||||
@@ -264,6 +266,7 @@ export class TabView extends TabViewBase {
|
||||
}
|
||||
|
||||
public _createNativeView() {
|
||||
initializeNativeClasses();
|
||||
if (traceEnabled()) {
|
||||
traceWrite("TabView._createUI(" + this + ");", traceCategory);
|
||||
}
|
||||
@@ -298,8 +301,7 @@ export class TabView extends TabViewBase {
|
||||
this._viewPager.setLayoutParams(lp);
|
||||
this._grid.addView(this._viewPager);
|
||||
|
||||
ensurePageChangedListenerClass();
|
||||
this._pageChagedListener = new PageChangedListenerClass(this);
|
||||
this._pageChagedListener = new PageChangedListener(this);
|
||||
(<any>this._viewPager).addOnPageChangeListener(this._pageChagedListener);
|
||||
this.nativeView = this._viewPager;
|
||||
this._nativeView = this._viewPager;
|
||||
@@ -331,9 +333,8 @@ export class TabView extends TabViewBase {
|
||||
tabItems.push(tabItemSpec);
|
||||
});
|
||||
|
||||
ensurePagerAdapterClass();
|
||||
// TODO: optimize by reusing the adapter and calling setAdapter(null) then the same adapter.
|
||||
this._pagerAdapter = new PagerAdapterClass(this, items);
|
||||
this._pagerAdapter = new PagerAdapter(this, items);
|
||||
this._viewPager.setAdapter(this._pagerAdapter);
|
||||
|
||||
const tabLayout = this._tabLayout;
|
||||
|
||||
@@ -331,8 +331,7 @@ function setSpanModifiers(ssb: android.text.SpannableStringBuilder, span: Span,
|
||||
const fontFamily = span.fontFamily;
|
||||
if (fontFamily) {
|
||||
const font = new Font(fontFamily, 0, (italic) ? "italic" : "normal", (bold) ? "bold" : "normal");
|
||||
ensureCustomTypefaceSpanClass();
|
||||
const typefaceSpan: android.text.style.TypefaceSpan = new CustomTypefaceSpanClass(fontFamily, font.getAndroidTypeface());
|
||||
const typefaceSpan: android.text.style.TypefaceSpan = new org.nativescript.widgets.CustomTypefaceSpan(fontFamily, font.getAndroidTypeface());
|
||||
ssb.setSpan(typefaceSpan, start, end, android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
|
||||
@@ -375,49 +374,4 @@ function setSpanModifiers(ssb: android.text.SpannableStringBuilder, span: Span,
|
||||
ssb.setSpan(new android.text.style.StrikethroughSpan(), start, end, android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var CustomTypefaceSpanClass;
|
||||
function ensureCustomTypefaceSpanClass() {
|
||||
if (CustomTypefaceSpanClass) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Move this class in widgets.
|
||||
class CustomTypefaceSpan extends android.text.style.TypefaceSpan {
|
||||
private typeface: android.graphics.Typeface;
|
||||
|
||||
constructor(family: string, typeface: android.graphics.Typeface) {
|
||||
super(family);
|
||||
this.typeface = typeface;
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
public updateDrawState(ds: android.text.TextPaint): void {
|
||||
this.applyCustomTypeFace(ds);
|
||||
}
|
||||
|
||||
public updateMeasureState(paint: android.text.TextPaint): void {
|
||||
this.applyCustomTypeFace(paint);
|
||||
}
|
||||
|
||||
private applyCustomTypeFace(paint: android.text.TextPaint) {
|
||||
const old = paint.getTypeface();
|
||||
const oldStyle = old === null ? 0 : old.getStyle();
|
||||
|
||||
const typeface = this.typeface;
|
||||
let fake = oldStyle & ~typeface.getStyle();
|
||||
if ((fake & android.graphics.Typeface.BOLD) !== 0) {
|
||||
paint.setFakeBoldText(true);
|
||||
}
|
||||
|
||||
if ((fake & android.graphics.Typeface.ITALIC) !== 0) {
|
||||
paint.setTextSkewX(-0.25);
|
||||
}
|
||||
|
||||
paint.setTypeface(typeface);
|
||||
}
|
||||
}
|
||||
|
||||
CustomTypefaceSpanClass = CustomTypefaceSpan;
|
||||
}
|
||||
@@ -2,21 +2,33 @@
|
||||
|
||||
export * from "./time-picker-common";
|
||||
|
||||
@Interfaces([android.widget.TimePicker.OnTimeChangedListener])
|
||||
class TimeChangedListener extends java.lang.Object implements android.widget.TimePicker.OnTimeChangedListener {
|
||||
constructor(public owner: WeakRef<TimePicker>) {
|
||||
super();
|
||||
return global.__native(this);
|
||||
interface TimeChangedListener {
|
||||
new (owner: TimePicker): android.widget.TimePicker.OnTimeChangedListener;
|
||||
}
|
||||
|
||||
let TimeChangedListener: TimeChangedListener;
|
||||
|
||||
function initializeTimeChangedListener(): void {
|
||||
if (TimeChangedListener) {
|
||||
return;
|
||||
}
|
||||
|
||||
onTimeChanged(picker: android.widget.TimePicker, hour: number, minute: number): void {
|
||||
let timePicker = this.owner.get();
|
||||
if (timePicker) {
|
||||
@Interfaces([android.widget.TimePicker.OnTimeChangedListener])
|
||||
class TimeChangedListenerImpl extends java.lang.Object implements android.widget.TimePicker.OnTimeChangedListener {
|
||||
constructor(public owner: TimePicker) {
|
||||
super();
|
||||
return global.__native(this);
|
||||
}
|
||||
|
||||
onTimeChanged(picker: android.widget.TimePicker, hour: number, minute: number): void {
|
||||
const timePicker = this.owner;
|
||||
let validTime = getValidTime(timePicker, hour, minute);
|
||||
timePicker._setNativeValueSilently(validTime.hour, validTime.minute);
|
||||
timeProperty.nativeValueChange(timePicker, new Date(0, 0, 0, validTime.hour, validTime.minute));
|
||||
}
|
||||
}
|
||||
|
||||
TimeChangedListener = TimeChangedListenerImpl;
|
||||
}
|
||||
|
||||
export class TimePicker extends TimePickerBase {
|
||||
@@ -24,8 +36,9 @@ export class TimePicker extends TimePickerBase {
|
||||
private _listener: android.widget.TimePicker.OnTimeChangedListener;
|
||||
|
||||
public _createNativeView() {
|
||||
initializeTimeChangedListener();
|
||||
this._android = new android.widget.TimePicker(this._context);
|
||||
this._listener = this._listener || new TimeChangedListener(new WeakRef(this));
|
||||
this._listener = this._listener || new TimeChangedListener(this);
|
||||
this._android.setOnTimeChangedListener(this._listener);
|
||||
|
||||
let c = java.util.Calendar.getInstance();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
export class FadeTransition extends Transition {
|
||||
public createAndroidAnimator(transitionType: string): android.animation.Animator {
|
||||
let alphaValues = Array.create("float", 2);
|
||||
const alphaValues = Array.create("float", 2);
|
||||
switch (transitionType) {
|
||||
case AndroidTransitionType.enter:
|
||||
case AndroidTransitionType.popEnter:
|
||||
@@ -15,11 +15,13 @@ export class FadeTransition extends Transition {
|
||||
alphaValues[1] = 0;
|
||||
break;
|
||||
}
|
||||
let animator = android.animation.ObjectAnimator.ofFloat(null, "alpha", alphaValues);
|
||||
let duration = this.getDuration();
|
||||
|
||||
const animator = android.animation.ObjectAnimator.ofFloat(null, "alpha", alphaValues);
|
||||
const duration = this.getDuration();
|
||||
if (duration !== undefined) {
|
||||
animator.setDuration(duration);
|
||||
}
|
||||
|
||||
animator.setInterpolator(this.getCurve());
|
||||
return animator;
|
||||
}
|
||||
|
||||
@@ -13,10 +13,10 @@ export class FlipTransition extends Transition {
|
||||
let objectAnimators;
|
||||
let values;
|
||||
let animator: android.animation.ObjectAnimator;
|
||||
let animatorSet = new android.animation.AnimatorSet();
|
||||
let fullDuration = this.getDuration() || 300;
|
||||
let interpolator = this.getCurve();
|
||||
let rotationY = this._direction === "right" ? 180 : -180;
|
||||
const animatorSet = new android.animation.AnimatorSet();
|
||||
const fullDuration = this.getDuration() || 300;
|
||||
const interpolator = this.getCurve();
|
||||
const rotationY = this._direction === "right" ? 180 : -180;
|
||||
|
||||
switch (transitionType) {
|
||||
case AndroidTransitionType.enter: // card_flip_right_in
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
import * as platform from "platform";
|
||||
import lazy from "utils/lazy";
|
||||
|
||||
let screenWidth = lazy(() => platform.screen.mainScreen.widthPixels);
|
||||
let screenHeight = lazy(() => platform.screen.mainScreen.heightPixels);
|
||||
const screenWidth = lazy(() => platform.screen.mainScreen.widthPixels);
|
||||
const screenHeight = lazy(() => platform.screen.mainScreen.heightPixels);
|
||||
|
||||
export class SlideTransition extends transition.Transition {
|
||||
private _direction: string;
|
||||
@@ -14,7 +14,7 @@ export class SlideTransition extends transition.Transition {
|
||||
}
|
||||
|
||||
public createAndroidAnimator(transitionType: string): android.animation.Animator {
|
||||
let translationValues = Array.create("float", 2);
|
||||
const translationValues = Array.create("float", 2);
|
||||
switch (this._direction) {
|
||||
case "left":
|
||||
switch (transitionType) {
|
||||
@@ -105,8 +105,8 @@ export class SlideTransition extends transition.Transition {
|
||||
prop = "translationY";
|
||||
}
|
||||
|
||||
let animator = android.animation.ObjectAnimator.ofFloat(null, prop, translationValues);
|
||||
let duration = this.getDuration();
|
||||
const animator = android.animation.ObjectAnimator.ofFloat(null, prop, translationValues);
|
||||
const duration = this.getDuration();
|
||||
if (duration !== undefined) {
|
||||
animator.setDuration(duration);
|
||||
}
|
||||
|
||||
@@ -45,10 +45,10 @@ interface ExpandedFragment {
|
||||
isDestroyed: boolean;
|
||||
}
|
||||
|
||||
let enterFakeResourceId = -10;
|
||||
let exitFakeResourceId = -20;
|
||||
let popEnterFakeResourceId = -30;
|
||||
let popExitFakeResourceId = -40;
|
||||
const enterFakeResourceId = -10;
|
||||
const exitFakeResourceId = -20;
|
||||
const popEnterFakeResourceId = -30;
|
||||
const popExitFakeResourceId = -40;
|
||||
|
||||
export module AndroidTransitionType {
|
||||
export const enter: string = "enter";
|
||||
|
||||
@@ -2,13 +2,18 @@ import { WebViewBase, knownFolders, traceEnabled, traceWrite, traceCategories }
|
||||
|
||||
export * from "./web-view-common";
|
||||
|
||||
let WebViewClientClass;
|
||||
function ensureWebViewClientClass() {
|
||||
if (WebViewClientClass) {
|
||||
interface WebViewClient {
|
||||
new (owner: WebView): android.webkit.WebViewClient;
|
||||
}
|
||||
|
||||
let WebViewClient: WebViewClient;
|
||||
|
||||
function initializeWebViewClient(): void {
|
||||
if (WebViewClient) {
|
||||
return;
|
||||
}
|
||||
|
||||
class WebViewClientClassInner extends android.webkit.WebViewClient {
|
||||
class WebViewClientImpl extends android.webkit.WebViewClient {
|
||||
private _view: WebViewBase;
|
||||
|
||||
constructor(view: WebViewBase) {
|
||||
@@ -79,25 +84,20 @@ function ensureWebViewClientClass() {
|
||||
}
|
||||
};
|
||||
|
||||
WebViewClientClass = WebViewClientClassInner;
|
||||
WebViewClient = WebViewClientImpl;
|
||||
}
|
||||
|
||||
export class WebView extends WebViewBase {
|
||||
private _android: android.webkit.WebView;
|
||||
private _webViewClient: android.webkit.WebViewClient;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
ensureWebViewClientClass();
|
||||
this._webViewClient = new WebViewClientClass(this);
|
||||
}
|
||||
|
||||
get android(): android.webkit.WebView {
|
||||
return this._android;
|
||||
}
|
||||
|
||||
public _createNativeView() {
|
||||
initializeWebViewClient();
|
||||
this._webViewClient = new WebViewClient(this);
|
||||
this._android = new android.webkit.WebView(this._context);
|
||||
this._android.getSettings().setJavaScriptEnabled(true);
|
||||
this._android.getSettings().setBuiltInZoomControls(true);
|
||||
|
||||
@@ -490,7 +490,19 @@
|
||||
public static getLetterspacing(view: android.view.View): number;
|
||||
public static setLetterspacing(view: android.view.View, value: number): void;
|
||||
|
||||
public static setBackground(view: android.view.View, background: android.graphics.drawable.Drawable): void;
|
||||
}
|
||||
|
||||
export class DisableUserInteractionListener extends java.lang.Object implements android.view.View.OnTouchListener {
|
||||
public onTouch(view: android.view.View, motionEvent: android.view.MotionEvent): boolean;
|
||||
}
|
||||
|
||||
export class SegmentedBarColorDrawable extends android.graphics.drawable.ColorDrawable {
|
||||
}
|
||||
|
||||
export class CustomTypefaceSpan extends android.text.style.TypefaceSpan {
|
||||
constructor(family: string, typeface: android.graphics.Typeface);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user