diff --git a/akka-bbb-apps/src/main/java/org/bigbluebutton/core/api/IBigBlueButtonInGW.java b/akka-bbb-apps/src/main/java/org/bigbluebutton/core/api/IBigBlueButtonInGW.java index cfd35a8751753d8dc84d21974e8dd6c0b169c072..53520a6e0020ee1b71fc0b5dafff1831afc859ed 100755 --- a/akka-bbb-apps/src/main/java/org/bigbluebutton/core/api/IBigBlueButtonInGW.java +++ b/akka-bbb-apps/src/main/java/org/bigbluebutton/core/api/IBigBlueButtonInGW.java @@ -76,7 +76,6 @@ public interface IBigBlueButtonInGW { void clear(String meetingID); void removePresentation(String meetingID, String presentationID); void getPresentationInfo(String meetingID, String requesterID, String replyTo); - void sendCursorUpdate(String meetingID, double xPercent, double yPercent); void resizeAndMoveSlide(String meetingID, double xOffset, double yOffset, double widthRatio, double heightRatio); void gotoSlide(String meetingID, String page); void sharePresentation(String meetingID, String presentationID, boolean share); @@ -110,7 +109,8 @@ public interface IBigBlueButtonInGW { void clearPublicChatHistory(String meetingID, String requesterID); // Whiteboard - void sendWhiteboardAnnotation(String meetingID, String requesterID, java.util.Map<String, Object> annotation); + void sendWhiteboardAnnotation(String meetingID, String requesterID, java.util.Map<String, Object> annotation); + void sendCursorPosition(String meetingID, String requesterID, double xPercent, double yPercent); void requestWhiteboardAnnotationHistory(String meetingID, String requesterID, String whiteboardId, String replyTo); void clearWhiteboard(String meetingID, String requesterID, String whiteboardId); void undoWhiteboard(String meetingID, String requesterID, String whiteboardId); diff --git a/akka-bbb-apps/src/main/java/org/bigbluebutton/core/pubsub/receivers/PresentationMessageListener.java b/akka-bbb-apps/src/main/java/org/bigbluebutton/core/pubsub/receivers/PresentationMessageListener.java index 1709bf91b3d42516ea18009fd65432d0dbc43ff1..6338c66f8edda5b8f43c9492fb4cb7c3f9436b80 100755 --- a/akka-bbb-apps/src/main/java/org/bigbluebutton/core/pubsub/receivers/PresentationMessageListener.java +++ b/akka-bbb-apps/src/main/java/org/bigbluebutton/core/pubsub/receivers/PresentationMessageListener.java @@ -10,7 +10,6 @@ import org.bigbluebutton.common.messages.RemovePresentationMessage; import org.bigbluebutton.common.messages.ResizeAndMoveSlideMessage; import org.bigbluebutton.common.messages.SendConversionCompletedMessage; import org.bigbluebutton.common.messages.SendConversionUpdateMessage; -import org.bigbluebutton.common.messages.SendCursorUpdateMessage; import org.bigbluebutton.common.messages.SendPageCountErrorMessage; import org.bigbluebutton.common.messages.SendSlideGeneratedMessage; import org.bigbluebutton.common.messages.SharePresentationMessage; @@ -118,9 +117,6 @@ public class PresentationMessageListener implements MessageHandler { } else if (RemovePresentationMessage.REMOVE_PRESENTATION.equals(messageName)) { RemovePresentationMessage msg = RemovePresentationMessage.fromJson(message); bbbInGW.removePresentation(msg.meetingId, msg.presentationId); - } else if (SendCursorUpdateMessage.SEND_CURSOR_UPDATE.equals(messageName)) { - SendCursorUpdateMessage msg = SendCursorUpdateMessage.fromJson(message); - bbbInGW.sendCursorUpdate(msg.meetingId, msg.xPercent, msg.yPercent); } else if (SharePresentationMessage.SHARE_PRESENTATION.equals(messageName)) { SharePresentationMessage msg = SharePresentationMessage.fromJson(message); bbbInGW.sharePresentation(msg.meetingId, msg.presentationId, msg.share); diff --git a/akka-bbb-apps/src/main/java/org/bigbluebutton/core/pubsub/receivers/WhiteboardMessageReceiver.java b/akka-bbb-apps/src/main/java/org/bigbluebutton/core/pubsub/receivers/WhiteboardMessageReceiver.java index a41344813b4e8d93ed9250755d182b0d9472d5db..62df29046ff01f74b288147d25f7515796101de3 100755 --- a/akka-bbb-apps/src/main/java/org/bigbluebutton/core/pubsub/receivers/WhiteboardMessageReceiver.java +++ b/akka-bbb-apps/src/main/java/org/bigbluebutton/core/pubsub/receivers/WhiteboardMessageReceiver.java @@ -7,6 +7,7 @@ import org.bigbluebutton.common.messages.ModifyWhiteboardAccessRequestMessage; import org.bigbluebutton.common.messages.GetWhiteboardAccessRequestMessage; import org.bigbluebutton.common.messages.MessagingConstants; import org.bigbluebutton.common.messages.RequestWhiteboardAnnotationHistoryRequestMessage; +import org.bigbluebutton.common.messages.SendCursorPositionMessage; import org.bigbluebutton.common.messages.SendWhiteboardAnnotationRequestMessage; import org.bigbluebutton.common.messages.UndoWhiteboardRequest; import org.bigbluebutton.core.api.IBigBlueButtonInGW; @@ -52,6 +53,9 @@ public class WhiteboardMessageReceiver implements MessageHandler { } else if (SendWhiteboardAnnotationRequestMessage.SEND_WHITEBOARD_ANNOTATION_REQUEST.equals(messageName)) { SendWhiteboardAnnotationRequestMessage msg = SendWhiteboardAnnotationRequestMessage.fromJson(message); bbbInGW.sendWhiteboardAnnotation(msg.meetingId, msg.requesterId, msg.annotation); + } else if (SendCursorPositionMessage.SEND_CURSOR_POSITION.equals(messageName)) { + SendCursorPositionMessage msg = SendCursorPositionMessage.fromJson(message); + bbbInGW.sendCursorPosition(msg.meetingId, msg.requesterId, msg.xPercent, msg.yPercent); } } } diff --git a/akka-bbb-apps/src/main/java/org/bigbluebutton/core/recorders/events/CursorUpdateRecordEvent.java b/akka-bbb-apps/src/main/java/org/bigbluebutton/core/recorders/events/CursorUpdateRecordEvent.java index 924c754d77834744e593f4792a535def2db3b322..22cedf83a77c1c14e3b6ab35240d9253fab15206 100755 --- a/akka-bbb-apps/src/main/java/org/bigbluebutton/core/recorders/events/CursorUpdateRecordEvent.java +++ b/akka-bbb-apps/src/main/java/org/bigbluebutton/core/recorders/events/CursorUpdateRecordEvent.java @@ -18,13 +18,17 @@ */ package org.bigbluebutton.core.recorders.events; -public class CursorUpdateRecordEvent extends AbstractPresentationRecordEvent{ +public class CursorUpdateRecordEvent extends AbstractWhiteboardRecordEvent{ public CursorUpdateRecordEvent() { super(); setEvent("CursorMoveEvent"); } + public void setUserId(String userId) { + eventMap.put("userId", userId); + } + public void setXPercent(double percent) { eventMap.put("xOffset", Double.toString(percent)); } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonInGW.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonInGW.scala index b4cebad5677ce49b6af70f60d39102d3ffa5c572..4bf0c7447c45849ae2d793e5e83e23fa6d9ac077 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonInGW.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonInGW.scala @@ -367,10 +367,6 @@ class BigBlueButtonInGW( eventBus.publish(BigBlueButtonEvent(meetingID, new GetPresentationInfo(meetingID, requesterID, replyTo))) } - def sendCursorUpdate(meetingID: String, xPercent: Double, yPercent: Double) { - eventBus.publish(BigBlueButtonEvent(meetingID, new SendCursorUpdate(meetingID, xPercent, yPercent))) - } - def resizeAndMoveSlide(meetingID: String, xOffset: Double, yOffset: Double, widthRatio: Double, heightRatio: Double) { eventBus.publish(BigBlueButtonEvent(meetingID, new ResizeAndMoveSlide(meetingID, xOffset, yOffset, widthRatio, heightRatio))) } @@ -466,6 +462,10 @@ class BigBlueButtonInGW( } } + def sendCursorPosition(meetingID: String, requesterID: String, xPercent: Double, yPercent: Double) { + eventBus.publish(BigBlueButtonEvent(meetingID, new SendCursorPositionRequest(meetingID, requesterID, xPercent, yPercent))) + } + def requestWhiteboardAnnotationHistory(meetingID: String, requesterID: String, whiteboardId: String, replyTo: String) { eventBus.publish(BigBlueButtonEvent(meetingID, new GetWhiteboardShapesRequest(meetingID, requesterID, whiteboardId, replyTo))) } diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/MessageSenderActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/MessageSenderActor.scala index 1a9ccde6b38cd7bcb8c7d21883aa9014b5f95916..adcc465807919dc8c59106252053900d24599d4c 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/MessageSenderActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/MessageSenderActor.scala @@ -86,7 +86,6 @@ class MessageSenderActor(val service: MessageSender) case msg: ClearPresentationOutMsg => handleClearPresentationOutMsg(msg) case msg: RemovePresentationOutMsg => handleRemovePresentationOutMsg(msg) case msg: GetPresentationInfoOutMsg => handleGetPresentationInfoOutMsg(msg) - case msg: SendCursorUpdateOutMsg => handleSendCursorUpdateOutMsg(msg) case msg: ResizeAndMoveSlideOutMsg => handleResizeAndMoveSlideOutMsg(msg) case msg: GotoSlideOutMsg => handleGotoSlideOutMsg(msg) case msg: SharePresentationOutMsg => handleSharePresentationOutMsg(msg) @@ -137,6 +136,7 @@ class MessageSenderActor(val service: MessageSender) case msg: LockLayoutEvent => handleLockLayoutEvent(msg) case msg: GetWhiteboardShapesReply => handleGetWhiteboardShapesReply(msg) case msg: SendWhiteboardAnnotationEvent => handleSendWhiteboardAnnotationEvent(msg) + case msg: CursorPositionUpdatedEvent => handleCursorPositionUpdatedEvent(msg) case msg: ClearWhiteboardEvent => handleClearWhiteboardEvent(msg) case msg: UndoWhiteboardEvent => handleUndoWhiteboardEvent(msg) case msg: ModifiedWhiteboardAccessEvent => handleModifiedWhiteboardAccessEvent(msg) @@ -381,11 +381,6 @@ class MessageSenderActor(val service: MessageSender) service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json) } - private def handleSendCursorUpdateOutMsg(msg: SendCursorUpdateOutMsg) { - val json = PesentationMessageToJsonConverter.sendCursorUpdateOutMsgToJson(msg) - service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json) - } - private def handleResizeAndMoveSlideOutMsg(msg: ResizeAndMoveSlideOutMsg) { val json = PesentationMessageToJsonConverter.resizeAndMoveSlideOutMsgToJson(msg) service.send(MessagingConstants.FROM_PRESENTATION_CHANNEL, json) @@ -748,6 +743,11 @@ class MessageSenderActor(val service: MessageSender) service.send(MessagingConstants.FROM_WHITEBOARD_CHANNEL, json) } + private def handleCursorPositionUpdatedEvent(msg: CursorPositionUpdatedEvent) { + val json = WhiteboardMessageToJsonConverter.cursorPositionUpdatedEventToJson(msg) + service.send(MessagingConstants.FROM_WHITEBOARD_CHANNEL, json) + } + private def handleClearWhiteboardEvent(msg: ClearWhiteboardEvent) { val json = WhiteboardMessageToJsonConverter.clearWhiteboardEventToJson(msg) service.send(MessagingConstants.FROM_WHITEBOARD_CHANNEL, json) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/RecorderActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/RecorderActor.scala index f4b45140767f0b20f8ddbb890f42ac170fcf8a6b..533532c2b2a88dd04d4c4626ad1cad8db378d229 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/RecorderActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/RecorderActor.scala @@ -66,7 +66,6 @@ class RecorderActor(val recorder: RecorderApplication) case msg: ClearPublicChatHistoryReply => handleClearPublicChatHistoryReply(msg) case msg: ClearPresentationOutMsg => handleClearPresentationOutMsg(msg) case msg: RemovePresentationOutMsg => handleRemovePresentationOutMsg(msg) - case msg: SendCursorUpdateOutMsg => handleSendCursorUpdateOutMsg(msg) case msg: ResizeAndMoveSlideOutMsg => handleResizeAndMoveSlideOutMsg(msg) case msg: GotoSlideOutMsg => handleGotoSlideOutMsg(msg) case msg: SharePresentationOutMsg => handleSharePresentationOutMsg(msg) @@ -86,6 +85,7 @@ class RecorderActor(val recorder: RecorderApplication) case msg: VoiceRecordingStarted => handleVoiceRecordingStarted(msg) case msg: VoiceRecordingStopped => handleVoiceRecordingStopped(msg) case msg: SendWhiteboardAnnotationEvent => handleSendWhiteboardAnnotationEvent(msg) + case msg: CursorPositionUpdatedEvent => handleCursorPositionUpdatedEvent(msg) case msg: ClearWhiteboardEvent => handleClearWhiteboardEvent(msg) case msg: UndoWhiteboardEvent => handleUndoWhiteboardEvent(msg) case msg: EditCaptionHistoryReply => handleEditCaptionHistoryReply(msg) @@ -196,18 +196,6 @@ class RecorderActor(val recorder: RecorderApplication) } } - private def handleSendCursorUpdateOutMsg(msg: SendCursorUpdateOutMsg) { - if (msg.recorded) { - val event = new CursorUpdateRecordEvent(); - event.setMeetingId(msg.meetingID); - event.setTimestamp(TimestampGenerator.generateTimestamp); - event.setXPercent(msg.xPercent); - event.setYPercent(msg.yPercent); - - recorder.record(msg.meetingID, event); - } - } - private def handleEndAndKickAll(msg: EndAndKickAll): Unit = { if (msg.recorded) { val ev = new ParticipantEndAndKickAllRecordEvent(); @@ -444,6 +432,19 @@ class RecorderActor(val recorder: RecorderApplication) } + private def handleCursorPositionUpdatedEvent(msg: CursorPositionUpdatedEvent) { + if (msg.recorded) { + val event = new CursorUpdateRecordEvent(); + event.setMeetingId(msg.meetingID); + event.setTimestamp(TimestampGenerator.generateTimestamp); + event.setUserId(msg.requesterID); + event.setXPercent(msg.xPercent); + event.setYPercent(msg.yPercent); + + recorder.record(msg.meetingID, event); + } + } + private def handleClearWhiteboardEvent(msg: ClearWhiteboardEvent) { if (msg.recorded) { val event = new ClearPageWhiteboardRecordEvent() diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala index e8c5dfdc3cb4e6f5fbb01120123a987361bd7126..1a7ef3a971fe245f5348276a1739194646ecec1d 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala @@ -137,7 +137,6 @@ case class BroadcastLayoutRequest(meetingID: String, requesterID: String, layout case class ClearPresentation(meetingID: String) extends InMessage case class RemovePresentation(meetingID: String, presentationID: String) extends InMessage case class GetPresentationInfo(meetingID: String, requesterID: String, replyTo: String) extends InMessage -case class SendCursorUpdate(meetingID: String, xPercent: Double, yPercent: Double) extends InMessage case class ResizeAndMoveSlide(meetingID: String, xOffset: Double, yOffset: Double, widthRatio: Double, heightRatio: Double) extends InMessage case class GotoSlide(meetingID: String, page: String) extends InMessage @@ -194,6 +193,7 @@ case class VoiceConfRecordingStartedMessage(voiceConfId: String, recordStream: S ///////////////////////////////////////////////////////////////////////////////////// case class SendWhiteboardAnnotationRequest(meetingID: String, requesterID: String, annotation: AnnotationVO) extends InMessage +case class SendCursorPositionRequest(meetingID: String, requesterID: String, xPercent: Double, yPercent: Double) extends InMessage case class GetWhiteboardShapesRequest(meetingID: String, requesterID: String, whiteboardId: String, replyTo: String) extends InMessage case class ClearWhiteboardRequest(meetingID: String, requesterID: String, whiteboardId: String) extends InMessage case class UndoWhiteboardRequest(meetingID: String, requesterID: String, whiteboardId: String) extends InMessage diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/MessageNames.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/MessageNames.scala index 9cd8256186f198e14bbc12729f51ad5581f41e5d..acebc5ba80150bb13bb7e30e0cf51281904f9458 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/MessageNames.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/MessageNames.scala @@ -62,7 +62,6 @@ object MessageNames { val PRESENTATION_PAGE_COUNT_ERROR = "presentation_page_count_error_message" val PRESENTATION_SLIDE_GENERATED = "presentation_slide_generated_message" val PRESENTATION_CONVERSION_COMPLETED = "presentation_conversion_completed_message" - val PRESENTATION_CURSOR_UPDATED = "presentation_cursor_updated_message" val SEND_VOICE_USERS_REQUEST = "send_voice_users_request" val MUTE_MEETING_REQUEST = "mute_meeting_request" val IS_MEETING_MUTED = "is_meeting_muted_request" @@ -163,6 +162,7 @@ object MessageNames { val PRESENTATION_PAGE_GENERATED = "presentation_page_generated_message" val GET_WHITEBOARD_SHAPES_REPLY = "get_whiteboard_shapes_reply" val SEND_WHITEBOARD_SHAPE = "send_whiteboard_shape_message" + val CURSOR_POSITION_UPDATED = "cursor_position_updated_message" val UNDO_WHITEBOARD_MESSAGE = "undo_whiteboard_message" val MODIFIED_WHITEBOARD_ACCESS = "modified_whiteboard_access_message" val GET_WHITEBOARD_ACCESS_REPLY = "get_whiteboard_access_reply" diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/OutMessages.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/OutMessages.scala index abb66df45a908d84544a934c33b5de5963a73358..e5260ecf91005ab9e70b2775041038f26000d40e 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/OutMessages.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/api/OutMessages.scala @@ -108,7 +108,6 @@ case class ClearPresentationOutMsg(meetingID: String, recorded: Boolean) extends case class RemovePresentationOutMsg(meetingID: String, recorded: Boolean, presentationID: String) extends IOutMessage case class GetPresentationInfoOutMsg(meetingID: String, recorded: Boolean, requesterID: String, info: CurrentPresentationInfo, replyTo: String) extends IOutMessage -case class SendCursorUpdateOutMsg(meetingID: String, recorded: Boolean, xPercent: Double, yPercent: Double) extends IOutMessage case class ResizeAndMoveSlideOutMsg(meetingID: String, recorded: Boolean, page: Page) extends IOutMessage case class GotoSlideOutMsg(meetingID: String, recorded: Boolean, page: Page) extends IOutMessage case class SharePresentationOutMsg(meetingID: String, recorded: Boolean, presentation: Presentation) extends IOutMessage @@ -145,6 +144,7 @@ case class GetCurrentPollReplyMessage(meetingID: String, recorded: Boolean, requ // Whiteboard case class GetWhiteboardShapesReply(meetingID: String, recorded: Boolean, requesterID: String, whiteboardId: String, shapes: Array[AnnotationVO], replyTo: String) extends IOutMessage case class SendWhiteboardAnnotationEvent(meetingID: String, recorded: Boolean, requesterID: String, whiteboardId: String, shape: AnnotationVO) extends IOutMessage +case class CursorPositionUpdatedEvent(meetingID: String, recorded: Boolean, requesterID: String, xPercent: Double, yPercent: Double) extends IOutMessage case class ClearWhiteboardEvent(meetingID: String, recorded: Boolean, requesterID: String, whiteboardId: String, fullClear: Boolean) extends IOutMessage case class UndoWhiteboardEvent(meetingID: String, recorded: Boolean, requesterID: String, whiteboardId: String, shapeId: String) extends IOutMessage case class ModifiedWhiteboardAccessEvent(meetingID: String, recorded: Boolean, requesterID: String, multiUser: Boolean) extends IOutMessage diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/PresentationApp.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/PresentationApp.scala index 3710d46cd4a48b90d52c709d4f65004e8566b4f8..7ab527ca39ce807a1a8bc02d2d1baf1deaf51c57 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/PresentationApp.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/PresentationApp.scala @@ -11,8 +11,6 @@ trait PresentationApp { val outGW: OutMessageGateway - private var cursorLocation = new CursorLocation - def handlePreuploadedPresentations(msg: PreuploadedPresentations) { val pres = msg.presentations @@ -83,11 +81,6 @@ trait PresentationApp { outGW.send(new GetPresentationInfoOutMsg(mProps.meetingID, mProps.recorded, msg.requesterID, presentationInfo, msg.replyTo)) } - def handleSendCursorUpdate(msg: SendCursorUpdate) { - cursorLocation = new CursorLocation(msg.xPercent, msg.yPercent) - outGW.send(new SendCursorUpdateOutMsg(mProps.meetingID, mProps.recorded, msg.xPercent, msg.yPercent)) - } - def handleResizeAndMoveSlide(msg: ResizeAndMoveSlide) { // Force coordinate that are out-of-bounds inside valid values val xOffset = if (msg.xOffset <= 0) msg.xOffset else 0 diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/PresentationModel.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/PresentationModel.scala index ac92710ac1a93eb652a98bebcf1a2e12d98b4294..5dccb4f1f22ec1019d37a9ccb124c2e1376590a2 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/PresentationModel.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/PresentationModel.scala @@ -2,7 +2,6 @@ package org.bigbluebutton.core.apps case class CurrentPresenter(userId: String, name: String, assignedBy: String) case class CurrentPresentationInfo(presenter: CurrentPresenter, presentations: Seq[Presentation]) -case class CursorLocation(xPercent: Double = 0D, yPercent: Double = 0D) case class Presentation(id: String, name: String, current: Boolean = false, pages: scala.collection.immutable.HashMap[String, Page], downloadable: Boolean) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/WhiteboardApp.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/WhiteboardApp.scala index 507299a5130a809fa893f16fbea0337001563c20..f6e1e317701d704d0c18ce16faeda96f631628b5 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/WhiteboardApp.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/WhiteboardApp.scala @@ -47,6 +47,10 @@ trait WhiteboardApp { } + def handleSendCursorPositionRequest(msg: SendCursorPositionRequest) { + outGW.send(new CursorPositionUpdatedEvent(mProps.meetingID, mProps.recorded, msg.requesterID, msg.xPercent, msg.yPercent)) + } + def handleGetWhiteboardShapesRequest(msg: GetWhiteboardShapesRequest) { //println("WB: Received page history [" + msg.whiteboardId + "]") val history = liveMeeting.wbModel.getHistory(msg.whiteboardId); diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/WhiteboardModel.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/WhiteboardModel.scala index 694553b1bb96a455741353a573d2639e857ed17f..0b97f4a829fee30093ed695af51e1462420951d8 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/WhiteboardModel.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/WhiteboardModel.scala @@ -3,7 +3,6 @@ package org.bigbluebutton.core.apps import java.util.ArrayList; import org.bigbluebutton.core.util.jhotdraw.BezierWrapper -import org.bigbluebutton.core.util.jhotdraw.PathData import scala.collection.immutable.List import scala.collection.immutable.HashMap diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/PesentationMessageToJsonConverter.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/PesentationMessageToJsonConverter.scala index a26548a2342e7ecf2c210ce17ecc39faac493b1f..d381c21ea6f6eab182c7dfd8144f5927e45f0db2 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/PesentationMessageToJsonConverter.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/PesentationMessageToJsonConverter.scala @@ -85,16 +85,6 @@ object PesentationMessageToJsonConverter { Util.buildJson(header, payload) } - def sendCursorUpdateOutMsgToJson(msg: SendCursorUpdateOutMsg): String = { - val payload = new java.util.HashMap[String, Any]() - payload.put(Constants.MEETING_ID, msg.meetingID) - payload.put(Constants.X_PERCENT, msg.xPercent) - payload.put(Constants.Y_PERCENT, msg.yPercent) - - val header = Util.buildHeader(MessageNames.PRESENTATION_CURSOR_UPDATED, None) - Util.buildJson(header, payload) - } - def resizeAndMoveSlideOutMsgToJson(msg: ResizeAndMoveSlideOutMsg): String = { val payload = new java.util.HashMap[String, Any]() payload.put(Constants.MEETING_ID, msg.meetingID) 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 d2b8f337c21ec26fdf132bc160d408eb49fa4f10..66d7190f6a062fbb122c1866975f76a6d10589f9 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 @@ -53,6 +53,17 @@ object WhiteboardMessageToJsonConverter { Util.buildJson(header, payload) } + def cursorPositionUpdatedEventToJson(msg: CursorPositionUpdatedEvent): String = { + val payload = new java.util.HashMap[String, Any]() + payload.put(Constants.MEETING_ID, msg.meetingID) + payload.put(Constants.REQUESTER_ID, msg.requesterID) + payload.put(Constants.X_PERCENT, msg.xPercent) + payload.put(Constants.Y_PERCENT, msg.yPercent) + + val header = Util.buildHeader(MessageNames.CURSOR_POSITION_UPDATED, None) + Util.buildJson(header, payload) + } + def clearWhiteboardEventToJson(msg: ClearWhiteboardEvent): String = { val payload = new java.util.HashMap[String, Any]() payload.put(Constants.MEETING_ID, msg.meetingID) diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala index 1a6197fc55c4656f3e39b430ab576d908b65db29..b8104da0458ffded4a07aafb8b923afa9571a265 100755 --- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala +++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala @@ -97,13 +97,13 @@ class MeetingActor(val mProps: MeetingProperties, case msg: PresentationConversionCompleted => handlePresentationConversionCompleted(msg) case msg: RemovePresentation => handleRemovePresentation(msg) case msg: GetPresentationInfo => handleGetPresentationInfo(msg) - case msg: SendCursorUpdate => handleSendCursorUpdate(msg) case msg: ResizeAndMoveSlide => handleResizeAndMoveSlide(msg) case msg: GotoSlide => handleGotoSlide(msg) case msg: SharePresentation => handleSharePresentation(msg) case msg: GetSlideInfo => handleGetSlideInfo(msg) case msg: PreuploadedPresentations => handlePreuploadedPresentations(msg) case msg: SendWhiteboardAnnotationRequest => handleSendWhiteboardAnnotationRequest(msg) + case msg: SendCursorPositionRequest => handleSendCursorPositionRequest(msg) case msg: GetWhiteboardShapesRequest => handleGetWhiteboardShapesRequest(msg) case msg: ClearWhiteboardRequest => handleClearWhiteboardRequest(msg) case msg: UndoWhiteboardRequest => handleUndoWhiteboardRequest(msg) diff --git a/bbb-common-message/src/main/java/org/bigbluebutton/common/messages/PresentationCursorUpdateMessage.java b/bbb-common-message/src/main/java/org/bigbluebutton/common/messages/CursorPositionUpdatedMessage.java similarity index 63% rename from bbb-common-message/src/main/java/org/bigbluebutton/common/messages/PresentationCursorUpdateMessage.java rename to bbb-common-message/src/main/java/org/bigbluebutton/common/messages/CursorPositionUpdatedMessage.java index a39042ec377986cfa6e726e780bef17926f1f067..83481c4a43790ca769870e6892021987b9a0496a 100755 --- a/bbb-common-message/src/main/java/org/bigbluebutton/common/messages/PresentationCursorUpdateMessage.java +++ b/bbb-common-message/src/main/java/org/bigbluebutton/common/messages/CursorPositionUpdatedMessage.java @@ -4,16 +4,18 @@ import java.util.HashMap; import com.google.gson.JsonObject; import com.google.gson.JsonParser; -public class PresentationCursorUpdateMessage implements ISubscribedMessage { - public static final String PRESENTATION_CURSOR_UPDATED = "presentation_cursor_updated_message"; +public class CursorPositionUpdatedMessage implements ISubscribedMessage { + public static final String CURSOR_POSITION_UPDATED = "cursor_position_updated_message"; public final String VERSION = "0.0.1"; public final String meetingId; + public final String requesterId; public final double xPercent; public final double yPercent; - public PresentationCursorUpdateMessage(String meetingId, double xPercent, double yPercent) { + public CursorPositionUpdatedMessage(String meetingId, String requesterId, double xPercent, double yPercent) { this.meetingId = meetingId; + this.requesterId = requesterId; this.xPercent = xPercent; this.yPercent = yPercent; } @@ -21,15 +23,16 @@ public class PresentationCursorUpdateMessage implements ISubscribedMessage { public String toJson() { HashMap<String, Object> payload = new HashMap<String, Object>(); payload.put(Constants.MEETING_ID, meetingId); + payload.put(Constants.REQUESTER_ID, requesterId); payload.put(Constants.X_PERCENT, xPercent); payload.put(Constants.Y_PERCENT, yPercent); - java.util.HashMap<String, Object> header = MessageBuilder.buildHeader(PRESENTATION_CURSOR_UPDATED, VERSION, null); + java.util.HashMap<String, Object> header = MessageBuilder.buildHeader(CURSOR_POSITION_UPDATED, VERSION, null); return MessageBuilder.buildJson(header, payload); } - public static PresentationCursorUpdateMessage fromJson(String message) { + public static CursorPositionUpdatedMessage fromJson(String message) { JsonParser parser = new JsonParser(); JsonObject obj = (JsonObject) parser.parse(message); @@ -39,15 +42,17 @@ public class PresentationCursorUpdateMessage implements ISubscribedMessage { if (header.has("name")) { String messageName = header.get("name").getAsString(); - if (PRESENTATION_CURSOR_UPDATED.equals(messageName)) { + if (CURSOR_POSITION_UPDATED.equals(messageName)) { if (payload.has(Constants.MEETING_ID) + && payload.has(Constants.REQUESTER_ID) && payload.has(Constants.X_PERCENT) && payload.has(Constants.Y_PERCENT)) { String meetingId = payload.get(Constants.MEETING_ID).getAsString(); + String requesterId = payload.get(Constants.REQUESTER_ID).getAsString(); double xPercent = payload.get(Constants.X_PERCENT).getAsDouble(); double yPercent = payload.get(Constants.Y_PERCENT).getAsDouble(); - return new PresentationCursorUpdateMessage(meetingId, xPercent, yPercent); + return new CursorPositionUpdatedMessage(meetingId, requesterId, xPercent, yPercent); } } } diff --git a/bbb-common-message/src/main/java/org/bigbluebutton/common/messages/SendCursorUpdateMessage.java b/bbb-common-message/src/main/java/org/bigbluebutton/common/messages/SendCursorPositionMessage.java similarity index 66% rename from bbb-common-message/src/main/java/org/bigbluebutton/common/messages/SendCursorUpdateMessage.java rename to bbb-common-message/src/main/java/org/bigbluebutton/common/messages/SendCursorPositionMessage.java index bb11902959715aed83aecf3cd0655775b62c52fb..f768d4b84d6a69dfa923fcd8ab03afcdc004454e 100755 --- a/bbb-common-message/src/main/java/org/bigbluebutton/common/messages/SendCursorUpdateMessage.java +++ b/bbb-common-message/src/main/java/org/bigbluebutton/common/messages/SendCursorPositionMessage.java @@ -5,16 +5,18 @@ import java.util.HashMap; import com.google.gson.JsonObject; import com.google.gson.JsonParser; -public class SendCursorUpdateMessage implements IBigBlueButtonMessage { - public static final String SEND_CURSOR_UPDATE = "send_cursor_update"; +public class SendCursorPositionMessage implements IBigBlueButtonMessage { + public static final String SEND_CURSOR_POSITION = "send_cursor_position"; public static final String VERSION = "0.0.1"; public final String meetingId; + public final String requesterId; public final double xPercent; public final double yPercent; - public SendCursorUpdateMessage(String meetingId, double xPercent, double yPercent){ + public SendCursorPositionMessage(String meetingId, String requesterId, double xPercent, double yPercent){ this.meetingId = meetingId; + this.requesterId = requesterId; this.xPercent = xPercent; this.yPercent = yPercent; } @@ -22,15 +24,16 @@ public class SendCursorUpdateMessage implements IBigBlueButtonMessage { public String toJson() { HashMap<String, Object> payload = new HashMap<String, Object>(); payload.put(Constants.MEETING_ID, meetingId); + payload.put(Constants.REQUESTER_ID, requesterId); payload.put(Constants.X_PERCENT, xPercent); payload.put(Constants.Y_PERCENT, yPercent); - java.util.HashMap<String, Object> header = MessageBuilder.buildHeader(SEND_CURSOR_UPDATE, VERSION, null); + java.util.HashMap<String, Object> header = MessageBuilder.buildHeader(SEND_CURSOR_POSITION, VERSION, null); return MessageBuilder.buildJson(header, payload); } - public static SendCursorUpdateMessage fromJson(String message) { + public static SendCursorPositionMessage fromJson(String message) { JsonParser parser = new JsonParser(); JsonObject obj = (JsonObject) parser.parse(message); @@ -40,15 +43,17 @@ public class SendCursorUpdateMessage implements IBigBlueButtonMessage { if (header.has("name")) { String messageName = header.get("name").getAsString(); - if (SEND_CURSOR_UPDATE.equals(messageName)) { + if (SEND_CURSOR_POSITION.equals(messageName)) { if (payload.has(Constants.MEETING_ID) + && payload.has(Constants.REQUESTER_ID) && payload.has(Constants.X_PERCENT) && payload.has(Constants.Y_PERCENT)) { String meetingId = payload.get(Constants.MEETING_ID).getAsString(); + String requesterId = payload.get(Constants.REQUESTER_ID).getAsString(); double xPercent = payload.get(Constants.X_PERCENT).getAsDouble(); double yPercent = payload.get(Constants.Y_PERCENT).getAsDouble(); - return new SendCursorUpdateMessage(meetingId, xPercent, yPercent); + return new SendCursorPositionMessage(meetingId, requesterId, xPercent, yPercent); } } } diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/PresentationClientMessageSender.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/PresentationClientMessageSender.java index b60d9f058c9735b902f1bb40803a054200778966..c8917eaf97fefef234eb7b4b11e9c3d31060b925 100755 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/PresentationClientMessageSender.java +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/PresentationClientMessageSender.java @@ -10,7 +10,6 @@ import org.bigbluebutton.common.messages.GoToSlideReplyMessage; import org.bigbluebutton.common.messages.PresentationConversionDoneMessage; import org.bigbluebutton.common.messages.PresentationConversionErrorMessage; import org.bigbluebutton.common.messages.PresentationConversionProgressMessage; -import org.bigbluebutton.common.messages.PresentationCursorUpdateMessage; import org.bigbluebutton.common.messages.PresentationPageGeneratedReplyMessage; import org.bigbluebutton.common.messages.PresentationPageResizedMessage; import org.bigbluebutton.common.messages.PresentationRemovedMessage; @@ -55,9 +54,6 @@ public class PresentationClientMessageSender { case PresentationPageGeneratedReplyMessage.PRESENTATION_PAGE_GENERATED: processPresentationPageGeneratedReply(message); break; - case PresentationCursorUpdateMessage.PRESENTATION_CURSOR_UPDATED: - processPresentationCursorUpdate(message); - break; case PresentationConversionErrorMessage.PRESENTATION_CONVERSION_ERROR: processPresentationConversionError(message); break; @@ -227,23 +223,6 @@ public class PresentationClientMessageSender { } } - private void processPresentationCursorUpdate(String json) { - PresentationCursorUpdateMessage msg = PresentationCursorUpdateMessage.fromJson(json); - if (msg != null) { - Map<String, Object> args = new HashMap<String, Object>(); - args.put("meetingID", msg.meetingId); - args.put("xPercent", msg.xPercent); - args.put("yPercent", msg.yPercent); - - Map<String, Object> message = new HashMap<String, Object>(); - Gson gson = new Gson(); - message.put("msg", gson.toJson(args)); - - BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "PresentationCursorUpdateCommand", message); - service.sendMessage(m); - } - } - private void processPresentationPageGeneratedReply(String json) { PresentationPageGeneratedReplyMessage msg = PresentationPageGeneratedReplyMessage.fromJson(json); if (msg != null) { diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/WhiteboardClientMessageSender.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/WhiteboardClientMessageSender.java index 1ee5b78250c10df202206229842129745c94e1cf..7545712acb389965e074825a2349ebfdc04634c3 100755 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/WhiteboardClientMessageSender.java +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/client/WhiteboardClientMessageSender.java @@ -4,6 +4,7 @@ import java.util.HashMap; import java.util.Map; import org.bigbluebutton.common.messages.ClearWhiteboardReplyMessage; +import org.bigbluebutton.common.messages.CursorPositionUpdatedMessage; import org.bigbluebutton.common.messages.GetWhiteboardShapesReplyMessage; import org.bigbluebutton.common.messages.GetWhiteboardAccessReplyMessage; import org.bigbluebutton.common.messages.SendWhiteboardAnnotationReplyMessage; @@ -59,6 +60,12 @@ public class WhiteboardClientMessageSender { processSendWhiteboardAnnotationReplyMessage(swarm); } break; + case CursorPositionUpdatedMessage.CURSOR_POSITION_UPDATED: + CursorPositionUpdatedMessage cpum = CursorPositionUpdatedMessage.fromJson(message); + if (cpum != null) { + processCursorPositionUpdatedMessage(cpum); + } + break; case ModifiedWhiteboardAccessMessage.MODIFIED_WHITEBOARD_ACCESS: ModifiedWhiteboardAccessMessage mwam = ModifiedWhiteboardAccessMessage.fromJson(message); if (mwam != null) { @@ -100,6 +107,20 @@ public class WhiteboardClientMessageSender { service.sendMessage(b); } + + private void processCursorPositionUpdatedMessage(CursorPositionUpdatedMessage msg) { + Map<String, Object> args = new HashMap<String, Object>(); + args.put("requesterId", msg.requesterId); + args.put("xPercent", msg.xPercent); + args.put("yPercent", msg.yPercent); + + Map<String, Object> message = new HashMap<String, Object>(); + Gson gson = new Gson(); + message.put("msg", gson.toJson(args)); + + BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "WhiteboardCursorPositionUpdatedCommand", message); + service.sendMessage(m); + } private void processGetWhiteboardShapesReplyMessage(GetWhiteboardShapesReplyMessage msg) { diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/pubsub/MessagePublisher.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/pubsub/MessagePublisher.java index 16faf4c49e847f7d1ad399c4b4492c7d062b0128..212ee5987a1fb20ea31e3e5a343568c1a2734059 100755 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/pubsub/MessagePublisher.java +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/pubsub/MessagePublisher.java @@ -180,11 +180,6 @@ public class MessagePublisher { } - public void sendCursorUpdate(String meetingID, double xPercent, double yPercent) { - SendCursorUpdateMessage msg = new SendCursorUpdateMessage(meetingID, xPercent, yPercent); - sender.send(MessagingConstants.TO_PRESENTATION_CHANNEL, msg.toJson()); - } - public void resizeAndMoveSlide(String meetingID, double xOffset, double yOffset, double widthRatio, double heightRatio) { ResizeAndMoveSlideMessage msg = new ResizeAndMoveSlideMessage(meetingID, xOffset, yOffset, widthRatio, heightRatio); sender.send(MessagingConstants.TO_PRESENTATION_CHANNEL, msg.toJson()); @@ -262,11 +257,17 @@ public class MessagePublisher { DeskShareGetInfoRequestMessage msg = new DeskShareGetInfoRequestMessage(meetingID, requesterID, replyTo); sender.send(MessagingConstants.FROM_VOICE_CONF_SYSTEM_CHAN, msg.toJson()); } + public void sendWhiteboardAnnotation(String meetingID, String requesterID, Map<String, Object> annotation) { SendWhiteboardAnnotationRequestMessage msg = new SendWhiteboardAnnotationRequestMessage(meetingID, requesterID, annotation); sender.send(MessagingConstants.TO_WHITEBOARD_CHANNEL, msg.toJson()); } + public void sendCursorPosition(String meetingID, String requesterID, double xPercent, double yPercent) { + SendCursorPositionMessage msg = new SendCursorPositionMessage(meetingID, requesterID, xPercent, yPercent); + sender.send(MessagingConstants.TO_WHITEBOARD_CHANNEL, msg.toJson()); + } + public void requestWhiteboardAnnotationHistory(String meetingID, String requesterID, String whiteboardId, String replyTo) { RequestWhiteboardAnnotationHistoryRequestMessage msg = new RequestWhiteboardAnnotationHistoryRequestMessage(meetingID, requesterID, whiteboardId, replyTo); sender.send(MessagingConstants.TO_WHITEBOARD_CHANNEL, msg.toJson()); diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/PresentationApplication.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/PresentationApplication.java index 45375188da97143c351a1e0c0ce99475724d9503..da9f85321a0dc8c5f3f905cdbe8d228ed1860030 100755 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/PresentationApplication.java +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/PresentationApplication.java @@ -77,11 +77,6 @@ public class PresentationApplication { red5BBBInGW.getPresentationInfo(meetingID, requesterID, replyTo); } - public void sendCursorUpdate(String meetingID, Double xPercent, Double yPercent) { - - red5BBBInGW.sendCursorUpdate(meetingID, xPercent, yPercent); - } - public void resizeAndMoveSlide(String meetingID, Double xOffset, Double yOffset, Double widthRatio, Double heightRatio) { red5BBBInGW.resizeAndMoveSlide(meetingID, xOffset, yOffset, widthRatio, heightRatio); diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/PresentationService.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/PresentationService.java index 7a647bbdd11cee47b2265934c964a95cccb10067..d3ce4c6b04a4f2e79bd618f30c61080b3e258c4c 100755 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/PresentationService.java +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/PresentationService.java @@ -73,29 +73,6 @@ public class PresentationService { presentationApplication.sharePresentation(scope.getName(), presentationID, share); } - public void sendCursorUpdate(Map<String, Object> msg) { - IScope scope = Red5.getConnectionLocal().getScope(); - - Double xPercent; - if (msg.get("xPercent") instanceof Integer) { - Integer tempXOffset = (Integer) msg.get("xPercent"); - xPercent = tempXOffset.doubleValue(); - } else { - xPercent = (Double) msg.get("xPercent"); - } - - Double yPercent; - - if (msg.get("yPercent") instanceof Integer) { - Integer tempYOffset = (Integer) msg.get("yPercent"); - yPercent = tempYOffset.doubleValue(); - } else { - yPercent = (Double) msg.get("yPercent"); - } - - presentationApplication.sendCursorUpdate(scope.getName(), xPercent, yPercent); - } - public void resizeAndMoveSlide(Map<String, Object> msg) { Double xOffset; if (msg.get("xOffset") instanceof Integer) { diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/WhiteboardApplication.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/WhiteboardApplication.java index 34be53789b673357a22883bf82066d788f7074bd..2a328d32541f8e48150ca9084cd574d3b48078a6 100755 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/WhiteboardApplication.java +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/WhiteboardApplication.java @@ -99,6 +99,10 @@ public class WhiteboardApplication implements IApplication { public void sendWhiteboardAnnotation(String meetingID, String requesterID, java.util.Map<String, Object> shape) { red5BBBInGW.sendWhiteboardAnnotation(meetingID, requesterID, shape); } + + public void sendCursorPosition(String meetingID, String requesterID, Double xPercent, Double yPercent) { + red5BBBInGW.sendCursorPosition(meetingID, requesterID, xPercent, yPercent); + } public void clearWhiteboard(String meetingID, String requesterID, String whiteboardId) { red5BBBInGW.clearWhiteboard(meetingID, requesterID, whiteboardId); diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/WhiteboardService.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/WhiteboardService.java index a373787be7b4e22fd01eff212685d7f4b57abd14..434991a4626a77d3f37bca1ff86e761e2a4299bc 100755 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/WhiteboardService.java +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/service/WhiteboardService.java @@ -24,6 +24,7 @@ import org.bigbluebutton.red5.BigBlueButtonSession; import org.bigbluebutton.red5.Constants; import org.red5.logging.Red5LoggerFactory; import org.red5.server.api.Red5; +import org.red5.server.api.scope.IScope; import org.slf4j.Logger; public class WhiteboardService { @@ -47,19 +48,6 @@ public class WhiteboardService { return false; } public void sendAnnotation(Map<String, Object> annotation) { -// for (Map.Entry<String, Object> entry : annotation.entrySet()) { -// String key = entry.getKey(); -// Object value = entry.getValue(); - -// if (key.equals("points")) { -// String points = "points=["; -// ArrayList<Double> v = (ArrayList<Double>) value; -// log.debug(points + pointsToString(v) + "]"); -// } else { -// log.debug(key + "=[" + value + "]"); -// } -// } - String meetingID = getMeetingId(); String requesterID = getBbbSession().getInternalUserID(); @@ -68,18 +56,29 @@ public class WhiteboardService { } } - /*private String pointsToString(ArrayList<Double> points){ - String datapoints = ""; - for (Double i : points) { - datapoints += i + ","; - } - // Trim the trailing comma -// log.debug("Data Point = " + datapoints); - return datapoints.substring(0, datapoints.length() - 1); + public void sendCursorPosition(Map<String, Object> msg) { + String meetingID = getMeetingId(); + String requesterID = getBbbSession().getInternalUserID(); + + Double xPercent; + if (msg.get("xPercent") instanceof Integer) { + Integer tempXOffset = (Integer) msg.get("xPercent"); + xPercent = tempXOffset.doubleValue(); + } else { + xPercent = (Double) msg.get("xPercent"); + } -// application.sendShape(shape, type, color, thickness, fill, fillColor, transparency, id, status); + Double yPercent; - }*/ + if (msg.get("yPercent") instanceof Integer) { + Integer tempYOffset = (Integer) msg.get("yPercent"); + yPercent = tempYOffset.doubleValue(); + } else { + yPercent = (Double) msg.get("yPercent"); + } + + application.sendCursorPosition(meetingID, requesterID, xPercent, yPercent); + } public void requestAnnotationHistory(Map<String, Object> message) { log.info("WhiteboardApplication - requestAnnotationHistory"); diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/business/PresentProxy.as b/bigbluebutton-client/src/org/bigbluebutton/modules/present/business/PresentProxy.as old mode 100644 new mode 100755 index 5b040abab2b3a117859dfee3b2548a57694e8aa5..4e2e3b500fa236bd4ea6c993bd45050513460768 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/business/PresentProxy.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/business/PresentProxy.as @@ -229,15 +229,5 @@ package org.bigbluebutton.modules.present.business public function zoomSlide(e:PresenterCommands):void{ sender.move(e.xOffset, e.yOffset, e.slideToCanvasWidthRatio, e.slideToCanvasHeightRatio); } - - /** - * Update the presenter cursor within the presentation window - * @param e - * - */ - public function sendCursorUpdate(e:PresenterCommands):void{ - sender.sendCursorUpdate(e.xPercent, e.yPercent); - } - } } \ No newline at end of file diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/events/PresenterCommands.as b/bigbluebutton-client/src/org/bigbluebutton/modules/present/events/PresenterCommands.as index 654b27f7931159d3950e63ee6e7df275c2d007d0..c8df6ffa38dc2d05fe82da8e63a777637a8be31b 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/events/PresenterCommands.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/events/PresenterCommands.as @@ -34,7 +34,6 @@ package org.bigbluebutton.modules.present.events public static const RESET_ZOOM:String = "RESTORE_ZOOM"; public static const MOVE:String = "MOVE_COMMAND"; public static const SHARE_PRESENTATION_COMMAND:String = "SHARE_PRESENTATION_COMMAND"; - public static const SEND_CURSOR_UPDATE:String = "SEND_CURSOR_UPDATE"; //Parameter for the slide navigation events public var slideNumber:Number; @@ -45,10 +44,6 @@ package org.bigbluebutton.modules.present.events //Parameters for the resize event public var newSizeInPercent:Number; - //Parameters for the cursor event - public var xPercent:Number; - public var yPercent:Number; - //Parameters for the move event public var xOffset:Number; public var yOffset:Number; diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/maps/PresentEventMap.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/present/maps/PresentEventMap.mxml index ed9bd0a7369e38d8d080fa4d6dbfafeac4ea3395..24a547f7d255e593db96df2dda3d18febbec7046 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/maps/PresentEventMap.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/maps/PresentEventMap.mxml @@ -108,10 +108,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. <EventHandlers type="{GetListOfPresentationsRequest.GET_LIST_OF_PRESENTATIONS}" > <MethodInvoker generator="{PresentProxy}" method="handleGetListOfPresentationsRequest" /> </EventHandlers> - - <EventHandlers type="{PresenterCommands.SEND_CURSOR_UPDATE}" > - <MethodInvoker generator="{PresentProxy}" method="sendCursorUpdate" arguments="{event}" /> - </EventHandlers> <EventHandlers type="{PresenterCommands.RESIZE}" > <MethodInvoker generator="{PresentProxy}" method="resizeSlide" arguments="{event}" /> diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/services/PresentationService.as b/bigbluebutton-client/src/org/bigbluebutton/modules/present/services/PresentationService.as index 0fad260c6f79819644ad10b43816a9478241d4f7..29e43eab75ae47065fec27818b5516870f339557 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/services/PresentationService.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/services/PresentationService.as @@ -5,7 +5,6 @@ package org.bigbluebutton.modules.present.services import mx.collections.ArrayCollection; import org.bigbluebutton.modules.present.commands.ChangePageCommand; - import org.bigbluebutton.modules.present.events.CursorEvent; import org.bigbluebutton.modules.present.events.PageChangedEvent; import org.bigbluebutton.modules.present.events.PresentationChangedEvent; import org.bigbluebutton.modules.present.events.RemovePresentationEvent; @@ -35,13 +34,6 @@ package org.bigbluebutton.modules.present.services dispatcher = new Dispatcher(); } - public function cursorMoved(x: Number, y: Number):void { - var e:CursorEvent = new CursorEvent(CursorEvent.UPDATE_CURSOR); - e.xPercent = x; - e.yPercent = y; - dispatcher.dispatchEvent(e); - } - public function pageChanged(page: PageVO):void { var np: Page = model.getPage(page.id); if (np != null) { diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/services/messaging/MessageReceiver.as b/bigbluebutton-client/src/org/bigbluebutton/modules/present/services/messaging/MessageReceiver.as index ead0449d8f11377883ef89abe12662cd7d925779..85dcfa103259fdf4731028a66aedb2f25a5955c9 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/services/messaging/MessageReceiver.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/services/messaging/MessageReceiver.as @@ -60,9 +60,6 @@ package org.bigbluebutton.modules.present.services.messaging //LOGGER.info("Presentation: received message " + messageName); switch (messageName) { - case "PresentationCursorUpdateCommand": - handlePresentationCursorUpdateCommand(message); - break; case "goToSlideCallback": handleGotoSlideCallback(message); break; @@ -101,14 +98,6 @@ package org.bigbluebutton.modules.present.services.messaging } - private function handlePresentationCursorUpdateCommand(msg:Object):void { -// trace(LOG + "*** handlePresentationCursorUpdateCommand " + msg.msg + " **** \n"); - var map:Object = JSON.parse(msg.msg); - if (map.hasOwnProperty("xPercent") && map.hasOwnProperty("yPercent")) { - service.cursorMoved(map.xPercent, map.yPercent); - } - } - private function handleGotoSlideCallback(msg:Object) : void { var map:Object = JSON.parse(msg.msg); diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/services/messaging/MessageSender.as b/bigbluebutton-client/src/org/bigbluebutton/modules/present/services/messaging/MessageSender.as index 00cccb12b20fc4db9f6e7814f430ad7ba057ecdd..6c09c2f9a1e228f64eb85660130e949534ab6b85 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/services/messaging/MessageSender.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/services/messaging/MessageSender.as @@ -27,29 +27,6 @@ package org.bigbluebutton.modules.present.services.messaging private static const LOGGER:ILogger = getClassLogger(MessageSender); - /** - * Send an event to the server to update the presenter's cursor view on the client - * @param xPercent - * @param yPercent - * - */ - public function sendCursorUpdate(xPercent:Number, yPercent:Number):void{ - var message:Object = new Object(); - message["xPercent"] = xPercent; - message["yPercent"] = yPercent; - - var _nc:ConnectionManager = BBB.initConnectionManager(); - _nc.sendMessage("presentation.sendCursorUpdate", - function(result:String):void { // On successful result - //LOGGER.debug(result); - }, - function(status:String):void { // status - On error occurred - LOGGER.error(status); - }, - message - ); - } - /** * Sends an event to the server to update the clients with the new slide position * @param slideXPosition diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/SlideView.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/SlideView.mxml index 0a2ffd2a13d2d84ec587077ca16db1253aca4faa..36f2c17a1be59365d7edfae5a8d703ce2e5d7c7d 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/SlideView.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/SlideView.mxml @@ -28,15 +28,14 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. x="{slideModel.viewportX}" y="{slideModel.viewportY}" creationComplete="onCreationComplete()" verticalScrollPolicy="off" - horizontalScrollPolicy="off" - rollOut="hideCursor()" styleName="presentationSlideViewStyle" + horizontalScrollPolicy="off" + styleName="presentationSlideViewStyle" xmlns:views="org.bigbluebutton.modules.present.views.*"> <mate:Listener type="{PageChangedEvent.PRESENTATION_PAGE_CHANGED_EVENT}" method="handlePageChangedEvent" /> <mate:Listener type="{PageLoadedEvent.PAGE_LOADED_EVENT}" method="handlePageLoadedEvent" /> <mate:Listener type="{MadePresenterEvent.SWITCH_TO_PRESENTER_MODE}" method="handleSwitchToPresenterEvent" /> <mate:Listener type="{MadePresenterEvent.SWITCH_TO_VIEWER_MODE}" method="handleSwitchToViewerEvent" /> - <mate:Listener type="{CursorEvent.UPDATE_CURSOR}" method="handleUpdateCursorEvent" /> <mate:Listener type="{ShortcutEvent.FOCUS_SLIDE}" method="focusSlide" /> <mx:Script> <![CDATA[ @@ -46,7 +45,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. import mx.collections.Sort; import mx.collections.SortField; import mx.containers.Canvas; - import mx.managers.CursorManager; import org.as3commons.logging.api.ILogger; import org.as3commons.logging.api.getClassLogger; @@ -55,7 +53,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. import org.bigbluebutton.main.events.MadePresenterEvent; import org.bigbluebutton.main.events.ShortcutEvent; import org.bigbluebutton.modules.present.commands.GoToPageCommand; - import org.bigbluebutton.modules.present.events.CursorEvent; import org.bigbluebutton.modules.present.events.DisplaySlideEvent; import org.bigbluebutton.modules.present.events.PageChangedEvent; import org.bigbluebutton.modules.present.events.PageLoadedEvent; @@ -73,8 +70,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. [Bindable] public var zoomPercentage:Number = 100; public static const ZOOM_STEP:int = 5; public static const THUMBNAILS_CLOSED:String = "ThumbnailsClosed"; - - private var cursor:Shape; + private var whiteboardCanvas:WhiteboardCanvas; private var dispatcher:Dispatcher = new Dispatcher(); @@ -84,21 +80,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. private var pageCache:ArrayCollection = new ArrayCollection(); - // Send update of mouse location to other users. - private var _sendCurrentMouseLocTimer:Timer = new Timer(100); - private var _lastMouseXPosition:Number = 0; - private var _lastMouseYPosition:Number = 0; - private function onCreationComplete():void { slideLoader.width = this.width; slideLoader.height = this.height; - cursor = new Shape(); - cursor.graphics.lineStyle(6, 0xFF0000, 0.6); - cursor.graphics.drawCircle(0,0,2.5); - this.rawChildren.addChild(cursor); - cursor.visible = false; - this.setChildIndex(thumbnailView, this.numChildren - 1); /* @@ -340,8 +325,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. private function becomeViewer():void { removeEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheelZoomEvent); this.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); - _sendCurrentMouseLocTimer.stop(); - _sendCurrentMouseLocTimer.removeEventListener(TimerEvent.TIMER, mouseCursorUpdateTimerListener); } /** @@ -361,9 +344,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheelZoomEvent); this.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); - _sendCurrentMouseLocTimer.addEventListener(TimerEvent.TIMER, mouseCursorUpdateTimerListener); - _sendCurrentMouseLocTimer.start(); - notifyOthersOfZoomEvent(); + notifyOthersOfZoomEvent(); } /** @@ -373,53 +354,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. becomePresenter(); } - - public function mouseCursorUpdateTimerListener(e:TimerEvent):void{ - if (noSlideContentLoaded()) return; - notifyOthersOfPresentersCursorPosition(this.mouseX, this.mouseY); - } - - /** - * Broadcast to other participants the location fo the mouse cursor. - */ - private function notifyOthersOfPresentersCursorPosition(cursorXPosition:int, cursorYPosition:int):void { - // Only update the other users if the mouse moved a certain delta - if ( (Math.abs(cursorXPosition - _lastMouseXPosition) < 0.1) - && (Math.abs(cursorYPosition - _lastMouseYPosition) < 0.1) ) { - return; - } - - if (cursorXPosition > this.width || cursorXPosition < 1 - || cursorYPosition > this.height || cursorYPosition < 1) { -// LogUtil.debug("Cursor outside the window...not sending [" + cursorXPosition + "," + cursorYPosition + "]"); - return; - } - - _lastMouseXPosition = cursorXPosition; - _lastMouseYPosition = cursorYPosition; - - var command:PresenterCommands = new PresenterCommands(PresenterCommands.SEND_CURSOR_UPDATE); - command.xPercent = cursorXPosition / this.width; - command.yPercent = cursorYPosition / this.height; - dispatchEvent(command); - } - - /** - * Handle notification from presenter about the location of the mouse cursor. - */ - private function handleUpdateCursorEvent(e:CursorEvent):void{ - if (noSlideContentLoaded()) return; - - cursor.x = e.xPercent * this.width; - cursor.y = e.yPercent * this.height; - - if (isCursorOutsideWindow(e)) { - hideCursor() - } else { - showCursor(); - } - } - private function noSlideContentLoaded():Boolean { return slideLoader.content == null } @@ -443,20 +377,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. dispEvent.slideHeight = slideRealHeight; dispatcher.dispatchEvent(dispEvent); } - - private function isCursorOutsideWindow(e:CursorEvent):Boolean { - return (e.xPercent > 1 && e.yPercent > 1) - || (cursor.x > this.width || cursor.x < 1 - || cursor.y > this.height || cursor.y < 1); - } - - private function showCursor():void { - cursor.visible = true; - } - - private function hideCursor():void{ - cursor.visible = false; - } public function acceptOverlayCanvas(overlay:WhiteboardCanvas):void{ whiteboardCanvas = overlay; diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/WhiteboardCanvasDisplayModel.as b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/WhiteboardCanvasDisplayModel.as index 0f137f4bf6a70264f56d4159bf8ce2a96f766e10..f5133121714c5420b3caa062dca121fdc70cd6d7 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/WhiteboardCanvasDisplayModel.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/WhiteboardCanvasDisplayModel.as @@ -23,6 +23,7 @@ package org.bigbluebutton.modules.whiteboard import flash.events.FocusEvent; import flash.events.KeyboardEvent; import flash.ui.Keyboard; + import flash.utils.Dictionary; import org.as3commons.logging.api.ILogger; import org.as3commons.logging.api.getClassLogger; @@ -42,6 +43,7 @@ package org.bigbluebutton.modules.whiteboard import org.bigbluebutton.modules.whiteboard.models.WhiteboardModel; import org.bigbluebutton.modules.whiteboard.views.TextUpdateListener; import org.bigbluebutton.modules.whiteboard.views.WhiteboardCanvas; + import org.bigbluebutton.modules.whiteboard.views.WhiteboardCursor; /** * Class to handle displaying of received annotations from the server. @@ -52,11 +54,13 @@ package org.bigbluebutton.modules.whiteboard private var whiteboardModel:WhiteboardModel; private var wbCanvas:WhiteboardCanvas; private var _annotationsList:Array = new Array(); + private var _cursors:Object = new Object(); private var shapeFactory:ShapeFactory = new ShapeFactory(); private var textUpdateListener:TextUpdateListener = new TextUpdateListener(); private var width:Number; private var height:Number; + private var presenterId:String; public function setDependencies(whiteboardCanvas:WhiteboardCanvas, whiteboardModel:WhiteboardModel):void { wbCanvas = whiteboardCanvas; @@ -209,6 +213,32 @@ package org.bigbluebutton.modules.whiteboard } } } + + public function drawCursor(userId:String, xPercent:Number, yPercent:Number):void { + if (!_cursors.hasOwnProperty(userId)) { + var newCursor:WhiteboardCursor = new WhiteboardCursor(userId, xPercent, yPercent, shapeFactory.parentWidth, shapeFactory.parentHeight, presenterId == userId); + wbCanvas.addCursor(newCursor); + + _cursors[userId] = newCursor; + } else { + (_cursors[userId] as WhiteboardCursor).updatePosition(xPercent, yPercent); + } + } + + public function presenterChange(amIPresenter:Boolean, presenterId:String):void { + this.presenterId = presenterId; + + for(var j:String in _cursors) { + (_cursors[j] as WhiteboardCursor).updatePresenter(j == presenterId); + } + } + + public function userLeft(userId:String):void { + if (_cursors.hasOwnProperty(userId)) { + wbCanvas.removeCursorChild(_cursors[userId]); + delete _cursors[userId]; + } + } public function zoomCanvas(width:Number, height:Number):void{ shapeFactory.setParentDim(width, height); @@ -218,6 +248,10 @@ package org.bigbluebutton.modules.whiteboard for (var i:int = 0; i < this._annotationsList.length; i++){ redrawGraphic(this._annotationsList[i] as GraphicObject, i); } + + for(var j:String in _cursors) { + (_cursors[j] as WhiteboardCursor).updateParentSize(width, height); + } } private function redrawGraphic(gobj:GraphicObject, objIndex:int):void { diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/WhiteboardCanvasModel.as b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/WhiteboardCanvasModel.as index 93bb55d31a4bb2f2d04a792495fb38aeebca70a3..1976c39d88284a37113f896870c93948adfc6838 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/WhiteboardCanvasModel.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/WhiteboardCanvasModel.as @@ -26,6 +26,7 @@ package org.bigbluebutton.modules.whiteboard import org.bigbluebutton.modules.whiteboard.business.shapes.ShapeFactory; import org.bigbluebutton.modules.whiteboard.models.WhiteboardModel; import org.bigbluebutton.modules.whiteboard.views.AnnotationIDGenerator; + import org.bigbluebutton.modules.whiteboard.views.CursorPositionListener; import org.bigbluebutton.modules.whiteboard.views.IDrawListener; import org.bigbluebutton.modules.whiteboard.views.PencilDrawListener; import org.bigbluebutton.modules.whiteboard.views.ShapeDrawListener; @@ -39,32 +40,23 @@ package org.bigbluebutton.modules.whiteboard public class WhiteboardCanvasModel { private var _wbCanvas:WhiteboardCanvas; private var drawListeners:Array = new Array(); + private var cursorPositionListener:CursorPositionListener; private var wbTool:WhiteboardTool = new WhiteboardTool(); private var shapeFactory:ShapeFactory = new ShapeFactory(); private var idGenerator:AnnotationIDGenerator = new AnnotationIDGenerator(); - - /* represents the max number of 'points' enumerated in 'segment' before - sending an update to server. Used to prevent spamming red5 with unnecessary packets */ - private var sendShapeFrequency:uint = 30; - - /* same as above, except a faster interval may be desirable when erasing, for aesthetics */ - private var sendEraserFrequency:uint = 20; - - private var width:Number; - private var height:Number; - public function setDependencies(canvas:WhiteboardCanvas, displayModel:WhiteboardCanvasDisplayModel):void { + public function setDependencies(canvas:WhiteboardCanvas):void { _wbCanvas = canvas; drawListeners.push(new PencilDrawListener(idGenerator, _wbCanvas, shapeFactory)); drawListeners.push(new ShapeDrawListener(idGenerator, _wbCanvas, shapeFactory)); drawListeners.push(new TextDrawListener(idGenerator, _wbCanvas, shapeFactory)); + + cursorPositionListener = new CursorPositionListener(_wbCanvas, shapeFactory); } public function zoomCanvas(width:Number, height:Number):void { - shapeFactory.setParentDim(width, height); - this.width = width; - this.height = height; + shapeFactory.setParentDim(width, height); } public function changeFontStyle(font:String):void { @@ -112,6 +104,14 @@ package org.bigbluebutton.modules.whiteboard public function changeThickness(thickness:uint):void { wbTool.thickness = thickness; } + + public function presenterChange(amIPresenter:Boolean, presenterId:String):void { + cursorPositionListener.presenterChange(amIPresenter); + } + + public function multiUserChange(multiUser:Boolean):void { + cursorPositionListener.multiUserChange(multiUser); + } /** Helper method to test whether this user is the presenter */ private function get isPresenter():Boolean { diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/events/CursorEvent.as b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/events/WhiteboardCursorEvent.as similarity index 71% rename from bigbluebutton-client/src/org/bigbluebutton/modules/present/events/CursorEvent.as rename to bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/events/WhiteboardCursorEvent.as index b783adaf58525990086ae44809818581fca759f0..ac7d6e6154b639fa2b65b10d242b3d08ad9f297f 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/events/CursorEvent.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/events/WhiteboardCursorEvent.as @@ -16,19 +16,18 @@ * with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. * */ -package org.bigbluebutton.modules.present.events -{ +package org.bigbluebutton.modules.whiteboard.events { import flash.events.Event; - public class CursorEvent extends Event - { - public static const UPDATE_CURSOR:String = "UPDATE_CURSOR"; + public class WhiteboardCursorEvent extends Event { + public static const SEND_CURSOR_POSITION:String = "SEND_CURSOR_POSITION"; + public static const RECEIVED_CURSOR_POSITION:String = "RECEIVE_CURSOR_POSITION"; public var xPercent:Number; public var yPercent:Number; + public var userId:String; - public function CursorEvent(type:String) - { + public function WhiteboardCursorEvent(type:String) { super(type, true, false); } diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/maps/WhiteboardEventMap.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/maps/WhiteboardEventMap.mxml index 75f5c2ff5492cb82ac4f9bf8bd99f3e172d57136..c771f555b0213455cdc551bdca7647d7cbf134b9 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/maps/WhiteboardEventMap.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/maps/WhiteboardEventMap.mxml @@ -32,6 +32,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. import org.bigbluebutton.modules.whiteboard.events.StartWhiteboardModuleEvent; import org.bigbluebutton.modules.whiteboard.events.WhiteboardAccessEvent; import org.bigbluebutton.modules.whiteboard.events.WhiteboardButtonEvent; + import org.bigbluebutton.modules.whiteboard.events.WhiteboardCursorEvent; import org.bigbluebutton.modules.whiteboard.events.WhiteboardDrawEvent; import org.bigbluebutton.modules.whiteboard.events.WhiteboardUpdateReceived; import org.bigbluebutton.modules.whiteboard.managers.WhiteboardManager; @@ -80,6 +81,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. <MethodInvoker generator="{WhiteboardService}" method="undoGraphic" arguments="{event}" /> </EventHandlers> + <EventHandlers type="{WhiteboardCursorEvent.SEND_CURSOR_POSITION}" > + <MethodInvoker generator="{WhiteboardService}" method="sendCursorPosition" arguments="{event}" /> + </EventHandlers> + <EventHandlers type="{GetWhiteboardShapesCommand.GET_SHAPES}" > <MethodInvoker generator="{WhiteboardService}" method="getAnnotationHistory" arguments="{event}" /> </EventHandlers> diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/models/WhiteboardModel.as b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/models/WhiteboardModel.as index 140ef52ada2aabc3e08c601de11483f3ef04b386..e9410aa03c8583c672feb7b0e07cd2219eedc089 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/models/WhiteboardModel.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/models/WhiteboardModel.as @@ -31,6 +31,7 @@ package org.bigbluebutton.modules.whiteboard.models import org.bigbluebutton.modules.whiteboard.business.shapes.DrawObject; import org.bigbluebutton.modules.whiteboard.commands.GetWhiteboardShapesCommand; import org.bigbluebutton.modules.whiteboard.events.WhiteboardAccessEvent; + import org.bigbluebutton.modules.whiteboard.events.WhiteboardCursorEvent; import org.bigbluebutton.modules.whiteboard.events.WhiteboardDrawEvent; import org.bigbluebutton.modules.whiteboard.events.WhiteboardUpdateReceived; @@ -153,11 +154,19 @@ package org.bigbluebutton.modules.whiteboard.models var event:WhiteboardAccessEvent = new WhiteboardAccessEvent(WhiteboardAccessEvent.MODIFIED_WHITEBOARD_ACCESS); event.multiUser = multiUser; dispatchEvent(event); - } + } + + public function get multiUser():Boolean { + return _multiUser; + } + + public function updateCursorPosition(userId:String, xPercent:Number, yPercent:Number):void { + var event:WhiteboardCursorEvent = new WhiteboardCursorEvent(WhiteboardCursorEvent.RECEIVED_CURSOR_POSITION); + event.userId = userId; + event.xPercent = xPercent; + event.yPercent = yPercent; + dispatchEvent(event); + } - public function get multiUser():Boolean { - return _multiUser; - } - } } \ No newline at end of file diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/services/MessageReceiver.as b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/services/MessageReceiver.as index 8c4b0a1dd283ff5416eb0393a797346b711c713a..f52c216f4c95ecb976bbd2cf9e55f5766ab7c122 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/services/MessageReceiver.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/services/MessageReceiver.as @@ -49,16 +49,19 @@ package org.bigbluebutton.modules.whiteboard.services break; case "WhiteboardAccessModifiedCommand": handleWhiteboardAccessModifiedCommand(message); - break; + break; case "WhiteboardNewAnnotationCommand": handleNewAnnotationCommand(message); break; case "WhiteboardClearCommand": handleClearCommand(message); - break; + break; case "WhiteboardUndoCommand": handleUndoCommand(message); - break; + break; + case "WhiteboardCursorPositionUpdatedCommand": + handleCursorPositionUpdatedCommand(message); + break; default: // LogUtil.warn("Cannot handle message [" + messageName + "]"); } @@ -124,5 +127,11 @@ package org.bigbluebutton.modules.whiteboard.services } } } + + private function handleCursorPositionUpdatedCommand(message:Object):void { + var map:Object = JSON.parse(message.msg); + + whiteboardModel.updateCursorPosition(map.requesterId, map.xPercent, map.yPercent); + } } } diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/services/MessageSender.as b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/services/MessageSender.as index b187e2f6e9a4f66fe5c7f181240e663e91bc0933..4a711ab430c6f5c0cf89311457a4dabf49662dc7 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/services/MessageSender.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/services/MessageSender.as @@ -143,5 +143,28 @@ package org.bigbluebutton.modules.whiteboard.services e.annotation.annotation ); } + + /** + * Send an event to the server to update the user's cursor position + * @param xPercent + * @param yPercent + * + */ + public function sendCursorPosition(xPercent:Number, yPercent:Number):void { + var message:Object = new Object(); + message["xPercent"] = xPercent; + message["yPercent"] = yPercent; + + var _nc:ConnectionManager = BBB.initConnectionManager(); + _nc.sendMessage("whiteboard.sendCursorPosition", + function(result:String):void { // On successful result + //LOGGER.debug(result); + }, + function(status:String):void { // status - On error occurred + LOGGER.error(status); + }, + message + ); + } } } diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/services/WhiteboardService.as b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/services/WhiteboardService.as index 4e54ef4ae96ca771bb162a861e558b732541e66c..a825d39593261a06c242fa953c925ee7e3499f0c 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/services/WhiteboardService.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/services/WhiteboardService.as @@ -21,8 +21,9 @@ package org.bigbluebutton.modules.whiteboard.services import org.as3commons.logging.api.ILogger; import org.as3commons.logging.api.getClassLogger; import org.bigbluebutton.modules.whiteboard.commands.GetWhiteboardShapesCommand; - import org.bigbluebutton.modules.whiteboard.events.WhiteboardDrawEvent; import org.bigbluebutton.modules.whiteboard.events.WhiteboardAccessEvent; + import org.bigbluebutton.modules.whiteboard.events.WhiteboardCursorEvent; + import org.bigbluebutton.modules.whiteboard.events.WhiteboardDrawEvent; import org.bigbluebutton.modules.whiteboard.models.WhiteboardModel; public class WhiteboardService @@ -66,6 +67,8 @@ package org.bigbluebutton.modules.whiteboard.services sender.sendShape(e); } - + public function sendCursorPosition(e:WhiteboardCursorEvent):void { + sender.sendCursorPosition(e.xPercent, e.yPercent); + } } } \ No newline at end of file diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/CursorPositionListener.as b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/CursorPositionListener.as new file mode 100755 index 0000000000000000000000000000000000000000..7b573f8bdd95cb19681d6bc50b03c3378a49d8eb --- /dev/null +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/CursorPositionListener.as @@ -0,0 +1,87 @@ +package org.bigbluebutton.modules.whiteboard.views { + import flash.events.TimerEvent; + import flash.geom.Point; + import flash.utils.Timer; + + import org.bigbluebutton.modules.whiteboard.business.shapes.ShapeFactory; + + public class CursorPositionListener { + + private var _wbCanvas:WhiteboardCanvas; + private var _shapeFactory:ShapeFactory; + + private var _timer:Timer; + private var _lastXPosition:Number; + private var _lastYPosition:Number; + + private var _amIPresenter:Boolean; + private var _multiUser:Boolean; + + public function CursorPositionListener(wbCanvas:WhiteboardCanvas, shapeFactory:ShapeFactory) { + _wbCanvas = wbCanvas; + _shapeFactory = shapeFactory; + + _lastXPosition = -1; + _lastYPosition = 1; + + _timer = new Timer(100); + _timer.addEventListener(TimerEvent.TIMER, onTimerInterval); + } + + public function presenterChange(amIPresenter:Boolean):void { + _amIPresenter = amIPresenter; + verifyTimerState(); + } + + public function multiUserChange(multiUser:Boolean):void { + _multiUser = multiUser; + verifyTimerState(); + } + + private function verifyTimerState():void { + if (_amIPresenter || _multiUser) { + startTimer(); + } else { + stopTimer(); + } + } + + private function startTimer():void { + if (!_timer.running) { + _timer.start(); + } + } + + private function stopTimer():void { + if (_timer.running) { + _timer.stop(); + checkMousePosition(-1, -1) + } + } + + private function onTimerInterval(e:TimerEvent):void { + checkMousePosition(_wbCanvas.mouseX, _wbCanvas.mouseY); + } + + private function checkMousePosition(x:Number, y:Number):void { + // check if mouse position is within bounds + if (isXYOutsideCanvas(x, y)){ + x = -1; + y = -1; + } + + if (x != _lastXPosition || y != _lastYPosition) { + _lastXPosition = x; + _lastYPosition = y; + + var np:Point = _shapeFactory.normalizePoint(x, y); + + _wbCanvas.sendCursorPositionToServer(np.x, np.y); + } + } + + private function isXYOutsideCanvas(x:Number, y:Number):Boolean { + return (x < 0 || y < 0 || x > _wbCanvas.width || y > _wbCanvas.height); + } + } +} \ No newline at end of file diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/ShapeDrawListener.as b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/ShapeDrawListener.as index 50463b10725dcddeced9e1de1f2ec1b19ae8761f..aa6a6fd1f00dd19ab46d67151bea5ff7653ba56b 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/ShapeDrawListener.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/ShapeDrawListener.as @@ -84,10 +84,12 @@ package org.bigbluebutton.modules.whiteboard.views //normalize points as we get them to avoid shape drift var np:Point = _shapeFactory.normalizePoint(mouseX, mouseY); + var statusToSend:String = (_segment.length == 2 ? AnnotationStatus.DRAW_START : AnnotationStatus.DRAW_UPDATE); + _segment[2] = np.x; _segment[3] = np.y; - sendShapeToServer(AnnotationStatus.DRAW_UPDATE, tool); + sendShapeToServer(statusToSend, tool); } } } @@ -102,14 +104,20 @@ package org.bigbluebutton.modules.whiteboard.views */ _isDrawing = false; + //normalize points as we get them to avoid shape drift + var np:Point = _shapeFactory.normalizePoint(mouseX, mouseY); + + _segment[2] = np.x; + _segment[3] = np.y; + sendShapeToServer(AnnotationStatus.DRAW_END, tool); } /* (_isDrawing) */ } } private function sendShapeToServer(status:String, tool:WhiteboardTool):void { - if (_segment.length == 0) { -// LogUtil.debug("SEGMENT LENGTH = 0"); + if (_segment.length > 2) { + // LogUtil.debug("SEGMENT too short"); return; } diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/WhiteboardCanvas.as b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/WhiteboardCanvas.as index 75de21a24634bea34adbcfd2322833b191973acd..8697eeb53191808e616e4808af8e7d2af6417b59 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/WhiteboardCanvas.as +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/WhiteboardCanvas.as @@ -25,12 +25,15 @@ package org.bigbluebutton.modules.whiteboard.views { import flash.display.DisplayObject; import flash.events.Event; import flash.events.MouseEvent; + import flash.geom.Point; import mx.containers.Canvas; import mx.managers.CursorManager; import org.bigbluebutton.common.Images; + import org.bigbluebutton.core.UsersUtil; import org.bigbluebutton.main.events.MadePresenterEvent; + import org.bigbluebutton.main.events.UserLeftEvent; import org.bigbluebutton.modules.whiteboard.WhiteboardCanvasDisplayModel; import org.bigbluebutton.modules.whiteboard.WhiteboardCanvasModel; import org.bigbluebutton.modules.whiteboard.business.shapes.DrawObject; @@ -39,6 +42,7 @@ package org.bigbluebutton.modules.whiteboard.views { import org.bigbluebutton.modules.whiteboard.commands.GetWhiteboardShapesCommand; import org.bigbluebutton.modules.whiteboard.events.WhiteboardAccessEvent; import org.bigbluebutton.modules.whiteboard.events.WhiteboardButtonEvent; + import org.bigbluebutton.modules.whiteboard.events.WhiteboardCursorEvent; import org.bigbluebutton.modules.whiteboard.events.WhiteboardDrawEvent; import org.bigbluebutton.modules.whiteboard.events.WhiteboardUpdateReceived; import org.bigbluebutton.modules.whiteboard.models.Annotation; @@ -52,8 +56,9 @@ package org.bigbluebutton.modules.whiteboard.views { private var textToolbar:WhiteboardTextToolbar; private var graphicObjectHolder:Canvas = new Canvas(); - private var images:Images = new Images(); + private var cursorObjectHolder:Canvas = new Canvas(); + private var images:Images = new Images(); [Bindable] private var pencil_icon:Class = images.pencil_icon; [Bindable] private var rectangle_icon:Class = images.square_icon; [Bindable] private var triangle_icon:Class = images.triangle_icon; @@ -64,12 +69,14 @@ package org.bigbluebutton.modules.whiteboard.views { private var whiteboardEnabled:Boolean = false; private var currentWhiteboardId:String; + private var dispatcher:Dispatcher = new Dispatcher(); + public function WhiteboardCanvas(wbModel:WhiteboardModel):void { canvasModel = new WhiteboardCanvasModel(); canvasDisplayModel = new WhiteboardCanvasDisplayModel(); //set up model cross dependencies - canvasModel.setDependencies(this, canvasDisplayModel); + canvasModel.setDependencies(this); canvasDisplayModel.setDependencies(this, wbModel); whiteboardToolbar = new WhiteboardToolbar(); @@ -87,17 +94,36 @@ package org.bigbluebutton.modules.whiteboard.views { graphicObjectHolder.clipContent = true; graphicObjectHolder.tabFocusEnabled = false; - addEventListener(MouseEvent.MOUSE_OVER, onMouseOver); - addEventListener(MouseEvent.MOUSE_OUT, onMouseOut); + //create the cursor display container + this.addChild(cursorObjectHolder); + cursorObjectHolder.x = 0; + cursorObjectHolder.y = 0; + cursorObjectHolder.clipContent = true; + cursorObjectHolder.tabFocusEnabled = false; wbModel.addEventListener(WhiteboardUpdateReceived.NEW_ANNOTATION, onNewAnnotationEvent); wbModel.addEventListener(WhiteboardUpdateReceived.RECEIVED_ANNOTATION_HISTORY, onReceivedAnnotationsHistory); wbModel.addEventListener(WhiteboardUpdateReceived.CLEAR_ANNOTATIONS, onClearAnnotations); wbModel.addEventListener(WhiteboardUpdateReceived.UNDO_ANNOTATION, onUndoAnnotation); wbModel.addEventListener(WhiteboardAccessEvent.MODIFIED_WHITEBOARD_ACCESS, onModifiedAccess); + wbModel.addEventListener(WhiteboardCursorEvent.RECEIVED_CURSOR_POSITION, onReceivedCursorPosition); whiteboardToolbar.addEventListener(WhiteboardButtonEvent.ENABLE_WHITEBOARD, onEnableWhiteboardEvent); whiteboardToolbar.addEventListener(WhiteboardButtonEvent.DISABLE_WHITEBOARD, onDisableWhiteboardEvent); + + var stpl:Listener = new Listener(); + stpl.type = MadePresenterEvent.SWITCH_TO_PRESENTER_MODE; + stpl.method = onSwitchToPresenterEvent; + + var stvl:Listener = new Listener(); + stvl.type = MadePresenterEvent.SWITCH_TO_VIEWER_MODE; + stvl.method = onSwitchToViewerEvent; + + presenterChange(UsersUtil.amIPresenter(), UsersUtil.getPresenterUserID()); + + var ull:Listener = new Listener(); + ull.type = UserLeftEvent.LEFT; + ull.method = onUserLeftEvent; } public function attachToReceivingObject(ro:IWhiteboardReceiver):void { @@ -107,14 +133,19 @@ package org.bigbluebutton.modules.whiteboard.views { private function registerForMouseEvents():void { addEventListener(MouseEvent.MOUSE_DOWN, doMouseDown); + addEventListener(MouseEvent.MOUSE_OVER, onMouseOver); + addEventListener(MouseEvent.MOUSE_OUT, onMouseOut); } private function unregisterForMouseEvents():void { removeEventListener(MouseEvent.MOUSE_DOWN, doMouseDown); + removeEventListener(MouseEvent.MOUSE_OVER, onMouseOver); + removeEventListener(MouseEvent.MOUSE_OUT, onMouseOut); } private function doMouseUp(event:MouseEvent):void { - canvasModel.doMouseUp(Math.min(Math.max(parent.mouseX, 0), parent.width) - this.x, Math.min(Math.max(parent.mouseY, 0), parent.height) - this.y); + var mousePoint:Point = getMouseXY(); + canvasModel.doMouseUp(mousePoint.x, mousePoint.y); stage.removeEventListener(MouseEvent.MOUSE_UP, doMouseUp); stage.removeEventListener(MouseEvent.MOUSE_MOVE, doMouseMove); @@ -130,7 +161,8 @@ package org.bigbluebutton.modules.whiteboard.views { } private function doMouseMove(event:MouseEvent):void { - canvasModel.doMouseMove(Math.min(Math.max(parent.mouseX, 0), parent.width-1) - this.x, Math.min(Math.max(parent.mouseY, 0), parent.height-1) - this.y); + var mousePoint:Point = getMouseXY(); + canvasModel.doMouseMove(mousePoint.x, mousePoint.y); } public function changeColor(e:Event):void { @@ -145,24 +177,28 @@ package org.bigbluebutton.modules.whiteboard.views { // LogUtil.debug("DISPATCHING SEND sendGraphicToServer [" + type + "]"); var event:WhiteboardDrawEvent = new WhiteboardDrawEvent(WhiteboardDrawEvent.SEND_SHAPE); event.annotation = gobj; - var dispatcher:Dispatcher = new Dispatcher(); - dispatcher.dispatchEvent(event); + dispatcher.dispatchEvent(event); } public function sendUndoToServer():void { var event:WhiteboardDrawEvent = new WhiteboardDrawEvent(WhiteboardDrawEvent.UNDO); event.wbId = currentWhiteboardId; - var dispatcher:Dispatcher = new Dispatcher(); dispatcher.dispatchEvent(event); } public function sendClearToServer():void { var event:WhiteboardDrawEvent = new WhiteboardDrawEvent(WhiteboardDrawEvent.CLEAR); event.wbId = currentWhiteboardId; - var dispatcher:Dispatcher = new Dispatcher(); dispatcher.dispatchEvent(event); } + public function sendCursorPositionToServer(x:Number, y:Number):void { + var event:WhiteboardCursorEvent = new WhiteboardCursorEvent(WhiteboardCursorEvent.SEND_CURSOR_POSITION); + event.xPercent = x; + event.yPercent = y; + dispatcher.dispatchEvent(event); + } + public function setGraphicType(type:String):void { if (canvasModel == null) return; canvasModel.setGraphicType(type); @@ -214,16 +250,21 @@ package org.bigbluebutton.modules.whiteboard.views { CursorManager.removeCursor(CursorManager.currentCursorID); } - public function doesContain(child:DisplayObject):Boolean { - return this.graphicObjectHolder.rawChildren.contains(child); + private function getMouseXY():Point { + return new Point(Math.min(Math.max(parent.mouseX, 0), parent.width-1) - this.x, Math.min(Math.max(parent.mouseY, 0), parent.height-1) - this.y); } - public function getMouseXY():Array { - return [Math.min(Math.max(parent.mouseX, 0), parent.width-2) - this.x, Math.min(Math.max(parent.mouseY, 0), parent.height-2) - this.y]; + private function presenterChange(amIPresenter:Boolean, presenterId:String):void { + canvasModel.presenterChange(amIPresenter, presenterId); + canvasDisplayModel.presenterChange(amIPresenter, presenterId); + } + + public function doesContainGraphic(child:DisplayObject):Boolean { + return this.graphicObjectHolder.rawChildren.contains(child); } public function removeGraphic(child:DisplayObject):void { - if (doesContain(child)) this.graphicObjectHolder.rawChildren.removeChild(child); + if (doesContainGraphic(child)) this.graphicObjectHolder.rawChildren.removeChild(child); else trace("Does not contain"); } @@ -231,6 +272,18 @@ package org.bigbluebutton.modules.whiteboard.views { this.graphicObjectHolder.rawChildren.addChild(child); } + private function doesContainCursor(cursor:DisplayObject):Boolean { + return this.cursorObjectHolder.rawChildren.contains(cursor); + } + + public function addCursor(cursor:DisplayObject):void { + this.cursorObjectHolder.rawChildren.addChild(cursor); + } + + public function removeCursorChild(cursor:DisplayObject):void { + if (doesContainCursor(cursor)) this.cursorObjectHolder.rawChildren.removeChild(cursor); + } + public function textToolbarSyncProxy(tobj:TextObject):void { textToolbar.syncPropsWith(tobj); } @@ -243,6 +296,8 @@ package org.bigbluebutton.modules.whiteboard.views { public function zoomCanvas(width:Number, height:Number):void { graphicObjectHolder.width = width; graphicObjectHolder.height = height; + cursorObjectHolder.width = width; + cursorObjectHolder.height = height; this.width = width; this.height = height; canvasDisplayModel.zoomCanvas(width, height); @@ -282,9 +337,14 @@ package org.bigbluebutton.modules.whiteboard.views { private function onModifiedAccess(e:WhiteboardAccessEvent):void { //if (e.whiteboardId == currentWhiteboardId) { whiteboardToolbar.whiteboardAccessModified(e.multiUser); + canvasModel.multiUserChange(e.multiUser); //} } + private function onReceivedCursorPosition(e:WhiteboardCursorEvent):void { + canvasDisplayModel.drawCursor(e.userId, e.xPercent, e.yPercent); + } + private function onEnableWhiteboardEvent(e:WhiteboardButtonEvent):void { e.stopPropagation(); @@ -298,5 +358,17 @@ package org.bigbluebutton.modules.whiteboard.views { this.whiteboardEnabled = false; setWhiteboardInteractable(); } + + private function onSwitchToPresenterEvent(e:MadePresenterEvent):void { + presenterChange(true, e.userID); + } + + private function onSwitchToViewerEvent(e:MadePresenterEvent):void { + presenterChange(false, e.userID); + } + + private function onUserLeftEvent(e:UserLeftEvent):void { + canvasDisplayModel.userLeft(e.userID); + } } } diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/WhiteboardCursor.as b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/WhiteboardCursor.as new file mode 100755 index 0000000000000000000000000000000000000000..ae87c19039c2b9ec8551d71bf34d1beb154621ab --- /dev/null +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/WhiteboardCursor.as @@ -0,0 +1,102 @@ +/** + * BigBlueButton open source conferencing system - http://www.bigbluebutton.org/ + * + * Copyright (c) 2017 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.views { + import flash.display.Shape; + + public class WhiteboardCursor extends Shape { + private static const PRESENTER_COLOR:uint = 0xFF0000; + private static const OTHER_COLOR:uint = 0x00FF00; + + private var _userId:String; + private var _origX:Number; + private var _origY:Number; + private var _parentWidth:Number; + private var _parentHeight:Number; + private var _isPresenter:Boolean; + + public function WhiteboardCursor(userId:String, x:Number, y:Number, parentWidth:Number, parentHeight:Number, isPresenter:Boolean) { + _userId = userId; + _origX = x; + _origY = y; + _parentWidth = parentWidth; + _parentHeight = parentHeight; + _isPresenter = isPresenter; + + drawCursor(); + setPosition(); + } + + public function updatePosition(x:Number, y:Number):void { + _origX = x; + _origY = y; + + setPosition(); + } + + public function updateParentSize(parentWidth:Number, parentHeight:Number):void { + _parentWidth = parentWidth; + _parentHeight = parentHeight; + + setPosition(); + } + + public function updatePresenter(isPresenter:Boolean):void { + _isPresenter = isPresenter; + + drawCursor(); + } + + private function setPosition():void { + x = denormalize(_origX, _parentWidth); + y = denormalize(_origY, _parentHeight); + + if (isCursorOutsideWindow()) { + hideCursor() + } else { + showCursor(); + } + } + + private function showCursor():void { + visible = true; + } + + private function hideCursor():void{ + visible = false; + } + + private function isCursorOutsideWindow():Boolean { + return (_origX > 100 || _origX < 0 || + _origY > 100 || _origY < 0); + } + + private function drawCursor():void { + var cursorColor:uint = (_isPresenter ? PRESENTER_COLOR : OTHER_COLOR); + + graphics.clear(); + graphics.lineStyle(6, cursorColor, 0.6); + graphics.drawCircle(0,0,2.5); + } + + private function denormalize(val:Number, side:Number):Number { + return (val*side)/100.0; + } + } +} \ No newline at end of file diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/WhiteboardTextToolbar.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/WhiteboardTextToolbar.mxml index 08ddea6168192a29880dfddb85eae73c6c496dd4..387b584ce2aaabc2af7260e90ed8ab2552285729 100755 --- a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/WhiteboardTextToolbar.mxml +++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/WhiteboardTextToolbar.mxml @@ -93,11 +93,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. * @param e The event * */ - protected function setTextColor(e:Event):void{ - enableTextToolbar(); - this.textColor = e.target.selectedColor; - currentlySelectedTextObject.applyNewFormat(textColor, textSize); - canvas.stage.focus = currentlySelectedTextObject; + protected function onFontColorChange(e:Event):void{ + setTextColor(e.target.selectedColor); } /** @@ -110,6 +107,12 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. this.textSize = size; currentlySelectedTextObject.applyNewFormat(textColor, textSize); } + + protected function setTextColor(color:uint):void { + enableTextToolbar(); + this.textColor = color; + currentlySelectedTextObject.applyNewFormat(textColor, textSize); + } private function viewerMode(e:MadePresenterEvent):void{ disableTextToolbar(); @@ -134,9 +137,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. if(tobj != null) { enableTextToolbar(); repositionToolbar(); - this.textColor = ctextpik.selectedColor = tobj.textColor; - this.textSizeMenu.selectedItem = String(tobj.fontSize); - this.textSize = tobj.fontSize; + setTextColor(ctextpik.selectedColor); + setTextSize(Number(textSizeMenu.selectedItem)); } else { disableTextToolbar(); } @@ -170,26 +172,12 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>. public function adjustForZoom(x:Number, y:Number):void { repositionToolbar(); } - - /* used to check whether or not the TextToolbar and its children have focus when - checking whether or not it should be made visible=false. see handleObjDeselected(). - */ - private function containsFocus(obj:DisplayObjectContainer):Boolean { - if(obj.stage.focus == obj) return true; - - for (var i:int = 0; i < obj.numChildren; i++) { - var currObj:DisplayObject = obj.getChildAt(i); - if(obj.stage.focus == currObj) return true; - } - - return false; - } ]]> </mx:Script> - <mx:ColorPicker width="20" height="20" change="setTextColor(event)" id="ctextpik" selectedColor="0x000000" + <mx:ColorPicker width="20" height="20" change="onFontColorChange(event)" id="ctextpik" selectedColor="0x000000" toolTip="{ResourceUtil.getInstance().getString('ltbcustom.bbb.highlighter.texttoolbar.textColorPicker')}"/> - <views:CustomComboBox id="textSizeMenu" dataProvider="{fontSizes}" change="onFontSizeChange()" rowCount="8" + <views:CustomComboBox id="textSizeMenu" dataProvider="{fontSizes}" selectedItem="18" change="onFontSizeChange()" rowCount="8" toolTip="{ResourceUtil.getInstance().getString('ltbcustom.bbb.highlighter.texttoolbar.textSizeMenu')}" /> </mx:HBox>