Skip to content

Commit eea5848

Browse files
committed
✨ Improve text display panel undo system and reactivity
1 parent 4c8792c commit eea5848

File tree

2 files changed

+78
-53
lines changed

2 files changed

+78
-53
lines changed

src/components/textDisplayElementPanel.svelte

Lines changed: 23 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<script lang="ts" context="module">
22
import { CodeJar } from '@novacbn/svelte-codejar'
33
import { Stopwatch } from 'src/util/stopwatch'
4-
import { onDestroy } from 'svelte'
54
import {
65
TEXT_DISPLAY_ALIGNMENT_SELECT,
76
TEXT_DISPLAY_BACKGROUND_COLOR_PICKER,
@@ -11,8 +10,6 @@
1110
TEXT_DISPLAY_WIDTH_SLIDER,
1211
} from '../interface/panel/textDisplayElement'
1312
import { TextDisplay } from '../outliner/textDisplay'
14-
import EVENTS from '../util/events'
15-
import { Valuable } from '../util/stores'
1613
import { translate } from '../util/translation'
1714
1815
const HIGHLIGHT_CACHE = new Map<string, string>()
@@ -27,50 +24,36 @@
2724
}
2825
const stopwatch = new Stopwatch('Highlighting').start()
2926
const result = Prism.highlight(code, Prism.languages[syntax], syntax)
30-
stopwatch.debug(result)
27+
stopwatch.debug({ code, result })
3128
HIGHLIGHT_CACHE.set(code, result)
3229
return result
3330
}
3431
</script>
3532

3633
<script lang="ts">
37-
let selected = TextDisplay.selected.at(0)
34+
export let selected: TextDisplay
3835
39-
let text = new Valuable(selected?.text ?? '')
40-
41-
let error = selected?.textError ?? new Valuable('')
36+
let text = selected.text
37+
let error = selected.textError
4238
4339
let codeJarElement: HTMLPreElement | undefined
4440
45-
let unsubFromText: (() => void) | undefined
46-
47-
const unsubFromEvent = EVENTS.UPDATE_SELECTION.subscribe(() => {
48-
unsubFromText?.()
49-
50-
selected = TextDisplay.selected.at(0)
51-
if (!selected || Group.first_selected) {
52-
$text = ''
53-
error = new Valuable('')
54-
return
41+
// Force the inputs to update
42+
TEXT_DISPLAY_WIDTH_SLIDER.setValue(selected.lineWidth)
43+
TEXT_DISPLAY_BACKGROUND_COLOR_PICKER.set(tinycolor(selected.backgroundColor))
44+
TEXT_DISPLAY_SHADOW_TOGGLE.set(selected.shadow)
45+
TEXT_DISPLAY_ALIGNMENT_SELECT.set(selected.align)
46+
TEXT_DISPLAY_SEE_THROUGH_TOGGLE.set(selected.seeThrough)
47+
48+
$: {
49+
if (selected.text !== text) {
50+
Undo.initEdit({ elements: [selected] })
51+
selected.text = text
52+
selected.updateTextMesh()
53+
Project!.saved = false
54+
Undo.finishEdit(`Change Text Display Text`, { elements: [selected] })
5555
}
56-
57-
$text = selected.text
58-
error = selected.textError
59-
60-
// Force the inputs to update
61-
TEXT_DISPLAY_WIDTH_SLIDER.setValue(selected.lineWidth)
62-
const color = tinycolor(selected.backgroundColor)
63-
TEXT_DISPLAY_BACKGROUND_COLOR_PICKER.set(color)
64-
TEXT_DISPLAY_SHADOW_TOGGLE.set(selected.shadow)
65-
TEXT_DISPLAY_ALIGNMENT_SELECT.set(selected.align)
66-
TEXT_DISPLAY_SEE_THROUGH_TOGGLE.set(selected.seeThrough)
67-
68-
text.subscribe(v => {
69-
console.log('Text changed:', v)
70-
if (!selected) return
71-
selected.text = v
72-
})
73-
})
56+
}
7457
7558
const mountLineWidth = (node: HTMLDivElement) => {
7659
node.appendChild(TEXT_DISPLAY_WIDTH_SLIDER.node)
@@ -109,25 +92,18 @@
10992
// CodeJar doesn't capture undo correctly. So we have to fudge it a little.
11093
requestAnimationFrame(() => {
11194
if (selected && codeJarElement?.textContent != undefined) {
112-
$text = codeJarElement.textContent
95+
text = codeJarElement.textContent
11396
}
11497
})
11598
}
11699
}
117-
118-
onDestroy(() => {
119-
unsubFromEvent()
120-
})
121100
</script>
122101

123-
<p class="panel_toolbar_label label" style={!!selected ? '' : 'visibility:hidden; height: 0px;'}>
102+
<p class="panel_toolbar_label label">
124103
{translate('panel.text_display.title')}
125104
</p>
126105

127-
<div
128-
class="toolbar text-display-toolbar"
129-
style={!!selected ? '' : 'visibility:hidden; height: 0px;'}
130-
>
106+
<div class="toolbar text-display-toolbar">
131107
<div class="content" use:mountLineWidth />
132108
<div class="content" use:mountShadow />
133109
<div class="content" use:mountAlignment />
@@ -145,7 +121,7 @@
145121
bind:element={codeJarElement}
146122
syntax="snbtTextComponent"
147123
{highlight}
148-
bind:value={$text}
124+
bind:value={text}
149125
on:change={() => forceNoWrap()}
150126
preserveIdent
151127
history

