/* * Copyright 2016 Hippo Seven * * 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.hippo.ehviewer.ui; import android.animation.Animator; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.annotation.SuppressLint; import android.content.ContentResolver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.res.Resources; import android.graphics.Typeface; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v7.app.AlertDialog; import android.support.v7.widget.SwitchCompat; import android.text.TextUtils; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.Window; import android.view.WindowManager; import android.webkit.MimeTypeMap; import android.widget.CompoundButton; import android.widget.FrameLayout; import android.widget.SeekBar; import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; import com.hippo.ehviewer.AppConfig; import com.hippo.ehviewer.R; import com.hippo.ehviewer.Settings; import com.hippo.ehviewer.client.data.GalleryInfo; import com.hippo.ehviewer.gallery.DirGalleryProvider; import com.hippo.ehviewer.gallery.EhGalleryProvider; import com.hippo.ehviewer.gallery.GalleryProvider2; import com.hippo.ehviewer.gallery.ZipGalleryProvider; import com.hippo.ehviewer.widget.GalleryGuideView; import com.hippo.ehviewer.widget.ReversibleSeekBar; import com.hippo.glgallery.GalleryPageView; import com.hippo.glgallery.GalleryProvider; import com.hippo.glgallery.GalleryView; import com.hippo.glgallery.SimpleAdapter; import com.hippo.glview.view.GLRootView; import com.hippo.unifile.UniFile; import com.hippo.util.SystemUiHelper; import com.hippo.widget.ColorView; import com.hippo.yorozuya.AnimationUtils; import com.hippo.yorozuya.ConcurrentPool; import com.hippo.yorozuya.MathUtils; import com.hippo.yorozuya.ResourcesUtils; import com.hippo.yorozuya.SimpleAnimatorListener; import com.hippo.yorozuya.SimpleHandler; import com.hippo.yorozuya.ViewUtils; import java.io.File; public class GalleryActivity extends EhActivity implements SeekBar.OnSeekBarChangeListener, GalleryView.Listener { public static final String ACTION_DIR = "dir"; public static final String ACTION_ZIP = "zip"; public static final String ACTION_EH = "eh"; public static final String KEY_ACTION = "action"; public static final String KEY_FILENAME = "filename"; public static final String KEY_URI = "uri"; public static final String KEY_GALLERY_INFO = "gallery_info"; public static final String KEY_PAGE = "page"; public static final String KEY_CURRENT_INDEX = "current_index"; private static final long SLIDER_ANIMATION_DURING = 150; private static final long HIDE_SLIDER_DELAY = 3000; private String mAction; private String mFilename; private Uri mUri; private GalleryInfo mGalleryInfo; private int mPage; @Nullable private GLRootView mGLRootView; @Nullable private GalleryView mGalleryView; @Nullable private GalleryProvider2 mGalleryProvider; @Nullable private GalleryAdapter mGalleryAdapter; @Nullable private SystemUiHelper mSystemUiHelper; private boolean mShowSystemUi; @Nullable private ColorView mMaskView; @Nullable private View mClock; @Nullable private TextView mProgress; @Nullable private View mBattery; @Nullable private View mSeekBarPanel; @Nullable private TextView mLeftText; @Nullable private TextView mRightText; @Nullable private ReversibleSeekBar mSeekBar; private ObjectAnimator mSeekBarPanelAnimator; private int mLayoutMode; private int mSize; private int mCurrentIndex; private final ConcurrentPool<NotifyTask> mNotifyTaskPool = new ConcurrentPool<>(3); private final ValueAnimator.AnimatorUpdateListener mUpdateSliderListener = new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { if (null != mSeekBarPanel) { mSeekBarPanel.requestLayout(); } } }; private final SimpleAnimatorListener mShowSliderListener = new SimpleAnimatorListener() { @Override public void onAnimationEnd(Animator animation) { mSeekBarPanelAnimator = null; } }; private final SimpleAnimatorListener mHideSliderListener = new SimpleAnimatorListener() { @Override public void onAnimationEnd(Animator animation) { mSeekBarPanelAnimator = null; if (mSeekBarPanel != null) { mSeekBarPanel.setVisibility(View.INVISIBLE); } } }; private final Runnable mHideSliderRunnable = new Runnable() { @Override public void run() { if (mSeekBarPanel != null) { hideSlider(mSeekBarPanel); } } }; private void buildProvider() { if (mGalleryProvider != null) { return; } if (ACTION_DIR.equals(mAction)) { if (mFilename != null) { mGalleryProvider = new DirGalleryProvider(UniFile.fromFile(new File(mFilename))); } } else if (ACTION_ZIP.equals(mAction)) { if (mFilename != null) { mGalleryProvider = new ZipGalleryProvider(new File(mFilename)); } } else if (ACTION_EH.equals(mAction)) { if (mGalleryInfo != null) { mGalleryProvider = new EhGalleryProvider(this, mGalleryInfo); } } else if (Intent.ACTION_VIEW.equals(mAction)) { if (mUri != null) { // Only support zip now mGalleryProvider = new ZipGalleryProvider(new File(mUri.getPath())); } } } private void onInit() { Intent intent = getIntent(); if (intent == null) { return; } mAction = intent.getAction(); mFilename = intent.getStringExtra(KEY_FILENAME); mUri = intent.getData(); mGalleryInfo = intent.getParcelableExtra(KEY_GALLERY_INFO); mPage = intent.getIntExtra(KEY_PAGE, -1); buildProvider(); } private void onRestore(@NonNull Bundle savedInstanceState) { mAction = savedInstanceState.getString(KEY_ACTION); mFilename = savedInstanceState.getString(KEY_FILENAME); mUri= savedInstanceState.getParcelable(KEY_URI); mGalleryInfo = savedInstanceState.getParcelable(KEY_GALLERY_INFO); mPage = savedInstanceState.getInt(KEY_PAGE, -1); mCurrentIndex = savedInstanceState.getInt(KEY_CURRENT_INDEX); buildProvider(); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putString(KEY_ACTION, mAction); outState.putString(KEY_FILENAME, mFilename); outState.putParcelable(KEY_URI, mUri); if (mGalleryInfo != null) { outState.putParcelable(KEY_GALLERY_INFO, mGalleryInfo); } outState.putInt(KEY_PAGE, mPage); outState.putInt(KEY_CURRENT_INDEX, mCurrentIndex); } @Override @SuppressWarnings({"deprecation", "WrongConstant"}) protected void onCreate(@Nullable Bundle savedInstanceState) { if (Settings.getReadingFullscreen() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { Window w = getWindow(); w.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); w.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); } super.onCreate(savedInstanceState); if (savedInstanceState == null) { onInit(); } else { onRestore(savedInstanceState); } if (mGalleryProvider == null) { finish(); return; } mGalleryProvider.start(); // Get start page int startPage; if (savedInstanceState == null) { startPage = mPage >= 0 ? mPage : mGalleryProvider.getStartPage(); } else { startPage = mCurrentIndex; } setContentView(R.layout.activity_gallery); mGLRootView = (GLRootView) ViewUtils.$$(this, R.id.gl_root_view); mGalleryAdapter = new GalleryAdapter(mGLRootView, mGalleryProvider); Resources resources = getResources(); int primaryColor = ResourcesUtils.getAttrColor(this, R.attr.colorPrimary); mGalleryView = new GalleryView.Builder(this, mGalleryAdapter) .setListener(this) .setLayoutMode(Settings.getReadingDirection()) .setScaleMode(Settings.getPageScaling()) .setStartPosition(Settings.getStartPosition()) .setStartPage(startPage) .setBackgroundColor(resources.getColor(R.color.gallery_background)) .setEdgeColor(primaryColor & 0xffffff | 0x33000000) .setPagerInterval(resources.getDimensionPixelOffset(R.dimen.gallery_pager_interval)) .setScrollInterval(resources.getDimensionPixelOffset(R.dimen.gallery_scroll_interval)) .setPageMinHeight(resources.getDimensionPixelOffset(R.dimen.gallery_page_min_height)) .setPageInfoInterval(resources.getDimensionPixelOffset(R.dimen.gallery_page_info_interval)) .setProgressColor(primaryColor) .setProgressSize(resources.getDimensionPixelOffset(R.dimen.gallery_progress_size)) .setPageTextColor(resources.getColor(R.color.secondary_text_default_dark)) .setPageTextSize(resources.getDimensionPixelOffset(R.dimen.gallery_page_text_size)) .setPageTextTypeface(Typeface.DEFAULT) .setErrorTextColor(resources.getColor(R.color.red_500)) .setErrorTextSize(resources.getDimensionPixelOffset(R.dimen.gallery_error_text_size)) .setDefaultErrorString(resources.getString(R.string.error_unknown)) .setEmptyString(resources.getString(R.string.error_empty)) .build(); mGLRootView.setContentPane(mGalleryView); mGalleryProvider.setListener(mGalleryAdapter); mGalleryProvider.setGLRoot(mGLRootView); // System UI helper if (Settings.getReadingFullscreen()) { int systemUiLevel; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { systemUiLevel = SystemUiHelper.LEVEL_IMMERSIVE; } else { systemUiLevel = SystemUiHelper.LEVEL_HIDE_STATUS_BAR; } mSystemUiHelper = new SystemUiHelper(this, systemUiLevel, SystemUiHelper.FLAG_LAYOUT_IN_SCREEN_OLDER_DEVICES | SystemUiHelper.FLAG_IMMERSIVE_STICKY); mSystemUiHelper.hide(); mShowSystemUi = false; } mMaskView = (ColorView) ViewUtils.$$(this, R.id.mask); mClock = ViewUtils.$$(this, R.id.clock); mProgress = (TextView) ViewUtils.$$(this, R.id.progress); mBattery = ViewUtils.$$(this, R.id.battery); mClock.setVisibility(Settings.getShowClock() ? View.VISIBLE : View.GONE); mProgress.setVisibility(Settings.getShowProgress() ? View.VISIBLE : View.GONE); mBattery.setVisibility(Settings.getShowBattery() ? View.VISIBLE : View.GONE); mSeekBarPanel = ViewUtils.$$(this, R.id.seek_bar_panel); mLeftText = (TextView) ViewUtils.$$(mSeekBarPanel, R.id.left); mRightText = (TextView) ViewUtils.$$(mSeekBarPanel, R.id.right); mSeekBar = (ReversibleSeekBar) ViewUtils.$$(mSeekBarPanel, R.id.seek_bar); mSeekBar.setOnSeekBarChangeListener(this); mSize = mGalleryProvider.size(); mCurrentIndex = startPage; mLayoutMode = mGalleryView.getLayoutMode(); updateSlider(); // Update keep screen on if (Settings.getKeepScreenOn()) { getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } else { getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } // Orientation int orientation; switch (Settings.getScreenRotation()) { default: case 0: orientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; break; case 1: orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT; break; case 2: orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE; break; } setRequestedOrientation(orientation); // Screen lightness setScreenLightness(Settings.getCustomScreenLightness(), Settings.getScreenLightness()); if (Settings.getGuideGallery()) { FrameLayout mainLayout = (FrameLayout) ViewUtils.$$(this, R.id.main); mainLayout.addView(new GalleryGuideView(this)); } } @Override protected void onDestroy() { super.onDestroy(); mGLRootView = null; mGalleryView = null; if (mGalleryAdapter != null) { mGalleryAdapter.clearUploader(); mGalleryAdapter = null; } if (mGalleryProvider != null) { mGalleryProvider.setListener(null); mGalleryProvider.stop(); mGalleryProvider = null; } mMaskView = null; mClock = null; mProgress = null; mBattery = null; mSeekBarPanel = null; mLeftText = null; mRightText = null; mSeekBar = null; SimpleHandler.getInstance().removeCallbacks(mHideSliderRunnable); } @Override protected void onPause() { super.onPause(); if (mGLRootView != null) { mGLRootView.onPause(); } } @Override protected void onResume() { super.onResume(); if (mGLRootView != null) { mGLRootView.onResume(); } } @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); if (hasFocus && mSystemUiHelper != null) { if (mShowSystemUi) { mSystemUiHelper.show(); } else { mSystemUiHelper.hide(); } } } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (mGalleryView == null) { return super.onKeyDown(keyCode, event); } // Check volume if (Settings.getVolumePage()) { if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) { if (mLayoutMode == GalleryView.LAYOUT_RIGHT_TO_LEFT) { mGalleryView.pageRight(); } else { mGalleryView.pageLeft(); } return true; } else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { if (mLayoutMode == GalleryView.LAYOUT_RIGHT_TO_LEFT) { mGalleryView.pageLeft(); } else { mGalleryView.pageRight(); } return true; } } // Check keyboard and Dpad switch (keyCode) { case KeyEvent.KEYCODE_PAGE_UP: case KeyEvent.KEYCODE_DPAD_UP: if (mLayoutMode == GalleryView.LAYOUT_RIGHT_TO_LEFT) { mGalleryView.pageRight(); } else { mGalleryView.pageLeft(); } return true; case KeyEvent.KEYCODE_DPAD_LEFT: mGalleryView.pageLeft(); return true; case KeyEvent.KEYCODE_PAGE_DOWN: case KeyEvent.KEYCODE_DPAD_DOWN: if (mLayoutMode == GalleryView.LAYOUT_RIGHT_TO_LEFT) { mGalleryView.pageLeft(); } else { mGalleryView.pageRight(); } return true; case KeyEvent.KEYCODE_DPAD_RIGHT: mGalleryView.pageRight(); return true; case KeyEvent.KEYCODE_DPAD_CENTER: case KeyEvent.KEYCODE_SPACE: case KeyEvent.KEYCODE_MENU: onTapMenuArea(); return true; } return super.onKeyDown(keyCode, event); } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { // Check volume if (Settings.getVolumePage()) { if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP) { return true; } } // Check keyboard and Dpad if (keyCode == KeyEvent.KEYCODE_PAGE_UP || keyCode == KeyEvent.KEYCODE_PAGE_DOWN || keyCode == KeyEvent.KEYCODE_DPAD_LEFT || keyCode == KeyEvent.KEYCODE_DPAD_UP || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT || keyCode == KeyEvent.KEYCODE_DPAD_DOWN || keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_SPACE || keyCode == KeyEvent.KEYCODE_MENU) { return true; } return super.onKeyUp(keyCode, event); } private GalleryPageView findPageByIndex(int index) { if (mGalleryView != null) { return mGalleryView.findPageByIndex(index); } else { return null; } } @SuppressLint("SetTextI18n") private void updateProgress() { if (mProgress == null) { return; } if (mSize <= 0 || mCurrentIndex < 0) { mProgress.setText(null); } else { mProgress.setText((mCurrentIndex + 1) + "/" + mSize); } } @SuppressLint("SetTextI18n") private void updateSlider() { if (mSeekBar == null || mRightText == null || mLeftText == null || mSize <= 0 || mCurrentIndex < 0) { return; } TextView start; TextView end; if (mLayoutMode == GalleryView.LAYOUT_RIGHT_TO_LEFT) { start = mRightText; end = mLeftText; mSeekBar.setReverse(true); } else { start = mLeftText; end = mRightText; mSeekBar.setReverse(false); } start.setText(Integer.toString(mCurrentIndex + 1)); end.setText(Integer.toString(mSize)); mSeekBar.setMax(mSize - 1); mSeekBar.setProgress(mCurrentIndex); } @Override @SuppressLint("SetTextI18n") public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { TextView start; if (mLayoutMode == GalleryView.LAYOUT_RIGHT_TO_LEFT) { start = mRightText; } else { start = mLeftText; } if (fromUser && null != start) { start.setText(Integer.toString(progress + 1)); } } @Override public void onStartTrackingTouch(SeekBar seekBar) { SimpleHandler.getInstance().removeCallbacks(mHideSliderRunnable); } @Override public void onStopTrackingTouch(SeekBar seekBar) { SimpleHandler.getInstance().postDelayed(mHideSliderRunnable, HIDE_SLIDER_DELAY); int progress = seekBar.getProgress(); if (progress != mCurrentIndex && null != mGalleryView) { mGalleryView.setCurrentPage(progress); } } @Override public void onUpdateCurrentIndex(int index) { if (null != mGalleryProvider) { mGalleryProvider.putStartPage(index); } NotifyTask task = mNotifyTaskPool.pop(); if (task == null) { task = new NotifyTask(); } task.setData(NotifyTask.KEY_CURRENT_INDEX, index); SimpleHandler.getInstance().post(task); } @Override public void onTapSliderArea() { NotifyTask task = mNotifyTaskPool.pop(); if (task == null) { task = new NotifyTask(); } task.setData(NotifyTask.KEY_TAP_SLIDER_AREA, 0); SimpleHandler.getInstance().post(task); } @Override public void onTapMenuArea() { NotifyTask task = mNotifyTaskPool.pop(); if (task == null) { task = new NotifyTask(); } task.setData(NotifyTask.KEY_TAP_MENU_AREA, 0); SimpleHandler.getInstance().post(task); } @Override public void onLongPressPage(int index) { NotifyTask task = mNotifyTaskPool.pop(); if (task == null) { task = new NotifyTask(); } task.setData(NotifyTask.KEY_LONG_PRESS_PAGE, index); SimpleHandler.getInstance().post(task); } private void showSlider(View sliderPanel) { if (null != mSeekBarPanelAnimator) { mSeekBarPanelAnimator.cancel(); mSeekBarPanelAnimator = null; } sliderPanel.setTranslationY(sliderPanel.getHeight()); sliderPanel.setVisibility(View.VISIBLE); mSeekBarPanelAnimator = ObjectAnimator.ofFloat(sliderPanel, "translationY", 0.0f); mSeekBarPanelAnimator.setDuration(SLIDER_ANIMATION_DURING); mSeekBarPanelAnimator.setInterpolator(AnimationUtils.FAST_SLOW_INTERPOLATOR); mSeekBarPanelAnimator.addUpdateListener(mUpdateSliderListener); mSeekBarPanelAnimator.addListener(mShowSliderListener); mSeekBarPanelAnimator.start(); if (null != mSystemUiHelper) { mSystemUiHelper.show(); mShowSystemUi = true; } } private void hideSlider(View sliderPanel) { if (null != mSeekBarPanelAnimator) { mSeekBarPanelAnimator.cancel(); mSeekBarPanelAnimator = null; } mSeekBarPanelAnimator = ObjectAnimator.ofFloat(sliderPanel, "translationY", sliderPanel.getHeight()); mSeekBarPanelAnimator.setDuration(SLIDER_ANIMATION_DURING); mSeekBarPanelAnimator.setInterpolator(AnimationUtils.SLOW_FAST_INTERPOLATOR); mSeekBarPanelAnimator.addUpdateListener(mUpdateSliderListener); mSeekBarPanelAnimator.addListener(mHideSliderListener); mSeekBarPanelAnimator.start(); if (null != mSystemUiHelper) { mSystemUiHelper.hide(); mShowSystemUi = false; } } /** * @param lightness 0 - 200 */ private void setScreenLightness(boolean enable, int lightness) { if (null == mMaskView) { return; } Window w = getWindow(); WindowManager.LayoutParams lp = w.getAttributes(); if (enable) { lightness = MathUtils.clamp(lightness, 0, 200); if (lightness > 100) { mMaskView.setColor(0); // Avoid BRIGHTNESS_OVERRIDE_OFF, // screen may be off when lp.screenBrightness is 0.0f lp.screenBrightness = Math.max((lightness - 100) / 100.0f, 0.01f); } else { mMaskView.setColor(MathUtils.lerp(0xde, 0x00, lightness / 100.0f) << 24); lp.screenBrightness = 0.01f; } } else { mMaskView.setColor(0); lp.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE; } w.setAttributes(lp); } private class GalleryMenuHelper implements DialogInterface.OnClickListener { private final View mView; private final Spinner mScreenRotation; private final Spinner mReadingDirection; private final Spinner mScaleMode; private final Spinner mStartPosition; private final SwitchCompat mKeepScreenOn; private final SwitchCompat mShowClock; private final SwitchCompat mShowProgress; private final SwitchCompat mShowBattery; private final SwitchCompat mVolumePage; private final SwitchCompat mReadingFullscreen; private final SwitchCompat mCustomScreenLightness; private final SeekBar mScreenLightness; @SuppressLint("InflateParams") public GalleryMenuHelper(Context context) { mView = LayoutInflater.from(context).inflate(R.layout.dialog_gallery_menu, null); mScreenRotation = (Spinner) mView.findViewById(R.id.screen_rotation); mReadingDirection = (Spinner) mView.findViewById(R.id.reading_direction); mScaleMode = (Spinner) mView.findViewById(R.id.page_scaling); mStartPosition = (Spinner) mView.findViewById(R.id.start_position); mKeepScreenOn = (SwitchCompat) mView.findViewById(R.id.keep_screen_on); mShowClock = (SwitchCompat) mView.findViewById(R.id.show_clock); mShowProgress = (SwitchCompat) mView.findViewById(R.id.show_progress); mShowBattery = (SwitchCompat) mView.findViewById(R.id.show_battery); mVolumePage = (SwitchCompat) mView.findViewById(R.id.volume_page); mReadingFullscreen = (SwitchCompat) mView.findViewById(R.id.reading_fullscreen); mCustomScreenLightness = (SwitchCompat) mView.findViewById(R.id.custom_screen_lightness); mScreenLightness = (SeekBar) mView.findViewById(R.id.screen_lightness); mScreenRotation.setSelection(Settings.getScreenRotation()); mReadingDirection.setSelection(Settings.getReadingDirection()); mScaleMode.setSelection(Settings.getPageScaling()); mStartPosition.setSelection(Settings.getStartPosition()); mKeepScreenOn.setChecked(Settings.getKeepScreenOn()); mShowClock.setChecked(Settings.getShowClock()); mShowProgress.setChecked(Settings.getShowProgress()); mShowBattery.setChecked(Settings.getShowBattery()); mVolumePage.setChecked(Settings.getVolumePage()); mReadingFullscreen.setChecked(Settings.getReadingFullscreen()); mCustomScreenLightness.setChecked(Settings.getCustomScreenLightness()); mScreenLightness.setProgress(Settings.getScreenLightness()); mScreenLightness.setEnabled(Settings.getCustomScreenLightness()); mCustomScreenLightness.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { mScreenLightness.setEnabled(isChecked); } }); } public View getView() { return mView; } @Override public void onClick(DialogInterface dialog, int which) { int screenRotation = mScreenRotation.getSelectedItemPosition(); int layoutMode = GalleryView.sanitizeLayoutMode(mReadingDirection.getSelectedItemPosition()); int scaleMode = GalleryView.sanitizeScaleMode(mScaleMode.getSelectedItemPosition()); int startPosition = GalleryView.sanitizeStartPosition(mStartPosition.getSelectedItemPosition()); boolean keepScreenOn = mKeepScreenOn.isChecked(); boolean showClock = mShowClock.isChecked(); boolean showProgress = mShowProgress.isChecked(); boolean showBattery = mShowBattery.isChecked(); boolean volumePage = mVolumePage.isChecked(); boolean readingFullscreen = mReadingFullscreen.isChecked(); boolean customScreenLightness = mCustomScreenLightness.isChecked(); int screenLightness = mScreenLightness.getProgress(); boolean oldReadingFullscreen = Settings.getReadingFullscreen(); Settings.putScreenRotation(screenRotation); Settings.putReadingDirection(layoutMode); Settings.putPageScaling(scaleMode); Settings.putStartPosition(startPosition); Settings.putKeepScreenOn(keepScreenOn); Settings.putShowClock(showClock); Settings.putShowProgress(showProgress); Settings.putShowBattery(showBattery); Settings.putVolumePage(volumePage); Settings.putReadingFullscreen(readingFullscreen); Settings.putCustomScreenLightness(customScreenLightness); Settings.putScreenLightness(screenLightness); int orientation; switch (screenRotation) { default: case 0: orientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; break; case 1: orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT; break; case 2: orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE; break; } setRequestedOrientation(orientation); if (mGalleryView != null) { mGalleryView.setLayoutMode(layoutMode); mGalleryView.setScaleMode(scaleMode); mGalleryView.setStartPosition(startPosition); } if (keepScreenOn) { getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } else { getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } if (mClock != null) { mClock.setVisibility(showClock ? View.VISIBLE : View.GONE); } if (mProgress != null) { mProgress.setVisibility(showProgress ? View.VISIBLE : View.GONE); } if (mBattery != null) { mBattery.setVisibility(showBattery ? View.VISIBLE : View.GONE); } setScreenLightness(customScreenLightness, screenLightness); // Update slider mLayoutMode = layoutMode; updateSlider(); if (oldReadingFullscreen != readingFullscreen) { recreate(); } } } private void shareImage(int page) { if (null == mGalleryProvider) { return; } File dir = AppConfig.getExternalImageDir(); if (null == dir) { Toast.makeText(this, R.string.error_cant_create_temp_file, Toast.LENGTH_SHORT).show(); return; } UniFile file; if (null == (file = mGalleryProvider.save(page, UniFile.fromFile(dir), mGalleryProvider.getImageFilename(page)))) { Toast.makeText(this, R.string.error_cant_save_image, Toast.LENGTH_SHORT).show(); return; } String filename = file.getName(); if (filename == null) { Toast.makeText(this, R.string.error_cant_save_image, Toast.LENGTH_SHORT).show(); return; } String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension( MimeTypeMap.getFileExtensionFromUrl(filename)); if (TextUtils.isEmpty(mimeType)) { mimeType = "image/jpeg"; } Uri uri = new Uri.Builder() .scheme(ContentResolver.SCHEME_CONTENT) .authority("com.hippo.ehviewer.fileprovider") .appendPath("image") .appendPath(filename) .build(); Intent intent = new Intent(); intent.setAction(Intent.ACTION_SEND); intent.putExtra(Intent.EXTRA_STREAM, uri); intent.setType(mimeType); startActivity(Intent.createChooser(intent, getString(R.string.share_image))); // Sync media store sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, file.getUri())); } private void saveImage(int page) { if (null == mGalleryProvider) { return; } File dir = AppConfig.getExternalImageDir(); if (null == dir) { Toast.makeText(this, R.string.error_cant_save_image, Toast.LENGTH_SHORT).show(); return; } UniFile file; if (null == (file = mGalleryProvider.save(page, UniFile.fromFile(dir), mGalleryProvider.getImageFilename(page)))) { Toast.makeText(this, R.string.error_cant_save_image, Toast.LENGTH_SHORT).show(); return; } Toast.makeText(this, getString(R.string.image_saved, file.getUri()), Toast.LENGTH_SHORT).show(); // Sync media store sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, file.getUri())); } private void showPageDialog(final int page) { Resources resources = GalleryActivity.this.getResources(); new AlertDialog.Builder(GalleryActivity.this) .setTitle(resources.getString(R.string.page_menu_title, page + 1)) .setItems(R.array.page_menu_entries, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (mGalleryProvider == null) { return; } switch (which) { case 0: // Refresh mGalleryProvider.forceRequest(page); break; case 1: // Share shareImage(page); break; case 2: // Save saveImage(page); break; case 3: // Add a bookmark break; } } }).show(); } private class NotifyTask implements Runnable { public static final int KEY_LAYOUT_MODE = 0; public static final int KEY_SIZE = 1; public static final int KEY_CURRENT_INDEX = 2; public static final int KEY_TAP_SLIDER_AREA = 3; public static final int KEY_TAP_MENU_AREA = 4; public static final int KEY_LONG_PRESS_PAGE = 5; private int mKey; private int mValue; public void setData(int key, int value) { mKey = key; mValue = value; } private void onTapMenuArea() { AlertDialog.Builder builder = new AlertDialog.Builder(GalleryActivity.this); GalleryMenuHelper helper = new GalleryMenuHelper(builder.getContext()); builder.setTitle(R.string.gallery_menu_title) .setView(helper.getView()) .setPositiveButton(android.R.string.ok, helper).show(); } private void onTapSliderArea() { if (mSeekBarPanel == null || mSize <= 0 || mCurrentIndex < 0) { return; } SimpleHandler.getInstance().removeCallbacks(mHideSliderRunnable); if (mSeekBarPanel.getVisibility() == View.VISIBLE) { hideSlider(mSeekBarPanel); } else { showSlider(mSeekBarPanel); SimpleHandler.getInstance().postDelayed(mHideSliderRunnable, HIDE_SLIDER_DELAY); } } private void onLongPressPage(final int index) { showPageDialog(index); } @Override public void run() { switch (mKey) { case KEY_LAYOUT_MODE: GalleryActivity.this.mLayoutMode = mValue; updateSlider(); break; case KEY_SIZE: GalleryActivity.this.mSize = mValue; updateSlider(); updateProgress(); break; case KEY_CURRENT_INDEX: GalleryActivity.this.mCurrentIndex = mValue; updateSlider(); updateProgress(); break; case KEY_TAP_MENU_AREA: onTapMenuArea(); break; case KEY_TAP_SLIDER_AREA: onTapSliderArea(); break; case KEY_LONG_PRESS_PAGE: onLongPressPage(mValue); break; } mNotifyTaskPool.push(this); } } private class GalleryAdapter extends SimpleAdapter { public GalleryAdapter(@NonNull GLRootView glRootView, @NonNull GalleryProvider provider) { super(glRootView, provider); } @Override public void onDataChanged() { super.onDataChanged(); if (mGalleryProvider != null) { int size = mGalleryProvider.size(); NotifyTask task = mNotifyTaskPool.pop(); if (task == null) { task = new NotifyTask(); } task.setData(NotifyTask.KEY_SIZE, size); SimpleHandler.getInstance().post(task); } } } }