Pages color filter implementation draft

pull/216/head
Koitharu 4 years ago
parent 68dcacb918
commit d853bb2c62
No known key found for this signature in database
GPG Key ID: 8E861F8CE6E7CE27

@ -132,11 +132,14 @@
<activity <activity
android:name="org.koitharu.kotatsu.sync.ui.SyncAuthActivity" android:name="org.koitharu.kotatsu.sync.ui.SyncAuthActivity"
android:label="@string/sync" /> android:label="@string/sync" />
<activity
android:name="org.koitharu.kotatsu.reader.ui.colorfilter.ColorFilterConfigActivity"
android:label="@string/color_filter" />
<service <service
android:name="org.koitharu.kotatsu.download.ui.service.DownloadService" android:name="org.koitharu.kotatsu.download.ui.service.DownloadService"
android:stopWithTask="false" android:foregroundServiceType="dataSync"
android:foregroundServiceType="dataSync" /> android:stopWithTask="false" />
<service android:name="org.koitharu.kotatsu.local.ui.LocalChaptersRemoveService" /> <service android:name="org.koitharu.kotatsu.local.ui.LocalChaptersRemoveService" />
<service android:name="org.koitharu.kotatsu.local.ui.ImportService" /> <service android:name="org.koitharu.kotatsu.local.ui.ImportService" />
<service <service

@ -14,6 +14,7 @@ import androidx.core.graphics.Insets
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding import androidx.core.view.updatePadding
import com.google.android.material.R as materialR
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject import javax.inject.Inject
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
@ -46,7 +47,7 @@ class FavouritesCategoryEditActivity :
setContentView(ActivityCategoryEditBinding.inflate(layoutInflater)) setContentView(ActivityCategoryEditBinding.inflate(layoutInflater))
supportActionBar?.run { supportActionBar?.run {
setDisplayHomeAsUpEnabled(true) setDisplayHomeAsUpEnabled(true)
setHomeAsUpIndicator(com.google.android.material.R.drawable.abc_ic_clear_material) setHomeAsUpIndicator(materialR.drawable.abc_ic_clear_material)
} }
initSortSpinner() initSortSpinner()
binding.buttonDone.setOnClickListener(this) binding.buttonDone.setOnClickListener(this)

@ -0,0 +1,108 @@
package org.koitharu.kotatsu.reader.ui.colorfilter
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.graphics.LightingColorFilter
import android.os.Bundle
import android.view.ViewGroup
import androidx.core.graphics.Insets
import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding
import androidx.lifecycle.lifecycleScope
import coil.ImageLoader
import coil.request.ImageRequest
import coil.size.Scale
import coil.size.ViewSizeResolver
import com.google.android.material.slider.Slider
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import org.koitharu.kotatsu.base.ui.BaseActivity
import org.koitharu.kotatsu.core.model.parcelable.ParcelableMangaPages
import org.koitharu.kotatsu.core.parser.MangaRepository
import org.koitharu.kotatsu.databinding.ActivityColorFilterBinding
import org.koitharu.kotatsu.parsers.model.MangaPage
import org.koitharu.kotatsu.utils.ext.enqueueWith
import org.koitharu.kotatsu.utils.ext.referer
import javax.inject.Inject
import kotlin.math.roundToInt
import com.google.android.material.R as materialR
@AndroidEntryPoint
class ColorFilterConfigActivity : BaseActivity<ActivityColorFilterBinding>(), Slider.OnChangeListener {
@Inject
lateinit var coil: ImageLoader
@Inject
lateinit var mangaRepositoryFacotry: MangaRepository.Factory
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(ActivityColorFilterBinding.inflate(layoutInflater))
supportActionBar?.run {
setDisplayHomeAsUpEnabled(true)
setHomeAsUpIndicator(materialR.drawable.abc_ic_clear_material)
}
binding.sliderLightness.addOnChangeListener(this)
binding.sliderSaturation.addOnChangeListener(this)
initPreview()
updateFilter()
}
override fun onValueChange(slider: Slider, value: Float, fromUser: Boolean) {
updateFilter()
}
override fun onWindowInsetsChanged(insets: Insets) {
binding.root.updatePadding(
left = insets.left,
right = insets.right,
)
binding.scrollView.updatePadding(
bottom = insets.bottom,
)
binding.toolbar.updateLayoutParams<ViewGroup.MarginLayoutParams> {
topMargin = insets.top
}
}
private fun updateFilter() {
fun Int.toColor() = Color.rgb(this, this, this)
val cf = LightingColorFilter(
binding.sliderSaturation.value.roundToInt().toColor(),
binding.sliderLightness.value.roundToInt().toColor(),
)
binding.imageViewAfter.colorFilter = cf
}
private fun initPreview() {
val page = intent?.getParcelableExtra<ParcelableMangaPages>(EXTRA_PAGES)?.pages?.firstOrNull()
if (page == null) {
finishAfterTransition()
return
}
lifecycleScope.launch {
val repository = mangaRepositoryFacotry.create(page.source)
val url = repository.getPageUrl(page)
ImageRequest.Builder(this@ColorFilterConfigActivity)
.data(url)
.referer(page.referer)
.scale(Scale.FILL)
.size(ViewSizeResolver(binding.imageViewBefore))
.allowRgb565(false)
.target(ShadowViewTarget(binding.imageViewBefore, binding.imageViewAfter))
.enqueueWith(coil)
}
}
companion object {
private const val EXTRA_PAGES = "pages"
fun newIntent(context: Context, page: MangaPage) = Intent(context, ColorFilterConfigActivity::class.java)
.putExtra(EXTRA_PAGES, ParcelableMangaPages(listOf(page)))
}
}

