mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-17 05:35:03 +00:00
Recent calls fixes; Directory browsing work
This commit is contained in:
@@ -21,7 +21,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
|||||||
{
|
{
|
||||||
enum eCommandType { SessionStart, SessionEnd, Command, GetStatus, GetConfiguration };
|
enum eCommandType { SessionStart, SessionEnd, Command, GetStatus, GetConfiguration };
|
||||||
|
|
||||||
public class CiscoCodec : VideoCodecBase, IHasCallHistory, IHasCallFavorites, IHasDirectory, IHasScheduleAwareness, IOccupancyStatusProvider, IHasCodecLayouts, IHasCodecSelfview
|
public class CiscoCodec : VideoCodecBase, IHasCallHistory, IHasCallFavorites, IHasDirectory,
|
||||||
|
IHasScheduleAwareness, IOccupancyStatusProvider, IHasCodecLayouts, IHasCodecSelfview
|
||||||
{
|
{
|
||||||
public event EventHandler<DirectoryEventArgs> DirectoryResultReturned;
|
public event EventHandler<DirectoryEventArgs> DirectoryResultReturned;
|
||||||
|
|
||||||
@@ -283,6 +284,17 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
|||||||
CodecStatus.Status.Video.Selfview.Mode.ValueChangedAction = SelfviewIsOnFeedback.FireUpdate;
|
CodecStatus.Status.Video.Selfview.Mode.ValueChangedAction = SelfviewIsOnFeedback.FireUpdate;
|
||||||
CodecStatus.Status.Video.Selfview.PIPPosition.ValueChangedAction = ComputeSelfviewPipStatus;
|
CodecStatus.Status.Video.Selfview.PIPPosition.ValueChangedAction = ComputeSelfviewPipStatus;
|
||||||
CodecStatus.Status.Video.Layout.LayoutFamily.Local.ValueChangedAction = ComputeLocalLayout;
|
CodecStatus.Status.Video.Layout.LayoutFamily.Local.ValueChangedAction = ComputeLocalLayout;
|
||||||
|
|
||||||
|
CodecOsdIn = new RoutingInputPort(RoutingPortNames.CodecOsd, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, new Action(StopSharing), this);
|
||||||
|
HdmiIn1 = new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, new Action(SelectPresentationSource1), this);
|
||||||
|
HdmiIn2 = new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, new Action(SelectPresentationSource2), this);
|
||||||
|
|
||||||
|
HdmiOut = new RoutingOutputPort(RoutingPortNames.HdmiOut, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, null, this);
|
||||||
|
|
||||||
|
InputPorts.Add(CodecOsdIn);
|
||||||
|
InputPorts.Add(HdmiIn1);
|
||||||
|
InputPorts.Add(HdmiIn2);
|
||||||
|
OutputPorts.Add(HdmiOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -304,19 +316,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Cisco
|
|||||||
socket.ConnectionChange += new EventHandler<GenericSocketStatusChageEventArgs>(socket_ConnectionChange);
|
socket.ConnectionChange += new EventHandler<GenericSocketStatusChageEventArgs>(socket_ConnectionChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
CommunicationMonitor.Start();
|
CommunicationMonitor.Start();
|
||||||
|
|
||||||
CodecOsdIn = new RoutingInputPort(RoutingPortNames.CodecOsd, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, new Action(StopSharing), this);
|
|
||||||
HdmiIn1 = new RoutingInputPort(RoutingPortNames.HdmiIn1, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, new Action(SelectPresentationSource1), this);
|
|
||||||
HdmiIn2 = new RoutingInputPort(RoutingPortNames.HdmiIn2, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, new Action(SelectPresentationSource2), this);
|
|
||||||
|
|
||||||
HdmiOut = new RoutingOutputPort(RoutingPortNames.HdmiOut, eRoutingSignalType.AudioVideo, eRoutingPortConnectionType.Hdmi, null, this);
|
|
||||||
|
|
||||||
InputPorts.Add(CodecOsdIn);
|
|
||||||
InputPorts.Add(HdmiIn1);
|
|
||||||
InputPorts.Add(HdmiIn2);
|
|
||||||
OutputPorts.Add(HdmiOut);
|
|
||||||
|
|
||||||
|
|
||||||
string prefix = "xFeedback register ";
|
string prefix = "xFeedback register ";
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -11,7 +11,8 @@ using PepperDash.Essentials.Devices.Common.Codec;
|
|||||||
|
|
||||||
namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||||
{
|
{
|
||||||
public abstract class VideoCodecBase : Device, IRoutingInputsOutputs, IUsageTracking, IHasDialer, IHasSharing, ICodecAudio, iCodecInfo
|
public abstract class VideoCodecBase : Device, IRoutingInputsOutputs,
|
||||||
|
IUsageTracking, IHasDialer, IHasSharing, ICodecAudio, iCodecInfo
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Fires when the status of any active, dialing, or incoming call changes or is new
|
/// Fires when the status of any active, dialing, or incoming call changes or is new
|
||||||
|
|||||||
@@ -0,0 +1,850 @@
|
|||||||
|
<<<<<<< HEAD
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Room.Config;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials
|
||||||
|
{
|
||||||
|
public class EssentialsHuddleSpaceRoom : EssentialsRoomBase, IHasCurrentSourceInfoChange
|
||||||
|
{
|
||||||
|
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
||||||
|
public event SourceInfoChangeHandler CurrentSingleSourceChange;
|
||||||
|
|
||||||
|
protected override Func<bool> OnFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
var val = CurrentSourceInfo != null
|
||||||
|
&& CurrentSourceInfo.Type == eSourceListItemType.Route
|
||||||
|
&& disp != null
|
||||||
|
&& disp.PowerIsOnFeedback.BoolValue;
|
||||||
|
return val;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override Func<bool> IsWarmingFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
if (disp != null)
|
||||||
|
return disp.IsWarmingUpFeedback.BoolValue;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override Func<bool> IsCoolingFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
if (disp != null)
|
||||||
|
return disp.IsCoolingDownFeedback.BoolValue;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public EssentialsRoomPropertiesConfig Config { get; private set; }
|
||||||
|
|
||||||
|
public IRoutingSinkWithSwitching DefaultDisplay { get; private set; }
|
||||||
|
public IRoutingSinkNoSwitching DefaultAudioDevice { get; private set; }
|
||||||
|
public IBasicVolumeControls DefaultVolumeControls { get; private set; }
|
||||||
|
|
||||||
|
public bool ExcludeFromGlobalFunctions { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The config name of the source list
|
||||||
|
/// </summary>
|
||||||
|
public string SourceListKey { get; set; }
|
||||||
|
|
||||||
|
public string DefaultSourceItem { get; set; }
|
||||||
|
|
||||||
|
public ushort DefaultVolume { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If room is off, enables power on to last source. Default true
|
||||||
|
/// </summary>
|
||||||
|
public bool EnablePowerOnToLastSource { get; set; }
|
||||||
|
string LastSourceKey;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public IBasicVolumeControls CurrentVolumeControls
|
||||||
|
{
|
||||||
|
get { return _CurrentAudioDevice; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == _CurrentAudioDevice) return;
|
||||||
|
|
||||||
|
var oldDev = _CurrentAudioDevice;
|
||||||
|
// derigister this room from the device, if it can
|
||||||
|
if (oldDev is IInUseTracking)
|
||||||
|
(oldDev as IInUseTracking).InUseTracker.RemoveUser(this, "audio");
|
||||||
|
var handler = CurrentVolumeDeviceChange;
|
||||||
|
if (handler != null)
|
||||||
|
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.WillChange));
|
||||||
|
_CurrentAudioDevice = value;
|
||||||
|
if (handler != null)
|
||||||
|
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.DidChange));
|
||||||
|
// register this room with new device, if it can
|
||||||
|
if (_CurrentAudioDevice is IInUseTracking)
|
||||||
|
(_CurrentAudioDevice as IInUseTracking).InUseTracker.AddUser(this, "audio");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IBasicVolumeControls _CurrentAudioDevice;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The SourceListItem last run - containing names and icons
|
||||||
|
/// </summary>
|
||||||
|
public SourceListItem CurrentSourceInfo
|
||||||
|
{
|
||||||
|
get { return _CurrentSourceInfo; }
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
if (value == _CurrentSourceInfo) return;
|
||||||
|
|
||||||
|
var handler = CurrentSingleSourceChange;
|
||||||
|
// remove from in-use tracker, if so equipped
|
||||||
|
if(_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||||
|
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.RemoveUser(this, "control");
|
||||||
|
|
||||||
|
if (handler != null)
|
||||||
|
handler(this, _CurrentSourceInfo, ChangeType.WillChange);
|
||||||
|
|
||||||
|
_CurrentSourceInfo = value;
|
||||||
|
|
||||||
|
// add to in-use tracking
|
||||||
|
if (_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||||
|
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control");
|
||||||
|
if (handler != null)
|
||||||
|
handler(this, _CurrentSourceInfo, ChangeType.DidChange);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SourceListItem _CurrentSourceInfo;
|
||||||
|
|
||||||
|
public string CurrentSourceInfoKey { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
public EssentialsHuddleSpaceRoom(string key, string name, IRoutingSinkWithSwitching defaultDisplay,
|
||||||
|
IRoutingSinkNoSwitching defaultAudio, EssentialsRoomPropertiesConfig config)
|
||||||
|
: base(key, name)
|
||||||
|
{
|
||||||
|
Config = config;
|
||||||
|
DefaultDisplay = defaultDisplay;
|
||||||
|
DefaultAudioDevice = defaultAudio;
|
||||||
|
if (defaultAudio is IBasicVolumeControls)
|
||||||
|
DefaultVolumeControls = defaultAudio as IBasicVolumeControls;
|
||||||
|
else if (defaultAudio is IHasVolumeDevice)
|
||||||
|
DefaultVolumeControls = (defaultAudio as IHasVolumeDevice).VolumeDevice;
|
||||||
|
CurrentVolumeControls = DefaultVolumeControls;
|
||||||
|
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
if (disp != null)
|
||||||
|
{
|
||||||
|
// Link power, warming, cooling to display
|
||||||
|
disp.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
if (disp.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
|
||||||
|
{
|
||||||
|
if (!disp.PowerIsOnFeedback.BoolValue)
|
||||||
|
CurrentSourceInfo = null;
|
||||||
|
OnFeedback.FireUpdate();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
IsWarmingUpFeedback.FireUpdate();
|
||||||
|
if (!IsWarmingUpFeedback.BoolValue)
|
||||||
|
(DefaultDisplay as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
|
||||||
|
};
|
||||||
|
disp.IsCoolingDownFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
IsCoolingDownFeedback.FireUpdate();
|
||||||
|
if (IsCoolingDownFeedback.BoolValue)
|
||||||
|
(DefaultDisplay as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceListKey = "default";
|
||||||
|
EnablePowerOnToLastSource = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public override void Shutdown()
|
||||||
|
{
|
||||||
|
RunRouteAction("roomOff");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Routes the default source item, if any
|
||||||
|
/// </summary>
|
||||||
|
public void RunDefaultRoute()
|
||||||
|
{
|
||||||
|
if (DefaultSourceItem != null)
|
||||||
|
RunRouteAction(DefaultSourceItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="routeKey"></param>
|
||||||
|
public void RunRouteAction(string routeKey)
|
||||||
|
{
|
||||||
|
RunRouteAction(routeKey, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a source from config list SourceListKey and dynamically build and executes the
|
||||||
|
/// route or commands
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
public void RunRouteAction(string routeKey, Action successCallback)
|
||||||
|
{
|
||||||
|
// Run this on a separate thread
|
||||||
|
new CTimer(o =>
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Run route action '{0}'", routeKey);
|
||||||
|
var dict = ConfigReader.ConfigObject.GetSourceListForKey(SourceListKey);
|
||||||
|
if(dict == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "WARNING: Config source list '{0}' not found", SourceListKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to get the list item by it's string key
|
||||||
|
if (!dict.ContainsKey(routeKey))
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "WARNING: No item '{0}' found on config list '{1}'",
|
||||||
|
routeKey, SourceListKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var item = dict[routeKey];
|
||||||
|
//Debug.Console(2, this, "Action {0} has {1} steps",
|
||||||
|
// item.SourceKey, item.RouteList.Count);
|
||||||
|
|
||||||
|
// End usage timer on last source
|
||||||
|
if (!string.IsNullOrEmpty(LastSourceKey))
|
||||||
|
{
|
||||||
|
var lastSource = dict[LastSourceKey].SourceDevice;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (lastSource != null && lastSource is IUsageTracking)
|
||||||
|
(lastSource as IUsageTracking).UsageTracker.EndDeviceUsage();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "*#* EXCEPTION in end usage tracking (257):\r{0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let's run it
|
||||||
|
if (routeKey.ToLower() != "roomoff")
|
||||||
|
{
|
||||||
|
LastSourceKey = routeKey;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CurrentSourceInfoKey = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var route in item.RouteList)
|
||||||
|
{
|
||||||
|
// if there is a $defaultAll on route, run two separate
|
||||||
|
if (route.DestinationKey.Equals("$defaultAll", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
// Going to assume a single-path route for now
|
||||||
|
var tempVideo = new SourceRouteListItem
|
||||||
|
{
|
||||||
|
DestinationKey = "$defaultDisplay",
|
||||||
|
SourceKey = route.SourceKey,
|
||||||
|
Type = eRoutingSignalType.Video
|
||||||
|
};
|
||||||
|
DoRoute(tempVideo);
|
||||||
|
|
||||||
|
//var tempAudio = new SourceRouteListItem
|
||||||
|
//{
|
||||||
|
// DestinationKey = "$defaultAudio",
|
||||||
|
// SourceKey = route.SourceKey,
|
||||||
|
// Type = eRoutingSignalType.Audio
|
||||||
|
//};
|
||||||
|
//DoRoute(tempAudio);
|
||||||
|
//continue; -- not sure why this was here
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DoRoute(route);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start usage timer on routed source
|
||||||
|
if (item.SourceDevice is IUsageTracking)
|
||||||
|
{
|
||||||
|
(item.SourceDevice as IUsageTracking).UsageTracker.StartDeviceUsage();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Set volume control on room, using default if non provided
|
||||||
|
IBasicVolumeControls volDev = null;
|
||||||
|
// Handle special cases for volume control
|
||||||
|
if (string.IsNullOrEmpty(item.VolumeControlKey)
|
||||||
|
|| item.VolumeControlKey.Equals("$defaultAudio", StringComparison.OrdinalIgnoreCase))
|
||||||
|
volDev = DefaultVolumeControls;
|
||||||
|
else if (item.VolumeControlKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
|
||||||
|
volDev = DefaultDisplay as IBasicVolumeControls;
|
||||||
|
// Or a specific device, probably rarely used.
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var dev = DeviceManager.GetDeviceForKey(item.VolumeControlKey);
|
||||||
|
if (dev is IBasicVolumeControls)
|
||||||
|
volDev = dev as IBasicVolumeControls;
|
||||||
|
else if (dev is IHasVolumeDevice)
|
||||||
|
volDev = (dev as IHasVolumeDevice).VolumeDevice;
|
||||||
|
}
|
||||||
|
CurrentVolumeControls = volDev;
|
||||||
|
|
||||||
|
// store the name and UI info for routes
|
||||||
|
if (item.SourceKey == "$off")
|
||||||
|
{
|
||||||
|
CurrentSourceInfoKey = routeKey;
|
||||||
|
CurrentSourceInfo = null;
|
||||||
|
}
|
||||||
|
else if (item.SourceKey != null)
|
||||||
|
{
|
||||||
|
CurrentSourceInfoKey = routeKey;
|
||||||
|
CurrentSourceInfo = item;
|
||||||
|
}
|
||||||
|
// And finally, set the "control". This will trigger event
|
||||||
|
//CurrentControlDevice = DeviceManager.GetDeviceForKey(item.SourceKey) as Device;
|
||||||
|
|
||||||
|
OnFeedback.FireUpdate();
|
||||||
|
|
||||||
|
// report back when done
|
||||||
|
if (successCallback != null)
|
||||||
|
successCallback();
|
||||||
|
|
||||||
|
}, 0); // end of CTimer
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Will power the room on with the last-used source
|
||||||
|
/// </summary>
|
||||||
|
public void PowerOnToDefaultOrLastSource()
|
||||||
|
{
|
||||||
|
if (!EnablePowerOnToLastSource || LastSourceKey == null)
|
||||||
|
return;
|
||||||
|
RunRouteAction(LastSourceKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Does what it says
|
||||||
|
/// </summary>
|
||||||
|
public override void SetDefaultLevels()
|
||||||
|
{
|
||||||
|
Debug.Console(0, this, "SetDefaultLevels not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="route"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool DoRoute(SourceRouteListItem route)
|
||||||
|
{
|
||||||
|
IRoutingSinkNoSwitching dest = null;
|
||||||
|
|
||||||
|
if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase))
|
||||||
|
dest = DefaultAudioDevice;
|
||||||
|
else if (route.DestinationKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
|
||||||
|
dest = DefaultDisplay;
|
||||||
|
else
|
||||||
|
dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSinkNoSwitching;
|
||||||
|
|
||||||
|
if (dest == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Cannot route, unknown destination '{0}'", route.DestinationKey);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
dest.ReleaseRoute();
|
||||||
|
if (dest is IPower)
|
||||||
|
(dest as IPower).PowerOff();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var source = DeviceManager.GetDeviceForKey(route.SourceKey) as IRoutingOutputs;
|
||||||
|
if (source == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Cannot route unknown source '{0}' to {1}", route.SourceKey, route.DestinationKey);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
dest.ReleaseAndMakeRoute(source, route.Type);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
=======
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Room.Config;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials
|
||||||
|
{
|
||||||
|
public class EssentialsHuddleSpaceRoom : EssentialsRoomBase, IHasCurrentSourceInfoChange
|
||||||
|
{
|
||||||
|
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
||||||
|
public event SourceInfoChangeHandler CurrentSingleSourceChange;
|
||||||
|
|
||||||
|
protected override Func<bool> OnFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
var val = CurrentSourceInfo != null
|
||||||
|
&& CurrentSourceInfo.Type == eSourceListItemType.Route
|
||||||
|
&& disp != null
|
||||||
|
&& disp.PowerIsOnFeedback.BoolValue;
|
||||||
|
return val;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override Func<bool> IsWarmingFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
if (disp != null)
|
||||||
|
return disp.IsWarmingUpFeedback.BoolValue;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override Func<bool> IsCoolingFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
if (disp != null)
|
||||||
|
return disp.IsCoolingDownFeedback.BoolValue;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public EssentialsRoomPropertiesConfig Config { get; private set; }
|
||||||
|
|
||||||
|
public IRoutingSinkWithSwitching DefaultDisplay { get; private set; }
|
||||||
|
public IRoutingSinkNoSwitching DefaultAudioDevice { get; private set; }
|
||||||
|
public IBasicVolumeControls DefaultVolumeControls { get; private set; }
|
||||||
|
|
||||||
|
public bool ExcludeFromGlobalFunctions { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The config name of the source list
|
||||||
|
/// </summary>
|
||||||
|
public string SourceListKey { get; set; }
|
||||||
|
|
||||||
|
public string DefaultSourceItem { get; set; }
|
||||||
|
|
||||||
|
public ushort DefaultVolume { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If room is off, enables power on to last source. Default true
|
||||||
|
/// </summary>
|
||||||
|
public bool EnablePowerOnToLastSource { get; set; }
|
||||||
|
string LastSourceKey;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public IBasicVolumeControls CurrentVolumeControls
|
||||||
|
{
|
||||||
|
get { return _CurrentAudioDevice; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == _CurrentAudioDevice) return;
|
||||||
|
|
||||||
|
var oldDev = _CurrentAudioDevice;
|
||||||
|
// derigister this room from the device, if it can
|
||||||
|
if (oldDev is IInUseTracking)
|
||||||
|
(oldDev as IInUseTracking).InUseTracker.RemoveUser(this, "audio");
|
||||||
|
var handler = CurrentVolumeDeviceChange;
|
||||||
|
if (handler != null)
|
||||||
|
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.WillChange));
|
||||||
|
_CurrentAudioDevice = value;
|
||||||
|
if (handler != null)
|
||||||
|
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.DidChange));
|
||||||
|
// register this room with new device, if it can
|
||||||
|
if (_CurrentAudioDevice is IInUseTracking)
|
||||||
|
(_CurrentAudioDevice as IInUseTracking).InUseTracker.AddUser(this, "audio");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IBasicVolumeControls _CurrentAudioDevice;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The SourceListItem last run - containing names and icons
|
||||||
|
/// </summary>
|
||||||
|
public SourceListItem CurrentSourceInfo
|
||||||
|
{
|
||||||
|
get { return _CurrentSourceInfo; }
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
if (value == _CurrentSourceInfo) return;
|
||||||
|
|
||||||
|
var handler = CurrentSingleSourceChange;
|
||||||
|
// remove from in-use tracker, if so equipped
|
||||||
|
if(_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||||
|
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.RemoveUser(this, "control");
|
||||||
|
|
||||||
|
if (handler != null)
|
||||||
|
handler(this, _CurrentSourceInfo, ChangeType.WillChange);
|
||||||
|
|
||||||
|
_CurrentSourceInfo = value;
|
||||||
|
|
||||||
|
// add to in-use tracking
|
||||||
|
if (_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||||
|
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control");
|
||||||
|
if (handler != null)
|
||||||
|
handler(this, _CurrentSourceInfo, ChangeType.DidChange);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SourceListItem _CurrentSourceInfo;
|
||||||
|
|
||||||
|
public string CurrentSourceInfoKey { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
public EssentialsHuddleSpaceRoom(string key, string name, IRoutingSinkWithSwitching defaultDisplay,
|
||||||
|
IRoutingSinkNoSwitching defaultAudio, EssentialsRoomPropertiesConfig config)
|
||||||
|
: base(key, name)
|
||||||
|
{
|
||||||
|
Config = config;
|
||||||
|
DefaultDisplay = defaultDisplay;
|
||||||
|
DefaultAudioDevice = defaultAudio;
|
||||||
|
if (defaultAudio is IBasicVolumeControls)
|
||||||
|
DefaultVolumeControls = defaultAudio as IBasicVolumeControls;
|
||||||
|
else if (defaultAudio is IHasVolumeDevice)
|
||||||
|
DefaultVolumeControls = (defaultAudio as IHasVolumeDevice).VolumeDevice;
|
||||||
|
CurrentVolumeControls = DefaultVolumeControls;
|
||||||
|
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
if (disp != null)
|
||||||
|
{
|
||||||
|
// Link power, warming, cooling to display
|
||||||
|
disp.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
if (disp.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
|
||||||
|
{
|
||||||
|
if (!disp.PowerIsOnFeedback.BoolValue)
|
||||||
|
CurrentSourceInfo = null;
|
||||||
|
OnFeedback.FireUpdate();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
IsWarmingUpFeedback.FireUpdate();
|
||||||
|
if (!IsWarmingUpFeedback.BoolValue)
|
||||||
|
(DefaultDisplay as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
|
||||||
|
};
|
||||||
|
disp.IsCoolingDownFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
IsCoolingDownFeedback.FireUpdate();
|
||||||
|
if (IsCoolingDownFeedback.BoolValue)
|
||||||
|
(DefaultDisplay as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceListKey = "default";
|
||||||
|
EnablePowerOnToLastSource = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override void EndShutdown()
|
||||||
|
{
|
||||||
|
RunRouteAction("roomOff");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Routes the default source item, if any
|
||||||
|
/// </summary>
|
||||||
|
public void RunDefaultRoute()
|
||||||
|
{
|
||||||
|
if (DefaultSourceItem != null)
|
||||||
|
RunRouteAction(DefaultSourceItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="routeKey"></param>
|
||||||
|
public void RunRouteAction(string routeKey)
|
||||||
|
{
|
||||||
|
RunRouteAction(routeKey, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a source from config list SourceListKey and dynamically build and executes the
|
||||||
|
/// route or commands
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
public void RunRouteAction(string routeKey, Action successCallback)
|
||||||
|
{
|
||||||
|
// Run this on a separate thread
|
||||||
|
new CTimer(o =>
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Run route action '{0}'", routeKey);
|
||||||
|
var dict = ConfigReader.ConfigObject.GetSourceListForKey(SourceListKey);
|
||||||
|
if(dict == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "WARNING: Config source list '{0}' not found", SourceListKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to get the list item by it's string key
|
||||||
|
if (!dict.ContainsKey(routeKey))
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "WARNING: No item '{0}' found on config list '{1}'",
|
||||||
|
routeKey, SourceListKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var item = dict[routeKey];
|
||||||
|
//Debug.Console(2, this, "Action {0} has {1} steps",
|
||||||
|
// item.SourceKey, item.RouteList.Count);
|
||||||
|
|
||||||
|
// End usage timer on last source
|
||||||
|
if (!string.IsNullOrEmpty(LastSourceKey))
|
||||||
|
{
|
||||||
|
var lastSource = dict[LastSourceKey].SourceDevice;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (lastSource != null && lastSource is IUsageTracking)
|
||||||
|
(lastSource as IUsageTracking).UsageTracker.EndDeviceUsage();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "*#* EXCEPTION in end usage tracking (257):\r{0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let's run it
|
||||||
|
if (routeKey.ToLower() != "roomoff")
|
||||||
|
{
|
||||||
|
LastSourceKey = routeKey;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CurrentSourceInfoKey = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var route in item.RouteList)
|
||||||
|
{
|
||||||
|
// if there is a $defaultAll on route, run two separate
|
||||||
|
if (route.DestinationKey.Equals("$defaultAll", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
// Going to assume a single-path route for now
|
||||||
|
var tempVideo = new SourceRouteListItem
|
||||||
|
{
|
||||||
|
DestinationKey = "$defaultDisplay",
|
||||||
|
SourceKey = route.SourceKey,
|
||||||
|
Type = eRoutingSignalType.Video
|
||||||
|
};
|
||||||
|
DoRoute(tempVideo);
|
||||||
|
|
||||||
|
//var tempAudio = new SourceRouteListItem
|
||||||
|
//{
|
||||||
|
// DestinationKey = "$defaultAudio",
|
||||||
|
// SourceKey = route.SourceKey,
|
||||||
|
// Type = eRoutingSignalType.Audio
|
||||||
|
//};
|
||||||
|
//DoRoute(tempAudio);
|
||||||
|
//continue; -- not sure why this was here
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DoRoute(route);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start usage timer on routed source
|
||||||
|
if (item.SourceDevice is IUsageTracking)
|
||||||
|
{
|
||||||
|
(item.SourceDevice as IUsageTracking).UsageTracker.StartDeviceUsage();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Set volume control on room, using default if non provided
|
||||||
|
IBasicVolumeControls volDev = null;
|
||||||
|
// Handle special cases for volume control
|
||||||
|
if (string.IsNullOrEmpty(item.VolumeControlKey)
|
||||||
|
|| item.VolumeControlKey.Equals("$defaultAudio", StringComparison.OrdinalIgnoreCase))
|
||||||
|
volDev = DefaultVolumeControls;
|
||||||
|
else if (item.VolumeControlKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
|
||||||
|
volDev = DefaultDisplay as IBasicVolumeControls;
|
||||||
|
// Or a specific device, probably rarely used.
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var dev = DeviceManager.GetDeviceForKey(item.VolumeControlKey);
|
||||||
|
if (dev is IBasicVolumeControls)
|
||||||
|
volDev = dev as IBasicVolumeControls;
|
||||||
|
else if (dev is IHasVolumeDevice)
|
||||||
|
volDev = (dev as IHasVolumeDevice).VolumeDevice;
|
||||||
|
}
|
||||||
|
CurrentVolumeControls = volDev;
|
||||||
|
|
||||||
|
// store the name and UI info for routes
|
||||||
|
if (item.SourceKey == "$off")
|
||||||
|
{
|
||||||
|
CurrentSourceInfoKey = routeKey;
|
||||||
|
CurrentSourceInfo = null;
|
||||||
|
}
|
||||||
|
else if (item.SourceKey != null)
|
||||||
|
{
|
||||||
|
CurrentSourceInfoKey = routeKey;
|
||||||
|
CurrentSourceInfo = item;
|
||||||
|
}
|
||||||
|
// And finally, set the "control". This will trigger event
|
||||||
|
//CurrentControlDevice = DeviceManager.GetDeviceForKey(item.SourceKey) as Device;
|
||||||
|
|
||||||
|
OnFeedback.FireUpdate();
|
||||||
|
|
||||||
|
// report back when done
|
||||||
|
if (successCallback != null)
|
||||||
|
successCallback();
|
||||||
|
|
||||||
|
}, 0); // end of CTimer
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Will power the room on with the last-used source
|
||||||
|
/// </summary>
|
||||||
|
public void PowerOnToDefaultOrLastSource()
|
||||||
|
{
|
||||||
|
if (!EnablePowerOnToLastSource || LastSourceKey == null)
|
||||||
|
return;
|
||||||
|
RunRouteAction(LastSourceKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Does what it says
|
||||||
|
/// </summary>
|
||||||
|
public override void SetDefaultLevels()
|
||||||
|
{
|
||||||
|
Debug.Console(0, this, "SetDefaultLevels not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="route"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool DoRoute(SourceRouteListItem route)
|
||||||
|
{
|
||||||
|
IRoutingSinkNoSwitching dest = null;
|
||||||
|
|
||||||
|
if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase))
|
||||||
|
dest = DefaultAudioDevice;
|
||||||
|
else if (route.DestinationKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
|
||||||
|
dest = DefaultDisplay;
|
||||||
|
else
|
||||||
|
dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSinkNoSwitching;
|
||||||
|
|
||||||
|
if (dest == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Cannot route, unknown destination '{0}'", route.DestinationKey);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
dest.ReleaseRoute();
|
||||||
|
if (dest is IPower)
|
||||||
|
(dest as IPower).PowerOff();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var source = DeviceManager.GetDeviceForKey(route.SourceKey) as IRoutingOutputs;
|
||||||
|
if (source == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Cannot route unknown source '{0}' to {1}", route.SourceKey, route.DestinationKey);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
dest.ReleaseAndMakeRoute(source, route.Type);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
>>>>>>> origin/feature/ecs-342
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void RoomVacatedForTimeoutPeriod(object o)
|
||||||
|
{
|
||||||
|
//Implement this
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Runs "roomOff" action on all rooms not set to ExcludeFromGlobalFunctions
|
||||||
|
/// </summary>
|
||||||
|
public static void AllRoomsOff()
|
||||||
|
{
|
||||||
|
var allRooms = DeviceManager.AllDevices.Where(d =>
|
||||||
|
d is EssentialsHuddleSpaceRoom && !(d as EssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions);
|
||||||
|
foreach (var room in allRooms)
|
||||||
|
(room as EssentialsHuddleSpaceRoom).RunRouteAction("roomOff");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,967 @@
|
|||||||
|
<<<<<<< HEAD
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Room.Config;
|
||||||
|
using PepperDash.Essentials.Devices.Common.Codec;
|
||||||
|
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials
|
||||||
|
{
|
||||||
|
public class EssentialsHuddleVtc1Room : EssentialsRoomBase, IHasCurrentSourceInfoChange, IPrivacy
|
||||||
|
{
|
||||||
|
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
||||||
|
public event SourceInfoChangeHandler CurrentSingleSourceChange;
|
||||||
|
|
||||||
|
|
||||||
|
//************************
|
||||||
|
// Call-related stuff
|
||||||
|
|
||||||
|
public BoolFeedback InCallFeedback { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Make this more specific
|
||||||
|
/// </summary>
|
||||||
|
public List<CodecActiveCallItem> ActiveCalls { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// States: 0 for on hook, 1 for video, 2 for audio, 3 for telekenesis
|
||||||
|
/// </summary>
|
||||||
|
public IntFeedback CallTypeFeedback { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public BoolFeedback PrivacyModeIsOnFeedback { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When something in the room is sharing with the far end or through other means
|
||||||
|
/// </summary>
|
||||||
|
public BoolFeedback IsSharingFeedback { get; private set; }
|
||||||
|
|
||||||
|
//************************
|
||||||
|
|
||||||
|
|
||||||
|
protected override Func<bool> OnFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
var val = CurrentSourceInfo != null
|
||||||
|
&& CurrentSourceInfo.Type == eSourceListItemType.Route
|
||||||
|
&& disp != null
|
||||||
|
&& disp.PowerIsOnFeedback.BoolValue;
|
||||||
|
return val;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override Func<bool> IsWarmingFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
if (disp != null)
|
||||||
|
return disp.IsWarmingUpFeedback.BoolValue;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override Func<bool> IsCoolingFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
if (disp != null)
|
||||||
|
return disp.IsCoolingDownFeedback.BoolValue;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public EssentialsHuddleVtc1PropertiesConfig Config { get; private set; }
|
||||||
|
|
||||||
|
public IRoutingSinkWithSwitching DefaultDisplay { get; private set; }
|
||||||
|
public IBasicVolumeControls DefaultAudioDevice { get; private set; }
|
||||||
|
public IBasicVolumeControls DefaultVolumeControls { get; private set; }
|
||||||
|
|
||||||
|
public VideoCodecBase VideoCodec { get; private set; }
|
||||||
|
|
||||||
|
public bool ExcludeFromGlobalFunctions { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The config name of the source list
|
||||||
|
/// </summary>
|
||||||
|
public string SourceListKey { get; set; }
|
||||||
|
|
||||||
|
public string DefaultSourceItem { get; set; }
|
||||||
|
|
||||||
|
public ushort DefaultVolume { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If room is off, enables power on to last source. Default true
|
||||||
|
/// </summary>
|
||||||
|
public bool EnablePowerOnToLastSource { get; set; }
|
||||||
|
string LastSourceKey;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public IBasicVolumeControls CurrentVolumeControls
|
||||||
|
{
|
||||||
|
get { return _CurrentAudioDevice; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == _CurrentAudioDevice) return;
|
||||||
|
|
||||||
|
var oldDev = _CurrentAudioDevice;
|
||||||
|
// derigister this room from the device, if it can
|
||||||
|
if (oldDev is IInUseTracking)
|
||||||
|
(oldDev as IInUseTracking).InUseTracker.RemoveUser(this, "audio");
|
||||||
|
var handler = CurrentVolumeDeviceChange;
|
||||||
|
if (handler != null)
|
||||||
|
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.WillChange));
|
||||||
|
_CurrentAudioDevice = value;
|
||||||
|
if (handler != null)
|
||||||
|
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.DidChange));
|
||||||
|
// register this room with new device, if it can
|
||||||
|
if (_CurrentAudioDevice is IInUseTracking)
|
||||||
|
(_CurrentAudioDevice as IInUseTracking).InUseTracker.AddUser(this, "audio");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IBasicVolumeControls _CurrentAudioDevice;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The SourceListItem last run - containing names and icons
|
||||||
|
/// </summary>
|
||||||
|
public SourceListItem CurrentSourceInfo
|
||||||
|
{
|
||||||
|
get { return _CurrentSourceInfo; }
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
if (value == _CurrentSourceInfo) return;
|
||||||
|
|
||||||
|
var handler = CurrentSingleSourceChange;
|
||||||
|
// remove from in-use tracker, if so equipped
|
||||||
|
if(_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||||
|
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.RemoveUser(this, "control");
|
||||||
|
|
||||||
|
if (handler != null)
|
||||||
|
handler(this, _CurrentSourceInfo, ChangeType.WillChange);
|
||||||
|
|
||||||
|
_CurrentSourceInfo = value;
|
||||||
|
|
||||||
|
// add to in-use tracking
|
||||||
|
if (_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||||
|
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control");
|
||||||
|
if (handler != null)
|
||||||
|
handler(this, _CurrentSourceInfo, ChangeType.DidChange);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SourceListItem _CurrentSourceInfo;
|
||||||
|
|
||||||
|
public string CurrentSourceInfoKey { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "codecOsd"
|
||||||
|
/// </summary>
|
||||||
|
public string DefaultCodecRouteString { get { return "codecOsd"; } }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Temporary implementation. Returns the schedule-ready object or null if none. Fow now,
|
||||||
|
/// always returns the VideoCodec if it is capable
|
||||||
|
/// </summary>
|
||||||
|
public IHasScheduleAwareness ScheduleSource { get { return VideoCodec as IHasScheduleAwareness; } }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
public EssentialsHuddleVtc1Room(string key, string name, IRoutingSinkWithSwitching defaultDisplay,
|
||||||
|
IBasicVolumeControls defaultAudio, VideoCodecBase codec, EssentialsHuddleVtc1PropertiesConfig config)
|
||||||
|
: base(key, name)
|
||||||
|
{
|
||||||
|
if (codec == null)
|
||||||
|
throw new ArgumentNullException("codec cannot be null");
|
||||||
|
Config = config;
|
||||||
|
DefaultDisplay = defaultDisplay;
|
||||||
|
VideoCodec = codec;
|
||||||
|
DefaultAudioDevice = defaultAudio;
|
||||||
|
|
||||||
|
if (defaultAudio is IBasicVolumeControls)
|
||||||
|
DefaultVolumeControls = defaultAudio as IBasicVolumeControls;
|
||||||
|
else if (defaultAudio is IHasVolumeDevice)
|
||||||
|
DefaultVolumeControls = (defaultAudio as IHasVolumeDevice).VolumeDevice;
|
||||||
|
CurrentVolumeControls = DefaultVolumeControls;
|
||||||
|
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
if (disp != null)
|
||||||
|
{
|
||||||
|
// Link power, warming, cooling to display
|
||||||
|
disp.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
if (disp.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
|
||||||
|
{
|
||||||
|
if (!disp.PowerIsOnFeedback.BoolValue)
|
||||||
|
CurrentSourceInfo = null;
|
||||||
|
OnFeedback.FireUpdate();
|
||||||
|
}
|
||||||
|
if (disp.PowerIsOnFeedback.BoolValue)
|
||||||
|
{
|
||||||
|
SetDefaultLevels();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
IsWarmingUpFeedback.FireUpdate();
|
||||||
|
if (!IsWarmingUpFeedback.BoolValue)
|
||||||
|
(DefaultDisplay as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
|
||||||
|
};
|
||||||
|
disp.IsCoolingDownFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
IsCoolingDownFeedback.FireUpdate();
|
||||||
|
if (IsCoolingDownFeedback.BoolValue)
|
||||||
|
(DefaultDisplay as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
InCallFeedback = new BoolFeedback(() => VideoCodec.IsInCall);
|
||||||
|
IsSharingFeedback = new BoolFeedback(() => VideoCodec.SharingSourceFeedback.StringValue != null);
|
||||||
|
|
||||||
|
// link privacy to VC (for now?)
|
||||||
|
PrivacyModeIsOnFeedback = new BoolFeedback(() => VideoCodec.PrivacyModeIsOnFeedback.BoolValue);
|
||||||
|
VideoCodec.PrivacyModeIsOnFeedback.OutputChange += (o, a) => this.PrivacyModeIsOnFeedback.FireUpdate();
|
||||||
|
|
||||||
|
CallTypeFeedback = new IntFeedback(() => 0);
|
||||||
|
|
||||||
|
SourceListKey = "default";
|
||||||
|
EnablePowerOnToLastSource = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public override void Shutdown()
|
||||||
|
{
|
||||||
|
RunRouteAction("roomOff");
|
||||||
|
VideoCodec.EndAllCalls();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Routes the default source item, if any. Returns true when default route exists
|
||||||
|
/// </summary>
|
||||||
|
public bool RunDefaultPresentRoute()
|
||||||
|
{
|
||||||
|
if (DefaultSourceItem != null)
|
||||||
|
RunRouteAction(DefaultSourceItem);
|
||||||
|
return DefaultSourceItem != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets up the room when started into call mode without presenting a source
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool RunDefaultCallRoute()
|
||||||
|
{
|
||||||
|
RunRouteAction(DefaultCodecRouteString);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="routeKey"></param>
|
||||||
|
public void RunRouteAction(string routeKey)
|
||||||
|
{
|
||||||
|
RunRouteAction(routeKey, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a source from config list SourceListKey and dynamically build and executes the
|
||||||
|
/// route or commands
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
public void RunRouteAction(string routeKey, Action successCallback)
|
||||||
|
{
|
||||||
|
// Run this on a separate thread
|
||||||
|
new CTimer(o =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
Debug.Console(1, this, "Run route action '{0}'", routeKey);
|
||||||
|
var dict = ConfigReader.ConfigObject.GetSourceListForKey(SourceListKey);
|
||||||
|
if (dict == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "WARNING: Config source list '{0}' not found", SourceListKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to get the list item by it's string key
|
||||||
|
if (!dict.ContainsKey(routeKey))
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "WARNING: No item '{0}' found on config list '{1}'",
|
||||||
|
routeKey, SourceListKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// End usage timer on last source
|
||||||
|
if (!string.IsNullOrEmpty(LastSourceKey))
|
||||||
|
{
|
||||||
|
var usageLastSource = dict[LastSourceKey].SourceDevice as IUsageTracking;
|
||||||
|
if (usageLastSource != null && usageLastSource.UsageTracker != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// There MAY have been failures in here. Protect
|
||||||
|
usageLastSource.UsageTracker.EndDeviceUsage();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let's run it
|
||||||
|
var item = dict[routeKey];
|
||||||
|
if (routeKey.ToLower() != "roomoff")
|
||||||
|
{
|
||||||
|
|
||||||
|
LastSourceKey = routeKey;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CurrentSourceInfoKey = null;
|
||||||
|
|
||||||
|
// hand off the individual routes to this helper
|
||||||
|
foreach (var route in item.RouteList)
|
||||||
|
DoRouteItem(route);
|
||||||
|
|
||||||
|
// Start usage timer on routed source
|
||||||
|
var usageNewSource = item.SourceDevice as IUsageTracking;
|
||||||
|
if (usageNewSource != null && usageNewSource.UsageTracker != null) // Have to make sure there is a usage tracker!
|
||||||
|
{
|
||||||
|
(item.SourceDevice as IUsageTracking).UsageTracker.StartDeviceUsage();
|
||||||
|
}
|
||||||
|
|
||||||
|
// store the name and UI info for routes
|
||||||
|
if (item.SourceKey == "$off")
|
||||||
|
{
|
||||||
|
CurrentSourceInfoKey = routeKey;
|
||||||
|
CurrentSourceInfo = null;
|
||||||
|
}
|
||||||
|
else if (item.SourceKey != null)
|
||||||
|
{
|
||||||
|
CurrentSourceInfoKey = routeKey;
|
||||||
|
CurrentSourceInfo = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
OnFeedback.FireUpdate();
|
||||||
|
|
||||||
|
// report back when done
|
||||||
|
if (successCallback != null)
|
||||||
|
successCallback();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "ERROR in routing: {0}", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}, 0); // end of CTimer
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="route"></param>
|
||||||
|
void DoRouteItem(SourceRouteListItem route)
|
||||||
|
{
|
||||||
|
// if there is a $defaultAll on route, run two separate
|
||||||
|
if (route.DestinationKey.Equals("$defaultAll", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
// Going to assume a single-path route for now
|
||||||
|
var tempVideo = new SourceRouteListItem
|
||||||
|
{
|
||||||
|
DestinationKey = "$defaultDisplay",
|
||||||
|
SourceKey = route.SourceKey,
|
||||||
|
Type = eRoutingSignalType.Video
|
||||||
|
};
|
||||||
|
DoRoute(tempVideo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DoRoute(route);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="route"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool DoRoute(SourceRouteListItem route)
|
||||||
|
{
|
||||||
|
IRoutingSinkNoSwitching dest = null;
|
||||||
|
|
||||||
|
if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase))
|
||||||
|
dest = DefaultAudioDevice as IRoutingSinkNoSwitching;
|
||||||
|
else if (route.DestinationKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
|
||||||
|
dest = DefaultDisplay;
|
||||||
|
else
|
||||||
|
dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSinkNoSwitching;
|
||||||
|
|
||||||
|
if (dest == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Cannot route, unknown destination '{0}'", route.DestinationKey);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
dest.ReleaseRoute();
|
||||||
|
if (dest is IPower)
|
||||||
|
(dest as IPower).PowerOff();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var source = DeviceManager.GetDeviceForKey(route.SourceKey) as IRoutingOutputs;
|
||||||
|
if (source == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Cannot route unknown source '{0}' to {1}", route.SourceKey, route.DestinationKey);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
dest.ReleaseAndMakeRoute(source, route.Type);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
=======
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
|
||||||
|
using PepperDash.Core;
|
||||||
|
using PepperDash.Essentials.Core;
|
||||||
|
using PepperDash.Essentials.Room.Config;
|
||||||
|
using PepperDash.Essentials.Devices.Common.Codec;
|
||||||
|
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials
|
||||||
|
{
|
||||||
|
public class EssentialsHuddleVtc1Room : EssentialsRoomBase, IHasCurrentSourceInfoChange, IPrivacy
|
||||||
|
{
|
||||||
|
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
||||||
|
public event SourceInfoChangeHandler CurrentSingleSourceChange;
|
||||||
|
|
||||||
|
|
||||||
|
//************************
|
||||||
|
// Call-related stuff
|
||||||
|
|
||||||
|
public BoolFeedback InCallFeedback { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Make this more specific
|
||||||
|
/// </summary>
|
||||||
|
public List<CodecActiveCallItem> ActiveCalls { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// States: 0 for on hook, 1 for video, 2 for audio, 3 for telekenesis
|
||||||
|
/// </summary>
|
||||||
|
public IntFeedback CallTypeFeedback { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public BoolFeedback PrivacyModeIsOnFeedback { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When something in the room is sharing with the far end or through other means
|
||||||
|
/// </summary>
|
||||||
|
public BoolFeedback IsSharingFeedback { get; private set; }
|
||||||
|
|
||||||
|
//************************
|
||||||
|
|
||||||
|
|
||||||
|
protected override Func<bool> OnFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
var val = CurrentSourceInfo != null
|
||||||
|
&& CurrentSourceInfo.Type == eSourceListItemType.Route
|
||||||
|
&& disp != null
|
||||||
|
&& disp.PowerIsOnFeedback.BoolValue;
|
||||||
|
return val;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override Func<bool> IsWarmingFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
if (disp != null)
|
||||||
|
return disp.IsWarmingUpFeedback.BoolValue;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override Func<bool> IsCoolingFeedbackFunc
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
if (disp != null)
|
||||||
|
return disp.IsCoolingDownFeedback.BoolValue;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public EssentialsHuddleVtc1PropertiesConfig Config { get; private set; }
|
||||||
|
|
||||||
|
public IRoutingSinkWithSwitching DefaultDisplay { get; private set; }
|
||||||
|
public IBasicVolumeControls DefaultAudioDevice { get; private set; }
|
||||||
|
public IBasicVolumeControls DefaultVolumeControls { get; private set; }
|
||||||
|
|
||||||
|
public VideoCodecBase VideoCodec { get; private set; }
|
||||||
|
|
||||||
|
public bool ExcludeFromGlobalFunctions { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The config name of the source list
|
||||||
|
/// </summary>
|
||||||
|
public string SourceListKey { get; set; }
|
||||||
|
|
||||||
|
public string DefaultSourceItem { get; set; }
|
||||||
|
|
||||||
|
public ushort DefaultVolume { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If room is off, enables power on to last source. Default true
|
||||||
|
/// </summary>
|
||||||
|
public bool EnablePowerOnToLastSource { get; set; }
|
||||||
|
string LastSourceKey;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public IBasicVolumeControls CurrentVolumeControls
|
||||||
|
{
|
||||||
|
get { return _CurrentAudioDevice; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == _CurrentAudioDevice) return;
|
||||||
|
|
||||||
|
var oldDev = _CurrentAudioDevice;
|
||||||
|
// derigister this room from the device, if it can
|
||||||
|
if (oldDev is IInUseTracking)
|
||||||
|
(oldDev as IInUseTracking).InUseTracker.RemoveUser(this, "audio");
|
||||||
|
var handler = CurrentVolumeDeviceChange;
|
||||||
|
if (handler != null)
|
||||||
|
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.WillChange));
|
||||||
|
_CurrentAudioDevice = value;
|
||||||
|
if (handler != null)
|
||||||
|
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.DidChange));
|
||||||
|
// register this room with new device, if it can
|
||||||
|
if (_CurrentAudioDevice is IInUseTracking)
|
||||||
|
(_CurrentAudioDevice as IInUseTracking).InUseTracker.AddUser(this, "audio");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IBasicVolumeControls _CurrentAudioDevice;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The SourceListItem last run - containing names and icons
|
||||||
|
/// </summary>
|
||||||
|
public SourceListItem CurrentSourceInfo
|
||||||
|
{
|
||||||
|
get { return _CurrentSourceInfo; }
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
if (value == _CurrentSourceInfo) return;
|
||||||
|
|
||||||
|
var handler = CurrentSingleSourceChange;
|
||||||
|
// remove from in-use tracker, if so equipped
|
||||||
|
if(_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||||
|
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.RemoveUser(this, "control");
|
||||||
|
|
||||||
|
if (handler != null)
|
||||||
|
handler(this, _CurrentSourceInfo, ChangeType.WillChange);
|
||||||
|
|
||||||
|
_CurrentSourceInfo = value;
|
||||||
|
|
||||||
|
// add to in-use tracking
|
||||||
|
if (_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||||
|
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control");
|
||||||
|
if (handler != null)
|
||||||
|
handler(this, _CurrentSourceInfo, ChangeType.DidChange);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SourceListItem _CurrentSourceInfo;
|
||||||
|
|
||||||
|
public string CurrentSourceInfoKey { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "codecOsd"
|
||||||
|
/// </summary>
|
||||||
|
public string DefaultCodecRouteString { get { return "codecOsd"; } }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Temporary implementation. Returns the schedule-ready object or null if none. Fow now,
|
||||||
|
/// always returns the VideoCodec if it is capable
|
||||||
|
/// </summary>
|
||||||
|
public IHasScheduleAwareness ScheduleSource { get { return VideoCodec as IHasScheduleAwareness; } }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
public EssentialsHuddleVtc1Room(string key, string name, IRoutingSinkWithSwitching defaultDisplay,
|
||||||
|
IBasicVolumeControls defaultAudio, VideoCodecBase codec, EssentialsHuddleVtc1PropertiesConfig config)
|
||||||
|
: base(key, name)
|
||||||
|
{
|
||||||
|
if (codec == null)
|
||||||
|
throw new ArgumentNullException("codec cannot be null");
|
||||||
|
Config = config;
|
||||||
|
DefaultDisplay = defaultDisplay;
|
||||||
|
VideoCodec = codec;
|
||||||
|
DefaultAudioDevice = defaultAudio;
|
||||||
|
|
||||||
|
if (defaultAudio is IBasicVolumeControls)
|
||||||
|
DefaultVolumeControls = defaultAudio as IBasicVolumeControls;
|
||||||
|
else if (defaultAudio is IHasVolumeDevice)
|
||||||
|
DefaultVolumeControls = (defaultAudio as IHasVolumeDevice).VolumeDevice;
|
||||||
|
CurrentVolumeControls = DefaultVolumeControls;
|
||||||
|
|
||||||
|
var disp = DefaultDisplay as DisplayBase;
|
||||||
|
if (disp != null)
|
||||||
|
{
|
||||||
|
// Link power, warming, cooling to display
|
||||||
|
disp.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
if (disp.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
|
||||||
|
{
|
||||||
|
if (!disp.PowerIsOnFeedback.BoolValue)
|
||||||
|
CurrentSourceInfo = null;
|
||||||
|
OnFeedback.FireUpdate();
|
||||||
|
}
|
||||||
|
if (disp.PowerIsOnFeedback.BoolValue)
|
||||||
|
{
|
||||||
|
SetDefaultLevels();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
IsWarmingUpFeedback.FireUpdate();
|
||||||
|
if (!IsWarmingUpFeedback.BoolValue)
|
||||||
|
(DefaultDisplay as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
|
||||||
|
};
|
||||||
|
disp.IsCoolingDownFeedback.OutputChange += (o, a) =>
|
||||||
|
{
|
||||||
|
IsCoolingDownFeedback.FireUpdate();
|
||||||
|
if (IsCoolingDownFeedback.BoolValue)
|
||||||
|
(DefaultDisplay as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
InCallFeedback = new BoolFeedback(() => VideoCodec.IsInCall);
|
||||||
|
IsSharingFeedback = new BoolFeedback(() => VideoCodec.SharingSourceFeedback.StringValue != null);
|
||||||
|
|
||||||
|
// link privacy to VC (for now?)
|
||||||
|
PrivacyModeIsOnFeedback = new BoolFeedback(() => VideoCodec.PrivacyModeIsOnFeedback.BoolValue);
|
||||||
|
VideoCodec.PrivacyModeIsOnFeedback.OutputChange += (o, a) => this.PrivacyModeIsOnFeedback.FireUpdate();
|
||||||
|
|
||||||
|
CallTypeFeedback = new IntFeedback(() => 0);
|
||||||
|
|
||||||
|
SourceListKey = "default";
|
||||||
|
EnablePowerOnToLastSource = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected override void EndShutdown()
|
||||||
|
{
|
||||||
|
RunRouteAction("roomOff");
|
||||||
|
VideoCodec.EndAllCalls();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Routes the default source item, if any. Returns true when default route exists
|
||||||
|
/// </summary>
|
||||||
|
public bool RunDefaultPresentRoute()
|
||||||
|
{
|
||||||
|
if (DefaultSourceItem != null)
|
||||||
|
RunRouteAction(DefaultSourceItem);
|
||||||
|
return DefaultSourceItem != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets up the room when started into call mode without presenting a source
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool RunDefaultCallRoute()
|
||||||
|
{
|
||||||
|
RunRouteAction(DefaultCodecRouteString);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="routeKey"></param>
|
||||||
|
public void RunRouteAction(string routeKey)
|
||||||
|
{
|
||||||
|
RunRouteAction(routeKey, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a source from config list SourceListKey and dynamically build and executes the
|
||||||
|
/// route or commands
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
public void RunRouteAction(string routeKey, Action successCallback)
|
||||||
|
{
|
||||||
|
// Run this on a separate thread
|
||||||
|
new CTimer(o =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
Debug.Console(1, this, "Run route action '{0}'", routeKey);
|
||||||
|
var dict = ConfigReader.ConfigObject.GetSourceListForKey(SourceListKey);
|
||||||
|
if (dict == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "WARNING: Config source list '{0}' not found", SourceListKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to get the list item by it's string key
|
||||||
|
if (!dict.ContainsKey(routeKey))
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "WARNING: No item '{0}' found on config list '{1}'",
|
||||||
|
routeKey, SourceListKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// End usage timer on last source
|
||||||
|
if (!string.IsNullOrEmpty(LastSourceKey))
|
||||||
|
{
|
||||||
|
var usageLastSource = dict[LastSourceKey].SourceDevice as IUsageTracking;
|
||||||
|
if (usageLastSource != null && usageLastSource.UsageTracker != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// There MAY have been failures in here. Protect
|
||||||
|
usageLastSource.UsageTracker.EndDeviceUsage();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "*#* EXCEPTION in end usage tracking:\r{0}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let's run it
|
||||||
|
var item = dict[routeKey];
|
||||||
|
if (routeKey.ToLower() != "roomoff")
|
||||||
|
{
|
||||||
|
|
||||||
|
LastSourceKey = routeKey;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CurrentSourceInfoKey = null;
|
||||||
|
|
||||||
|
// hand off the individual routes to this helper
|
||||||
|
foreach (var route in item.RouteList)
|
||||||
|
DoRouteItem(route);
|
||||||
|
|
||||||
|
// Start usage timer on routed source
|
||||||
|
var usageNewSource = item.SourceDevice as IUsageTracking;
|
||||||
|
if (usageNewSource != null && usageNewSource.UsageTracker != null) // Have to make sure there is a usage tracker!
|
||||||
|
{
|
||||||
|
(item.SourceDevice as IUsageTracking).UsageTracker.StartDeviceUsage();
|
||||||
|
}
|
||||||
|
|
||||||
|
// store the name and UI info for routes
|
||||||
|
if (item.SourceKey == "$off")
|
||||||
|
{
|
||||||
|
CurrentSourceInfoKey = routeKey;
|
||||||
|
CurrentSourceInfo = null;
|
||||||
|
}
|
||||||
|
else if (item.SourceKey != null)
|
||||||
|
{
|
||||||
|
CurrentSourceInfoKey = routeKey;
|
||||||
|
CurrentSourceInfo = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
OnFeedback.FireUpdate();
|
||||||
|
|
||||||
|
// report back when done
|
||||||
|
if (successCallback != null)
|
||||||
|
successCallback();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "ERROR in routing: {0}", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}, 0); // end of CTimer
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="route"></param>
|
||||||
|
void DoRouteItem(SourceRouteListItem route)
|
||||||
|
{
|
||||||
|
// if there is a $defaultAll on route, run two separate
|
||||||
|
if (route.DestinationKey.Equals("$defaultAll", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
// Going to assume a single-path route for now
|
||||||
|
var tempVideo = new SourceRouteListItem
|
||||||
|
{
|
||||||
|
DestinationKey = "$defaultDisplay",
|
||||||
|
SourceKey = route.SourceKey,
|
||||||
|
Type = eRoutingSignalType.Video
|
||||||
|
};
|
||||||
|
DoRoute(tempVideo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DoRoute(route);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="route"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
bool DoRoute(SourceRouteListItem route)
|
||||||
|
{
|
||||||
|
IRoutingSinkNoSwitching dest = null;
|
||||||
|
|
||||||
|
if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase))
|
||||||
|
dest = DefaultAudioDevice as IRoutingSinkNoSwitching;
|
||||||
|
else if (route.DestinationKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
|
||||||
|
dest = DefaultDisplay;
|
||||||
|
else
|
||||||
|
dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSinkNoSwitching;
|
||||||
|
|
||||||
|
if (dest == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Cannot route, unknown destination '{0}'", route.DestinationKey);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
dest.ReleaseRoute();
|
||||||
|
if (dest is IPower)
|
||||||
|
(dest as IPower).PowerOff();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var source = DeviceManager.GetDeviceForKey(route.SourceKey) as IRoutingOutputs;
|
||||||
|
if (source == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Cannot route unknown source '{0}' to {1}", route.SourceKey, route.DestinationKey);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
dest.ReleaseAndMakeRoute(source, route.Type);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
>>>>>>> origin/feature/ecs-342
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void RoomVacatedForTimeoutPeriod(object o)
|
||||||
|
{
|
||||||
|
//Implement this
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Does what it says
|
||||||
|
/// </summary>
|
||||||
|
public override void SetDefaultLevels()
|
||||||
|
{
|
||||||
|
Debug.Console(1, this, "Restoring default levels");
|
||||||
|
var vc = CurrentVolumeControls as IBasicVolumeWithFeedback;
|
||||||
|
if (vc != null)
|
||||||
|
vc.SetVolume(DefaultVolume);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Will power the room on with the last-used source
|
||||||
|
/// </summary>
|
||||||
|
public void PowerOnToDefaultOrLastSource()
|
||||||
|
{
|
||||||
|
if (!EnablePowerOnToLastSource || LastSourceKey == null)
|
||||||
|
return;
|
||||||
|
RunRouteAction(LastSourceKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Runs "roomOff" action on all rooms not set to ExcludeFromGlobalFunctions
|
||||||
|
/// </summary>
|
||||||
|
public static void AllRoomsOff()
|
||||||
|
{
|
||||||
|
var allRooms = DeviceManager.AllDevices.Where(d =>
|
||||||
|
d is EssentialsHuddleSpaceRoom && !(d as EssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions);
|
||||||
|
foreach (var room in allRooms)
|
||||||
|
(room as EssentialsHuddleSpaceRoom).RunRouteAction("roomOff");
|
||||||
|
}
|
||||||
|
|
||||||
|
#region IPrivacy Members
|
||||||
|
|
||||||
|
|
||||||
|
public void PrivacyModeOff()
|
||||||
|
{
|
||||||
|
VideoCodec.PrivacyModeOff();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PrivacyModeOn()
|
||||||
|
{
|
||||||
|
VideoCodec.PrivacyModeOn();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PrivacyModeToggle()
|
||||||
|
{
|
||||||
|
VideoCodec.PrivacyModeToggle();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,9 +27,15 @@ namespace PepperDash.Essentials
|
|||||||
// RANGE IN USE
|
// RANGE IN USE
|
||||||
public const uint VCRecentListTextEnd = 1230;
|
public const uint VCRecentListTextEnd = 1230;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 1231 - the current layout mode
|
/// 1231 - 1261 range of joins for recent list time
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const uint VCLayoutModeText = 1231;
|
public const uint VCRecentListTimeTextStart = 1231;
|
||||||
|
//
|
||||||
|
public const uint VCRecentListTimeTextEnd = 1260;
|
||||||
|
/// <summary>
|
||||||
|
/// 1291 - the current layout mode
|
||||||
|
/// </summary>
|
||||||
|
public const uint VCLayoutModeText = 1291;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 1301 - 1400
|
/// 1301 - 1400
|
||||||
|
|||||||
@@ -59,6 +59,8 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
|||||||
|
|
||||||
SmartObjectDynamicList DirectoryList;
|
SmartObjectDynamicList DirectoryList;
|
||||||
|
|
||||||
|
CodecDirectory CurrentDirectoryResult;
|
||||||
|
|
||||||
// These are likely temp until we get a keyboard built
|
// These are likely temp until we get a keyboard built
|
||||||
StringFeedback DialStringFeedback;
|
StringFeedback DialStringFeedback;
|
||||||
StringBuilder DialStringBuilder = new StringBuilder();
|
StringBuilder DialStringBuilder = new StringBuilder();
|
||||||
@@ -85,6 +87,7 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
|||||||
SetupCallStagingPopover();
|
SetupCallStagingPopover();
|
||||||
SetupDialKeypad();
|
SetupDialKeypad();
|
||||||
ActiveCallsSRL = new SubpageReferenceList(TriList, UISmartObjectJoin.CodecActiveCallsHeaderList, 3, 3, 3);
|
ActiveCallsSRL = new SubpageReferenceList(TriList, UISmartObjectJoin.CodecActiveCallsHeaderList, 3, 3, 3);
|
||||||
|
SetupDirectoryList();
|
||||||
SetupRecentCallsList();
|
SetupRecentCallsList();
|
||||||
SetupFavorites();
|
SetupFavorites();
|
||||||
SetupSelfViewControls();
|
SetupSelfViewControls();
|
||||||
@@ -368,13 +371,32 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
|||||||
void RefreshRecentCallsList()
|
void RefreshRecentCallsList()
|
||||||
{
|
{
|
||||||
var codec = Codec as IHasCallHistory;
|
var codec = Codec as IHasCallHistory;
|
||||||
|
uint textOffset = 1200;
|
||||||
|
uint timeTextOffset = 1230;
|
||||||
if (codec != null)
|
if (codec != null)
|
||||||
{
|
{
|
||||||
ushort i = 0;
|
ushort i = 0;
|
||||||
foreach (var c in codec.CallHistory.RecentCalls)
|
foreach (var c in codec.CallHistory.RecentCalls)
|
||||||
{
|
{
|
||||||
i++;
|
i++;
|
||||||
RecentCallsList.SetItemMainText(i, c.Name);
|
TriList.SetString(textOffset + i, c.Name);
|
||||||
|
// if it's today, show a simpler string
|
||||||
|
string timeText = null;
|
||||||
|
if (c.StartTime.Date == DateTime.Now.Date)
|
||||||
|
timeText = c.StartTime.ToShortTimeString();
|
||||||
|
else
|
||||||
|
timeText = c.StartTime.ToString();
|
||||||
|
TriList.SetString(timeTextOffset + i, timeText);
|
||||||
|
|
||||||
|
string iconName = null;
|
||||||
|
if (c.Direction == eCodecCallDirection.Incoming)
|
||||||
|
iconName = "Left";
|
||||||
|
else if (c.Direction == eCodecCallDirection.Outgoing)
|
||||||
|
iconName = "Right";
|
||||||
|
else
|
||||||
|
iconName = "Blank";
|
||||||
|
RecentCallsList.SetItemIcon(i, iconName);
|
||||||
|
|
||||||
var call = c; // for lambda scope
|
var call = c; // for lambda scope
|
||||||
RecentCallsList.SetItemButtonAction(i, b => { if(!b) Codec.Dial(call.Number); });
|
RecentCallsList.SetItemButtonAction(i, b => { if(!b) Codec.Dial(call.Number); });
|
||||||
}
|
}
|
||||||
@@ -406,7 +428,6 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
TriList.SetBool(1221 + i, false);
|
TriList.SetBool(1221 + i, false);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -419,17 +440,80 @@ namespace PepperDash.Essentials.UIDrivers.VC
|
|||||||
var codec = Codec as IHasDirectory;
|
var codec = Codec as IHasDirectory;
|
||||||
if (codec != null)
|
if (codec != null)
|
||||||
{
|
{
|
||||||
//codec.CallHistory.RecentCallsListHasChanged += (o, a) => RefreshRecentCallsList();
|
var dir = Codec as IHasDirectory;
|
||||||
// EVENT??????????????? Pointed at refresh
|
if (dir != null)
|
||||||
DirectoryList = new SmartObjectDynamicList(TriList.SmartObjects[UISmartObjectJoin.VCDirectoryList],
|
{
|
||||||
true, 1300);
|
DirectoryList = new SmartObjectDynamicList(TriList.SmartObjects[UISmartObjectJoin.VCDirectoryList],
|
||||||
RefreshDirectory();
|
true, 1300);
|
||||||
|
dir.DirectoryResultReturned += new EventHandler<DirectoryEventArgs>(dir_DirectoryResultReturned);
|
||||||
|
CurrentDirectoryResult = dir.DirectoryRoot;
|
||||||
|
|
||||||
|
if (CurrentDirectoryResult != null && dir.DirectoryRoot.DirectoryResults.Count > 0)
|
||||||
|
{
|
||||||
|
// populate it
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// it will just show up??????
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RefreshDirectory()
|
///// <summary>
|
||||||
{
|
/////
|
||||||
|
///// </summary>
|
||||||
|
//void RefreshDirectory()
|
||||||
|
//{
|
||||||
|
// (Codec as IHasDirectory).GetDirectoryFolderContents(CurrentDirectoryResult.
|
||||||
|
//}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
void dir_DirectoryResultReturned(object sender, DirectoryEventArgs e)
|
||||||
|
{
|
||||||
|
CurrentDirectoryResult = e.Directory;
|
||||||
|
ushort i = 0;
|
||||||
|
foreach (var r in CurrentDirectoryResult.DirectoryResults)
|
||||||
|
{
|
||||||
|
if (i == DirectoryList.MaxCount)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
DirectoryList.SetItemMainText(i, r.Name);
|
||||||
|
if(r is DirectoryContact)
|
||||||
|
{
|
||||||
|
var dc = r as DirectoryContact;
|
||||||
|
// if more than one contact method, pop up modal to choose
|
||||||
|
// otherwiese dial 0 entry
|
||||||
|
if (dc.ContactMethods.Count == 1)
|
||||||
|
{
|
||||||
|
DirectoryList.SetItemButtonAction(i, b => { if (!b) Codec.Dial(dc.ContactMethods[0].Number); });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DirectoryList.SetItemButtonAction(i, b =>
|
||||||
|
{
|
||||||
|
if (!b)
|
||||||
|
{
|
||||||
|
var id = (r as DirectoryFolder).FolderId;
|
||||||
|
(Codec as IHasDirectory).GetDirectoryFolderContents(id);
|
||||||
|
// will later call event handler
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DirectoryList.Count = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user