# HG changeset patch # User bsmith@81767d24-ef19-dc11-ae90-00e081727c95 # Date 1619743893 0 # Node ID 666af45f33b5770f91841a62cd3c0858f61abd52 # Parent 83f8f4f58a98ec1db0ccb38690fdd861b94903e1 Android: Implment a bunch of window functions: enable/disable/data/id Add basic structure for the notebook control. diff -r 83f8f4f58a98 -r 666af45f33b5 android/DWindows.kt --- a/android/DWindows.kt Tue Apr 27 09:19:29 2021 +0000 +++ b/android/DWindows.kt Fri Apr 30 00:51:33 2021 +0000 @@ -7,16 +7,45 @@ import android.text.method.PasswordTransformationMethod import android.util.Log import android.view.Gravity +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import android.widget.* import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity +import androidx.collection.SimpleArrayMap +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentActivity +import androidx.fragment.app.FragmentManager +import androidx.fragment.app.FragmentStatePagerAdapter +import androidx.recyclerview.widget.RecyclerView +import androidx.viewpager.widget.ViewPager +import androidx.viewpager2.adapter.FragmentStateAdapter +import androidx.viewpager2.widget.ViewPager2 +import com.google.android.material.tabs.TabLayout +import com.google.android.material.tabs.TabLayoutMediator +class TabViewPagerAdapter : RecyclerView.Adapter() { + val eventList = listOf("0", "1", "2") -class DWindows : AppCompatActivity() -{ - override fun onCreate(savedInstanceState: Bundle?) - { + // Layout "layout_demo_viewpager2_cell.xml" will be defined later + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = + EventViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.dwindows_main, parent, false)) + + override fun getItemCount() = eventList.count() + override fun onBindViewHolder(holder: EventViewHolder, position: Int) { + (holder.view as? TextView)?.also{ + it.text = "Page " + eventList.get(position) + } + } + + class EventViewHolder(val view: View) : RecyclerView.ViewHolder(view) +} + +class DWindows : AppCompatActivity() { + var firstWindow: Boolean = true + + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Turn on rotation @@ -32,23 +61,74 @@ // This will start a new thread that calls the app's dwmain() dwindowsInit(s) } + /* * These are the Android calls to actually create the UI... * forwarded from the C Dynamic Windows API */ - fun windowNew(title: String, style: Int): LinearLayout + fun windowNew(title: String, style: Int): LinearLayout? + { + if(firstWindow) + { + var windowLayout: LinearLayout = LinearLayout(this) + var dataArrayMap = SimpleArrayMap() + + windowLayout.tag = dataArrayMap + 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 + return windowLayout + } + return null + } + + fun windowFromId(window: View, cid: Int): View + { + return window.findViewById(cid) + } + + fun windowSetData(window: View, name: String, data: Long) { - var windowLayout: LinearLayout = LinearLayout(this) - setContentView(windowLayout) - this.title = title - // For now we just return our DWindows' main activity layout... - // in the future, later calls should create new activities - return windowLayout + if(window.tag != null) + { + var dataArrayMap: SimpleArrayMap = window.tag as SimpleArrayMap + + if(data != 0L) { + dataArrayMap.put(name, data) + } + else + { + dataArrayMap.remove(name) + } + } + } + + fun windowGetData(window: View, name: String): Long + { + var retval: Long = 0L + + if (window.tag != null) + { + var dataArrayMap: SimpleArrayMap = window.tag as SimpleArrayMap + + retval = dataArrayMap.get(name)!! + } + return retval + } + + fun windowSetEnabled(window: View, state: Boolean) + { + window.setEnabled(state) } fun boxNew(type: Int, pad: Int): LinearLayout { val box = LinearLayout(this) + var dataArrayMap = SimpleArrayMap() + + box.tag = dataArrayMap box.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT) if (type > 0) { @@ -119,7 +199,7 @@ params.gravity = Gravity.FILL_VERTICAL or grav } item.layoutParams = params - box.addView(item) + box.addView(item, index) } fun boxUnpack(item: View) @@ -131,7 +211,11 @@ fun buttonNew(text: String, cid: Int): Button { val button = Button(this) + var dataArrayMap = SimpleArrayMap() + + button.tag = dataArrayMap button.text = text + button.id = cid button.setOnClickListener { eventHandlerSimple(button, 8) } @@ -141,6 +225,10 @@ fun entryfieldNew(text: String, cid: Int, password: Int): EditText { val entryfield = EditText(this) + var dataArrayMap = SimpleArrayMap() + + entryfield.tag = dataArrayMap + entryfield.id = cid if(password > 0) { entryfield.transformationMethod = PasswordTransformationMethod.getInstance() } @@ -151,6 +239,10 @@ fun radioButtonNew(text: String, cid: Int): RadioButton { val radiobutton = RadioButton(this) + var dataArrayMap = SimpleArrayMap() + + radiobutton.tag = dataArrayMap + radiobutton.id = cid radiobutton.text = text radiobutton.setOnClickListener { eventHandlerSimple(radiobutton, 8) @@ -161,6 +253,10 @@ fun checkboxNew(text: String, cid: Int): CheckBox { val checkbox = CheckBox(this) + var dataArrayMap = SimpleArrayMap() + + checkbox.tag = dataArrayMap + checkbox.id = cid checkbox.text = text checkbox.setOnClickListener { eventHandlerSimple(checkbox, 8) @@ -171,10 +267,36 @@ fun textNew(text: String, cid: Int, status: Int): TextView { val textview = TextView(this) + var dataArrayMap = SimpleArrayMap() + + textview.tag = dataArrayMap + textview.id = cid textview.text = text return textview } + fun notebookNew(cid: Int, top: Int) + { + val notebook = RelativeLayout(this) + val pager = ViewPager2(this) + val tabs = TabLayout(this) + var w: Int = RelativeLayout.LayoutParams.MATCH_PARENT + var h: Int = RelativeLayout.LayoutParams.WRAP_CONTENT + var dataArrayMap = SimpleArrayMap() + + notebook.tag = dataArrayMap + notebook.id = cid + pager.adapter = TabViewPagerAdapter() + TabLayoutMediator(tabs, pager) { tab, position -> + tab.text = "OBJECT ${(position + 1)}" + }.attach() + + var params: RelativeLayout.LayoutParams = RelativeLayout.LayoutParams(w, h) + tabs.layoutParams = params + notebook.addView(tabs) + notebook.addView(pager) + } + fun debugMessage(text: String) { Log.d(null, text) diff -r 83f8f4f58a98 -r 666af45f33b5 android/dw.cpp --- a/android/dw.cpp Tue Apr 27 09:19:29 2021 +0000 +++ b/android/dw.cpp Fri Apr 30 00:51:33 2021 +0000 @@ -901,7 +901,7 @@ /* 65536 is the table limit on GTK... * seems like a high enough value we will never hit it here either. */ - _dw_box_pack(box, item, 65536, width, height, hsize, vsize, pad, "dw_box_pack_start()"); + _dw_box_pack(box, item, -1, width, height, hsize, vsize, pad, "dw_box_pack_start()"); } /* @@ -3140,6 +3140,22 @@ { } +void _dw_window_set_enabled(HWND handle, jboolean state) +{ + JNIEnv *env; + + if((env = (JNIEnv *)pthread_getspecific(_dw_env_key))) + { + // First get the class that contains the method you need to call + jclass clazz = _dw_find_class(env, DW_CLASS_NAME); + // Get the method that you want to call + jmethodID windowSetEnabled = env->GetMethodID(clazz, "windowSetEnabled", + "(Landroid/view/View;Z)V"); + // Call the method on the object + env->CallVoidMethod(_dw_obj, windowSetEnabled, handle, state); + } +} + /* * Disables given window (widget). * Parameters: @@ -3147,6 +3163,7 @@ */ void API dw_window_disable(HWND handle) { + _dw_window_set_enabled(handle, JNI_FALSE); } /* @@ -3156,6 +3173,7 @@ */ void API dw_window_enable(HWND handle) { + _dw_window_set_enabled(handle, JNI_TRUE); } /* @@ -3207,7 +3225,20 @@ */ HWND API dw_window_from_id(HWND handle, int id) { - return 0; + JNIEnv *env; + HWND retval = 0; + + if((env = (JNIEnv *)pthread_getspecific(_dw_env_key))) + { + // First get the class that contains the method you need to call + jclass clazz = _dw_find_class(env, DW_CLASS_NAME); + // Get the method that you want to call + jmethodID windowFromId = env->GetMethodID(clazz, "windowFromId", + "(Landroid/view/View;I)Landroid/view/View;"); + // Call the method on the object + retval = env->CallObjectMethod(_dw_obj, windowFromId, handle, id); + } + return retval; } /* @@ -3394,6 +3425,20 @@ */ void API dw_window_set_data(HWND window, const char *dataname, void *data) { + JNIEnv *env; + + if((env = (JNIEnv *)pthread_getspecific(_dw_env_key))) + { + // Construct a String + jstring jstr = env->NewStringUTF(dataname); + // First get the class that contains the method you need to call + jclass clazz = _dw_find_class(env, DW_CLASS_NAME); + // Get the method that you want to call + jmethodID windowSetData = env->GetMethodID(clazz, "windowSetData", + "(Landroid/view/View;Ljava/lang/String;J)V"); + // Call the method on the object + env->CallVoidMethod(_dw_obj, windowSetData, window, jstr); + } } /* @@ -3406,7 +3451,22 @@ */ void * API dw_window_get_data(HWND window, const char *dataname) { - return NULL; + JNIEnv *env; + void *retval = NULL; + + if((env = (JNIEnv *)pthread_getspecific(_dw_env_key))) + { + // Construct a String + jstring jstr = env->NewStringUTF(dataname); + // First get the class that contains the method you need to call + jclass clazz = _dw_find_class(env, DW_CLASS_NAME); + // Get the method that you want to call + jmethodID windowGetData = env->GetMethodID(clazz, "windowGetData", + "(Landroid/view/View;Ljava/lang/String;)J"); + // Call the method on the object + retval = DW_INT_TO_POINTER(env->CallLongMethod(_dw_obj, windowGetData, window, jstr)); + } + return retval; } /*