Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 32 additions & 1 deletion src/components/count-field.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
<template lang="pug">
.CountField(:data-active="props.value !== off" :data-inactive="props.inactive" @click="toggle")
.CountField(
:data-active="props.value !== off"
:data-inactive="props.inactive"
@mousedown="onMouseDown"
@mouseup="onMouseUp"
@contextmenu.stop="onContextMenu")
.body
.label {{translate(props.label)}}
.input-group(@click.stop)
TextInput.text-input(
ref="textInputEl"
:value="props.value"
:line="true"
:filter="valueFilter"
Expand All @@ -13,7 +19,9 @@
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import { translate } from 'src/dict'
import type { TextInputComponent } from 'src/types'
import TextInput from './text-input.vue'
import ToggleInput from './toggle-input.vue'

Expand All @@ -28,6 +36,25 @@ interface CountFieldProps {

const emit = defineEmits(['update:value', 'change'])
const props = withDefaults(defineProps<CountFieldProps>(), { min: 0 })
const textInputEl = ref<TextInputComponent | null>(null)

let rangeIsSelected = false

function onMouseDown(e: DOMEvent<MouseEvent>) {
rangeIsSelected = getSelection()?.type === 'Range'
if (e.detail > 1) e.preventDefault()
}

function onMouseUp(e: DOMEvent<MouseEvent>) {
if (rangeIsSelected || getSelection()?.type === 'Range') return
if (e.button === 0) focusTextInput()
if (e.button === 2) toggle()
}

function onContextMenu(payload: PointerEvent) {
if (rangeIsSelected || getSelection()?.type === 'Range') return
payload.preventDefault()
}

function onInput(val: string): void {
emit('update:value', val)
Expand All @@ -44,6 +71,10 @@ function valueFilter(e: Event): number {
else return val
}

function focusTextInput(): void {
textInputEl.value?.focus()
}

function toggle(): void {
if (props.inactive) return
else if (props.value === props.off && props.off) emit('update:value', props.min ?? props.off + 1)
Expand Down
50 changes: 48 additions & 2 deletions src/components/num-field.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
<template lang="pug">
.NumField(:data-active="!!props.value" :data-inactive="props.inactive")
.NumField(
:data-active="!!props.value"
:data-inactive="props.inactive"
@mousedown="onMouseDown"
@mouseup="onMouseUp"
@contextmenu.stop="onContextMenu")
.body
.label {{translate(props.label)}}
.input-group
TextInput.text-input(
ref="textInputEl"
:value="props.value"
:line="true"
:filter="valueFilter"
Expand All @@ -20,9 +26,10 @@
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import { computed } from 'vue'
import { translate } from 'src/dict'
import type { InputOption } from 'src/types'
import type { InputOption, InputObjOpt, TextInputComponent } from 'src/types'
import TextInput from './text-input.vue'
import SelectInput from './select-input.vue'

Expand All @@ -41,11 +48,46 @@ interface NumFieldProps {

const emit = defineEmits(['update:value', 'update:unit'])
const props = defineProps<NumFieldProps>()
const textInputEl = ref<TextInputComponent | null>(null)

const validUnit = computed((): string => {
return !props.value ? 'none' : (props.unit ?? 'none')
})

let rangeIsSelected = false

function onMouseDown(e: DOMEvent<MouseEvent>) {
rangeIsSelected = getSelection()?.type === 'Range'
if (e.detail > 1) e.preventDefault()
}

function onMouseUp(e: DOMEvent<MouseEvent>) {
if (rangeIsSelected || getSelection()?.type === 'Range') return
if (e.button === 0) focusTextInput()
if (e.button === 2) switchUnitOption(-1)
}

function onContextMenu(payload: PointerEvent) {
if (rangeIsSelected || getSelection()?.type === 'Range') return
payload.preventDefault()
}

function switchUnitOption(dir: 1 | -1): void {
if (props.inactive || !props.unitOpts || Array.isArray(props.unit)) return
let i = props.unit !== undefined ? props.unitOpts.indexOf(props.unit) : -1
if (i === -1) i = props.unitOpts.findIndex(o => (o as InputObjOpt).value === props.unit)
if (i === -1) return
i += dir
if (i >= props.unitOpts.length) i = 0
if (i < 0) i = props.unitOpts.length - 1
let selected = props.unitOpts[i]
if (selected && (selected as InputObjOpt).value) {
emit('update:unit', (selected as InputObjOpt).value)
} else {
emit('update:unit', selected)
}
}

function valueFilter(e: Event): number | void {
const target = e.target as HTMLInputElement
let raw = target.value
Expand All @@ -59,6 +101,10 @@ function valueFilter(e: Event): number | void {
return val
}

function focusTextInput(): void {
textInputEl.value?.focus()
}

function select(unit: string): void {
if (props.inactive) return

Expand Down
20 changes: 17 additions & 3 deletions src/components/select-field.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
:data-inactive="props.inactive"
:data-drop-down="dropDownOpen"
@mousedown="onMouseDown"
@contextmenu.stop.prevent=""
@blur="onBlur"
@mouseup="onMouseUp"
@contextmenu.stop="onContextMenu"
@keydown="onKeyDown")
.focus-fx
.body
Expand All @@ -20,6 +20,7 @@
:icon="props.icon"
:folded="folded"
:preSelected="preSelected"
@dropdown-blur="onDropdownBlur"
@update:value="select")
.note(v-if="props.note") {{props.note}}
</template>
Expand Down Expand Up @@ -59,12 +60,25 @@ const preSelected = ref<string | number>(-1)
const inputComponent = ref<SelectInputComponent | null>(null)
const rootEl = ref<HTMLElement | null>(null)

let rangeIsSelected = false

function onMouseDown(e: DOMEvent<MouseEvent>) {
rangeIsSelected = getSelection()?.type === 'Range'
if (e.detail > 1) e.preventDefault()
}

function onMouseUp(e: DOMEvent<MouseEvent>) {
if (rangeIsSelected || getSelection()?.type === 'Range') return
if (props.inactive || !props.opts || Array.isArray(props.value)) return
if (e.button === 0) switchOption(1)
if (e.button === 2) switchOption(-1)
}

function onContextMenu(payload: PointerEvent) {
if (rangeIsSelected || getSelection()?.type === 'Range') return
payload.preventDefault()
}

function switchOption(dir: 1 | -1): void {
if (props.inactive || !props.opts || Array.isArray(props.value)) return
if (props.folded && !dropDownOpen.value) {
Expand Down Expand Up @@ -141,7 +155,7 @@ function select(option: string): void {
if (rootEl.value) rootEl.value.tabIndex = -1
}

function onBlur(): void {
function onDropdownBlur(): void {
dropDownOpen.value = false
if (inputComponent.value) inputComponent.value.close()
if (rootEl.value) rootEl.value.tabIndex = -1
Expand Down
10 changes: 7 additions & 3 deletions src/components/select-input.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
.opt.-exp(v-if="folded")
svg: use(href="#icon_expand")
teleport(v-if="folded && !disabledDropDownTeleport" to="#root")
.select-input-drop-down-layer(v-if="isOpen" @wheel="onWheel")
.select-input-drop-down-layer(v-if="isOpen" @wheel="onWheel" @mouseup="onMouseUp" @contextmenu.stop.prevent)
.select-input-drop-down(:style="dropDownStyle")
.select-input-drop-down-content(ref="dropDownEl")
.opt(
Expand All @@ -25,7 +25,7 @@
:data-none="((opt as InputObjOpt).value ?? opt) === props.noneOpt"
:data-color="getOptColor(opt) ?? false"
:data-active="((opt as InputObjOpt).value ?? opt) === preSelected"
@mousedown.stop="select(opt)")
@mouseup.stop="select(opt)")
svg(v-if="((opt as InputObjOpt).icon || props.icon)?.startsWith('#')")
use(:href="((opt as InputObjOpt).icon || props.icon)")
img(v-else-if="(opt as InputObjOpt).icon || props.icon" :src="(opt as InputObjOpt).icon || props.icon")
Expand Down Expand Up @@ -76,7 +76,7 @@ const focusEl = ref<HTMLElement | null>(null)
const dropDownEl = ref<HTMLElement | null>(null)
const disabledDropDownTeleport = ref(true)
const isOpen = ref(false)
const emit = defineEmits(['update:value'])
const emit = defineEmits(['update:value', 'dropdown-blur'])
const props = withDefaults(defineProps<SelectInputProps>(), { noneOpt: 'none' })
const dropDownStyle = reactive({
'--left': '0px',
Expand Down Expand Up @@ -144,6 +144,10 @@ function getTooltip(option: InputOption): string {
return ''
}

function onMouseUp(e: DOMEvent<MouseEvent>) {
emit('dropdown-blur')
}

function onWheel(e: WheelEvent): void {
if (!dropDownEl.value) return

Expand Down
32 changes: 31 additions & 1 deletion src/components/style-field.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
<template lang="pug">
.StyleField(:class="{ '-no-separator': noSeparator }" :data-active="!!props.value")
.StyleField(
:class="{ '-no-separator': noSeparator }"
:data-active="!!props.value"
@mousedown="onMouseDown"
@mouseup="onMouseUp"
@contextmenu.stop="onContextMenu")
.label
.desc {{translate(props.label) || props.name}}
.var(v-if="props.name") {{props.name}}
Expand All @@ -11,6 +16,7 @@
:value="colorValue"
@input="onColorInput")
TextInput.text-input(
ref="textInputEl"
:value="props.value"
:line="true"
:or="props.or"
Expand All @@ -24,6 +30,7 @@
import { ref, computed } from 'vue'
import * as Utils from 'src/utils'
import { translate } from 'src/dict'
import type { TextInputComponent } from 'src/types'
import TextInput from './text-input.vue'
import ToggleInput from './toggle-input.vue'

Expand All @@ -39,6 +46,7 @@ interface StyleFieldProps {

const emit = defineEmits(['update:value', 'change', 'toggle'])
const props = defineProps<StyleFieldProps>()
const textInputEl = ref<TextInputComponent | null>(null)

const opaq = ref('ff')

Expand All @@ -58,6 +66,24 @@ const colorOpacity = computed((): number => {
return num / 255
})

let rangeIsSelected = false

function onMouseDown(e: DOMEvent<MouseEvent>) {
rangeIsSelected = getSelection()?.type === 'Range'
if (e.detail > 1) e.preventDefault()
}

function onMouseUp(e: DOMEvent<MouseEvent>) {
if (rangeIsSelected || getSelection()?.type === 'Range') return
if (e.button === 0) focusTextInput()
if (e.button === 2) toggle()
}

function onContextMenu(payload: PointerEvent) {
if (rangeIsSelected || getSelection()?.type === 'Range') return
payload.preventDefault()
}

function onColorInput(e: Event): void {
const len = (e.target as HTMLInputElement).value.length
if (len < 7) (e.target as HTMLInputElement).value += '0'.repeat(6 - len)
Expand All @@ -79,6 +105,10 @@ function onChange(): void {
emit('change', props.value)
}

function focusTextInput(): void {
textInputEl.value?.focus()
}

function toggle(): void {
emit('toggle')
}
Expand Down
23 changes: 22 additions & 1 deletion src/components/text-field.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<template lang="pug">
.TextField(:data-inactive="props.inactive" @click="focus")
.TextField(
:data-inactive="props.inactive"
@mousedown="onMouseDown"
@mouseup="onMouseUp"
@contextmenu.stop="onContextMenu")
.body
.label {{translate(props.label)}}
TextInput(
Expand Down Expand Up @@ -44,6 +48,23 @@ const props = withDefaults(defineProps<TextFieldProps>(), { padding: 0, tabindex

const inputEl = ref<TextInputComponent | null>(null)

let rangeIsSelected = false

function onMouseDown(e: DOMEvent<MouseEvent>) {
rangeIsSelected = getSelection()?.type === 'Range'
if (e.detail > 1) e.preventDefault()
}

function onMouseUp(e: DOMEvent<MouseEvent>) {
if (rangeIsSelected || getSelection()?.type === 'Range') return
focus()
}

function onContextMenu(payload: PointerEvent) {
if (rangeIsSelected || getSelection()?.type === 'Range') return
payload.preventDefault()
}

function focus(): void {
inputEl.value?.focus()
}
Expand Down
3 changes: 3 additions & 0 deletions src/components/text-input.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
:data-valid="props.valid"
:data-wrong="state.wrongValueAnimation"
:data-width="props.width"
@contextmenu.stop
@mousedown.stop
@mouseup.stop
@animationend="onAnimationEnd")
.focus-fx
input(
Expand Down
21 changes: 20 additions & 1 deletion src/components/toggle-field.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
.ToggleField(
:data-inactive="props.inactive"
:data-loading="loading"
@click="toggle"
@mousedown="onMouseDown"
@mouseup="onMouseUp"
@contextmenu.stop="onContextMenu"
@keydown="onKeyDown")
.focus-fx
.body
Expand Down Expand Up @@ -39,6 +41,23 @@ const emit = defineEmits(['toggle', 'update:value'])
const props = defineProps<ToggleFieldProps>()
const inputComponent = ref<ToggleInputComponent | null>(null)

let rangeIsSelected = false

function onMouseDown(e: DOMEvent<MouseEvent>) {
rangeIsSelected = getSelection()?.type === 'Range'
if (e.detail > 1) e.preventDefault()
}

function onMouseUp(e: DOMEvent<MouseEvent>) {
if (rangeIsSelected || getSelection()?.type === 'Range') return
toggle()
}

function onContextMenu(payload: PointerEvent) {
if (rangeIsSelected || getSelection()?.type === 'Range') return
payload.preventDefault()
}

function toggle(): void {
if (props.inactive) return
if (props.loading) return
Expand Down
Loading