Skip to content

Commit e360c23

Browse files
committed
refactor: replace TabView with new LiquidTabsUi
1 parent b27b1b6 commit e360c23

File tree

6 files changed

+157
-243
lines changed

6 files changed

+157
-243
lines changed

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

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,22 @@ import android.widget.ViewAnimator
88
import com.osfans.trime.core.Rime
99
import com.osfans.trime.core.RimeNotification.OptionNotification
1010
import com.osfans.trime.data.theme.ColorManager
11+
import com.osfans.trime.data.theme.Theme
1112
import com.osfans.trime.databinding.CandidateBarBinding
12-
import com.osfans.trime.databinding.TabBarBinding
1313
import com.osfans.trime.ime.broadcast.InputBroadcastReceiver
1414
import com.osfans.trime.ime.core.TrimeInputMethodService
1515
import com.osfans.trime.ime.dependency.InputScope
1616
import com.osfans.trime.ime.enums.SymbolKeyboardType
17+
import com.osfans.trime.ime.symbol.LiquidTabsUi
18+
import com.osfans.trime.ime.symbol.TabManager
1719
import me.tatarka.inject.annotations.Inject
1820
import splitties.views.dsl.core.add
1921
import splitties.views.dsl.core.lParams
2022
import splitties.views.dsl.core.matchParent
2123

