Index: lams_central/web/author2.jsp =================================================================== diff -u -re1f6c04ba5b6d797d9687b375fb062fa10d754b0 -re1be1f233c3aaea87dd4336c486758ceadb35061 --- lams_central/web/author2.jsp (.../author2.jsp) (revision e1f6c04ba5b6d797d9687b375fb062fa10d754b0) +++ lams_central/web/author2.jsp (.../author2.jsp) (revision e1be1f233c3aaea87dd4336c486758ceadb35061) @@ -74,31 +74,58 @@
Arrange
+
+ Zoom out +
- - - + + +
-
- -
- - - -
+ +
+ +
+ +
+ + + - - -
+
+ +
+ + + +
+
+
- - -
-
-
+
+
+
+ + +
+ + + + + + + + + +
Title
Description
+
+ + + - - Index: lams_central/web/css/authoring.css =================================================================== diff -u -re1f6c04ba5b6d797d9687b375fb062fa10d754b0 -re1be1f233c3aaea87dd4336c486758ceadb35061 --- lams_central/web/css/authoring.css (.../authoring.css) (revision e1f6c04ba5b6d797d9687b375fb062fa10d754b0) +++ lams_central/web/css/authoring.css (.../authoring.css) (revision e1be1f233c3aaea87dd4336c486758ceadb35061) @@ -9,9 +9,7 @@ } - /**** Dialog styles ****/ - .ui-dialog { font-size: 12px !important; } @@ -149,7 +147,42 @@ /**** Main authoring styles ****/ +#tabs { + padding: 0; + border: none; + font-size: 12px; +} +#tabs .ui-tabs-panel { + padding: 0; + height: 718px; +} + +#tabs .tabs-spacer { + float: left; + height: 200px; +} + +#tabs .ui-tabs-nav { + clear: left; + padding: 0 .2em .2em .2em; + background: none; + border: none; +} + +#tabs .ui-tabs-nav li { + top: auto; + bottom: 0; + border: 1px solid #C5DBEC; + border-top: 0; +} + +#tabs .ui-tabs-nav li.ui-tabs-active { + margin-top: 0; + padding-top: 0; +} + + div#toolbar { padding: 3px; height: 27px; @@ -196,7 +229,7 @@ } div#templateContainer { - height: 741px; + height: 711px; overflow: auto; } @@ -215,11 +248,31 @@ width: 92px; padding-top: 11px; font-size: 10pt; + font-family: serif; } #canvas { overflow: auto; width: 844px; - height: 741px; + height: 711px; vertical-align: top; +} + + +#tabDescription > table { + margin: auto; + padding-top: 180px; +} + +#tabDescription > table td { + padding: 0 0 30px 20px; +} + +td.ldDescriptionLabel { + font-weight: bold; +} + +#ldDescriptionFieldDescription { + width: 500px; + height: 200px; } \ No newline at end of file Index: lams_central/web/includes/javascript/authoring/authoringActivity.js =================================================================== diff -u -re1f6c04ba5b6d797d9687b375fb062fa10d754b0 -re1be1f233c3aaea87dd4336c486758ceadb35061 --- lams_central/web/includes/javascript/authoring/authoringActivity.js (.../authoringActivity.js) (revision e1f6c04ba5b6d797d9687b375fb062fa10d754b0) +++ lams_central/web/includes/javascript/authoring/authoringActivity.js (.../authoringActivity.js) (revision e1be1f233c3aaea87dd4336c486758ceadb35061) @@ -28,7 +28,7 @@ * Constructor for a Grouping Activity. */ GroupingActivity : function(id, x, y, title, groupingID, groupingType, groupDivide, groupCount, learnerCount, - equalSizes, viewLearners, groupNames) { + equalSizes, viewLearners, groups) { this.id = id; this.groupingID = groupingID; this.type = 'grouping'; @@ -39,7 +39,7 @@ this.learnerCount = learnerCount || 1; this.equalSizes = equalSizes || false; this.viewLearners = viewLearners || false; - this.groupNames = groupNames || []; + this.groups = groups || []; this.transitions = { 'from' : [], 'to' : [] @@ -107,14 +107,17 @@ this.id = id; this.start = branchingEdgeStart; this.branches = []; + // mapping between groups and branches, if applicable + this.groupsToBranches = []; }, /** * Represents a subsequence of activities. It is not displayed on canvas. */ - BranchActivity : function(id, title, branchingActivity, transitionFrom) { + BranchActivity : function(id, uiid, title, branchingActivity, transitionFrom) { this.id = id; + this.uiid = uiid; this.title = title; this.transitionFrom = transitionFrom; this.branchingActivity = branchingActivity; @@ -387,9 +390,10 @@ transition.mousedown(HandlerLib.transitionMousedownHandler); if (!redraw && fromActivity.type == 'branchingEdge' && fromActivity.isStart - && (toActivity.type != 'branchingEdge' || fromActivity.branchingActivity != toActivity.branchingActivity)) { + && (toActivity.type != 'branchingEdge' + || fromActivity.branchingActivity != toActivity.branchingActivity)) { // create a new branch - var branch = new ActivityLib.BranchActivity(null, null, fromActivity.branchingActivity, transition); + var branch = new ActivityLib.BranchActivity(null, null, null, fromActivity.branchingActivity, transition); fromActivity.branchingActivity.branches.push(branch); transition.data('branch', branch); } Index: lams_central/web/includes/javascript/authoring/authoringGeneral.js =================================================================== diff -u -re1f6c04ba5b6d797d9687b375fb062fa10d754b0 -re1be1f233c3aaea87dd4336c486758ceadb35061 --- lams_central/web/includes/javascript/authoring/authoringGeneral.js (.../authoringGeneral.js) (revision e1f6c04ba5b6d797d9687b375fb062fa10d754b0) +++ lams_central/web/includes/javascript/authoring/authoringGeneral.js (.../authoringGeneral.js) (revision e1be1f233c3aaea87dd4336c486758ceadb35061) @@ -8,6 +8,7 @@ // configuration and storage of various elements var layout = { + 'isZoomed' : false, 'activities' : null, 'items' : { 'bin' : null, @@ -145,6 +146,13 @@ * Initialises various Authoring widgets. */ function initLayout() { + $('#tabs').tabs(); + $('#tabs .ui-tabs-nav, #tabs .ui-tabs-nav > *') + .removeClass( "ui-corner-all ui-corner-top" ) + .addClass( "ui-corner-bottom" ); + $('#tabs .ui-tabs-nav').appendTo('#tabs'); + + // initalise open Learning Design dialog var ldStoreDialog = $('#ldStoreDialog').dialog({ 'autoOpen' : false, @@ -267,6 +275,9 @@ // remove existing activities MenuLib.newLearningDesign(true); + $('#ldDescriptionFieldTitle').text(ld.title); + $('#ldDescriptionFieldDescription').text(ld.description); + var resizeNeeded = false, arrangeNeeded = false, // current paper dimensions @@ -300,7 +311,7 @@ var groupingData = this; if (groupingData.groupingID == activityData.createGroupingID) { var groupingType = null, - groupNames = []; + groups = []; // translate backend grouping type to human readable for better understanding switch(groupingData.groupingTypeID) { @@ -316,7 +327,11 @@ }; // get groups names $.each(groupingData.groups, function(){ - groupNames.push(this.groupName); + groups.push({ + 'name' : this.groupName, + 'id' : this.groupID, + 'uiid' : this.groupUIID + }); }); activity = new ActivityLib.GroupingActivity(activityData.activityID, @@ -330,7 +345,7 @@ groupingData.learnersPerGroup, groupingData.equalNumberOfLearnersPerGroup, groupingData.viewStudentsBeforeSelection, - groupNames); + groups); return false; } }) @@ -375,6 +390,7 @@ // create a branch inside the branching activity this.branchingActivity.branches.push( new ActivityLib.BranchActivity(activityData.activityID, + activityData.activityUIID, activityData.activityTitle, this.branchingActivity)); return false; @@ -449,7 +465,46 @@ } }); + // apply group -> branch mappings + $.each(ld.branchMappings, function(){ + var groupUIID = this.groupUIID, + branchUIID = this.sequenceActivityUIID, + group = null, + branch = null; + $.each(layout.activities, function(){ + // is it the branch we're looking for? + if (this.type == 'branchingEdge' && this.isStart) { + $.each(this.branchingActivity.branches, function(){ + if (branchUIID == this.uiid) { + branch = this; + return false; + } + }); + // is it the grouping we're looking for + } else if (this.type == 'grouping') { + $.each(this.groups, function(){ + if (groupUIID == this.uiid) { + group = this; + return false; + } + }); + } + + // found both, no need to continue iteration + if (group && branch) { + return false; + } + }); + + if (group && branch) { + branch.branchingActivity.groupsToBranches.push({ + 'group' : group, + 'branch' : branch + }); + } + }); + // draw starting and ending transitions in branches $.each(layout.activities, function(){ if (this.type == 'branchingEdge' && this.isStart) { @@ -466,9 +521,7 @@ } }); - // draw transitions from last activities in branches to end edge point - // draw plain transitions $.each(ld.transitions, function(){ var transition = this, @@ -501,7 +554,7 @@ if (arrangeNeeded) { MenuLib.arrangeActivities(); } else if (resizeNeeded) { - ActivityLib.resizePaper(paperWidth, paperHeight); + resizePaper(paperWidth, paperHeight); } else { HandlerLib.resetCanvasMode(); } Index: lams_central/web/includes/javascript/authoring/authoringMenu.js =================================================================== diff -u -re1f6c04ba5b6d797d9687b375fb062fa10d754b0 -re1be1f233c3aaea87dd4336c486758ceadb35061 --- lams_central/web/includes/javascript/authoring/authoringMenu.js (.../authoringMenu.js) (revision e1f6c04ba5b6d797d9687b375fb062fa10d754b0) +++ lams_central/web/includes/javascript/authoring/authoringMenu.js (.../authoringMenu.js) (revision e1be1f233c3aaea87dd4336c486758ceadb35061) @@ -98,9 +98,14 @@ * Run when gate is dropped on canvas. Creates a new gate activity. */ addTransition : function() { + var dialog = layout.items.infoDialog.text('Click on an activity'); + dialog.dialog('open'); + canvas.css('cursor', 'pointer').click(function(event){ HandlerLib.resetCanvasMode(); - + dialog.text(''); + dialog.dialog('close'); + var startActivity = null, targetElement = paper.getElementByPoint(event.pageX, event.pageY); @@ -407,6 +412,8 @@ return; } + $('.ldDescriptionField').text(''); + layout.activities = []; if (paper) { paper.clear(); @@ -477,5 +484,19 @@ newActivity.grouping = activity.grouping; newActivity.draw(); } + }, + + + zoom : function(){ + var zoomButton = $('#zoomButton > span'); + if (layout.isZoomed) { + paper.setViewBox(0, 0, paper.width, paper.height, true); + layout.isZoomed = false; + zoomButton.text('Zoom out'); + } else { + paper.setViewBox(-paper.width / 2, -paper.height / 2, paper.width * 2, paper.height * 2, true); + layout.isZoomed = true; + zoomButton.text('Cancel zoom'); + } } }; \ No newline at end of file Index: lams_central/web/includes/javascript/authoring/authoringProperty.js =================================================================== diff -u -re1f6c04ba5b6d797d9687b375fb062fa10d754b0 -re1be1f233c3aaea87dd4336c486758ceadb35061 --- lams_central/web/includes/javascript/authoring/authoringProperty.js (.../authoringProperty.js) (revision e1f6c04ba5b6d797d9687b375fb062fa10d754b0) +++ lams_central/web/includes/javascript/authoring/authoringProperty.js (.../authoringProperty.js) (revision e1be1f233c3aaea87dd4336c486758ceadb35061) @@ -47,13 +47,8 @@ activity = dialog.dialog('option', 'activity'); // extract group names from text fields - activity.groupNames = []; - $('input', dialog).each(function(){ - // do not take into account empty group names - var groupName = $(this).val().trim(); - if (groupName) { - activity.groupNames.push(groupName); - } + $('input', dialog).each(function(index){ + activity.groups[index].groupName = $(this).val().trim(); }); dialog.dialog('close'); @@ -86,23 +81,32 @@ 'text' : 'OK', 'click' : function() { var dialog = $(this), - activity = dialog.dialog('option', 'activity'); + branchingActivity = dialog.dialog('option', 'branchingActivity'); // find references to groups and branches - activity.groupsToBranches = []; + branchingActivity.groupsToBranches = []; $('#gtbMappingGroupCell div', dialog).each(function(){ - var groupName = $(this).text(), - branchName = $(this).data('boundItem').text(), + var groupUIID = $(this).attr('uiid'), + branchUIID = $(this).data('boundItem').attr('uiid'), + group = null, branch = null; - $.each(activity.branchingActivity.branches, function(){ - if (branchName == this.title) { + $.each(branchingActivity.branches, function(){ + if (branchUIID == this.uiid) { branch = this; return false; } }); - activity.groupsToBranches.push({ - 'group' : groupName, + $.each(branchingActivity.grouping.groups, function(){ + if (groupUIID == this.uiid) { + group = this; + return false; + } + }); + + // add the mapping + branchingActivity.groupsToBranches.push({ + 'group' : group, 'branch' : branch }); }); @@ -306,7 +310,7 @@ */ branchingProperties : function() { var activity = this, - content = activity.propertiesContent; + content = activity.propertiesContent; var fillWidgetsFunction = function(){ $('.propertiesContentFieldTitle', content).val(activity.branchingActivity.title); @@ -429,10 +433,10 @@ // remove existing entries and add reference to the initiating activity dialog.empty().dialog('option', 'activity', activity); - activity.groupNames = PropertyLib.createNameList(activity.groupCount, - activity.groupNames, 'Group '); - $.each(activity.groupNames, function(){ - $('').addClass('groupName').appendTo(dialog).val(this); + activity.groups = PropertyLib.fillNameAndUIIDList(activity.groupCount, + activity.groups, 'name', 'Group '); + $.each(activity.groups, function(){ + $('').addClass('groupName').appendTo(dialog).val(this.groupName); dialog.append('
'); }); @@ -449,28 +453,47 @@ grouping = branchingActivity.grouping, groupsCell = $('#gtbGroupsCell', dialog), branchesCell = $('#gtbBranchesCell', dialog), - branchNames = []; + groupCell = $('#gtbMappingGroupCell', dialog), + branchCell = $('#gtbMappingBranchCell', dialog), + branches = branchingActivity.branches; + // remove existing entries and add reference to the initiating activity - dialog.dialog('option', 'activity', activity); + dialog.dialog('option', 'branchingActivity', branchingActivity); $('.gtbListCell', dialog).empty(); // find group names and create DOM elements out of them - grouping.groupNames = PropertyLib.createNameList(grouping.groupCount, - grouping.groupNames, 'Group '); - $.each(grouping.groupNames, function(){ - $('
').click(PropertyLib.selectGroupsToBranchesListItem).appendTo(groupsCell) - .text(this); - }); + grouping.groups = PropertyLib.fillNameAndUIIDList(grouping.groupCount, + grouping.groups, 'name', 'Group '); + branches = branchingActivity.branches = PropertyLib.fillNameAndUIIDList(branches.length, + branches, 'title', 'Branch '); - // find branch names and create DOM elements out of them - $.each(branchingActivity.branches, function(){ - branchNames.push(this.title); + $.each(grouping.groups, function(){ + var group = this, + groupElem = $('
').click(PropertyLib.selectGroupsToBranchesListItem) + .text(group.name).attr('uiid', group.uiid); + + // check if a group-branch mapping is already defined + $.each(branchingActivity.groupsToBranches, function() { + if (this.group == group) { + var branchElem = $('
').click(PropertyLib.selectGroupsToBranchesListItem) + .appendTo(branchCell) + .text(this.branch.title) + .attr('uiid', this.branch.uiid) + .data('boundItem', groupElem); + groupElem.appendTo(groupCell).data('boundItem', branchElem); + groupElem = null; + return false; + } + }); + + if (groupElem) { + // no existing mapping was found, make the group available for mapping + groupElem.appendTo(groupsCell); + } }); - branchNames = PropertyLib.createNameList(branchNames.length, - branchNames, 'Branch '); - $.each(branchNames, function(){ + $.each(branches, function(){ $('
').click(PropertyLib.selectGroupsToBranchesListItem).appendTo(branchesCell) - .text(this); + .text(this.title).attr('uiid', this.uiid); }); dialog.dialog('open'); @@ -497,12 +520,19 @@ /** * Creates group and branch names, if they are not already provided. */ - createNameList : function(size, existingList, prefix) { + fillNameAndUIIDList : function(size, existingList, nameAttr, prefix) { var list = []; for (var itemIndex = 1; itemIndex <= size; itemIndex++) { - // generate a name if it does not exist - list.push(itemIndex > existingList.length || !existingList[itemIndex - 1] ? - prefix + itemIndex : existingList[itemIndex - 1]); + // generate a name and an UIID if they do not exist + var item = itemIndex > existingList.length ? {} : existingList[itemIndex - 1]; + if (!item[nameAttr]) { + item[nameAttr] = prefix + itemIndex; + } + if (!item.uiid) { + // new unique UIID; TODO: change + item.uiid = new Date().getTime() + '_' + itemIndex; + } + list.push(item); } return list; },