Skip to content

Commit de112cd

Browse files
committed
refactor(symbol): tidy TabView, TabManager and SimpleKeyDao
1 parent e6ca3be commit de112cd

File tree

5 files changed

+77
-138
lines changed

5 files changed

+77
-138
lines changed

app/src/main/java/com/osfans/trime/ime/bar/QuickBar.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,7 @@ class QuickBar(context: Context, service: TrimeInputMethodService) {
3333
}
3434

3535
val oldTabBar by lazy {
36-
TabBarBinding.inflate(LayoutInflater.from(context)).apply {
37-
tabs.reset()
38-
}
36+
TabBarBinding.inflate(LayoutInflater.from(context))
3937
}
4038

4139
enum class State {

app/src/main/java/com/osfans/trime/ime/symbol/LiquidKeyboard.kt

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -286,12 +286,13 @@ class LiquidKeyboard(
286286
}
287287

288288
service.lifecycleScope.launch {
289-
val all = when (type) {
290-
SymbolKeyboardType.CLIPBOARD -> ClipboardHelper.getAll()
291-
SymbolKeyboardType.COLLECTION -> CollectionHelper.getAll()
292-
SymbolKeyboardType.DRAFT -> DraftHelper.getAll()
293-
else -> emptyList()
294-
}
289+
val all =
290+
when (type) {
291+
SymbolKeyboardType.CLIPBOARD -> ClipboardHelper.getAll()
292+
SymbolKeyboardType.COLLECTION -> CollectionHelper.getAll()
293+
SymbolKeyboardType.DRAFT -> DraftHelper.getAll()
294+
else -> emptyList()
295+
}
295296
dbAdapter.updateBeans(all)
296297
}
297298
// 注册剪贴板更新监听器

app/src/main/java/com/osfans/trime/ime/symbol/SimpleKeyDao.kt

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,19 @@
11
package com.osfans.trime.ime.symbol
22

3-
@Suppress("ktlint:standard:function-naming")
43
object SimpleKeyDao {
5-
fun SimpleKeyboard(string: String): List<SimpleKeyBean> {
6-
val strings = string.split("\n+".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
7-
val list: MutableList<SimpleKeyBean> = ArrayList()
8-
for (str in strings) {
9-
if (str.isEmpty()) continue
10-
val keyBean = SimpleKeyBean(str)
11-
list.add(keyBean)
12-
}
13-
return list
4+
fun simpleKeyboardData(raw: String): List<SimpleKeyBean> {
5+
val lines = raw.split("\n+".toRegex()).dropLastWhile { it.isEmpty() }
6+
return lines.filterNot { it.isEmpty() }.map { SimpleKeyBean(it) }
147
}
158

16-
fun Single(string: String): List<SimpleKeyBean> {
17-
val list: MutableList<SimpleKeyBean> = ArrayList()
18-
var h = 0.toChar()
19-
for (element in string) {
20-
if (element in '\uD800'..'\udbff') {
9+
fun singleData(raw: String): List<SimpleKeyBean> {
10+
val list = mutableListOf<SimpleKeyBean>()
11+
var h = Char(0)
12+
for (element in raw) {
13+
if (element.isHighSurrogate()) {
2114
h = element
22-
} else if (element in '\udc00'..'\udfff') {
23-
list.add(SimpleKeyBean(java.lang.String.valueOf(charArrayOf(h, element))))
15+
} else if (element.isLowSurrogate()) {
16+
list.add(SimpleKeyBean(String(charArrayOf(h, element))))
2417
} else {
2518
list.add(SimpleKeyBean(element.toString()))
2619
}

app/src/main/java/com/osfans/trime/ime/symbol/TabManager.kt

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,11 @@ object TabManager {
6262
type: SymbolKeyboardType,
6363
keyBeans: List<SimpleKeyBean>,
6464
) {
65-
if (name.trim { it <= ' ' }.isEmpty()) return
65+
if (name.isBlank()) return
6666
if (SymbolKeyboardType.hasKeys(type)) {
67-
for (i in tabTags.indices) {
68-
val tag = tabTags[i]
69-
if (tag.text == name) {
70-
keyboards[i] = keyBeans
71-
return
72-
}
67+
val index = tabTags.indexOfFirst { it.text == name }
68+
if (index >= 0) {
69+
keyboards[index] = keyBeans
7370
}
7471
}
7572
tabTags.add(TabTag(name, type))
@@ -84,13 +81,13 @@ object TabManager {
8481
// 处理single类型和no_key类型。前者把字符串切分为多个按键,后者把字符串转换为命令
8582
if (keys is String) {
8683
when (type) {
87-
SymbolKeyboardType.SINGLE -> addListTab(name, type, SimpleKeyDao.Single(keys))
84+
SymbolKeyboardType.SINGLE -> addListTab(name, type, SimpleKeyDao.singleData(keys))
8885
SymbolKeyboardType.NO_KEY -> {
8986
val commandType = KeyCommandType.fromString(keys)
9087
tabTags.add(TabTag(name, type, commandType))
9188
keyboards.add(notKeyboard)
9289
}
93-
else -> addListTab(name, type, SimpleKeyDao.SimpleKeyboard(keys))
90+
else -> addListTab(name, type, SimpleKeyDao.simpleKeyboardData(keys))
9491
}
9592
}
9693

@@ -123,8 +120,8 @@ object TabManager {
123120
}
124121

125122
fun selectTabByIndex(index: Int): List<SimpleKeyBean> {
123+
if (index !in tabTags.indices) return listOf()
126124
currentTabIndex = index
127-
if (index >= tabTags.size) return listOf()
128125
val tag = tabTags[index]
129126
if (tag.type == SymbolKeyboardType.TABS) tabSwitchPosition = currentTabIndex
130127
return keyboards[index]

app/src/main/java/com/osfans/trime/ime/symbol/TabView.kt

Lines changed: 52 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import android.content.Context
2121
import android.graphics.Canvas
2222
import android.graphics.Color
2323
import android.graphics.Paint
24-
import android.graphics.Typeface
2524
import android.graphics.drawable.PaintDrawable
2625
import android.util.AttributeSet
2726
import android.view.MotionEvent
@@ -35,48 +34,43 @@ import com.osfans.trime.ime.enums.KeyCommandType
3534
import com.osfans.trime.ime.enums.SymbolKeyboardType
3635
import com.osfans.trime.util.GraphicUtils.drawText
3736
import com.osfans.trime.util.GraphicUtils.measureText
38-
import com.osfans.trime.util.dp2px
3937
import com.osfans.trime.util.sp
38+
import splitties.dimensions.dp
4039
import timber.log.Timber
4140
import kotlin.math.abs
4241

4342
// 这是滑动键盘顶部的view,展示了键盘布局的多个标签。
4443
// 为了公用候选栏的皮肤参数以及外观,大部分代码从Candidate.java复制而来。
4544
class TabView(context: Context?, attrs: AttributeSet?) : View(context, attrs) {
45+
private val theme = ThemeManager.activeTheme
4646
private var highlightIndex = 0
47-
private var tabTags: ArrayList<TabTag>? = null
48-
private var candidateHighlight: PaintDrawable? = null
49-
private val separatorPaint: Paint
50-
private val candidatePaint: Paint
51-
private var candidateFont: Typeface? = null
52-
private var candidateTextColor = 0
53-
private var hilitedCandidateTextColor = 0
54-
private var candidateViewHeight = 0
55-
private var commentHeight = 0
56-
private var candidateSpacing = 0
57-
private var candidatePadding = 0
58-
private var isCommentOnTop = false
59-
private var shouldCandidateUseCursor = false
47+
private val tabTags = mutableListOf<TabTag>()
48+
private val candidateHighlight =
49+
PaintDrawable(ColorManager.getColor("hilited_candidate_back_color")!!).apply {
50+
setCornerRadius(theme.style.getFloat("layout/round_corner"))
51+
}
52+
private val separatorPaint =
53+
Paint().apply {
54+
color = ColorManager.getColor("candidate_separator_color") ?: Color.BLACK
55+
}
56+
private val candidatePaint =
57+
Paint().apply {
58+
isAntiAlias = true
59+
strokeWidth = 0f
60+
textSize = sp(theme.style.getFloat("candidate_text_size"))
61+
typeface = candidateFont
62+
}
63+
private val candidateFont = FontManager.getTypeface("candidate_font")
64+
private val candidateTextColor = ColorManager.getColor("candidate_text_color")!!
65+
private val hilitedCandidateTextColor = ColorManager.getColor("hilited_candidate_text_color")!!
66+
private val candidateViewHeight = theme.style.getInt("candidate_view_height")
67+
private val commentHeight = theme.style.getInt("comment_height")
68+
private val candidateSpacing = theme.style.getFloat("candidate_spacing")
69+
private val candidatePadding = theme.style.getFloat("candidate_padding")
70+
private val isCommentOnTop = theme.style.getBoolean("comment_on_top")
71+
private val shouldCandidateUseCursor = theme.style.getBoolean("comment_on_top")
6072

6173
// private final Rect[] tabGeometries = new Rect[MAX_CANDIDATE_COUNT + 2];
62-
fun reset() {
63-
val theme = ThemeManager.activeTheme
64-
candidateHighlight = PaintDrawable(ColorManager.getColor("hilited_candidate_back_color")!!)
65-
candidateHighlight!!.setCornerRadius(theme.style.getFloat("layout/round_corner"))
66-
separatorPaint.color = ColorManager.getColor("candidate_separator_color")!!
67-
candidateSpacing = dp2px(theme.style.getFloat("candidate_spacing")).toInt()
68-
candidatePadding = dp2px(theme.style.getFloat("candidate_padding")).toInt()
69-
candidateTextColor = ColorManager.getColor("candidate_text_color")!!
70-
hilitedCandidateTextColor = ColorManager.getColor("hilited_candidate_text_color")!!
71-
commentHeight = dp2px(theme.style.getFloat("comment_height")).toInt()
72-
candidateViewHeight = dp2px(theme.style.getFloat("candidate_view_height")).toInt()
73-
candidateFont = FontManager.getTypeface("candidate_font")
74-
candidatePaint.textSize = sp(theme.style.getFloat("candidate_text_size"))
75-
candidatePaint.setTypeface(candidateFont)
76-
isCommentOnTop = theme.style.getBoolean("comment_on_top")
77-
shouldCandidateUseCursor = theme.style.getBoolean("candidate_use_cursor")
78-
invalidate()
79-
}
8074

8175
override fun onMeasure(
8276
widthMeasureSpec: Int,
@@ -85,7 +79,7 @@ class TabView(context: Context?, attrs: AttributeSet?) : View(context, attrs) {
8579
val h = if (isCommentOnTop) candidateViewHeight + commentHeight else candidateViewHeight
8680
setMeasuredDimension(
8781
MeasureSpec.makeMeasureSpec(widthMeasureSpec, MeasureSpec.UNSPECIFIED),
88-
MeasureSpec.makeMeasureSpec(h, MeasureSpec.AT_MOST),
82+
MeasureSpec.makeMeasureSpec(dp(h), MeasureSpec.AT_MOST),
8983
)
9084
}
9185

@@ -94,62 +88,51 @@ class TabView(context: Context?, attrs: AttributeSet?) : View(context, attrs) {
9488
}
9589

9690
val highlightLeft: Int
97-
get() = tabTags!![highlightIndex].geometry.left
91+
get() = tabTags[highlightIndex].geometry.left
9892
val highlightRight: Int
99-
get() = tabTags!![highlightIndex].geometry.right
93+
get() = tabTags[highlightIndex].geometry.right
10094

10195
override fun onDraw(canvas: Canvas) {
102-
if (tabTags == null) return
96+
if (tabTags.isEmpty()) return
10397
super.onDraw(canvas)
10498

10599
// Draw highlight background
106100
if (isHighlighted(highlightIndex)) {
107-
candidateHighlight!!.bounds = tabTags!![highlightIndex].geometry
108-
candidateHighlight!!.draw(canvas)
101+
candidateHighlight.bounds = tabTags[highlightIndex].geometry
102+
candidateHighlight.draw(canvas)
109103
}
110104
// Draw tab text
111-
val tabY = (
112-
/* (shouldShowComment && isCommentOnTop)
113-
? tabTags.get(0).geometry.centerY()
114-
- (candidatePaint.ascent() + candidatePaint.descent()) / 2.0f
115-
+ commentHeight / 2.0f
116-
: */
117-
tabTags!![0].geometry.centerY() -
105+
val tabY =
106+
tabTags[0].geometry.centerY() -
118107
(candidatePaint.ascent() + candidatePaint.descent()) / 2.0f
119-
)
120-
for ((i, computedTab) in tabTags!!.withIndex()) {
108+
for ((i, computedTab) in tabTags.withIndex()) {
121109
// Calculate a position where the text could be centered in the rectangle.
122110
val tabX = computedTab.geometry.centerX().toFloat()
123111
candidatePaint.color = if (isHighlighted(i)) hilitedCandidateTextColor else candidateTextColor
124-
canvas.drawText(computedTab.text, tabX, tabY, candidatePaint, candidateFont!!)
112+
canvas.drawText(computedTab.text, tabX, tabY, candidatePaint, candidateFont)
125113
// Draw the separator at the right edge of each candidate.
126114
canvas.drawRect(
127-
(
128-
computedTab.geometry.right - candidateSpacing
129-
).toFloat(),
115+
computedTab.geometry.right - dp(candidateSpacing),
130116
computedTab.geometry.top.toFloat(),
131-
(
132-
computedTab.geometry.right + candidateSpacing
133-
).toFloat(),
117+
computedTab.geometry.right + dp(candidateSpacing),
134118
computedTab.geometry.bottom.toFloat(),
135119
separatorPaint,
136120
)
137121
}
138122
}
139123

140124
fun updateTabWidth() {
141-
tabTags = TabManager.tabCandidates
125+
tabTags.clear()
126+
tabTags.addAll(TabManager.tabCandidates)
142127
highlightIndex = TabManager.selectedOrZero
143128
var x = 0
144-
for ((i, computedTab) in tabTags!!.withIndex()) {
129+
for ((i, computedTab) in tabTags.withIndex()) {
145130
computedTab.geometry.set(x, 0, (x + getTabWidth(i)).toInt(), height)
146131
x = (x + (getTabWidth(i) + candidateSpacing)).toInt()
147132
}
148133
updateLayoutParams {
149-
Timber.d("updateTabWidth: layoutPrams from: height=$height, width=$width")
150134
width = x
151-
height = if (isCommentOnTop) candidateViewHeight + commentHeight else candidateViewHeight
152-
Timber.d("updateTabWidth: layoutPrams to: height=$height, width=$width")
135+
height = dp(if (isCommentOnTop) candidateViewHeight + commentHeight else candidateViewHeight)
153136
}
154137
invalidate()
155138
}
@@ -162,24 +145,17 @@ class TabView(context: Context?, attrs: AttributeSet?) : View(context, attrs) {
162145
) {
163146
super.onSizeChanged(w, h, oldw, oldh)
164147
updateTabWidth()
165-
Timber.d("onSizeChanged() w=$w, Height=$oldh=>$h")
166148
}
167149

168150
override fun performClick(): Boolean {
169151
return super.performClick()
170152
}
171153

172-
var x0 = 0
173-
var y0 = 0
154+
private var x0 = 0
155+
private var y0 = 0
174156
private var time0: Long = 0
175157

176158
init {
177-
candidatePaint = Paint()
178-
candidatePaint.isAntiAlias = true
179-
candidatePaint.strokeWidth = 0f
180-
separatorPaint = Paint()
181-
separatorPaint.color = Color.BLACK
182-
reset()
183159
setWillNotDraw(false)
184160
}
185161

@@ -195,58 +171,32 @@ class TabView(context: Context?, attrs: AttributeSet?) : View(context, attrs) {
195171

196172
MotionEvent.ACTION_MOVE -> if (abs(x - x0) > 100) time0 = 0
197173
MotionEvent.ACTION_UP -> {
198-
val i = getTabIndex(x, y)
174+
val i = tabTags.indexOfFirst { it.geometry.contains(x, y) }
199175
if (i > -1) {
200176
performClick()
201177
val tag = TabManager.tabTags[i]
202178
if (tag.type == SymbolKeyboardType.NO_KEY) {
203-
when (tag.command) {
204-
KeyCommandType.EXIT -> TrimeInputMethodService.getService().selectLiquidKeyboard(-1)
205-
KeyCommandType.DEL_LEFT, KeyCommandType.DEL_RIGHT, KeyCommandType.REDO, KeyCommandType.UNDO -> {}
206-
else -> {}
179+
if (tag.command == KeyCommandType.EXIT) {
180+
TrimeInputMethodService.getService().selectLiquidKeyboard(-1)
207181
}
208182
} else if (System.currentTimeMillis() - time0 < 500) {
209183
highlightIndex = i
210184
invalidate()
211185
TrimeInputMethodService.getService().selectLiquidKeyboard(i)
212186
}
213-
Timber.d("index=" + i + " length=" + tabTags!!.size)
187+
Timber.d("index=" + i + " length=" + tabTags.size)
214188
}
215189
}
216190
}
217191
return true
218192
}
219193

220-
/**
221-
* 獲得觸摸處候選項序號
222-
*
223-
* @param x 觸摸點橫座標
224-
* @param y 觸摸點縱座標
225-
* @return `>=0`: 觸摸點 (x, y) 處候選項序號,從0開始編號; `-1`: 觸摸點 (x, y) 處無候選項;
226-
*/
227-
private fun getTabIndex(
228-
x: Int,
229-
y: Int,
230-
): Int {
231-
// Rect r = new Rect();
232-
var retIndex = -1 // Returns -1 if there is no tab in the hitting rectangle.
233-
for (computedTab in tabTags!!) {
234-
/* Enlarge the rectangle to be more responsive to user clicks.
235-
// r.set(tabGeometries[j++]);
236-
//r.inset(0, CANDIDATE_TOUCH_OFFSET); */
237-
if (computedTab.geometry.contains(x, y)) {
238-
retIndex = tabTags!!.indexOf(computedTab)
239-
}
240-
}
241-
return retIndex
242-
}
243-
244194
private fun getTabWidth(i: Int): Float {
245-
val s = tabTags!![i].text
195+
val s = tabTags[i].text
246196
return if (s.isNotEmpty()) {
247-
2 * candidatePadding + candidatePaint.measureText(s, candidateFont!!)
197+
2 * dp(candidatePadding) + candidatePaint.measureText(s, candidateFont)
248198
} else {
249-
(2 * candidatePadding).toFloat()
199+
2 * dp(candidatePadding)
250200
}
251201
}
252202
}

0 commit comments

Comments
 (0)