ecs-411: Most of keyboard driver

This commit is contained in:
Heath Volmer
2017-09-21 21:23:48 -06:00
parent 69e76bdb3a
commit f498d55dd6
14 changed files with 320 additions and 39 deletions

View File

@@ -0,0 +1,111 @@
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using Crestron.SimplSharp;
//using Crestron.SimplSharpPro;
//using Crestron.SimplSharpPro.UI;
//namespace PepperDash.Essentials.Core
//{
// /// <summary>
// /// Controls the device/tech status list - links in to the first 10, 1, 5 statuses in an item's StatusProperties
// /// </summary>
// public class DeviceStatusListController : SubpageReferenceListController
// {
// Dictionary<uint, Device> Items = new Dictionary<uint, Device>();
// public DeviceStatusListController(SmartObject list)
// {
// TheList = new SubpageReferenceList(list, 10, 1, 5);
// }
// /// <summary>
// /// Attaches an item's StatusProperties to the list item.
// /// THIS METHOD MAY BE BETTER ABSORBED INTO SOME OTHER CONTROLLER CLASS AS A
// /// PSIG -> LIST ITEM ADAPTER
// /// </summary>
// /// <param name="index">List position</param>
// /// <param name="device"></param>
// public void AddItem(uint listIndex, Device device)
// {
// if (device == null) throw new ArgumentNullException("device");
// Items[listIndex] = device;
// // Feedback - read the status properties and if there is room for them on the list sigs
// // link them up.
// //foreach (PValue statusPsig in device.StatusProperties)
// //{
// // uint num = statusPsig.Number;
// // Sig listSig = null;
// // switch (statusPsig.Type) // Switch on the PSig type and whether the PSig number is within the increment range
// // {
// // case eSigType.Bool:
// // if (num > TheList.BoolIncrement) return;
// // listSig = TheList.BoolInputSig(listIndex, num); // Pull the appropriate list sig.
// // break;
// // case eSigType.String:
// // if (num > TheList.StringIncrement) return;
// // listSig = TheList.StringInputSig(listIndex, num);
// // break;
// // case eSigType.UShort:
// // if (num > TheList.UShortIncrement) return;
// // listSig = TheList.UShortInputSig(listIndex, num);
// // break;
// // default:
// // return;
// // }
// // if (listSig != null) // If we got a sig, plug it into the PSig for updates.
// // statusPsig.AddLinkedSig(listSig, true);
// //}
// // Press/other handlers - read the Commands and if there is room, add them as Sig handlers.
// //foreach (var id in device.Commands.Keys)
// //{
// // var pValueNumber = id.Number;
// // Sig listSig = null;
// // // Switch on type of a command and if it's in range, get it's list Sig.
// // switch (id.Type)
// // {
// // case eSigType.Bool:
// // if (pValueNumber > TheList.BoolIncrement) return;
// // listSig = TheList.BoolFeedbackSig(listIndex, pValueNumber);
// // break;
// // case eSigType.String:
// // if (pValueNumber > TheList.StringIncrement) return;
// // listSig = TheList.StringOutputSig(listIndex, pValueNumber);
// // break;
// // case eSigType.UShort:
// // if (pValueNumber > TheList.UShortIncrement) return;
// // listSig = TheList.UShortOutputSig(listIndex, pValueNumber);
// // break;
// // default:
// // return;
// // }
// // if (listSig != null) // If we got a sig, add the command to its ChangeAction
// // SigToAction.GetSigToActionUserObjectForSig(listSig).SigChangeAction += device.Commands[id];
// // // This will need to be undone when detached MAKE A HELPER!!!!
// //}
// // "Custom things" below
// // Set the name on sig 1 - just an assignment. Don't
// var nameSig = TheList.StringInputSig(listIndex, 1);
// if (nameSig != null)
// nameSig.StringValue = device.Key;
// // Map IsOnline bool to a 0 / 1 state analog icon
// // Add an action to the online PValue that maps to a ushort sig on the list POTENTIAL LEAK HERE IF
// // this isn't cleaned up on disconnect
// var onlineSig = TheList.UShortInputSig(listIndex, 1);
// //var onlinePValue = device.StatusProperties[Device.JoinIsOnline];
// //if (onlineSig != null && onlinePValue != null)
// // onlinePValue.AddChangeAction(pv => onlineSig.UShortValue = (ushort)(onlinePValue.BoolValue ? 1 : 0));
// // //OR onlinePValue.AddLinkedSig(onlineSig, true);
// // Set the list length based on largest key
// TheList.Count = (ushort)Items.Keys.DefaultIfEmpty().Max(); // The count will be the largest key or 0
// }
// }
//}

