diff --git a/android/modules/ui/src/java/ti/modules/titanium/ui/TabGroupProxy.java b/android/modules/ui/src/java/ti/modules/titanium/ui/TabGroupProxy.java index 33c44342021..ccb9611a93c 100644 --- a/android/modules/ui/src/java/ti/modules/titanium/ui/TabGroupProxy.java +++ b/android/modules/ui/src/java/ti/modules/titanium/ui/TabGroupProxy.java @@ -1,6 +1,6 @@ /** * Appcelerator Titanium Mobile - * Copyright (c) 2009-2019 by Appcelerator, Inc. All Rights Reserved. + * Copyright (c) 2009-2021 by Axway, Inc. All Rights Reserved. * Licensed under the terms of the Apache Public License * Please see the LICENSE included with this distribution for details. */ @@ -11,9 +11,7 @@ import org.appcelerator.kroll.KrollDict; import org.appcelerator.kroll.annotations.Kroll; -import org.appcelerator.kroll.common.AsyncResult; import org.appcelerator.kroll.common.Log; -import org.appcelerator.kroll.common.TiMessenger; import org.appcelerator.titanium.TiActivity; import org.appcelerator.titanium.TiActivityWindow; import org.appcelerator.titanium.TiActivityWindows; @@ -22,6 +20,7 @@ import org.appcelerator.titanium.TiBlob; import org.appcelerator.titanium.TiC; import org.appcelerator.titanium.TiRootActivity; +import org.appcelerator.titanium.proxy.ActivityProxy; import org.appcelerator.titanium.proxy.TiWindowProxy; import org.appcelerator.titanium.util.TiConvert; import org.appcelerator.titanium.util.TiRHelper; @@ -34,7 +33,6 @@ import android.app.Activity; import android.content.Intent; -import android.os.Message; import android.os.Bundle; import androidx.annotation.NonNull; import androidx.appcompat.app.ActionBar; @@ -65,8 +63,8 @@ public class TabGroupProxy extends TiWindowProxy implements TiActivityWindow protected static final int MSG_LAST_ID = MSG_FIRST_ID + 999; - private ArrayList tabs = new ArrayList(); - private WeakReference tabGroupActivity; + private ArrayList tabs = new ArrayList<>(); + private WeakReference tabGroupActivity = new WeakReference<>(null); private TabProxy selectedTab; private String tabGroupTitle = null; private static int id_toolbar; @@ -78,51 +76,6 @@ public TabGroupProxy() defaultValues.put(TiC.PROPERTY_SMOOTH_SCROLL_ON_TAB_CLICK, true); } - @Override - public boolean handleMessage(Message msg) - { - switch (msg.what) { - case MSG_ADD_TAB: { - AsyncResult result = (AsyncResult) msg.obj; - handleAddTab((TabProxy) result.getArg()); - result.setResult(null); - return true; - } - case MSG_REMOVE_TAB: { - AsyncResult result = (AsyncResult) msg.obj; - handleRemoveTab((TabProxy) result.getArg()); - result.setResult(null); - return true; - } - case MSG_SET_ACTIVE_TAB: { - AsyncResult result = (AsyncResult) msg.obj; - handleSetActiveTab((TabProxy) result.getArg()); - result.setResult(null); - return true; - } - case MSG_GET_ACTIVE_TAB: { - AsyncResult result = (AsyncResult) msg.obj; - result.setResult(handleGetActiveTab()); - return true; - } - case MSG_SET_TABS: { - AsyncResult result = (AsyncResult) msg.obj; - handleSetTabs(result.getArg()); - result.setResult(null); - return true; - } - case MSG_DISABLE_TAB_NAVIGATION: { - AsyncResult result = (AsyncResult) msg.obj; - handleDisableTabNavigation(TiConvert.toBoolean(result.getArg())); - result.setResult(null); - return true; - } - default: { - return super.handleMessage(msg); - } - } - } - public int getTabIndex(TabProxy tabProxy) { return tabs.indexOf(tabProxy); @@ -130,17 +83,6 @@ public int getTabIndex(TabProxy tabProxy) @Kroll.method public void disableTabNavigation(boolean disable) - { - if (TiApplication.isUIThread()) { - handleDisableTabNavigation(disable); - - return; - } - - TiMessenger.sendBlockingMainMessage(getMainHandler().obtainMessage(MSG_DISABLE_TAB_NAVIGATION), disable); - } - - private void handleDisableTabNavigation(boolean disable) { TiUIAbstractTabGroup tabGroup = (TiUIAbstractTabGroup) view; if (tabGroup != null) { @@ -155,20 +97,6 @@ public void addTab(TabProxy tab) return; } - if (TiApplication.isUIThread()) { - handleAddTab(tab); - return; - } - - TiMessenger.sendBlockingMainMessage(getMainHandler().obtainMessage(MSG_ADD_TAB), tab); - } - - private void handleAddTab(TabProxy tab) - { - if (tab == null) { - return; - } - // Set the tab's parent to this tab group. // This allows for certain events to bubble up. tab.setTabGroup(this); @@ -183,18 +111,6 @@ private void handleAddTab(TabProxy tab) @Kroll.method public void removeTab(TabProxy tab) - { - if (TiApplication.isUIThread()) { - handleRemoveTab(tab); - - } else { - TiMessenger.sendBlockingMainMessage(getMainHandler().obtainMessage(MSG_REMOVE_TAB), tab); - } - - tab.setParent(null); - } - - public void handleRemoveTab(TabProxy tab) { int indexToRemove = tabs.indexOf(tab); // Guard for trying to remove a Tab that has not been added. @@ -207,9 +123,25 @@ public void handleRemoveTab(TabProxy tab) if (tabGroup != null) { tabGroup.removeTabAt(indexToRemove); } + + tab.setParent(null); } - @Kroll.method + @Kroll.getProperty + public TabProxy getActiveTab() + { + //selectedTab may not be set when user queries activeTab, so we return + //the first tab (default selected tab) if it exists. + if (selectedTab != null) { + return selectedTab; + } else if (tabs.size() > 0) { + return tabs.get(0); + } else { + return null; + } + } + + @Kroll.setProperty public void setActiveTab(Object tabOrIndex) { TabProxy tab = parseTab(tabOrIndex); @@ -218,37 +150,49 @@ public void setActiveTab(Object tabOrIndex) return; } - if (TiApplication.isUIThread()) { - handleSetActiveTab(tab); - - } else { - TiMessenger.sendBlockingMainMessage(getMainHandler().obtainMessage(MSG_SET_ACTIVE_TAB), tab); - } - } - - protected void handleSetActiveTab(TabProxy tab) - { TiUIAbstractTabGroup tabGroup = (TiUIAbstractTabGroup) view; if (tabGroup != null) { // Change the selected tab of the group. // Once the change is completed onTabSelected() will be // called to fire events and update the active tab. tabGroup.selectTab(tab); - } else { - // Mark this tab to be selected when the tab group opens. - selectedTab = tab; } + selectedTab = tab; } - @Kroll.method + @Kroll.getProperty(name = "activity") + public ActivityProxy _getActivity() + { + final AppCompatActivity activity = tabGroupActivity.get(); + + if (activity instanceof TiBaseActivity) { + return ((TiBaseActivity) activity).getActivityProxy(); + } + return null; + } + + @Kroll.getProperty + public TabProxy[] getTabs() + { + return tabs.toArray(new TabProxy[tabs.size()]); + } + + @Kroll.setProperty public void setTabs(Object obj) { - if (TiApplication.isUIThread()) { - handleSetTabs(obj); - return; + for (final TabProxy tab : getTabs()) { + removeTab(tab); } + tabs.clear(); - TiMessenger.sendBlockingMainMessage(getMainHandler().obtainMessage(MSG_SET_TABS), obj); + if (obj instanceof Object[]) { + Object[] objArray = (Object[]) obj; + for (Object tabProxy : objArray) { + if (tabProxy instanceof TabProxy) { + addTab((TabProxy) tabProxy); + } + } + } } private TabProxy parseTab(Object tabOrIndex) @@ -274,23 +218,6 @@ private TabProxy parseTab(Object tabOrIndex) return tab; } - private void handleSetTabs(Object obj) - { - if (tabs != null) { - tabs.clear(); - } else { - tabs = new ArrayList(); - } - if (obj instanceof Object[]) { - Object[] objArray = (Object[]) obj; - for (Object tabProxy : objArray) { - if (tabProxy instanceof TabProxy) { - handleAddTab((TabProxy) tabProxy); - } - } - } - } - @Override public void handleCreationDict(KrollDict options) { @@ -307,17 +234,12 @@ public void handleCreationDict(KrollDict options) Log.e(TAG, "Invalid orientationMode array. Must only contain orientation mode constants."); } } - } - - @Kroll.method - public TabProxy getActiveTab() - { - if (TiApplication.isUIThread()) { - return handleGetActiveTab(); - } else { - return (TabProxy) TiMessenger.sendBlockingMainMessage( - getMainHandler().obtainMessage(MSG_GET_ACTIVE_TAB, tab)); + if (options.containsKeyAndNotNull(TiC.PROPERTY_TABS)) { + setTabs(options.get(TiC.PROPERTY_TABS)); + } + if (options.containsKeyAndNotNull(TiC.PROPERTY_ACTIVE_TAB)) { + setActiveTab(options.get(TiC.PROPERTY_ACTIVE_TAB)); } } @@ -351,19 +273,6 @@ public void setTitle(String title) } } - private TabProxy handleGetActiveTab() - { - //selectedTab may not be set when user queries activeTab, so we return - //the first tab (default selected tab) if it exists. - if (selectedTab != null) { - return selectedTab; - } else if (tabs.size() > 0) { - return tabs.get(0); - } else { - return null; - } - } - @Override protected void handleOpen(KrollDict options) { @@ -481,12 +390,12 @@ protected void handlePostOpen() } } - TabProxy activeTab = handleGetActiveTab(); + TabProxy activeTab = getActiveTab(); if (activeTab != null) { - selectedTab = null; // If tabHost's selected tab is same as the active tab, we need // to invoke onTabSelected so focus/blur event fire appropriately tg.selectTab(activeTab); + selectedTab = activeTab; } // Selected tab should have been focused by now. diff --git a/common/Resources/ti.internal/extensions/ti/ui/tabgroup.js b/common/Resources/ti.internal/extensions/ti/ui/tabgroup.js index ba7423877f3..c71dab978ec 100644 --- a/common/Resources/ti.internal/extensions/ti/ui/tabgroup.js +++ b/common/Resources/ti.internal/extensions/ti/ui/tabgroup.js @@ -1,168 +1,14 @@ /** * Appcelerator Titanium Mobile - * Copyright (c) 2012-Present by Appcelerator, Inc. All Rights Reserved. + * Copyright (c) 2021 by Axway, Inc. All Rights Reserved. * Licensed under the terms of the Apache Public License * Please see the LICENSE included with this distribution for details. */ /* globals OS_ANDROID */ -import PersistentHandle from '../persistentHandle'; - if (OS_ANDROID) { - const TAG = 'TabGroup'; const TabGroup = Titanium.UI.TabGroup; - // Set constants for representing states for the tab group - TabGroup.prototype.state = { closed: 0, opening: 1, opened: 2 }; - TabGroup.prototype._cachedActivityProxy = null; - - function createTabGroup(options) { - const tabGroup = new TabGroup(options); - - if (options) { - tabGroup._tabs = options.tabs || []; - tabGroup._activeTab = options.activeTab || -1; - } else { - tabGroup._tabs = []; - tabGroup._activeTab = -1; - } - - // Keeps track of the current tab group state - tabGroup.currentState = tabGroup.state.closed; - - return tabGroup; - } - - Titanium.UI.createTabGroup = createTabGroup; - - // Activity getter (account for scenario when tab group's activity is not created yet) - function activityProxyGetter() { - const activityProxy = this._getWindowActivityProxy(); - if (activityProxy) { - return activityProxy; - } - if (this._cachedActivityProxy == null) { // eslint-disable-line - this._cachedActivityProxy = {}; - } - - return this._cachedActivityProxy; - } - TabGroup.prototype.getActivity = activityProxyGetter; - Object.defineProperty(TabGroup.prototype, 'activity', { get: activityProxyGetter }); - - TabGroup.prototype.postTabGroupCreated = function () { - if (kroll.DBG) { - kroll.log(TAG, 'Checkpoint: postTabGroupCreated()'); - } - if (this._cachedActivityProxy) { - this._internalActivity.extend(this._cachedActivityProxy); - } - }; - - const _removeTab = TabGroup.prototype.removeTab; - TabGroup.prototype.removeTab = function (options) { - if (this.currentState !== this.state.opened) { - const index = this._tabs.indexOf(options); - if (index > -1) { - this._tabs.splice(index, 1); - } - } else { - _removeTab.call(this, options); - } - }; - - const _open = TabGroup.prototype.open; - TabGroup.prototype.open = function (options) { - - if (this.currentState === this.state.opened) { - return Promise.reject(new Error('Window is already opened or opening.')); - } - - this.currentState = this.state.opening; - - // Retain the tab group until is has closed. - const handle = new PersistentHandle(this); - - const self = this; - this.on('close', function (e) { - if (e._closeFromActivityForcedToDestroy) { - if (kroll.DBG) { - kroll.log(TAG, 'Tabgroup is closed because the activity is forced to destroy by Android OS.'); - } - return; - } - - self.currentState = self.state.closed; - handle.dispose(); - - if (kroll.DBG) { - kroll.log(TAG, 'Tabgroup is closed normally.'); - } - }); - - this.setTabs(this._tabs); - if (this._activeTab !== -1) { - this.setActiveTab(this._activeTab); - } - const result = _open.call(this, options); - - this.currentState = this.state.opened; - return result; - }; - - const _addTab = TabGroup.prototype.addTab; - TabGroup.prototype.addTab = function (tab) { - this._tabs.push(tab); - if (this.currentState === this.state.opened) { - _addTab.call(this, tab); - } - }; - - const _getActiveTab = TabGroup.prototype.getActiveTab; - TabGroup.prototype.getActiveTab = function () { - if (this.currentState === this.state.opened) { - return _getActiveTab.call(this); - } - - if (this._activeTab !== -1) { - return this._activeTab; - } - return null; - }; - - const _setActiveTab = TabGroup.prototype.setActiveTab; - TabGroup.prototype.setActiveTab = function (taborindex) { - this._activeTab = taborindex; - if ((this.currentState === this.state.opened) - || (this.currentState === this.state.opening)) { - _setActiveTab.call(this, taborindex); - } - }; - - TabGroup.prototype.getTabs = function () { - return this._tabs; - }; - - const _setTabs = TabGroup.prototype.setTabs; - TabGroup.prototype.setTabs = function (tabs) { - - if (!Array.isArray(tabs)) { - kroll.log(TAG, 'Invalid type of tabs for setTabs()'); - return; - } - - if (this.currentState !== this.state.opened) { - this._tabs = tabs; - _setTabs.call(this, tabs); - - } else { - kroll.log(TAG, 'Cannot set tabs after tab group opens'); - } - }; - - Object.defineProperty(TabGroup.prototype, 'tabs', { get: TabGroup.prototype.getTabs, set: TabGroup.prototype.setTabs }); - Object.defineProperty(TabGroup.prototype, 'activeTab', { get: TabGroup.prototype.getActiveTab, set: TabGroup.prototype.setActiveTab }); - // Avoid circular loops in toJSON() Object.defineProperty(TabGroup.prototype, 'toJSON', { value: function () {