569 lines
18 KiB
Java
569 lines
18 KiB
Java
/*
|
|
* Twidere - Twitter client for Android
|
|
*
|
|
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
package org.mariotaku.gallery3d;
|
|
|
|
import android.app.ActionBar;
|
|
import android.app.ActionBar.OnMenuVisibilityListener;
|
|
import android.content.ActivityNotFoundException;
|
|
import android.content.Intent;
|
|
import android.graphics.Color;
|
|
import android.net.Uri;
|
|
import android.os.Bundle;
|
|
import android.os.Handler;
|
|
import android.os.Message;
|
|
import android.support.v4.app.LoaderManager;
|
|
import android.support.v4.content.Loader;
|
|
import android.view.Menu;
|
|
import android.view.MenuItem;
|
|
import android.view.SubMenu;
|
|
import android.view.View;
|
|
import android.view.animation.Animation;
|
|
import android.view.animation.Animation.AnimationListener;
|
|
import android.view.animation.TranslateAnimation;
|
|
import android.widget.ImageView;
|
|
import android.widget.ProgressBar;
|
|
|
|
import org.mariotaku.gallery3d.ui.GLRoot;
|
|
import org.mariotaku.gallery3d.ui.GLRootView;
|
|
import org.mariotaku.gallery3d.ui.GLView;
|
|
import org.mariotaku.gallery3d.ui.PhotoView;
|
|
import org.mariotaku.gallery3d.ui.SynchronizedHandler;
|
|
import org.mariotaku.gallery3d.util.GalleryUtils;
|
|
import org.mariotaku.gallery3d.util.ThreadPool;
|
|
import org.mariotaku.menucomponent.widget.MenuBar;
|
|
import org.mariotaku.menucomponent.widget.MenuBar.MenuBarListener;
|
|
import org.mariotaku.twidere.Constants;
|
|
import org.mariotaku.twidere.R;
|
|
import org.mariotaku.twidere.activity.support.BaseSupportActivity;
|
|
import org.mariotaku.twidere.loader.support.TileImageLoader;
|
|
import org.mariotaku.twidere.util.SaveImageTask;
|
|
import org.mariotaku.twidere.util.ThemeUtils;
|
|
import org.mariotaku.twidere.util.Utils;
|
|
|
|
import java.io.File;
|
|
|
|
public final class ImageViewerGLActivityOld extends BaseSupportActivity implements Constants, PhotoView.Listener,
|
|
TileImageLoader.DownloadListener, LoaderManager.LoaderCallbacks<TileImageLoader.Result>, OnMenuVisibilityListener,
|
|
MenuBarListener {
|
|
|
|
private final GLView mRootPane = new GLView() {
|
|
@Override
|
|
protected void onLayout(final boolean changed, final int left, final int top, final int right, final int bottom) {
|
|
mPhotoView.layout(0, 0, right - left, bottom - top);
|
|
}
|
|
};
|
|
protected static final int FLAG_HIDE_ACTION_BAR = 1;
|
|
protected static final int FLAG_HIDE_STATUS_BAR = 2;
|
|
|
|
private static final int MSG_HIDE_BARS = 1;
|
|
private static final int MSG_ON_FULL_SCREEN_CHANGED = 4;
|
|
private static final int MSG_UPDATE_ACTION_BAR = 5;
|
|
private static final int MSG_UNFREEZE_GLROOT = 6;
|
|
private static final int MSG_WANT_BARS = 7;
|
|
private static final int MSG_REFRESH_BOTTOM_CONTROLS = 8;
|
|
private static final int UNFREEZE_GLROOT_TIMEOUT = 250;
|
|
|
|
private ActionBar mActionBar;
|
|
|
|
private GLView mContentPane;
|
|
private GLRootView mGLRootView;
|
|
private ProgressBar mProgress;
|
|
private ImageView mImageViewer;
|
|
private MenuBar mMenuBar;
|
|
|
|
private PhotoView mPhotoView;
|
|
|
|
private PhotoView.ITileImageAdapter mAdapter;
|
|
private Handler mHandler;
|
|
protected int mFlags;
|
|
|
|
private boolean mShowBars = true;
|
|
private boolean mActionBarAllowed = true;
|
|
private boolean mLoaderInitialized;
|
|
|
|
private long mContentLength;
|
|
private ThreadPool mThreadPool;
|
|
|
|
private File mImageFile;
|
|
|
|
public GLRoot getGLRoot() {
|
|
return mGLRootView;
|
|
}
|
|
|
|
@Override
|
|
public int getThemeResourceId() {
|
|
return ThemeUtils.getViewerThemeResource(this);
|
|
}
|
|
|
|
public ThreadPool getThreadPool() {
|
|
if (mThreadPool != null) return mThreadPool;
|
|
return mThreadPool = new ThreadPool();
|
|
}
|
|
|
|
public void hideProgress() {
|
|
mProgress.setVisibility(View.GONE);
|
|
mProgress.setProgress(0);
|
|
}
|
|
|
|
@Override
|
|
public void onActionBarAllowed(final boolean allowed) {
|
|
mActionBarAllowed = allowed;
|
|
mHandler.sendEmptyMessage(MSG_UPDATE_ACTION_BAR);
|
|
}
|
|
|
|
@Override
|
|
public void onActionBarWanted() {
|
|
mHandler.sendEmptyMessage(MSG_WANT_BARS);
|
|
}
|
|
|
|
@Override
|
|
public void onContentChanged() {
|
|
super.onContentChanged();
|
|
mGLRootView = (GLRootView) findViewById(R.id.gl_root_view);
|
|
mImageViewer = (ImageView) findViewById(R.id.image_viewer);
|
|
mProgress = (ProgressBar) findViewById(R.id.progress);
|
|
mMenuBar = (MenuBar) findViewById(R.id.menu_bar);
|
|
}
|
|
|
|
@Override
|
|
public Loader<TileImageLoader.Result> onCreateLoader(final int id, final Bundle args) {
|
|
mProgress.setVisibility(View.VISIBLE);
|
|
mProgress.setIndeterminate(true);
|
|
invalidateOptionsMenu();
|
|
final Uri uri = args.getParcelable(EXTRA_URI);
|
|
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
|
return new TileImageLoader(this, this, accountId, uri);
|
|
}
|
|
|
|
@Override
|
|
public boolean onCreateOptionsMenu(final Menu menu) {
|
|
getMenuInflater().inflate(R.menu.menu_image_viewer_action_bar, menu);
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public void onCurrentImageUpdated() {
|
|
mGLRootView.unfreeze();
|
|
}
|
|
|
|
@Override
|
|
public void onDownloadError(final Throwable t) {
|
|
mContentLength = 0;
|
|
}
|
|
|
|
@Override
|
|
public void onDownloadFinished() {
|
|
mContentLength = 0;
|
|
}
|
|
|
|
@Override
|
|
public void onDownloadStart(final long total) {
|
|
mContentLength = total;
|
|
mProgress.setIndeterminate(total <= 0);
|
|
mProgress.setMax(total > 0 ? (int) (total / 1024) : 0);
|
|
}
|
|
|
|
|
|
@Override
|
|
public void onLoaderReset(final Loader<TileImageLoader.Result> loader) {
|
|
|
|
}
|
|
|
|
@Override
|
|
public void onLoadFinished(final Loader<TileImageLoader.Result> loader, final TileImageLoader.Result data) {
|
|
if (data != null && (data.decoder != null || data.bitmap != null)) {
|
|
if (data.decoder != null) {
|
|
mGLRootView.setVisibility(View.VISIBLE);
|
|
mImageViewer.setVisibility(View.GONE);
|
|
mAdapter.setData(data.decoder, data.bitmap, data.orientation);
|
|
mImageViewer.setImageBitmap(null);
|
|
} else if (data.bitmap != null) {
|
|
mGLRootView.setVisibility(View.GONE);
|
|
mImageViewer.setVisibility(View.VISIBLE);
|
|
mImageViewer.setImageBitmap(data.bitmap);
|
|
}
|
|
mImageFile = data.file;
|
|
} else {
|
|
mImageFile = null;
|
|
if (data != null) {
|
|
Utils.showErrorMessage(this, null, data.exception, true);
|
|
}
|
|
}
|
|
mProgress.setVisibility(View.GONE);
|
|
mProgress.setProgress(0);
|
|
invalidateOptionsMenu();
|
|
updateShareIntent();
|
|
}
|
|
|
|
@Override
|
|
public boolean onMenuItemClick(final MenuItem item) {
|
|
switch (item.getItemId()) {
|
|
case MENU_SAVE: {
|
|
if (mImageFile != null) {
|
|
new SaveImageTask(this, mImageFile).execute();
|
|
}
|
|
break;
|
|
}
|
|
case MENU_OPEN_IN_BROWSER: {
|
|
final Intent intent = getIntent();
|
|
intent.setExtrasClassLoader(getClassLoader());
|
|
final Uri uri = intent.getData();
|
|
final Uri orig = intent.getParcelableExtra(EXTRA_URI_ORIG);
|
|
final Uri uriPreferred = orig != null ? orig : uri;
|
|
if (uriPreferred == null) return false;
|
|
final String scheme = uriPreferred.getScheme();
|
|
if ("http".equals(scheme) || "https".equals(scheme)) {
|
|
final Intent open_intent = new Intent(Intent.ACTION_VIEW, uriPreferred);
|
|
open_intent.addCategory(Intent.CATEGORY_BROWSABLE);
|
|
try {
|
|
startActivity(open_intent);
|
|
} catch (final ActivityNotFoundException e) {
|
|
// Ignore.
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
final Intent intent = item.getIntent();
|
|
if (intent != null) {
|
|
try {
|
|
startActivity(intent);
|
|
} catch (final ActivityNotFoundException e) {
|
|
// Ignore.
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public void onMenuVisibilityChanged(final boolean isVisible) {
|
|
}
|
|
|
|
@Override
|
|
public boolean onOptionsItemSelected(final MenuItem item) {
|
|
switch (item.getItemId()) {
|
|
case MENU_HOME: {
|
|
onBackPressed();
|
|
break;
|
|
}
|
|
case MENU_REFRESH: {
|
|
loadImage();
|
|
break;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public void onPictureCenter() {
|
|
mPhotoView.setWantPictureCenterCallbacks(false);
|
|
}
|
|
|
|
@Override
|
|
public boolean onPrepareOptionsMenu(final Menu menu) {
|
|
final LoaderManager lm = getSupportLoaderManager();
|
|
Utils.setMenuItemAvailability(menu, MENU_REFRESH, !lm.hasRunningLoaders());
|
|
return super.onPrepareOptionsMenu(menu);
|
|
}
|
|
|
|
@Override
|
|
public void onProgressUpdate(final long downloaded) {
|
|
if (mContentLength == 0) {
|
|
mProgress.setIndeterminate(true);
|
|
return;
|
|
}
|
|
mProgress.setIndeterminate(false);
|
|
mProgress.setProgress((int) (downloaded / 1024));
|
|
}
|
|
|
|
|
|
@Override
|
|
public void onSingleTapUp(final int x, final int y) {
|
|
toggleBars();
|
|
}
|
|
|
|
public void showProgress() {
|
|
mProgress.setVisibility(View.VISIBLE);
|
|
mProgress.setIndeterminate(true);
|
|
}
|
|
|
|
@Override
|
|
protected void onCreate(final Bundle savedInstanceState) {
|
|
super.onCreate(savedInstanceState);
|
|
setContentView(R.layout.image_viewer_gl);
|
|
mActionBar = getActionBar();
|
|
mActionBar.setDisplayHomeAsUpEnabled(true);
|
|
mActionBar.addOnMenuVisibilityListener(this);
|
|
mHandler = new MyHandler(this);
|
|
mPhotoView = new PhotoView(this);
|
|
mPhotoView.setListener(this);
|
|
final int bgColor = ThemeUtils.getColorBackgroundCacheHint(this);
|
|
final int r = Color.red(bgColor), g = Color.green(bgColor), b = Color.blue(bgColor);
|
|
final float[] rootBg = {r / 255f, g / 255f, b / 255f, 1};
|
|
mRootPane.setBackgroundColor(rootBg);
|
|
mRootPane.addComponent(mPhotoView);
|
|
mAdapter = new PhotoViewAdapter(mPhotoView);
|
|
mPhotoView.setModel(mAdapter);
|
|
if (savedInstanceState == null) {
|
|
loadImage();
|
|
}
|
|
mMenuBar.setMenuBarListener(this);
|
|
mMenuBar.inflate(R.menu.menu_image_viewer);
|
|
mMenuBar.setIsBottomBar(true);
|
|
mMenuBar.show();
|
|
}
|
|
|
|
@Override
|
|
protected void onDestroy() {
|
|
mActionBar.removeOnMenuVisibilityListener(this);
|
|
super.onDestroy();
|
|
mGLRootView.lockRenderThread();
|
|
try {
|
|
// Remove all pending messages.
|
|
mHandler.removeCallbacksAndMessages(null);
|
|
} finally {
|
|
mGLRootView.unlockRenderThread();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void onNewIntent(final Intent intent) {
|
|
setIntent(intent);
|
|
loadImage();
|
|
}
|
|
|
|
@Override
|
|
protected void onPause() {
|
|
super.onPause();
|
|
mGLRootView.onPause();
|
|
mGLRootView.lockRenderThread();
|
|
try {
|
|
mGLRootView.unfreeze();
|
|
mHandler.removeMessages(MSG_UNFREEZE_GLROOT);
|
|
|
|
if (mAdapter != null) {
|
|
mAdapter.recycleScreenNail();
|
|
}
|
|
mPhotoView.pause();
|
|
mHandler.removeMessages(MSG_HIDE_BARS);
|
|
mHandler.removeMessages(MSG_REFRESH_BOTTOM_CONTROLS);
|
|
} finally {
|
|
mGLRootView.unlockRenderThread();
|
|
}
|
|
|
|
}
|
|
|
|
@Override
|
|
protected void onResume() {
|
|
super.onResume();
|
|
mGLRootView.lockRenderThread();
|
|
try {
|
|
if (mAdapter == null) {
|
|
finish();
|
|
return;
|
|
}
|
|
mGLRootView.freeze();
|
|
setContentPane(mRootPane);
|
|
|
|
mPhotoView.resume();
|
|
if (!mShowBars) {
|
|
hideBars();
|
|
}
|
|
mHandler.sendEmptyMessageDelayed(MSG_UNFREEZE_GLROOT, UNFREEZE_GLROOT_TIMEOUT);
|
|
} finally {
|
|
mGLRootView.unlockRenderThread();
|
|
}
|
|
mGLRootView.onResume();
|
|
}
|
|
|
|
@Override
|
|
protected void onSaveInstanceState(final Bundle outState) {
|
|
mGLRootView.lockRenderThread();
|
|
try {
|
|
super.onSaveInstanceState(outState);
|
|
} finally {
|
|
mGLRootView.unlockRenderThread();
|
|
}
|
|
}
|
|
|
|
protected void setContentPane(final GLView content) {
|
|
mContentPane = content;
|
|
mContentPane.setBackgroundColor(GalleryUtils.intColorToFloatARGBArray(Color.BLACK));
|
|
mGLRootView.setContentPane(mContentPane);
|
|
}
|
|
|
|
private boolean canShowBars() {
|
|
// No bars if it's not allowed.
|
|
if (!mActionBarAllowed) return false;
|
|
return true;
|
|
}
|
|
|
|
private void hideBars() {
|
|
if (!mShowBars) return;
|
|
mShowBars = false;
|
|
mActionBar.hide();
|
|
final TranslateAnimation anim = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0,
|
|
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1);
|
|
anim.setDuration(getResources().getInteger(android.R.integer.config_shortAnimTime));
|
|
anim.setAnimationListener(new AnimationListener() {
|
|
|
|
@Override
|
|
public void onAnimationEnd(final Animation animation) {
|
|
mMenuBar.setVisibility(View.GONE);
|
|
}
|
|
|
|
@Override
|
|
public void onAnimationRepeat(final Animation animation) {
|
|
|
|
}
|
|
|
|
@Override
|
|
public void onAnimationStart(final Animation animation) {
|
|
|
|
}
|
|
});
|
|
mMenuBar.startAnimation(anim);
|
|
mHandler.removeMessages(MSG_HIDE_BARS);
|
|
}
|
|
|
|
private void loadImage() {
|
|
getSupportLoaderManager().destroyLoader(0);
|
|
final Intent intent = getIntent();
|
|
final Uri uri = intent.getData();
|
|
final long accountId = intent.getLongExtra(EXTRA_ACCOUNT_ID, -1);
|
|
if (uri == null) {
|
|
finish();
|
|
return;
|
|
}
|
|
final Bundle args = new Bundle();
|
|
args.putParcelable(EXTRA_URI, uri);
|
|
args.putLong(EXTRA_ACCOUNT_ID, accountId);
|
|
if (!mLoaderInitialized) {
|
|
getSupportLoaderManager().initLoader(0, args, this);
|
|
mLoaderInitialized = true;
|
|
} else {
|
|
getSupportLoaderManager().restartLoader(0, args, this);
|
|
}
|
|
}
|
|
|
|
private void showBars() {
|
|
if (mShowBars) return;
|
|
mShowBars = true;
|
|
mActionBar.show();
|
|
mMenuBar.setVisibility(View.VISIBLE);
|
|
final TranslateAnimation anim = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0,
|
|
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1, Animation.RELATIVE_TO_SELF, 0);
|
|
anim.setDuration(getResources().getInteger(android.R.integer.config_shortAnimTime));
|
|
mMenuBar.startAnimation(anim);
|
|
}
|
|
|
|
private void toggleBars() {
|
|
if (mShowBars) {
|
|
hideBars();
|
|
} else {
|
|
if (canShowBars()) {
|
|
showBars();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void updateBars() {
|
|
if (!canShowBars()) {
|
|
hideBars();
|
|
}
|
|
}
|
|
|
|
private void wantBars() {
|
|
if (canShowBars()) {
|
|
showBars();
|
|
}
|
|
}
|
|
|
|
void updateShareIntent() {
|
|
final MenuItem item = mMenuBar.getMenu().findItem(MENU_SHARE);
|
|
if (item == null || !item.hasSubMenu()) return;
|
|
final SubMenu subMenu = item.getSubMenu();
|
|
subMenu.clear();
|
|
final Intent intent = getIntent();
|
|
final Uri uri = intent.getData();
|
|
final Intent shareIntent = new Intent(Intent.ACTION_SEND);
|
|
if (mImageFile != null && mImageFile.exists()) {
|
|
shareIntent.setType("image/*");
|
|
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(mImageFile));
|
|
} else {
|
|
shareIntent.setType("text/plain");
|
|
shareIntent.putExtra(Intent.EXTRA_TEXT, uri.toString());
|
|
}
|
|
Utils.addIntentToMenu(this, subMenu, shareIntent);
|
|
}
|
|
|
|
@Override
|
|
public void onPreShowMenu(Menu menu) {
|
|
|
|
}
|
|
|
|
@Override
|
|
public void onPostShowMenu(Menu menu) {
|
|
|
|
}
|
|
|
|
private static class MyHandler extends SynchronizedHandler {
|
|
ImageViewerGLActivityOld activity;
|
|
|
|
private MyHandler(final ImageViewerGLActivityOld activity) {
|
|
super(activity.getGLRoot());
|
|
this.activity = activity;
|
|
}
|
|
|
|
@Override
|
|
public void handleMessage(final Message message) {
|
|
switch (message.what) {
|
|
case MSG_HIDE_BARS: {
|
|
activity.hideBars();
|
|
break;
|
|
}
|
|
case MSG_REFRESH_BOTTOM_CONTROLS: {
|
|
break;
|
|
}
|
|
case MSG_ON_FULL_SCREEN_CHANGED: {
|
|
break;
|
|
}
|
|
case MSG_UPDATE_ACTION_BAR: {
|
|
activity.updateBars();
|
|
break;
|
|
}
|
|
case MSG_WANT_BARS: {
|
|
activity.wantBars();
|
|
break;
|
|
}
|
|
case MSG_UNFREEZE_GLROOT: {
|
|
mGLRoot.unfreeze();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|