Commit 3d6fcb80 authored by Roumen Petrov's avatar Roumen Petrov
Browse files

new action bar management based on support toolbar

(ensure compatible look for API Level 7+)
parent ac15ecdd
......@@ -47,6 +47,7 @@
android:name="Term"
android:configChanges="keyboard|keyboardHidden|orientation"
android:launchMode="singleTask"
android:theme="@style/AppTheme.NoActionBar"
android:windowSoftInputMode="adjustResize|stateAlwaysVisible">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
......
/*
* Copyright (C) 2017 Roumen Petrov. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.termoneplus;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Spinner;
import jackpal.androidterm.R;
import jackpal.androidterm.WindowListAdapter;
import jackpal.androidterm.util.SessionList;
/**
* An action bar for terminal emulator activity.
*/
public class TermActionBar {
private final Toolbar toolbar;
private final Spinner spinner;
private TermActionBar(AppCompatActivity context, boolean floating) {
toolbar = (Toolbar) context.findViewById(R.id.toolbar);
context.setSupportActionBar(toolbar);
ActionBar appbar = context.getSupportActionBar();
if (appbar != null)
appbar.setDisplayShowTitleEnabled(false);
spinner = (Spinner) context.findViewById(R.id.spinner);
if (floating)
hide();
}
public static TermActionBar setTermContentView(AppCompatActivity context, boolean floating) {
if (floating)
context.setContentView(R.layout.activity_term_floatbar);
else
context.setContentView(R.layout.activity_term);
return new TermActionBar(context, floating);
}
public void setAdapter(WindowListAdapter adapter) {
spinner.setAdapter(adapter);
}
public void setOnItemSelectedListener(OnItemSelectedListener listener) {
final OnItemSelectedListener callback = listener;
AdapterView.OnItemSelectedListener wrapper = new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
callback.onItemSelected(position);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
};
spinner.setOnItemSelectedListener(wrapper);
}
public void setSessions(SessionList sessions) {
WindowListAdapter adapter = (WindowListAdapter) spinner.getAdapter();
adapter.setSessions(sessions);
}
public void setSelection(int position) {
spinner.setSelection(position);
}
public boolean isShowing() {
return toolbar.getVisibility() == View.VISIBLE;
}
public void hide() {
toolbar.setVisibility(View.GONE);
}
public void show() {
toolbar.setVisibility(View.VISIBLE);
}
public void doToggleActionBar() {
if (isShowing()) {
hide();
} else {
show();
}
}
public interface OnItemSelectedListener {
void onItemSelected(int position);
}
}
......@@ -17,8 +17,6 @@
package jackpal.androidterm;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
......@@ -37,6 +35,8 @@
import android.os.IBinder;
import android.os.PowerManager;
import android.preference.PreferenceManager;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
......@@ -56,6 +56,7 @@
import android.widget.TextView;
import android.widget.Toast;
import com.termoneplus.TermActionBar;
import com.termoneplus.utils.WrapOpenURL;
import java.io.IOException;
......@@ -63,7 +64,6 @@
import java.util.Arrays;
import java.util.Locale;
import jackpal.androidterm.compat.ActionBarCompat;
import jackpal.androidterm.compat.ActivityCompat;
import jackpal.androidterm.compat.AndroidCompat;
import jackpal.androidterm.compat.MenuItemCompat;
......@@ -80,7 +80,8 @@
* A terminal emulator activity.
*/
public class Term extends Activity implements UpdateCallback, SharedPreferences.OnSharedPreferenceChangeListener {
public class Term extends AppCompatActivity
implements UpdateCallback, SharedPreferences.OnSharedPreferenceChangeListener {
public static final int REQUEST_CHOOSE_WINDOW = 1;
public static final String EXTRA_WINDOW_ID = "jackpal.androidterm.window_id";
/**
......@@ -115,8 +116,8 @@ public class Term extends Activity implements UpdateCallback, SharedPreferences.
private WifiManager.WifiLock mWifiLock;
private int mPendingPathBroadcasts = 0;
private TermService mTermService;
private ActionBarCompat mActionBar;
private int mActionBarMode = TermSettings.ACTION_BAR_MODE_NONE;
private TermActionBar mActionBar;
private int mActionBarMode;
private WindowListAdapter mWinListAdapter;
private boolean mHaveFullHwKeyboard = false;
/**
......@@ -169,7 +170,7 @@ private boolean keyboardShortcuts(int keyCode, KeyEvent event) {
* Make sure the back button always leaves the application.
*/
private boolean backkeyInterceptor(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && mActionBarMode == TermSettings.ACTION_BAR_MODE_HIDES && mActionBar != null && mActionBar.isShowing()) {
if (keyCode == KeyEvent.KEYCODE_BACK && mActionBarMode == TermSettings.ACTION_BAR_MODE_HIDES && mActionBar.isShowing()) {
/* We need to intercept the key event before the view sees it,
otherwise the view will handle it before we get it */
onKeyUp(keyCode, event);
......@@ -179,21 +180,6 @@ private boolean backkeyInterceptor(int keyCode, KeyEvent event) {
}
}
};
private ActionBarCompat.OnNavigationListener mWinListItemSelected = new ActionBarCompat.OnNavigationListener() {
public boolean onNavigationItemSelected(int position, long id) {
int oldPosition = mViewFlipper.getDisplayedChild();
if (position != oldPosition) {
if (position >= mViewFlipper.getChildCount()) {
mViewFlipper.addView(createEmulatorView(mTermSessions.get(position)));
}
mViewFlipper.setDisplayedChild(position);
if (mActionBarMode == TermSettings.ACTION_BAR_MODE_HIDES) {
mActionBar.hide();
}
}
return true;
}
};
private BroadcastReceiver mPathReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String path = makePathFromBundle(getResultExtras(false));
......@@ -254,6 +240,7 @@ public void onCreate(Bundle icicle) {
final SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
mSettings = new TermSettings(getResources(), mPrefs);
mPrefs.registerOnSharedPreferenceChangeListener(this);
mActionBarMode = mSettings.actionBarMode();
Intent broadcast = new Intent(ACTION_PATH_APPEND_BROADCAST);
if (AndroidCompat.SDK >= 12) {
......@@ -270,24 +257,24 @@ public void onCreate(Bundle icicle) {
TSIntent = new Intent(this, TermService.class);
startService(TSIntent);
if (AndroidCompat.SDK >= 11) {
int actionBarMode = mSettings.actionBarMode();
mActionBarMode = actionBarMode;
if (AndroidCompat.V11ToV20) {
switch (actionBarMode) {
case TermSettings.ACTION_BAR_MODE_ALWAYS_VISIBLE:
setTheme(R.style.Theme_Holo);
break;
case TermSettings.ACTION_BAR_MODE_HIDES:
setTheme(R.style.Theme_Holo_ActionBarOverlay);
break;
mActionBar = TermActionBar.setTermContentView(this,
mActionBarMode == TermSettings.ACTION_BAR_MODE_HIDES);
mActionBar.setOnItemSelectedListener(new TermActionBar.OnItemSelectedListener() {
@Override
public void onItemSelected(int position) {
int oldPosition = mViewFlipper.getDisplayedChild();
if (position == oldPosition) return;
if (position >= mViewFlipper.getChildCount()) {
TermSession session = mTermSessions.get(position);
mViewFlipper.addView(createEmulatorView(session));
}
mViewFlipper.setDisplayedChild(position);
if (mActionBarMode == TermSettings.ACTION_BAR_MODE_HIDES)
mActionBar.hide();
}
} else {
mActionBarMode = TermSettings.ACTION_BAR_MODE_ALWAYS_VISIBLE;
}
});
setContentView(R.layout.term_activity);
mViewFlipper = (TermViewFlipper) findViewById(VIEW_FLIPPER);
Context app = getApplicationContext();
......@@ -302,16 +289,6 @@ public void onCreate(Bundle icicle) {
}
mWifiLock = wm.createWifiLock(wifiLockMode, TermDebug.LOG_TAG);
ActionBarCompat actionBar = ActivityCompat.getActionBar(this);
if (actionBar != null) {
mActionBar = actionBar;
actionBar.setNavigationMode(ActionBarCompat.NAVIGATION_MODE_LIST);
actionBar.setDisplayOptions(0, ActionBarCompat.DISPLAY_SHOW_TITLE);
if (mActionBarMode == TermSettings.ACTION_BAR_MODE_HIDES) {
actionBar.hide();
}
}
mHaveFullHwKeyboard = checkHaveFullHwKeyboard(getResources().getConfiguration());
updatePrefs();
......@@ -381,15 +358,11 @@ private void populateViewFlipper() {
}
private void populateWindowList() {
if (mActionBar == null) {
// Not needed
return;
}
if (mTermSessions != null) {
if (mWinListAdapter == null) {
mWinListAdapter = new WindowListActionBarAdapter(mTermSessions);
mActionBar.setListNavigationCallbacks(mWinListAdapter, mWinListItemSelected);
mActionBar.setAdapter(mWinListAdapter);
} else {
mWinListAdapter.setSessions(mTermSessions);
}
......@@ -480,7 +453,7 @@ private void updatePrefs() {
WindowManager.LayoutParams params = win.getAttributes();
final int FULLSCREEN = WindowManager.LayoutParams.FLAG_FULLSCREEN;
int desiredFlag = mSettings.showStatusBar() ? 0 : FULLSCREEN;
if (desiredFlag != (params.flags & FULLSCREEN) || (AndroidCompat.SDK >= 11 && mActionBarMode != mSettings.actionBarMode())) {
if (desiredFlag != (params.flags & FULLSCREEN) || (mActionBarMode != mSettings.actionBarMode())) {
if (mAlreadyStarted) {
// Can't switch to/from fullscreen after
// starting the activity.
......@@ -488,9 +461,7 @@ private void updatePrefs() {
} else {
win.setFlags(desiredFlag, FULLSCREEN);
if (mActionBarMode == TermSettings.ACTION_BAR_MODE_HIDES) {
if (mActionBar != null) {
mActionBar.hide();
}
mActionBar.hide();
}
}
}
......@@ -796,7 +767,7 @@ public boolean onContextItemSelected(MenuItem item) {
public boolean onKeyUp(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
if (mActionBarMode == TermSettings.ACTION_BAR_MODE_HIDES && mActionBar != null && mActionBar.isShowing()) {
if (mActionBarMode == TermSettings.ACTION_BAR_MODE_HIDES && mActionBar.isShowing()) {
mActionBar.hide();
return true;
}
......@@ -813,7 +784,7 @@ public boolean onKeyUp(int keyCode, KeyEvent event) {
return false;
}
case KeyEvent.KEYCODE_MENU:
if (mActionBar != null && !mActionBar.isShowing()) {
if (!mActionBar.isShowing()) {
mActionBar.show();
return true;
} else {
......@@ -976,28 +947,8 @@ private void doToggleWifiLock() {
ActivityCompat.invalidateOptionsMenu(this);
}
private void doToggleActionBar() {
ActionBarCompat bar = mActionBar;
if (bar == null) {
return;
}
if (bar.isShowing()) {
bar.hide();
} else {
bar.show();
}
}
private void doUIToggle(int x, int y, int width, int height) {
switch (mActionBarMode) {
case TermSettings.ACTION_BAR_MODE_NONE:
if (AndroidCompat.SDK >= 11 && (mHaveFullHwKeyboard || y < height / 2)) {
openOptionsMenu();
return;
} else {
doToggleSoftKeyboard();
}
break;
case TermSettings.ACTION_BAR_MODE_ALWAYS_VISIBLE:
if (!mHaveFullHwKeyboard) {
doToggleSoftKeyboard();
......@@ -1005,7 +956,7 @@ private void doUIToggle(int x, int y, int width, int height) {
break;
case TermSettings.ACTION_BAR_MODE_HIDES:
if (mHaveFullHwKeyboard || y < height / 2) {
doToggleActionBar();
mActionBar.doToggleActionBar();
return;
} else {
doToggleSoftKeyboard();
......@@ -1017,7 +968,7 @@ private void doUIToggle(int x, int y, int width, int height) {
private void synchronizeActionBar() {
int position = mViewFlipper.getDisplayedChild();
mActionBar.setSelectedNavigationItem(position);
mActionBar.setSelection(position);
}
private class WindowListActionBarAdapter extends WindowListAdapter implements UpdateCallback {
......
......@@ -36,16 +36,6 @@ protected void onCreate(Bundle savedInstanceState) {
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
// Remove the action bar pref on older platforms without an action bar
if (AndroidCompat.SDK < 11) {
Preference actionBarPref = findPreference(ACTIONBAR_KEY);
PreferenceCategory screenCategory =
(PreferenceCategory) findPreference(CATEGORY_SCREEN_KEY);
if ((actionBarPref != null) && (screenCategory != null)) {
screenCategory.removePreference(actionBarPref);
}
}
// Display up indicator on action bar home button
if (AndroidCompat.V11ToV20) {
ActionBarCompat bar = ActivityCompat.getActionBar(this);
......
......@@ -77,7 +77,8 @@ private void commonConstructor(Context context) {
this.context = context;
callbacks = new LinkedList<UpdateCallback>();
updateVisibleRect();
if (!isInEditMode())
updateVisibleRect();
Rect visible = mVisibleRect;
mChildParams = new LayoutParams(visible.width(), visible.height(),
Gravity.TOP|Gravity.LEFT);
......
......@@ -109,7 +109,6 @@ public class TermSettings {
{LINUX_CONSOLE_WHITE, BLACK}
};
public static final int ACTION_BAR_MODE_NONE = 0;
public static final int ACTION_BAR_MODE_ALWAYS_VISIBLE = 1;
public static final int ACTION_BAR_MODE_HIDES = 2;
private static final int ACTION_BAR_MODE_MAX = 2;
......
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2017 Roumen Petrov. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:logo="@mipmap/ic_launcher"
app:popupTheme="@style/AppTheme.PopupOverlay">
<Spinner
android:id="@+id/spinner"
android:layout_width="wrap_content"
android:layout_height="match_parent"/>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<jackpal.androidterm.TermViewFlipper
android:id="@+id/view_flipper"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black"/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2017 Roumen Petrov. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<jackpal.androidterm.TermViewFlipper
android:id="@+id/view_flipper"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black"/>
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:background="@android:color/transparent"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/floatToolbar"
app:logo="@mipmap/ic_launcher"
app:popupTheme="@style/AppTheme.PopupOverlay">
<Spinner
android:id="@+id/spinner"
android:layout_width="wrap_content"
android:layout_height="match_parent"/>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
</FrameLayout>
......@@ -18,4 +18,5 @@
<color name="colorPrimary">#607D8B</color>
<color name="colorPrimaryDark">#455A64</color>
<color name="colorAccent">#8BC34A</color>
<color name="floatToolbar">#A0607D8B</color>
</resources>
......@@ -34,7 +34,7 @@
android:key="actionbar"
android:defaultValue="@integer/pref_actionbar_default"
android:title="@string/title_actionbar_preference"
android:summary="@string/summary_actionbar_preference"
android:summary="@string/summary_actionbar_preference_compat"
android:entries="@array/entries_actionbar_preference"
android:entryValues="@array/entryvalues_actionbar_preference"
android:dialogTitle="@string/dialog_title_actionbar_preference" />
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment