2023-02-17 19:00:27 +00:00
|
|
|
<template>
|
|
|
|
<SVGRect :rectangle="door.position" :focused="editing" />
|
2023-09-06 16:25:35 +00:00
|
|
|
<foreignObject :x="Math.round(parent_aspect_ratio * door.position.left)" :y="door.position.top"
|
|
|
|
:width="Math.round(parent_aspect_ratio * door.position.width)" :height="door.position.height"
|
|
|
|
:style="`transform: scaleX(${1 / parent_aspect_ratio})`">
|
|
|
|
<div xmlns="http://www.w3.org/1999/xhtml" class="is-flex is-align-items-center is-justify-content-center"
|
|
|
|
@click.left="on_click">
|
|
|
|
<input v-if="editing" v-model="day_str" ref="day_input" class="input is-large" type="number" min="-1"
|
|
|
|
placeholder="Tag" @keydown="on_keydown" />
|
2023-02-18 00:43:07 +00:00
|
|
|
<div v-else class="is-size-1 has-text-weight-bold">
|
|
|
|
<template v-if="door.day >= 0">{{ door.day }}</template>
|
2023-02-17 19:00:27 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</foreignObject>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script lang="ts">
|
|
|
|
import { Options, Vue } from "vue-class-component";
|
|
|
|
import { Door } from "./calendar";
|
|
|
|
|
|
|
|
import SVGRect from "../rects/SVGRect.vue";
|
|
|
|
|
|
|
|
@Options({
|
|
|
|
components: {
|
|
|
|
SVGRect,
|
|
|
|
},
|
|
|
|
props: {
|
|
|
|
door: Door,
|
|
|
|
},
|
|
|
|
emits: ["update:door"],
|
|
|
|
})
|
|
|
|
export default class extends Vue {
|
2023-09-06 16:25:35 +00:00
|
|
|
public door!: Door;
|
2023-02-17 19:00:27 +00:00
|
|
|
|
2023-09-06 16:25:35 +00:00
|
|
|
public day_str = "";
|
|
|
|
public editing = false;
|
2023-02-17 19:00:27 +00:00
|
|
|
private refreshKey = 0;
|
|
|
|
|
2023-02-18 00:43:07 +00:00
|
|
|
declare $refs: {
|
|
|
|
day_input: HTMLInputElement | null | undefined;
|
|
|
|
};
|
|
|
|
|
2023-02-17 19:00:27 +00:00
|
|
|
private refresh() {
|
|
|
|
window.setTimeout(() => {
|
|
|
|
// don't loop endlessly
|
|
|
|
if (this.refreshKey < 10000) {
|
|
|
|
this.refreshKey++;
|
|
|
|
}
|
|
|
|
}, 100);
|
|
|
|
}
|
|
|
|
|
2023-09-06 16:25:35 +00:00
|
|
|
public get parent_aspect_ratio(): number {
|
2023-02-17 19:00:27 +00:00
|
|
|
this.refreshKey; // read it just to force recompute on change
|
|
|
|
|
|
|
|
if (!(this.$el instanceof Text) || this.$el.parentElement === null) {
|
|
|
|
this.refresh();
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
const parent = this.$el.parentElement;
|
|
|
|
const result = parent.clientWidth / parent.clientHeight;
|
|
|
|
|
|
|
|
// force recompute for suspicious results
|
|
|
|
if (result === 0 || result === Infinity) {
|
|
|
|
this.refresh();
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
private toggle_editing() {
|
|
|
|
this.day_str = String(this.door.day);
|
2023-09-07 00:34:42 +00:00
|
|
|
this.editing = !this.editing;
|
2023-02-17 19:00:27 +00:00
|
|
|
}
|
|
|
|
|
2023-09-06 16:25:35 +00:00
|
|
|
public on_click(event: MouseEvent) {
|
2023-02-18 00:43:07 +00:00
|
|
|
if (event.target === null || !(event.target instanceof HTMLDivElement)) {
|
2023-02-17 19:00:27 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-02-18 00:43:07 +00:00
|
|
|
if (!this.editing) {
|
|
|
|
const day_input_focus = () => {
|
|
|
|
if (this.$refs.day_input instanceof HTMLInputElement) {
|
2023-09-04 21:27:37 +00:00
|
|
|
this.$refs.day_input.select();
|
2023-02-18 00:43:07 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.$nextTick(day_input_focus);
|
|
|
|
};
|
|
|
|
day_input_focus();
|
|
|
|
} else {
|
2023-09-07 00:34:42 +00:00
|
|
|
this.door.day = this.day_str;
|
2023-02-17 19:00:27 +00:00
|
|
|
}
|
|
|
|
|
2023-02-18 00:43:07 +00:00
|
|
|
this.toggle_editing();
|
2023-02-17 19:00:27 +00:00
|
|
|
}
|
|
|
|
|
2023-09-06 16:25:35 +00:00
|
|
|
public on_keydown(event: KeyboardEvent) {
|
2023-02-17 19:00:27 +00:00
|
|
|
if (!this.editing) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (event.key === "Enter") {
|
2023-09-07 00:34:42 +00:00
|
|
|
this.door.day = this.day_str;
|
2023-02-17 19:00:27 +00:00
|
|
|
this.toggle_editing();
|
|
|
|
} else if (event.key === "Delete") {
|
|
|
|
this.door.day = -1;
|
|
|
|
this.toggle_editing();
|
|
|
|
} else if (event.key === "Escape") {
|
|
|
|
this.toggle_editing();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public beforeUnmount() {
|
|
|
|
this.$emit("update:door", this.door);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
foreignObject {
|
|
|
|
cursor: pointer;
|
|
|
|
|
2023-09-06 16:25:35 +00:00
|
|
|
>div {
|
2023-02-17 19:00:27 +00:00
|
|
|
color: red;
|
|
|
|
height: inherit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</style>
|