diff --git a/labs/meteor-client/client/globals.coffee b/labs/meteor-client/client/globals.coffee index da7a44bfdc..48b6401dd6 100755 --- a/labs/meteor-client/client/globals.coffee +++ b/labs/meteor-client/client/globals.coffee @@ -188,7 +188,7 @@ Handlebars.registerHelper "getShapesForSlide", -> presentationId = currentPresentation?.presentation?.id currentSlide = Meteor.Slides.findOne({"presentationId": presentationId, "slide.current": true}) # try to reuse the lines above - Meteor.Shapes.find({whiteboardId: currentSlide?.slide?.id}).fetch() + Meteor.Shapes.find({whiteboardId: currentSlide?.slide?.id}) Handlebars.registerHelper "pointerLocation", -> currentPresentation = Meteor.Presentations.findOne({"presentation.current": true}) diff --git a/labs/meteor-client/client/main.coffee b/labs/meteor-client/client/main.coffee index d02498ec1c..a5f0170493 100755 --- a/labs/meteor-client/client/main.coffee +++ b/labs/meteor-client/client/main.coffee @@ -75,4 +75,3 @@ Meteor.startup -> {isActive:false, name:"Options", class: "optionsChatTab"} ] - @whiteboardPaperModel = new WhiteboardPaperModel('whiteboard-paper') diff --git a/labs/meteor-client/client/views/whiteboard/slide.coffee b/labs/meteor-client/client/views/whiteboard/slide.coffee index 21c55214ac..a4501ac73c 100755 --- a/labs/meteor-client/client/views/whiteboard/slide.coffee +++ b/labs/meteor-client/client/views/whiteboard/slide.coffee @@ -23,6 +23,23 @@ Template.slide.helpers wpm = Template.slide.whiteboardPaperModel wpm?.moveCursor(pointer.x, pointer.y) + manuallyDisplayShapes: -> + currentPresentation = Meteor.Presentations.findOne({"presentation.current": true}) + presentationId = currentPresentation?.presentation?.id + currentSlide = Meteor.Slides.findOne({"presentationId": presentationId, "slide.current": true}) + wpm = Template.slide.whiteboardPaperModel + + shapes = Meteor.Shapes.find({whiteboardId: currentSlide?.slide?.id}).fetch() + for s in shapes + shapeInfo = s.shape?.shape + shapeType = shapeInfo?.type + + for num in [0..3] # the coordinates must be in the range 0 to 1 + shapeInfo.points[num] = shapeInfo.points[num] / 100 + wpm.makeShape(shapeType, shapeInfo) + wpm.updateShape(shapeType, shapeInfo) + + #### SHAPE #### Template.shape.rendered = -> # @data is the shape object coming from the {{#each}} in the html file @@ -36,3 +53,9 @@ Template.shape.rendered = -> wpm.makeShape(shapeType, shapeInfo) wpm.updateShape(shapeType, shapeInfo) +Template.shape.destroyed = -> + wpm = Template.slide.whiteboardPaperModel + wpm.clearShapes() + Template.slide.displaySlide(wpm) + Template.slide.manuallyDisplayShapes() + diff --git a/labs/meteor-client/client/views/whiteboard/whiteboard.html b/labs/meteor-client/client/views/whiteboard/whiteboard.html index 23646e52f5..428f085904 100755 --- a/labs/meteor-client/client/views/whiteboard/whiteboard.html +++ b/labs/meteor-client/client/views/whiteboard/whiteboard.html @@ -2,12 +2,13 @@

{{title}}

