Skip to content

Commit 94eeeeb

Browse files
committed
🚧 More Display Panel progress
1 parent a5ab36c commit 94eeeeb

File tree

6 files changed

+339
-168
lines changed

6 files changed

+339
-168
lines changed

src/lang/en.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,13 +117,20 @@ config:
117117

118118
animated_java:item_display:
119119
label: Item Display
120+
description: Properties specific to Item Displays.
120121

121122
animated_java:block_display:
122123
label: Block Display
124+
description: Properties specific to Block Displays.
123125

124126
panel:
125127
display:
126128
title: Display
129+
linked.tooltip: Linked - This display option will be inherited from the parent node.
130+
unlinked.tooltip: Unlinked - This display option is unique to this node.
131+
set_all_linked.tooltip: Set All Linked - Set all display options to inherit the display properties from the parent node.
132+
set_all_unlinked.tooltip: Set All Unlinked - Set all display options to be unique to this node.
133+
reset_all.tooltip: Reset All - Reset all display options to their default values.
127134

128135
node:
129136
structure.title: |-
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<script lang="ts">
2+
import { roundTo } from '@aj/util/misc'
3+
import { onDestroy } from 'svelte'
4+
5+
export let id: string
6+
export let value: number
7+
export let min = -Infinity
8+
export let max = Infinity
9+
/** Minimum difference between two unique values */
10+
export let valueStep = 0.1
11+
/** How much to change when dragging */
12+
export let dragStep: number | undefined = valueStep
13+
14+
let input: HTMLInputElement
15+
let slider: HTMLElement
16+
17+
function clampValue(value: number) {
18+
return Math.clamp(roundTo(value, 1 / (valueStep ?? 1)), min, max) || 0
19+
}
20+
21+
function onStartDrag(moveEvent: MouseEvent | TouchEvent) {
22+
const mouseStartEvent = convertTouchEvent(moveEvent)
23+
const originalValue = value
24+
25+
function drag(moveEvent: MouseEvent | TouchEvent) {
26+
const mouseEndEvent = convertTouchEvent(moveEvent)
27+
const diff =
28+
Math.trunc((mouseEndEvent.clientX - mouseStartEvent.clientX) / 10) * (dragStep ?? 1)
29+
const adjustedValue = clampValue(originalValue + diff)
30+
if (adjustedValue !== value) {
31+
value = adjustedValue
32+
}
33+
}
34+
35+
function end() {
36+
removeEventListeners(document, 'mousemove touchmove', drag)
37+
}
38+
addEventListeners(document, 'mousemove touchmove', drag)
39+
addEventListeners(document, 'mouseup touchend', end, { once: true })
40+
}
41+
42+
const MOLANG_PARSER = new Molang()
43+
const onInput = () => {
44+
value = clampValue(MOLANG_PARSER.parse(value))
45+
}
46+
47+
// onMount
48+
requestAnimationFrame(() => {
49+
addEventListeners(slider, 'mousedown touchstart', onStartDrag)
50+
addEventListeners(input, 'focusout dblclick', onInput)
51+
})
52+
53+
onDestroy(() => {
54+
removeEventListeners(input, 'focusout dblclick', onInput)
55+
removeEventListeners(slider, 'mousedown touchstart', onStartDrag)
56+
})
57+
</script>
58+
59+
<div class="numeric_input">
60+
<input
61+
bind:this={input}
62+
{id}
63+
class="dark_bordered focusable_input"
64+
bind:value
65+
inputmode="decimal"
66+
/>
67+
<div bind:this={slider} class="tool numaric_input_slider">
68+
<i class="material-icons icon">code</i>
69+
</div>
70+
</div>
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<script lang="ts">
2+
import { BlockDisplay } from '@aj/blockbench-additions/outliner-elements/blockDisplay'
3+
import { ItemDisplay } from '@aj/blockbench-additions/outliner-elements/itemDisplay'
4+
import { TextDisplay } from '@aj/blockbench-additions/outliner-elements/textDisplay'
5+
import Number from '@aj/svelte-components/inputs/number.svelte'
6+
import { CommonDisplayConfig } from '@aj/systems/node-configs'
7+
import EVENTS from '@aj/util/events'
8+
9+
export let node: TextDisplay | BlockDisplay | ItemDisplay | Group
10+
11+
const CONFIG = new CommonDisplayConfig().fromJSON(node.commonConfig)
12+
const LINK_STATES = CONFIG.getAllLinkedStates()
13+
14+
// Key is a string, but I need it to be any to make TypeScript happy when indexing into the config object.
15+
function toggleLinked(key: any) {
16+
if (!CONFIG || !LINK_STATES) {
17+
console.error('Attempted to cycle common mode without a common config')
18+
return
19+
}
20+
21+
const mode = LINK_STATES.get(key)
22+
if (mode) {
23+
CONFIG.makeDefault(key)
24+
CONFIG.setKeyInheritance(key, false)
25+
LINK_STATES.set(key, false)
26+
} else {
27+
CONFIG.set(key, undefined)
28+
CONFIG.setKeyInheritance(key, true)
29+
LINK_STATES.set(key, true)
30+
}
31+
32+
Undo.initEdit({ elements: [node] })
33+
node.commonConfig = CONFIG.toJSON()
34+
Undo.finishEdit(`Set ${key} inheritance mode to ${mode}`, {
35+
elements: [node],
36+
})
37+
38+
EVENTS.UPDATE_SELECTION.dispatch()
39+
}
40+
</script>
41+
42+
<ul class="option-list">
43+
{#each CONFIG.keys() as key}
44+
{@const display = CONFIG.getPropertyDescription(key)}
45+
<li>
46+
<div>
47+
<div class="option-title">
48+
{display?.displayName}
49+
</div>
50+
<!-- svelte-ignore a11y-click-events-have-key-events -->
51+
<i
52+
on:click={() => toggleLinked(key)}
53+
class="material-icons notranslate icon option-mode-toggle"
54+
>
55+
{LINK_STATES.get(key) ? 'link' : 'link_off'}
56+
</i>
57+
</div>
58+
{#if LINK_STATES.get(key) === false}
59+
{#if display?.displayMode === 'checkbox'}
60+
<div class="option-value">
61+
<input type="checkbox" checked={!!CONFIG[key]} />
62+
</div>
63+
{:else if display?.displayMode === 'number'}
64+
<div class="option-value">
65+
<Number
66+
id={key}
67+
bind:value={CONFIG[key]}
68+
min={display?.min}
69+
max={display?.max}
70+
dragStep={display?.step}
71+
/>
72+
</div>
73+
{:else}
74+
<div class="option-value">
75+
<input type="text" value={CONFIG[key]} />
76+
</div>
77+
{/if}
78+
{/if}
79+
</li>
80+
{/each}
81+
</ul>

0 commit comments

Comments
 (0)