mirror of
https://github.com/mihonapp/mihon.git
synced 2024-11-21 20:47:03 -05:00
Implement zoom start position. Closes #92. Rapid decoder properly throws an error when it fails to decode.
This commit is contained in:
parent
6aa07dd17e
commit
391550f49a
16 changed files with 120 additions and 11 deletions
|
@ -116,6 +116,10 @@ public class PreferencesHelper {
|
||||||
return rxPrefs.getInteger(getKey(R.string.pref_image_decoder_key), 0);
|
return rxPrefs.getInteger(getKey(R.string.pref_image_decoder_key), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Preference<Integer> zoomStart() {
|
||||||
|
return rxPrefs.getInteger(getKey(R.string.pref_zoom_start_key), 1);
|
||||||
|
}
|
||||||
|
|
||||||
public Preference<Integer> readerTheme() {
|
public Preference<Integer> readerTheme() {
|
||||||
return rxPrefs.getInteger(getKey(R.string.pref_reader_theme_key), 0);
|
return rxPrefs.getInteger(getKey(R.string.pref_reader_theme_key), 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,9 +43,10 @@ public class ReaderMenu {
|
||||||
@Bind(R.id.page_seeker) SeekBar seekBar;
|
@Bind(R.id.page_seeker) SeekBar seekBar;
|
||||||
@Bind(R.id.total_pages) TextView totalPages;
|
@Bind(R.id.total_pages) TextView totalPages;
|
||||||
@Bind(R.id.lock_orientation) ImageButton lockOrientation;
|
@Bind(R.id.lock_orientation) ImageButton lockOrientation;
|
||||||
|
@Bind(R.id.reader_zoom_selector) ImageButton zoomSelector;
|
||||||
|
@Bind(R.id.reader_scale_type_selector) ImageButton scaleTypeSelector;
|
||||||
@Bind(R.id.reader_selector) ImageButton readerSelector;
|
@Bind(R.id.reader_selector) ImageButton readerSelector;
|
||||||
@Bind(R.id.reader_extra_settings) ImageButton extraSettings;
|
@Bind(R.id.reader_extra_settings) ImageButton extraSettings;
|
||||||
@Bind(R.id.reader_scale_type_selector) ImageButton scaleTypeSelector;
|
|
||||||
|
|
||||||
private MenuItem nextChapterBtn;
|
private MenuItem nextChapterBtn;
|
||||||
private MenuItem prevChapterBtn;
|
private MenuItem prevChapterBtn;
|
||||||
|
@ -189,9 +190,23 @@ public class ReaderMenu {
|
||||||
lockOrientation.setOnClickListener(v ->
|
lockOrientation.setOnClickListener(v ->
|
||||||
preferences.lockOrientation().set(!preferences.lockOrientation().get()));
|
preferences.lockOrientation().set(!preferences.lockOrientation().get()));
|
||||||
|
|
||||||
|
// Zoom selector
|
||||||
|
zoomSelector.setOnClickListener(v -> {
|
||||||
|
showImmersiveDialog(new MaterialDialog.Builder(activity)
|
||||||
|
.title(R.string.pref_zoom_start)
|
||||||
|
.items(R.array.zoom_start)
|
||||||
|
.itemsCallbackSingleChoice(preferences.zoomStart().get() - 1,
|
||||||
|
(d, itemView, which, text) -> {
|
||||||
|
preferences.zoomStart().set(which + 1);
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.build());
|
||||||
|
});
|
||||||
|
|
||||||
// Scale type selector
|
// Scale type selector
|
||||||
scaleTypeSelector.setOnClickListener(v -> {
|
scaleTypeSelector.setOnClickListener(v -> {
|
||||||
showImmersiveDialog(new MaterialDialog.Builder(activity)
|
showImmersiveDialog(new MaterialDialog.Builder(activity)
|
||||||
|
.title(R.string.pref_image_scale_type)
|
||||||
.items(R.array.image_scale_type)
|
.items(R.array.image_scale_type)
|
||||||
.itemsCallbackSingleChoice(preferences.imageScaleType().get() - 1,
|
.itemsCallbackSingleChoice(preferences.imageScaleType().get() - 1,
|
||||||
(d, itemView, which, text) -> {
|
(d, itemView, which, text) -> {
|
||||||
|
@ -205,6 +220,7 @@ public class ReaderMenu {
|
||||||
readerSelector.setOnClickListener(v -> {
|
readerSelector.setOnClickListener(v -> {
|
||||||
final Manga manga = activity.getPresenter().getManga();
|
final Manga manga = activity.getPresenter().getManga();
|
||||||
showImmersiveDialog(new MaterialDialog.Builder(activity)
|
showImmersiveDialog(new MaterialDialog.Builder(activity)
|
||||||
|
.title(R.string.pref_viewer_type)
|
||||||
.items(R.array.viewers_selector)
|
.items(R.array.viewers_selector)
|
||||||
.itemsCallbackSingleChoice(manga.viewer,
|
.itemsCallbackSingleChoice(manga.viewer,
|
||||||
(d, itemView, which, text) -> {
|
(d, itemView, which, text) -> {
|
||||||
|
|
|
@ -6,10 +6,13 @@ import android.view.ViewGroup;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.R;
|
import eu.kanade.tachiyomi.R;
|
||||||
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper;
|
||||||
import eu.kanade.tachiyomi.data.source.model.Page;
|
import eu.kanade.tachiyomi.data.source.model.Page;
|
||||||
import eu.kanade.tachiyomi.ui.reader.viewer.base.BaseReader;
|
import eu.kanade.tachiyomi.ui.reader.viewer.base.BaseReader;
|
||||||
import eu.kanade.tachiyomi.ui.reader.viewer.base.OnChapterBoundariesOutListener;
|
import eu.kanade.tachiyomi.ui.reader.viewer.base.OnChapterBoundariesOutListener;
|
||||||
import eu.kanade.tachiyomi.ui.reader.viewer.base.OnChapterSingleTapListener;
|
import eu.kanade.tachiyomi.ui.reader.viewer.base.OnChapterSingleTapListener;
|
||||||
|
import eu.kanade.tachiyomi.ui.reader.viewer.pager.horizontal.LeftToRightReader;
|
||||||
|
import eu.kanade.tachiyomi.ui.reader.viewer.pager.horizontal.RightToLeftReader;
|
||||||
import rx.subscriptions.CompositeSubscription;
|
import rx.subscriptions.CompositeSubscription;
|
||||||
|
|
||||||
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
|
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
|
||||||
|
@ -24,6 +27,12 @@ public abstract class PagerReader extends BaseReader {
|
||||||
protected CompositeSubscription subscriptions;
|
protected CompositeSubscription subscriptions;
|
||||||
|
|
||||||
protected int scaleType = 1;
|
protected int scaleType = 1;
|
||||||
|
protected int zoomStart = 1;
|
||||||
|
|
||||||
|
public static final int ALIGN_AUTO = 1;
|
||||||
|
public static final int ALIGN_LEFT = 2;
|
||||||
|
public static final int ALIGN_RIGHT = 3;
|
||||||
|
public static final int ALIGN_CENTER = 4;
|
||||||
|
|
||||||
protected void initializePager(Pager pager) {
|
protected void initializePager(Pager pager) {
|
||||||
this.pager = pager;
|
this.pager = pager;
|
||||||
|
@ -61,22 +70,30 @@ public abstract class PagerReader extends BaseReader {
|
||||||
adapter = new PagerReaderAdapter(getChildFragmentManager());
|
adapter = new PagerReaderAdapter(getChildFragmentManager());
|
||||||
pager.setAdapter(adapter);
|
pager.setAdapter(adapter);
|
||||||
|
|
||||||
|
PreferencesHelper preferences = getReaderActivity().getPreferences();
|
||||||
subscriptions = new CompositeSubscription();
|
subscriptions = new CompositeSubscription();
|
||||||
subscriptions.add(getReaderActivity().getPreferences().imageDecoder()
|
subscriptions.add(preferences.imageDecoder()
|
||||||
.asObservable()
|
.asObservable()
|
||||||
.doOnNext(this::setDecoderClass)
|
.doOnNext(this::setDecoderClass)
|
||||||
.skip(1)
|
.skip(1)
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
.subscribe(v -> adapter.notifyDataSetChanged()));
|
.subscribe(v -> adapter.notifyDataSetChanged()));
|
||||||
|
|
||||||
subscriptions.add(getReaderActivity().getPreferences().imageScaleType()
|
subscriptions.add(preferences.imageScaleType()
|
||||||
.asObservable()
|
.asObservable()
|
||||||
.doOnNext(this::setImageScaleType)
|
.doOnNext(this::setImageScaleType)
|
||||||
.skip(1)
|
.skip(1)
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
.subscribe(v -> adapter.notifyDataSetChanged()));
|
.subscribe(v -> adapter.notifyDataSetChanged()));
|
||||||
|
|
||||||
subscriptions.add(getReaderActivity().getPreferences().enableTransitions()
|
subscriptions.add(preferences.zoomStart()
|
||||||
|
.asObservable()
|
||||||
|
.doOnNext(this::setZoomStart)
|
||||||
|
.skip(1)
|
||||||
|
.distinctUntilChanged()
|
||||||
|
.subscribe(v -> adapter.notifyDataSetChanged()));
|
||||||
|
|
||||||
|
subscriptions.add(preferences.enableTransitions()
|
||||||
.asObservable()
|
.asObservable()
|
||||||
.subscribe(value -> transitions = value));
|
.subscribe(value -> transitions = value));
|
||||||
|
|
||||||
|
@ -125,6 +142,19 @@ public abstract class PagerReader extends BaseReader {
|
||||||
this.scaleType = scaleType;
|
this.scaleType = scaleType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setZoomStart(int zoomStart) {
|
||||||
|
if (zoomStart == ALIGN_AUTO) {
|
||||||
|
if (this instanceof LeftToRightReader)
|
||||||
|
setZoomStart(ALIGN_LEFT);
|
||||||
|
else if (this instanceof RightToLeftReader)
|
||||||
|
setZoomStart(ALIGN_RIGHT);
|
||||||
|
else
|
||||||
|
setZoomStart(ALIGN_CENTER);
|
||||||
|
} else {
|
||||||
|
this.zoomStart = zoomStart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public abstract void onFirstPageOut();
|
public abstract void onFirstPageOut();
|
||||||
public abstract void onLastPageOut();
|
public abstract void onLastPageOut();
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package eu.kanade.tachiyomi.ui.reader.viewer.pager;
|
package eu.kanade.tachiyomi.ui.reader.viewer.pager;
|
||||||
|
|
||||||
|
import android.graphics.PointF;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.content.ContextCompat;
|
import android.support.v4.content.ContextCompat;
|
||||||
|
@ -70,6 +71,23 @@ public class PagerReaderFragment extends BaseFragment {
|
||||||
imageView.setVerticalScrollingParent(parentFragment instanceof VerticalReader);
|
imageView.setVerticalScrollingParent(parentFragment instanceof VerticalReader);
|
||||||
imageView.setOnTouchListener((v, motionEvent) -> parentFragment.onImageTouch(motionEvent));
|
imageView.setOnTouchListener((v, motionEvent) -> parentFragment.onImageTouch(motionEvent));
|
||||||
imageView.setOnImageEventListener(new SubsamplingScaleImageView.DefaultOnImageEventListener() {
|
imageView.setOnImageEventListener(new SubsamplingScaleImageView.DefaultOnImageEventListener() {
|
||||||
|
@Override
|
||||||
|
public void onReady() {
|
||||||
|
switch (parentFragment.zoomStart) {
|
||||||
|
case PagerReader.ALIGN_LEFT:
|
||||||
|
imageView.setScaleAndCenter(imageView.getScale(), new PointF(0, 0));
|
||||||
|
break;
|
||||||
|
case PagerReader.ALIGN_RIGHT:
|
||||||
|
imageView.setScaleAndCenter(imageView.getScale(), new PointF(99999f, 0));
|
||||||
|
break;
|
||||||
|
case PagerReader.ALIGN_CENTER:
|
||||||
|
PointF center = imageView.getCenter();
|
||||||
|
center.y = 0;
|
||||||
|
imageView.setScaleAndCenter(imageView.getScale(), center);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onImageLoadError(Exception e) {
|
public void onImageLoadError(Exception e) {
|
||||||
showImageLoadError();
|
showImageLoadError();
|
||||||
|
@ -93,6 +111,7 @@ public class PagerReaderFragment extends BaseFragment {
|
||||||
public void onDestroyView() {
|
public void onDestroyView() {
|
||||||
unsubscribeProgress();
|
unsubscribeProgress();
|
||||||
unsubscribeStatus();
|
unsubscribeStatus();
|
||||||
|
imageView.setOnImageEventListener(null);
|
||||||
ButterKnife.unbind(this);
|
ButterKnife.unbind(this);
|
||||||
super.onDestroyView();
|
super.onDestroyView();
|
||||||
}
|
}
|
||||||
|
|
BIN
app/src/main/res/drawable-hdpi/ic_crop_original_white_24dp.png
Normal file
BIN
app/src/main/res/drawable-hdpi/ic_crop_original_white_24dp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 271 B |
BIN
app/src/main/res/drawable-ldpi/ic_crop_original_white_24dp.png
Normal file
BIN
app/src/main/res/drawable-ldpi/ic_crop_original_white_24dp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 237 B |
BIN
app/src/main/res/drawable-mdpi/ic_crop_original_white_24dp.png
Normal file
BIN
app/src/main/res/drawable-mdpi/ic_crop_original_white_24dp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 179 B |
BIN
app/src/main/res/drawable-xhdpi/ic_crop_original_white_24dp.png
Normal file
BIN
app/src/main/res/drawable-xhdpi/ic_crop_original_white_24dp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 304 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_crop_original_white_24dp.png
Normal file
BIN
app/src/main/res/drawable-xxhdpi/ic_crop_original_white_24dp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 441 B |
Binary file not shown.
After Width: | Height: | Size: 580 B |
|
@ -78,6 +78,16 @@
|
||||||
android:src="@drawable/ic_screen_rotation"
|
android:src="@drawable/ic_screen_rotation"
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
android:background="?android:selectableItemBackground" />
|
android:background="?android:selectableItemBackground" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:id="@+id/reader_zoom_selector"
|
||||||
|
android:src="@drawable/ic_crop_original_white_24dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:background="?android:selectableItemBackground"/>
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
@ -95,6 +105,7 @@
|
||||||
android:src="@drawable/ic_view_carousel"
|
android:src="@drawable/ic_view_carousel"
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
android:background="?android:selectableItemBackground" />
|
android:background="?android:selectableItemBackground" />
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
|
|
@ -66,6 +66,20 @@
|
||||||
<item>6</item>
|
<item>6</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="zoom_start">
|
||||||
|
<item>@string/zoom_start_automatic</item>
|
||||||
|
<item>@string/zoom_start_left</item>
|
||||||
|
<item>@string/zoom_start_right</item>
|
||||||
|
<item>@string/zoom_start_center</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="zoom_start_values">
|
||||||
|
<item>1</item>
|
||||||
|
<item>2</item>
|
||||||
|
<item>3</item>
|
||||||
|
<item>4</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
<string-array name="library_update_interval">
|
<string-array name="library_update_interval">
|
||||||
<item>@string/update_never</item>
|
<item>@string/update_never</item>
|
||||||
<item>@string/update_1hour</item>
|
<item>@string/update_1hour</item>
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
<string name="pref_default_viewer_key">pref_default_viewer_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_image_scale_type_key">pref_image_scale_type_key</string>
|
||||||
|
<string name="pref_zoom_start_key">pref_zoom_start_key</string>
|
||||||
<string name="pref_hide_status_bar_key">pref_hide_status_bar_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_lock_orientation_key">pref_lock_orientation_key</string>
|
||||||
<string name="pref_enable_transitions_key">pref_enable_transitions_key</string>
|
<string name="pref_enable_transitions_key">pref_enable_transitions_key</string>
|
||||||
|
|
|
@ -93,7 +93,7 @@
|
||||||
<string name="left_to_right_viewer">Left to right</string>
|
<string name="left_to_right_viewer">Left to right</string>
|
||||||
<string name="right_to_left_viewer">Right to left</string>
|
<string name="right_to_left_viewer">Right to left</string>
|
||||||
<string name="vertical_viewer">Vertical</string>
|
<string name="vertical_viewer">Vertical</string>
|
||||||
<string name="webtoon_viewer">Webtoon (experimental)</string>
|
<string name="webtoon_viewer">Webtoon</string>
|
||||||
<string name="pref_image_decoder">Image decoder</string>
|
<string name="pref_image_decoder">Image decoder</string>
|
||||||
<string name="rapid_decoder">Rapid</string>
|
<string name="rapid_decoder">Rapid</string>
|
||||||
<string name="skia_decoder">Skia</string>
|
<string name="skia_decoder">Skia</string>
|
||||||
|
@ -104,7 +104,11 @@
|
||||||
<string name="scale_type_fit_height">Fit height</string>
|
<string name="scale_type_fit_height">Fit height</string>
|
||||||
<string name="scale_type_original_size">Original size</string>
|
<string name="scale_type_original_size">Original size</string>
|
||||||
<string name="scale_type_smart_fit">Smart fit</string>
|
<string name="scale_type_smart_fit">Smart fit</string>
|
||||||
|
<string name="pref_zoom_start">Zoom start position</string>
|
||||||
|
<string name="zoom_start_automatic">Automatic</string>
|
||||||
|
<string name="zoom_start_left">Left</string>
|
||||||
|
<string name="zoom_start_right">Right</string>
|
||||||
|
<string name="zoom_start_center">Center</string>
|
||||||
|
|
||||||
<!-- Downloads section -->
|
<!-- Downloads section -->
|
||||||
<string name="pref_download_directory">Downloads directory</string>
|
<string name="pref_download_directory">Downloads directory</string>
|
||||||
|
|
|
@ -37,6 +37,14 @@
|
||||||
android:defaultValue="1"
|
android:defaultValue="1"
|
||||||
android:summary="%s"/>
|
android:summary="%s"/>
|
||||||
|
|
||||||
|
<eu.kanade.tachiyomi.widget.preference.IntListPreference
|
||||||
|
android:title="@string/pref_zoom_start"
|
||||||
|
android:key="@string/pref_zoom_start_key"
|
||||||
|
android:entries="@array/zoom_start"
|
||||||
|
android:entryValues="@array/zoom_start_values"
|
||||||
|
android:defaultValue="1"
|
||||||
|
android:summary="%s"/>
|
||||||
|
|
||||||
<eu.kanade.tachiyomi.widget.preference.IntListPreference
|
<eu.kanade.tachiyomi.widget.preference.IntListPreference
|
||||||
android:title="@string/pref_reader_theme"
|
android:title="@string/pref_reader_theme"
|
||||||
android:key="@string/pref_reader_theme_key"
|
android:key="@string/pref_reader_theme_key"
|
||||||
|
|
|
@ -6,8 +6,6 @@ import android.graphics.Point;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
|
||||||
import com.davemorrissey.labs.subscaleview.decoder.ImageRegionDecoder;
|
|
||||||
|
|
||||||
import rapid.decoder.BitmapDecoder;
|
import rapid.decoder.BitmapDecoder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -26,15 +24,19 @@ public class RapidImageRegionDecoder implements ImageRegionDecoder {
|
||||||
public Point init(Context context, Uri uri) throws Exception {
|
public Point init(Context context, Uri uri) throws Exception {
|
||||||
decoder = BitmapDecoder.from(context, uri);
|
decoder = BitmapDecoder.from(context, uri);
|
||||||
decoder.useBuiltInDecoder(true);
|
decoder.useBuiltInDecoder(true);
|
||||||
return new Point(decoder.sourceWidth(), decoder.sourceHeight());
|
int width = decoder.sourceWidth();
|
||||||
|
int height = decoder.sourceHeight();
|
||||||
|
if (width == 0 || height == 0)
|
||||||
|
throw new Exception("Rapid image decoder returned empty image - image format may not be supported");
|
||||||
|
return new Point(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized Bitmap decodeRegion(Rect sRect, int sampleSize) {
|
public synchronized Bitmap decodeRegion(Rect sRect, int sampleSize) {
|
||||||
try {
|
try {
|
||||||
return decoder.reset().region(sRect).scale(sRect.width()/sampleSize, sRect.height()/sampleSize).decode();
|
return decoder.reset().region(sRect).scale(sRect.width() / sampleSize, sRect.height() / sampleSize).decode();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return null;
|
throw new RuntimeException("Rapid image decoder returned null bitmap - image format may not be supported");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue