mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-17 15:28:04 +08:00
* wasm: do the async initialization only once This allows the rest of the app to access wasm synchronously. This allows removing of a global. * provide the wasm via vue provide/inject. There's still code directly accessing the wasm. That will be changed later. * MenuBarInput: use injected wasm instead of the global instance * Let the App handle event listeners * move stateful modules into state/ * state/fullscreen: create per instance * App: load the initial document list on mount. This got lost a few commits ago. Now it's back. * state/dialog: create per instance * util/input: remove dependency on global dialog instance * state/documents: create per instance * reponse-handler: move into EditorWasm * comingSoon: move into dialog * wasm: allow instantiating multiple editors * input handlers: do not look at canvases outside the mounted App * input: listen on the container instead of the window when possible * - removed proxy from wasm-loader - integrated with js-dispatcher - state functions to classes - integrated some upstream changes * fix errors caused by merge * Getting closer: - added global state to track all instances - fix fullscreen close trigger - wasm-loader is statefull - panic across instanes * - fix outline while using editor - removed circular import rule - added editorInstance to js message constructor * - changed input handler to a class - still need a better way of handeling it in App.vue * - fixed single instance of inputManager to weakmap * - fix no-explicit-any in a few places - removed global state from input.ts * simplified two long lines * removed global state * removed $data from App * add mut self to functions in api.rs * Update Workspace.vue remove outdated import * fixed missing import * Changes throughout code review; note this causes some bugs to be fixed in a later commit * PR review round 1 * - fix coming soon bugs - changed folder structure * moved declaration to .d.ts * - changed from classes to functions - moved decs back to app.vue * removed need to export js function to rust * changed folder structure * fixed indentation breaking multiline strings * Fix eslint rule to whitelist @/../ * Simplify strip-indents implementation * replace type assertions with better annotations or proper runtime checks * Small tweaks and code rearranging improvements after second code review pass * maybe fix mouse events * Add back preventDefault for mouse scroll * code review round 2 * Comment improvements * -removed runtime checks - fixed layers not showing * - extened proxy to cover classes - stopped multiple panics from logging - Stop wasm-bindgen from mut ref counting our struct * cleaned up messageConstructors exports * Fix input and fullscreen regressions Co-authored-by: Max Fisher <maxmfishernj@gmail.com> Co-authored-by: mfish33 <32677537+mfish33@users.noreply.github.com> Co-authored-by: Keavon Chambers <keavon@keavon.com>
154 lines
4.5 KiB
Vue
154 lines
4.5 KiB
Vue
<template>
|
|
<div class="swatch-pair">
|
|
<div class="secondary swatch">
|
|
<button @click="clickSecondarySwatch" ref="secondaryButton" data-hover-menu-spawner></button>
|
|
<FloatingMenu :type="MenuType.Popover" :direction="MenuDirection.Right" horizontal ref="secondarySwatchFloatingMenu">
|
|
<ColorPicker @update:color="secondaryColorChanged" :color="secondaryColor" />
|
|
</FloatingMenu>
|
|
</div>
|
|
<div class="primary swatch">
|
|
<button @click="clickPrimarySwatch" ref="primaryButton" data-hover-menu-spawner></button>
|
|
<FloatingMenu :type="MenuType.Popover" :direction="MenuDirection.Right" horizontal ref="primarySwatchFloatingMenu">
|
|
<ColorPicker @update:color="primaryColorChanged" :color="primaryColor" />
|
|
</FloatingMenu>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style lang="scss">
|
|
.swatch-pair {
|
|
display: flex;
|
|
// Reversed order of elements paired with `column-reverse` allows primary to overlap secondary without relying on `z-index`
|
|
flex-direction: column-reverse;
|
|
|
|
.swatch {
|
|
width: 28px;
|
|
height: 28px;
|
|
margin: 0 2px;
|
|
position: relative;
|
|
|
|
button {
|
|
--swatch-color: #ffffff;
|
|
width: 100%;
|
|
height: 100%;
|
|
border-radius: 50%;
|
|
border: 2px var(--color-7-middlegray) solid;
|
|
box-shadow: 0 0 0 2px var(--color-3-darkgray);
|
|
margin: 0;
|
|
padding: 0;
|
|
box-sizing: border-box;
|
|
outline: none;
|
|
background: linear-gradient(45deg, #cccccc 25%, transparent 25%, transparent 75%, #cccccc 75%), linear-gradient(45deg, #cccccc 25%, transparent 25%, transparent 75%, #cccccc 75%),
|
|
linear-gradient(#ffffff, #ffffff);
|
|
background-size: 16px 16px;
|
|
background-position: 0 0, 8px 8px;
|
|
overflow: hidden;
|
|
|
|
&::before {
|
|
content: "";
|
|
display: block;
|
|
width: 100%;
|
|
height: 100%;
|
|
background: var(--swatch-color);
|
|
}
|
|
}
|
|
|
|
.floating-menu {
|
|
top: 50%;
|
|
right: -2px;
|
|
}
|
|
|
|
&.primary {
|
|
margin-bottom: -8px;
|
|
}
|
|
}
|
|
}
|
|
</style>
|
|
|
|
<script lang="ts">
|
|
import { defineComponent } from "vue";
|
|
|
|
import { rgbToDecimalRgb, RGB } from "@/utilities/color";
|
|
|
|
import ColorPicker from "@/components/widgets/floating-menus/ColorPicker.vue";
|
|
import FloatingMenu, { MenuDirection, MenuType } from "@/components/widgets/floating-menus/FloatingMenu.vue";
|
|
import { UpdateWorkingColors } from "@/dispatcher/js-messages";
|
|
|
|
export default defineComponent({
|
|
inject: ["editor"],
|
|
components: {
|
|
FloatingMenu,
|
|
ColorPicker,
|
|
},
|
|
props: {},
|
|
methods: {
|
|
clickPrimarySwatch() {
|
|
this.getRef<typeof FloatingMenu>("primarySwatchFloatingMenu").setOpen();
|
|
this.getRef<typeof FloatingMenu>("secondarySwatchFloatingMenu").setClosed();
|
|
},
|
|
|
|
clickSecondarySwatch() {
|
|
this.getRef<typeof FloatingMenu>("secondarySwatchFloatingMenu").setOpen();
|
|
this.getRef<typeof FloatingMenu>("primarySwatchFloatingMenu").setClosed();
|
|
},
|
|
|
|
getRef<T>(name: string) {
|
|
return this.$refs[name] as T;
|
|
},
|
|
|
|
primaryColorChanged(color: RGB) {
|
|
this.primaryColor = color;
|
|
this.updatePrimaryColor();
|
|
},
|
|
|
|
secondaryColorChanged(color: RGB) {
|
|
this.secondaryColor = color;
|
|
this.updateSecondaryColor();
|
|
},
|
|
|
|
async updatePrimaryColor() {
|
|
let color = this.primaryColor;
|
|
const button = this.getRef<HTMLButtonElement>("primaryButton");
|
|
button.style.setProperty("--swatch-color", `rgba(${color.r}, ${color.g}, ${color.b}, ${color.a})`);
|
|
|
|
color = rgbToDecimalRgb(this.primaryColor);
|
|
this.editor.instance.update_primary_color(color.r, color.g, color.b, color.a);
|
|
},
|
|
|
|
async updateSecondaryColor() {
|
|
let color = this.secondaryColor;
|
|
const button = this.getRef<HTMLButtonElement>("secondaryButton");
|
|
button.style.setProperty("--swatch-color", `rgba(${color.r}, ${color.g}, ${color.b}, ${color.a})`);
|
|
|
|
color = rgbToDecimalRgb(this.secondaryColor);
|
|
this.editor.instance.update_secondary_color(color.r, color.g, color.b, color.a);
|
|
},
|
|
},
|
|
data() {
|
|
return {
|
|
MenuDirection,
|
|
MenuType,
|
|
primaryColor: { r: 0, g: 0, b: 0, a: 1 },
|
|
secondaryColor: { r: 255, g: 255, b: 255, a: 1 },
|
|
};
|
|
},
|
|
mounted() {
|
|
this.editor.dispatcher.subscribeJsMessage(UpdateWorkingColors, (updateWorkingColors) => {
|
|
const { primary, secondary } = updateWorkingColors;
|
|
|
|
this.primaryColor = primary.toRgba();
|
|
this.secondaryColor = secondary.toRgba();
|
|
|
|
const primaryButton = this.getRef<HTMLButtonElement>("primaryButton");
|
|
primaryButton.style.setProperty("--swatch-color", primary.toRgbaCSS());
|
|
|
|
const secondaryButton = this.getRef<HTMLButtonElement>("secondaryButton");
|
|
secondaryButton.style.setProperty("--swatch-color", secondary.toRgbaCSS());
|
|
});
|
|
|
|
this.updatePrimaryColor();
|
|
this.updateSecondaryColor();
|
|
},
|
|
});
|
|
</script>
|