diff --git a/gui-js/apps/minsky-electron/src/app/managers/ApplicationMenuManager.ts b/gui-js/apps/minsky-electron/src/app/managers/ApplicationMenuManager.ts index 1413e4bf8..8404aef13 100644 --- a/gui-js/apps/minsky-electron/src/app/managers/ApplicationMenuManager.ts +++ b/gui-js/apps/minsky-electron/src/app/managers/ApplicationMenuManager.ts @@ -448,6 +448,14 @@ export class ApplicationMenuManager { label: 'Random Layout', async click() {minsky.randomLayout();} }, + { + label: 'Open All Godley Tables', + click() {CommandsManager.openAllGodleyTables();}, + }, + { + label: 'Close All Godley Tables', + click() {CommandsManager.closeAllGodleyTables();}, + }, ], }; } diff --git a/gui-js/apps/minsky-electron/src/app/managers/CommandsManager.ts b/gui-js/apps/minsky-electron/src/app/managers/CommandsManager.ts index 1d5ce0794..fb2044549 100644 --- a/gui-js/apps/minsky-electron/src/app/managers/CommandsManager.ts +++ b/gui-js/apps/minsky-electron/src/app/managers/CommandsManager.ts @@ -831,82 +831,98 @@ export class CommandsManager { if (itemInfo?.classType) { switch (itemInfo?.classType) { - case ClassType.GodleyIcon: - await CommandsManager.openGodleyTable(itemInfo); - break; + case ClassType.GodleyIcon: + CommandsManager.openGodleyTable(itemInfo.id); + break; - case ClassType.PlotWidget: - await CommandsManager.expandPlot(itemInfo); + case ClassType.PlotWidget: + await CommandsManager.expandPlot(itemInfo); break; - case ClassType.Ravel: - await CommandsManager.openRavelPopup(itemInfo); - break; - - case ClassType.Variable: - case ClassType.VarConstant: - await CommandsManager.editVar(); - break; - - case ClassType.Operation: - await CommandsManager.editItem(ClassType.Operation); - - break; - - case ClassType.IntOp: - case ClassType.DataOp: - await CommandsManager.editItem(ClassType.IntOp); - - break; - - case ClassType.UserFunction: - await CommandsManager.editItem(ClassType.UserFunction); - - break; + case ClassType.Ravel: + await CommandsManager.openRavelPopup(itemInfo); + break; + case ClassType.Variable: + case ClassType.VarConstant: + await CommandsManager.editVar(); + break; + + case ClassType.Operation: + await CommandsManager.editItem(ClassType.Operation); + + break; + + case ClassType.IntOp: + case ClassType.DataOp: + await CommandsManager.editItem(ClassType.IntOp); + + break; + + case ClassType.UserFunction: + await CommandsManager.editItem(ClassType.UserFunction); + + break; + case ClassType.Group: if (await CommandsManager.selectVar(mouseX,mouseY)) await CommandsManager.editVar(); else await CommandsManager.editItem(ClassType.Group); break; - - case ClassType.Item: - await CommandsManager.postNote('item'); - break; - + + case ClassType.Item: + await CommandsManager.postNote('item'); + break; + case ClassType.Lock: new Lock(minsky.canvas.item).toggleLocked(); minsky.canvas.requestRedraw(); break; - default: - break; + default: + break; } } } - static async openGodleyTable(itemInfo: CanvasItem) { - if (!WindowManager.focusIfWindowIsPresent(itemInfo.id)) { - CommandsManager.addItemToNamedItems(itemInfo); - let godley=new GodleyIcon(minsky.namedItems.elem(itemInfo.id)); + static async openAllGodleyTables() { + for (const id of await minsky.allGodleyTables()) + this.openGodleyTable(id); + } + + static async closeAllGodleyTables() { + for (const id of await minsky.allGodleyTables()) + WindowManager.closeWindowByUid(id); + } + + static async openGodleyTable(id: string) { + if (!WindowManager.focusIfWindowIsPresent(id)) { + await minsky.itemFromNamedItem(id); // ensure named items is populated + let godley=new GodleyIcon(minsky.namedItems.elem(id)); var title=await godley.table.title(); - - const window = await this.initializePopupWindow({ - customTitle: `Godley Table : ${title}`, - itemInfo, - url: `#/headless/godley-widget-view?systemWindowId=0&itemId=${itemInfo.id}`, + const itemInfo={classType: ClassType.GodleyIcon, displayContents: false, id}; // TODO - is this stuff useful? + + const window = await WindowManager.createPopupWindowWithRouting({ + title: `Godley Table : ${title}`, + height: 600, + width: 800, + url: `#/headless/godley-widget-view?systemWindowId=0&itemId=${id}`, + uid: id, modal: false, + }, + () => { + this.onPopupWindowClose(itemInfo.id); }); - + Object.defineProperty(window,'dontCloseOnEscape',{value: true,writable:false}); godley.adjustPopupWidgets(); - let systemWindowId = WindowManager.getWindowByUid(itemInfo.id).systemWindowId; + let systemWindowId = WindowManager.getWindowByUid(id).systemWindowId; window.loadURL( WindowManager.getWindowUrl( - `#/headless/godley-widget-view?systemWindowId=${systemWindowId}&itemId=${itemInfo.id}` + `#/headless/godley-widget-view?systemWindowId=${systemWindowId}&itemId=${id}` ) ); @@ -915,7 +931,7 @@ export class CommandsManager { itemInfo, }); - this.activeGodleyWindowItems.set(itemInfo.id, itemInfo); + this.activeGodleyWindowItems.set(id, itemInfo); } } diff --git a/gui-js/apps/minsky-electron/src/app/managers/ContextMenuManager.ts b/gui-js/apps/minsky-electron/src/app/managers/ContextMenuManager.ts index 7c3c9459f..1444cc0df 100644 --- a/gui-js/apps/minsky-electron/src/app/managers/ContextMenuManager.ts +++ b/gui-js/apps/minsky-electron/src/app/managers/ContextMenuManager.ts @@ -646,7 +646,17 @@ export class ContextMenuManager { const menuItems = [ new MenuItem({ label: 'Open Godley Table', - click: () => CommandsManager.openGodleyTable(itemInfo) + click: () => { + CommandsManager.openGodleyTable(itemInfo.id); + } + }), + new MenuItem({ + label: 'Open All Godley Tables', + click: () => {CommandsManager.openAllGodleyTables();} + }), + new MenuItem({ + label: 'Close All Godley Tables', + click() {CommandsManager.closeAllGodleyTables();}, }), new MenuItem({ label: 'Title', diff --git a/gui-js/libs/shared/src/lib/backend/minsky.ts b/gui-js/libs/shared/src/lib/backend/minsky.ts index dbbd20a86..3eb3d7e06 100644 --- a/gui-js/libs/shared/src/lib/backend/minsky.ts +++ b/gui-js/libs/shared/src/lib/backend/minsky.ts @@ -1335,6 +1335,7 @@ export class Minsky extends CppClass { async addIntegral(): Promise {return this.$callMethod('addIntegral');} async addNewPublicationTab(a1: string): Promise {return this.$callMethod('addNewPublicationTab',a1);} async allGodleyFlowVars(): Promise {return this.$callMethod('allGodleyFlowVars');} + async allGodleyTables(): Promise {return this.$callMethod('allGodleyTables');} async assetClasses(): Promise {return this.$callMethod('assetClasses');} async author(...args: string[]): Promise {return this.$callMethod('author',...args);} async autoLayout(): Promise {return this.$callMethod('autoLayout');} diff --git a/model/minsky.cc b/model/minsky.cc index e025d26d6..76afc2e3b 100644 --- a/model/minsky.cc +++ b/model/minsky.cc @@ -1658,6 +1658,22 @@ namespace minsky variableInstanceList.reset(); } + void Minsky::itemFromNamedItem(const std::string& name) + { + canvas.item=namedItems[name].lock(); + if (!canvas.item) + { + // name all items by id + model->recursiveDo(&GroupItems::items, + [this](const Items&,const Items::const_iterator& x){ + namedItems[(*x)->id()]=*x; + return false; + }); + canvas.item=namedItems[name].lock(); + } + } + + void Minsky::removeItems(Wire& wire) { if (wire.from()->wires().size()==1) @@ -1736,6 +1752,15 @@ namespace minsky }); } + vector Minsky::allGodleyTables() const + { + vector r; + for (auto& i: canvas.model->items) + if (i->godleyIconCast()) + r.push_back(i->id()); + return r; + } + size_t Minsky::physicalMem() { #if defined(__linux__) diff --git a/model/minsky.h b/model/minsky.h index 89aaea4c9..af2bb0f01 100644 --- a/model/minsky.h +++ b/model/minsky.h @@ -436,6 +436,9 @@ namespace minsky /// request all Godley table windows to redraw void redrawAllGodleyTables(); + /// returns list of ids of all Godley tables in the current top level canvas + std::vector allGodleyTables() const; + /// set/clear busy cursor in GUI virtual void setBusyCursor() {} virtual void clearBusyCursor() {} @@ -524,7 +527,7 @@ namespace minsky std::map> namedItems; void nameCurrentItem(const std::string& name) {namedItems[name]=canvas.item;} - void itemFromNamedItem(const std::string& name) {canvas.item=namedItems[name].lock();} + void itemFromNamedItem(const std::string& name); VariablePane variablePane;