- Changes to the layout manager

- Whiteboard UI improvements
This commit is contained in:
BigBlueButton 2010-06-04 20:50:49 +00:00
parent 72f842148a
commit 67841cec85
29 changed files with 2263 additions and 2445 deletions

View File

@ -1,47 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<actionScriptProperties mainApplicationPath="BigBlueButton.mxml" version="3">
<compiler additionalCompilerArguments="-locale=" copyDependentFiles="true" enableModuleDebug="false" generateAccessible="false" htmlExpressInstall="true" htmlGenerate="true" htmlHistoryManagement="true" htmlPlayerVersion="9.0.115" htmlPlayerVersionCheck="true" outputFolderPath="bin" sourceFolderPath="src" strict="true" useApolloConfig="false" verifyDigests="true" warn="true">
<compilerSourcePath>
<compilerSourcePathEntry kind="1" linkType="1" path="tests/integration"/>
<compilerSourcePathEntry kind="1" linkType="1" path="tests/unit"/>
<compilerSourcePathEntry kind="1" linkType="1" path="tests/suite"/>
</compilerSourcePath>
<libraryPath defaultLinkType="1">
<libraryPathEntry kind="4" path="">
<modifiedEntries>
<libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/framework.swc" sourcepath="${PROJECT_FRAMEWORKS}/source" useDefaultLinkType="true"/>
</modifiedEntries>
<excludedEntries>
<libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation.swc" useDefaultLinkType="false"/>
<libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_agent.swc" useDefaultLinkType="false"/>
<libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/qtp.swc" useDefaultLinkType="false"/>
<libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_dmv.swc" useDefaultLinkType="false"/>
</excludedEntries>
</libraryPathEntry>
<libraryPathEntry kind="1" linkType="1" path="libs"/>
</libraryPath>
<sourceAttachmentPath>
<sourceAttachmentPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/datavisualization.swc" sourcepath="${PROJECT_FRAMEWORKS}/source" useDefaultLinkType="false"/>
<sourceAttachmentPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/framework.swc" sourcepath="${PROJECT_FRAMEWORKS}/source" useDefaultLinkType="true"/>
</sourceAttachmentPath>
</compiler>
<applications>
<application path="src/main.mxml"/>
<application path="MessagingUnitTests.mxml"/>
<application path="BbbUnitTests.mxml"/>
<application path="src/TestRunners.mxml"/>
<application path="BigBlueButton.mxml"/>
<application path="DeskshareStandalone.mxml"/>
</applications>
<modules>
<module application="src/BigBlueButton.mxml" destPath="VideoconfModule.swf" optimize="true" sourcePath="src/VideoconfModule.mxml"/>
<module application="src/BigBlueButton.mxml" destPath="ChatModule.swf" optimize="true" sourcePath="src/ChatModule.mxml"/>
<module application="src/BigBlueButton.mxml" destPath="PresentModule.swf" optimize="true" sourcePath="src/PresentModule.mxml"/>
<module application="src/BigBlueButton.mxml" destPath="ListenersModule.swf" optimize="true" sourcePath="src/ListenersModule.mxml"/>
<module application="src/BigBlueButton.mxml" destPath="HighlighterModule.swf" optimize="true" sourcePath="src/HighlighterModule.mxml"/>
<module application="src/BigBlueButton.mxml" destPath="DeskShareModule.swf" optimize="true" sourcePath="src/DeskShareModule.mxml"/>
<module application="src/BigBlueButton.mxml" destPath="PhoneModule.swf" optimize="true" sourcePath="src/PhoneModule.mxml"/>
<module application="src/BigBlueButton.mxml" destPath="ViewersModule.swf" optimize="true" sourcePath="src/ViewersModule.mxml"/>
</modules>
<buildCSSFiles/>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<actionScriptProperties mainApplicationPath="BigBlueButton.mxml" projectUUID="71ca15c9-a313-4acd-a765-12a897cbc088" version="6">
<compiler additionalCompilerArguments="-locale=" autoRSLOrdering="false" copyDependentFiles="true" fteInMXComponents="false" generateAccessible="false" htmlExpressInstall="true" htmlGenerate="true" htmlHistoryManagement="true" htmlPlayerVersionCheck="true" includeNetmonSwc="false" outputFolderPath="bin" sourceFolderPath="src" strict="true" targetPlayerVersion="0.0.0" useApolloConfig="false" useDebugRSLSwfs="true" verifyDigests="true" warn="true">
<compilerSourcePath>
<compilerSourcePathEntry kind="1" linkType="1" path="tests/integration"/>
<compilerSourcePathEntry kind="1" linkType="1" path="tests/unit"/>
<compilerSourcePathEntry kind="1" linkType="1" path="tests/suite"/>
</compilerSourcePath>
<libraryPath defaultLinkType="1">
<libraryPathEntry kind="4" path="">
<excludedEntries>
<libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/qtp.swc" useDefaultLinkType="false"/>
<libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation.swc" useDefaultLinkType="false"/>
<libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_dmv.swc" useDefaultLinkType="false"/>
<libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_agent.swc" useDefaultLinkType="false"/>
</excludedEntries>
</libraryPathEntry>
<libraryPathEntry kind="1" linkType="1" path="libs"/>
</libraryPath>
<sourceAttachmentPath>
<sourceAttachmentPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/datavisualization.swc" sourcepath="${PROJECT_FRAMEWORKS}/source" useDefaultLinkType="false"/>
<sourceAttachmentPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/framework.swc" sourcepath="${PROJECT_FRAMEWORKS}/source" useDefaultLinkType="true"/>
</sourceAttachmentPath>
</compiler>
<applications>
<application path="src/main.mxml"/>
<application path="MessagingUnitTests.mxml"/>
<application path="BbbUnitTests.mxml"/>
<application path="src/TestRunners.mxml"/>
<application path="BigBlueButton.mxml"/>
<application path="DeskshareStandalone.mxml"/>
</applications>
<modules>
<module application="src/BigBlueButton.mxml" destPath="VideoconfModule.swf" optimize="true" sourcePath="src/VideoconfModule.mxml"/>
<module application="src/BigBlueButton.mxml" destPath="ChatModule.swf" optimize="true" sourcePath="src/ChatModule.mxml"/>
<module application="src/BigBlueButton.mxml" destPath="PresentModule.swf" optimize="true" sourcePath="src/PresentModule.mxml"/>
<module application="src/BigBlueButton.mxml" destPath="ListenersModule.swf" optimize="true" sourcePath="src/ListenersModule.mxml"/>
<module application="src/BigBlueButton.mxml" destPath="HighlighterModule.swf" optimize="true" sourcePath="src/HighlighterModule.mxml"/>
<module application="src/BigBlueButton.mxml" destPath="DeskShareModule.swf" optimize="true" sourcePath="src/DeskShareModule.mxml"/>
<module application="src/BigBlueButton.mxml" destPath="PhoneModule.swf" optimize="true" sourcePath="src/PhoneModule.mxml"/>
<module application="src/BigBlueButton.mxml" destPath="ViewersModule.swf" optimize="true" sourcePath="src/ViewersModule.mxml"/>
</modules>
<buildCSSFiles/>
</actionScriptProperties>

View File

@ -1,2 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<flexProperties flexServerType="0" toolCompile="true" useServerFlexSDK="false" version="1"/>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<flexProperties enableServiceManager="false" flexServerFeatures="0" flexServerType="0" toolCompile="true" useServerFlexSDK="false" version="1"/>

View File

@ -1,3 +1,4 @@
#Sun Mar 16 18:41:03 EDT 2008
#Fri Jun 04 16:38:36 EDT 2010
eclipse.preferences.version=1
upgradeSDK/fb3=
upgradeSDK/fb4=Flex 3.5

View File

@ -1,58 +1,58 @@
<?xml version="1.0" ?>
<config>
<version>dev build</version>
<help url="http://192.168.0.194/help.html"/>
<porttest host="192.168.0.194" application="video"/>
<help url="http://192.168.0.172/help.html"/>
<porttest host="192.168.0.172" application="video"/>
<modules>
<module name="ChatModule" url="ChatModule.swf"
uri="rtmp://192.168.0.194/bigbluebutton"
uri="rtmp://192.168.0.172/bigbluebutton"
loadNextModule="ListenersModule"
onUserJoinedEvent="START"
onUserLogoutEvent="STOP"
/>
<!--host="http://192.168.0.194/bigbluebutton/conference-session/enter"-->
<!--host="http://192.168.0.172/bigbluebutton/conference-session/enter"-->
<!--host="conf/join-mock.xml"-->
<module name="ViewersModule" url="ViewersModule.swf"
uri="rtmp://192.168.0.194/bigbluebutton"
uri="rtmp://192.168.0.172/bigbluebutton"
host="conf/join-mock.xml"
onAppInitEvent="LOAD" loadNextModule="ChatModule"
onAppStartEvent="START"
onUserLogoutEvent="STOP"
/>
<module name="ListenersModule" url="ListenersModule.swf"
uri="rtmp://192.168.0.194/bigbluebutton"
recordingHost="http://192.168.0.194"
uri="rtmp://192.168.0.172/bigbluebutton"
recordingHost="http://192.168.0.172"
loadNextModule="PhoneModule"
onUserJoinedEvent="START"
onUserLogoutEvent="STOP"
/>
<!--module name="DeskShareModule" url="DeskShareModule.swf" uri="rtmp://192.168.0.194/deskShare" onUserJoinedEvent="START" onUserLogoutEvent="STOP" loadNextModule="PhoneModule" /-->
<!--module name="DeskShareModule" url="DeskShareModule.swf" uri="rtmp://192.168.0.172/deskShare" onUserJoinedEvent="START" onUserLogoutEvent="STOP" loadNextModule="PhoneModule" /-->
<module name="PhoneModule" url="PhoneModule.swf"
uri="rtmp://192.168.0.194/sip"
uri="rtmp://192.168.0.172/sip"
onUserJoinedEvent="START"
onUserLogoutEvent="STOP"
loadNextModule="VideoconfModule"
/>
<module name="VideoconfModule" url="VideoconfModule.swf"
uri="rtmp://192.168.0.194/video"
uri="rtmp://192.168.0.172/video"
onUserJoinedEvent="START"
onUserLogoutEvent="STOP"
loadNextModule="PresentModule"
/>
<module name="HighlighterModule" url="HighlighterModule.swf"
uri="rtmp://192.168.0.194/bigbluebutton"
uri="rtmp://192.168.0.172/bigbluebutton"
onUserJoinedEvent="START"
onUserLogoutEvent="STOP"
/>
<module name="PresentModule" url="PresentModule.swf"
uri="rtmp://192.168.0.194/bigbluebutton"
host="http://192.168.0.194"
uri="rtmp://192.168.0.172/bigbluebutton"
host="http://192.168.0.172"
onUserJoinedEvent="START"
onUserLogoutEvent="STOP"
loadNextModule="HighlighterModule"
@ -60,9 +60,9 @@
<!-- new module in development:
<module name="DynamicInfoModule" url="DynamicInfoModule.swf"
uri="rtmp://192.168.0.194/bigbluebutton"
host="http://192.168.0.194"
infoURL="http://192.168.0.194/client/conf/example-info-data.xml?user={userID}&role={role}&meetingID={meetingID}"
uri="rtmp://192.168.0.172/bigbluebutton"
host="http://192.168.0.172"
infoURL="http://192.168.0.172/client/conf/example-info-data.xml?user={userID}&role={role}&meetingID={meetingID}"
onUserJoinedEvent="START"
onUserLogoutEvent="STOP"
/>

View File

