mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-04 08:08:55 +01:00 
			
		
		
		
	Custom color filter for reader (#434)
* [WIP] Custom color filter for reader * Improvements * temp image to prevent build error * Shift all the bits * Some improvements. Removed DiscreteSeekBar * Improvements * API 16 + fixes * Reduced lag. Fixed brightness value being reset to 0 * Small fixes
This commit is contained in:
		
				
					committed by
					
						
						inorichi
					
				
			
			
				
	
			
			
			
						parent
						
							58a2f7a874
						
					
				
				
					commit
					8be67a4431
				
			@@ -165,7 +165,6 @@ dependencies {
 | 
			
		||||
    compile 'com.afollestad.material-dialogs:core:0.8.6.2'
 | 
			
		||||
    compile 'net.xpece.android:support-preference:0.8.1'
 | 
			
		||||
    compile 'me.zhanghai.android.systemuihelper:library:1.0.0'
 | 
			
		||||
    compile 'org.adw.library:discrete-seekbar:1.0.1'
 | 
			
		||||
    compile 'de.hdodenhof:circleimageview:2.1.0'
 | 
			
		||||
 | 
			
		||||
    // Tests
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,10 @@ class PreferenceKeys(context: Context) {
 | 
			
		||||
 | 
			
		||||
    val customBrightnessValue = context.getString(R.string.pref_custom_brightness_value_key)
 | 
			
		||||
 | 
			
		||||
    val colorFilter = context.getString(R.string.pref_color_filter_key)
 | 
			
		||||
 | 
			
		||||
    val colorFilterValue = context.getString(R.string.pref_color_filter_value_key)
 | 
			
		||||
 | 
			
		||||
    val defaultViewer = context.getString(R.string.pref_default_viewer_key)
 | 
			
		||||
 | 
			
		||||
    val imageScaleType = context.getString(R.string.pref_image_scale_type_key)
 | 
			
		||||
 
 | 
			
		||||
@@ -52,6 +52,10 @@ class PreferencesHelper(context: Context) {
 | 
			
		||||
 | 
			
		||||
    fun customBrightnessValue() = rxPrefs.getInteger(keys.customBrightnessValue, 0)
 | 
			
		||||
 | 
			
		||||
    fun colorFilter() = rxPrefs.getBoolean(keys.colorFilter, false)
 | 
			
		||||
 | 
			
		||||
    fun colorFilterValue() = rxPrefs.getInteger(keys.colorFilterValue, 0)
 | 
			
		||||
 | 
			
		||||
    fun defaultViewer() = prefs.getInt(keys.defaultViewer, 1)
 | 
			
		||||
 | 
			
		||||
    fun imageScaleType() = rxPrefs.getInteger(keys.imageScaleType, 1)
 | 
			
		||||
 
 | 
			
		||||
@@ -38,10 +38,12 @@ import me.zhanghai.android.systemuihelper.SystemUiHelper
 | 
			
		||||
import me.zhanghai.android.systemuihelper.SystemUiHelper.*
 | 
			
		||||
import nucleus.factory.RequiresPresenter
 | 
			
		||||
import rx.Subscription
 | 
			
		||||
import rx.android.schedulers.AndroidSchedulers
 | 
			
		||||
import rx.subscriptions.CompositeSubscription
 | 
			
		||||
import timber.log.Timber
 | 
			
		||||
import uy.kohesive.injekt.injectLazy
 | 
			
		||||
import java.text.DecimalFormat
 | 
			
		||||
import java.util.concurrent.TimeUnit
 | 
			
		||||
 | 
			
		||||
@RequiresPresenter(ReaderPresenter::class)
 | 
			
		||||
class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
 | 
			
		||||
@@ -70,6 +72,8 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
 | 
			
		||||
 | 
			
		||||
    private var customBrightnessSubscription: Subscription? = null
 | 
			
		||||
 | 
			
		||||
    private var customFilterColorSubscription: Subscription? = null
 | 
			
		||||
 | 
			
		||||
    var readerTheme: Int = 0
 | 
			
		||||
        private set
 | 
			
		||||
 | 
			
		||||
@@ -140,6 +144,7 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
 | 
			
		||||
    override fun onOptionsItemSelected(item: MenuItem): Boolean {
 | 
			
		||||
        when (item.itemId) {
 | 
			
		||||
            R.id.action_settings -> ReaderSettingsDialog().show(supportFragmentManager, "settings")
 | 
			
		||||
            R.id.action_custom_filter -> ReaderCustomFilterDialog().show(supportFragmentManager, "filter")
 | 
			
		||||
            else -> return super.onOptionsItemSelected(item)
 | 
			
		||||
        }
 | 
			
		||||
        return true
 | 
			
		||||
@@ -354,9 +359,9 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
 | 
			
		||||
        reader_menu_bottom.setOnTouchListener { v, event -> true }
 | 
			
		||||
 | 
			
		||||
        page_seekbar.setOnSeekBarChangeListener(object : SimpleSeekBarListener() {
 | 
			
		||||
            override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
 | 
			
		||||
            override fun onProgressChanged(seekBar: SeekBar, value: Int, fromUser: Boolean) {
 | 
			
		||||
                if (fromUser) {
 | 
			
		||||
                    gotoPageInCurrentChapter(progress)
 | 
			
		||||
                    gotoPageInCurrentChapter(value)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
@@ -378,6 +383,9 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
 | 
			
		||||
        subscriptions += preferences.customBrightness().asObservable()
 | 
			
		||||
                .subscribe { setCustomBrightness(it) }
 | 
			
		||||
 | 
			
		||||
        subscriptions += preferences.colorFilter().asObservable()
 | 
			
		||||
                .subscribe { setColorFilter(it) }
 | 
			
		||||
 | 
			
		||||
        subscriptions += preferences.readerTheme().asObservable()
 | 
			
		||||
                .distinctUntilChanged()
 | 
			
		||||
                .subscribe { applyTheme(it) }
 | 
			
		||||
@@ -424,6 +432,7 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
 | 
			
		||||
    private fun setCustomBrightness(enabled: Boolean) {
 | 
			
		||||
        if (enabled) {
 | 
			
		||||
            customBrightnessSubscription = preferences.customBrightnessValue().asObservable()
 | 
			
		||||
                    .sample(100, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread())
 | 
			
		||||
                    .subscribe { setCustomBrightnessValue(it) }
 | 
			
		||||
 | 
			
		||||
            subscriptions.add(customBrightnessSubscription)
 | 
			
		||||
@@ -433,6 +442,19 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun setColorFilter(enabled: Boolean) {
 | 
			
		||||
        if (enabled) {
 | 
			
		||||
            customFilterColorSubscription = preferences.colorFilterValue().asObservable()
 | 
			
		||||
                    .sample(100, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread())
 | 
			
		||||
                    .subscribe { setColorFilterValue(it) }
 | 
			
		||||
 | 
			
		||||
            subscriptions.add(customFilterColorSubscription)
 | 
			
		||||
        } else {
 | 
			
		||||
            customFilterColorSubscription?.let { subscriptions.remove(it) }
 | 
			
		||||
            color_overlay.visibility = View.GONE
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the brightness of the screen. Range is [-75, 100].
 | 
			
		||||
     * From -75 to -1 a semi-transparent black view is shown at the top with the minimum brightness.
 | 
			
		||||
@@ -459,6 +481,11 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun setColorFilterValue(value: Int) {
 | 
			
		||||
        color_overlay.visibility = View.VISIBLE
 | 
			
		||||
        color_overlay.setBackgroundColor(value)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun applyTheme(theme: Int) {
 | 
			
		||||
        readerTheme = theme
 | 
			
		||||
        val rootView = window.decorView.rootView
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,329 @@
 | 
			
		||||
package eu.kanade.tachiyomi.ui.reader
 | 
			
		||||
 | 
			
		||||
import android.app.Dialog
 | 
			
		||||
import android.graphics.Color
 | 
			
		||||
import android.os.Bundle
 | 
			
		||||
import android.support.annotation.ColorInt
 | 
			
		||||
import android.support.v4.app.DialogFragment
 | 
			
		||||
import android.view.View
 | 
			
		||||
import android.widget.SeekBar
 | 
			
		||||
import com.afollestad.materialdialogs.MaterialDialog
 | 
			
		||||
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.SimpleSeekBarListener
 | 
			
		||||
import kotlinx.android.synthetic.main.dialog_reader_custom_filter.view.*
 | 
			
		||||
import rx.Subscription
 | 
			
		||||
import rx.android.schedulers.AndroidSchedulers
 | 
			
		||||
import rx.subscriptions.CompositeSubscription
 | 
			
		||||
import uy.kohesive.injekt.injectLazy
 | 
			
		||||
import java.util.concurrent.TimeUnit
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Custom dialog which can be used to set overlay value's
 | 
			
		||||
 */
 | 
			
		||||
class ReaderCustomFilterDialog : DialogFragment() {
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
        /** Integer mask of alpha value **/
 | 
			
		||||
        private const val ALPHA_MASK: Long = 0xFF000000
 | 
			
		||||
 | 
			
		||||
        /** Integer mask of red value **/
 | 
			
		||||
        private const val RED_MASK: Long = 0x00FF0000
 | 
			
		||||
 | 
			
		||||
        /** Integer mask of green value **/
 | 
			
		||||
        private const val GREEN_MASK: Long = 0x0000FF00
 | 
			
		||||
 | 
			
		||||
        /** Integer mask of blue value **/
 | 
			
		||||
        private const val BLUE_MASK: Long = 0x000000FF
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Provides operations to manage preferences
 | 
			
		||||
     */
 | 
			
		||||
    private val preferences by injectLazy<PreferencesHelper>()
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Subscription used for filter overlay
 | 
			
		||||
     */
 | 
			
		||||
    private lateinit var subscriptions: CompositeSubscription
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Subscription used for custom brightness overlay
 | 
			
		||||
     */
 | 
			
		||||
    private var customBrightnessSubscription: Subscription? = null
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Subscription used for color filter overlay
 | 
			
		||||
     */
 | 
			
		||||
    private var customFilterColorSubscription: Subscription? = null
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method will be called after onCreate(Bundle)
 | 
			
		||||
     * @param savedState The last saved instance state of the Fragment.
 | 
			
		||||
     */
 | 
			
		||||
    override fun onCreateDialog(savedState: Bundle?): Dialog {
 | 
			
		||||
        val dialog = MaterialDialog.Builder(activity)
 | 
			
		||||
                .customView(R.layout.dialog_reader_custom_filter, false)
 | 
			
		||||
                .positiveText(android.R.string.ok)
 | 
			
		||||
                .build()
 | 
			
		||||
 | 
			
		||||
        subscriptions = CompositeSubscription()
 | 
			
		||||
        onViewCreated(dialog.view, savedState)
 | 
			
		||||
 | 
			
		||||
        return dialog
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Called immediately after onCreateView()
 | 
			
		||||
     * @param view The View returned by onCreateDialog.
 | 
			
		||||
     * @param savedInstanceState If non-null, this fragment is being re-constructed
 | 
			
		||||
     */
 | 
			
		||||
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) = with(view) {
 | 
			
		||||
        // Initialize subscriptions.
 | 
			
		||||
        subscriptions += preferences.colorFilter().asObservable()
 | 
			
		||||
                .subscribe { setColorFilter(it, view) }
 | 
			
		||||
 | 
			
		||||
        subscriptions += preferences.customBrightness().asObservable()
 | 
			
		||||
                .subscribe { setCustomBrightness(it, view) }
 | 
			
		||||
 | 
			
		||||
        // Get color and update values
 | 
			
		||||
        val color = preferences.colorFilterValue().getOrDefault()
 | 
			
		||||
        val brightness = preferences.customBrightnessValue().getOrDefault()
 | 
			
		||||
 | 
			
		||||
        val argb = setValues(color, view)
 | 
			
		||||
 | 
			
		||||
        // Set brightness value
 | 
			
		||||
        txt_brightness_seekbar_value.text = brightness.toString()
 | 
			
		||||
 | 
			
		||||
        // Initialize seekBar progress
 | 
			
		||||
        seekbar_color_filter_alpha.progress = argb[0]
 | 
			
		||||
        seekbar_color_filter_red.progress = argb[1]
 | 
			
		||||
        seekbar_color_filter_green.progress = argb[2]
 | 
			
		||||
        seekbar_color_filter_blue.progress = argb[3]
 | 
			
		||||
 | 
			
		||||
        // Set listeners
 | 
			
		||||
        switch_color_filter.isChecked = preferences.colorFilter().getOrDefault()
 | 
			
		||||
        switch_color_filter.setOnCheckedChangeListener { v, isChecked ->
 | 
			
		||||
            preferences.colorFilter().set(isChecked)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        custom_brightness.isChecked = preferences.customBrightness().getOrDefault()
 | 
			
		||||
        custom_brightness.setOnCheckedChangeListener { v, isChecked ->
 | 
			
		||||
            preferences.customBrightness().set(isChecked)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        seekbar_color_filter_alpha.setOnSeekBarChangeListener(object : SimpleSeekBarListener() {
 | 
			
		||||
            override fun onProgressChanged(seekBar: SeekBar, value: Int, fromUser: Boolean) {
 | 
			
		||||
                if (fromUser) {
 | 
			
		||||
                    setColorValue(value, ALPHA_MASK, 24)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
        seekbar_color_filter_red.setOnSeekBarChangeListener(object : SimpleSeekBarListener() {
 | 
			
		||||
            override fun onProgressChanged(seekBar: SeekBar, value: Int, fromUser: Boolean) {
 | 
			
		||||
                if (fromUser) {
 | 
			
		||||
                    setColorValue(value, RED_MASK, 16)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
        seekbar_color_filter_green.setOnSeekBarChangeListener(object : SimpleSeekBarListener() {
 | 
			
		||||
            override fun onProgressChanged(seekBar: SeekBar, value: Int, fromUser: Boolean) {
 | 
			
		||||
                if (fromUser) {
 | 
			
		||||
                    setColorValue(value, GREEN_MASK, 8)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
        seekbar_color_filter_blue.setOnSeekBarChangeListener(object : SimpleSeekBarListener() {
 | 
			
		||||
            override fun onProgressChanged(seekBar: SeekBar, value: Int, fromUser: Boolean) {
 | 
			
		||||
                if (fromUser) {
 | 
			
		||||
                    setColorValue(value, BLUE_MASK, 0)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
        brightness_seekbar.progress = preferences.customBrightnessValue().getOrDefault()
 | 
			
		||||
        brightness_seekbar.setOnSeekBarChangeListener(object : SimpleSeekBarListener() {
 | 
			
		||||
            override fun onProgressChanged(seekBar: SeekBar, value: Int, fromUser: Boolean) {
 | 
			
		||||
                if (fromUser) {
 | 
			
		||||
                    preferences.customBrightnessValue().set(value)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set enabled status of seekBars belonging to color filter
 | 
			
		||||
     * @param enabled determines if seekBar gets enabled
 | 
			
		||||
     * @param view view of the dialog
 | 
			
		||||
     */
 | 
			
		||||
    private fun setColorFilterSeekBar(enabled: Boolean, view: View) = with(view) {
 | 
			
		||||
        seekbar_color_filter_red.isEnabled = enabled
 | 
			
		||||
        seekbar_color_filter_green.isEnabled = enabled
 | 
			
		||||
        seekbar_color_filter_blue.isEnabled = enabled
 | 
			
		||||
        seekbar_color_filter_alpha.isEnabled = enabled
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set enabled status of seekBars belonging to custom brightness
 | 
			
		||||
     * @param enabled value which determines if seekBar gets enabled
 | 
			
		||||
     * @param view view of the dialog
 | 
			
		||||
     */
 | 
			
		||||
    private fun setCustomBrightnessSeekBar(enabled: Boolean, view: View) = with(view) {
 | 
			
		||||
        brightness_seekbar.isEnabled = enabled
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the text value's of color filter
 | 
			
		||||
     * @param color integer containing color information
 | 
			
		||||
     * @param view view of the dialog
 | 
			
		||||
     */
 | 
			
		||||
    fun setValues(color: Int, view: View): Array<Int> {
 | 
			
		||||
        val alpha = getAlphaFromColor(color)
 | 
			
		||||
        val red = getRedFromColor(color)
 | 
			
		||||
        val green = getGreenFromColor(color)
 | 
			
		||||
        val blue = getBlueFromColor(color)
 | 
			
		||||
 | 
			
		||||
        //Initialize values
 | 
			
		||||
        with(view) {
 | 
			
		||||
            txt_color_filter_alpha_value.text = alpha.toString()
 | 
			
		||||
 | 
			
		||||
            txt_color_filter_red_value.text = red.toString()
 | 
			
		||||
 | 
			
		||||
            txt_color_filter_green_value.text = green.toString()
 | 
			
		||||
 | 
			
		||||
            txt_color_filter_blue_value.text = blue.toString()
 | 
			
		||||
        }
 | 
			
		||||
        return arrayOf(alpha, red, green, blue)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Manages the custom brightness value subscription
 | 
			
		||||
     * @param enabled determines if the subscription get (un)subscribed
 | 
			
		||||
     * @param view view of the dialog
 | 
			
		||||
     */
 | 
			
		||||
    private fun setCustomBrightness(enabled: Boolean, view: View) {
 | 
			
		||||
        if (enabled) {
 | 
			
		||||
            customBrightnessSubscription = preferences.customBrightnessValue().asObservable()
 | 
			
		||||
                    .sample(100, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread())
 | 
			
		||||
                    .subscribe { setCustomBrightnessValue(it, view) }
 | 
			
		||||
 | 
			
		||||
            subscriptions.add(customBrightnessSubscription)
 | 
			
		||||
        } else {
 | 
			
		||||
            customBrightnessSubscription?.let { subscriptions.remove(it) }
 | 
			
		||||
            setCustomBrightnessValue(0, view, true)
 | 
			
		||||
        }
 | 
			
		||||
        setCustomBrightnessSeekBar(enabled, view)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the brightness of the screen. Range is [-75, 100].
 | 
			
		||||
     * From -75 to -1 a semi-transparent black view is shown at the top with the minimum brightness.
 | 
			
		||||
     * From 1 to 100 it sets that value as brightness.
 | 
			
		||||
     * 0 sets system brightness and hides the overlay.
 | 
			
		||||
     */
 | 
			
		||||
    private fun setCustomBrightnessValue(value: Int, view: View, isDisabled: Boolean = false) = with(view) {
 | 
			
		||||
        // Set black overlay visibility.
 | 
			
		||||
        if (value < 0) {
 | 
			
		||||
            brightness_overlay.visibility = View.VISIBLE
 | 
			
		||||
            val alpha = (Math.abs(value) * 2.56).toInt()
 | 
			
		||||
            brightness_overlay.setBackgroundColor(Color.argb(alpha, 0, 0, 0))
 | 
			
		||||
        } else {
 | 
			
		||||
            brightness_overlay.visibility = View.GONE
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!isDisabled)
 | 
			
		||||
            txt_brightness_seekbar_value.text = value.toString()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Manages the color filter value subscription
 | 
			
		||||
     * @param enabled determines if the subscription get (un)subscribed
 | 
			
		||||
     * @param view view of the dialog
 | 
			
		||||
     */
 | 
			
		||||
    private fun setColorFilter(enabled: Boolean, view: View) {
 | 
			
		||||
        if (enabled) {
 | 
			
		||||
            customFilterColorSubscription = preferences.colorFilterValue().asObservable()
 | 
			
		||||
                    .sample(100, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread())
 | 
			
		||||
                    .subscribe { setColorFilterValue(it, view) }
 | 
			
		||||
 | 
			
		||||
            subscriptions.add(customFilterColorSubscription)
 | 
			
		||||
        } else {
 | 
			
		||||
            customFilterColorSubscription?.let { subscriptions.remove(it) }
 | 
			
		||||
            view.color_overlay.visibility = View.GONE
 | 
			
		||||
        }
 | 
			
		||||
        setColorFilterSeekBar(enabled, view)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the color filter overlay of the screen. Determined by HEX of integer
 | 
			
		||||
     * @param color hex of color.
 | 
			
		||||
     * @param view view of the dialog
 | 
			
		||||
     */
 | 
			
		||||
    private fun setColorFilterValue(@ColorInt color: Int, view: View) = with(view) {
 | 
			
		||||
        color_overlay.visibility = View.VISIBLE
 | 
			
		||||
        color_overlay.setBackgroundColor(color)
 | 
			
		||||
        setValues(color, view)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Updates the color value in preference
 | 
			
		||||
     * @param color value of color range [0,255]
 | 
			
		||||
     * @param mask contains hex mask of chosen color
 | 
			
		||||
     * @param bitShift amounts of bits that gets shifted to receive value
 | 
			
		||||
     */
 | 
			
		||||
    fun setColorValue(color: Int, mask: Long, bitShift: Int) {
 | 
			
		||||
        val currentColor = preferences.colorFilterValue().getOrDefault()
 | 
			
		||||
        val updatedColor = (color shl bitShift) or (currentColor and mask.inv().toInt())
 | 
			
		||||
        preferences.colorFilterValue().set(updatedColor)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the alpha value from the Color Hex
 | 
			
		||||
     * @param color color hex as int
 | 
			
		||||
     * @return alpha of color
 | 
			
		||||
     */
 | 
			
		||||
    fun getAlphaFromColor(color: Int): Int {
 | 
			
		||||
        return color shr 24 and 0xFF
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the red value from the Color Hex
 | 
			
		||||
     * @param color color hex as int
 | 
			
		||||
     * @return red of color
 | 
			
		||||
     */
 | 
			
		||||
    fun getRedFromColor(color: Int): Int {
 | 
			
		||||
        return color shr 16 and 0xFF
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the green value from the Color Hex
 | 
			
		||||
     * @param color color hex as int
 | 
			
		||||
     * @return green of color
 | 
			
		||||
     */
 | 
			
		||||
    fun getGreenFromColor(color: Int): Int {
 | 
			
		||||
        return color shr 8 and 0xFF
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the blue value from the Color Hex
 | 
			
		||||
     * @param color color hex as int
 | 
			
		||||
     * @return blue of color
 | 
			
		||||
     */
 | 
			
		||||
    fun getBlueFromColor(color: Int): Int {
 | 
			
		||||
        return color and 0xFF
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Called when dialog is dismissed
 | 
			
		||||
     */
 | 
			
		||||
    override fun onDestroyView() {
 | 
			
		||||
        subscriptions.unsubscribe()
 | 
			
		||||
        super.onDestroyView()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -11,7 +11,6 @@ import eu.kanade.tachiyomi.data.preference.getOrDefault
 | 
			
		||||
import eu.kanade.tachiyomi.util.plusAssign
 | 
			
		||||
import eu.kanade.tachiyomi.widget.IgnoreFirstSpinnerListener
 | 
			
		||||
import kotlinx.android.synthetic.main.dialog_reader_settings.view.*
 | 
			
		||||
import org.adw.library.widgets.discreteseekbar.DiscreteSeekBar
 | 
			
		||||
import rx.Observable
 | 
			
		||||
import rx.android.schedulers.AndroidSchedulers
 | 
			
		||||
import rx.subscriptions.CompositeSubscription
 | 
			
		||||
@@ -84,24 +83,6 @@ class ReaderSettingsDialog : DialogFragment() {
 | 
			
		||||
        fullscreen.setOnCheckedChangeListener { v, isChecked ->
 | 
			
		||||
            preferences.fullscreen().set(isChecked)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        custom_brightness.isChecked = preferences.customBrightness().getOrDefault()
 | 
			
		||||
        custom_brightness.setOnCheckedChangeListener { v, isChecked ->
 | 
			
		||||
            preferences.customBrightness().set(isChecked)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        brightness_seekbar.progress = preferences.customBrightnessValue().getOrDefault()
 | 
			
		||||
        brightness_seekbar.setOnProgressChangeListener(object : DiscreteSeekBar.OnProgressChangeListener {
 | 
			
		||||
            override fun onProgressChanged(seekBar: DiscreteSeekBar, value: Int, fromUser: Boolean) {
 | 
			
		||||
                if (fromUser) {
 | 
			
		||||
                    preferences.customBrightnessValue().set(value)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            override fun onStartTrackingTouch(seekBar: DiscreteSeekBar) {}
 | 
			
		||||
 | 
			
		||||
            override fun onStopTrackingTouch(seekBar: DiscreteSeekBar) {}
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onDestroyView() {
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,61 @@
 | 
			
		||||
package eu.kanade.tachiyomi.widget
 | 
			
		||||
 | 
			
		||||
import android.content.Context
 | 
			
		||||
import android.util.AttributeSet
 | 
			
		||||
import android.widget.SeekBar
 | 
			
		||||
import eu.kanade.tachiyomi.R
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class NegativeSeekBar @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
 | 
			
		||||
        SeekBar(context, attrs) {
 | 
			
		||||
 | 
			
		||||
    private var minValue: Int = 0
 | 
			
		||||
    private var maxValue: Int = 0
 | 
			
		||||
    private var listener: OnSeekBarChangeListener? = null
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        val styledAttributes = context.obtainStyledAttributes(
 | 
			
		||||
                attrs,
 | 
			
		||||
                R.styleable.NegativeSeekBar, 0, 0)
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            setMinSeek(styledAttributes.getInt(R.styleable.NegativeSeekBar_min_seek, 0))
 | 
			
		||||
            setMaxSeek(styledAttributes.getInt(R.styleable.NegativeSeekBar_max_seek, 0))
 | 
			
		||||
        } finally {
 | 
			
		||||
            styledAttributes.recycle()
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        super.setOnSeekBarChangeListener(object : OnSeekBarChangeListener {
 | 
			
		||||
            override fun onProgressChanged(seekBar: SeekBar?, value: Int, fromUser: Boolean) {
 | 
			
		||||
                listener?.let { it.onProgressChanged(seekBar, minValue + value, fromUser) }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            override fun onStartTrackingTouch(p0: SeekBar?) {
 | 
			
		||||
                listener?.let { it.onStartTrackingTouch(p0) }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            override fun onStopTrackingTouch(p0: SeekBar?) {
 | 
			
		||||
                listener?.let { it.onStopTrackingTouch(p0) }
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun setProgress(progress: Int) {
 | 
			
		||||
        super.setProgress(Math.abs(minValue) + progress)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun setMinSeek(minValue: Int) {
 | 
			
		||||
        this.minValue = minValue
 | 
			
		||||
        max = (this.maxValue - this.minValue)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun setMaxSeek(maxValue: Int) {
 | 
			
		||||
        this.maxValue = maxValue
 | 
			
		||||
        max = (this.maxValue - this.minValue)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun setOnSeekBarChangeListener(listener: OnSeekBarChangeListener?) {
 | 
			
		||||
        this.listener = listener
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,11 +1,13 @@
 | 
			
		||||
package eu.kanade.tachiyomi.widget
 | 
			
		||||
 | 
			
		||||
import android.widget.SeekBar
 | 
			
		||||
 | 
			
		||||
open class SimpleSeekBarListener : SeekBar.OnSeekBarChangeListener {
 | 
			
		||||
    override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {}
 | 
			
		||||
    override fun onProgressChanged(seekBar: SeekBar, value: Int, fromUser: Boolean) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onStartTrackingTouch(seekBar: SeekBar) {}
 | 
			
		||||
    override fun onStartTrackingTouch(seekBar: SeekBar) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onStopTrackingTouch(seekBar: SeekBar) {}
 | 
			
		||||
    override fun onStopTrackingTouch(seekBar: SeekBar) {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								app/src/main/res/drawable/filter_mock.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								app/src/main/res/drawable/filter_mock.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 334 KiB  | 
							
								
								
									
										9
									
								
								app/src/main/res/drawable/ic_brightness_4_white_24dp.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								app/src/main/res/drawable/ic_brightness_4_white_24dp.xml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
        android:width="24dp"
 | 
			
		||||
        android:height="24dp"
 | 
			
		||||
        android:viewportWidth="24.0"
 | 
			
		||||
        android:viewportHeight="24.0">
 | 
			
		||||
    <path
 | 
			
		||||
        android:fillColor="#FFFFFFFF"
 | 
			
		||||
        android:pathData="M20,8.69V4h-4.69L12,0.69 8.69,4H4v4.69L0.69,12 4,15.31V20h4.69L12,23.31 15.31,20H20v-4.69L23.31,12 20,8.69zM12,18c-0.89,0 -1.74,-0.2 -2.5,-0.55C11.56,16.5 13,14.42 13,12s-1.44,-4.5 -3.5,-5.45C10.26,6.2 11.11,6 12,6c3.31,0 6,2.69 6,6s-2.69,6 -6,6z"/>
 | 
			
		||||
</vector>
 | 
			
		||||
							
								
								
									
										9
									
								
								app/src/main/res/drawable/ic_brightness_5_black_24dp.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								app/src/main/res/drawable/ic_brightness_5_black_24dp.xml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
        android:width="24dp"
 | 
			
		||||
        android:height="24dp"
 | 
			
		||||
        android:viewportWidth="24.0"
 | 
			
		||||
        android:viewportHeight="24.0">
 | 
			
		||||
    <path
 | 
			
		||||
        android:fillColor="#FF000000"
 | 
			
		||||
        android:pathData="M20,15.31L23.31,12 20,8.69V4h-4.69L12,0.69 8.69,4H4v4.69L0.69,12 4,15.31V20h4.69L12,23.31 15.31,20H20v-4.69zM12,18c-3.31,0 -6,-2.69 -6,-6s2.69,-6 6,-6 6,2.69 6,6 -2.69,6 -6,6z"/>
 | 
			
		||||
</vector>
 | 
			
		||||
@@ -105,4 +105,10 @@
 | 
			
		||||
        android:layout_height="match_parent"
 | 
			
		||||
        android:visibility="gone"/>
 | 
			
		||||
 | 
			
		||||
    <View
 | 
			
		||||
        android:id="@+id/color_overlay"
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="match_parent"
 | 
			
		||||
        android:visibility="gone"/>
 | 
			
		||||
 | 
			
		||||
</FrameLayout>
 | 
			
		||||
							
								
								
									
										257
									
								
								app/src/main/res/layout/dialog_reader_custom_filter.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										257
									
								
								app/src/main/res/layout/dialog_reader_custom_filter.xml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,257 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    xmlns:app="http://schemas.android.com/apk/res-auto"
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="match_parent"
 | 
			
		||||
    android:orientation="vertical">
 | 
			
		||||
 | 
			
		||||
    <RelativeLayout
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="wrap_content">
 | 
			
		||||
 | 
			
		||||
        <android.support.v7.widget.AppCompatImageView
 | 
			
		||||
            android:layout_width="wrap_content"
 | 
			
		||||
            android:layout_height="200dp"
 | 
			
		||||
            android:scaleType="centerCrop"
 | 
			
		||||
            android:src="@drawable/filter_mock" />
 | 
			
		||||
 | 
			
		||||
        <View
 | 
			
		||||
            android:id="@+id/brightness_overlay"
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="200dp"
 | 
			
		||||
            android:visibility="gone" />
 | 
			
		||||
 | 
			
		||||
        <View
 | 
			
		||||
            android:id="@+id/color_overlay"
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="200dp"
 | 
			
		||||
            android:visibility="gone" />
 | 
			
		||||
    </RelativeLayout>
 | 
			
		||||
 | 
			
		||||
    <LinearLayout
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="match_parent"
 | 
			
		||||
        android:orientation="vertical"
 | 
			
		||||
        android:padding="@dimen/material_component_dialogs_padding_around_content_area">
 | 
			
		||||
 | 
			
		||||
        <android.support.v7.widget.SwitchCompat
 | 
			
		||||
            android:id="@+id/switch_color_filter"
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:text="@string/pref_custom_color_filter" />
 | 
			
		||||
 | 
			
		||||
        <RelativeLayout
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="wrap_content">
 | 
			
		||||
 | 
			
		||||
            <TextView
 | 
			
		||||
                android:id="@+id/txt_color_filter_red_symbol"
 | 
			
		||||
                android:layout_width="wrap_content"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:layout_alignParentLeft="true"
 | 
			
		||||
                android:layout_alignParentStart="true"
 | 
			
		||||
                android:layout_centerVertical="true"
 | 
			
		||||
                android:text="@string/color_filter_r_value"
 | 
			
		||||
                android:textAppearance="@style/TextAppearance.Regular.SubHeading.Secondary" />
 | 
			
		||||
 | 
			
		||||
            <TextView
 | 
			
		||||
                android:id="@+id/txt_color_filter_red_value"
 | 
			
		||||
                android:layout_width="30dp"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:layout_alignParentEnd="true"
 | 
			
		||||
                android:layout_alignParentRight="true"
 | 
			
		||||
                android:layout_centerVertical="true"
 | 
			
		||||
                android:textAppearance="@style/TextAppearance.Regular.SubHeading.Secondary" />
 | 
			
		||||
 | 
			
		||||
            <SeekBar
 | 
			
		||||
                android:id="@+id/seekbar_color_filter_red"
 | 
			
		||||
                android:layout_width="match_parent"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:layout_centerVertical="true"
 | 
			
		||||
                android:layout_marginEnd="8dp"
 | 
			
		||||
                android:layout_marginLeft="8dp"
 | 
			
		||||
                android:layout_marginRight="8dp"
 | 
			
		||||
                android:layout_marginStart="8dp"
 | 
			
		||||
                android:layout_toEndOf="@id/txt_color_filter_red_symbol"
 | 
			
		||||
                android:layout_toLeftOf="@id/txt_color_filter_red_value"
 | 
			
		||||
                android:layout_toRightOf="@id/txt_color_filter_red_symbol"
 | 
			
		||||
                android:layout_toStartOf="@id/txt_color_filter_red_value"
 | 
			
		||||
                android:max="255"
 | 
			
		||||
                android:padding="@dimen/material_component_text_fields_floating_label_padding_between_label_and_input_text" />
 | 
			
		||||
 | 
			
		||||
        </RelativeLayout>
 | 
			
		||||
 | 
			
		||||
        <RelativeLayout
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="wrap_content">
 | 
			
		||||
 | 
			
		||||
            <TextView
 | 
			
		||||
                android:id="@+id/txt_color_filter_green_symbol"
 | 
			
		||||
                android:layout_width="wrap_content"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:layout_alignParentLeft="true"
 | 
			
		||||
                android:layout_alignParentStart="true"
 | 
			
		||||
                android:layout_centerVertical="true"
 | 
			
		||||
                android:text="@string/color_filter_g_value"
 | 
			
		||||
                android:textAppearance="@style/TextAppearance.Regular.SubHeading.Secondary" />
 | 
			
		||||
 | 
			
		||||
            <TextView
 | 
			
		||||
                android:id="@+id/txt_color_filter_green_value"
 | 
			
		||||
                android:layout_width="30dp"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:layout_alignParentEnd="true"
 | 
			
		||||
                android:layout_alignParentRight="true"
 | 
			
		||||
                android:layout_centerVertical="true"
 | 
			
		||||
                android:textAppearance="@style/TextAppearance.Regular.SubHeading.Secondary" />
 | 
			
		||||
 | 
			
		||||
            <SeekBar
 | 
			
		||||
                android:id="@+id/seekbar_color_filter_green"
 | 
			
		||||
                android:layout_width="match_parent"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:layout_centerVertical="true"
 | 
			
		||||
                android:layout_marginEnd="8dp"
 | 
			
		||||
                android:layout_marginLeft="8dp"
 | 
			
		||||
                android:layout_marginRight="8dp"
 | 
			
		||||
                android:layout_marginStart="8dp"
 | 
			
		||||
                android:layout_toEndOf="@id/txt_color_filter_green_symbol"
 | 
			
		||||
                android:layout_toLeftOf="@id/txt_color_filter_green_value"
 | 
			
		||||
                android:layout_toRightOf="@id/txt_color_filter_green_symbol"
 | 
			
		||||
                android:layout_toStartOf="@id/txt_color_filter_green_value"
 | 
			
		||||
                android:max="255"
 | 
			
		||||
                android:padding="@dimen/material_component_text_fields_floating_label_padding_between_label_and_input_text" />
 | 
			
		||||
 | 
			
		||||
        </RelativeLayout>
 | 
			
		||||
 | 
			
		||||
        <RelativeLayout
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="wrap_content">
 | 
			
		||||
 | 
			
		||||
            <TextView
 | 
			
		||||
                android:id="@+id/txt_color_filter_blue_symbol"
 | 
			
		||||
                android:layout_width="wrap_content"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:layout_alignParentLeft="true"
 | 
			
		||||
                android:layout_alignParentStart="true"
 | 
			
		||||
                android:layout_centerVertical="true"
 | 
			
		||||
                android:text="@string/color_filter_b_value"
 | 
			
		||||
                android:textAppearance="@style/TextAppearance.Regular.SubHeading.Secondary" />
 | 
			
		||||
 | 
			
		||||
            <TextView
 | 
			
		||||
                android:id="@+id/txt_color_filter_blue_value"
 | 
			
		||||
                android:layout_width="30dp"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:layout_alignParentEnd="true"
 | 
			
		||||
                android:layout_alignParentRight="true"
 | 
			
		||||
                android:layout_centerVertical="true"
 | 
			
		||||
                android:textAppearance="@style/TextAppearance.Regular.SubHeading.Secondary" />
 | 
			
		||||
 | 
			
		||||
            <SeekBar
 | 
			
		||||
                android:id="@+id/seekbar_color_filter_blue"
 | 
			
		||||
                android:layout_width="match_parent"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:layout_centerVertical="true"
 | 
			
		||||
                android:layout_marginEnd="8dp"
 | 
			
		||||
                android:layout_marginLeft="8dp"
 | 
			
		||||
                android:layout_marginRight="8dp"
 | 
			
		||||
                android:layout_marginStart="8dp"
 | 
			
		||||
                android:layout_toEndOf="@id/txt_color_filter_blue_symbol"
 | 
			
		||||
                android:layout_toLeftOf="@id/txt_color_filter_blue_value"
 | 
			
		||||
                android:layout_toRightOf="@id/txt_color_filter_blue_symbol"
 | 
			
		||||
                android:layout_toStartOf="@id/txt_color_filter_blue_value"
 | 
			
		||||
                android:max="255"
 | 
			
		||||
                android:padding="@dimen/material_component_text_fields_floating_label_padding_between_label_and_input_text" />
 | 
			
		||||
        </RelativeLayout>
 | 
			
		||||
 | 
			
		||||
        <RelativeLayout
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="wrap_content">
 | 
			
		||||
 | 
			
		||||
            <TextView
 | 
			
		||||
                android:id="@+id/txt_color_filter_alpha_symbol"
 | 
			
		||||
                android:layout_width="wrap_content"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:layout_alignParentLeft="true"
 | 
			
		||||
                android:layout_alignParentStart="true"
 | 
			
		||||
                android:layout_centerVertical="true"
 | 
			
		||||
                android:text="@string/color_filter_a_value"
 | 
			
		||||
                android:textAppearance="@style/TextAppearance.Regular.SubHeading.Secondary" />
 | 
			
		||||
 | 
			
		||||
            <TextView
 | 
			
		||||
                android:id="@+id/txt_color_filter_alpha_value"
 | 
			
		||||
                android:layout_width="30dp"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:layout_alignParentEnd="true"
 | 
			
		||||
                android:layout_alignParentRight="true"
 | 
			
		||||
                android:layout_centerVertical="true"
 | 
			
		||||
                android:textAppearance="@style/TextAppearance.Regular.SubHeading.Secondary" />
 | 
			
		||||
 | 
			
		||||
            <SeekBar
 | 
			
		||||
                android:id="@+id/seekbar_color_filter_alpha"
 | 
			
		||||
                android:layout_width="match_parent"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:layout_centerVertical="true"
 | 
			
		||||
                android:layout_marginEnd="8dp"
 | 
			
		||||
                android:layout_marginLeft="8dp"
 | 
			
		||||
                android:layout_marginRight="8dp"
 | 
			
		||||
                android:layout_marginStart="8dp"
 | 
			
		||||
                android:layout_toEndOf="@id/txt_color_filter_alpha_symbol"
 | 
			
		||||
                android:layout_toLeftOf="@id/txt_color_filter_alpha_value"
 | 
			
		||||
                android:layout_toRightOf="@id/txt_color_filter_alpha_symbol"
 | 
			
		||||
                android:layout_toStartOf="@id/txt_color_filter_alpha_value"
 | 
			
		||||
                android:max="255"
 | 
			
		||||
                android:padding="@dimen/material_component_text_fields_floating_label_padding_between_label_and_input_text" />
 | 
			
		||||
 | 
			
		||||
        </RelativeLayout>
 | 
			
		||||
 | 
			
		||||
        <android.support.v7.widget.SwitchCompat
 | 
			
		||||
            android:id="@+id/custom_brightness"
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:layout_marginTop="@dimen/material_component_cards_primary_title_top_padding"
 | 
			
		||||
            android:text="@string/pref_custom_brightness" />
 | 
			
		||||
 | 
			
		||||
        <RelativeLayout
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="wrap_content">
 | 
			
		||||
 | 
			
		||||
            <android.support.v7.widget.AppCompatImageView
 | 
			
		||||
                android:id="@+id/txt_brightness_seekbar_icon"
 | 
			
		||||
                android:layout_width="wrap_content"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:layout_alignParentLeft="true"
 | 
			
		||||
                android:layout_alignParentStart="true"
 | 
			
		||||
                android:layout_centerVertical="true"
 | 
			
		||||
                android:textAppearance="@style/TextAppearance.Regular.SubHeading.Secondary"
 | 
			
		||||
                android:tint="?android:attr/textColorSecondary"
 | 
			
		||||
                app:srcCompat="@drawable/ic_brightness_5_black_24dp" />
 | 
			
		||||
 | 
			
		||||
            <TextView
 | 
			
		||||
                android:id="@+id/txt_brightness_seekbar_value"
 | 
			
		||||
                android:layout_width="30dp"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:layout_alignParentEnd="true"
 | 
			
		||||
                android:layout_alignParentRight="true"
 | 
			
		||||
                android:layout_centerVertical="true"
 | 
			
		||||
                android:textAppearance="@style/TextAppearance.Regular.SubHeading.Secondary" />
 | 
			
		||||
 | 
			
		||||
            <eu.kanade.tachiyomi.widget.NegativeSeekBar
 | 
			
		||||
                android:id="@+id/brightness_seekbar"
 | 
			
		||||
                android:layout_width="match_parent"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:layout_centerVertical="true"
 | 
			
		||||
                android:layout_marginEnd="8dp"
 | 
			
		||||
                android:layout_marginLeft="8dp"
 | 
			
		||||
                android:layout_marginRight="8dp"
 | 
			
		||||
                android:layout_marginStart="8dp"
 | 
			
		||||
                android:layout_toEndOf="@id/txt_brightness_seekbar_icon"
 | 
			
		||||
                android:layout_toLeftOf="@id/txt_brightness_seekbar_value"
 | 
			
		||||
                android:layout_toRightOf="@id/txt_brightness_seekbar_icon"
 | 
			
		||||
                android:layout_toStartOf="@id/txt_brightness_seekbar_value"
 | 
			
		||||
                android:padding="@dimen/material_component_text_fields_floating_label_padding_between_label_and_input_text"
 | 
			
		||||
                app:max_seek="100"
 | 
			
		||||
                app:min_seek="-75" />
 | 
			
		||||
 | 
			
		||||
        </RelativeLayout>
 | 
			
		||||
    </LinearLayout>
 | 
			
		||||
 | 
			
		||||
</LinearLayout>
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<LinearLayout
 | 
			
		||||
    xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    xmlns:app="http://schemas.android.com/apk/res-auto"
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="match_parent"
 | 
			
		||||
    xmlns:setting="http://schemas.android.com/tools"
 | 
			
		||||
    android:orientation="vertical"
 | 
			
		||||
    android:padding="@dimen/material_component_dialogs_padding_around_content_area"
 | 
			
		||||
    android:divider="@drawable/empty_divider"
 | 
			
		||||
@@ -171,21 +171,4 @@
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:text="@string/pref_fullscreen"/>
 | 
			
		||||
 | 
			
		||||
    <android.support.v7.widget.SwitchCompat
 | 
			
		||||
        android:id="@+id/custom_brightness"
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:text="@string/pref_custom_brightness"/>
 | 
			
		||||
 | 
			
		||||
    <org.adw.library.widgets.discreteseekbar.DiscreteSeekBar
 | 
			
		||||
        android:id="@+id/brightness_seekbar"
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        app:dsb_min="-75"
 | 
			
		||||
        app:dsb_max="100"
 | 
			
		||||
        app:dsb_indicatorFormatter="%d%%"
 | 
			
		||||
        app:dsb_indicatorTextAppearance="@style/TextAppearance.Regular"
 | 
			
		||||
        app:dsb_indicatorColor="?colorAccent"
 | 
			
		||||
        app:dsb_progressColor="?colorAccent" />
 | 
			
		||||
 | 
			
		||||
</LinearLayout>
 | 
			
		||||
@@ -2,11 +2,18 @@
 | 
			
		||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
      xmlns:app="http://schemas.android.com/apk/res-auto">
 | 
			
		||||
 | 
			
		||||
    <item
 | 
			
		||||
        android:id="@+id/action_custom_filter"
 | 
			
		||||
        android:title="@string/label_settings"
 | 
			
		||||
        android:icon="@drawable/ic_brightness_4_white_24dp"
 | 
			
		||||
        app:showAsAction="ifRoom"
 | 
			
		||||
        />
 | 
			
		||||
 | 
			
		||||
    <item
 | 
			
		||||
        android:id="@+id/action_settings"
 | 
			
		||||
        android:title="@string/label_settings"
 | 
			
		||||
        android:icon="@drawable/ic_settings_white_24dp"
 | 
			
		||||
        app:showAsAction="always"
 | 
			
		||||
        app:showAsAction="ifRoom"
 | 
			
		||||
        />
 | 
			
		||||
 | 
			
		||||
</menu>
 | 
			
		||||
@@ -17,6 +17,11 @@
 | 
			
		||||
        <attr name="max" format="integer"/>
 | 
			
		||||
    </declare-styleable>
 | 
			
		||||
 | 
			
		||||
    <declare-styleable name="NegativeSeekBar">
 | 
			
		||||
        <attr name="min_seek" format="integer"/>
 | 
			
		||||
        <attr name="max_seek" format="integer"/>
 | 
			
		||||
    </declare-styleable>
 | 
			
		||||
 | 
			
		||||
    <attr name="navigation_view_theme" format="reference"/>
 | 
			
		||||
    <attr name="selectable_list_drawable" format="reference|integer" />
 | 
			
		||||
    <attr name="selectable_library_drawable" format="reference|integer"/>
 | 
			
		||||
 
 | 
			
		||||
@@ -32,6 +32,9 @@
 | 
			
		||||
    <string name="pref_keep_screen_on_key">pref_keep_screen_on_key</string>
 | 
			
		||||
    <string name="pref_custom_brightness_key">pref_custom_brightness_key</string>
 | 
			
		||||
    <string name="pref_custom_brightness_value_key">custom_brightness_value</string>
 | 
			
		||||
    <string name="pref_color_filter_key">pref_color_filter_key</string>
 | 
			
		||||
    <string name="pref_color_filter_value_key">color_filter_value</string>
 | 
			
		||||
    <string name="pref_red_filter_value_key">pref_red_filter_value</string>
 | 
			
		||||
    <string name="pref_reader_theme_key">pref_reader_theme_key</string>
 | 
			
		||||
    <string name="pref_image_decoder_key">pref_image_decoder_key</string>
 | 
			
		||||
    <string name="pref_read_with_volume_keys_key">reader_volume_keys</string>
 | 
			
		||||
 
 | 
			
		||||
@@ -105,6 +105,7 @@
 | 
			
		||||
    <string name="pref_enable_transitions">Enable transitions</string>
 | 
			
		||||
    <string name="pref_show_page_number">Show page number</string>
 | 
			
		||||
    <string name="pref_custom_brightness">Use custom brightness</string>
 | 
			
		||||
    <string name="pref_custom_color_filter">Use custom color filter</string>
 | 
			
		||||
    <string name="pref_keep_screen_on">Keep screen on</string>
 | 
			
		||||
    <string name="pref_reader_navigation">Navigation</string>
 | 
			
		||||
    <string name="pref_read_with_volume_keys">Volume keys</string>
 | 
			
		||||
@@ -138,6 +139,11 @@
 | 
			
		||||
    <string name="rotation_lock">Lock</string>
 | 
			
		||||
    <string name="rotation_force_portrait">Force portrait</string>
 | 
			
		||||
    <string name="rotation_force_landscape">Force landscape</string>
 | 
			
		||||
    <string name="color_filter_r_value">R</string>
 | 
			
		||||
    <string name="color_filter_g_value">G</string>
 | 
			
		||||
    <string name="color_filter_b_value">B</string>
 | 
			
		||||
    <string name="color_filter_a_value">A</string>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      <!-- Downloads section -->
 | 
			
		||||
    <string name="pref_download_directory">Downloads directory</string>
 | 
			
		||||
 
 | 
			
		||||
@@ -91,6 +91,10 @@
 | 
			
		||||
        <item name="android:textSize">16sp</item>
 | 
			
		||||
    </style>
 | 
			
		||||
 | 
			
		||||
    <style name="TextAppearance.Regular.SubHeading.Secondary">
 | 
			
		||||
        <item name="android:textColor">?android:attr/textColorSecondary</item>
 | 
			
		||||
    </style>
 | 
			
		||||
 | 
			
		||||
    <style name="TextAppearance.Regular.SubHeading.Light">
 | 
			
		||||
        <item name="android:textColor">@color/textColorPrimaryDark</item>
 | 
			
		||||
    </style>
 | 
			
		||||
@@ -107,6 +111,10 @@
 | 
			
		||||
        <item name="android:textSize">20sp</item>
 | 
			
		||||
    </style>
 | 
			
		||||
 | 
			
		||||
    <style name="TextAppearance.Medium.Title.Secondary">
 | 
			
		||||
        <item name="android:textColor">?android:attr/textColorSecondary</item>
 | 
			
		||||
    </style>
 | 
			
		||||
 | 
			
		||||
    <style name="TextAppearance.Medium.Body2">
 | 
			
		||||
        <item name="android:textSize">14sp</item>
 | 
			
		||||
    </style>
 | 
			
		||||
 
 | 
			
		||||
@@ -69,11 +69,6 @@
 | 
			
		||||
            android:key="@string/pref_show_page_number_key"
 | 
			
		||||
            android:defaultValue="true" />
 | 
			
		||||
 | 
			
		||||
        <SwitchPreference
 | 
			
		||||
            android:title="@string/pref_custom_brightness"
 | 
			
		||||
            android:key="@string/pref_custom_brightness_key"
 | 
			
		||||
            android:defaultValue="false" />
 | 
			
		||||
 | 
			
		||||
        <SwitchPreference
 | 
			
		||||
            android:title="@string/pref_keep_screen_on"
 | 
			
		||||
            android:key="@string/pref_keep_screen_on_key"
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user