diff --git a/js/drawingtools/selectiontools/BaseSelect.js b/js/drawingtools/selectiontools/BaseSelect.js index e52ff0ee..ae454c2b 100644 --- a/js/drawingtools/selectiontools/BaseSelect.js +++ b/js/drawingtools/selectiontools/BaseSelect.js @@ -20,21 +20,78 @@ /** * @override */ + ns.BaseSelect.prototype.applyToolAt = function(col, row, color, frame, overlay) { + this.startCol = col; + this.startRow = row; + + this.lastCol = col; + this.lastRow = row; + + // The select tool can be in two different state. + // If the inital click of the tool is not on a selection, we go in "select" + // mode to create a selection. + // If the initial click is on a previous selection, we go in "moveSelection" + // mode to allow to move the selection by drag'n dropping it. + if(overlay.getPixel(col, row) != Constants.SELECTION_TRANSPARENT_COLOR) { + + this.mode = "select"; + this.onSelectStart_(col, row, color, frame, overlay); + } + else { + + this.mode = "moveSelection"; + this.onSelectionDragStart_(col, row, color, frame, overlay); + } + }; + + /** + * @override + */ + ns.BaseSelect.prototype.moveToolAt = function(col, row, color, frame, overlay) { + if(this.mode == "select") { + + this.onSelect_(col, row, color, frame, overlay); + } + else if(this.mode == "moveSelection") { + + this.onSelectionDrag_(col, row, color, frame, overlay); + } + }; + + /** + * @override + */ + ns.BaseSelect.prototype.releaseToolAt = function(col, row, color, frame, overlay) { + if(this.mode == "select") { + + this.onSelectEnd_(col, row, color, frame, overlay); + } else if(this.mode == "moveSelection") { + + this.onSelectionDragEnd_(col, row, color, frame, overlay); + } + }; + + + /** + * If we mouseover the selection draw inside the overlay frame, show the 'move' cursor + * instead of the 'select' one. It indicates that we can move the selection by dragndroping it. + * @override + */ ns.BaseSelect.prototype.moveUnactiveToolAt = function(col, row, color, frame, overlay) { - // If we mouseover the selection draw inside the overlay frame, show the 'move' cursor - // instead of the 'select' one. It indicates that we can move the selection by dragndroping it. if(overlay.getPixel(col, row) != Constants.SELECTION_TRANSPARENT_COLOR) { + // We're hovering the selection, show the move tool: this.BodyRoot.addClass(this.toolId); this.BodyRoot.removeClass(this.secondaryToolId); } else { + // We're not hovering the selection, show create selection tool: this.BodyRoot.addClass(this.secondaryToolId); this.BodyRoot.removeClass(this.toolId); } }; /** - * Move the overlay frame filled with semi-transparent pixels that represent the selection + * Move the overlay frame filled with semi-transparent pixels that represent the selection. * @private */ ns.BaseSelect.prototype.shiftOverlayFrame_ = function (colDiff, rowDiff, overlayFrame, reference) { @@ -50,4 +107,44 @@ } } }; + + + // The list of callbacks to implement by specialized tools to implement the selection creation behavior. + /** @protected */ + ns.BaseSelect.prototype.onSelectStart_ = function (col, row, color, frame, overlay) {}; + /** @protected */ + ns.BaseSelect.prototype.onSelect_ = function (col, row, color, frame, overlay) {}; + /** @protected */ + ns.BaseSelect.prototype.onSelectEnd_ = function (col, row, color, frame, overlay) {}; + + + // The list of callbacks that define the drag'n drop behavior of the selection. + /** @private */ + ns.BaseSelect.prototype.onSelectionDragStart_ = function (col, row, color, frame, overlay) { + // Since we will move the overlayFrame in which the current selection is rendered, + // we clone it to have a reference for the later shifting process. + this.overlayFrameReference = overlay.clone(); + }; + /** @private */ + ns.BaseSelect.prototype.onSelectionDrag_ = function (col, row, color, frame, overlay) { + var deltaCol = col - this.lastCol; + var deltaRow = row - this.lastRow; + + var colDiff = col - this.startCol, rowDiff = row - this.startRow; + if (colDiff != 0 || rowDiff != 0) { + // Shifting selection on overlay frame: + this.shiftOverlayFrame_(colDiff, rowDiff, overlay, this.overlayFrameReference); + + // Update selection model: + $.publish(Events.SELECTION_MOVE_REQUEST, [deltaCol, deltaRow]); + } + this.lastCol = col; + this.lastRow = row; + }; + /** @private */ + ns.BaseSelect.prototype.onSelectionDragEnd_ = function (col, row, color, frame, overlay) { + this.onSelectionDrag_(col, row, color, frame, overlay); + }; + + })(); diff --git a/js/drawingtools/selectiontools/RectangleSelect.js b/js/drawingtools/selectiontools/RectangleSelect.js index 29139077..c6d5ee00 100644 --- a/js/drawingtools/selectiontools/RectangleSelect.js +++ b/js/drawingtools/selectiontools/RectangleSelect.js @@ -14,81 +14,37 @@ pskl.utils.inherit(ns.RectangleSelect, ns.BaseSelect); + /** * @override */ - ns.RectangleSelect.prototype.applyToolAt = function(col, row, color, frame, overlay) { - this.startCol = col; - this.startRow = row; - - this.lastCol = col; - this.lastRow = row; - - // TODO(vincz): Comment here nasty vince - if(overlay.getPixel(col, row) != Constants.SELECTION_TRANSPARENT_COLOR) { - this.mode = "select"; - - // Drawing the first point of the rectangle in the fake overlay canvas: - overlay.setPixel(col, row, color); - } - else { - this.mode = "moveSelection"; - - this.overlayFrameReference = overlay.clone(); - } + ns.RectangleSelect.prototype.onSelectStart_ = function (col, row, color, frame, overlay) { + // Drawing the first point of the rectangle in the fake overlay canvas: + overlay.setPixel(col, row, color); }; - ns.RectangleSelect.prototype.moveToolAt = function(col, row, color, frame, overlay) { - if(this.mode == "select") { - // Clean overlay canvas: - overlay.clear(); - - // When the user moussemove (before releasing), we dynamically compute the - // pixel to draw the line and draw this line in the overlay : - var strokePoints = pskl.PixelUtils.getBoundRectanglePixels(this.startCol, this.startRow, col, row); - - color = Constants.SELECTION_TRANSPARENT_COLOR; - // Drawing current stroke: - for(var i = 0; i< strokePoints.length; i++) { - overlay.setPixel(strokePoints[i].col, strokePoints[i].row, color); - } - } - else if(this.mode == "moveSelection") { - - // TODO(vincz): Comment here nasty vince - var deltaCol = col - this.lastCol; - var deltaRow = row - this.lastRow; - - console.log(deltaCol) - console.log(deltaRow) - var colDiff = col - this.startCol, rowDiff = row - this.startRow; - if (colDiff != 0 || rowDiff != 0) { - // Update selection on overlay frame: - this.shiftOverlayFrame_(colDiff, rowDiff, overlay, this.overlayFrameReference); - - // Update selection model: - $.publish(Events.SELECTION_MOVE_REQUEST, [deltaCol, deltaRow]); - } - this.lastCol = col; - this.lastRow = row; + /** + * When creating the rectangle selection, we clear the current overlayFrame and + * redraw the current rectangle based on the orgin coordinate and + * the current mouse coordiinate in sprite. + * @override + */ + ns.RectangleSelect.prototype.onSelect_ = function (col, row, color, frame, overlay) { + overlay.clear(); + if(this.startCol == col &&this.startRow == row) { + $.publish(Events.SELECTION_DISMISSED); + } else { + var selection = new pskl.selection.RectangularSelection( + this.startCol, this.startRow, col, row); + $.publish(Events.SELECTION_CREATED, [selection]); } }; /** * @override */ - ns.RectangleSelect.prototype.releaseToolAt = function(col, row, color, frame, overlay) { - if(this.mode == "select") { - overlay.clear(); - if(this.startCol == col &&this.startRow == row) { - $.publish(Events.SELECTION_DISMISSED); - } else { - var selection = new pskl.selection.RectangularSelection( - this.startCol, this.startRow, col, row); - $.publish(Events.SELECTION_CREATED, [selection]); - } - } else if(this.mode == "moveSelection") { - this.moveToolAt(col, row, color, frame, overlay); - } + ns.RectangleSelect.prototype.onSelectEnd_ = function (col, row, color, frame, overlay) { + this.onSelect_(col, row, color, frame, overlay) }; + })(); diff --git a/js/drawingtools/selectiontools/ShapeSelect.js b/js/drawingtools/selectiontools/ShapeSelect.js index df655773..237dcf94 100644 --- a/js/drawingtools/selectiontools/ShapeSelect.js +++ b/js/drawingtools/selectiontools/ShapeSelect.js @@ -14,62 +14,20 @@ pskl.utils.inherit(ns.ShapeSelect, ns.BaseSelect); - /** - * @override - */ - ns.ShapeSelect.prototype.applyToolAt = function(col, row, color, frame, overlay) { - this.startCol = col; - this.startRow = row; - - this.lastCol = col; - this.lastRow = row; - - // TODO(vincz): Comment here nasty vince - if(overlay.getPixel(col, row) != Constants.SELECTION_TRANSPARENT_COLOR) { - this.mode = "select"; - - $.publish(Events.SELECTION_DISMISSED); - var pixels = pskl.PixelUtils.getSimilarConnectedPixelsFromFrame(frame, col, row); - var selection = new pskl.selection.ShapeSelection(pixels); - $.publish(Events.SELECTION_CREATED, [selection]); - } - else { - this.mode = "moveSelection"; - - this.overlayFrameReference = overlay.clone(); - } - }; - - ns.ShapeSelect.prototype.moveToolAt = function(col, row, color, frame, overlay) { - if(this.mode == "moveSelection") { - - // TODO(vincz): Comment here nasty vince - var deltaCol = col - this.lastCol; - var deltaRow = row - this.lastRow; - - console.log(deltaCol) - console.log(deltaRow) - var colDiff = col - this.startCol, rowDiff = row - this.startRow; - if (colDiff != 0 || rowDiff != 0) { - // Update selection on overlay frame: - this.shiftOverlayFrame_(colDiff, rowDiff, overlay, this.overlayFrameReference); - - // Update selection model: - $.publish(Events.SELECTION_MOVE_REQUEST, [deltaCol, deltaRow]); - } - this.lastCol = col; - this.lastRow = row; - } - }; /** + * For the shape select tool, you just need to click one time to create a selection. + * So we jsut need to implement onSelectStart_ (no need for onSelect_ & onSelectEnd_) * @override */ - ns.ShapeSelect.prototype.releaseToolAt = function(col, row, color, frame, overlay) { - if(this.mode == "select") { - // TODO(vincz): define a way to dismiss the shape select - } else if(this.mode == "moveSelection") { - this.moveToolAt(col, row, color, frame, overlay); - } + ns.ShapeSelect.prototype.onSelectStart_ = function (col, row, color, frame, overlay) { + // Clean previous selection: + $.publish(Events.SELECTION_DISMISSED); + + // From the pixel cliked, get shape using an algorithm similar to the paintbucket one: + var pixels = pskl.PixelUtils.getSimilarConnectedPixelsFromFrame(frame, col, row); + var selection = new pskl.selection.ShapeSelection(pixels); + $.publish(Events.SELECTION_CREATED, [selection]); }; + })();