Mercurial > dwindows
comparison android/DWindows.kt @ 2502:b6319aed3298
Android: Massive thread safety overhaul. Not quite back to fully functional.
WebView is having many complaints about not being on the UI thread...
better to get this figured out early... All UI calls will be wrapped in a
waitOnUiThread() closure. This is our version of Android's runOnUiThread()
except it waits for the closure to finish running so we can return results...
and also so that our calls will be in the order desired in the application.
author | bsmith@81767d24-ef19-dc11-ae90-00e081727c95 |
---|---|
date | Thu, 06 May 2021 09:55:32 +0000 |
parents | 41984ffb5ca2 |
children | 1c2a79313b04 |
comparison
equal
deleted
inserted
replaced
2501:41984ffb5ca2 | 2502:b6319aed3298 |
---|---|
29 import androidx.viewpager2.widget.ViewPager2 | 29 import androidx.viewpager2.widget.ViewPager2 |
30 import com.google.android.material.tabs.TabLayout | 30 import com.google.android.material.tabs.TabLayout |
31 import com.google.android.material.tabs.TabLayout.OnTabSelectedListener | 31 import com.google.android.material.tabs.TabLayout.OnTabSelectedListener |
32 import com.google.android.material.tabs.TabLayoutMediator | 32 import com.google.android.material.tabs.TabLayoutMediator |
33 import java.util.* | 33 import java.util.* |
34 import java.util.concurrent.locks.Lock | |
35 import java.util.concurrent.locks.ReentrantLock | |
34 | 36 |
35 | 37 |
36 class DWTabViewPagerAdapter : RecyclerView.Adapter<DWTabViewPagerAdapter.DWEventViewHolder>() { | 38 class DWTabViewPagerAdapter : RecyclerView.Adapter<DWTabViewPagerAdapter.DWEventViewHolder>() { |
37 public val viewList = mutableListOf<LinearLayout>() | 39 public val viewList = mutableListOf<LinearLayout>() |
38 public val pageList = mutableListOf<Long>() | 40 public val pageList = mutableListOf<Long>() |
53 } | 55 } |
54 | 56 |
55 class DWindows : AppCompatActivity() { | 57 class DWindows : AppCompatActivity() { |
56 var firstWindow: Boolean = true | 58 var firstWindow: Boolean = true |
57 var windowLayout: LinearLayout? = null | 59 var windowLayout: LinearLayout? = null |
60 var threadLock = ReentrantLock() | |
61 var threadCond = threadLock.newCondition() | |
62 | |
63 // Our version of runOnUiThread that waits for execution | |
64 fun waitOnUiThread(runnable: Runnable) | |
65 { | |
66 if(Looper.myLooper() == Looper.getMainLooper()) { | |
67 runnable.run() | |
68 } else { | |
69 threadLock.lock() | |
70 val ourRunnable = Runnable { | |
71 threadLock.lock() | |
72 runnable.run() | |
73 threadCond.signal() | |
74 threadLock.unlock() | |
75 } | |
76 runOnUiThread(ourRunnable) | |
77 threadCond.await() | |
78 threadLock.unlock() | |
79 } | |
80 } | |
58 | 81 |
59 // We only want to call this once when the app starts up | 82 // We only want to call this once when the app starts up |
60 // By default Android will call onCreate for rotation and other | 83 // By default Android will call onCreate for rotation and other |
61 // changes. This is incompatible with Dynamic Windows... | 84 // changes. This is incompatible with Dynamic Windows... |
62 // Make sure the following is in your AndroidManifest.xml | 85 // Make sure the following is in your AndroidManifest.xml |
94 * These are the Android calls to actually create the UI... | 117 * These are the Android calls to actually create the UI... |
95 * forwarded from the C Dynamic Windows API | 118 * forwarded from the C Dynamic Windows API |
96 */ | 119 */ |
97 fun windowNew(title: String, style: Int): LinearLayout? { | 120 fun windowNew(title: String, style: Int): LinearLayout? { |
98 if (firstWindow) { | 121 if (firstWindow) { |
99 var dataArrayMap = SimpleArrayMap<String, Long>() | 122 waitOnUiThread { |
100 windowLayout = LinearLayout(this) | 123 var dataArrayMap = SimpleArrayMap<String, Long>() |
101 | 124 windowLayout = LinearLayout(this) |
102 windowLayout!!.tag = dataArrayMap | 125 |
103 setContentView(windowLayout) | 126 windowLayout!!.tag = dataArrayMap |
104 this.title = title | 127 setContentView(windowLayout) |
105 // For now we just return our DWindows' main activity layout... | 128 this.title = title |
106 // in the future, later calls should create new activities | 129 // For now we just return our DWindows' main activity layout... |
107 firstWindow = false | 130 // in the future, later calls should create new activities |
131 firstWindow = false | |
132 } | |
108 return windowLayout | 133 return windowLayout |
109 } | 134 } |
110 return null | 135 return null |
111 } | 136 } |
112 | 137 |
136 } | 161 } |
137 return retval | 162 return retval |
138 } | 163 } |
139 | 164 |
140 fun windowSetEnabled(window: View, state: Boolean) { | 165 fun windowSetEnabled(window: View, state: Boolean) { |
141 window.setEnabled(state) | 166 waitOnUiThread { |
167 window.setEnabled(state) | |
168 } | |
142 } | 169 } |
143 | 170 |
144 fun windowSetText(window: View, text: String) { | 171 fun windowSetText(window: View, text: String) { |
145 if (window is TextView) { | 172 waitOnUiThread { |
146 var textview: TextView = window | 173 if (window is TextView) { |
147 textview.text = text | 174 var textview: TextView = window |
148 } else if (window is Button) { | 175 textview.text = text |
149 var button: Button = window | 176 } else if (window is Button) { |
150 button.text = text | 177 var button: Button = window |
151 } else if (window is LinearLayout) { | 178 button.text = text |
152 // TODO: Make sure this is actually the top-level layout, not just a box | 179 } else if (window is LinearLayout) { |
153 this.title = text | 180 // TODO: Make sure this is actually the top-level layout, not just a box |
181 this.title = text | |
182 } | |
154 } | 183 } |
155 } | 184 } |
156 | 185 |
157 fun windowGetText(window: View): String? { | 186 fun windowGetText(window: View): String? { |
158 if (window is TextView) { | 187 var text: String? = null |
159 var textview: TextView = window | 188 |
160 return textview.text.toString() | 189 waitOnUiThread { |
161 } else if (window is Button) { | 190 if (window is TextView) { |
162 var button: Button = window | 191 var textview: TextView = window |
163 return button.text.toString() | 192 text = textview.text.toString() |
164 } else if (window is LinearLayout) { | 193 } else if (window is Button) { |
165 // TODO: Make sure this is actually the top-level layout, not just a box | 194 var button: Button = window |
166 return this.title.toString() | 195 text = button.text.toString() |
167 } | 196 } else if (window is LinearLayout) { |
168 return null | 197 // TODO: Make sure this is actually the top-level layout, not just a box |
198 text = this.title.toString() | |
199 } | |
200 } | |
201 return text | |
169 } | 202 } |
170 | 203 |
171 fun clipboardGetText(): String { | 204 fun clipboardGetText(): String { |
172 var cm: ClipboardManager = getSystemService(CLIPBOARD_SERVICE) as ClipboardManager | 205 var cm: ClipboardManager = getSystemService(CLIPBOARD_SERVICE) as ClipboardManager |
173 var clipdata = cm.primaryClip | 206 var clipdata = cm.primaryClip |
183 var clipdata = ClipData.newPlainText("text", text) | 216 var clipdata = ClipData.newPlainText("text", text) |
184 | 217 |
185 cm.setPrimaryClip(clipdata) | 218 cm.setPrimaryClip(clipdata) |
186 } | 219 } |
187 | 220 |
188 fun boxNew(type: Int, pad: Int): LinearLayout { | 221 fun boxNew(type: Int, pad: Int): LinearLayout? { |
189 val box = LinearLayout(this) | 222 var box: LinearLayout? = null |
190 var dataArrayMap = SimpleArrayMap<String, Long>() | 223 waitOnUiThread { |
191 | 224 box = LinearLayout(this) |
192 box.tag = dataArrayMap | 225 var dataArrayMap = SimpleArrayMap<String, Long>() |
193 box.layoutParams = | 226 |
227 box!!.tag = dataArrayMap | |
228 box!!.layoutParams = | |
194 LinearLayout.LayoutParams( | 229 LinearLayout.LayoutParams( |
195 LinearLayout.LayoutParams.WRAP_CONTENT, | 230 LinearLayout.LayoutParams.WRAP_CONTENT, |
196 LinearLayout.LayoutParams.WRAP_CONTENT | 231 LinearLayout.LayoutParams.WRAP_CONTENT |
197 ) | 232 ) |
198 if (type > 0) { | 233 if (type > 0) { |
199 box.orientation = LinearLayout.VERTICAL | 234 box!!.orientation = LinearLayout.VERTICAL |
200 } else { | 235 } else { |
201 box.orientation = LinearLayout.HORIZONTAL | 236 box!!.orientation = LinearLayout.HORIZONTAL |
202 } | 237 } |
203 box.setPadding(pad, pad, pad, pad) | 238 box!!.setPadding(pad, pad, pad, pad) |
239 } | |
204 return box | 240 return box |
205 } | 241 } |
206 | 242 |
207 fun scrollBoxNew(type: Int, pad: Int) : ScrollView { | 243 fun scrollBoxNew(type: Int, pad: Int) : ScrollView? { |
208 val scrollBox = ScrollView(this) | 244 var scrollBox: ScrollView? = null |
209 val box = LinearLayout(this) | 245 |
210 var dataArrayMap = SimpleArrayMap<String, Long>() | 246 waitOnUiThread { |
211 | 247 val box = LinearLayout(this) |
212 scrollBox.tag = dataArrayMap | 248 scrollBox = ScrollView(this) |
213 box.layoutParams = | 249 var dataArrayMap = SimpleArrayMap<String, Long>() |
214 LinearLayout.LayoutParams( | 250 |
215 LinearLayout.LayoutParams.MATCH_PARENT, | 251 scrollBox!!.tag = dataArrayMap |
216 LinearLayout.LayoutParams.MATCH_PARENT | 252 box.layoutParams = |
217 ) | 253 LinearLayout.LayoutParams( |
218 if (type > 0) { | 254 LinearLayout.LayoutParams.MATCH_PARENT, |
219 box.orientation = LinearLayout.VERTICAL | 255 LinearLayout.LayoutParams.MATCH_PARENT |
220 } else { | 256 ) |
221 box.orientation = LinearLayout.HORIZONTAL | 257 if (type > 0) { |
222 } | 258 box.orientation = LinearLayout.VERTICAL |
223 box.setPadding(pad, pad, pad, pad) | 259 } else { |
224 // Add a pointer back to the ScrollView | 260 box.orientation = LinearLayout.HORIZONTAL |
225 box.tag = scrollBox | 261 } |
226 scrollBox.addView(box) | 262 box.setPadding(pad, pad, pad, pad) |
263 // Add a pointer back to the ScrollView | |
264 box.tag = scrollBox | |
265 scrollBox!!.addView(box) | |
266 } | |
227 return scrollBox | 267 return scrollBox |
228 } | 268 } |
229 | 269 |
230 fun boxPack( | 270 fun boxPack( |
231 boxview: View, | 271 boxview: View, |
235 height: Int, | 275 height: Int, |
236 hsize: Int, | 276 hsize: Int, |
237 vsize: Int, | 277 vsize: Int, |
238 pad: Int | 278 pad: Int |
239 ) { | 279 ) { |
240 var w: Int = LinearLayout.LayoutParams.WRAP_CONTENT | 280 waitOnUiThread { |
241 var h: Int = LinearLayout.LayoutParams.WRAP_CONTENT | 281 var w: Int = LinearLayout.LayoutParams.WRAP_CONTENT |
242 var box: LinearLayout? = null | 282 var h: Int = LinearLayout.LayoutParams.WRAP_CONTENT |
243 | 283 var box: LinearLayout? = null |
244 // Handle scrollboxes by pulling the LinearLayout | 284 |
245 // out of the ScrollView to pack into | 285 // Handle scrollboxes by pulling the LinearLayout |
246 if(boxview is LinearLayout) { | 286 // out of the ScrollView to pack into |
247 box = boxview as LinearLayout | 287 if (boxview is LinearLayout) { |
248 } else if(boxview is ScrollView) { | 288 box = boxview as LinearLayout |
249 var sv: ScrollView = boxview | 289 } else if (boxview is ScrollView) { |
250 | 290 var sv: ScrollView = boxview |
251 if(sv.getChildAt(0) is LinearLayout) { | 291 |
252 box = sv.getChildAt(0) as LinearLayout | 292 if (sv.getChildAt(0) is LinearLayout) { |
253 } | 293 box = sv.getChildAt(0) as LinearLayout |
254 } | 294 } |
255 | 295 } |
256 if(box != null) { | 296 |
257 if ((item is LinearLayout) or (item is ScrollView)) { | 297 if (box != null) { |
298 if ((item is LinearLayout) or (item is ScrollView)) { | |
299 if (box.orientation == LinearLayout.VERTICAL) { | |
300 if (hsize > 0) { | |
301 w = LinearLayout.LayoutParams.MATCH_PARENT | |
302 } | |
303 } else { | |
304 if (vsize > 0) { | |
305 h = LinearLayout.LayoutParams.MATCH_PARENT | |
306 } | |
307 } | |
308 } | |
309 var params: LinearLayout.LayoutParams = LinearLayout.LayoutParams(w, h) | |
310 | |
311 if (item !is LinearLayout && (width != -1 || height != -1)) { | |
312 item.measure(0, 0) | |
313 if (width > 0) { | |
314 w = width | |
315 } else if (width == -1) { | |
316 w = item.getMeasuredWidth() | |
317 } | |
318 if (height > 0) { | |
319 h = height | |
320 } else if (height == -1) { | |
321 h = item.getMeasuredHeight() | |
322 } | |
323 } | |
258 if (box.orientation == LinearLayout.VERTICAL) { | 324 if (box.orientation == LinearLayout.VERTICAL) { |
259 if (hsize > 0) { | 325 if (vsize > 0) { |
260 w = LinearLayout.LayoutParams.MATCH_PARENT | 326 if (w > 0) { |
327 params.weight = w.toFloat() | |
328 } else { | |
329 params.weight = 1F | |
330 } | |
261 } | 331 } |
262 } else { | 332 } else { |
263 if (vsize > 0) { | 333 if (hsize > 0) { |
264 h = LinearLayout.LayoutParams.MATCH_PARENT | 334 if (h > 0) { |
335 params.weight = h.toFloat() | |
336 } else { | |
337 params.weight = 1F | |
338 } | |
265 } | 339 } |
266 } | 340 } |
267 } | 341 if (pad > 0) { |
268 var params: LinearLayout.LayoutParams = LinearLayout.LayoutParams(w, h) | 342 params.setMargins(pad, pad, pad, pad) |
269 | 343 } |
270 if (item !is LinearLayout && (width != -1 || height != -1)) { | 344 var grav: Int = Gravity.CLIP_HORIZONTAL or Gravity.CLIP_VERTICAL |
271 item.measure(0, 0) | 345 if (hsize > 0 && vsize > 0) { |
272 if (width > 0) { | 346 params.gravity = Gravity.FILL or grav |
273 w = width | 347 } else if (hsize > 0) { |
274 } else if (width == -1) { | 348 params.gravity = Gravity.FILL_HORIZONTAL or grav |
275 w = item.getMeasuredWidth() | 349 } else if (vsize > 0) { |
276 } | 350 params.gravity = Gravity.FILL_VERTICAL or grav |
277 if (height > 0) { | 351 } |
278 h = height | 352 item.layoutParams = params |
279 } else if (height == -1) { | 353 box.addView(item, index) |
280 h = item.getMeasuredHeight() | 354 } |
281 } | 355 } |
282 } | 356 } |
283 if (box.orientation == LinearLayout.VERTICAL) { | 357 |
284 if (vsize > 0) { | 358 fun boxUnpack(item: View) { |
285 if (w > 0) { | 359 waitOnUiThread { |
286 params.weight = w.toFloat() | 360 var box: LinearLayout = item.parent as LinearLayout |
287 } else { | 361 box.removeView(item) |
288 params.weight = 1F | 362 } |
289 } | 363 } |
290 } | 364 |
365 fun boxUnpackAtIndex(box: LinearLayout, index: Int): View? { | |
366 var item: View? = null | |
367 | |
368 waitOnUiThread { | |
369 item = box.getChildAt(index) | |
370 | |
371 box.removeView(item) | |
372 } | |
373 return item | |
374 } | |
375 | |
376 fun buttonNew(text: String, cid: Int): Button? { | |
377 var button: Button? = null | |
378 waitOnUiThread { | |
379 button = Button(this) | |
380 var dataArrayMap = SimpleArrayMap<String, Long>() | |
381 | |
382 button!!.tag = dataArrayMap | |
383 button!!.text = text | |
384 button!!.id = cid | |
385 button!!.setOnClickListener { | |
386 eventHandlerSimple(button!!, 8) | |
387 } | |
388 } | |
389 return button | |
390 } | |
391 | |
392 fun entryfieldNew(text: String, cid: Int, password: Int): EditText? { | |
393 var entryfield: EditText? = null | |
394 | |
395 waitOnUiThread { | |
396 var dataArrayMap = SimpleArrayMap<String, Long>() | |
397 entryfield = EditText(this) | |
398 | |
399 entryfield!!.tag = dataArrayMap | |
400 entryfield!!.id = cid | |
401 if (password > 0) { | |
402 entryfield!!.transformationMethod = PasswordTransformationMethod.getInstance() | |
403 } | |
404 entryfield!!.setText(text) | |
405 } | |
406 return entryfield | |
407 } | |
408 | |
409 fun entryfieldSetLimit(entryfield: EditText, limit: Long) { | |
410 waitOnUiThread { | |
411 entryfield.filters = arrayOf<InputFilter>(LengthFilter(limit.toInt())) | |
412 } | |
413 } | |
414 | |
415 fun radioButtonNew(text: String, cid: Int): RadioButton? { | |
416 var radiobutton: RadioButton? = null | |
417 | |
418 waitOnUiThread { | |
419 var dataArrayMap = SimpleArrayMap<String, Long>() | |
420 radiobutton = RadioButton(this) | |
421 | |
422 radiobutton!!.tag = dataArrayMap | |
423 radiobutton!!.id = cid | |
424 radiobutton!!.text = text | |
425 radiobutton!!.setOnClickListener { | |
426 eventHandlerSimple(radiobutton!!, 8) | |
427 } | |
428 } | |
429 return radiobutton | |
430 } | |
431 | |
432 fun checkboxNew(text: String, cid: Int): CheckBox? { | |
433 var checkbox: CheckBox? = null | |
434 | |
435 waitOnUiThread { | |
436 var dataArrayMap = SimpleArrayMap<String, Long>() | |
437 | |
438 checkbox = CheckBox(this) | |
439 checkbox!!.tag = dataArrayMap | |
440 checkbox!!.id = cid | |
441 checkbox!!.text = text | |
442 checkbox!!.setOnClickListener { | |
443 eventHandlerSimple(checkbox!!, 8) | |
444 } | |
445 } | |
446 return checkbox | |
447 } | |
448 | |
449 fun checkOrRadioSetChecked(control: View, state: Int) | |
450 { | |
451 waitOnUiThread { | |
452 if (control is CheckBox) { | |
453 var checkbox: CheckBox = control | |
454 checkbox.isChecked = state != 0 | |
455 } else if (control is RadioButton) { | |
456 var radiobutton: RadioButton = control | |
457 radiobutton.isChecked = state != 0 | |
458 } | |
459 } | |
460 } | |
461 | |
462 fun checkOrRadioGetChecked(control: View): Boolean | |
463 { | |
464 var retval: Boolean = false | |
465 | |
466 waitOnUiThread { | |
467 if (control is CheckBox) { | |
468 var checkbox: CheckBox = control | |
469 retval = checkbox.isChecked | |
470 } else if (control is RadioButton) { | |
471 var radiobutton: RadioButton = control | |
472 retval = radiobutton.isChecked | |
473 } | |
474 } | |
475 return retval | |
476 } | |
477 | |
478 fun textNew(text: String, cid: Int, status: Int): TextView? { | |
479 var textview: TextView? = null | |
480 | |
481 waitOnUiThread { | |
482 var dataArrayMap = SimpleArrayMap<String, Long>() | |
483 | |
484 textview = TextView(this) | |
485 textview!!.tag = dataArrayMap | |
486 textview!!.id = cid | |
487 textview!!.text = text | |
488 if (status != 0) { | |
489 val border = GradientDrawable() | |
490 | |
491 // Set a black border on white background... | |
492 // might need to change this to invisible... | |
493 // or the color from windowSetColor | |
494 border.setColor(-0x1) | |
495 border.setStroke(1, -0x1000000) | |
496 textview!!.background = border | |
497 } | |
498 } | |
499 return textview | |
500 } | |
501 | |
502 fun notebookNew(cid: Int, top: Int): RelativeLayout? | |
503 { | |
504 var notebook: RelativeLayout? = null | |
505 | |
506 waitOnUiThread { | |
507 val pager = ViewPager2(this) | |
508 val tabs = TabLayout(this) | |
509 var w: Int = RelativeLayout.LayoutParams.MATCH_PARENT | |
510 var h: Int = RelativeLayout.LayoutParams.WRAP_CONTENT | |
511 var dataArrayMap = SimpleArrayMap<String, Long>() | |
512 | |
513 notebook = RelativeLayout(this) | |
514 notebook!!.tag = dataArrayMap | |
515 notebook!!.id = cid | |
516 tabs.id = View.generateViewId() | |
517 pager.id = View.generateViewId() | |
518 pager.adapter = DWTabViewPagerAdapter() | |
519 TabLayoutMediator(tabs, pager) { tab, position -> | |
520 // This code never gets called? | |
521 }.attach() | |
522 | |
523 var params: RelativeLayout.LayoutParams = RelativeLayout.LayoutParams(w, h) | |
524 if (top != 0) { | |
525 params.addRule(RelativeLayout.ALIGN_PARENT_TOP) | |
291 } else { | 526 } else { |
292 if (hsize > 0) { | 527 params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM) |
293 if (h > 0) { | 528 } |
294 params.weight = h.toFloat() | 529 tabs.tabGravity = TabLayout.GRAVITY_FILL |
295 } else { | 530 tabs.tabMode = TabLayout.MODE_FIXED |
296 params.weight = 1F | 531 notebook!!.addView(tabs, params) |
297 } | 532 params = RelativeLayout.LayoutParams(w, w) |
298 } | 533 if (top != 0) { |
299 } | 534 params.addRule(RelativeLayout.BELOW, tabs.id) |
300 if (pad > 0) { | 535 } else { |
301 params.setMargins(pad, pad, pad, pad) | 536 params.addRule(RelativeLayout.ABOVE, tabs.id) |
302 } | 537 } |
303 var grav: Int = Gravity.CLIP_HORIZONTAL or Gravity.CLIP_VERTICAL | 538 notebook!!.addView(pager, params) |
304 if (hsize > 0 && vsize > 0) { | 539 tabs.addOnTabSelectedListener(object : OnTabSelectedListener { |
305 params.gravity = Gravity.FILL or grav | 540 override fun onTabSelected(tab: TabLayout.Tab) { |
306 } else if (hsize > 0) { | 541 val adapter = pager.adapter as DWTabViewPagerAdapter |
307 params.gravity = Gravity.FILL_HORIZONTAL or grav | 542 |
308 } else if (vsize > 0) { | 543 pager.currentItem = tab.position |
309 params.gravity = Gravity.FILL_VERTICAL or grav | 544 eventHandlerNotebook(notebook!!, 15, adapter.pageList[tab.position]) |
310 } | 545 } |
311 item.layoutParams = params | 546 |
312 box.addView(item, index) | 547 override fun onTabUnselected(tab: TabLayout.Tab) {} |
313 } | 548 override fun onTabReselected(tab: TabLayout.Tab) {} |
314 } | 549 }) |
315 | 550 } |
316 fun boxUnpack(item: View) { | |
317 var box: LinearLayout = item.parent as LinearLayout | |
318 box.removeView(item) | |
319 } | |
320 | |
321 fun boxUnpackAtIndex(box: LinearLayout, index: Int): View? { | |
322 var item: View = box.getChildAt(index) | |
323 | |
324 box.removeView(item) | |
325 return item | |
326 } | |
327 | |
328 fun buttonNew(text: String, cid: Int): Button { | |
329 val button = Button(this) | |
330 var dataArrayMap = SimpleArrayMap<String, Long>() | |
331 | |
332 button.tag = dataArrayMap | |
333 button.text = text | |
334 button.id = cid | |
335 button.setOnClickListener { | |
336 eventHandlerSimple(button, 8) | |
337 } | |
338 return button | |
339 } | |
340 | |
341 fun entryfieldNew(text: String, cid: Int, password: Int): EditText { | |
342 val entryfield = EditText(this) | |
343 var dataArrayMap = SimpleArrayMap<String, Long>() | |
344 | |
345 entryfield.tag = dataArrayMap | |
346 entryfield.id = cid | |
347 if (password > 0) { | |
348 entryfield.transformationMethod = PasswordTransformationMethod.getInstance() | |
349 } | |
350 entryfield.setText(text) | |
351 return entryfield | |
352 } | |
353 | |
354 fun entryfieldSetLimit(entryfield: EditText, limit: Long) { | |
355 entryfield.filters = arrayOf<InputFilter>(LengthFilter(limit.toInt())) | |
356 } | |
357 | |
358 fun radioButtonNew(text: String, cid: Int): RadioButton { | |
359 val radiobutton = RadioButton(this) | |
360 var dataArrayMap = SimpleArrayMap<String, Long>() | |
361 | |
362 radiobutton.tag = dataArrayMap | |
363 radiobutton.id = cid | |
364 radiobutton.text = text | |
365 radiobutton.setOnClickListener { | |
366 eventHandlerSimple(radiobutton, 8) | |
367 } | |
368 return radiobutton | |
369 } | |
370 | |
371 fun checkboxNew(text: String, cid: Int): CheckBox { | |
372 val checkbox = CheckBox(this) | |
373 var dataArrayMap = SimpleArrayMap<String, Long>() | |
374 | |
375 checkbox.tag = dataArrayMap | |
376 checkbox.id = cid | |
377 checkbox.text = text | |
378 checkbox.setOnClickListener { | |
379 eventHandlerSimple(checkbox, 8) | |
380 } | |
381 return checkbox | |
382 } | |
383 | |
384 fun checkOrRadioSetChecked(control: View, state: Int) | |
385 { | |
386 if(control is CheckBox) { | |
387 var checkbox: CheckBox = control | |
388 checkbox.isChecked = state != 0 | |
389 } else if(control is RadioButton) { | |
390 var radiobutton: RadioButton = control | |
391 radiobutton.isChecked = state != 0 | |
392 } | |
393 } | |
394 | |
395 fun checkOrRadioGetChecked(control: View): Boolean | |
396 { | |
397 if(control is CheckBox) { | |
398 var checkbox: CheckBox = control | |
399 return checkbox.isChecked | |
400 } else if(control is RadioButton) { | |
401 var radiobutton: RadioButton = control | |
402 return radiobutton.isChecked | |
403 } | |
404 return false | |
405 } | |
406 | |
407 fun textNew(text: String, cid: Int, status: Int): TextView { | |
408 val textview = TextView(this) | |
409 var dataArrayMap = SimpleArrayMap<String, Long>() | |
410 | |
411 textview.tag = dataArrayMap | |
412 textview.id = cid | |
413 textview.text = text | |
414 if (status != 0) { | |
415 val border = GradientDrawable() | |
416 | |
417 // Set a black border on white background... | |
418 // might need to change this to invisible... | |
419 // or the color from windowSetColor | |
420 border.setColor(-0x1) | |
421 border.setStroke(1, -0x1000000) | |
422 textview.background = border | |
423 } | |
424 return textview | |
425 } | |
426 | |
427 fun notebookNew(cid: Int, top: Int): RelativeLayout | |
428 { | |
429 val notebook = RelativeLayout(this) | |
430 val pager = ViewPager2(this) | |
431 val tabs = TabLayout(this) | |
432 var w: Int = RelativeLayout.LayoutParams.MATCH_PARENT | |
433 var h: Int = RelativeLayout.LayoutParams.WRAP_CONTENT | |
434 var dataArrayMap = SimpleArrayMap<String, Long>() | |
435 | |
436 notebook.tag = dataArrayMap | |
437 notebook.id = cid | |
438 tabs.id = View.generateViewId() | |
439 pager.id = View.generateViewId() | |
440 pager.adapter = DWTabViewPagerAdapter() | |
441 TabLayoutMediator(tabs, pager) { tab, position -> | |
442 // This code never gets called? | |
443 }.attach() | |
444 | |
445 var params: RelativeLayout.LayoutParams = RelativeLayout.LayoutParams(w, h) | |
446 if(top != 0) { | |
447 params.addRule(RelativeLayout.ALIGN_PARENT_TOP) | |
448 } else { | |
449 params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM) | |
450 } | |
451 tabs.tabGravity = TabLayout.GRAVITY_FILL | |
452 tabs.tabMode = TabLayout.MODE_FIXED | |
453 notebook.addView(tabs, params) | |
454 params = RelativeLayout.LayoutParams(w, w) | |
455 if(top != 0) { | |
456 params.addRule(RelativeLayout.BELOW, tabs.id) | |
457 } else { | |
458 params.addRule(RelativeLayout.ABOVE, tabs.id) | |
459 } | |
460 notebook.addView(pager, params) | |
461 tabs.addOnTabSelectedListener(object : OnTabSelectedListener { | |
462 override fun onTabSelected(tab: TabLayout.Tab) { | |
463 val adapter = pager.adapter as DWTabViewPagerAdapter | |
464 | |
465 pager.currentItem = tab.position | |
466 eventHandlerNotebook(notebook, 15, adapter.pageList[tab.position]) | |
467 } | |
468 override fun onTabUnselected(tab: TabLayout.Tab) {} | |
469 override fun onTabReselected(tab: TabLayout.Tab) {} | |
470 }) | |
471 return notebook | 551 return notebook |
472 } | 552 } |
473 | 553 |
474 fun notebookPageNew(notebook: RelativeLayout, flags: Long, front: Int): Long | 554 fun notebookPageNew(notebook: RelativeLayout, flags: Long, front: Int): Long |
475 { | 555 { |
476 var pager: ViewPager2? = null | |
477 var tabs: TabLayout? = null | |
478 var pageID = 0L | 556 var pageID = 0L |
479 | 557 |
480 if(notebook.getChildAt(0) is ViewPager2 && notebook.getChildAt(1) is TabLayout) { | 558 waitOnUiThread { |
481 pager = notebook.getChildAt(0) as ViewPager2 | 559 var pager: ViewPager2? = null |
482 tabs = notebook.getChildAt(1) as TabLayout | 560 var tabs: TabLayout? = null |
483 } else if(notebook.getChildAt(1) is ViewPager2 && notebook.getChildAt(0) is TabLayout) { | 561 |
484 pager = notebook.getChildAt(1) as ViewPager2 | 562 if (notebook.getChildAt(0) is ViewPager2 && notebook.getChildAt(1) is TabLayout) { |
485 tabs = notebook.getChildAt(0) as TabLayout | 563 pager = notebook.getChildAt(0) as ViewPager2 |
486 } | 564 tabs = notebook.getChildAt(1) as TabLayout |
487 | 565 } else if (notebook.getChildAt(1) is ViewPager2 && notebook.getChildAt(0) is TabLayout) { |
488 if(pager != null && tabs != null) { | 566 pager = notebook.getChildAt(1) as ViewPager2 |
489 var adapter: DWTabViewPagerAdapter = pager.adapter as DWTabViewPagerAdapter | 567 tabs = notebook.getChildAt(0) as TabLayout |
490 var tab = tabs.newTab() | 568 } |
491 | 569 |
492 // Increment our page ID... making sure no duplicates exist | 570 if (pager != null && tabs != null) { |
493 do { | 571 var adapter: DWTabViewPagerAdapter = pager.adapter as DWTabViewPagerAdapter |
494 adapter.currentPageID += 1 | 572 var tab = tabs.newTab() |
495 } | 573 |
496 while(adapter.currentPageID == 0L || adapter.pageList.contains(adapter.currentPageID)) | 574 // Increment our page ID... making sure no duplicates exist |
497 pageID = adapter.currentPageID | 575 do { |
498 // Temporarily add a black tab with an empty layout/box | 576 adapter.currentPageID += 1 |
499 if(front != 0) { | 577 } while (adapter.currentPageID == 0L || adapter.pageList.contains(adapter.currentPageID)) |
500 adapter.viewList.add(0, LinearLayout(this)) | 578 pageID = adapter.currentPageID |
501 adapter.pageList.add(0, pageID) | 579 // Temporarily add a black tab with an empty layout/box |
502 tabs.addTab(tab, 0) | 580 if (front != 0) { |
503 } else { | 581 adapter.viewList.add(0, LinearLayout(this)) |
504 adapter.viewList.add(LinearLayout(this)) | 582 adapter.pageList.add(0, pageID) |
505 adapter.pageList.add(pageID) | 583 tabs.addTab(tab, 0) |
506 tabs.addTab(tab) | 584 } else { |
585 adapter.viewList.add(LinearLayout(this)) | |
586 adapter.pageList.add(pageID) | |
587 tabs.addTab(tab) | |
588 } | |
507 } | 589 } |
508 } | 590 } |
509 return pageID | 591 return pageID |
510 } | 592 } |
511 | 593 |
512 fun notebookPageDestroy(notebook: RelativeLayout, pageID: Long) | 594 fun notebookPageDestroy(notebook: RelativeLayout, pageID: Long) |
513 { | 595 { |
514 var pager: ViewPager2? = null | 596 waitOnUiThread { |
515 var tabs: TabLayout? = null | 597 var pager: ViewPager2? = null |
516 | 598 var tabs: TabLayout? = null |
517 if(notebook.getChildAt(0) is ViewPager2 && notebook.getChildAt(1) is TabLayout) { | 599 |
518 pager = notebook.getChildAt(0) as ViewPager2 | 600 if (notebook.getChildAt(0) is ViewPager2 && notebook.getChildAt(1) is TabLayout) { |
519 tabs = notebook.getChildAt(1) as TabLayout | 601 pager = notebook.getChildAt(0) as ViewPager2 |
520 } else if(notebook.getChildAt(1) is ViewPager2 && notebook.getChildAt(0) is TabLayout) { | 602 tabs = notebook.getChildAt(1) as TabLayout |
521 pager = notebook.getChildAt(1) as ViewPager2 | 603 } else if (notebook.getChildAt(1) is ViewPager2 && notebook.getChildAt(0) is TabLayout) { |
522 tabs = notebook.getChildAt(0) as TabLayout | 604 pager = notebook.getChildAt(1) as ViewPager2 |
523 } | 605 tabs = notebook.getChildAt(0) as TabLayout |
524 | 606 } |
525 if(pager != null && tabs != null) { | 607 |
526 var adapter: DWTabViewPagerAdapter = pager.adapter as DWTabViewPagerAdapter | 608 if (pager != null && tabs != null) { |
527 val index = adapter.pageList.indexOf(pageID) | 609 var adapter: DWTabViewPagerAdapter = pager.adapter as DWTabViewPagerAdapter |
528 val tab = tabs.getTabAt(index) | 610 val index = adapter.pageList.indexOf(pageID) |
529 | 611 val tab = tabs.getTabAt(index) |
530 if (tab != null) { | 612 |
531 adapter.viewList.removeAt(index) | 613 if (tab != null) { |
532 adapter.pageList.removeAt(index) | 614 adapter.viewList.removeAt(index) |
533 tabs.removeTab(tab) | 615 adapter.pageList.removeAt(index) |
616 tabs.removeTab(tab) | |
617 } | |
534 } | 618 } |
535 } | 619 } |
536 } | 620 } |
537 | 621 |
538 fun notebookPageSetText(notebook: RelativeLayout, pageID: Long, text: String) | 622 fun notebookPageSetText(notebook: RelativeLayout, pageID: Long, text: String) |
539 { | 623 { |
540 var pager: ViewPager2? = null | 624 waitOnUiThread { |
541 var tabs: TabLayout? = null | 625 var pager: ViewPager2? = null |
542 | 626 var tabs: TabLayout? = null |
543 if(notebook.getChildAt(0) is ViewPager2 && notebook.getChildAt(1) is TabLayout) { | 627 |
544 pager = notebook.getChildAt(0) as ViewPager2 | 628 if (notebook.getChildAt(0) is ViewPager2 && notebook.getChildAt(1) is TabLayout) { |
545 tabs = notebook.getChildAt(1) as TabLayout | 629 pager = notebook.getChildAt(0) as ViewPager2 |
546 } else if(notebook.getChildAt(1) is ViewPager2 && notebook.getChildAt(0) is TabLayout) { | 630 tabs = notebook.getChildAt(1) as TabLayout |
547 pager = notebook.getChildAt(1) as ViewPager2 | 631 } else if (notebook.getChildAt(1) is ViewPager2 && notebook.getChildAt(0) is TabLayout) { |
548 tabs = notebook.getChildAt(0) as TabLayout | 632 pager = notebook.getChildAt(1) as ViewPager2 |
549 } | 633 tabs = notebook.getChildAt(0) as TabLayout |
550 | 634 } |
551 if(pager != null && tabs != null) { | 635 |
552 val adapter: DWTabViewPagerAdapter = pager.adapter as DWTabViewPagerAdapter | 636 if (pager != null && tabs != null) { |
553 val index = adapter.pageList.indexOf(pageID) | 637 val adapter: DWTabViewPagerAdapter = pager.adapter as DWTabViewPagerAdapter |
554 val tab = tabs.getTabAt(index) | 638 val index = adapter.pageList.indexOf(pageID) |
555 | 639 val tab = tabs.getTabAt(index) |
556 if (tab != null) { | 640 |
557 tab.text = text | 641 if (tab != null) { |
642 tab.text = text | |
643 } | |
558 } | 644 } |
559 } | 645 } |
560 } | 646 } |
561 | 647 |
562 fun notebookPagePack(notebook: RelativeLayout, pageID: Long, box: LinearLayout) | 648 fun notebookPagePack(notebook: RelativeLayout, pageID: Long, box: LinearLayout) |
563 { | 649 { |
564 var pager: ViewPager2? = null | 650 waitOnUiThread { |
565 var tabs: TabLayout? = null | 651 var pager: ViewPager2? = null |
566 | 652 var tabs: TabLayout? = null |
567 if(notebook.getChildAt(0) is ViewPager2 && notebook.getChildAt(1) is TabLayout) { | 653 |
568 pager = notebook.getChildAt(0) as ViewPager2 | 654 if (notebook.getChildAt(0) is ViewPager2 && notebook.getChildAt(1) is TabLayout) { |
569 tabs = notebook.getChildAt(1) as TabLayout | 655 pager = notebook.getChildAt(0) as ViewPager2 |
570 } else if(notebook.getChildAt(1) is ViewPager2 && notebook.getChildAt(0) is TabLayout) { | 656 tabs = notebook.getChildAt(1) as TabLayout |
571 pager = notebook.getChildAt(1) as ViewPager2 | 657 } else if (notebook.getChildAt(1) is ViewPager2 && notebook.getChildAt(0) is TabLayout) { |
572 tabs = notebook.getChildAt(0) as TabLayout | 658 pager = notebook.getChildAt(1) as ViewPager2 |
573 } | 659 tabs = notebook.getChildAt(0) as TabLayout |
574 | 660 } |
575 if(pager != null && tabs != null) { | 661 |
576 var adapter: DWTabViewPagerAdapter = pager.adapter as DWTabViewPagerAdapter | 662 if (pager != null && tabs != null) { |
577 val index = adapter.pageList.indexOf(pageID) | 663 var adapter: DWTabViewPagerAdapter = pager.adapter as DWTabViewPagerAdapter |
578 | 664 val index = adapter.pageList.indexOf(pageID) |
579 // Make sure the box is MATCH_PARENT | 665 |
580 box.layoutParams = LinearLayout.LayoutParams( | 666 // Make sure the box is MATCH_PARENT |
581 LinearLayout.LayoutParams.MATCH_PARENT, | 667 box.layoutParams = LinearLayout.LayoutParams( |
582 LinearLayout.LayoutParams.MATCH_PARENT | 668 LinearLayout.LayoutParams.MATCH_PARENT, |
583 ); | 669 LinearLayout.LayoutParams.MATCH_PARENT |
584 | 670 ); |
585 adapter.viewList[index] = box | 671 |
672 adapter.viewList[index] = box | |
673 } | |
586 } | 674 } |
587 } | 675 } |
588 | 676 |
589 fun notebookPageGet(notebook: RelativeLayout): Long | 677 fun notebookPageGet(notebook: RelativeLayout): Long |
590 { | 678 { |
591 var pager: ViewPager2? = null | 679 var retval: Long = 0L |
592 var tabs: TabLayout? = null | 680 |
593 | 681 waitOnUiThread { |
594 if(notebook.getChildAt(0) is ViewPager2 && notebook.getChildAt(1) is TabLayout) { | 682 var pager: ViewPager2? = null |
595 pager = notebook.getChildAt(0) as ViewPager2 | 683 var tabs: TabLayout? = null |
596 tabs = notebook.getChildAt(1) as TabLayout | 684 |
597 } else if(notebook.getChildAt(1) is ViewPager2 && notebook.getChildAt(0) is TabLayout) { | 685 if (notebook.getChildAt(0) is ViewPager2 && notebook.getChildAt(1) is TabLayout) { |
598 pager = notebook.getChildAt(1) as ViewPager2 | 686 pager = notebook.getChildAt(0) as ViewPager2 |
599 tabs = notebook.getChildAt(0) as TabLayout | 687 tabs = notebook.getChildAt(1) as TabLayout |
600 } | 688 } else if (notebook.getChildAt(1) is ViewPager2 && notebook.getChildAt(0) is TabLayout) { |
601 | 689 pager = notebook.getChildAt(1) as ViewPager2 |
602 if(pager != null && tabs != null) { | 690 tabs = notebook.getChildAt(0) as TabLayout |
603 var adapter: DWTabViewPagerAdapter = pager.adapter as DWTabViewPagerAdapter | 691 } |
604 return adapter.pageList.get(tabs.selectedTabPosition) | 692 |
605 } | 693 if (pager != null && tabs != null) { |
606 return 0L | 694 var adapter: DWTabViewPagerAdapter = pager.adapter as DWTabViewPagerAdapter |
695 retval = adapter.pageList.get(tabs.selectedTabPosition) | |
696 } | |
697 } | |
698 return retval | |
607 } | 699 } |
608 | 700 |
609 fun notebookPageSet(notebook: RelativeLayout, pageID: Long) | 701 fun notebookPageSet(notebook: RelativeLayout, pageID: Long) |
610 { | 702 { |
611 var pager: ViewPager2? = null | 703 waitOnUiThread { |
612 var tabs: TabLayout? = null | 704 var pager: ViewPager2? = null |
613 | 705 var tabs: TabLayout? = null |
614 if(notebook.getChildAt(0) is ViewPager2 && notebook.getChildAt(1) is TabLayout) { | 706 |
615 pager = notebook.getChildAt(0) as ViewPager2 | 707 if (notebook.getChildAt(0) is ViewPager2 && notebook.getChildAt(1) is TabLayout) { |
616 tabs = notebook.getChildAt(1) as TabLayout | 708 pager = notebook.getChildAt(0) as ViewPager2 |
617 } else if(notebook.getChildAt(1) is ViewPager2 && notebook.getChildAt(0) is TabLayout) { | 709 tabs = notebook.getChildAt(1) as TabLayout |
618 pager = notebook.getChildAt(1) as ViewPager2 | 710 } else if (notebook.getChildAt(1) is ViewPager2 && notebook.getChildAt(0) is TabLayout) { |
619 tabs = notebook.getChildAt(0) as TabLayout | 711 pager = notebook.getChildAt(1) as ViewPager2 |
620 } | 712 tabs = notebook.getChildAt(0) as TabLayout |
621 | 713 } |
622 if(pager != null && tabs != null) { | 714 |
623 val adapter: DWTabViewPagerAdapter = pager.adapter as DWTabViewPagerAdapter | 715 if (pager != null && tabs != null) { |
624 val index = adapter.pageList.indexOf(pageID) | 716 val adapter: DWTabViewPagerAdapter = pager.adapter as DWTabViewPagerAdapter |
625 val tab = tabs.getTabAt(index) | 717 val index = adapter.pageList.indexOf(pageID) |
626 | 718 val tab = tabs.getTabAt(index) |
627 tabs.selectTab(tab) | 719 |
628 } | 720 tabs.selectTab(tab) |
629 } | 721 } |
630 | 722 } |
631 fun sliderNew(vertical: Int, increments: Int, cid: Int): SeekBar | 723 } |
632 { | 724 |
633 val slider = SeekBar(this) | 725 fun sliderNew(vertical: Int, increments: Int, cid: Int): SeekBar? |
634 var dataArrayMap = SimpleArrayMap<String, Long>() | 726 { |
635 | 727 var slider: SeekBar? = null |
636 slider.tag = dataArrayMap | 728 |
637 slider.id = cid | 729 waitOnUiThread { |
638 slider.max = increments | 730 var dataArrayMap = SimpleArrayMap<String, Long>() |
639 if(vertical != 0) { | 731 |
640 slider.rotation = 270F | 732 slider = SeekBar(this) |
641 } | 733 slider!!.tag = dataArrayMap |
642 slider.setOnSeekBarChangeListener(object : OnSeekBarChangeListener { | 734 slider!!.id = cid |
643 override fun onStopTrackingTouch(seekBar: SeekBar) { | 735 slider!!.max = increments |
644 } | 736 if (vertical != 0) { |
645 | 737 slider!!.rotation = 270F |
646 override fun onStartTrackingTouch(seekBar: SeekBar) { | 738 } |
647 } | 739 slider!!.setOnSeekBarChangeListener(object : OnSeekBarChangeListener { |
648 | 740 override fun onStopTrackingTouch(seekBar: SeekBar) { |
649 override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) { | 741 } |
650 eventHandler(slider, null, 14, null, null, slider.progress, 0, 0, 0) | 742 |
651 } | 743 override fun onStartTrackingTouch(seekBar: SeekBar) { |
652 }) | 744 } |
745 | |
746 override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) { | |
747 eventHandler(slider, null, 14, null, null, slider!!.progress, 0, 0, 0) | |
748 } | |
749 }) | |
750 } | |
653 return slider | 751 return slider |
654 } | 752 } |
655 | 753 |
656 fun percentNew(cid: Int): ProgressBar | 754 fun percentNew(cid: Int): ProgressBar? |
657 { | 755 { |
658 val percent = ProgressBar(this) | 756 var percent: ProgressBar? = null |
659 var dataArrayMap = SimpleArrayMap<String, Long>() | 757 |
660 | 758 waitOnUiThread { |
661 percent.tag = dataArrayMap | 759 var dataArrayMap = SimpleArrayMap<String, Long>() |
662 percent.id = cid | 760 |
663 percent.max = 100 | 761 percent = ProgressBar(this) |
762 percent!!.tag = dataArrayMap | |
763 percent!!.id = cid | |
764 percent!!.max = 100 | |
765 } | |
664 return percent | 766 return percent |
665 } | 767 } |
666 | 768 |
667 fun percentGetPos(percent: ProgressBar): Int | 769 fun percentGetPos(percent: ProgressBar): Int |
668 { | 770 { |
669 return percent.progress | 771 var retval: Int = 0 |
772 | |
773 waitOnUiThread { | |
774 retval = percent.progress | |
775 } | |
776 return retval | |
670 } | 777 } |
671 | 778 |
672 fun percentSetPos(percent: ProgressBar, position: Int) | 779 fun percentSetPos(percent: ProgressBar, position: Int) |
673 { | 780 { |
674 percent.progress = position | 781 waitOnUiThread { |
782 percent.progress = position | |
783 } | |
675 } | 784 } |
676 | 785 |
677 fun percentSetRange(percent: ProgressBar, range: Int) | 786 fun percentSetRange(percent: ProgressBar, range: Int) |
678 { | 787 { |
679 percent.max = range | 788 waitOnUiThread { |
789 percent.max = range | |
790 } | |
680 } | 791 } |
681 | 792 |
682 fun htmlNew(cid: Int): WebView? | 793 fun htmlNew(cid: Int): WebView? |
683 { | 794 { |
684 val looper = Looper.myLooper() | 795 var html: WebView? = null |
685 | 796 |
686 // WebView requires an active Looper | 797 waitOnUiThread { |
687 if(looper == null) { | 798 var dataArrayMap = SimpleArrayMap<String, Long>() |
688 Looper.prepare() | 799 |
689 } | 800 html = WebView(this) |
690 | 801 html!!.tag = dataArrayMap |
691 var dataArrayMap = SimpleArrayMap<String, Long>() | 802 html!!.id = cid |
692 val html = WebView(this) | 803 } |
693 | |
694 html.tag = dataArrayMap | |
695 html.id = cid | |
696 return html | 804 return html |
697 } | 805 } |
698 | 806 |
699 fun htmlLoadURL(html: WebView, url: String) | 807 fun htmlLoadURL(html: WebView, url: String) |
700 { | 808 { |
701 html.loadUrl(url) | 809 waitOnUiThread { |
810 html.loadUrl(url) | |
811 } | |
702 } | 812 } |
703 | 813 |
704 fun htmlRaw(html: WebView, data: String) | 814 fun htmlRaw(html: WebView, data: String) |
705 { | 815 { |
706 val encodedHtml: String = Base64.encodeToString(data.toByteArray(), Base64.NO_PADDING) | 816 waitOnUiThread { |
707 html.loadData(encodedHtml, "text/html", "base64") | 817 val encodedHtml: String = Base64.encodeToString(data.toByteArray(), Base64.NO_PADDING) |
818 html.loadData(encodedHtml, "text/html", "base64") | |
819 } | |
708 } | 820 } |
709 | 821 |
710 fun htmlJavascriptRun(html: WebView, javascript: String, data: Long) | 822 fun htmlJavascriptRun(html: WebView, javascript: String, data: Long) |
711 { | 823 { |
712 html.evaluateJavascript(javascript) { value -> | 824 waitOnUiThread { |
713 // Execute onReceiveValue's code | 825 html.evaluateJavascript(javascript) { value -> |
714 eventHandlerHTMLResult(html, 18, value, data) | 826 // Execute onReceiveValue's code |
827 eventHandlerHTMLResult(html, 18, value, data) | |
828 } | |
715 } | 829 } |
716 } | 830 } |
717 | 831 |
718 fun htmlAction(html: WebView, action: Int) | 832 fun htmlAction(html: WebView, action: Int) |
719 { | 833 { |
720 when (action) { | 834 waitOnUiThread { |
721 0 -> html.goBack() | 835 when (action) { |
722 1 -> html.goForward() | 836 0 -> html.goBack() |
723 2 -> html.loadUrl("http://dwindows.netlabs.org") | 837 1 -> html.goForward() |
724 4 -> html.reload() | 838 2 -> html.loadUrl("http://dwindows.netlabs.org") |
725 5 -> html.stopLoading() | 839 4 -> html.reload() |
840 5 -> html.stopLoading() | |
841 } | |
726 } | 842 } |
727 } | 843 } |
728 | 844 |
729 fun timerConnect(interval: Long, sigfunc: Long, data: Long): Timer | 845 fun timerConnect(interval: Long, sigfunc: Long, data: Long): Timer |
730 { | 846 { |
761 Log.d(null, text) | 877 Log.d(null, text) |
762 } | 878 } |
763 | 879 |
764 fun messageBox(title: String, body: String, flags: Int): Int | 880 fun messageBox(title: String, body: String, flags: Int): Int |
765 { | 881 { |
766 // make a text input dialog and show it | |
767 var alert = AlertDialog.Builder(this) | |
768 var retval: Int = 0 | 882 var retval: Int = 0 |
769 | 883 |
770 alert.setTitle(title) | 884 waitOnUiThread { |
771 alert.setMessage(body) | 885 // make a text input dialog and show it |
772 if((flags and (1 shl 3)) != 0) { | 886 var alert = AlertDialog.Builder(this) |
773 alert.setPositiveButton( | 887 |
774 "Yes", | 888 alert.setTitle(title) |
775 DialogInterface.OnClickListener { _: DialogInterface, _: Int -> | 889 alert.setMessage(body) |
776 retval = 1 | 890 if ((flags and (1 shl 3)) != 0) { |
777 throw java.lang.RuntimeException() | 891 alert.setPositiveButton( |
778 }); | 892 "Yes", |
779 } | 893 DialogInterface.OnClickListener { _: DialogInterface, _: Int -> |
780 if((flags and ((1 shl 1) or (1 shl 2))) != 0) { | 894 retval = 1 |
781 alert.setNegativeButton( | 895 throw java.lang.RuntimeException() |
782 "Ok", | 896 }); |
783 DialogInterface.OnClickListener { _: DialogInterface, _: Int -> | 897 } |
784 retval = 0 | 898 if ((flags and ((1 shl 1) or (1 shl 2))) != 0) { |
785 throw java.lang.RuntimeException() | 899 alert.setNegativeButton( |
786 }); | 900 "Ok", |
787 } | 901 DialogInterface.OnClickListener { _: DialogInterface, _: Int -> |
788 if((flags and ((1 shl 3) or (1 shl 4))) != 0) { | 902 retval = 0 |
789 alert.setNegativeButton( | 903 throw java.lang.RuntimeException() |
790 "No", | 904 }); |
791 DialogInterface.OnClickListener { _: DialogInterface, _: Int -> | 905 } |
792 retval = 0 | 906 if ((flags and ((1 shl 3) or (1 shl 4))) != 0) { |
793 throw java.lang.RuntimeException() | 907 alert.setNegativeButton( |
794 }); | 908 "No", |
795 } | 909 DialogInterface.OnClickListener { _: DialogInterface, _: Int -> |
796 if((flags and ((1 shl 2) or (1 shl 4))) != 0) { | 910 retval = 0 |
797 alert.setNeutralButton( | 911 throw java.lang.RuntimeException() |
798 "Cancel", | 912 }); |
799 DialogInterface.OnClickListener { _: DialogInterface, _: Int -> | 913 } |
800 retval = 2 | 914 if ((flags and ((1 shl 2) or (1 shl 4))) != 0) { |
801 throw java.lang.RuntimeException() | 915 alert.setNeutralButton( |
802 }); | 916 "Cancel", |
803 } | 917 DialogInterface.OnClickListener { _: DialogInterface, _: Int -> |
804 alert.show(); | 918 retval = 2 |
805 | 919 throw java.lang.RuntimeException() |
806 // loop till a runtime exception is triggered. | 920 }); |
807 try { | 921 } |
808 Looper.loop() | 922 alert.show(); |
809 } catch (e2: RuntimeException) { | 923 |
924 // loop till a runtime exception is triggered. | |
925 try { | |
926 Looper.loop() | |
927 } catch (e2: RuntimeException) { | |
928 } | |
810 } | 929 } |
811 return retval | 930 return retval |
812 } | 931 } |
813 | 932 |
814 fun dwindowsExit(exitcode: Int) | 933 fun dwindowsExit(exitcode: Int) |
815 { | 934 { |
816 this.finishAffinity() | 935 waitOnUiThread { |
817 System.exit(exitcode) | 936 this.finishAffinity() |
937 System.exit(exitcode) | |
938 } | |
818 } | 939 } |
819 | 940 |
820 fun dwindowsShutdown() | 941 fun dwindowsShutdown() |
821 { | 942 { |
822 this.finishAffinity() | 943 waitOnUiThread { |
944 this.finishAffinity() | |
945 } | |
823 } | 946 } |
824 | 947 |
825 /* | 948 /* |
826 * Native methods that are implemented by the 'dwindows' native library, | 949 * Native methods that are implemented by the 'dwindows' native library, |
827 * which is packaged with this application. | 950 * which is packaged with this application. |