feat(layout-inflater): provide optional child view to IViewGroup.canAcceptChild

This commit is contained in:
Akash Yadav
2023-05-27 19:50:26 +05:30
parent 79cbcda75a
commit 2cd7bb9c9c
6 changed files with 68 additions and 29 deletions
@@ -56,7 +56,7 @@ internal class WidgetDragListener(
return event.clipDescription.hasMimeType(DRAGGING_WIDGET_MIME) &&
event.localState != view &&
view.canAcceptChild(name)
view.canAcceptChild(name, event.localState as? IView?)
}
DragEvent.ACTION_DRAG_ENTERED,
DragEvent.ACTION_DRAG_LOCATION -> {
@@ -48,11 +48,25 @@ interface IViewGroup : IView, Iterable<IView> {
* @param name The fully qualified name of the [View][android.view.View] instance.
* @return `true` if this view group can accept the child view, `false` otherwise. The default
* implementation returns `true` if and only if [canModifyChildViews] returns `true` and this
* view's [IViewAdapter.canAcceptChild] returns `true`.
* view's [IViewGroupAdapter.canAcceptChild] returns `true`.
*/
fun canAcceptChild(name: String): Boolean {
return canAcceptChild(name, null)
}
/**
* Called to check whether this view group can accept child view with the given fully qualifed
* name.
*
* @param name The fully qualified name of the [View][android.view.View] instance.
* @param child The child view which should be checked.
* @return `true` if this view group can accept the child view, `false` otherwise. The default
* implementation returns `true` if and only if [canModifyChildViews] returns `true` and this
* view's [IViewGroupAdapter.canAcceptChild] returns `true`.
*/
fun canAcceptChild(name: String, child: IView?): Boolean {
return canModifyChildViews() && (this.viewAdapter as? IViewGroupAdapter)?.canAcceptChild(
this, name) == true
this, child, name) == true
}
/**
@@ -50,8 +50,23 @@ interface IViewGroupAdapter {
/**
* Called by the UI Designer to check if the given view group (which this adpater handles) can
* accept the child view with the given qualified name.
*
* @param view The parent in which the child will be added.
* @param name The fully qualified name of the child view.
*/
fun canAcceptChild(view: IViewGroup, name: String): Boolean {
return canAcceptChild(view, null, name)
}
/**
* Called by the UI Designer to check if the given view group (which this adpater handles) can
* accept the child view with the given qualified name.
*
* @param view The parent in which the child will be added.
* @param child The child view which will be added. May be `null`.
* @param name The fully qualified name of the child view.
*/
fun canAcceptChild(view: IViewGroup, child: IView?, name: String): Boolean {
return true
}
}
@@ -21,35 +21,37 @@ import android.widget.HorizontalScrollView
import com.itsaky.androidide.annotations.uidesigner.IncludeInDesigner
import com.itsaky.androidide.annotations.uidesigner.IncludeInDesigner.Group.LAYOUTS
import com.itsaky.androidide.inflater.AttributeHandlerScope
import com.itsaky.androidide.inflater.IView
import com.itsaky.androidide.inflater.IViewGroup
import com.itsaky.androidide.resources.R
import com.itsaky.androidide.inflater.models.UiWidget
import com.itsaky.androidide.resources.R
/**
* View adapter for [HorizontalScrollView].
*
* @author Akash Yadav
*/
@com.itsaky.androidide.annotations.inflater.ViewAdapter(HorizontalScrollView::class)
@com.itsaky.androidide.annotations.inflater.ViewAdapter(
HorizontalScrollView::class)
@IncludeInDesigner(group = LAYOUTS)
open class HorizontalScrollViewAdapter<T : HorizontalScrollView> : FrameLayoutAdapter<T>() {
open class HorizontalScrollViewAdapter<T : HorizontalScrollView> :
FrameLayoutAdapter<T>() {
override fun createAttrHandlers(create: (String, AttributeHandlerScope<T>.() -> Unit) -> Unit) {
override fun createAttrHandlers(
create: (String, AttributeHandlerScope<T>.() -> Unit) -> Unit
) {
super.createAttrHandlers(create)
create("fillViewPort") { view.isFillViewport = parseBoolean(value, false) }
}
override fun createUiWidgets(): List<UiWidget> {
return listOf(
UiWidget(
HorizontalScrollView::class.java,
R.string.widget_horizontal_scrollview,
R.drawable.ic_widget_horizontal_scroll_view
)
)
return listOf(UiWidget(HorizontalScrollView::class.java,
R.string.widget_horizontal_scrollview,
R.drawable.ic_widget_horizontal_scroll_view))
}
override fun canAcceptChild(view: IViewGroup, name: String): Boolean {
override fun canAcceptChild(view: IViewGroup, child: IView?, name: String
): Boolean {
// scrollview can have only one child
return view.childCount == 0
}
@@ -22,32 +22,36 @@ import android.widget.RadioGroup
import com.itsaky.androidide.annotations.uidesigner.IncludeInDesigner
import com.itsaky.androidide.annotations.uidesigner.IncludeInDesigner.Group.LAYOUTS
import com.itsaky.androidide.inflater.AttributeHandlerScope
import com.itsaky.androidide.inflater.IView
import com.itsaky.androidide.inflater.IViewGroup
import com.itsaky.androidide.inflater.models.UiWidget
import com.itsaky.androidide.resources.R.drawable
import com.itsaky.androidide.resources.R.string
import com.itsaky.androidide.inflater.models.UiWidget
/**
* View adapter for [RadioGroup].
*
* @author Akash Yadav
*/
@com.itsaky.androidide.annotations.inflater.ViewAdapter(forView = RadioGroup::class)
@com.itsaky.androidide.annotations.inflater.ViewAdapter(
forView = RadioGroup::class)
@IncludeInDesigner(group = LAYOUTS)
open class RadioGroupAdapter<T : RadioGroup> : LinearLayoutAdapter<T>() {
override fun createAttrHandlers(create: (String, AttributeHandlerScope<T>.() -> Unit) -> Unit) {
override fun createAttrHandlers(
create: (String, AttributeHandlerScope<T>.() -> Unit) -> Unit
) {
super.createAttrHandlers(create)
create("checkedButton") { view.check(parseId(file.resName, value, -1)) }
}
override fun createUiWidgets(): List<UiWidget> {
return listOf(
UiWidget(RadioGroup::class.java, string.widget_radio_group, drawable.ic_widget_radio_group)
)
return listOf(UiWidget(RadioGroup::class.java, string.widget_radio_group,
drawable.ic_widget_radio_group))
}
override fun canAcceptChild(view: IViewGroup, name: String): Boolean {
override fun canAcceptChild(view: IViewGroup, child: IView?, name: String
): Boolean {
return name == RadioButton::class.java.name
}
}
@@ -21,31 +21,35 @@ import android.widget.ScrollView
import com.itsaky.androidide.annotations.uidesigner.IncludeInDesigner
import com.itsaky.androidide.annotations.uidesigner.IncludeInDesigner.Group.LAYOUTS
import com.itsaky.androidide.inflater.AttributeHandlerScope
import com.itsaky.androidide.inflater.IView
import com.itsaky.androidide.inflater.IViewGroup
import com.itsaky.androidide.resources.R
import com.itsaky.androidide.inflater.models.UiWidget
import com.itsaky.androidide.resources.R
/**
* View adapter for [ScrollView].
*
* @author Akash Yadav
*/
@com.itsaky.androidide.annotations.inflater.ViewAdapter(forView = ScrollView::class)
@com.itsaky.androidide.annotations.inflater.ViewAdapter(
forView = ScrollView::class)
@IncludeInDesigner(group = LAYOUTS)
open class ScrollViewAdapter<T : ScrollView> : FrameLayoutAdapter<T>() {
override fun createAttrHandlers(create: (String, AttributeHandlerScope<T>.() -> Unit) -> Unit) {
override fun createAttrHandlers(
create: (String, AttributeHandlerScope<T>.() -> Unit) -> Unit
) {
super.createAttrHandlers(create)
create("fillViewPort") { view.isFillViewport = parseBoolean(value, false) }
}
override fun createUiWidgets(): List<UiWidget> {
return listOf(
UiWidget(ScrollView::class.java, R.string.widget_scrollview, R.drawable.ic_widget_scroll_view)
)
return listOf(UiWidget(ScrollView::class.java, R.string.widget_scrollview,
R.drawable.ic_widget_scroll_view))
}
override fun canAcceptChild(view: IViewGroup, name: String): Boolean {
override fun canAcceptChild(view: IViewGroup, child: IView?, name: String
): Boolean {
// scrollview can have only one child
return view.childCount == 0
}