Skip to content

Commit 8346806

Browse files
authored
Feat/allow modificatio of title (#247)
2 parents 8486c0d + 0678bcc commit 8346806

16 files changed

Lines changed: 240 additions & 120 deletions

File tree

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled
77
javaVersion=25
88
mcVersion=1.21.11
99
group=dev.slne.surf
10-
version=1.21.11-2.64.0
10+
version=1.21.11-2.65.0
1111
relocationPrefix=dev.slne.surf.surfapi.libs
1212
snapshot=false

surf-api-bukkit/surf-api-bukkit-api/api/surf-api-bukkit-api.api

Lines changed: 76 additions & 23 deletions
Large diffs are not rendered by default.

surf-api-bukkit/surf-api-bukkit-api/src/main/kotlin/dev/slne/surf/surfapi/bukkit/api/inventory/framework/view/AbstractSurfView.kt

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -43,21 +43,22 @@ import org.bukkit.plugin.java.JavaPlugin
4343
* view.open(player)
4444
* ```
4545
*
46-
* @param header the plain-text title string rendered in the inventory's title bar
46+
* @param defaultHeader the plain-text title string rendered in the inventory's title bar
4747
* @see surfView
4848
* @see paginatedSurfView
4949
* @see SurfViewSettings
5050
*/
5151
@Suppress("UnstableApiUsage")
5252
abstract class AbstractSurfView(
53-
private val header: String,
53+
private val defaultHeader: String,
5454
) : View() {
5555
/**
5656
* The [SurfViewSettings] controlling layout, cancel behaviours, font, and alignment.
5757
* Defaults to [SimpleViewSettings] with all defaults applied.
5858
*/
5959
open val settings: SurfViewSettings = SimpleViewSettings()
60-
private val container = ViewContainer()
60+
61+
private val containerState = lazyState { _ -> ViewContainer() }
6162

6263
/**
6364
* Called during [onInit] after the container defaults are applied.
@@ -108,42 +109,41 @@ abstract class AbstractSurfView(
108109
protected open fun onViewUpdate(update: Context) = Unit
109110

110111
/**
111-
* Applies modifications to the [ViewContainer] and optionally updates the inventory title.
112+
* Applies modifications to the [ViewContainer] and updates the inventory title.
112113
*
113114
* The [block] is executed within a [ViewContainerModificationContext] that provides
114-
* component management functions. If [updateContext] is provided:
115+
* component management functions. Title updates are propagated based on [context]:
115116
* - For an [OpenContext], the title is set via `modifyConfig`.
116117
* - For any other context, `updateTitleForEveryone` is called to update all viewers.
117118
*
118-
* @param updateContext optional context used to propagate the title change; `null` skips
119-
* the title update (useful during initial setup)
119+
* @param context context used to propagate the title change to viewers
120120
* @param block modifications to apply to the [ViewContainer]
121121
*/
122122
protected fun modifyContainer(
123-
updateContext: Context? = null,
123+
context: Context,
124124
block: context(ViewContainerModificationContext) () -> Unit
125125
) {
126+
val container = containerState.get(context)
127+
126128
context(ViewContainerModificationContext(container)) {
127129
block()
128130
}
129131

130-
if (updateContext != null) {
131-
if (updateContext is OpenContext) {
132-
updateContext.modifyConfig {
133-
title(container.render())
134-
}
135-
} else {
136-
updateContext.updateTitleForEveryone(container.render())
132+
if (context is OpenContext) {
133+
context.modifyConfig {
134+
title(container.render())
137135
}
136+
} else {
137+
context.updateTitleForEveryone(container.render())
138138
}
139139
}
140140

141-
private fun applyContainerDefaults() {
142-
modifyContainer {
141+
private fun applyContainerDefaults(context: Context) {
142+
modifyContainer(context) {
143143
addChild(ViewContainerGlyphComponent(settings.rows))
144144
addChild(
145145
ViewContainerTitleComponent(
146-
title = header,
146+
title = defaultHeader,
147147
font = settings.font,
148148
charSpacing = ViewContainerTitleComponent.CHAR_SPACING,
149149
textAlignment = settings.headerTextAlignment
@@ -169,8 +169,6 @@ abstract class AbstractSurfView(
169169
}
170170

171171
final override fun onInit(config: ViewConfigBuilder) {
172-
applyContainerDefaults()
173-
174172
with(settings) {
175173
if (cancelOnPickup) config.cancelOnPickup()
176174
if (cancelOnDrag) config.cancelOnDrag()
@@ -180,12 +178,12 @@ abstract class AbstractSurfView(
180178

181179
onViewInit(config)
182180

183-
config.title(container.render())
184181
config.size(settings.rows.rows)
185182
config.type(ViewType.CHEST)
186183
}
187184

188185
final override fun onOpen(open: OpenContext) {
186+
applyContainerDefaults(open)
189187
onViewOpen(open)
190188
}
191189

@@ -224,11 +222,13 @@ abstract class AbstractSurfView(
224222
}
225223

226224
val player = click.player
225+
val previousState = viewer.previousContext.initialData
227226

228227
viewer.previousContext = null
229228
click.closeForPlayer()
229+
230230
player.scheduler.run(JavaPlugin.getProvidingPlugin(javaClass), {
231-
viewFrame.open(previousView.javaClass, player)
231+
viewFrame.open(previousView.javaClass, player, previousState)
232232
}, null)
233233
}
234234
}

surf-api-bukkit/surf-api-bukkit-api/src/main/kotlin/dev/slne/surf/surfapi/bukkit/api/inventory/framework/view/PaginatedSurfViewDSLImpl.kt

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -70,26 +70,8 @@ abstract class PaginatedSurfViewDSLImpl @PublishedApi internal constructor(
7070
ctx.containerDefaults?.invoke(modificationCtx, ref)
7171
}
7272

73-
/**
74-
* Modifies the [ViewContainer] of this paginated view from within a lifecycle callback.
75-
*
76-
* Only callable inside a [PaginatedSurfViewRef] context (i.e. within lifecycle callbacks).
77-
* Delegates to the internal `modifyContainer` method of [AbstractSurfView].
78-
*
79-
* @param updateContext optional context used to propagate the updated title;
80-
* pass `null` to skip the title update
81-
* @param block modifications to apply to the [ViewContainer]
82-
*/
83-
context(_: PaginatedSurfViewRef)
84-
fun modifyContainer(
85-
updateContext: Context? = null,
86-
block: context(ViewContainerModificationContext) () -> Unit
87-
) {
88-
modifyContainer0(updateContext, block)
89-
}
90-
91-
private fun modifyContainer0(
92-
updateContext: Context? = null,
73+
internal fun modifyContainer0(
74+
updateContext: Context,
9375
block: context(ViewContainerModificationContext) () -> Unit
9476
) = modifyContainer(updateContext, block)
9577
}

surf-api-bukkit/surf-api-bukkit-api/src/main/kotlin/dev/slne/surf/surfapi/bukkit/api/inventory/framework/view/SurfViewBuilder.kt

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@ import dev.slne.surf.surfapi.bukkit.api.inventory.framework.view.pagination.Abst
55
/**
66
* Creates a simple (non-paginated) [AbstractSurfView] using a DSL builder.
77
*
8-
* The [block] is called with both a [SurfViewContext] (for lifecycle hooks and settings)
9-
* and a [SurfViewRef] (for accessing the view inside callbacks) as context receivers.
10-
* After the block executes, the concrete view implementation is instantiated and the
11-
* reference is resolved.
8+
* The [block] is called with a [SurfViewContext] as its context receiver, which exposes
9+
* lifecycle hooks and view settings for configuration. After the block executes, the
10+
* concrete view implementation is instantiated and its internal reference is resolved.
1211
*
1312
* ```kotlin
1413
* val myView = surfView("Inventory Title") {
@@ -25,16 +24,16 @@ import dev.slne.surf.surfapi.bukkit.api.inventory.framework.view.pagination.Abst
2524
* ```
2625
*
2726
* @param header the plain-text title rendered in the inventory header
28-
* @param block DSL configuration block accepting both [SurfViewContext] and [SurfViewRef]
27+
* @param block DSL configuration block with [SurfViewContext] as its context receiver
2928
* @return the fully configured [AbstractSurfView]
3029
* @see paginatedSurfView
3130
* @see AbstractSurfView
3231
*/
33-
inline fun surfView(header: String, block: context (SurfViewContext, SurfViewRef) () -> Unit): AbstractSurfView {
32+
inline fun surfView(header: String, block: context (SurfViewContext) () -> Unit): AbstractSurfView {
3433
val ctx = SurfViewContext()
3534
val ref = SurfViewRef()
3635

37-
context(ctx, ref) {
36+
context(ctx) {
3837
block()
3938
}
4039

@@ -47,9 +46,9 @@ inline fun surfView(header: String, block: context (SurfViewContext, SurfViewRef
4746
/**
4847
* Creates a paginated [AbstractPaginatedSurfView] using a DSL builder.
4948
*
50-
* Works the same as [surfView] but accepts a [PaginatedSurfViewContext] and
51-
* [PaginatedSurfViewRef]. The [block] must configure at least a `layoutTarget` character
52-
* and a `pagination { }` block, otherwise [IllegalStateException] is thrown at view creation.
49+
* Works similarly to [surfView] but uses a [PaginatedSurfViewContext] as the context
50+
* receiver. The [block] must configure at least a `layoutTarget` character and a
51+
* `pagination { }` block, otherwise [IllegalStateException] is thrown at view creation.
5352
*
5453
* ```kotlin
5554
* val listView = paginatedSurfView("Item List") {
@@ -68,19 +67,19 @@ inline fun surfView(header: String, block: context (SurfViewContext, SurfViewRef
6867
* ```
6968
*
7069
* @param header the plain-text title rendered in the inventory header
71-
* @param block DSL configuration block accepting both [PaginatedSurfViewContext] and [PaginatedSurfViewRef]
70+
* @param block DSL configuration block with [PaginatedSurfViewContext] as its context receiver
7271
* @return the fully configured [AbstractPaginatedSurfView]
7372
* @see surfView
7473
* @see dev.slne.surf.surfapi.bukkit.api.inventory.framework.view.pagination.AbstractPaginatedSurfView
7574
*/
7675
inline fun paginatedSurfView(
7776
header: String,
78-
block: context (PaginatedSurfViewContext, PaginatedSurfViewRef) () -> Unit
77+
block: context (PaginatedSurfViewContext) () -> Unit
7978
): AbstractPaginatedSurfView {
8079
val ctx = PaginatedSurfViewContext()
8180
val ref = PaginatedSurfViewRef()
8281

83-
context(ctx, ref) {
82+
context(ctx) {
8483
block()
8584
}
8685

surf-api-bukkit/surf-api-bukkit-api/src/main/kotlin/dev/slne/surf/surfapi/bukkit/api/inventory/framework/view/SurfViewDSLImpl.kt

Lines changed: 2 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -66,37 +66,8 @@ abstract class SurfViewDSLImpl @PublishedApi internal constructor(
6666
ctx.containerDefaults?.invoke(modificationCtx, ref)
6767
}
6868

69-
/**
70-
* Modifies the [ViewContainer] of this view from within a lifecycle callback.
71-
*
72-
* This function is only callable inside a [SurfViewRef] context (i.e. within lifecycle
73-
* callbacks). It is a type-safe forwarding wrapper that delegates to the internal
74-
* `modifyContainer` method of [AbstractSurfView].
75-
*
76-
* ```kotlin
77-
* onFirstRender {
78-
* with(view) {
79-
* modifyContainer {
80-
* blockRow(5)
81-
* }
82-
* }
83-
* }
84-
* ```
85-
*
86-
* @param updateContext optional context used to propagate the updated title;
87-
* pass `null` to skip the title update
88-
* @param block modifications to apply to the [ViewContainer]
89-
*/
90-
context(_: SurfViewRef)
91-
fun modifyContainer(
92-
updateContext: Context? = null,
93-
block: context(ViewContainerModificationContext) () -> Unit
94-
) {
95-
modifyContainer0(updateContext, block)
96-
}
97-
98-
private fun modifyContainer0(
99-
updateContext: Context? = null,
69+
internal fun modifyContainer0(
70+
updateContext: Context,
10071
block: context(ViewContainerModificationContext) () -> Unit
10172
) = modifyContainer(updateContext, block)
10273
}

surf-api-bukkit/surf-api-bukkit-api/src/main/kotlin/dev/slne/surf/surfapi/bukkit/api/inventory/framework/view/SurfViewLifecycleDsl.kt

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,24 @@ fun <ViewRef : AbstractSurfViewRef> containerDefaults(block: context (@Inventory
160160
ctx.containerDefaults = block
161161
}
162162

163+
164+
/**
165+
* Modifies the [ViewContainer] of this view from within a lifecycle callback.
166+
* This function is only callable inside a [AbstractSurfViewRef] context (i.e. within lifecycle
167+
* callbacks). It is a type-safe forwarding wrapper that delegates to the internal `modifyContainer` method of [AbstractSurfView].
168+
*
169+
*/
170+
context(ref: AbstractSurfViewRef)
171+
fun Context.modifyContainer(
172+
block: context(ViewContainerModificationContext) () -> Unit
173+
) {
174+
when (val view = ref.getRegisteredView()) {
175+
is SurfViewDSLImpl -> view.modifyContainer0(this, block)
176+
is PaginatedSurfViewDSLImpl -> view.modifyContainer0(this, block)
177+
else -> error("Unknown view type: ${view::class}")
178+
}
179+
}
180+
163181
/**
164182
* Configures the [SimpleViewSettings] for this simple (non-paginated) view.
165183
*
@@ -225,4 +243,4 @@ fun settings(block: @InventoryFrameworkDSL PaginatedViewSettingsBuilder.() -> Un
225243
context(ctx: PaginatedSurfViewContext)
226244
fun layoutTarget(target: Char) {
227245
ctx.layoutTarget = target
228-
}
246+
}

surf-api-bukkit/surf-api-bukkit-api/src/main/kotlin/dev/slne/surf/surfapi/bukkit/api/inventory/framework/view/container/component/components/ViewContainerBackHintComponent.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ import dev.slne.surf.surfapi.core.api.messages.builder.SurfComponentBuilder
1313
* texture width 15 pixels) to hint to the player that clicking outside the inventory navigates back.
1414
*/
1515
data object ViewContainerBackHintComponent : ViewContainerComponent {
16-
override val positionalShift = -21
17-
override val textureWidth = 15
16+
override val positionalShift = -22
17+
override val textureWidth = 15 + 2 // 2 pixel for spacing
1818

1919
override fun SurfComponentBuilder.renderComponent() {
2020
text("")

surf-api-bukkit/surf-api-bukkit-api/src/main/kotlin/dev/slne/surf/surfapi/bukkit/api/inventory/framework/view/container/component/components/ViewContainerTitleComponent.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import net.kyori.adventure.key.Key
3333
* @param charSpacing the pixel spacing to insert between each character
3434
* @param textAlignment the [TextAlignment] controlling horizontal positioning
3535
*/
36-
internal class ViewContainerTitleComponent(
36+
class ViewContainerTitleComponent(
3737
title: String,
3838
private val font: Key,
3939
charSpacing: Int,
@@ -61,8 +61,7 @@ internal class ViewContainerTitleComponent(
6161
)
6262

6363
override val positionalShift = textAlignment.calculateShift(title, alignmentOptions)
64-
override val textureWidth =
65-
TextAlignment.calculateTextWidth(title, alignmentOptions) - 1 // -1 because of the last char spacing
64+
override val textureWidth = TextAlignment.calculateTextWidth(title, alignmentOptions)
6665

6766
override fun SurfComponentBuilder.renderComponent() {
6867
text(formattedTitle)

surf-api-bukkit/surf-api-bukkit-api/src/main/kotlin/dev/slne/surf/surfapi/bukkit/api/inventory/framework/view/container/dsl/ViewContainerDSL.kt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package dev.slne.surf.surfapi.bukkit.api.inventory.framework.view.container.dsl
22

3+
import dev.slne.surf.surfapi.bukkit.api.inventory.framework.view.AbstractSurfViewRef
34
import dev.slne.surf.surfapi.bukkit.api.inventory.framework.view.container.component.ViewContainerComponent
45
import dev.slne.surf.surfapi.bukkit.api.inventory.framework.view.container.component.components.ViewBlockCellComponent
56
import dev.slne.surf.surfapi.bukkit.api.inventory.framework.view.container.component.components.ViewContainerBackHintComponent
7+
import dev.slne.surf.surfapi.bukkit.api.inventory.framework.view.container.component.components.ViewContainerTitleComponent
68
import it.unimi.dsi.fastutil.ints.IntCollection
79
import it.unimi.dsi.fastutil.ints.IntLists
810

@@ -164,4 +166,28 @@ fun blockColumn(column: Int, exemptRows: IntCollection = IntLists.EMPTY_LIST) {
164166
context(context: ViewContainerModificationContext)
165167
fun backHint() {
166168
addChild(ViewContainerBackHintComponent)
169+
}
170+
171+
/**
172+
* Sets a title header for the [ViewContainer][dev.slne.surf.surfapi.bukkit.api.inventory.framework.view.container.ViewContainer] by removing any existing title component
173+
* and adding a new `ViewContainerTitleComponent` with the specified header text.
174+
*
175+
* @param header The text to set as the title for the container.
176+
* @param context Provides access to the container modification API for the current view.
177+
* @param ref A deferred reference to the associated view, providing configuration details
178+
* such as font and text alignment settings.
179+
*/
180+
context(context: ViewContainerModificationContext, ref: AbstractSurfViewRef)
181+
fun header(header: String) {
182+
removeChildrenOfType<ViewContainerTitleComponent>()
183+
184+
val settings = ref.getRegisteredView().settings
185+
addChild(
186+
ViewContainerTitleComponent(
187+
header,
188+
settings.font,
189+
ViewContainerTitleComponent.CHAR_SPACING,
190+
settings.headerTextAlignment
191+
)
192+
)
167193
}

0 commit comments

Comments
 (0)