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