diff --git a/akka-bbb-apps/build.sbt b/akka-bbb-apps/build.sbt index cc04561c592ef48a55fe3321d9ccd422b3e0e849..fd706f13697451f3b8e9c8db5384e008a62cf06a 100755 --- a/akka-bbb-apps/build.sbt +++ b/akka-bbb-apps/build.sbt @@ -50,7 +50,7 @@ libraryDependencies ++= { "com.google.code.gson" % "gson" % "1.7.1", "redis.clients" % "jedis" % "2.1.0", "org.apache.commons" % "commons-lang3" % "3.2", - "org.bigbluebutton" % "bbb-common-message" % "0.0.7" + "org.bigbluebutton" % "bbb-common-message" % "0.0.8" )} diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/PollApp.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/PollApp.scala index 8f12fe068a90aa9f49355f23998fb967010a360e..0d34440a50a0d7bca0c69d79ec09d3f1eca5582b 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/PollApp.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/PollApp.scala @@ -93,7 +93,7 @@ trait PollApp { annotation = new AnnotationVO(poll.id, WhiteboardKeyUtil.DRAW_END_STATUS, WhiteboardKeyUtil.POLL_RESULT_TYPE, shape, page.id) } this.context.self ! new SendWhiteboardAnnotationRequest(mProps.meetingID, msg.requesterId, annotation) - // outGW.send(new PollShowResultMessage(mProps.meetingID, mProps.recorded, msg.requesterId, msg.pollId, poll)) + outGW.send(new PollShowResultMessage(mProps.meetingID, mProps.recorded, msg.requesterId, msg.pollId, poll)) } case None => { diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/WhiteboardMessageToJsonConverter.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/WhiteboardMessageToJsonConverter.scala index 01f08b6831ddc0cf32967a8f2cb87ad3bbe083bc..4063cafa8acf38f39b17e2a49b3c5c5ef48c447d 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/WhiteboardMessageToJsonConverter.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/WhiteboardMessageToJsonConverter.scala @@ -15,6 +15,7 @@ object WhiteboardMessageToJsonConverter { res += "wb_id" -> shape.wbId val shapeMap = new scala.collection.mutable.HashMap[String, Any]() + shapeMap += "whiteboardId" -> shape.wbId for ((key, value) <- shape.shape) { shapeMap += key -> value } diff --git a/akka-bbb-fsesl/build.sbt b/akka-bbb-fsesl/build.sbt index 18e9c65a787779d5ce8e101a5f7721fed4cfcb7e..6253f5e1b677b2964d93fee12cc16897838b306e 100755 --- a/akka-bbb-fsesl/build.sbt +++ b/akka-bbb-fsesl/build.sbt @@ -50,7 +50,7 @@ libraryDependencies ++= { "com.google.code.gson" % "gson" % "1.7.1", "redis.clients" % "jedis" % "2.1.0", "org.apache.commons" % "commons-lang3" % "3.2", - "org.bigbluebutton" % "bbb-common-message" % "0.0.7", + "org.bigbluebutton" % "bbb-common-message" % "0.0.8", "org.bigbluebutton" % "bbb-fsesl-client" % "0.0.2" )} diff --git a/bbb-common-message/build.sbt b/bbb-common-message/build.sbt index b9f7b2e4270f8919fe52422316c26071402050fc..d15b61d81ab4898a93c3fbba69091a61411dfe54 100755 --- a/bbb-common-message/build.sbt +++ b/bbb-common-message/build.sbt @@ -4,7 +4,7 @@ name := "bbb-common-message" organization := "org.bigbluebutton" -version := "0.0.7" +version := "0.0.8" // We want to have our jar files in lib_managed dir. // This way we'll have the right path when we import diff --git a/bbb-common-message/src/main/java/org/bigbluebutton/common/messages/Util.java b/bbb-common-message/src/main/java/org/bigbluebutton/common/messages/Util.java index 08b09460076f0ed3dd8636bee14d69af6e6d1347..32f78f99ad69c6434e486eec0bbd901697c925cc 100755 --- a/bbb-common-message/src/main/java/org/bigbluebutton/common/messages/Util.java +++ b/bbb-common-message/src/main/java/org/bigbluebutton/common/messages/Util.java @@ -419,10 +419,11 @@ public class Util { } public Map<String, Object> extractPollResultAnnotation(JsonObject annotationElement) { - if (annotationElement.has("result") + if (annotationElement.has("result") && annotationElement.has("whiteboardId") && annotationElement.has("points")) { Map<String, Object> finalAnnotation = new HashMap<String, Object>(); + String whiteboardId = annotationElement.get("whiteboardId").getAsString(); String resultJson = annotationElement.get("result").getAsString(); JsonParser parser = new JsonParser(); JsonArray resultJsonArray = parser.parse(resultJson).getAsJsonArray(); @@ -454,6 +455,7 @@ public class Util { } } + finalAnnotation.put("whiteboardId", whiteboardId); finalAnnotation.put("result", collection); finalAnnotation.put("points", pointsArray); diff --git a/bigbluebutton-apps/build.gradle b/bigbluebutton-apps/build.gradle index e8296558ca14b42e18e538ab7a6fe52675c703ee..d9a54ee90a0fa00d512f0b7abee97c70326615ed 100755 --- a/bigbluebutton-apps/build.gradle +++ b/bigbluebutton-apps/build.gradle @@ -112,7 +112,7 @@ dependencies { compile 'com.google.code.gson:gson:1.7.1' providedCompile 'org.apache.commons:commons-lang3:3.2' - compile 'org.bigbluebutton:bbb-common-message:0.0.7' + compile 'org.bigbluebutton:bbb-common-message:0.0.8' } test { diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/business/shapes/GraphicObject.as b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/business/shapes/GraphicObject.as index d1ee3159736aedbf5e04fbba4e8c66097b21f0be..21b1204ffd80bfe6154bf6ce6efa2cbe68a4042c 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/business/shapes/GraphicObject.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/business/shapes/GraphicObject.as @@ -18,9 +18,6 @@ */ package org.bigbluebutton.modules.whiteboard.business.shapes { - import flash.display.DisplayObject; - - import org.bigbluebutton.common.LogUtil; public interface GraphicObject { function get type():String; diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/business/shapes/PollResultObject.as b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/business/shapes/PollResultObject.as new file mode 100755 index 0000000000000000000000000000000000000000..85d363596cef0e899c181d617ec0cb12e6a9a932 --- /dev/null +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/business/shapes/PollResultObject.as @@ -0,0 +1,298 @@ +/** + * BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ + * + * Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below). + * + * This program is free software; you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free Software + * Foundation; either version 3.0 of the License, or (at your option) any later + * version. + * + * BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along + * with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. + * + */ + +package org.bigbluebutton.modules.whiteboard.business.shapes +{ + import flash.text.TextField; + import flash.text.TextFormat; + import flash.text.TextFormatAlign; + + import org.bigbluebutton.modules.whiteboard.business.shapes.DrawObject; + import org.bigbluebutton.modules.whiteboard.models.Annotation; + + public class PollResultObject extends DrawObject { + private const sx:int = 0; + private const sy:int = 0; + //private const h:uint = 100; + //private const w:uint = 280; + private const bgFill:uint = 0XCECECE; //0xFFFFFF; + private const colFill:uint = 0x000000; + private const vpadding:Number = 10; + private const hpadding:Number = 5; + private const labelStartWidth:int = 40; + private const percentStartWidth:int = 40; + + private var sampledata:Array = [{a:"A", v:3}, {a:"B", v:1}, {a:"C", v:5}, {a:"D", v:8}]; + private var _data:Array; + private var _textFields:Array; + + public function PollResultObject(id:String, type:String, status:String) { + super(id, type, status) + + _textFields = new Array(); + data = null; + // temp setter for testing purposes + //data = sampledata; + + } + + public function set data(d:Array):void { + _data = d; + } + + public function get data():Array { + return _data; + } + + private function makeTextFields(num:int):void { + if (num > _textFields.length) { + var textField:TextField; + for (var i:int=_textFields.length; i < num; i++) { + textField = new TextField(); + addChild(textField); + _textFields.push(textField); + } + } else if (num < _textFields.length) { + for (var j:int=_textFields.length; i > num; i--) { + removeChild(_textFields.pop()); + } + } + } + + private function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void { +// graphics.clear(); + + if (_data != null && _data.length > 0) { + graphics.lineStyle(2); + graphics.beginFill(bgFill, 1.0); + graphics.drawRect(sx, sy, unscaledWidth, unscaledHeight); + graphics.endFill(); + + var actualRH:Number = (unscaledHeight-vpadding*(_data.length+1)) / _data.length; + trace("PollGraphic - as raw " + actualRH +" int " + int(actualRH)); + // Current problem is that the rowHeight is truncated. It would be nice if the extra pixels + // could be distributed for a more even look. + var avgRowHeight:int = (unscaledHeight-vpadding*(_data.length+1)) / _data.length; + var extraVPixels:int = unscaledHeight - (_data.length * (avgRowHeight+vpadding) + vpadding); + trace("PollGraphic - extraVPixels " + extraVPixels); + var largestVal:int = -1; + var totalCount:Number = 0; + //find largest value + for (var i:int=0; i<_data.length; i++) { + if (_data[i].v > largestVal) largestVal = _data[i].v; + totalCount += _data[i].v; + } + + var currTFIdx:int = 0; + var answerText:TextField; + var percentText:TextField; + var answerArray:Array = new Array(); + var percentArray:Array = new Array(); + var minFontSize:int = 20; + var currFontSize:int; + + graphics.lineStyle(2); + graphics.beginFill(colFill, 1.0); + for (var j:int=0, vp:int=extraVPixels, ry:int=0, curRowHeight:int=0; j<_data.length; j++) { + ry += Math.round(curRowHeight/2)+vpadding; // add the last row's height plus padding + + curRowHeight = avgRowHeight; + if (j%2==0 && vp > 0) { + curRowHeight += 1; + vp--; + } + ry += curRowHeight/2; + + //ry += curRowHeight * (j+0.5) + vpadding*(j+1); + // add row label + answerText = _textFields[currTFIdx++]; + answerText.text = _data[j].a; + answerText.width = labelStartWidth; + answerText.height = curRowHeight; + answerText.selectable = false; + //addChild(answerText); + answerArray.push(answerText); + currFontSize = findFontSize(answerText, 20); + if (currFontSize < minFontSize) minFontSize = currFontSize; + //rowText.height = rowText.textHeight; + answerText.x = hpadding; + //rowText.y = ry-rowText.height/2; + + // add percentage + percentText = _textFields[currTFIdx++];;// new TextField(); + var percentNum:Number = (totalCount == 0 ? 0 : ((_data[j].v/totalCount)*100)); + percentText.text = Math.round(percentNum).toString() + "%"; + percentText.width = percentStartWidth; + percentText.height = curRowHeight; + percentText.selectable = false; + //addChild(percentText); + percentArray.push(percentText); + currFontSize = findFontSize(percentText, 20); + if (currFontSize < minFontSize) minFontSize = currFontSize; + //percentText.height = percentText.textHeight; + //percentText.x = unscaledWidth-percentStartWidth/2-percentText.width/2; + //percentText.y = ry-percentText.height/2; + } + + var maxAnswerWidth:int = 0; + var maxPercentWidth:int = 0; + + for (j=0, vp=extraVPixels, ry=0, curRowHeight=0; j<_data.length; j++) { + ry += Math.round(curRowHeight/2)+vpadding; // add the last row's height plus padding + + curRowHeight = avgRowHeight; + if (j%2==0 && vp > 0) { + curRowHeight += 1; + vp--; + } + ry += curRowHeight/2; + + //ry = curRowHeight * (j+0.5) + vpadding*(j+1); + + answerText = TextField(answerArray[j]); + findFontSize(answerText, minFontSize); + answerText.width = answerText.textWidth+4; + answerText.height = answerText.textHeight+4; + answerText.y = ry-answerText.height/2; + if (answerText.width > maxAnswerWidth) maxAnswerWidth = answerText.width; + + percentText = TextField(percentArray[j]); + findFontSize(percentText, minFontSize); + percentText.width = percentText.textWidth+4; + percentText.height = percentText.textHeight+4; + percentText.x = unscaledWidth - hpadding - percentText.width; + percentText.y = ry-percentText.height/2; + if (percentText.width > maxPercentWidth) maxPercentWidth = percentText.width; + + } + + var countText:TextField; + var maxBarWidth:int = unscaledWidth - (hpadding*4) - maxAnswerWidth - maxPercentWidth; + var barStartX:int = maxAnswerWidth + (hpadding*2); + + for (j=0, vp=extraVPixels, ry=0, curRowHeight=0; j<_data.length; j++) { + ry += Math.round(curRowHeight/2)+vpadding; // add the last row's height plus padding + + curRowHeight = avgRowHeight; + if (j%2==0 && vp > 0) { + curRowHeight += 1; + vp--; + } + ry += curRowHeight/2; + + //ry = curRowHeight * (j+0.5) + vpadding*(j+1); + + // draw rect + var rectWidth:int = maxBarWidth*(_data[j].v/largestVal); + graphics.drawRect(barStartX, ry-curRowHeight/2, rectWidth, curRowHeight); + // add vote count in middle of rect + countText = _textFields[currTFIdx++]; // new TextField(); + countText.text = _data[j].v; + countText.width = rectWidth; + countText.height = curRowHeight; + countText.textColor = 0xFFFFFF; + countText.selectable = false; + //addChild(countText); + findFontSize(countText, minFontSize); + countText.width = countText.textWidth+4; + countText.height = countText.textHeight+4; + countText.x = barStartX+rectWidth/2-countText.width/2; + countText.y = ry-countText.height/2; + } + + graphics.endFill(); + } + } + + private function findFontSize(textField:TextField, defaultSize:Number):int { + var tFormat:TextFormat = new TextFormat(); + tFormat.size = defaultSize; + tFormat.align = TextFormatAlign.CENTER; + textField.setTextFormat(tFormat); + var size:Number = defaultSize; + while((textField.textWidth+4 > textField.width || textField.textHeight+4 > textField.height) && size > 0) { + size = size - 1; + tFormat.size = size; + textField.setTextFormat(tFormat); + } + + return size; + } + + private function drawRect(a:Annotation, parentWidth:Number, parentHeight:Number, zoom:Number):void { + // LogUtil.debug("Drawing RECTANGLE"); + var ao:Object = a.annotation; + this.graphics.lineStyle(1 * zoom, 0); + + var arrayEnd:Number = (ao.points as Array).length; + var startX:Number = denormalize(21.845575, parentWidth); + var startY:Number = denormalize(23.145401, parentHeight); + var width:Number = denormalize(46.516006, parentWidth) - startX; + var height:Number = denormalize(61.42433, parentHeight) - startY; + + this.graphics.drawRect(startX, startY, width, height); + + } + + override public function draw(a:Annotation, parentWidth:Number, parentHeight:Number, zoom:Number):void { + // if (_pollGraphic != null) { + // this.removeChild(_pollGraphic); + // } + + // _pollGraphic = new PollGraphic(); + // this.addChild(_pollGraphic); + + var ao:Object = a.annotation; + trace("RESULT = " + JSON.stringify(a)); +// drawRect(a, parentWidth, parentHeight, zoom); +/* + _pollGraphic.x = denormalize((ao.points as Array)[0], parentWidth); + _pollGraphic.y = denormalize((ao.points as Array)[1], parentHeight); + _pollGraphic.width = denormalize((ao.points as Array)[2], parentWidth); + _pollGraphic.height = denormalize((ao.points as Array)[3], parentHeight); +*/ + var arrayEnd:Number = (ao.points as Array).length; + var startX:Number = denormalize(21.845575, parentWidth); + var startY:Number = denormalize(23.145401, parentHeight); + var pwidth:Number = denormalize(46.516006, parentWidth) - startX; + var pheight:Number = denormalize(61.42433, parentHeight) - startY; + + var answers:Array = ao.result as Array; + var ans:Array = new Array(); + for (var j:int = 0; j < answers.length; j++) { + var ar:Object = answers[j]; + var rs:Object = {a: ar.key, v: ar.num_votes as Number}; + trace("poll result a=[" + ar.key + "] v=[" + ar.num_votes +"]"); + ans.push(rs); + } + + data = ans; + makeTextFields((answers != null ? answers.length*3 : 0)); + + updateDisplayList(pwidth, pheight); + +// drawRect(a, parentWidth, parentHeight, zoom); + + } + + override public function redraw(a:Annotation, parentWidth:Number, parentHeight:Number, zoom:Number):void { + draw(a, parentWidth, parentHeight, zoom); + } + } +} \ No newline at end of file diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/business/shapes/Rectangle.as b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/business/shapes/Rectangle.as index 54cc5f71c04e1eda4b756e5764ee8f5e42da8b71..860b13840c6d19353dd77d4af453bed8a07c2e83 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/business/shapes/Rectangle.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/business/shapes/Rectangle.as @@ -18,9 +18,6 @@ */ package org.bigbluebutton.modules.whiteboard.business.shapes { - import flash.display.Sprite; - - import org.bigbluebutton.common.LogUtil; import org.bigbluebutton.modules.whiteboard.models.Annotation; /** diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/business/shapes/ShapeFactory.as b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/business/shapes/ShapeFactory.as index 6746dbc33803c24c229b20c020e946e14b6a1128..ebe7d9258025259cf72af78a34ea5f3a939501f3 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/business/shapes/ShapeFactory.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/business/shapes/ShapeFactory.as @@ -18,8 +18,6 @@ */ package org.bigbluebutton.modules.whiteboard.business.shapes { - import flash.display.Shape; - import org.bigbluebutton.common.LogUtil; import org.bigbluebutton.modules.whiteboard.models.Annotation; import org.bigbluebutton.modules.whiteboard.models.WhiteboardModel; @@ -65,7 +63,7 @@ package org.bigbluebutton.modules.whiteboard.business.shapes } else if (a.type == DrawObject.TRIANGLE) { return new Triangle(a.id, a.type, a.status); } else if (a.type == DrawObject.POLL) { - return new PollResult(a.id, a.type, a.status); + return new PollResultObject(a.id, a.type, a.status); } return null; diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/business/shapes/TextObject.as b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/business/shapes/TextObject.as index 45f93ff6e5c5d3dce09d10bc75e16f13c6d5e665..1349c1c3311310812d2d95886b4f7f99cc05d949 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/business/shapes/TextObject.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/business/shapes/TextObject.as @@ -18,29 +18,14 @@ */ package org.bigbluebutton.modules.whiteboard.business.shapes { - import com.asfusion.mate.core.GlobalDispatcher; - - import flash.display.DisplayObject; - import flash.display.Shape; - import flash.display.Stage; import flash.events.Event; import flash.events.FocusEvent; import flash.events.KeyboardEvent; - import flash.events.MouseEvent; import flash.events.TextEvent; import flash.text.AntiAliasType; import flash.text.TextField; import flash.text.TextFieldType; import flash.text.TextFormat; - - import flashx.textLayout.edit.SelectionManager; - - import flexlib.scheduling.scheduleClasses.utils.Selection; - - import mx.controls.Text; - - import org.bigbluebutton.common.LogUtil; - import org.bigbluebutton.modules.whiteboard.WhiteboardCanvasModel; public class TextObject extends TextField implements GraphicObject { public static const TYPE_NOT_EDITABLE:String = "dynamic"; diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/models/WhiteboardModel.as b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/models/WhiteboardModel.as old mode 100644 new mode 100755 index f333bd1c5c0a32a6ac165e750a23ed874539495c..91a2e06b80eaee87c8197c9021d4de70c3d739d9 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/models/WhiteboardModel.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/models/WhiteboardModel.as @@ -53,7 +53,8 @@ package org.bigbluebutton.modules.whiteboard.models public function addAnnotation(annotation:Annotation):void { trace(LOG + "*** Adding annotation [" + annotation.id + "," + annotation.type + "," + annotation.status + "] ****"); var wb:Whiteboard; - if (annotation.status == DrawObject.DRAW_START || annotation.status == TextObject.TEXT_CREATED) { + if (annotation.status == DrawObject.DRAW_START || annotation.type == DrawObject.POLL + || annotation.status == TextObject.TEXT_CREATED) { wb = getWhiteboard(annotation.whiteboardId); if (wb != null) { wb.addAnnotation(annotation);