mirror of
https://github.com/null2264/yokai.git
synced 2025-06-21 10:44:42 +00:00
Initial support for custom images scaling (#40)
This commit is contained in:
parent
c6ecfb2f67
commit
0c9bc97fe8
19 changed files with 127 additions and 91 deletions
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
BIN
app/src/main/res/drawable-hdpi/ic_zoom_out_map_white_24dp.png
Normal file
BIN
app/src/main/res/drawable-hdpi/ic_zoom_out_map_white_24dp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 326 B |
BIN
app/src/main/res/drawable-mdpi/ic_zoom_out_map_white_24dp.png
Normal file
BIN
app/src/main/res/drawable-mdpi/ic_zoom_out_map_white_24dp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 235 B |
BIN
app/src/main/res/drawable-xhdpi/ic_zoom_out_map_white_24dp.png
Normal file
BIN
app/src/main/res/drawable-xhdpi/ic_zoom_out_map_white_24dp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 332 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_zoom_out_map_white_24dp.png
Normal file
BIN
app/src/main/res/drawable-xxhdpi/ic_zoom_out_map_white_24dp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 510 B |
BIN
app/src/main/res/drawable-xxxhdpi/ic_zoom_out_map_white_24dp.png
Normal file
BIN
app/src/main/res/drawable-xxxhdpi/ic_zoom_out_map_white_24dp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 584 B |
|
@ -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>
|
|
@ -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"
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue