Skip to content

Commit 6a59881

Browse files
committed
Move the view when performing actions on the list
1 parent 21776a5 commit 6a59881

File tree

8 files changed

+97
-26
lines changed

8 files changed

+97
-26
lines changed

Common/src/main/kotlin/gay/object/hexdebug/blocks/splicing/SplicingTableBlockEntity.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,9 @@ class SplicingTableBlockEntity(pos: BlockPos, state: BlockState) :
244244
}
245245
if (writeList(list)) {
246246
shouldConsumeMedia = true
247-
selection = Selection.edge(typedSelection.start + 1)
247+
selection = Selection.edge(typedSelection.start + 1)?.also {
248+
makeEdgeVisible(it.index)
249+
}
248250
pushUndoState(
249251
list = Some(list),
250252
selection = Some(selection),

Common/src/main/kotlin/gay/object/hexdebug/gui/splicing/SplicingTableMenu.kt

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,18 @@ class SplicingTableMenu(
5151
index3 = SplicingTableDataSlot.MEDIA_3.index,
5252
)
5353

54-
val selection by ContainerDataSelectionDelegate(
54+
var selection by ContainerDataSelectionDelegate(
5555
data,
5656
fromIndex = SplicingTableDataSlot.SELECTION_FROM.index,
5757
toIndex = SplicingTableDataSlot.SELECTION_TO.index,
5858
)
59+
private set
5960

60-
val viewStartIndex by ContainerDataDelegate(
61+
var viewStartIndex by ContainerDataDelegate(
6162
data,
6263
index = SplicingTableDataSlot.VIEW_START_INDEX.index,
6364
)
65+
private set
6466

6567
var clientView = SplicingTableClientView.empty()
6668

@@ -141,7 +143,16 @@ class SplicingTableMenu(
141143
) = addSlot(FilteredSlot(table, slot, x, y).also(builder))
142144

143145
fun sendData(player: ServerPlayer) {
144-
table.getClientView()?.let { MsgSplicingTableNewDataS2C(it).sendToPlayer(player) }
146+
table.getClientView()?.let {
147+
MsgSplicingTableNewDataS2C(it, selection, viewStartIndex).sendToPlayer(player)
148+
}
149+
}
150+
151+
fun receiveData(msg: MsgSplicingTableNewDataS2C) {
152+
clientView = msg.data
153+
// TODO: does this make the client send a packet to the server?
154+
selection = msg.selection
155+
viewStartIndex = msg.viewStartIndex
145156
}
146157

147158
companion object {

Common/src/main/kotlin/gay/object/hexdebug/networking/handler/ClientMessageHandler.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ fun HexDebugMessageS2C.applyOnClient(ctx: PacketContext) = ctx.queue {
7171

7272
is MsgSplicingTableNewDataS2C -> {
7373
SplicingTableMenu.getInstance(ctx.player)?.also { menu ->
74-
menu.clientView = data
74+
menu.receiveData(this)
7575
SplicingTableScreen.getInstance()?.reloadData()
7676
}
7777
}

Common/src/main/kotlin/gay/object/hexdebug/networking/msg/MsgSplicingTableNewDataS2C.kt

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
package gay.`object`.hexdebug.networking.msg
22

33
import at.petrak.hexcasting.api.casting.math.HexPattern
4-
import gay.`object`.hexdebug.splicing.IotaClientView
5-
import gay.`object`.hexdebug.splicing.SplicingTableClientView
4+
import gay.`object`.hexdebug.splicing.*
65
import net.minecraft.nbt.CompoundTag
76
import net.minecraft.network.FriendlyByteBuf
87

98
/** The result of running a splicing table action on the server. */
10-
data class MsgSplicingTableNewDataS2C(val data: SplicingTableClientView) : HexDebugMessageS2C {
9+
data class MsgSplicingTableNewDataS2C(
10+
val data: SplicingTableClientView,
11+
// these are sent in the container data, but we also need to send them in this packet to avoid weird flickering
12+
val selection: Selection?,
13+
val viewStartIndex: Int,
14+
) : HexDebugMessageS2C {
1115
companion object : HexDebugMessageCompanion<MsgSplicingTableNewDataS2C> {
1216
override val type = MsgSplicingTableNewDataS2C::class.java
1317

@@ -31,6 +35,8 @@ data class MsgSplicingTableNewDataS2C(val data: SplicingTableClientView) : HexDe
3135
undoSize = buf.readInt(),
3236
undoIndex = buf.readInt(),
3337
),
38+
selection = buf.readSelection(),
39+
viewStartIndex = buf.readInt(),
3440
)
3541

3642
override fun MsgSplicingTableNewDataS2C.encode(buf: FriendlyByteBuf) {
@@ -50,6 +56,8 @@ data class MsgSplicingTableNewDataS2C(val data: SplicingTableClientView) : HexDe
5056
buf.writeBoolean(hasHex)
5157
buf.writeInt(undoSize)
5258
buf.writeInt(undoIndex)
59+
buf.writeSelection(selection)
60+
buf.writeInt(viewStartIndex)
5361
}
5462
}
5563
}

Common/src/main/kotlin/gay/object/hexdebug/splicing/Selection.kt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package gay.`object`.hexdebug.splicing
22

3+
import net.minecraft.network.FriendlyByteBuf
34
import java.util.*
45
import kotlin.math.max
56
import kotlin.math.min
@@ -88,3 +89,23 @@ sealed class Selection private constructor(val from: Int, open val to: Int?) {
8889
}
8990
}
9091
}
92+
93+
/** Writes an optional [Selection] to the buffer. */
94+
fun FriendlyByteBuf.writeSelection(selection: Selection?) {
95+
writeNullable(selection) { buf, value ->
96+
value.also {
97+
buf.writeInt(it.from)
98+
buf.writeNullable(it.to, FriendlyByteBuf::writeInt)
99+
}
100+
}
101+
}
102+
103+
/** Reads an optional [Selection] from the buffer. */
104+
fun FriendlyByteBuf.readSelection(): Selection? {
105+
return readNullable { buf ->
106+
Selection.of(
107+
from = buf.readInt(),
108+
to = buf.readNullable(FriendlyByteBuf::readInt),
109+
)
110+
}
111+
}

Common/src/main/kotlin/gay/object/hexdebug/splicing/SplicingTableAction.kt

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,7 @@ enum class SplicingTableAction(val value: Value<*>) {
8484
test = { _, _ -> undoSize > 1 && undoIndex > 0 },
8585
validate = { undoStack.size > 1 && undoStack.index > 0 },
8686
) {
87-
val state = undoStack.undo()
88-
if (state != null) {
89-
selection = state.applyTo(this, selection)
90-
}
87+
undoStack.undo()?.applyTo(this)
9188
}),
9289

9390
REDO(Value(
@@ -96,10 +93,7 @@ enum class SplicingTableAction(val value: Value<*>) {
9693
test = { _, _ -> undoSize > 1 && undoIndex < undoSize - 1 },
9794
validate = { undoStack.size > 1 && undoStack.index < undoStack.stack.lastIndex },
9895
) {
99-
val state = undoStack.redo()
100-
if (state != null) {
101-
selection = state.applyTo(this, selection)
102-
}
96+
undoStack.redo()?.applyTo(this)
10397
}),
10498

10599
// rw list range
@@ -112,7 +106,9 @@ enum class SplicingTableAction(val value: Value<*>) {
112106
) {
113107
list.add(typedSelection.end, list.removeAt(typedSelection.start - 1))
114108
if (writeList(list)) {
115-
selection = typedSelection.moveBy(-1)
109+
selection = typedSelection.moveBy(-1)?.also {
110+
makeIotaVisible(it.start)
111+
}
116112
pushUndoState(
117113
list = Some(list),
118114
selection = Some(selection),
@@ -128,7 +124,9 @@ enum class SplicingTableAction(val value: Value<*>) {
128124
) {
129125
list.add(typedSelection.start, list.removeAt(typedSelection.end + 1))
130126
if (writeList(list)) {
131-
selection = typedSelection.moveBy(1)
127+
selection = typedSelection.moveBy(1)?.also {
128+
makeIotaVisible(it.lastIndex)
129+
}
132130
pushUndoState(
133131
list = Some(list),
134132
selection = Some(selection),
@@ -139,7 +137,9 @@ enum class SplicingTableAction(val value: Value<*>) {
139137
DUPLICATE(Value(ReadWriteListRange, consumesMedia = true) {
140138
list.addAll(typedSelection.end + 1, typedSelection.subList(list))
141139
if (writeList(list)) {
142-
selection = Selection.withSize(typedSelection.end + 1, typedSelection.size)
140+
selection = Selection.withSize(typedSelection.end + 1, typedSelection.size)?.also {
141+
makeIotaVisible(it.end)
142+
}
143143
pushUndoState(
144144
list = Some(list),
145145
selection = Some(selection),
@@ -150,7 +150,9 @@ enum class SplicingTableAction(val value: Value<*>) {
150150
DELETE(Value(ReadWriteListRange, consumesMedia = true) {
151151
typedSelection.mutableSubList(list).clear()
152152
if (writeList(list)) {
153-
selection = Selection.edge(typedSelection.start)
153+
selection = Selection.edge(typedSelection.start)?.also {
154+
makeEdgeVisible(it.index)
155+
}
154156
pushUndoState(
155157
list = Some(list),
156158
selection = Some(selection),
@@ -165,7 +167,9 @@ enum class SplicingTableAction(val value: Value<*>) {
165167
typedSelection.mutableSubList(list).clear()
166168
if (isClipboardTransferSafe(iota) && writeClipboard(iota)) {
167169
if (writeList(list)) {
168-
selection = Selection.edge(typedSelection.start)
170+
selection = Selection.edge(typedSelection.start)?.also {
171+
makeEdgeVisible(it.index)
172+
}
169173
pushUndoState(
170174
list = Some(list),
171175
clipboard = Some(iota),
@@ -196,7 +200,9 @@ enum class SplicingTableAction(val value: Value<*>) {
196200
add(clipboard)
197201
}
198202
if (isClipboardTransferSafe(clipboard) && writeList(list)) {
199-
selection = Selection.edge(typedSelection.start + 1)
203+
selection = Selection.edge(typedSelection.start + 1)?.also {
204+
makeEdgeVisible(it.index)
205+
}
200206
pushUndoState(
201207
list = Some(list),
202208
selection = Some(selection),
@@ -214,7 +220,9 @@ enum class SplicingTableAction(val value: Value<*>) {
214220
addAll(values)
215221
}
216222
if (isClipboardTransferSafe(clipboard) && writeList(list)) {
217-
selection = Selection.edge(typedSelection.start + values.size)
223+
selection = Selection.edge(typedSelection.start + values.size)?.also {
224+
makeEdgeVisible(it.index)
225+
}
218226
pushUndoState(
219227
list = Some(list),
220228
selection = Some(selection),

Common/src/main/kotlin/gay/object/hexdebug/splicing/SplicingTableData.kt

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,28 @@ open class SplicingTableData(
7070
selection: Option<Selection?> = None(),
7171
) {
7272
// copy list to avoid mutability issues
73-
undoStack.push(UndoStack.Entry(list.map { it.toList() }, clipboard, selection))
73+
undoStack.push(UndoStack.Entry(
74+
list = list.map { it.toList() },
75+
clipboard = clipboard,
76+
selection = selection,
77+
))
78+
}
79+
80+
fun makeIotaVisible(index: Int) {
81+
when {
82+
index < viewStartIndex -> viewStartIndex = index
83+
index > viewEndIndex -> viewEndIndex = index
84+
}
85+
}
86+
87+
fun makeEdgeVisible(index: Int) {
88+
// index refers to the cell to the right of this edge
89+
when {
90+
// an edge is visible on the LEFT side if the cell to the RIGHT is visible
91+
index < viewStartIndex -> viewStartIndex = index
92+
// or on the RIGHT side if the cell to the LEFT is visible
93+
index - 1 > viewEndIndex -> viewEndIndex = index - 1
94+
}
7495
}
7596

7697
fun writeList(value: List<Iota>) = writeIota(listWriter, ListIota(value))

Common/src/main/kotlin/gay/object/hexdebug/splicing/UndoStack.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,10 @@ data class UndoStack(
4747
) {
4848
val isNotEmpty = list is Some || clipboard is Some || selection is Some
4949

50-
fun applyTo(data: SplicingTableData, defaultSelection: Selection?): Selection? = data.let {
50+
fun applyTo(data: SplicingTableData) {
5151
list.ifPresent(data::writeList)
5252
clipboard.ifPresent(data::writeClipboard)
53-
selection.getOrElse(defaultSelection)
53+
selection.ifPresent { data.selection = it }
5454
}
5555
}
5656
}

0 commit comments

Comments
 (0)