2224
@InputScope
2325
@Inject
24-
class QuickBar(context: Context, service: TrimeInputMethodService) : InputBroadcastReceiver {
26+
class QuickBar(context: Context, service: TrimeInputMethodService, theme: Theme) : InputBroadcastReceiver {
2527
val oldCandidateBar by lazy {
2628
CandidateBarBinding.inflate(LayoutInflater.from(context)).apply {
2729
with(root) {
@@ -38,8 +40,10 @@ class QuickBar(context: Context, service: TrimeInputMethodService) : InputBroadc
3840
}
3941
}
4042

41-
val oldTabBar by lazy {
42-
TabBarBinding.inflate(LayoutInflater.from(context))
43+
val tabsUi by lazy {
44+
LiquidTabsUi(context, theme).apply {
45+
setTabs(TabManager.tabCandidates)
46+
}
4347
}
4448

4549
enum class State {
@@ -71,7 +75,7 @@ class QuickBar(context: Context, service: TrimeInputMethodService) : InputBroadc
7175
"candidate_border_round",
7276
)
7377
add(oldCandidateBar.root, lParams(matchParent, matchParent))
74-
add(oldTabBar.root, lParams(matchParent, matchParent))
78+
add(tabsUi.root, lParams(matchParent, matchParent))
7579
}
7680
}
7781

app/src/main/java/com/osfans/trime/ime/core/TrimeInputMethodService.kt

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ import com.osfans.trime.data.theme.ThemeManager
5555
import com.osfans.trime.ime.broadcast.IntentReceiver
5656
import com.osfans.trime.ime.enums.FullscreenMode
5757
import com.osfans.trime.ime.enums.InlinePreeditMode
58+
import com.osfans.trime.ime.enums.KeyCommandType
5859
import com.osfans.trime.ime.enums.Keycode
5960
import com.osfans.trime.ime.enums.SymbolKeyboardType
6061
import com.osfans.trime.ime.keyboard.Event
@@ -63,11 +64,10 @@ import com.osfans.trime.ime.keyboard.InputFeedbackManager
6364
import com.osfans.trime.ime.keyboard.Key
6465
import com.osfans.trime.ime.keyboard.KeyboardSwitcher
6566
import com.osfans.trime.ime.keyboard.KeyboardView
67+
import com.osfans.trime.ime.symbol.LiquidTabsUi
6668
import com.osfans.trime.ime.symbol.TabManager
67-
import com.osfans.trime.ime.symbol.TabView
6869
import com.osfans.trime.ime.text.Candidate
6970
import com.osfans.trime.ime.text.CompositionPopupWindow
70-
import com.osfans.trime.ime.text.ScrollView
7171
import com.osfans.trime.ime.text.TextInputManager
7272
import com.osfans.trime.util.ShortcutUtils
7373
import com.osfans.trime.util.StringUtils
@@ -89,8 +89,7 @@ open class TrimeInputMethodService : LifecycleInputMethodService() {
8989
get() = AppPrefs.defaultInstance()
9090
private var mainKeyboardView: KeyboardView? = null // 主軟鍵盤
9191
private var mCandidate: Candidate? = null // 候選
92-
private var mTabRoot: ScrollView? = null
93-
private var tabView: TabView? = null
92+
private var liquidTabsUi: LiquidTabsUi? = null
9493
var inputView: InputView? = null
9594
private var initializationUi: InitializationUi? = null
9695
private var eventListeners = WeakHashSet<EventListener>()
@@ -272,8 +271,7 @@ open class TrimeInputMethodService : LifecycleInputMethodService() {
272271
if (tabIndex >= 0) {
273272
inputView!!.switchBoard(InputView.Board.Symbol)
274273
symbolKeyboardType = inputView!!.liquidKeyboard.select(tabIndex)
275-
tabView!!.updateTabWidth()
276-
mTabRoot!!.move(tabView!!.highlightLeft, tabView!!.highlightRight)
274+
liquidTabsUi?.activateTab(TabManager.selectedOrZero)
277275
mCompositionPopupWindow?.composition?.compositionView?.changeToLiquidKeyboardToolbar()
278276
showCompositionView(false)
279277
} else {
@@ -321,8 +319,17 @@ open class TrimeInputMethodService : LifecycleInputMethodService() {
321319
mainKeyboardView = inputView!!.keyboardWindow.oldMainInputView.mainKeyboardView
322320
// 初始化候选栏
323321
mCandidate = inputView!!.quickBar.oldCandidateBar.candidates
324-
mTabRoot = inputView!!.quickBar.oldTabBar.root
325-
tabView = inputView!!.quickBar.oldTabBar.tabs
322+
liquidTabsUi =
323+
inputView!!.quickBar.tabsUi.apply {
324+
setOnTabClickListener {
325+
val tag = TabManager.tabTags[it]
326+
if (tag.type == SymbolKeyboardType.NO_KEY && tag.command == KeyCommandType.EXIT) {
327+
selectLiquidKeyboard(-1)
328+
} else {
329+
selectLiquidKeyboard(it)
330+
}
331+
}
332+
}
326333

327334
mCompositionPopupWindow =
328335
CompositionPopupWindow(this, ThemeManager.activeTheme).apply {
@@ -1128,7 +1135,7 @@ open class TrimeInputMethodService : LifecycleInputMethodService() {
11281135
mCandidate!!.setText(0)
11291136
}
11301137
// 刷新候选词后,如果候选词超出屏幕宽度,滚动候选栏
1131-
mTabRoot?.move(mCandidate!!.highlightLeft, mCandidate!!.highlightRight)
1138+
// mTabRoot?.move(mCandidate!!.highlightLeft, mCandidate!!.highlightRight)
11321139
}
11331140
mainKeyboardView?.invalidateComposingKeys()
11341141
if (!onEvaluateInputViewShown()) setCandidatesViewShown(textInputManager!!.isComposable) // 實體鍵盤打字時顯示候選欄
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
package com.osfans.trime.ime.symbol
2+
3+
import android.content.Context
4+
import android.graphics.Color
5+
import android.graphics.drawable.PaintDrawable
6+
import com.osfans.trime.data.theme.ColorManager
7+
import com.osfans.trime.data.theme.FontManager
8+
import com.osfans.trime.data.theme.Theme
9+
import com.osfans.trime.ime.text.ScrollView
10+
import com.osfans.trime.util.rippleDrawable
11+
import splitties.dimensions.dp
12+
import splitties.views.dsl.core.Ui
13+
import splitties.views.dsl.core.add
14+
import splitties.views.dsl.core.frameLayout
15+
import splitties.views.dsl.core.horizontalLayout
16+
import splitties.views.dsl.core.lParams
17+
import splitties.views.dsl.core.matchParent
18+
import splitties.views.dsl.core.textView
19+
import splitties.views.dsl.core.wrapContent
20+
import splitties.views.gravityCenter
21+
import splitties.views.gravityCenterVertical
22+
import splitties.views.horizontalPadding
23+
24+
class LiquidTabsUi(override val ctx: Context, val theme: Theme) : Ui {
25+
inner class TabUi : Ui {
26+
override val ctx = this@LiquidTabsUi.ctx
27+
28+
var position: Int = -1
29+
30+
val text =
31+
textView {
32+
textSize = theme.style.getFloat("candidate_text_size")
33+
typeface = FontManager.getTypeface("candidate_font")
34+
ColorManager.getColor("candidate_text_color")?.let { setTextColor(it) }
35+
}
36+
37+
override val root =
38+
frameLayout {
39+
add(
40+
text,
41+
lParams {
42+
gravity = gravityCenter
43+
horizontalPadding = dp(theme.style.getFloat("candidate_padding")).toInt()
44+
},
45+
)
46+
background = rippleDrawable(ColorManager.getColor("hilited_candidate_back_color")!!)
47+
setOnClickListener {
48+
onTabClick(this@TabUi)
49+
}
50+
}
51+
52+
fun setText(str: String) {
53+
text.text = str
54+
}
55+
56+
fun setActive(active: Boolean) {
57+
val color =
58+
if (active) {
59+
ColorManager.getColor(
60+
"hilited_candidate_text_color",
61+
)!!
62+
} else {
63+
ColorManager.getColor("candidate_text_color")!!
64+
}
65+
val background = if (active) ColorManager.getColor("hilited_candidate_back_color")!! else Color.TRANSPARENT
66+
text.setTextColor(color)
67+
root.background = PaintDrawable(background).apply { setCornerRadius(theme.style.getFloat("layout/round_corner")) }
68+
}
69+
}
70+
71+
private var tabs: Array<TabUi> = arrayOf()
72+
private var selected = -1
73+
74+
private var onTabClick: (TabUi.(Int) -> Unit)? = null
75+
76+
private val horizontal = horizontalLayout()
77+
78+
override val root =
79+
ScrollView(ctx, null).apply {
80+
isHorizontalScrollBarEnabled = false
81+
add(
82+
horizontal,
83+
lParams(wrapContent, matchParent) {
84+
gravity = gravityCenterVertical
85+
},
86+
)
87+
}
88+
89+
fun setTabs(tags: List<TabTag>) {
90+
tabs.forEach { root.removeView(it.root) }
91+
selected = -1
92+
tabs =
93+
Array(tags.size) {
94+
val tag = tags[it]
95+
TabUi().apply {
96+
position = it
97+
setText(tag.text)
98+
setActive(false)
99+
}
100+
}
101+
tabs.forEach { tabUi ->
102+
horizontal.apply {
103+
add(
104+
tabUi.root,
105+
lParams(wrapContent, matchParent) {
106+
gravity = gravityCenter
107+
},
108+
)
109+
}
110+
}
111+
}
112+
113+
fun activateTab(index: Int) {
114+
if (index == selected) return
115+
if (selected >= 0) {
116+
tabs[selected].setActive(false)
117+
}
118+
tabs[index].setActive(true)
119+
selected = index
120+
}
121+
122+
private fun onTabClick(tabUi: TabUi) {
123+
onTabClick?.invoke(tabUi, tabUi.position)
124+
}
125+
126+
fun setOnTabClickListener(listener: (TabUi.(Int) -> Unit)? = null) {
127+
onTabClick = listener
128+
}
129+
}

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

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,15 @@ data class TabTag(
1111
val text: String,
1212
/** additional comment of the tab */
1313
val comment: String,
14-
/** position and size info of the tab */
15-
val geometry: Rect,
1614
/** data type of the tab (unused) */
1715
val type: SymbolKeyboardType,
1816
/** action type of the tab */
1917
val command: KeyCommandType,
2018
) {
2119
constructor(text: String, type: SymbolKeyboardType) :
22-
this(text, "", Rect(), type, KeyCommandType.NULL)
20+
this(text, "", type, KeyCommandType.NULL)
2321
constructor(text: String, comment: String, type: SymbolKeyboardType) :
24-
this(text, comment, Rect(), type, KeyCommandType.NULL)
22+
this(text, comment, type, KeyCommandType.NULL)
2523
constructor(text: String, type: SymbolKeyboardType, command: KeyCommandType) :
26-
this(text, "", Rect(), type, command)
24+
this(text, "", type, command)
2725
}

0 commit comments

Comments
 (0)