@ -1,34 +1,26 @@
/*
* BigBlueButton - http://www.bigbluebutton.org
*
* Copyright (c) 2008-2009 by respective authors (see below). All rights reserved.
*
* BigBlueButton 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 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, If not, see <http://www.gnu.org/licenses/>.
*
* $Id: $
*/
package org.bigbluebutton.common
{
public interface IBbbModuleWindow
{
function get xPosition():int;
function get yPosition():int;
function set xPosition(x:int):void;
function set yPosition(y:int):void;
function get defaultWidth():int
function get defaultHeight():int;
function set defaultWidth(width:int):void;
function set defaultHeight(height:int):void;
function resetWidthAndHeight():void;
}
/*
* BigBlueButton - http://www.bigbluebutton.org
*
* Copyright (c) 2008-2009 by respective authors (see below). All rights reserved.
*
* BigBlueButton 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 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, If not, see <http://www.gnu.org/licenses/>.
*
* $Id: $
*/
package org.bigbluebutton.common
{
public interface IBbbModuleWindow
{
function getPrefferedPosition():String;
}
}

View File

@ -1,245 +1,244 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2008 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 2.1 of the License, or (at your option) any later
* version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package org.bigbluebutton.main.view
{
import flash.events.Event;
import flash.geom.Point;
import flexlib.mdi.containers.MDIWindow;
import mx.managers.PopUpManager;
import mx.managers.PopUpManagerChildList;
import org.bigbluebutton.common.IBbbModuleWindow;
import org.bigbluebutton.main.MainApplicationConstants;
import org.bigbluebutton.main.events.OpenWindowEvent;
import org.bigbluebutton.main.model.ModulesProxy;
import org.bigbluebutton.main.model.PortTestProxy;
import org.bigbluebutton.main.view.components.LoggedOutWindow;
import org.bigbluebutton.main.view.components.MainApplicationShell;
import org.bigbluebutton.main.view.components.ModuleStoppedWindow;
import org.bigbluebutton.main.view.events.StartModuleEvent;
import org.bigbluebutton.modules.phone.views.components.ToolbarButton;
import org.bigbluebutton.util.i18n.ResourceUtil;
import org.puremvc.as3.multicore.interfaces.INotification;
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2008 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 2.1 of the License, or (at your option) any later
* version.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package org.bigbluebutton.main.view
{
import flash.events.Event;
import flash.geom.Point;
import flexlib.mdi.containers.MDIWindow;
import mx.managers.PopUpManager;
import mx.managers.PopUpManagerChildList;
import org.bigbluebutton.common.IBbbModuleWindow;
import org.bigbluebutton.main.MainApplicationConstants;
import org.bigbluebutton.main.events.OpenWindowEvent;
import org.bigbluebutton.main.model.ModulesProxy;
import org.bigbluebutton.main.model.PortTestProxy;
import org.bigbluebutton.main.view.components.LoggedOutWindow;
import org.bigbluebutton.main.view.components.MainApplicationShell;
import org.bigbluebutton.main.view.components.ModuleStoppedWindow;
import org.bigbluebutton.main.view.events.StartModuleEvent;
import org.bigbluebutton.modules.phone.views.components.ToolbarButton;
import org.bigbluebutton.util.i18n.ResourceUtil;
import org.puremvc.as3.multicore.interfaces.INotification;
import org.puremvc.as3.multicore.patterns.mediator.Mediator;
/**
* This is the Mediator class for MainApplicationShell view compom\nent
*/
public class MainApplicationShellMediator extends Mediator
{
public static const NAME:String = 'MainApplicationShellMediator';
public static const OPEN_CHAT_MODULE:String = 'openChatModule';
public static const OPEN_LOG_MODULE:String = 'openLogModule';
public static const LOGOUT:String = "Logout";
public static const START_WEBCAM:String = "Start Webcam";
private var mshell:MainApplicationShell;
private var phoneButton:ToolbarButton;
private var phoneRegistered:Boolean = false;
private var logoutWindow:LoggedOutWindow;
public function MainApplicationShellMediator( viewComponent:MainApplicationShell )
{
super( NAME, viewComponent );
viewComponent.toolbar.addEventListener(MainApplicationConstants.LOGOUT_EVENT, onLogoutEventHandler);
viewComponent.addEventListener(StartModuleEvent.START_MODULE_RETRY_EVENT, onRestartModuleEvent);
}
private function addWindowMessageHandler(event:OpenWindowEvent):void {
trace("Received ADD WINDOW EVENT");
}
private function displayWindow(window:IBbbModuleWindow):void {
shell.mdiCanvas.windowManager.add(window as MDIWindow);
shell.mdiCanvas.windowManager.absPos(window as MDIWindow, window.xPosition, window.yPosition);
}
protected function get shell():MainApplicationShell
{
return viewComponent as MainApplicationShell;
}
private function onLogoutEventHandler(e:Event):void {
sendNotification(MainApplicationConstants.LOGOUT);
}
private function onRestartModuleEvent(e:StartModuleEvent):void {
sendNotification(MainApplicationConstants.RESTART_MODULE, e.moduleName);
}
override public function listNotificationInterests():Array{
return [
MainApplicationConstants.APP_MODEL_INITIALIZED,
MainApplicationConstants.PORT_TEST_FAILED,
MainApplicationConstants.ADD_WINDOW_MSG,
MainApplicationConstants.REMOVE_WINDOW_MSG,
MainApplicationConstants.USER_JOINED,
MainApplicationConstants.USER_LOGGED_IN,
MainApplicationConstants.USER_LOGGED_OUT,
MainApplicationConstants.LOADED_MODULE,
MainApplicationConstants.MODULE_STOPPED,
MainApplicationConstants.MODULE_LOAD_PROGRESS
];
}
private var red5phoneAdded:Boolean = false;
override public function handleNotification(notification:INotification):void{
switch(notification.getName()){
case MainApplicationConstants.APP_MODEL_INITIALIZED:
shell.appVersion = modulesProxy.getVersion();
shell.numberOfModules = modulesProxy.getNumberOfModules();
testRTMPConnection();
break;
case MainApplicationConstants.PORT_TEST_FAILED:
var portTestResult:Object = notification.getBody();
if (portTestResult["protocol"] == "RTMP") {
testRTMPTConnection()
} else {
shell.statusProgress.text = "Sorry, we cannot connect to the server.";
}
break;
case MainApplicationConstants.ADD_WINDOW_MSG:
var win:IBbbModuleWindow = notification.getBody() as IBbbModuleWindow;
displayWindow(win);
break;
case MainApplicationConstants.REMOVE_WINDOW_MSG:
var rwin:IBbbModuleWindow = notification.getBody() as IBbbModuleWindow;
//LogUtil.debug(NAME + "::removing window " + (rwin as MDIWindow).name);
shell.mdiCanvas.windowManager.remove(rwin as MDIWindow);
break;
case MainApplicationConstants.USER_LOGGED_OUT:
handleUserLoggedOut(notification.getBody() as String);
// if (red5phoneAdded) {
// red5phoneAdded = false;
// shell.mdiCanvas.windowManager.remove(red5PhoneWindow as MDIWindow);
// }
break;
case MainApplicationConstants.USER_JOINED:
/**
* Workaround to pass in username for sip registration.
*/
//red5PhoneWindow.sipusername = modulesProxy.username;
shell.statusInfo.text = "";
shell.statusProgress.text = "";
shell.statusInfo2.text = "";
trace("User has joined");
// if (!red5phoneAdded) {
// red5phoneAdded = true;
// phoneButton = new ToolbarButton();
// phoneButton.addEventListener(PhoneModuleConstants.START_PHONE_EVENT, onStartPhoneEvent);
// trace("Adding red5phone button");
// var uid:String = String( Math.floor( new Date().getTime() ) );
// red5Manager = new Red5Manager(uid, "Ricahrd ALam", '600', "rtmp://192.168.0.136/sip");
// sendNotification(MainApplicationConstants.ADD_BUTTON, phoneButton);
// }
break;
case MainApplicationConstants.USER_LOGGED_IN:
shell.statusInfo.text = "";
shell.statusProgress.text = "";
shell.statusInfo2.text = "";
break;
case MainApplicationConstants.MODULE_STOPPED:
var info:Object = notification.getBody();
// handleModuleStopped(info.moduleId, info.errors);
break;
case MainApplicationConstants.LOADED_MODULE:
shell.statusInfo.text += ResourceUtil.getInstance().getString('bbb.mainshell.statusInfo.loaded',[notification.getBody()]);
// Should do this properly.
//if (notification.getBody() == "ViewersModule") {
// shell.loadedModules.text = "";
// shell.loadProgress.text = "";
//}
break;
case MainApplicationConstants.MODULE_LOAD_PROGRESS:
var mod:String = notification.getBody().name as String;
var prog:Number = notification.getBody().progress as Number;
shell.statusProgress.text = ResourceUtil.getInstance().getString('bbb.mainshell.statusProgress.loaded',[mod, prog]);
break;
}
}
private function testRTMPConnection():void {
var host:String = modulesProxy.getPortTestHost();
var app:String = modulesProxy.getPortTestApplication();
shell.statusInfo.text = ResourceUtil.getInstance().getString('bbb.mainshell.statusInfo.testRTMPConnection');
shell.statusInfo2.text = ResourceUtil.getInstance().getString('bbb.mainshell.statusInfo2.testRTMPConnection');
shell.statusProgress.text = ResourceUtil.getInstance().getString('bbb.mainshell.statusProgress.testRTMPConnection', [host, app]);
portTestProxy.connect("RTMP", host, "1935", app);
}
private function testRTMPTConnection():void {
var host:String = modulesProxy.getPortTestHost();
var app:String = modulesProxy.getPortTestApplication();
shell.statusProgress.text = ResourceUtil.getInstance().getString('bbb.mainshell.statusProgress.testRTMPTConnection', [host, app]);
portTestProxy.connect("RTMPT", host, "", "bigbluebutton");
}
private function handleUserLoggedOut(reason:String):void {
if (logoutWindow != null) return;
logoutWindow = LoggedOutWindow(PopUpManager.createPopUp( shell.mdiCanvas, LoggedOutWindow, false));
var point1:Point = new Point();
// Calculate position of TitleWindow in Application's coordinates.
point1.x = 400;
point1.y = 300;
point1 = shell.localToGlobal(point1);
logoutWindow.x = point1.x + 25;
logoutWindow.y = point1.y + 25;
logoutWindow.setReason(reason);
/*
var pageURL:String = mx.core.Application.application.url.split("/")[2];
var url:URLRequest = new URLRequest("http://" + pageURL + "/bigbluebutton/conference-session/signOut");
LogUtil.debug("Log out url: " + pageURL);
navigateToURL(url, '_self');
*/
}
private function handleModuleStopped(moduleName:String, errors:Array):void {
var t:ModuleStoppedWindow = ModuleStoppedWindow(PopUpManager.createPopUp( shell.mdiCanvas, ModuleStoppedWindow, false));
t.addEventListener(StartModuleEvent.START_MODULE_RETRY_EVENT, onRestartModuleEvent);
t.displayErrors(moduleName, errors);
var point1:Point = new Point();
// Calculate position of TitleWindow in Application's coordinates.
point1.x = 200;
point1.y = 400;
point1 = shell.localToGlobal(point1);
t.x = point1.x + 25;
t.y = point1.y + 25;
}
private function get modulesProxy():ModulesProxy {
return facade.retrieveProxy(ModulesProxy.NAME) as ModulesProxy;
}
private function get portTestProxy():PortTestProxy {
return facade.retrieveProxy(PortTestProxy.NAME) as PortTestProxy;
}
}
/**
* This is the Mediator class for MainApplicationShell view compom\nent
*/
public class MainApplicationShellMediator extends Mediator
{
public static const NAME:String = 'MainApplicationShellMediator';
public static const OPEN_CHAT_MODULE:String = 'openChatModule';
public static const OPEN_LOG_MODULE:String = 'openLogModule';
public static const LOGOUT:String = "Logout";
public static const START_WEBCAM:String = "Start Webcam";
private var mshell:MainApplicationShell;
private var phoneButton:ToolbarButton;
private var phoneRegistered:Boolean = false;
private var logoutWindow:LoggedOutWindow;
public function MainApplicationShellMediator( viewComponent:MainApplicationShell )
{
super( NAME, viewComponent );
viewComponent.toolbar.addEventListener(MainApplicationConstants.LOGOUT_EVENT, onLogoutEventHandler);
viewComponent.addEventListener(StartModuleEvent.START_MODULE_RETRY_EVENT, onRestartModuleEvent);
}
private function addWindowMessageHandler(event:OpenWindowEvent):void {
trace("Received ADD WINDOW EVENT");
}
private function displayWindow(window:IBbbModuleWindow):void {
shell.mdiCanvas.addWindow(window);
}
protected function get shell():MainApplicationShell
{
return viewComponent as MainApplicationShell;
}
private function onLogoutEventHandler(e:Event):void {
sendNotification(MainApplicationConstants.LOGOUT);
}
private function onRestartModuleEvent(e:StartModuleEvent):void {
sendNotification(MainApplicationConstants.RESTART_MODULE, e.moduleName);
}
override public function listNotificationInterests():Array{
return [
MainApplicationConstants.APP_MODEL_INITIALIZED,
MainApplicationConstants.PORT_TEST_FAILED,
MainApplicationConstants.ADD_WINDOW_MSG,
MainApplicationConstants.REMOVE_WINDOW_MSG,
MainApplicationConstants.USER_JOINED,
MainApplicationConstants.USER_LOGGED_IN,
MainApplicationConstants.USER_LOGGED_OUT,
MainApplicationConstants.LOADED_MODULE,
MainApplicationConstants.MODULE_STOPPED,
MainApplicationConstants.MODULE_LOAD_PROGRESS
];
}
private var red5phoneAdded:Boolean = false;
override public function handleNotification(notification:INotification):void{
switch(notification.getName()){
case MainApplicationConstants.APP_MODEL_INITIALIZED:
shell.appVersion = modulesProxy.getVersion();
shell.numberOfModules = modulesProxy.getNumberOfModules();
testRTMPConnection();
break;
case MainApplicationConstants.PORT_TEST_FAILED:
var portTestResult:Object = notification.getBody();
if (portTestResult["protocol"] == "RTMP") {
testRTMPTConnection()
} else {
shell.statusProgress.text = "Sorry, we cannot connect to the server.";
}
break;
case MainApplicationConstants.ADD_WINDOW_MSG:
var win:IBbbModuleWindow = notification.getBody() as IBbbModuleWindow;
displayWindow(win);
break;
case MainApplicationConstants.REMOVE_WINDOW_MSG:
var rwin:IBbbModuleWindow = notification.getBody() as IBbbModuleWindow;
//LogUtil.debug(NAME + "::removing window " + (rwin as MDIWindow).name);
shell.mdiCanvas.windowManager.remove(rwin as MDIWindow);
break;
case MainApplicationConstants.USER_LOGGED_OUT:
handleUserLoggedOut(notification.getBody() as String);
// if (red5phoneAdded) {
// red5phoneAdded = false;
// shell.mdiCanvas.windowManager.remove(red5PhoneWindow as MDIWindow);
// }
break;
case MainApplicationConstants.USER_JOINED:
/**
* Workaround to pass in username for sip registration.
*/
//red5PhoneWindow.sipusername = modulesProxy.username;
shell.statusInfo.text = "";
shell.statusProgress.text = "";
shell.statusInfo2.text = "";
trace("User has joined");
// if (!red5phoneAdded) {
// red5phoneAdded = true;
// phoneButton = new ToolbarButton();
// phoneButton.addEventListener(PhoneModuleConstants.START_PHONE_EVENT, onStartPhoneEvent);
// trace("Adding red5phone button");
// var uid:String = String( Math.floor( new Date().getTime() ) );
// red5Manager = new Red5Manager(uid, "Ricahrd ALam", '600', "rtmp://192.168.0.136/sip");
// sendNotification(MainApplicationConstants.ADD_BUTTON, phoneButton);
// }
break;
case MainApplicationConstants.USER_LOGGED_IN:
shell.statusInfo.text = "";
shell.statusProgress.text = "";
shell.statusInfo2.text = "";
break;
case MainApplicationConstants.MODULE_STOPPED:
var info:Object = notification.getBody();
// handleModuleStopped(info.moduleId, info.errors);
break;
case MainApplicationConstants.LOADED_MODULE:
shell.statusInfo.text += ResourceUtil.getInstance().getString('bbb.mainshell.statusInfo.loaded',[notification.getBody()]);
// Should do this properly.
//if (notification.getBody() == "ViewersModule") {
// shell.loadedModules.text = "";
// shell.loadProgress.text = "";
//}
break;
case MainApplicationConstants.MODULE_LOAD_PROGRESS:
var mod:String = notification.getBody().name as String;
var prog:Number = notification.getBody().progress as Number;
shell.statusProgress.text = ResourceUtil.getInstance().getString('bbb.mainshell.statusProgress.loaded',[mod, prog]);
break;
}
}
private function testRTMPConnection():void {
var host:String = modulesProxy.getPortTestHost();
var app:String = modulesProxy.getPortTestApplication();
shell.statusInfo.text = ResourceUtil.getInstance().getString('bbb.mainshell.statusInfo.testRTMPConnection');
shell.statusInfo2.text = ResourceUtil.getInstance().getString('bbb.mainshell.statusInfo2.testRTMPConnection');
shell.statusProgress.text = ResourceUtil.getInstance().getString('bbb.mainshell.statusProgress.testRTMPConnection', [host, app]);
portTestProxy.connect("RTMP", host, "1935", app);
}
private function testRTMPTConnection():void {
var host:String = modulesProxy.getPortTestHost();
var app:String = modulesProxy.getPortTestApplication();
shell.statusProgress.text = ResourceUtil.getInstance().getString('bbb.mainshell.statusProgress.testRTMPTConnection', [host, app]);
portTestProxy.connect("RTMPT", host, "", "bigbluebutton");
}
private function handleUserLoggedOut(reason:String):void {
if (logoutWindow != null) return;
logoutWindow = LoggedOutWindow(PopUpManager.createPopUp( shell.mdiCanvas, LoggedOutWindow, false));
var point1:Point = new Point();
// Calculate position of TitleWindow in Application's coordinates.
point1.x = 400;
point1.y = 300;
point1 = shell.localToGlobal(point1);
logoutWindow.x = point1.x + 25;
logoutWindow.y = point1.y + 25;
logoutWindow.setReason(reason);
/*
var pageURL:String = mx.core.Application.application.url.split("/")[2];
var url:URLRequest = new URLRequest("http://" + pageURL + "/bigbluebutton/conference-session/signOut");
LogUtil.debug("Log out url: " + pageURL);
navigateToURL(url, '_self');
*/
}
private function handleModuleStopped(moduleName:String, errors:Array):void {
var t:ModuleStoppedWindow = ModuleStoppedWindow(PopUpManager.createPopUp( shell.mdiCanvas, ModuleStoppedWindow, false));
t.addEventListener(StartModuleEvent.START_MODULE_RETRY_EVENT, onRestartModuleEvent);
t.displayErrors(moduleName, errors);
var point1:Point = new Point();
// Calculate position of TitleWindow in Application's coordinates.
point1.x = 200;
point1.y = 400;
point1 = shell.localToGlobal(point1);
t.x = point1.x + 25;
t.y = point1.y + 25;
}
private function get modulesProxy():ModulesProxy {
return facade.retrieveProxy(ModulesProxy.NAME) as ModulesProxy;
}
private function get portTestProxy():PortTestProxy {
return facade.retrieveProxy(PortTestProxy.NAME) as PortTestProxy;
}
}
}

View File

@ -1,197 +1,191 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
BigBlueButton - http://www.bigbluebutton.org
Copyright (c) 2008-2009 by respective authors (see below). All rights reserved.
BigBlueButton 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 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, If not, see <http://www.gnu.org/licenses/>.
$Id: $
-->
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:flexmdi="flexlib.mdi.containers.*"
xmlns:logModule="org.bigbluebutton.modules.log.view.components.*"
xmlns:main="org.bigbluebutton.main.view.components.*"
xmlns:mate="http://mate.asfusion.com/"
width="100%" height="100%"
creationComplete="initializeShell()" xmlns:maps="org.bigbluebutton.main.maps.*">
<mate:Listener type="{OpenWindowEvent.OPEN_WINDOW_EVENT}" method="handleOpenWindowEvent" />
<mate:Listener type="{CloseWindowEvent.CLOSE_WINDOW_EVENT}" method="handleCloseWindowEvent"/>
<mate:Listener type="{JoinFailedEvent.JOIN_FAILED_EVENT}" method="handleJoinFailedEvent" />
<mate:Listener type="{AddUIComponentToMainCanvas.ADD_COMPONENT}" method="addComponentToCanvas" />
<maps:CrossModuleEventMap />
<mx:Script>
<![CDATA[
import org.bigbluebutton.main.events.AddUIComponentToMainCanvas;
import org.bigbluebutton.util.i18n.ResourceUtil;
import org.bigbluebutton.common.Images;
import org.bigbluebutton.modules.viewers.events.JoinFailedEvent;
import com.asfusion.mate.events.Dispatcher;
import org.bigbluebutton.main.events.OpenWindowEvent;
import org.bigbluebutton.main.events.CloseWindowEvent;
import org.bigbluebutton.common.IBbbModuleWindow;
import flexlib.mdi.containers.MDIWindow;
import org.bigbluebutton.util.logging.Logger;
import org.bigbluebutton.main.view.events.StartModuleEvent;
import mx.collections.ArrayCollection;
import mx.managers.PopUpManager;
import mx.containers.TitleWindow;
import mx.core.Application;
import mx.controls.Alert;
import org.bigbluebutton.common.Constants;
import flexlib.mdi.effects.effectsLib.MDIVistaEffects;
import org.bigbluebutton.main.MainApplicationFacade;
import org.bigbluebutton.main.view.MainApplicationShellMediator;
import flash.events.MouseEvent;
public static const NAME:String = 'MainApplicationShell';
protected var facade:MainApplicationFacade = MainApplicationFacade.getInstance();
private var globalDispatcher:Dispatcher;
private var dispState:String; //full-screen?
private var images:Images = new Images();
private var stoppedModules:ArrayCollection;
private var logs:Logger = new Logger();
private var logWindow:LogWindow;
// LIVE or PLAYBACK
private var _mode:String = 'LIVE';
[Bindable]
public var appVersion:String = '0.6';
[Bindable]
public var numberOfModules:int = 0;
[Bindable] private var fullscreen_icon:Class = images.full_screen;
[Bindable] private var logs_icon:Class = images.table;
[Bindable] private var reset_layout_icon:Class = images.layout;
public function get mode():String {
return _mode;
}
protected function initializeShell():void
{
trace('Initializing');
logWindow = new LogWindow();
logWindow.logs = logs;
facade.startup(this);
globalDispatcher = new Dispatcher();
}
protected function initFullScreen():void
{
/* Set up full screen handler. */
stage.addEventListener(FullScreenEvent.FULL_SCREEN, fullScreenHandler);
dispState = stage.displayState;
}
private function fullScreenHandler(evt:FullScreenEvent):void {
dispState = stage.displayState + " (fullScreen=" + evt.fullScreen.toString() + ")";
if (evt.fullScreen) {
LogUtil.debug("Switching to full screen");
/* Do something specific here if we switched to full screen mode. */
} else {
LogUtil.debug("Switching to normal screen");
/* Do something specific here if we switched to normal mode. */
}
}
private function openLogWindow():void {
mdiCanvas.windowManager.add(logWindow);
mdiCanvas.windowManager.absPos(logWindow, 100, 100);
}
private function toggleFullScreen():void{
LogUtil.debug("Toggling fullscreen");
try {
switch (stage.displayState) {
case StageDisplayState.FULL_SCREEN:
LogUtil.debug("full screen mode");
// If already in full screen mode, switch to normal mode.
stage.displayState = StageDisplayState.NORMAL;
break;
default:
LogUtil.debug("Normal screen mode");
// If not in full screen mode, switch to full screen mode.
stage.displayState = StageDisplayState.FULL_SCREEN;
break;
}
} catch (err:SecurityError) {
// ignore
}
}
private function handleOpenWindowEvent(event:OpenWindowEvent):void {
var window:IBbbModuleWindow = event.window;
mdiCanvas.windowManager.add(window as MDIWindow);
mdiCanvas.windowManager.absPos(window as MDIWindow, window.xPosition, window.yPosition);
}
private function handleCloseWindowEvent(event:CloseWindowEvent):void {
var window:IBbbModuleWindow = event.window;
mdiCanvas.windowManager.remove(window as MDIWindow);
}
private function handleJoinFailedEvent(event:JoinFailedEvent):void {
LogUtil.debug("GOT JOIN FAILED EVENT");
var t:JoinFailedWindow = JoinFailedWindow(PopUpManager.createPopUp( this, JoinFailedWindow, false));
var point1:Point = new Point();
// Calculate position of TitleWindow in Application's coordinates.
point1.x = 200;
point1.y = 400;
point1 = this.localToGlobal(point1);
t.x = point1.x + 25;
t.y = point1.y + 25;
}
private function resetLayout():void{
var windows:Array = mdiCanvas.windowManager.getOpenWindowList();
for (var i:Number=0; i<windows.length; i++){
var window:IBbbModuleWindow = windows[i] as IBbbModuleWindow;
mdiCanvas.windowManager.absPos(window as MDIWindow, window.xPosition, window.yPosition);
window.resetWidthAndHeight();
}
}
private function addComponentToCanvas(e:AddUIComponentToMainCanvas):void{
mdiCanvas.addChild(e.component);
}
]]>
</mx:Script>
<main:MainToolbar id="toolbar" dock="true" width="100%" height="30" visible="false" verticalAlign="middle"/>
<flexmdi:MDICanvas id="mdiCanvas" horizontalScrollPolicy="off" verticalScrollPolicy="off"
effectsLib="{flexlib.mdi.effects.effectsLib.MDIVistaEffects}"
width="100%" height="100%">
<mx:Label x="200" y="400" id="statusInfo" text="{ResourceUtil.getInstance().getString('bbb.mainshell.statusInfo',[numberOfModules])}"/>
<mx:Label x="200" y="420" id="statusInfo2"/>
<mx:Label x="200" y="440" id="statusProgress" text="{ResourceUtil.getInstance().getString('bbb.mainshell.statusProgress.loading')}"/>
</flexmdi:MDICanvas>
<mx:ControlBar width="100%" height="20" paddingTop="0">
<mx:Label text="{ResourceUtil.getInstance().getString('bbb.mainshell.copyrightLabel2',[appVersion])}" id="copyrightLabel2"/>
<mx:Spacer width="20"/>
<mx:Spacer width="100%"/>
<mx:Button width="20" height="20" toolTip="{ResourceUtil.getInstance().getString('bbb.mainshell.logBtn.toolTip')}" id="logBtn" icon="{logs_icon}" click="openLogWindow()" />
<mx:Button width="20" height="20" toolTip="{ResourceUtil.getInstance().getString('bbb.mainshell.fullScreenBtn.toolTip')}" id="fullScreen" icon="{fullscreen_icon}" click="toggleFullScreen()" />
<mx:Button width="20" height="20" toolTip="{ResourceUtil.getInstance().getString('bbb.mainshell.resetLayoutBtn.toolTip')}" id="btnResetLayout" icon="{reset_layout_icon}" click="resetLayout()" />
</mx:ControlBar>
</mx:VBox>
<?xml version="1.0" encoding="utf-8"?>
<!--
BigBlueButton - http://www.bigbluebutton.org
Copyright (c) 2008-2009 by respective authors (see below). All rights reserved.
BigBlueButton 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 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, If not, see <http://www.gnu.org/licenses/>.
$Id: $
-->
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:flexmdi="flexlib.mdi.containers.*"
xmlns:logModule="org.bigbluebutton.modules.log.view.components.*"
xmlns:main="org.bigbluebutton.main.view.components.*"
xmlns:mate="http://mate.asfusion.com/"
width="100%" height="100%"
creationComplete="initializeShell()" xmlns:maps="org.bigbluebutton.main.maps.*">
<mate:Listener type="{OpenWindowEvent.OPEN_WINDOW_EVENT}" method="handleOpenWindowEvent" />
<mate:Listener type="{CloseWindowEvent.CLOSE_WINDOW_EVENT}" method="handleCloseWindowEvent"/>
<mate:Listener type="{JoinFailedEvent.JOIN_FAILED_EVENT}" method="handleJoinFailedEvent" />
<mate:Listener type="{AddUIComponentToMainCanvas.ADD_COMPONENT}" method="addComponentToCanvas" />
<maps:CrossModuleEventMap />
<mx:Script>
<![CDATA[
import org.bigbluebutton.main.events.AddUIComponentToMainCanvas;
import org.bigbluebutton.util.i18n.ResourceUtil;
import org.bigbluebutton.common.Images;
import org.bigbluebutton.modules.viewers.events.JoinFailedEvent;
import com.asfusion.mate.events.Dispatcher;
import org.bigbluebutton.main.events.OpenWindowEvent;
import org.bigbluebutton.main.events.CloseWindowEvent;
import org.bigbluebutton.common.IBbbModuleWindow;
import flexlib.mdi.containers.MDIWindow;
import org.bigbluebutton.util.logging.Logger;
import org.bigbluebutton.main.view.events.StartModuleEvent;
import mx.collections.ArrayCollection;
import mx.managers.PopUpManager;
import mx.containers.TitleWindow;
import mx.core.Application;
import mx.controls.Alert;
import org.bigbluebutton.common.Constants;
import flexlib.mdi.effects.effectsLib.MDIVistaEffects;
import org.bigbluebutton.main.MainApplicationFacade;
import org.bigbluebutton.main.view.MainApplicationShellMediator;
import flash.events.MouseEvent;
public static const NAME:String = 'MainApplicationShell';
protected var facade:MainApplicationFacade = MainApplicationFacade.getInstance();
private var globalDispatcher:Dispatcher;
private var dispState:String; //full-screen?
private var images:Images = new Images();
private var stoppedModules:ArrayCollection;
private var logs:Logger = new Logger();
private var logWindow:LogWindow;
// LIVE or PLAYBACK
private var _mode:String = 'LIVE';
[Bindable]
public var appVersion:String = '0.6';
[Bindable]
public var numberOfModules:int = 0;
[Bindable] private var fullscreen_icon:Class = images.full_screen;
[Bindable] private var logs_icon:Class = images.table;
[Bindable] private var reset_layout_icon:Class = images.layout;
public function get mode():String {
return _mode;
}
protected function initializeShell():void
{
trace('Initializing');
logWindow = new LogWindow();
logWindow.logs = logs;
facade.startup(this);
globalDispatcher = new Dispatcher();
}
protected function initFullScreen():void
{
/* Set up full screen handler. */
stage.addEventListener(FullScreenEvent.FULL_SCREEN, fullScreenHandler);
dispState = stage.displayState;
}
private function fullScreenHandler(evt:FullScreenEvent):void {
dispState = stage.displayState + " (fullScreen=" + evt.fullScreen.toString() + ")";
if (evt.fullScreen) {
LogUtil.debug("Switching to full screen");
/* Do something specific here if we switched to full screen mode. */
} else {
LogUtil.debug("Switching to normal screen");
/* Do something specific here if we switched to normal mode. */
}
}
private function openLogWindow():void {
mdiCanvas.windowManager.add(logWindow);
mdiCanvas.windowManager.absPos(logWindow, 100, 100);
}
private function toggleFullScreen():void{
LogUtil.debug("Toggling fullscreen");
try {
switch (stage.displayState) {
case StageDisplayState.FULL_SCREEN:
LogUtil.debug("full screen mode");
// If already in full screen mode, switch to normal mode.
stage.displayState = StageDisplayState.NORMAL;
break;
default:
LogUtil.debug("Normal screen mode");
// If not in full screen mode, switch to full screen mode.
stage.displayState = StageDisplayState.FULL_SCREEN;
break;
}
} catch (err:SecurityError) {
// ignore
}
}
private function handleOpenWindowEvent(event:OpenWindowEvent):void {
var window:IBbbModuleWindow = event.window;
mdiCanvas.addWindow(window);
}
private function handleCloseWindowEvent(event:CloseWindowEvent):void {
var window:IBbbModuleWindow = event.window;
mdiCanvas.removeWindow(window);
}
private function handleJoinFailedEvent(event:JoinFailedEvent):void {
LogUtil.debug("GOT JOIN FAILED EVENT");
var t:JoinFailedWindow = JoinFailedWindow(PopUpManager.createPopUp( this, JoinFailedWindow, false));
var point1:Point = new Point();
// Calculate position of TitleWindow in Application's coordinates.
point1.x = 200;
point1.y = 400;
point1 = this.localToGlobal(point1);
t.x = point1.x + 25;
t.y = point1.y + 25;
}
private function resetLayout():void{
mdiCanvas.resetWindowLayout();
}
private function addComponentToCanvas(e:AddUIComponentToMainCanvas):void{
mdiCanvas.addChild(e.component);
}
]]>
</mx:Script>
<main:MainToolbar id="toolbar" dock="true" width="100%" height="30" visible="false" verticalAlign="middle"/>
<main:MainCanvas id="mdiCanvas" horizontalScrollPolicy="off" verticalScrollPolicy="off"
effectsLib="{flexlib.mdi.effects.effectsLib.MDIVistaEffects}"
width="100%" height="100%">
<mx:Label x="200" y="400" id="statusInfo" text="{ResourceUtil.getInstance().getString('bbb.mainshell.statusInfo',[numberOfModules])}"/>
<mx:Label x="200" y="420" id="statusInfo2"/>
<mx:Label x="200" y="440" id="statusProgress" text="{ResourceUtil.getInstance().getString('bbb.mainshell.statusProgress.loading')}"/>
</main:MainCanvas>
<mx:ControlBar width="100%" height="20" paddingTop="0">
<mx:Label text="{ResourceUtil.getInstance().getString('bbb.mainshell.copyrightLabel2',[appVersion])}" id="copyrightLabel2"/>
<mx:Spacer width="20"/>
<mx:Spacer width="100%"/>
<mx:Button width="20" height="20" toolTip="{ResourceUtil.getInstance().getString('bbb.mainshell.logBtn.toolTip')}" id="logBtn" icon="{logs_icon}" click="openLogWindow()" />
<mx:Button width="20" height="20" toolTip="{ResourceUtil.getInstance().getString('bbb.mainshell.fullScreenBtn.toolTip')}" id="fullScreen" icon="{fullscreen_icon}" click="toggleFullScreen()" />
<mx:Button width="20" height="20" toolTip="{ResourceUtil.getInstance().getString('bbb.mainshell.resetLayoutBtn.toolTip')}" id="btnResetLayout" icon="{reset_layout_icon}" click="resetLayout()" />
</mx:ControlBar>
</mx:VBox>

View File

@ -0,0 +1,103 @@
<?xml version="1.0" encoding="utf-8"?>
<containers:MDICanvas xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:containers="flexlib.mdi.containers.*" >
<mx:Script>
<![CDATA[
import flexlib.mdi.containers.MDIWindow;
import mx.controls.Alert;
import org.bigbluebutton.common.IBbbModuleWindow;
public static const TOP_LEFT:String = "TOP_LEFT_WINDOW";
public static const BOTTOM_LEFT:String = "BOTTOM_LEFT_WINDOW";
public static const MIDDLE:String = "MIDDLE_WINDOW";
public static const BOTTOM:String = "BOTTOM_WINDOW";
public static const RIGHT:String = "RIGHT_WINDOW";
public static const POPUP:String = "POP_UP_WINDOW";
private var leftWindowWidth:Number;
private var leftWindowHeight:Number;
private var centerWindowWidth:Number;
private var centerWindowHeight:Number;
private var rightWindowWidth:Number;
private var rightWindowHeight:Number;
private function determineWindowSizes():void{
}
public function addWindow(window:IBbbModuleWindow):void{
windowManager.add(window as MDIWindow);
positionWindow(window);
}
public function removeWindow(window:IBbbModuleWindow):void{
windowManager.remove(window as MDIWindow);
}
public function resetWindowLayout():void{
/*var windows:Array = mdiCanvas.windowManager.getOpenWindowList();
for (var i:Number=0; i<windows.length; i++){
var window:IBbbModuleWindow = windows[i] as IBbbModuleWindow;
mdiCanvas.windowManager.absPos(window as MDIWindow, window.xPosition, window.yPosition);
window.resetWidthAndHeight();
}*/
}
public function positionWindow(window:IBbbModuleWindow):void{
leftWindowHeight = this.height/2 - 30;
leftWindowWidth = (this.width / 20) * 3;
rightWindowHeight = this.height - 10;
rightWindowWidth = this.width / 3;
centerWindowHeight = this.height - 10;
centerWindowWidth = this.width / 2;
var position:String = window.getPrefferedPosition();
var win:MDIWindow = window as MDIWindow;
var x:Number;
var y:Number;
switch(position){
case TOP_LEFT:
x = 1;
y = 1;
win.width = leftWindowWidth;
win.height = leftWindowHeight;
break;
case BOTTOM_LEFT:
x = 1;
y = leftWindowHeight + 50;
win.width = leftWindowWidth;
win.height = leftWindowHeight;
break;
case MIDDLE:
x = this.width - rightWindowWidth - centerWindowWidth;
y = 1;
win.width = centerWindowWidth;
win.height = centerWindowHeight;
break;
case BOTTOM:
x = 1;
y = this.height - 300;
win.width = this.width - 5;
win.height = 300;
break;
case RIGHT:
x = this.width - rightWindowWidth - 10;
y = 1;
win.width = rightWindowWidth;
win.height = rightWindowHeight;
break;
case POPUP:
x = 200;
y = 200;
break;
}
windowManager.absPos(win, x, y);
}
]]>
</mx:Script>
</containers:MDICanvas>

View File

@ -130,7 +130,7 @@
public function openWindow(window:IBbbModuleWindow):void {
mdiCanvas.windowManager.add(window as MDIWindow);
mdiCanvas.windowManager.absPos(window as MDIWindow, window.xPosition, window.yPosition);
//mdiCanvas.windowManager.absPos(window as MDIWindow, window.xPosition, window.yPosition);
}
]]>
</mx:Script>

