From 54539c8cfded830593419571b0503540acfb8f34 Mon Sep 17 00:00:00 2001 From: NathanViaud <nathan.viaud@inria.fr> Date: Thu, 16 Mar 2023 10:50:27 +0100 Subject: [PATCH] create new page at pos from context menu --- electron/components/contextMenu.js | 25 +++++++++++++++--- src/features/sideBar/SideBarV0.vue | 1 - src/shared/services/editor.service.ts | 5 ++++ src/shared/stores/editorStore.ts | 37 ++++++++++++++++++++++----- 4 files changed, 56 insertions(+), 12 deletions(-) diff --git a/electron/components/contextMenu.js b/electron/components/contextMenu.js index a4c72277..4f4a79c8 100644 --- a/electron/components/contextMenu.js +++ b/electron/components/contextMenu.js @@ -1,5 +1,8 @@ -const { ipcMain, Menu } = require('electron'); -const path = require('path'); +const { Menu } = require('electron'); +const { BrowserWindow } = require('electron'); +const { sendToFrontend } = require('./ipc'); + +const { screen } = require('electron'); const contextTemplate = [ { @@ -7,11 +10,11 @@ const contextTemplate = [ submenu: [ { label: 'Ajouter du texte', - click: () => { console.log('Ajout d\'une page texte'); } + click: () => { sendToFrontend(BrowserWindow.getFocusedWindow(),'addPage', { type: 'text', pos: getRelativeCursorPosition() }); } }, { label: 'Ajouter une vidéo', - click: () => { console.log('Ajout d\'une page vidéo'); } + click: () => { sendToFrontend(BrowserWindow.getFocusedWindow(), 'addPage', { type: 'video', pos: getRelativeCursorPosition() }); } } ] }, @@ -25,5 +28,19 @@ const contextTemplate = [ } ]; +function getRelativeCursorPosition() { + const cursorPosition = screen.getCursorScreenPoint(); + // Get the position of the current window + const windowPosition = BrowserWindow.getFocusedWindow().getPosition(); + + // Calculate the cursor position relative to the current window + const cursorPositionRelativeToWindow = { + x: cursorPosition.x - windowPosition[0], + y: cursorPosition.y - windowPosition[1] + }; + + return cursorPositionRelativeToWindow; +} + module.exports.popupMenu = Menu.buildFromTemplate(contextTemplate); \ No newline at end of file diff --git a/src/features/sideBar/SideBarV0.vue b/src/features/sideBar/SideBarV0.vue index 3b2ef361..b3eb96ad 100644 --- a/src/features/sideBar/SideBarV0.vue +++ b/src/features/sideBar/SideBarV0.vue @@ -17,7 +17,6 @@ const editorStore = useEditorStore(); :side-action="item" /> </div> - <button class="btn btn-content" @click="editorStore.addNewPage('text')">Add page</button> </div> </template> diff --git a/src/shared/services/editor.service.ts b/src/shared/services/editor.service.ts index 63658171..5a111780 100644 --- a/src/shared/services/editor.service.ts +++ b/src/shared/services/editor.service.ts @@ -122,6 +122,11 @@ const setup = function () { editorStore.exporting = false; }); + api.receive('addPage', (data: string) => { + const page = JSON.parse(data); + editorStore.addNewPage(page.type, page.pos); + }); + initialized = true; }; function newEpocProject(): void { diff --git a/src/shared/stores/editorStore.ts b/src/shared/stores/editorStore.ts index 4300e5e9..53f15199 100644 --- a/src/shared/stores/editorStore.ts +++ b/src/shared/stores/editorStore.ts @@ -1,11 +1,11 @@ import { defineStore } from 'pinia'; import { ePocProject, Form, FormButton, NodeElement, Screen, SideAction } from '@/src/shared/interfaces'; -import { toRaw } from 'vue'; +import { nextTick, toRaw, watch } from 'vue'; import { applyNodeChanges, getConnectedEdges, useVueFlow } from '@vue-flow/core'; import { formsModel, questions, standardScreen } from '@/src/shared/data/form.data'; -const { findNode, nodes, edges, addNodes } = useVueFlow({ id: 'main' }); +const { findNode, nodes, edges, addNodes, project, vueFlowRef } = useVueFlow({ id: 'main' }); type uid = string; @@ -249,30 +249,53 @@ export const useEditorStore = defineStore('editor', { node.data.elements.push(newElement); this.addElementToScreen(node.id, newElement.action); }, - addNewPage(type: string, following?: string) { - console.log('adding a new page of type', type); + addNewPage(type: string, pos: { x: number, y: number }) { + const types = standardScreen.concat(questions); const elements: NodeElement[] = []; const id = this.generateId(); elements.push({ id: this.generateId(), - action: { icon: 'icon-texte', type: 'text', label: 'Texte' }, - formType: 'text', + action: types.find((value) => value.type === type), + formType: type, formValues: {}, parentId: id, contentId: this.generateContentId(), }); + const { left, top } = vueFlowRef.value.getBoundingClientRect(); + + const position = project({ + x: pos.x - left, + y: pos.y - top, + }); + const newNode = { id: id, type: 'content', data: { type: type, readyToDrop: false, animated: false, elements: elements, formType: 'screen', formValues: {}, contentId: id }, - position: { x: 200, y: 200 }, + position: position, deletable: false }; addNodes([newNode]); + + nextTick(() => { + const node = findNode(newNode.id); + const stop = watch( + () => node.dimensions, + (dimensions) => { + if (dimensions.width > 0 && dimensions.height > 0) { + node.position = { x: node.position.x - node.dimensions.width / 2, y: node.position.y - node.dimensions.height / 2 }; + stop(); + } + }, + { deep: true, flush: 'post' }, + ); + }); + + this.addElementToScreen(id, elements[0].action); } } }); -- GitLab