Skip to content

Commit 8903f52

Browse files
committed
refactor(whiteboard): extract toolbar into a separate view
Also 1. made `fragment_whiteboard` a FrameLayout, so changing the toolbar position is wayyyyyyyyyy easier with layout gravity 2. Used a `RecyclerView` instead of separate Horizontal and Vertical scrollViews, which should be more performant
1 parent 1512be9 commit 8903f52

File tree

5 files changed

+351
-287
lines changed

5 files changed

+351
-287
lines changed
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
* Copyright (c) 2025 Brayan Oliveira <[email protected]>
3+
*
4+
* This program is free software; you can redistribute it and/or modify it under
5+
* the terms of the GNU General Public License as published by the Free Software
6+
* Foundation; either version 3 of the License, or (at your option) any later
7+
* version.
8+
*
9+
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
10+
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
11+
* PARTICULAR PURPOSE. See the GNU General Public License for more details.
12+
*
13+
* You should have received a copy of the GNU General Public License along with
14+
* this program. If not, see <http://www.gnu.org/licenses/>.
15+
*/
16+
package com.ichi2.anki.ui.windows.reviewer.whiteboard
17+
18+
import android.graphics.drawable.GradientDrawable
19+
import android.graphics.drawable.LayerDrawable
20+
import android.view.LayoutInflater
21+
import android.view.View
22+
import android.view.ViewGroup
23+
import androidx.recyclerview.widget.RecyclerView
24+
import com.google.android.material.button.MaterialButton
25+
import com.ichi2.anki.R
26+
import kotlin.math.roundToInt
27+
28+
class BrushAdapter(
29+
private val onBrushClick: (View, Int) -> Unit,
30+
private val onBrushLongClick: (Int) -> Unit,
31+
) : RecyclerView.Adapter<BrushAdapter.BrushViewHolder>() {
32+
private var brushes: List<BrushInfo> = emptyList()
33+
private var activeIndex: Int = -1
34+
private var isEraserActive: Boolean = false
35+
36+
fun updateData(
37+
newBrushes: List<BrushInfo>,
38+
newActiveIndex: Int,
39+
eraserActive: Boolean,
40+
) {
41+
brushes = newBrushes
42+
activeIndex = newActiveIndex
43+
isEraserActive = eraserActive
44+
notifyDataSetChanged()
45+
}
46+
47+
fun updateSelection(
48+
newActiveIndex: Int,
49+
eraserActive: Boolean,
50+
) {
51+
val oldIndex = activeIndex
52+
activeIndex = newActiveIndex
53+
isEraserActive = eraserActive
54+
55+
if (oldIndex in brushes.indices) notifyItemChanged(oldIndex)
56+
if (newActiveIndex in brushes.indices) notifyItemChanged(newActiveIndex)
57+
}
58+
59+
override fun getItemCount(): Int = brushes.size
60+
61+
override fun onCreateViewHolder(
62+
parent: ViewGroup,
63+
viewType: Int,
64+
): BrushViewHolder {
65+
val inflater = LayoutInflater.from(parent.context)
66+
val itemView = inflater.inflate(R.layout.button_color_brush, parent, false)
67+
return BrushViewHolder(itemView)
68+
}
69+
70+
override fun onBindViewHolder(
71+
holder: BrushViewHolder,
72+
position: Int,
73+
) {
74+
val brush = brushes[position]
75+
holder.bind(brush, position == activeIndex && !isEraserActive)
76+
}
77+
78+
inner class BrushViewHolder(
79+
itemView: View,
80+
) : RecyclerView.ViewHolder(itemView) {
81+
private val button: MaterialButton = itemView as MaterialButton
82+
83+
fun bind(
84+
brush: BrushInfo,
85+
isSelected: Boolean,
86+
) = button.apply {
87+
isCheckable = true
88+
isChecked = isSelected
89+
text = brush.width.roundToInt().toString()
90+
iconTint = null
91+
92+
val layer = icon?.mutate() as? LayerDrawable
93+
val fill = layer?.findDrawableByLayerId(R.id.brush_preview_fill) as? GradientDrawable
94+
fill?.setColor(brush.color)
95+
96+
setOnClickListener { onBrushClick(it, bindingAdapterPosition) }
97+
setOnLongClickListener {
98+
onBrushLongClick(bindingAdapterPosition)
99+
true
100+
}
101+
}
102+
}
103+
}

0 commit comments

Comments
 (0)