Skip to content

Commit aae7ba3

Browse files
committed
Fix exception when accessing the current frame in a stateless slide
1 parent 4a2d46b commit aae7ba3

4 files changed

Lines changed: 49 additions & 12 deletions

File tree

storyboard-core/src/commonMain/kotlin/dev/bnorm/storyboard/core/Storyboard.kt

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,17 @@ class Storyboard private constructor(
6161
var direction by mutableStateOf(AdvanceDirection.Forward)
6262
private set
6363

64-
val currentFrame: Frame
65-
get() = node.currentState.let { it.frames[it.stateIndex.currentState] }
64+
val currentFrame: Frame by derivedStateOf {
65+
val currentNode = node.currentState
66+
if (currentNode.frames.isEmpty()) {
67+
when (direction) {
68+
AdvanceDirection.Forward -> currentNode.previousFrame()!!
69+
AdvanceDirection.Backward -> currentNode.nextFrame()!!
70+
}
71+
} else {
72+
currentNode.frames[currentNode.stateIndex.currentState]
73+
}
74+
}
6675

6776
val advancementProgress: Float
6877
get() = node.fraction.takeIf { it != 0.0f }

storyboard-core/src/commonMain/kotlin/dev/bnorm/storyboard/core/internal/SlideNode.kt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,28 @@ internal class SlideNode<T> private constructor(
142142
}
143143
}
144144

145+
fun nextFrame(): Storyboard.Frame? {
146+
var iter = next
147+
while (iter != null) {
148+
if (iter.frames.isNotEmpty()) {
149+
return iter.frames.first()
150+
}
151+
iter = iter.next
152+
}
153+
return null
154+
}
155+
156+
fun previousFrame(): Storyboard.Frame? {
157+
var iter = prev
158+
while (iter != null) {
159+
if (iter.frames.isNotEmpty()) {
160+
return iter.frames.last()
161+
}
162+
iter = iter.prev
163+
}
164+
return null
165+
}
166+
145167
override fun compareTo(other: SlideNode<*>): Int {
146168
return compareValues(slideIndex, other.slideIndex)
147169
}

storyboard-easel/src/commonMain/kotlin/dev/bnorm/storyboard/easel/StoryboardOverview.kt

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ fun StoryboardOverview(
123123

124124
class StoryboardOverview private constructor(
125125
val storyboard: Storyboard,
126-
val columns: ImmutableList<Column>,
126+
internal val columns: ImmutableList<Column>,
127127
) {
128128
private var _isVisible = mutableStateOf(false)
129129
var isVisible: Boolean
@@ -135,7 +135,7 @@ class StoryboardOverview private constructor(
135135
}
136136

137137
var currentColumnIndex by mutableStateOf(0)
138-
val currentItem: Item
138+
internal val currentItem: Item
139139
get() = columns[currentColumnIndex].let { it.items[it.currentItemIndex] }
140140

141141
fun jumpTo(columnIndex: Int, itemIndex: Int) {
@@ -164,7 +164,7 @@ class StoryboardOverview private constructor(
164164
}
165165

166166
@Immutable
167-
class Column(
167+
internal class Column(
168168
val slide: Slide<*>,
169169
val index: Int,
170170
val items: ImmutableList<Item>,
@@ -173,7 +173,7 @@ class StoryboardOverview private constructor(
173173
}
174174

175175
@Immutable
176-
class Item(
176+
internal class Item(
177177
val frame: Storyboard.Frame,
178178
)
179179

@@ -182,10 +182,8 @@ class StoryboardOverview private constructor(
182182
val columns = storyboard.slides
183183
.mapIndexed { slideIndex, slide ->
184184
val items = slide.states
185-
.mapIndexedNotNull { stateIndex, _ ->
186-
Item(
187-
frame = Storyboard.Frame(slideIndex, stateIndex)
188-
)
185+
.mapIndexed { stateIndex, _ ->
186+
Item(frame = Storyboard.Frame(slideIndex, stateIndex))
189187
}
190188
.toImmutableList()
191189

storyboard-text/src/commonMain/kotlin/dev/bnorm/storyboard/text/highlight/Kotlin.kt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ internal fun highlightKotlin(
2626

2727
fun AnnotatedString.Builder.addStyle(token: Token): Token {
2828
when (token.type) {
29+
KotlinLexer.Tokens.AS_SAFE,
2930
KotlinLexer.Tokens.GET,
3031
KotlinLexer.Tokens.SET,
3132
KotlinLexer.Tokens.FUN,
@@ -34,6 +35,8 @@ internal fun highlightKotlin(
3435
KotlinLexer.Tokens.CLASS,
3536
KotlinLexer.Tokens.INTERFACE,
3637
KotlinLexer.Tokens.TYPE_ALIAS,
38+
KotlinLexer.Tokens.CONSTRUCTOR,
39+
KotlinLexer.Tokens.BY,
3740
KotlinLexer.Tokens.VAL,
3841
KotlinLexer.Tokens.VAR,
3942
KotlinLexer.Tokens.COMPANION,
@@ -49,8 +52,11 @@ internal fun highlightKotlin(
4952
KotlinLexer.Tokens.WHILE,
5053
KotlinLexer.Tokens.THROW,
5154
KotlinLexer.Tokens.RETURN,
55+
KotlinLexer.Tokens.AS,
5256
KotlinLexer.Tokens.IS,
5357
KotlinLexer.Tokens.IN,
58+
KotlinLexer.Tokens.NOT_IS,
59+
KotlinLexer.Tokens.NOT_IN,
5460
KotlinLexer.Tokens.PUBLIC,
5561
KotlinLexer.Tokens.PRIVATE,
5662
KotlinLexer.Tokens.PROTECTED,
@@ -68,12 +74,14 @@ internal fun highlightKotlin(
6874
KotlinLexer.Tokens.BooleanLiteral,
6975
-> addStyle(codeStyle.keyword, token)
7076

77+
KotlinLexer.Tokens.RealLiteral,
78+
KotlinLexer.Tokens.FloatLiteral,
79+
KotlinLexer.Tokens.DoubleLiteral,
7180
KotlinLexer.Tokens.IntegerLiteral,
7281
KotlinLexer.Tokens.HexLiteral,
7382
KotlinLexer.Tokens.BinLiteral,
74-
KotlinLexer.Tokens.RealLiteral,
75-
KotlinLexer.Tokens.LongLiteral,
7683
KotlinLexer.Tokens.UnsignedLiteral,
84+
KotlinLexer.Tokens.LongLiteral,
7785
-> addStyle(codeStyle.number, token)
7886

7987
KotlinLexer.Tokens.CharacterLiteral,

0 commit comments

Comments
 (0)