View File

@ -27,8 +27,6 @@ package org.bigbluebutton.modules.chat.maps
public function openChatWindow():void {
_chatWindow.title = ResourceUtil.getInstance().getString("bbb.chat.title");
_chatWindow.showCloseButton = false;
_chatWindow.xPosition = 752;
_chatWindow.yPosition = 0;
// Set the local dispatcher for this window so that it can send messages
// that can be heard by the LocalEventMap.

View File

@ -1,110 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
BigBlueButton - http://www.bigbluebutton.org
Copyright (c) 2008-2009 by respective authors (see below). All rights reserved.
BigBlueButton 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 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/>.
$Id: $
-->
<MDIWindow xmlns="flexlib.mdi.containers.*"
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:chat="org.bigbluebutton.modules.chat.views.components.*"
width="{_defaultWidth}" height="{_defaultHeight}" showCloseButton="false"
implements="org.bigbluebutton.common.IBbbModuleWindow"
creationComplete="onCreationComplete()"
xmlns:components="org.bigbluebutton.modules.chat.view.components.*" xmlns:mate="http://mate.asfusion.com/">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import flexlib.mdi.events.MDIWindowEvent;
import mx.core.Application;
private var _xPosition:int;
private var _yPosition:int;
private var localDispatcher:IEventDispatcher;
private var dispState:String;
[Bindable] private var _defaultWidth:int = 470;
[Bindable] private var _defaultHeight:int = 450;
public function get defaultWidth():int{
return _defaultWidth;
}
public function get defaultHeight():int{
return _defaultHeight;
}
public function set defaultHeight(height:int):void{
this._defaultHeight = height;
}
public function set defaultWidth(width:int):void{
this._defaultWidth = width;
}
public function resetWidthAndHeight():void{
this.width = _defaultWidth;
this.height = _defaultHeight;
}
public function get xPosition():int {
return _xPosition;
}
public function get yPosition():int {
return _yPosition;
}
public function set xPosition(x:int):void {
_xPosition = x;
}
public function set yPosition(y:int):void {
_yPosition = y;
}
public function setLocalDispatcher(dispatcher:IEventDispatcher):void {
localDispatcher = dispatcher;
}
private function onCreationComplete():void {
chatView.localDispatcher = localDispatcher;
/* Set up full screen handler. */
Application.application.stage.addEventListener(FullScreenEvent.FULL_SCREEN, fullScreenHandler);
dispState = Application.application.stage.displayState;
}
private function fullScreenHandler(evt:FullScreenEvent):void {
dispState = Application.application.stage.displayState + " (fullScreen=" + evt.fullScreen.toString() + ")";
if (evt.fullScreen) {
chatView.txtMsg.text = "Chat not enabled in full screen mode";
chatView.txtMsg.enabled = false;
} else {
chatView.txtMsg.text = "";
chatView.txtMsg.enabled = true;
}
}
]]>
</mx:Script>
<chat:ChatView id="chatView"/>
</MDIWindow>
<?xml version="1.0" encoding="utf-8"?>
<!--
BigBlueButton - http://www.bigbluebutton.org
Copyright (c) 2008-2009 by respective authors (see below). All rights reserved.
BigBlueButton 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 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/>.
$Id: $
-->
<MDIWindow xmlns="flexlib.mdi.containers.*"
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:chat="org.bigbluebutton.modules.chat.views.components.*"
showCloseButton="false"
implements="org.bigbluebutton.common.IBbbModuleWindow"
creationComplete="onCreationComplete()"
xmlns:components="org.bigbluebutton.modules.chat.view.components.*" xmlns:mate="http://mate.asfusion.com/">
<mx:Script>
<![CDATA[
import flexlib.mdi.events.MDIWindowEvent;
import mx.controls.Alert;
import mx.core.Application;
import org.bigbluebutton.main.view.components.MainCanvas;
private var _xPosition:int;
private var _yPosition:int;
private var localDispatcher:IEventDispatcher;
private var dispState:String;
public function getPrefferedPosition():String{
return MainCanvas.RIGHT;
}
public function setLocalDispatcher(dispatcher:IEventDispatcher):void {
localDispatcher = dispatcher;
}
private function onCreationComplete():void {
chatView.localDispatcher = localDispatcher;
/* Set up full screen handler. */
Application.application.stage.addEventListener(FullScreenEvent.FULL_SCREEN, fullScreenHandler);
dispState = Application.application.stage.displayState;
}
private function fullScreenHandler(evt:FullScreenEvent):void {
dispState = Application.application.stage.displayState + " (fullScreen=" + evt.fullScreen.toString() + ")";
if (evt.fullScreen) {
chatView.txtMsg.text = "Chat not enabled in full screen mode";
chatView.txtMsg.enabled = false;
} else {
chatView.txtMsg.text = "";
chatView.txtMsg.enabled = true;
}
}
]]>
</mx:Script>
<chat:ChatView id="chatView"/>
</MDIWindow>

