Explorar o código

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.
Deumiankio %!s(int64=6) %!d(string=hai) anos
pai
achega
021dde66eb

+ 2 - 0
app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt

@@ -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"

+ 2 - 0
app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt

@@ -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)

+ 4 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt

@@ -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())
         }
 
     }

+ 10 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderColorFilterSheet.kt

@@ -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)
     }
 

+ 32 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderColorFilterView.kt

@@ -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)
+    }
+}

+ 1 - 1
app/src/main/res/layout-land/reader_color_filter_sheet.xml

@@ -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"

+ 1 - 1
app/src/main/res/layout/reader_activity.xml

@@ -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"

+ 35 - 1
app/src/main/res/layout/reader_color_filter.xml

@@ -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>

+ 1 - 1
app/src/main/res/layout/reader_color_filter_sheet.xml

@@ -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 - 0
app/src/main/res/values-v28/arrays.xml

@@ -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>

+ 6 - 0
app/src/main/res/values/arrays.xml

@@ -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>

+ 7 - 0
app/src/main/res/values/strings.xml

@@ -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>