View File

@@ -0,0 +1,167 @@
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using Crestron.SimplSharp;
//using Crestron.SimplSharpPro;
//using Crestron.SimplSharpPro.DeviceSupport;
//using Crestron.SimplSharpPro.UI;
//using PepperDash.Core;
//namespace PepperDash.Essentials.Core
//{
// //*****************************************************************************
// /// <summary>
// /// Wrapper class for subpage reference list. Contains helpful methods to get at the various signal groupings
// /// and to get individual signals using an index and a join.
// /// </summary>
// public class SourceListSubpageReferenceList : SubpageReferenceList
// {
// public const uint SmartObjectJoin = 3801;
// Action<uint> SourceSelectCallback;
// EssentialsRoom CurrentRoom;
// public SourceListSubpageReferenceList(BasicTriListWithSmartObject tl,
// Action<uint> sourceSelectCallback)
// : base(tl, SmartObjectJoin, 3, 1, 3)
// {
// SourceSelectCallback = sourceSelectCallback;
// }
// void SetSourceList(Dictionary<uint, IPresentationSource> dict)
// {
// // Iterate all positions, including ones missing from the dict.
// var max = dict.Keys.Max();
// for (uint i = 1; i <= max; i++)
// {
// // Add the source if it's in the dict
// if (dict.ContainsKey(i))
// {
// Items.Add(new SourceListSubpageReferenceListItem(i, dict[i], this, SourceSelectCallback));
// // Plug the callback function into the buttons
// }
// // Blank the line
// else
// Items.Add(new SourceListSubpageReferenceListItem(i, null,
// this, SourceSelectCallback));
// }
// Count = (ushort)max;
// }
// /// <summary>
// /// Links the SRL to the Room's PresentationSourceChange event for updating of the UI
// /// </summary>
// /// <param name="room"></param>
// public void AttachToRoom(EssentialsRoom room)
// {
// CurrentRoom = room;
// SetSourceList(room.Sources);
// CurrentRoom.PresentationSourceChange -= CurrentRoom_PresentationSourceChange;
// CurrentRoom.PresentationSourceChange += CurrentRoom_PresentationSourceChange;
// SetPresentationSourceFb(CurrentRoom.CurrentPresentationSource);
// }
// /// <summary>
// /// Disconnects the SRL from a Room's PresentationSourceChange
// /// </summary>
// public void DetachFromCurrentRoom()
// {
// ClearPresentationSourceFb(CurrentRoom.CurrentPresentationSource);
// if(CurrentRoom != null)
// CurrentRoom.PresentationSourceChange -= CurrentRoom_PresentationSourceChange;
// CurrentRoom = null;
// }
// // Handler to route source changes into list feedback
// void CurrentRoom_PresentationSourceChange(object sender, EssentialsRoomSourceChangeEventArgs args)
// {
// Debug.Console(2, "SRL received source change");
// ClearPresentationSourceFb(args.OldSource);
// SetPresentationSourceFb(args.NewSource);
// }
// void ClearPresentationSourceFb(IPresentationSource source)
// {
// if (source == null) return;
// var oldSourceItem = (SourceListSubpageReferenceListItem)Items.FirstOrDefault(
// i => ((SourceListSubpageReferenceListItem)i).SourceDevice == source);
// if (oldSourceItem != null)
// oldSourceItem.ClearFeedback();
// }
// void SetPresentationSourceFb(IPresentationSource source)
// {
// if (source == null) return;
// // Now set the new source to light up
// var newSourceItem = (SourceListSubpageReferenceListItem)Items.FirstOrDefault(
// i => ((SourceListSubpageReferenceListItem)i).SourceDevice == source);
// if (newSourceItem != null)
// newSourceItem.SetFeedback();
// }
// }
// public class SourceListSubpageReferenceListItem : SubpageReferenceListItem
// {
// public readonly IPresentationSource SourceDevice;
// public const uint ButtonPressJoin = 1;
// public const uint SelectedFeedbackJoin = 2;
// public const uint ButtonTextJoin = 1;
// public const uint IconNameJoin = 2;
// public SourceListSubpageReferenceListItem(uint index,
// IPresentationSource srcDevice, SubpageReferenceList owner, Action<uint> sourceSelectCallback)
// : base(index, owner)
// {
// if (srcDevice == null) throw new ArgumentNullException("srcDevice");
// if (owner == null) throw new ArgumentNullException("owner");
// if (sourceSelectCallback == null) throw new ArgumentNullException("sourceSelectCallback");
// SourceDevice = srcDevice;
// var nameSig = owner.StringInputSig(index, ButtonTextJoin);
// // Should be able to see if there is not enough buttons right here
// if (nameSig == null)
// {
// Debug.Console(0, "ERROR: Item {0} does not exist on source list SRL", index);
// return;
// }
// nameSig.StringValue = srcDevice.Name;
// owner.StringInputSig(index, IconNameJoin).StringValue = srcDevice.IconName;
// // Assign a source selection action to the appropriate button's UserObject - on release
// owner.GetBoolFeedbackSig(index, ButtonPressJoin).UserObject = new Action<bool>(b =>
// { if (!b) sourceSelectCallback(index); });
// // hook up the video icon
// var videoDev = srcDevice as IAttachVideoStatus;
// if (videoDev != null)
// {
// var status = videoDev.GetVideoStatuses();
// if (status != null)
// {
// Debug.Console(1, "Linking {0} video status to SRL", videoDev.Key);
// videoDev.GetVideoStatuses().VideoSyncFeedback.LinkInputSig(owner.BoolInputSig(index, 3));
// }
// }
// }
// public void SetFeedback()
// {
// Owner.BoolInputSig(Index, SelectedFeedbackJoin).BoolValue = true;
// }
// public void ClearFeedback()
// {
// Owner.BoolInputSig(Index, SelectedFeedbackJoin).BoolValue = false;
// }
// }
//}

