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
					
				| @ -29,6 +29,8 @@ object PreferenceKeys { | |||||||
| 
 | 
 | ||||||
|     const val colorFilterValue = "color_filter_value" |     const val colorFilterValue = "color_filter_value" | ||||||
| 
 | 
 | ||||||
|  |     const val colorFilterMode = "color_filter_mode" | ||||||
|  | 
 | ||||||
|     const val defaultViewer = "pref_default_viewer_key" |     const val defaultViewer = "pref_default_viewer_key" | ||||||
| 
 | 
 | ||||||
|     const val imageScaleType = "pref_image_scale_type_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 colorFilterValue() = rxPrefs.getInteger(Keys.colorFilterValue, 0) | ||||||
| 
 | 
 | ||||||
|  |     fun colorFilterMode() = rxPrefs.getInteger(Keys.colorFilterMode, 0) | ||||||
|  | 
 | ||||||
|     fun defaultViewer() = prefs.getInt(Keys.defaultViewer, 1) |     fun defaultViewer() = prefs.getInt(Keys.defaultViewer, 1) | ||||||
| 
 | 
 | ||||||
|     fun imageScaleType() = rxPrefs.getInteger(Keys.imageScaleType, 1) |     fun imageScaleType() = rxPrefs.getInteger(Keys.imageScaleType, 1) | ||||||
|  | |||||||
| @ -574,6 +574,9 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>() { | |||||||
| 
 | 
 | ||||||
|             subscriptions += preferences.colorFilter().asObservable() |             subscriptions += preferences.colorFilter().asObservable() | ||||||
|                 .subscribe { setColorFilter(it) } |                 .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) { |         private fun setColorFilterValue(value: Int) { | ||||||
|             color_overlay.visibility = View.VISIBLE |             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.PreferencesHelper | ||||||
| import eu.kanade.tachiyomi.data.preference.getOrDefault | import eu.kanade.tachiyomi.data.preference.getOrDefault | ||||||
| import eu.kanade.tachiyomi.util.plusAssign | import eu.kanade.tachiyomi.util.plusAssign | ||||||
|  | import eu.kanade.tachiyomi.widget.IgnoreFirstSpinnerListener | ||||||
| import eu.kanade.tachiyomi.widget.SimpleSeekBarListener | import eu.kanade.tachiyomi.widget.SimpleSeekBarListener | ||||||
| import kotlinx.android.synthetic.main.reader_color_filter.* | import kotlinx.android.synthetic.main.reader_color_filter.* | ||||||
| import kotlinx.android.synthetic.main.reader_color_filter_sheet.* | import kotlinx.android.synthetic.main.reader_color_filter_sheet.* | ||||||
| @ -54,6 +55,9 @@ class ReaderColorFilterSheet(activity: ReaderActivity) : BottomSheetDialog(activ | |||||||
|         subscriptions += preferences.colorFilter().asObservable() |         subscriptions += preferences.colorFilter().asObservable() | ||||||
|             .subscribe { setColorFilter(it, view) } |             .subscribe { setColorFilter(it, view) } | ||||||
| 
 | 
 | ||||||
|  |         subscriptions += preferences.colorFilterMode().asObservable() | ||||||
|  |             .subscribe { setColorFilter(preferences.colorFilter().getOrDefault(), view) } | ||||||
|  | 
 | ||||||
|         subscriptions += preferences.customBrightness().asObservable() |         subscriptions += preferences.customBrightness().asObservable() | ||||||
|             .subscribe { setCustomBrightness(it, view) } |             .subscribe { setCustomBrightness(it, view) } | ||||||
| 
 | 
 | ||||||
| @ -84,6 +88,11 @@ class ReaderColorFilterSheet(activity: ReaderActivity) : BottomSheetDialog(activ | |||||||
|             preferences.customBrightness().set(isChecked) |             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() { |         seekbar_color_filter_alpha.setOnSeekBarChangeListener(object : SimpleSeekBarListener() { | ||||||
|             override fun onProgressChanged(seekBar: SeekBar, value: Int, fromUser: Boolean) { |             override fun onProgressChanged(seekBar: SeekBar, value: Int, fromUser: Boolean) { | ||||||
|                 if (fromUser) { |                 if (fromUser) { | ||||||
| @ -248,7 +257,7 @@ class ReaderColorFilterSheet(activity: ReaderActivity) : BottomSheetDialog(activ | |||||||
|      */ |      */ | ||||||
|     private fun setColorFilterValue(@ColorInt color: Int, view: View) = with(view) { |     private fun setColorFilterValue(@ColorInt color: Int, view: View) = with(view) { | ||||||
|         color_overlay.visibility = View.VISIBLE |         color_overlay.visibility = View.VISIBLE | ||||||
|         color_overlay.setBackgroundColor(color) |         color_overlay.setFilterColor(color, preferences.colorFilterMode().getOrDefault()) | ||||||
|         setValues(color, view) |         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:layout_height="wrap_content" | ||||||
|             android:visibility="gone" /> |             android:visibility="gone" /> | ||||||
| 
 | 
 | ||||||
|         <View |         <eu.kanade.tachiyomi.ui.reader.ReaderColorFilterView | ||||||
|             android:id="@+id/color_overlay" |             android:id="@+id/color_overlay" | ||||||
|             android:layout_width="match_parent" |             android:layout_width="match_parent" | ||||||
|             android:layout_height="wrap_content" |             android:layout_height="wrap_content" | ||||||
|  | |||||||
| @ -111,7 +111,7 @@ | |||||||
|         android:layout_height="match_parent" |         android:layout_height="match_parent" | ||||||
|         android:visibility="gone"/> |         android:visibility="gone"/> | ||||||
| 
 | 
 | ||||||
|     <View |     <eu.kanade.tachiyomi.ui.reader.ReaderColorFilterView | ||||||
|         android:id="@+id/color_overlay" |         android:id="@+id/color_overlay" | ||||||
|         android:layout_width="match_parent" |         android:layout_width="match_parent" | ||||||
|         android:layout_height="match_parent" |         android:layout_height="match_parent" | ||||||
|  | |||||||
| @ -6,6 +6,12 @@ | |||||||
|     xmlns:app="http://schemas.android.com/apk/res-auto" |     xmlns:app="http://schemas.android.com/apk/res-auto" | ||||||
|     android:padding="16dp"> |     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 --> |     <!-- Color filter --> | ||||||
| 
 | 
 | ||||||
|     <android.support.v7.widget.SwitchCompat |     <android.support.v7.widget.SwitchCompat | ||||||
| @ -157,6 +163,27 @@ | |||||||
|         app:layout_constraintBottom_toBottomOf="@id/seekbar_color_filter_alpha" |         app:layout_constraintBottom_toBottomOf="@id/seekbar_color_filter_alpha" | ||||||
|         app:layout_constraintRight_toRightOf="parent"/> |         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 --> |     <!-- Brightness --> | ||||||
| 
 | 
 | ||||||
|     <android.support.v7.widget.SwitchCompat |     <android.support.v7.widget.SwitchCompat | ||||||
| @ -165,7 +192,7 @@ | |||||||
|         android:layout_height="wrap_content" |         android:layout_height="wrap_content" | ||||||
|         android:layout_marginTop="16dp" |         android:layout_marginTop="16dp" | ||||||
|         android:text="@string/pref_custom_brightness" |         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 --> |     <!-- Brightness value --> | ||||||
| 
 | 
 | ||||||
| @ -202,4 +229,11 @@ | |||||||
|         app:layout_constraintBottom_toBottomOf="@id/brightness_seekbar" |         app:layout_constraintBottom_toBottomOf="@id/brightness_seekbar" | ||||||
|         app:layout_constraintRight_toRightOf="parent"/> |         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> | </android.support.constraint.ConstraintLayout> | ||||||
|  | |||||||
| @ -21,7 +21,7 @@ | |||||||
|             android:layout_height="match_parent" |             android:layout_height="match_parent" | ||||||
|             android:visibility="gone" /> |             android:visibility="gone" /> | ||||||
| 
 | 
 | ||||||
|         <View |         <eu.kanade.tachiyomi.ui.reader.ReaderColorFilterView | ||||||
|             android:id="@+id/color_overlay" |             android:id="@+id/color_overlay" | ||||||
|             android:layout_width="match_parent" |             android:layout_width="match_parent" | ||||||
|             android:layout_height="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> |         <item>2</item> | ||||||
|     </string-array> |     </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> | </resources> | ||||||
|  | |||||||
| @ -178,6 +178,13 @@ | |||||||
|     <string name="pref_crop_borders">Crop borders</string> |     <string name="pref_crop_borders">Crop borders</string> | ||||||
|     <string name="pref_custom_brightness">Use custom brightness</string> |     <string name="pref_custom_brightness">Use custom brightness</string> | ||||||
|     <string name="pref_custom_color_filter">Use custom color filter</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_keep_screen_on">Keep screen on</string> | ||||||
|     <string name="pref_skip_read_chapters">Skip chapters marked read</string> |     <string name="pref_skip_read_chapters">Skip chapters marked read</string> | ||||||
|     <string name="pref_reader_navigation">Navigation</string> |     <string name="pref_reader_navigation">Navigation</string> | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Deumiankio
						Deumiankio