Add windows menu opts; adjust data format

main
kts of kettek 2024-02-13 13:39:22 -08:00
parent 875fe06d62
commit 96a5e128d7
9 changed files with 115 additions and 36 deletions

6
app.go
View File

@ -31,11 +31,11 @@ func (a *App) Greet(name string) string {
return fmt.Sprintf("Hello %s, It's show time!", name)
}
func (a *App) Load(name string) *data.StackistFile {
return &data.StackistFile{}
func (a *App) Load(name string) *data.StackistFileV1 {
return &data.StackistFileV1{}
}
func (a *App) Save(name string, file *data.StackistFile) error {
func (a *App) Save(name string, file *data.StackistFileV1) error {
b, err := json.Marshal(file)
if err != nil {
return err

View File

@ -26,8 +26,10 @@
let showImport: boolean = false
let importValid: boolean = false
let importImage: HTMLImageElement = null
let importFile: data.StackistFile = null
let importFile: data.StackistFileV1 = null
let importFilepath: string = ''
let showPreview: boolean = false
let refresh = {}
@ -53,7 +55,7 @@
<Theme bind:theme/>
<main>
<menu>
<OverflowMenu size="sm">
<OverflowMenu size="sm" iconClass='shitcuck' menuOptionsClass='dickfuck'>
<div slot="menu">File</div>
<OverflowMenuItem text="New"/>
<OverflowMenuItem text="Open..."/>
@ -62,6 +64,10 @@
<OverflowMenuItem text="Save As..."/>
<OverflowMenuItem hasDivider danger text="Quit"/>
</OverflowMenu>
<OverflowMenu size="sm">
<div slot="menu">Windows</div>
<OverflowMenuItem text="Preview" on:click={() => showPreview = true}/>
</OverflowMenu>
</menu>
<section class='content'>
<section class='left'>
@ -86,12 +92,15 @@
</svelte:fragment>
</Tabs>
</section>
<FloatingPanel
label="Stack Preview"
noPadding
>
<StackPreview files={files} />
</FloatingPanel>
{#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}>
@ -111,6 +120,15 @@
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;

View File

@ -5,18 +5,62 @@
ModalFooter,
} from "carbon-components-svelte"
import {
Close
} from 'carbon-icons-svelte'
export let title: string = "Untitled"
export let label: string = "Untitled"
export let noPadding: boolean = false
export let open: boolean = false
function drag(node) {
let dragging: boolean = false
let x: number = 0
let y: number = 0
node.addEventListener('mousedown', start)
window.addEventListener('mouseup', stop)
window.addEventListener('mouseleave', stop)
window.addEventListener('mousemove', move)
function start(e: MouseEvent) {
dragging = true
x = e.clientX
y = e.clientY
node.style.cursor = 'grabbing'
document.body.style.cursor = 'grabbing'
document.body.style.userSelect = 'none'
}
function stop(e: MouseEvent) {
dragging = false
node.style.cursor = 'auto'
document.body.style.cursor = 'auto'
document.body.style.userSelect = 'auto'
}
function move(e: MouseEvent) {
if (!dragging) return
let dx = e.clientX - x
let dy = e.clientY - y
x = e.clientX
y = e.clientY
node.style.left = parseInt(node.style.left) + dx + 'px'
node.style.top = parseInt(node.style.top) + dy + 'px'
}
}
</script>
<dialog>
<dialog use:drag style="left: 100px; top: 100px;">
<header class='bx--modal-header'>
<h2 class='bx--modal-header__label bx--type-delta'>{label}</h2>
<button class='bx--modal-close' aria-label='Close' title='Close' on:click={()=>{open=false}}>
<Close/>
</button>
</header>
<section class='bx--modal-content {noPadding?'-noPadding':''}'>
<section class='bx--modal-content {noPadding?'-noPadding':''}' on:mousedown={e=>e.stopPropagation()}>
<slot/>
</section>
</dialog>
@ -24,16 +68,28 @@
<style>
dialog {
position: fixed;
left: 100;
top: 100;
background-color: var(--cds-ui-01, #f4f4f4);
display: grid;
grid-template-columns: 100%;
grid-template-rows: auto 1fr auto;
outline: 3px solid rgba(0, 0, 0, 0);
outline-offset: -3px;
box-shadow: 3px 3px 10px rgba(0, 0, 0, 0.5);
padding: 0;
width: 40rem;
}
header {
padding: var(--cds-spacing-03, 1rem);
}
header button {
width: 2rem;
height: 2rem;
right: 0;
top: 0;
padding: 0rem;
}
section.-noPadding {
padding: 0 !important;
margin-bottom: var(--cds-spacing-03, 1rem);
}
</style>

View File

@ -28,7 +28,7 @@
let width: number = 16
let height: number = 16
let rowBasedFrames: boolean = true
export let file: data.StackistFile
export let file: data.StackistFileV1
export let filepath: string = ''
export let img: HTMLImageElement
let path: string = ''
@ -98,15 +98,15 @@
}
function remakeFile() {
file = data.StackistFile.createFrom({
file = data.StackistFileV1.createFrom({
width: width,
height: height,
groups: {}
})
let cx = 0
let cy = 0
for (let gi = 0; gi < groups; gi++) {
let group: data.Group = data.Group.createFrom({
width: width,
height: height,
animations: {},
})
for (let ai = 0; ai < animations; ai++) {

View File

@ -7,6 +7,7 @@
let shownFiles: Record<string, boolean> = {}
let rotation: number = 0
let layerDistance: number = 1
let canvas: HTMLCanvasElement
function draw() {
@ -37,16 +38,16 @@
ctx.save()
ctx.translate(x, y)
ctx.rotate(rotation * Math.PI / 180)
ctx.drawImage(file.image, layer.x, layer.y, group.width, group.height, -group.width/2, -group.height/2, group.width, group.height)
ctx.drawImage(file.image, layer.x, layer.y, file.data.width, file.data.height, -file.data.width/2, -file.data.height/2, file.data.width, file.data.height)
ctx.restore()
y -= 1
y -= 1 * layerDistance
}
done = true
if (done) break
}
if (done) break
}
x += group.width
x += file.data.width
y = canvas.height/2
if (done) break
}
@ -74,7 +75,8 @@
</Column>
<Column>
<canvas bind:this={canvas}></canvas>
<Slider labelText="Rotation" min={0} max={360} step={1} bind:value={rotation} fullWidth></Slider>
<Slider labelText="Global Rotation" min={0} max={360} step={1} bind:value={rotation} fullWidth></Slider>
<Slider labelText="Global Layer Distance" min={0} max={2} step={0.1} bind:value={layerDistance} fullWidth></Slider>
</Column>
</Row>
</Grid>

View File

@ -4,5 +4,5 @@ export class LoadedFile {
filepath: string
title: string
image: HTMLImageElement
data: data.StackistFile
data: data.StackistFileV1
}

View File

@ -6,10 +6,10 @@ export function GetFilePath():Promise<string>;
export function Greet(arg1:string):Promise<string>;
export function Load(arg1:string):Promise<data.StackistFile>;
export function Load(arg1:string):Promise<data.StackistFileV1>;
export function OpenFileBytes(arg1:string):Promise<Array<number>>;
export function ReadBytes(arg1:string):Promise<Array<number>>;
export function Save(arg1:string,arg2:data.StackistFile):Promise<void>;
export function Save(arg1:string,arg2:data.StackistFileV1):Promise<void>;

View File

@ -80,8 +80,6 @@ export namespace data {
}
export class Group {
width: number;
height: number;
animations: {[key: string]: Animation};
static createFrom(source: any = {}) {
@ -90,8 +88,6 @@ export namespace data {
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.width = source["width"];
this.height = source["height"];
this.animations = this.convertValues(source["animations"], Animation, true);
}
@ -114,16 +110,22 @@ export namespace data {
}
}
export class StackistFile {
export class StackistFileV1 {
version: string;
groups: {[key: string]: Group};
width: number;
height: number;
static createFrom(source: any = {}) {
return new StackistFile(source);
return new StackistFileV1(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.version = source["version"];
this.groups = this.convertValues(source["groups"], Group, true);
this.width = source["width"];
this.height = source["height"];
}
convertValues(a: any, classs: any, asMap: boolean = false): any {

View File

@ -1,12 +1,13 @@
package data
type StackistFile struct {
Groups map[string]Group `json:"groups"`
type StackistFileV1 struct {
Version string `json:"version"` // The version of the file format.
Groups map[string]Group `json:"groups"`
Width int `json:"width"`
Height int `json:"height"`
}
type Group struct {
Width int `json:"width"`
Height int `json:"height"`
Animations map[string]Animation `json:"animations"`
}