+ {{#if getInSession "display_whiteboard"}} + {{#each getCurrentSlide}} + {{> slide}} + {{/each}}
- - {{#each getCurrentSlide}} - {{> slide}} - {{/each}}
+ {{/if}}
diff --git a/labs/meteor-client/client/whiteboard_models/whiteboard_ellipse.coffee b/labs/meteor-client/client/whiteboard_models/whiteboard_ellipse.coffee index 7844f625da..bacf2f6a9e 100755 --- a/labs/meteor-client/client/whiteboard_models/whiteboard_ellipse.coffee +++ b/labs/meteor-client/client/whiteboard_models/whiteboard_ellipse.coffee @@ -2,14 +2,11 @@ class @WhiteboardEllipseModel extends WhiteboardToolModel constructor: (@paper) -> - super @paper + super @paper - # the defintion of this shape, kept so we can redraw the shape whenever needed - # format: top left x, top left y, bottom right x, bottom right y, stroke color, thickness - @definition = [0, 0, 0, 0, "#000", "0px"] - - # @ellipseX = null - # @ellipseY = null + # the defintion of this shape, kept so we can redraw the shape whenever needed + # format: top left x, top left y, bottom right x, bottom right y, stroke color, thickness + @definition = [0, 0, 0, 0, "#000", "0px"] # Make an ellipse on the whiteboard # @param {[type]} x the x value of the top left corner @@ -17,18 +14,19 @@ class @WhiteboardEllipseModel extends WhiteboardToolModel # @param {string} colour the colour of the object # @param {number} thickness the thickness of the object's line(s) make: (info) -> - if info?.payload?.data?.coordinate? - x = info.payload.data.coordinate.first_x - y = info.payload.data.coordinate.first_y - color = info.payload.data.line.color - thickness = info.payload.data.line.weight + console.log "Whiteboard - Making ellipse: " + console.log info + if info?.points? + x = info.points[0] + y = info.points[1] + color = info.color + thickness = info.thickness - @obj = @paper.ellipse(x * @gw + @xOffset, y * @gh + @yOffset, 0, 0) - @obj.attr Utils.strokeAndThickness(color, thickness) - @definition = - shape: "ellipse" - data: [x, y, y, x, @obj.attrs["stroke"], @obj.attrs["stroke-width"]] - @obj + @obj = @paper.ellipse(x * @gw + @xOffset, y * @gh + @yOffset, 0, 0) + @obj.attr Meteor.call("strokeAndThickness", color, thickness) + @definition = [x, y, y, x, @obj.attrs["stroke"], @obj.attrs["stroke-width"]] + + @obj # Update ellipse drawn # @param {number} x1 the x value of the top left corner in percent of current slide size @@ -37,59 +35,55 @@ class @WhiteboardEllipseModel extends WhiteboardToolModel # @param {number} y2 the y value of the bottom right corner in percent of current slide size # @param {boolean} square (draw a circle or not update: (info) -> - x1 = info.payload.data.coordinate.first_x - y1 = info.payload.data.coordinate.first_y - x2 = info.payload.data.coordinate.last_x - y2 = info.payload.data.coordinate.last_y - circle = info.payload.data.square - + console.log info + if info?.points? + x1 = info.points[0] + y1 = info.points[1] + x2 = info.points[2] + y2 = info.points[3] + + circle = !info.square + if @obj? + [x1, x2] = [x2, x1] if x2 < x1 - [x1, x2] = [x2, x1] if x2 < x1 + if y2 < y1 + [y1, y2] = [y2, y1] + reversed = true - - - - if y2 < y1 - [y1, y2] = [y2, y1] - reversed = true - - if circle - if reversed #if reveresed, the y1 coordinate gets updated, not the y2 coordinate - y1 = y2 - (x2 - x1) * @gw / @gh - else - y2 = y1 + (x2 - x1) * @gw / @gh + if circle + if reversed # if reveresed, the y1 coordinate gets updated, not the y2 coordinate + y1 = y2 - (x2 - x1) * @gw / @gh + else + y2 = y1 + (x2 - x1) * @gw / @gh #if the control key is pressed then the width and height of the ellipse are equal (a circle) #we calculate this by making the y2 coord equal to the y1 coord plus the width of x2-x1 and corrected for the slide size - - - coords = - x1: x1 - x2: x2 - y1: y1 - y2: y2 + coords = + x1: x1 + x2: x2 + y1: y1 + y2: y2 console.log(coords) rx = (x2 - x1) / 2 ry = (y2 - y1) / 2 - - r= - rx: rx * @gw - ry: ry * @gh - cx: (rx + x1) * @gw + @xOffset - cy: (ry + y1) * @gh + @yOffset - console.log "------------>", r + r = + rx: rx * @gw + ry: ry * @gh + cx: (rx + x1) * @gw + @xOffset + cy: (ry + y1) * @gh + @yOffset + @obj.attr(r) - console.log( "@gw: " + @gw + "\n@gh: " + @gh + "\n@xOffset: " + @xOffset + "\n@yOffset: " + @yOffset ); + console.log( "@gw: " + @gw + "\n@gh: " + @gh + "\n@xOffset: " + @xOffset + "\n@yOffset: " + @yOffset ); # we need to update all these values, specially for when shapes are drawn backwards - @definition.data[0] = x1 - @definition.data[1] = y1 - @definition.data[2] = x2 - @definition.data[3] = y2 + @definition[0] = x1 + @definition[1] = y1 + @definition[2] = x2 + @definition[3] = y2 # Draw an ellipse on the whiteboard # @param {number} x1 the x value of the top left corner diff --git a/labs/meteor-client/client/whiteboard_models/whiteboard_line.coffee b/labs/meteor-client/client/whiteboard_models/whiteboard_line.coffee index 4b4f1f30ed..6714f08479 100755 --- a/labs/meteor-client/client/whiteboard_models/whiteboard_line.coffee +++ b/labs/meteor-client/client/whiteboard_models/whiteboard_line.coffee @@ -23,24 +23,23 @@ class @WhiteboardLineModel extends WhiteboardToolModel # @param {string} colour the colour of the shape to be drawn # @param {number} thickness the thickness of the line to be drawn make: (info) -> - console.log "in line MAKE(info): " + info - if info?.payload?.data?.coordinate? - x = info.payload.data.coordinate.first_x - y = info.payload.data.coordinate.first_y - color = info.payload.data.line.color - thickness = info.payload.data.line.weight + console.log "in line MAKE(info): " + console.log info + if info?.points? + x = info.points[0] + y = info.points[1] + color = info.color + thickness = info.thickness x1 = x * @gw + @xOffset y1 = y * @gh + @yOffset path = "M" + x1 + " " + y1 + " L" + x1 + " " + y1 pathPercent = "M" + x + " " + y + " L" + x + " " + y @obj = @paper.path(path) - @obj.attr Utils.strokeAndThickness(color, thickness) + @obj.attr Meteor.call("strokeAndThickness", color, thickness) @obj.attr({"stroke-linejoin": "round"}) - @definition = - shape: "path" - data: [pathPercent, @obj.attrs["stroke"], @obj.attrs["stroke-width"]] + @definition = [pathPercent, @obj.attrs["stroke"], @obj.attrs["stroke-width"]] @obj @@ -55,12 +54,13 @@ class @WhiteboardLineModel extends WhiteboardToolModel # @param {number} y2 1) the y of the second point # 2) undefined update: (info) -> - console.log "in line-UPDATE(info): " + info - if info?.payload?.data?.coordinate? - x1 = info.payload.data.coordinate.first_x - y1 = info.payload.data.coordinate.first_y - x2 = info.payload.data.coordinate.last_x - y2 = info.payload.data.coordinate.last_y + console.log "in line-UPDATE(info): " + console.log info + if info?.points? + x1 = info.points[0] + y1 = info.points[1] + x2 = info.points[2] + y2 = info.points[3] if @obj? @@ -89,7 +89,7 @@ class @WhiteboardLineModel extends WhiteboardToolModel # adding lines from the line tool else path = @_buildPath(x1, y1, x2, y2) - @definition.data[0] = path + @definition[0] = path path = @_scaleLinePath(path, @gw, @gh, @xOffset, @yOffset) @obj.attr path: path diff --git a/labs/meteor-client/client/whiteboard_models/whiteboard_paper.coffee b/labs/meteor-client/client/whiteboard_models/whiteboard_paper.coffee index 936db37614..4ed01068e7 100755 --- a/labs/meteor-client/client/whiteboard_models/whiteboard_paper.coffee +++ b/labs/meteor-client/client/whiteboard_models/whiteboard_paper.coffee @@ -4,7 +4,6 @@ class @WhiteboardPaperModel # Container must be a DOM element constructor: (@container) -> - # console.log "paper in WhiteboardPaperModel =" + @container # a WhiteboardCursorModel @cursor = null @@ -56,8 +55,7 @@ class @WhiteboardPaperModel # are not yet created in the page. create: -> # paper is embedded within the div#slide of the page. - console.log ("@container=" + @container) - @raphaelObj ?= ScaleRaphael(@container, "500", "500") + @raphaelObj ?= ScaleRaphael(@container, "900", "500") @raphaelObj.canvas.setAttribute "preserveAspectRatio", "xMinYMin slice" @cursor = new WhiteboardCursorModel(@raphaelObj) @@ -318,12 +316,14 @@ class @WhiteboardPaperModel @currentShapesDefinitions = shapes @currentShapes = @raphaelObj.set() for shape in shapes - data = if _.isString(shape.data) then JSON.parse(shape.data) else shape.data - tool = @_createTool(shape.shape) + shapeType = shape?.shape?.shape_type + dataBlock = shape?.shape?.shape + data = if _.isString(dataBlock) then JSON.parse(dataBlock) else dataBlock + tool = @_createTool(shapeType) if tool? @currentShapes.push tool.draw.apply(tool, data) else - ;#console.log "shape not recognized at drawListOfShapes", shape + console.log "shape not recognized at drawListOfShapes", shape # make sure the cursor is still on top @cursor.toFront() @@ -345,7 +345,6 @@ class @WhiteboardPaperModel # Updated a shape `shape` with the data in `data`. # TODO: check if the objects exist before calling update, if they don't they should be created updateShape: (shape, data) -> - # alert "updating a " + shape switch shape when "line" @currentLine.update(data) @@ -358,11 +357,10 @@ class @WhiteboardPaperModel when "text" @currentText.update.apply(@currentText, data) else - ;#console.log "shape not recognized at updateShape", shape + console.log "shape not recognized at updateShape", shape # Make a shape `shape` with the data in `data`. makeShape: (shape, data) -> - # alert "making a " + shape tool = null switch shape when "path", "line" @@ -386,10 +384,9 @@ class @WhiteboardPaperModel toolModel = @currentText tool = @currentText.make.apply(@currentText, data) else - ;#console.log "shape not recognized at makeShape", shape + console.log "shape not recognized at makeShape", shape if tool? @currentShapes ?= @raphaelObj.set() - console.log "currentShapes:" + @currentShapes @currentShapes.push(tool) @currentShapesDefinitions.push(toolModel.getDefinition()) @@ -822,10 +819,6 @@ class @WhiteboardPaperModel _displayPage: (data) -> @removeAllImagesFromPaper() - #page = data?.payload?.currentPage - #pngSlide = "http://www.tux.org/pub/sites/ftp.gnome.org/GNOME/teams/art.gnome.org/backgrounds/ABSTRACT-BlueRidge_1280x1024.png" - #@addImageToPaper(page.png_uri, 400, 400) # TODO the dimensions should be modified - # get dimensions for available whiteboard space # get where to start from the left -> either the end of the user's list or the left edge of the screen if getInSession "display_usersList" then xBegin = $("#userListContainer").width() @@ -848,9 +841,10 @@ class @WhiteboardPaperModel presentationId = currentPresentation?.presentation?.id currentSlide = Meteor.Slides.findOne({"presentationId": presentationId, "slide.current": true}) - imageWidth = boardWidth * (currentSlide.slide.width_ratio/100) - imageHeight = boardHeight * (currentSlide.slide.height_ratio/100) - + # TODO currentSlide undefined in some cases - will check later why + imageWidth = boardWidth * (currentSlide?.slide.width_ratio/100) or 500 + imageHeight = boardHeight * (currentSlide?.slide.height_ratio/100) or 500 + # console.log "xBegin: #{xBegin}" # console.log "xEnd: #{xEnd}" # console.log "yBegin: #{yBegin}" diff --git a/labs/meteor-client/client/whiteboard_models/whiteboard_rect.coffee b/labs/meteor-client/client/whiteboard_models/whiteboard_rect.coffee index 5de4cffd1a..c230eb7c56 100644 --- a/labs/meteor-client/client/whiteboard_models/whiteboard_rect.coffee +++ b/labs/meteor-client/client/whiteboard_models/whiteboard_rect.coffee @@ -2,7 +2,6 @@ class @WhiteboardRectModel extends WhiteboardToolModel constructor: (@paper) -> super @paper - console.log "@paper in WhiteboardRectModel=" + @paper # the defintion of this shape, kept so we can redraw the shape whenever needed # format: x1, y1, x2, y2, stroke color, thickness @@ -15,10 +14,6 @@ class @WhiteboardRectModel extends WhiteboardToolModel # @param {string} colour the colour of the object # @param {number} thickness the thickness of the object's line(s) make: (startingData) => - console.log "MAKING RECT" - console.log "@paper in make in WhiteboardRectModel=" + @paper - console.log "make startingData"+ JSON.stringify startingData - x = startingData.points[0] y = startingData.points[1] color = startingData.color @@ -37,13 +32,13 @@ class @WhiteboardRectModel extends WhiteboardToolModel # @param {number} x2 the x value of the bottom right corner # @param {number} y2 the y value of the bottom right corner # @param {boolean} square (draw a square or not) - update: (startingData) -> - console.log "UPDATING RECT" + update: (startingData) -> + x1 = startingData.points[0] y1 = startingData.points[1] x2 = startingData.points[2] y2 = startingData.points[3] - console.log "updating rect points:" + x1, x2, y1, y2 + square = startingData.square if @obj? [x1, x2] = [x2, x1] if x2 < x1 diff --git a/labs/meteor-client/client/whiteboard_models/whiteboard_triangle.coffee b/labs/meteor-client/client/whiteboard_models/whiteboard_triangle.coffee index f023d2a7af..ce845cccdc 100755 --- a/labs/meteor-client/client/whiteboard_models/whiteboard_triangle.coffee +++ b/labs/meteor-client/client/whiteboard_models/whiteboard_triangle.coffee @@ -2,6 +2,7 @@ class @WhiteboardTriangleModel extends WhiteboardToolModel constructor: (@paper) -> + console.log "Whiteboard - Creating rectangle" super @paper # the defintion of this shape, kept so we can redraw the shape whenever needed @@ -14,20 +15,18 @@ class @WhiteboardTriangleModel extends WhiteboardToolModel # @param {string} colour the colour of the object # @param {number} thickness the thickness of the object's line(s) make: (info) -> - if info?.payload?.data?.coordinate? - x = info.payload.data.coordinate.first_x - y = info.payload.data.coordinate.first_y - color = info.payload.data.line.color - thickness = info.payload.data.line.weight + if info?.points? + x = info.points[0] + y = info.points[1] + color = info.color + thickness = info.thickness path = @_buildPath(x, y, x, y, x, y) @obj = @paper.path(path) - @obj.attr Utils.strokeAndThickness(color, thickness) + @obj.attr Meteor.call("strokeAndThickness", color, thickness) @obj.attr({"stroke-linejoin": "round"}) - @definition = - shape: "triangle" - data: [x, y, x, y, @obj.attrs["stroke"], @obj.attrs["stroke-width"]] + @definition = [x, y, x, y, @obj.attrs["stroke"], @obj.attrs["stroke-width"]] @obj @@ -37,11 +36,12 @@ class @WhiteboardTriangleModel extends WhiteboardToolModel # @param {number} x2 the x value of the bottom right corner # @param {number} y2 the y value of the bottom right corner update: (info) -> - if info?.payload?.data?.coordinate? - x1 = info.payload.data.coordinate.first_x - y1 = info.payload.data.coordinate.first_y - x2 = info.payload.data.coordinate.last_x - y2 = info.payload.data.coordinate.last_y + console.log "Whiteboard - updating triangle points" + if info?.points? + x1 = info.points[0] + y1 = info.points[1] + x2 = info.points[2] + y2 = info.points[3] if @obj? [xTop, yTop, xBottomLeft, yBottomLeft, xBottomRight, yBottomRight] = @_getCornersFromPoints(x1, y1, x2, y2) @@ -51,10 +51,10 @@ class @WhiteboardTriangleModel extends WhiteboardToolModel xBottomRight * @gw + @xOffset, yBottomRight * @gh + @yOffset) @obj.attr path: path - @definition.data[0] = x1 - @definition.data[1] = y1 - @definition.data[2] = x2 - @definition.data[3] = y2 + @definition[0] = x1 + @definition[1] = y1 + @definition[2] = x2 + @definition[3] = y2 # Draw a triangle on the whiteboard # @param {number} x1 the x value of the top left corner diff --git a/labs/meteor-client/collections/shapes.coffee b/labs/meteor-client/collections/shapes.coffee index 29c2208a1f..7c4f2203c1 100644 --- a/labs/meteor-client/collections/shapes.coffee +++ b/labs/meteor-client/collections/shapes.coffee @@ -1,6 +1,6 @@ Meteor.methods addShapeToCollection: (meetingId, whiteboardId, shapeObject) -> - unless Meteor.Shapes.findOne({whiteboardId:whiteboardId, meetingId: meetingId, "shape.wb_id": "shapeObject.wb_id"})? + if shapeObject?.status is "DRAW_END" #the mouse button was released - the drawing is complete entry = meetingId: meetingId whiteboardId: whiteboardId @@ -21,5 +21,30 @@ Meteor.methods color: shapeObject.shape.color id = Meteor.Shapes.insert(entry) - console.log "added shape id =[#{id}]:#{shapeObject.id} in #{meetingId}" + numShapesOnSlide = Meteor.Shapes.find({meetingId: meetingId, whiteboardId: whiteboardId}).fetch().length + console.log "added shape id =[#{id}]:#{shapeObject.id} in #{meetingId} || now there are #{numShapesOnSlide} shapes on the slide" + + removeAllShapesFromSlide: (meetingId, whiteboardId) -> + console.log "removeAllShapesFromSlide__" + whiteboardId + if meetingId? and whiteboardId? and Meteor.Shapes.find({meetingId: meetingId, whiteboardId: whiteboardId})? + shapesOnSlide = Meteor.Shapes.find({meetingId: meetingId, whiteboardId: whiteboardId}).fetch() + console.log "number of shapes:" + shapesOnSlide.length + for s in shapesOnSlide + console.log "shape=" + s.shape.id + id = Meteor.Shapes.findOne({meetingId: meetingId, whiteboardId: whiteboardId, "shape.id": s.shape.id}) + if id? + Meteor.Shapes.remove(id._id) + console.log "----removed shape[" + s.shape.id + "] from " + whiteboardId + console.log "remaining shapes on the slide:" + Meteor.Shapes.find({meetingId: meetingId, whiteboardId: whiteboardId}).fetch().length + + removeShapeFromSlide: (meetingId, whiteboardId, shapeId) -> + console.log "remove a shape from slide:" + shapeId + shapeToRemove = Meteor.Shapes.findOne({meetingId: meetingId, whiteboardId: whiteboardId, "shape.id": shapeId}) + if meetingId? and whiteboardId? and shapeId? and shapeToRemove? + console.log "found the shape to be removed" + Meteor.Shapes.remove(shapeToRemove._id) + console.log "----removed shape[" + shapeId + "] from " + whiteboardId + console.log "remaining shapes on the slide:" + Meteor.Shapes.find({meetingId: meetingId, whiteboardId: whiteboardId}).count() + + diff --git a/labs/meteor-client/server/redispubsub.coffee b/labs/meteor-client/server/redispubsub.coffee index 450d51107f..2ce9ad452e 100755 --- a/labs/meteor-client/server/redispubsub.coffee +++ b/labs/meteor-client/server/redispubsub.coffee @@ -121,6 +121,7 @@ class Meteor.RedisPubSub "keep_alive_reply" "page_resized_message" "presentation_page_resized_message" + "presentation_cursor_updated_message" # just because it's common. we handle it anyway ] unless message.header?.name in ignoredEventTypes @@ -239,7 +240,20 @@ class Meteor.RedisPubSub y = message.payload?.y_percent Meteor.Presentations.update({"presentation.current": true, meetingId: meetingId},{$set: {"pointer.x": x, "pointer.y": y}}) - console.log "presentation_cursor_updated_message #{x}_#{y}" + + if message.header?.name is "whiteboard_cleared_message" + whiteboardId = message.payload?.whiteboard_id + # shapesOnSlide = Meteor.Shapes.find({whiteboardId:whiteboardId, meetingId: meetingId}).fetch() + # console.log "shapesOnSlide:" + shapesOnSlide.size() + + Meteor.call("removeAllShapesFromSlide", meetingId, whiteboardId) + + if message.header?.name is "undo_whiteboard_request" + whiteboardId = message.payload?.whiteboard_id + shapeId = message.payload?.shape_id + + Meteor.call("removeShapeFromSlide", meetingId, whiteboardId, shapeId) + if message.header?.name in ["meeting_ended_message", "meeting_destroyed_event", "end_and_kick_all_message", "disconnect_all_users_message"]