Selection toolbox color picker button (#2637)

Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
Chenlei Hu
2025-02-19 15:25:46 -05:00
committed by GitHub
parent 08a6867c00
commit 6c6d86a30b
13 changed files with 299 additions and 8 deletions

View File

@@ -34,15 +34,20 @@ import ColorPicker from 'primevue/colorpicker'
import SelectButton from 'primevue/selectbutton'
import { computed, onMounted, ref, watch } from 'vue'
const { modelValue, colorOptions } = defineProps<{
const {
modelValue,
colorOptions,
allowCustom = true
} = defineProps<{
modelValue: string | null
colorOptions: { name: Exclude<string, '_custom'>; value: string }[]
allowCustom?: boolean
}>()
const customColorOption = { name: '_custom', value: '' }
const colorOptionsWithCustom = computed(() => [
...colorOptions,
customColorOption
...(allowCustom ? [customColorOption] : [])
])
const emit = defineEmits<{

View File

@@ -6,6 +6,7 @@
content: 'p-0 flex flex-row'
}"
>
<ColorPickerButton />
<Button
v-if="nodeSelected"
severity="secondary"
@@ -46,6 +47,7 @@ import Button from 'primevue/button'
import Panel from 'primevue/panel'
import { computed } from 'vue'
import ColorPickerButton from '@/components/graph/selectionToolbox/ColorPickerButton.vue'
import { useRefreshableSelection } from '@/composables/useRefreshableSelection'
import { useCommandStore } from '@/stores/commandStore'
import { useCanvasStore } from '@/stores/graphStore'

View File

@@ -0,0 +1,140 @@
<template>
<div class="relative">
<Button
severity="secondary"
text
@click="() => (showColorPicker = !showColorPicker)"
>
<template #icon>
<div class="flex items-center gap-1">
<i class="pi pi-circle-fill" :style="{ color: currentColor }" />
<i class="pi pi-chevron-down" :style="{ fontSize: '0.5rem' }" />
</div>
</template>
</Button>
<div
v-if="showColorPicker"
class="color-picker-container absolute -top-10 left-1/2"
>
<SelectButton
:modelValue="selectedColorOption"
@update:modelValue="applyColor"
:options="colorOptions"
optionLabel="name"
dataKey="value"
>
<template #option="{ option }">
<i
class="pi pi-circle-fill"
:style="{
color: isLightTheme ? option.value.light : option.value.dark
}"
v-tooltip.top="option.localizedName"
:data-testid="option.name"
/>
</template>
</SelectButton>
</div>
</div>
</template>
<script setup lang="ts">
import type { ColorOption as CanvasColorOption } from '@comfyorg/litegraph'
import { LGraphCanvas, LiteGraph, isColorable } from '@comfyorg/litegraph'
import Button from 'primevue/button'
import SelectButton from 'primevue/selectbutton'
import { computed, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n'
import { useCanvasStore } from '@/stores/graphStore'
import { useColorPaletteStore } from '@/stores/workspace/colorPaletteStore'
import { adjustColor } from '@/utils/colorUtil'
import { getItemsColorOption } from '@/utils/litegraphUtil'
const { t } = useI18n()
const canvasStore = useCanvasStore()
const colorPaletteStore = useColorPaletteStore()
const isLightTheme = computed(
() => colorPaletteStore.completedActivePalette.light_theme
)
const toLightThemeColor = (color: string) =>
adjustColor(color, { lightness: 0.5 })
const showColorPicker = ref(false)
type ColorOption = {
name: string
localizedName: string
value: {
dark: string
light: string
}
}
const NO_COLOR_OPTION: ColorOption = {
name: 'noColor',
localizedName: t('color.noColor'),
value: {
dark: LiteGraph.NODE_DEFAULT_BGCOLOR,
light: toLightThemeColor(LiteGraph.NODE_DEFAULT_BGCOLOR)
}
}
const colorOptions: ColorOption[] = [
NO_COLOR_OPTION,
...Object.entries(LGraphCanvas.node_colors).map(([name, color]) => ({
name,
localizedName: t(`color.${name}`),
value: {
dark: color.bgcolor,
light: toLightThemeColor(color.bgcolor)
}
}))
]
const selectedColorOption = ref<ColorOption | null>(null)
const applyColor = (colorOption: ColorOption | null) => {
const colorName = colorOption?.name ?? NO_COLOR_OPTION.name
const canvasColorOption =
colorName === NO_COLOR_OPTION.name
? null
: LGraphCanvas.node_colors[colorName]
for (const item of canvasStore.selectedItems) {
if (isColorable(item)) {
item.setColorOption(canvasColorOption)
}
}
canvasStore.canvas?.setDirty(true, true)
currentColorOption.value = canvasColorOption
showColorPicker.value = false
}
const currentColorOption = ref<CanvasColorOption | null>(null)
const currentColor = computed(() =>
currentColorOption.value
? isLightTheme.value
? toLightThemeColor(currentColorOption.value?.bgcolor)
: currentColorOption.value?.bgcolor
: null
)
watch(
() => canvasStore.selectedItems,
(newSelectedItems) => {
showColorPicker.value = false
selectedColorOption.value = null
currentColorOption.value = getItemsColorOption(newSelectedItems)
}
)
</script>
<style scoped>
.color-picker-container {
transform: translateX(-50%);
}
:deep(.p-togglebutton) {
@apply py-2 px-1;
}
</style>