Initial support for custom images scaling (#40)

This commit is contained in:
inorichi 2016-01-27 01:48:40 +01:00
parent c6ecfb2f67
commit 0c9bc97fe8
19 changed files with 127 additions and 91 deletions

View file

@ -328,7 +328,6 @@ public class DownloadManager {
// Return the page list from the chapter's directory if it exists, null otherwise
public List<Page> getSavedPageList(Source source, Manga manga, Chapter chapter) {
List<Page> pages = null;
File chapterDir = getAbsoluteChapterDirectory(source, manga, chapter);
File pagesFile = new File(chapterDir, PAGE_LIST_FILE);
@ -337,14 +336,14 @@ public class DownloadManager {
if (pagesFile.exists()) {
reader = new JsonReader(new FileReader(pagesFile.getAbsolutePath()));
Type collectionType = new TypeToken<List<Page>>() {}.getType();
pages = gson.fromJson(reader, collectionType);
return gson.fromJson(reader, collectionType);
}
} catch (Exception e) {
Timber.e(e.getCause(), e.getMessage());
} finally {
if (reader != null) try { reader.close(); } catch (IOException e) { /* Do nothing */ }
}
return pages;
return null;
}
// Shortcut for the method above

View file

@ -47,7 +47,7 @@ public class DownloadQueue extends ArrayList<Download> {
}
public Observable<Download> getProgressObservable() {
return statusSubject
return statusSubject.onBackpressureBuffer()
.startWith(getActiveDownloads())
.flatMap(download -> {
if (download.getStatus() == Download.DOWNLOADING) {

View file

@ -88,6 +88,10 @@ public class PreferencesHelper {
return prefs.getInt(getKey(R.string.pref_default_viewer_key), 1);
}
public Preference<Integer> imageScaleType() {
return rxPrefs.getInteger(getKey(R.string.pref_image_scale_type_key), 1);
}
public Preference<Integer> portraitColumns() {
return rxPrefs.getInteger(getKey(R.string.pref_library_columns_portrait_key), 0);
}

View file

@ -7,6 +7,7 @@ import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.view.animation.Animation;
@ -44,7 +45,7 @@ public class ReaderMenu {
@Bind(R.id.lock_orientation) ImageButton lockOrientation;
@Bind(R.id.reader_selector) ImageButton readerSelector;
@Bind(R.id.reader_extra_settings) ImageButton extraSettings;
@Bind(R.id.reader_brightness) ImageButton brightnessSettings;
@Bind(R.id.reader_scale_type_selector) ImageButton scaleTypeSelector;
private MenuItem nextChapterBtn;
private MenuItem prevChapterBtn;
@ -56,7 +57,6 @@ public class ReaderMenu {
@State boolean showing;
private PopupWindow settingsPopup;
private PopupWindow brightnessPopup;
private boolean inverted;
private DecimalFormat decimalFormat;
@ -73,7 +73,7 @@ public class ReaderMenu {
decimalFormat = new DecimalFormat("#.###");
inverted = false;
initializeOptions();
initializeMenu();
}
public void add(Subscription subscription) {
@ -110,7 +110,6 @@ public class ReaderMenu {
bottomMenu.startAnimation(bottomMenuAnimation);
settingsPopup.dismiss();
brightnessPopup.dismiss();
showing = false;
}
@ -175,7 +174,7 @@ public class ReaderMenu {
if (nextChapterBtn != null) nextChapterBtn.setVisible(nextChapter != null);
}
private void initializeOptions() {
private void initializeMenu() {
// Orientation changes
add(preferences.lockOrientation().asObservable()
.subscribe(locked -> {
@ -190,6 +189,18 @@ public class ReaderMenu {
lockOrientation.setOnClickListener(v ->
preferences.lockOrientation().set(!preferences.lockOrientation().get()));
// Scale type selector
scaleTypeSelector.setOnClickListener(v -> {
showImmersiveDialog(new MaterialDialog.Builder(activity)
.items(R.array.image_scale_type)
.itemsCallbackSingleChoice(preferences.imageScaleType().get() - 1,
(d, itemView, which, text) -> {
preferences.imageScaleType().set(which + 1);
return true;
})
.build());
});
// Reader selector
readerSelector.setOnClickListener(v -> {
final Manga manga = activity.getPresenter().getManga();
@ -215,17 +226,6 @@ public class ReaderMenu {
settingsPopup.dismiss();
});
// Brightness popup
final View brightnessView = activity.getLayoutInflater().inflate(R.layout.reader_brightness, null);
brightnessPopup = new BrightnessPopupWindow(brightnessView);
brightnessSettings.setOnClickListener(v -> {
if (!brightnessPopup.isShowing())
brightnessPopup.showAtLocation(brightnessSettings,
Gravity.BOTTOM | Gravity.LEFT, 0, bottomMenu.getHeight());
else
brightnessPopup.dismiss();
});
}
private void showImmersiveDialog(Dialog dialog) {
@ -247,8 +247,11 @@ public class ReaderMenu {
@Bind(R.id.hide_status_bar) CheckBox hideStatusBar;
@Bind(R.id.keep_screen_on) CheckBox keepScreenOn;
@Bind(R.id.reader_theme) CheckBox readerTheme;
@Bind(R.id.image_decoder_container) ViewGroup imageDecoderContainer;
@Bind(R.id.image_decoder) TextView imageDecoder;
@Bind(R.id.image_decoder_initial) TextView imageDecoderInitial;
@Bind(R.id.custom_brightness) CheckBox customBrightness;
@Bind(R.id.brightness_seekbar) SeekBar brightnessSeekbar;
public SettingsPopupWindow(View view) {
super(view, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
@ -282,7 +285,7 @@ public class ReaderMenu {
readerTheme.setOnCheckedChangeListener((view, isChecked) ->
preferences.readerTheme().set(isChecked ? 1 : 0));
imageDecoder.setOnClickListener(v -> {
imageDecoderContainer.setOnClickListener(v -> {
showImmersiveDialog(new MaterialDialog.Builder(activity)
.title(R.string.pref_image_decoder)
.items(R.array.image_decoders)
@ -294,6 +297,21 @@ public class ReaderMenu {
})
.build());
});
add(preferences.customBrightness()
.asObservable()
.subscribe(isEnabled -> {
customBrightness.setChecked(isEnabled);
brightnessSeekbar.setEnabled(isEnabled);
}));
customBrightness.setOnCheckedChangeListener((view, isChecked) ->
preferences.customBrightness().set(isChecked));
brightnessSeekbar.setMax(100);
brightnessSeekbar.setProgress(Math.round(
preferences.customBrightnessValue().get() * brightnessSeekbar.getMax()));
brightnessSeekbar.setOnSeekBarChangeListener(new BrightnessSeekBarChangeListener());
}
private void setDecoderInitial(int decoder) {
@ -314,37 +332,6 @@ public class ReaderMenu {
}
class BrightnessPopupWindow extends PopupWindow {
@Bind(R.id.custom_brightness) CheckBox customBrightness;
@Bind(R.id.brightness_seekbar) SeekBar brightnessSeekbar;
public BrightnessPopupWindow(View view) {
super(view, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
setAnimationStyle(R.style.reader_brightness_popup_animation);
ButterKnife.bind(this, view);
initializePopupMenu();
}
private void initializePopupMenu() {
add(preferences.customBrightness()
.asObservable()
.subscribe(isEnabled -> {
customBrightness.setChecked(isEnabled);
brightnessSeekbar.setEnabled(isEnabled);
}));
customBrightness.setOnCheckedChangeListener((view, isChecked) ->
preferences.customBrightness().set(isChecked));
brightnessSeekbar.setMax(100);
brightnessSeekbar.setProgress(Math.round(
preferences.customBrightnessValue().get() * brightnessSeekbar.getMax()));
brightnessSeekbar.setOnSeekBarChangeListener(new BrightnessSeekBarChangeListener());
}
}
class PageSeekBarChangeListener implements SeekBar.OnSeekBarChangeListener {
@Override

View file

@ -22,6 +22,8 @@ public abstract class PagerReader extends BaseReader {
protected boolean transitions;
protected CompositeSubscription subscriptions;
protected int scaleType = 1;
protected void initializePager(Pager pager) {
this.pager = pager;
pager.setLayoutParams(new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
@ -66,6 +68,13 @@ public abstract class PagerReader extends BaseReader {
.distinctUntilChanged()
.subscribe(v -> adapter.notifyDataSetChanged()));
subscriptions.add(getReaderActivity().getPreferences().imageScaleType()
.asObservable()
.doOnNext(this::setImageScaleType)
.skip(1)
.distinctUntilChanged()
.subscribe(v -> adapter.notifyDataSetChanged()));
subscriptions.add(getReaderActivity().getPreferences().enableTransitions()
.asObservable()
.subscribe(value -> transitions = value));
@ -110,6 +119,10 @@ public abstract class PagerReader extends BaseReader {
return pager.onImageTouch(motionEvent);
}
private void setImageScaleType(int scaleType) {
this.scaleType = scaleType;
}
public abstract void onFirstPageOut();
public abstract void onLastPageOut();

View file

@ -25,7 +25,6 @@ import eu.kanade.tachiyomi.R;
import eu.kanade.tachiyomi.data.source.model.Page;
import eu.kanade.tachiyomi.ui.base.fragment.BaseFragment;
import eu.kanade.tachiyomi.ui.reader.ReaderActivity;
import eu.kanade.tachiyomi.ui.reader.viewer.base.BaseReader;
import rx.Observable;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
@ -55,7 +54,7 @@ public class PagerReaderFragment extends BaseFragment {
View view = inflater.inflate(R.layout.item_pager_reader, container, false);
ButterKnife.bind(this, view);
ReaderActivity activity = getReaderActivity();
BaseReader parentFragment = (BaseReader) getParentFragment();
PagerReader parentFragment = (PagerReader) getParentFragment();
if (activity.getReaderTheme() == ReaderActivity.BLACK_THEME) {
progressText.setTextColor(ContextCompat.getColor(getContext(), R.color.light_grey));
@ -65,7 +64,7 @@ public class PagerReaderFragment extends BaseFragment {
imageView.setMaxDimensions(activity.getMaxBitmapSize(), activity.getMaxBitmapSize());
imageView.setDoubleTapZoomStyle(SubsamplingScaleImageView.ZOOM_FOCUS_FIXED);
imageView.setPanLimit(SubsamplingScaleImageView.PAN_LIMIT_INSIDE);
imageView.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE);
imageView.setMinimumScaleType(parentFragment.scaleType);
imageView.setRegionDecoderClass(parentFragment.getRegionDecoderClass());
imageView.setOnTouchListener((v, motionEvent) -> parentFragment.onImageTouch(motionEvent));
imageView.setOnImageEventListener(new SubsamplingScaleImageView.DefaultOnImageEventListener() {

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 332 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 584 B

View file

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="@color/reader_menu_background"
android:paddingRight="10dp"
android:paddingLeft="5dp"
android:paddingTop="5dp"
android:paddingBottom="5dp">
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/reader_menu_settings_item"
android:text="@string/pref_custom_brightness"
android:id="@+id/custom_brightness" />
<SeekBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/brightness_seekbar" />
</LinearLayout>

View file

@ -74,18 +74,19 @@
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:id="@+id/reader_brightness"
android:src="@drawable/ic_brightness_high"
android:id="@+id/lock_orientation"
android:src="@drawable/ic_screen_rotation"
android:layout_gravity="center_vertical"
android:background="?android:selectableItemBackground" />
<ImageButton
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:id="@+id/lock_orientation"
android:src="@drawable/ic_screen_rotation"
android:id="@+id/reader_scale_type_selector"
android:src="@drawable/ic_zoom_out_map_white_24dp"
android:layout_gravity="center_vertical"
android:background="?android:selectableItemBackground" />
<ImageButton
android:layout_width="0dp"
android:layout_height="match_parent"

View file

@ -10,7 +10,8 @@
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:id="@+id/image_decoder_container">
<TextView
android:id="@+id/image_decoder_initial"
@ -53,4 +54,16 @@
style="@style/reader_menu_settings_item"
android:text="@string/pref_keep_screen_on"/>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/reader_menu_settings_item"
android:text="@string/pref_custom_brightness"
android:id="@+id/custom_brightness" />
<SeekBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/brightness_seekbar" />
</LinearLayout>

View file

@ -48,6 +48,22 @@
<item>1</item>
</string-array>
<string-array name="image_scale_type">
<item>@string/scale_type_fit_screen</item>
<item>@string/scale_type_stretch</item>
<item>@string/scale_type_fit_width</item>
<item>@string/scale_type_fit_height</item>
<item>@string/scale_type_original_size</item>
</string-array>
<string-array name="image_scale_type_values">
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
<item>5</item>
</string-array>
<string-array name="library_update_interval">
<item>@string/update_never</item>
<item>@string/update_1hour</item>

View file

@ -16,6 +16,7 @@
<string name="pref_ask_update_manga_sync_key">pref_ask_update_manga_sync_key</string>
<string name="pref_default_viewer_key">pref_default_viewer_key</string>
<string name="pref_image_scale_type_key">pref_image_scale_type_key</string>
<string name="pref_hide_status_bar_key">pref_hide_status_bar_key</string>
<string name="pref_lock_orientation_key">pref_lock_orientation_key</string>
<string name="pref_enable_transitions_key">pref_enable_transitions_key</string>

View file

@ -97,6 +97,12 @@
<string name="pref_image_decoder">Image decoder</string>
<string name="rapid_decoder">Rapid</string>
<string name="skia_decoder">Skia</string>
<string name="pref_image_scale_type">Scale type</string>
<string name="scale_type_fit_screen">Fit screen</string>
<string name="scale_type_stretch">Stretch</string>
<string name="scale_type_fit_width">Fit width</string>
<string name="scale_type_fit_height">Fit height</string>
<string name="scale_type_original_size">Original size</string>
<!-- Downloads section -->
<string name="pref_download_directory">Downloads directory</string>

View file

@ -25,6 +25,14 @@
android:defaultValue="1"
android:summary="%s"/>
<eu.kanade.tachiyomi.widget.preference.IntListPreference
android:title="@string/pref_image_scale_type"
android:key="@string/pref_image_scale_type_key"
android:entries="@array/image_scale_type"
android:entryValues="@array/image_scale_type_values"
android:defaultValue="1"
android:summary="%s"/>
<eu.kanade.tachiyomi.widget.preference.IntListPreference
android:title="@string/pref_reader_theme"
android:key="@string/pref_reader_theme_key"