MDL-43462 assignfeedback_editpdf: fix display of landscape PDFs

The size of the drawing canvas is now set from the size of the generated page image, with automatic
scrolling if it is too wide to display
Absolutely-positioned nodes (comments + stamps) are repositioned as the drawing canvas is scrolled
This commit is contained in:
Davo Smith
2014-12-16 11:54:42 +00:00
parent 9258886927
commit fc4da5659e
10 changed files with 298 additions and 27 deletions
+7
View File
@@ -91,6 +91,13 @@ if ($action == 'loadallpages') {
'/',
$pagefile->get_filename())->out();
$page->comments = $comments;
if ($imageinfo = $pagefile->get_imageinfo()) {
$page->width = $imageinfo['width'];
$page->height = $imageinfo['height'];
} else {
$page->width = 0;
$page->height = 0;
}
$annotations = page_editor::get_annotations($grade->id, $index, $draft);
$page->annotations = $annotations;
array_push($response->pages, $page);
@@ -209,9 +209,8 @@ class assignfeedback_editpdf_renderer extends plugin_renderer_base {
$loading = html_writer::div($progressbar . $progressbarlabel, 'loading');
$canvas = html_writer::div($loading, 'drawingcanvas');
$body .= html_writer::div($canvas, 'drawingregion');
$body .= '<hr/>';
$canvas = html_writer::div($canvas, 'drawingregion');
$body .= html_writer::div($canvas, 'hideoverflow');
$footer = '';
+11 -1
View File
@@ -8,8 +8,14 @@
.assignfeedback_editpdf_widget .drawingcanvas {
position: relative;
min-width: 817px;
min-height: 1169px;
min-height: 400px;
cursor: crosshair;
background-repeat: no-repeat;
background-color: #ccc;
}
.assignfeedback_editpdf_widget .drawingregion {
overflow: auto;
width: 842px; /* A4 portrait should not need a horizontal scrollbar */
}
.assignfeedback_editpdf_widget {
@@ -280,3 +286,7 @@ ul.assignfeedback_editpdf_menu {
.assignfeedback_editpdf_widget .drawingcanvas .loading .progressbarlabel {
text-align: center;
}
.hideoverflow {
overflow: hidden;
position: relative;
}
@@ -468,6 +468,42 @@ DRAWABLE = function(editor) {
}
};
/**
* Update the positions of all absolutely positioned nodes, when the drawing canvas is scrolled
* @public
* @method scroll_update
* @param scrollx int
* @param scrolly int
*/
this.scroll_update = function(scrollx, scrolly) {
var i, x, y;
for (i = 0; i < this.nodes.length; i++) {
x = this.nodes[i].getData('x');
y = this.nodes[i].getData('y');
if (x !== undefined && y !== undefined) {
this.nodes[i].setX(parseInt(x, 10) - scrollx);
this.nodes[i].setY(parseInt(y, 10) - scrolly);
}
}
};
/**
* Store the initial position of the node, so it can be updated when the drawing canvas is scrolled
* @public
* @method store_position
* @param container
* @param x
* @param y
*/
this.store_position = function(container, x, y) {
var drawingregion, scrollx, scrolly;
drawingregion = Y.one(SELECTOR.DRAWINGREGION);
scrollx = parseInt(drawingregion.get('scrollLeft'), 10);
scrolly = parseInt(drawingregion.get('scrollTop'), 10);
container.setData('x', x + scrollx);
container.setData('y', y + scrolly);
};
};
M.assignfeedback_editpdf = M.assignfeedback_editpdf || {};
@@ -1533,6 +1569,7 @@ Y.extend(ANNOTATIONSTAMP, M.assignfeedback_editpdf.annotation, {
drawingregion.append(node);
node.setX(position.x);
node.setY(position.y);
drawable.store_position(node, position.x, position.y);
// Pass throught the event handlers on the div.
node.on('gesturemovestart', this.editor.edit_start, null, this.editor);
@@ -1576,6 +1613,7 @@ Y.extend(ANNOTATIONSTAMP, M.assignfeedback_editpdf.annotation, {
drawingregion.append(node);
node.setX(position.x);
node.setY(position.y);
drawable.store_position(node, position.x, position.y);
drawable.nodes.push(node);
@@ -2493,6 +2531,7 @@ COMMENT = function(editor, gradeid, pageno, x, y, width, colour, rawtext) {
container.setStyle('position', 'absolute');
container.setX(position.x);
container.setY(position.y);
drawable.store_position(container, position.x, position.y);
drawable.nodes.push(container);
node.set('value', this.rawtext);
scrollheight = node.get('scrollHeight'),
@@ -2600,6 +2639,7 @@ COMMENT = function(editor, gradeid, pageno, x, y, width, colour, rawtext) {
windowlocation = this.editor.get_window_coordinates(newlocation);
node.ancestor().setX(windowlocation.x);
node.ancestor().setY(windowlocation.y);
this.drawable.store_position(node.ancestor(), windowlocation.x, windowlocation.y);
}, null, this);
this.menu = new M.assignfeedback_editpdf.commentmenu({
@@ -3296,7 +3336,7 @@ EDITOR.prototype = {
* @method link_handler
*/
link_handler : function(e) {
var drawingcanvas;
var drawingcanvas, drawingregion, resize = true;
e.preventDefault();
if (!this.dialogue) {
@@ -3318,6 +3358,9 @@ EDITOR.prototype = {
drawingcanvas = Y.one(SELECTOR.DRAWINGCANVAS);
this.graphic = new Y.Graphic({render : SELECTOR.DRAWINGCANVAS});
drawingregion = Y.one(SELECTOR.DRAWINGREGION);
drawingregion.on('scroll', this.move_canvas, this);
if (!this.get('readonly')) {
drawingcanvas.on('gesturemovestart', this.edit_start, null, this);
drawingcanvas.on('gesturemove', this.edit_move, null, this);
@@ -3327,10 +3370,18 @@ EDITOR.prototype = {
}
this.load_all_pages();
drawingcanvas.on('windowresize', this.resize, this);
resize = false;
}
this.dialogue.centerDialogue();
this.dialogue.show();
drawingcanvas.on('windowresize', this.resize, this);
// Redraw when the dialogue is moved, to ensure the absolute elements are all positioned correctly.
this.dialogue.dd.on('drag:end', this.redraw, this);
if (resize) {
this.resize(); // When re-opening the dialog call redraw, to make sure the size + layout is correct.
}
},
/**
@@ -3843,7 +3894,21 @@ EDITOR.prototype = {
* @method resize
*/
resize : function() {
var drawingregion, drawregionheight;
if (!this.dialogue.get('visible')) {
return;
}
this.dialogue.centerDialogue();
// Make sure the dialogue box is not bigger than the max height of the viewport.
drawregionheight = Y.one('body').get('winHeight') - 120; // Space for toolbar + titlebar.
if (drawregionheight < 100) {
drawregionheight = 100;
}
drawingregion = Y.one(SELECTOR.DRAWINGREGION);
drawingregion.setStyle('maxHeight', drawregionheight +'px');
this.redraw();
return true;
},
@@ -3944,6 +4009,9 @@ EDITOR.prototype = {
page;
page = this.pages[this.currentpage];
if (page === undefined) {
return; // Can happen if a redraw is triggered by an event, before the page has been selected.
}
while (this.drawables.length > 0) {
this.drawables.pop().erase();
}
@@ -3984,11 +4052,13 @@ EDITOR.prototype = {
page = this.pages[this.currentpage];
this.loadingicon.hide();
drawingcanvas.setStyle('backgroundImage', 'url("' + page.url + '")');
drawingcanvas.setStyle('width', page.width + 'px');
drawingcanvas.setStyle('height', page.height + 'px');
// Update page select.
Y.one(SELECTOR.PAGESELECT).set('value', this.currentpage);
this.redraw();
this.resize(); // Internally will call 'redraw', after checking the dialogue size.
},
/**
@@ -4056,10 +4126,25 @@ EDITOR.prototype = {
this.currentpage = this.pages.length - 1;
}
this.change_page();
},
/**
* Update any absolutely positioned nodes, within each drawable, when the drawing canvas is scrolled
* @protected
* @method move_canvas
*/
move_canvas: function() {
var drawingregion, x, y, i;
drawingregion = Y.one(SELECTOR.DRAWINGREGION);
x = parseInt(drawingregion.get('scrollLeft'), 10);
y = parseInt(drawingregion.get('scrollTop'), 10);
for (i = 0; i < this.drawables.length; i++) {
this.drawables[i].scroll_update(x, y);
}
}
};
Y.extend(EDITOR, Y.Base, EDITOR.prototype, {
File diff suppressed because one or more lines are too long
@@ -468,6 +468,42 @@ DRAWABLE = function(editor) {
}
};
/**
* Update the positions of all absolutely positioned nodes, when the drawing canvas is scrolled
* @public
* @method scroll_update
* @param scrollx int
* @param scrolly int
*/
this.scroll_update = function(scrollx, scrolly) {
var i, x, y;
for (i = 0; i < this.nodes.length; i++) {
x = this.nodes[i].getData('x');
y = this.nodes[i].getData('y');
if (x !== undefined && y !== undefined) {
this.nodes[i].setX(parseInt(x, 10) - scrollx);
this.nodes[i].setY(parseInt(y, 10) - scrolly);
}
}
};
/**
* Store the initial position of the node, so it can be updated when the drawing canvas is scrolled
* @public
* @method store_position
* @param container
* @param x
* @param y
*/
this.store_position = function(container, x, y) {
var drawingregion, scrollx, scrolly;
drawingregion = Y.one(SELECTOR.DRAWINGREGION);
scrollx = parseInt(drawingregion.get('scrollLeft'), 10);
scrolly = parseInt(drawingregion.get('scrollTop'), 10);
container.setData('x', x + scrollx);
container.setData('y', y + scrolly);
};
};
M.assignfeedback_editpdf = M.assignfeedback_editpdf || {};
@@ -1533,6 +1569,7 @@ Y.extend(ANNOTATIONSTAMP, M.assignfeedback_editpdf.annotation, {
drawingregion.append(node);
node.setX(position.x);
node.setY(position.y);
drawable.store_position(node, position.x, position.y);
// Pass throught the event handlers on the div.
node.on('gesturemovestart', this.editor.edit_start, null, this.editor);
@@ -1576,6 +1613,7 @@ Y.extend(ANNOTATIONSTAMP, M.assignfeedback_editpdf.annotation, {
drawingregion.append(node);
node.setX(position.x);
node.setY(position.y);
drawable.store_position(node, position.x, position.y);
drawable.nodes.push(node);
@@ -2493,6 +2531,7 @@ COMMENT = function(editor, gradeid, pageno, x, y, width, colour, rawtext) {
container.setStyle('position', 'absolute');
container.setX(position.x);
container.setY(position.y);
drawable.store_position(container, position.x, position.y);
drawable.nodes.push(container);
node.set('value', this.rawtext);
scrollheight = node.get('scrollHeight'),
@@ -2600,6 +2639,7 @@ COMMENT = function(editor, gradeid, pageno, x, y, width, colour, rawtext) {
windowlocation = this.editor.get_window_coordinates(newlocation);
node.ancestor().setX(windowlocation.x);
node.ancestor().setY(windowlocation.y);
this.drawable.store_position(node.ancestor(), windowlocation.x, windowlocation.y);
}, null, this);
this.menu = new M.assignfeedback_editpdf.commentmenu({
@@ -3296,7 +3336,7 @@ EDITOR.prototype = {
* @method link_handler
*/
link_handler : function(e) {
var drawingcanvas;
var drawingcanvas, drawingregion, resize = true;
e.preventDefault();
if (!this.dialogue) {
@@ -3318,6 +3358,9 @@ EDITOR.prototype = {
drawingcanvas = Y.one(SELECTOR.DRAWINGCANVAS);
this.graphic = new Y.Graphic({render : SELECTOR.DRAWINGCANVAS});
drawingregion = Y.one(SELECTOR.DRAWINGREGION);
drawingregion.on('scroll', this.move_canvas, this);
if (!this.get('readonly')) {
drawingcanvas.on('gesturemovestart', this.edit_start, null, this);
drawingcanvas.on('gesturemove', this.edit_move, null, this);
@@ -3327,10 +3370,18 @@ EDITOR.prototype = {
}
this.load_all_pages();
drawingcanvas.on('windowresize', this.resize, this);
resize = false;
}
this.dialogue.centerDialogue();
this.dialogue.show();
drawingcanvas.on('windowresize', this.resize, this);
// Redraw when the dialogue is moved, to ensure the absolute elements are all positioned correctly.
this.dialogue.dd.on('drag:end', this.redraw, this);
if (resize) {
this.resize(); // When re-opening the dialog call redraw, to make sure the size + layout is correct.
}
},
/**
@@ -3843,7 +3894,21 @@ EDITOR.prototype = {
* @method resize
*/
resize : function() {
var drawingregion, drawregionheight;
if (!this.dialogue.get('visible')) {
return;
}
this.dialogue.centerDialogue();
// Make sure the dialogue box is not bigger than the max height of the viewport.
drawregionheight = Y.one('body').get('winHeight') - 120; // Space for toolbar + titlebar.
if (drawregionheight < 100) {
drawregionheight = 100;
}
drawingregion = Y.one(SELECTOR.DRAWINGREGION);
drawingregion.setStyle('maxHeight', drawregionheight +'px');
this.redraw();
return true;
},
@@ -3944,6 +4009,9 @@ EDITOR.prototype = {
page;
page = this.pages[this.currentpage];
if (page === undefined) {
return; // Can happen if a redraw is triggered by an event, before the page has been selected.
}
while (this.drawables.length > 0) {
this.drawables.pop().erase();
}
@@ -3984,11 +4052,13 @@ EDITOR.prototype = {
page = this.pages[this.currentpage];
this.loadingicon.hide();
drawingcanvas.setStyle('backgroundImage', 'url("' + page.url + '")');
drawingcanvas.setStyle('width', page.width + 'px');
drawingcanvas.setStyle('height', page.height + 'px');
// Update page select.
Y.one(SELECTOR.PAGESELECT).set('value', this.currentpage);
this.redraw();
this.resize(); // Internally will call 'redraw', after checking the dialogue size.
},
/**
@@ -4056,10 +4126,25 @@ EDITOR.prototype = {
this.currentpage = this.pages.length - 1;
}
this.change_page();
},
/**
* Update any absolutely positioned nodes, within each drawable, when the drawing canvas is scrolled
* @protected
* @method move_canvas
*/
move_canvas: function() {
var drawingregion, x, y, i;
drawingregion = Y.one(SELECTOR.DRAWINGREGION);
x = parseInt(drawingregion.get('scrollLeft'), 10);
y = parseInt(drawingregion.get('scrollTop'), 10);
for (i = 0; i < this.drawables.length; i++) {
this.drawables[i].scroll_update(x, y);
}
}
};
Y.extend(EDITOR, Y.Base, EDITOR.prototype, {
@@ -61,6 +61,7 @@ Y.extend(ANNOTATIONSTAMP, M.assignfeedback_editpdf.annotation, {
drawingregion.append(node);
node.setX(position.x);
node.setY(position.y);
drawable.store_position(node, position.x, position.y);
// Pass throught the event handlers on the div.
node.on('gesturemovestart', this.editor.edit_start, null, this.editor);
@@ -104,6 +105,7 @@ Y.extend(ANNOTATIONSTAMP, M.assignfeedback_editpdf.annotation, {
drawingregion.append(node);
node.setX(position.x);
node.setY(position.y);
drawable.store_position(node, position.x, position.y);
drawable.nodes.push(node);
@@ -193,6 +193,7 @@ COMMENT = function(editor, gradeid, pageno, x, y, width, colour, rawtext) {
container.setStyle('position', 'absolute');
container.setX(position.x);
container.setY(position.y);
drawable.store_position(container, position.x, position.y);
drawable.nodes.push(container);
node.set('value', this.rawtext);
scrollheight = node.get('scrollHeight'),
@@ -300,6 +301,7 @@ COMMENT = function(editor, gradeid, pageno, x, y, width, colour, rawtext) {
windowlocation = this.editor.get_window_coordinates(newlocation);
node.ancestor().setX(windowlocation.x);
node.ancestor().setY(windowlocation.y);
this.drawable.store_position(node.ancestor(), windowlocation.x, windowlocation.y);
}, null, this);
this.menu = new M.assignfeedback_editpdf.commentmenu({
@@ -70,6 +70,42 @@ DRAWABLE = function(editor) {
}
};
/**
* Update the positions of all absolutely positioned nodes, when the drawing canvas is scrolled
* @public
* @method scroll_update
* @param scrollx int
* @param scrolly int
*/
this.scroll_update = function(scrollx, scrolly) {
var i, x, y;
for (i = 0; i < this.nodes.length; i++) {
x = this.nodes[i].getData('x');
y = this.nodes[i].getData('y');
if (x !== undefined && y !== undefined) {
this.nodes[i].setX(parseInt(x, 10) - scrollx);
this.nodes[i].setY(parseInt(y, 10) - scrolly);
}
}
};
/**
* Store the initial position of the node, so it can be updated when the drawing canvas is scrolled
* @public
* @method store_position
* @param container
* @param x
* @param y
*/
this.store_position = function(container, x, y) {
var drawingregion, scrollx, scrolly;
drawingregion = Y.one(SELECTOR.DRAWINGREGION);
scrollx = parseInt(drawingregion.get('scrollLeft'), 10);
scrolly = parseInt(drawingregion.get('scrollTop'), 10);
container.setData('x', x + scrollx);
container.setData('y', y + scrolly);
};
};
M.assignfeedback_editpdf = M.assignfeedback_editpdf || {};
+50 -5
View File
@@ -291,7 +291,7 @@ EDITOR.prototype = {
* @method link_handler
*/
link_handler : function(e) {
var drawingcanvas;
var drawingcanvas, drawingregion, resize = true;
e.preventDefault();
if (!this.dialogue) {
@@ -313,6 +313,9 @@ EDITOR.prototype = {
drawingcanvas = Y.one(SELECTOR.DRAWINGCANVAS);
this.graphic = new Y.Graphic({render : SELECTOR.DRAWINGCANVAS});
drawingregion = Y.one(SELECTOR.DRAWINGREGION);
drawingregion.on('scroll', this.move_canvas, this);
if (!this.get('readonly')) {
drawingcanvas.on('gesturemovestart', this.edit_start, null, this);
drawingcanvas.on('gesturemove', this.edit_move, null, this);
@@ -322,10 +325,18 @@ EDITOR.prototype = {
}
this.load_all_pages();
drawingcanvas.on('windowresize', this.resize, this);
resize = false;
}
this.dialogue.centerDialogue();
this.dialogue.show();
drawingcanvas.on('windowresize', this.resize, this);
// Redraw when the dialogue is moved, to ensure the absolute elements are all positioned correctly.
this.dialogue.dd.on('drag:end', this.redraw, this);
if (resize) {
this.resize(); // When re-opening the dialog call redraw, to make sure the size + layout is correct.
}
},
/**
@@ -838,7 +849,21 @@ EDITOR.prototype = {
* @method resize
*/
resize : function() {
var drawingregion, drawregionheight;
if (!this.dialogue.get('visible')) {
return;
}
this.dialogue.centerDialogue();
// Make sure the dialogue box is not bigger than the max height of the viewport.
drawregionheight = Y.one('body').get('winHeight') - 120; // Space for toolbar + titlebar.
if (drawregionheight < 100) {
drawregionheight = 100;
}
drawingregion = Y.one(SELECTOR.DRAWINGREGION);
drawingregion.setStyle('maxHeight', drawregionheight +'px');
this.redraw();
return true;
},
@@ -939,6 +964,9 @@ EDITOR.prototype = {
page;
page = this.pages[this.currentpage];
if (page === undefined) {
return; // Can happen if a redraw is triggered by an event, before the page has been selected.
}
while (this.drawables.length > 0) {
this.drawables.pop().erase();
}
@@ -979,11 +1007,13 @@ EDITOR.prototype = {
page = this.pages[this.currentpage];
this.loadingicon.hide();
drawingcanvas.setStyle('backgroundImage', 'url("' + page.url + '")');
drawingcanvas.setStyle('width', page.width + 'px');
drawingcanvas.setStyle('height', page.height + 'px');
// Update page select.
Y.one(SELECTOR.PAGESELECT).set('value', this.currentpage);
this.redraw();
this.resize(); // Internally will call 'redraw', after checking the dialogue size.
},
/**
@@ -1051,10 +1081,25 @@ EDITOR.prototype = {
this.currentpage = this.pages.length - 1;
}
this.change_page();
},
/**
* Update any absolutely positioned nodes, within each drawable, when the drawing canvas is scrolled
* @protected
* @method move_canvas
*/
move_canvas: function() {
var drawingregion, x, y, i;
drawingregion = Y.one(SELECTOR.DRAWINGREGION);
x = parseInt(drawingregion.get('scrollLeft'), 10);
y = parseInt(drawingregion.get('scrollTop'), 10);
for (i = 0; i < this.drawables.length; i++) {
this.drawables[i].scroll_update(x, y);
}
}
};
Y.extend(EDITOR, Y.Base, EDITOR.prototype, {