Skip to content

Commit

Permalink
add templ8Modular
Browse files Browse the repository at this point in the history
  • Loading branch information
eepsmedia committed Jul 16, 2024
1 parent 1b80598 commit d0ee394
Show file tree
Hide file tree
Showing 8 changed files with 761 additions and 0 deletions.
19 changes: 19 additions & 0 deletions templ8Modular/css/templ8.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
body {
background-color: aliceblue;
margin : 0;
padding : 0;
height : 100vh;
}

#header {
padding: 0.5em 1em 0.5em 1em ;
}

#content {
padding: 0.5em 1em 0.5em 1em ;
}

#theSVG {
background-color: white;
width : 100%;
}
51 changes: 51 additions & 0 deletions templ8Modular/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<!DOCTYPE html>

<!--
local just this: http://localhost/~tim/plugins/templ8/
local in local codap :
http://localhost/~tim/codap/static/dg/en/cert/index.html?di=https://localhost/~tim/plugins/templ8Modular/
-->

<html lang="en">
<head>
<meta charset="UTF-8">
<title>templ8</title>

<link rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Sirin+Stencil:wght@400;700">

<link rel='stylesheet' type='text/css' href='css/templ8.css'/>

<script src="https://d3js.org/d3.v7.min.js"></script>

<script src="strings/localize.js"></script>

<!-- These five scripts take care of the communication with CODAP -->
<script src="../common/iframe-phone.js"></script>
<script src="../common/codap_helper_newAPI.js"></script>
<script src="../common/codapInterface.js"></script>
<script src="../common/pluginHelper.js"></script>
<script src="../common/pluginLang.js"></script>


</head>
<body>

<div id="header">Template Plugin</div>
<div id="content">
<svg id="theSVG"></svg>
<div id="status"></div>
<input type="button" id="counterButton" value="click to count">
<label for="counterButton" id="counterButtonLabel"></label>
</div>

</body>

<script type="module">
import {initialize} from "./src/templ8.js";

initialize();
</script>

</html>
136 changes: 136 additions & 0 deletions templ8Modular/src/connect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/**
* communicates with CODAP
*/

import * as HANDLERS from "./handlers.js"
import * as TEMPL8 from "./templ8.js"

let theDSD;

export async function initialize() {

await codapInterface.init(
getIFrameDescriptor(),
HANDLERS.restorePluginFromStore // restores the state, if any
);
await allowReorg();
await renameIFrame(localize.getString("frameTitle")); // localize the frame title

theDSD = getDatasetDescriptor();
await pluginHelper.initDataSet(theDSD); // open the output dataset

}

export async function emitData(iValues) {
const theMessage = {
action: "create",
resource: `dataContext[${theDSD.name}].item`,
values: iValues
}

try {
await codapInterface.sendRequest(theMessage);
} catch (err) {
alert(`Error creating CODAP items: ${err}`)
}

makeCaseTableAppear(theDSD.name, localize.getString("outputDatasetTitle"));
}

export async function getAllItems(iDSName) {
let out = null;

const theMessage = {
action : "get",
resource : `dataContext[${iDSName}].itemSearch[*]`
}

try {
const result = await codapInterface.sendRequest(theMessage);
if (result.success) {
return result.values;
}
} catch(err) {
alert(`ERROR getting items: ${err}`);
}

return out;
}

async function makeCaseTableAppear(contextName, title) {
const theMessage = {
action: "create",
resource: "component",
values: {
type: 'caseTable',
dataContext: contextName,
title: title,
cannotClose: true
}
};
await codapInterface.sendRequest(theMessage);
}



async function renameIFrame(iName) {
const theMessage = {
action: "update",
resource: "interactiveFrame",
values: {
title: iName,
}
};
await codapInterface.sendRequest(theMessage);
}


/**
* Kludge to ensure that a dataset is reorg-able.
*
* @returns {Promise<void>}
*/
async function allowReorg() {
const tMutabilityMessage = {
"action": "update",
"resource": "interactiveFrame",
"values": {
"preventBringToFront": false,
"preventDataContextReorg": false
}
};

codapInterface.sendRequest(tMutabilityMessage);
}

function getDatasetDescriptor() {
return {
name : TEMPL8.constants.outputDatasetName,
title : localize.getString("outputDatasetTitle"),
collections : [
{
name: "data",
title: localize.getString("dataCollectionTitle"),
attrs: [
{ name : localize.getString("attributeNames.count") },
{ name : localize.getString("attributeNames.time"), type : "date", unit : "UTC" },
{ name : localize.getString("attributeNames.interval"), unit : "sec" }

]
}
]
}
}

