diff --git a/css/mirador.css b/css/mirador.css index 1c1ba522d1..0eb88d7519 100644 --- a/css/mirador.css +++ b/css/mirador.css @@ -1175,6 +1175,68 @@ li.highlight { /* color picker custom style ---------------------------------------------------------------------------- */ +.draw-tool * { + text-shadow: none !important; +} + +.draw-tool>i { + text-shadow: 0 0 5px black !important; +} + +.draw-tool .sp-replacer { + vertical-align: top; + margin-top: 2px; + height: 14px !important; +} + +.mirador-line-type:hover { + border-color: #F0C49B; + color: #111; + transition: all 0.3s ease; + opacity: 1; +} + +.mirador-line-type { + border-radius: 5px !important; + padding: 0px !important; + height: 22px !important; + width: 67px !important; + opacity: 0.6; + border: 1px solid #91765d; + background: white none repeat scroll 0 0; + margin: 2px 10px 0px 0px !important; +} + +.mirador-line-type ul { + color: #333333; + margin-top: 0px !important; +} + +.mirador-line-type li { + text-shadow: none !important; + font-size: 10px !important; +} + +.mirador-line-type>span { + color: black; + float: right; + margin-right: 5px; +} + +.mirador-line-type>i { + vertical-align: top; + width: 30px !important; + margin: 4px 0px 0px 4px !important; +} + +.mirador-line-type i { + color: #333333; + width: 45px; + height: 10px; + font-size: 15px !important; + background-repeat: no-repeat; +} + .sp-button-container a { color: #555555 !important; text-shadow: none !important; @@ -1185,6 +1247,8 @@ li.highlight { .borderColorPicker + div + .sp-container, .fillColorPicker + div + .sp-container { width: 300px !important; + border-width: 0px !important; + opacity: 0.9; } .borderColorPicker + div .sp-preview, .fillColorPicker + div .sp-preview { diff --git a/js/src/annotations/osd-region-draw-tool.js b/js/src/annotations/osd-region-draw-tool.js index c9fd589a60..4954d04261 100644 --- a/js/src/annotations/osd-region-draw-tool.js +++ b/js/src/annotations/osd-region-draw-tool.js @@ -184,6 +184,10 @@ } } } + if (_this.svgOverlay.availableExternalCommentsPanel) { + _this.eventEmitter.publish('annotationMousePosition.' + _this.parent.windowId, [annotations]); + return; + } _this.annoTooltip.showViewer({ annotations: annotations, triggerEvent: event, diff --git a/js/src/annotations/osd-svg-ellipse.js b/js/src/annotations/osd-svg-ellipse.js index 26e369a21e..a49874c93c 100644 --- a/js/src/annotations/osd-svg-ellipse.js +++ b/js/src/annotations/osd-svg-ellipse.js @@ -38,6 +38,7 @@ segments: segments, name: overlay.getName(_this) }); + shape.dashArray = overlay.dashArray; shape.strokeWidth = 1 / overlay.paperScope.view.zoom; shape.strokeColor = overlay.strokeColor; shape.fillColor = overlay.fillColor; diff --git a/js/src/annotations/osd-svg-freehand.js b/js/src/annotations/osd-svg-freehand.js index 2a9017f6b1..aa4e81e006 100644 --- a/js/src/annotations/osd-svg-freehand.js +++ b/js/src/annotations/osd-svg-freehand.js @@ -18,6 +18,7 @@ var _this = this; var shape = new overlay.paperScope.Path({ segments: [initialPoint], + dashArray: overlay.dashArray, strokeWidth: 1 / overlay.paperScope.view.zoom, strokeColor: overlay.strokeColor, fullySelected: true, diff --git a/js/src/annotations/osd-svg-overlay.js b/js/src/annotations/osd-svg-overlay.js index 8afe11c8ee..766727ba42 100644 --- a/js/src/annotations/osd-svg-overlay.js +++ b/js/src/annotations/osd-svg-overlay.js @@ -1,9 +1,9 @@ (function($) { - $.getTools = function() { + $.getTools = function(options) { if (this.svgOverlayTools) { return this.svgOverlayTools; } - this.svgOverlayTools = [new $.Rectangle(), new $.Freehand(), new $.Polygon(), new $.Ellipse(), new $.Pin()]; + this.svgOverlayTools = [new $.Rectangle(options), new $.Freehand(options), new $.Polygon(options), new $.Ellipse(options), new $.Pin(options)]; return this.svgOverlayTools; }; @@ -12,8 +12,9 @@ }; $.Overlay = function(viewer, osdViewerId, windowId, state, eventEmitter) { - var drawingToolsSettings = state.getStateProperty('drawingToolsSettings'), - availableAnnotationDrawingTools = state.getStateProperty('availableAnnotationDrawingTools'); + var drawingToolsSettings = state.getStateProperty('drawingToolsSettings'); + var availableAnnotationDrawingTools = state.getStateProperty('availableAnnotationDrawingTools'); + var availableExternalCommentsPanel = state.getStateProperty('availableExternalCommentsPanel'); jQuery.extend(this, { disabled: true, osdViewerId: osdViewerId, @@ -28,9 +29,10 @@ latestMouseDownTime: -1, doubleClickReactionTime: drawingToolsSettings.doubleClickReactionTime, availableAnnotationDrawingTools: availableAnnotationDrawingTools, - pinSize: 10, + availableExternalCommentsPanel: availableExternalCommentsPanel, + dashArray: [], + fixedShapeSize: 10, hitOptions: { - fill: true, stroke: true, segments: true, tolerance: 5 @@ -38,7 +40,7 @@ }); // Initialization of overlay object. - this.tools = $.getTools(); + this.tools = $.getTools(drawingToolsSettings); this.currentTool = null; // Default colors. this.strokeColor = drawingToolsSettings.fillColor; @@ -77,7 +79,7 @@ for (var i = 0; i < _this.tools.length; i++) { if (_this.tools[i].logoClass == tool) { _this.currentTool = _this.tools[i]; - jQuery('#' + osdViewerId).parent().find('.hud-container').find('.material-icons:contains(\'' + tool + '\')').parent('.draw-tool').addClass('selected'); + jQuery('#' + osdViewerId).parent().find('.hud-container').find('.material-icons:contains(\'' + tool + '\')').parent('.draw-tool').addClass('selected').css('opacity', '1'); } } }); @@ -93,7 +95,7 @@ for (var j = 0; j < _this.tools.length; j++) { if (_this.availableAnnotationDrawingTools[i] == _this.tools[j].name) { _this.currentTool = _this.tools[j]; - jQuery('#' + osdViewerId).parent().find('.hud-container').find('.material-icons:contains(\'' + _this.tools[j].logoClass + '\')').parent('.draw-tool').addClass('selected'); + jQuery('#' + osdViewerId).parent().find('.hud-container').find('.material-icons:contains(\'' + _this.tools[j].logoClass + '\')').parent('.draw-tool').addClass('selected').css('opacity', '1'); break; } } @@ -133,6 +135,7 @@ this.paperScope = new paper.PaperScope(); this.paperScope.setup('draw_canvas_' + _this.windowId); this.paperScope.activate(); + this.paperScope.project.options.handleSize = 10; jQuery(_this.canvas).attr('keepalive', 'true'); this.paperScope.view.onFrame = function(event) { if (_this.paperScope.snapPoint) { @@ -200,6 +203,11 @@ var _this = this; this.overlay.cursorLocation = event.point; if (!this.overlay.disabled) { + if (this.overlay.paperScope.project.hitTest(event.point, this.overlay.hitOptions)) { + document.body.style.cursor = "pointer"; + } else { + document.body.style.cursor = "default"; + } event.stopPropagation(); this.overlay.currentTool.onMouseMove(event, this.overlay); } else { @@ -270,71 +278,44 @@ } }, - fitPinSize: function(shape) { - var scale = 1 / shape.bounds.width; - scale *= this.pinSize / this.paperScope.view.zoom; - shape.scale(scale, shape.segments[0].point); + fitFixedSizeShapes: function(shape) { + shape.data.fixedSize = true; + if (shape.name.toString().indexOf('pin_') != -1) { + var scale = 1 / shape.bounds.width; + scale *= this.fixedShapeSize / this.paperScope.view.zoom; + shape.scale(scale, shape.segments[0].point); + } }, resize: function() { - var viewportBounds = this.viewer.viewport.getBounds(true); /* in viewport coordinates */ - var pointZero = this.viewer.viewport.pixelFromPoint(new OpenSeadragon.Point(0, 0), true); - - // maximum canvas size which should be less that limitations from each browser. - // http://stackoverflow.com/questions/6081483/maximum-size-of-a-canvas-element - var maxSize = 2048; - var realSize = { - width: this.viewer.viewport.containerSize.x / viewportBounds.width, - height: this.viewer.viewport.containerSize.x / viewportBounds.width / this.viewer.viewport.contentAspectX, - offsetX: 0, - offsetY: 0, - scale: 1 - }; - if (realSize.width > maxSize) { - realSize.scale = realSize.width / maxSize; - realSize.width /= realSize.scale; - realSize.height /= realSize.scale; - realSize.offsetX -= pointZero.x; - realSize.offsetY -= pointZero.y; - pointZero.x = 0; - pointZero.y = 0; - } else if (realSize.height > maxSize) { - realSize.scale = realSize.height / maxSize; - realSize.width /= realSize.scale; - realSize.height /= realSize.scale; - realSize.offsetX -= pointZero.x; - realSize.offsetY -= pointZero.y; - pointZero.x = 0; - pointZero.y = 0; - } - - this.canvas.width = realSize.width; - this.canvas.height = realSize.height; + var viewportBounds = this.viewer.viewport.getBounds(true); + /* in viewport coordinates */ + this.canvas.width = this.viewer.viewport.containerSize.x; + this.canvas.height = this.viewer.viewport.containerSize.y; var transform = 'translate(0px,0px)'; this.canvas.style.WebkitTransform = transform; this.canvas.style.msTransform = transform; this.canvas.style.transform = transform; - this.canvas.style.marginLeft = pointZero.x + "px"; - this.canvas.style.marginTop = pointZero.y + "px"; + this.canvas.style.marginLeft = "0px"; + this.canvas.style.marginTop = "0px"; if (this.paperScope && this.paperScope.view) { this.paperScope.view.viewSize = new this.paperScope.Size(this.canvas.width, this.canvas.height); this.paperScope.view.zoom = this.viewer.viewport.viewportToImageZoom(this.viewer.viewport.getZoom(true)); this.paperScope.view.center = new this.paperScope.Size( - realSize.offsetX / this.paperScope.view.zoom + this.paperScope.view.bounds.width / 2, - realSize.offsetY / this.paperScope.view.zoom + this.paperScope.view.bounds.height / 2); + this.viewer.viewport.contentSize.x * viewportBounds.x + this.paperScope.view.bounds.width / 2, + this.viewer.viewport.contentSize.x * viewportBounds.y + this.paperScope.view.bounds.height / 2); this.paperScope.view.update(true); - // Fit pins to the current zoom level. - var items = this.paperScope.project.getItems({ - name: /^pin_/ - }); - for (var i = 0; i < items.length; i++) { - this.fitPinSize(items[i]); - } var allItems = this.paperScope.project.getItems({ name: /_/ }); for (var j = 0; j < allItems.length; j++) { + if (allItems[j].data.fixedSize) { + this.fitFixedSizeShapes(allItems[j]); + } allItems[j].strokeWidth = 1 / this.paperScope.view.zoom; + if (allItems[j].style) { + allItems[j].style.strokeWidth = 1 / this.paperScope.view.zoom; + } } } }, @@ -393,6 +374,7 @@ }); cloned.strokeWidth = 1 / this.paperScope.view.zoom; cloned.strokeColor = shape.strokeColor; + cloned.dashArray = shape.dashArray; if (shape.fillColor) { cloned.fillColor = shape.fillColor; if (shape.fillColor.alpha) { @@ -401,9 +383,10 @@ } cloned.closed = shape.closed; cloned.data.rotation = shape.data.rotation; + cloned.data.fixedSize = shape.data.fixedSize; cloned.data.annotation = annotation; - if (cloned.name.toString().indexOf('pin_') != -1) { // pin shapes with fixed size. - this.fitPinSize(cloned); + if (cloned.data.fixedSize) { + this.fitFixedSizeShapes(cloned); } shape.remove(); return cloned; @@ -412,6 +395,7 @@ // creating shapes used for backward compatibility. // shape coordinates are viewport coordinates. createRectangle: function(shape, annotation) { + var scale = this.viewer.viewport.contentSize.x; var paperItems = []; var rect = new $.Rectangle(); var newShape = this.viewer.viewport.viewportToImageRectangle(shape); @@ -481,17 +465,23 @@ shapeArray[idx].name = this.editedPaths[i].name; shapeArray[idx].strokeWidth = 1 / this.paperScope.view.zoom; shapeArray[idx].strokeColor = this.editedPaths[i].strokeColor; + shapeArray[idx].dashArray = this.editedPaths[i].dashArray; if (this.editedPaths[i].fillColor) { shapeArray[idx].fillColor = this.editedPaths[i].fillColor; if (this.editedPaths[i].fillColor.alpha) { shapeArray[idx].fillColor.alpha = this.editedPaths[i].fillColor.alpha; } } + if (this.editedPaths[i].style) { + shapeArray[idx].style = this.editedPaths[i].style; + shapeArray[idx].style.strokeWidth = 1 / this.paperScope.view.zoom; + } shapeArray[idx].closed = this.editedPaths[i].closed; shapeArray[idx].data.rotation = this.editedPaths[i].data.rotation; + shapeArray[idx].data.fixedSize = this.editedPaths[i].data.fixedSize; shapeArray[idx].data.annotation = this.editedPaths[i].data.annotation; - if (shapeArray[idx].name.toString().indexOf('pin_') != -1) { // pin shapes with fixed size. - this.fitPinSize(shapeArray[idx]); + if (shapeArray[idx].data.fixedSize) { + this.fitFixedSizeShapes(shapeArray[idx]); } } } @@ -558,8 +548,8 @@ if (shapes.length > 1) { svg += ""; for (var i = 0; i < shapes.length; i++) { - if (shapes[i].name.toString().indexOf('pin_') != -1) { - this.fitPinSize(shapes[i]); + if (shapes[i].data.fixedSize) { + this.fitFixedSizeShapes(shapes[i]); } var anno = shapes[i].data.annotation; shapes[i].data.annotation = null; @@ -570,8 +560,8 @@ } svg += ""; } else { - if (shapes[0].name.toString().indexOf('pin_') != -1) { - this.fitPinSize(shapes[0]); + if (shapes[0].data.fixedSize) { + this.fitFixedSizeShapes(shapes[0]); } var annoSingle = shapes[0].data.annotation; shapes[0].data.annotation = null; @@ -605,9 +595,13 @@ windowId: this.windowId }); var _this = this; + if (_this.availableExternalCommentsPanel) { + _this.eventEmitter.publish('annotationShapeCreated.' + _this.windowId, [_this, shape]); + return; + } annoTooltip.showEditor({ annotation: {}, - onAnnotationCreated: function (oaAnno) { + onAnnotationCreated: function(oaAnno) { var svg = _this.getSVGString(_this.draftPaths); oaAnno.on = { "@type": "oa:SpecificResource", diff --git a/js/src/annotations/osd-svg-pin.js b/js/src/annotations/osd-svg-pin.js index 63530b41a0..c8e7e2be99 100644 --- a/js/src/annotations/osd-svg-pin.js +++ b/js/src/annotations/osd-svg-pin.js @@ -17,7 +17,7 @@ overlay.mode = 'create'; var _this = this; var pathData = ''; - var size = overlay.pinSize; + var size = overlay.fixedShapeSize; pathData += 'M' + initialPoint.x + ',' + initialPoint.y; pathData += ' Q' + initialPoint.x + ',' + (initialPoint.y - size); pathData += ' ' + (initialPoint.x + size) + ',' + (initialPoint.y - 2 * size); @@ -27,13 +27,14 @@ pathData += ' ' + initialPoint.x + ',' + initialPoint.y; var shape = new overlay.paperScope.Path(pathData); shape.name = overlay.getName(_this); + shape.dashArray = overlay.dashArray; shape.strokeWidth = 1 / overlay.paperScope.view.zoom; shape.strokeColor = overlay.strokeColor; shape.fillColor = overlay.fillColor; shape.fillColor.alpha = overlay.fillColorAlpha; shape.fullySelected = true; shape.closed = true; - overlay.fitPinSize(shape); + overlay.fitFixedSizeShapes(shape); return shape; }, diff --git a/js/src/annotations/osd-svg-polygon.js b/js/src/annotations/osd-svg-polygon.js index 6466f3de66..62b5572e8c 100644 --- a/js/src/annotations/osd-svg-polygon.js +++ b/js/src/annotations/osd-svg-polygon.js @@ -18,6 +18,7 @@ var _this = this; var shape = new overlay.paperScope.Path({ segments: [initialPoint], + dashArray: overlay.dashArray, strokeWidth: 1 / overlay.paperScope.view.zoom, strokeColor: overlay.strokeColor, fullySelected: true, diff --git a/js/src/annotations/osd-svg-rectangle.js b/js/src/annotations/osd-svg-rectangle.js index 7cd1910048..a9d583e5aa 100644 --- a/js/src/annotations/osd-svg-rectangle.js +++ b/js/src/annotations/osd-svg-rectangle.js @@ -37,6 +37,7 @@ fullySelected: true, name: overlay.getName(_this) }); + shape.dashArray = overlay.dashArray; shape.strokeWidth = 1 / overlay.paperScope.view.zoom; shape.strokeColor = overlay.strokeColor; shape.fillColor = overlay.fillColor; diff --git a/js/src/settings.js b/js/src/settings.js index ea5eceb884..4d609ced0f 100644 --- a/js/src/settings.js +++ b/js/src/settings.js @@ -101,12 +101,19 @@ ], 'drawingToolsSettings': { + // Additional tool settings. + /** + *'Pin': { + *}, + **/ 'doubleClickReactionTime': 300, 'strokeColor': 'deepSkyBlue', 'fillColor': 'deepSkyBlue', 'fillColorAlpha': 0.0 }, + 'availableExternalCommentsPanel': false, + 'availableCanvasTools': [ ], diff --git a/js/src/widgets/imageView.js b/js/src/widgets/imageView.js index d478b0b7c4..6828651a28 100755 --- a/js/src/widgets/imageView.js +++ b/js/src/widgets/imageView.js @@ -53,7 +53,7 @@ this.createOpenSeadragonInstance($.Iiif.getImageUrl(this.currentImg)); _this.eventEmitter.publish('UPDATE_FOCUS_IMAGES.' + this.windowId, {array: [this.canvasID]}); - var allTools = $.getTools(); + var allTools = $.getTools(this.state.getStateProperty('drawingToolsSettings')); this.availableTools = []; for ( var i = 0; i < this.state.getStateProperty('availableAnnotationDrawingTools').length; i++) { for ( var j = 0; j < allTools.length; j++) { diff --git a/spec/annotations/osd-svg-overlay.test.js b/spec/annotations/osd-svg-overlay.test.js index 0acf91b31b..336e8ca19e 100644 --- a/spec/annotations/osd-svg-overlay.test.js +++ b/spec/annotations/osd-svg-overlay.test.js @@ -66,8 +66,11 @@ describe('Overlay', function() { 'pixelFromPoint': function(point, current) { return point; }, - getBounds: function() { - return {x:0, y:0, width:10, height: 10}; + 'getBounds': function(current) { + return { + 'x': 800, + 'y': 600 + }; }, 'containerSize': { 'x': 800, @@ -88,6 +91,27 @@ describe('Overlay', function() { 'fillColorAlpha': 0.0 }; var state = new Mirador.SaveController({eventEmitter: this.eventEmitter}); + /* + + TODO RADOSLAV + getStateProperty: function(key) { + if (key === 'drawingToolsSettings') { + return { + 'doubleClickReactionTime': 300, + 'strokeColor': 'deepSkyBlue', + 'fillColor': 'deepSkyBlue', + 'fillColorAlpha': 0.0 + }; + } + if (key === 'availableAnnotationDrawingTools') { + return []; + } + if (key === 'availableExternalCommentsPanel') { + return false; + } + return null; + } + */ this.overlay = new Mirador.Overlay(this.viewerMock, this.windowObjMock.viewer.id, this.windowObjMock.windowId, state, this.eventEmitter); }); diff --git a/spec/annotations/osd-svg-pin.test.js b/spec/annotations/osd-svg-pin.test.js index 64589405e1..083c49e850 100644 --- a/spec/annotations/osd-svg-pin.test.js +++ b/spec/annotations/osd-svg-pin.test.js @@ -20,14 +20,14 @@ describe('Pin', function() { 'mode': mode, 'path': path, 'segment': segment, - 'pinSize': 5, + 'fixedShapeSize': 5, 'hitOptions': { 'fill': true, 'stroke': true, 'segments': true, 'tolerance': 0 }, - 'fitPinSize': function() { + 'fitFixedSizeShapes': function() { }, onDrawFinish: function() { },