diff --git a/hikage-compiler/src/main/java/com/highcapable/hikage/compiler/subprocessor/HikageViewGenerator.kt b/hikage-compiler/src/main/java/com/highcapable/hikage/compiler/subprocessor/HikageViewGenerator.kt index ce8ef12..c466c7c 100644 --- a/hikage-compiler/src/main/java/com/highcapable/hikage/compiler/subprocessor/HikageViewGenerator.kt +++ b/hikage-compiler/src/main/java/com/highcapable/hikage/compiler/subprocessor/HikageViewGenerator.kt @@ -206,7 +206,8 @@ class HikageViewGenerator(override val environment: SymbolProcessorEnvironment) addParameter( ParameterSpec.builder( name = "init", - ViewLambdaClass.parameterizedBy(viewClass.second) + type = ViewLambdaClass.parameterizedBy(viewClass.second), + modifiers = listOf(KModifier.NOINLINE) ).apply { if (!performer.annotation.requireInit) defaultValue("{}") }.build() @@ -215,7 +216,8 @@ class HikageViewGenerator(override val environment: SymbolProcessorEnvironment) addParameter( ParameterSpec.builder( name = "performer", - PerformerLambdaClass.parameterizedBy(it) + type = PerformerLambdaClass.parameterizedBy(it), + modifiers = listOf(KModifier.NOINLINE) ).apply { if (!performer.annotation.requirePerformer) defaultValue("{}") }.build() diff --git a/hikage-core/src/main/java/com/highcapable/hikage/core/Hikage.kt b/hikage-core/src/main/java/com/highcapable/hikage/core/Hikage.kt index 7a054e5..e3b1999 100644 --- a/hikage-core/src/main/java/com/highcapable/hikage/core/Hikage.kt +++ b/hikage-core/src/main/java/com/highcapable/hikage/core/Hikage.kt @@ -19,10 +19,7 @@ * * This file is created by fankes on 2025/2/25. */ -@file:Suppress( - "unused", "FunctionName", "PropertyName", "ConstPropertyName", "UNCHECKED_CAST", - "MemberVisibilityCanBePrivate", "TOPLEVEL_TYPEALIASES_ONLY", "NON_PUBLIC_CALL_FROM_PUBLIC_INLINE" -) +@file:Suppress("unused", "FunctionName", "PropertyName", "ConstPropertyName", "UNCHECKED_CAST", "MemberVisibilityCanBePrivate") package com.highcapable.hikage.core @@ -40,6 +37,7 @@ import androidx.annotation.StringRes import androidx.core.graphics.drawable.toBitmap import androidx.viewbinding.ViewBinding import com.highcapable.betterandroid.ui.extension.binding.ViewBinding +import com.highcapable.betterandroid.ui.extension.binding.ViewBindingBuilder import com.highcapable.betterandroid.ui.extension.component.base.DisplayDensity import com.highcapable.betterandroid.ui.extension.component.base.getColorCompat import com.highcapable.betterandroid.ui.extension.component.base.getColorStateListCompat @@ -57,6 +55,7 @@ import com.highcapable.hikage.core.base.HikageFactory import com.highcapable.hikage.core.base.HikageFactoryBuilder import com.highcapable.hikage.core.base.HikagePerformer import com.highcapable.hikage.core.base.HikageView +import com.highcapable.hikage.core.base.LayoutParamsBody import com.highcapable.hikage.core.base.PerformerException import com.highcapable.hikage.core.base.ProvideException import com.highcapable.hikage.core.extension.ResourcesScope @@ -119,8 +118,8 @@ class Hikage private constructor(private val factories: List) { context: Context, parent: ViewGroup? = null, attachToParent: Boolean = parent != null, - factory: HikageFactoryBuilder.() -> Unit = {}, - performer: HikagePerformer + noinline factory: HikageFactoryBuilder.() -> Unit = {}, + noinline performer: HikagePerformer ) = create(classOf(), context, parent, attachToParent, factory, performer) /** @@ -132,7 +131,7 @@ class Hikage private constructor(private val factories: List) { * @param performer the performer body. * @return [Hikage] */ - inline fun create( + fun create( context: Context, parent: ViewGroup? = null, attachToParent: Boolean = parent != null, @@ -150,7 +149,7 @@ class Hikage private constructor(private val factories: List) { * @param performer the performer body. * @return [Hikage] */ - inline fun create( + fun create( lpClass: Class, context: Context, parent: ViewGroup? = null, @@ -208,9 +207,6 @@ class Hikage private constructor(private val factories: List) { ) = Delegate(lpClass, factory, performer) } - /** The [Hikage] layout params body type. */ - private typealias LayoutParamsBody = LP.() -> Unit - /** * The [Hikage.Performer] scope interface. */ @@ -434,19 +430,6 @@ class Hikage private constructor(private val factories: List) { */ private fun createAttributeSet(context: Context): AttributeSet = XmlBlockBypass.newParser(context) - /** - * Start a new performer [LP]. - * @param parent the parent view group. - * @param attachToParent whether to attach the layout to the parent when the [parent] is filled. - * @param context the context, priority is given to [parent]'s context. - * @return [Performer] - */ - private inline fun newPerformer( - parent: ViewGroup? = null, - attachToParent: Boolean = parent != null, - context: Context? = null - ) = newPerformer(classOf(), parent, attachToParent, context) - /** * Start a new performer [LP]. * @param lpClass the layout params type. @@ -548,6 +531,32 @@ class Hikage private constructor(private val factories: List) { /** The count of providing views. */ private var provideCount = 0 + /** + * Provide a new [View] instance [V]. + * @param viewClass the view class. + * @param lparams the view layout params. + * @param id the view id, generated by default. + * @param init the view initialization body. + * @return [V] + */ + @Hikageable + fun View( + viewClass: Class, + lparams: LayoutParams? = null, + id: String? = null, + init: HikageView = {} + ): V { + val lpDelegate = LayoutParams.from(current, lpClass, parent, lparams) + val view = createView(viewClass, id, context) + view.layoutParams = lpDelegate.create() + + requireNoPerformers(viewClass.name) { view.init() } + startProvide(id, viewClass) + addToParentIfRequired(view) + + return view + } + /** * Provide a new [View] instance [V]. * @param lparams the view layout params. @@ -560,18 +569,8 @@ class Hikage private constructor(private val factories: List) { inline fun View( lparams: LayoutParams? = null, id: String? = null, - init: HikageView = {} - ): V { - val lpDelegate = LayoutParams.from(current, lpClass, parent, lparams) - val view = createView(classOf(), id, context) - view.layoutParams = lpDelegate.create() - - requireNoPerformers(classOf().name) { view.init() } - startProvide(id, classOf()) - addToParentIfRequired(view) - - return view - } + noinline init: HikageView = {} + ) = View(classOf(), lparams, id, init) /** * Provide a new [View] instance. @@ -581,12 +580,67 @@ class Hikage private constructor(private val factories: List) { * @return [View] */ @Hikageable - inline fun View( + fun View( lparams: LayoutParams? = null, id: String? = null, init: HikageView = {} ) = View(lparams, id, init) + /** + * Provide a new [ViewGroup] instance [VG]. + * + * Provide the new type of [ViewGroup.LayoutParams] down via [LP]. + * + * - Note: The [VG] must be inherited from [ViewGroup]. + * @param viewClass the view class. + * @param lpClass the layout params class. + * @param lparams the view layout params. + * @param id the view id, generated by default. + * @param init the view initialization body. + * @param performer the performer body. + * @return [VG] + */ + @Hikageable + fun ViewGroup( + viewClass: Class, + lpClass: Class, + lparams: LayoutParams? = null, + id: String? = null, + init: HikageView = {}, + performer: HikagePerformer = {} + ): VG { + val lpDelegate = LayoutParams.from(current, lpClass, parent, lparams) + val view = createView(viewClass, id, context) + view.layoutParams = lpDelegate.create() + + requireNoPerformers(viewClass.name) { view.init() } + startProvide(id, viewClass) + addToParentIfRequired(view) + newPerformer(lpClass, view).apply(performer) + + return view + } + + /** + * Provide a new [ViewGroup] instance [VG]. + * + * - Note: The [VG] must be inherited from [ViewGroup]. + * @param viewClass the view class. + * @param lparams the view layout params. + * @param id the view id, generated by default. + * @param init the view initialization body. + * @param performer the performer body. + * @return [VG] + */ + @Hikageable + fun ViewGroup( + viewClass: Class, + lparams: LayoutParams? = null, + id: String? = null, + init: HikageView = {}, + performer: HikagePerformer = {} + ) = ViewGroup(viewClass, classOf(), lparams, id, init, performer) + /** * Provide a new [ViewGroup] instance [VG]. * @@ -604,20 +658,9 @@ class Hikage private constructor(private val factories: List) { inline fun ViewGroup( lparams: LayoutParams? = null, id: String? = null, - init: HikageView = {}, - performer: HikagePerformer = {} - ): VG { - val lpDelegate = LayoutParams.from(current, lpClass, parent, lparams) - val view = createView(classOf(), id, context) - view.layoutParams = lpDelegate.create() - - requireNoPerformers(classOf().name) { view.init() } - startProvide(id, classOf()) - addToParentIfRequired(view) - newPerformer(view).apply(performer) - - return view - } + noinline init: HikageView = {}, + noinline performer: HikagePerformer = {} + ) = ViewGroup(classOf(), classOf(), lparams, id, init, performer) /** * Provide a new [ViewGroup] instance [VG]. @@ -633,9 +676,9 @@ class Hikage private constructor(private val factories: List) { inline fun ViewGroup( lparams: LayoutParams? = null, id: String? = null, - init: HikageView = {}, - performer: HikagePerformer = {} - ) = ViewGroup(lparams, id, init, performer) + noinline init: HikageView = {}, + noinline performer: HikagePerformer = {} + ) = ViewGroup(classOf(), lparams, id, init, performer) /** * Provide layout from [resId]. @@ -661,16 +704,18 @@ class Hikage private constructor(private val factories: List) { /** * Provide layout from [ViewBinding]. + * @param bindingBuilder the view binding builder. * @param lparams the view layout params. * @param id the view id, generated by default. * @return [VB] */ @Hikageable - inline fun Layout( + fun Layout( + bindingBuilder: ViewBindingBuilder, lparams: LayoutParams? = null, id: String? = null ): VB { - val viewBinding = ViewBinding().inflate(context.layoutInflater, parent, attachToParent = false) + val viewBinding = bindingBuilder.inflate(context.layoutInflater, parent, attachToParent = false) val view = viewBinding.root startProvide(id, view.javaClass, view) @@ -686,6 +731,18 @@ class Hikage private constructor(private val factories: List) { return viewBinding } + /** + * Provide layout from [ViewBinding]. + * @param lparams the view layout params. + * @param id the view id, generated by default. + * @return [VB] + */ + @Hikageable + inline fun Layout( + lparams: LayoutParams? = null, + id: String? = null + ) = Layout(ViewBinding(), lparams, id) + /** * Provide layout from exists [View]. * @param view the view instance. @@ -702,7 +759,7 @@ class Hikage private constructor(private val factories: List) { if (view.parent != null) throw ProvideException("The view $view already has a parent, cannot be provided.") startProvide(id, view.javaClass, view) - val lpDelegate = LayoutParams.from(current = this@Hikage, lpClass, parent, lparams, view.layoutParams) + val lpDelegate = LayoutParams.from(current, lpClass, parent, lparams, view.layoutParams) view.layoutParams = lpDelegate.create() provideView(view, id) @@ -984,7 +1041,6 @@ class Hikage private constructor(private val factories: List) { * @param attachToParent whether to attach the layout to the parent when the [parent] is filled. * @return [Hikage] */ - fun create(context: Context, parent: ViewGroup? = null, attachToParent: Boolean = parent != null) = create(lpClass, context, parent, attachToParent, factory, performer) } diff --git a/hikage-core/src/main/java/com/highcapable/hikage/core/base/Exceptions.kt b/hikage-core/src/main/java/com/highcapable/hikage/core/base/Exceptions.kt index f45290c..c54fd09 100644 --- a/hikage-core/src/main/java/com/highcapable/hikage/core/base/Exceptions.kt +++ b/hikage-core/src/main/java/com/highcapable/hikage/core/base/Exceptions.kt @@ -27,10 +27,12 @@ package com.highcapable.hikage.core.base * The exception of performing view. * @param message the exception message. */ +@PublishedApi internal class PerformerException(message: String) : Exception(message) /** * The exception of providing view. * @param message the exception message. */ +@PublishedApi internal class ProvideException(message: String) : Exception(message) \ No newline at end of file diff --git a/hikage-core/src/main/java/com/highcapable/hikage/core/base/Hikageable.kt b/hikage-core/src/main/java/com/highcapable/hikage/core/base/Hikageable.kt index bc57b67..63e901b 100644 --- a/hikage-core/src/main/java/com/highcapable/hikage/core/base/Hikageable.kt +++ b/hikage-core/src/main/java/com/highcapable/hikage/core/base/Hikageable.kt @@ -19,7 +19,7 @@ * * This file is created by fankes on 2025/2/25. */ -@file:Suppress("unused", "FunctionName", "NON_PUBLIC_CALL_FROM_PUBLIC_INLINE") +@file:Suppress("unused", "FunctionName") @file:JvmName("HikageableUtils") package com.highcapable.hikage.core.base @@ -38,6 +38,9 @@ typealias HikagePerformer = Hikage.Performer.() -> Unit */ typealias HikageView = V.() -> Unit +/** The [Hikage] layout params body type. */ +internal typealias LayoutParamsBody = LP.() -> Unit + /** * Start performing a [Hikage] layout [LP]. * @param context the context to create the layout. @@ -47,14 +50,13 @@ typealias HikageView = V.() -> Unit * @param performer the performer body. * @return [Hikage] */ -@JvmSynthetic @JvmName("HikageableTyped") inline fun Hikageable( context: Context, parent: ViewGroup? = null, attachToParent: Boolean = parent != null, - factory: HikageFactoryBuilder.() -> Unit = {}, - performer: HikagePerformer + noinline factory: HikageFactoryBuilder.() -> Unit = {}, + noinline performer: HikagePerformer ) = Hikage.create(context, parent, attachToParent, factory, performer) /** @@ -67,7 +69,7 @@ inline fun Hikageable( * @return [Hikage] */ @JvmSynthetic -inline fun Hikageable( +fun Hikageable( context: Context, parent: ViewGroup? = null, attachToParent: Boolean = parent != null, @@ -81,7 +83,6 @@ inline fun Hikageable( * @param performer the performer body. * @return [Hikage.Delegate]<[LP]> */ -@JvmSynthetic @JvmName("HikageableTyped") inline fun Hikageable( noinline factory: HikageFactoryBuilder.() -> Unit = {}, diff --git a/hikage-extension/src/main/java/com/highcapable/hikage/extension/Activity.kt b/hikage-extension/src/main/java/com/highcapable/hikage/extension/Activity.kt index e70656d..2998019 100644 --- a/hikage-extension/src/main/java/com/highcapable/hikage/extension/Activity.kt +++ b/hikage-extension/src/main/java/com/highcapable/hikage/extension/Activity.kt @@ -36,7 +36,7 @@ import com.highcapable.hikage.core.base.Hikageable * @see Hikageable * @return [Hikage] */ -inline fun Activity.setContentView( +fun Activity.setContentView( factory: HikageFactoryBuilder.() -> Unit = {}, performer: HikagePerformer ) = Hikageable(context = this, factory = factory, performer = performer).apply { setContentView(root) } diff --git a/hikage-extension/src/main/java/com/highcapable/hikage/extension/Dialog.kt b/hikage-extension/src/main/java/com/highcapable/hikage/extension/Dialog.kt index 720e8e3..7ce9689 100644 --- a/hikage-extension/src/main/java/com/highcapable/hikage/extension/Dialog.kt +++ b/hikage-extension/src/main/java/com/highcapable/hikage/extension/Dialog.kt @@ -38,7 +38,7 @@ import androidx.appcompat.app.AlertDialog as AndroidXAlertDialog * @see Hikageable * @return [Hikage] */ -inline fun AlertDialog.setView( +fun AlertDialog.setView( factory: HikageFactoryBuilder.() -> Unit = {}, performer: HikagePerformer ) = Hikageable(context = context, factory = factory, performer = performer).apply { setView(root) } @@ -62,7 +62,7 @@ fun AlertDialog.setView(delegate: Hikage.Delegate<*>) = * @see Hikageable * @return [AlertDialog.Builder] */ -inline fun AlertDialog.Builder.setView( +fun AlertDialog.Builder.setView( factory: HikageFactoryBuilder.() -> Unit = {}, performer: HikagePerformer ): AlertDialog.Builder = setView(Hikageable(context = context, factory = factory, performer = performer).root) @@ -87,7 +87,7 @@ fun AlertDialog.Builder.setView(delegate: Hikage.Delegate<*>): AlertDialog.Build * @see Hikageable * @return [Hikage] */ -inline fun AndroidXAlertDialog.setView( +fun AndroidXAlertDialog.setView( factory: HikageFactoryBuilder.() -> Unit = {}, performer: HikagePerformer ) = Hikageable(context = context, factory = factory, performer = performer).apply { setView(root) } @@ -111,7 +111,7 @@ fun AndroidXAlertDialog.setView(delegate: Hikage.Delegate<*>) = * @see Hikageable * @return [AndroidXAlertDialog.Builder] */ -inline fun AndroidXAlertDialog.Builder.setView( +fun AndroidXAlertDialog.Builder.setView( factory: HikageFactoryBuilder.() -> Unit = {}, performer: HikagePerformer ): AndroidXAlertDialog.Builder = setView(Hikageable(context = context, factory = factory, performer = performer).root) @@ -136,7 +136,7 @@ fun AndroidXAlertDialog.Builder.setView(delegate: Hikage.Delegate<*>): AndroidXA * @see Hikageable * @return [Hikage] */ -inline fun Dialog.setContentView( +fun Dialog.setContentView( factory: HikageFactoryBuilder.() -> Unit = {}, performer: HikagePerformer ) = Hikageable(context = context, factory = factory, performer = performer).apply { setContentView(root) } diff --git a/hikage-extension/src/main/java/com/highcapable/hikage/extension/PopupWindow.kt b/hikage-extension/src/main/java/com/highcapable/hikage/extension/PopupWindow.kt index 7eea3fe..8e87c0b 100644 --- a/hikage-extension/src/main/java/com/highcapable/hikage/extension/PopupWindow.kt +++ b/hikage-extension/src/main/java/com/highcapable/hikage/extension/PopupWindow.kt @@ -19,7 +19,7 @@ * * This file is created by fankes on 2025/2/27. */ -@file:Suppress("unused", "NON_PUBLIC_CALL_FROM_PUBLIC_INLINE") +@file:Suppress("unused") @file:JvmName("PopupWindowUtils") package com.highcapable.hikage.extension @@ -38,7 +38,7 @@ import com.highcapable.kavaref.KavaRef.Companion.asResolver * @see Hikageable * @return [Hikage] */ -inline fun PopupWindow.setContentView( +fun PopupWindow.setContentView( context: Context = requireContext(), factory: HikageFactoryBuilder.() -> Unit = {}, performer: HikagePerformer diff --git a/hikage-extension/src/main/java/com/highcapable/hikage/extension/ViewGroup.kt b/hikage-extension/src/main/java/com/highcapable/hikage/extension/ViewGroup.kt index 123ede7..7f329eb 100644 --- a/hikage-extension/src/main/java/com/highcapable/hikage/extension/ViewGroup.kt +++ b/hikage-extension/src/main/java/com/highcapable/hikage/extension/ViewGroup.kt @@ -38,8 +38,8 @@ import com.highcapable.hikage.core.base.Hikageable @JvmName("addViewTyped") inline fun ViewGroup.addView( index: Int = -1, - factory: HikageFactoryBuilder.() -> Unit = {}, - performer: HikagePerformer + noinline factory: HikageFactoryBuilder.() -> Unit = {}, + noinline performer: HikagePerformer ) = Hikageable(context = context, factory = factory, performer = performer).apply { addView(root, index) } /** @@ -47,7 +47,7 @@ inline fun ViewGroup.addView( * @see Hikageable * @return [Hikage] */ -inline fun ViewGroup.addView( +fun ViewGroup.addView( index: Int = -1, factory: HikageFactoryBuilder.() -> Unit = {}, performer: HikagePerformer diff --git a/hikage-extension/src/main/java/com/highcapable/hikage/extension/Window.kt b/hikage-extension/src/main/java/com/highcapable/hikage/extension/Window.kt index 45f7919..66bc6b5 100644 --- a/hikage-extension/src/main/java/com/highcapable/hikage/extension/Window.kt +++ b/hikage-extension/src/main/java/com/highcapable/hikage/extension/Window.kt @@ -36,7 +36,7 @@ import com.highcapable.hikage.core.base.Hikageable * @see Hikageable * @return [Hikage] */ -inline fun Window.setContentView( +fun Window.setContentView( factory: HikageFactoryBuilder.() -> Unit = {}, performer: HikagePerformer ) = Hikageable(context = context, factory = factory, performer = performer).apply { setContentView(root) }