/**
* Constant descriptor for the iFrame.
* Find and edit the values in `templ8.constants`
*/
function getIFrameDescriptor() {
return {
name: TEMPL8.constants.pluginName,
title: localize.getString("frameTitle"),
version: TEMPL8.constants.version,
dimensions: TEMPL8.constants.dimensions, // dimensions,
}
}
162 changes: 162 additions & 0 deletions templ8Modular/src/handlers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
import * as TEMPL8 from "./templ8.js"
import * as UI from "./ui.js"

let caseChangeSubscriberIndex = null;
let attributeDragDropSubscriberIndex = null;

let currentlyDraggingCODAPAttribute = false;

/**
* Set up handlers, e.g., event handlers
*/
export function initialize() {
registerForDragDropEvents(); // if you're accepting drops!

// note: these subscriptions must happen BEFORE `connect.initialize()` so that the `.on` there does not
// override our handlers.

codapInterface.on('update', 'interactiveState', "", restorePluginFromStore);
codapInterface.on('get', 'interactiveState', "", getPluginState);

document.getElementById("counterButton").addEventListener('click', pressCountButton);

}

function getPluginState() {
return {
success: true,
values: {
store: TEMPL8.state,
}
};
}

function restorePluginFromStore(iStorage) {
if (iStorage) {
TEMPL8.state = iStorage.store;
}
}

/**
* handler for our initial button
*/
function pressCountButton() {
TEMPL8.doButton();
}

/**
* Handlers for drag and drop of attributes frm CODAP
* @param iMessage
* @returns {Promise<void>}
*/
export async function handleDragDrop(iMessage) {

switch (iMessage.values.operation) {
case `dragstart`:
currentlyDraggingCODAPAttribute = true;
console.log(` drag start`);
break;
case `dragend`:
currentlyDraggingCODAPAttribute = false;
highlightNone();
console.log(` drag end`);
break;
case `drag`:
handleDrag(iMessage.values.position);
break;
case `drop`:
await TEMPL8.copeWithAttributeDrop(
iMessage.values.context,
iMessage.values.collection,
iMessage.values.attribute,
iMessage.values.position
);
UI.redraw();
break;
case `dragenter`:
console.log(` drag enter`);
highlightNear();
break;
case `dragleave`:
highlightNone();
console.log(` drag leave`);
break;
}
}

/**
* CODAP has told us that a case has changed.
* This will cause a re-get of all data and a re-analysis.
*
* @param iMessage
* @returns {Promise<void>}
*/
export async function handleCaseChangeNotice(iMessage) {
const theOp = iMessage.values.operation;

switch (theOp) {
case 'createCases':
case 'updateCases':
case 'deleteCases':
case `dependentCases`: // fires on rerandomize
case `updateAttributes`:
case `deleteAttributes`:
case `createAttributes`:
TEMPL8.copeWithCaseChange();
break;

default:
break;
}
// console.log(`end ${tMess}`);

}

function handleDrag(iPosition) {

}

function highlightNone() {

}

function highlightNear() {

}

/**
* Register for the dragDrop[attribute] event.
*
* Called from connect.initialize();
*/
function registerForDragDropEvents() {
const tResource = `dragDrop[attribute]`;

attributeDragDropSubscriberIndex = codapInterface.on(
'notify', tResource, handleDragDrop
)
console.log(`registered for drags and drops. Index ${attributeDragDropSubscriberIndex}`);
}

/**
* register to receive notifications about changes to the data context (including selection)
* called from templ8.setDataset()
*/
export async function registerForCaseChanges(iName) {
if (caseChangeSubscriberIndex) { // zero is a valid index... :P but it should be the "get"
codapInterface.off(caseChangeSubscriberIndex); // blank that subscription.
}

const theResource = `dataContextChangeNotice[${iName}]`;
// const sResource = `dataContext[${iName}].case`;
try {
caseChangeSubscriberIndex = codapInterface.on(
'notify',
theResource,
handleCaseChangeNotice
);
console.log(`registered for case changes in ${iName}. Index ${this.caseChangeSubscriberIndex}`);
} catch (msg) {
console.log(`problem registering for case changes: ${msg}`);
}
}
Loading

0 comments on commit d0ee394

Please sign in to comment.