@momo-kits/calculator-keyboard 0.150.2-phuc.13 → 0.151.1-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -3
- package/android/src/main/java/com/calculatorkeyboard/CalculatorKeyboardPackage.kt +1 -1
- package/android/src/main/java/com/calculatorkeyboard/CustomKeyboardView.kt +184 -95
- package/android/src/main/java/com/calculatorkeyboard/Event.kt +36 -0
- package/android/src/main/java/com/calculatorkeyboard/InputCalculatorViewManager.kt +270 -0
- package/android/src/main/java/com/calculatorkeyboard/KeyboardOverplayHost.kt +232 -0
- package/ios/CalculatorKeyboardView.h +30 -0
- package/ios/CalculatorKeyboardView.mm +231 -0
- package/ios/NativeInputCalculator.h +11 -0
- package/ios/NativeInputCalculator.mm +369 -0
- package/package.json +21 -131
- package/react-native-calculator-keyboard.podspec +5 -4
- package/src/InputCalculatorNativeComponent.ts +62 -0
- package/src/index.tsx +124 -82
- package/android/src/main/java/com/calculatorkeyboard/RCTInputCalculator.kt +0 -339
- package/ios/CalculatorKeyboardView.swift +0 -165
- package/ios/InputCalculator-Bridging-Header.h +0 -23
- package/ios/InputCalculator.m +0 -85
- package/ios/InputCalculator.swift +0 -158
- package/ios/extension.swift +0 -23
- package/lib/commonjs/index.js +0 -72
- package/lib/commonjs/index.js.map +0 -1
- package/lib/module/index.js +0 -68
- package/lib/module/index.js.map +0 -1
- package/lib/typescript/commonjs/package.json +0 -1
- package/lib/typescript/commonjs/src/index.d.ts +0 -31
- package/lib/typescript/commonjs/src/index.d.ts.map +0 -1
- package/lib/typescript/module/package.json +0 -1
- package/lib/typescript/module/src/index.d.ts +0 -31
- package/lib/typescript/module/src/index.d.ts.map +0 -1
|
@@ -1,339 +0,0 @@
|
|
|
1
|
-
package com.calculatorkeyboard
|
|
2
|
-
|
|
3
|
-
import android.annotation.SuppressLint
|
|
4
|
-
import android.app.Activity
|
|
5
|
-
import android.content.Context
|
|
6
|
-
import android.content.ContextWrapper
|
|
7
|
-
import android.graphics.Color
|
|
8
|
-
import android.view.Gravity
|
|
9
|
-
import android.view.KeyEvent
|
|
10
|
-
import android.view.View
|
|
11
|
-
import android.view.WindowManager
|
|
12
|
-
import android.view.animation.DecelerateInterpolator
|
|
13
|
-
import android.view.inputmethod.InputMethodManager
|
|
14
|
-
import android.widget.PopupWindow
|
|
15
|
-
import androidx.core.graphics.Insets
|
|
16
|
-
import androidx.core.graphics.drawable.toDrawable
|
|
17
|
-
import androidx.core.graphics.toColorInt
|
|
18
|
-
import androidx.core.view.OnApplyWindowInsetsListener
|
|
19
|
-
import androidx.core.view.ViewCompat
|
|
20
|
-
import androidx.core.view.WindowInsetsCompat
|
|
21
|
-
import com.facebook.react.bridge.ReadableArray
|
|
22
|
-
import com.facebook.react.bridge.UiThreadUtil
|
|
23
|
-
import com.facebook.react.uimanager.PixelUtil.dpToPx
|
|
24
|
-
import com.facebook.react.uimanager.ThemedReactContext
|
|
25
|
-
import com.facebook.react.uimanager.annotations.ReactProp
|
|
26
|
-
import com.facebook.react.views.textinput.ReactEditText
|
|
27
|
-
import com.facebook.react.views.textinput.ReactTextInputManager
|
|
28
|
-
|
|
29
|
-
class RCTInputCalculator : ReactTextInputManager() {
|
|
30
|
-
|
|
31
|
-
private var keyboardView: CustomKeyboardView? = null
|
|
32
|
-
private var popup: PopupWindow? = null
|
|
33
|
-
private val animationDuration = 250L
|
|
34
|
-
|
|
35
|
-
private lateinit var editText: CalculatorEditText
|
|
36
|
-
|
|
37
|
-
private var fakeImeListener: OnApplyWindowInsetsListener? = null
|
|
38
|
-
private var fakeImeAttachedTo: View? = null
|
|
39
|
-
|
|
40
|
-
private lateinit var imm: InputMethodManager
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
override fun getName() = REACT_CLASS
|
|
44
|
-
|
|
45
|
-
companion object {
|
|
46
|
-
const val REACT_CLASS = "RCTInputCalculator"
|
|
47
|
-
val calculatorHeight: Int = 240.dpToPx().toInt()
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
@ReactProp(name = "value")
|
|
51
|
-
fun setValue(view: ReactEditText, value: String?) {
|
|
52
|
-
UiThreadUtil.runOnUiThread {
|
|
53
|
-
val e = view.editableText ?: run { view.setText(value ?: ""); return@runOnUiThread }
|
|
54
|
-
val newText = value ?: ""
|
|
55
|
-
if (e.toString() == newText) return@runOnUiThread
|
|
56
|
-
|
|
57
|
-
val wasFocused = view.hasFocus()
|
|
58
|
-
val atEnd = wasFocused && view.selectionStart == e.length && view.selectionEnd == e.length
|
|
59
|
-
|
|
60
|
-
e.replace(0, e.length, newText)
|
|
61
|
-
|
|
62
|
-
if (!wasFocused || atEnd) {
|
|
63
|
-
view.setSelection(newText.length)
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
@ReactProp(name = "customKeyText")
|
|
69
|
-
fun setCustomKeyText(view: ReactEditText, text: String?) {
|
|
70
|
-
keyboardView?.setCustomKeyText(text ?: "Xong")
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
@ReactProp(name = "customKeyBackground")
|
|
74
|
-
fun setCustomKeyBackground(view: ReactEditText, background: String?) {
|
|
75
|
-
keyboardView?.setCustomKeyBackground((background?: "#d8d8d8").toColorInt())
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
@ReactProp(name = "customKeyTextColor")
|
|
79
|
-
fun setCustomKeyTextColor(view: ReactEditText, textColor: String?) {
|
|
80
|
-
keyboardView?.setCustomKeyTextColor(textColor?.toColorInt() ?: Color.BLACK)
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
@ReactProp(name = "customKeyState")
|
|
85
|
-
fun setCustomKeyState(view: ReactEditText, state: Int?) {
|
|
86
|
-
keyboardView?.setCustomKeyState(state ?: 0)
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
@ReactProp(name = "keyboardColor")
|
|
90
|
-
fun setKeyboardColor(view: ReactEditText, color: String) {
|
|
91
|
-
keyboardView?.updateButtonColors(color.toColorInt())
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
@SuppressLint("ClickableViewAccessibility")
|
|
95
|
-
override fun createViewInstance(context: ThemedReactContext): ReactEditText {
|
|
96
|
-
imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
|
97
|
-
|
|
98
|
-
editText = CalculatorEditText(context).apply {
|
|
99
|
-
showSoftInputOnFocus = true
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
keyboardView = CustomKeyboardView(context, editText).apply {
|
|
103
|
-
setBackgroundColor("#f2f2f6".toColorInt())
|
|
104
|
-
elevation = 24f
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
editText.onFocusListener = object : CalculatorEditText.OnFocusChangeListener {
|
|
108
|
-
override fun onFocusChange(view: CalculatorEditText, hasFocus: Boolean) {
|
|
109
|
-
UiThreadUtil.runOnUiThread {
|
|
110
|
-
if (hasFocus) {
|
|
111
|
-
showKeyboardPopup(view)
|
|
112
|
-
} else {
|
|
113
|
-
hideKeyboardPopup()
|
|
114
|
-
}
|
|
115
|
-
view.setOnKeyListener { v, keyCode, _ ->
|
|
116
|
-
if (keyCode == KeyEvent.KEYCODE_BACK && hasFocus) {
|
|
117
|
-
v.clearFocus()
|
|
118
|
-
true
|
|
119
|
-
} else false
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
return editText
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
override fun getCommandsMap(): Map<String, Int> {
|
|
129
|
-
return mapOf(
|
|
130
|
-
"blur" to 1,
|
|
131
|
-
"focus" to 2
|
|
132
|
-
)
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
override fun receiveCommand(reactEditText: ReactEditText, commandId: Int, args: ReadableArray?) {
|
|
136
|
-
when (commandId) {
|
|
137
|
-
1 -> blur()
|
|
138
|
-
2 -> focus()
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
override fun getExportedCustomBubblingEventTypeConstants(): MutableMap<String, Any> {
|
|
143
|
-
val base = super.getExportedCustomBubblingEventTypeConstants().toMutableMap()
|
|
144
|
-
|
|
145
|
-
base["onKeyPress"] = mapOf(
|
|
146
|
-
"phasedRegistrationNames" to mapOf(
|
|
147
|
-
"bubbled" to "onKeyPress"
|
|
148
|
-
)
|
|
149
|
-
)
|
|
150
|
-
|
|
151
|
-
return base
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any> {
|
|
155
|
-
val base = super.getExportedCustomDirectEventTypeConstants().toMutableMap()
|
|
156
|
-
base["onCustomKeyEvent"] = mapOf("registrationName" to "onCustomKeyEvent")
|
|
157
|
-
return base
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
private fun ensurePopup() {
|
|
161
|
-
if (popup != null) return
|
|
162
|
-
val content = keyboardView ?: return
|
|
163
|
-
|
|
164
|
-
popup = PopupWindow(
|
|
165
|
-
content,
|
|
166
|
-
WindowManager.LayoutParams.MATCH_PARENT,
|
|
167
|
-
calculatorHeight + bottomInsetFrom(editText.rootView),
|
|
168
|
-
false
|
|
169
|
-
).apply {
|
|
170
|
-
setBackgroundDrawable(android.graphics.Color.TRANSPARENT.toDrawable())
|
|
171
|
-
isOutsideTouchable = false
|
|
172
|
-
isClippingEnabled = false
|
|
173
|
-
softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING
|
|
174
|
-
inputMethodMode = PopupWindow.INPUT_METHOD_NOT_NEEDED
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
private fun bottomInsetFrom(view: View): Int {
|
|
179
|
-
val insets = ViewCompat.getRootWindowInsets(view) ?: return 0
|
|
180
|
-
val mask = WindowInsetsCompat.Type.navigationBars() or WindowInsetsCompat.Type.displayCutout()
|
|
181
|
-
return insets.getInsets(mask).bottom
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
private fun showKeyboardPopup(anchor: View) {
|
|
185
|
-
ensurePopup()
|
|
186
|
-
val p = popup ?: return
|
|
187
|
-
if (p.isShowing) return
|
|
188
|
-
|
|
189
|
-
disableSystemImeFor(editText)
|
|
190
|
-
|
|
191
|
-
p.animationStyle = 0
|
|
192
|
-
p.height = calculatorHeight + bottomInsetFrom(anchor.rootView)
|
|
193
|
-
p.showAtLocation(anchor.rootView, Gravity.BOTTOM or Gravity.START, 0, 0)
|
|
194
|
-
|
|
195
|
-
val content = p.contentView
|
|
196
|
-
|
|
197
|
-
val h = content.height.takeIf { it > 0 } ?: p.height
|
|
198
|
-
content.translationY = h.toFloat()
|
|
199
|
-
|
|
200
|
-
content.post {
|
|
201
|
-
content.animate()
|
|
202
|
-
.translationY(0f)
|
|
203
|
-
.setDuration(animationDuration)
|
|
204
|
-
.setInterpolator(DecelerateInterpolator())
|
|
205
|
-
.withStartAction { content.setLayerType(View.LAYER_TYPE_HARDWARE, null) }
|
|
206
|
-
.withEndAction { content.setLayerType(View.LAYER_TYPE_NONE, null) }
|
|
207
|
-
.start()
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
content.post {
|
|
211
|
-
findActivityFrom(content)?.let { act ->
|
|
212
|
-
setFakeIme(act.window.decorView, true, calculatorHeight)
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
private fun hideKeyboardPopup() {
|
|
218
|
-
val p = popup ?: run {
|
|
219
|
-
enableSystemImeFor(editText, requestShow = false)
|
|
220
|
-
return
|
|
221
|
-
}
|
|
222
|
-
if (!p.isShowing) {
|
|
223
|
-
enableSystemImeFor(editText, requestShow = false)
|
|
224
|
-
popup = null
|
|
225
|
-
return
|
|
226
|
-
}
|
|
227
|
-
val content = p.contentView
|
|
228
|
-
|
|
229
|
-
content.animate().cancel()
|
|
230
|
-
|
|
231
|
-
val distance = (content.height.takeIf { it > 0 } ?: p.height).toFloat()
|
|
232
|
-
|
|
233
|
-
content.animate()
|
|
234
|
-
.translationY(distance)
|
|
235
|
-
.setDuration(animationDuration)
|
|
236
|
-
.setInterpolator(DecelerateInterpolator())
|
|
237
|
-
.withEndAction {
|
|
238
|
-
try { if (p.isShowing) p.dismiss() } catch (_: Throwable) {}
|
|
239
|
-
popup = null
|
|
240
|
-
content.translationY = 0f
|
|
241
|
-
content.setLayerType(View.LAYER_TYPE_NONE, null)
|
|
242
|
-
|
|
243
|
-
findActivityFrom(content)?.let { act ->
|
|
244
|
-
setFakeIme(act.window.decorView, false, 0)
|
|
245
|
-
}
|
|
246
|
-
enableSystemImeFor(editText, requestShow = false)
|
|
247
|
-
|
|
248
|
-
}
|
|
249
|
-
.start()
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
private fun disableSystemImeFor(v: ReactEditText) {
|
|
253
|
-
v.showSoftInputOnFocus = false
|
|
254
|
-
if (android.os.Build.VERSION.SDK_INT >= 30) {
|
|
255
|
-
ViewCompat.getWindowInsetsController(v)?.hide(WindowInsetsCompat.Type.ime())
|
|
256
|
-
}
|
|
257
|
-
imm.hideSoftInputFromWindow(v.windowToken, 0)
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
private fun enableSystemImeFor(v: ReactEditText, requestShow: Boolean) {
|
|
262
|
-
v.showSoftInputOnFocus = true
|
|
263
|
-
if (requestShow && v.isFocused) {
|
|
264
|
-
v.post {
|
|
265
|
-
if (android.os.Build.VERSION.SDK_INT >= 30) {
|
|
266
|
-
ViewCompat.getWindowInsetsController(v)?.show(WindowInsetsCompat.Type.ime())
|
|
267
|
-
} else {
|
|
268
|
-
imm.showSoftInput(v, InputMethodManager.SHOW_IMPLICIT)
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
private fun setFakeIme(rootView: View, show: Boolean, heightPx: Int) {
|
|
275
|
-
if (show) {
|
|
276
|
-
if (fakeImeListener != null && fakeImeAttachedTo === rootView) {
|
|
277
|
-
ViewCompat.requestApplyInsets(rootView)
|
|
278
|
-
return
|
|
279
|
-
}
|
|
280
|
-
fakeImeAttachedTo?.let { ViewCompat.setOnApplyWindowInsetsListener(it, null) }
|
|
281
|
-
fakeImeAttachedTo = rootView
|
|
282
|
-
|
|
283
|
-
val listener = OnApplyWindowInsetsListener { _, insets ->
|
|
284
|
-
val curBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
|
285
|
-
val newBarsBottom = maxOf(curBars.bottom, heightPx)
|
|
286
|
-
|
|
287
|
-
WindowInsetsCompat.Builder(insets)
|
|
288
|
-
.setInsets(WindowInsetsCompat.Type.ime(), Insets.of(0, 0, 0, heightPx))
|
|
289
|
-
.setVisible(WindowInsetsCompat.Type.ime(), true)
|
|
290
|
-
.setInsets(
|
|
291
|
-
WindowInsetsCompat.Type.systemBars(),
|
|
292
|
-
Insets.of(curBars.left, curBars.top, curBars.right, newBarsBottom)
|
|
293
|
-
)
|
|
294
|
-
.build()
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
fakeImeListener = listener
|
|
298
|
-
ViewCompat.setOnApplyWindowInsetsListener(rootView, listener)
|
|
299
|
-
ViewCompat.requestApplyInsets(rootView)
|
|
300
|
-
} else {
|
|
301
|
-
fakeImeAttachedTo?.let { ViewCompat.setOnApplyWindowInsetsListener(it, null) }
|
|
302
|
-
fakeImeListener = null
|
|
303
|
-
fakeImeAttachedTo = null
|
|
304
|
-
|
|
305
|
-
ViewCompat.requestApplyInsets(rootView)
|
|
306
|
-
|
|
307
|
-
if (android.os.Build.VERSION.SDK_INT >= 30) {
|
|
308
|
-
rootView.rootWindowInsets?.let { wi ->
|
|
309
|
-
rootView.dispatchApplyWindowInsets(wi)
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
private fun findActivityFrom(view: View): Activity? {
|
|
316
|
-
var ctx: Context? = view.context
|
|
317
|
-
if (ctx is ThemedReactContext) {
|
|
318
|
-
ctx.currentActivity?.let { return it }
|
|
319
|
-
ctx = ctx.baseContext
|
|
320
|
-
}
|
|
321
|
-
while (ctx is ContextWrapper) {
|
|
322
|
-
if (ctx is Activity) return ctx
|
|
323
|
-
ctx = ctx.baseContext
|
|
324
|
-
}
|
|
325
|
-
return null
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
private fun focus() {
|
|
329
|
-
UiThreadUtil.runOnUiThread {
|
|
330
|
-
if (!editText.isFocused) editText.requestFocus()
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
private fun blur() {
|
|
335
|
-
UiThreadUtil.runOnUiThread {
|
|
336
|
-
if (editText.isFocused) editText.clearFocus()
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
}
|
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
import UIKit
|
|
2
|
-
import Foundation
|
|
3
|
-
|
|
4
|
-
import UIKit
|
|
5
|
-
import Foundation
|
|
6
|
-
|
|
7
|
-
class CalculatorKeyboardView: UIView {
|
|
8
|
-
weak var input: InputCalculator?
|
|
9
|
-
|
|
10
|
-
private let keys: [[String]] = [
|
|
11
|
-
["1", "2", "3", "÷", "back"],
|
|
12
|
-
["4", "5", "6", "×", "="],
|
|
13
|
-
["7", "8", "9", "-", "Xong"],
|
|
14
|
-
["000", "0", "+"],
|
|
15
|
-
]
|
|
16
|
-
private let SEPARATOR_WIDTH: CGFloat = 4
|
|
17
|
-
private let specialKeys: Set<String> = ["=", "-", "×", "÷", "back", "+"]
|
|
18
|
-
|
|
19
|
-
var customKeyText: String? { didSet { updateCustomKeyTitle() } }
|
|
20
|
-
var customKeyBackground: String? { didSet { updateCustomKeyBackground() } }
|
|
21
|
-
var customKeyTextColor: String? { didSet { updateCustomKeyBackground() } }
|
|
22
|
-
var customKeyState: Int? { didSet { updateCustomKeyBackground() } }
|
|
23
|
-
private weak var customKeyButton: UIButton?
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
override init(frame: CGRect) {
|
|
27
|
-
super.init(frame: frame)
|
|
28
|
-
setup()
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
required init?(coder aDecoder: NSCoder) {
|
|
32
|
-
fatalError("init(coder:) has not been implemented")
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
public func setKeyboardColor(_ color: UIColor) {
|
|
36
|
-
self.setup(color)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
private func setup(_ color: UIColor = UIColor(hex: "#d8d8d8")) {
|
|
40
|
-
self.subviews.forEach { $0.removeFromSuperview() }
|
|
41
|
-
|
|
42
|
-
backgroundColor = UIColor(hex: "#f2f2f6")
|
|
43
|
-
let buttonWidth = (UIScreen.main.bounds.width - SEPARATOR_WIDTH * 2 - 4 * SEPARATOR_WIDTH) / 5
|
|
44
|
-
let buttonHeight: CGFloat = (240 - SEPARATOR_WIDTH * 2 - 3 * SEPARATOR_WIDTH) / 4
|
|
45
|
-
|
|
46
|
-
// Create a wrapper view
|
|
47
|
-
let contentView = UIView()
|
|
48
|
-
contentView.translatesAutoresizingMaskIntoConstraints = false
|
|
49
|
-
addSubview(contentView)
|
|
50
|
-
|
|
51
|
-
// Set contentView constraints
|
|
52
|
-
NSLayoutConstraint.activate([
|
|
53
|
-
contentView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: SEPARATOR_WIDTH),
|
|
54
|
-
contentView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -SEPARATOR_WIDTH),
|
|
55
|
-
contentView.topAnchor.constraint(equalTo: topAnchor, constant: SEPARATOR_WIDTH),
|
|
56
|
-
contentView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -SEPARATOR_WIDTH)
|
|
57
|
-
])
|
|
58
|
-
|
|
59
|
-
// Add buttons to the wrapper view
|
|
60
|
-
var yOffset: CGFloat = 0
|
|
61
|
-
for (rowIndex, row) in keys.enumerated() {
|
|
62
|
-
var xOffset: CGFloat = 0
|
|
63
|
-
for (colIndex, key) in row.enumerated() {
|
|
64
|
-
let isCustomKey = colIndex == 4 && rowIndex == 2
|
|
65
|
-
let button = UIButton(type: .system)
|
|
66
|
-
button.backgroundColor = UIColor.white
|
|
67
|
-
button.layer.cornerRadius = 8
|
|
68
|
-
let title = isCustomKey ? (customKeyText ?? key) : key
|
|
69
|
-
button.setTitle(title, for: .normal)
|
|
70
|
-
button.setTitleColor(.black, for: .normal)
|
|
71
|
-
button.titleLabel?.font = UIFont.systemFont(ofSize: isCustomKey ? 18 : 24, weight: .medium)
|
|
72
|
-
button.nativeID = key
|
|
73
|
-
button.tag = isCustomKey ? 1 : 0
|
|
74
|
-
|
|
75
|
-
var buttonFrame = CGRect(x: xOffset, y: yOffset, width: buttonWidth, height: buttonHeight)
|
|
76
|
-
if isCustomKey {
|
|
77
|
-
buttonFrame.size.height = buttonHeight * 2 + SEPARATOR_WIDTH
|
|
78
|
-
}
|
|
79
|
-
if key == "000" {
|
|
80
|
-
buttonFrame.size.width = buttonWidth * 2 + SEPARATOR_WIDTH
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
button.frame = buttonFrame
|
|
84
|
-
|
|
85
|
-
if key == "back" {
|
|
86
|
-
button.setTitle("", for: .normal)
|
|
87
|
-
let image = UIImage(systemName: "delete.backward", withConfiguration: UIImage.SymbolConfiguration(weight: .bold))
|
|
88
|
-
button.setImage(image, for: .normal)
|
|
89
|
-
button.tintColor = .black
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if specialKeys.contains(key) {
|
|
93
|
-
button.setTitleColor(.black, for: .normal)
|
|
94
|
-
button.backgroundColor = color
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
if isCustomKey {
|
|
98
|
-
self.customKeyButton = button
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
button.addTarget(self, action: #selector(keyPressed(_:)), for: .touchUpInside)
|
|
102
|
-
contentView.addSubview(button)
|
|
103
|
-
|
|
104
|
-
// Adjust xOffset for the next button in the row
|
|
105
|
-
xOffset += buttonFrame.width + SEPARATOR_WIDTH
|
|
106
|
-
}
|
|
107
|
-
// Adjust yOffset for the next row
|
|
108
|
-
yOffset += buttonHeight + SEPARATOR_WIDTH
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
private func updateCustomKeyTitle() {
|
|
113
|
-
guard let btn = customKeyButton, let title = customKeyText else { return }
|
|
114
|
-
btn.setTitle(title, for: .normal)
|
|
115
|
-
btn.setImage(nil, for: .normal)
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
private func updateCustomKeyBackground() {
|
|
119
|
-
guard let btn = customKeyButton,
|
|
120
|
-
let background = customKeyBackground,
|
|
121
|
-
let textColor = customKeyTextColor,
|
|
122
|
-
let state = customKeyState else { return }
|
|
123
|
-
|
|
124
|
-
let bgColor: String
|
|
125
|
-
if state == 1 {
|
|
126
|
-
bgColor = "#EBEBF2"
|
|
127
|
-
} else {
|
|
128
|
-
bgColor = background
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
let txtColor: UIColor
|
|
132
|
-
if state == 1 {
|
|
133
|
-
txtColor = .white
|
|
134
|
-
} else {
|
|
135
|
-
txtColor = UIColor(hex: textColor)
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
btn.isEnabled = state == 0
|
|
139
|
-
btn.backgroundColor = UIColor(hex: bgColor)
|
|
140
|
-
btn.setTitleColor(txtColor, for: .normal)
|
|
141
|
-
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
@objc private func keyPressed(_ sender: UIButton) {
|
|
146
|
-
guard let key = sender.nativeID else { return }
|
|
147
|
-
let isCustomKey = sender.tag == 1
|
|
148
|
-
if (isCustomKey) {
|
|
149
|
-
input?.emitCustomKey()
|
|
150
|
-
return
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
input?.emitKeyPress(key)
|
|
154
|
-
switch key {
|
|
155
|
-
case "back":
|
|
156
|
-
input?.onBackSpace()
|
|
157
|
-
case "=":
|
|
158
|
-
input?.calculateResult()
|
|
159
|
-
case "+", "-", "÷", "×":
|
|
160
|
-
input?.keyDidPress(" \(key) ")
|
|
161
|
-
default:
|
|
162
|
-
input?.keyDidPress(key)
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
#import <React/RCTBridgeModule.h>
|
|
2
|
-
#import <React/RCTViewManager.h>
|
|
3
|
-
#import <React/RCTBaseTextInputViewManager.h>
|
|
4
|
-
#import <React/RCTSinglelineTextInputView.h>
|
|
5
|
-
#import <React/RCTUITextField.h>
|
|
6
|
-
#import <React/RCTBaseTextInputViewManager.h>
|
|
7
|
-
|
|
8
|
-
#import <React/RCTBridge.h>
|
|
9
|
-
#import <React/RCTConvert.h>
|
|
10
|
-
#import <React/RCTFont.h>
|
|
11
|
-
#import <React/RCTShadowView+Layout.h>
|
|
12
|
-
#import <React/RCTShadowView.h>
|
|
13
|
-
#import <React/RCTUIManager.h>
|
|
14
|
-
#import <React/RCTUIManagerObserverCoordinator.h>
|
|
15
|
-
#import <React/RCTUIManagerUtils.h>
|
|
16
|
-
|
|
17
|
-
#import <React/RCTBaseTextInputShadowView.h>
|
|
18
|
-
#import <React/RCTBaseTextInputView.h>
|
|
19
|
-
#import <React/RCTConvert+Text.h>
|
|
20
|
-
|
|
21
|
-
@interface Calculator : NSObject <RCTBridgeModule>
|
|
22
|
-
|
|
23
|
-
@end
|
package/ios/InputCalculator.m
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
#import <InputCalculator-Bridging-Header.h>
|
|
2
|
-
|
|
3
|
-
@implementation Calculator
|
|
4
|
-
|
|
5
|
-
- (dispatch_queue_t)methodQueue
|
|
6
|
-
{
|
|
7
|
-
return dispatch_get_main_queue();
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
RCT_EXPORT_MODULE()
|
|
11
|
-
|
|
12
|
-
@end
|
|
13
|
-
|
|
14
|
-
@interface RCT_EXTERN_MODULE(RCTInputCalculator, RCTViewManager)
|
|
15
|
-
|
|
16
|
-
RCT_REMAP_VIEW_PROPERTY(autoCapitalize, backedTextInputView.autocapitalizationType, UITextAutocapitalizationType)
|
|
17
|
-
RCT_REMAP_VIEW_PROPERTY(autoCorrect, backedTextInputView.autocorrectionType, UITextAutocorrectionType)
|
|
18
|
-
RCT_REMAP_VIEW_PROPERTY(contextMenuHidden, backedTextInputView.contextMenuHidden, BOOL)
|
|
19
|
-
RCT_REMAP_VIEW_PROPERTY(editable, backedTextInputView.editable, BOOL)
|
|
20
|
-
RCT_REMAP_VIEW_PROPERTY(enablesReturnKeyAutomatically, backedTextInputView.enablesReturnKeyAutomatically, BOOL)
|
|
21
|
-
RCT_REMAP_VIEW_PROPERTY(keyboardAppearance, backedTextInputView.keyboardAppearance, UIKeyboardAppearance)
|
|
22
|
-
RCT_REMAP_VIEW_PROPERTY(placeholder, backedTextInputView.placeholder, NSString)
|
|
23
|
-
RCT_REMAP_VIEW_PROPERTY(placeholderTextColor, backedTextInputView.placeholderColor, UIColor)
|
|
24
|
-
RCT_REMAP_VIEW_PROPERTY(returnKeyType, backedTextInputView.returnKeyType, UIReturnKeyType)
|
|
25
|
-
RCT_REMAP_VIEW_PROPERTY(selectionColor, backedTextInputView.tintColor, UIColor)
|
|
26
|
-
RCT_REMAP_VIEW_PROPERTY(spellCheck, backedTextInputView.spellCheckingType, UITextSpellCheckingType)
|
|
27
|
-
RCT_REMAP_VIEW_PROPERTY(caretHidden, backedTextInputView.caretHidden, BOOL)
|
|
28
|
-
RCT_REMAP_VIEW_PROPERTY(clearButtonMode, backedTextInputView.clearButtonMode, UITextFieldViewMode)
|
|
29
|
-
RCT_REMAP_VIEW_PROPERTY(scrollEnabled, backedTextInputView.scrollEnabled, BOOL)
|
|
30
|
-
RCT_REMAP_VIEW_PROPERTY(secureTextEntry, backedTextInputView.secureTextEntry, BOOL)
|
|
31
|
-
RCT_REMAP_VIEW_PROPERTY(smartInsertDelete, backedTextInputView.smartInsertDeleteType, UITextSmartInsertDeleteType)
|
|
32
|
-
|
|
33
|
-
RCT_EXPORT_VIEW_PROPERTY(autoFocus, BOOL)
|
|
34
|
-
RCT_EXPORT_VIEW_PROPERTY(submitBehavior, NSString)
|
|
35
|
-
RCT_EXPORT_VIEW_PROPERTY(clearTextOnFocus, BOOL)
|
|
36
|
-
RCT_EXPORT_VIEW_PROPERTY(keyboardType, UIKeyboardType)
|
|
37
|
-
RCT_EXPORT_VIEW_PROPERTY(showSoftInputOnFocus, BOOL)
|
|
38
|
-
RCT_EXPORT_VIEW_PROPERTY(maxLength, NSNumber)
|
|
39
|
-
RCT_EXPORT_VIEW_PROPERTY(selectTextOnFocus, BOOL)
|
|
40
|
-
RCT_EXPORT_VIEW_PROPERTY(selection, RCTTextSelection)
|
|
41
|
-
RCT_EXPORT_VIEW_PROPERTY(inputAccessoryViewID, NSString)
|
|
42
|
-
RCT_EXPORT_VIEW_PROPERTY(textContentType, NSString)
|
|
43
|
-
RCT_EXPORT_VIEW_PROPERTY(passwordRules, NSString)
|
|
44
|
-
|
|
45
|
-
RCT_EXPORT_VIEW_PROPERTY(onChange, RCTBubblingEventBlock)
|
|
46
|
-
RCT_EXPORT_VIEW_PROPERTY(onKeyPressSync, RCTDirectEventBlock)
|
|
47
|
-
RCT_EXPORT_VIEW_PROPERTY(onChangeSync, RCTDirectEventBlock)
|
|
48
|
-
RCT_EXPORT_VIEW_PROPERTY(onSelectionChange, RCTDirectEventBlock)
|
|
49
|
-
RCT_EXPORT_VIEW_PROPERTY(onScroll, RCTDirectEventBlock)
|
|
50
|
-
|
|
51
|
-
RCT_EXPORT_VIEW_PROPERTY(mostRecentEventCount, NSInteger)
|
|
52
|
-
|
|
53
|
-
RCT_EXPORT_SHADOW_PROPERTY(text, NSString)
|
|
54
|
-
RCT_EXPORT_SHADOW_PROPERTY(placeholder, NSString)
|
|
55
|
-
RCT_EXPORT_SHADOW_PROPERTY(onContentSizeChange, RCTDirectEventBlock)
|
|
56
|
-
RCT_EXPORT_VIEW_PROPERTY(value, NSString)
|
|
57
|
-
RCT_EXPORT_VIEW_PROPERTY(onFocus, RCTBubblingEventBlock)
|
|
58
|
-
RCT_EXPORT_VIEW_PROPERTY(onBlur, RCTBubblingEventBlock)
|
|
59
|
-
RCT_EXPORT_VIEW_PROPERTY(onKeyPress, RCTBubblingEventBlock)
|
|
60
|
-
RCT_EXPORT_VIEW_PROPERTY(onCustomKeyEvent, RCTDirectEventBlock)
|
|
61
|
-
|
|
62
|
-
RCT_EXPORT_METHOD(focus : (nonnull NSNumber *)viewTag)
|
|
63
|
-
{
|
|
64
|
-
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
|
|
65
|
-
UIView *view = viewRegistry[viewTag];
|
|
66
|
-
[view reactFocus];
|
|
67
|
-
}];
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
RCT_EXPORT_METHOD(blur : (nonnull NSNumber *)viewTag)
|
|
71
|
-
{
|
|
72
|
-
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
|
|
73
|
-
UIView *view = viewRegistry[viewTag];
|
|
74
|
-
[view reactBlur];
|
|
75
|
-
}];
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
RCT_EXPORT_VIEW_PROPERTY(keyboardColor, UIColor)
|
|
79
|
-
RCT_EXPORT_VIEW_PROPERTY(customKeyText, NSString)
|
|
80
|
-
RCT_EXPORT_VIEW_PROPERTY(customKeyBackground, NSString)
|
|
81
|
-
RCT_EXPORT_VIEW_PROPERTY(customKeyTextColor, NSString)
|
|
82
|
-
RCT_EXPORT_VIEW_PROPERTY(customKeyState, NSNumber)
|
|
83
|
-
|
|
84
|
-
@end
|
|
85
|
-
|