# HG changeset patch # User bsmith@81767d24-ef19-dc11-ae90-00e081727c95 # Date 1634079853 0 # Node ID aca4b56f50dd82f035ec5247ce547a5712bdd48e # Parent b0712a3debe273bf6264b21ac92b655493a26ddf Android: Attempt at multi-window support using ViewPager2. I tried initially with FragmentContainerView but ran into issues. Seems to be having issues with nested ViewPager2s used in the notebooks. Still needs a lot o work but the core is there now. diff -r b0712a3debe2 -r aca4b56f50dd android/DWindows.kt --- a/android/DWindows.kt Tue Oct 05 06:26:28 2021 +0000 +++ b/android/DWindows.kt Tue Oct 12 23:04:13 2021 +0000 @@ -768,8 +768,7 @@ } class DWindows : AppCompatActivity() { - var firstWindow: Boolean = true - var windowLayout: LinearLayout? = null + var windowLayout: ViewPager2? = null var threadLock = ReentrantLock() var threadCond = threadLock.newCondition() var notificationID: Int = 0 @@ -778,10 +777,14 @@ private var paint = Paint() private var bgcolor: Int? = null private var menuBar: DWMenu? = null - private var defaultItem: View? = null private var fileURI: Uri? = null private var fileLock = ReentrantLock() private var fileCond = threadLock.newCondition() + // Lists of data for our Windows + private var windowTitles = mutableListOf() + private var windowMenuBars = mutableListOf() + private var windowStyles = mutableListOf() + private var windowDefault = mutableListOf() // Our version of runOnUiThread that waits for execution fun waitOnUiThread(runnable: Runnable) @@ -880,6 +883,17 @@ // other Dynamic Windows platforms extractAssets() + // Setup our ViewPager2 as our activty window container + windowLayout = ViewPager2(this) + windowLayout!!.id = View.generateViewId() + windowLayout!!.adapter = DWTabViewPagerAdapter() + windowLayout!!.isUserInputEnabled = false + windowLayout!!.layoutParams = + ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT + ) + // Initialize the Dynamic Windows code... // This will start a new thread that calls the app's dwmain() dwindowsInit(s, c, this.getPackageName()) @@ -898,8 +912,10 @@ if(windowLayout != null) { val width: Int = windowLayout!!.width val height: Int = windowLayout!!.height - - eventHandlerInt(windowLayout as View, DWEvent.CONFIGURE, width, height, 0, 0) + val adapter: DWTabViewPagerAdapter = windowLayout!!.adapter as DWTabViewPagerAdapter + val window = adapter.viewList[windowLayout!!.currentItem] + + eventHandlerInt(window, DWEvent.CONFIGURE, width, height, 0, 0) } } @@ -1046,22 +1062,40 @@ } fun windowNew(title: String, style: Int): LinearLayout? { - if (firstWindow) { + var window: LinearLayout? = null + + if(windowLayout != null) { waitOnUiThread { val dataArrayMap = SimpleArrayMap() - windowLayout = LinearLayout(this) - - windowLayout!!.visibility = View.GONE - windowLayout!!.tag = dataArrayMap + val adapter: DWTabViewPagerAdapter = windowLayout!!.adapter as DWTabViewPagerAdapter + setContentView(windowLayout) - this.title = title - // For now we just return our DWindows' main activity layout... - // in the future, later calls should create new activities - firstWindow = false + + window = LinearLayout(this) + window!!.visibility = View.GONE + window!!.tag = dataArrayMap + window!!.layoutParams = + LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, + LinearLayout.LayoutParams.MATCH_PARENT + ) + + // Update our window list + adapter.viewList.add(window!!) + windowTitles.add(title) + windowMenuBars.add(null) + windowStyles.add(style) + windowDefault.add(null) + + // If this is our first/only window... + // We can set stuff immediately + if (adapter.viewList.count() == 1) { + this.title = title + windowLayout!!.setCurrentItem(0, false) + } } - return windowLayout } - return null + return window } fun windowSetFocus(window: View) @@ -1073,22 +1107,27 @@ fun windowDefault(window: View, default: View) { - // TODO: Verify this is the correct activity... - defaultItem = default + if(windowLayout != null) { + val adapter: DWTabViewPagerAdapter = windowLayout!!.adapter as DWTabViewPagerAdapter + val index = adapter.viewList.indexOf(window) + + if (index != -1) { + windowDefault[index] = default + } + } } fun windowSetStyle(window: View, style: Int, mask: Int) { waitOnUiThread { if (window is TextView && window !is EditText) { - val text = window val ourmask = (Gravity.HORIZONTAL_GRAVITY_MASK or Gravity.VERTICAL_GRAVITY_MASK) and mask if (ourmask != 0) { // Gravity with the masked parts zeroed out val newgravity = style and ourmask - text.gravity = newgravity + window.gravity = newgravity } } } @@ -1264,16 +1303,25 @@ } fun windowSetText(window: View, text: String) { - waitOnUiThread { - if (window is TextView) { - val textview: TextView = window - textview.text = text - } else if (window is Button) { - val button: Button = window - button.text = text - } else if (window is LinearLayout) { - // TODO: Make sure this is actually the top-level layout, not just a box - this.title = text + if(windowLayout != null) { + waitOnUiThread { + if (window is TextView) { + val textview: TextView = window + textview.text = text + } else if (window is Button) { + val button: Button = window + button.text = text + } else if (window is LinearLayout) { + val adapter: DWTabViewPagerAdapter = windowLayout!!.adapter as DWTabViewPagerAdapter + val index = adapter.viewList.indexOf(window) + + if(index != -1) { + windowTitles[index] = text + if(index == windowLayout!!.currentItem) { + this.title = text + } + } + } } } } @@ -1281,16 +1329,22 @@ fun windowGetText(window: View): String? { var text: String? = null - waitOnUiThread { - if (window is TextView) { - val textview: TextView = window - text = textview.text.toString() - } else if (window is Button) { - val button: Button = window - text = button.text.toString() - } else if (window is LinearLayout) { - // TODO: Make sure this is actually the top-level layout, not just a box - text = this.title.toString() + if(windowLayout != null) { + waitOnUiThread { + if (window is TextView) { + val textview: TextView = window + text = textview.text.toString() + } else if (window is Button) { + val button: Button = window + text = button.text.toString() + } else if (window is LinearLayout) { + val adapter: DWTabViewPagerAdapter = windowLayout!!.adapter as DWTabViewPagerAdapter + val index = adapter.viewList.indexOf(window) + + if(index != -1) { + text = windowTitles[index] + } + } } } return text @@ -1298,12 +1352,26 @@ fun windowHideShow(window: View, state: Int) { - waitOnUiThread { - if(state == 0) { - window.visibility = View.GONE - } else { - window.visibility = View.VISIBLE - defaultItem?.requestFocus() + if(windowLayout != null) { + waitOnUiThread { + val adapter: DWTabViewPagerAdapter = windowLayout!!.adapter as DWTabViewPagerAdapter + val index = adapter.viewList.indexOf(window) + var defaultItem: View? = null + + if(state == 0) { + window.visibility = View.GONE + } else { + window.visibility = View.VISIBLE + } + if (index != -1) { + defaultItem = windowDefault[index] + if(state != 0) { + windowLayout!!.setCurrentItem(index, true) + } + } + if(state != 0 && defaultItem != null) { + defaultItem.requestFocus() + } } } }