From 586a47a2ad2d4210f02c08d22bc679196c6553e6 Mon Sep 17 00:00:00 2001 From: Valera Rozuvan Date: Thu, 3 Jan 2013 14:25:53 +0200 Subject: [PATCH] Rewrote functionality to include labels as separate from the container. Fixed bugs. Refactoring. --- .../js/capa/drag_and_drop/config_parser.js | 2 + .../js/capa/drag_and_drop/draggables.js | 178 +++++++++++++++--- .../static/js/capa/drag_and_drop/scroller.js | 8 +- common/static/js/capa/drag_and_drop/state.js | 4 +- .../js/capa/drag_and_drop/update_input.js | 103 +++++++--- 5 files changed, 242 insertions(+), 53 deletions(-) diff --git a/common/static/js/capa/drag_and_drop/config_parser.js b/common/static/js/capa/drag_and_drop/config_parser.js index 664324e0b9..6800cb7c97 100644 --- a/common/static/js/capa/drag_and_drop/config_parser.js +++ b/common/static/js/capa/drag_and_drop/config_parser.js @@ -12,6 +12,8 @@ define(['logme'], function (logme) { returnStatus = true; + logme('imageDir', imageDir); + state.config = { 'imageDir': '/static/' + imageDir + '/images', 'draggables': [], diff --git a/common/static/js/capa/drag_and_drop/draggables.js b/common/static/js/capa/drag_and_drop/draggables.js index 2123e7650a..c4c5a94ec0 100644 --- a/common/static/js/capa/drag_and_drop/draggables.js +++ b/common/static/js/capa/drag_and_drop/draggables.js @@ -11,11 +11,13 @@ define(['logme', 'update_input'], function (logme, updateInput) { var c1; state.draggables = []; + state.numDraggablesInSlider = 0; for (c1 = 0; c1 < state.config.draggables.length; c1 += 1) { processDraggable(state.config.draggables[c1], c1 + 1); } + state.updateArrowOpacity(); state.currentMovingDraggable = null; $(document).mousemove(function (event) { @@ -34,17 +36,35 @@ define(['logme', 'update_input'], function (logme, updateInput) { state.baseImageEl.offset().top - state.currentMovingDraggable.iconHeight * 0.5 ); + + if (state.currentMovingDraggable.labelEl !== null) { + state.currentMovingDraggable.labelEl.css( + 'top', + event.pageY - + state.baseImageEl.offset().top + + state.currentMovingDraggable.iconHeight * 0.5 + + 5 + ); + state.currentMovingDraggable.labelEl.css( + 'left', + event.pageX - + state.baseImageEl.offset().left - + state.currentMovingDraggable.labelWidth * 0.5 + ); + } } }); return; function processDraggable(obj, objIndex) { - var inContainer, mousePressed, onTarget, draggableObj, marginCss; + var inContainer, mousePressed, onTarget, draggableObj; - draggableObj = {}; - - draggableObj.zIndex = objIndex; + draggableObj = { + 'zIndex': objIndex, + 'labelEl': null, + 'hasLoaded': false + }; draggableObj.containerEl = $( '
' ); + draggableObj.containerEl.appendTo(state.sliderEl); if (obj.icon.length > 0) { + draggableObj.hasIcon = true; + draggableObj.iconEl = $(''); draggableObj.iconEl.attr( 'src', @@ -73,32 +97,90 @@ define(['logme', 'update_input'], function (logme, updateInput) { draggableObj.iconWidth = this.width; draggableObj.iconHeight = this.height; + if (draggableObj.iconWidth >= draggableObj.iconHeight) { + draggableObj.iconWidthSmall = 60; + draggableObj.iconHeightSmall = draggableObj.iconWidthSmall * (draggableObj.iconHeight / draggableObj.iconWidth); + } else { + draggableObj.iconHeightSmall = 60; + draggableObj.iconWidthSmall = draggableObj.iconHeightSmall * (draggableObj.iconWidth / draggableObj.iconHeight); + } + draggableObj.iconEl.css('position', 'absolute'); - draggableObj.iconEl.css('top', (50 - this.height * 0.5) + 'px'); - draggableObj.iconEl.css('left', (50 - this.width * 0.5) + 'px'); + + draggableObj.iconEl.css('width', draggableObj.iconWidthSmall); + draggableObj.iconEl.css('height', draggableObj.iconHeightSmall); + + draggableObj.iconEl.css('left', 50 - draggableObj.iconWidthSmall * 0.5); + + if (obj.label.length > 0) { + draggableObj.iconEl.css('top', 5); + } else { + draggableObj.iconEl.css('top', 50 - draggableObj.iconHeightSmall * 0.5); + } draggableObj.iconEl.appendTo(draggableObj.containerEl); - }); - draggableObj.iconEl.mousedown(mouseDown); - draggableObj.iconEl.mouseup(mouseUp); - draggableObj.iconEl.mousemove(mouseMove); + if (obj.label.length > 0) { + draggableObj.labelEl = $( + '
' + + obj.label + + '
' + ); + + draggableObj.labelEl.appendTo(draggableObj.containerEl); + + draggableObj.labelWidth = draggableObj.labelEl.width(); + + draggableObj.labelEl.css('left', 50 - draggableObj.labelWidth * 0.5); + draggableObj.labelEl.css('top', 5 + draggableObj.iconHeightSmall + 5); + + draggableObj.labelEl.mousedown(mouseDown); + draggableObj.labelEl.mouseup(mouseUp); + draggableObj.labelEl.mousemove(mouseMove); + } + + draggableObj.hasLoaded = true; + }); } else { - // Must fix - add +label support, and just label support. - return; + // To make life easier, if there is no icon, but there is a + // label, we will create a label and store it as if it was an + // icon. All the existing code will work, and the user will + // see a label instead of an icon. + if (obj.label.length > 0) { + logme('We have a label length > 0.'); + + draggableObj.iconEl = $( + '
' + + obj.label + + '
' + ); + + draggableObj.iconEl.appendTo(draggableObj.containerEl); + + draggableObj.iconWidth = draggableObj.iconEl.width(); + draggableObj.iconHeight = draggableObj.iconEl.height(); + draggableObj.iconWidthSmall = draggableObj.iconWidth; + draggableObj.iconHeightSmall = draggableObj.iconHeight; + + draggableObj.iconEl.css('left', 50 - draggableObj.iconWidthSmall * 0.5); + draggableObj.iconEl.css('top', 50 - draggableObj.iconHeightSmall * 0.5); + } else { + // If no icon and no label, don't create a draggable. + return; + } } - // if (obj.label.length > 0) { - // marginCss = ''; - // - // if (obj.icon.length === 0) { - // marginCss = 'margin-top: 38px;'; - // } - - // draggableContainerEl.append( - // $('
' + obj.label + '
') - // ); - // } + draggableObj.iconEl.mousedown(mouseDown); + draggableObj.iconEl.mouseup(mouseUp); + draggableObj.iconEl.mousemove(mouseMove); inContainer = true; mousePressed = false; @@ -114,6 +196,12 @@ define(['logme', 'update_input'], function (logme, updateInput) { state.draggables.push(draggableObj); + state.numDraggablesInSlider += 1; + + if (obj.icon.length === 0) { + draggableObj.hasLoaded = true; + } + return; function mouseDown(event) { @@ -125,11 +213,23 @@ define(['logme', 'update_input'], function (logme, updateInput) { draggableObj.containerEl.hide(); draggableObj.iconEl.detach(); + + draggableObj.iconEl.css('width', draggableObj.iconWidth); + draggableObj.iconEl.css('height', draggableObj.iconHeight); + draggableObj.iconEl.css('left', event.pageX - state.baseImageEl.offset().left - draggableObj.iconWidth * 0.5); draggableObj.iconEl.css('top', event.pageY - state.baseImageEl.offset().top - draggableObj.iconHeight * 0.5); draggableObj.iconEl.appendTo(state.baseImageEl.parent()); + if (draggableObj.labelEl !== null) { + draggableObj.labelEl.detach(); + draggableObj.labelEl.css('left', event.pageX - state.baseImageEl.offset().left - draggableObj.labelWidth * 0.5); + draggableObj.labelEl.css('top', event.pageY - state.baseImageEl.offset().top + draggableObj.iconHeight * 0.5 + 5); + draggableObj.labelEl.appendTo(state.baseImageEl.parent()); + } + inContainer = false; + state.numDraggablesInSlider -= 1; } draggableObj.oldZIndex = draggableObj.zIndex; @@ -178,6 +278,8 @@ define(['logme', 'update_input'], function (logme, updateInput) { } else { moveBackToSlider(); removeObjIdFromTarget(); + + state.numDraggablesInSlider += 1; } } else { if ( @@ -190,6 +292,8 @@ define(['logme', 'update_input'], function (logme, updateInput) { draggableObj.x = -1; draggableObj.y = -1; + + state.numDraggablesInSlider += 1; } else { correctZIndexes(); @@ -283,6 +387,11 @@ define(['logme', 'update_input'], function (logme, updateInput) { draggableObj.iconEl.css('left', target.offset.left + 0.5 * target.w - draggableObj.iconWidth * 0.5 + offset); draggableObj.iconEl.css('top', target.offset.top + 0.5 * target.h - draggableObj.iconHeight * 0.5 + offset); + + if (draggableObj.labelEl !== null) { + draggableObj.labelEl.css('left', target.offset.left + 0.5 * target.w - draggableObj.labelWidth * 0.5 + offset); + draggableObj.labelEl.css('top', target.offset.top + 0.5 * target.h + draggableObj.iconHeight * 0.5 + 5 + offset); + } } // Go through all of the draggables subtract 1 from the z-index @@ -316,17 +425,30 @@ define(['logme', 'update_input'], function (logme, updateInput) { // move it back to the slider, placing it in the same position // that it was dragged out of. function moveBackToSlider() { - var c1; - draggableObj.containerEl.show(); draggableObj.iconEl.detach(); - draggableObj.iconEl.css('top', (50 - draggableObj.iconHeight * 0.5) + 'px'); - draggableObj.iconEl.css('left', (50 - draggableObj.iconWidth * 0.5) + 'px'); + draggableObj.iconEl.css('width', draggableObj.iconWidthSmall); + draggableObj.iconEl.css('height', draggableObj.iconHeightSmall); + + draggableObj.iconEl.css('left', 50 - draggableObj.iconWidthSmall * 0.5); + + if (draggableObj.labelEl !== null) { + draggableObj.iconEl.css('top', 5); + } else { + draggableObj.iconEl.css('top', 50 - draggableObj.iconHeightSmall * 0.5); + } draggableObj.iconEl.appendTo(draggableObj.containerEl); + if (draggableObj.labelEl !== null) { + draggableObj.labelEl.detach(); + draggableObj.labelEl.css('left', 50 - draggableObj.labelWidth * 0.5); + draggableObj.labelEl.css('top', 5 + draggableObj.iconHeightSmall + 5); + draggableObj.labelEl.appendTo(draggableObj.containerEl); + } + inContainer = true; } } diff --git a/common/static/js/capa/drag_and_drop/scroller.js b/common/static/js/capa/drag_and_drop/scroller.js index d3a4d23eab..505785086d 100644 --- a/common/static/js/capa/drag_and_drop/scroller.js +++ b/common/static/js/capa/drag_and_drop/scroller.js @@ -105,7 +105,9 @@ define(['logme'], function (logme) { '
' ); @@ -158,7 +160,7 @@ define(['logme'], function (logme) { // When there are no more hidden draggables, prevent from // scrolling infinitely. - if (showElLeftMargin < -102 * (state.sliderEl.children().length - 6)) { + if (showElLeftMargin < -102 * (state.numDraggablesInSlider - 6)) { return; } @@ -192,7 +194,7 @@ define(['logme'], function (logme) { moveLeftEl.children('div').css('opacity', '1'); moveRightEl.children('div').css('opacity', '1'); - if (showElLeftMargin < -102 * (state.sliderEl.children().length - 6)) { + if (showElLeftMargin < -102 * (state.numDraggablesInSlider - 6)) { moveRightEl.children('div').css('opacity', '.4'); } if (showElLeftMargin > -102) { diff --git a/common/static/js/capa/drag_and_drop/state.js b/common/static/js/capa/drag_and_drop/state.js index 5bf957eff5..c3a4d3c4ac 100644 --- a/common/static/js/capa/drag_and_drop/state.js +++ b/common/static/js/capa/drag_and_drop/state.js @@ -14,7 +14,9 @@ define([], function () { // Will indicate when all targetsand draggables have been loaded, // processed, and postioned intially. 'targetsLoaded': false, - 'draggablesLoaded': false + 'draggablesLoaded': false, + + 'numDraggablesInSlider': 0 }; } }); diff --git a/common/static/js/capa/drag_and_drop/update_input.js b/common/static/js/capa/drag_and_drop/update_input.js index 6ebf62ef11..0ae95e6a30 100644 --- a/common/static/js/capa/drag_and_drop/update_input.js +++ b/common/static/js/capa/drag_and_drop/update_input.js @@ -75,7 +75,12 @@ define(['logme'], function (logme) { function repositionDraggables(answer) { var draggableId, draggable, targetId, target, draggablePosition, - c1; + c1, offset; + + offset = 0; + if (state.config.targetOutline === true) { + offset = 1; + } logme(answer); @@ -98,22 +103,47 @@ define(['logme'], function (logme) { continue; } + (function (c1, draggableId, draggable) { + moveDraggableToBaseImage(); + return; - draggable.setInContainer(false); + function moveDraggableToBaseImage() { + if (draggable.hasLoaded === false) { + setTimeout(moveDraggableToBaseImage, 50); + return; + } - draggable.el.detach(); - draggable.el.css('border', 'none'); - draggable.el.css('position', 'absolute'); - draggable.el.css('left', answer.draggables[c1][draggableId][0] - 50); - draggable.el.css('top', answer.draggables[c1][draggableId][1] - 50); + draggable.setInContainer(false); + draggable.containerEl.hide(); - draggable.el.css('left', target.offset.left + 0.5 * target.w - 50); - draggable.el.css('top', target.offset.top + 0.5 * target.h - 50); + draggable.iconEl.detach(); - draggable.el.appendTo(state.baseImageEl.parent()); + draggable.iconEl.css('width', draggable.iconWidth); + draggable.iconEl.css('height', draggable.iconHeight); + draggable.iconEl.css( + 'left', + target.offset.left + 0.5 * target.w - draggable.iconWidth * 0.5 + offset + ); + draggable.iconEl.css( + 'top', + target.offset.top + 0.5 * target.h - draggable.iconHeight * 0.5 + offset + ); - draggable.setOnTarget(target); - target.draggable.push(draggableId); + draggable.iconEl.appendTo(state.baseImageEl.parent()); + + if (draggable.labelEl !== null) { + draggable.labelEl.detach(); + + draggable.labelEl.css('left', target.offset.left + 0.5 * target.w - draggable.labelWidth * 0.5 + offset); + draggable.labelEl.css('top', target.offset.top + 0.5 * target.h + draggable.iconHeight * 0.5 + 5 + offset); + + draggable.labelEl.appendTo(state.baseImageEl.parent()); + } + + draggable.setOnTarget(target); + target.draggable.push(draggableId); + } + }(c1, draggableId, draggable)); } } } else if ( @@ -128,17 +158,47 @@ define(['logme'], function (logme) { continue; } - draggable.setInContainer(false); + (function (c1, draggableId, draggable) { + moveDraggableToBaseImage(); + return; - draggable.el.detach(); - draggable.el.css('border', 'none'); - draggable.el.css('position', 'absolute'); - draggable.el.css('left', answer.draggables[c1][draggableId][0] - 50); - draggable.el.css('top', answer.draggables[c1][draggableId][1] - 50); - draggable.el.appendTo(state.baseImageEl.parent()); + function moveDraggableToBaseImage() { + if (draggable.hasLoaded === false) { + setTimeout(moveDraggableToBaseImage, 50); + return; + } - draggable.x = answer.draggables[c1][draggableId][0]; - draggable.y = answer.draggables[c1][draggableId][1]; + draggable.setInContainer(false); + draggable.containerEl.hide(); + + draggable.iconEl.detach(); + + draggable.iconEl.css('width', draggable.iconWidth); + draggable.iconEl.css('height', draggable.iconHeight); + draggable.iconEl.css( + 'left', + answer.draggables[c1][draggableId][0] - draggable.iconWidth * 0.5 + offset + ); + draggable.iconEl.css( + 'top', + answer.draggables[c1][draggableId][0] - draggable.iconHeight * 0.5 + offset + ); + + draggable.iconEl.appendTo(state.baseImageEl.parent()); + + if (draggable.labelEl !== null) { + draggable.labelEl.detach(); + + draggable.labelEl.css('left', answer.draggables[c1][draggableId][0] - draggable.iconWidth * 0.5 - draggable.labelWidth * 0.5 + offset); + draggable.labelEl.css('top', answer.draggables[c1][draggableId][0] - draggable.iconHeight * 0.5 + draggable.iconHeight + 5 + offset); + + draggable.labelEl.appendTo(state.baseImageEl.parent()); + } + + draggable.x = answer.draggables[c1][draggableId][0]; + draggable.y = answer.draggables[c1][draggableId][1]; + } + }(c1, draggableId, draggable)); } } } else { @@ -147,6 +207,7 @@ define(['logme'], function (logme) { return; } + state.numDraggablesInSlider -= 1; state.updateArrowOpacity(); }