View File

@ -149,8 +149,6 @@ package org.bigbluebutton.modules.deskShare.managers
public function handleStartSharingEvent():void {
LogUtil.debug("opening desk share window");
shareWindow = new DesktopPublishWindow();
shareWindow.xPosition = 675;
shareWindow.yPosition = 310;
shareWindow.initWindow(service.getConnection(), module.getCaptureServerUri(), module.getRoom());
openWindow(shareWindow);
}

View File

@ -38,7 +38,6 @@
<mate:Listener type="{CursorEvent.UPDATE_CURSOR_LOC_EVENT}" method="onUpdateCursorEvent" />
<mx:Script>
<![CDATA[
import org.bigbluebutton.modules.deskShare.events.CursorEvent;
import com.asfusion.mate.events.Dispatcher;
import flexlib.mdi.events.MDIWindowEvent;
@ -48,7 +47,9 @@
import org.bigbluebutton.common.Images;
import org.bigbluebutton.main.events.BBBEvent;
import org.bigbluebutton.main.events.MadePresenterEvent;
import org.bigbluebutton.main.view.components.MainCanvas;
import org.bigbluebutton.modules.deskShare.events.AppletStartedEvent;
import org.bigbluebutton.modules.deskShare.events.CursorEvent;
import org.bigbluebutton.modules.deskShare.events.ShareWindowEvent;
import org.bigbluebutton.modules.deskShare.events.StreamEvent;
@ -58,9 +59,6 @@
[Bindable] public var bbbLogo:Class = images.bbb_logo;
[Bindable] private var cursorIcon:Class = images.cursorIcon;
private var _xPosition:int = 675;
private var _yPosition:int = 310;
private var connection:NetConnection;
private var uri:String;
private var room:String;
@ -90,22 +88,6 @@
cursor.graphics.drawCircle(0,0,3);
}
public function get xPosition():int {
return _xPosition;
}
public function get yPosition():int {
return _yPosition;
}
public function set xPosition(x:int):void {
_xPosition = x;
}
public function set yPosition(y:int):void {
_yPosition = y;
}
public function get defaultWidth():int{
return this.width;
@ -122,6 +104,10 @@
public function set defaultWidth(width:int):void{
this.width = width;
}
public function getPrefferedPosition():String{
return MainCanvas.POPUP;
}
/*
* Implement resizeable interface.
@ -159,13 +145,7 @@
private function onUpdateCursorEvent(event:CursorEvent):void {
cursor.x = ((event.x/captureWidth)) * videoHolder.width;
cursor.y = ((event.y/captureHeight)) * videoHolder.height;
// cursor.visible = true;
cursorImg.visible = true;
cursorMove.end();
cursorMove.xTo=cursor.x;
cursorMove.yTo=cursor.y;
cursorMove.play();
cursor.visible = true;
}
private function onAppletStart(event:AppletStartedEvent):void{
@ -190,7 +170,6 @@
videoHolder.height = captureHeight/SCALE;
videoHolder.addChild(video);
videoHolder.addChild(cursor);
videoHolder.addChild(cursorImg);
cursor.visible = false;
this.addChild(videoHolder);
this.width = video.width + 6;
@ -250,7 +229,4 @@
]]>
</mx:Script>
<mx:Move id="cursorMove" target="{cursorImg}"/>
<mx:Image id="cursorImg" visible="false" source="@Embed('../../assets/images/Cursor.png')"/>
</MDIWindow>

View File

@ -38,7 +38,6 @@
<mx:Script>
<![CDATA[
import org.bigbluebutton.modules.deskShare.events.CursorEvent;
import com.asfusion.mate.events.Dispatcher;
import flexlib.mdi.events.MDIWindowEvent;
@ -46,6 +45,8 @@
import mx.core.UIComponent;
import org.bigbluebutton.common.Images;
import org.bigbluebutton.main.view.components.MainCanvas;
import org.bigbluebutton.modules.deskShare.events.CursorEvent;
import org.bigbluebutton.modules.deskShare.events.StartedViewingEvent;
import org.bigbluebutton.modules.deskShare.events.ViewStreamEvent;
import org.bigbluebutton.modules.deskShare.events.ViewWindowEvent;
@ -63,9 +64,6 @@
private var videoHeight:Number;
private var videoWidth:Number;
private var _xPosition:int = 675;
private var _yPosition:int = 310;
private static const VIDEO_WIDTH_PADDING:int = 7;
private static const VIDEO_HEIGHT_PADDING:int = 65;
@ -198,46 +196,10 @@
stopViewing();
break;
}
}
public function get xPosition():int {
return _xPosition;
}
public function get yPosition():int {
return _yPosition;
}
public function set xPosition(x:int):void {
_xPosition = x;
}
public function set yPosition(y:int):void {
_yPosition = y;
}
private var _defaultWidth:int = 400;
private var _defaultHeight:int = 300;
public function get defaultWidth():int{
return _defaultWidth;
}
public function get defaultHeight():int{
return _defaultHeight;
}
public function set defaultHeight(height:int):void{
this._defaultHeight = height;
}
public function set defaultWidth(width:int):void{
this._defaultWidth = width;
}
public function resetWidthAndHeight():void{
this.width = _defaultWidth;
this.height = _defaultHeight;
public function getPrefferedPosition():String{
return MainCanvas.POPUP;
}
/**
@ -312,11 +274,9 @@
if (btnActualSize.selected) {
fitToActualSize();
btnActualSize.toolTip = "Fit to window";
btnActualSize.label = "Fit to window";
} else {
fitToWindow();
btnActualSize.toolTip = "Display actual size";
btnActualSize.label = "Display actual size";
}
}
@ -332,6 +292,6 @@
<mx:Button id="btnActualSize" toggle="true" click="determineHowToDisplayVideo()" selected="true"
height="90%" icon="{btnActualSize.selected ? fitToActualSizeIcon : fitToWidthIcon}"
toolTip="Display actual size" />
<!--mx:Label text="Click to toggle between fit-to-window and actual screen size. Resize the window to see more of the presenters' screen" /-->
<mx:Label text="Click to toggle between fit-to-window and actual screen size. Resize the window to see more of the presenters' screen" />
</mx:ControlBar>
</MDIWindow>

View File

@ -1,138 +1,138 @@
/*
* BigBlueButton - http://www.bigbluebutton.org
*
* Copyright (c) 2008-2009 by respective authors (see below). All rights reserved.
*
* BigBlueButton 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 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, If not, see <http://www.gnu.org/licenses/>.
*
* $Id: $
*/
package org.bigbluebutton.modules.highlighter.business.shapes
{
import flash.display.Shape;
/**
* The ShapeFactory receives DrawObjects and converts them to Flash Shapes which can then be displayed
* <p>
* This approach is necessary because Red5 does not allow Graphical Objects to be stored
* in remote shared objects
* @author dzgonjan
*
*/
public class ShapeFactory
{
private var drawFactory:DrawObjectFactory;
public function ShapeFactory()
{
drawFactory = new DrawObjectFactory();
}
/**
* Creates a Flash Shape, given a DrawObject representation of it
* @param shape
* @return
*
*/
public function makeShape(shape:DrawObject):Shape{
var s:Shape = null;
if (shape.getType() == DrawObject.PENCIL){
s = makePencil(Pencil(shape));
} else if (shape.getType() == DrawObject.RECTANGLE){
s = makeRectangle(Rectangle(shape));
} else if (shape.getType() == DrawObject.ELLIPSE){
s = makeEllipse(Ellipse(shape));
}
return s;
}
/**
* Creates a shape from the specified parameters
* @param segment
* @param type
* @param color
* @param thickness
* @return A Flash Shape object
*
*/
public function makeFeedback(segment:Array, type:String, color:uint, thickness:uint):Shape{
return makeShape(drawFactory.makeDrawObject(type,segment, color, thickness));
}
/**
* Creates a Flash Shape from a Pencil DrawObject
* @param p a Pencil DrawObject
* @return a Shape
*
*/
private function makePencil(p:Pencil):Shape{
var newShape:Shape = new Shape();
newShape.graphics.lineStyle(p.getThickness(), p.getColor());
newShape.graphics.moveTo(p.getShapeArray()[0], p.getShapeArray()[1]);
for (var c:Number = 2; c < p.getShapeArray().length ; c += 2){
newShape.graphics.lineTo(p.getShapeArray()[c],p.getShapeArray()[c+1]);
}
if (p.getColor() == 0x000000) newShape.alpha = 1;
else newShape.alpha = 0.6;
return newShape;
}
/**
* Creates a Flash Shape from a Rectangle DrawObject
* @param r a Rectangle DrawObject
* @return a Shape
*
*/
private function makeRectangle(r:Rectangle):Shape{
var newShape:Shape = new Shape();
newShape.graphics.lineStyle(r.getThickness(), r.getColor());
var arrayEnd:Number = r.getShapeArray().length;
var x:Number = r.getShapeArray()[0];
var y:Number = r.getShapeArray()[1];
var width:Number = r.getShapeArray()[arrayEnd-2] - x;
var height:Number = r.getShapeArray()[arrayEnd-1] - y;
newShape.graphics.drawRect(x,y,width,height);
if (r.getColor() == 0x000000) newShape.alpha = 1.0;
else newShape.alpha = 0.6;
return newShape;
}
/**
* Creates a Flash Shape from an Ellipse DrawObject
* @param e an Ellipse DrawObject
* @return a Shape
*
*/
private function makeEllipse(e:Ellipse):Shape{
var newShape:Shape = new Shape();
newShape.graphics.lineStyle(e.getThickness(), e.getColor());
var arrayEnd:Number = e.getShapeArray().length;
var x:Number = e.getShapeArray()[0];
var y:Number = e.getShapeArray()[1];
var width:Number = e.getShapeArray()[arrayEnd-2] - x;
var height:Number = e.getShapeArray()[arrayEnd-1] - y;
newShape.graphics.drawEllipse(x,y,width,height);
if (e.getColor() == 0x000000) newShape.alpha = 1.0;
else newShape.alpha = 0.6;
return newShape;
}
}
/*
* BigBlueButton - http://www.bigbluebutton.org
*
* Copyright (c) 2008-2009 by respective authors (see below). All rights reserved.
*
* BigBlueButton 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 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, If not, see <http://www.gnu.org/licenses/>.
*
* $Id: $
*/
package org.bigbluebutton.modules.highlighter.business.shapes
{
import flash.display.Shape;
/**
* The ShapeFactory receives DrawObjects and converts them to Flash Shapes which can then be displayed
* <p>
* This approach is necessary because Red5 does not allow Graphical Objects to be stored
* in remote shared objects
* @author dzgonjan
*
*/
public class ShapeFactory
{
private var drawFactory:DrawObjectFactory;
public function ShapeFactory()
{
drawFactory = new DrawObjectFactory();
}
/**
* Creates a Flash Shape, given a DrawObject representation of it
* @param shape
* @return
*
*/
public function makeShape(shape:DrawObject):Shape{
var s:Shape = null;
if (shape.getType() == DrawObject.PENCIL){
s = makePencil(Pencil(shape));
} else if (shape.getType() == DrawObject.RECTANGLE){
s = makeRectangle(Rectangle(shape));
} else if (shape.getType() == DrawObject.ELLIPSE){
s = makeEllipse(Ellipse(shape));
}
return s;
}
/**
* Creates a shape from the specified parameters
* @param segment
* @param type
* @param color
* @param thickness
* @return A Flash Shape object
*
*/
public function makeFeedback(segment:Array, type:String, color:uint, thickness:uint):Shape{
return makeShape(drawFactory.makeDrawObject(type,segment, color, thickness));
}
/**
* Creates a Flash Shape from a Pencil DrawObject
* @param p a Pencil DrawObject
* @return a Shape
*
*/
private function makePencil(p:Pencil):Shape{
var newShape:Shape = new Shape();
newShape.graphics.lineStyle(p.getThickness(), p.getColor());
newShape.graphics.moveTo(p.getShapeArray()[0], p.getShapeArray()[1]);
for (var c:Number = 2; c < p.getShapeArray().length ; c += 2){
newShape.graphics.lineTo(p.getShapeArray()[c],p.getShapeArray()[c+1]);
}
if (p.getColor() == 0x000000 || p.getColor() == 0xFFFFFF) newShape.alpha = 1;
else newShape.alpha = 0.6;
return newShape;
}
/**
* Creates a Flash Shape from a Rectangle DrawObject
* @param r a Rectangle DrawObject
* @return a Shape
*
*/
private function makeRectangle(r:Rectangle):Shape{
var newShape:Shape = new Shape();
newShape.graphics.lineStyle(r.getThickness(), r.getColor());
var arrayEnd:Number = r.getShapeArray().length;
var x:Number = r.getShapeArray()[0];
var y:Number = r.getShapeArray()[1];
var width:Number = r.getShapeArray()[arrayEnd-2] - x;
var height:Number = r.getShapeArray()[arrayEnd-1] - y;
newShape.graphics.drawRect(x,y,width,height);
if (r.getColor() == 0x000000 || r.getColor() == 0xFFFFFF) newShape.alpha = 1.0;
else newShape.alpha = 0.6;
return newShape;
}
/**
* Creates a Flash Shape from an Ellipse DrawObject
* @param e an Ellipse DrawObject
* @return a Shape
*
*/
private function makeEllipse(e:Ellipse):Shape{
var newShape:Shape = new Shape();
newShape.graphics.lineStyle(e.getThickness(), e.getColor());
var arrayEnd:Number = e.getShapeArray().length;
var x:Number = e.getShapeArray()[0];
var y:Number = e.getShapeArray()[1];
var width:Number = e.getShapeArray()[arrayEnd-2] - x;
var height:Number = e.getShapeArray()[arrayEnd-1] - y;
newShape.graphics.drawEllipse(x,y,width,height);
if (e.getColor() == 0x000000 || e.getColor() == 0xFFFFFF) newShape.alpha = 1.0;
else newShape.alpha = 0.6;
return newShape;
}
}
}

View File

@ -10,6 +10,8 @@ package org.bigbluebutton.modules.highlighter.events
public static const DISABLE_WHITEBOARD:String = "disable_whiteboard";
public static const WHITEBOARD_ADDED_TO_PRESENTATION:String = "whiteboard_added";
public static const CHANGE_TO_PENCIL:String = "change-to-pencil";
public var window:PresentationWindow;
public function WhiteboardButtonEvent(type:String)

View File

@ -48,9 +48,6 @@ package org.bigbluebutton.modules.highlighter.managers
}
private function addHighlighterToolbar(e:TimerEvent):void{
//var toolbarEvent:AddPresentationToolbarEvent = new AddPresentationToolbarEvent(AddPresentationToolbarEvent.ADD_TOOLBAR);
//toolbarEvent.toolbar = highlighterToolbar;
//globalDispatcher.dispatchEvent(toolbarEvent);
var buttonEvent:AddButtonToPresentationEvent = new AddButtonToPresentationEvent(AddButtonToPresentationEvent.ADD_BUTTON);
buttonEvent.button = whiteboardButton;
globalDispatcher.dispatchEvent(buttonEvent);

View File

@ -5,6 +5,7 @@
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.core.Application;
import mx.managers.CursorManager;
@ -15,6 +16,7 @@
import org.bigbluebutton.modules.highlighter.business.shapes.DrawObjectFactory;
import org.bigbluebutton.modules.highlighter.business.shapes.ShapeFactory;
import org.bigbluebutton.modules.highlighter.events.HighlighterDrawEvent;
import org.bigbluebutton.modules.highlighter.events.HighlighterPresenterEvent;
import org.bigbluebutton.modules.highlighter.events.HighlighterUpdate;
import org.bigbluebutton.modules.highlighter.events.PageEvent;
import org.bigbluebutton.modules.highlighter.events.WhiteboardButtonEvent;
@ -38,8 +40,8 @@
protected var bbbCanvas:IBbbCanvas;
protected var shapeStyle:String = DrawObject.PENCIL;
protected var drawColor:uint = 0xCCFF00;
protected var thickness:uint = 10;
protected var drawColor:uint = 0x000000;
protected var thickness:uint = 1;
private var _xPosition:int;
private var _yPosition:int;

View File

@ -5,10 +5,10 @@
<mate:Listener type="{MadePresenterEvent.SWITCH_TO_PRESENTER_MODE}" method="presenterMode" />
<mate:Listener type="{MadePresenterEvent.SWITCH_TO_VIEWER_MODE}" method="viewerMode" />
<!--<mate:Listener type="{PresentationEvent.PRESENTATION_LOADED}" method="showToolbar" />-->
<mate:Listener type="{WhiteboardButtonEvent.DISABLE_WHITEBOARD}" method="disableWhiteboard" />
<mate:Listener type="{WhiteboardButtonEvent.ENABLE_WHITEBOARD}" method="enableWhiteboard" />
<mate:Listener type="{StopHighlighterModuleEvent.STOP_HIGHLIGHTER_MODULE_EVENT}" method="closeToolbar" />
<mate:Listener type="{WhiteboardButtonEvent.CHANGE_TO_PENCIL}" method="setShapeToPencil" />
<mx:Style>
.colorPickerStyle {
@ -55,8 +55,8 @@
public var canvas:HighlighterCanvas;
private var presentationWindow:PresentationWindow;
[Bindable] private var colorPickerColours:Array = ['0xCCFF00', '0xFF0000', '0xFF8800',
'0xFFFF00', '0x000000', '0x00FF00', '0x00FF88', '0x00FFFF',
[Bindable] private var colorPickerColours:Array = ['0x000000', '0xFFFFFF' , '0xFF0000', '0xFF8800',
'0xCCFF00', '0x00FF00', '0x00FF88', '0x00FFFF',
'0x0088FF', '0x0000FF', '0x8800FF', '0xFF00FF'];
/**
@ -66,6 +66,28 @@
*/
protected function setShape(s:String):void{
canvas.setShape(s);
switch(s){
case DrawObject.PENCIL:
btnPenc.selected = true;
btnEllipse.selected = false;
btnRectangle.selected = false;
break;
case DrawObject.ELLIPSE:
btnPenc.selected = false;
btnEllipse.selected = true;
btnRectangle.selected = false;
break;
case DrawObject.RECTANGLE:
btnPenc.selected = false;
btnEllipse.selected = false;
btnRectangle.selected = true;
break;
}
}
private function setShapeToPencil(e:WhiteboardButtonEvent):void{
this.setShape(DrawObject.PENCIL);
}
/**
@ -139,16 +161,16 @@
]]>
</mx:Script>
<mx:Button width="20" height="20" id="btnPenc" click="setShape(DrawObject.PENCIL)" icon="{pencil_icon}" toolTip="Highlighter" />
<mx:Button width="20" height="20" id="btnRectangle" click="setShape(DrawObject.RECTANGLE)" icon="{rectangle_icon}" toolTip="Rectangle" />
<mx:Button width="20" height="20" id="btnEllipse" click="setShape(DrawObject.ELLIPSE)" icon="{ellipse_icon}" toolTip="Circle" />
<mx:Button width="20" height="20" id="btnPenc" click="setShape(DrawObject.PENCIL)" icon="{pencil_icon}" toolTip="Highlighter" toggle="true" selected="true" />
<mx:Button width="20" height="20" id="btnRectangle" click="setShape(DrawObject.RECTANGLE)" icon="{rectangle_icon}" toolTip="Rectangle" toggle="true" />
<mx:Button width="20" height="20" id="btnEllipse" click="setShape(DrawObject.ELLIPSE)" icon="{ellipse_icon}" toolTip="Circle" toggle="true" />
<mx:Spacer height="5" />
<mx:Button width="20" height="20" id="btnClear" click="dispatchEvent(new HighlighterDrawEvent(HighlighterDrawEvent.CLEAR_BOARD))" icon="{delete_icon}" toolTip="Clear Page" />
<mx:Button width="20" height="20" id="btnUndo" click="sendUndoCommand()" icon="{undo_icon}" toolTip="Undo Shape" />
<mx:Spacer height="5" />
<mx:ColorPicker change="changeColor(event)" id="cpik" swatchPanelStyleName="colorPickerStyle" dataProvider="{colorPickerColours}" selectedColor="0xCCFF00" toolTip="Select Color"/>
<mx:ColorPicker change="changeColor(event)" id="cpik" swatchPanelStyleName="colorPickerStyle" dataProvider="{colorPickerColours}" selectedColor="0x000000" toolTip="Select Color"/>
<mx:Spacer height="3" />
<mx:VSlider height="50" id="sld" change="changeThickness(event)" toolTip="Change Thickness" minimum="1" maximum="20"
useHandCursor="true" value="10" showDataTip="false" snapInterval="1" />
useHandCursor="true" value="1" showDataTip="false" snapInterval="1" />
</mx:VBox>

View File

@ -1,12 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<mx:Button xmlns:mx="http://www.adobe.com/2006/mxml" icon="{whiteboard_icon}" width="20" height="20" click="toggleWhiteboard()" visible="false"
implements="org.bigbluebutton.modules.present.api.IPresentationButton" xmlns:mate="http://mate.asfusion.com/" >
implements="org.bigbluebutton.modules.present.api.IPresentationButton" xmlns:mate="http://mate.asfusion.com/" toggle="true" >
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.core.Application;
import org.bigbluebutton.common.Images;
import org.bigbluebutton.modules.highlighter.events.HighlighterPresenterEvent;
import org.bigbluebutton.modules.highlighter.events.HighlighterUpdate;
import org.bigbluebutton.modules.highlighter.events.WhiteboardButtonEvent;
import org.bigbluebutton.modules.present.views.PresentationWindow;
@ -19,18 +20,21 @@
private function toggleWhiteboard():void{
this.whiteboardEnabled = !this.whiteboardEnabled;
if (this.whiteboardEnabled) this.selected = true;
else if (!this.whiteboardEnabled) this.selected = false;
if (whiteboardEnabled) sendEnableWhiteboardEvent();
else if (!whiteboardEnabled) sendDisableWhiteboardEvent();
}
private function sendEnableWhiteboardEvent():void{
dispatchEvent(new WhiteboardButtonEvent(WhiteboardButtonEvent.ENABLE_WHITEBOARD));
this.toolTip = "Disable Whiteboard";
this.toolTip = "Show Whiteboard";
}
private function sendDisableWhiteboardEvent():void{
dispatchEvent(new WhiteboardButtonEvent(WhiteboardButtonEvent.DISABLE_WHITEBOARD));
this.toolTip = "Enable Whiteboard";
this.toolTip = "Hide Whiteboard";
}
public function buttonAdded(buttonParent:PresentationWindow):void{
@ -42,8 +46,17 @@
}
private function checkWhiteboardKeyCombo(e:KeyboardEvent):void{
if (e.keyCode == 87){ //Shift-W
takeActionOnKeyPressed(e.keyCode);
}
private function takeActionOnKeyPressed(key:int):void{
if (key == 87){ //W
toggleWhiteboard();
} else if (key == 68){ //D
this.whiteboardEnabled = true;
this.selected = true;
sendEnableWhiteboardEvent();
dispatchEvent(new WhiteboardButtonEvent(WhiteboardButtonEvent.CHANGE_TO_PENCIL));
}
}

View File

@ -155,8 +155,6 @@ package org.bigbluebutton.modules.listeners.view
_listenersWindow.listeners = proxy.listeners;
_listenersWindow.moderator = proxy.isModerator();
_listenersWindow.showCloseButton = false;
_listenersWindow.xPosition = 0;
_listenersWindow.yPosition = 225;
facade.sendNotification(ListenersModuleConstants.ADD_WINDOW, _listenersWindow);
}

View File

@ -1,193 +1,157 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
BigBlueButton - http://www.bigbluebutton.org
Copyright (c) 2008-2009 by respective authors (see below). All rights reserved.
BigBlueButton 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 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, If not, see <http://www.gnu.org/licenses/>.
$Id: $
-->
<MDIWindow xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns="flexlib.mdi.containers.*"
implements="org.bigbluebutton.common.IBbbModuleWindow"
width="233" height="226"
title="{windowTitle}"
creationComplete="onCreationComplete()">
<mx:Script>
<![CDATA[
import flash.events.MouseEvent;
import flexlib.mdi.events.MDIWindowEvent;
import mx.binding.utils.BindingUtils;
import mx.collections.ArrayCollection;
import mx.controls.Image;
import mx.controls.Label;
import mx.events.ListEvent;
import org.bigbluebutton.modules.listeners.ListenersModuleConstants;
import org.bigbluebutton.modules.listeners.view.components.Images;
import org.bigbluebutton.modules.listeners.view.events.ListenerSelectedEvent;
import org.bigbluebutton.util.i18n.ResourceUtil;
private var images:Images = new Images();
private var _xPosition:int;
private var _yPosition:int;
[Bindable] private var muteAllIcon:Class = images.sound_mute;
[Bindable] private var unmuteAllIcon:Class = images.sound_none;
[Bindable] private var ejectIcon:Class = images.eject_user;
[Bindable] public var listeners:ArrayCollection;
[Bindable] public var moderator:Boolean;
[Bindable] private var windowTitle:String = ResourceUtil.getInstance().getString('bbb.listeners.title', ["",""]);
private function onCreationComplete():void {
BindingUtils.bindSetter(updateNumberOfListeners, listeners, "length");
}
private function updateNumberOfListeners(numListeners:int):void {
if (numListeners > 4)
windowTitle = ResourceUtil.getInstance().getString('bbb.listeners.title', [":", numListeners]) ;
else
windowTitle = ResourceUtil.getInstance().getString('bbb.listeners.title', ["", ""]) ;
}
//The following code block is to deal with a bug in FLexLib with MDI windows not responding well to being maximized
private var savedWindowWidth:Number;
private var savedWindowHeight:Number;
private var savedX:Number;
private var savedY:Number;
private var isMaximized:Boolean = false;
override public function maximize():void{
if (!isMaximized){
savedWindowHeight = this.height;
savedWindowWidth = this.width;
savedX = this.x;
savedY = this.y;
dispatchEvent(new MDIWindowEvent(MDIWindowEvent.MAXIMIZE, this));
isMaximized = true;
} else{
this.width = savedWindowWidth;
this.height = savedWindowHeight;
this.x = savedX;
this.y = savedY;
isMaximized = false;
//dispatchEvent(new MDIWindowEvent(MDIWindowEvent.RESTORE, this));
}
}
public function get xPosition():int {
return _xPosition;
}
public function get yPosition():int {
return _yPosition;
}
public function set xPosition(x:int):void {
_xPosition = x;
}
public function set yPosition(y:int):void {
_yPosition = y;
}
private var _defaultWidth:int = 233;
private var _defaultHeight:int = 226;
public function get defaultWidth():int{
return _defaultWidth;
}
public function get defaultHeight():int{
return _defaultHeight;
}
public function set defaultHeight(height:int):void{
this._defaultHeight = height;
}
public function set defaultWidth(width:int):void{
this._defaultWidth = width;
}
public function resetWidthAndHeight():void{
this.width = _defaultWidth;
this.height = _defaultHeight;
}
private function listenerSelectEvent(event:ListEvent):void {
dispatchEvent(new ListenerSelectedEvent(moderator , listeners.getItemAt(listenersList.selectedIndex).userid));
}
private function handleEjectButtonClick():void {
if ((listeners != null) && (listeners.length > 0)) {
dispatchEvent(new Event(ListenersModuleConstants.EJECT_LISTENER_EVENT));
ejectBtn.enabled = false;
}
}
/*private function handleMuteAllButtonClick():void {
if (unmuteAllBtn.selected) {
dispatchEvent(new Event(ListenersModuleConstants.MUTE_ALL))
} else {
dispatchEvent(new Event(ListenersModuleConstants.UNMUTE_ALL))
}
}*/
public function setMuteState(mute:Boolean):void{
if (mute){
muteAllBtn.toolTip = ResourceUtil.getInstance().getString('bbb.listeners.unmuteAllBtn.toolTip');
muteAllBtn.selected = true;
} else{
muteAllBtn.toolTip = ResourceUtil.getInstance().getString('bbb.listeners.muteAllBtn.toolTip');
muteAllBtn.selected = false;
}
}
private function toggleMuteState():void{
if (muteAllBtn.selected) dispatchEvent(new Event(ListenersModuleConstants.MUTE_ALL));
else if (!muteAllBtn.selected) dispatchEvent(new Event(ListenersModuleConstants.UNMUTE_ALL));
setMuteState(muteAllBtn.selected);
}
]]>
</mx:Script>
<mx:TileList id="listenersList" height="100%" width="100%" itemClick="listenerSelectEvent(event);"
itemRenderer="org.bigbluebutton.modules.listeners.view.components.ListenerItem"
maxColumns="1" rowHeight="25" dragEnabled="false" dataProvider="{listeners}">
</mx:TileList>
<mx:ControlBar width="100%">
<mx:Button id="muteAllBtn" icon="{muteAllIcon}" visible="{moderator}" toggle="true" selected="false"
toolTip="{ResourceUtil.getInstance().getString('bbb.listeners.muteAllBtn.toolTip')}"
click="toggleMuteState()" width="18" height="18"/>
<!--<mx:Button id="unmuteAllBtn" icon="{unmuteAllIcon}"
toolTip="{ResourceUtil.getInstance().getString('bbb.listeners.unmuteAllBtn.toolTip')}"
click="dispatchEvent(new Event(ListenersModuleConstants.UNMUTE_ALL))"
visible="{moderator}" width="18" height="18"/>-->
<mx:Spacer width="100%"/>
<mx:Button id="ejectBtn" icon="{ejectIcon}"
toolTip="{ResourceUtil.getInstance().getString('bbb.listeners.ejectBtn.toolTip')}"
click="handleEjectButtonClick()"
visible="{moderator}" enabled="false" width="18" height="18"/>
</mx:ControlBar>
</MDIWindow>
<?xml version="1.0" encoding="utf-8"?>
<!--
BigBlueButton - http://www.bigbluebutton.org
Copyright (c) 2008-2009 by respective authors (see below). All rights reserved.
BigBlueButton 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 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, If not, see <http://www.gnu.org/licenses/>.
$Id: $
-->
<MDIWindow xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns="flexlib.mdi.containers.*"
implements="org.bigbluebutton.common.IBbbModuleWindow"
title="{windowTitle}"
creationComplete="onCreationComplete()">
<mx:Script>
<![CDATA[
import flash.events.MouseEvent;
import flexlib.mdi.events.MDIWindowEvent;
import mx.binding.utils.BindingUtils;
import mx.collections.ArrayCollection;
import mx.controls.Image;
import mx.controls.Label;
import mx.events.ListEvent;
import org.bigbluebutton.main.view.components.MainCanvas;
import org.bigbluebutton.modules.listeners.ListenersModuleConstants;
import org.bigbluebutton.modules.listeners.view.components.Images;
import org.bigbluebutton.modules.listeners.view.events.ListenerSelectedEvent;
import org.bigbluebutton.util.i18n.ResourceUtil;
private var images:Images = new Images();
private var _xPosition:int;
private var _yPosition:int;
[Bindable] private var muteAllIcon:Class = images.sound_mute;
[Bindable] private var unmuteAllIcon:Class = images.sound_none;
[Bindable] private var ejectIcon:Class = images.eject_user;
[Bindable] public var listeners:ArrayCollection;
[Bindable] public var moderator:Boolean;
[Bindable] private var windowTitle:String = ResourceUtil.getInstance().getString('bbb.listeners.title', ["",""]);
private function onCreationComplete():void {
BindingUtils.bindSetter(updateNumberOfListeners, listeners, "length");
}
private function updateNumberOfListeners(numListeners:int):void {
if (numListeners > 4)
windowTitle = ResourceUtil.getInstance().getString('bbb.listeners.title', [":", numListeners]) ;
else
windowTitle = ResourceUtil.getInstance().getString('bbb.listeners.title', ["", ""]) ;
}
//The following code block is to deal with a bug in FLexLib with MDI windows not responding well to being maximized
private var savedWindowWidth:Number;
private var savedWindowHeight:Number;
private var savedX:Number;
private var savedY:Number;
private var isMaximized:Boolean = false;
override public function maximize():void{
if (!isMaximized){
savedWindowHeight = this.height;
savedWindowWidth = this.width;
savedX = this.x;
savedY = this.y;
dispatchEvent(new MDIWindowEvent(MDIWindowEvent.MAXIMIZE, this));
isMaximized = true;
} else{
this.width = savedWindowWidth;
this.height = savedWindowHeight;
this.x = savedX;
this.y = savedY;
isMaximized = false;
//dispatchEvent(new MDIWindowEvent(MDIWindowEvent.RESTORE, this));
}
}
public function getPrefferedPosition():String{
return MainCanvas.BOTTOM_LEFT;
}
private function listenerSelectEvent(event:ListEvent):void {
dispatchEvent(new ListenerSelectedEvent(moderator , listeners.getItemAt(listenersList.selectedIndex).userid));
}
private function handleEjectButtonClick():void {
if ((listeners != null) && (listeners.length > 0)) {
dispatchEvent(new Event(ListenersModuleConstants.EJECT_LISTENER_EVENT));
ejectBtn.enabled = false;
}
}
/*private function handleMuteAllButtonClick():void {
if (unmuteAllBtn.selected) {
dispatchEvent(new Event(ListenersModuleConstants.MUTE_ALL))
} else {
dispatchEvent(new Event(ListenersModuleConstants.UNMUTE_ALL))
}
}*/
public function setMuteState(mute:Boolean):void{
if (mute){
muteAllBtn.toolTip = ResourceUtil.getInstance().getString('bbb.listeners.unmuteAllBtn.toolTip');
muteAllBtn.selected = true;
} else{
muteAllBtn.toolTip = ResourceUtil.getInstance().getString('bbb.listeners.muteAllBtn.toolTip');
muteAllBtn.selected = false;
}
}
private function toggleMuteState():void{
if (muteAllBtn.selected) dispatchEvent(new Event(ListenersModuleConstants.MUTE_ALL));
else if (!muteAllBtn.selected) dispatchEvent(new Event(ListenersModuleConstants.UNMUTE_ALL));
setMuteState(muteAllBtn.selected);
}
]]>
</mx:Script>
<mx:TileList id="listenersList" height="100%" width="100%" itemClick="listenerSelectEvent(event);"
itemRenderer="org.bigbluebutton.modules.listeners.view.components.ListenerItem"
maxColumns="1" rowHeight="25" dragEnabled="false" dataProvider="{listeners}">
</mx:TileList>
<mx:ControlBar width="100%">
<mx:Button id="muteAllBtn" icon="{muteAllIcon}" visible="{moderator}" toggle="true" selected="false"
toolTip="{ResourceUtil.getInstance().getString('bbb.listeners.muteAllBtn.toolTip')}"
click="toggleMuteState()" width="18" height="18"/>
<!--<mx:Button id="unmuteAllBtn" icon="{unmuteAllIcon}"
toolTip="{ResourceUtil.getInstance().getString('bbb.listeners.unmuteAllBtn.toolTip')}"
click="dispatchEvent(new Event(ListenersModuleConstants.UNMUTE_ALL))"
visible="{moderator}" width="18" height="18"/>-->
<mx:Spacer width="100%"/>
<mx:Button id="ejectBtn" icon="{ejectIcon}"
toolTip="{ResourceUtil.getInstance().getString('bbb.listeners.ejectBtn.toolTip')}"
click="handleEjectButtonClick()"
visible="{moderator}" enabled="false" width="18" height="18"/>
</mx:ControlBar>
</MDIWindow>

File diff suppressed because it is too large Load Diff

View File

@ -1,478 +1,481 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
BigBlueButton - http://www.bigbluebutton.org
Copyright (c) 2008-2009 by respective authors (see below). All rights reserved.
BigBlueButton 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 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, If not, see <http://www.gnu.org/licenses/>.
$Id: $
-->
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:mate="http://mate.asfusion.com/"
xmlns:local="*"
width="100%" height="100%"
paddingBottom="5"
creationComplete="onCreationComplete()" verticalScrollPolicy="off" horizontalScrollPolicy="off"
rollOut="hideCursor()"
xmlns:views="org.bigbluebutton.modules.present.views.*"
implements="org.bigbluebutton.common.IBbbCanvas">
<mate:Listener type="{ZoomEvent.ZOOM}" method="handleZoomEvent" />
<mate:Listener type="{MoveEvent.MOVE}" method="handleMoveEvent" />
<mate:Listener type="{SlideEvent.SLIDE_LOADED}" method="handleSlideLoadedEvent" />
<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="{WindowResizedEvent.PRESENTATION_WINDOW_RESIZED_EVENT}" method="handleWindowResizeEvent"/>
<mate:Listener type="{PresenterCommands.RESIZE}" method="handleSlideResizeEvent"/>
<mx:Script>
<![CDATA[
import com.asfusion.mate.events.Dispatcher;
import flash.events.Event;
import mx.binding.utils.BindingUtils;
import mx.collections.ArrayCollection;
import mx.controls.Button;
import mx.events.FlexEvent;
import mx.events.ListEvent;
import org.bigbluebutton.common.IBbbCanvas;
import org.bigbluebutton.main.events.MadePresenterEvent;
import org.bigbluebutton.modules.present.events.CursorEvent;
import org.bigbluebutton.modules.present.events.DisplaySlideEvent;
import org.bigbluebutton.modules.present.events.MoveEvent;
import org.bigbluebutton.modules.present.events.PresenterCommands;
import org.bigbluebutton.modules.present.events.SlideEvent;
import org.bigbluebutton.modules.present.events.SlideResizedEvent;
import org.bigbluebutton.modules.present.events.UploadEvent;
import org.bigbluebutton.modules.present.events.WindowResizedEvent;
import org.bigbluebutton.modules.present.events.ZoomEvent;
private var zoomPercentage:int = 100;
private static const ZOOM_STEP:int = 5;
public static const THUMBNAILS_CLOSED:String = "ThumbnailsClosed";
/**
* Variables that holds the presenter's locations of the
* loader so we can move the participant's slides in the
* same scale to maintain sync on the presenter's cursor.
*/
private var presentersLoaderXOffsetFromCanvas:Number = 0;
private var presentersLoaderYOffsetFromCanvas:Number = 0;
/**
* Variables that stores the presenter's ratio between
* loader and canvas. We need to size the slide with the
* same scale as the presenter so that the cursor syncs
* properly.
*/
private var presentersLoaderCanvasWidthRatio:Number = 1;
private var presentersLoaderCanvasHeightRatio:Number = 1;
private var canvasMouseXOnMouseDown:int;
private var canvasMouseYOnMouseDown:int;
private var loaderXOnMouseDown:int;
private var loaderYOnMouseDown:int;
private var cursor:Shape;
private var overlayChildrenHolder:Canvas = new Canvas();
private var overlayCanvas:IBbbCanvas;
//The following few variables concern text selection
private var slideClip:MovieClip;
private var slideText:TextSnapshot;
private var firstChar:Number = -1;
private var lastChar:Number = -1;
[Bindable] public var slides:ArrayCollection;
[Bindable] public var selectedSlide:int=0;
[Bindable] private var isPresenter:Boolean = false;
private var dispatcher:Dispatcher = new Dispatcher();
private function onCreationComplete():void{
swfSlideLoader.width = this.width;
swfSlideLoader.height = this.height;
cursor = new Shape();
cursor.graphics.lineStyle(6, 0xFF0000, 0.6);
cursor.graphics.drawCircle(0,0,3);
this.rawChildren.addChild(cursor);
cursor.visible = false;
overlayChildrenHolder = new Canvas();
this.addChild(overlayChildrenHolder);
overlayChildrenHolder.x = 0;
overlayChildrenHolder.y = 0;
this.setChildIndex(thumbnailView, this.numChildren - 1);
}
public function setSlides(slides:ArrayCollection):void{
this.slides = slides;
thumbnailView.dataProvider = this.slides.toArray();
}
private function changeSlide():void{
dispatchEvent(new PresenterCommands(PresenterCommands.GOTO_SLIDE, thumbnailView.selectedIndex));
thumbnailView.visible = false;
showOverlayCanvas(true);
dispatchEvent(new Event(THUMBNAILS_CLOSED));
}
private function changeIndex(e:ListEvent):void{
dispatchEvent(e);
}
private function onMouseDown(e:MouseEvent):void{
canvasMouseXOnMouseDown = this.mouseX;
canvasMouseYOnMouseDown = this.mouseY;
loaderXOnMouseDown = swfSlideLoader.x;
loaderYOnMouseDown = swfSlideLoader.y;
addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
}
private function onMouseMove(e:MouseEvent):void {
var deltaCanvasMouseX:Number = this.mouseX - canvasMouseXOnMouseDown;
var deltaCanvasMouseY:Number = this.mouseY - canvasMouseYOnMouseDown;
swfSlideLoader.x = loaderXOnMouseDown + deltaCanvasMouseX/2;
swfSlideLoader.y = loaderYOnMouseDown + deltaCanvasMouseY/2;
fitSlideToLoader();
notifyOtherParticipantsOfSlideMoving();
}
private function notifyOtherParticipantsOfSlideMoving():void {
var presentEvent:PresenterCommands = new PresenterCommands(PresenterCommands.MOVE);
presentEvent.xOffset = swfSlideLoader.x/swfSlideLoader.width;
presentEvent.yOffset = swfSlideLoader.y/swfSlideLoader.height;
presentEvent.slideToCanvasWidthRatio = swfSlideLoader.width/this.width;
presentEvent.slideToCanvasHeightRatio = swfSlideLoader.height/this.height;
dispatchEvent(presentEvent);
}
private function onMouseUp(e:MouseEvent):void{
removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
}
private function onMouseOut(e:MouseEvent):void{
removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
}
private function handleWindowResizeEvent(event:WindowResizedEvent):void {
this.width = event.width;
this.height = event.height;
resizeAndMoveLoaderInRelationToCanvas();
}
private function resizeAndMoveLoaderInRelationToCanvas():void {
swfSlideLoader.width = this.width * presentersLoaderCanvasWidthRatio;
swfSlideLoader.height = this.height * presentersLoaderCanvasHeightRatio;
swfSlideLoader.x = swfSlideLoader.width * presentersLoaderXOffsetFromCanvas;
swfSlideLoader.y = swfSlideLoader.width * presentersLoaderYOffsetFromCanvas;
fitSlideToLoader();
}
private function fitSlideToLoader():void {
if (noSlideContentLoaded()) return;
swfSlideLoader.content.x = swfSlideLoader.x;
swfSlideLoader.content.y = swfSlideLoader.y;
swfSlideLoader.content.width = swfSlideLoader.width;
swfSlideLoader.content.height = swfSlideLoader.height;
zoomCanvas(swfSlideLoader.width, swfSlideLoader.height);
}
private function fitLoaderToCanvas():void{
if (noSlideContentLoaded()) return;
swfSlideLoader.width = this.width;
swfSlideLoader.height = this.height;
swfSlideLoader.x = this.x;
swfSlideLoader.y = this.y;
fitSlideToLoader();
}
private function resizeAndMoveLoaderBy(percent:Number):void {
// Save the old loader dimensions. We need these to calculate
// the new position of the loader;
var oldLoaderHeight:int = swfSlideLoader.height;
var oldLoaderWidth:int = swfSlideLoader.width;
swfSlideLoader.width = this.width * percent/100;
swfSlideLoader.height = this.height * percent/100;
swfSlideLoader.x = calculateNewLoaderX(oldLoaderWidth);
swfSlideLoader.y = calculateNewLoaderY(oldLoaderHeight);
fitSlideToLoader();
}
private function calculateNewLoaderY(oldLoaderHeight:int):int {
var deltaPercentHeight:Number = (swfSlideLoader.height - oldLoaderHeight) /oldLoaderHeight;
var newLoaderY:int = (swfSlideLoader.y/swfSlideLoader.height) * deltaPercentHeight;
if (newLoaderY == 0) {
newLoaderY = swfSlideLoader.y - (deltaPercentHeight * 100);
} else {
newLoaderY = swfSlideLoader.y - newLoaderY;
}
return newLoaderY;
}
private function calculateNewLoaderX(oldLoaderWidth:int):int {
var deltaPercentWidth:Number = (swfSlideLoader.width - oldLoaderWidth) / oldLoaderWidth;
var newLoaderX:int = (swfSlideLoader.x/swfSlideLoader.width) * deltaPercentWidth;
if (newLoaderX == 0) {
newLoaderX = swfSlideLoader.x - (deltaPercentWidth * 100);
} else {
newLoaderX = swfSlideLoader.x - newLoaderX;
}
return newLoaderX;
}
private function handleSlideResizeEvent(event:PresenterCommands):void {
zoomLoaderBy(event.newSizeInPercent);
}
private function zoomLoaderBy(percent:Number):void {
if (percent < 100) {
zoomPercentage = 100;
} else if (percent > 400) {
zoomPercentage = 400;
} else {
zoomPercentage = percent;
}
if (zoomPercentage == 100) {
fitLoaderToCanvas();
} else {
resizeAndMoveLoaderBy(zoomPercentage);
}
notifyOthersOfZoomEvent();
}
private function onMouseWheelZoomEvent(e:MouseEvent):void {
if (presenterIsZoomingOut(e.delta)) {
zoomPercentage -= ZOOM_STEP;
} else {
zoomPercentage += ZOOM_STEP;
}
zoomLoaderBy(zoomPercentage);
notifyListenersOfSlideResize(zoomPercentage);
}
private function notifyListenersOfSlideResize(percent:Number):void {
var event:SlideResizedEvent = new SlideResizedEvent();
event.percent = percent;
dispatcher.dispatchEvent(event);
}
private function notifyOthersOfZoomEvent():void {
var presentEvent:PresenterCommands = new PresenterCommands(PresenterCommands.ZOOM);
presentEvent.xOffset = swfSlideLoader.x/swfSlideLoader.width;
presentEvent.yOffset = swfSlideLoader.y/swfSlideLoader.height;
presentEvent.slideToCanvasWidthRatio = swfSlideLoader.width/this.width;
presentEvent.slideToCanvasHeightRatio = swfSlideLoader.height/this.height;
dispatchEvent(presentEvent);
}
private function presenterIsZoomingOut(delta:Number):Boolean {
// If delta is negative, the presenter is zooming-out of the presentation.
return delta < 0;
}
private function handleMoveEvent(e:MoveEvent):void{
savePresentersSettings(e.xOffset, e.yOffset, e.slideToCanvasWidthRatio, e.slideToCanvasHeightRatio);
if (!isPresenter) {
resizeAndMoveLoaderInRelationToCanvas();
}
moveCanvas(swfSlideLoader.x, swfSlideLoader.y);
}
private function handleZoomEvent(e:ZoomEvent):void {
savePresentersSettings(e.xOffset, e.yOffset, e.slideToCanvasWidthRatio, e.slideToCanvasHeightRatio);
if (!isPresenter) {
resizeAndMoveLoaderInRelationToCanvas();
}
zoomCanvas(swfSlideLoader.width, swfSlideLoader.height);
}
private function handleSlideLoadedEvent(e:SlideEvent):void{
swfSlideLoader.source = e.slide;
}
private function handleSwitchToViewerEvent(e:MadePresenterEvent):void{
participantIsNowPresenter(false);
removeEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheelZoomEvent);
swfSlideLoader.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
swfSlideLoader.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
swfSlideLoader.removeEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
removeEventListener(MouseEvent.MOUSE_MOVE, mouseCursorUpdateListener);
}
private function handleSwitchToPresenterEvent(e:MadePresenterEvent):void{
participantIsNowPresenter(true);
addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheelZoomEvent);
swfSlideLoader.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
swfSlideLoader.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
swfSlideLoader.addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
addEventListener(MouseEvent.MOUSE_MOVE, mouseCursorUpdateListener);
}
private function participantIsNowPresenter(presenter:Boolean):void {
this.isPresenter = presenter;
}
public function mouseCursorUpdateListener(e:MouseEvent):void{
if (noSlideContentLoaded()) return;
notifyOthersOfPresentersCursorPosition(this.mouseX, this.mouseY);
}
private function notifyOthersOfPresentersCursorPosition(cursorXPosition:int, cursorYPosition:int):void {
var command:PresenterCommands = new PresenterCommands(PresenterCommands.SEND_CURSOR_UPDATE);
command.xPercent = cursorXPosition / this.width;
command.yPercent = cursorYPosition / this.height;
dispatchEvent(command);
}
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 swfSlideLoader.content == null
}
private function savePresentersSettings(xOffset:Number, yOffset:Number, widthRatio:Number, heightRatio:Number):void {
presentersLoaderXOffsetFromCanvas = xOffset;
presentersLoaderYOffsetFromCanvas = yOffset;
presentersLoaderCanvasWidthRatio = widthRatio;
presentersLoaderCanvasHeightRatio = heightRatio;
}
/******************************************************
* Helper functions to determine offsets
******************************************************/
/*
* Fire an event when a single slide has been loaded.
*/
private function listenForSlideLoadedCompleteEvent():void {
swfSlideLoader.addEventListener(Event.COMPLETE, handleSlideLoadedCompleteEvent);
}
private function handleSlideLoadedCompleteEvent(event:Event):void {
var slideRealWidth:int = swfSlideLoader.content.width;
var slideRealHeight:int = swfSlideLoader.content.height;
fitLoaderToCanvas();
dispatchNewSlideDisplayedEvent(slideRealWidth, slideRealHeight);
}
private function dispatchNewSlideDisplayedEvent(slideRealWidth:int, slideRealHeight:int):void {
var dispEvent:DisplaySlideEvent = new DisplaySlideEvent(DisplaySlideEvent.DISPLAY_SLIDE_EVENT);
dispEvent.slideWidth = slideRealWidth;
dispEvent.slideHeight = slideRealHeight;
dispatcher.dispatchEvent(dispEvent);
}
private function isCursorOutsideWindow(e:CursorEvent):Boolean {
return (e.xPercent > 1 && e.yPercent > 1) || (cursor.x > this.width || cursor.y > this.height);
}
private function showCursor():void {
cursor.visible = true;
}
private function hideCursor():void{
cursor.visible = false;
}
/** Inherited from IBbbCanvas*/
public function addRawChild(child:DisplayObject):void{
this.overlayChildrenHolder.rawChildren.addChild(child);
}
public function removeRawChild(child:DisplayObject):void{
this.overlayChildrenHolder.rawChildren.removeChild(child);
}
public function doesContain(child:DisplayObject):Boolean{
return this.overlayChildrenHolder.rawChildren.contains(child);
}
public function acceptOverlayCanvas(overlay:IBbbCanvas):void{
overlayCanvas = overlay;
var c:Canvas = overlay as Canvas;
this.addChild(c);
c.x = 0;
c.y = 0;
}
public function moveCanvas(x:int, y:int):void{
overlayChildrenHolder.x = swfSlideLoader.x * 2;
overlayChildrenHolder.y = swfSlideLoader.y * 2;
if (overlayCanvas != null) overlayCanvas.moveCanvas(overlayChildrenHolder.x, overlayChildrenHolder.y);
}
public function zoomCanvas(width:int, height:int):void{
overlayChildrenHolder.width = width;
overlayChildrenHolder.height = height;
moveCanvas(swfSlideLoader.x, swfSlideLoader.y);
if (overlayCanvas != null) overlayCanvas.zoomCanvas(width, height);
}
public function showOverlayCanvas(show:Boolean):void{
overlayCanvas.showCanvas(show);
}
public function showCanvas(show:Boolean):void{
}
]]>
</mx:Script>
<mx:SWFLoader id="swfSlideLoader" width="100%" height="100%" creationComplete="listenForSlideLoadedCompleteEvent()"
scaleContent="false" maintainAspectRatio="true" showBusyCursor="true" completeEffect="Fade"/>
<mx:HorizontalList id="thumbnailView" itemRenderer="org.bigbluebutton.modules.present.views.Thumbnail" itemRollOver="changeIndex(event)"
visible="false" width="100%" height="100" y="{this.height - 100}" change="changeSlide()" />
</mx:Canvas>
<?xml version="1.0" encoding="utf-8"?>
<!--
BigBlueButton - http://www.bigbluebutton.org
Copyright (c) 2008-2009 by respective authors (see below). All rights reserved.
BigBlueButton 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 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, If not, see <http://www.gnu.org/licenses/>.
$Id: $
-->
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:mate="http://mate.asfusion.com/"
xmlns:local="*"
width="100%" height="100%"
paddingBottom="5"
creationComplete="onCreationComplete()" verticalScrollPolicy="off" horizontalScrollPolicy="off"
rollOut="hideCursor()"
xmlns:views="org.bigbluebutton.modules.present.views.*"
implements="org.bigbluebutton.common.IBbbCanvas">
<mate:Listener type="{ZoomEvent.ZOOM}" method="handleZoomEvent" />
<mate:Listener type="{MoveEvent.MOVE}" method="handleMoveEvent" />
<mate:Listener type="{SlideEvent.SLIDE_LOADED}" method="handleSlideLoadedEvent" />
<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="{WindowResizedEvent.PRESENTATION_WINDOW_RESIZED_EVENT}" method="handleWindowResizeEvent"/>
<mate:Listener type="{PresenterCommands.RESIZE}" method="handleSlideResizeEvent"/>
<mx:Script>
<![CDATA[
import com.asfusion.mate.events.Dispatcher;
import flash.events.Event;
import mx.binding.utils.BindingUtils;
import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.controls.Button;
import mx.events.FlexEvent;
import mx.events.ListEvent;
import org.bigbluebutton.common.IBbbCanvas;
import org.bigbluebutton.main.events.MadePresenterEvent;
import org.bigbluebutton.modules.present.events.CursorEvent;
import org.bigbluebutton.modules.present.events.DisplaySlideEvent;
import org.bigbluebutton.modules.present.events.MoveEvent;
import org.bigbluebutton.modules.present.events.PresenterCommands;
import org.bigbluebutton.modules.present.events.SlideEvent;
import org.bigbluebutton.modules.present.events.SlideResizedEvent;
import org.bigbluebutton.modules.present.events.UploadEvent;
import org.bigbluebutton.modules.present.events.WindowResizedEvent;
import org.bigbluebutton.modules.present.events.ZoomEvent;
public var zoomPercentage:int = 100;
public static const ZOOM_STEP:int = 5;
public static const THUMBNAILS_CLOSED:String = "ThumbnailsClosed";
/**
* Variables that holds the presenter's locations of the
* loader so we can move the participant's slides in the
* same scale to maintain sync on the presenter's cursor.
*/
private var presentersLoaderXOffsetFromCanvas:Number = 0;
private var presentersLoaderYOffsetFromCanvas:Number = 0;
/**
* Variables that stores the presenter's ratio between
* loader and canvas. We need to size the slide with the
* same scale as the presenter so that the cursor syncs
* properly.
*/
private var presentersLoaderCanvasWidthRatio:Number = 1;
private var presentersLoaderCanvasHeightRatio:Number = 1;
private var canvasMouseXOnMouseDown:int;
private var canvasMouseYOnMouseDown:int;
private var loaderXOnMouseDown:int;
private var loaderYOnMouseDown:int;
private var cursor:Shape;
private var overlayChildrenHolder:Canvas = new Canvas();
private var overlayCanvas:IBbbCanvas;
//The following few variables concern text selection
private var slideClip:MovieClip;
private var slideText:TextSnapshot;
private var firstChar:Number = -1;
private var lastChar:Number = -1;
[Bindable] public var slides:ArrayCollection;
[Bindable] public var selectedSlide:int=0;
[Bindable] private var isPresenter:Boolean = false;
private var dispatcher:Dispatcher = new Dispatcher();
private function onCreationComplete():void{
swfSlideLoader.width = this.width;
swfSlideLoader.height = this.height;
cursor = new Shape();
cursor.graphics.lineStyle(6, 0xFF0000, 0.6);
cursor.graphics.drawCircle(0,0,3);
this.rawChildren.addChild(cursor);
cursor.visible = false;
overlayChildrenHolder = new Canvas();
this.addChild(overlayChildrenHolder);
overlayChildrenHolder.x = 0;
overlayChildrenHolder.y = 0;
this.setChildIndex(thumbnailView, this.numChildren - 1);
}
public function setSlides(slides:ArrayCollection):void{
this.slides = slides;
thumbnailView.dataProvider = this.slides.toArray();
}
private function changeSlide():void{
dispatchEvent(new PresenterCommands(PresenterCommands.GOTO_SLIDE, thumbnailView.selectedIndex));
thumbnailView.visible = false;
showOverlayCanvas(true);
dispatchEvent(new Event(THUMBNAILS_CLOSED));
}
private function changeIndex(e:ListEvent):void{
dispatchEvent(e);
}
private function onMouseDown(e:MouseEvent):void{
canvasMouseXOnMouseDown = this.mouseX;
canvasMouseYOnMouseDown = this.mouseY;
loaderXOnMouseDown = swfSlideLoader.x;
loaderYOnMouseDown = swfSlideLoader.y;
addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
}
private function onMouseMove(e:MouseEvent):void {
var deltaCanvasMouseX:Number = this.mouseX - canvasMouseXOnMouseDown;
var deltaCanvasMouseY:Number = this.mouseY - canvasMouseYOnMouseDown;
swfSlideLoader.x = loaderXOnMouseDown + deltaCanvasMouseX/2;
swfSlideLoader.y = loaderYOnMouseDown + deltaCanvasMouseY/2;
fitSlideToLoader();
notifyOtherParticipantsOfSlideMoving();
}
private function notifyOtherParticipantsOfSlideMoving():void {
var presentEvent:PresenterCommands = new PresenterCommands(PresenterCommands.MOVE);
presentEvent.xOffset = swfSlideLoader.x/swfSlideLoader.width;
presentEvent.yOffset = swfSlideLoader.y/swfSlideLoader.height;
presentEvent.slideToCanvasWidthRatio = swfSlideLoader.width/this.width;
presentEvent.slideToCanvasHeightRatio = swfSlideLoader.height/this.height;
dispatchEvent(presentEvent);
}
private function onMouseUp(e:MouseEvent):void{
removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
}
private function onMouseOut(e:MouseEvent):void{
removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
}
private function handleWindowResizeEvent(event:WindowResizedEvent):void {
this.width = event.width;
this.height = event.height;
resizeAndMoveLoaderInRelationToCanvas();
}
private function resizeAndMoveLoaderInRelationToCanvas():void {
swfSlideLoader.width = this.width * presentersLoaderCanvasWidthRatio;
swfSlideLoader.height = this.height * presentersLoaderCanvasHeightRatio;
swfSlideLoader.x = swfSlideLoader.width * presentersLoaderXOffsetFromCanvas;
swfSlideLoader.y = swfSlideLoader.width * presentersLoaderYOffsetFromCanvas;
fitSlideToLoader();
}
private function fitSlideToLoader():void {
if (noSlideContentLoaded()) return;
swfSlideLoader.content.x = swfSlideLoader.x;
swfSlideLoader.content.y = swfSlideLoader.y;
swfSlideLoader.content.width = swfSlideLoader.width;
swfSlideLoader.content.height = swfSlideLoader.height;
zoomCanvas(swfSlideLoader.width, swfSlideLoader.height);
}
private function fitLoaderToCanvas():void{
if (noSlideContentLoaded()) return;
swfSlideLoader.width = this.width;
swfSlideLoader.height = this.height;
swfSlideLoader.x = this.x;
swfSlideLoader.y = this.y;
fitSlideToLoader();
}
private function resizeAndMoveLoaderBy(percent:Number):void {
// Save the old loader dimensions. We need these to calculate
// the new position of the loader;
var oldLoaderHeight:int = swfSlideLoader.height;
var oldLoaderWidth:int = swfSlideLoader.width;
swfSlideLoader.width = this.width * percent/100;
swfSlideLoader.height = this.height * percent/100;
swfSlideLoader.x = calculateNewLoaderX(oldLoaderWidth);
swfSlideLoader.y = calculateNewLoaderY(oldLoaderHeight);
fitSlideToLoader();
}
private function calculateNewLoaderY(oldLoaderHeight:int):int {
var deltaPercentHeight:Number = (swfSlideLoader.height - oldLoaderHeight) /oldLoaderHeight;
var newLoaderY:int = (swfSlideLoader.y/swfSlideLoader.height) * deltaPercentHeight;
if (newLoaderY == 0) {
newLoaderY = swfSlideLoader.y - (deltaPercentHeight * 100);
} else {
newLoaderY = swfSlideLoader.y - newLoaderY;
}
return newLoaderY;
}
private function calculateNewLoaderX(oldLoaderWidth:int):int {
var deltaPercentWidth:Number = (swfSlideLoader.width - oldLoaderWidth) / oldLoaderWidth;
var newLoaderX:int = (swfSlideLoader.x/swfSlideLoader.width) * deltaPercentWidth;
if (newLoaderX == 0) {
newLoaderX = swfSlideLoader.x - (deltaPercentWidth * 100);
} else {
newLoaderX = swfSlideLoader.x - newLoaderX;
}
return newLoaderX;
}
private function handleSlideResizeEvent(event:PresenterCommands):void {
zoomLoaderBy(event.newSizeInPercent);
}
public function zoomLoaderBy(percent:Number):void {
if (percent < 100) {
zoomPercentage = 100;
} else if (percent > 400) {
zoomPercentage = 400;
} else {
zoomPercentage = percent;
}
if (zoomPercentage == 100) {
fitLoaderToCanvas();
} else {
resizeAndMoveLoaderBy(zoomPercentage);
}
notifyOthersOfZoomEvent();
}
private function onMouseWheelZoomEvent(e:MouseEvent):void {
if (presenterIsZoomingOut(e.delta)) {
zoomPercentage -= ZOOM_STEP;
} else {
zoomPercentage += ZOOM_STEP;
}
zoomLoaderBy(zoomPercentage);
notifyListenersOfSlideResize(zoomPercentage);
}
public function notifyListenersOfSlideResize(percent:Number):void {
var event:SlideResizedEvent = new SlideResizedEvent();
event.percent = percent;
dispatcher.dispatchEvent(event);
}
private function notifyOthersOfZoomEvent():void {
var presentEvent:PresenterCommands = new PresenterCommands(PresenterCommands.ZOOM);
presentEvent.xOffset = swfSlideLoader.x/swfSlideLoader.width;
presentEvent.yOffset = swfSlideLoader.y/swfSlideLoader.height;
presentEvent.slideToCanvasWidthRatio = swfSlideLoader.width/this.width;
presentEvent.slideToCanvasHeightRatio = swfSlideLoader.height/this.height;
dispatchEvent(presentEvent);
}
private function presenterIsZoomingOut(delta:Number):Boolean {
// If delta is negative, the presenter is zooming-out of the presentation.
return delta < 0;
}
private function handleMoveEvent(e:MoveEvent):void{
savePresentersSettings(e.xOffset, e.yOffset, e.slideToCanvasWidthRatio, e.slideToCanvasHeightRatio);
if (!isPresenter) {
resizeAndMoveLoaderInRelationToCanvas();
}
moveCanvas(swfSlideLoader.x, swfSlideLoader.y);
}
private function handleZoomEvent(e:ZoomEvent):void {
savePresentersSettings(e.xOffset, e.yOffset, e.slideToCanvasWidthRatio, e.slideToCanvasHeightRatio);
if (!isPresenter) {
resizeAndMoveLoaderInRelationToCanvas();
}
zoomCanvas(swfSlideLoader.width, swfSlideLoader.height);
}
private function handleSlideLoadedEvent(e:SlideEvent):void{
swfSlideLoader.source = e.slide;
}
private function handleSwitchToViewerEvent(e:MadePresenterEvent):void{
participantIsNowPresenter(false);
removeEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheelZoomEvent);
swfSlideLoader.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
swfSlideLoader.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
swfSlideLoader.removeEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
removeEventListener(MouseEvent.MOUSE_MOVE, mouseCursorUpdateListener);
}
private function handleSwitchToPresenterEvent(e:MadePresenterEvent):void{
participantIsNowPresenter(true);
addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheelZoomEvent);
swfSlideLoader.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
swfSlideLoader.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
swfSlideLoader.addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
addEventListener(MouseEvent.MOUSE_MOVE, mouseCursorUpdateListener);
}
private function participantIsNowPresenter(presenter:Boolean):void {
this.isPresenter = presenter;
}
public function mouseCursorUpdateListener(e:MouseEvent):void{
if (noSlideContentLoaded()) return;
notifyOthersOfPresentersCursorPosition(this.mouseX, this.mouseY);
}
private function notifyOthersOfPresentersCursorPosition(cursorXPosition:int, cursorYPosition:int):void {
var command:PresenterCommands = new PresenterCommands(PresenterCommands.SEND_CURSOR_UPDATE);
command.xPercent = cursorXPosition / this.width;
command.yPercent = cursorYPosition / this.height;
dispatchEvent(command);
}
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 swfSlideLoader.content == null
}
private function savePresentersSettings(xOffset:Number, yOffset:Number, widthRatio:Number, heightRatio:Number):void {
presentersLoaderXOffsetFromCanvas = xOffset;
presentersLoaderYOffsetFromCanvas = yOffset;
presentersLoaderCanvasWidthRatio = widthRatio;
presentersLoaderCanvasHeightRatio = heightRatio;
}
/******************************************************
* Helper functions to determine offsets
******************************************************/
/*
* Fire an event when a single slide has been loaded.
*/
private function listenForSlideLoadedCompleteEvent():void {
swfSlideLoader.addEventListener(Event.COMPLETE, handleSlideLoadedCompleteEvent);
}
private function handleSlideLoadedCompleteEvent(event:Event):void {
var slideRealWidth:int = swfSlideLoader.content.width;
var slideRealHeight:int = swfSlideLoader.content.height;
fitLoaderToCanvas();
dispatchNewSlideDisplayedEvent(slideRealWidth, slideRealHeight);
}
private function dispatchNewSlideDisplayedEvent(slideRealWidth:int, slideRealHeight:int):void {
var dispEvent:DisplaySlideEvent = new DisplaySlideEvent(DisplaySlideEvent.DISPLAY_SLIDE_EVENT);
dispEvent.slideWidth = slideRealWidth;
dispEvent.slideHeight = slideRealHeight;
dispatcher.dispatchEvent(dispEvent);
}
private function isCursorOutsideWindow(e:CursorEvent):Boolean {
return (e.xPercent > 1 && e.yPercent > 1) || (cursor.x > this.width || cursor.y > this.height);
}
private function showCursor():void {
cursor.visible = true;
}
private function hideCursor():void{
cursor.visible = false;
}
/** Inherited from IBbbCanvas*/
public function addRawChild(child:DisplayObject):void{
this.overlayChildrenHolder.rawChildren.addChild(child);
}
public function removeRawChild(child:DisplayObject):void{
this.overlayChildrenHolder.rawChildren.removeChild(child);
}
public function doesContain(child:DisplayObject):Boolean{
return this.overlayChildrenHolder.rawChildren.contains(child);
}
public function acceptOverlayCanvas(overlay:IBbbCanvas):void{
overlayCanvas = overlay;
var c:Canvas = overlay as Canvas;
this.addChild(c);
c.x = 0;
c.y = 0;
}
public function moveCanvas(x:int, y:int):void{
overlayChildrenHolder.x = swfSlideLoader.x * 2;
overlayChildrenHolder.y = swfSlideLoader.y * 2;
if (overlayCanvas != null) overlayCanvas.moveCanvas(overlayChildrenHolder.x, overlayChildrenHolder.y);
}
public function zoomCanvas(width:int, height:int):void{
overlayChildrenHolder.width = width;
overlayChildrenHolder.height = height;
moveCanvas(swfSlideLoader.x, swfSlideLoader.y);
if (overlayCanvas != null) overlayCanvas.zoomCanvas(width, height);
}
public function showOverlayCanvas(show:Boolean):void{
overlayCanvas.showCanvas(show);
}
public function showCanvas(show:Boolean):void{
}
]]>
</mx:Script>
<mx:SWFLoader id="swfSlideLoader" width="100%" height="100%" creationComplete="listenForSlideLoadedCompleteEvent()"
scaleContent="false" maintainAspectRatio="true" showBusyCursor="true" completeEffect="Fade"/>
<mx:HorizontalList id="thumbnailView" itemRenderer="org.bigbluebutton.modules.present.views.Thumbnail" itemRollOver="changeIndex(event)"
visible="false" width="100%" height="100" y="{this.height - 100}" change="changeSlide()" />
</mx:Canvas>