View File

@@ -0,0 +1,263 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.UI;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
////*****************************************************************************
///// <summary>
///// Base class for all subpage reference list controllers
///// </summary>
//public class SubpageReferenceListController
//{
// public SubpageReferenceList TheList { get; protected set; }
//}
//*****************************************************************************
/// <summary>
/// Wrapper class for subpage reference list. Contains helpful methods to get at the various signal groupings
/// and to get individual signals using an index and a join.
/// </summary>
public class SubpageReferenceList
{
public ushort Count
{
get { return SetNumberOfItemsSig.UShortValue; }
set { SetNumberOfItemsSig.UShortValue = value; }
}
public ushort MaxDefinedItems { get; private set; }
public UShortInputSig ScrollToItemSig { get; private set; }
UShortInputSig SetNumberOfItemsSig;
public uint BoolIncrement { get; protected set; }
public uint UShortIncrement { get; protected set; }
public uint StringIncrement { get; protected set; }
protected readonly SmartObject SRL;
protected readonly List<SubpageReferenceListItem> Items = new List<SubpageReferenceListItem>();
public SubpageReferenceList(BasicTriListWithSmartObject triList, uint smartObjectId,
uint boolIncrement, uint ushortIncrement, uint stringIncrement)
{
SmartObject obj;
// Fail cleanly if not defined
if (triList.SmartObjects == null || triList.SmartObjects.Count == 0)
{
Debug.Console(0, "TriList {0:X2} Smart objects have not been loaded", triList.ID, smartObjectId);
return;
}
if (triList.SmartObjects.TryGetValue(smartObjectId, out obj))
{
SRL = triList.SmartObjects[smartObjectId];
ScrollToItemSig = SRL.UShortInput["Scroll To Item"];
SetNumberOfItemsSig = SRL.UShortInput["Set Number of Items"];
BoolIncrement = boolIncrement;
UShortIncrement = ushortIncrement;
StringIncrement = stringIncrement;
// Count the enable lines to see what max items is
MaxDefinedItems = (ushort)SRL.BooleanInput
.Where(s => s.Name.Contains("Enable")).Count();
Debug.Console(0, "SRL {0} contains max {1} items", SRL.ID, MaxDefinedItems);
SRL.SigChange -= new SmartObjectSigChangeEventHandler(SRL_SigChange);
SRL.SigChange += new SmartObjectSigChangeEventHandler(SRL_SigChange);
}
else
Debug.Console(0, "ERROR: TriList 0x{0:X2} Cannot load smart object {1}. Verify correct SGD file is loaded",
triList.ID, smartObjectId);
}
/// <summary>
/// Adds item to saved list of displayed items (not necessarily in order)
/// DOES NOT adjust Count
/// </summary>
/// <param name="item"></param>
public void AddItem(SubpageReferenceListItem item)
{
Items.Add(item);
}
/// <summary>
/// Items need to be responsible for managing their own deallocation process,
/// disconnecting from events, etc.
///
/// </summary>
public void Clear()
{
// If a line item needs to disconnect an CueActionPair or do something to release RAM
foreach (var item in Items) item.Clear();
// Empty the list
Items.Clear();
// Clean up the SRL
Count = 0;
ScrollToItemSig.UShortValue = 1;
}
/// <summary>
/// Optional call to refresh the signals on the objects in the SRL - this calls Refresh() on
/// all SubpageReferenceListItem items
/// </summary>
public void Refresh()
{
foreach (var item in Items) item.Refresh();
}
// Helpers to get sigs by their weird SO names
/// <summary>
/// Returns the Sig associated with a given SRL line index
/// and the join number of the object on the SRL subpage.
/// Note: If the join number exceeds the increment range, or the count of Sigs on the
/// list object, this will return null
/// </summary>
/// <param name="index">The line or item position on the SRL</param>
/// <param name="sigNum">The join number of the item on the SRL subpage</param>
/// <returns>A Sig or null if the numbers are out of range</returns>
public BoolOutputSig GetBoolFeedbackSig(uint index, uint sigNum)
{
if (sigNum > BoolIncrement) return null;
return SRL.BooleanOutput.FirstOrDefault(s => s.Name.Equals(GetBoolFeedbackSigName(index, sigNum)));
}
/// <summary>
/// Returns the Sig associated with a given SRL line index
/// and the join number of the object on the SRL subpage.
/// Note: If the join number exceeds the increment range, or the count of Sigs on the
/// list object, this will return null
/// </summary>
/// <param name="index">The line or item position on the SRL</param>
/// <param name="sigNum">The join number of the item on the SRL subpage</param>
/// <returns>A Sig or null if the numbers are out of range</returns>
public UShortOutputSig GetUShortOutputSig(uint index, uint sigNum)
{
if (sigNum > UShortIncrement) return null;
return SRL.UShortOutput.FirstOrDefault(s => s.Name.Equals(GetBoolFeedbackSigName(index, sigNum)));
}
/// <summary>
/// Returns the Sig associated with a given SRL line index
/// and the join number of the object on the SRL subpage.
/// Note: If the join number exceeds the increment range, or the count of Sigs on the
/// list object, this will return null
/// </summary>
/// <param name="index">The line or item position on the SRL</param>
/// <param name="sigNum">The join number of the item on the SRL subpage</param>
/// <returns>A Sig or null if the numbers are out of range</returns>
public StringOutputSig GetStringOutputSig(uint index, uint sigNum)
{
if (sigNum > StringIncrement) return null;
return SRL.StringOutput.FirstOrDefault(s => s.Name.Equals(GetBoolFeedbackSigName(index, sigNum)));
}
/// <summary>
/// Returns the Sig associated with a given SRL line index
/// and the join number of the object on the SRL subpage.
/// Note: If the join number exceeds the increment range, or the count of Sigs on the
/// list object, this will return null
/// </summary>
/// <param name="index">The line on the SRL</param>
/// <param name="sigNum">The join number of the item on the SRL subpage</param>
/// <returns>A Sig or null if the numbers are out of range</returns>
public BoolInputSig BoolInputSig(uint index, uint sigNum)
{
if (sigNum > BoolIncrement) return null;
return SRL.BooleanInput.FirstOrDefault(s => s.Name.Equals(GetBoolInputSigName(index, sigNum)));
}
/// <summary>
/// Returns the Sig associated with a given SRL line index
/// and the join number of the object on the SRL subpage.
/// Note: If the join number exceeds the increment range, or the count of Sigs on the
/// list object, this will return null
/// </summary>
/// <param name="index">The line on the SRL</param>
/// <param name="sigNum">The join number of the item on the SRL subpage</param>
/// <returns>A Sig or null if the numbers are out of range</returns>
public UShortInputSig UShortInputSig(uint index, uint sigNum)
{
if (sigNum > UShortIncrement) return null;
return SRL.UShortInput.FirstOrDefault(s => s.Name.Equals(GetUShortInputSigName(index, sigNum)));
}
/// <summary>
/// Returns the Sig associated with a given SRL line index
/// and the join number of the object on the SRL subpage.
/// Note: If the join number exceeds the increment range, or the count of Sigs on the
/// list object, this will return null
/// </summary>
/// <param name="index">The line on the SRL</param>
/// <param name="sigNum">The join number of the item on the SRL subpage</param>
/// <returns>A Sig or null if the numbers are out of range</returns>
public StringInputSig StringInputSig(uint index, uint sigNum)
{
if (sigNum > StringIncrement) return null;
return SRL.StringInput.FirstOrDefault(s => s.Name.Equals(GetStringInputSigName(index, sigNum)));
}
// Helpers to get signal names
string GetBoolFeedbackSigName(uint index, uint sigNum)
{
var num = (index - 1) * BoolIncrement + sigNum;
return String.Format("press{0}", num);
}
string GetUShortOutputSigName(uint index, uint sigNum)
{
var num = (index - 1) * UShortIncrement + sigNum;
return String.Format("an_act{0}", num);
}
string GetStringOutputSigName(uint index, uint sigNum)
{
var num = (index - 1) * StringIncrement + sigNum;
return String.Format("text-i{0}", num);
}
string GetBoolInputSigName(uint index, uint sigNum)
{
var num = (index - 1) * BoolIncrement + sigNum;
return String.Format("fb{0}", num);
}
string GetUShortInputSigName(uint index, uint sigNum)
{
var num = (index - 1) * UShortIncrement + sigNum;
return String.Format("an_fb{0}", num);
}
string GetStringInputSigName(uint index, uint sigNum)
{
var num = (index - 1) * StringIncrement + sigNum;
return String.Format("text-o{0}", num);
}
/// <summary>
/// Stock SigChange handler
/// </summary>
/// <param name="currentDevice"></param>
/// <param name="args"></param>
public static void SRL_SigChange(GenericBase currentDevice, SmartObjectEventArgs args)
{
var uo = args.Sig.UserObject;
if (uo is Action<bool>)
(uo as Action<bool>)(args.Sig.BoolValue);
else if (uo is Action<ushort>)
(uo as Action<ushort>)(args.Sig.UShortValue);
else if (uo is Action<string>)
(uo as Action<string>)(args.Sig.StringValue);
}
}
}

View File

@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.UI;
namespace PepperDash.Essentials.Core
{
public class SubpageReferenceListItem
{
/// <summary>
/// The list that this lives in
/// </summary>
protected SubpageReferenceList Owner;
protected uint Index;
public SubpageReferenceListItem(uint index, SubpageReferenceList owner)
{
Index = index;
Owner = owner;
}
/// <summary>
/// Called by SRL to release all referenced objects
/// </summary>
public virtual void Clear()
{
}
public virtual void Refresh() { }
}
}