172 lines
5.0 KiB
Svelte
172 lines
5.0 KiB
Svelte
<script lang="ts">
|
|
import type { data } from '../wailsjs/go/models.js'
|
|
import Editor2D from './sections/Editor2D.svelte'
|
|
import Importer from './sections/Importer.svelte';
|
|
import PaletteSection from './sections/Palette.svelte'
|
|
import FloatingPanel from './components/FloatingPanel.svelte'
|
|
import { Palette, PaletteEntry, defaultPalette } from './types/palette'
|
|
|
|
import { LoadedFile } from './types/file.ts'
|
|
|
|
import "carbon-components-svelte/css/all.css"
|
|
import { Tabs, Tab, TabContent, Theme, Button, Modal, Truncate } from "carbon-components-svelte"
|
|
import { ComposedModal } from "carbon-components-svelte"
|
|
|
|
import { OverflowMenu, OverflowMenuItem } from "carbon-components-svelte"
|
|
|
|
import { Close } from "carbon-icons-svelte"
|
|
import StackPreview from './sections/StackPreview.svelte'
|
|
import type { Canvas } from './types/canvas'
|
|
|
|
let theme: 'white'|'g10'|'g80'|'g90'|'g100' = 'g90'
|
|
|
|
let palette: Palette = defaultPalette()
|
|
let primaryColorIndex: number = 1
|
|
let secondaryColorIndex: number = 0
|
|
|
|
let showImport: boolean = false
|
|
let importValid: boolean = false
|
|
let importFile: data.StackistFileV1 = null
|
|
let importFilepath: string = ''
|
|
let importCanvas: Canvas = null
|
|
|
|
let showPreview: boolean = false
|
|
|
|
let refresh = {}
|
|
|
|
let files: LoadedFile[] = []
|
|
let focusedFileIndex: number = -1
|
|
let focusedFile: LoadedFile = null
|
|
$: focusedFile = files[focusedFileIndex] ?? null
|
|
$: console.log(focusedFile)
|
|
|
|
function selectFile(file: LoadedFile, index: number) {
|
|
focusedFileIndex = index
|
|
refresh = {}
|
|
}
|
|
|
|
function engageImport() {
|
|
if (importValid) {
|
|
files = [...files, new LoadedFile({filepath: importFilepath, title: importFilepath, canvas: importCanvas, data: importFile})]
|
|
console.log(files)
|
|
}
|
|
showImport = false
|
|
}
|
|
function closeFile(index: number) {
|
|
files = files.filter((_,i)=>i!==index)
|
|
}
|
|
</script>
|
|
|
|
<Theme bind:theme/>
|
|
<main>
|
|
<menu>
|
|
<OverflowMenu size="sm">
|
|
<div slot="menu">File</div>
|
|
<OverflowMenuItem text="New"/>
|
|
<OverflowMenuItem text="Open..."/>
|
|
<OverflowMenuItem text="Import from PNG..." on:click={() => showImport = true}/>
|
|
<OverflowMenuItem text="Save"/>
|
|
<OverflowMenuItem text="Save As..."/>
|
|
<OverflowMenuItem hasDivider danger text="Quit"/>
|
|
</OverflowMenu>
|
|
<OverflowMenu size="sm">
|
|
<div slot="menu">Edit</div>
|
|
<OverflowMenuItem text="Undo" on:click={() => focusedFile?.undo()} disabled={!focusedFile?.canUndo()}/>
|
|
<OverflowMenuItem text="Redo" on:click={() => focusedFile?.redo()} disabled={!focusedFile?.canRedo()}/>
|
|
</OverflowMenu>
|
|
<OverflowMenu size="sm">
|
|
<div slot="menu">Windows</div>
|
|
<OverflowMenuItem text="Preview" on:click={() => showPreview = true}/>
|
|
</OverflowMenu>
|
|
</menu>
|
|
<section class='content'>
|
|
<section class='left'>
|
|
<PaletteSection bind:palette bind:primaryColorIndex bind:secondaryColorIndex file={focusedFile} />
|
|
</section>
|
|
<section class='middle'>
|
|
<Tabs>
|
|
{#each files as file, index}
|
|
<Tab on:click={()=>selectFile(file, index)}>
|
|
<span class='tab'>
|
|
<span>{file.title}</span>
|
|
<Button size="small" kind="ghost" iconDescription="close" icon={Close} href="#" on:click={(e)=>{e.preventDefault();closeFile(index)}} />
|
|
</span>
|
|
</Tab>
|
|
{/each}
|
|
<svelte:fragment slot="content">
|
|
{#each files as file}
|
|
<TabContent>
|
|
<Editor2D bind:file={file} refresh={refresh} primaryColorIndex={primaryColorIndex} secondaryColorIndex={secondaryColorIndex} />
|
|
</TabContent>
|
|
{/each}
|
|
</svelte:fragment>
|
|
</Tabs>
|
|
</section>
|
|
{#if showPreview}
|
|
<FloatingPanel
|
|
label="Stack Preview"
|
|
noPadding
|
|
bind:open={showPreview}
|
|
>
|
|
<StackPreview files={files} />
|
|
</FloatingPanel>
|
|
{/if}
|
|
</section>
|
|
</main>
|
|
<ComposedModal bind:open={showImport} size="sm" preventCloseOnClickOutside on:click:button--primary={engageImport}>
|
|
<Importer
|
|
bind:open={showImport}
|
|
bind:valid={importValid}
|
|
bind:file={importFile}
|
|
bind:filepath={importFilepath}
|
|
bind:canvas={importCanvas}
|
|
/>
|
|
</ComposedModal>
|
|
|
|
<style>
|
|
main {
|
|
width: 100%;
|
|
height: 100%;
|
|
display: grid;
|
|
grid-template-rows: auto minmax(0, 1fr);
|
|
}
|
|
menu {
|
|
display: flex;
|
|
flex-direction: row;
|
|
justify-content: flex-start;
|
|
}
|
|
:global(menu > button) {
|
|
width: 4rem !important;
|
|
color: var(--cds-text-02, #c6c6c6);
|
|
}
|
|
.content {
|
|
display: grid;
|
|
grid-template-columns: 1fr 4fr;
|
|
grid-template-rows: minmax(0, 1fr);
|
|
}
|
|
.left {
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: flex-start;
|
|
}
|
|
.middle {
|
|
display: grid;
|
|
grid-template-rows: auto minmax(0, 1fr);
|
|
}
|
|
.tab {
|
|
display: inline-grid;
|
|
grid-template-columns: 9em minmax(0, 1fr);
|
|
grid-template-rows: minmax(0, 1fr);
|
|
width: 100%;
|
|
height: 100%;
|
|
overflow: hidden;
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
}
|
|
.tab span {
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
</style>
|