Implement new polling popup.

This commit is contained in:
Ghazi Triki 2018-04-11 23:18:05 +01:00
parent 04eefb40f2
commit ba2e8212aa
25 changed files with 608 additions and 138 deletions

View File

@ -79,8 +79,12 @@
/* Shared styles */
global {
font-family : SourceSansPro;
color : PropertyReference("bbbBlack");
font-family : SourceSansPro;
color : PropertyReference("bbbBlack");
modalTransparencyBlur : 0;
modalTransparency : 0.5;
modalTransparencyColor : black;
modalTransparencyDuration : 250;
}
/* Classes */
@ -92,9 +96,9 @@ s|Application {
s|Button {
fontFamily : SourceSansPro;
color : PropertyReference("white");
backgroundColor : PropertyReference("blue500");
borderColor : PropertyReference("white");
selectedBackgroundColor : PropertyReference("blue900");
backgroundColor : PropertyReference("bbbBlue");
borderVisible : false;
selectedBackgroundColor : PropertyReference("blue500");
skinClass : ClassReference("org.bigbluebutton.air.main.views.skins.ActionButtonSkin");
}
@ -193,6 +197,35 @@ main|EmojiItemRenderer {
selectedColor : PropertyReference("bbbBlue");
}
main|MobilePopUp {
separatorColor : PropertyReference("grey300");
skinClass : ClassReference("org.bigbluebutton.air.main.views.skins.MobilePopUpSkin");
}
.mobilePopUpUniqueButton, .mobilePopUpFirstButton, .mobilePopUpLastButton, .mobilePopUpLastButton {
fontFamily : SourceSansPro;
color : PropertyReference("bbbBlue");
backgroundColor : PropertyReference("white");
borderVisible : false;
selectedBackgroundColor : PropertyReference("grey100");
skinClass : ClassReference("org.bigbluebutton.air.main.views.skins.MobilePopUpButtonSkin");
}
.mobilePopUpUniqueButton {
position : "unique";
}
.mobilePopUpFirstButton {
position : "first";
}
.mobilePopUpMiddleButton {
position : "middle";
}
.mobilePopUpLastButton {
position : "last";
}
.statusList {
contentBackgroundAlpha : 0;
@ -268,16 +301,6 @@ settings|SettingsItemRenderer {
skinClass : ClassReference("org.bigbluebutton.air.main.views.skins.SaveButtonSkin");
}
.voteButton {
color : PropertyReference("white");
cornerRadius : 0;
borderVisible : false;
backgroundColor : PropertyReference("bbbBlue");
fontFamily : SourceSansPro;
selectedBackgroundColor : PropertyReference("darkBlue");
skinClass : ClassReference("org.bigbluebutton.air.main.views.skins.ActionButtonSkin");
}
.settingsIcon {
iconColor : PropertyReference("grey700");
}

View File

@ -118,9 +118,13 @@
fontSize: 16.50;
}
poll|PollButtons {
padding: 9.00;
gap: 13.50;
main|MobilePopUp {
cornerRadius: 6.00;
fontSize: 16.50;
}
.mobilePopUpUniqueButton, .mobilePopUpFirstButton, .mobilePopUpLastButton, .mobilePopUpLastButton {
cornerRadius: 6.00;
}
.icon {

View File

@ -118,9 +118,13 @@
fontSize: 8.250;
}
poll|PollButtons {
padding: 4.500;
gap: 6.750;
main|MobilePopUp {
cornerRadius: 3.000;
fontSize: 8.250;
}
.mobilePopUpUniqueButton, .mobilePopUpFirstButton, .mobilePopUpLastButton, .mobilePopUpLastButton {
cornerRadius: 3.000;
}
.icon {

View File

@ -118,9 +118,13 @@
fontSize: 11.0;
}
poll|PollButtons {
padding: 6.0;
gap: 9.0;
main|MobilePopUp {
cornerRadius: 4.0;
fontSize: 11.0;
}
.mobilePopUpUniqueButton, .mobilePopUpFirstButton, .mobilePopUpLastButton, .mobilePopUpLastButton {
cornerRadius: 4.0;
}
.icon {

View File

@ -106,9 +106,13 @@
fontSize : 22;
}
poll|PollButtons {
padding : 12;
gap : 18;
main|MobilePopUp {
cornerRadius : 8;
fontSize : 22;
}
.mobilePopUpUniqueButton, .mobilePopUpFirstButton, .mobilePopUpLastButton, .mobilePopUpLastButton {
cornerRadius : 8;
}
.icon {

View File

@ -118,9 +118,13 @@
fontSize: 33.0;
}
poll|PollButtons {
padding: 18.0;
gap: 27.0;
main|MobilePopUp {
cornerRadius: 12.0;
fontSize: 33.0;
}
.mobilePopUpUniqueButton, .mobilePopUpFirstButton, .mobilePopUpLastButton, .mobilePopUpLastButton {
cornerRadius: 12.0;
}
.icon {

View File

@ -118,9 +118,13 @@
fontSize: 44;
}
poll|PollButtons {
padding: 24;
gap: 36;
main|MobilePopUp {
cornerRadius: 16;
fontSize: 44;
}
.mobilePopUpUniqueButton, .mobilePopUpFirstButton, .mobilePopUpLastButton, .mobilePopUpLastButton {
cornerRadius: 16;
}
.icon {

View File

@ -1,11 +0,0 @@
<Graphic version="2.0" xmlns="http://ns.adobe.com/fxg/2008"
scaleGridLeft="16" scaleGridTop="16" scaleGridRight="504" scaleGridBottom="50">
<!-- border -->
<Path data="M12 2 518 2L518 64L12 64C6 64 2 60 2 54L2 12C2 6 6 2 12 2ZM12 0C6 0 0 6 0 12L0 54C0 60 6 66 12 66L520 66L520 0L12 0Z">
<fill>
<SolidColor color="#8B9AA8"/>
</fill>
</Path>
</Graphic>

View File

@ -1,17 +0,0 @@
package org.bigbluebutton.air.chat.views.skins {
import spark.skins.mobile.ScrollingStageTextInputSkin;
public class MessageInputSkin extends ScrollingStageTextInputSkin {
public function MessageInputSkin() {
super();
borderClass = MessageInputBorder320;
}
override protected function drawBackground(unscaledWidth:Number, unscaledHeight:Number):void {
// need to redo background draw so that it follows the new border shape.
super.drawBackground(unscaledWidth, unscaledHeight);
}
}
}

View File

@ -1,7 +1,9 @@
package org.bigbluebutton.air.common.views {
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.events.StageOrientationEvent;
import flash.ui.Keyboard;
import spark.components.View;
@ -20,12 +22,18 @@ package org.bigbluebutton.air.common.views {
_topToolbar = createToolbar();
_topToolbar.percentWidth = 100;
addElement(_topToolbar);
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage, false, 0, true);
}
protected function onAddedToStage(event:Event):void {
stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGE, onOrientationChange, false, 0, true);
}
/**
* Override this method in subclasses to be notified of rotation changes
*/
public function rotationHandler(rotation:String):void {
protected function onOrientationChange(event:Event):void {
invalidateDisplayList();
}
public function triggerLeftMenuTap(event:KeyboardEvent):void {

View File

@ -15,8 +15,8 @@ package org.bigbluebutton.air.main.views {
return _statusList;
}
public function EmojiCallout() {
super();
override protected function partAdded(partName:String, instance:Object):void {
super.partAdded(partName, instance);
var mainGroup:VGroup = new VGroup();
mainGroup.horizontalAlign = HorizontalAlign.CENTER;
@ -27,7 +27,6 @@ package org.bigbluebutton.air.main.views {
_statusList.percentWidth = 100;
_statusList.percentHeight = 100;
_statusList.itemRenderer = new ClassFactory(EmojiItemRenderer);
_statusList.styleName = "statusList";
_statusList.labelField = "label";
mainGroup.addElement(_statusList);
}
@ -35,6 +34,7 @@ package org.bigbluebutton.air.main.views {
override protected function updateDisplayList(w:Number, h:Number):void {
super.updateDisplayList(w, h);
_statusList.styleName = "statusList";
_statusList.setStyle('verticalScrollPolicy', ScrollPolicy.OFF);
_statusList.setStyle('horizontalScrollPolicy', ScrollPolicy.OFF);

View File

@ -1,9 +1,9 @@
package org.bigbluebutton.air.main.views {
import spark.components.Button;
import spark.layouts.BasicLayout;
import spark.layouts.VerticalLayout;
import org.bigbluebutton.air.common.views.NoTabView;
import org.bigbluebutton.air.poll.views.PollButtons;
import org.bigbluebutton.air.presentation.views.PresentationView;
import org.bigbluebutton.air.screenshare.views.ScreenshareDock;
import org.bigbluebutton.air.video.views.WebcamDock;
@ -18,7 +18,12 @@ package org.bigbluebutton.air.main.views {
private var _webcamDock:WebcamDock;
private var _screenshareView:ScreenshareDock;
private var _pollButton:PollButtons;
private var _pollButton:Button;
public function get pollButton():Button {
return _pollButton;
}
public function MainView() {
super();
@ -57,9 +62,9 @@ package org.bigbluebutton.air.main.views {
_menuButtons.bottom = 0;
addElement(_menuButtons);
_pollButton = new PollButtons();
_pollButton.visible = false;
_pollButton.percentWidth = 100;
_pollButton = new Button();
_pollButton.visible = _pollButton.includeInLayout = false;
_pollButton.label = "View Polling Options";
_pollButton.horizontalCenter = 0;
addElement(_pollButton);
}
@ -80,7 +85,11 @@ package org.bigbluebutton.air.main.views {
_webcamDock.bottom = _menuButtons.height;
_pollButton.bottom = getStyle("pollPadding");;
_pollButton.bottom = _menuButtons.height - _pollButton.height - 8;
}
public function showPollingButton(visible:Boolean):void {
_pollButton.visible = _pollButton.includeInLayout = visible;
}
private function onScreenshareRunning(usingStageVideo:Boolean, running:Boolean):void {

View File

@ -1,4 +1,13 @@
package org.bigbluebutton.air.main.views {
import flash.display.DisplayObjectContainer;
import flash.events.MouseEvent;
import org.bigbluebutton.air.main.models.IMeetingData;
import org.bigbluebutton.air.poll.commands.RespondToPollSignal;
import org.bigbluebutton.air.poll.models.PollChangeEnum;
import org.bigbluebutton.air.poll.models.PollVO;
import org.bigbluebutton.air.poll.views.PollPopUp;
import robotlegs.bender.bundles.mvcs.Mediator;
public class MainViewMediator extends Mediator {
@ -6,13 +15,45 @@ package org.bigbluebutton.air.main.views {
[Inject]
public var view:MainView;
[Inject]
public var meetingData:IMeetingData;
[Inject]
public var respondToPollSignal:RespondToPollSignal;
override public function initialize():void {
//trace("************ MainViewMediator:: INIT **************");
meetingData.polls.pollChangeSignal.add(onPollChange);
respondToPollSignal.add(onRespondToPollSignal);
view.pollButton.addEventListener(MouseEvent.CLICK, onPollButtonMouseClick);
if (meetingData.polls.getCurrentPoll() && !meetingData.polls.getCurrentPoll().answered) {
view.showPollingButton(true);
}
}
private function onPollButtonMouseClick(event:MouseEvent):void {
var pollPopUp:PollPopUp = new PollPopUp();
pollPopUp.open(view.parentApplication as DisplayObjectContainer, true);
}
private function onRespondToPollSignal(answer:String):void {
view.showPollingButton(false);
}
private function onPollChange(poll:PollVO, enum:int):void {
switch (enum) {
case PollChangeEnum.START:
view.showPollingButton(true);
break;
case PollChangeEnum.STOP:
view.showPollingButton(false);
break;
default:
break;
}
}
override public function destroy():void {
//trace("************ MainViewMediator:: destroy **************");
meetingData.polls.pollChangeSignal.remove(onPollChange);
}
}
}

View File

@ -11,6 +11,7 @@ package org.bigbluebutton.air.main.views {
public class MenuButtons extends SkinnableContainer {
private var _audioButton:Button;
private var bLayout:HorizontalLayout
public function get audioButton():Button {
@ -38,7 +39,7 @@ package org.bigbluebutton.air.main.views {
public function MenuButtons() {
super();
bLayout = new HorizontalLayout();
bLayout = new HorizontalLayout();
bLayout.horizontalAlign = HorizontalAlign.CENTER
layout = bLayout;

View File

@ -1,15 +1,15 @@
package org.bigbluebutton.air.main.views {
import flash.events.MouseEvent;
import spark.components.CalloutPosition;
import spark.components.Alert;
import spark.components.CalloutPosition;
import org.bigbluebutton.air.common.PageEnum;
import org.bigbluebutton.air.main.models.IConferenceParameters;
import org.bigbluebutton.air.main.models.IMedia;
import org.bigbluebutton.air.main.models.IMeetingData;
import org.bigbluebutton.air.main.models.IUISession;
import org.bigbluebutton.air.main.models.LockSettings2x;
import org.bigbluebutton.air.user.models.UserRole;
import org.bigbluebutton.air.video.commands.ShareCameraSignal;
import org.bigbluebutton.air.video.models.WebcamStreamInfo;
@ -17,6 +17,7 @@ package org.bigbluebutton.air.main.views {
import org.bigbluebutton.air.voice.commands.ShareMicrophoneSignal;
import org.bigbluebutton.air.voice.models.AudioTypeEnum;
import org.bigbluebutton.air.voice.models.VoiceUser;
import robotlegs.bender.bundles.mvcs.Mediator;
import robotlegs.bender.extensions.mediatorMap.api.IMediatorMap;
@ -52,7 +53,7 @@ package org.bigbluebutton.air.main.views {
public override function initialize():void {
meetingData.voiceUsers.userChangeSignal.add(onVoiceUserChanged);
meetingData.webcams.webcamChangeSignal.add(onWebcamChange);
media.cameraPermissionSignal.add(onCameraPermission);
media.microphonePermissionSignal.add(onMicrophonePermission);
@ -69,7 +70,7 @@ package org.bigbluebutton.air.main.views {
if (meetingData.meetingStatus.lockSettings.disableCam) {
view.camButton.enabled = false;
} else {
view.camButton.enabled = true;
view.camButton.enabled = true;
}
}
}
@ -96,9 +97,9 @@ package org.bigbluebutton.air.main.views {
microphoneMuteSignal.dispatch(meetingData.users.me.intId);
}
}
} else {
} else {
microphoneMuteSignal.dispatch(meetingData.users.me.intId);
}
}
}
}
@ -114,22 +115,18 @@ package org.bigbluebutton.air.main.views {
private function joinOrLeaveAudio():void {
if (meetingData.voiceUsers.me == null) {
if (meetingData.users.me.locked &&
meetingData.users.me.role != UserRole.MODERATOR &&
meetingData.meetingStatus.lockSettings.disableMic) {
if (meetingData.users.me.locked && meetingData.users.me.role != UserRole.MODERATOR && meetingData.meetingStatus.lockSettings.disableMic) {
shareMicrophoneSignal.dispatch(AudioTypeEnum.LISTEN_ONLY, conferenceParameters.webvoiceconf);
} else {
uiSession.pushPage(PageEnum.AUDIO);
}
uiSession.pushPage(PageEnum.AUDIO);
}
} else {
shareMicrophoneSignal.dispatch(AudioTypeEnum.LEAVE, "");
}
}
private function camOnOff(e:MouseEvent):void {
if (meetingData.users.me.locked &&
meetingData.users.me.role != UserRole.MODERATOR &&
meetingData.meetingStatus.lockSettings.disableCam) {
if (meetingData.users.me.locked && meetingData.users.me.role != UserRole.MODERATOR && meetingData.meetingStatus.lockSettings.disableCam) {
Alert.show("Sharing webcam denied.");
} else {
if (media.cameraAvailable) {
@ -155,7 +152,7 @@ package org.bigbluebutton.air.main.views {
view.camButton.label = "Cam on"; // ResourceManager.getInstance().getString('resources', 'menuButtons.camOn');
view.camButton.styleName = "icon-video menuButton"
}
if (meetingData.voiceUsers.me) {
view.micButton.visible = view.micButton.includeInLayout = !meetingData.voiceUsers.me.listenOnly;
view.audioButton.styleName = "icon-audio-off menuButtonRed";
@ -209,7 +206,7 @@ package org.bigbluebutton.air.main.views {
public override function destroy():void {
meetingData.voiceUsers.userChangeSignal.remove(onVoiceUserChanged);
meetingData.webcams.webcamChangeSignal.remove(onWebcamChange);
media.cameraPermissionSignal.remove(onCameraPermission);
media.microphonePermissionSignal.remove(onMicrophonePermission);
view.audioButton.removeEventListener(MouseEvent.CLICK, audioOnOff);

View File

@ -0,0 +1,78 @@
package org.bigbluebutton.air.main.views {
import flash.display.DisplayObjectContainer;
import flash.events.Event;
import flash.events.StageOrientationEvent;
import mx.managers.PopUpManager;
import spark.components.Group;
import spark.components.Label;
import spark.components.Scroller;
import spark.components.SkinnablePopUpContainer;
public class MobilePopUp extends SkinnablePopUpContainer {
protected var _text:String;
protected var _title:String;
[SkinPart(required = "false")]
public var titleDisplay:Label;
[SkinPart(required = "false")]
public var textDisplay:Label;
[SkinPart(required = "false")]
public var scroller:Scroller;
[SkinPart(required = "false")]
public var controlBarGroup:Group;
public function MobilePopUp() {
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage, false, 0, true);
addEventListener(Event.REMOVED_FROM_STAGE, removeFromStage, false, 0, true);
}
protected function onAddedToStage(event:Event):void {
percentWidth = 80;
stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGE, onOrientationChange, false, 0, true);
}
protected function removeFromStage(event:Event):void {
stage.removeEventListener(StageOrientationEvent.ORIENTATION_CHANGE, onOrientationChange);
}
protected function onOrientationChange(event:Event):void {
invalidateDisplayList();
}
protected override function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
super.updateDisplayList(unscaledWidth, unscaledHeight);
PopUpManager.centerPopUp(this);
}
override protected function partAdded(partName:String, instance:Object):void {
super.partAdded(partName, instance);
if (instance == titleDisplay) {
titleDisplay.text = _title;
}
if (instance == textDisplay) {
textDisplay.text = _text;
}
}
override protected function commitProperties():void {
super.commitProperties();
if (textDisplay) {
textDisplay.text = _text;
}
}
override public function open(owner:DisplayObjectContainer, modal:Boolean = false):void {
super.open(owner, modal);
PopUpManager.centerPopUp(this);
}
}
}

View File

@ -0,0 +1,108 @@
<?xml version="1.0" encoding="utf-8"?>
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
minWidth="21"
minHeight="21"
alpha.disabled="0.5">
<fx:Metadata>
<![CDATA[
[HostComponent("spark.components.Button")]
]]>
</fx:Metadata>
<fx:Script fb:purpose="styling">
<![CDATA[
import spark.components.Button;
/**
* @private
*/
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
var cr:Number = getStyle("cornerRadius");
if (cornerRadius != cr) {
cornerRadius = cr;
var position:String = getStyle("position");
if (position == "unique") {
fill.bottomLeftRadiusX = cornerRadius;
fill.bottomRightRadiusX = cornerRadius;
border.bottomLeftRadiusX = cornerRadius;
border.bottomRightRadiusX = cornerRadius;
} else if (position == "first") {
fill.bottomLeftRadiusX = cornerRadius;
border.bottomLeftRadiusX = cornerRadius;
} else if (position == "middle") {
fill.bottomLeftRadiusX = 0;
fill.bottomRightRadiusX = 0;
border.bottomLeftRadiusX = 0;
border.bottomRightRadiusX = 0;
} else if (position == "last") {
fill.bottomRightRadiusX = cornerRadius;
border.bottomRightRadiusX = cornerRadius;
}
}
border.visible = getStyle("borderVisible");
super.updateDisplayList(unscaledWidth, unscaledHeight);
}
private var cornerRadius:Number = 2;
]]>
</fx:Script>
<!-- states -->
<s:states>
<s:State name="up" />
<s:State name="over" />
<s:State name="down" />
<s:State name="disabled" />
</s:states>
<!-- fill -->
<!--- @private -->
<s:Rect id="fill"
left="1"
right="1"
top="1"
bottom="1"
radiusX="2">
<s:fill>
<s:SolidColor color="{hostComponent.getStyle('backgroundColor')}"
color.down="{hostComponent.getStyle('selectedBackgroundColor')}" />
</s:fill>
</s:Rect>
<!-- border - put on top of the fill so it doesn't disappear when scale is less than 1 -->
<!--- @private -->
<s:Rect id="border"
left="0"
right="0"
top="0"
bottom="0"
width="69"
height="20"
radiusX="2">
<s:stroke>
<s:SolidColorStroke weight="2"
color="{hostComponent.getStyle('borderColor')}" />
</s:stroke>
</s:Rect>
<!-- layer : text -->
<s:Label id="labelDisplay"
textAlign="center"
maxDisplayedLines="1"
horizontalCenter="0"
verticalCenter="1"
verticalAlign="middle"
left="40"
right="40"
top="20"
bottom="20">
</s:Label>
</s:Skin>

View File

@ -0,0 +1,147 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!--- The default skin class for a Spark SkinnablePopUpContainer container.
@see spark.components.SkinnablePopUpContainer
@langversion 3.0
@playerversion Flash 10
@playerversion AIR 2.5
@productversion Flex 4.5
-->
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
minWidth="131" minHeight="30" alpha.disabled="0.5">
<fx:Metadata>[HostComponent("org.bigbluebutton.air.main.views.MobilePopUp")]</fx:Metadata>
<fx:Script fb:purpose="styling">
<![CDATA[
import spark.components.Application;
/**
* @private
*/
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number) : void
{
// Push backgroundColor and backgroundAlpha directly.
// Handle undefined backgroundColor by hiding the background object.
if (isNaN(getStyle("backgroundColor")))
{
background.visible = false;
}
else
{
background.visible = true;
background.bottomLeftRadiusX = getStyle("cornerRadius");
background.bottomRightRadiusX = getStyle("cornerRadius");
background.topLeftRadiusX = getStyle("cornerRadius");
background.topRightRadiusX = getStyle("cornerRadius");
bgFill.color = getStyle("backgroundColor");
bgFill.alpha = getStyle("backgroundAlpha");
}
super.updateDisplayList(unscaledWidth, unscaledHeight);
}
]]>
</fx:Script>
<s:states>
<s:State name="normal"/>
<s:State name="disabled"/>
<s:State name="closed" stateGroups="closedGroup"/>
<s:State name="disabledAndClosed" stateGroups="closedGroup"/>
</s:states>
<!-- Transitions for open and close -->
<s:transitions>
<s:Transition fromState="closed" toState="normal" autoReverse="true">
<s:Fade duration="150" target="{chrome}"/>
</s:Transition>
<s:Transition fromState="disabledAndClosed" toState="disabled" autoReverse="true">
<s:Fade duration="150" target="{chrome}"/>
</s:Transition>
<s:Transition fromState="normal" toState="closed" autoReverse="true">
<s:Fade duration="150" target="{chrome}"/>
</s:Transition>
<s:Transition fromState="disabled" toState="disabledAndClosed" autoReverse="true">
<s:Fade duration="150" target="{chrome}"/>
</s:Transition>
</s:transitions>
<!--- Defines the appearance of the SkinnablePopUpContainer class's background. -->
<s:Rect id="background" left="0" right="0" top="0" bottom="0">
<s:fill>
<!--- @private -->
<s:SolidColor id="bgFill" color="#FFFFFF" alpha="0.9"/>
</s:fill>
</s:Rect>
<!--- Defines the background and content group used by this skin. -->
<s:Group id="chrome" left="0" right="0" top="0" bottom="0" visible.closedGroup="false">
<s:layout>
<s:VerticalLayout gap="5" paddingTop="5" horizontalAlign="center"/>
</s:layout>
<s:Label id="titleDisplay" maxDisplayedLines="0" left="10" right="10"
minHeight="30" verticalAlign="middle"
textAlign="center" fontWeight="bold"/>
<s:Label id="textDisplay" maxDisplayedLines="0"
left="10" right="10" maxWidth="{Application(parentApplication).width * 0.8}" textAlign="center"
paddingLeft="10" paddingRight="10" paddingBottom="10"/>
<!--
Note: Setting the minimum size to 0 here so that changes to the host component's
size will not be thwarted by this skin part's minimum size. This is a compromise,
more about it here: http://bugs.adobe.com/jira/browse/SDK-21143
-->
<s:Scroller width="100%" height="100%" id="scroller">
<!--- @copy spark.components.SkinnableContainer#contentGroup -->
<s:Group id="contentGroup" width="100%" height="100%" minWidth="0" minHeight="0">
<s:layout>
<s:BasicLayout/>
</s:layout>
</s:Group>
</s:Scroller>
<s:VGroup gap="0" width="100%">
<s:Line width="100%">
<s:stroke>
<s:SolidColorStroke color="{getStyle('separatorColor')}" weight="1" />
</s:stroke>
</s:Line>
<s:Group id="controlBarGroup" width="100%">
<s:layout>
<s:HorizontalLayout paddingLeft="0" paddingRight="0" paddingTop="0"
paddingBottom="0" gap="0" horizontalAlign="center"/>
</s:layout>
</s:Group>
</s:VGroup>
</s:Group>
</s:Skin>

View File

@ -1,8 +1,8 @@
package org.bigbluebutton.air.poll {
import org.bigbluebutton.air.poll.commands.RespondToPollCommand;
import org.bigbluebutton.air.poll.commands.RespondToPollSignal;
import org.bigbluebutton.air.poll.views.PollButtons;
import org.bigbluebutton.air.poll.views.PollButtonsMediator;
import org.bigbluebutton.air.poll.views.PollPopUp;
import org.bigbluebutton.air.poll.views.PollPopUpMediator;
import robotlegs.bender.extensions.mediatorMap.api.IMediatorMap;
import robotlegs.bender.extensions.signalCommandMap.api.ISignalCommandMap;
@ -25,7 +25,7 @@ package org.bigbluebutton.air.poll {
* Maps view mediators to views.
*/
private function mediators():void {
mediatorMap.map(PollButtons).toMediator(PollButtonsMediator);
mediatorMap.map(PollPopUp).toMediator(PollPopUpMediator);
}
/**

View File

@ -16,6 +16,7 @@ package org.bigbluebutton.air.poll.commands {
public var answer:String;
override public function execute():void {
meetingData.polls.voteCurrentPoll();
pollService.votePoll(meetingData.polls.getCurrentPoll().id, answer);
}
}

View File

@ -5,6 +5,8 @@ package org.bigbluebutton.air.poll.models {
private var _answers:Array;
private var _answered:Boolean
public function PollVO(id:String, answers:Array) {
_id = id;
_answers = answers;
@ -17,5 +19,13 @@ package org.bigbluebutton.air.poll.models {
public function get answers():Array {
return _answers;
}
public function get answered():Boolean {
return _answered;
}
public function set answered(value:Boolean):void {
_answered = value;
}
}
}

View File

@ -16,6 +16,10 @@ package org.bigbluebutton.air.poll.models {
_pollChangeSignal.dispatch(null, PollChangeEnum.STOP);
}
public function voteCurrentPoll():void {
_currentPoll.answered = true;
}
public function getCurrentPoll():PollVO {
return _currentPoll;
}

View File

@ -1,34 +0,0 @@
package org.bigbluebutton.air.poll.views {
import spark.components.Button;
import spark.components.TileGroup;
import spark.layouts.ColumnAlign;
import org.bigbluebutton.air.poll.models.PollVO;
public class PollButtons extends TileGroup {
public function PollButtons() {
columnAlign = ColumnAlign.JUSTIFY_USING_GAP;
}
public function addButtons(poll:PollVO):void {
var voteBtn:Button;
var numBtns:int = poll.answers.length;
var btnWidth:int = 100 / numBtns;
for (var i:int = 0; i < numBtns; i++) {
voteBtn = new Button();
voteBtn.percentWidth = btnWidth;
voteBtn.styleName = "voteButton";
// To be localised
voteBtn.label = poll.answers[i].key;
voteBtn.name = poll.answers[i].id;
this.addElement(voteBtn);
}
}
override protected function updateDisplayList(w:Number, h:Number):void {
super.updateDisplayList(w, h);
this.padding = getStyle("padding");
}
}
}

View File

@ -0,0 +1,73 @@
package org.bigbluebutton.air.poll.views {
import flash.display.DisplayObjectContainer;
import flash.events.Event;
import spark.components.Application;
import spark.components.Button;
import spark.components.VGroup;
import spark.layouts.HorizontalAlign;
import org.bigbluebutton.air.main.views.MobilePopUp;
import org.bigbluebutton.air.poll.models.PollVO;
public class PollPopUp extends MobilePopUp {
private var _closeButton:Button;
public function get closeButton():Button {
return _closeButton;
}
public function PollPopUp() {
super();
_closeButton = new Button();
_title = "Polling";
_text = "Provide your response to the poll by selecting an option below.";
}
public function addButtons(poll:PollVO):void {
var voteBtn:Button;
var numBtns:int = poll.answers.length;
contentGroup.removeAllElements();
var buttonsGroup:VGroup = new VGroup();
buttonsGroup.percentWidth = 100;
buttonsGroup.horizontalAlign = HorizontalAlign.CENTER;
contentGroup.addElement(buttonsGroup);
for (var i:int = 0; i < numBtns; i++) {
voteBtn = new Button();
voteBtn.percentWidth = 80;
// @todo: To be localised
voteBtn.label = poll.answers[i].key;
voteBtn.name = poll.answers[i].id;
buttonsGroup.addElement(voteBtn);
}
}
override public function open(owner:DisplayObjectContainer, modal:Boolean = false):void {
super.open(owner, modal);
maxHeight = Application(parentApplication).height - 120;
}
override protected function partAdded(partName:String, instance:Object):void {
super.partAdded(partName, instance);
if (instance == controlBarGroup) {
_closeButton.percentWidth = 100;
_closeButton.label = "Close Polling Options";
_closeButton.styleName = "mobilePopUpUniqueButton";
controlBarGroup.addElement(_closeButton);
}
}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
super.updateDisplayList(unscaledWidth, unscaledHeight);
if (scroller && scroller.verticalScrollBar) {
scroller.verticalScrollBar.visible = true;
}
}
}
}

View File

@ -1,6 +1,8 @@
package org.bigbluebutton.air.poll.views {
import flash.events.MouseEvent;
import flash.events.StageOrientationEvent;
import spark.components.Application;
import spark.components.Button;
import org.bigbluebutton.air.main.models.IMeetingData;
@ -10,10 +12,10 @@ package org.bigbluebutton.air.poll.views {
import robotlegs.bender.bundles.mvcs.Mediator;
public class PollButtonsMediator extends Mediator {
public class PollPopUpMediator extends Mediator {
[Inject]
public var view:PollButtons;
public var view:PollPopUp;
[Inject]
public var meetingData:IMeetingData;
@ -24,25 +26,30 @@ package org.bigbluebutton.air.poll.views {
public override function initialize():void {
meetingData.polls.pollChangeSignal.add(onPollChange);
view.addEventListener(MouseEvent.CLICK, viewMouseEventHandler);
view.removeAllElements();
view.addButtons(meetingData.polls.getCurrentPoll());
view.stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGE, onStageOrientation);
}
private function viewMouseEventHandler(event:MouseEvent):void {
if (event.target is Button) {
view.removeAllElements();
if (event.target == view.closeButton) {
view.close();
} else if (event.target is Button) {
respondToPollSignal.dispatch(event.target.name);
view.close();
}
}
private function onStageOrientation(event:StageOrientationEvent):void {
view.addButtons(meetingData.polls.getCurrentPoll());
view.maxHeight = Application(view.parentApplication).height - 120;
}
private function onPollChange(poll:PollVO, enum:int):void {
switch (enum) {
case PollChangeEnum.START:
view.removeAllElements();
view.addButtons(poll);
view.visible = true;
break;
case PollChangeEnum.STOP:
view.removeAllElements();
view.visible = false;
view.close();
break;
default:
break;
@ -53,5 +60,6 @@ package org.bigbluebutton.air.poll.views {
meetingData.polls.pollChangeSignal.remove(onPollChange);
view.removeEventListener(MouseEvent.CLICK, viewMouseEventHandler);
}
}
}