Merge branch 'fix-context-menu' into mconf-live0.6.2
Conflicts: bigbluebutton-client/src/org/bigbluebutton/modules/chat/views/ChatView.mxml bigbluebutton-client/src/org/bigbluebutton/modules/deskshare/view/components/DesktopPublishWindow.mxml bigbluebutton-client/src/org/bigbluebutton/modules/deskshare/view/components/DesktopViewWindow.mxml bigbluebutton-client/src/org/bigbluebutton/modules/sharednotes/SharedNotesWindow.mxml bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/business/VideoWindowItf.as bigbluebutton-client/src/org/bigbluebutton/modules/videodock/views/VideoDock.mxml bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/WhiteboardToolbar.mxml
This commit is contained in:
commit
1f0ecdfa0e
@ -30,8 +30,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
<![CDATA[
|
||||
import com.asfusion.mate.events.Dispatcher;
|
||||
|
||||
import flexlib.mdi.containers.MDIWindow;
|
||||
|
||||
import org.bigbluebutton.common.IBbbModuleWindow;
|
||||
import org.bigbluebutton.common.LogUtil;
|
||||
import org.bigbluebutton.common.events.CloseWindowEvent;
|
||||
|
@ -0,0 +1,91 @@
|
||||
/**
|
||||
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
*
|
||||
* Copyright (c) 2015 BigBlueButton Inc. and by respective authors (see below).
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||
* Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package org.bigbluebutton.common
|
||||
{
|
||||
import flash.ui.ContextMenu;
|
||||
|
||||
import flexlib.mdi.containers.MDIWindow;
|
||||
import flexlib.mdi.managers.MDIManager;
|
||||
|
||||
import mx.utils.ObjectUtil;
|
||||
|
||||
/**
|
||||
* This class exists so we can properly handle context menus on MDIWindow
|
||||
* instances. Also, we'll be able in the future to properly handle shortcuts
|
||||
* such as SHIFT + LEFT/RIGHT ARROW while in a text area (today, besides
|
||||
* selecting the text, it will move the window).
|
||||
*/
|
||||
public class CustomMdiWindow extends MDIWindow {
|
||||
|
||||
private static const IGNORED_MENU_ITEMS:Array = new Array(
|
||||
MDIWindow.CONTEXT_MENU_LABEL_CLOSE,
|
||||
MDIManager.CONTEXT_MENU_LABEL_TILE,
|
||||
MDIManager.CONTEXT_MENU_LABEL_TILE_FILL,
|
||||
MDIManager.CONTEXT_MENU_LABEL_CASCADE,
|
||||
MDIManager.CONTEXT_MENU_LABEL_SHOW_ALL );
|
||||
|
||||
private var _customContextMenuItems:Array = null;
|
||||
|
||||
private function filterContextMenu(item:*, index:int, array:Array):Boolean {
|
||||
return IGNORED_MENU_ITEMS.indexOf(item.caption) < 0;
|
||||
}
|
||||
|
||||
override public function updateContextMenu():void {
|
||||
super.updateContextMenu();
|
||||
|
||||
var modifiedContextMenuItems:Array = new Array();
|
||||
|
||||
if (customContextMenuItems != null) {
|
||||
if (modifiedContextMenuItems.length > 0 && customContextMenuItems.length > 0) {
|
||||
modifiedContextMenuItems[0].separatorBefore = true;
|
||||
}
|
||||
modifiedContextMenuItems = customContextMenuItems.concat(modifiedContextMenuItems);
|
||||
}
|
||||
|
||||
if (this.contextMenu != null) {
|
||||
var filteredMenu:Array = this.contextMenu.customItems.filter(filterContextMenu);
|
||||
if (modifiedContextMenuItems.length > 0 && filteredMenu.length > 0) {
|
||||
filteredMenu[0].separatorBefore = true;
|
||||
}
|
||||
modifiedContextMenuItems = modifiedContextMenuItems.concat(filteredMenu);
|
||||
}
|
||||
|
||||
var modifiedContextMenu:ContextMenu = new ContextMenu();
|
||||
modifiedContextMenu.hideBuiltInItems();
|
||||
modifiedContextMenu.customItems = modifiedContextMenuItems;
|
||||
this.contextMenu = modifiedContextMenu;
|
||||
}
|
||||
|
||||
override public function set showCloseButton(value:Boolean):void {
|
||||
super.showCloseButton = value;
|
||||
|
||||
updateContextMenu();
|
||||
}
|
||||
|
||||
public function get customContextMenuItems():Array {
|
||||
return _customContextMenuItems;
|
||||
}
|
||||
|
||||
public function set customContextMenuItems(value:Array):void {
|
||||
_customContextMenuItems = value;
|
||||
|
||||
updateContextMenu();
|
||||
}
|
||||
}
|
||||
}
|
@ -20,7 +20,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
-->
|
||||
|
||||
<MDIWindow xmlns="flexlib.mdi.containers.*"
|
||||
<CustomMdiWindow xmlns="org.bigbluebutton.common.*"
|
||||
xmlns:mx="http://www.adobe.com/2006/mxml"
|
||||
title="Log Window" creationComplete="displayLogMessages();"
|
||||
showCloseButton="true" xmlns:text="flash.text.*">
|
||||
@ -88,4 +88,4 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
<mx:Button label="Refresh" click="displayLogMessages()"/>
|
||||
</mx:HBox>
|
||||
</mx:ApplicationControlBar>
|
||||
</MDIWindow>
|
||||
</CustomMdiWindow>
|
||||
|
@ -76,7 +76,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
import flash.events.MouseEvent;
|
||||
import flash.geom.Point;
|
||||
|
||||
import flexlib.mdi.containers.MDIWindow;
|
||||
import flexlib.mdi.effects.effectsLib.MDIVistaEffects;
|
||||
|
||||
import mx.collections.ArrayCollection;
|
||||
|
@ -20,7 +20,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
-->
|
||||
|
||||
<MDIWindow xmlns="flexlib.mdi.containers.*"
|
||||
<CustomMdiWindow xmlns="org.bigbluebutton.common.*"
|
||||
xmlns:mx="http://www.adobe.com/2006/mxml"
|
||||
xmlns:mate="http://mate.asfusion.com/"
|
||||
title="{ResourceUtil.getInstance().getString('bbb.bwmonitor.title')}"
|
||||
@ -113,4 +113,4 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
</mx:VBox>
|
||||
</mx:Panel>
|
||||
|
||||
</MDIWindow>
|
||||
</CustomMdiWindow>
|
||||
|
@ -20,7 +20,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
-->
|
||||
|
||||
<MDIWindow xmlns="flexlib.mdi.containers.*"
|
||||
<CustomMdiWindow xmlns="org.bigbluebutton.common.*"
|
||||
xmlns:mx="http://www.adobe.com/2006/mxml"
|
||||
showCloseButton="true"
|
||||
initialize="init()"
|
||||
@ -289,4 +289,4 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
<mx:DataGridColumn dataField="func" headerText="{ResourceUtil.getInstance().getString('bbb.shortcuthelp.headers.function')}"/>
|
||||
</mx:columns>
|
||||
</mx:DataGrid>
|
||||
</MDIWindow>
|
||||
</CustomMdiWindow>
|
||||
|
@ -18,8 +18,8 @@ You should have received a copy of the GNU Lesser General Public License along
|
||||
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
-->
|
||||
<bcast:MDIWindow xmlns:mx="http://www.adobe.com/2006/mxml"
|
||||
xmlns:bcast="flexlib.mdi.containers.*"
|
||||
<bcast:CustomMdiWindow xmlns:mx="http://www.adobe.com/2006/mxml"
|
||||
xmlns:bcast="org.bigbluebutton.common.*"
|
||||
implements="org.bigbluebutton.common.IBbbModuleWindow"
|
||||
styleNameFocus="broadcastStyleFocus"
|
||||
styleNameNoFocus="broadcastStyleNoFocus"
|
||||
@ -30,7 +30,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
<mx:Script>
|
||||
<![CDATA[
|
||||
import flexlib.mdi.events.MDIWindowEvent;
|
||||
import mx.core.UIComponent;
|
||||
import mx.events.ResizeEvent;
|
||||
import mx.skins.Border;
|
||||
@ -146,4 +145,4 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
<mx:Button id="playBtn" label="Play" width="15% " click="playStopVideo()" toggle="true"/>
|
||||
</mx:HBox>
|
||||
</mx:ControlBar>
|
||||
</bcast:MDIWindow>
|
||||
</bcast:CustomMdiWindow>
|
||||
|
@ -1,405 +1,404 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
|
||||
BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
|
||||
Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU Lesser General Public License as published by the Free Software
|
||||
Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
-->
|
||||
|
||||
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
|
||||
xmlns:mate="http://mate.asfusion.com/"
|
||||
creationComplete="onCreationComplete()"
|
||||
initialize="init()"
|
||||
xmlns:flexlib="http://code.google.com/p/flexlib/"
|
||||
width="100%" height="100%" xmlns:containers="flexlib.containers.*"
|
||||
verticalScrollPolicy="off">
|
||||
|
||||
<mate:Listener type="{PrivateChatMessageEvent.PRIVATE_CHAT_MESSAGE_EVENT}" method="handlePrivateChatMessageEvent"/>
|
||||
<mate:Listener type="{PublicChatMessageEvent.PUBLIC_CHAT_MESSAGE_EVENT}" method="handlePublicChatMessageEvent"/>
|
||||
<mate:Listener type="{EventConstants.START_PRIVATE_CHAT}" method="handleStartPrivateChatMessageEvent"/>
|
||||
<mate:Listener type="{ShortcutEvent.FOCUS_CHAT_TABS}" method="focusChatTabs" />
|
||||
<mate:Listener type="{ChatToolbarButtonEvent.SAVE_CHAT_TOOLBAR_EVENT}" method="dispatchSaveChatEvent" />
|
||||
<mate:Listener type="{ChatToolbarButtonEvent.COPY_CHAT_TOOLBAR_EVENT}" method="dispatchCopyChatEvent" />
|
||||
|
||||
<mx:Script>
|
||||
<![CDATA[
|
||||
import com.asfusion.mate.events.Dispatcher;
|
||||
import flash.accessibility.Accessibility;
|
||||
import flash.events.Event;
|
||||
import flash.events.FocusEvent;
|
||||
import flash.external.ExternalInterface;
|
||||
import flash.media.Sound;
|
||||
import flash.media.SoundChannel;
|
||||
import flexlib.controls.tabBarClasses.SuperTab;
|
||||
import flexlib.controls.textClasses.StringBoundaries;
|
||||
import flexlib.events.SuperTabEvent;
|
||||
import flexlib.mdi.containers.MDIWindow;
|
||||
import mx.collections.ArrayCollection;
|
||||
import mx.containers.ControlBar;
|
||||
import mx.controls.Button;
|
||||
import mx.core.Container;
|
||||
import mx.core.UIComponent;
|
||||
import mx.events.IndexChangedEvent;
|
||||
import org.bigbluebutton.common.LogUtil;
|
||||
import org.bigbluebutton.core.BBB;
|
||||
import org.bigbluebutton.core.EventConstants;
|
||||
import org.bigbluebutton.core.UsersUtil;
|
||||
import org.bigbluebutton.core.events.CoreEvent;
|
||||
import org.bigbluebutton.core.managers.UserManager;
|
||||
import org.bigbluebutton.main.events.BBBEvent;
|
||||
import org.bigbluebutton.main.events.ShortcutEvent;
|
||||
import org.bigbluebutton.main.model.users.BBBUser;
|
||||
import org.bigbluebutton.modules.chat.ChatUtil;
|
||||
import org.bigbluebutton.modules.chat.events.ChatCopyEvent;
|
||||
import org.bigbluebutton.modules.chat.events.ChatOptionsEvent;
|
||||
import org.bigbluebutton.modules.chat.events.ChatSaveEvent;
|
||||
import org.bigbluebutton.modules.chat.events.PrivateChatMessageEvent;
|
||||
import org.bigbluebutton.modules.chat.events.PublicChatMessageEvent;
|
||||
import org.bigbluebutton.modules.chat.events.SendPrivateChatMessageEvent;
|
||||
import org.bigbluebutton.modules.chat.events.SendPublicChatMessageEvent;
|
||||
import org.bigbluebutton.modules.chat.model.ChatOptions;
|
||||
import org.bigbluebutton.modules.chat.model.business.UserVO;
|
||||
import org.bigbluebutton.modules.chat.vo.ChatMessageVO;
|
||||
import org.bigbluebutton.util.i18n.ResourceUtil;
|
||||
import org.bigbluebutton.modules.chat.events.ChatToolbarButtonEvent;
|
||||
|
||||
private static const PUBLIC_CHAT_USERID:String = 'public_chat_userid';
|
||||
private var PUBLIC_CHAT_USERNAME:String = ResourceUtil.getInstance().getString("bbb.chat.publicChatUsername");
|
||||
private var OPTION_TAB_ID:String = ResourceUtil.getInstance().getString("bbb.chat.optionsTabName");
|
||||
private var tabBox:AddChatTabBox;
|
||||
private var publicBox:ChatBox;
|
||||
private var focus:Boolean = true;
|
||||
private var globalDispatcher:Dispatcher = new Dispatcher();
|
||||
|
||||
[Bindable] public var chatOptions:ChatOptions;
|
||||
|
||||
[Bindable] private var baseIndex:int;
|
||||
|
||||
private static const PUBLIC_TAB_NEW:String = ResourceUtil.getInstance().getString("bbb.accessibility.chat.chatView.publicTabNew");
|
||||
private var publicWaiting:Boolean = false;
|
||||
private var publicFocus:Boolean = false;
|
||||
private var noticeLabel:String;
|
||||
|
||||
[Embed(source="../sounds/notice.mp3")]
|
||||
private var noticeSoundClass:Class;
|
||||
private var noticeSound:Sound = new noticeSoundClass() as Sound;
|
||||
// All author and license information for the use of this sound can be found in:
|
||||
// src/org/bigbluebutton/modules/chat/sounds/license.txt
|
||||
|
||||
// Initialization
|
||||
private function init():void {
|
||||
chatOptions = new ChatOptions();
|
||||
noticeLabel = ResourceUtil.getInstance().getString('bbb.chat.chatTabs.accessibleNotice');
|
||||
// Get the base tab index from config, and add four to make up for the min/max/close buttons and title overlay
|
||||
baseIndex = chatOptions.getBaseIndex() + 4;
|
||||
}
|
||||
|
||||
|
||||
private function onCreationComplete():void{
|
||||
openChatBoxFor(PUBLIC_CHAT_USERID, true);
|
||||
makePublicChatUncloseable();
|
||||
|
||||
if (chatOptions.privateEnabled) {
|
||||
createAddTabBox();
|
||||
makeAddPrivateChatUncloseable();
|
||||
}
|
||||
|
||||
ResourceUtil.getInstance().addEventListener(Event.CHANGE, localeChanged); // Listen for locale changing
|
||||
|
||||
addEventListener(SuperTabEvent.TAB_CLOSE, onUserClosedTab);
|
||||
|
||||
systemManager.stage.addEventListener(Event.MOUSE_LEAVE, mouseLeave);
|
||||
systemManager.stage.addEventListener(Event.ACTIVATE, activate);
|
||||
systemManager.stage.addEventListener(Event.DEACTIVATE, deactivate);
|
||||
}
|
||||
|
||||
private function getVisibleChatBox():ChatBox {
|
||||
var chatBox:ChatBox = chatTabs.getChildAt(chatTabs.selectedIndex) as ChatBox;
|
||||
return chatBox;
|
||||
}
|
||||
|
||||
private function dispatchSaveChatEvent(e:Event):void {
|
||||
var chatBox:ChatBox = getVisibleChatBox();
|
||||
var saveEvent:ChatSaveEvent = new ChatSaveEvent(ChatSaveEvent.SAVE_CHAT_EVENT);
|
||||
|
||||
if (chatBox.chatWithUsername == null || chatBox.chatWithUsername == "") {
|
||||
saveEvent.filename = ResourceUtil.getInstance().getString('bbb.chat.save.filename');
|
||||
} else {
|
||||
saveEvent.filename = chatBox.chatWithUsername;
|
||||
}
|
||||
|
||||
saveEvent.chatMessages = chatBox.getChatMessages();
|
||||
globalDispatcher.dispatchEvent(saveEvent);
|
||||
}
|
||||
|
||||
private function dispatchCopyChatEvent(e:Event):void {
|
||||
var chatBox:ChatBox = getVisibleChatBox();
|
||||
var copyEvent:ChatCopyEvent = new ChatCopyEvent(ChatCopyEvent.COPY_CHAT_EVENT);
|
||||
|
||||
copyEvent.chatMessages = chatBox.getChatMessages();
|
||||
globalDispatcher.dispatchEvent(copyEvent);
|
||||
}
|
||||
|
||||
private function focusChatTabs(e:ShortcutEvent):void{
|
||||
focusManager.setFocus(chatTabs);
|
||||
}
|
||||
|
||||
private function localeChanged(e:Event):void{
|
||||
setTabTitles();
|
||||
}
|
||||
|
||||
private function setTabTitles():void {
|
||||
PUBLIC_CHAT_USERNAME = ResourceUtil.getInstance().getString("bbb.chat.publicChatUsername");
|
||||
OPTION_TAB_ID = ResourceUtil.getInstance().getString("bbb.chat.optionsTabName");
|
||||
|
||||
if (tabBox != null) {
|
||||
tabBox.id = OPTION_TAB_ID;
|
||||
tabBox.label = OPTION_TAB_ID;
|
||||
tabBox.name = OPTION_TAB_ID;
|
||||
}
|
||||
|
||||
if (publicBox != null) {
|
||||
publicBox.label = PUBLIC_CHAT_USERNAME;
|
||||
}
|
||||
}
|
||||
|
||||
private function handlePublicChatMessageEvent(event:PublicChatMessageEvent):void {
|
||||
notifyUserOfNewMessage(PUBLIC_CHAT_USERID);
|
||||
if (!UsersUtil.isMe(event.message.fromUserID)) {
|
||||
publicNotification();
|
||||
}
|
||||
}
|
||||
|
||||
private function handlePrivateChatMessageEvent(event:PrivateChatMessageEvent):void {
|
||||
// This message is from me. Ignore as a chatbox has already been created for this
|
||||
// private chat and that chatbox will handle this message.
|
||||
if (UsersUtil.isMe(event.message.fromUserID)) return;
|
||||
|
||||
// I received a new private chat. Open up a new chatbox and forward the message
|
||||
// to the chatbox. Succeeding messages will be handled by that chatbox.
|
||||
if (! userHasChatBox(event.message.fromUserID)) {
|
||||
// Open a private chat tab.
|
||||
openChatBoxFor(event.message.fromUserID, false).handleFirstPrivateMessage(event);
|
||||
}
|
||||
|
||||
// See if the chatbox is not in focus and notify user about the message.
|
||||
notifyUserOfNewMessage(event.message.fromUserID);
|
||||
privateNotification(event);
|
||||
}
|
||||
|
||||
private function notifyUserOfNewMessage(userID:String):void {
|
||||
if (! isChatBoxCurrentlySelected(userID)) {
|
||||
notifyParticipantOfUnreadMessageFrom(userID);
|
||||
}
|
||||
}
|
||||
|
||||
private function mouseLeave(event:Event):void{
|
||||
this.focus = false;
|
||||
}
|
||||
|
||||
private function activate(event:Event):void{
|
||||
this.focus = true;
|
||||
}
|
||||
|
||||
private function deactivate(event:Event):void{
|
||||
this.focus = false;
|
||||
}
|
||||
|
||||
private function makePublicChatUncloseable():void {
|
||||
// See definition of callLater on Adobe Flash doc.
|
||||
callLater(calledOnTheNextScreenRefreshToMakePublicChatUncloseable);
|
||||
}
|
||||
|
||||
private function makeAddPrivateChatUncloseable():void {
|
||||
// See definition of callLater on Adobe Flash doc.
|
||||
callLater(calledOnTheNextScreenRefreshToMakeTabUncloseable);
|
||||
}
|
||||
|
||||
private function calledOnTheNextScreenRefreshToMakeTabUncloseable():void {
|
||||
chatTabs.setClosePolicyForTab(chatTabs.getChildIndex(tabBox), SuperTab.CLOSE_NEVER);
|
||||
}
|
||||
|
||||
private function calledOnTheNextScreenRefreshToMakePublicChatUncloseable():void {
|
||||
var chatBox:ChatBox = getChatBoxForUser(PUBLIC_CHAT_USERID);
|
||||
var chatIndex:int = getTabIndexFor(chatBox);
|
||||
chatTabs.setClosePolicyForTab(chatIndex, SuperTab.CLOSE_NEVER);
|
||||
}
|
||||
|
||||
private function isChatBoxCurrentlySelected(id:String):Boolean {
|
||||
if (chatTabs.getChildByName(id) == chatTabs.selectedChild){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function notifyParticipantOfUnreadMessageFrom(userid:String):void {
|
||||
var chatBox:ChatBox = getChatBoxForUser(userid);
|
||||
var tabIndex:int = getTabIndexFor(chatBox);
|
||||
var tab:Button = chatTabs.getTabAt(tabIndex);
|
||||
tab.setStyle("fillColors", new Array(0xFFAE00, 0xD3800A));
|
||||
tab.setStyle("fillAlphas", new Array(1.0, 0.8));
|
||||
|
||||
// An event to change the accessibilityDescription of the given chat tab to <existing label> + "NEW MESSAGE" should go here.
|
||||
// However, the SuperTabNavigator does not cooperate with changes to it's accessibility properties.
|
||||
}
|
||||
|
||||
private function getTabIndexFor(chatBox:ChatBox):int {
|
||||
return chatTabs.getChildIndex(chatBox);
|
||||
}
|
||||
|
||||
private function onTabNavChange():void{
|
||||
var tab:Button = chatTabs.getTabAt(chatTabs.selectedIndex);
|
||||
tab.setStyle("fillColors", new Array(0xFFFFFF, 0xCCCCCC));
|
||||
|
||||
// An event to remove the "NEW MESSAGE" notification from the accessibilityDescription of the given chat tab (if it exists) should go here.
|
||||
// However, the SuperTabNavigator does not cooperate with changes to it's accessibility properties.
|
||||
|
||||
var chatBox:IChatTab = chatTabs.getChildAt(chatTabs.selectedIndex) as IChatTab;
|
||||
chatBox.focusToTextMessageArea();
|
||||
}
|
||||
|
||||
private function userHasChatBox(userID:String):Boolean {
|
||||
var chatBox:ChatBox = chatTabs.getChildByName(userID) as ChatBox;
|
||||
if (chatBox != null) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private function getChatBoxForUser(userID:String):ChatBox {
|
||||
return chatTabs.getChildByName(userID) as ChatBox;
|
||||
}
|
||||
|
||||
private function handleStartPrivateChatMessageEvent(event:CoreEvent):void {
|
||||
var userID:String = event.message.chatWith;
|
||||
var tabIndex:int = getTabIndexFor(openChatBoxFor(userID));
|
||||
chatTabs.selectedIndex = tabIndex;
|
||||
}
|
||||
|
||||
public function openChatBoxFor(chatWithUserID:String, publicChat:Boolean=false):ChatBox {
|
||||
if (userHasChatBox(chatWithUserID)) {
|
||||
return getChatBoxForUser(chatWithUserID);
|
||||
} else {
|
||||
return createChatBoxFor(chatWithUserID, publicChat);
|
||||
}
|
||||
}
|
||||
|
||||
private function createChatBoxFor(chatWithUserID:String, publicChat:Boolean=false):ChatBox {
|
||||
var chatBox:ChatBox = new ChatBox();
|
||||
chatBox.id = chatWithUserID;
|
||||
chatBox.name = chatWithUserID;
|
||||
chatBox.chatWithUserID = chatWithUserID;
|
||||
chatBox.baseIndex = baseIndex;
|
||||
|
||||
if (publicChat) {
|
||||
chatBox.label = PUBLIC_CHAT_USERNAME
|
||||
chatBox.publicChat = true;
|
||||
publicBox = chatBox; // keep a reference to the public chat box
|
||||
} else {
|
||||
chatBox.publicChat = false;
|
||||
chatBox.label = UsersUtil.getUserName(chatWithUserID);
|
||||
}
|
||||
|
||||
chatBox.chatWithUsername = UsersUtil.getUserName(chatWithUserID);
|
||||
|
||||
if (chatTabs.numChildren >= 2) {
|
||||
chatTabs.addChildAt(chatBox, chatTabs.numChildren - 1);
|
||||
} else {
|
||||
chatTabs.addChild(chatBox);
|
||||
}
|
||||
|
||||
// set the font size on tab opening
|
||||
if (tabBox) chatBox.setStyle("fontSize", int(tabBox.cmbFontSize.selectedItem));
|
||||
|
||||
return chatBox;
|
||||
}
|
||||
|
||||
private function createAddTabBox():AddChatTabBox {
|
||||
tabBox = new AddChatTabBox();
|
||||
tabBox.chatView = this;
|
||||
tabBox.id = OPTION_TAB_ID;
|
||||
tabBox.label = OPTION_TAB_ID;
|
||||
tabBox.name = OPTION_TAB_ID;
|
||||
tabBox.chatOptions = chatOptions;
|
||||
|
||||
tabBox.addEventListener(KeyboardEvent.KEY_DOWN, tabBox.accessibleClick);
|
||||
chatTabs.addChild(tabBox);
|
||||
|
||||
return tabBox;
|
||||
}
|
||||
|
||||
|
||||
// Activates an audio alert for screen-reader users on public message reception
|
||||
private function publicNotification():void {
|
||||
publicWaiting = true;
|
||||
if (Accessibility.active){
|
||||
noticeSound.play();
|
||||
}
|
||||
chatTabs.getChildByName(PUBLIC_CHAT_USERID).addEventListener(FocusEvent.FOCUS_IN, publicChatFocus);
|
||||
chatTabs.getChildByName(PUBLIC_CHAT_USERID).addEventListener(FocusEvent.FOCUS_OUT, publicChatUnfocus);
|
||||
}
|
||||
|
||||
// Activates an audio alert for screen-reader users on private message reception
|
||||
private function privateNotification(event:PrivateChatMessageEvent):void{
|
||||
if (! UsersUtil.isMe(event.message.fromUserID)) {
|
||||
if (Accessibility.active){
|
||||
noticeSound.play();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function publicChatFocus(event:FocusEvent):void{
|
||||
publicFocus = true;
|
||||
publicWaiting = false;
|
||||
}
|
||||
|
||||
public function publicChatUnfocus(event:FocusEvent):void {
|
||||
publicFocus = false;
|
||||
}
|
||||
|
||||
private function focusPreviousChatTab(e:ShortcutEvent):void{
|
||||
if (chatTabs.selectedIndex > 0){
|
||||
chatTabs.selectedIndex--;
|
||||
}
|
||||
else{
|
||||
chatTabs.selectedIndex = chatTabs.numChildren - 1;
|
||||
}
|
||||
}
|
||||
|
||||
private function focusNextChatTab(e:ShortcutEvent):void{
|
||||
if (chatTabs.selectedIndex < chatTabs.numChildren - 1){
|
||||
chatTabs.selectedIndex++;
|
||||
}
|
||||
else{
|
||||
chatTabs.selectedIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private function onTabClose(e:SuperTabEvent):void{
|
||||
dispatchEvent(e);
|
||||
}
|
||||
|
||||
private function onUserClosedTab(e:SuperTabEvent):void{
|
||||
var name:String = chatTabs.getChildAt(e.tabIndex).name;
|
||||
}
|
||||
|
||||
]]>
|
||||
</mx:Script>
|
||||
<containers:SuperTabNavigator includeInLayout="false" id="chatTabs"
|
||||
width="100%" height="100%" change="onTabNavChange()"
|
||||
tabClose="onTabClose(event)" minTabWidth="20"
|
||||
dragEnabled="false" popUpButtonPolicy="off" tabIndex="{baseIndex}"
|
||||
/>
|
||||
</mx:VBox>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
|
||||
BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
|
||||
Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU Lesser General Public License as published by the Free Software
|
||||
Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
-->
|
||||
|
||||
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
|
||||
xmlns:mate="http://mate.asfusion.com/"
|
||||
creationComplete="onCreationComplete()"
|
||||
initialize="init()"
|
||||
xmlns:flexlib="http://code.google.com/p/flexlib/"
|
||||
width="100%" height="100%" xmlns:containers="flexlib.containers.*"
|
||||
verticalScrollPolicy="off">
|
||||
|
||||
<mate:Listener type="{PrivateChatMessageEvent.PRIVATE_CHAT_MESSAGE_EVENT}" method="handlePrivateChatMessageEvent"/>
|
||||
<mate:Listener type="{PublicChatMessageEvent.PUBLIC_CHAT_MESSAGE_EVENT}" method="handlePublicChatMessageEvent"/>
|
||||
<mate:Listener type="{EventConstants.START_PRIVATE_CHAT}" method="handleStartPrivateChatMessageEvent"/>
|
||||
<mate:Listener type="{ShortcutEvent.FOCUS_CHAT_TABS}" method="focusChatTabs" />
|
||||
<mate:Listener type="{ChatToolbarButtonEvent.SAVE_CHAT_TOOLBAR_EVENT}" method="dispatchSaveChatEvent" />
|
||||
<mate:Listener type="{ChatToolbarButtonEvent.COPY_CHAT_TOOLBAR_EVENT}" method="dispatchCopyChatEvent" />
|
||||
|
||||
<mx:Script>
|
||||
<![CDATA[
|
||||
import com.asfusion.mate.events.Dispatcher;
|
||||
import flash.accessibility.Accessibility;
|
||||
import flash.events.Event;
|
||||
import flash.events.FocusEvent;
|
||||
import flash.external.ExternalInterface;
|
||||
import flash.media.Sound;
|
||||
import flash.media.SoundChannel;
|
||||
import flexlib.controls.tabBarClasses.SuperTab;
|
||||
import flexlib.controls.textClasses.StringBoundaries;
|
||||
import flexlib.events.SuperTabEvent;
|
||||
import mx.collections.ArrayCollection;
|
||||
import mx.containers.ControlBar;
|
||||
import mx.controls.Button;
|
||||
import mx.core.Container;
|
||||
import mx.core.UIComponent;
|
||||
import mx.events.IndexChangedEvent;
|
||||
import org.bigbluebutton.common.LogUtil;
|
||||
import org.bigbluebutton.core.BBB;
|
||||
import org.bigbluebutton.core.EventConstants;
|
||||
import org.bigbluebutton.core.UsersUtil;
|
||||
import org.bigbluebutton.core.events.CoreEvent;
|
||||
import org.bigbluebutton.core.managers.UserManager;
|
||||
import org.bigbluebutton.main.events.BBBEvent;
|
||||
import org.bigbluebutton.main.events.ShortcutEvent;
|
||||
import org.bigbluebutton.main.model.users.BBBUser;
|
||||
import org.bigbluebutton.modules.chat.ChatUtil;
|
||||
import org.bigbluebutton.modules.chat.events.ChatCopyEvent;
|
||||
import org.bigbluebutton.modules.chat.events.ChatOptionsEvent;
|
||||
import org.bigbluebutton.modules.chat.events.ChatSaveEvent;
|
||||
import org.bigbluebutton.modules.chat.events.PrivateChatMessageEvent;
|
||||
import org.bigbluebutton.modules.chat.events.PublicChatMessageEvent;
|
||||
import org.bigbluebutton.modules.chat.events.SendPrivateChatMessageEvent;
|
||||
import org.bigbluebutton.modules.chat.events.SendPublicChatMessageEvent;
|
||||
import org.bigbluebutton.modules.chat.model.ChatOptions;
|
||||
import org.bigbluebutton.modules.chat.model.business.UserVO;
|
||||
import org.bigbluebutton.modules.chat.vo.ChatMessageVO;
|
||||
import org.bigbluebutton.util.i18n.ResourceUtil;
|
||||
import org.bigbluebutton.modules.chat.events.ChatToolbarButtonEvent;
|
||||
|
||||
private static const PUBLIC_CHAT_USERID:String = 'public_chat_userid';
|
||||
private var PUBLIC_CHAT_USERNAME:String = ResourceUtil.getInstance().getString("bbb.chat.publicChatUsername");
|
||||
private var OPTION_TAB_ID:String = ResourceUtil.getInstance().getString("bbb.chat.optionsTabName");
|
||||
private var tabBox:AddChatTabBox;
|
||||
private var publicBox:ChatBox;
|
||||
private var focus:Boolean = true;
|
||||
private var globalDispatcher:Dispatcher = new Dispatcher();
|
||||
|
||||
[Bindable] public var chatOptions:ChatOptions;
|
||||
|
||||
[Bindable] private var baseIndex:int;
|
||||
|
||||
private static const PUBLIC_TAB_NEW:String = ResourceUtil.getInstance().getString("bbb.accessibility.chat.chatView.publicTabNew");
|
||||
private var publicWaiting:Boolean = false;
|
||||
private var publicFocus:Boolean = false;
|
||||
private var noticeLabel:String;
|
||||
|
||||
[Embed(source="../sounds/notice.mp3")]
|
||||
private var noticeSoundClass:Class;
|
||||
private var noticeSound:Sound = new noticeSoundClass() as Sound;
|
||||
// All author and license information for the use of this sound can be found in:
|
||||
// src/org/bigbluebutton/modules/chat/sounds/license.txt
|
||||
|
||||
// Initialization
|
||||
private function init():void {
|
||||
chatOptions = new ChatOptions();
|
||||
noticeLabel = ResourceUtil.getInstance().getString('bbb.chat.chatTabs.accessibleNotice');
|
||||
// Get the base tab index from config, and add four to make up for the min/max/close buttons and title overlay
|
||||
baseIndex = chatOptions.getBaseIndex() + 4;
|
||||
}
|
||||
|
||||
|
||||
private function onCreationComplete():void{
|
||||
openChatBoxFor(PUBLIC_CHAT_USERID, true);
|
||||
makePublicChatUncloseable();
|
||||
|
||||
if (chatOptions.privateEnabled) {
|
||||
createAddTabBox();
|
||||
makeAddPrivateChatUncloseable();
|
||||
}
|
||||
|
||||
ResourceUtil.getInstance().addEventListener(Event.CHANGE, localeChanged); // Listen for locale changing
|
||||
|
||||
addEventListener(SuperTabEvent.TAB_CLOSE, onUserClosedTab);
|
||||
|
||||
systemManager.stage.addEventListener(Event.MOUSE_LEAVE, mouseLeave);
|
||||
systemManager.stage.addEventListener(Event.ACTIVATE, activate);
|
||||
systemManager.stage.addEventListener(Event.DEACTIVATE, deactivate);
|
||||
}
|
||||
|
||||
private function getVisibleChatBox():ChatBox {
|
||||
var chatBox:ChatBox = chatTabs.getChildAt(chatTabs.selectedIndex) as ChatBox;
|
||||
return chatBox;
|
||||
}
|
||||
|
||||
private function dispatchSaveChatEvent(e:Event):void {
|
||||
var chatBox:ChatBox = getVisibleChatBox();
|
||||
var saveEvent:ChatSaveEvent = new ChatSaveEvent(ChatSaveEvent.SAVE_CHAT_EVENT);
|
||||
|
||||
if (chatBox.chatWithUsername == null || chatBox.chatWithUsername == "") {
|
||||
saveEvent.filename = ResourceUtil.getInstance().getString('bbb.chat.save.filename');
|
||||
} else {
|
||||
saveEvent.filename = chatBox.chatWithUsername;
|
||||
}
|
||||
|
||||
saveEvent.chatMessages = chatBox.getChatMessages();
|
||||
globalDispatcher.dispatchEvent(saveEvent);
|
||||
}
|
||||
|
||||
private function dispatchCopyChatEvent(e:Event):void {
|
||||
var chatBox:ChatBox = getVisibleChatBox();
|
||||
var copyEvent:ChatCopyEvent = new ChatCopyEvent(ChatCopyEvent.COPY_CHAT_EVENT);
|
||||
|
||||
copyEvent.chatMessages = chatBox.getChatMessages();
|
||||
globalDispatcher.dispatchEvent(copyEvent);
|
||||
}
|
||||
|
||||
private function focusChatTabs(e:ShortcutEvent):void{
|
||||
focusManager.setFocus(chatTabs);
|
||||
}
|
||||
|
||||
private function localeChanged(e:Event):void{
|
||||
setTabTitles();
|
||||
}
|
||||
|
||||
private function setTabTitles():void {
|
||||
PUBLIC_CHAT_USERNAME = ResourceUtil.getInstance().getString("bbb.chat.publicChatUsername");
|
||||
OPTION_TAB_ID = ResourceUtil.getInstance().getString("bbb.chat.optionsTabName");
|
||||
|
||||
if (tabBox != null) {
|
||||
tabBox.id = OPTION_TAB_ID;
|
||||
tabBox.label = OPTION_TAB_ID;
|
||||
tabBox.name = OPTION_TAB_ID;
|
||||
}
|
||||
|
||||
if (publicBox != null) {
|
||||
publicBox.label = PUBLIC_CHAT_USERNAME;
|
||||
}
|
||||
}
|
||||
|
||||
private function handlePublicChatMessageEvent(event:PublicChatMessageEvent):void {
|
||||
notifyUserOfNewMessage(PUBLIC_CHAT_USERID);
|
||||
if (!UsersUtil.isMe(event.message.fromUserID)) {
|
||||
publicNotification();
|
||||
}
|
||||
}
|
||||
|
||||
private function handlePrivateChatMessageEvent(event:PrivateChatMessageEvent):void {
|
||||
// This message is from me. Ignore as a chatbox has already been created for this
|
||||
// private chat and that chatbox will handle this message.
|
||||
if (UsersUtil.isMe(event.message.fromUserID)) return;
|
||||
|
||||
// I received a new private chat. Open up a new chatbox and forward the message
|
||||
// to the chatbox. Succeeding messages will be handled by that chatbox.
|
||||
if (! userHasChatBox(event.message.fromUserID)) {
|
||||
// Open a private chat tab.
|
||||
openChatBoxFor(event.message.fromUserID, false).handleFirstPrivateMessage(event);
|
||||
}
|
||||
|
||||
// See if the chatbox is not in focus and notify user about the message.
|
||||
notifyUserOfNewMessage(event.message.fromUserID);
|
||||
privateNotification(event);
|
||||
}
|
||||
|
||||
private function notifyUserOfNewMessage(userID:String):void {
|
||||
if (! isChatBoxCurrentlySelected(userID)) {
|
||||
notifyParticipantOfUnreadMessageFrom(userID);
|
||||
}
|
||||
}
|
||||
|
||||
private function mouseLeave(event:Event):void{
|
||||
this.focus = false;
|
||||
}
|
||||
|
||||
private function activate(event:Event):void{
|
||||
this.focus = true;
|
||||
}
|
||||
|
||||
private function deactivate(event:Event):void{
|
||||
this.focus = false;
|
||||
}
|
||||
|
||||
private function makePublicChatUncloseable():void {
|
||||
// See definition of callLater on Adobe Flash doc.
|
||||
callLater(calledOnTheNextScreenRefreshToMakePublicChatUncloseable);
|
||||
}
|
||||
|
||||
private function makeAddPrivateChatUncloseable():void {
|
||||
// See definition of callLater on Adobe Flash doc.
|
||||
callLater(calledOnTheNextScreenRefreshToMakeTabUncloseable);
|
||||
}
|
||||
|
||||
private function calledOnTheNextScreenRefreshToMakeTabUncloseable():void {
|
||||
chatTabs.setClosePolicyForTab(chatTabs.getChildIndex(tabBox), SuperTab.CLOSE_NEVER);
|
||||
}
|
||||
|
||||
private function calledOnTheNextScreenRefreshToMakePublicChatUncloseable():void {
|
||||
var chatBox:ChatBox = getChatBoxForUser(PUBLIC_CHAT_USERID);
|
||||
var chatIndex:int = getTabIndexFor(chatBox);
|
||||
chatTabs.setClosePolicyForTab(chatIndex, SuperTab.CLOSE_NEVER);
|
||||
}
|
||||
|
||||
private function isChatBoxCurrentlySelected(id:String):Boolean {
|
||||
if (chatTabs.getChildByName(id) == chatTabs.selectedChild){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function notifyParticipantOfUnreadMessageFrom(userid:String):void {
|
||||
var chatBox:ChatBox = getChatBoxForUser(userid);
|
||||
var tabIndex:int = getTabIndexFor(chatBox);
|
||||
var tab:Button = chatTabs.getTabAt(tabIndex);
|
||||
tab.setStyle("fillColors", new Array(0xFFAE00, 0xD3800A));
|
||||
tab.setStyle("fillAlphas", new Array(1.0, 0.8));
|
||||
|
||||
// An event to change the accessibilityDescription of the given chat tab to <existing label> + "NEW MESSAGE" should go here.
|
||||
// However, the SuperTabNavigator does not cooperate with changes to it's accessibility properties.
|
||||
}
|
||||
|
||||
private function getTabIndexFor(chatBox:ChatBox):int {
|
||||
return chatTabs.getChildIndex(chatBox);
|
||||
}
|
||||
|
||||
private function onTabNavChange():void{
|
||||
var tab:Button = chatTabs.getTabAt(chatTabs.selectedIndex);
|
||||
tab.setStyle("fillColors", new Array(0xFFFFFF, 0xCCCCCC));
|
||||
|
||||
// An event to remove the "NEW MESSAGE" notification from the accessibilityDescription of the given chat tab (if it exists) should go here.
|
||||
// However, the SuperTabNavigator does not cooperate with changes to it's accessibility properties.
|
||||
|
||||
var chatBox:IChatTab = chatTabs.getChildAt(chatTabs.selectedIndex) as IChatTab;
|
||||
chatBox.focusToTextMessageArea();
|
||||
}
|
||||
|
||||
private function userHasChatBox(userID:String):Boolean {
|
||||
var chatBox:ChatBox = chatTabs.getChildByName(userID) as ChatBox;
|
||||
if (chatBox != null) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private function getChatBoxForUser(userID:String):ChatBox {
|
||||
return chatTabs.getChildByName(userID) as ChatBox;
|
||||
}
|
||||
|
||||
private function handleStartPrivateChatMessageEvent(event:CoreEvent):void {
|
||||
var userID:String = event.message.chatWith;
|
||||
var tabIndex:int = getTabIndexFor(openChatBoxFor(userID));
|
||||
chatTabs.selectedIndex = tabIndex;
|
||||
}
|
||||
|
||||
public function openChatBoxFor(chatWithUserID:String, publicChat:Boolean=false):ChatBox {
|
||||
if (userHasChatBox(chatWithUserID)) {
|
||||
return getChatBoxForUser(chatWithUserID);
|
||||
} else {
|
||||
return createChatBoxFor(chatWithUserID, publicChat);
|
||||
}
|
||||
}
|
||||
|
||||
private function createChatBoxFor(chatWithUserID:String, publicChat:Boolean=false):ChatBox {
|
||||
var chatBox:ChatBox = new ChatBox();
|
||||
chatBox.id = chatWithUserID;
|
||||
chatBox.name = chatWithUserID;
|
||||
chatBox.chatWithUserID = chatWithUserID;
|
||||
chatBox.baseIndex = baseIndex;
|
||||
|
||||
if (publicChat) {
|
||||
chatBox.label = PUBLIC_CHAT_USERNAME
|
||||
chatBox.publicChat = true;
|
||||
publicBox = chatBox; // keep a reference to the public chat box
|
||||
} else {
|
||||
chatBox.publicChat = false;
|
||||
chatBox.label = UsersUtil.getUserName(chatWithUserID);
|
||||
}
|
||||
|
||||
chatBox.chatWithUsername = UsersUtil.getUserName(chatWithUserID);
|
||||
|
||||
if (chatTabs.numChildren >= 2) {
|
||||
chatTabs.addChildAt(chatBox, chatTabs.numChildren - 1);
|
||||
} else {
|
||||
chatTabs.addChild(chatBox);
|
||||
}
|
||||
|
||||
// set the font size on tab opening
|
||||
if (tabBox) chatBox.setStyle("fontSize", int(tabBox.cmbFontSize.selectedItem));
|
||||
|
||||
return chatBox;
|
||||
}
|
||||
|
||||
private function createAddTabBox():AddChatTabBox {
|
||||
tabBox = new AddChatTabBox();
|
||||
tabBox.chatView = this;
|
||||
tabBox.id = OPTION_TAB_ID;
|
||||
tabBox.label = OPTION_TAB_ID;
|
||||
tabBox.name = OPTION_TAB_ID;
|
||||
tabBox.chatOptions = chatOptions;
|
||||
|
||||
tabBox.addEventListener(KeyboardEvent.KEY_DOWN, tabBox.accessibleClick);
|
||||
chatTabs.addChild(tabBox);
|
||||
|
||||
return tabBox;
|
||||
}
|
||||
|
||||
|
||||
// Activates an audio alert for screen-reader users on public message reception
|
||||
private function publicNotification():void {
|
||||
publicWaiting = true;
|
||||
if (Accessibility.active){
|
||||
noticeSound.play();
|
||||
}
|
||||
chatTabs.getChildByName(PUBLIC_CHAT_USERID).addEventListener(FocusEvent.FOCUS_IN, publicChatFocus);
|
||||
chatTabs.getChildByName(PUBLIC_CHAT_USERID).addEventListener(FocusEvent.FOCUS_OUT, publicChatUnfocus);
|
||||
}
|
||||
|
||||
// Activates an audio alert for screen-reader users on private message reception
|
||||
private function privateNotification(event:PrivateChatMessageEvent):void{
|
||||
if (! UsersUtil.isMe(event.message.fromUserID)) {
|
||||
if (Accessibility.active){
|
||||
noticeSound.play();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function publicChatFocus(event:FocusEvent):void{
|
||||
publicFocus = true;
|
||||
publicWaiting = false;
|
||||
}
|
||||
|
||||
public function publicChatUnfocus(event:FocusEvent):void {
|
||||
publicFocus = false;
|
||||
}
|
||||
|
||||
private function focusPreviousChatTab(e:ShortcutEvent):void{
|
||||
if (chatTabs.selectedIndex > 0){
|
||||
chatTabs.selectedIndex--;
|
||||
}
|
||||
else{
|
||||
chatTabs.selectedIndex = chatTabs.numChildren - 1;
|
||||
}
|
||||
}
|
||||
|
||||
private function focusNextChatTab(e:ShortcutEvent):void{
|
||||
if (chatTabs.selectedIndex < chatTabs.numChildren - 1){
|
||||
chatTabs.selectedIndex++;
|
||||
}
|
||||
else{
|
||||
chatTabs.selectedIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private function onTabClose(e:SuperTabEvent):void{
|
||||
dispatchEvent(e);
|
||||
}
|
||||
|
||||
private function onUserClosedTab(e:SuperTabEvent):void{
|
||||
var name:String = chatTabs.getChildAt(e.tabIndex).name;
|
||||
}
|
||||
|
||||
]]>
|
||||
</mx:Script>
|
||||
<containers:SuperTabNavigator includeInLayout="false" id="chatTabs"
|
||||
width="100%" height="100%" change="onTabNavChange()"
|
||||
tabClose="onTabClose(event)" minTabWidth="20"
|
||||
dragEnabled="false" popUpButtonPolicy="off" tabIndex="{baseIndex}"
|
||||
/>
|
||||
</mx:VBox>
|
||||
|
@ -20,7 +20,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
-->
|
||||
|
||||
<MDIWindow xmlns="flexlib.mdi.containers.*"
|
||||
<CustomMdiWindow xmlns="org.bigbluebutton.common.*"
|
||||
xmlns:mx="http://www.adobe.com/2006/mxml"
|
||||
xmlns:chat="org.bigbluebutton.modules.chat.views.components.*"
|
||||
showCloseButton="false"
|
||||
@ -40,7 +40,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
<![CDATA[
|
||||
import org.bigbluebutton.modules.chat.model.ChatOptions;
|
||||
import com.asfusion.mate.events.Dispatcher;
|
||||
import flexlib.mdi.events.MDIWindowEvent;
|
||||
import mx.controls.Alert;
|
||||
import mx.core.Application;
|
||||
import mx.core.FlexGlobals;
|
||||
@ -192,4 +191,4 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
</mx:Script>
|
||||
|
||||
<views:ChatView id="chatView" chatOptions="{chatOptions}" includeInLayout="false"/>
|
||||
</MDIWindow>
|
||||
</CustomMdiWindow>
|
||||
|
@ -20,11 +20,11 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
-->
|
||||
|
||||
<dspub:MDIWindow
|
||||
<dspub:CustomMdiWindow
|
||||
xmlns:mx="http://www.adobe.com/2006/mxml"
|
||||
implements="org.bigbluebutton.common.IBbbModuleWindow"
|
||||
xmlns:mate="http://mate.asfusion.com/"
|
||||
xmlns:dspub="flexlib.mdi.containers.*"
|
||||
xmlns:dspub="org.bigbluebutton.common.*"
|
||||
backgroundColor="#C0C0C0"
|
||||
initialize="init()"
|
||||
creationComplete="onCreationComplete()"
|
||||
@ -48,7 +48,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
<![CDATA[
|
||||
import com.asfusion.mate.events.Dispatcher;
|
||||
|
||||
import flexlib.mdi.events.MDIWindowEvent;
|
||||
import flexlib.scheduling.scheduleClasses.BackgroundItem;
|
||||
|
||||
import mx.core.UIComponent;
|
||||
@ -455,4 +454,4 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
</dspub:states>
|
||||
<mx:Image id="cursorImg" visible="false" source="@Embed('../../assets/images/cursor4.png')"/>
|
||||
|
||||
</dspub:MDIWindow>
|
||||
</dspub:CustomMdiWindow>
|
||||
|
@ -20,7 +20,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
-->
|
||||
|
||||
<MDIWindow xmlns="flexlib.mdi.containers.*"
|
||||
<CustomMdiWindow xmlns="org.bigbluebutton.common.*"
|
||||
xmlns:mx="http://www.adobe.com/2006/mxml"
|
||||
xmlns:views="org.bigbluebutton.modules.deskshare.view.components.*"
|
||||
width="600" height="400"
|
||||
@ -270,4 +270,4 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
toolTip="{actualSize ? ResourceUtil.getInstance().getString('bbb.desktopView.fitToWindow') : ResourceUtil.getInstance().getString('bbb.desktopView.actualSize')}"
|
||||
tabIndex="{baseIndex+4}"/>
|
||||
</views:DesktopViewToolbar>
|
||||
</MDIWindow>
|
||||
</CustomMdiWindow>
|
||||
|
@ -23,15 +23,13 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
<!--
|
||||
Notes.mxml is the main view of the SharedNotes application
|
||||
-->
|
||||
<MDIWindow xmlns="flexlib.mdi.containers.*" xmlns:mx="http://www.adobe.com/2006/mxml"
|
||||
<CustomMdiWindow xmlns="org.bigbluebutton.common.*" xmlns:mx="http://www.adobe.com/2006/mxml"
|
||||
width="400" height="300" xmlns:mate="http://mate.asfusion.com/"
|
||||
implements="org.bigbluebutton.common.IBbbModuleWindow" creationComplete="onCreationComplete()"
|
||||
label="Example Chat Window" layout="vertical">
|
||||
|
||||
<mx:Script>
|
||||
<![CDATA[
|
||||
import flexlib.mdi.events.MDIWindowEvent;
|
||||
|
||||
import org.bigbluebutton.main.views.MainCanvas;
|
||||
|
||||
private var proxy:ExampleChatProxy;
|
||||
@ -65,4 +63,4 @@ Notes.mxml is the main view of the SharedNotes application
|
||||
<mx:TextInput id="txtInput" width="90%" />
|
||||
<mx:Button id="btnSendMessage" label="Send Message" click="sendNewMessage()" />
|
||||
</mx:HBox>
|
||||
</MDIWindow>
|
||||
</CustomMdiWindow>
|
||||
|
@ -43,9 +43,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
import flash.net.FileReference;
|
||||
|
||||
import flexlib.mdi.containers.MDICanvas;
|
||||
import flexlib.mdi.containers.MDIWindow;
|
||||
import flexlib.mdi.events.MDIManagerEvent;
|
||||
import flexlib.mdi.events.MDIWindowEvent;
|
||||
import flexlib.mdi.managers.MDIManager;
|
||||
|
||||
import mx.collections.ArrayCollection;
|
||||
|
@ -18,8 +18,8 @@ You should have received a copy of the GNU Lesser General Public License along
|
||||
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
-->
|
||||
<ns:MDIWindow xmlns:mx="http://www.adobe.com/2006/mxml"
|
||||
xmlns:ns="http://code.google.com/p/flexlib/"
|
||||
<ns:CustomMdiWindow xmlns:mx="http://www.adobe.com/2006/mxml"
|
||||
xmlns:ns="org.bigbluebutton.common.*"
|
||||
xmlns:views="org.bigbluebutton.modules.notes.views.*"
|
||||
implements="org.bigbluebutton.common.IBbbModuleWindow"
|
||||
title="Notes"
|
||||
@ -46,4 +46,4 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
</mx:Script>
|
||||
|
||||
<views:NotesView id="notesView" notesArray="{notesModel}"/>
|
||||
</ns:MDIWindow>
|
||||
</ns:CustomMdiWindow>
|
||||
|
@ -18,7 +18,7 @@ $Id: $
|
||||
<!--
|
||||
Notes.mxml is the main view of the SharedNotes application
|
||||
-->
|
||||
<MDIWindow xmlns="flexlib.mdi.containers.*"
|
||||
<CustomMdiWindow xmlns="org.bigbluebutton.common.*"
|
||||
xmlns:mx="http://www.adobe.com/2006/mxml"
|
||||
width="510" height="600"
|
||||
xmlns:mate="http://mate.asfusion.com/"
|
||||
@ -46,4 +46,4 @@ Notes.mxml is the main view of the SharedNotes application
|
||||
|
||||
|
||||
<poll:PollCreatePanel width="100%" height="100%"/>
|
||||
</MDIWindow>
|
||||
</CustomMdiWindow>
|
||||
|
@ -20,7 +20,7 @@
|
||||
$Id: $
|
||||
-->
|
||||
|
||||
<MDIWindow xmlns="flexlib.mdi.containers.*"
|
||||
<CustomMdiWindow xmlns="org.bigbluebutton.common.*"
|
||||
xmlns:mx="http://www.adobe.com/2006/mxml"
|
||||
xmlns:poll="org.bigbluebutton.modules.polling.views.*"
|
||||
height="510"
|
||||
@ -54,4 +54,4 @@
|
||||
</mx:Script>
|
||||
|
||||
<poll:PollResultPanel width="100%" height="100%" viewModel="{viewModel}" pollID="{pollID}"/>
|
||||
</MDIWindow>
|
||||
</CustomMdiWindow>
|
||||
|
@ -18,7 +18,7 @@ $Id: $
|
||||
<!--
|
||||
Notes.mxml is the main view of the SharedNotes application
|
||||
-->
|
||||
<MDIWindow xmlns="flexlib.mdi.containers.*"
|
||||
<CustomMdiWindow xmlns="org.bigbluebutton.common.*"
|
||||
xmlns:mx="http://www.adobe.com/2006/mxml"
|
||||
width="510" height="600"
|
||||
xmlns:mate="http://mate.asfusion.com/"
|
||||
@ -32,8 +32,6 @@ Notes.mxml is the main view of the SharedNotes application
|
||||
<![CDATA[
|
||||
import com.asfusion.mate.events.Dispatcher;
|
||||
|
||||
import flexlib.mdi.events.MDIWindowEvent;
|
||||
|
||||
import mx.collections.ArrayCollection;
|
||||
import mx.containers.HBox;
|
||||
import mx.controls.Alert;
|
||||
@ -179,4 +177,4 @@ Notes.mxml is the main view of the SharedNotes application
|
||||
label="{ResourceUtil.getInstance().getString('bbb.polling.pollPreview.cancel')}" />
|
||||
</mx:ControlBar>
|
||||
|
||||
</MDIWindow>
|
||||
</CustomMdiWindow>
|
||||
|
@ -18,7 +18,7 @@ $Id: $
|
||||
<!--
|
||||
Notes.mxml is the main view of the SharedNotes application
|
||||
-->
|
||||
<MDIWindow xmlns="flexlib.mdi.containers.*"
|
||||
<CustomMdiWindow xmlns="org.bigbluebutton.common.*"
|
||||
xmlns:mx="http://www.adobe.com/2006/mxml"
|
||||
width="700" height="450"
|
||||
xmlns:mate="http://mate.asfusion.com/"
|
||||
@ -49,4 +49,4 @@ Notes.mxml is the main view of the SharedNotes application
|
||||
|
||||
<poll:PollMainPanel width="100%" height="100%" viewModel="{viewModel}"/>
|
||||
|
||||
</MDIWindow>
|
||||
</CustomMdiWindow>
|
||||
|
@ -18,7 +18,7 @@ $Id: $
|
||||
<!--
|
||||
Notes.mxml is the main view of the SharedNotes application
|
||||
-->
|
||||
<MDIWindow xmlns="flexlib.mdi.containers.*"
|
||||
<CustomMdiWindow xmlns="org.bigbluebutton.common.*"
|
||||
xmlns:mx="http://www.adobe.com/2006/mxml"
|
||||
width="510" height="450"
|
||||
xmlns:mate="http://mate.asfusion.com/"
|
||||
@ -49,4 +49,4 @@ Notes.mxml is the main view of the SharedNotes application
|
||||
|
||||
|
||||
<poll:TakePollPanel id="takePollPanel" width="100%" height="100%" viewModel="{viewModel}" pollID="{pollID}"/>
|
||||
</MDIWindow>
|
||||
</CustomMdiWindow>
|
||||
|
@ -18,7 +18,7 @@ $Id: $
|
||||
<!--
|
||||
Notes.mxml is the main view of the SharedNotes application
|
||||
-->
|
||||
<MDIWindow xmlns="flexlib.mdi.containers.*"
|
||||
<CustomMdiWindow xmlns="org.bigbluebutton.common.*"
|
||||
xmlns:mx="http://www.adobe.com/2006/mxml"
|
||||
width="510" height="450"
|
||||
xmlns:mate="http://mate.asfusion.com/"
|
||||
@ -49,4 +49,4 @@ Notes.mxml is the main view of the SharedNotes application
|
||||
|
||||
|
||||
<poll:UpdatePollPanel width="100%" height="100%" viewModel="{viewModel}" pollID="{pollID}"/>
|
||||
</MDIWindow>
|
||||
</CustomMdiWindow>
|
||||
|
@ -21,9 +21,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
|
||||
<pres:MDIWindow xmlns:mx="http://www.adobe.com/2006/mxml"
|
||||
<pres:CustomMdiWindow xmlns:mx="http://www.adobe.com/2006/mxml"
|
||||
xmlns:thumb="org.bigbluebutton.modules.present.views.*"
|
||||
xmlns:pres="flexlib.mdi.containers.*"
|
||||
xmlns:pres="org.bigbluebutton.common.*"
|
||||
xmlns:code="http://code.google.com/p/flexlib/"
|
||||
xmlns:containers="flexlib.containers.*"
|
||||
xmlns:mate="http://mate.asfusion.com/"
|
||||
@ -104,8 +104,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
private static const LOG:String = "Present::PresentationWindow - ";
|
||||
|
||||
public static const TITLE:String = "Presentation";
|
||||
private static const NEXT_BUTTON:String = "Next";
|
||||
private static const PREVIOUS_BUTTON:String = "Previous";
|
||||
private static const GOTO_PAGE_BUTTON:String = "Go to Page...";
|
||||
|
||||
[Bindable]
|
||||
@ -350,8 +348,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
private function becomeViewer():void{
|
||||
setupPresenter(false);
|
||||
dispatchEvent(new UploadEvent(UploadEvent.CLOSE_UPLOAD_WINDOW));
|
||||
this.contextMenu = new ContextMenu();
|
||||
this.contextMenu.hideBuiltInItems();
|
||||
this.customContextMenuItems = new Array();
|
||||
if (slideView.thumbnailView.visible)
|
||||
showThumbnails();
|
||||
}
|
||||
@ -399,31 +396,19 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
}
|
||||
|
||||
private function addContextMenuItems():void{
|
||||
var contextMenu:ContextMenu = new ContextMenu();
|
||||
contextMenu.hideBuiltInItems();
|
||||
var contextMenuItems:Array = new Array();
|
||||
|
||||
var nextButton:ContextMenuItem = new ContextMenuItem(NEXT_BUTTON);
|
||||
nextButton.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, menuItemHandler);
|
||||
contextMenu.customItems.push(nextButton);
|
||||
var nextButton:ContextMenuItem = new ContextMenuItem(ResourceUtil.getInstance().getString('bbb.presentation.forwardBtn.toolTip'));
|
||||
nextButton.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, function(e:ContextMenuEvent):void { gotoNextSlide(); });
|
||||
contextMenuItems.push(nextButton);
|
||||
|
||||
var previousButton:ContextMenuItem = new ContextMenuItem(PREVIOUS_BUTTON);
|
||||
previousButton.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, menuItemHandler);
|
||||
contextMenu.customItems.push(previousButton);
|
||||
var previousButton:ContextMenuItem = new ContextMenuItem(ResourceUtil.getInstance().getString('bbb.presentation.backBtn.toolTip'));
|
||||
previousButton.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, function(e:ContextMenuEvent):void { gotoPreviousSlide(); });
|
||||
contextMenuItems.push(previousButton);
|
||||
|
||||
this.contextMenu = contextMenu;
|
||||
this.customContextMenuItems = contextMenuItems;
|
||||
}
|
||||
|
||||
private function menuItemHandler(e:ContextMenuEvent):void{
|
||||
switch(e.target.caption){
|
||||
case NEXT_BUTTON:
|
||||
gotoNextSlide();
|
||||
break;
|
||||
case PREVIOUS_BUTTON:
|
||||
gotoPreviousSlide();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private function notifyOthersOfSharingPresentation(presentationName:String):void {
|
||||
var shareEvent:PresenterCommands = new PresenterCommands(PresenterCommands.SHARE_PRESENTATION_COMMAND);
|
||||
shareEvent.presentationName = presentationName;
|
||||
@ -527,6 +512,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
if(Capabilities.hasAccessibility)
|
||||
Accessibility.updateProperties();
|
||||
|
||||
addContextMenuItems();
|
||||
}
|
||||
|
||||
private function localeChanged(e:Event):void{
|
||||
@ -658,4 +645,4 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
<!-- This spacer is to prevent the whiteboard toolbar from overlapping the fit-ot-page button -->
|
||||
<mx:Spacer width="30" height="30" id="spacer4"/>
|
||||
</mx:ControlBar>
|
||||
</pres:MDIWindow>
|
||||
</pres:CustomMdiWindow>
|
||||
|
@ -18,8 +18,8 @@
|
||||
|
||||
Author: Islam El-Ashi <ielashi@gmail.com>, <http://www.ielashi.com>
|
||||
-->
|
||||
<containers:MDIWindow xmlns:mx="http://www.adobe.com/2006/mxml"
|
||||
xmlns:containers="flexlib.mdi.containers.*"
|
||||
<containers:CustomMdiWindow xmlns:mx="http://www.adobe.com/2006/mxml"
|
||||
xmlns:containers="org.bigbluebutton.common.*"
|
||||
xmlns:mate="http://mate.asfusion.com/"
|
||||
layout="absolute"
|
||||
minWidth="160"
|
||||
@ -38,8 +38,6 @@
|
||||
|
||||
import flash.utils.getTimer;
|
||||
|
||||
import flexlib.mdi.events.MDIWindowEvent;
|
||||
|
||||
import mx.accessibility.AlertAccImpl;
|
||||
import mx.binding.utils.BindingUtils;
|
||||
import mx.controls.Alert;
|
||||
@ -210,4 +208,4 @@
|
||||
<mx:Button width="26" height="26" click="btnSave_clickHandler(event)" icon="@Embed(source='images/ic_save_16px.png')" toolTip="{ResourceUtil.getInstance().getString('bbb.sharedNotes.save.toolTip')}"/>
|
||||
</mx:HBox>
|
||||
</mx:VBox>
|
||||
</containers:MDIWindow>
|
||||
</containers:CustomMdiWindow>
|
||||
|
@ -20,8 +20,8 @@
|
||||
$Id: $
|
||||
-->
|
||||
|
||||
<mdi:MDIWindow xmlns:mx="http://www.adobe.com/2006/mxml"
|
||||
xmlns:mdi="flexlib.mdi.containers.*"
|
||||
<mdi:CustomMdiWindow xmlns:mx="http://www.adobe.com/2006/mxml"
|
||||
xmlns:mdi="org.bigbluebutton.common.*"
|
||||
xmlns:flc="flexlib.controls.*"
|
||||
implements="org.bigbluebutton.common.IBbbModuleWindow"
|
||||
xmlns:mate="http://mate.asfusion.com/"
|
||||
@ -614,4 +614,4 @@
|
||||
</mx:VBox>
|
||||
</mx:ControlBar>
|
||||
|
||||
</mdi:MDIWindow>
|
||||
</mdi:CustomMdiWindow>
|
||||
|
@ -20,7 +20,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
-->
|
||||
|
||||
<MDIWindow xmlns="flexlib.mdi.containers.*"
|
||||
<CustomMdiWindow xmlns="org.bigbluebutton.common.*"
|
||||
xmlns:mx="http://www.adobe.com/2006/mxml"
|
||||
initialize="init()"
|
||||
horizontalScrollPolicy="off"
|
||||
@ -51,4 +51,4 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
}
|
||||
]]>
|
||||
</mx:Script>
|
||||
</MDIWindow>
|
||||
</CustomMdiWindow>
|
||||
|
@ -1,436 +1,435 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
|
||||
BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
|
||||
Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU Lesser General Public License as published by the Free Software
|
||||
Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
-->
|
||||
|
||||
<mx:VBox xmlns="flexlib.containers.*"
|
||||
initialize="init()"
|
||||
xmlns:mx="http://www.adobe.com/2006/mxml"
|
||||
xmlns:view="org.bigbluebutton.modules.whiteboard.views.*"
|
||||
xmlns:wbBtns="org.bigbluebutton.modules.whiteboard.views.buttons.*"
|
||||
xmlns:mate="http://mate.asfusion.com/"
|
||||
creationComplete="onCreationComplete()"
|
||||
visible="{showWhiteboardToolbar}"
|
||||
includeInLayout="{showWhiteboardToolbar}"
|
||||
styleName="whiteboardToolbarStyle"
|
||||
hideEffect="{fadeOut}" showEffect="{fadeIn}">
|
||||
|
||||
<mate:Listener type="{MadePresenterEvent.SWITCH_TO_PRESENTER_MODE}" method="presenterMode" />
|
||||
<mate:Listener type="{MadePresenterEvent.SWITCH_TO_VIEWER_MODE}" method="viewerMode" />
|
||||
<mate:Listener type="{StopWhiteboardModuleEvent.STOP_HIGHLIGHTER_MODULE_EVENT}" method="closeToolbar" />
|
||||
<mate:Listener type="{ShortcutEvent.UNDO_WHITEBOARD}" method="undoShortcut" />
|
||||
<mate:Listener type="{GraphicObjectFocusEvent.OBJECT_SELECTED}" method="graphicObjSelected" />
|
||||
<mate:Listener type="{GraphicObjectFocusEvent.OBJECT_DESELECTED}" method="graphicObjDeselected" />
|
||||
<mate:Listener type="{WhiteboardButtonEvent.WHITEBOARD_BUTTON_PRESSED}" method="handleWhiteboardButtonPressed"/>
|
||||
<mate:Listener type="{ChangeMyRole.CHANGE_MY_ROLE_EVENT}" method="refreshRole" />
|
||||
<mate:Listener type="{NavigationEvent.GOTO_PAGE}" method="handleSlideChange" />
|
||||
<mate:Listener type="{DisplaySlideEvent.DISPLAY_SLIDE_EVENT}" method="handleSlideLoaded" />
|
||||
<mate:Listener type="{UploadEvent.PRESENTATION_READY}" method="handlePresentationSwitch" />
|
||||
|
||||
<mx:Style>
|
||||
.colorPickerStyle {
|
||||
backgroundColor:#E5E6E7;
|
||||
columnCount:13;
|
||||
horizontalGap:0;
|
||||
previewHeight:22;
|
||||
previewWidth:50;
|
||||
swatchGridBackgroundColor:#000000;
|
||||
swatchGridBorderSize:0;
|
||||
swatchHeight:60;
|
||||
swatchHighlightColor:#FFFFFF;
|
||||
swatchHighlightSize:1;
|
||||
swatchWidth:12;
|
||||
textFieldWidth:72;
|
||||
verticalGap:0;
|
||||
}
|
||||
|
||||
</mx:Style>
|
||||
|
||||
<mx:Script>
|
||||
<![CDATA[
|
||||
import com.asfusion.mate.events.Listener;
|
||||
import flash.ui.Keyboard;
|
||||
import flexlib.mdi.events.MDIWindowEvent;
|
||||
import mx.containers.ControlBar;
|
||||
import mx.events.MoveEvent;
|
||||
import mx.events.ResizeEvent;
|
||||
import mx.managers.CursorManager;
|
||||
import org.bigbluebutton.common.Images;
|
||||
import org.bigbluebutton.common.LogUtil;
|
||||
import org.bigbluebutton.core.UsersUtil;
|
||||
import org.bigbluebutton.core.managers.UserManager;
|
||||
import org.bigbluebutton.main.events.MadePresenterEvent;
|
||||
import org.bigbluebutton.main.events.ShortcutEvent;
|
||||
import org.bigbluebutton.main.model.users.events.ChangeMyRole;
|
||||
import org.bigbluebutton.modules.present.events.DisplaySlideEvent;
|
||||
import org.bigbluebutton.modules.present.events.PresentationEvent;
|
||||
import org.bigbluebutton.modules.present.events.NavigationEvent;
|
||||
import org.bigbluebutton.modules.present.events.UploadEvent;
|
||||
import org.bigbluebutton.modules.present.ui.views.PresentationWindow;
|
||||
import org.bigbluebutton.modules.present.ui.views.SlideView;
|
||||
import org.bigbluebutton.modules.whiteboard.business.shapes.DrawObject;
|
||||
import org.bigbluebutton.modules.whiteboard.business.shapes.GraphicObject;
|
||||
import org.bigbluebutton.modules.whiteboard.business.shapes.TextObject;
|
||||
import org.bigbluebutton.modules.whiteboard.business.shapes.WhiteboardConstants;
|
||||
import org.bigbluebutton.modules.whiteboard.events.GraphicObjectFocusEvent;
|
||||
import org.bigbluebutton.modules.whiteboard.events.StopWhiteboardModuleEvent;
|
||||
import org.bigbluebutton.modules.whiteboard.events.ToggleGridEvent;
|
||||
import org.bigbluebutton.modules.whiteboard.events.WhiteboardButtonEvent;
|
||||
import org.bigbluebutton.modules.whiteboard.events.WhiteboardDrawEvent;
|
||||
import org.bigbluebutton.modules.whiteboard.events.WhiteboardPresenterEvent;
|
||||
import org.bigbluebutton.modules.whiteboard.events.WhiteboardSettingResetEvent;
|
||||
import org.bigbluebutton.modules.whiteboard.views.models.WhiteboardOptions;
|
||||
import org.bigbluebutton.util.i18n.ResourceUtil;
|
||||
|
||||
private var images:Images = new Images();
|
||||
[Bindable] private var hand_icon:Class = images.hand_icon;
|
||||
[Bindable] private var pencil_icon:Class = images.pencil_icon;
|
||||
[Bindable] private var undo_icon:Class = images.undo_icon;
|
||||
[Bindable] private var delete_icon:Class = images.delete_icon;
|
||||
[Bindable] private var rectangle_icon:Class = images.square_icon;
|
||||
[Bindable] private var ellipse_icon:Class = images.circle_icon;
|
||||
[Bindable] private var thick_icon:Class = images.whiteboard_thick;
|
||||
[Bindable] private var thin_icon:Class = images.whiteboard_thin;
|
||||
[Bindable] private var scribble_icon:Class = images.scribble_icon;
|
||||
[Bindable] private var text_icon:Class = images.text_icon;
|
||||
[Bindable] private var triangle_icon:Class = images.triangle_icon;
|
||||
[Bindable] private var line_icon:Class = images.line_icon;
|
||||
[Bindable] private var fill_icon:Class = images.fill_icon;
|
||||
[Bindable] private var transparency_icon:Class = images.transparency_icon;
|
||||
[Bindable] private var eraser_icon:Class = images.eraser_icon;
|
||||
[Bindable] private var highlighter_icon:Class = images.highlighter_icon;
|
||||
[Bindable] private var select_icon:Class = images.select_icon;
|
||||
[Bindable] private var grid_icon:Class = images.grid_icon;
|
||||
|
||||
[Bindable] public var wbOptions:WhiteboardOptions;
|
||||
[Bindable] private var baseIndex:int;
|
||||
|
||||
[Bindable] private var showWhiteboardToolbar:Boolean = false;
|
||||
|
||||
private static const LOG:String = "WB::WhiteboardToolbar - ";
|
||||
|
||||
private var mousedOver:Boolean = false;
|
||||
private var slideLoaded:Boolean = false;
|
||||
|
||||
public var canvas:WhiteboardCanvas;
|
||||
private var presentationWindow:PresentationWindow;
|
||||
|
||||
[Bindable] private var colorPickerColours:Array = ['0x000000', '0xFFFFFF' , '0xFF0000', '0xFF8800',
|
||||
'0xCCFF00', '0x00FF00', '0x00FF88', '0x00FFFF', '0x0088FF', '0x0000FF', '0x8800FF', '0xFF00FF', '0xC0C0C0'];
|
||||
|
||||
private var _hideToolbarTimer:Timer = new Timer(500, 1);
|
||||
|
||||
private function init():void{
|
||||
wbOptions = new WhiteboardOptions();
|
||||
baseIndex = wbOptions.baseTabIndex;
|
||||
}
|
||||
|
||||
private function onCreationComplete():void {
|
||||
setToolType(WhiteboardConstants.TYPE_ZOOM, null);
|
||||
_hideToolbarTimer.addEventListener(TimerEvent.TIMER, onHideToolbarTimerComplete);
|
||||
}
|
||||
|
||||
private function handleWhiteboardButtonPressed(e:WhiteboardButtonEvent):void {
|
||||
setToolType(e.graphicType, e.toolType);
|
||||
}
|
||||
|
||||
private function setToolType(graphicType:String, toolType:String):void {
|
||||
if (graphicType == WhiteboardConstants.TYPE_CLEAR) {
|
||||
dispatchEvent(new WhiteboardDrawEvent(WhiteboardDrawEvent.CLEAR));
|
||||
} else if (graphicType == WhiteboardConstants.TYPE_UNDO) {
|
||||
sendUndoCommand();
|
||||
} else {
|
||||
canvas.setGraphicType(graphicType);
|
||||
canvas.setTool(toolType);
|
||||
|
||||
if (panzoomBtn != null) {
|
||||
panzoomBtn.setTool(graphicType, toolType);
|
||||
}
|
||||
|
||||
if (scribbleBtn != null) {
|
||||
scribbleBtn.setTool(graphicType, toolType);
|
||||
}
|
||||
|
||||
if (rectangleBtn != null) {
|
||||
rectangleBtn.setTool(graphicType, toolType);
|
||||
}
|
||||
|
||||
if (circleBtn != null) {
|
||||
circleBtn.setTool(graphicType, toolType);
|
||||
}
|
||||
|
||||
if (triangleBtn != null) {
|
||||
triangleBtn.setTool(graphicType, toolType);
|
||||
}
|
||||
|
||||
if (lineBtn != null) {
|
||||
lineBtn.setTool(graphicType, toolType);
|
||||
}
|
||||
|
||||
if (textBtn != null) {
|
||||
textBtn.setTool(graphicType, toolType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function changeColor(e:Event):void {
|
||||
canvas.changeColor(e);
|
||||
}
|
||||
|
||||
protected function changeFillColor(e:Event):void {
|
||||
canvas.changeFillColor(e);
|
||||
}
|
||||
|
||||
protected function changeThickness(e:Event):void {
|
||||
canvas.changeThickness(e);
|
||||
}
|
||||
|
||||
protected function toggleFill():void {
|
||||
canvas.toggleFill();
|
||||
}
|
||||
|
||||
protected function toggleTransparency():void {
|
||||
canvas.toggleTransparency();
|
||||
}
|
||||
|
||||
private function presenterMode(e:MadePresenterEvent):void {
|
||||
if (canvas == null) return;
|
||||
|
||||
canvas.makeTextObjectsEditable(e);
|
||||
setToolType(WhiteboardConstants.TYPE_ZOOM, null);
|
||||
}
|
||||
|
||||
private function viewerMode(e:MadePresenterEvent):void {
|
||||
canvas.makeTextObjectsUneditable(e);
|
||||
if (!toolbarAllowed()) {
|
||||
checkVisibility();
|
||||
if (panzoomBtn) {
|
||||
panzoomBtn.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function undoShortcut(e:ShortcutEvent):void{
|
||||
trace(LOG + "Ctrl-Z got into undoShortcut");
|
||||
sendUndoCommand();
|
||||
}
|
||||
|
||||
private function sendUndoCommand():void {
|
||||
// if (!canvas.isPageEmpty()) {
|
||||
dispatchEvent(new WhiteboardDrawEvent(WhiteboardDrawEvent.UNDO));
|
||||
// }
|
||||
}
|
||||
|
||||
public function positionToolbar(window:PresentationWindow):void {
|
||||
trace(LOG + "Positioning whiteboard toolbar");
|
||||
presentationWindow = window;
|
||||
presentationWindow.addEventListener(MoveEvent.MOVE, setPositionAndDepth);
|
||||
presentationWindow.addEventListener(ResizeEvent.RESIZE, setPositionAndDepth);
|
||||
presentationWindow.addEventListener(MouseEvent.CLICK, setPositionAndDepth);
|
||||
|
||||
if (!wbOptions.keepToolbarVisible) {
|
||||
window.presCtrlBar.addEventListener(MouseEvent.ROLL_OVER, handleMouseOut);
|
||||
window.presCtrlBar.addEventListener(MouseEvent.ROLL_OUT, handleMouseIn);
|
||||
|
||||
window.addEventListener(MouseEvent.ROLL_OVER, handleMouseIn);
|
||||
window.addEventListener(MouseEvent.ROLL_OUT, handleMouseOut);
|
||||
|
||||
this.addEventListener(MouseEvent.ROLL_OVER, handleMouseIn);
|
||||
this.addEventListener(MouseEvent.ROLL_OUT, handleMouseOut);
|
||||
} else {
|
||||
var listener1:Listener = new Listener();
|
||||
listener1.method = checkVisibility;
|
||||
listener1.type = MadePresenterEvent.SWITCH_TO_PRESENTER_MODE;
|
||||
var listener2:Listener = new Listener();
|
||||
listener2.method = checkVisibility;
|
||||
listener2.type = MadePresenterEvent.SWITCH_TO_VIEWER_MODE;
|
||||
//Do an initial check to see if the toolbar should be visible
|
||||
checkVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
private function refreshRole(e:ChangeMyRole):void {
|
||||
checkVisibility();
|
||||
}
|
||||
|
||||
private function checkVisibility(e:MadePresenterEvent = null):void {
|
||||
if (toolbarAllowed() && slideLoaded && (wbOptions.keepToolbarVisible || mousedOver) && !presentationWindow.minimized) {
|
||||
setPositionAndDepth();
|
||||
showToolbar();
|
||||
} else {
|
||||
hideToolbar();
|
||||
}
|
||||
}
|
||||
|
||||
private function showToolbar():void {
|
||||
_hideToolbarTimer.reset();
|
||||
showWhiteboardToolbar = true;
|
||||
}
|
||||
|
||||
private function hideToolbar():void {
|
||||
_hideToolbarTimer.reset();
|
||||
_hideToolbarTimer.start();
|
||||
}
|
||||
|
||||
private function onHideToolbarTimerComplete(event:TimerEvent):void {
|
||||
showWhiteboardToolbar = false;
|
||||
}
|
||||
|
||||
private function setPositionAndDepth(e:Event = null):void {
|
||||
this.x = presentationWindow.x + presentationWindow.width - 43;
|
||||
this.y = presentationWindow.y + 30;
|
||||
parent.setChildIndex(this, parent.numChildren - 1);
|
||||
}
|
||||
|
||||
private function closeToolbar(e:StopWhiteboardModuleEvent):void {
|
||||
parent.removeChild(this);
|
||||
}
|
||||
|
||||
private function handleMouseIn(e:MouseEvent):void {
|
||||
mousedOver = true;
|
||||
checkVisibility();
|
||||
}
|
||||
|
||||
private function handleMouseOut(e:MouseEvent = null):void {
|
||||
mousedOver = false;
|
||||
checkVisibility();
|
||||
}
|
||||
|
||||
private function handleSlideLoaded(e:DisplaySlideEvent):void {
|
||||
slideLoaded = true;
|
||||
checkVisibility();
|
||||
}
|
||||
|
||||
private function handleSlideChange(e:NavigationEvent):void {
|
||||
slideLoaded = false;
|
||||
// don't switch the toolbar button on slide change
|
||||
checkVisibility();
|
||||
}
|
||||
|
||||
private function handlePresentationSwitch(e:UploadEvent):void {
|
||||
slideLoaded = false;
|
||||
if (panzoomBtn) {
|
||||
panzoomBtn.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
|
||||
}
|
||||
checkVisibility();
|
||||
}
|
||||
|
||||
private function graphicObjSelected(event:GraphicObjectFocusEvent):void {
|
||||
var gobj:GraphicObject = event.data;
|
||||
}
|
||||
|
||||
private function graphicObjDeselected(event:GraphicObjectFocusEvent):void {
|
||||
var gobj:GraphicObject = event.data;
|
||||
}
|
||||
|
||||
private function toolbarAllowed():Boolean {
|
||||
if (wbOptions) {
|
||||
if (wbOptions.whiteboardAccess == "presenter")
|
||||
return isPresenter;
|
||||
else if (wbOptions.whiteboardAccess == "moderator")
|
||||
return isModerator || isPresenter;
|
||||
else if (wbOptions.whiteboardAccess == "all")
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Helper method to test whether this user is the presenter */
|
||||
private function get isPresenter():Boolean {
|
||||
return UsersUtil.amIPresenter();
|
||||
}
|
||||
|
||||
private function get isModerator():Boolean {
|
||||
return UsersUtil.amIModerator();
|
||||
}
|
||||
|
||||
]]>
|
||||
</mx:Script>
|
||||
|
||||
<mx:Fade id="fadeOut" duration="200" alphaFrom="1.0" alphaTo="0.0" />
|
||||
<mx:Fade id="fadeIn" duration="200" alphaFrom="0.0" alphaTo="1.0" />
|
||||
|
||||
<!-- Now, every 'tool' has two types of identifiers, one is found in WhiteboardConstants
|
||||
that identifies the "category" of the tool (ex. shape vs text), and the other specifies the
|
||||
tool itself (ex. line tool vs triangle tool, even though both are "shapes")
|
||||
-->
|
||||
<wbBtns:PanZoomButton id="panzoomBtn"
|
||||
tabIndex="{baseIndex}"
|
||||
visible="{showWhiteboardToolbar}"/>
|
||||
<mx:Spacer height="10" visible="{showWhiteboardToolbar}"/>
|
||||
<wbBtns:ScribbleButton id="scribbleBtn"
|
||||
tabIndex="{baseIndex+1}"
|
||||
visible="{showWhiteboardToolbar}"/>
|
||||
<wbBtns:RectangleButton id="rectangleBtn"
|
||||
tabIndex="{baseIndex+2}"
|
||||
visible="{showWhiteboardToolbar}"/>
|
||||
<wbBtns:CircleButton id="circleBtn"
|
||||
tabIndex="{baseIndex+3}"
|
||||
visible="{showWhiteboardToolbar}"/>
|
||||
<wbBtns:TriangleButton id="triangleBtn"
|
||||
tabIndex="{baseIndex+4}"
|
||||
visible="{showWhiteboardToolbar}"/>
|
||||
<wbBtns:LineButton id="lineBtn"
|
||||
tabIndex="{baseIndex+5}"
|
||||
visible="{showWhiteboardToolbar}"/>
|
||||
<wbBtns:TextButton id="textBtn"
|
||||
tabIndex="{baseIndex+6}"
|
||||
visible="{showWhiteboardToolbar}"/>
|
||||
|
||||
<mx:Spacer height="5" visible="{showWhiteboardToolbar}"/>
|
||||
<wbBtns:ClearButton id="clearBtn"
|
||||
tabIndex="{baseIndex+7}"
|
||||
visible="{showWhiteboardToolbar}"/>
|
||||
<wbBtns:UndoButton id="undoBtn"
|
||||
tabIndex="{baseIndex+8}"
|
||||
visible="{showWhiteboardToolbar}"/>
|
||||
|
||||
<mx:Spacer height="5" visible="{showWhiteboardToolbar}"/>
|
||||
|
||||
<!--
|
||||
Properties that were removed from original color picker:
|
||||
|
||||
swatchPanelStyleName="colorPickerStyle"
|
||||
dataProvider="{colorPickerColours}"
|
||||
-->
|
||||
|
||||
<!-- Layout is really bad right now, and is confusing. Basically, there are two
|
||||
of ColorPickers, one for the "line" color for the outlines of shapes, and the other for
|
||||
the "fill" color that is used only if "fill" is enabled in WhiteboardCanvasModel
|
||||
-->
|
||||
<mx:ColorPicker change="changeColor(event)" id="cpik" visible="{showWhiteboardToolbar}"
|
||||
selectedColor="0x000000" width="30" dataProvider="{colorPickerColours}" swatchPanelStyleName="colorPickerStyle"
|
||||
toolTip="{ResourceUtil.getInstance().getString('bbb.highlighter.toolbar.color')}"
|
||||
tabIndex="{baseIndex+9}"
|
||||
accessibilityName="{ResourceUtil.getInstance().getString('bbb.highlighter.toolbar.color')}"/>
|
||||
|
||||
<mx:Spacer height="3" visible="{showWhiteboardToolbar}"/>
|
||||
<mx:Image source="{thick_icon}" horizontalAlign="center" width="30" visible="{showWhiteboardToolbar}"/>
|
||||
<mx:VSlider height="50" id="sld" change="changeThickness(event)" visible="{showWhiteboardToolbar}"
|
||||
toolTip="{ResourceUtil.getInstance().getString('bbb.highlighter.toolbar.thickness.accessibilityName')}"
|
||||
minimum="1" maximum="30"
|
||||
useHandCursor="true" value="2" showDataTip="true" snapInterval="1" dataTipOffset="0" labelOffset="0"
|
||||
tabIndex="{baseIndex+10}"
|
||||
accessibilityName="{ResourceUtil.getInstance().getString('bbb.highlighter.toolbar.thickness.accessibilityName')}" />
|
||||
<mx:Image source="{thin_icon}" horizontalAlign="center" width="30" visible="{showWhiteboardToolbar}"/>
|
||||
|
||||
</mx:VBox>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
|
||||
BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
|
||||
Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU Lesser General Public License as published by the Free Software
|
||||
Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
-->
|
||||
|
||||
<mx:VBox xmlns="flexlib.containers.*"
|
||||
initialize="init()"
|
||||
xmlns:mx="http://www.adobe.com/2006/mxml"
|
||||
xmlns:view="org.bigbluebutton.modules.whiteboard.views.*"
|
||||
xmlns:wbBtns="org.bigbluebutton.modules.whiteboard.views.buttons.*"
|
||||
xmlns:mate="http://mate.asfusion.com/"
|
||||
creationComplete="onCreationComplete()"
|
||||
visible="{showWhiteboardToolbar}"
|
||||
includeInLayout="{showWhiteboardToolbar}"
|
||||
styleName="whiteboardToolbarStyle"
|
||||
hideEffect="{fadeOut}" showEffect="{fadeIn}">
|
||||
|
||||
<mate:Listener type="{MadePresenterEvent.SWITCH_TO_PRESENTER_MODE}" method="presenterMode" />
|
||||
<mate:Listener type="{MadePresenterEvent.SWITCH_TO_VIEWER_MODE}" method="viewerMode" />
|
||||
<mate:Listener type="{StopWhiteboardModuleEvent.STOP_HIGHLIGHTER_MODULE_EVENT}" method="closeToolbar" />
|
||||
<mate:Listener type="{ShortcutEvent.UNDO_WHITEBOARD}" method="undoShortcut" />
|
||||
<mate:Listener type="{GraphicObjectFocusEvent.OBJECT_SELECTED}" method="graphicObjSelected" />
|
||||
<mate:Listener type="{GraphicObjectFocusEvent.OBJECT_DESELECTED}" method="graphicObjDeselected" />
|
||||
<mate:Listener type="{WhiteboardButtonEvent.WHITEBOARD_BUTTON_PRESSED}" method="handleWhiteboardButtonPressed"/>
|
||||
<mate:Listener type="{ChangeMyRole.CHANGE_MY_ROLE_EVENT}" method="refreshRole" />
|
||||
<mate:Listener type="{NavigationEvent.GOTO_PAGE}" method="handleSlideChange" />
|
||||
<mate:Listener type="{DisplaySlideEvent.DISPLAY_SLIDE_EVENT}" method="handleSlideLoaded" />
|
||||
<mate:Listener type="{UploadEvent.PRESENTATION_READY}" method="handlePresentationSwitch" />
|
||||
|
||||
<mx:Style>
|
||||
.colorPickerStyle {
|
||||
backgroundColor:#E5E6E7;
|
||||
columnCount:13;
|
||||
horizontalGap:0;
|
||||
previewHeight:22;
|
||||
previewWidth:50;
|
||||
swatchGridBackgroundColor:#000000;
|
||||
swatchGridBorderSize:0;
|
||||
swatchHeight:60;
|
||||
swatchHighlightColor:#FFFFFF;
|
||||
swatchHighlightSize:1;
|
||||
swatchWidth:12;
|
||||
textFieldWidth:72;
|
||||
verticalGap:0;
|
||||
}
|
||||
|
||||
</mx:Style>
|
||||
|
||||
<mx:Script>
|
||||
<![CDATA[
|
||||
import com.asfusion.mate.events.Listener;
|
||||
import flash.ui.Keyboard;
|
||||
import mx.containers.ControlBar;
|
||||
import mx.events.MoveEvent;
|
||||
import mx.events.ResizeEvent;
|
||||
import mx.managers.CursorManager;
|
||||
import org.bigbluebutton.common.Images;
|
||||
import org.bigbluebutton.common.LogUtil;
|
||||
import org.bigbluebutton.core.UsersUtil;
|
||||
import org.bigbluebutton.core.managers.UserManager;
|
||||
import org.bigbluebutton.main.events.MadePresenterEvent;
|
||||
import org.bigbluebutton.main.events.ShortcutEvent;
|
||||
import org.bigbluebutton.main.model.users.events.ChangeMyRole;
|
||||
import org.bigbluebutton.modules.present.events.DisplaySlideEvent;
|
||||
import org.bigbluebutton.modules.present.events.PresentationEvent;
|
||||
import org.bigbluebutton.modules.present.events.NavigationEvent;
|
||||
import org.bigbluebutton.modules.present.events.UploadEvent;
|
||||
import org.bigbluebutton.modules.present.ui.views.PresentationWindow;
|
||||
import org.bigbluebutton.modules.present.ui.views.SlideView;
|
||||
import org.bigbluebutton.modules.whiteboard.business.shapes.DrawObject;
|
||||
import org.bigbluebutton.modules.whiteboard.business.shapes.GraphicObject;
|
||||
import org.bigbluebutton.modules.whiteboard.business.shapes.TextObject;
|
||||
import org.bigbluebutton.modules.whiteboard.business.shapes.WhiteboardConstants;
|
||||
import org.bigbluebutton.modules.whiteboard.events.GraphicObjectFocusEvent;
|
||||
import org.bigbluebutton.modules.whiteboard.events.StopWhiteboardModuleEvent;
|
||||
import org.bigbluebutton.modules.whiteboard.events.ToggleGridEvent;
|
||||
import org.bigbluebutton.modules.whiteboard.events.WhiteboardButtonEvent;
|
||||
import org.bigbluebutton.modules.whiteboard.events.WhiteboardDrawEvent;
|
||||
import org.bigbluebutton.modules.whiteboard.events.WhiteboardPresenterEvent;
|
||||
import org.bigbluebutton.modules.whiteboard.events.WhiteboardSettingResetEvent;
|
||||
import org.bigbluebutton.modules.whiteboard.views.models.WhiteboardOptions;
|
||||
import org.bigbluebutton.util.i18n.ResourceUtil;
|
||||
|
||||
private var images:Images = new Images();
|
||||
[Bindable] private var hand_icon:Class = images.hand_icon;
|
||||
[Bindable] private var pencil_icon:Class = images.pencil_icon;
|
||||
[Bindable] private var undo_icon:Class = images.undo_icon;
|
||||
[Bindable] private var delete_icon:Class = images.delete_icon;
|
||||
[Bindable] private var rectangle_icon:Class = images.square_icon;
|
||||
[Bindable] private var ellipse_icon:Class = images.circle_icon;
|
||||
[Bindable] private var thick_icon:Class = images.whiteboard_thick;
|
||||
[Bindable] private var thin_icon:Class = images.whiteboard_thin;
|
||||
[Bindable] private var scribble_icon:Class = images.scribble_icon;
|
||||
[Bindable] private var text_icon:Class = images.text_icon;
|
||||
[Bindable] private var triangle_icon:Class = images.triangle_icon;
|
||||
[Bindable] private var line_icon:Class = images.line_icon;
|
||||
[Bindable] private var fill_icon:Class = images.fill_icon;
|
||||
[Bindable] private var transparency_icon:Class = images.transparency_icon;
|
||||
[Bindable] private var eraser_icon:Class = images.eraser_icon;
|
||||
[Bindable] private var highlighter_icon:Class = images.highlighter_icon;
|
||||
[Bindable] private var select_icon:Class = images.select_icon;
|
||||
[Bindable] private var grid_icon:Class = images.grid_icon;
|
||||
|
||||
[Bindable] public var wbOptions:WhiteboardOptions;
|
||||
[Bindable] private var baseIndex:int;
|
||||
|
||||
[Bindable] private var showWhiteboardToolbar:Boolean = false;
|
||||
|
||||
private static const LOG:String = "WB::WhiteboardToolbar - ";
|
||||
|
||||
private var mousedOver:Boolean = false;
|
||||
private var slideLoaded:Boolean = false;
|
||||
|
||||
public var canvas:WhiteboardCanvas;
|
||||
private var presentationWindow:PresentationWindow;
|
||||
|
||||
[Bindable] private var colorPickerColours:Array = ['0x000000', '0xFFFFFF' , '0xFF0000', '0xFF8800',
|
||||
'0xCCFF00', '0x00FF00', '0x00FF88', '0x00FFFF', '0x0088FF', '0x0000FF', '0x8800FF', '0xFF00FF', '0xC0C0C0'];
|
||||
|
||||
private var _hideToolbarTimer:Timer = new Timer(500, 1);
|
||||
|
||||
private function init():void{
|
||||
wbOptions = new WhiteboardOptions();
|
||||
baseIndex = wbOptions.baseTabIndex;
|
||||
}
|
||||
|
||||
private function onCreationComplete():void {
|
||||
setToolType(WhiteboardConstants.TYPE_ZOOM, null);
|
||||
_hideToolbarTimer.addEventListener(TimerEvent.TIMER, onHideToolbarTimerComplete);
|
||||
}
|
||||
|
||||
private function handleWhiteboardButtonPressed(e:WhiteboardButtonEvent):void {
|
||||
setToolType(e.graphicType, e.toolType);
|
||||
}
|
||||
|
||||
private function setToolType(graphicType:String, toolType:String):void {
|
||||
if (graphicType == WhiteboardConstants.TYPE_CLEAR) {
|
||||
dispatchEvent(new WhiteboardDrawEvent(WhiteboardDrawEvent.CLEAR));
|
||||
} else if (graphicType == WhiteboardConstants.TYPE_UNDO) {
|
||||
sendUndoCommand();
|
||||
} else {
|
||||
canvas.setGraphicType(graphicType);
|
||||
canvas.setTool(toolType);
|
||||
|
||||
if (panzoomBtn != null) {
|
||||
panzoomBtn.setTool(graphicType, toolType);
|
||||
}
|
||||
|
||||
if (scribbleBtn != null) {
|
||||
scribbleBtn.setTool(graphicType, toolType);
|
||||
}
|
||||
|
||||
if (rectangleBtn != null) {
|
||||
rectangleBtn.setTool(graphicType, toolType);
|
||||
}
|
||||
|
||||
if (circleBtn != null) {
|
||||
circleBtn.setTool(graphicType, toolType);
|
||||
}
|
||||
|
||||
if (triangleBtn != null) {
|
||||
triangleBtn.setTool(graphicType, toolType);
|
||||
}
|
||||
|
||||
if (lineBtn != null) {
|
||||
lineBtn.setTool(graphicType, toolType);
|
||||
}
|
||||
|
||||
if (textBtn != null) {
|
||||
textBtn.setTool(graphicType, toolType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function changeColor(e:Event):void {
|
||||
canvas.changeColor(e);
|
||||
}
|
||||
|
||||
protected function changeFillColor(e:Event):void {
|
||||
canvas.changeFillColor(e);
|
||||
}
|
||||
|
||||
protected function changeThickness(e:Event):void {
|
||||
canvas.changeThickness(e);
|
||||
}
|
||||
|
||||
protected function toggleFill():void {
|
||||
canvas.toggleFill();
|
||||
}
|
||||
|
||||
protected function toggleTransparency():void {
|
||||
canvas.toggleTransparency();
|
||||
}
|
||||
|
||||
private function presenterMode(e:MadePresenterEvent):void {
|
||||
if (canvas == null) return;
|
||||
|
||||
canvas.makeTextObjectsEditable(e);
|
||||
setToolType(WhiteboardConstants.TYPE_ZOOM, null);
|
||||
}
|
||||
|
||||
private function viewerMode(e:MadePresenterEvent):void {
|
||||
canvas.makeTextObjectsUneditable(e);
|
||||
if (!toolbarAllowed()) {
|
||||
checkVisibility();
|
||||
if (panzoomBtn) {
|
||||
panzoomBtn.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function undoShortcut(e:ShortcutEvent):void{
|
||||
trace(LOG + "Ctrl-Z got into undoShortcut");
|
||||
sendUndoCommand();
|
||||
}
|
||||
|
||||
private function sendUndoCommand():void {
|
||||
// if (!canvas.isPageEmpty()) {
|
||||
dispatchEvent(new WhiteboardDrawEvent(WhiteboardDrawEvent.UNDO));
|
||||
// }
|
||||
}
|
||||
|
||||
public function positionToolbar(window:PresentationWindow):void {
|
||||
trace(LOG + "Positioning whiteboard toolbar");
|
||||
presentationWindow = window;
|
||||
presentationWindow.addEventListener(MoveEvent.MOVE, setPositionAndDepth);
|
||||
presentationWindow.addEventListener(ResizeEvent.RESIZE, setPositionAndDepth);
|
||||
presentationWindow.addEventListener(MouseEvent.CLICK, setPositionAndDepth);
|
||||
|
||||
if (!wbOptions.keepToolbarVisible) {
|
||||
window.presCtrlBar.addEventListener(MouseEvent.ROLL_OVER, handleMouseOut);
|
||||
window.presCtrlBar.addEventListener(MouseEvent.ROLL_OUT, handleMouseIn);
|
||||
|
||||
window.addEventListener(MouseEvent.ROLL_OVER, handleMouseIn);
|
||||
window.addEventListener(MouseEvent.ROLL_OUT, handleMouseOut);
|
||||
|
||||
this.addEventListener(MouseEvent.ROLL_OVER, handleMouseIn);
|
||||
this.addEventListener(MouseEvent.ROLL_OUT, handleMouseOut);
|
||||
} else {
|
||||
var listener1:Listener = new Listener();
|
||||
listener1.method = checkVisibility;
|
||||
listener1.type = MadePresenterEvent.SWITCH_TO_PRESENTER_MODE;
|
||||
var listener2:Listener = new Listener();
|
||||
listener2.method = checkVisibility;
|
||||
listener2.type = MadePresenterEvent.SWITCH_TO_VIEWER_MODE;
|
||||
//Do an initial check to see if the toolbar should be visible
|
||||
checkVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
private function refreshRole(e:ChangeMyRole):void {
|
||||
checkVisibility();
|
||||
}
|
||||
|
||||
private function checkVisibility(e:MadePresenterEvent = null):void {
|
||||
if (toolbarAllowed() && slideLoaded && (wbOptions.keepToolbarVisible || mousedOver) && !presentationWindow.minimized) {
|
||||
setPositionAndDepth();
|
||||
showToolbar();
|
||||
} else {
|
||||
hideToolbar();
|
||||
}
|
||||
}
|
||||
|
||||
private function showToolbar():void {
|
||||
_hideToolbarTimer.reset();
|
||||
showWhiteboardToolbar = true;
|
||||
}
|
||||
|
||||
private function hideToolbar():void {
|
||||
_hideToolbarTimer.reset();
|
||||
_hideToolbarTimer.start();
|
||||
}
|
||||
|
||||
private function onHideToolbarTimerComplete(event:TimerEvent):void {
|
||||
showWhiteboardToolbar = false;
|
||||
}
|
||||
|
||||
private function setPositionAndDepth(e:Event = null):void {
|
||||
this.x = presentationWindow.x + presentationWindow.width - 43;
|
||||
this.y = presentationWindow.y + 30;
|
||||
parent.setChildIndex(this, parent.numChildren - 1);
|
||||
}
|
||||
|
||||
private function closeToolbar(e:StopWhiteboardModuleEvent):void {
|
||||
parent.removeChild(this);
|
||||
}
|
||||
|
||||
private function handleMouseIn(e:MouseEvent):void {
|
||||
mousedOver = true;
|
||||
checkVisibility();
|
||||
}
|
||||
|
||||
private function handleMouseOut(e:MouseEvent = null):void {
|
||||
mousedOver = false;
|
||||
checkVisibility();
|
||||
}
|
||||
|
||||
private function handleSlideLoaded(e:DisplaySlideEvent):void {
|
||||
slideLoaded = true;
|
||||
checkVisibility();
|
||||
}
|
||||
|
||||
private function handleSlideChange(e:NavigationEvent):void {
|
||||
slideLoaded = false;
|
||||
// don't switch the toolbar button on slide change
|
||||
checkVisibility();
|
||||
}
|
||||
|
||||
private function handlePresentationSwitch(e:UploadEvent):void {
|
||||
slideLoaded = false;
|
||||
if (panzoomBtn) {
|
||||
panzoomBtn.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
|
||||
}
|
||||
checkVisibility();
|
||||
}
|
||||
|
||||
private function graphicObjSelected(event:GraphicObjectFocusEvent):void {
|
||||
var gobj:GraphicObject = event.data;
|
||||
}
|
||||
|
||||
private function graphicObjDeselected(event:GraphicObjectFocusEvent):void {
|
||||
var gobj:GraphicObject = event.data;
|
||||
}
|
||||
|
||||
private function toolbarAllowed():Boolean {
|
||||
if (wbOptions) {
|
||||
if (wbOptions.whiteboardAccess == "presenter")
|
||||
return isPresenter;
|
||||
else if (wbOptions.whiteboardAccess == "moderator")
|
||||
return isModerator || isPresenter;
|
||||
else if (wbOptions.whiteboardAccess == "all")
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Helper method to test whether this user is the presenter */
|
||||
private function get isPresenter():Boolean {
|
||||
return UsersUtil.amIPresenter();
|
||||
}
|
||||
|
||||
private function get isModerator():Boolean {
|
||||
return UsersUtil.amIModerator();
|
||||
}
|
||||
|
||||
]]>
|
||||
</mx:Script>
|
||||
|
||||
<mx:Fade id="fadeOut" duration="200" alphaFrom="1.0" alphaTo="0.0" />
|
||||
<mx:Fade id="fadeIn" duration="200" alphaFrom="0.0" alphaTo="1.0" />
|
||||
|
||||
<!-- Now, every 'tool' has two types of identifiers, one is found in WhiteboardConstants
|
||||
that identifies the "category" of the tool (ex. shape vs text), and the other specifies the
|
||||
tool itself (ex. line tool vs triangle tool, even though both are "shapes")
|
||||
-->
|
||||
<wbBtns:PanZoomButton id="panzoomBtn"
|
||||
tabIndex="{baseIndex}"
|
||||
visible="{showWhiteboardToolbar}"/>
|
||||
<mx:Spacer height="10" visible="{showWhiteboardToolbar}"/>
|
||||
<wbBtns:ScribbleButton id="scribbleBtn"
|
||||
tabIndex="{baseIndex+1}"
|
||||
visible="{showWhiteboardToolbar}"/>
|
||||
<wbBtns:RectangleButton id="rectangleBtn"
|
||||
tabIndex="{baseIndex+2}"
|
||||
visible="{showWhiteboardToolbar}"/>
|
||||
<wbBtns:CircleButton id="circleBtn"
|
||||
tabIndex="{baseIndex+3}"
|
||||
visible="{showWhiteboardToolbar}"/>
|
||||
<wbBtns:TriangleButton id="triangleBtn"
|
||||
tabIndex="{baseIndex+4}"
|
||||
visible="{showWhiteboardToolbar}"/>
|
||||
<wbBtns:LineButton id="lineBtn"
|
||||
tabIndex="{baseIndex+5}"
|
||||
visible="{showWhiteboardToolbar}"/>
|
||||
<wbBtns:TextButton id="textBtn"
|
||||
tabIndex="{baseIndex+6}"
|
||||
visible="{showWhiteboardToolbar}"/>
|
||||
|
||||
<mx:Spacer height="5" visible="{showWhiteboardToolbar}"/>
|
||||
<wbBtns:ClearButton id="clearBtn"
|
||||
tabIndex="{baseIndex+7}"
|
||||
visible="{showWhiteboardToolbar}"/>
|
||||
<wbBtns:UndoButton id="undoBtn"
|
||||
tabIndex="{baseIndex+8}"
|
||||
visible="{showWhiteboardToolbar}"/>
|
||||
|
||||
<mx:Spacer height="5" visible="{showWhiteboardToolbar}"/>
|
||||
|
||||
<!--
|
||||
Properties that were removed from original color picker:
|
||||
|
||||
swatchPanelStyleName="colorPickerStyle"
|
||||
dataProvider="{colorPickerColours}"
|
||||
-->
|
||||
|
||||
<!-- Layout is really bad right now, and is confusing. Basically, there are two
|
||||
of ColorPickers, one for the "line" color for the outlines of shapes, and the other for
|
||||
the "fill" color that is used only if "fill" is enabled in WhiteboardCanvasModel
|
||||
-->
|
||||
<mx:ColorPicker change="changeColor(event)" id="cpik" visible="{showWhiteboardToolbar}"
|
||||
selectedColor="0x000000" width="30" dataProvider="{colorPickerColours}" swatchPanelStyleName="colorPickerStyle"
|
||||
toolTip="{ResourceUtil.getInstance().getString('bbb.highlighter.toolbar.color')}"
|
||||
tabIndex="{baseIndex+9}"
|
||||
accessibilityName="{ResourceUtil.getInstance().getString('bbb.highlighter.toolbar.color')}"/>
|
||||
|
||||
<mx:Spacer height="3" visible="{showWhiteboardToolbar}"/>
|
||||
<mx:Image source="{thick_icon}" horizontalAlign="center" width="30" visible="{showWhiteboardToolbar}"/>
|
||||
<mx:VSlider height="50" id="sld" change="changeThickness(event)" visible="{showWhiteboardToolbar}"
|
||||
toolTip="{ResourceUtil.getInstance().getString('bbb.highlighter.toolbar.thickness.accessibilityName')}"
|
||||
minimum="1" maximum="30"
|
||||
useHandCursor="true" value="2" showDataTip="true" snapInterval="1" dataTipOffset="0" labelOffset="0"
|
||||
tabIndex="{baseIndex+10}"
|
||||
accessibilityName="{ResourceUtil.getInstance().getString('bbb.highlighter.toolbar.thickness.accessibilityName')}" />
|
||||
<mx:Image source="{thin_icon}" horizontalAlign="center" width="30" visible="{showWhiteboardToolbar}"/>
|
||||
|
||||
</mx:VBox>
|
||||
|
Loading…
Reference in New Issue
Block a user