Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hooks for File #288

Closed
wants to merge 3 commits into from
Closed
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
2 changes: 1 addition & 1 deletion spx-gui/src/components/editor/ProjectEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ import { provide, type InjectionKey, ref, watch, shallowReactive, computed, watc
import { Project } from '@/models/project'
import type { UserInfo } from '@/stores/user'
import SpxEditor from './SpxEditor.vue'
import SpxStage from './stage/SpxStage.vue'
import SpxStage from './preview/SpxStage.vue'
import EditorPanels from './panels/EditorPanels.vue'

const props = defineProps<{
Expand Down
4 changes: 3 additions & 1 deletion spx-gui/src/components/editor/SpxEditor.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
<template>
<SoundEditor v-if="editorCtx.selected?.type === 'sound'" />
<SpriteEditor v-if="editorCtx.selectedSprite != null" :sprite="editorCtx.selectedSprite" />
<SpriteEditor v-else-if="editorCtx.selectedSprite != null" :sprite="editorCtx.selectedSprite" />
<StageEditor v-else-if="editorCtx.selected?.type === 'stage'" :stage="editorCtx.project.stage" />
<div v-else>TODO</div>
</template>

<script setup lang="ts">
import SoundEditor from './sound/SoundEditor.vue'
import SpriteEditor from './sprite/SpriteEditor.vue'
import StageEditor from './stage/StageEditor.vue'
import { useEditorCtx } from './ProjectEditor.vue'

const editorCtx = useEditorCtx()
Expand Down
11 changes: 3 additions & 8 deletions spx-gui/src/components/editor/panels/sprite/SpriteItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
</template>

<script setup lang="ts">
import { ref, effect, computed } from 'vue'
import { computed } from 'vue'
import { useFileUrl } from '@/utils/file'
import { Sprite } from '@/models/sprite'

const props = defineProps<{
Expand All @@ -19,13 +20,7 @@ const emit = defineEmits<{
remove: []
}>()

const imgSrc = ref<string | null>(null)

effect(async () => {
const img = props.sprite.costume?.img
imgSrc.value = img != null ? await img.url() : null // TODO: race condition
})

const imgSrc = useFileUrl(() => props.sprite.costume?.img)
const imgStyle = computed(() => imgSrc.value && { backgroundImage: `url("${imgSrc.value}")` })
</script>

Expand Down
37 changes: 0 additions & 37 deletions spx-gui/src/components/editor/panels/stage/BackdropList.vue

This file was deleted.

50 changes: 0 additions & 50 deletions spx-gui/src/components/editor/panels/stage/StageEdit.vue

This file was deleted.

115 changes: 111 additions & 4 deletions spx-gui/src/components/editor/panels/stage/StagePanel.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,122 @@
<template>
<div class="stage-panel">
<StageEdit />
</div>
<section class="stage-panel">
<header class="header">
{{ _t({ en: 'Stage', zh: '舞台' }) }}
</header>
<main class="main">
<NDropdown trigger="hover" :options="options" @select="handleOption">
<div class="overview" :class="{ active: isSelected }" @click="select">
<div class="img" :style="imgStyle"></div>
</div>
</NDropdown>
</main>
<footer>
<!-- Entry for "add to library", its appearance or position may change later -->
<NButton v-if="backdrop != null" @click="handleAddToLibrary()">Add to library</NButton>
</footer>
</section>
</template>

<script setup lang="ts">
import StageEdit from './StageEdit.vue'
import { computed } from 'vue'
import { NDropdown, NButton } from 'naive-ui'
import { useAddAssetFromLibrary, useAddAssetToLibrary } from '@/components/library'
import { useMessageHandle } from '@/utils/exception'
import { useI18n } from '@/utils/i18n'
import { AssetType } from '@/apis/asset'
import { selectImg, useFileUrl } from '@/utils/file'
import { fromNativeFile } from '@/models/common/file'
import { Backdrop } from '@/models/backdrop'
import { stripExt } from '@/utils/path'
import { useEditorCtx } from '../../ProjectEditor.vue'

const { t } = useI18n()
const editorCtx = useEditorCtx()

const isSelected = computed(() => editorCtx.selected?.type === 'stage')

function select() {
editorCtx.select('stage')
}

const backdrop = computed(() => editorCtx.project.stage.backdrop)
const imgSrc = useFileUrl(() => backdrop.value?.img)
const imgStyle = computed(() => imgSrc.value && { backgroundImage: `url("${imgSrc.value}")` })

const handleUpload = useMessageHandle(
async () => {
const img = await selectImg()
const file = fromNativeFile(img)
const backdrop = new Backdrop(stripExt(img.name), file)
editorCtx.project.stage.setBackdrop(backdrop)
},
{ en: 'Upload failed', zh: '上传失败' }
)

const addAssetFromLibrary = useAddAssetFromLibrary()

const options = computed(() => {
return [
{
key: 'upload',
label: t({ en: 'Upload', zh: '上传' }),
handler: handleUpload
},
{
key: 'fromLibrary',
label: t({ en: 'Choose from asset library', zh: '从素材库选择' }),
handler: () => addAssetFromLibrary(editorCtx.project, AssetType.Backdrop)
}
]
})

function handleOption(key: string) {
for (const option of options.value) {
if (option.key === key) {
option.handler()
return
}
}
throw new Error(`unknown option key: ${key}`)
}

const addToLibrary = useAddAssetToLibrary()

function handleAddToLibrary() {
addToLibrary(backdrop.value!)
}
</script>

<style scoped lang="scss">
.stage-panel {
border: 1px solid #333;
}

.header {
padding: 0.5em 1em;
}

.overview {
display: flex;
flex-direction: column;
width: 80px;
height: fit-content;
padding: 6px;
position: relative;
align-items: center;
border: 1px solid #333;

&.active {
border-color: yellow;
background-color: yellow;
}
}

.img {
width: 100%;
height: 68px;
background-position: center;
background-repeat: no-repeat;
background-size: contain;
}
</style>
2 changes: 1 addition & 1 deletion spx-gui/src/components/editor/panels/todo/AssetAddBtn.vue
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ const beforeUpload = async (
message.error(t('message.image'))
return false
}
editorCtx.project.stage.addBackdrop(new Backdrop(assetName, file))
editorCtx.project.stage.setBackdrop(new Backdrop(assetName, file))
break
}
case 'sound': {
Expand Down
Loading
Loading