From 3d8d4bda86928e9ae923a63840be064838ffa9ea Mon Sep 17 00:00:00 2001 From: Ghaz Triki Date: Sun, 3 Apr 2016 10:36:50 +0100 Subject: [PATCH] Implemented desktop sharing display to web-client. --- .../air/deskshare/views/DeskshareConfig.as | 2 + .../air/deskshare/views/DeskshareView.as | 2 +- .../deskshare/views/DeskshareViewMediator.as | 44 +--- .../air/deskshare/views/IDeskshareViewAir.as | 13 + .../lib/deskshare/views/DeskshareMediator.as | 77 ++++++ .../lib}/deskshare/views/IDeskshareView.as | 3 +- clients/flash/web-client/src/Main.mxml | 5 +- .../web-client/src/assets/images/cursor.png | Bin 0 -> 3240 bytes .../web/deskshare/views/DeskshareConfig.as | 52 ++++ .../web/deskshare/views/DeskshareVideoView.as | 142 +++++++++++ .../web/deskshare/views/DeskshareWindow.as | 225 ++++++++++++++++++ .../views/DeskshareWindowMediator.as | 19 ++ 12 files changed, 546 insertions(+), 38 deletions(-) create mode 100644 clients/flash/air-client/src/org/bigbluebutton/air/deskshare/views/IDeskshareViewAir.as create mode 100644 clients/flash/common-library/src/org/bigbluebutton/lib/deskshare/views/DeskshareMediator.as rename clients/flash/{air-client/src/org/bigbluebutton/air => common-library/src/org/bigbluebutton/lib}/deskshare/views/IDeskshareView.as (81%) create mode 100644 clients/flash/web-client/src/assets/images/cursor.png create mode 100644 clients/flash/web-client/src/org/bigbluebutton/web/deskshare/views/DeskshareConfig.as create mode 100644 clients/flash/web-client/src/org/bigbluebutton/web/deskshare/views/DeskshareVideoView.as create mode 100644 clients/flash/web-client/src/org/bigbluebutton/web/deskshare/views/DeskshareWindow.as create mode 100644 clients/flash/web-client/src/org/bigbluebutton/web/deskshare/views/DeskshareWindowMediator.as diff --git a/clients/flash/air-client/src/org/bigbluebutton/air/deskshare/views/DeskshareConfig.as b/clients/flash/air-client/src/org/bigbluebutton/air/deskshare/views/DeskshareConfig.as index 6ea803f82f..ff43e78234 100644 --- a/clients/flash/air-client/src/org/bigbluebutton/air/deskshare/views/DeskshareConfig.as +++ b/clients/flash/air-client/src/org/bigbluebutton/air/deskshare/views/DeskshareConfig.as @@ -1,5 +1,7 @@ package org.bigbluebutton.air.deskshare.views { + import org.bigbluebutton.lib.deskshare.views.IDeskshareView; + import robotlegs.bender.extensions.mediatorMap.api.IMediatorMap; import robotlegs.bender.extensions.signalCommandMap.api.ISignalCommandMap; import robotlegs.bender.framework.api.IConfig; diff --git a/clients/flash/air-client/src/org/bigbluebutton/air/deskshare/views/DeskshareView.as b/clients/flash/air-client/src/org/bigbluebutton/air/deskshare/views/DeskshareView.as index aab465fb38..8aa69d95c8 100644 --- a/clients/flash/air-client/src/org/bigbluebutton/air/deskshare/views/DeskshareView.as +++ b/clients/flash/air-client/src/org/bigbluebutton/air/deskshare/views/DeskshareView.as @@ -8,7 +8,7 @@ package org.bigbluebutton.air.deskshare.views { import spark.components.Group; import spark.components.Label; - public class DeskshareView extends DeskshareViewBase implements IDeskshareView { + public class DeskshareView extends DeskshareViewBase implements IDeskshareViewAir { private var deskshareVideoView:DeskshareVideoView; /** diff --git a/clients/flash/air-client/src/org/bigbluebutton/air/deskshare/views/DeskshareViewMediator.as b/clients/flash/air-client/src/org/bigbluebutton/air/deskshare/views/DeskshareViewMediator.as index 5a3433af30..2961be18d1 100644 --- a/clients/flash/air-client/src/org/bigbluebutton/air/deskshare/views/DeskshareViewMediator.as +++ b/clients/flash/air-client/src/org/bigbluebutton/air/deskshare/views/DeskshareViewMediator.as @@ -8,41 +8,32 @@ package org.bigbluebutton.air.deskshare.views { import org.bigbluebutton.air.common.views.PagesENUM; import org.bigbluebutton.air.main.models.IUserUISession; + import org.bigbluebutton.lib.deskshare.views.DeskshareMediator; import org.bigbluebutton.lib.main.models.IConferenceParameters; import org.bigbluebutton.lib.main.models.IUserSession; import robotlegs.bender.bundles.mvcs.Mediator; - public class DeskshareViewMediator extends Mediator { - - [Inject] - public var view:IDeskshareView; - - [Inject] - public var userSession:IUserSession; + public class DeskshareViewMediator extends DeskshareMediator { [Inject] public var userUISession:IUserUISession; - [Inject] - public var params:IConferenceParameters; - public override function initialize():void { showDeskshare(userSession.deskshareConnection.streamWidth, userSession.deskshareConnection.streamHeight); - userSession.deskshareConnection.isStreamingSignal.add(onDeskshareStreamChange); FlexGlobals.topLevelApplication.stage.addEventListener(ResizeEvent.RESIZE, stageOrientationChangingHandler); - userSession.deskshareConnection.mouseLocationChangedSignal.add(onMouseLocationChanged); FlexGlobals.topLevelApplication.pageName.text = ResourceManager.getInstance().getString('resources', 'deskshare.title'); FlexGlobals.topLevelApplication.backBtn.visible = false; FlexGlobals.topLevelApplication.profileBtn.visible = true; + super.initialize(); } /** * On Deskshare View initialization - start the video stream */ - private function showDeskshare(width:Number, height:Number):void { - view.noDeskshareMessage.visible = view.noDeskshareMessage.includeInLayout = false; - view.startStream(userSession.deskshareConnection.connection, null, params.room, null, userSession.deskshareConnection.streamWidth, userSession.deskshareConnection.streamHeight); + override protected function showDeskshare(width:Number, height:Number):void { + (view as DeskshareView).noDeskshareMessage.visible = (view as DeskshareView).noDeskshareMessage.includeInLayout = false; + super.showDeskshare(width, height); } private function stageOrientationChangingHandler(e:Event):void { @@ -57,22 +48,9 @@ package org.bigbluebutton.air.deskshare.views { * If desktop sharing stream dropped - show notification message, remove video * else show the desktop sharing stream and cursor */ - public function onDeskshareStreamChange(isDeskshareStreaming:Boolean):void { - view.noDeskshareMessage.visible = view.noDeskshareMessage.includeInLayout = !isDeskshareStreaming; - if (!isDeskshareStreaming) { - view.stopStream(); - userSession.deskshareConnection.mouseLocationChangedSignal.remove(onMouseLocationChanged); - } else { - userSession.deskshareConnection.mouseLocationChangedSignal.add(onMouseLocationChanged); - showDeskshare(userSession.deskshareConnection.streamWidth, userSession.deskshareConnection.streamHeight); - } - } - - /** - * Notify view that mouse location was changed - */ - public function onMouseLocationChanged(x:Number, y:Number):void { - view.changeMouseLocation(x, y); + override public function onDeskshareStreamChange(isDeskshareStreaming:Boolean):void { + (view as DeskshareView).noDeskshareMessage.visible = (view as DeskshareView).noDeskshareMessage.includeInLayout = !isDeskshareStreaming; + super.onDeskshareStreamChange(isDeskshareStreaming); } /** @@ -80,10 +58,8 @@ package org.bigbluebutton.air.deskshare.views { * Stop desktop sharing stream */ override public function destroy():void { - userSession.deskshareConnection.isStreamingSignal.remove(onDeskshareStreamChange); FlexGlobals.topLevelApplication.stage.removeEventListener(ResizeEvent.RESIZE, stageOrientationChangingHandler); - userSession.deskshareConnection.mouseLocationChangedSignal.remove(onMouseLocationChanged); - view.stopStream(); + super.destroy(); } } } diff --git a/clients/flash/air-client/src/org/bigbluebutton/air/deskshare/views/IDeskshareViewAir.as b/clients/flash/air-client/src/org/bigbluebutton/air/deskshare/views/IDeskshareViewAir.as new file mode 100644 index 0000000000..eb60accb4f --- /dev/null +++ b/clients/flash/air-client/src/org/bigbluebutton/air/deskshare/views/IDeskshareViewAir.as @@ -0,0 +1,13 @@ +package org.bigbluebutton.air.deskshare.views { + + import flash.net.NetConnection; + + import org.bigbluebutton.lib.deskshare.views.IDeskshareView; + + import spark.components.Group; + import spark.components.Label; + + public interface IDeskshareViewAir extends IDeskshareView { + function get noDeskshareMessage():Label; + } +} diff --git a/clients/flash/common-library/src/org/bigbluebutton/lib/deskshare/views/DeskshareMediator.as b/clients/flash/common-library/src/org/bigbluebutton/lib/deskshare/views/DeskshareMediator.as new file mode 100644 index 0000000000..7f672ce44c --- /dev/null +++ b/clients/flash/common-library/src/org/bigbluebutton/lib/deskshare/views/DeskshareMediator.as @@ -0,0 +1,77 @@ +package org.bigbluebutton.lib.deskshare.views { + + import flash.events.Event; + + import mx.core.FlexGlobals; + import mx.events.ResizeEvent; + import mx.resources.ResourceManager; + + import org.bigbluebutton.lib.deskshare.views.IDeskshareView; + import org.bigbluebutton.lib.main.models.IConferenceParameters; + import org.bigbluebutton.lib.main.models.IUserSession; + + import robotlegs.bender.bundles.mvcs.Mediator; + + public class DeskshareMediator extends Mediator { + + [Inject] + public var view:IDeskshareView; + + [Inject] + public var userSession:IUserSession; + + [Inject] + public var params:IConferenceParameters; + + public override function initialize():void { + if (userSession.deskshareConnection) { + assignedDeskshare(); + } else { + userSession.assignedDeskshareSignal.add(assignedDeskshare) + } + } + + private function assignedDeskshare():void { + userSession.deskshareConnection.isStreamingSignal.add(onDeskshareStreamChange); + userSession.deskshareConnection.mouseLocationChangedSignal.add(onMouseLocationChanged); + } + + /** + * On Deskshare View initialization - start the video stream + */ + protected function showDeskshare(width:Number, height:Number):void { + view.startStream(userSession.deskshareConnection.connection, null, params.room, null, userSession.deskshareConnection.streamWidth, userSession.deskshareConnection.streamHeight); + } + + /** + * If desktop sharing stream dropped - show notification message, remove video + * else show the desktop sharing stream and cursor + */ + public function onDeskshareStreamChange(isDeskshareStreaming:Boolean):void { + if (!isDeskshareStreaming) { + view.stopStream(); + userSession.deskshareConnection.mouseLocationChangedSignal.remove(onMouseLocationChanged); + } else { + userSession.deskshareConnection.mouseLocationChangedSignal.add(onMouseLocationChanged); + showDeskshare(userSession.deskshareConnection.streamWidth, userSession.deskshareConnection.streamHeight); + } + } + + /** + * Notify view that mouse location was changed + */ + public function onMouseLocationChanged(x:Number, y:Number):void { + view.changeMouseLocation(x, y); + } + + /** + * Unsibscribe from signal listeners + * Stop desktop sharing stream + */ + override public function destroy():void { + userSession.deskshareConnection.isStreamingSignal.remove(onDeskshareStreamChange); + userSession.deskshareConnection.mouseLocationChangedSignal.remove(onMouseLocationChanged); + view.stopStream(); + } + } +} diff --git a/clients/flash/air-client/src/org/bigbluebutton/air/deskshare/views/IDeskshareView.as b/clients/flash/common-library/src/org/bigbluebutton/lib/deskshare/views/IDeskshareView.as similarity index 81% rename from clients/flash/air-client/src/org/bigbluebutton/air/deskshare/views/IDeskshareView.as rename to clients/flash/common-library/src/org/bigbluebutton/lib/deskshare/views/IDeskshareView.as index f2ac399a13..def7a4cf05 100644 --- a/clients/flash/air-client/src/org/bigbluebutton/air/deskshare/views/IDeskshareView.as +++ b/clients/flash/common-library/src/org/bigbluebutton/lib/deskshare/views/IDeskshareView.as @@ -1,4 +1,4 @@ -package org.bigbluebutton.air.deskshare.views { +package org.bigbluebutton.lib.deskshare.views { import flash.net.NetConnection; @@ -9,7 +9,6 @@ package org.bigbluebutton.air.deskshare.views { function get deskshareGroup():Group; function stopStream():void; function startStream(connection:NetConnection, name:String, streamName:String, userID:String, width:Number, height:Number):void; - function get noDeskshareMessage():Label; function changeMouseLocation(x:Number, y:Number):void; } } diff --git a/clients/flash/web-client/src/Main.mxml b/clients/flash/web-client/src/Main.mxml index 08a538825c..49d9f28b28 100644 --- a/clients/flash/web-client/src/Main.mxml +++ b/clients/flash/web-client/src/Main.mxml @@ -30,6 +30,8 @@ import org.bigbluebutton.web.AppConfig; import org.bigbluebutton.web.chat.ChatConfig; import org.bigbluebutton.web.chat.views.ChatWindow; + import org.bigbluebutton.web.deskshare.views.DeskshareConfig; + import org.bigbluebutton.web.deskshare.views.DeskshareWindow; import org.bigbluebutton.web.main.MainConfig; import org.bigbluebutton.web.main.views.LoadingScreen; import org.bigbluebutton.web.presentation.views.PresentationConfig; @@ -108,7 +110,7 @@ private function setupContext():void { context = new Context().install(MVCSBundle, SignalCommandMapExtension).configure(AppConfig) - .configure(MainConfig).configure(ChatConfig).configure(UserConfig).configure(VideoConfig).configure(MainToolbarConfig).configure(CameraDisplaySettingsConfig).configure(ToolbarPopupButtonConfig).configure(ToolbarButtonConfig).configure(AudioSelectionWindowConfig).configure(ShortcutHelpConfig).configure(PresentationConfig).configure(WhiteboardConfig) + .configure(MainConfig).configure(ChatConfig).configure(UserConfig).configure(VideoConfig).configure(MainToolbarConfig).configure(CameraDisplaySettingsConfig).configure(ToolbarPopupButtonConfig).configure(ToolbarButtonConfig).configure(AudioSelectionWindowConfig).configure(ShortcutHelpConfig).configure(PresentationConfig).configure(WhiteboardConfig).configure(DeskshareConfig) .configure(new ContextView(this)); @@ -151,6 +153,7 @@ mainCanvas.windowManager.add(new UserWindow()); mainCanvas.windowManager.add(new VideoWindow()); mainCanvas.windowManager.add(new PresentationWindow()); + mainCanvas.windowManager.add(new DeskshareWindow()); } private function onFooterLinkClicked(e:TextEvent):void { diff --git a/clients/flash/web-client/src/assets/images/cursor.png b/clients/flash/web-client/src/assets/images/cursor.png new file mode 100644 index 0000000000000000000000000000000000000000..b4e47d8ecae0040591910381301886b0995daf90 GIT binary patch literal 3240 zcmd5;U2NM_6gC?S=r*y5i7_77#RUf168|MlVkK?UIB7FTsj^fngNeHKZDQ)!nSGO{ z6=(%9iM=BBvImNwPea-R4~S`#HefG+1dkgC2`UXHh6E3ViA~+gv7Ka28(`8TM3tts z?>XQ1ou7N|JvuTxxVh_*E{dWyXNROb{N3XG-nRk1cP_2S6t!_wD~yq`+_R!$mV>ft zPT*j@T!D3piuctkvNDAUn!rWPNYKBXK1(A_P0;(pIW|{G;gU8qYvFyf!v$q_N{Oj- zUvF2uE&@Oq6B*UZx?zj;1nuIA@W1n#p^1;It4l zts=w4Vljs08J-V-MZlghh+GdCcDDoJVMy3kEUiK`(?AZUJYiNzf~H{|HNYz+lbCkN zth6W$yOA}>AJbZ9xFE~;9kUgpgdi_Ym@Qx6Qe1I1Q5nC5>+WW+4FvpKzHPj9xw3{4 zjB~kvHZPak;BAtwLA;IJbtJG0GZoC_v29i@1*dD+Al?2jRi))$sam=loT@Nb$7L|J zK_u5k2_o}au|({aTSr>UwedV#ITn*uQZg-j#I!Z1X3$L*L6T-+g_xGB>XvQF!m0+r zIUP|1DLS5%6&!@3tumBkg25QRq0f1iV*@M)AJ@uXA~9 zgfp3pkcx7dh?M5ISUNcnW2Fcii6%3#P|^o;hwfR!CbFU6Cc6gg;dGP_rG!W_l8HL( zQJzbsLj!y&k`{VEgu9VYye&y?CQU14!fsPY)|fQi&D3tAB~>e>k(mTNV#&oScEdnx zZAKJRg)DMCY$IbGY*NGmoYX8X>BfP9m;T9O#o^< z@aYnUjnV33zQC~}9~Hx#ukl*ON=Y_~PTw=moOb$__9ANx$U74*34D}GvVt_=b#F2T zb6rTYNsbQ-0~x73^fkg^$8em;$Nqca|JwL%-02x@jtoLSpjaa9qC z29wO!X-S>5cbao$0I@3q7OR za8}kjF*V&>CO@jf;vJAalBTW}N#{Jc^I5B5xPFz(reUKbA(l2#b?-pKrV()7V@uIw z9SxgE!j@K(2{_oDBsNK1i9SirV9dKmxHxLdMO?sE+5Z2C{X2DDh`w7PNcP^rZ4)lK zOzWl#53Rd0Hei5Sa1(xE?4?)X7QKU{$H+c&l1$4Mro0PpwhURwV_BU!^f``$(a%{a zS*U+IG2XupPWa{i@4oI|H$L#w^2*Bm;`e6{-*f%?^`)cXxvdBL2L~_ry?yG3FOKa# z`uHj8?wdDnZ2av0A=l zJ31{LI569LDo82g+jbA_-Fv0`gW@NX)I;pzAHQ5UvM{@N*OtR`AFdzTe17A(f<`Uu z>c7@?=FFL^(i1tu`1M*m9$y~$D86OoUO5;%d1KQhs#d#tt$%sv8{b^Kcq!X6ckI~c z{E;I+_HDcH{+GgoJoRvud2R7A>O3>|@%pEJ-}?Nc=p6OVS7$%%u0HuL1Wjer!_vut H@z?(X#TES& literal 0 HcmV?d00001 diff --git a/clients/flash/web-client/src/org/bigbluebutton/web/deskshare/views/DeskshareConfig.as b/clients/flash/web-client/src/org/bigbluebutton/web/deskshare/views/DeskshareConfig.as new file mode 100644 index 0000000000..fb2e540f47 --- /dev/null +++ b/clients/flash/web-client/src/org/bigbluebutton/web/deskshare/views/DeskshareConfig.as @@ -0,0 +1,52 @@ +package org.bigbluebutton.web.deskshare.views { + import org.bigbluebutton.lib.deskshare.views.IDeskshareView; + import org.bigbluebutton.web.deskshare.views.DeskshareWindowMediator; + import org.bigbluebutton.web.user.views.UserWindow; + import org.bigbluebutton.web.user.views.UserWindowMediator; + + import robotlegs.bender.extensions.matching.TypeMatcher; + import robotlegs.bender.extensions.mediatorMap.api.IMediatorMap; + import robotlegs.bender.extensions.signalCommandMap.api.ISignalCommandMap; + import robotlegs.bender.framework.api.IConfig; + import robotlegs.bender.framework.api.IInjector; + + public class DeskshareConfig implements IConfig { + + [Inject] + public var injector:IInjector; + + [Inject] + public var mediatorMap:IMediatorMap; + + [Inject] + public var signalCommandMap:ISignalCommandMap; + + public function configure():void { + dependencies(); + mediators(); + signals(); + } + + /** + * Specifies all the dependencies for the feature + * that will be injected onto objects used by the + * application. + */ + private function dependencies():void { + } + + /** + * Maps view mediators to views. + */ + private function mediators():void { + mediatorMap.map(IDeskshareView).toMediator(DeskshareWindowMediator); + } + + /** + * Maps signals to commands using the signalCommandMap. + */ + private function signals():void { + + } + } +} diff --git a/clients/flash/web-client/src/org/bigbluebutton/web/deskshare/views/DeskshareVideoView.as b/clients/flash/web-client/src/org/bigbluebutton/web/deskshare/views/DeskshareVideoView.as new file mode 100644 index 0000000000..7f0080155f --- /dev/null +++ b/clients/flash/web-client/src/org/bigbluebutton/web/deskshare/views/DeskshareVideoView.as @@ -0,0 +1,142 @@ +package org.bigbluebutton.web.deskshare.views { + + import flash.display.Bitmap; + import flash.display.Loader; + import flash.events.Event; + import flash.net.NetConnection; + import flash.net.URLRequest; + + import mx.controls.VideoDisplay; + + import org.bigbluebutton.lib.common.views.VideoView; + + public class DeskshareVideoView extends VideoView { + + protected var originalVideoWidth:Number; + + protected var originalVideoHeight:Number; + + protected var screenWidth:Number; + + protected var screenHeight:Number; + + protected var aspectRatio:Number; + + protected var _videoDisplay:VideoDisplay; + + private var _mouse:Bitmap; + + public function DeskshareVideoView(videoDisplay:VideoDisplay) { + _videoDisplay = videoDisplay; + super(); + } + + public function addVideo():void { + _videoDisplay.addChild(video); + } + + public function setVideoPosition(x:Number, y:Number, w:Number, h:Number):void { + this.screenHeight = h; + this.screenWidth = w; + if (!aspectRatio) { + aspectRatio = video.width / video.height; + } + if (w / aspectRatio < h) { + video.width = w; + video.height = w / aspectRatio + } else { + video.height = h; + video.width = h * aspectRatio + } + video.x = (w - video.width) / 2; + video.y = (h - video.height) / 2; + } + + public function displayOriginalSize(w:Number, h:Number, xChange:Number = 0, yChange:Number = 0):void { + this.screenHeight = h; + this.screenWidth = w; + video.width = originalVideoWidth; + video.height = originalVideoHeight; + video.x = (screenWidth - video.width) * xChange / 100; + video.y = (screenHeight - video.height) * yChange / 100;; + } + + public function initializeScreenSizeValues(originalVideoWidth0:Number, originalVideoHeight0:Number, screenHeight0:Number, screenWidth0:Number):void { + this.screenHeight = screenHeight0; + this.screenWidth = screenWidth0; + this.originalVideoWidth = originalVideoWidth0; + this.originalVideoHeight = originalVideoHeight0; + } + + public function get videoWidth():Number { + return video.width; + } + + public function get videoHeight():Number { + return video.height; + } + + /** + * We can't add image to the stage, need to load the image as a bitmap + */ + public function addMouse():void { + var loader:Loader = new Loader(); + loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadMouseComplete); + var request:URLRequest = new URLRequest("assets/images/cursor.png"); + loader.load(request); + } + + /** + * Move mouse + * Based on provided values from the server need to recalculate position respecting current screen size and rotation + */ + public function moveMouse(originalX:Number, originalY:Number):void { + var reducedScreenPercentage:Number; + // need to wait until mouse bitmap is loaded and added to the stage + if (_mouse) { + if (video.height == screenHeight) { + reducedScreenPercentage = originalVideoHeight / video.height; + } else { + reducedScreenPercentage = originalVideoWidth / video.width; + } + if (originalY <= 0) { + _mouse.y = video.y; + } else if (originalY / reducedScreenPercentage > video.height) { + _mouse.y = video.y + video.height; + } else { + _mouse.y = video.y + originalY / reducedScreenPercentage; + } + if (originalX <= 0) { + _mouse.x = video.x; + } else if (originalX / reducedScreenPercentage > video.width) { + _mouse.x = video.x + video.width; + } else { + _mouse.x = video.x + originalX * video.width / originalVideoWidth; + } + } + } + + /** + * Once cursor bitmap loaded - add it to the stage + */ + private function loadMouseComplete(event:Event):void { + _mouse = Bitmap(event.target.loader.content); + _videoDisplay.addChild(_mouse); + } + + public function removeMouse():void { + _videoDisplay.removeChild(_mouse); + } + + /** + * Move mouse + * Based on provided values from the server need to recalculate position respecting current screen size and rotation + */ + public function changeMouseLocation(x:Number, y:Number):void { + if (_mouse) { + _mouse.x = x; + _mouse.y = y; + } + } + } +} diff --git a/clients/flash/web-client/src/org/bigbluebutton/web/deskshare/views/DeskshareWindow.as b/clients/flash/web-client/src/org/bigbluebutton/web/deskshare/views/DeskshareWindow.as new file mode 100644 index 0000000000..9b82bd62c9 --- /dev/null +++ b/clients/flash/web-client/src/org/bigbluebutton/web/deskshare/views/DeskshareWindow.as @@ -0,0 +1,225 @@ +package org.bigbluebutton.web.deskshare.views { + import flash.display.Bitmap; + import flash.display.Loader; + import flash.events.Event; + import flash.events.MouseEvent; + import flash.net.NetConnection; + import flash.net.URLRequest; + + import flexlib.controls.HSlider; + + import mx.containers.Canvas; + import mx.controls.Button; + import mx.controls.VideoDisplay; + import mx.events.MoveEvent; + import mx.events.ResizeEvent; + import mx.events.ScrollEvent; + + import org.bigbluebutton.lib.deskshare.views.IDeskshareView; + import org.bigbluebutton.web.util.i18n.ResourceUtil; + import org.bigbluebutton.web.window.views.BBBWindow; + import org.osflash.signals.Signal; + + import spark.components.Group; + import spark.components.HScrollBar; + import spark.components.Scroller; + import spark.components.VScrollBar; + import spark.layouts.VerticalLayout; + + + public class DeskshareWindow extends BBBWindow implements IDeskshareView { + + private var _deskshareVideoView:DeskshareVideoView; + + private var _videoDisplay:VideoDisplay; + + private var _deskshareGroup:Group; + + private var _displayActualSizeButton:Button; + + private var _hscroll:HScrollBar; + + private var _vscroll:VScrollBar; + + private var _displayActualSize:Boolean = false; + + public function DeskshareWindow() { + super(); + hideWindow(); + title = ResourceUtil.getInstance().getString("bbb.desktopView.title"); + width = 300; + height = 400; + + _deskshareGroup = new Group(); + _deskshareGroup.clipAndEnableScrolling = true; + _deskshareGroup.percentHeight = 100; + _deskshareGroup.percentWidth = 100; + _deskshareGroup.horizontalScrollPosition = 50; + + addElement(_deskshareGroup); + + var layout:VerticalLayout = new VerticalLayout(); + layout.verticalAlign = "middle"; + + _deskshareGroup.layout = layout; + + _videoDisplay = new VideoDisplay(); + _videoDisplay.width = 0; //this hides the black background + + _deskshareGroup.addElement(_videoDisplay); + + _hscroll = new HScrollBar(); + _hscroll.percentWidth = 100; + _hscroll.addEventListener(Event.CHANGE, scrollChange); + addElement(_hscroll); + + _vscroll = new VScrollBar(); + _vscroll.percentHeight = 100; + _vscroll.addEventListener(Event.CHANGE, scrollChange); + addElement(_vscroll); + + showScrollers(_displayActualSize); + + _displayActualSizeButton = new Button(); + _displayActualSizeButton.label = ResourceUtil.getInstance().getString("bbb.desktopView.actualSize"); + _displayActualSizeButton.addEventListener(MouseEvent.CLICK, changeDisplayMode) + this.addEventListener(MouseEvent.MOUSE_OVER, mouseOverWindow); + this.addEventListener(MouseEvent.MOUSE_OUT, mouseOutWindow) + addElement(_displayActualSizeButton); + + this.addEventListener(MoveEvent.MOVE, moveWindow) + } + + private function mouseOverWindow(e:MouseEvent):void { + showDisplayActualSizeButton(true); + } + + private function mouseOutWindow(e:MouseEvent):void { + showDisplayActualSizeButton(false); + } + + private function scrollChange(e:Event):void { + setDeskshareVideoPosition(this.width, this.height); + } + + private function showDisplayActualSizeButton(value:Boolean):void { + _displayActualSizeButton.visible = value; + _displayActualSizeButton.includeInLayout = value; + } + + private function showScrollers(value:Boolean):void { + _vscroll.visible = value; + _hscroll.visible = value; + } + + private function changeDisplayMode(e:MouseEvent):void { + if (_displayActualSize) { + _displayActualSize = false; + _displayActualSizeButton.label = ResourceUtil.getInstance().getString("bbb.desktopView.actualSize"); + + } else { + _displayActualSize = true; + _displayActualSizeButton.label = ResourceUtil.getInstance().getString("bbb.desktopView.fitToWindow"); + } + showScrollers(_displayActualSize); + setDeskshareVideoPosition(this.width, this.height); + } + + private function setDeskshareVideoPosition(w:Number, h:Number):void { + if (_deskshareVideoView) { + // validates the view to get actual components dimensions + this.validateNow(); + // limit the view the window borders + h -= titleBarOverlay.height + 3; + w -= 2; + if (_displayActualSize) { + // if deskshare video fits window, hide scroll bars + if (_deskshareVideoView.videoWidth < w) { + _hscroll.value = 50; + _hscroll.visible = false; + } else { + _hscroll.visible = true; + h -= _hscroll.height; + } + if (_deskshareVideoView.videoHeight < h) { + _vscroll.value = 50; + _vscroll.visible = false; + } else { + _vscroll.visible = true; + w -= _vscroll.width; + } + _deskshareVideoView.displayOriginalSize(w, h, _hscroll.value, _vscroll.value); + _hscroll.width = w; + _vscroll.height = h; + _vscroll.x = w; + _hscroll.y = h; + } else { + _deskshareVideoView.setVideoPosition(x, y, w, h); + } + } + _deskshareGroup.width = w; + _deskshareGroup.height = h; + _displayActualSizeButton.x = (w - _displayActualSizeButton.width) / 2; + _displayActualSizeButton.y = h - titleBarOverlay.height * 2; + } + + override protected function updateDisplayList(w:Number, h:Number):void { + super.updateDisplayList(w, h); + setDeskshareVideoPosition(w, h); + } + + private function moveWindow(e:MoveEvent):void { + setDeskshareVideoPosition(this.width, this.height); + } + + public function showWindow():void { + this.visible = true; + this.includeInLayout = true; + } + + public function hideWindow():void { + this.visible = false; + this.includeInLayout = false; + } + + public function get deskshareGroup():Group { + return _deskshareGroup; + } + + public function startStream(connection:NetConnection, name:String, streamName:String, userID:String, width:Number, height:Number):void { + if (_deskshareVideoView) { + stopStream(); + } + _deskshareVideoView = new DeskshareVideoView(_videoDisplay); + _deskshareVideoView.percentWidth = 100; + _deskshareVideoView.percentHeight = 100; + _deskshareGroup.addElement(_deskshareVideoView); + _deskshareVideoView.addVideo(); + _deskshareVideoView.initializeScreenSizeValues(width, height, this.deskshareGroup.height, this.deskshareGroup.width); + _deskshareVideoView.startStream(connection, name, streamName, userID); + setDeskshareVideoPosition(this.width, this.height); + _deskshareVideoView.addMouse(); + } + + public function changeMouseLocation(x:Number, y:Number):void { + if (_deskshareVideoView) { + _deskshareVideoView.moveMouse(x, y); + } + } + + /** + * Close the video stream and remove video from layout + */ + public function stopStream():void { + if (_deskshareVideoView) { + _deskshareVideoView.removeMouse(); + _deskshareVideoView.close(); + if (this.deskshareGroup.containsElement(_deskshareVideoView)) { + this.deskshareGroup.removeElement(_deskshareVideoView); + } + _deskshareVideoView = null; + } + } + } +} + diff --git a/clients/flash/web-client/src/org/bigbluebutton/web/deskshare/views/DeskshareWindowMediator.as b/clients/flash/web-client/src/org/bigbluebutton/web/deskshare/views/DeskshareWindowMediator.as new file mode 100644 index 0000000000..7ea9885850 --- /dev/null +++ b/clients/flash/web-client/src/org/bigbluebutton/web/deskshare/views/DeskshareWindowMediator.as @@ -0,0 +1,19 @@ +package org.bigbluebutton.web.deskshare.views { + import flash.events.Event; + import flash.events.MouseEvent; + + import org.bigbluebutton.lib.deskshare.views.DeskshareMediator; + + public class DeskshareWindowMediator extends DeskshareMediator { + + override public function onDeskshareStreamChange(isDeskshareStreaming:Boolean):void { + if (isDeskshareStreaming) { + (view as DeskshareWindow).showWindow(); + } else { + (view as DeskshareWindow).hideWindow(); + } + super.onDeskshareStreamChange(isDeskshareStreaming); + } + + } +}