diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/swipe/SwipeControlsPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/swipe/SwipeControlsPatch.java index f4b0d16ad..794b9f0e1 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/swipe/SwipeControlsPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/swipe/SwipeControlsPatch.java @@ -4,6 +4,7 @@ import android.view.View; import java.lang.ref.WeakReference; +import app.revanced.extension.shared.settings.Setting; import app.revanced.extension.youtube.settings.Settings; @SuppressWarnings({"unused", "deprecation"}) @@ -59,4 +60,20 @@ public class SwipeControlsPatch { return engagementOverlayView != null && engagementOverlayView.getVisibility() == View.VISIBLE; } + public static final class SwipeOverlayTextSizeAvailability implements Setting.Availability { + @Override + public boolean isAvailable() { + return (Settings.ENABLE_SWIPE_BRIGHTNESS.get() || Settings.ENABLE_SWIPE_VOLUME.get()) && + !Settings.SWIPE_OVERLAY_ALTERNATIVE_UI.get(); + } + } + + public static final class SwipeOverlayModernUIAvailability implements Setting.Availability { + @Override + public boolean isAvailable() { + return (Settings.ENABLE_SWIPE_BRIGHTNESS.get() || Settings.ENABLE_SWIPE_VOLUME.get()) && + Settings.SWIPE_OVERLAY_ALTERNATIVE_UI.get(); + } + } + } diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java index b5bc6994e..ae6f3fea3 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java @@ -42,6 +42,7 @@ import app.revanced.extension.youtube.patches.player.ExitFullscreenPatch.Fullscr import app.revanced.extension.youtube.patches.player.MiniplayerPatch; import app.revanced.extension.youtube.patches.shorts.AnimationFeedbackPatch.AnimationType; import app.revanced.extension.youtube.patches.shorts.ShortsRepeatStatePatch.ShortsLoopBehavior; +import app.revanced.extension.youtube.patches.swipe.SwipeControlsPatch; import app.revanced.extension.youtube.patches.utils.PatchStatus; import app.revanced.extension.youtube.shared.PlaylistIdPrefix; import app.revanced.extension.youtube.sponsorblock.SponsorBlockSettings; @@ -522,9 +523,15 @@ public class Settings extends BaseSettings { public static final BooleanSetting ENABLE_SWIPE_PRESS_TO_ENGAGE = new BooleanSetting("revanced_enable_swipe_press_to_engage", FALSE, true, parentsAny(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)); public static final BooleanSetting ENABLE_SWIPE_HAPTIC_FEEDBACK = new BooleanSetting("revanced_enable_swipe_haptic_feedback", TRUE, true, parentsAny(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)); public static final BooleanSetting SWIPE_LOCK_MODE = new BooleanSetting("revanced_swipe_gestures_lock_mode", FALSE, true, parentsAny(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)); + public static final BooleanSetting SWIPE_OVERLAY_ALTERNATIVE_UI = new BooleanSetting("revanced_swipe_overlay_alternative_ui", TRUE, true, parentsAny(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)); + public static final BooleanSetting SWIPE_SHOW_CIRCULAR_OVERLAY = new BooleanSetting("revanced_swipe_show_circular_overlay", FALSE, true, + new SwipeControlsPatch.SwipeOverlayModernUIAvailability()); + public static final BooleanSetting SWIPE_OVERLAY_MINIMAL_STYLE = new BooleanSetting("revanced_swipe_overlay_minimal_style", FALSE, true, + new SwipeControlsPatch.SwipeOverlayModernUIAvailability()); + public static final IntegerSetting SWIPE_OVERLAY_BACKGROUND_OPACITY = new IntegerSetting("revanced_swipe_overlay_background_opacity", 60, true, parentsAny(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)); + public static final IntegerSetting SWIPE_OVERLAY_TEXT_SIZE = new IntegerSetting("revanced_swipe_overlay_text_size", 20, true, + new SwipeControlsPatch.SwipeOverlayTextSizeAvailability()); public static final IntegerSetting SWIPE_MAGNITUDE_THRESHOLD = new IntegerSetting("revanced_swipe_magnitude_threshold", 0, true, parentsAny(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)); - public static final IntegerSetting SWIPE_OVERLAY_BACKGROUND_ALPHA = new IntegerSetting("revanced_swipe_overlay_background_alpha", 127, true, parentsAny(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)); - public static final IntegerSetting SWIPE_OVERLAY_TEXT_SIZE = new IntegerSetting("revanced_swipe_overlay_text_size", 20, true, parentsAny(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)); public static final IntegerSetting SWIPE_OVERLAY_RECT_SIZE = new IntegerSetting("revanced_swipe_overlay_rect_size", 20, true, parentsAny(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)); public static final LongSetting SWIPE_OVERLAY_TIMEOUT = new LongSetting("revanced_swipe_overlay_timeout", 500L, true, parentsAny(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)); diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/swipecontrols/SwipeControlsConfigurationProvider.kt b/extensions/shared/src/main/java/app/revanced/extension/youtube/swipecontrols/SwipeControlsConfigurationProvider.kt index 3d3c5d83d..dbe9cf385 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/swipecontrols/SwipeControlsConfigurationProvider.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/swipecontrols/SwipeControlsConfigurationProvider.kt @@ -125,7 +125,7 @@ class SwipeControlsConfigurationProvider( * get the background color for text on the overlay, as a color int */ val overlayTextBackgroundColor: Int - get() = Color.argb(Settings.SWIPE_OVERLAY_BACKGROUND_ALPHA.get(), 0, 0, 0) + get() = overlayBackgroundOpacity /** * get the foreground color for text on the overlay, as a color int @@ -133,6 +133,59 @@ class SwipeControlsConfigurationProvider( val overlayForegroundColor: Int get() = Color.WHITE + /** + * Gets the opacity value (0-100%) is converted to an alpha value (0-255) for transparency. + * If the opacity value is out of range, it resets to the default and displays a warning message. + */ + val overlayBackgroundOpacity: Int + get() { + var opacity = validateValue( + Settings.SWIPE_OVERLAY_BACKGROUND_OPACITY, + 0, + 100, + "revanced_swipe_overlay_background_opacity_invalid_toast" + ) + + opacity = opacity * 255 / 100 + return Color.argb(opacity, 0, 0, 0) + } + + /** + * The color of the progress overlay. + */ + val overlayProgressColor: Int + get() = 0xBFFFFFFF.toInt() + + /** + * The color used for the background of the progress overlay fill. + */ + val overlayFillBackgroundPaint: Int + get() = 0x80D3D3D3.toInt() + + /** + * The color used for the text and icons in the overlay. + */ + val overlayTextColor: Int + get() = Color.WHITE + + /** + * A flag that determines whether to use the alternate UI. + */ + val isAlternativeUI: Boolean + get() = Settings.SWIPE_OVERLAY_ALTERNATIVE_UI.get() + + /** + * A flag that determines if the overlay should only show the icon. + */ + val overlayShowOverlayMinimalStyle: Boolean + get() = isAlternativeUI && Settings.SWIPE_OVERLAY_MINIMAL_STYLE.get() + + /** + * A flag that determines if the progress bar should be circular. + */ + val isCircularProgressBar: Boolean + get() = isAlternativeUI && Settings.SWIPE_SHOW_CIRCULAR_OVERLAY.get() + // endregion // region behaviour diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/swipecontrols/SwipeControlsHostActivity.kt b/extensions/shared/src/main/java/app/revanced/extension/youtube/swipecontrols/SwipeControlsHostActivity.kt index 3ebebc252..f2b5e4aa4 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/swipecontrols/SwipeControlsHostActivity.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/swipecontrols/SwipeControlsHostActivity.kt @@ -24,7 +24,7 @@ import java.lang.ref.WeakReference * The main controller for volume and brightness swipe controls. * note that the superclass is overwritten to the superclass of the MainActivity at patch time * - * @smali Lapp/revanced/integrations/youtube/swipecontrols/SwipeControlsHostActivity; + * @smali Lapp/revanced/extension/youtube/swipecontrols/SwipeControlsHostActivity; */ class SwipeControlsHostActivity : Activity() { /** diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/swipecontrols/views/SwipeControlsOverlayLayout.kt b/extensions/shared/src/main/java/app/revanced/extension/youtube/swipecontrols/views/SwipeControlsOverlayLayout.kt index 6d2cef606..edc936b75 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/swipecontrols/views/SwipeControlsOverlayLayout.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/swipecontrols/views/SwipeControlsOverlayLayout.kt @@ -1,14 +1,18 @@ package app.revanced.extension.youtube.swipecontrols.views +import android.annotation.SuppressLint import android.content.Context +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.RectF import android.graphics.drawable.Drawable import android.graphics.drawable.GradientDrawable import android.os.Handler import android.os.Looper +import android.util.AttributeSet import android.util.TypedValue import android.view.HapticFeedbackConstants import android.view.View -import android.view.ViewGroup import android.widget.RelativeLayout import android.widget.TextView import app.revanced.extension.shared.utils.ResourceUtils.ResourceType @@ -17,6 +21,7 @@ import app.revanced.extension.shared.utils.StringRef.str import app.revanced.extension.youtube.swipecontrols.SwipeControlsConfigurationProvider import app.revanced.extension.youtube.swipecontrols.misc.SwipeControlsOverlay import app.revanced.extension.youtube.swipecontrols.misc.applyDimension +import kotlin.math.min import kotlin.math.round /** @@ -33,36 +38,82 @@ class SwipeControlsOverlayLayout( */ constructor(context: Context) : this(context, SwipeControlsConfigurationProvider(context)) - private val feedbackTextView: TextView private val autoBrightnessIcon: Drawable + private val lowBrightnessIcon: Drawable = getDrawable("revanced_ic_sc_brightness_low") + private val mediumBrightnessIcon: Drawable = getDrawable("revanced_ic_sc_brightness_medium") + private val highBrightnessIcon: Drawable = getDrawable("revanced_ic_sc_brightness_high") + private val fullBrightnessIcon: Drawable = getDrawable("revanced_ic_sc_brightness_full") private val manualBrightnessIcon: Drawable private val mutedVolumeIcon: Drawable + private val lowVolumeIcon: Drawable = getDrawable("revanced_ic_sc_volume_low") private val normalVolumeIcon: Drawable + private val feedbackTextView: TextView + private val fullVolumeIcon: Drawable = getDrawable("revanced_ic_sc_volume_high") - private fun getDrawable(name: String, width: Int, height: Int): Drawable { - return resources.getDrawable( + private val circularProgressView: CircularProgressView = CircularProgressView( + context, + config.overlayBackgroundOpacity, + config.overlayShowOverlayMinimalStyle, + config.overlayProgressColor, + config.overlayFillBackgroundPaint, + config.overlayTextColor + ).apply { + layoutParams = LayoutParams(300, 300).apply { + addRule(CENTER_IN_PARENT, TRUE) + } + visibility = GONE // Initially hidden + } + private val horizontalProgressView: HorizontalProgressView + + private val isAlternativeUI: Boolean = config.isAlternativeUI + + private fun getDrawable(name: String, width: Int? = null, height: Int? = null): Drawable { + val drawable = resources.getDrawable( getIdentifier(name, ResourceType.DRAWABLE, context), - context.theme - ).apply { - setTint(config.overlayForegroundColor) - setBounds( + context.theme, + ) + + if (width != null && height != null) { + drawable.setTint(config.overlayForegroundColor) + drawable.setBounds( 0, 0, width, height, ) + } else { + drawable.setTint(config.overlayTextColor) } + return drawable } init { + // Initialize horizontal progress bar + val screenWidth = resources.displayMetrics.widthPixels + val layoutWidth = (screenWidth * 2 / 3).toInt() // 2/3 of screen width + horizontalProgressView = HorizontalProgressView( + context, + config.overlayBackgroundOpacity, + config.overlayShowOverlayMinimalStyle, + config.overlayProgressColor, + config.overlayFillBackgroundPaint, + config.overlayTextColor + ).apply { + layoutParams = LayoutParams(layoutWidth, 100).apply { + addRule(CENTER_HORIZONTAL) + topMargin = 40 // Top margin + } + visibility = GONE // Initially hidden + } + // init views val feedbackYTextViewPadding = 5.applyDimension(context, TypedValue.COMPLEX_UNIT_DIP) val feedbackXTextViewPadding = 12.applyDimension(context, TypedValue.COMPLEX_UNIT_DIP) val compoundIconPadding = 4.applyDimension(context, TypedValue.COMPLEX_UNIT_DIP) feedbackTextView = TextView(context).apply { layoutParams = LayoutParams( - ViewGroup.LayoutParams.WRAP_CONTENT, - ViewGroup.LayoutParams.WRAP_CONTENT, + LayoutParams.WRAP_CONTENT, + LayoutParams.WRAP_CONTENT, ).apply { addRule(CENTER_IN_PARENT, TRUE) setPadding( @@ -81,19 +132,34 @@ class SwipeControlsOverlayLayout( compoundDrawablePadding = compoundIconPadding visibility = GONE } - addView(feedbackTextView) - // get icons scaled, assuming square icons - val iconHeight = round(feedbackTextView.lineHeight * .8).toInt() - autoBrightnessIcon = getDrawable("ic_sc_brightness_auto", iconHeight, iconHeight) - manualBrightnessIcon = getDrawable("ic_sc_brightness_manual", iconHeight, iconHeight) - mutedVolumeIcon = getDrawable("ic_sc_volume_mute", iconHeight, iconHeight) - normalVolumeIcon = getDrawable("ic_sc_volume_normal", iconHeight, iconHeight) + if (isAlternativeUI) { + addView(circularProgressView) + addView(horizontalProgressView) + + autoBrightnessIcon = getDrawable("revanced_ic_sc_brightness_auto") + manualBrightnessIcon = getDrawable("revanced_ic_sc_brightness_manual") + mutedVolumeIcon = getDrawable("revanced_ic_sc_volume_mute") + normalVolumeIcon = getDrawable("revanced_ic_sc_volume_normal") + } else { + addView(feedbackTextView) + // get icons scaled, assuming square icons + val iconHeight = round(feedbackTextView.lineHeight * .8).toInt() + autoBrightnessIcon = getDrawable("revanced_ic_sc_brightness_auto", iconHeight, iconHeight) + manualBrightnessIcon = getDrawable("revanced_ic_sc_brightness_manual", iconHeight, iconHeight) + mutedVolumeIcon = getDrawable("revanced_ic_sc_volume_mute", iconHeight, iconHeight) + normalVolumeIcon = getDrawable("revanced_ic_sc_volume_normal", iconHeight, iconHeight) + } } private val feedbackHideHandler = Handler(Looper.getMainLooper()) private val feedbackHideCallback = Runnable { - feedbackTextView.visibility = View.GONE + if (isAlternativeUI) { + circularProgressView.visibility = GONE + horizontalProgressView.visibility = GONE + } else { + feedbackTextView.visibility = GONE + } } /** @@ -117,21 +183,68 @@ class SwipeControlsOverlayLayout( } } + /** + * Displays the progress bar with the appropriate value, icon, and type (brightness or volume). + */ + private fun showFeedbackView(value: String, progress: Int, max: Int, icon: Drawable, isBrightness: Boolean) { + feedbackHideHandler.removeCallbacks(feedbackHideCallback) + feedbackHideHandler.postDelayed(feedbackHideCallback, config.overlayShowTimeoutMillis) + + val viewToShow = if (config.isCircularProgressBar) circularProgressView else horizontalProgressView + viewToShow.apply { + setProgress(progress, max, value, isBrightness) + this.icon = icon + visibility = VISIBLE + } + } + override fun onVolumeChanged(newVolume: Int, maximumVolume: Int) { - showFeedbackView( - "$newVolume", - if (newVolume > 0) normalVolumeIcon else mutedVolumeIcon, - ) + if (isAlternativeUI) { + val volumePercentage = (newVolume.toFloat() / maximumVolume) * 100 + val icon = when { + newVolume == 0 -> mutedVolumeIcon + volumePercentage < 33 -> lowVolumeIcon + volumePercentage < 66 -> normalVolumeIcon + else -> fullVolumeIcon + } + showFeedbackView("$newVolume", newVolume, maximumVolume, icon, isBrightness = false) + } else { + showFeedbackView( + "$newVolume", + if (newVolume > 0) normalVolumeIcon else mutedVolumeIcon, + ) + } } override fun onBrightnessChanged(brightness: Double) { if (config.shouldLowestValueEnableAutoBrightness && brightness <= 0) { - showFeedbackView( - str("revanced_swipe_lowest_value_auto_brightness_overlay_text"), - autoBrightnessIcon, - ) + if (isAlternativeUI) { + showFeedbackView( + str("revanced_swipe_lowest_value_auto_brightness_overlay_text"), + 0, + 100, + autoBrightnessIcon, + isBrightness = true, + ) + } else { + showFeedbackView( + str("revanced_swipe_lowest_value_auto_brightness_overlay_text"), + autoBrightnessIcon, + ) + } } else if (brightness >= 0) { - showFeedbackView("${round(brightness).toInt()}%", manualBrightnessIcon) + if (isAlternativeUI) { + val brightnessValue = round(brightness).toInt() + val icon = when { + brightnessValue < 25 -> lowBrightnessIcon + brightnessValue < 50 -> mediumBrightnessIcon + brightnessValue < 75 -> highBrightnessIcon + else -> fullBrightnessIcon + } + showFeedbackView("$brightnessValue%", brightnessValue, 100, icon, isBrightness = true) + } else { + showFeedbackView("${round(brightness).toInt()}%", manualBrightnessIcon) + } } } @@ -145,3 +258,227 @@ class SwipeControlsOverlayLayout( } } } + +/** + * Abstract base class for progress views. + */ +abstract class AbstractProgressView( + context: Context, + overlayBackgroundOpacity: Int, + protected val overlayShowOverlayMinimalStyle: Boolean, + overlayProgressColor: Int, + overlayFillBackgroundPaint: Int, + protected val overlayTextColor: Int, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : View(context, attrs, defStyleAttr) { + + // Combined paint creation function for both fill and stroke styles + private fun createPaint(color: Int, style: Paint.Style = Paint.Style.FILL, strokeCap: Paint.Cap = Paint.Cap.BUTT, strokeWidth: Float = 0f) = Paint(Paint.ANTI_ALIAS_FLAG).apply { + this.style = style + this.color = color + this.strokeCap = strokeCap + this.strokeWidth = strokeWidth + } + + // Initialize paints + val backgroundPaint = createPaint(overlayBackgroundOpacity, style = Paint.Style.FILL) + val progressPaint = createPaint(overlayProgressColor, style = Paint.Style.STROKE, strokeCap = Paint.Cap.ROUND, strokeWidth = 20f) + val fillBackgroundPaint = createPaint(overlayFillBackgroundPaint, style = Paint.Style.FILL) + val textPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { + color = overlayTextColor + textAlign = Paint.Align.CENTER + textSize = 40f // Can adjust based on need + } + + protected var progress = 0 + protected var maxProgress = 100 + protected var displayText: String = "0" + protected var isBrightness = true + var icon: Drawable? = null + + fun setProgress(value: Int, max: Int, text: String, isBrightnessMode: Boolean) { + progress = value + maxProgress = max + displayText = text + isBrightness = isBrightnessMode + invalidate() + } + + override fun onDraw(canvas: Canvas) { + // Base class implementation can be empty + } +} + +/** + * Custom view for rendering a circular progress indicator with icons and text. + */ +@SuppressLint("ViewConstructor") +class CircularProgressView( + context: Context, + overlayBackgroundOpacity: Int, + overlayShowOverlayMinimalStyle: Boolean, + overlayProgressColor: Int, + overlayFillBackgroundPaint: Int, + overlayTextColor: Int, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : AbstractProgressView( + context, + overlayBackgroundOpacity, + overlayShowOverlayMinimalStyle, + overlayProgressColor, + overlayFillBackgroundPaint, + overlayTextColor, + attrs, + defStyleAttr +) { + private val rectF = RectF() + + init { + textPaint.textSize = 40f // Override default text size for circular view + progressPaint.strokeWidth = 20f + fillBackgroundPaint.strokeWidth = 20f + progressPaint.strokeCap = Paint.Cap.ROUND + fillBackgroundPaint.strokeCap = Paint.Cap.BUTT + progressPaint.style = Paint.Style.STROKE + fillBackgroundPaint.style = Paint.Style.STROKE + } + + override fun onDraw(canvas: Canvas) { + super.onDraw(canvas) + + val size = min(width, height).toFloat() + rectF.set(20f, 20f, size - 20f, size - 20f) + + canvas.drawOval(rectF, fillBackgroundPaint) // Draw the outer ring. + canvas.drawCircle(width / 2f, height / 2f, size / 3, backgroundPaint) // Draw the inner circle. + + // Select the paint for drawing based on whether it's brightness or volume. + val sweepAngle = (progress.toFloat() / maxProgress) * 360 + canvas.drawArc(rectF, -90f, sweepAngle, false, progressPaint) // Draw the progress arc. + + // Draw the icon in the center. + icon?.let { + val iconSize = if (overlayShowOverlayMinimalStyle) 100 else 80 + val iconX = (width - iconSize) / 2 + val iconY = (height / 2) - if (overlayShowOverlayMinimalStyle) 50 else 80 + it.setBounds(iconX, iconY, iconX + iconSize, iconY + iconSize) + it.draw(canvas) + } + + // If not a minimal style mode, draw the text inside the ring. + if (!overlayShowOverlayMinimalStyle) { + canvas.drawText(displayText, width / 2f, height / 2f + 60f, textPaint) + } + } +} + +/** + * Custom view for rendering a rectangular progress bar with icons and text. + */ +@SuppressLint("ViewConstructor") +class HorizontalProgressView( + context: Context, + overlayBackgroundOpacity: Int, + overlayShowOverlayMinimalStyle: Boolean, + overlayProgressColor: Int, + overlayFillBackgroundPaint: Int, + overlayTextColor: Int, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : AbstractProgressView( + context, + overlayBackgroundOpacity, + overlayShowOverlayMinimalStyle, + overlayProgressColor, + overlayFillBackgroundPaint, + overlayTextColor, + attrs, + defStyleAttr +) { + + private val iconSize = 60f + private val padding = 40f + + init { + textPaint.textSize = 36f // Override default text size for horizontal view + progressPaint.strokeWidth = 0f + progressPaint.strokeCap = Paint.Cap.BUTT + progressPaint.style = Paint.Style.FILL + fillBackgroundPaint.style = Paint.Style.FILL + } + + override fun onDraw(canvas: Canvas) { + super.onDraw(canvas) + + val width = width.toFloat() + val height = height.toFloat() + + // Radius for rounded corners + val cornerRadius = min(width, height) / 2 + + // Calculate the total width for the elements + val minimalElementWidth = 5 * padding + iconSize + + // Calculate the starting point (X) to center the elements + val minimalStartX = (width - minimalElementWidth) / 2 + + // Draw the background + if (!overlayShowOverlayMinimalStyle) { + canvas.drawRoundRect(0f, 0f, width, height, cornerRadius, cornerRadius, backgroundPaint) + } else { + canvas.drawRoundRect(minimalStartX, 0f, minimalStartX + minimalElementWidth, height, cornerRadius, cornerRadius, backgroundPaint) + } + + if (!overlayShowOverlayMinimalStyle) { + // Draw the fill background + val startX = 2 * padding + iconSize + val endX = width - 4 * padding + val fillWidth = endX - startX + + canvas.drawRoundRect( + startX, + height / 2 - 5f, + endX, + height / 2 + 5f, + 10f, 10f, + fillBackgroundPaint + ) + + // Draw the progress + val progressWidth = (progress.toFloat() / maxProgress) * fillWidth + canvas.drawRoundRect( + startX, + height / 2 - 5f, + startX + progressWidth, + height / 2 + 5f, + 10f, 10f, + progressPaint + ) + } + + // Draw the icon + icon?.let { + val iconX = if (!overlayShowOverlayMinimalStyle) { + padding + } else { + padding + minimalStartX + } + val iconY = height / 2 - iconSize / 2 + it.setBounds(iconX.toInt(), iconY.toInt(), (iconX + iconSize).toInt(), (iconY + iconSize).toInt()) + it.draw(canvas) + } + + // Draw the text on the right + val textX = if (!overlayShowOverlayMinimalStyle) { + width - 2 * padding + } else { + minimalStartX + minimalElementWidth - 2 * padding + } + val textY = height / 2 + textPaint.textSize / 3 + + // Draw the text + canvas.drawText(displayText, textX, textY, textPaint) + } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/swipe/controls/SwipeControlsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/swipe/controls/SwipeControlsPatch.kt index af0c104b5..3b82fb404 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/swipe/controls/SwipeControlsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/swipe/controls/SwipeControlsPatch.kt @@ -160,13 +160,13 @@ val swipeControlsPatch = bytecodePatch( val reference = getReference() opcode == Opcode.INVOKE_VIRTUAL && reference?.returnType == "V" && - reference.parameterTypes.size == 0 + reference.parameterTypes.isEmpty() } val targetIndex = indexOfFirstInstructionOrThrow(middleIndex + 1) { val reference = getReference() opcode == Opcode.INVOKE_VIRTUAL && reference?.returnType == "V" && - reference.parameterTypes.size == 0 + reference.parameterTypes.isEmpty() } if (getInstruction(targetIndex - 1).opcode != Opcode.IGET_OBJECT) { throw PatchException( @@ -242,10 +242,16 @@ val swipeControlsPatch = bytecodePatch( "youtube/swipecontrols", ResourceGroup( "drawable", - "ic_sc_brightness_auto.xml", - "ic_sc_brightness_manual.xml", - "ic_sc_volume_mute.xml", - "ic_sc_volume_normal.xml" + "revanced_ic_sc_brightness_auto.xml", + "revanced_ic_sc_brightness_full.xml", + "revanced_ic_sc_brightness_high.xml", + "revanced_ic_sc_brightness_low.xml", + "revanced_ic_sc_brightness_manual.xml", + "revanced_ic_sc_brightness_medium.xml", + "revanced_ic_sc_volume_high.xml", + "revanced_ic_sc_volume_low.xml", + "revanced_ic_sc_volume_mute.xml", + "revanced_ic_sc_volume_normal.xml", ) ) diff --git a/patches/src/main/resources/youtube/settings/host/values/strings.xml b/patches/src/main/resources/youtube/settings/host/values/strings.xml index c2bdc0677..13936985f 100644 --- a/patches/src/main/resources/youtube/settings/host/values/strings.xml +++ b/patches/src/main/resources/youtube/settings/host/values/strings.xml @@ -1693,10 +1693,14 @@ No margins on top and bottom of player." Lowest value of the brightness gesture activates auto-brightness. Lowest value of the brightness gesture does not activate auto-brightness. Enable brightness gesture - Brightness swipe is enabled. + "Fullscreen brightness swipe is enabled. + + Adjust brightness by swiping vertically on the left side of the screen." Brightness swipe is disabled. Enable volume gesture - Volume swipe is enabled. + "Fullscreen volume swipe is enabled. + + Adjust volume by swiping vertically on the right side of the screen." Volume swipe is disabled. Enable save and restore brightness Save and restore brightness when exiting or entering fullscreen. @@ -1710,10 +1714,20 @@ No margins on top and bottom of player." Swipe gestures in Lock screen mode Swipe gestures are enabled in Lock screen mode. Swipe gestures are disabled in Lock screen mode. - Swipe background visibility - The visibility of the swipe overlay background. Swipe magnitude threshold The threshold for a swipe to occur. + Swipe overlay alternative UI + Alternative UI is used. + Legacy UI is used. + Enable minimal style + Minimal overlay style is enabled. + Minimal overlay style is disabled. + Show circular overlay + Circular overlay is shown. + Horizontal overlay is shown. + Swipe overlay background opacity + Opacity value between 0-100. + Swipe opacity must be between 0-100. Swipe overlay text size The text size in the swipe overlay. Swipe overlay screen size @@ -1721,6 +1735,7 @@ No margins on top and bottom of player." Swipeable area size cannot be more than 50. Swipe overlay timeout The amount of milliseconds the overlay is visible. + Brightness swipe sensitivity Configure the minimum distance for brightness swiping between 1 and 1000 (%).\nThe shorter the minimum distance, the faster the brightness level changes. Brightness swipe sensitivity must be between 1-1000 (%). diff --git a/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml b/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml index 355ae717e..f75bc168d 100644 --- a/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml +++ b/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml @@ -700,8 +700,11 @@ - + + + + diff --git a/patches/src/main/resources/youtube/swipecontrols/drawable/ic_sc_brightness_auto.xml b/patches/src/main/resources/youtube/swipecontrols/drawable/ic_sc_brightness_auto.xml deleted file mode 100644 index 827919d70..000000000 --- a/patches/src/main/resources/youtube/swipecontrols/drawable/ic_sc_brightness_auto.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/patches/src/main/resources/youtube/swipecontrols/drawable/ic_sc_brightness_manual.xml b/patches/src/main/resources/youtube/swipecontrols/drawable/ic_sc_brightness_manual.xml deleted file mode 100644 index 567940298..000000000 --- a/patches/src/main/resources/youtube/swipecontrols/drawable/ic_sc_brightness_manual.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/patches/src/main/resources/youtube/swipecontrols/drawable/ic_sc_volume_mute.xml b/patches/src/main/resources/youtube/swipecontrols/drawable/ic_sc_volume_mute.xml deleted file mode 100644 index d3b17332a..000000000 --- a/patches/src/main/resources/youtube/swipecontrols/drawable/ic_sc_volume_mute.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/patches/src/main/resources/youtube/swipecontrols/drawable/ic_sc_volume_normal.xml b/patches/src/main/resources/youtube/swipecontrols/drawable/ic_sc_volume_normal.xml deleted file mode 100644 index 144ec4c4c..000000000 --- a/patches/src/main/resources/youtube/swipecontrols/drawable/ic_sc_volume_normal.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_auto.xml b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_auto.xml new file mode 100644 index 000000000..252a97982 --- /dev/null +++ b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_auto.xml @@ -0,0 +1,28 @@ + + + + + diff --git a/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_full.xml b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_full.xml new file mode 100644 index 000000000..c0d45293c --- /dev/null +++ b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_full.xml @@ -0,0 +1,29 @@ + + + + + diff --git a/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_high.xml b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_high.xml new file mode 100644 index 000000000..fe45b31be --- /dev/null +++ b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_high.xml @@ -0,0 +1,29 @@ + + + + + diff --git a/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_low.xml b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_low.xml new file mode 100644 index 000000000..66010e253 --- /dev/null +++ b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_low.xml @@ -0,0 +1,29 @@ + + + + + diff --git a/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_manual.xml b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_manual.xml new file mode 100644 index 000000000..a5dc31c48 --- /dev/null +++ b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_manual.xml @@ -0,0 +1,30 @@ + + + + + diff --git a/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_medium.xml b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_medium.xml new file mode 100644 index 000000000..fc191d25e --- /dev/null +++ b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_medium.xml @@ -0,0 +1,28 @@ + + + + + diff --git a/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_volume_high.xml b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_volume_high.xml new file mode 100644 index 000000000..5dfb76a0e --- /dev/null +++ b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_volume_high.xml @@ -0,0 +1,29 @@ + + + + + diff --git a/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_volume_low.xml b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_volume_low.xml new file mode 100644 index 000000000..e52b1fe4a --- /dev/null +++ b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_volume_low.xml @@ -0,0 +1,29 @@ + + + + + diff --git a/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_volume_mute.xml b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_volume_mute.xml new file mode 100644 index 000000000..59b9e72e4 --- /dev/null +++ b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_volume_mute.xml @@ -0,0 +1,28 @@ + + + + + diff --git a/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_volume_normal.xml b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_volume_normal.xml new file mode 100644 index 000000000..602cd2a64 --- /dev/null +++ b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_volume_normal.xml @@ -0,0 +1,29 @@ + + + + +