diff --git a/index.html b/index.html index 5115fde0a8f73b1f4b4ae6e65c5c448a40ffbb1e..eeba76546c3522d0619c1455d2d9f46c7f9ce1fd 100644 --- a/index.html +++ b/index.html @@ -48,6 +48,8 @@ <script type="text/javascript" src="js/authoring/controllers/navBarController.js"></script> <script type="text/javascript" src="js/authoring/controllers/sliderController.js"></script> <script type="text/javascript" src="js/authoring/controllers/unitController.js"></script> + <script type="text/javascript" src="js/authoring/controllers/simulator/simulationController.js"></script> + <script type="text/javascript" src="js/authoring/controllers/simulator/timelineController.js"></script> <!-- tab controllers --> <script type="text/javascript" src="js/authoring/controllers/tabs/contextTabController.js"></script> @@ -95,6 +97,7 @@ <link rel="stylesheet" href="css/tabs.css"> <link rel="stylesheet" href="css/navigation.css"> + <link rel="stylesheet" href="css/timeline.css"> <!-- google maps api --> @@ -123,8 +126,8 @@ <ul class="dropdown-menu"> <li id="showNewScenario"><a href="#">Erstellen <b class="fui-plus" style="float: right"></b></a></li> <li id="deleteScenario"><a href="#">Löschen <b class="fui-trash" style="float: right"></b></a></li> - <li id="loadScenario"><a href="#">Laden <b class="fui-upload3" style="float: right"></b></a></li> - <li id="saveScenario"><a download="szenario.json">Speichern <b class="fui-download3" style="float: right"></b></a></li> + <li id="loadScenario"><a href="#">Laden <b class="fui-upload" style="float: right"></b></a></li> + <li id="saveScenario"><a download="szenario.json">Speichern <b class="fui-export" style="float: right"></b></a></li> </ul> </li> <li class="dropdown"> @@ -137,9 +140,12 @@ <!--<li><a href="#test"><b class="fui-exit"></b> Testen</a></li>--> <!--<li id="navHeadStatistic"><a href="#statistic"><img src="img/Icons/iconmonstr-bar-chart-icon-32.png"> Statistiken</a></li>--> <li class="dropdown"> - <a id="navHeadStatistic" href="#" class="dropdown-toggle" data-toggle="dropdown"><b class="fui-folder-download"></b> Statistiken</a> + <a id="contextSimulation" href="#" class="dropdown-toggle" data-toggle="dropdown"><b class="fui-play"></b> Kontextsimulation <b class="caret"></b></a> <ul class="dropdown-menu"> - <li id="downloadContextData"><a href="#">Herunterladen <b class="fui-download3" style="float: right"></b></a></li> + <li id="createSimulation"><a href="#">Erstellen <b class="fui-plus" style="float: right"></b></a></li> + <li id="openSimulation"><a href="#">Öffnen <b class="fui-folder-open" style="float: right"></b></a></li> + <li id="deleteSimulation"><a href="#">Löschen <b class="fui-trash" style="float: right"></b></a></li> + <li id="importSimulation"><a href="#">Importieren <b class="fui-upload" style="float: right"></b></a></li> </ul> </li> </ul> @@ -201,6 +207,9 @@ <!-- Property area --> <div class="properties"> + <div id="simulatorContainer"></div> + + <!-- tabs header--> <div class="tab-Container"> <ul> diff --git a/js/authoring/controllers/simulator/simulationController.js b/js/authoring/controllers/simulator/simulationController.js new file mode 100644 index 0000000000000000000000000000000000000000..90b077e898921f30a428d53d30135f907fba825f --- /dev/null +++ b/js/authoring/controllers/simulator/simulationController.js @@ -0,0 +1,36 @@ +/** + * Created by Helena on 06.01.2016. + */ + + +/** + * Initialize timeline + */ +$(function() { + + // event handler listening for click on "Kontextsimulation" in horizontal menu (top) + // TODO: Consider switching between scenarios! + $("#contextSimulation").on("click", function() { + + var currentScenarioName = $("#lname")[0].innerHTML; + var scenarioContextList; + + if (currentScenarioName) { + // get a list of all context information items added in this scenario, with chosen values reset to "" + scenarioContextList = authorSystemContent.getScenario(currentScenarioName).getScenarioContext(); + } + + // init the simulation editor timeline + $.get( "simulator.html", function( data ) { + $( "#simulatorContainer" ).html( data ); + + // create a column for each ContextInformation object + createColumns(scenarioContextList ? scenarioContextList.length : 0); + + // set event handlers for these generated cells + setCellEventHandlers(); + }); + + }); + +}); \ No newline at end of file diff --git a/js/authoring/controllers/timelineController.js b/js/authoring/controllers/simulator/timelineController.js similarity index 77% rename from js/authoring/controllers/timelineController.js rename to js/authoring/controllers/simulator/timelineController.js index 9ab33e2b4bc2cac8c660f9e1eaf07b99cfdff323..97d0630e37479c343c6b50daa5671d8033b7363a 100644 --- a/js/authoring/controllers/timelineController.js +++ b/js/authoring/controllers/simulator/timelineController.js @@ -13,50 +13,23 @@ var xFirstCellLeft, yFirstCellTop; // coordinates of clicked cell (in px) var horizontalBorderPx = 2; // a marked cell's top and bottom border sum in px var verticalBorderPx = 4; // a marked cell's left and right border sum in px -/** - * Initialize timeline - */ -$(function() { - - // get the list of all contextInformation items that were added in the author system - var contextList = new ContextInfoList(); - $.get("data.json", function(data) { - // and convert all items to their proper model type: ContextInformation (incl. Parameter) - contextList.fromJSON(data); - - // create a column for each ContextInformation object - createColumns(contextList.getItems()); - - // set event handlers for these generated cells - setCellEventHandlers(); - }); - -}); - /** * Create one column per (unique) context item * @param contextList An array containing all context items (incl. duplicates) added in the author system */ -function createColumns(contextList) { - // functions as a set of unique context item IDs - var itemIDList = []; - // iterate through all context items - for (var i in contextList) { - var contextItemID = contextList[i].getID(); - - // ensure IDs are unique (no duplicates) - if (itemIDList.indexOf(contextItemID) == -1) { - itemIDList.push(contextItemID); - - // add one column for each unique item - $(".timelineStep").each(function() { - var newCell = $("<td>") - .addClass("timelineCell") - .attr("contextID", contextItemID); - $(this).append(newCell); - }); - } +function createColumns(contextListLength) { + // in case no context has been added to any unit in the scenario yet + if (contextListLength == 0 || typeof contextListLength == "undefined") + contextListLength = 5; + + for (var i = 0; i < contextListLength; i++) { + + // add one column for each context item + $(".timelineStep").each(function() { + var newCell = $("<td>").addClass("timelineCell"); + $(this).append(newCell); + }); } } @@ -83,8 +56,8 @@ function _mousedown(event) { yOnMousedown = event.pageY; xOnMousedown = event.pageX; - xFirstCellLeft = $(this).position().left; - yFirstCellTop = $(this).position().top; + xFirstCellLeft = $(this).offset().left; + yFirstCellTop = $(this).offset().top; } /** @@ -114,18 +87,19 @@ function _mouseup(event) { // if the mouse has been down, and is now released if (down) { // get height of marked area - var height = _getHeight(); + var height = _getHeight(event); // prevent erroneous behavior when cursor is dragged beyond top if (event.pageY > yFirstCellTop) { // create and add the draggable, resizable information container var eventDiv = _createEventDiv(height); - var popoverDiv = _createPopover(); + //var popoverDiv = _createPopover(); // TODO: just a mock-up for now, will be replaced by formatting in author system var contextColor = "#"+((1<<24)*Math.random()|0).toString(16); - eventDiv.css("background-color", contextColor); + eventDiv.css("background-color", contextColor) + .css("z-index", 1000); // add new div to timeline $("#timelineContainer").append(eventDiv); @@ -207,9 +181,9 @@ function _createPopover () { function _mark(event) { $('.timelineCell').each(function () { - var top = $(this).position().top; + var top = $(this).offset().top; var bottom = top + $(this).height()+horizontalBorderPx; - var left = $(this).position().left; + var left = $(this).offset().left; var right = left + $(this).width()+verticalBorderPx; if( bottom > yOnMousedown && event.pageY >= top && xOnMousedown >= left && xOnMousedown < right) @@ -238,7 +212,7 @@ function _unmark() { * @private */ function _bottom(element){ - return $(element).position().top + $(element).height()+horizontalBorderPx; + return $(element).offset().top + $(element).height()+horizontalBorderPx; } /** @@ -246,7 +220,7 @@ function _bottom(element){ * @returns {number} The height of the selected, i.e. marked area in px * @private */ -function _getHeight() { +function _getHeight(event) { // if a single cell was clicked, without dragging, mark it (to access it afterwards) if (!dragging) _mark(event); diff --git a/js/authoring/models/authorSystemContentModel.js b/js/authoring/models/authorSystemContentModel.js index e24c9bda54f547d505a9752c83b0e0106275a13b..ced3fd05cd88d5f8a23685c2db9a57e4b60dc7bd 100644 --- a/js/authoring/models/authorSystemContentModel.js +++ b/js/authoring/models/authorSystemContentModel.js @@ -63,18 +63,23 @@ AuthorSystemContent.prototype.removeScenario = function(scenarioName) { } }; +// returns a list of all context items added in all scenarios, chosen values reset to "" AuthorSystemContent.prototype.getContextInformation = function() { var contextList = []; for (var i in this._scenarioList) { - var unitList = this._scenarioList[i].getUnits(); - for (var j in unitList) { - var unitContext = unitList[j].getContextData(); - for (var k in unitContext) { - var contextItem = unitContext[k]; - if (contextList.indexOf(contextItem) == -1) - contextList.push(contextItem); - } - } + var scenarioContext = this._scenarioList[i].getScenarioContext(); + for (var j in scenarioContext) + contextList.push(scenarioContext[j]); } return contextList; +}; + +/** + * Same as in scenarioModel, only for whole content (i.e. all scenarios). + * @returns {boolean} true if any conntext has been added, else false. + */ +AuthorSystemContent.prototype.hasContext = function() { + for (var i in this._scenarioList) + if (this._scenarioList[i].hasContext()) return true; + return false; }; \ No newline at end of file diff --git a/js/authoring/models/contextInfoListModel.js b/js/authoring/models/contextInfoListModel.js index fbccec0f79072c21ff654be205b6e4e7cdb33901..21b507bb30b133077609f02f3ddfff4c0ba4ff44 100644 --- a/js/authoring/models/contextInfoListModel.js +++ b/js/authoring/models/contextInfoListModel.js @@ -47,20 +47,8 @@ function ContextInfoList() { // generates and adds a new items list from a list of JSON objects duck-typable as ContextInformation ContextInfoList.prototype.fromJSON = function (data) { for (var i in data) { - // "cast" the context items to ContextInformation and remove previously entered values - var contextItem = new ContextInformation().fromJSON(data[i]); - contextItem.setChosenValue(""); - contextItem.setChosenOperator(""); - - // "cast" the item's parameters to Parameter and remove previously entered values - var parameters = [], tempParams = contextItem.getParameters(); - for (var ip in tempParams) { - var param = new Parameter().fromJSON(tempParams[ip]); - param.setChosenValue(""); - parameters.push(param); - } - contextItem.setParameters(parameters); - this._items.push(contextItem); + // "cast" the context items to ContextInformation (incl. Parameter) + this._items.push(new ContextInformation().fromJSON(data[i])); } }; @@ -77,6 +65,14 @@ ContextInfoList.prototype.addItem = function (item) { this._items.push(item); }; +// if list contains context items with chosen values, remove these (i.e. reset to "") +ContextInfoList.prototype.resetAllContextValues = function() { + for (var i in this._items) this._items[i].resetAllValues(); +}; + + +// getter + ContextInfoList.prototype.getItems = function () { return this._items; }; diff --git a/js/authoring/models/contextInfoModel.js b/js/authoring/models/contextInfoModel.js index 7918129f2142d1c9d27db04a6fec5018879ac6cf..d796c871469c5e76c5631552331de95c9ddfb0cc 100644 --- a/js/authoring/models/contextInfoModel.js +++ b/js/authoring/models/contextInfoModel.js @@ -22,8 +22,17 @@ function ContextInformation() { // support "casting" a duck-typed JSON object to ContextInformation ContextInformation.prototype.fromJSON = function(item) { - for (i in item) - this[i] = item[i]; + // copy all values (shallow copy) + for (i in item) this[i] = item[i]; + + // "cast" parameters to type Parameter (deep copy) + var parameters = [], tempParams = this._parameters; + for (var ip in tempParams) { + var param = new Parameter().fromJSON(tempParams[ip]); + parameters.push(param); + } + this._parameters = parameters; + return this; }; @@ -120,6 +129,14 @@ ContextInformation.prototype.setParameters = function (parameters) { this._parameters = parameters; }; +// reset all chosen values +ContextInformation.prototype.resetAllValues = function() { + this._chosenOperator = ""; + this._chosenValue = ""; + for (var i in this._parameters) + this._parameters[i].resetValue(); +}; + /***** JSON-LD formatting *****/ diff --git a/js/authoring/models/parameterModel.js b/js/authoring/models/parameterModel.js index 51f83d17561220b74e62dbadc17c78351bc1a3a9..eac2fe104a488411d86476e69bad7a8f6f6b1a2f 100644 --- a/js/authoring/models/parameterModel.js +++ b/js/authoring/models/parameterModel.js @@ -18,7 +18,6 @@ function Parameter() { // support "casting" a duck-typed JSON object to Parameter Parameter.prototype.fromJSON = function(item) { for (i in item) this[i] = item[i]; - return this; }; @@ -84,6 +83,9 @@ Parameter.prototype.setEnums = function (enums) { this._enums = enums; }; +Parameter.prototype.resetValue = function () { + this._chosenValue = ""; +}; // JSON-LD formatting diff --git a/js/authoring/models/scenarioModel.js b/js/authoring/models/scenarioModel.js index 729b610c2b48589634c66ff9de8dc0824a79f422..c884bac1df67a0007d44e350b53ee6232591e7dd 100644 --- a/js/authoring/models/scenarioModel.js +++ b/js/authoring/models/scenarioModel.js @@ -77,4 +77,41 @@ Scenario.prototype.removeConnection = function(connId) { if (conn.getID() == connId) this._connections.splice(i, 1); } +}; + + +/** + * Goes through all units of this scenario and gets (copies of) their associated context information items. + * Chosen values will be reset to "". + * + * @returns {Array} A list of all context items relevant to this scenario. + */ +Scenario.prototype.getScenarioContext = function() { + var contextList = []; + // for each unit ... + for (var i in this._units) { + // ... get its associated context items + var unitContext = this._units[i].getContextData(); + for (var j in unitContext) { + // make a deep copy of each + var contextItem = new ContextInformation().fromJSON(unitContext[j]); + // reset chosen values + contextItem.resetAllValues(); + + // and add it to return list, avoiding unnecessary duplicates + if (contextList.indexOf(contextItem) == -1) + contextList.push(contextItem); + } + } + return contextList; +}; + +/** + * Find out if any context was added to any of the units in this scenario. + * @returns {boolean} true if there is context, else false. + */ +Scenario.prototype.hasContext = function() { + for (var i in this._units) + if (this._units[i].getContextData().length != 0) return true; + return false; }; \ No newline at end of file diff --git a/js/main.js b/js/main.js index 202e518ba145b3311e6e5f16a70a29ec6e3c925f..85802204aa92bcc1e1c4c5c99d8525310c7b8816 100644 --- a/js/main.js +++ b/js/main.js @@ -28,14 +28,4 @@ jsPlumb.ready(function () { initPlumbCanvas(); // reload data from localStorage initLoader(); - - $("#navHeadStatistic").on("click", function() { - var obj = authorSystemContent.getContextInformation(); - var data = "text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(obj)); - - var a = $("#downloadContextData > a")[0]; - a.href = 'data:' + data; - a.download = 'data.json'; - }); - }); \ No newline at end of file diff --git a/simulator.html b/simulator.html new file mode 100644 index 0000000000000000000000000000000000000000..838748a09ec11672508a666f5584ccdd14b4d9a0 --- /dev/null +++ b/simulator.html @@ -0,0 +1,42 @@ +<div id="timelineContainer"> + <table id="timelineTable" class="ui-widget"> + <tbody> + <tr class="timelineStep"> + <td class="timelineStepLabel"> + 0 + </td> + <td class="timelineScale"></td> + </tr> + <tr class="timelineStep"> + <td class="timelineStepLabel">1</td> + <td class="timelineScale"></td> + </tr> + <tr class="timelineStep"> + <td class="timelineStepLabel">2</td> + <td class="timelineScale"></td> + </tr> + <tr class="timelineStep"> + <td class="timelineStepLabel">3</td> + <td class="timelineScale"></td> + </tr> + <tr class="timelineStep"> + <td class="timelineStepLabel">4</td> + <td class="timelineScale"></td> + </tr> + <tr class="timelineStep"> + <td class="timelineStepLabel">5</td> + <td class="timelineScale"></td> + </tr> + <tr class="timelineStep"> + <td class="timelineStepLabel">6</td> + <td class="timelineScale"></td> + </tr> + <tr class="timelineStep"> + <td class="timelineStepLabel"> + 7 + </td> + <td class="timelineScale"></td> + </tr> + </tbody> + </table> +</div> \ No newline at end of file