Add color filter blend modes (#2013)
* Add color filter blend modes * Only show modes supported by currently used API level. * Fix arrays.xml for API level <=27.
This commit is contained in:
parent
5840a3e1e2
commit
021dde66eb
12 changed files with 116 additions and 6 deletions
|
@ -29,6 +29,8 @@ object PreferenceKeys {
|
|||
|
||||
const val colorFilterValue = "color_filter_value"
|
||||
|
||||
const val colorFilterMode = "color_filter_mode"
|
||||
|
||||
const val defaultViewer = "pref_default_viewer_key"
|
||||
|
||||
const val imageScaleType = "pref_image_scale_type_key"
|
||||
|
|
|
@ -57,6 +57,8 @@ class PreferencesHelper(val context: Context) {
|
|||
|
||||
fun colorFilterValue() = rxPrefs.getInteger(Keys.colorFilterValue, 0)
|
||||
|
||||
fun colorFilterMode() = rxPrefs.getInteger(Keys.colorFilterMode, 0)
|
||||
|
||||
fun defaultViewer() = prefs.getInt(Keys.defaultViewer, 1)
|
||||
|
||||
fun imageScaleType() = rxPrefs.getInteger(Keys.imageScaleType, 1)
|
||||
|
|
|
@ -574,6 +574,9 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
|
|||
|
||||
subscriptions += preferences.colorFilter().asObservable()
|
||||
.subscribe { setColorFilter(it) }
|
||||
|
||||
subscriptions += preferences.colorFilterMode().asObservable()
|
||||
.subscribe { setColorFilter(preferences.colorFilter().getOrDefault()) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -722,7 +725,7 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
|
|||
*/
|
||||
private fun setColorFilterValue(value: Int) {
|
||||
color_overlay.visibility = View.VISIBLE
|
||||
color_overlay.setBackgroundColor(value)
|
||||
color_overlay.setFilterColor(value, preferences.colorFilterMode().getOrDefault())
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import eu.kanade.tachiyomi.R
|
|||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||
import eu.kanade.tachiyomi.util.plusAssign
|
||||
import eu.kanade.tachiyomi.widget.IgnoreFirstSpinnerListener
|
||||
import eu.kanade.tachiyomi.widget.SimpleSeekBarListener
|
||||
import kotlinx.android.synthetic.main.reader_color_filter.*
|
||||
import kotlinx.android.synthetic.main.reader_color_filter_sheet.*
|
||||
|
@ -54,6 +55,9 @@ class ReaderColorFilterSheet(activity: ReaderActivity) : BottomSheetDialog(activ
|
|||
subscriptions += preferences.colorFilter().asObservable()
|
||||
.subscribe { setColorFilter(it, view) }
|
||||
|
||||
subscriptions += preferences.colorFilterMode().asObservable()
|
||||
.subscribe { setColorFilter(preferences.colorFilter().getOrDefault(), view) }
|
||||
|
||||
subscriptions += preferences.customBrightness().asObservable()
|
||||
.subscribe { setCustomBrightness(it, view) }
|
||||
|
||||
|
@ -84,6 +88,11 @@ class ReaderColorFilterSheet(activity: ReaderActivity) : BottomSheetDialog(activ
|
|||
preferences.customBrightness().set(isChecked)
|
||||
}
|
||||
|
||||
color_filter_mode.onItemSelectedListener = IgnoreFirstSpinnerListener { position ->
|
||||
preferences.colorFilterMode().set(position)
|
||||
}
|
||||
color_filter_mode.setSelection(preferences.colorFilterMode().getOrDefault(), false)
|
||||
|
||||
seekbar_color_filter_alpha.setOnSeekBarChangeListener(object : SimpleSeekBarListener() {
|
||||
override fun onProgressChanged(seekBar: SeekBar, value: Int, fromUser: Boolean) {
|
||||
if (fromUser) {
|
||||
|
@ -248,7 +257,7 @@ class ReaderColorFilterSheet(activity: ReaderActivity) : BottomSheetDialog(activ
|
|||
*/
|
||||
private fun setColorFilterValue(@ColorInt color: Int, view: View) = with(view) {
|
||||
color_overlay.visibility = View.VISIBLE
|
||||
color_overlay.setBackgroundColor(color)
|
||||
color_overlay.setFilterColor(color, preferences.colorFilterMode().getOrDefault())
|
||||
setValues(color, view)
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
package eu.kanade.tachiyomi.ui.reader
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.*
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
|
||||
class ReaderColorFilterView(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null
|
||||
) : View(context, attrs) {
|
||||
|
||||
private val colorFilterPaint: Paint = Paint()
|
||||
|
||||
fun setFilterColor(color: Int, filterMode: Int) {
|
||||
colorFilterPaint.setColor(color)
|
||||
colorFilterPaint.xfermode = PorterDuffXfermode(when (filterMode) {
|
||||
1 -> PorterDuff.Mode.MULTIPLY
|
||||
2 -> PorterDuff.Mode.SCREEN
|
||||
3 -> PorterDuff.Mode.OVERLAY
|
||||
4 -> PorterDuff.Mode.LIGHTEN
|
||||
5 -> PorterDuff.Mode.DARKEN
|
||||
else -> PorterDuff.Mode.SRC_OVER
|
||||
})
|
||||
invalidate()
|
||||
}
|
||||
|
||||
override fun onDraw(canvas: Canvas) {
|
||||
super.onDraw(canvas)
|
||||
canvas.drawPaint(colorFilterPaint)
|
||||
}
|
||||
}
|
|
@ -29,7 +29,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:visibility="gone" />
|
||||
|
||||
<View
|
||||
<eu.kanade.tachiyomi.ui.reader.ReaderColorFilterView
|
||||
android:id="@+id/color_overlay"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
|
@ -111,7 +111,7 @@
|
|||
android:layout_height="match_parent"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<View
|
||||
<eu.kanade.tachiyomi.ui.reader.ReaderColorFilterView
|
||||
android:id="@+id/color_overlay"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
|
|
@ -6,6 +6,12 @@
|
|||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:padding="16dp">
|
||||
|
||||
<android.support.v4.widget.Space
|
||||
android:id="@+id/spinner_end"
|
||||
android:layout_width="16dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintLeft_toRightOf="parent" />
|
||||
|
||||
<!-- Color filter -->
|
||||
|
||||
<android.support.v7.widget.SwitchCompat
|
||||
|
@ -157,6 +163,27 @@
|
|||
app:layout_constraintBottom_toBottomOf="@id/seekbar_color_filter_alpha"
|
||||
app:layout_constraintRight_toRightOf="parent"/>
|
||||
|
||||
<!-- Filter mode -->
|
||||
|
||||
<TextView
|
||||
android:id="@+id/color_filter_mode_text"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/pref_color_filter_mode"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toLeftOf="@id/color_filter_mode"
|
||||
app:layout_constraintBaseline_toBaselineOf="@id/color_filter_mode"/>
|
||||
|
||||
<android.support.v7.widget.AppCompatSpinner
|
||||
android:id="@+id/color_filter_mode"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:entries="@array/color_filter_modes"
|
||||
app:layout_constraintTop_toBottomOf="@id/seekbar_color_filter_alpha"
|
||||
app:layout_constraintLeft_toRightOf="@id/verticalcenter"
|
||||
app:layout_constraintRight_toRightOf="@id/spinner_end" />
|
||||
|
||||
<!-- Brightness -->
|
||||
|
||||
<android.support.v7.widget.SwitchCompat
|
||||
|
@ -165,7 +192,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/pref_custom_brightness"
|
||||
app:layout_constraintTop_toBottomOf="@id/seekbar_color_filter_alpha"/>
|
||||
app:layout_constraintTop_toBottomOf="@id/color_filter_mode_text"/>
|
||||
|
||||
<!-- Brightness value -->
|
||||
|
||||
|
@ -202,4 +229,11 @@
|
|||
app:layout_constraintBottom_toBottomOf="@id/brightness_seekbar"
|
||||
app:layout_constraintRight_toRightOf="parent"/>
|
||||
|
||||
<android.support.constraint.Guideline
|
||||
android:id="@+id/verticalcenter"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintGuide_percent="0.5" />
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
android:layout_height="match_parent"
|
||||
android:visibility="gone" />
|
||||
|
||||
<View
|
||||
<eu.kanade.tachiyomi.ui.reader.ReaderColorFilterView
|
||||
android:id="@+id/color_overlay"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
|
15
app/src/main/res/values-v28/arrays.xml
Normal file
15
app/src/main/res/values-v28/arrays.xml
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<string-array name="color_filter_modes">
|
||||
<item>@string/filter_mode_default</item>
|
||||
<item>@string/filter_mode_multiply</item>
|
||||
<item>@string/filter_mode_screen</item>
|
||||
|
||||
<!-- Attributes specific for SDK 28 and up -->
|
||||
<item>@string/filter_mode_overlay</item>
|
||||
<item>@string/filter_mode_lighten</item>
|
||||
<item>@string/filter_mode_darken</item>
|
||||
</string-array>
|
||||
|
||||
</resources>
|
|
@ -102,4 +102,10 @@
|
|||
<item>2</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="color_filter_modes">
|
||||
<item>@string/filter_mode_default</item>
|
||||
<item>@string/filter_mode_multiply</item>
|
||||
<item>@string/filter_mode_screen</item>
|
||||
</string-array>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -178,6 +178,13 @@
|
|||
<string name="pref_crop_borders">Crop borders</string>
|
||||
<string name="pref_custom_brightness">Use custom brightness</string>
|
||||
<string name="pref_custom_color_filter">Use custom color filter</string>
|
||||
<string name="pref_color_filter_mode">Color filter blend mode</string>
|
||||
<string name="filter_mode_default">Default</string>
|
||||
<string name="filter_mode_overlay">Overlay</string>
|
||||
<string name="filter_mode_multiply">Multiply</string>
|
||||
<string name="filter_mode_screen">Screen</string>
|
||||
<string name="filter_mode_lighten">Dodge / Lighten</string>
|
||||
<string name="filter_mode_darken">Burn / Darken</string>
|
||||
<string name="pref_keep_screen_on">Keep screen on</string>
|
||||
<string name="pref_skip_read_chapters">Skip chapters marked read</string>
|
||||
<string name="pref_reader_navigation">Navigation</string>
|
||||
|
|
Reference in a new issue