Implemented desktop sharing display to web-client.

This commit is contained in:
Ghaz Triki 2016-04-03 10:36:50 +01:00
parent 384da3a606
commit 3d8d4bda86
12 changed files with 546 additions and 38 deletions

View File

@ -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;

View File

@ -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;
/**

View File

@ -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();
}
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}
}

View File

@ -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;
}
}

View File

@ -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 {

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -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 {
}
}
}

View File

@ -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;
}
}
}
}

View File

@ -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;
}
}
}
}

View File

@ -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);
}
}
}