View File

@ -33,16 +33,16 @@
<mx:Script>
<![CDATA[
import flexlib.mdi.events.MDIWindowEvent;
import mx.events.ResizeEvent;
import org.bigbluebutton.modules.videoconf.events.CloseAllWindowsEvent;
import org.bigbluebutton.common.Images;
import org.bigbluebutton.modules.videoconf.events.StopBroadcastEvent;
import org.bigbluebutton.modules.videoconf.events.StartBroadcastEvent;
import mx.core.UIComponent;
import mx.controls.Alert;
private var _xPosition:int = 200;
private var _yPosition:int = 200;
import mx.core.UIComponent;
import mx.events.ResizeEvent;
import org.bigbluebutton.common.Images;
import org.bigbluebutton.main.view.components.MainCanvas;
import org.bigbluebutton.modules.videoconf.events.CloseAllWindowsEvent;
import org.bigbluebutton.modules.videoconf.events.StartBroadcastEvent;
import org.bigbluebutton.modules.videoconf.events.StopBroadcastEvent;
private var images:Images = new Images();
[Bindable] public var camIcon:Class = images.control_play;
@ -63,43 +63,10 @@
maximizeRestoreBtn.visible = false;
}
public function get xPosition():int {
return _xPosition;
public function getPrefferedPosition():String{
return MainCanvas.POPUP;
}
public function get yPosition():int {
return _yPosition;
}
public function set xPosition(x:int):void {
_xPosition = x;
}
public function set yPosition(y:int):void {
_yPosition = y;
}
private var _defaultWidth:int;
private var _defaultHeight:int;
public function get defaultWidth():int{
return _defaultWidth;
}
public function get defaultHeight():int{
return _defaultHeight;
}
public function set defaultHeight(height:int):void{
this._defaultHeight = height;
}
public function set defaultWidth(width:int):void{
this._defaultWidth = width;
}
public function resetWidthAndHeight():void{}
private function startPublishing():void{
var camera:Camera = Camera.getCamera(cmbCameraSelector.selectedIndex.toString());
if (camera == null) return;

View File

@ -29,15 +29,15 @@
<mx:Script>
<![CDATA[
import mx.core.UIComponent;
import flexlib.mdi.events.MDIWindowEvent;
import mx.core.UIComponent;
import org.bigbluebutton.main.view.components.MainCanvas;
public static const TILE_WIDTH:Number = 128;
public static const TILE_HEIGHT:Number = 96;
private var _xPosition:int = 200;
private var _yPosition:int = 200;
private var tiles:Array = new Array(9);
public var connection:NetConnection;
private var numStreamsPlaying:Number = 0;
@ -69,44 +69,8 @@
LogUtil.debug("TiledVideoWindow::asyncerror " + e.toString());
}
public function get xPosition():int {
return _xPosition;
}
public function get yPosition():int {
return _yPosition;
}
public function set xPosition(x:int):void {
_xPosition = x;
}
public function set yPosition(y:int):void {
_yPosition = y;
}
private var _defaultWidth:int = 390;
private var _defaultHeight:int = 361;
public function get defaultWidth():int{
return _defaultWidth;
}
public function get defaultHeight():int{
return _defaultHeight;
}
public function set defaultHeight(height:int):void{
this._defaultHeight = height;
}
public function set defaultWidth(width:int):void{
this._defaultWidth = width;
}
public function resetWidthAndHeight():void{
this.width = _defaultWidth;
this.height = _defaultHeight;
public function getPrefferedPosition():String{
return MainCanvas.POPUP;
}
private function setupTiles():void{

View File

@ -36,6 +36,7 @@
import mx.core.UIComponent;
import org.bigbluebutton.main.events.BBBEvent;
import org.bigbluebutton.main.view.components.MainCanvas;
import org.bigbluebutton.modules.videoconf.events.CloseAllWindowsEvent;
private var video:Video;
@ -58,8 +59,6 @@
private var globalDispatcher:Dispatcher;
private function init():void{
_xPosition = 250;
_yPosition = 250;
videoHolder = new UIComponent();
videoHolder.addChild(video);
this.addChild(videoHolder);
@ -126,40 +125,10 @@
videoHolder.height = info.height;
}
public function get xPosition():int {
return _xPosition;
public function getPrefferedPosition():String{
return MainCanvas.POPUP;
}
public function get yPosition():int {
return _yPosition;
}
public function set xPosition(x:int):void {
_xPosition = x;
}
public function set yPosition(y:int):void {
_yPosition = y;
}
public function get defaultWidth():int{
return this.width;
}
public function get defaultHeight():int{
return this.height;
}
public function set defaultHeight(height:int):void{
this.height = height;
}
public function set defaultWidth(width:int):void{
this.width = width;
}
public function resetWidthAndHeight():void{}
private function onNetStatus(e:NetStatusEvent):void{
switch(e.info.code){
case "NetStream.Publish.Start":

View File

@ -118,9 +118,7 @@ package org.bigbluebutton.modules.viewers.view
_viewersWindow.participants = proxy.participants;
_viewersWindow.isModerator = proxy.isModerator();
_viewersWindow.showCloseButton = false;
_viewersWindow.xPosition = 0;
_viewersWindow.yPosition = 0;
facade.sendNotification(ViewersModuleConstants.ADD_WINDOW, _viewersWindow);
facade.sendNotification(ViewersModuleConstants.ADD_WINDOW, _viewersWindow);
}
/**

View File

@ -1,159 +1,124 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
BigBlueButton - http://www.bigbluebutton.org
Copyright (c) 2008-2009 by respective authors (see below). All rights reserved.
BigBlueButton 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 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, If not, see <http://www.gnu.org/licenses/>.
$Id: $
-->
<viewer:MDIWindow xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:viewer="flexlib.mdi.containers.*"
implements="org.bigbluebutton.common.IBbbModuleWindow"
xmlns:mate="http://mate.asfusion.com/"
title="{windowTitle}"
creationComplete="onCreationComplete()"
width="233" height="220">
<mx:Script>
<![CDATA[
import flexlib.mdi.events.MDIWindowEvent;
import mx.controls.Alert;
import org.bigbluebutton.main.events.ParticipantJoinEvent;
import org.bigbluebutton.modules.viewers.view.events.ChangeStatusEvent;
import org.bigbluebutton.modules.viewers.ViewersModuleConstants;
import mx.events.ListEvent;
import org.bigbluebutton.modules.viewers.view.events.AssignPresenterEvent;
import org.bigbluebutton.modules.viewers.view.components.Images;
import org.bigbluebutton.modules.viewers.view.ViewersWindowMediator;
import mx.collections.ArrayCollection;
import org.bigbluebutton.util.i18n.ResourceUtil;
import mx.binding.utils.BindingUtils;
[Bindable]
private var windowTitle:String = ResourceUtil.getInstance().getString('bbb.viewers.title',["", ""]) ;
[Bindable]
public var participants:ArrayCollection;
[Bindable]
public var isModerator:Boolean = false;
public var images:Images = new Images();
[Bindable]
public var handIcon:Class = images.raisehand;
[Bindable]
public var toggleTooltip : String = "Click to raise hand.";
private var _xPosition:int;
private var _yPosition:int;
private function onCreationComplete():void {
BindingUtils.bindSetter(updateNumberOfViewers, participants, "length");
}
private function updateNumberOfViewers(numViewers:int):void {
if (numViewers > 4)
windowTitle = ResourceUtil.getInstance().getString('bbb.viewers.title', [":", numViewers]);
else
windowTitle = ResourceUtil.getInstance().getString('bbb.viewers.title', ["", ""]);
}
public function get xPosition():int {
return _xPosition;
}
public function get yPosition():int {
return _yPosition;
}
public function set xPosition(x:int):void {
_xPosition = x;
}
public function set yPosition(y:int):void {
_yPosition = y;
}
private var _defaultWidth:int = 233;
private var _defaultHeight:int = 220;
public function get defaultWidth():int{
return _defaultWidth;
}
public function get defaultHeight():int{
return _defaultHeight;
}
public function set defaultHeight(height:int):void{
this._defaultHeight = height;
}
public function set defaultWidth(width:int):void{
this._defaultWidth = width;
}
public function resetWidthAndHeight():void{
this.width = _defaultWidth;
this.height = _defaultHeight;
}
public function changeStatus(status:ArrayCollection):void {
dispatchEvent(new ChangeStatusEvent(status));
}
private function viewerSelectEvent(event:ListEvent):void {
dispatchEvent(new Event(ViewersModuleConstants.VIEWER_SELECTED_EVENT));
}
private function assignPresenterClicked():void {
// Ignore if the selected user is already the presenter.
if (viewersGrid.selectedItem.presenter) return;
dispatchEvent(new AssignPresenterEvent(viewersGrid.selectedItem.userid, viewersGrid.selectedItem.name));
}
]]>
</mx:Script>
<mx:DataGrid id="viewersGrid" dataProvider="{participants}" editable="false"
dragEnabled="false" itemClick="viewerSelectEvent(event);" width="100%" height="100%">
<mx:columns>
<mx:DataGridColumn dataField="role" headerText="{ResourceUtil.getInstance().getString('bbb.viewers.viewersGrid.roleItemRenderer')}" dataTipField="Role" editable="false" width="35"
itemRenderer="org.bigbluebutton.modules.viewers.view.components.RoleItemRenderer" sortable="false"/>
<mx:DataGridColumn dataField="name" headerText="{ResourceUtil.getInstance().getString('bbb.viewers.viewersGrid.nameItemRenderer')}" editable="true" width="100" sortable="false"
itemRenderer="org.bigbluebutton.modules.viewers.view.components.NameItemRenderer"/>
<mx:DataGridColumn dataField="status" headerText="{ResourceUtil.getInstance().getString('bbb.viewers.viewersGrid.statusItemRenderer')}" sortable="false"
itemRenderer="org.bigbluebutton.modules.viewers.view.components.StatusItemRenderer"/>
</mx:columns>
</mx:DataGrid>
<mx:ControlBar width="100%">
<mx:Button id="presentBtn" label="Switch Presenter" visible="{isModerator}" enabled="{viewersGrid.selectedItem != null}"
width="130" height="20"
toolTip="{ResourceUtil.getInstance().getString('bbb.viewers.presentBtn.toolTip')}"
click="assignPresenterClicked()"/>
<mx:Spacer width="100%"/>
<mx:Button id="raiseHandImage" icon="{handIcon}" toggle="true"
width="20" height="20"
toolTip="{ResourceUtil.getInstance().getString('bbb.viewers.raiseHandBtn.toolTip')}"
click="dispatchEvent(new Event(ViewersWindowMediator.CHANGE_STATUS))"/>
</mx:ControlBar>
</viewer:MDIWindow>
<?xml version="1.0" encoding="utf-8"?>
<!--
BigBlueButton - http://www.bigbluebutton.org
Copyright (c) 2008-2009 by respective authors (see below). All rights reserved.
BigBlueButton 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 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, If not, see <http://www.gnu.org/licenses/>.
$Id: $
-->
<viewer:MDIWindow xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:viewer="flexlib.mdi.containers.*"
implements="org.bigbluebutton.common.IBbbModuleWindow"
xmlns:mate="http://mate.asfusion.com/"
title="{windowTitle}"
creationComplete="onCreationComplete()">
<mx:Script>
<![CDATA[
import flexlib.mdi.events.MDIWindowEvent;
import mx.binding.utils.BindingUtils;
import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.events.ListEvent;
import org.bigbluebutton.main.events.ParticipantJoinEvent;
import org.bigbluebutton.main.view.components.MainCanvas;
import org.bigbluebutton.modules.viewers.ViewersModuleConstants;
import org.bigbluebutton.modules.viewers.view.ViewersWindowMediator;
import org.bigbluebutton.modules.viewers.view.components.Images;
import org.bigbluebutton.modules.viewers.view.events.AssignPresenterEvent;
import org.bigbluebutton.modules.viewers.view.events.ChangeStatusEvent;
import org.bigbluebutton.util.i18n.ResourceUtil;
[Bindable]
private var windowTitle:String = ResourceUtil.getInstance().getString('bbb.viewers.title',["", ""]) ;
[Bindable]
public var participants:ArrayCollection;
[Bindable]
public var isModerator:Boolean = false;
public var images:Images = new Images();
[Bindable]
public var presenterIcon : Class = images.presenter;
[Bindable]
public var handIcon:Class = images.raisehand;
[Bindable]
public var toggleTooltip : String = "Click to raise hand.";
private function onCreationComplete():void {
BindingUtils.bindSetter(updateNumberOfViewers, participants, "length");
}
private function updateNumberOfViewers(numViewers:int):void {
if (numViewers > 4)
windowTitle = ResourceUtil.getInstance().getString('bbb.viewers.title', [":", numViewers]);
else
windowTitle = ResourceUtil.getInstance().getString('bbb.viewers.title', ["", ""]);
}
public function getPrefferedPosition():String{
return MainCanvas.TOP_LEFT;
}
public function changeStatus(status:ArrayCollection):void {
dispatchEvent(new ChangeStatusEvent(status));
}
private function viewerSelectEvent(event:ListEvent):void {
dispatchEvent(new Event(ViewersModuleConstants.VIEWER_SELECTED_EVENT));
}
private function assignPresenterClicked():void {
// Ignore if the selected user is already the presenter.
if (viewersGrid.selectedItem.presenter) return;
dispatchEvent(new AssignPresenterEvent(viewersGrid.selectedItem.userid, viewersGrid.selectedItem.name));
}
]]>
</mx:Script>
<mx:DataGrid id="viewersGrid" dataProvider="{participants}" editable="false"
dragEnabled="false" itemClick="viewerSelectEvent(event);" width="100%" height="100%">
<mx:columns>
<mx:DataGridColumn dataField="role" headerText="{ResourceUtil.getInstance().getString('bbb.viewers.viewersGrid.roleItemRenderer')}" dataTipField="Role" editable="false" width="35"
itemRenderer="org.bigbluebutton.modules.viewers.view.components.RoleItemRenderer" sortable="false"/>
<mx:DataGridColumn dataField="name" headerText="{ResourceUtil.getInstance().getString('bbb.viewers.viewersGrid.nameItemRenderer')}" editable="true" width="100" sortable="false"
itemRenderer="org.bigbluebutton.modules.viewers.view.components.NameItemRenderer"/>
<mx:DataGridColumn dataField="status" headerText="{ResourceUtil.getInstance().getString('bbb.viewers.viewersGrid.statusItemRenderer')}" sortable="false"
itemRenderer="org.bigbluebutton.modules.viewers.view.components.StatusItemRenderer"/>
</mx:columns>
</mx:DataGrid>
<mx:ControlBar width="100%">
<mx:Button id="presentBtn" label="Switch Presenter" visible="{isModerator}" enabled="{viewersGrid.selectedItem != null}"
width="130" height="20"
toolTip="{ResourceUtil.getInstance().getString('bbb.viewers.presentBtn.toolTip')}"
click="assignPresenterClicked()"/>
<mx:Spacer width="100%"/>
<mx:Button id="raiseHandImage" icon="{handIcon}" toggle="true"
width="20" height="20"
toolTip="{ResourceUtil.getInstance().getString('bbb.viewers.raiseHandBtn.toolTip')}"
click="dispatchEvent(new Event(ViewersWindowMediator.CHANGE_STATUS))"/>
</mx:ControlBar>
</viewer:MDIWindow>