Skip to content

Commit

Permalink
Merge pull request #106 from mdenet/102-add-support-for-panel-customi…
Browse files Browse the repository at this point in the history
…sation-in-activity-files

Support for panel customisation in activity files
  • Loading branch information
barnettwilliam authored Nov 14, 2023
2 parents b2f47ec + 1032f28 commit 240da3c
Show file tree
Hide file tree
Showing 8 changed files with 206 additions and 112 deletions.
80 changes: 80 additions & 0 deletions platform/src/Button.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@

var buttonTypes= {
BUTTON_ACTION: 'BUTTON_ACTION',
BUTTON_HELP: 'BUTTON_HELP'
}

class Button {
id;
icon;
hint;
action;
type;

/**
* Create a Button
* @param {object} buttonConfigObject
* @param {string} parentPanel
*/
constructor(buttonConfigObject, parentPanel){
this.id= buttonConfigObject.id;
this.icon= buttonConfigObject.icon;
this.hint= buttonConfigObject.hint;
this.action = buttonConfigObject.action;

// Set button's onclick action
if (buttonConfigObject["url"] != undefined) {
this.type = buttonTypes.BUTTON_HELP;
this.action = "window.open('" + buttonConfigObject.url + "');";

} else if (buttonConfigObject["actionfunction"] != undefined) {
this.type = buttonTypes.BUTTON_ACTION;
this.action = "runAction( '" + parentPanel + "', '" + buttonConfigObject.id +"' )";

} else if (buttonConfigObject["internal"] != undefined) {
this.action = buttonConfigObject.internal;

} else {
console.log( "Button '" + buttonConfigObject.id + "' with uknown key.");
}
}


buttonHtml() {
return "<span class='mif-" + this.icon + "' data-role='hint' data-hint-text='" + this.hint + "' data-hint-position='bottom'></span>";
}

/**
* Get a string representation of the button for its display
* @returns {String} DOM object with html, cls and onclick properties
*/
getView() {
var buttonData={};

buttonData.html= this.buttonHtml();
buttonData.cls= "sys-button";
buttonData.onclick= this.action;

return buttonData;
}


/**
* Create an array of buttons from an array of configurations
* @param {object[]} buttonConfigs
* @param {string} parentPanel
* @returns {Button[]} the Button objects
*/
static createButtons(buttonConfigs, parentPanel){

let buttons= [];

buttonConfigs.forEach((config)=>{
buttons.push( new Button(config, parentPanel) );
})

return buttons;
}
}

export {Button}
22 changes: 13 additions & 9 deletions platform/src/ConsolePanel.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
import { Panel } from "./Panel.js";
import { define } from "ace-builds";
import { Button } from "./Button.js";