src/interface/panel/textDisplayElement.ts

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,45 @@
11
import { JsonTextParser } from 'src/systems/jsonText/parser'
2-
import { registerMountSvelteComponentMod } from 'src/util/mountSvelteComponent'
2+
import EVENTS from 'src/util/events'
3+
import { registerProjectMod } from 'src/util/moddingTools'
4+
import { mountSvelteComponent } from 'src/util/mountSvelteComponent'
35
import TextDisplayElementPanel from '../../components/textDisplayElementPanel.svelte'
4-
import { activeProjectIsBlueprintFormat } from '../../formats/blueprint'
6+
import { activeProjectIsBlueprintFormat, BLUEPRINT_FORMAT_ID } from '../../formats/blueprint'
57
import { type Alignment, TextDisplay } from '../../outliner/textDisplay'
68
import { translate } from '../../util/translation'
79

8-
registerMountSvelteComponentMod({
9-
id: 'animated-java:panel/text-display',
10-
component: TextDisplayElementPanel,
11-
target: '#panel_element',
10+
let mounted: TextDisplayElementPanel | null = null
11+
12+
const destroyMounted = () => {
13+
mounted?.$destroy()
14+
mounted = null
15+
}
16+
17+
const updatePanel = () => {
18+
destroyMounted()
19+
const textDisplay = TextDisplay.selected.at(0)
20+
if (textDisplay) {
21+
mounted = mountSvelteComponent({
22+
component: TextDisplayElementPanel,
23+
props: { selected: textDisplay },
24+
target: '#panel_element',
25+
})
26+
}
27+
}
28+
29+
registerProjectMod({
30+
id: 'animated-java:append-element-panel/text-display',
31+
32+
condition: project => project.format.id === BLUEPRINT_FORMAT_ID,
33+
34+
apply: () => {
35+
const unsubscribers = [EVENTS.UPDATE_SELECTION.subscribe(updatePanel)]
36+
return { unsubscribers }
37+
},
38+
39+
revert: ({ unsubscribers }) => {
40+
unsubscribers.forEach(u => u())
41+
destroyMounted()
42+
},
1243
})
1344

1445
type Grammar = ReturnType<typeof Prism.languages.extend>
@@ -103,6 +134,7 @@ export const TEXT_DISPLAY_WIDTH_SLIDER = new NumSlider(
103134
const newLineWidth = Math.clamp(value(selected.lineWidth), 1, 10000)
104135
if (selected.lineWidth === newLineWidth) return
105136
selected.lineWidth = newLineWidth
137+
selected.updateTextMesh()
106138
Project.saved = false
107139
},
108140
}
@@ -135,7 +167,13 @@ TEXT_DISPLAY_BACKGROUND_COLOR_PICKER.set = function (this: ColorPicker, color: t
135167

136168
const selected = TextDisplay.selected.at(0)
137169
if (!selected) return this
170+
171+
const value = color.toHex8String()
172+
if (selected.backgroundColor === value) return this
173+
138174
selected.backgroundColor = color.toHex8String()
175+
selected.updateTextMesh()
176+
Project!.saved = false
139177
return this
140178
}
141179
TEXT_DISPLAY_BACKGROUND_COLOR_PICKER.change = function (
@@ -145,9 +183,13 @@ TEXT_DISPLAY_BACKGROUND_COLOR_PICKER.change = function (
145183
if (!Project) return this
146184
const selected = TextDisplay.selected.at(0)
147185
if (!selected) return this
186+
148187
const newBackground = color.toHex8String()
188+
149189
if (selected.backgroundColor === newBackground) return this
190+
150191
selected.backgroundColor = newBackground
192+
selected.updateTextMesh()
151193
Project!.saved = false
152194
return this
153195
}
@@ -166,6 +208,7 @@ export const TEXT_DISPLAY_SHADOW_TOGGLE = new Toggle(`animated-java:text-display
166208
if (!selected) return
167209
if (selected.shadow === TEXT_DISPLAY_SHADOW_TOGGLE.value) return
168210
selected.shadow = TEXT_DISPLAY_SHADOW_TOGGLE.value
211+
selected.updateTextMesh()
169212
Project!.saved = false
170213
},
171214
})
@@ -205,7 +248,12 @@ TEXT_DISPLAY_ALIGNMENT_SELECT.set = function (this: BarSelect<Alignment>, value:
205248
if (!this.nodes.includes(this.node)) {
206249
$(this.node).find('bb-select').text(name)
207250
}
251+
252+
if (selected.align === value) return this
253+
208254
selected.align = value
255+
selected.updateTextMesh()
256+
Project!.saved = false
209257
return this
210258
}
211259

@@ -224,6 +272,7 @@ export const TEXT_DISPLAY_SEE_THROUGH_TOGGLE = new Toggle(
224272
if (!selected) return
225273
if (selected.seeThrough === TEXT_DISPLAY_SEE_THROUGH_TOGGLE.value) return
226274
selected.seeThrough = TEXT_DISPLAY_SEE_THROUGH_TOGGLE.value
275+
selected.updateTextMesh()
227276
Project!.saved = false
228277
},
229278
}

0 commit comments

Comments
 (0)