From 58c9e820ed7de52d815cf86f54a8b673095f2d99 Mon Sep 17 00:00:00 2001 From: Anthony Restaino Date: Thu, 20 Aug 2015 20:58:33 -0400 Subject: [PATCH] Initial support for tabs on the top instead of in the navigation drawer added a setting to switch between modes. Still needs work to be less buggy --- app/build.gradle | 1 + app/proguard-project.txt | 9 +- .../lightning/activity/BrowserActivity.java | 181 +++++++++++++----- ...vity.java => ThemableBrowserActivity.java} | 13 +- .../fragment/GeneralSettingsFragment.java | 12 +- .../preference/PreferenceManager.java | 9 + .../acr/browser/lightning/utils/Utils.java | 64 ++++++- .../browser/lightning/view/LightningView.java | 5 +- app/src/main/res/layout/search.xml | 12 +- app/src/main/res/layout/tab_drawer.xml | 2 +- app/src/main/res/layout/tab_list_item.xml | 1 + .../res/layout/tab_list_item_horizontal.xml | 51 +++++ app/src/main/res/layout/toolbar.xml | 13 ++ app/src/main/res/layout/toolbar_content.xml | 2 +- app/src/main/res/values/strings.xml | 3 + app/src/main/res/values/styles.xml | 4 + app/src/main/res/xml/preference_general.xml | 4 + 17 files changed, 319 insertions(+), 67 deletions(-) rename app/src/main/java/acr/browser/lightning/activity/{ThemableActivity.java => ThemableBrowserActivity.java} (57%) create mode 100644 app/src/main/res/layout/tab_list_item_horizontal.xml diff --git a/app/build.gradle b/app/build.gradle index 3e51088..707d474 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -43,6 +43,7 @@ dependencies { compile 'com.android.support:appcompat-v7:22.2.1' compile 'com.android.support:design:22.2.1' compile 'org.jsoup:jsoup:1.8.1' + compile 'org.lucasr.twowayview:twowayview:0.1.4' // Only Lightning Plus needs the proxy libraries lightningPlusCompile 'net.i2p.android:client:0.7' lightningPlusCompile(project(':libnetcipher')) diff --git a/app/proguard-project.txt b/app/proguard-project.txt index 9c79170..31dc513 100644 --- a/app/proguard-project.txt +++ b/app/proguard-project.txt @@ -35,6 +35,7 @@ -keep public class * extends android.preference.Preference -keep public class com.android.vending.licensing.ILicensingService -keep public class acr.browser.lightning.reading.* +-keep class org.lucasr.twowayview.** { *; } -assumenosideeffects class android.util.Log { public static *** d(...); @@ -45,14 +46,14 @@ # this will fix a force close in ReadingActivity -keep public class org.jsoup.** { - public *; + public *; } # Without this rule, openFileChooser does not get called on KitKat -keep class acr.browser.lightning.view.LightningView$LightningChromeClient { - void openFileChooser(android.webkit.ValueCallback); - void openFileChooser(android.webkit.ValueCallback, java.lang.String); - void openFileChooser(android.webkit.ValueCallback, java.lang.String, java.lang.String); + void openFileChooser(android.webkit.ValueCallback); + void openFileChooser(android.webkit.ValueCallback, java.lang.String); + void openFileChooser(android.webkit.ValueCallback, java.lang.String, java.lang.String); } -keepclasseswithmembernames class * { diff --git a/app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java b/app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java index 8aaced0..a497882 100644 --- a/app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java +++ b/app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java @@ -15,16 +15,17 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; -import android.content.res.Configuration; import android.database.Cursor; import android.database.sqlite.SQLiteException; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; +import android.graphics.Color; import android.graphics.ColorMatrix; import android.graphics.ColorMatrixColorFilter; import android.graphics.Paint; import android.graphics.PorterDuff; +import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.media.MediaPlayer; @@ -38,6 +39,7 @@ import android.provider.Browser; import android.provider.MediaStore; import android.support.annotation.IdRes; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.support.v4.view.GravityCompat; import android.support.v4.view.ViewCompat; import android.support.v4.widget.DrawerLayout; @@ -90,6 +92,8 @@ import android.widget.TextView; import android.widget.TextView.OnEditorActionListener; import android.widget.VideoView; +import org.lucasr.twowayview.TwoWayView; + import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; @@ -126,13 +130,14 @@ import acr.browser.lightning.utils.WebUtils; import acr.browser.lightning.view.AnimatedProgressBar; import acr.browser.lightning.view.LightningView; -public abstract class BrowserActivity extends ThemableActivity implements BrowserController, OnClickListener, OnLongClickListener { +public abstract class BrowserActivity extends ThemableBrowserActivity implements BrowserController, OnClickListener, OnLongClickListener { // Layout private DrawerLayout mDrawerLayout; private FrameLayout mBrowserFrame; private FullscreenHolder mFullscreenContainer; - private ListView mDrawerListLeft, mDrawerListRight; + private ListView mDrawerListRight; + private TwoWayView mDrawerListLeft; private LinearLayout mDrawerLeft, mDrawerRight, mUiLayout, mToolbarLayout; private RelativeLayout mSearchBar; @@ -168,7 +173,8 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse mSystemBrowser = false, mIsNewIntent = false, mIsFullScreen = false, - mIsImmersive = false; + mIsImmersive = false, + mShowTabsInDrawer; private int mOriginalOrientation, mBackgroundColor, mIdGenerator, mIconColor; private String mSearchText, mUntitledTitle, mHomepage, mCameraPhotoPath; @@ -221,6 +227,8 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse //TODO make sure dark theme flag gets set correctly mDarkTheme = mPreferences.getUseTheme() != 0 || isIncognito(); mIconColor = mDarkTheme ? ThemeUtils.getIconDarkThemeColor(this) : ThemeUtils.getIconLightThemeColor(this); + mShowTabsInDrawer = mPreferences.getShowTabsInDrawer(!isTablet()); + mActivity = this; mWebViewList.clear(); @@ -237,7 +245,6 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse // Drawer stutters otherwise mDrawerLeft.setLayerType(View.LAYER_TYPE_HARDWARE, null); mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); - mDrawerListLeft = (ListView) findViewById(R.id.left_drawer_list); mDrawerRight = (LinearLayout) findViewById(R.id.right_drawer); mDrawerRight.setLayerType(View.LAYER_TYPE_HARDWARE, null); mDrawerListRight = (ListView) findViewById(R.id.right_drawer_list); @@ -246,6 +253,10 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse ImageView tabTitleImage = (ImageView) findViewById(R.id.plusIcon); tabTitleImage.setColorFilter(mIconColor, PorterDuff.Mode.SRC_IN); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && !mShowTabsInDrawer) { + getWindow().setStatusBarColor(Color.BLACK); + } + setNavigationDrawerWidth(); mDrawerLayout.setDrawerListener(new DrawerLocker()); @@ -254,7 +265,20 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse mHomepage = mPreferences.getHomepage(); - mTitleAdapter = new LightningViewAdapter(this, R.layout.tab_list_item, mWebViewList); + TwoWayView horizontalListView = (TwoWayView) findViewById(R.id.twv_list); + + if (mShowTabsInDrawer) { + mTitleAdapter = new LightningViewAdapter(this, R.layout.tab_list_item, mWebViewList); + mDrawerListLeft = (TwoWayView) findViewById(R.id.left_drawer_list); + mDrawerListLeft.setOverScrollMode(View.OVER_SCROLL_IF_CONTENT_SCROLLS); + mToolbarLayout.removeView(horizontalListView); + } else { + mTitleAdapter = new LightningViewAdapter(this, R.layout.tab_list_item_horizontal, mWebViewList); + mDrawerListLeft = horizontalListView; + mDrawerListLeft.setOverScrollMode(View.OVER_SCROLL_NEVER); + mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED, mDrawerLeft); + } + mDrawerListLeft.setAdapter(mTitleAdapter); mDrawerListLeft.setOnItemClickListener(new DrawerItemClickListener()); mDrawerListLeft.setOnItemLongClickListener(new DrawerItemLongClickListener()); @@ -276,8 +300,15 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse View v = actionBar.getCustomView(); LayoutParams lp = v.getLayoutParams(); lp.width = LayoutParams.MATCH_PARENT; + lp.height = LayoutParams.MATCH_PARENT; v.setLayoutParams(lp); + LinearLayout searchContainer = (LinearLayout) v.findViewById(R.id.search_container); + LinearLayout.LayoutParams p = (LinearLayout.LayoutParams) searchContainer.getLayoutParams(); + int leftMargin = !mShowTabsInDrawer ? Utils.dpToPx(10) : Utils.dpToPx(2); + p.setMargins(leftMargin, Utils.dpToPx(8), Utils.dpToPx(2), Utils.dpToPx(6)); + searchContainer.setLayoutParams(p); + mArrowDrawable = new DrawerArrowDrawable(this); mArrowImage = (ImageView) actionBar.getCustomView().findViewById(R.id.arrow); // Use hardware acceleration for the animation @@ -285,7 +316,11 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse mArrowImage.setImageDrawable(mArrowDrawable); FrameLayout arrowButton = (FrameLayout) actionBar.getCustomView().findViewById( R.id.arrow_button); - arrowButton.setOnClickListener(this); + if (mShowTabsInDrawer) { + arrowButton.setOnClickListener(this); + } else { + arrowButton.setVisibility(View.GONE); + } mProxyUtils = ProxyUtils.getInstance(this); @@ -305,7 +340,7 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse mRefreshIcon = ThemeUtils.getLightThemedDrawable(this, R.drawable.ic_action_refresh); mCopyIcon = ThemeUtils.getLightThemedDrawable(this, R.drawable.ic_action_copy); - int iconBounds = Utils.convertDpToPixels(30); + int iconBounds = Utils.dpToPx(30); mDeleteIcon.setBounds(0, 0, iconBounds, iconBounds); mRefreshIcon.setBounds(0, 0, iconBounds, iconBounds); mCopyIcon.setBounds(0, 0, iconBounds, iconBounds); @@ -522,7 +557,7 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse @Override public void onDrawerClosed(View v) { - if (v == mDrawerRight) { + if (v == mDrawerRight && mShowTabsInDrawer) { mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED, mDrawerLeft); } else { mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED, mDrawerRight); @@ -548,17 +583,13 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse } - private boolean isTablet() { - return (getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE; - } - private void setNavigationDrawerWidth() { - int width = getResources().getDisplayMetrics().widthPixels - Utils.convertDpToPixels(56); + int width = getResources().getDisplayMetrics().widthPixels - Utils.dpToPx(56); int maxWidth; if (isTablet()) { - maxWidth = Utils.convertDpToPixels(320); + maxWidth = Utils.dpToPx(320); } else { - maxWidth = Utils.convertDpToPixels(300); + maxWidth = Utils.dpToPx(300); } if (width > maxWidth) { DrawerLayout.LayoutParams params = (android.support.v4.widget.DrawerLayout.LayoutParams) mDrawerLeft @@ -630,10 +661,11 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse mColorMode = mPreferences.getColorModeEnabled(); mColorMode &= !mDarkTheme; if (!isIncognito() && !mColorMode && !mDarkTheme && mWebpageBitmap != null) { - changeToolbarBackground(mWebpageBitmap); + //TODO fix toolbar coloring +// changeToolbarBackground(mWebpageBitmap, null); } else if (!isIncognito() && mCurrentView != null && !mDarkTheme && mCurrentView.getFavicon() != null) { - changeToolbarBackground(mCurrentView.getFavicon()); +// changeToolbarBackground(mCurrentView.getFavicon(), null); } if (mFullScreen) { @@ -914,6 +946,9 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse } private void showCloseDialog(final int position) { + if (position < 0) { + return; + } AlertDialog.Builder builder = new AlertDialog.Builder(mActivity); ArrayAdapter adapter = new ArrayAdapter<>(mActivity, android.R.layout.simple_dropdown_item_1line); @@ -1022,7 +1057,7 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse getFolder.setAdapter(suggestionsAdapter); LinearLayout layout = new LinearLayout(mActivity); layout.setOrientation(LinearLayout.VERTICAL); - int padding = Utils.convertDpToPixels(10); + int padding = Utils.dpToPx(10); layout.setPadding(padding, padding, padding, padding); layout.addView(getTitle); layout.addView(getUrl); @@ -1074,7 +1109,7 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse getTitle.setSingleLine(); LinearLayout layout = new LinearLayout(mActivity); layout.setOrientation(LinearLayout.VERTICAL); - int padding = Utils.convertDpToPixels(10); + int padding = Utils.dpToPx(10); layout.setPadding(padding, padding, padding, padding); layout.addView(getTitle); editFolderDialog.setView(layout); @@ -1240,6 +1275,13 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse mDrawerListLeft.setItemChecked(mWebViewList.size() - 1, true); showTab(startingTab); } + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + mDrawerListLeft.smoothScrollToPosition(mWebViewList.size() - 1); + } + }, 300); + return true; } @@ -1248,7 +1290,10 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse return; } - int current = mDrawerListLeft.getCheckedItemPosition(); + int current = mWebViewList.indexOf(mCurrentView); + if (current < 0) { + return; + } LightningView reference = mWebViewList.get(position); if (reference == null) { return; @@ -1336,7 +1381,7 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse @Override public boolean onKeyLongPress(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { - showCloseDialog(mDrawerListLeft.getCheckedItemPosition()); + showCloseDialog(mWebViewList.indexOf(mCurrentView)); } return true; } @@ -1378,7 +1423,7 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse mCurrentView.goBack(); } } else { - deleteTab(mDrawerListLeft.getCheckedItemPosition()); + deleteTab(mWebViewList.indexOf(mCurrentView)); } } else { Log.e(Constants.TAG, "This shouldn't happen ever"); @@ -1470,8 +1515,8 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse * searches the web for the query fixing any and all problems with the input * checks if it is a search, url, etc. */ - private void searchTheWeb(String query) { - if (query.equals("")) { + private void searchTheWeb(@NonNull String query) { + if (query.isEmpty()) { return; } String SEARCH = mSearchText; @@ -1521,6 +1566,8 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse final int layoutResourceId; List data = null; final CloseTabListener mExitListener; + private final Drawable mBackgroundTabDrawable; + private final Drawable mForegroundTabDrawable; public LightningViewAdapter(Context context, int layoutResourceId, List data) { super(context, layoutResourceId, data); @@ -1528,6 +1575,17 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse this.context = context; this.data = data; this.mExitListener = new CloseTabListener(); + + + int backgroundColor = Utils.mixTwoColors(ThemeUtils.getPrimaryColor(mActivity), Color.BLACK, 0.75f); + Bitmap backgroundTabBitmap = Bitmap.createBitmap(Utils.dpToPx(175), Utils.dpToPx(30), Bitmap.Config.ARGB_8888); + Utils.drawTrapezoid(new Canvas(backgroundTabBitmap), backgroundColor, true); + mBackgroundTabDrawable = new BitmapDrawable(getResources(), backgroundTabBitmap); + + int foregroundColor = ThemeUtils.getPrimaryColor(context); + Bitmap foregroundTabBitmap = Bitmap.createBitmap(Utils.dpToPx(175), Utils.dpToPx(30), Bitmap.Config.ARGB_8888); + Utils.drawTrapezoid(new Canvas(foregroundTabBitmap), foregroundColor, false); + mForegroundTabDrawable = new BitmapDrawable(getResources(), foregroundTabBitmap); } @Override @@ -1535,13 +1593,16 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse View row = convertView; LightningViewHolder holder; if (row == null) { - LayoutInflater inflater = ((Activity) context).getLayoutInflater(); + LayoutInflater inflater = LayoutInflater.from(context); row = inflater.inflate(layoutResourceId, parent, false); holder = new LightningViewHolder(); holder.txtTitle = (TextView) row.findViewById(R.id.textTab); holder.favicon = (ImageView) row.findViewById(R.id.faviconTab); holder.exit = (ImageView) row.findViewById(R.id.deleteButton); + if (!mShowTabsInDrawer) { + holder.layout = (LinearLayout) row.findViewById(R.id.tab_item_background); + } holder.exitButton = (FrameLayout) row.findViewById(R.id.deleteAction); holder.exit.setColorFilter(mIconColor, PorterDuff.Mode.SRC_IN); row.setTag(holder); @@ -1552,23 +1613,35 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse holder.exitButton.setTag(position); holder.exitButton.setOnClickListener(mExitListener); - ViewCompat.jumpDrawablesToCurrentState(holder.exit); + ViewCompat.jumpDrawablesToCurrentState(holder.exitButton); LightningView web = data.get(position); holder.txtTitle.setText(web.getTitle()); - if (web.isForegroundTab()) { - holder.txtTitle.setTextAppearance(context, R.style.boldText); - } else { - holder.txtTitle.setTextAppearance(context, R.style.normalText); - } Bitmap favicon = web.getFavicon(); if (web.isForegroundTab()) { - + holder.txtTitle.setTextAppearance(context, R.style.boldText); holder.favicon.setImageBitmap(favicon); - if (!isIncognito() && mColorMode) - changeToolbarBackground(favicon); + if (!mShowTabsInDrawer) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + holder.layout.setBackground(mForegroundTabDrawable); + } else { + holder.layout.setBackgroundDrawable(mForegroundTabDrawable); + } + } + if (!isIncognito() && mColorMode) { + // TODO fix toolbar coloring +// changeToolbarBackground(favicon, mForegroundTabDrawable); + } } else { + holder.txtTitle.setTextAppearance(context, R.style.normalText); + if (!mShowTabsInDrawer) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + holder.layout.setBackground(mBackgroundTabDrawable); + } else { + holder.layout.setBackgroundDrawable(mBackgroundTabDrawable); + } + } Bitmap grayscaleBitmap = Bitmap.createBitmap(favicon.getWidth(), favicon.getHeight(), Bitmap.Config.ARGB_8888); @@ -1576,7 +1649,7 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse if (colorMatrix == null || filter == null || paint == null) { paint = new Paint(); colorMatrix = new ColorMatrix(); - colorMatrix.setSaturation(0); + colorMatrix.setSaturation(0.5f); filter = new ColorMatrixColorFilter(colorMatrix); paint.setColorFilter(filter); } @@ -1592,6 +1665,7 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse ImageView favicon; ImageView exit; FrameLayout exitButton; + LinearLayout layout; } } @@ -1604,7 +1678,15 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse } - private void changeToolbarBackground(Bitmap favicon) { + /** + * Animates the color of the toolbar from one color to another. Optionally animates + * the color of the tab background, for use when the tabs are displayed on the top + * of the screen. + * + * @param favicon the Bitmap to extract the color from + * @param tabBackground the optional LinearLayout to color + */ + private void changeToolbarBackground(@NonNull Bitmap favicon, @Nullable final Drawable tabBackground) { Palette.from(favicon).generate(new Palette.PaletteAsyncListener() { @Override public void onGenerated(Palette palette) { @@ -1625,22 +1707,28 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse ValueAnimator anim = ValueAnimator.ofObject(new ArgbEvaluator(), mBackground.getColor(), finalColor); - + final Window window = getWindow(); + if (!mShowTabsInDrawer) { + window.setBackgroundDrawable(new ColorDrawable(Color.BLACK)); + } anim.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { - int color = (Integer) animation.getAnimatedValue(); - mBackground.setColor(color); - getWindow().setBackgroundDrawable(mBackground); + final int color = (Integer) animation.getAnimatedValue(); + if (mShowTabsInDrawer) { + mBackground.setColor(color); + window.setBackgroundDrawable(mBackground); + } mToolbarLayout.setBackgroundColor(color); + if (tabBackground != null) { + tabBackground.setColorFilter(color, PorterDuff.Mode.SRC_IN); + } } }); - anim.setDuration(300); anim.start(); - } }); } @@ -2138,7 +2226,7 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse mFilePathCallback = filePathCallback; Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); - if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null) { + if (takePictureIntent.resolveActivity(mActivity.getPackageManager()) != null) { // Create the File where the photo should go File photoFile = null; try { @@ -2370,6 +2458,7 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse /** * Closes the specified view, implementing the JavaScript callback to close a window + * * @param view the LightningView to close */ @Override @@ -2776,7 +2865,7 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse if (mCurrentView.canGoBack()) { mCurrentView.goBack(); } else { - deleteTab(mDrawerListLeft.getCheckedItemPosition()); + deleteTab(mWebViewList.indexOf(mCurrentView)); } } break; @@ -2790,7 +2879,7 @@ public abstract class BrowserActivity extends ThemableActivity implements Browse case R.id.arrow_button: if (mSearch != null && mSearch.hasFocus()) { mCurrentView.requestFocus(); - } else { + } else if (mShowTabsInDrawer) { mDrawerLayout.openDrawer(mDrawerLeft); } break; diff --git a/app/src/main/java/acr/browser/lightning/activity/ThemableActivity.java b/app/src/main/java/acr/browser/lightning/activity/ThemableBrowserActivity.java similarity index 57% rename from app/src/main/java/acr/browser/lightning/activity/ThemableActivity.java rename to app/src/main/java/acr/browser/lightning/activity/ThemableBrowserActivity.java index badd3eb..a09c20b 100644 --- a/app/src/main/java/acr/browser/lightning/activity/ThemableActivity.java +++ b/app/src/main/java/acr/browser/lightning/activity/ThemableBrowserActivity.java @@ -1,19 +1,22 @@ package acr.browser.lightning.activity; import android.content.Intent; +import android.content.res.Configuration; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import acr.browser.lightning.R; import acr.browser.lightning.preference.PreferenceManager; -public abstract class ThemableActivity extends AppCompatActivity { +public abstract class ThemableBrowserActivity extends AppCompatActivity { private int mTheme; + private boolean mShowTabsInDrawer; @Override protected void onCreate(Bundle savedInstanceState) { mTheme = PreferenceManager.getInstance().getUseTheme(); + mShowTabsInDrawer = PreferenceManager.getInstance().getShowTabsInDrawer(!isTablet()); // set the theme if (mTheme == 1) { @@ -27,11 +30,17 @@ public abstract class ThemableActivity extends AppCompatActivity { @Override protected void onResume() { super.onResume(); - if (PreferenceManager.getInstance().getUseTheme() != mTheme) { + int theme = PreferenceManager.getInstance().getUseTheme(); + boolean drawerTabs = PreferenceManager.getInstance().getShowTabsInDrawer(!isTablet()); + if (theme != mTheme || mShowTabsInDrawer != drawerTabs) { restart(); } } + public boolean isTablet() { + return (getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE; + } + private void restart() { Intent intent = getIntent(); finish(); diff --git a/app/src/main/java/acr/browser/lightning/fragment/GeneralSettingsFragment.java b/app/src/main/java/acr/browser/lightning/fragment/GeneralSettingsFragment.java index 9ce14d7..864d8e8 100644 --- a/app/src/main/java/acr/browser/lightning/fragment/GeneralSettingsFragment.java +++ b/app/src/main/java/acr/browser/lightning/fragment/GeneralSettingsFragment.java @@ -41,6 +41,7 @@ public class GeneralSettingsFragment extends PreferenceFragment implements Prefe private static final String SETTINGS_HOME = "home"; private static final String SETTINGS_SEARCHENGINE = "search"; private static final String SETTINGS_GOOGLESUGGESTIONS = "google_suggestions"; + private static final String SETTINGS_DRAWERTABS = "cb_drawertabs"; private Activity mActivity; private static final int API = android.os.Build.VERSION.SDK_INT; @@ -50,7 +51,7 @@ public class GeneralSettingsFragment extends PreferenceFragment implements Prefe private String mDownloadLocation; private int mAgentChoice; private String mHomepage; - private CheckBoxPreference cbFlash, cbAds, cbImages, cbJsScript, cbColorMode, cbgooglesuggest; + private CheckBoxPreference cbFlash, cbAds, cbImages, cbJsScript, cbColorMode, cbgooglesuggest, cbDrawerTabs; @Override public void onCreate(Bundle savedInstanceState) { @@ -72,12 +73,14 @@ public class GeneralSettingsFragment extends PreferenceFragment implements Prefe downloadloc = findPreference(SETTINGS_DOWNLOAD); home = findPreference(SETTINGS_HOME); searchengine = findPreference(SETTINGS_SEARCHENGINE); + cbFlash = (CheckBoxPreference) findPreference(SETTINGS_FLASH); cbAds = (CheckBoxPreference) findPreference(SETTINGS_ADS); cbImages = (CheckBoxPreference) findPreference(SETTINGS_IMAGES); cbJsScript = (CheckBoxPreference) findPreference(SETTINGS_JAVASCRIPT); cbColorMode = (CheckBoxPreference) findPreference(SETTINGS_COLORMODE); cbgooglesuggest = (CheckBoxPreference) findPreference(SETTINGS_GOOGLESUGGESTIONS); + cbDrawerTabs = (CheckBoxPreference) findPreference(SETTINGS_DRAWERTABS); proxy.setOnPreferenceClickListener(this); useragent.setOnPreferenceClickListener(this); @@ -90,6 +93,7 @@ public class GeneralSettingsFragment extends PreferenceFragment implements Prefe cbJsScript.setOnPreferenceChangeListener(this); cbColorMode.setOnPreferenceChangeListener(this); cbgooglesuggest.setOnPreferenceChangeListener(this); + cbDrawerTabs.setOnPreferenceChangeListener(this); mAgentChoice = mPreferences.getUserAgentChoice(); mHomepage = mPreferences.getHomepage(); @@ -149,6 +153,7 @@ public class GeneralSettingsFragment extends PreferenceFragment implements Prefe cbAds.setChecked(Constants.FULL_VERSION && mPreferences.getAdBlockEnabled()); cbColorMode.setChecked(mPreferences.getColorModeEnabled()); cbgooglesuggest.setChecked(mPreferences.getGoogleSearchSuggestionsEnabled()); + cbDrawerTabs.setChecked(mPreferences.getShowTabsInDrawer(true)); } private void searchUrlPicker() { @@ -477,7 +482,7 @@ public class GeneralSettingsFragment extends PreferenceFragment implements Prefe final EditText getDownload = new EditText(mActivity); getDownload.setText(mPreferences.getDownloadDirectory()); - int padding = Utils.convertDpToPixels(10); + int padding = Utils.dpToPx(10); TextView v = new TextView(mActivity); v.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18); @@ -607,6 +612,9 @@ public class GeneralSettingsFragment extends PreferenceFragment implements Prefe mPreferences.setGoogleSearchSuggestionsEnabled((Boolean) newValue); cbgooglesuggest.setChecked((Boolean) newValue); return true; + case SETTINGS_DRAWERTABS: + mPreferences.setShowTabsInDrawer((Boolean) newValue); + cbDrawerTabs.setChecked((Boolean) newValue); default: return false; } diff --git a/app/src/main/java/acr/browser/lightning/preference/PreferenceManager.java b/app/src/main/java/acr/browser/lightning/preference/PreferenceManager.java index 7d801b4..1a053ad 100644 --- a/app/src/main/java/acr/browser/lightning/preference/PreferenceManager.java +++ b/app/src/main/java/acr/browser/lightning/preference/PreferenceManager.java @@ -49,6 +49,7 @@ public class PreferenceManager { public static final String DEFAULT_BOOKMARKS = "defaultBookmarks"; public static final String TEXT_ENCODING = "textEncoding"; public static final String CLEAR_WEBSTORAGE_EXIT = "clearWebStorageExit"; + public static final String SHOW_TABS_IN_DRAWER = "showTabsInDrawer"; public static final String USE_PROXY = "useProxy"; public static final String PROXY_CHOICE = "proxyChoice"; @@ -258,6 +259,10 @@ public class PreferenceManager { return mPrefs.getString(Name.TEXT_ENCODING, Constants.DEFAULT_ENCODING); } + public boolean getShowTabsInDrawer(boolean defaultValue){ + return mPrefs.getBoolean(Name.SHOW_TABS_IN_DRAWER, defaultValue); + } + private void putBoolean(String name, boolean value) { mPrefs.edit().putBoolean(name, value).apply(); } @@ -270,6 +275,10 @@ public class PreferenceManager { mPrefs.edit().putString(name, value).apply(); } + public void setShowTabsInDrawer(boolean show){ + putBoolean(Name.SHOW_TABS_IN_DRAWER, show); + } + public void setTextEncoding(String encoding) { putString(Name.TEXT_ENCODING, encoding); } diff --git a/app/src/main/java/acr/browser/lightning/utils/Utils.java b/app/src/main/java/acr/browser/lightning/utils/Utils.java index ef8b30a..66b9f3e 100644 --- a/app/src/main/java/acr/browser/lightning/utils/Utils.java +++ b/app/src/main/java/acr/browser/lightning/utils/Utils.java @@ -13,7 +13,11 @@ import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.LinearGradient; import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.Shader; import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Environment; @@ -88,9 +92,12 @@ public final class Utils { } /** - * Returns the number of pixels corresponding to the passed density pixels + * Converts Density Pixels (DP) to Pixels (PX) + * + * @param dp the number of density pixels to convert + * @return the number of pixels */ - public static int convertDpToPixels(int dp) { + public static int dpToPx(int dp) { DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics(); return (int) (dp * metrics.density + 0.5f); } @@ -166,7 +173,7 @@ public final class Utils { * @return the padded bitmap. */ public static Bitmap padFavicon(Bitmap bitmap) { - int padding = Utils.convertDpToPixels(4); + int padding = Utils.dpToPx(4); Bitmap paddedBitmap = Bitmap.createBitmap(bitmap.getWidth() + padding, bitmap.getHeight() + padding, Bitmap.Config.ARGB_8888); @@ -220,6 +227,12 @@ public final class Utils { ); } + /** + * Checks if flash player is installed + * + * @param context the context needed to obtain the PackageManager + * @return true if flash is installed, false otherwise + */ public static boolean isFlashInstalled(Context context) { try { PackageManager pm = context.getPackageManager(); @@ -233,6 +246,12 @@ public final class Utils { return false; } + /** + * Quietly closes a closeable object like an InputStream or OutputStream without + * throwing any errors or requiring you do do any checks. + * + * @param closeable the object to close + */ public static void close(Closeable closeable) { if (closeable == null) return; @@ -251,4 +270,43 @@ public final class Utils { } } + /** + * Draws the trapezoid background for the horizontal tabs on a canvas object using + * the specified color. + * + * @param canvas the canvas to draw upon + * @param color the color to use to draw the tab + */ + public static void drawTrapezoid(Canvas canvas, int color, boolean withShader) { + + Paint paint = new Paint(); + paint.setColor(color); + paint.setStyle(Paint.Style.FILL); +// paint.setFilterBitmap(true); + paint.setAntiAlias(true); + paint.setDither(true); + if (withShader) { + paint.setShader(new LinearGradient(0, 0.9f * canvas.getHeight(), + 0, canvas.getHeight(), + color, mixTwoColors(Color.BLACK, color, 0.5f), + Shader.TileMode.CLAMP)); + } else { + paint.setShader(null); + } + int width = canvas.getWidth(); + int height = canvas.getHeight(); + double radians = Math.PI / 3; + int base = (int) (height / Math.tan(radians)); + + Path wallpath = new Path(); + wallpath.reset(); + wallpath.moveTo(0, height); + wallpath.lineTo(width, height); + wallpath.lineTo(width - base, 0); + wallpath.lineTo(base, 0); + wallpath.close(); + + canvas.drawPath(wallpath, paint); + } + } diff --git a/app/src/main/java/acr/browser/lightning/view/LightningView.java b/app/src/main/java/acr/browser/lightning/view/LightningView.java index c9e1b20..a683151 100644 --- a/app/src/main/java/acr/browser/lightning/view/LightningView.java +++ b/app/src/main/java/acr/browser/lightning/view/LightningView.java @@ -75,7 +75,8 @@ public class LightningView { private final Activity mActivity; private static String mHomepage; private static String mDefaultUserAgent; - private static Bitmap mWebpageBitmap; + // TODO fix so that mWebpageBitmap can be static - static changes the icon when switching from light to dark and then back to light + private Bitmap mWebpageBitmap; private static PreferenceManager mPreferences; private final AdBlock mAdBlock; private IntentUtils mIntentUtils; @@ -86,7 +87,7 @@ public class LightningView { private boolean mToggleDesktop = false; private static float mMaxFling; private static final int API = android.os.Build.VERSION.SDK_INT; - private static final int SCROLL_UP_THRESHOLD = Utils.convertDpToPixels(10); + private static final int SCROLL_UP_THRESHOLD = Utils.dpToPx(10); private static final float[] mNegativeColorArray = {-1.0f, 0, 0, 0, 255, // red 0, -1.0f, 0, 0, 255, // green 0, 0, -1.0f, 0, 255, // blue diff --git a/app/src/main/res/layout/search.xml b/app/src/main/res/layout/search.xml index a2dd47d..e4f58c6 100644 --- a/app/src/main/res/layout/search.xml +++ b/app/src/main/res/layout/search.xml @@ -1,24 +1,25 @@ + android:gravity="center"> - + android:textCursorDrawable="@null"> \ No newline at end of file diff --git a/app/src/main/res/layout/tab_drawer.xml b/app/src/main/res/layout/tab_drawer.xml index 4e4724b..bd6f3c5 100644 --- a/app/src/main/res/layout/tab_drawer.xml +++ b/app/src/main/res/layout/tab_drawer.xml @@ -44,7 +44,7 @@ android:textAppearance="?android:attr/textAppearanceLarge" /> - + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/toolbar.xml b/app/src/main/res/layout/toolbar.xml index 86ddd1f..e33630c 100644 --- a/app/src/main/res/layout/toolbar.xml +++ b/app/src/main/res/layout/toolbar.xml @@ -8,6 +8,19 @@ android:elevation="2dp" android:orientation="vertical"> + + + Clear Web Storage Clear web storage on exit Web Storage Cleared + Hosts File Ad Blocking Source + Ad Block Settings + Show tabs in Navigation Drawer diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index e4deb6e..53bd99c 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -126,4 +126,8 @@ sans-serif-light + + \ No newline at end of file diff --git a/app/src/main/res/xml/preference_general.xml b/app/src/main/res/xml/preference_general.xml index d2b3d99..45cfb68 100644 --- a/app/src/main/res/xml/preference_general.xml +++ b/app/src/main/res/xml/preference_general.xml @@ -2,6 +2,10 @@ +