Implement remove for var decls and expressions

This commit is contained in:
Garrett Mills 2022-04-09 21:10:17 -05:00
parent 1def341c03
commit ee6d20ddeb
7 changed files with 128 additions and 31 deletions

View File

@ -36,14 +36,6 @@ computed(() => value = getValueStatement())
.sidebar { .sidebar {
padding-left: 10px; padding-left: 10px;
} }
.edit-button {
border: none;
}
.edit-button:hover {
cursor: pointer;
}
</style> </style>
<template> <template>
@ -56,9 +48,18 @@ computed(() => value = getValueStatement())
</div> </div>
</div> </div>
<div class="sidebar"> <div class="sidebar">
<button class="edit-button" @click="() => $emit('edit')" title="Edit this expression"> <q-btn color="grey-7" round flat icon="more_vert">
<img src="../assets/edit.svg" alt="Edit" height="16"> <q-menu cover auto-close>
</button> <q-list>
<q-item clickable>
<q-item-section @click="() => $emit('edit')">Edit</q-item-section>
</q-item>
<q-item clickable>
<q-item-section @click="() => $emit('remove')">Remove</q-item-section>
</q-item>
</q-list>
</q-menu>
</q-btn>
</div> </div>
</div> </div>
</template> </template>

View File

@ -1,17 +1,15 @@
<script setup lang="ts"> <script setup lang="ts">
import {onMounted, ref} from 'vue' import {onMounted, ref} from 'vue'
import { v4 as uuidv4 } from 'uuid' import { v4 as uuidv4 } from 'uuid'
import WrapperBox from '../components/WrapperBox.vue'
import {MathPage} from '../support/page' import {MathPage} from '../support/page'
import {MathStatement} from '../support/parse' import {MathStatement} from '../support/parse'
import Katex from '../components/Katex.vue' import {EvaluationResult, hasOwnProperty} from '../types'
import {EvaluationResult, hasOwnProperty, StatementID} from '../types'
import Statement from '../components/Statement.vue' import Statement from '../components/Statement.vue'
import VarDeclEditor from './VarDeclEditor.vue' import VarDeclEditor from './VarDeclEditor.vue'
import ExpressionEditor from './ExpressionEditor.vue' import ExpressionEditor from './ExpressionEditor.vue'
import TextBox from '../components/TextBox.vue' import TextBox from '../components/TextBox.vue'
import {RichTextBox} from "../types.ts"; import {RichTextBox} from '../types'
import { stepX, stepY } from "../support/const.ts"; import { stepX, stepY } from '../support/const'
const math = new MathPage(uuidv4()) const math = new MathPage(uuidv4())
const statements = ref<MathStatement[]>([]) const statements = ref<MathStatement[]>([])
@ -49,6 +47,17 @@ const openNewExpressionModal = () => {
newExpressionModalOpen.value = true newExpressionModalOpen.value = true
} }
const editingStatement = ref<MathStatement|undefined>()
const editExpressionModalOpen = ref(false)
const openEditExpressionModal = () => {
editExpressionModalOpen.value = true
}
const editVarDeclModalOpen = ref(false)
const openEditVarDeclModal = () => {
editVarDeclModalOpen.value = true
}
const updateStatements = () => { const updateStatements = () => {
statements.value = math.getStatements() statements.value = math.getStatements()
try { try {
@ -92,6 +101,27 @@ const saveNewExpression = (stmt: MathStatement) => {
updateStatements() updateStatements()
} }
const editStatement = (stmt: MathStatement) => {
editingStatement.value = stmt
if ( stmt.isDeclaration() ) {
openEditVarDeclModal()
} else if ( stmt.isFunctionDeclaration() ) {
} else {
openEditExpressionModal()
}
}
const removeStatement = (stmt: MathStatement) => {
math.removeStatement(stmt.id)
updateStatements()
}
const finishEditStatement = () => {
editExpressionModalOpen.value = false
updateStatements()
}
/* /*
Rich Text Stuff Rich Text Stuff
*/ */
@ -204,6 +234,8 @@ function richUpdateValue() {
:key="statementsKey" :key="statementsKey"
:statement="statement" :statement="statement"
:evaluation="evaluation" :evaluation="evaluation"
v-on:edit="() => editStatement(statement)"
v-on:remove="() => removeStatement(statement)"
/> />
</div> </div>
@ -222,6 +254,20 @@ function richUpdateValue() {
/> />
</q-dialog> </q-dialog>
<q-dialog v-model="editExpressionModalOpen">
<ExpressionEditor
:statement="editingStatement"
v-on:save="() => finishEditStatement()"
/>
</q-dialog>
<q-dialog v-model="editVarDeclModalOpen">
<VarDeclEditor
:statement="editingStatement"
v-on:save="() => finishEditStatement()"
/>
</q-dialog>
<q-page-sticky position="bottom-right" :offset="[32, 32]"> <q-page-sticky position="bottom-right" :offset="[32, 32]">
<q-fab color="primary" icon="add" direction="left"> <q-fab color="primary" icon="add" direction="left">
<q-fab-action <q-fab-action

View File

@ -1,10 +1,14 @@
<script setup lang="ts"> <script setup lang="ts">
import {defineEmits, ref} from 'vue' import {defineEmits, onMounted, ref} from 'vue'
import {MathStatement} from '../support/parse' import {MathStatement} from '../support/parse'
import Katex from '../components/Katex.vue' import Katex from '../components/Katex.vue'
import { v4 as uuidv4 } from 'uuid' import { v4 as uuidv4 } from 'uuid'
import {StatementID} from '../types' import {StatementID} from '../types'
const props = defineProps<{
statement?: MathStatement,
}>()
const emit = defineEmits<{ const emit = defineEmits<{
(eventName: 'save', statement: MathStatement): void (eventName: 'save', statement: MathStatement): void
}>() }>()
@ -39,11 +43,23 @@ const saveExpression = () => {
return return
} }
if ( props.statement ) {
props.statement.raw = expressionValue.value
emit('save', props.statement)
} else {
emit('save', new MathStatement( emit('save', new MathStatement(
uuidv4() as StatementID, uuidv4() as StatementID,
expressionValue.value expressionValue.value
)) ))
}
} }
onMounted(() => {
if ( props.statement ) {
expressionValue.value = props.statement.raw
updateExpressionPreview()
}
})
</script> </script>
<template> <template>

View File

@ -1,10 +1,14 @@
<script setup lang="ts"> <script setup lang="ts">
import {ref} from 'vue' import {onMounted, ref} from 'vue'
import {MathStatement} from '../support/parse' import {MathStatement} from '../support/parse'
import {v4 as uuidv4} from 'uuid' import {v4 as uuidv4} from 'uuid'
import Katex from '../components/Katex.vue' import Katex from '../components/Katex.vue'
import {StatementID} from '../types' import {StatementID} from '../types'
const props = defineProps<{
statement?: MathStatement,
}>()
const emit = defineEmits<{ const emit = defineEmits<{
(eventName: 'save', statement: MathStatement): void, (eventName: 'save', statement: MathStatement): void,
}>() }>()
@ -48,11 +52,25 @@ const saveNewVariable = () => {
return return
} }
if ( props.statement ) {
props.statement.raw = `${newVariableName.value} = ${newVariableValue.value}`
emit('save', props.statement)
} else {
emit('save', new MathStatement( emit('save', new MathStatement(
uuidv4() as StatementID, uuidv4() as StatementID,
`${newVariableName.value} = ${newVariableValue.value}` `${newVariableName.value} = ${newVariableValue.value}`
)) ))
}
} }
onMounted(() => {
if ( props.statement ) {
const [ define ] = props.statement.defines()
newVariableName.value = define.name
newVariableValue.value = props.statement.raw
updateNewVariablePreview()
}
})
</script> </script>
<template> <template>

View File

@ -21,6 +21,11 @@ export class MathPage {
return Object.values(this.statements) return Object.values(this.statements)
} }
/** Remove a statement from the math page. */
removeStatement(id: StatementID) {
delete this.statements[id]
}
/** Get a statement by ID if it exists. */ /** Get a statement by ID if it exists. */
getStatement(id: StatementID): Maybe<MathStatement> { getStatement(id: StatementID): Maybe<MathStatement> {
return this.statements[id] return this.statements[id]

View File

@ -268,10 +268,13 @@ export class MathStatement {
public readonly id: StatementID, public readonly id: StatementID,
/** The raw statement input by the user. */ /** The raw statement input by the user. */
public readonly raw: string, public raw: string,
public x: Number = 0, /** The x position in the grid. */
public y: Number = 0, public x: number = 0,
/** The y position in the grid. */
public y: number = 0,
) {} ) {}
/** Parse the raw statement to an AST. */ /** Parse the raw statement to an AST. */
@ -341,4 +344,12 @@ export class MathStatement {
return true return true
} }
isDeclaration(): boolean {
return this.defines().length > 0
}
isFunctionDeclaration(): boolean {
return false
}
} }