class ConsolePanel extends Panel {

constructor(id) {
super(id);
this.editor.setReadOnly(true);
this.editor.setValue("", 1);
this.element.dataset.customButtons = JSON.stringify(this.getButtons());

let buttons = [];
let clearButton = new Button(
{ id:"clear",
hint:"Clear the console",
internal: `panels.find((p) => p.id==="${this.id}").editor.setValue('')`,
icon: "clear" },
this.id
);
buttons.push(clearButton);
this.addButtons(buttons);

this.detectHyperlinks(this.editor);
this.setTitleAndIcon("Console", "console");
}

getButtons() {
return [{
html: this.buttonHtml("clear", "Clear the console"),
cls: "sys-button",
onclick: "consolePanel.setValue('')"
}];
}

setOutput(str) {
document.getElementById(this.id + "Editor").style.color = "black";
this.editor.getSession().setUseWrapMode(false);
Expand Down
17 changes: 0 additions & 17 deletions platform/src/MetamodelPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,13 @@ import { ModelPanel } from './ModelPanel.js';
class MetamodelPanel extends ModelPanel {
constructor(id) {
super(id, true, null);
this.element.dataset.customButtons = JSON.stringify(this.getButtons());
this.setTitleAndIcon("Metamodel", "emfatic");
}

setupSyntaxHighlighting() {
this.editor.getSession().setMode("ace/mode/emfatic");
}

getButtons() {
return [{
html: this.buttonHtml("help", "Emfatic language reference"),
cls: "sys-button",
onclick: "window.open('https://www.eclipse.org/epsilon/doc/articles/playground/#emfatic-metamodels-in-the-playground');"
},{
html: this.buttonHtml("refresh", "Render the metamodel class diagram"),
cls: "sys-button",
onclick: this.id + "Panel.refreshDiagram()"
},{
html: this.buttonHtml("diagram", "Show/hide the metamodel class diagram"),
cls: "sys-button",
onclick: "toggle('" + this.id + "Diagram', function(){" + this.id + "Panel.refreshDiagram();})"
}];
}

refreshDiagram() {
this.refreshDiagramImpl(backend.getEmfaticToPlantUMLService(), this.id + "Diagram", "metamodel", null, this.getEditor());
}
Expand Down
17 changes: 0 additions & 17 deletions platform/src/ModelPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ class ModelPanel extends Panel {
this.editable = editable;
this.metamodelPanel = metamodelPanel;
this.setupSyntaxHighlighting();
this.element.dataset.customButtons = JSON.stringify(this.getButtons());
this.setTitleAndIcon("Model", "flexmi");
}

Expand Down Expand Up @@ -62,22 +61,6 @@ class ModelPanel extends Panel {
}
}

getButtons() {
return this.editable ? [{
html: this.buttonHtml("help", "Flexmi language reference"),
cls: "sys-button",
onclick: "window.open('https://www.eclipse.org/epsilon/doc/flexmi');"
}, {
html: this.buttonHtml("refresh", "Render the model object diagram"),
cls: "sys-button",
onclick: this.id + "Panel.refreshDiagram()"
}, {
html: this.buttonHtml("diagram", "Show/hide the model object diagram"),
cls: "sys-button",
onclick: "toggle('" + this.id + "Diagram', function(){" + this.id + "Panel.refreshDiagram();})"
}] : [];
}

/* TODO: Rename to something more sensible */
refreshDiagramImpl(url, diagramId, diagramName, modelEditor, metamodelEditor) {
var xhr = new XMLHttpRequest();
Expand Down
25 changes: 16 additions & 9 deletions platform/src/OutputPanel.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@

import { ModelPanel } from "./ModelPanel.js";
import { language } from "./Playground.js";
import { Button } from "./Button.js";

class OutputPanel extends ModelPanel {

Expand All @@ -13,20 +15,25 @@ class OutputPanel extends ModelPanel {
this.outputType = outputType;
this.outputLanguage = outputLanguage;
this.language = language;
this.element.dataset.customButtons = JSON.stringify(this.getButtons());

let buttons = [];
if (this.outputType == "code"){
let highlightButton = new Button(
{ id:"highlight",
hint:"Set generated text language",
internal: `panels.find((p) => p.id==="${this.id}").editor.setOutputLanguage()`,
icon: "highlight" },
this.id
);
buttons.push(highlightButton);
}
this.addButtons(buttons);

this.getEditor().getSession().setMode("ace/mode/" + outputLanguage.toLowerCase());
//this.getEditor().getSession().setUseWrapMode(false);
}

setupSyntaxHighlighting() {}

getButtons() {
return (this.outputType == "code") ? [{
html: this.buttonHtml("highlight", "Set generated text language"),
cls: "sys-button",
onclick: this.id + "Panel.setOutputLanguage()"
}] : [];
}

getSelect() {
return Metro.getPlugin("#generatedFiles", 'select');
Expand Down
28 changes: 8 additions & 20 deletions platform/src/Panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,32 +97,20 @@ class Panel {
return this.type;
}

buttonHtml(icon, hint) {
return "<span class='mif-" + icon + "' data-role='hint' data-hint-text='" + hint + "' data-hint-position='bottom'></span>";
}


/**
* Add the buttons to the page
* @param {object[]} buttons Objects with attributes: icon, hint, action
*
* TODO Support image files for icon
* @param {Button[]} buttons - The Button objects to add.
*/
addButtons(buttons){
if (buttons.length > 0){
var buttonViewData= buttons.map( (btn) => {
return btn.getView();
});

var buttonViewData= buttons.map( (btn) => {
var buttonData={};

buttonData.html= this.buttonHtml(btn.icon, btn.hint);
buttonData.cls= "sys-button";
buttonData.onclick= btn.action;
buttonViewData.reverse(); // So they are displayed in the order they are defined

return buttonData;
});

buttonViewData.reverse(); // So they are displayed in the order they are defined

this.element.dataset.customButtons = JSON.stringify(buttonViewData);
this.element.dataset.customButtons = JSON.stringify(buttonViewData);
}
}


Expand Down
78 changes: 38 additions & 40 deletions platform/src/Playground.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { OutputPanel } from "./OutputPanel.js";
import { TestPanel } from './TestPanel.js';
import { BlankPanel } from './BlankPanel .js';
import { XtextEditorPanel } from './XtextEditorPanel.js';
import { Button } from './Button.js';

import { Preloader } from './Preloader.js';
import { Backend } from './Backend.js';
Expand Down Expand Up @@ -262,8 +263,8 @@ function initialisePanels() {
/**
* Create a panel for a given panel config entry
*
* @param {string} panel
* @return {Panel}
* @param {Object} panel - The activity config panel definition.
* @return {Panel} the platform Panel
*/
function createPanelForDefinitionId(panel){
const panelDefinition = panel.ref;
Expand All @@ -278,7 +279,6 @@ function initialisePanels() {
newPanel = new ProgramPanel(newPanelId);

// Set from the tool panel definition
newPanel.setIcon(panelDefinition.icon);
newPanel.setEditorMode(panelDefinition.language);

newPanel.setType(panelDefinition.language);
Expand All @@ -301,8 +301,6 @@ function initialisePanels() {
const panelDef = toolsManager.getPanelDefinition(newPanelId);

newPanel = new OutputPanel(newPanelId, panelDefinition.language, outputType, outputLanguage);

newPanel.setIcon(panelDefinition.icon);

newPanel.hideEditor();
newPanel.showDiagram();
Expand All @@ -314,7 +312,6 @@ function initialisePanels() {

newPanel = new XtextEditorPanel(newPanelId, editorUrl, panel.extension);

newPanel.setIcon(panelDefinition.icon);
newPanel.setType(panelDefinition.language);

break;
Expand All @@ -327,44 +324,38 @@ function initialisePanels() {
// Add elements common to all panels
newPanel.setTitle(panel.name);

if (panelDefinition.buttons != null){

var buttons = panel.ref.buttons.map( (btn) => {
var buttonData = {};

buttonData.icon = btn.icon;
buttonData.hint = btn.hint;
buttonData.action = generateButtonOnclickHtml(btn, panel.id);

return buttonData;
if(panel.icon != null){
newPanel.setIcon(panel.icon);
} else {
newPanel.setIcon(panelDefinition.icon);
}

if (panel.buttons == null && panelDefinition.buttons != null){
// No activity defined buttons
newPanel.addButtons( Button.createButtons( panelDefinition.buttons, panel.id));

} else if (panel.buttons != null && panelDefinition.buttons != null) {
// The activity has defined the buttons
let resolvedButtonConfigs = panel.buttons.map(btn =>{
let resolvedButton;

if (btn.ref){
// button reference so resolve
resolvedButton= panelDefinition.buttons.find((pdBtn)=> pdBtn.id===btn.ref);
} else {
// activity defined button
resolvedButton= btn;
}
return resolvedButton;
});

newPanel.addButtons(buttons);
}


panel.buttons = resolvedButtonConfigs;
newPanel.addButtons( Button.createButtons( resolvedButtonConfigs, panel.id));
}

return newPanel;
}


function generateButtonOnclickHtml(button, panelId){

var onclickHtml;

if (button["url"] != undefined) {
onclickHtml = "window.open('" + button.url + "');";

} else if (button["actionfunction"] != undefined) {
onclickHtml = "runAction( '" + panelId + "', '" + button.id +"' )";

} else {
console.log( "Button '" + button.id + "' with uknown key.");
}

return onclickHtml;
}


function copyToClipboard(str) {
var el = document.createElement('textarea');
el.value = str;
Expand Down Expand Up @@ -816,7 +807,14 @@ function runAction(source, sourceButton) {
// Get the action
var action = activityManager.getActionForCurrentActivity(source, sourceButton);

const buttonConfig = action.source.ref.buttons.find( btn => btn.id == sourceButton );
let buttonConfig;
if(action.source.buttons){
//Buttons defined by activity
buttonConfig= action.source.buttons.find( btn => btn.id == sourceButton );
} else {
//Buttons defined by tool
buttonConfig= action.source.ref.buttons.find( btn => btn.id == sourceButton );
}
const toolActionFunction = toolsManager.getActionFunction( buttonConfig.actionfunction ); // TODO tidy up by resolving tool references

// Create map containing panel values
Expand Down
Loading

0 comments on commit 240da3c

Please sign in to comment.