mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-16 06:38:03 +08:00
* Add AI Artist layer * WIP add a button to download the rendered folder under an AI Artist layer * Successfully download the correct image * Break out image downloading JS into helper function * Change file download from using data URLs to blob URLs * WIP rasterize to blob * Remove dimensions from AI Artist layer * Successfully draw rasterized image on layer after calculation * Working txt2img generation based on user prompt * Add img2img and the main parameters * Fix ability to rasterize multi-depth documents with blob URL images by switching them to base64 * Fix test * Rasterize with artboard background color * Allow aspect ratio stretch of AI Artist images * Add automatic resolution choosing * Add a terminate button, and make the lifecycle more robust * Add negative prompt * Add range bounds for parameter inputs * Add seed * Add tiling and restore faces * Add server status check, server hostname customization, and resizing layer to fit AI Artist resolution * Fix background color of infinite canvas rasterization * Escape prompt text sent in the JSON * Revoke blob URLs when cleared/replaced to reduce memory leak * Fix welcome screen logo color * Add PreferencesMessageHandler * Add persistent storage of preferences * Fix crash introduced in previous commit when moving mouse on page load * Add tooltips to the AI Artist layer properties * Integrate AI Artist tool into the raster section of the tool shelf * Add a refresh button to the connection status * Fix crash when generating and switching to a different document tab * Add persistent image storage to AI Artist layers and fix duplication bugs * Add a generate with random seed button * Simplify and standardize message names * Majorly improve robustness of networking code * Fix race condition causing default server hostname to show disconnected when app loads with AI Artist layer selected (probably, not confirmed fixed) * Clean up messages and function calls by changing arguments into structs * Update API to more recent server commit * Add support for picking the sampling method * Add machinery for filtering selected layers with type * Replace placeholder button icons * Improve the random icon by tilting the dice * Use selected_layers() instead of repeating that code * Fix borrow error * Change message flow in progress towards fixing #797 * Allow loading image on non-active document (fixes #797) * Reduce code duplication with rasterization * Add AI Artist tool and layer icons, and remove ugly node layer icon style * Rename "AI Artist" codename to "Imaginate" feature name Co-authored-by: otdavies <oliver@psyfer.io> Co-authored-by: 0hypercube <0hypercube@gmail.com>
88 lines
2.5 KiB
Vue
88 lines
2.5 KiB
Vue
<template>
|
|
<FieldInput
|
|
class="text-input"
|
|
v-model:value="text"
|
|
:label="label"
|
|
:spellcheck="true"
|
|
:disabled="disabled"
|
|
:tooltip="tooltip"
|
|
:style="minWidth > 0 ? `min-width: ${minWidth}px` : ''"
|
|
@textFocused="() => onTextFocused()"
|
|
@textChanged="() => onTextChanged()"
|
|
@cancelTextChange="() => onCancelTextChange()"
|
|
ref="fieldInput"
|
|
></FieldInput>
|
|
</template>
|
|
|
|
<style lang="scss">
|
|
.text-input {
|
|
input {
|
|
text-align: left;
|
|
}
|
|
}
|
|
</style>
|
|
|
|
<script lang="ts">
|
|
import { defineComponent, type PropType } from "vue";
|
|
|
|
import FieldInput from "@/components/widgets/inputs/FieldInput.vue";
|
|
|
|
export default defineComponent({
|
|
emits: ["update:value", "commitText"],
|
|
props: {
|
|
value: { type: String as PropType<string>, required: true },
|
|
label: { type: String as PropType<string>, required: false },
|
|
disabled: { type: Boolean as PropType<boolean>, default: false },
|
|
minWidth: { type: Number as PropType<number>, default: 0 },
|
|
tooltip: { type: String as PropType<string | undefined>, required: false },
|
|
},
|
|
data() {
|
|
return {
|
|
editing: false,
|
|
};
|
|
},
|
|
computed: {
|
|
text: {
|
|
get() {
|
|
return this.value;
|
|
},
|
|
set(value: string) {
|
|
this.$emit("update:value", value);
|
|
},
|
|
},
|
|
},
|
|
methods: {
|
|
onTextFocused() {
|
|
this.editing = true;
|
|
|
|
const inputElement = (this.$refs.fieldInput as typeof FieldInput).$refs.input as HTMLInputElement;
|
|
// Setting the value directly is required to make `inputElement.select()` work
|
|
inputElement.value = this.text;
|
|
inputElement.select();
|
|
},
|
|
// Called only when `value` is changed from the <input> element via user input and committed, either with the
|
|
// enter key (via the `change` event) or when the <input> element is defocused (with the `blur` event binding)
|
|
onTextChanged() {
|
|
// The `inputElement.blur()` call in `onCancelTextChange()` causes itself to be run again, so this if statement skips a second run
|
|
if (!this.editing) return;
|
|
|
|
this.onCancelTextChange();
|
|
|
|
// TODO: Find a less hacky way to do this
|
|
const inputElement = (this.$refs.fieldInput as typeof FieldInput).$refs.input as HTMLInputElement;
|
|
this.$emit("commitText", inputElement.value);
|
|
|
|
// Required if value is not changed by the parent component upon update:value event
|
|
inputElement.value = this.value;
|
|
},
|
|
onCancelTextChange() {
|
|
this.editing = false;
|
|
|
|
const inputElement = (this.$refs.fieldInput as typeof FieldInput).$refs.input as HTMLInputElement;
|
|
inputElement.blur();
|
|
},
|
|
},
|
|
components: { FieldInput },
|
|
});
|
|
</script>
|