Feat: Complete 14 sliders integration, remove pen button and implement custom 3-second long press (10_FIX_SLIDER.md)

This commit is contained in:
2026-07-05 18:16:39 +07:00
parent 1a74887fe0
commit bcbb853558
5 changed files with 530 additions and 112 deletions
@@ -136,19 +136,30 @@ class MainActivity : AppCompatActivity() {
val contrast = extractJsonDoubleField(content, "contrast").toFloat()
val saturation = extractJsonDoubleField(content, "saturation").toFloat()
val vibrance = extractJsonDoubleField(content, "vibrance").toFloat()
val temperature = extractJsonDoubleField(content, "temperature").toFloat()
val tint = extractJsonDoubleField(content, "tint").toFloat()
val clarity = extractJsonDoubleField(content, "clarity").toFloat()
val dehaze = extractJsonDoubleField(content, "dehaze").toFloat()
val vignetteAmount = extractJsonDoubleField(content, "vignette_amount").toFloat()
val fadedBlackLevel = extractJsonDoubleField(content, "faded_black_level").toFloat()
val shadowsTintR = extractJsonDoubleField(content, "shadows_tint_r").toFloat()
val shadowsTintG = extractJsonDoubleField(content, "shadows_tint_g").toFloat()
val shadowsTintB = extractJsonDoubleField(content, "shadows_tint_b").toFloat()
val grainAmount = extractJsonDoubleField(content, "grain_amount").toFloat()
val grainSize = extractJsonDoubleField(content, "grain_size").toFloat()
val preset = ColorPreset(
id = id,
name = name,
themeCategory = category,
isEditable = true,
basic = BasicAdjustments(brightness, contrast, saturation, vibrance, 0f, 0f),
advanced = AdvancedEffects(clarity, dehaze, 0f),
toneCurve = ToneCurveEmulation(0f, 0f, 0f, 0f),
grain = FilmGrain(0f, 0f)
basic = BasicAdjustments(brightness, contrast, saturation, vibrance, temperature, tint),
advanced = AdvancedEffects(clarity, dehaze, vignetteAmount),
toneCurve = ToneCurveEmulation(fadedBlackLevel, shadowsTintR, shadowsTintG, shadowsTintB),
grain = FilmGrain(grainAmount, grainSize)
)
customList.add(preset)
} catch (e: Exception) {
@@ -213,11 +224,22 @@ class MainActivity : AppCompatActivity() {
"instax_bw_cool" -> android.graphics.Color.argb(80, 128, 128, 128)
"instax_cool_summer" -> android.graphics.Color.argb(45, 0, 188, 212)
else -> {
// Map user configured RGB overlay incorporating Vibrance, Clarity, and Dehaze
val alpha = ((preset.basic.vibrance + 1.0f) * 45 + 15).toInt().coerceIn(10, 110)
val r = ((preset.advanced.clarity + 1.0f) * 115 + 20).toInt().coerceIn(0, 255)
val g = ((preset.basic.contrast + 1.0f) * 100 + 20).toInt().coerceIn(0, 255)
val b = ((preset.advanced.dehaze + 1.0f) * 95 + 15).toInt().coerceIn(0, 255)
// Sophisticated ARGB mapping to simulate film filters using adjustment parameters
// Vibrance and Saturation increase opacity of the filter color
val alpha = (((preset.basic.vibrance + preset.basic.saturation) / 2f + 1.0f) * 40 + 20).toInt().coerceIn(10, 120)
// Temperature (+ is warm/red-yellow), Brightness, Clarity, and ShadowsTintR affect red
val tempWarmth = if (preset.basic.temperature > 0) preset.basic.temperature * 50f else 0f
val r = (((preset.advanced.clarity + preset.basic.brightness) / 2f + 1.0f) * 100 + 30 + tempWarmth + (preset.toneCurve.shadowsTintR * 30)).toInt().coerceIn(0, 255)
// Contrast, Tint (- is green), and ShadowsTintG affect green
val tintGreen = if (preset.basic.tint < 0) -preset.basic.tint * 50f else 0f
val g = ((preset.basic.contrast + 1.0f) * 90 + 20 + tintGreen + (preset.toneCurve.shadowsTintG * 30)).toInt().coerceIn(0, 255)
// Dehaze, cool Temperature (- is blue), and ShadowsTintB affect blue
val tempCoolness = if (preset.basic.temperature < 0) -preset.basic.temperature * 60f else 0f
val b = (((preset.advanced.dehaze + 1.0f) * 80) + 20 + tempCoolness + (preset.toneCurve.shadowsTintB * 30)).toInt().coerceIn(0, 255)
android.graphics.Color.argb(alpha, r, g, b)
}
}
@@ -308,6 +330,27 @@ class MainActivity : AppCompatActivity() {
}
// Advanced Sliders listeners
binding.sliderBrightness.addOnChangeListener { _, value, _ ->
editingPreset?.let { preset ->
preset.basic.brightness = value
binding.tvLabelBrightness.text = "Brightness (Độ sáng): ${String.format("%.2f", value)}"
applyPresetFilter(preset)
}
}
binding.sliderContrast.addOnChangeListener { _, value, _ ->
editingPreset?.let { preset ->
preset.basic.contrast = value
binding.tvLabelContrast.text = "Contrast (Tương phản): ${String.format("%.2f", value)}"
applyPresetFilter(preset)
}
}
binding.sliderSaturation.addOnChangeListener { _, value, _ ->
editingPreset?.let { preset ->
preset.basic.saturation = value
binding.tvLabelSaturation.text = "Saturation (Bão hòa màu): ${String.format("%.2f", value)}"
applyPresetFilter(preset)
}
}
binding.sliderVibrance.addOnChangeListener { _, value, _ ->
editingPreset?.let { preset ->
preset.basic.vibrance = value
@@ -315,6 +358,20 @@ class MainActivity : AppCompatActivity() {
applyPresetFilter(preset)
}
}
binding.sliderTemperature.addOnChangeListener { _, value, _ ->
editingPreset?.let { preset ->
preset.basic.temperature = value
binding.tvLabelTemperature.text = "Temperature (Nhiệt màu): ${String.format("%.2f", value)}"
applyPresetFilter(preset)
}
}
binding.sliderTint.addOnChangeListener { _, value, _ ->
editingPreset?.let { preset ->
preset.basic.tint = value
binding.tvLabelTint.text = "Tint (Sắc độ hồng/xanh): ${String.format("%.2f", value)}"
applyPresetFilter(preset)
}
}
binding.sliderClarity.addOnChangeListener { _, value, _ ->
editingPreset?.let { preset ->
preset.advanced.clarity = value
@@ -329,6 +386,55 @@ class MainActivity : AppCompatActivity() {
applyPresetFilter(preset)
}
}
binding.sliderVignetteAmount.addOnChangeListener { _, value, _ ->
editingPreset?.let { preset ->
preset.advanced.vignetteAmount = value
binding.tvLabelVignetteAmount.text = "Vignette Amount (Bo tối góc): ${String.format("%.2f", value)}"
applyPresetFilter(preset)
}
}
binding.sliderFadedBlack.addOnChangeListener { _, value, _ ->
editingPreset?.let { preset ->
preset.toneCurve.fadedBlackLevel = value
binding.tvLabelFadedBlack.text = "Faded Black Level (Độ mờ vùng đen): ${String.format("%.2f", value)}"
applyPresetFilter(preset)
}
}
binding.sliderShadowsTintR.addOnChangeListener { _, value, _ ->
editingPreset?.let { preset ->
preset.toneCurve.shadowsTintR = value
binding.tvLabelShadowsTintR.text = "Shadows Tint R (Sắc Đỏ vùng tối): ${String.format("%.2f", value)}"
applyPresetFilter(preset)
}
}
binding.sliderShadowsTintG.addOnChangeListener { _, value, _ ->
editingPreset?.let { preset ->
preset.toneCurve.shadowsTintG = value
binding.tvLabelShadowsTintG.text = "Shadows Tint G (Sắc Lục vùng tối): ${String.format("%.2f", value)}"
applyPresetFilter(preset)
}
}
binding.sliderShadowsTintB.addOnChangeListener { _, value, _ ->
editingPreset?.let { preset ->
preset.toneCurve.shadowsTintB = value
binding.tvLabelShadowsTintB.text = "Shadows Tint B (Sắc Lam vùng tối): ${String.format("%.2f", value)}"
applyPresetFilter(preset)
}
}
binding.sliderGrainAmount.addOnChangeListener { _, value, _ ->
editingPreset?.let { preset ->
preset.grain.grainAmount = value
binding.tvLabelGrainAmount.text = "Grain Amount (Mật độ hạt): ${String.format("%.2f", value)}"
applyPresetFilter(preset)
}
}
binding.sliderGrainSize.addOnChangeListener { _, value, _ ->
editingPreset?.let { preset ->
preset.grain.grainSize = value
binding.tvLabelGrainSize.text = "Grain Size (Kích thước hạt): ${String.format("%.2f", value)}"
applyPresetFilter(preset)
}
}
binding.btnCancelEdit.setOnClickListener {
closeAdvancedSliders()
@@ -433,14 +539,38 @@ class MainActivity : AppCompatActivity() {
binding.tvEditPresetName.text = "Chỉnh sửa: ${selectedPreset.name}"
// Update Sliders visual values
binding.sliderBrightness.value = editingPreset!!.basic.brightness
binding.sliderContrast.value = editingPreset!!.basic.contrast
binding.sliderSaturation.value = editingPreset!!.basic.saturation
binding.sliderVibrance.value = editingPreset!!.basic.vibrance
binding.sliderTemperature.value = editingPreset!!.basic.temperature
binding.sliderTint.value = editingPreset!!.basic.tint
binding.sliderClarity.value = editingPreset!!.advanced.clarity
binding.sliderDehaze.value = editingPreset!!.advanced.dehaze
binding.sliderVignetteAmount.value = editingPreset!!.advanced.vignetteAmount
binding.sliderFadedBlack.value = editingPreset!!.toneCurve.fadedBlackLevel
binding.sliderShadowsTintR.value = editingPreset!!.toneCurve.shadowsTintR
binding.sliderShadowsTintG.value = editingPreset!!.toneCurve.shadowsTintG
binding.sliderShadowsTintB.value = editingPreset!!.toneCurve.shadowsTintB
binding.sliderGrainAmount.value = editingPreset!!.grain.grainAmount
binding.sliderGrainSize.value = editingPreset!!.grain.grainSize
// Update text labels
binding.tvLabelBrightness.text = "Brightness (Độ sáng): ${String.format("%.2f", editingPreset!!.basic.brightness)}"
binding.tvLabelContrast.text = "Contrast (Tương phản): ${String.format("%.2f", editingPreset!!.basic.contrast)}"
binding.tvLabelSaturation.text = "Saturation (Bão hòa màu): ${String.format("%.2f", editingPreset!!.basic.saturation)}"
binding.tvLabelVibrance.text = "Vibrance (Bão hòa thông minh): ${String.format("%.2f", editingPreset!!.basic.vibrance)}"
binding.tvLabelTemperature.text = "Temperature (Nhiệt màu): ${String.format("%.2f", editingPreset!!.basic.temperature)}"
binding.tvLabelTint.text = "Tint (Sắc độ hồng/xanh): ${String.format("%.2f", editingPreset!!.basic.tint)}"
binding.tvLabelClarity.text = "Clarity (Độ rõ nét vùng trung tính): ${String.format("%.2f", editingPreset!!.advanced.clarity)}"
binding.tvLabelDehaze.text = "Dehaze (Độ trong suốt / Sương mù): ${String.format("%.2f", editingPreset!!.advanced.dehaze)}"
binding.tvLabelVignetteAmount.text = "Vignette Amount (Bo tối góc): ${String.format("%.2f", editingPreset!!.advanced.vignetteAmount)}"
binding.tvLabelFadedBlack.text = "Faded Black Level (Độ mờ vùng đen): ${String.format("%.2f", editingPreset!!.toneCurve.fadedBlackLevel)}"
binding.tvLabelShadowsTintR.text = "Shadows Tint R (Sắc Đỏ vùng tối): ${String.format("%.2f", editingPreset!!.toneCurve.shadowsTintR)}"
binding.tvLabelShadowsTintG.text = "Shadows Tint G (Sắc Lục vùng tối): ${String.format("%.2f", editingPreset!!.toneCurve.shadowsTintG)}"
binding.tvLabelShadowsTintB.text = "Shadows Tint B (Sắc Lam vùng tối): ${String.format("%.2f", editingPreset!!.toneCurve.shadowsTintB)}"
binding.tvLabelGrainAmount.text = "Grain Amount (Mật độ hạt): ${String.format("%.2f", editingPreset!!.grain.grainAmount)}"
binding.tvLabelGrainSize.text = "Grain Size (Kích thước hạt): ${String.format("%.2f", editingPreset!!.grain.grainSize)}"
// Scale animation from center
binding.cardAdvancedSliders.apply {
@@ -503,13 +633,32 @@ class MainActivity : AppCompatActivity() {
name = newName,
themeCategory = "Custom",
isEditable = true,
basic = BasicAdjustments(tempPreset.basic.brightness, tempPreset.basic.contrast, tempPreset.basic.saturation, tempPreset.basic.vibrance, 0f, 0f),
advanced = AdvancedEffects(tempPreset.advanced.clarity, tempPreset.advanced.dehaze, 0f),
toneCurve = ToneCurveEmulation(0f, 0f, 0f, 0f),
grain = FilmGrain(0f, 0f)
basic = BasicAdjustments(
tempPreset.basic.brightness,
tempPreset.basic.contrast,
tempPreset.basic.saturation,
tempPreset.basic.vibrance,
tempPreset.basic.temperature,
tempPreset.basic.tint
),
advanced = AdvancedEffects(
tempPreset.advanced.clarity,
tempPreset.advanced.dehaze,
tempPreset.advanced.vignetteAmount
),
toneCurve = ToneCurveEmulation(
tempPreset.toneCurve.fadedBlackLevel,
tempPreset.toneCurve.shadowsTintR,
tempPreset.toneCurve.shadowsTintG,
tempPreset.toneCurve.shadowsTintB
),
grain = FilmGrain(
tempPreset.grain.grainAmount,
tempPreset.grain.grainSize
)
)
// Serialize to JSON format manually
// Serialize to JSON format manually (incorporating all 14 parameters)
val jsonString = """
{
"id": "$customId",
@@ -521,23 +670,23 @@ class MainActivity : AppCompatActivity() {
"contrast": ${customPreset.basic.contrast},
"saturation": ${customPreset.basic.saturation},
"vibrance": ${customPreset.basic.vibrance},
"temperature": 0.0,
"tint": 0.0
"temperature": ${customPreset.basic.temperature},
"tint": ${customPreset.basic.tint}
},
"advanced_effects": {
"clarity": ${customPreset.advanced.clarity},
"dehaze": ${customPreset.advanced.dehaze},
"vignette_amount": 0.0
"vignette_amount": ${customPreset.advanced.vignetteAmount}
},
"tone_curve_emulation": {
"faded_black_level": 0.0,
"shadows_tint_r": 0.0,
"shadows_tint_g": 0.0,
"shadows_tint_b": 0.0
"faded_black_level": ${customPreset.toneCurve.fadedBlackLevel},
"shadows_tint_r": ${customPreset.toneCurve.shadowsTintR},
"shadows_tint_g": ${customPreset.toneCurve.shadowsTintG},
"shadows_tint_b": ${customPreset.toneCurve.shadowsTintB}
},
"film_grain": {
"grain_amount": 0.0,
"grain_size": 0.0
"grain_amount": ${customPreset.grain.grainAmount},
"grain_size": ${customPreset.grain.grainSize}
}
}
""".trimIndent()
@@ -18,13 +18,11 @@ class PresetAdapter(
) : RecyclerView.Adapter<PresetAdapter.ViewHolder>() {
private var selectedPosition = 0
private var editingPosition = -1
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val cardPreset: MaterialCardView = view.findViewById(R.id.cardPreset)
val viewPresetColor: View = view.findViewById(R.id.viewPresetColor)
val txtPresetName: TextView = view.findViewById(R.id.txtPresetName)
val btnSmallEdit: ImageButton = view.findViewById(R.id.btnSmallEdit)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
@@ -55,13 +53,6 @@ class PresetAdapter(
holder.viewPresetColor.background = circleDrawable
}
// Show edit button on long press
if (position == editingPosition && preset.isEditable) {
holder.btnSmallEdit.visibility = View.VISIBLE
} else {
holder.btnSmallEdit.visibility = View.GONE
}
// Highlight selection
val strokeWidthPx = (3 * holder.itemView.context.resources.displayMetrics.density).toInt()
if (position == selectedPosition) {
@@ -72,30 +63,53 @@ class PresetAdapter(
holder.cardPreset.strokeWidth = 0
}
holder.itemView.setOnClickListener {
val previousSelected = selectedPosition
selectedPosition = position
notifyItemChanged(previousSelected)
notifyItemChanged(selectedPosition)
onPresetSelected(preset)
// Setup custom 3-second long press detector with touch slop cancellation
val handler = android.os.Handler(android.os.Looper.getMainLooper())
var isLongPressTriggered = false
var startX = 0f
var startY = 0f
val touchSlop = 15f // pixels
val longPressRunnable = Runnable {
if (preset.isEditable) {
isLongPressTriggered = true
holder.itemView.performHapticFeedback(android.view.HapticFeedbackConstants.LONG_PRESS)
onEditClicked(preset)
}
}
holder.itemView.setOnLongClickListener {
if (preset.isEditable) {
val prevEditing = editingPosition
editingPosition = if (editingPosition == position) -1 else position
notifyItemChanged(prevEditing)
if (editingPosition != -1) {
notifyItemChanged(editingPosition)
holder.itemView.setOnTouchListener { view, event ->
when (event.action) {
android.view.MotionEvent.ACTION_DOWN -> {
isLongPressTriggered = false
startX = event.x
startY = event.y
handler.postDelayed(longPressRunnable, 3000)
}
android.view.MotionEvent.ACTION_MOVE -> {
if (Math.abs(event.x - startX) > touchSlop || Math.abs(event.y - startY) > touchSlop) {
handler.removeCallbacks(longPressRunnable)
}
}
android.view.MotionEvent.ACTION_UP -> {
handler.removeCallbacks(longPressRunnable)
if (!isLongPressTriggered) {
val previousSelected = selectedPosition
selectedPosition = holder.adapterPosition
if (selectedPosition != RecyclerView.NO_POSITION) {
notifyItemChanged(previousSelected)
notifyItemChanged(selectedPosition)
onPresetSelected(preset)
view.performClick()
}
}
}
android.view.MotionEvent.ACTION_CANCEL -> {
handler.removeCallbacks(longPressRunnable)
}
holder.itemView.performHapticFeedback(android.view.HapticFeedbackConstants.LONG_PRESS)
}
true
}
holder.btnSmallEdit.setOnClickListener {
onEditClicked(preset)
}
}
override fun getItemCount(): Int = presets.size
@@ -108,7 +122,6 @@ class PresetAdapter(
fun resetSelection() {
val previousSelected = selectedPosition
selectedPosition = 0
editingPosition = -1
notifyItemChanged(previousSelected)
notifyItemChanged(selectedPosition)
}
@@ -151,65 +151,112 @@
android:contentDescription="Cancel Edit" />
</RelativeLayout>
<!-- ================= DANH SÁCH CÁC CỤM SLIDERS ĐỂ CUỘN ================= -->
<!-- 1. VIBRANCE -->
<!-- ================= NHÓM 1: CƠ BẢN (BASIC ADJUSTMENTS) ================= -->
<TextView
android:id="@+id/tvLabelVibrance"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Vibrance (Bão hòa thông minh): 0.0"
android:textColor="#FFFFFF"
android:textSize="12sp" />
<com.google.android.material.slider.Slider
android:id="@+id/sliderVibrance"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:valueFrom="-1.0"
android:valueTo="1.0"
android:value="0.0"
app:thumbColor="#FF9800"
app:trackColorActive="#FF9800"
app:trackColorInactive="#333333" />
android:text="ĐIỀU CHỈNH CƠ BẢN"
android:textColor="#FF9800"
android:textStyle="bold"
android:textSize="11sp"
android:layout_marginTop="8dp"
android:layout_marginBottom="4dp"/>
<!-- 2. CLARITY -->
<TextView
android:id="@+id/tvLabelClarity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Clarity (Độ rõ nét vùng trung tính): 0.0"
android:textColor="#FFFFFF"
android:textSize="12sp"
android:layout_marginTop="8dp" />
<com.google.android.material.slider.Slider
android:id="@+id/sliderClarity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:valueFrom="-1.0"
android:valueTo="1.0"
android:value="0.0"
app:thumbColor="#FF9800"
app:trackColorActive="#FF9800"
app:trackColorInactive="#333333" />
<!-- Brightness -->
<TextView android:id="@+id/tvLabelBrightness" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="#FFFFFF" android:textSize="11sp" android:text="Brightness (Độ sáng): 0.00"/>
<com.google.android.material.slider.Slider android:id="@+id/sliderBrightness" android:layout_width="match_parent" android:layout_height="wrap_content" android:valueFrom="-1.0" android:valueTo="1.0" android:value="0.0" app:thumbColor="#FF9800" app:trackColorActive="#FF9800" app:trackColorInactive="#333333"/>
<!-- 3. DEHAZE -->
<!-- Contrast -->
<TextView android:id="@+id/tvLabelContrast" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="#FFFFFF" android:textSize="11sp" android:text="Contrast (Tương phản): 0.00"/>
<com.google.android.material.slider.Slider android:id="@+id/sliderContrast" android:layout_width="match_parent" android:layout_height="wrap_content" android:valueFrom="-1.0" android:valueTo="1.0" android:value="0.0" app:thumbColor="#FF9800" app:trackColorActive="#FF9800" app:trackColorInactive="#333333"/>
<!-- Saturation -->
<TextView android:id="@+id/tvLabelSaturation" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="#FFFFFF" android:textSize="11sp" android:text="Saturation (Bão hòa màu): 0.00"/>
<com.google.android.material.slider.Slider android:id="@+id/sliderSaturation" android:layout_width="match_parent" android:layout_height="wrap_content" android:valueFrom="-1.0" android:valueTo="1.0" android:value="0.0" app:thumbColor="#FF9800" app:trackColorActive="#FF9800" app:trackColorInactive="#333333"/>
<!-- Vibrance -->
<TextView android:id="@+id/tvLabelVibrance" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="#FFFFFF" android:textSize="11sp" android:text="Vibrance (Bão hòa thông minh): 0.00"/>
<com.google.android.material.slider.Slider android:id="@+id/sliderVibrance" android:layout_width="match_parent" android:layout_height="wrap_content" android:valueFrom="-1.0" android:valueTo="1.0" android:value="0.0" app:thumbColor="#FF9800" app:trackColorActive="#FF9800" app:trackColorInactive="#333333"/>
<!-- Temperature -->
<TextView android:id="@+id/tvLabelTemperature" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="#FFFFFF" android:textSize="11sp" android:text="Temperature (Nhiệt màu): 0.00"/>
<com.google.android.material.slider.Slider android:id="@+id/sliderTemperature" android:layout_width="match_parent" android:layout_height="wrap_content" android:valueFrom="-1.0" android:valueTo="1.0" android:value="0.0" app:thumbColor="#FF9800" app:trackColorActive="#FF9800" app:trackColorInactive="#333333"/>
<!-- Tint -->
<TextView android:id="@+id/tvLabelTint" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="#FFFFFF" android:textSize="11sp" android:text="Tint (Sắc độ hồng/xanh): 0.00"/>
<com.google.android.material.slider.Slider android:id="@+id/sliderTint" android:layout_width="match_parent" android:layout_height="wrap_content" android:valueFrom="-1.0" android:valueTo="1.0" android:value="0.0" app:thumbColor="#FF9800" app:trackColorActive="#FF9800" app:trackColorInactive="#333333"/>
<!-- ================= NHÓM 2: NÂNG CAO (ADVANCED EFFECTS) ================= -->
<TextView
android:id="@+id/tvLabelDehaze"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Dehaze (Độ trong suốt / Sương mù): 0.0"
android:textColor="#FFFFFF"
android:textSize="12sp"
android:layout_marginTop="8dp" />
<com.google.android.material.slider.Slider
android:id="@+id/sliderDehaze"
android:text="HIỆU ỨNG NÂNG CAO"
android:textColor="#FF9800"
android:textStyle="bold"
android:textSize="11sp"
android:layout_marginTop="12dp"
android:layout_marginBottom="4dp"/>
<!-- Clarity -->
<TextView android:id="@+id/tvLabelClarity" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="#FFFFFF" android:textSize="11sp" android:text="Clarity (Độ rõ nét vùng trung tính): 0.00"/>
<com.google.android.material.slider.Slider android:id="@+id/sliderClarity" android:layout_width="match_parent" android:layout_height="wrap_content" android:valueFrom="-1.0" android:valueTo="1.0" android:value="0.0" app:thumbColor="#FF9800" app:trackColorActive="#FF9800" app:trackColorInactive="#333333"/>
<!-- Dehaze -->
<TextView android:id="@+id/tvLabelDehaze" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="#FFFFFF" android:textSize="11sp" android:text="Dehaze (Độ trong suốt / Sương mù): 0.00"/>
<com.google.android.material.slider.Slider android:id="@+id/sliderDehaze" android:layout_width="match_parent" android:layout_height="wrap_content" android:valueFrom="-1.0" android:valueTo="1.0" android:value="0.0" app:thumbColor="#FF9800" app:trackColorActive="#FF9800" app:trackColorInactive="#333333"/>
<!-- Vignette Amount -->
<TextView android:id="@+id/tvLabelVignetteAmount" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="#FFFFFF" android:textSize="11sp" android:text="Vignette Amount (Bo tối góc): 0.00"/>
<com.google.android.material.slider.Slider android:id="@+id/sliderVignetteAmount" android:layout_width="match_parent" android:layout_height="wrap_content" android:valueFrom="0.0" android:valueTo="1.0" android:value="0.0" app:thumbColor="#FF9800" app:trackColorActive="#FF9800" app:trackColorInactive="#333333"/>
<!-- ================= NHÓM 3: GIẢ LẬP ĐƯỜNG CONG MÀU (TONE CURVE EMULATION) ================= -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:valueFrom="-1.0"
android:valueTo="1.0"
android:value="0.0"
app:thumbColor="#FF9800"
app:trackColorActive="#FF9800"
app:trackColorInactive="#333333" />
android:text="GIẢ LẬP TONE CURVE &amp; MÀU VÙNG TỐI"
android:textColor="#FF9800"
android:textStyle="bold"
android:textSize="11sp"
android:layout_marginTop="12dp"
android:layout_marginBottom="4dp"/>
<!-- Faded Black Level -->
<TextView android:id="@+id/tvLabelFadedBlack" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="#FFFFFF" android:textSize="11sp" android:text="Faded Black Level (Độ mờ vùng đen): 0.00"/>
<com.google.android.material.slider.Slider android:id="@+id/sliderFadedBlack" android:layout_width="match_parent" android:layout_height="wrap_content" android:valueFrom="0.0" android:valueTo="1.0" android:value="0.0" app:thumbColor="#FF9800" app:trackColorActive="#FF9800" app:trackColorInactive="#333333"/>
<!-- Shadows Tint R -->
<TextView android:id="@+id/tvLabelShadowsTintR" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="#FFFFFF" android:textSize="11sp" android:text="Shadows Tint R (Sắc Đỏ vùng tối): 0.00"/>
<com.google.android.material.slider.Slider android:id="@+id/sliderShadowsTintR" android:layout_width="match_parent" android:layout_height="wrap_content" android:valueFrom="0.0" android:valueTo="1.0" android:value="0.0" app:thumbColor="#FF9800" app:trackColorActive="#FF9800" app:trackColorInactive="#333333"/>
<!-- Shadows Tint G -->
<TextView android:id="@+id/tvLabelShadowsTintG" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="#FFFFFF" android:textSize="11sp" android:text="Shadows Tint G (Sắc Lục vùng tối): 0.00"/>
<com.google.android.material.slider.Slider android:id="@+id/sliderShadowsTintG" android:layout_width="match_parent" android:layout_height="wrap_content" android:valueFrom="0.0" android:valueTo="1.0" android:value="0.0" app:thumbColor="#FF9800" app:trackColorActive="#FF9800" app:trackColorInactive="#333333"/>
<!-- Shadows Tint B -->
<TextView android:id="@+id/tvLabelShadowsTintB" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="#FFFFFF" android:textSize="11sp" android:text="Shadows Tint B (Sắc Lam vùng tối): 0.00"/>
<com.google.android.material.slider.Slider android:id="@+id/sliderShadowsTintB" android:layout_width="match_parent" android:layout_height="wrap_content" android:valueFrom="0.0" android:valueTo="1.0" android:value="0.0" app:thumbColor="#FF9800" app:trackColorActive="#FF9800" app:trackColorInactive="#333333"/>
<!-- ================= NHÓM 4: HẠT NHIỄU PHIM (FILM GRAIN) ================= -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="HẠT NHIỄU PHIM"
android:textColor="#FF9800"
android:textStyle="bold"
android:textSize="11sp"
android:layout_marginTop="12dp"
android:layout_marginBottom="4dp"/>
<!-- Grain Amount -->
<TextView android:id="@+id/tvLabelGrainAmount" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="#FFFFFF" android:textSize="11sp" android:text="Grain Amount (Mật độ hạt): 0.00"/>
<com.google.android.material.slider.Slider android:id="@+id/sliderGrainAmount" android:layout_width="match_parent" android:layout_height="wrap_content" android:valueFrom="0.0" android:valueTo="1.0" android:value="0.0" app:thumbColor="#FF9800" app:trackColorActive="#FF9800" app:trackColorInactive="#333333"/>
<!-- Grain Size -->
<TextView android:id="@+id/tvLabelGrainSize" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="#FFFFFF" android:textSize="11sp" android:text="Grain Size (Kích thước hạt): 0.00"/>
<com.google.android.material.slider.Slider android:id="@+id/sliderGrainSize" android:layout_width="match_parent" android:layout_height="wrap_content" android:valueFrom="0.0" android:valueTo="1.0" android:value="0.0" app:thumbColor="#FF9800" app:trackColorActive="#FF9800" app:trackColorInactive="#333333"/>
<!-- NÚT LƯU THÀNH PRESET MỚI -->
<Button
@@ -41,16 +41,4 @@
android:text="Preset" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<!-- Nút edit nhỏ ở góc trên bên phải, hiển thị đè đục lên card -->
<ImageButton
android:id="@+id/btnSmallEdit"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="top|end"
android:background="@android:color/transparent"
android:src="@drawable/ic_edit_small"
android:visibility="gone"
app:tint="@color/theme_primary"
android:contentDescription="Edit Preset" />
</FrameLayout>