Merge branch 'broadcast-layout' of github.com:mconf/bigbluebutton into broadcast-layout
Conflicts: bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/layout/LayoutApplication.java bigbluebutton-apps/src/main/java/org/bigbluebutton/conference/service/layout/LayoutService.java bigbluebutton-apps/src/main/java/org/bigbluebutton/core/api/IBigBlueButtonInGW.java bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonInGW.scala bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/apps/layout/LayoutApp.scala bigbluebutton-client/src/org/bigbluebutton/modules/layout/events/LayoutEvent.as bigbluebutton-client/src/org/bigbluebutton/modules/layout/services/LayoutService.as bigbluebutton-client/src/org/bigbluebutton/modules/layout/services/MessageReceiver.as
This commit is contained in:
commit
04c271996d
@ -19,7 +19,7 @@
|
|||||||
package org.bigbluebutton.conference.service.layout;
|
package org.bigbluebutton.conference.service.layout;
|
||||||
|
|
||||||
import org.bigbluebutton.core.api.IBigBlueButtonInGW;
|
import org.bigbluebutton.core.api.IBigBlueButtonInGW;
|
||||||
|
|
||||||
public class LayoutApplication {
|
public class LayoutApplication {
|
||||||
private IBigBlueButtonInGW bbbInGW;
|
private IBigBlueButtonInGW bbbInGW;
|
||||||
|
|
||||||
@ -31,8 +31,8 @@ public class LayoutApplication {
|
|||||||
bbbInGW.syncLayout(meetingID, requesterID, layoutID);
|
bbbInGW.syncLayout(meetingID, requesterID, layoutID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void lockLayout(String meetingID, String requesterID, String layoutID) {
|
public void broadcastLayout(String meetingID, String requesterID, String layoutID, Boolean locked) {
|
||||||
bbbInGW.lockLayout(meetingID, requesterID, layoutID);
|
bbbInGW.broadcastLayout(meetingID, requesterID, layoutID, locked);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unlockLayout(String meetingID, String requesterID) {
|
public void unlockLayout(String meetingID, String requesterID) {
|
||||||
|
@ -25,7 +25,7 @@ import org.bigbluebutton.conference.Constants;
|
|||||||
import org.red5.logging.Red5LoggerFactory;
|
import org.red5.logging.Red5LoggerFactory;
|
||||||
import org.red5.server.api.Red5;
|
import org.red5.server.api.Red5;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
public class LayoutService {
|
public class LayoutService {
|
||||||
|
|
||||||
private static Logger log = Red5LoggerFactory.getLogger( LayoutService.class, "bigbluebutton" );
|
private static Logger log = Red5LoggerFactory.getLogger( LayoutService.class, "bigbluebutton" );
|
||||||
@ -43,9 +43,9 @@ public class LayoutService {
|
|||||||
application.syncLayout(meetingID, getBbbSession().getInternalUserID(), (String) message.get("layout"));
|
application.syncLayout(meetingID, getBbbSession().getInternalUserID(), (String) message.get("layout"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void lock(Map<String, Object> message) {
|
public void broadcast(Map<String, Object> message) {
|
||||||
String meetingID = Red5.getConnectionLocal().getScope().getName();
|
String meetingID = Red5.getConnectionLocal().getScope().getName();
|
||||||
application.lockLayout(meetingID, (String) message.get("setByUserID"), (String) message.get("layout"));
|
application.broadcastLayout(meetingID, (String) message.get("setByUserID"), (String) message.get("layout"), (Boolean) message.get("locked"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unlock() {
|
public void unlock() {
|
||||||
|
@ -95,7 +95,7 @@ public interface IBigBlueButtonInGW {
|
|||||||
void getCurrentLayout(String meetingID, String requesterID);
|
void getCurrentLayout(String meetingID, String requesterID);
|
||||||
void setLayout(String meetingID, String requesterID, String layoutID);
|
void setLayout(String meetingID, String requesterID, String layoutID);
|
||||||
void syncLayout(String meetingID, String requesterID, String layoutID);
|
void syncLayout(String meetingID, String requesterID, String layoutID);
|
||||||
void lockLayout(String meetingID, String requesterID, String layoutID);
|
void broadcastLayout(String meetingID, String requesterID, String layoutID, Boolean locked);
|
||||||
void unlockLayout(String meetingID, String requesterID);
|
void unlockLayout(String meetingID, String requesterID);
|
||||||
|
|
||||||
// Chat
|
// Chat
|
||||||
|
@ -37,7 +37,7 @@ class BigBlueButtonInGW(bbbGW: BigBlueButtonGateway) extends IBigBlueButtonInGW
|
|||||||
|
|
||||||
bbbGW.accept(new PreuploadedPresentations(meetingID, presentations.values.toSeq))
|
bbbGW.accept(new PreuploadedPresentations(meetingID, presentations.values.toSeq))
|
||||||
}
|
}
|
||||||
|
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,8 +349,8 @@ class BigBlueButtonInGW(bbbGW: BigBlueButtonGateway) extends IBigBlueButtonInGW
|
|||||||
layoutGW.setLayout(meetingID, requesterID, layoutID)
|
layoutGW.setLayout(meetingID, requesterID, layoutID)
|
||||||
}
|
}
|
||||||
|
|
||||||
def lockLayout(meetingID: String, requesterID: String, layoutID: String) {
|
def broadcastLayout(meetingID: String, requesterID: String, layoutID: String, locked: java.lang.Boolean) {
|
||||||
layoutGW.lockLayout(meetingID, requesterID, layoutID)
|
layoutGW.broadcastLayout(meetingID, requesterID, layoutID, locked)
|
||||||
}
|
}
|
||||||
|
|
||||||
def unlockLayout(meetingID: String, requesterID: String) {
|
def unlockLayout(meetingID: String, requesterID: String) {
|
||||||
@ -461,4 +461,4 @@ class BigBlueButtonInGW(bbbGW: BigBlueButtonGateway) extends IBigBlueButtonInGW
|
|||||||
voiceGW.voiceRecording(meetingId, recordingFile,
|
voiceGW.voiceRecording(meetingId, recordingFile,
|
||||||
timestamp, recording)
|
timestamp, recording)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ class CollectorActor(dispatcher: IDispatcher) extends Actor {
|
|||||||
case msg: SendPrivateMessageRequest => handleSendPrivateMessageRequest(msg)
|
case msg: SendPrivateMessageRequest => handleSendPrivateMessageRequest(msg)
|
||||||
case msg: GetCurrentLayoutRequest => handleGetCurrentLayoutRequest(msg)
|
case msg: GetCurrentLayoutRequest => handleGetCurrentLayoutRequest(msg)
|
||||||
case msg: SetLayoutRequest => handleSetLayoutRequest(msg)
|
case msg: SetLayoutRequest => handleSetLayoutRequest(msg)
|
||||||
case msg: LockLayoutRequest => handleLockLayoutRequest(msg)
|
case msg: BroadcastLayoutRequest => handleBroadcastLayoutRequest(msg)
|
||||||
case msg: UnlockLayoutRequest => handleUnlockLayoutRequest(msg)
|
case msg: UnlockLayoutRequest => handleUnlockLayoutRequest(msg)
|
||||||
case msg: PreCreatedPoll => handlePreCreatedPoll(msg)
|
case msg: PreCreatedPoll => handlePreCreatedPoll(msg)
|
||||||
case msg: CreatePoll => handleCreatePoll(msg)
|
case msg: CreatePoll => handleCreatePoll(msg)
|
||||||
@ -144,7 +144,7 @@ class CollectorActor(dispatcher: IDispatcher) extends Actor {
|
|||||||
case msg: SendPrivateMessageEvent => handleSendPrivateMessageEvent(msg)
|
case msg: SendPrivateMessageEvent => handleSendPrivateMessageEvent(msg)
|
||||||
case msg: GetCurrentLayoutReply => handleGetCurrentLayoutReply(msg)
|
case msg: GetCurrentLayoutReply => handleGetCurrentLayoutReply(msg)
|
||||||
case msg: SetLayoutEvent => handleSetLayoutEvent(msg)
|
case msg: SetLayoutEvent => handleSetLayoutEvent(msg)
|
||||||
case msg: LockLayoutEvent => handleLockLayoutEvent(msg)
|
case msg: BroadcastLayoutEvent => handleBroadcastLayoutEvent(msg)
|
||||||
case msg: UnlockLayoutEvent => handleUnlockLayoutEvent(msg)
|
case msg: UnlockLayoutEvent => handleUnlockLayoutEvent(msg)
|
||||||
case msg: GetPollResultReply => handleGetPollResultReply(msg)
|
case msg: GetPollResultReply => handleGetPollResultReply(msg)
|
||||||
case msg: GetPollsReplyOutMsg => handleGetPollsReplyOutMsg(msg)
|
case msg: GetPollsReplyOutMsg => handleGetPollsReplyOutMsg(msg)
|
||||||
@ -644,17 +644,18 @@ class CollectorActor(dispatcher: IDispatcher) extends Actor {
|
|||||||
dispatcher.dispatch(buildJson(header, payload))
|
dispatcher.dispatch(buildJson(header, payload))
|
||||||
}
|
}
|
||||||
|
|
||||||
private def handleLockLayoutRequest(msg: LockLayoutRequest) {
|
private def handleBroadcastLayoutRequest(msg: BroadcastLayoutRequest) {
|
||||||
val payload = new java.util.HashMap[String, Any]()
|
val payload = new java.util.HashMap[String, Any]()
|
||||||
payload.put(Constants.MEETING_ID, msg.meetingID)
|
payload.put(Constants.MEETING_ID, msg.meetingID)
|
||||||
payload.put(Constants.REQUESTER_ID, msg.requesterID)
|
payload.put(Constants.REQUESTER_ID, msg.requesterID)
|
||||||
payload.put(Constants.LAYOUT_ID, msg.layoutID)
|
payload.put(Constants.LAYOUT_ID, msg.layoutID)
|
||||||
|
payload.put(Constants.LOCKED, msg.locked)
|
||||||
|
|
||||||
val header = new java.util.HashMap[String, Any]()
|
val header = new java.util.HashMap[String, Any]()
|
||||||
header.put(Constants.NAME, MessageNames.LOCK_LAYOUT)
|
header.put(Constants.NAME, MessageNames.BROADCAST_LAYOUT)
|
||||||
header.put(Constants.TIMESTAMP, TimestampGenerator.generateTimestamp)
|
header.put(Constants.TIMESTAMP, TimestampGenerator.generateTimestamp)
|
||||||
|
|
||||||
println("***** DISPATCHING LOCK LAYOUT REQUEST *****************")
|
println("***** DISPATCHING BROADCAST LAYOUT REQUEST *****************")
|
||||||
dispatcher.dispatch(buildJson(header, payload))
|
dispatcher.dispatch(buildJson(header, payload))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1812,7 +1813,7 @@ class CollectorActor(dispatcher: IDispatcher) extends Actor {
|
|||||||
dispatcher.dispatch(buildJson(header, payload))
|
dispatcher.dispatch(buildJson(header, payload))
|
||||||
}
|
}
|
||||||
|
|
||||||
private def handleLockLayoutEvent(msg: LockLayoutEvent) {
|
private def handleBroadcastLayoutEvent(msg: BroadcastLayoutEvent) {
|
||||||
val payload = new java.util.HashMap[String, Any]()
|
val payload = new java.util.HashMap[String, Any]()
|
||||||
payload.put(Constants.MEETING_ID, msg.meetingID)
|
payload.put(Constants.MEETING_ID, msg.meetingID)
|
||||||
payload.put(Constants.RECORDED, msg.recorded)
|
payload.put(Constants.RECORDED, msg.recorded)
|
||||||
@ -1822,10 +1823,10 @@ class CollectorActor(dispatcher: IDispatcher) extends Actor {
|
|||||||
payload.put(Constants.SET_BY_USER_ID, msg.setByUserID)
|
payload.put(Constants.SET_BY_USER_ID, msg.setByUserID)
|
||||||
|
|
||||||
val header = new java.util.HashMap[String, Any]()
|
val header = new java.util.HashMap[String, Any]()
|
||||||
header.put(Constants.NAME, MessageNames.LOCK_LAYOUT_REPLY)
|
header.put(Constants.NAME, MessageNames.BROADCAST_LAYOUT_REPLY)
|
||||||
header.put(Constants.TIMESTAMP, TimestampGenerator.generateTimestamp)
|
header.put(Constants.TIMESTAMP, TimestampGenerator.generateTimestamp)
|
||||||
|
|
||||||
println("***** DISPATCHING LOCK LAYOUT EVENT *****************")
|
println("***** DISPATCHING BROADCAST LAYOUT EVENT *****************")
|
||||||
dispatcher.dispatch(buildJson(header, payload))
|
dispatcher.dispatch(buildJson(header, payload))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2132,4 +2133,4 @@ class CollectorActor(dispatcher: IDispatcher) extends Actor {
|
|||||||
val json = WhiteboardMessageToJsonConverter.isWhiteboardEnabledReplyToJson(msg)
|
val json = WhiteboardMessageToJsonConverter.isWhiteboardEnabledReplyToJson(msg)
|
||||||
dispatcher.dispatch(json)
|
dispatcher.dispatch(json)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,10 +72,10 @@ class MeetingActor(val meetingID: String, meetingName: String, val recorded: Boo
|
|||||||
case msg: UserConnectedToGlobalAudio => handleUserConnectedToGlobalAudio(msg)
|
case msg: UserConnectedToGlobalAudio => handleUserConnectedToGlobalAudio(msg)
|
||||||
case msg: UserDisconnectedFromGlobalAudio => handleUserDisconnectedFromGlobalAudio(msg)
|
case msg: UserDisconnectedFromGlobalAudio => handleUserDisconnectedFromGlobalAudio(msg)
|
||||||
case msg: GetCurrentLayoutRequest => handleGetCurrentLayoutRequest(msg)
|
case msg: GetCurrentLayoutRequest => handleGetCurrentLayoutRequest(msg)
|
||||||
case msg: LayoutLockSettings => handleLayoutLockSettings(msg)
|
// case msg: LayoutLockSettings => handleLayoutLockSettings(msg)
|
||||||
case msg: SetLayoutRequest => handleSetLayoutRequest(msg)
|
case msg: SetLayoutRequest => handleSetLayoutRequest(msg)
|
||||||
case msg: LockLayoutRequest => handleLockLayoutRequest(msg)
|
case msg: BroadcastLayoutRequest => handleBroadcastLayoutRequest(msg)
|
||||||
case msg: UnlockLayoutRequest => handleUnlockLayoutRequest(msg)
|
// case msg: UnlockLayoutRequest => handleUnlockLayoutRequest(msg)
|
||||||
case msg: InitializeMeeting => handleInitializeMeeting(msg)
|
case msg: InitializeMeeting => handleInitializeMeeting(msg)
|
||||||
case msg: ClearPresentation => handleClearPresentation(msg)
|
case msg: ClearPresentation => handleClearPresentation(msg)
|
||||||
case msg: PresentationConversionUpdate => handlePresentationConversionUpdate(msg)
|
case msg: PresentationConversionUpdate => handlePresentationConversionUpdate(msg)
|
||||||
|
@ -201,10 +201,11 @@ case class LayoutLockSettings(
|
|||||||
locked: Boolean
|
locked: Boolean
|
||||||
) extends InMessage
|
) extends InMessage
|
||||||
|
|
||||||
case class LockLayoutRequest(
|
case class BroadcastLayoutRequest(
|
||||||
meetingID: String,
|
meetingID: String,
|
||||||
requesterID: String,
|
requesterID: String,
|
||||||
layoutID: String
|
layoutID: String,
|
||||||
|
locked: Boolean
|
||||||
) extends InMessage
|
) extends InMessage
|
||||||
|
|
||||||
case class UnlockLayoutRequest(
|
case class UnlockLayoutRequest(
|
||||||
|
@ -30,7 +30,7 @@ object MessageNames {
|
|||||||
val SEND_PRIVATE_MESSAGE = "send_private_chat_message_request"
|
val SEND_PRIVATE_MESSAGE = "send_private_chat_message_request"
|
||||||
val GET_CURRENT_LAYOUT = "get_current_layout_request"
|
val GET_CURRENT_LAYOUT = "get_current_layout_request"
|
||||||
val SET_LAYOUT = "set_layout_request"
|
val SET_LAYOUT = "set_layout_request"
|
||||||
val LOCK_LAYOUT = "lock_layout_request"
|
val BROADCAST_LAYOUT = "broadcast_layout_request"
|
||||||
val UNLOCK_LAYOUT = "unlock_layout_request"
|
val UNLOCK_LAYOUT = "unlock_layout_request"
|
||||||
val PRECREATED_POLL = "precreated_poll_request"
|
val PRECREATED_POLL = "precreated_poll_request"
|
||||||
val CREATE_POLL = "create_poll_request"
|
val CREATE_POLL = "create_poll_request"
|
||||||
@ -121,7 +121,7 @@ object MessageNames {
|
|||||||
val SEND_PRIVATE_CHAT_MESSAGE = "send_private_chat_message"
|
val SEND_PRIVATE_CHAT_MESSAGE = "send_private_chat_message"
|
||||||
val GET_CURRENT_LAYOUT_REPLY = "get_current_layout_reply"
|
val GET_CURRENT_LAYOUT_REPLY = "get_current_layout_reply"
|
||||||
val SET_LAYOUT_REPLY = "set_layout_reply"
|
val SET_LAYOUT_REPLY = "set_layout_reply"
|
||||||
val LOCK_LAYOUT_REPLY = "lock_layout_reply"
|
val BROADCAST_LAYOUT_REPLY = "broadcast_layout_reply"
|
||||||
val UNLOCK_LAYOUT_REPLY = "unlock_layout_reply"
|
val UNLOCK_LAYOUT_REPLY = "unlock_layout_reply"
|
||||||
val GET_POLL_RESULT_REPLY = "get_poll_result_reply"
|
val GET_POLL_RESULT_REPLY = "get_poll_result_reply"
|
||||||
val POLL_CLEARED = "poll_cleared_message"
|
val POLL_CLEARED = "poll_cleared_message"
|
||||||
|
@ -345,7 +345,7 @@ case class SetLayoutEvent(
|
|||||||
applyTo: Array[UserVO]
|
applyTo: Array[UserVO]
|
||||||
) extends IOutMessage
|
) extends IOutMessage
|
||||||
|
|
||||||
case class LockLayoutEvent(
|
case class BroadcastLayoutEvent(
|
||||||
meetingID: String,
|
meetingID: String,
|
||||||
recorded: Boolean,
|
recorded: Boolean,
|
||||||
requesterID: String,
|
requesterID: String,
|
||||||
|
@ -9,9 +9,9 @@ trait LayoutApp {
|
|||||||
|
|
||||||
val outGW: MessageOutGateway
|
val outGW: MessageOutGateway
|
||||||
|
|
||||||
private var _locked:Boolean = false;
|
private var _locked:Boolean = false;
|
||||||
private var _setByUserID:String = "system";
|
private var _setByUserID:String = "system";
|
||||||
private var _currentLayoutID = "";
|
private var _currentLayoutID = "";
|
||||||
|
|
||||||
def handleGetCurrentLayoutRequest(msg: GetCurrentLayoutRequest) {
|
def handleGetCurrentLayoutRequest(msg: GetCurrentLayoutRequest) {
|
||||||
outGW.send(new GetCurrentLayoutReply(msg.meetingID, recorded, msg.requesterID, _currentLayoutID, _locked, _setByUserID))
|
outGW.send(new GetCurrentLayoutReply(msg.meetingID, recorded, msg.requesterID, _currentLayoutID, _locked, _setByUserID))
|
||||||
@ -22,16 +22,16 @@ trait LayoutApp {
|
|||||||
outGW.send(new SetLayoutEvent(msg.meetingID, recorded, msg.requesterID, _currentLayoutID, _locked, _setByUserID, affectedUsers))
|
outGW.send(new SetLayoutEvent(msg.meetingID, recorded, msg.requesterID, _currentLayoutID, _locked, _setByUserID, affectedUsers))
|
||||||
}
|
}
|
||||||
|
|
||||||
def handleLayoutLockSettings(msg: LayoutLockSettings) {
|
def handleBroadcastLayoutRequest(msg: BroadcastLayoutRequest) {
|
||||||
if (msg.locked) {
|
_locked = msg.locked
|
||||||
_locked = true
|
_currentLayoutID = msg.layoutID
|
||||||
_setByUserID = msg.requesterId
|
outGW.send(new BroadcastLayoutEvent(msg.meetingID, recorded, msg.requesterID, _currentLayoutID, _locked, _setByUserID, affectedUsers))
|
||||||
outGW.send(new LockLayoutEvent(msg.meetingID, recorded, msg.requesterId, _currentLayoutID, _locked, _setByUserID, affectedUsers))
|
}
|
||||||
} else {
|
|
||||||
_locked = false
|
def handleUnlockLayoutRequest(msg: UnlockLayoutRequest) {
|
||||||
_setByUserID = msg.requesterId
|
_locked = false
|
||||||
outGW.send(new UnlockLayoutEvent(msg.meetingID, recorded, msg.requesterId, _currentLayoutID, _locked, _setByUserID, affectedUsers))
|
_setByUserID = msg.requesterID
|
||||||
}
|
outGW.send(new UnlockLayoutEvent(msg.meetingID, recorded, msg.requesterID, _currentLayoutID, _locked, _setByUserID, affectedUsers))
|
||||||
}
|
}
|
||||||
|
|
||||||
def affectedUsers():Array[UserVO] = {
|
def affectedUsers():Array[UserVO] = {
|
||||||
@ -44,14 +44,4 @@ trait LayoutApp {
|
|||||||
au.toArray
|
au.toArray
|
||||||
}
|
}
|
||||||
|
|
||||||
def handleLockLayoutRequest(msg: LockLayoutRequest) {
|
}
|
||||||
_locked = true
|
|
||||||
_currentLayoutID = msg.layoutID
|
|
||||||
outGW.send(new LockLayoutEvent(msg.meetingID, recorded, msg.requesterID, _currentLayoutID, _locked, _setByUserID, affectedUsers))
|
|
||||||
}
|
|
||||||
|
|
||||||
def handleUnlockLayoutRequest(msg: UnlockLayoutRequest) {
|
|
||||||
_locked = false
|
|
||||||
outGW.send(new UnlockLayoutEvent(msg.meetingID, recorded, msg.requesterID, _currentLayoutID, _locked, _setByUserID, affectedUsers))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -13,8 +13,8 @@ class LayoutInGateway(bbbGW: BigBlueButtonGateway) {
|
|||||||
bbbGW.accept(new SetLayoutRequest(meetingID, requesterID, layoutID))
|
bbbGW.accept(new SetLayoutRequest(meetingID, requesterID, layoutID))
|
||||||
}
|
}
|
||||||
|
|
||||||
def lockLayout(meetingID: String, requesterID: String, layoutID: String) {
|
def broadcastLayout(meetingID: String, requesterID: String, layoutID: String, locked: Boolean) {
|
||||||
bbbGW.accept(new LockLayoutRequest(meetingID, requesterID, layoutID))
|
bbbGW.accept(new BroadcastLayoutRequest(meetingID, requesterID, layoutID, locked))
|
||||||
}
|
}
|
||||||
|
|
||||||
def unlockLayout(meetingID: String, requesterID: String) {
|
def unlockLayout(meetingID: String, requesterID: String) {
|
||||||
|
@ -12,7 +12,7 @@ class LayoutClientMessageSender(service: ConnectionInvokerService) extends OutMe
|
|||||||
msg match {
|
msg match {
|
||||||
case msg:GetCurrentLayoutReply => handleGetCurrentLayoutReply(msg)
|
case msg:GetCurrentLayoutReply => handleGetCurrentLayoutReply(msg)
|
||||||
case msg:SetLayoutEvent => handleSetLayoutEvent(msg)
|
case msg:SetLayoutEvent => handleSetLayoutEvent(msg)
|
||||||
case msg:LockLayoutEvent => handleLockLayoutEvent(msg)
|
case msg:BroadcastLayoutEvent => handleBroadcastLayoutEvent(msg)
|
||||||
case msg:UnlockLayoutEvent => handleUnlockLayoutEvent(msg)
|
case msg:UnlockLayoutEvent => handleUnlockLayoutEvent(msg)
|
||||||
case _ => // do nothing
|
case _ => // do nothing
|
||||||
}
|
}
|
||||||
@ -38,7 +38,7 @@ class LayoutClientMessageSender(service: ConnectionInvokerService) extends OutMe
|
|||||||
service.sendMessage(m);
|
service.sendMessage(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
private def handleLockLayoutEvent(msg: LockLayoutEvent) {
|
private def handleBroadcastLayoutEvent(msg: BroadcastLayoutEvent) {
|
||||||
val message = new java.util.HashMap[String, Object]()
|
val message = new java.util.HashMap[String, Object]()
|
||||||
message.put("locked", msg.locked:java.lang.Boolean);
|
message.put("locked", msg.locked:java.lang.Boolean);
|
||||||
message.put("setByUserID", msg.setByUserID);
|
message.put("setByUserID", msg.setByUserID);
|
||||||
|
@ -230,6 +230,7 @@ bbb.toolbar.deskshare.toolTip.stop = Stop Sharing My Desktop
|
|||||||
bbb.toolbar.video.toolTip.start = Share My Webcam
|
bbb.toolbar.video.toolTip.start = Share My Webcam
|
||||||
bbb.toolbar.video.toolTip.stop = Stop Sharing My Webcam
|
bbb.toolbar.video.toolTip.stop = Stop Sharing My Webcam
|
||||||
bbb.layout.addButton.toolTip = Add the custom layout to the list
|
bbb.layout.addButton.toolTip = Add the custom layout to the list
|
||||||
|
bbb.layout.broadcastButton.toolTip = Apply Current Layout to All Viewers
|
||||||
bbb.layout.combo.toolTip = Change the current layout
|
bbb.layout.combo.toolTip = Change the current layout
|
||||||
bbb.layout.loadButton.toolTip = Load layouts from a file
|
bbb.layout.loadButton.toolTip = Load layouts from a file
|
||||||
bbb.layout.saveButton.toolTip = Save layouts to a file
|
bbb.layout.saveButton.toolTip = Save layouts to a file
|
||||||
|
@ -18,30 +18,30 @@
|
|||||||
*/
|
*/
|
||||||
package org.bigbluebutton.modules.layout.events
|
package org.bigbluebutton.modules.layout.events
|
||||||
{
|
{
|
||||||
import flash.events.Event;
|
import flash.events.Event;
|
||||||
|
|
||||||
public class LayoutEvent extends Event
|
|
||||||
{
|
|
||||||
public static const REMOTE_LOCK_LAYOUT_EVENT:String = 'REMOTE_LOCK_LAYOUT_EVENT';
|
|
||||||
public static const REMOTE_UNLOCK_LAYOUT_EVENT:String = 'REMOTE_UNLOCK_LAYOUT_EVENT';
|
|
||||||
|
|
||||||
|
public class LayoutEvent extends Event
|
||||||
|
{
|
||||||
|
public static const REMOTE_LOCK_LAYOUT_EVENT:String = 'REMOTE_LOCK_LAYOUT_EVENT';
|
||||||
|
public static const REMOTE_UNLOCK_LAYOUT_EVENT:String = 'REMOTE_UNLOCK_LAYOUT_EVENT';
|
||||||
public static const SYNC_LAYOUT_EVENT:String = 'SYNC_LAYOUT_EVENT';
|
public static const SYNC_LAYOUT_EVENT:String = 'SYNC_LAYOUT_EVENT';
|
||||||
public static const LOCK_LAYOUT_EVENT:String = 'LOCK_LAYOUT_EVENT';
|
public static const BROADCAST_LAYOUT_EVENT:String = 'BROADCAST_LAYOUT_EVENT';
|
||||||
public static const UNLOCK_LAYOUT_EVENT:String = 'UNLOCK_LAYOUT_EVENT';
|
public static const LOCK_LAYOUT_EVENT:String = 'LOCK_LAYOUT_EVENT';
|
||||||
public static const STOP_LAYOUT_MODULE_EVENT:String = 'STOP_LAYOUT_MODULE_EVENT';
|
public static const UNLOCK_LAYOUT_EVENT:String = 'UNLOCK_LAYOUT_EVENT';
|
||||||
public static const VIEW_INITIALIZED_EVENT:String = 'VIEW_INITIALIZED_EVENT';
|
public static const STOP_LAYOUT_MODULE_EVENT:String = 'STOP_LAYOUT_MODULE_EVENT';
|
||||||
|
public static const VIEW_INITIALIZED_EVENT:String = 'VIEW_INITIALIZED_EVENT';
|
||||||
public static const SAVE_LAYOUTS_EVENT:String = 'SAVE_LAYOUTS_EVENT';
|
|
||||||
public static const LOAD_LAYOUTS_EVENT:String = 'LOAD_LAYOUTS_EVENT';
|
public static const SAVE_LAYOUTS_EVENT:String = 'SAVE_LAYOUTS_EVENT';
|
||||||
public static const ADD_CURRENT_LAYOUT_EVENT:String = 'ADD_CURRENT_LAYOUT_EVENT';
|
public static const LOAD_LAYOUTS_EVENT:String = 'LOAD_LAYOUTS_EVENT';
|
||||||
public static const FILE_LOADED_SUCCESSFULLY_EVENT:String = 'FILE_LOADED_SUCCESSFULLY_EVENT';
|
public static const ADD_CURRENT_LAYOUT_EVENT:String = 'ADD_CURRENT_LAYOUT_EVENT';
|
||||||
public static const APPLY_DEFAULT_LAYOUT_EVENT:String = 'APPLY_DEFAULT_LAYOUT_EVENT';
|
public static const FILE_LOADED_SUCCESSFULLY_EVENT:String = 'FILE_LOADED_SUCCESSFULLY_EVENT';
|
||||||
public static const INVALIDATE_LAYOUT_EVENT:String = 'INVALIDATE_LAYOUT_EVENT';
|
public static const APPLY_DEFAULT_LAYOUT_EVENT:String = 'APPLY_DEFAULT_LAYOUT_EVENT';
|
||||||
|
public static const INVALIDATE_LAYOUT_EVENT:String = 'INVALIDATE_LAYOUT_EVENT';
|
||||||
public function LayoutEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
|
|
||||||
{
|
public function LayoutEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
|
||||||
super(type, bubbles, cancelable);
|
{
|
||||||
}
|
super(type, bubbles, cancelable);
|
||||||
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -26,6 +26,7 @@ package org.bigbluebutton.modules.layout.events
|
|||||||
{
|
{
|
||||||
public static const UPDATE_LAYOUT_EVENT:String = 'UPDATE_LAYOUT_EVENT';
|
public static const UPDATE_LAYOUT_EVENT:String = 'UPDATE_LAYOUT_EVENT';
|
||||||
public var layout:LayoutDefinition;
|
public var layout:LayoutDefinition;
|
||||||
|
public var locked:Boolean;
|
||||||
|
|
||||||
public function UpdateLayoutEvent(type:String=UPDATE_LAYOUT_EVENT, bubbles:Boolean=true, cancelable:Boolean=false)
|
public function UpdateLayoutEvent(type:String=UPDATE_LAYOUT_EVENT, bubbles:Boolean=true, cancelable:Boolean=false)
|
||||||
{
|
{
|
||||||
|
@ -259,11 +259,20 @@ package org.bigbluebutton.modules.layout.managers
|
|||||||
sendLayoutUpdate(_currentLayout);
|
sendLayoutUpdate(_currentLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function broadcastLayout():void {
|
||||||
|
LogUtil.debug("LayoutManager: layout broadcasted by myself");
|
||||||
|
var e:UpdateLayoutEvent = new UpdateLayoutEvent();
|
||||||
|
e.layout = _currentLayout;
|
||||||
|
e.locked = _locked;
|
||||||
|
_globalDispatcher.dispatchEvent(e);
|
||||||
|
}
|
||||||
|
|
||||||
private function sendLayoutUpdate(layout:LayoutDefinition):void {
|
private function sendLayoutUpdate(layout:LayoutDefinition):void {
|
||||||
if (UsersUtil.amIModerator() || UsersUtil.amIPresenter()) {
|
if (UsersUtil.amIModerator() || UsersUtil.amIPresenter()) {
|
||||||
trace("LayoutManager: sending layout to remotes");
|
trace("LayoutManager: sending layout to remotes");
|
||||||
var e:UpdateLayoutEvent = new UpdateLayoutEvent();
|
var e:UpdateLayoutEvent = new UpdateLayoutEvent();
|
||||||
e.layout = layout;
|
e.layout = layout;
|
||||||
|
e.locked = _locked;
|
||||||
_globalDispatcher.dispatchEvent(e);
|
_globalDispatcher.dispatchEvent(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
|||||||
-->
|
-->
|
||||||
<EventMap xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="http://mate.asfusion.com/">
|
<EventMap xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="http://mate.asfusion.com/">
|
||||||
<mx:Script>
|
<mx:Script>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
import mx.events.FlexEvent;
|
import mx.events.FlexEvent;
|
||||||
|
|
||||||
import org.bigbluebutton.core.EventConstants;
|
import org.bigbluebutton.core.EventConstants;
|
||||||
@ -37,7 +37,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
|||||||
import org.bigbluebutton.modules.layout.managers.LayoutManager;
|
import org.bigbluebutton.modules.layout.managers.LayoutManager;
|
||||||
import org.bigbluebutton.modules.layout.services.LayoutService;
|
import org.bigbluebutton.modules.layout.services.LayoutService;
|
||||||
import org.bigbluebutton.modules.layout.services.MessageReceiver;
|
import org.bigbluebutton.modules.layout.services.MessageReceiver;
|
||||||
import org.bigbluebutton.modules.layout.services.MessageSender;
|
import org.bigbluebutton.modules.layout.services.MessageSender;
|
||||||
]]>
|
]]>
|
||||||
</mx:Script>
|
</mx:Script>
|
||||||
|
|
||||||
@ -70,7 +70,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
|||||||
</EventHandlers>
|
</EventHandlers>
|
||||||
|
|
||||||
<EventHandlers type="{LayoutEvent.LOCK_LAYOUT_EVENT}">
|
<EventHandlers type="{LayoutEvent.LOCK_LAYOUT_EVENT}">
|
||||||
<MethodInvoker generator="{LayoutManager}" method="lockLayout" />
|
<MethodInvoker generator="{LayoutManager}" method="lockLayout" />
|
||||||
</EventHandlers>
|
</EventHandlers>
|
||||||
|
|
||||||
<EventHandlers type="{EventConstants.LOCK_LAYOUT_REQ}">
|
<EventHandlers type="{EventConstants.LOCK_LAYOUT_REQ}">
|
||||||
@ -85,8 +85,12 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
|||||||
<MethodInvoker generator="{LayoutService}" method="unlockLayout"/>
|
<MethodInvoker generator="{LayoutService}" method="unlockLayout"/>
|
||||||
</EventHandlers>
|
</EventHandlers>
|
||||||
|
|
||||||
|
<EventHandlers type="{LayoutEvent.BROADCAST_LAYOUT_EVENT}">
|
||||||
|
<MethodInvoker generator="{LayoutManager}" method="broadcastLayout" />
|
||||||
|
</EventHandlers>
|
||||||
|
|
||||||
<EventHandlers type="{UpdateLayoutEvent.UPDATE_LAYOUT_EVENT}">
|
<EventHandlers type="{UpdateLayoutEvent.UPDATE_LAYOUT_EVENT}">
|
||||||
<MethodInvoker generator="{LayoutService}" method="lockLayout" arguments="{event.layout}" />
|
<MethodInvoker generator="{LayoutService}" method="broadcastLayout" arguments="{[event.layout, event.locked]}" />
|
||||||
</EventHandlers>
|
</EventHandlers>
|
||||||
|
|
||||||
<EventHandlers type="{SyncLayoutEvent.SYNC_LAYOUT_EVENT}">
|
<EventHandlers type="{SyncLayoutEvent.SYNC_LAYOUT_EVENT}">
|
||||||
|
@ -18,30 +18,31 @@
|
|||||||
*/
|
*/
|
||||||
package org.bigbluebutton.modules.layout.services
|
package org.bigbluebutton.modules.layout.services
|
||||||
{
|
{
|
||||||
import flash.events.IEventDispatcher;
|
import flash.events.IEventDispatcher;
|
||||||
|
|
||||||
|
import org.bigbluebutton.common.LogUtil;
|
||||||
|
import org.bigbluebutton.modules.layout.model.LayoutDefinition;
|
||||||
|
|
||||||
import org.bigbluebutton.common.LogUtil;
|
public class LayoutService
|
||||||
import org.bigbluebutton.modules.layout.model.LayoutDefinition;
|
{
|
||||||
|
|
||||||
public class LayoutService
|
|
||||||
{
|
|
||||||
public var sender:MessageSender;
|
public var sender:MessageSender;
|
||||||
public var receiver:MessageReceiver;
|
public var receiver:MessageReceiver;
|
||||||
|
|
||||||
public function getCurrentLayout():void {
|
public function getCurrentLayout():void {
|
||||||
sender.getCurrentLayout();
|
sender.getCurrentLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function syncLayout(layout:LayoutDefinition):void {
|
public function syncLayout(layout:LayoutDefinition):void {
|
||||||
sender.syncLayout(layout);
|
sender.syncLayout(layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function lockLayout(layout:LayoutDefinition):void {
|
|
||||||
sender.lockLayout(layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function unlockLayout():void {
|
public function broadcastLayout(layout:LayoutDefinition, locked:Boolean):void {
|
||||||
sender.unlockLayout();
|
sender.broadcastLayout(layout, locked);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
public function unlockLayout():void {
|
||||||
|
sender.unlockLayout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -10,6 +10,7 @@ package org.bigbluebutton.modules.layout.services
|
|||||||
import org.bigbluebutton.core.EventConstants;
|
import org.bigbluebutton.core.EventConstants;
|
||||||
import org.bigbluebutton.core.events.CoreEvent;
|
import org.bigbluebutton.core.events.CoreEvent;
|
||||||
import org.bigbluebutton.core.managers.UserManager;
|
import org.bigbluebutton.core.managers.UserManager;
|
||||||
|
import org.bigbluebutton.core.UsersUtil;
|
||||||
import org.bigbluebutton.main.events.ModuleLoadEvent;
|
import org.bigbluebutton.main.events.ModuleLoadEvent;
|
||||||
import org.bigbluebutton.main.model.users.IMessageListener;
|
import org.bigbluebutton.main.model.users.IMessageListener;
|
||||||
import org.bigbluebutton.modules.layout.events.LayoutEvent;
|
import org.bigbluebutton.modules.layout.events.LayoutEvent;
|
||||||
@ -100,11 +101,9 @@ package org.bigbluebutton.modules.layout.services
|
|||||||
_dispatcher.dispatchEvent(new CoreEvent(EventConstants.REMOTE_UNLOCKED_LAYOUT));
|
_dispatcher.dispatchEvent(new CoreEvent(EventConstants.REMOTE_UNLOCKED_LAYOUT));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (locked && !dispatchedByMe) {
|
if (!dispatchedByMe && !UsersUtil.amIModerator()) {
|
||||||
trace("LayoutService: handling remote layout= [" + layout + "]");
|
LogUtil.debug("LayoutService: handling remote layout");
|
||||||
|
LogUtil.debug(layout);
|
||||||
if (layout == "") return;
|
|
||||||
|
|
||||||
var layoutDefinition:LayoutDefinition = new LayoutDefinition();
|
var layoutDefinition:LayoutDefinition = new LayoutDefinition();
|
||||||
layoutDefinition.load(new XML(layout));
|
layoutDefinition.load(new XML(layout));
|
||||||
layoutDefinition.name = "[" + ResourceUtil.getInstance().getString('bbb.layout.combo.remote') + "] " + layoutDefinition.name;
|
layoutDefinition.name = "[" + ResourceUtil.getInstance().getString('bbb.layout.combo.remote') + "] " + layoutDefinition.name;
|
||||||
@ -117,4 +116,4 @@ package org.bigbluebutton.modules.layout.services
|
|||||||
_locked = locked;
|
_locked = locked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,13 +37,14 @@ package org.bigbluebutton.modules.layout.services
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function lockLayout(layout:LayoutDefinition):void {
|
public function broadcastLayout(layout:LayoutDefinition, locked:Boolean):void {
|
||||||
var message:Object = new Object();
|
var message:Object = new Object();
|
||||||
message["setByUserID"] = UserManager.getInstance().getConference().getMyUserId();
|
message["setByUserID"] = UserManager.getInstance().getConference().getMyUserId();
|
||||||
message["layout"] = layout.toXml().toXMLString();
|
message["layout"] = layout.toXml().toXMLString();
|
||||||
|
message["locked"] = locked;
|
||||||
|
|
||||||
var _nc:ConnectionManager = BBB.initConnectionManager();
|
var _nc:ConnectionManager = BBB.initConnectionManager();
|
||||||
_nc.sendMessage("layout.lock",
|
_nc.sendMessage("layout.broadcast",
|
||||||
function(result:String):void { // On successful result
|
function(result:String):void { // On successful result
|
||||||
LogUtil.debug(result);
|
LogUtil.debug(result);
|
||||||
},
|
},
|
||||||
|
@ -0,0 +1,61 @@
|
|||||||
|
<?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/>.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<views:LayoutButton xmlns:mx="http://www.adobe.com/2006/mxml"
|
||||||
|
creationComplete="init()"
|
||||||
|
xmlns:mate="http://mate.asfusion.com/"
|
||||||
|
xmlns:views="org.bigbluebutton.modules.layout.views.*"
|
||||||
|
toolTip="{ResourceUtil.getInstance().getString('bbb.layout.broadcastButton.toolTip')}"
|
||||||
|
icon="{_icon}"
|
||||||
|
click="onClick(event)"
|
||||||
|
enabled="{UserManager.getInstance().getConference().amIModerator()}">
|
||||||
|
|
||||||
|
<mx:Script>
|
||||||
|
<![CDATA[
|
||||||
|
import com.asfusion.mate.events.Dispatcher;
|
||||||
|
|
||||||
|
import flash.events.Event;
|
||||||
|
|
||||||
|
import org.bigbluebutton.common.Images;
|
||||||
|
import org.bigbluebutton.common.LogUtil;
|
||||||
|
import org.bigbluebutton.core.managers.UserManager;
|
||||||
|
import org.bigbluebutton.util.i18n.ResourceUtil;
|
||||||
|
import org.bigbluebutton.modules.layout.events.LayoutEvent;
|
||||||
|
|
||||||
|
import org.bigbluebutton.main.events.BBBEvent;
|
||||||
|
import org.bigbluebutton.main.events.ShortcutEvent;
|
||||||
|
import flash.events.FocusEvent;
|
||||||
|
|
||||||
|
private var _dispatcher:Dispatcher = new Dispatcher();
|
||||||
|
private var _images:Images = new Images();
|
||||||
|
[Bindable] private var _icon:Class = _images.raisehand;
|
||||||
|
|
||||||
|
private function init():void {
|
||||||
|
if (!UserManager.getInstance().getConference().amIModerator()) {
|
||||||
|
this.visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function onClick(e:Event):void {
|
||||||
|
_dispatcher.dispatchEvent(new LayoutEvent(LayoutEvent.BROADCAST_LAYOUT_EVENT));
|
||||||
|
}
|
||||||
|
]]>
|
||||||
|
</mx:Script>
|
||||||
|
</views:LayoutButton>
|
9
bigbluebutton-client/src/org/bigbluebutton/modules/layout/views/ToolbarComponent.mxml
Executable file → Normal file
9
bigbluebutton-client/src/org/bigbluebutton/modules/layout/views/ToolbarComponent.mxml
Executable file → Normal file
@ -27,9 +27,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
|||||||
<mx:Script>
|
<mx:Script>
|
||||||
<![CDATA[
|
<![CDATA[
|
||||||
import com.asfusion.mate.events.Dispatcher;
|
import com.asfusion.mate.events.Dispatcher;
|
||||||
|
|
||||||
import flexlib.mdi.containers.MDICanvas;
|
import flexlib.mdi.containers.MDICanvas;
|
||||||
|
|
||||||
import org.bigbluebutton.core.managers.UserManager;
|
import org.bigbluebutton.core.managers.UserManager;
|
||||||
import org.bigbluebutton.main.views.MainToolbar;
|
import org.bigbluebutton.main.views.MainToolbar;
|
||||||
import org.bigbluebutton.modules.layout.events.ViewInitializedEvent;
|
import org.bigbluebutton.modules.layout.events.ViewInitializedEvent;
|
||||||
@ -92,6 +90,11 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
|||||||
includeInLayout="{_enableEdit}"
|
includeInLayout="{_enableEdit}"
|
||||||
visible="{_enableEdit}"
|
visible="{_enableEdit}"
|
||||||
tabIndex="{baseIndex+3}"/>
|
tabIndex="{baseIndex+3}"/>
|
||||||
|
<views:BroadcastButton id="broadcastButton"
|
||||||
|
tabIndex="{baseIndex+4}"
|
||||||
|
enabled="{!lockButton.selected}"/>
|
||||||
<views:LockButton id="lockButton"
|
<views:LockButton id="lockButton"
|
||||||
tabIndex="{baseIndex+4}"/>
|
tabIndex="{baseIndex+5}"
|
||||||
|
visible="false"
|
||||||
|
includeInLayout="false"/>
|
||||||
</mx:HBox>
|
</mx:HBox>
|
||||||
|
Loading…
Reference in New Issue
Block a user