@ -0,0 +1,18 @@
package org.koitharu.kotatsu.reader.ui.colorfilter
import android.graphics.drawable.Drawable
import android.widget.ImageView
import coil.target.ImageViewTarget
class ShadowViewTarget(
view: ImageView,
private val shadowView: ImageView,
) : ImageViewTarget(view) {
override var drawable: Drawable?
get() = super.drawable
set(value) {
super.drawable = value
shadowView.setImageDrawable(value?.constantState?.newDrawable())
}
}

@ -20,6 +20,7 @@ import org.koitharu.kotatsu.core.prefs.ReaderMode
import org.koitharu.kotatsu.databinding.SheetReaderConfigBinding import org.koitharu.kotatsu.databinding.SheetReaderConfigBinding
import org.koitharu.kotatsu.reader.ui.PageSaveContract import org.koitharu.kotatsu.reader.ui.PageSaveContract
import org.koitharu.kotatsu.reader.ui.ReaderViewModel import org.koitharu.kotatsu.reader.ui.ReaderViewModel
import org.koitharu.kotatsu.reader.ui.colorfilter.ColorFilterConfigActivity
import org.koitharu.kotatsu.settings.SettingsActivity import org.koitharu.kotatsu.settings.SettingsActivity
import org.koitharu.kotatsu.utils.ScreenOrientationHelper import org.koitharu.kotatsu.utils.ScreenOrientationHelper
import org.koitharu.kotatsu.utils.ext.viewLifecycleScope import org.koitharu.kotatsu.utils.ext.viewLifecycleScope
@ -59,6 +60,7 @@ class ReaderConfigBottomSheet :
binding.buttonSavePage.setOnClickListener(this) binding.buttonSavePage.setOnClickListener(this)
binding.buttonScreenRotate.setOnClickListener(this) binding.buttonScreenRotate.setOnClickListener(this)
binding.buttonSettings.setOnClickListener(this) binding.buttonSettings.setOnClickListener(this)
binding.buttonColorFilter.setOnClickListener(this)
binding.sliderTimer.addOnSliderTouchListener(this) binding.sliderTimer.addOnSliderTouchListener(this)
binding.sliderTimer.setLabelFormatter(PageSwitchTimer.DelayLabelFormatter(view.resources)) binding.sliderTimer.setLabelFormatter(PageSwitchTimer.DelayLabelFormatter(view.resources))
@ -80,6 +82,10 @@ class ReaderConfigBottomSheet :
R.id.button_screen_rotate -> { R.id.button_screen_rotate -> {
orientationHelper?.toggleOrientation() orientationHelper?.toggleOrientation()
} }
R.id.button_color_filter -> {
val page = viewModel.getCurrentPage() ?: return
startActivity(ColorFilterConfigActivity.newIntent(v.context, page))
}
} }
} }

