implement UiWidget.createView()

This commit is contained in:
Akash Yadav
2022-11-25 14:12:38 +05:30
parent c2c21c5b94
commit 775d9a24ac
7 changed files with 116 additions and 16 deletions
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 34 KiB

@@ -0,0 +1,30 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.uidesigner.drag
import android.view.DragEvent
import android.view.View
/**
* @author Akash Yadav
*/
class WidgetDragListener : View.OnDragListener {
override fun onDrag(v: View, event: DragEvent): Boolean {
TODO("Not yet implemented")
}
}
@@ -27,7 +27,6 @@ import com.itsaky.androidide.fragments.BaseFragment
import com.itsaky.androidide.inflater.IInflateEventsListener import com.itsaky.androidide.inflater.IInflateEventsListener
import com.itsaky.androidide.inflater.ILayoutInflater import com.itsaky.androidide.inflater.ILayoutInflater
import com.itsaky.androidide.inflater.OnInflateViewEvent import com.itsaky.androidide.inflater.OnInflateViewEvent
import com.itsaky.androidide.inflater.internal.utils.startParse
import com.itsaky.androidide.uidesigner.UIDesignerActivity import com.itsaky.androidide.uidesigner.UIDesignerActivity
import com.itsaky.androidide.uidesigner.databinding.FragmentDesignerWorkspaceBinding import com.itsaky.androidide.uidesigner.databinding.FragmentDesignerWorkspaceBinding
import com.itsaky.androidide.uidesigner.databinding.LayoutDesignerErrorBinding import com.itsaky.androidide.uidesigner.databinding.LayoutDesignerErrorBinding
@@ -94,11 +93,7 @@ class DesignerWorkspaceFragment : BaseFragment() {
super.onDestroyView() super.onDestroyView()
this.binding = null this.binding = null
} }
private fun createErrorView(@StringRes message: Int): View {
return createErrorView(getString(message))
}
private fun createErrorView(message: String): View { private fun createErrorView(message: String): View {
return LayoutDesignerErrorBinding.inflate(layoutInflater).let { return LayoutDesignerErrorBinding.inflate(layoutInflater).let {
it.root.text = message it.root.text = message
@@ -17,10 +17,16 @@
package com.itsaky.androidide.uidesigner.models package com.itsaky.androidide.uidesigner.models
import android.content.Context
import android.view.View import android.view.View
import android.view.ViewGroup
import androidx.annotation.DrawableRes import androidx.annotation.DrawableRes
import androidx.annotation.StringRes import androidx.annotation.StringRes
import com.itsaky.androidide.inflater.IView import com.itsaky.androidide.inflater.IView
import com.itsaky.androidide.inflater.internal.LayoutFile
import com.itsaky.androidide.inflater.internal.ViewGroupImpl
import com.itsaky.androidide.inflater.internal.ViewImpl
import com.itsaky.androidide.inflater.internal.utils.ViewFactory
open class UiWidget(val name: String, @StringRes val label: Int, @DrawableRes val icon: Int) { open class UiWidget(val name: String, @StringRes val label: Int, @DrawableRes val icon: Int) {
constructor( constructor(
@@ -29,8 +35,18 @@ open class UiWidget(val name: String, @StringRes val label: Int, @DrawableRes va
@DrawableRes icon: Int @DrawableRes icon: Int
) : this(klass.name, label, icon) ) : this(klass.name, label, icon)
fun createView(): IView { /**
TODO() * Creates an [IView] for this widget.
*
* @param context The context that will be used for creating (View)[android.view.View] instance.
* @param layoutFile The layout file that is being edited.
*/
fun createView(context: Context, layoutFile: LayoutFile): IView {
val v = ViewFactory.createViewInstance(name, context)
if (v is ViewGroup) {
return ViewGroupImpl(layoutFile, name, v)
}
return ViewImpl(layoutFile, name, v)
} }
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
@@ -0,0 +1,27 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.uidesigner.utils
import com.itsaky.androidide.inflater.IViewGroup
/**
* An [IViewGroup] implementation that forwards all calls to [src].
*
* @author Akash Yadav
*/
class ForwardingViewGroup(val src: IViewGroup) : IViewGroup by src
@@ -17,7 +17,6 @@
package com.itsaky.androidide.inflater.internal package com.itsaky.androidide.inflater.internal
import android.content.Context
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams import android.view.ViewGroup.LayoutParams
@@ -45,6 +44,7 @@ import com.itsaky.androidide.inflater.InflationStartEvent
import com.itsaky.androidide.inflater.OnApplyAttributeEvent import com.itsaky.androidide.inflater.OnApplyAttributeEvent
import com.itsaky.androidide.inflater.OnInflateViewEvent import com.itsaky.androidide.inflater.OnInflateViewEvent
import com.itsaky.androidide.inflater.internal.utils.IDTable import com.itsaky.androidide.inflater.internal.utils.IDTable
import com.itsaky.androidide.inflater.internal.utils.ViewFactory.createViewInstance
import com.itsaky.androidide.inflater.internal.utils.endParse import com.itsaky.androidide.inflater.internal.utils.endParse
import com.itsaky.androidide.inflater.internal.utils.isParsing import com.itsaky.androidide.inflater.internal.utils.isParsing
import com.itsaky.androidide.inflater.internal.utils.parseLayoutReference import com.itsaky.androidide.inflater.internal.utils.parseLayoutReference
@@ -282,7 +282,7 @@ open class LayoutInflaterImpl : ILayoutInflater() {
widgets: WidgetTable, widgets: WidgetTable,
): IView { ): IView {
return try { return try {
val v = createViewInstance(widget, parent) val v = createViewInstance(widget.qualifiedName, parent.context)
if (v is ViewGroup) { if (v is ViewGroup) {
return ViewGroupImpl(currentLayoutFile, widget.qualifiedName, v) return ViewGroupImpl(currentLayoutFile, widget.qualifiedName, v)
} }
@@ -351,12 +351,6 @@ open class LayoutInflaterImpl : ILayoutInflater() {
return processor to module return processor to module
} }
private fun createViewInstance(widget: Widget, parent: ViewGroup): View {
val klass = javaClass.classLoader!!.loadClass(widget.qualifiedName)
val constructor = klass.getConstructor(Context::class.java)
return constructor.newInstance(parent.context) as View
}
private fun onCreateUnsupportedView(message: String, parent: ViewGroup): IView { private fun onCreateUnsupportedView(message: String, parent: ViewGroup): IView {
return ErrorView(currentLayoutFile, parent.context, message) return ErrorView(currentLayoutFile, parent.context, message)
} }
@@ -0,0 +1,38 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.inflater.internal.utils
import android.content.Context
import android.view.View
import com.itsaky.androidide.utils.ILogger
/** @author Akash Yadav */
object ViewFactory {
private val log = ILogger.newInstance("ViewFactory")
fun createViewInstance(name: String, context: Context): View {
return try {
val klass = javaClass.classLoader!!.loadClass(name)
val constructor = klass.getConstructor(Context::class.java)
constructor.newInstance(context) as View
} catch (err: Throwable) {
log.error(err)
throw RuntimeException(err)
}
}
}