@ -1,5 +1,12 @@
<vector android:autoMirrored="true" android:height="24dp" <vector
android:tint="#000000" android:viewportHeight="24" xmlns:android="http://schemas.android.com/apk/res/android"
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> android:width="24dp"
<path android:fillColor="@android:color/white" android:pathData="M12,4l-1.41,1.41L16.17,11H4v2h12.17l-5.58,5.59L12,20l8,-8z"/> android:height="24dp"
android:autoMirrored="true"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M12,4l-1.41,1.41L16.17,11H4v2h12.17l-5.58,5.59L12,20l8,-8z" />
</vector> </vector>

@ -0,0 +1,108 @@
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
tools:navigationIcon="@drawable/abc_ic_clear_material"
tools:title="@string/color_filter">
<Button
android:id="@+id/button_done"
style="@style/Widget.Material3.Button.UnelevatedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginHorizontal="@dimen/toolbar_button_margin"
android:text="@string/done" />
</com.google.android.material.appbar.MaterialToolbar>
<ScrollView
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:overScrollMode="ifContentScrolls">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="@dimen/margin_normal">
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/imageView_before"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="centerCrop"
app:layout_constraintDimensionRatio="W,14:9"
app:layout_constraintEnd_toStartOf="@id/imageView_arrow"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:shapeAppearance="?shapeAppearanceCornerLarge"
app:strokeColor="?colorOutline"
app:strokeWidth="1dp"
tools:src="@sample/covers" />
<ImageView
android:id="@+id/imageView_arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/margin_normal"
android:src="@drawable/ic_arrow_forward"
app:layout_constraintBottom_toBottomOf="@id/imageView_before"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/imageView_before" />
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/imageView_after"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="centerCrop"
app:layout_constraintDimensionRatio="W,14:9"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/imageView_arrow"
app:layout_constraintTop_toTopOf="parent"
app:shapeAppearance="?shapeAppearanceCornerLarge"
app:strokeColor="?colorOutline"
app:strokeWidth="1dp"
tools:src="@sample/covers" />
<com.google.android.material.slider.Slider
android:id="@+id/slider_saturation"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_normal"
android:value="255.0"
android:valueFrom="0.0"
android:valueTo="255.0"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/imageView_before" />
<com.google.android.material.slider.Slider
android:id="@+id/slider_lightness"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_normal"
android:value="0.0"
android:valueFrom="0.0"
android:valueTo="255.0"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/slider_saturation" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</LinearLayout>

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/textView"
android:padding="8dp"
android:textAppearance="@style/TextAppearance.AppCompat"
android:textSize="20sp"
app:drawableEndCompat="@drawable/ic_arrow_forward"
app:drawableTint="?attr/colorPrimary"
tools:text="History" />

@ -133,6 +133,17 @@
</LinearLayout> </LinearLayout>
<org.koitharu.kotatsu.base.ui.widgets.ListItemTextView
android:id="@+id/button_color_filter"
android:layout_width="match_parent"
android:layout_height="?android:listPreferredItemHeightSmall"
android:drawablePadding="?android:listPreferredItemPaddingStart"
android:paddingStart="?android:listPreferredItemPaddingStart"
android:paddingEnd="?android:listPreferredItemPaddingEnd"
android:text="@string/color_filter"
android:textAppearance="?attr/textAppearanceButton"
app:drawableStartCompat="@drawable/ic_appearance" />
<org.koitharu.kotatsu.base.ui.widgets.ListItemTextView <org.koitharu.kotatsu.base.ui.widgets.ListItemTextView
android:id="@+id/button_settings" android:id="@+id/button_settings"
android:layout_width="match_parent" android:layout_width="match_parent"

@ -376,4 +376,5 @@
<string name="import_completed_hint">You can delete the original file from storage to save space</string> <string name="import_completed_hint">You can delete the original file from storage to save space</string>
<string name="import_will_start_soon">Import will start soon</string> <string name="import_will_start_soon">Import will start soon</string>
<string name="feed">Feed</string> <string name="feed">Feed</string>
<string name="color_filter">Color filter</string>
</resources> </resources>

Loading…
Cancel
Save