Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1e59d104ff | ||
|
|
dbf529123f | ||
|
|
5860432c7e | ||
|
|
c7f3e946ee | ||
|
|
542e6879bc | ||
|
|
d0c799a821 | ||
|
|
b0e77c3fb8 | ||
|
|
a65ae57d7b | ||
|
|
907e4a2a36 | ||
|
|
f4ff363cb9 | ||
|
|
ad65c72747 | ||
|
|
482ebc828b | ||
|
|
0b8688ed7b | ||
|
|
10d936eef0 | ||
|
|
1334c23fea | ||
|
|
0e0edae19c | ||
|
|
eb6d794806 | ||
|
|
4fd750f8e0 | ||
|
|
adfff4f035 | ||
|
|
2dfc29591d | ||
|
|
a77bf79119 | ||
|
|
f2b760e549 | ||
|
|
7c531b5c89 | ||
|
|
6343d239a4 | ||
|
|
e5ae43c9ee | ||
|
|
ae63b92fd1 | ||
|
|
4888eedde6 | ||
|
|
b5f262b30a | ||
|
|
1794718ed4 | ||
|
|
d8bd6194ff | ||
|
|
c8af704c9b | ||
|
|
e21233484b | ||
|
|
d30645926b | ||
|
|
a098c1738c | ||
|
|
597309ca72 | ||
|
|
1109d90dca | ||
|
|
5d6dd99b97 | ||
|
|
011b145672 | ||
|
|
f615d01b82 | ||
|
|
7c3a84d4cf | ||
|
|
ccd5f25f9e | ||
|
|
2e381c8073 | ||
|
|
9e26f98979 | ||
|
|
5f46913360 | ||
|
|
badecbeac3 | ||
|
|
56885c4001 | ||
|
|
5a1dc5e980 | ||
|
|
403aacf788 |
@@ -0,0 +1,267 @@
|
||||
using HueUWP.Helpers;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
using Windows.Storage;
|
||||
using HueUWP.Lights;
|
||||
using Windows.Networking.Connectivity;
|
||||
using Windows.Networking;
|
||||
|
||||
namespace HueUWP
|
||||
{
|
||||
public class APIHandler
|
||||
{
|
||||
bool discomode = false;
|
||||
|
||||
public APIHandler()
|
||||
{
|
||||
}
|
||||
|
||||
public async Task<String> Register()
|
||||
{
|
||||
var hostNames = NetworkInformation.GetHostNames();
|
||||
var hostName = hostNames.FirstOrDefault(name => name.Type == HostNameType.DomainName)?.DisplayName ?? "Unknown Device";
|
||||
|
||||
try
|
||||
{
|
||||
var json = await NetworkHandler.RegisterName("YK Hue", hostName);
|
||||
json = json.Replace("[", "").Replace("]", "");
|
||||
JObject o = JObject.Parse(json);
|
||||
string id = o["success"]["username"].ToString();
|
||||
App.LOCAL_SETTINGS.Values["id"] = id;
|
||||
return "success";
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.WriteLine("Could not register.");
|
||||
return "error";
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<String> UpdateGroup(Light g)
|
||||
{
|
||||
string json = await NetworkHandler.Group(g.ID);
|
||||
JObject o = JObject.Parse(json);
|
||||
var state = o["action"];
|
||||
|
||||
g.IsOn = ((string)state["on"]).ToLower() == "true" ? true : false;
|
||||
if(g.HueEnabled)
|
||||
g.Hue = (int)state["hue"];
|
||||
if(g.BrightnessEnabled)
|
||||
g.Brightness = (int)state["bri"];
|
||||
if(g.SaturationEnabled)
|
||||
g.Saturation = (int)state["sat"];
|
||||
|
||||
return "success";
|
||||
|
||||
}
|
||||
|
||||
public async Task<String> UpdateLight(Light l)
|
||||
{
|
||||
string json = await NetworkHandler.Light(l.ID);
|
||||
JObject o = JObject.Parse(json);
|
||||
|
||||
Debug.WriteLine(o);
|
||||
|
||||
var state = o["state"];
|
||||
|
||||
l.IsOn = ((string)state["on"]).ToLower() == "true" ? true : false;
|
||||
if(l.HueEnabled)
|
||||
l.Hue = (int)state["hue"];
|
||||
if(l.BrightnessEnabled)
|
||||
l.Brightness = (int)state["bri"];
|
||||
if(l.SaturationEnabled)
|
||||
l.Saturation = (int)state["sat"];
|
||||
|
||||
return "success";
|
||||
}
|
||||
|
||||
public async Task<String> SetLightState(Light l)
|
||||
{
|
||||
string json = "error";
|
||||
if (l is LightSingle)
|
||||
json = await NetworkHandler.SetLight(l.ID, l.IsOn);
|
||||
return json;
|
||||
}
|
||||
|
||||
|
||||
public async Task<String> SetLightColor(Light l, bool instant = false)
|
||||
{
|
||||
if(l is LightSingle && l.IsOn)
|
||||
{
|
||||
var json = await NetworkHandler.SetLight(l.ID, l.Hue, l.Saturation, l.Brightness, instant);
|
||||
return "success";
|
||||
}
|
||||
return "error";
|
||||
}
|
||||
|
||||
public async Task<String> SetGroupState(Light l)
|
||||
{
|
||||
string json = "error";
|
||||
if (l is LightGroup)
|
||||
json = await NetworkHandler.SetGroup(l.ID, l.IsOn);
|
||||
return json;
|
||||
}
|
||||
|
||||
|
||||
public async Task<String> SetGroupColor(Light l, bool instant = false)
|
||||
{
|
||||
if (l is LightGroup && l.IsOn)
|
||||
{
|
||||
var json = await NetworkHandler.SetGroup(l.ID, l.Hue, l.Saturation, l.Brightness, instant);
|
||||
return "success";
|
||||
}
|
||||
|
||||
return "error";
|
||||
}
|
||||
|
||||
public async Task<String> Groups(ObservableCollection<Light> groups)
|
||||
{
|
||||
try
|
||||
{
|
||||
var json = await NetworkHandler.Groups();
|
||||
JObject o = JObject.Parse(json);
|
||||
foreach (var i in o)
|
||||
{
|
||||
var groupjson = await NetworkHandler.Group(Int32.Parse(i.Key));
|
||||
JObject o2 = JObject.Parse(groupjson);
|
||||
var state = o2["action"];
|
||||
|
||||
Light g = new LightGroup(Int32.Parse(i.Key), (string)o2["name"]);
|
||||
|
||||
g.IsOn = ((string)state["on"]).ToLower() == "true" ? true : false;
|
||||
|
||||
//Hue
|
||||
if (!state["hue"].IsNullOrEmpty())
|
||||
{
|
||||
g.HueEnabled = true;
|
||||
g.Hue = (int)state["hue"];
|
||||
}
|
||||
else
|
||||
g.HueEnabled = false;
|
||||
|
||||
//Brightness
|
||||
if (!state["bri"].IsNullOrEmpty())
|
||||
{
|
||||
g.BrightnessEnabled = true;
|
||||
g.Brightness = (int)state["bri"];
|
||||
}
|
||||
else
|
||||
g.BrightnessEnabled = false;
|
||||
|
||||
//Saturation
|
||||
if (!state["sat"].IsNullOrEmpty())
|
||||
{
|
||||
g.SaturationEnabled = true;
|
||||
g.Saturation = (int)state["sat"];
|
||||
}
|
||||
else
|
||||
g.SaturationEnabled = false;
|
||||
|
||||
groups.Add(g);
|
||||
|
||||
}
|
||||
return "success";
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.WriteLine(e.StackTrace);
|
||||
Debug.WriteLine("Could not get all groups.");
|
||||
return "error";
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<String> Lights(ObservableCollection<Light> lights)
|
||||
{
|
||||
|
||||
//List<Light> _lights = new List<Light>();
|
||||
|
||||
try {
|
||||
var json = await NetworkHandler.Lights();
|
||||
JObject o = JObject.Parse(json);
|
||||
foreach(var i in o)
|
||||
{
|
||||
var light = o["" + i.Key];
|
||||
var state = light["state"];
|
||||
|
||||
Light l = new LightSingle(Int32.Parse(i.Key), (string)light["name"], (string)light["type"]);
|
||||
|
||||
l.IsOn = ((string)state["on"]).ToLower() == "true" ? true : false;
|
||||
|
||||
//Hue
|
||||
if (!state["hue"].IsNullOrEmpty())
|
||||
{
|
||||
l.HueEnabled = true;
|
||||
l.Hue = (int)state["hue"];
|
||||
}
|
||||
else
|
||||
l.HueEnabled = false;
|
||||
|
||||
//Brightness
|
||||
if (!state["bri"].IsNullOrEmpty())
|
||||
{
|
||||
l.BrightnessEnabled = true;
|
||||
l.Brightness = (int)state["bri"];
|
||||
}
|
||||
else
|
||||
l.BrightnessEnabled = false;
|
||||
|
||||
//Saturation
|
||||
if (!state["sat"].IsNullOrEmpty())
|
||||
{
|
||||
l.SaturationEnabled = true;
|
||||
l.Saturation = (int)state["sat"];
|
||||
}
|
||||
else
|
||||
l.SaturationEnabled = false;
|
||||
|
||||
lights.Add(l);
|
||||
}
|
||||
|
||||
//if(_lights.Count > 0)
|
||||
//{
|
||||
// _lights.OrderBy(l => l.Name);
|
||||
// lights = new ObservableCollection<Light>(_lights);
|
||||
//}
|
||||
|
||||
return "success";
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Debug.WriteLine(e.StackTrace);
|
||||
Debug.WriteLine("Could not get all lights.");
|
||||
return "error";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public async void DiscoMode(ObservableCollection<Light> lights)
|
||||
{
|
||||
discomode = true;
|
||||
Random rnd = new Random();
|
||||
while (discomode)
|
||||
{
|
||||
lights.ToList().Where(l => l.IsOn == true).ToList().ForEach(l =>
|
||||
{
|
||||
l.Hue = rnd.Next(0, 65535);
|
||||
l.Brightness = rnd.Next(214, 254);
|
||||
l.Saturation = 254;
|
||||
l.SetColor(true);
|
||||
});
|
||||
await Task.Delay(TimeSpan.FromMilliseconds(lights.Count * 100));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public async void DiscoMode(bool on)
|
||||
{
|
||||
discomode = on;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<Application
|
||||
x:Class="HueUWP.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:HueUWP">
|
||||
<!-- RequestedTheme="Dark" -->
|
||||
|
||||
<Application.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Dark" Source="Themes/DarkTheme.xaml"/>
|
||||
<ResourceDictionary x:Key="Light" Source="Themes/LightTheme.xaml"/>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
|
||||
</Application>
|
||||
@@ -0,0 +1,152 @@
|
||||
using HueUWP.Views;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using Windows.ApplicationModel;
|
||||
using Windows.ApplicationModel.Activation;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using Windows.Storage;
|
||||
using Windows.UI.Core;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
namespace HueUWP
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides application-specific behavior to supplement the default Application class.
|
||||
/// </summary>
|
||||
sealed partial class App : Application
|
||||
{
|
||||
public static ApplicationDataContainer LOCAL_SETTINGS = ApplicationData.Current.LocalSettings;
|
||||
Frame rootFrame;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the singleton application object. This is the first line of authored code
|
||||
/// executed, and as such is the logical equivalent of main() or WinMain().
|
||||
/// </summary>
|
||||
public App()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.Suspending += OnSuspending;
|
||||
}
|
||||
|
||||
private static APIHandler _api;
|
||||
|
||||
public static APIHandler api
|
||||
{
|
||||
get {
|
||||
if (_api == null)
|
||||
_api = new APIHandler();
|
||||
return _api;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when the application is launched normally by the end user. Other entry points
|
||||
/// will be used such as when the application is launched to open a specific file.
|
||||
/// </summary>
|
||||
/// <param name="e">Details about the launch request and process.</param>
|
||||
protected override void OnLaunched(LaunchActivatedEventArgs e)
|
||||
{
|
||||
|
||||
#if DEBUG
|
||||
if (System.Diagnostics.Debugger.IsAttached)
|
||||
{
|
||||
this.DebugSettings.EnableFrameRateCounter = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
rootFrame = Window.Current.Content as Frame;
|
||||
|
||||
// Do not repeat app initialization when the Window already has content,
|
||||
// just ensure that the window is active
|
||||
if (rootFrame == null)
|
||||
{
|
||||
// Create a Frame to act as the navigation context and navigate to the first page
|
||||
rootFrame = new Frame();
|
||||
|
||||
rootFrame.NavigationFailed += OnNavigationFailed;
|
||||
rootFrame.Navigated += RootFrame_Navigated;
|
||||
SystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested;
|
||||
|
||||
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
|
||||
{
|
||||
//TODO: Load state from previously suspended application
|
||||
}
|
||||
|
||||
// Place the frame in the current Window
|
||||
Window.Current.Content = rootFrame;
|
||||
}
|
||||
|
||||
if (rootFrame.Content == null)
|
||||
{
|
||||
// When the navigation stack isn't restored navigate to the first page,
|
||||
// configuring the new page by passing required information as a navigation
|
||||
// parameter
|
||||
rootFrame.Navigate(typeof(LightsView), e.Arguments);
|
||||
}
|
||||
|
||||
if(LOCAL_SETTINGS.Values["ip"] == null)
|
||||
LOCAL_SETTINGS.Values["ip"] = "145.48.205.190";
|
||||
if (LOCAL_SETTINGS.Values["port"] == null)
|
||||
LOCAL_SETTINGS.Values["port"] = 80;
|
||||
if (LOCAL_SETTINGS.Values["autorefresh"] == null)
|
||||
LOCAL_SETTINGS.Values["autorefresh"] = true;
|
||||
|
||||
|
||||
|
||||
// Ensure the current window is active
|
||||
Window.Current.Activate();
|
||||
}
|
||||
|
||||
private void RootFrame_Navigated(object sender, NavigationEventArgs e)
|
||||
{
|
||||
SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility =
|
||||
rootFrame.CanGoBack ?
|
||||
AppViewBackButtonVisibility.Visible :
|
||||
AppViewBackButtonVisibility.Collapsed;
|
||||
}
|
||||
|
||||
private void OnBackRequested(object sender, BackRequestedEventArgs e)
|
||||
{
|
||||
if (rootFrame.CanGoBack)
|
||||
{
|
||||
e.Handled = true;
|
||||
rootFrame.GoBack();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when Navigation to a certain page fails
|
||||
/// </summary>
|
||||
/// <param name="sender">The Frame which failed navigation</param>
|
||||
/// <param name="e">Details about the navigation failure</param>
|
||||
void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
|
||||
{
|
||||
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when application execution is being suspended. Application state is saved
|
||||
/// without knowing whether the application will be terminated or resumed with the contents
|
||||
/// of memory still intact.
|
||||
/// </summary>
|
||||
/// <param name="sender">The source of the suspend request.</param>
|
||||
/// <param name="e">Details about the suspend request.</param>
|
||||
private void OnSuspending(object sender, SuspendingEventArgs e)
|
||||
{
|
||||
var deferral = e.SuspendingOperation.GetDeferral();
|
||||
//TODO: Save application state and stop any background activity
|
||||
deferral.Complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
@@ -0,0 +1,198 @@
|
||||
using HueUWP.Lights;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.UI;
|
||||
|
||||
namespace HueUWP.Helpers
|
||||
{
|
||||
public static class ColorUtil
|
||||
{
|
||||
|
||||
public static Color getColor(Light light)
|
||||
{
|
||||
double hue = ((double)light.Hue * 360.0f) / 65535.0f;
|
||||
double sat = (double)light.Saturation / 255.0f;
|
||||
double val = (double)light.Brightness/ 255.0f;
|
||||
|
||||
int r, g, b;
|
||||
HsvToRgb(hue, sat, val, out r, out g, out b);
|
||||
return Color.FromArgb(255, Convert.ToByte(r), Convert.ToByte(g), Convert.ToByte(b));
|
||||
}
|
||||
|
||||
public static void RGBtoHSV(double r, double g, double b, out double h, out double s, out double v)
|
||||
{
|
||||
double min, max, delta;
|
||||
|
||||
min = Math.Min(r, Math.Min(g, b));
|
||||
max = Math.Max(r, Math.Max(g, b));
|
||||
|
||||
v = max; // v
|
||||
delta = max - min;
|
||||
|
||||
if (max != 0)
|
||||
s = delta / max; // s
|
||||
else
|
||||
{
|
||||
// r = g = b = 0 // s = 0, v is undefined
|
||||
s = 0;
|
||||
h = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (r == max)
|
||||
h = (g - b) / delta; // between yellow & magenta
|
||||
else if (g == max)
|
||||
h = 2 + (b - r) / delta; // between cyan & yellow
|
||||
else
|
||||
h = 4 + (r - g) / delta; // between magenta & cyan
|
||||
|
||||
h *= 60; // degrees
|
||||
|
||||
if (h < 0)
|
||||
h += 360;
|
||||
}
|
||||
|
||||
private static void HsvToRgb(double h, double S, double V, out int r, out int g, out int b)
|
||||
{
|
||||
double H = h;
|
||||
while (H < 0)
|
||||
{
|
||||
H += 360;
|
||||
}
|
||||
while (H >= 360)
|
||||
{
|
||||
H -= 360;
|
||||
}
|
||||
|
||||
double R, G, B;
|
||||
if (V <= 0)
|
||||
R = G = B = 0;
|
||||
else if (S <= 0)
|
||||
R = G = B = V;
|
||||
else
|
||||
{
|
||||
double hf = H / 60.0;
|
||||
int i = (int)Math.Floor(hf);
|
||||
double f = hf - i;
|
||||
double pv = V * (1 - S);
|
||||
double qv = V * (1 - S * f);
|
||||
double tv = V * (1 - S * (1 - f));
|
||||
switch (i)
|
||||
{
|
||||
// Red is the dominant color
|
||||
case 0:
|
||||
R = V;
|
||||
G = tv;
|
||||
B = pv;
|
||||
break;
|
||||
// Green is the dominant color
|
||||
case 1:
|
||||
R = qv;
|
||||
G = V;
|
||||
B = pv;
|
||||
break;
|
||||
case 2:
|
||||
R = pv;
|
||||
G = V;
|
||||
B = tv;
|
||||
break;
|
||||
// Blue is the dominant color
|
||||
case 3:
|
||||
R = pv;
|
||||
G = qv;
|
||||
B = V;
|
||||
break;
|
||||
case 4:
|
||||
R = tv;
|
||||
G = pv;
|
||||
B = V;
|
||||
break;
|
||||
// Red is the dominant color
|
||||
case 5:
|
||||
R = V;
|
||||
G = pv;
|
||||
B = qv;
|
||||
break;
|
||||
// Just in case we overshoot on our math by a little, we put these here. Since its a switch it won't slow us down at all to put these here.
|
||||
case 6:
|
||||
R = V;
|
||||
G = tv;
|
||||
B = pv;
|
||||
break;
|
||||
case -1:
|
||||
R = V;
|
||||
G = pv;
|
||||
B = qv;
|
||||
break;
|
||||
// The color is not defined, we should throw an error.
|
||||
default:
|
||||
//LFATAL("i Value error in Pixel conversion, Value is %d", i);
|
||||
R = G = B = V; // Just pretend its black/white
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
r = Clamp((int)(R * 255.0));
|
||||
g = Clamp((int)(G * 255.0));
|
||||
b = Clamp((int)(B * 255.0));
|
||||
}
|
||||
|
||||
private static int Clamp(int i)
|
||||
{
|
||||
if (i < 0) return 0;
|
||||
if (i > 255) return 255;
|
||||
return i;
|
||||
}
|
||||
|
||||
public static Color HsvToRgb(double hue, double sat, double val)
|
||||
{
|
||||
|
||||
double h = ((double)hue * 360.0f) / 65535.0f;
|
||||
double s = (double)sat / 255.0f;
|
||||
double v = (double)val / 255.0f;
|
||||
|
||||
int hi = (int)Math.Floor(h / 60.0) % 6;
|
||||
double f = (h / 60.0) - Math.Floor(h / 60.0);
|
||||
|
||||
double p = v * (1.0 - s);
|
||||
double q = v * (1.0 - (f * s));
|
||||
double t = v * (1.0 - ((1.0 - f) * s));
|
||||
|
||||
Color ret;
|
||||
|
||||
switch (hi)
|
||||
{
|
||||
case 0:
|
||||
ret = GetRgb(v, t, p);
|
||||
break;
|
||||
case 1:
|
||||
ret = GetRgb(q, v, p);
|
||||
break;
|
||||
case 2:
|
||||
ret = GetRgb(p, v, t);
|
||||
break;
|
||||
case 3:
|
||||
ret = GetRgb(p, q, v);
|
||||
break;
|
||||
case 4:
|
||||
ret = GetRgb(t, p, v);
|
||||
break;
|
||||
case 5:
|
||||
ret = GetRgb(v, p, q);
|
||||
break;
|
||||
default:
|
||||
ret = Color.FromArgb(0xFF, 0x00, 0x00, 0x00);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static Color GetRgb(double r, double g, double b)
|
||||
{
|
||||
return Color.FromArgb(255, (byte)(r * 255.0), (byte)(g * 255.0), (byte)(b * 255.0));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HueUWP.Helpers
|
||||
{
|
||||
public static class Extensions
|
||||
{
|
||||
public static string ToDelimitedString<T>(this IEnumerable<T> source, Func<T, string> func)
|
||||
{
|
||||
return ToDelimitedString(source, ", ", func);
|
||||
}
|
||||
|
||||
public static string ToDelimitedString<T>(this IEnumerable<T> source, string delimiter, Func<T, string> func)
|
||||
{
|
||||
return String.Join(delimiter, source.Select(func).ToArray());
|
||||
}
|
||||
|
||||
public static bool IsNullOrEmpty(this JToken token)
|
||||
{
|
||||
return (token == null) ||
|
||||
(token.Type == JTokenType.Array && !token.HasValues) ||
|
||||
(token.Type == JTokenType.Object && !token.HasValues) ||
|
||||
(token.Type == JTokenType.String && token.ToString() == String.Empty) ||
|
||||
(token.Type == JTokenType.Null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.UI.Xaml.Data;
|
||||
|
||||
namespace HueUWP.Helpers
|
||||
{
|
||||
public class NullableBooleanConverter : IValueConverter
|
||||
{
|
||||
//From bool to nullable
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
bool b = (bool)value;
|
||||
bool? be = b as bool?;
|
||||
return be;
|
||||
}
|
||||
|
||||
//From nullable to bool
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
bool? b = (bool?)value;
|
||||
bool be = false;
|
||||
if (b.HasValue)
|
||||
be = (bool)b;
|
||||
|
||||
return be;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Data;
|
||||
|
||||
namespace HueUWP.Helpers
|
||||
{
|
||||
class VisibilityConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
bool b = (bool)value;
|
||||
|
||||
if (b)
|
||||
return Visibility.Visible;
|
||||
else
|
||||
return Visibility.Collapsed;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
Visibility v = (Visibility)value;
|
||||
|
||||
if (v == Visibility.Visible)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
<ProjectGuid>{88414ECD-0462-41DE-ABA9-462D2F154595}</ProjectGuid>
|
||||
<OutputType>AppContainerExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>HueUWP</RootNamespace>
|
||||
<AssemblyName>HueUWP</AssemblyName>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
|
||||
<TargetPlatformVersion>10.0.10240.0</TargetPlatformVersion>
|
||||
<TargetPlatformMinVersion>10.0.10240.0</TargetPlatformMinVersion>
|
||||
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
|
||||
<EnableDotNetNativeCompatibleProfile>true</EnableDotNetNativeCompatibleProfile>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<PackageCertificateKeyFile>HueUWP_TemporaryKey.pfx</PackageCertificateKeyFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\ARM\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>ARM</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'">
|
||||
<OutputPath>bin\ARM\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>ARM</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<!-- A reference to the entire .Net Framework and Windows SDK are automatically included -->
|
||||
<None Include="project.json" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Lights\LightGroupListDataSource.cs" />
|
||||
<Compile Include="Views\AboutView.xaml.cs">
|
||||
<DependentUpon>AboutView.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="APIHandler.cs" />
|
||||
<Compile Include="App.xaml.cs">
|
||||
<DependentUpon>App.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Helpers\ColorUtil.cs" />
|
||||
<Compile Include="Helpers\NullableBooleanConverter.cs" />
|
||||
<Compile Include="Helpers\VisibilityConverter.cs" />
|
||||
<Compile Include="Views\DetailView.xaml.cs">
|
||||
<DependentUpon>DetailView.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Helpers\Extensions.cs" />
|
||||
<Compile Include="Lights\Light.cs" />
|
||||
<Compile Include="Lights\LightGroup.cs" />
|
||||
<Compile Include="Lights\LightListDataSource.cs" />
|
||||
<Compile Include="Lights\LightMulti.cs" />
|
||||
<Compile Include="Lights\LightSingle.cs" />
|
||||
<Compile Include="Views\GroupsView.xaml.cs">
|
||||
<DependentUpon>GroupsView.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Views\LightsView.xaml.cs">
|
||||
<DependentUpon>LightsView.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="MultiEdit.xaml.cs">
|
||||
<DependentUpon>MultiEdit.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="NetworkHandler.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Views\SettingsView.xaml.cs">
|
||||
<DependentUpon>SettingsView.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="SettingsViewModel.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AppxManifest Include="Package.appxmanifest">
|
||||
<SubType>Designer</SubType>
|
||||
</AppxManifest>
|
||||
<None Include="HueUWP_TemporaryKey.pfx" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Properties\Default.rd.xml" />
|
||||
<Content Include="Assets\LockScreenLogo.scale-200.png" />
|
||||
<Content Include="Assets\SplashScreen.scale-200.png" />
|
||||
<Content Include="Assets\Square150x150Logo.scale-200.png" />
|
||||
<Content Include="Assets\Square44x44Logo.scale-200.png" />
|
||||
<Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
|
||||
<Content Include="Assets\StoreLogo.png" />
|
||||
<Content Include="Assets\Wide310x150Logo.scale-200.png" />
|
||||
<Content Include="Todo.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ApplicationDefinition Include="App.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</ApplicationDefinition>
|
||||
<Page Include="Views\AboutView.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Views\DetailView.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Views\GroupsView.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Views\LightsView.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="MultiEdit.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Views\SettingsView.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Themes\DarkTheme.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Page>
|
||||
<Page Include="Themes\LightTheme.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' ">
|
||||
<VisualStudioVersion>14.0</VisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
@@ -0,0 +1,40 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.23107.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HueUWP", "HueUWP.csproj", "{88414ECD-0462-41DE-ABA9-462D2F154595}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|ARM = Debug|ARM
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|ARM = Release|ARM
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{88414ECD-0462-41DE-ABA9-462D2F154595}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||
{88414ECD-0462-41DE-ABA9-462D2F154595}.Debug|ARM.Build.0 = Debug|ARM
|
||||
{88414ECD-0462-41DE-ABA9-462D2F154595}.Debug|ARM.Deploy.0 = Debug|ARM
|
||||
{88414ECD-0462-41DE-ABA9-462D2F154595}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{88414ECD-0462-41DE-ABA9-462D2F154595}.Debug|x64.Build.0 = Debug|x64
|
||||
{88414ECD-0462-41DE-ABA9-462D2F154595}.Debug|x64.Deploy.0 = Debug|x64
|
||||
{88414ECD-0462-41DE-ABA9-462D2F154595}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{88414ECD-0462-41DE-ABA9-462D2F154595}.Debug|x86.Build.0 = Debug|x86
|
||||
{88414ECD-0462-41DE-ABA9-462D2F154595}.Debug|x86.Deploy.0 = Debug|x86
|
||||
{88414ECD-0462-41DE-ABA9-462D2F154595}.Release|ARM.ActiveCfg = Release|ARM
|
||||
{88414ECD-0462-41DE-ABA9-462D2F154595}.Release|ARM.Build.0 = Release|ARM
|
||||
{88414ECD-0462-41DE-ABA9-462D2F154595}.Release|ARM.Deploy.0 = Release|ARM
|
||||
{88414ECD-0462-41DE-ABA9-462D2F154595}.Release|x64.ActiveCfg = Release|x64
|
||||
{88414ECD-0462-41DE-ABA9-462D2F154595}.Release|x64.Build.0 = Release|x64
|
||||
{88414ECD-0462-41DE-ABA9-462D2F154595}.Release|x64.Deploy.0 = Release|x64
|
||||
{88414ECD-0462-41DE-ABA9-462D2F154595}.Release|x86.ActiveCfg = Release|x86
|
||||
{88414ECD-0462-41DE-ABA9-462D2F154595}.Release|x86.Build.0 = Release|x86
|
||||
{88414ECD-0462-41DE-ABA9-462D2F154595}.Release|x86.Deploy.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,85 @@
|
||||
using HueUWP.Helpers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
|
||||
namespace HueUWP.Lights
|
||||
{
|
||||
public abstract class Light : INotifyPropertyChanged
|
||||
{
|
||||
public int ID { get; private set; }
|
||||
public string Name { get; private set; }
|
||||
public string Type { get; private set; }
|
||||
|
||||
public bool HueEnabled {get; set; }
|
||||
public bool SaturationEnabled { get; set; }
|
||||
public bool BrightnessEnabled { get; set; }
|
||||
|
||||
public Light(int id, string name, string type)
|
||||
{
|
||||
this.ID = id;
|
||||
this.Name = name;
|
||||
this.Type = type;
|
||||
}
|
||||
|
||||
//IsOn
|
||||
protected bool _isOn = false;
|
||||
public bool IsOn
|
||||
{
|
||||
get { return _isOn; }
|
||||
set { _isOn = value; NotifyPropertyChanged(nameof(IsOn)); }
|
||||
}
|
||||
|
||||
//Hue
|
||||
protected int _hue = 0;
|
||||
public int Hue
|
||||
{
|
||||
get { return _hue; }
|
||||
set { _hue = value; NotifyPropertyChanged(nameof(Hue)); NotifyPropertyChanged(nameof(Color)); }
|
||||
}
|
||||
|
||||
//Brightness
|
||||
protected int _brightness = 0;
|
||||
public int Brightness
|
||||
{
|
||||
get { return _brightness; }
|
||||
set { _brightness = value; NotifyPropertyChanged(nameof(Brightness)); NotifyPropertyChanged(nameof(Color)); }
|
||||
}
|
||||
|
||||
//Saturation
|
||||
protected int _saturation = 0;
|
||||
public int Saturation
|
||||
{
|
||||
get { return _saturation; }
|
||||
set { _saturation = value; NotifyPropertyChanged(nameof(Saturation)); NotifyPropertyChanged(nameof(Color)); }
|
||||
}
|
||||
|
||||
public SolidColorBrush Color
|
||||
{
|
||||
get { return new SolidColorBrush(ColorUtil.HsvToRgb(Hue, Saturation, Brightness)); }
|
||||
}
|
||||
|
||||
public abstract void SetState();
|
||||
|
||||
public abstract void SetColor(bool instant = false);
|
||||
|
||||
public abstract Task<String> Update();
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
protected virtual void NotifyPropertyChanged(string propertyName)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HueUWP.Lights
|
||||
{
|
||||
class LightGroup : Light
|
||||
{
|
||||
public LightGroup(int id, string name) : base(id, name, "Group")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void SetColor(bool instant = false)
|
||||
{
|
||||
App.api.SetGroupColor(this, instant);
|
||||
}
|
||||
|
||||
public override void SetState()
|
||||
{
|
||||
App.api.SetGroupState(this);
|
||||
}
|
||||
|
||||
public override async Task<String> Update()
|
||||
{
|
||||
return await App.api.UpdateGroup(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HueUWP.Lights
|
||||
{
|
||||
class LightGroupListDataSource
|
||||
{
|
||||
private ObservableCollection<Light> _groups;
|
||||
|
||||
public LightGroupListDataSource()
|
||||
{
|
||||
_groups = new ObservableCollection<Light>();
|
||||
}
|
||||
|
||||
public async Task<String> LoadGroups()
|
||||
{
|
||||
return await App.api.Groups(_groups);
|
||||
}
|
||||
|
||||
public ObservableCollection<Light> GetGroups()
|
||||
{
|
||||
return _groups;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_groups.Clear();
|
||||
}
|
||||
|
||||
public async Task<String> UpdateGroups()
|
||||
{
|
||||
foreach (Light g in _groups)
|
||||
{
|
||||
await g.Update();
|
||||
await Task.Delay(TimeSpan.FromMilliseconds(100));
|
||||
}
|
||||
|
||||
return "success";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HueUWP.Lights
|
||||
{
|
||||
|
||||
public class LightListDataSource
|
||||
{
|
||||
private ObservableCollection<Light> _lights;
|
||||
|
||||
public LightListDataSource()
|
||||
{
|
||||
_lights = new ObservableCollection<Light>();
|
||||
}
|
||||
|
||||
public async Task<String> LoadLights()
|
||||
{
|
||||
return await App.api.Lights(_lights);
|
||||
}
|
||||
|
||||
public ObservableCollection<Light> GetLights()
|
||||
{
|
||||
return _lights;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_lights.Clear();
|
||||
}
|
||||
|
||||
public async Task<String> UpdateLights()
|
||||
{
|
||||
foreach(Light l in _lights)
|
||||
{
|
||||
await l.Update();
|
||||
await Task.Delay(TimeSpan.FromMilliseconds(100));
|
||||
}
|
||||
|
||||
return "success";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
using HueUWP.Helpers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HueUWP.Lights
|
||||
{
|
||||
class LightMulti : Light
|
||||
{
|
||||
private List<Light> _lights;
|
||||
|
||||
public LightMulti(List<Light> lights) : base(0, "Multiple Lights", (lights.ToDelimitedString(l => l.Name)))
|
||||
{
|
||||
_lights = lights;
|
||||
Light l = _lights.First();
|
||||
|
||||
SaturationEnabled = true;
|
||||
HueEnabled = true;
|
||||
BrightnessEnabled = true;
|
||||
|
||||
_isOn = l.IsOn;
|
||||
|
||||
_hue = l.Hue;
|
||||
_brightness = l.Brightness;
|
||||
_saturation = l.Saturation;
|
||||
|
||||
NotifyPropertyChanged(nameof(IsOn));
|
||||
NotifyPropertyChanged(nameof(Hue));
|
||||
NotifyPropertyChanged(nameof(Saturation));
|
||||
NotifyPropertyChanged(nameof(Brightness));
|
||||
}
|
||||
|
||||
public override void SetColor(bool instant = false)
|
||||
{
|
||||
_lights.ForEach(l => { l.SetColor(instant); });
|
||||
}
|
||||
|
||||
public override void SetState()
|
||||
{
|
||||
_lights.ForEach(l => { l.SetState(); });
|
||||
}
|
||||
|
||||
public override async Task<String> Update()
|
||||
{
|
||||
//Do nothing, performance reasons
|
||||
return "success";
|
||||
}
|
||||
|
||||
protected override void NotifyPropertyChanged(string propertyName)
|
||||
{
|
||||
base.NotifyPropertyChanged(propertyName);
|
||||
_lights.ForEach(l => { l.IsOn = IsOn; l.Hue = Hue; l.Saturation = Saturation; l.Brightness = Brightness; });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
|
||||
namespace HueUWP.Lights
|
||||
{
|
||||
public class LightSingle : Light
|
||||
{
|
||||
public LightSingle(int id, string name, string type) : base (id, name, type)
|
||||
{
|
||||
}
|
||||
|
||||
public override void SetState()
|
||||
{
|
||||
App.api.SetLightState(this);
|
||||
}
|
||||
|
||||
public override void SetColor(bool instant = false)
|
||||
{
|
||||
App.api.SetLightColor(this, instant);
|
||||
}
|
||||
|
||||
public override async Task<String> Update()
|
||||
{
|
||||
return await App.api.UpdateLight(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<Page
|
||||
x:Class="HueUWP.MultiEdit"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:HueUWP"
|
||||
xmlns:convert="using:HueUWP.Helpers"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ctrl="using:Windows.UI.Xaml.Controls.Control"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Page.Resources>
|
||||
<convert:NullableBooleanConverter x:Key="BoolConverter"/>
|
||||
<convert:VisibilityConverter x:Key="VisibilityConverter"/>
|
||||
</Page.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<RelativePanel Grid.Row="0">
|
||||
<TextBlock RelativePanel.AlignLeftWithPanel="True" FontSize="24" Margin="20,10,0,0" Text="Miltiple Lights"/>
|
||||
</RelativePanel>
|
||||
<RelativePanel Grid.Row="1">
|
||||
<TextBlock RelativePanel.AlignLeftWithPanel="True" FontSize="14" Name="LightsSelectedField" Margin="20,10,0,0" Text="" TextWrapping="WrapWholeWords"/>
|
||||
</RelativePanel>
|
||||
<RelativePanel Grid.Row="2">
|
||||
<Rectangle Fill="Red" Name="ColorRectangle" RelativePanel.AlignLeftWithPanel="True" RelativePanel.AlignRightWithPanel="True" Height="20" Margin="0,10,0,10" />
|
||||
</RelativePanel>
|
||||
|
||||
<StackPanel Grid.Row="3">
|
||||
<ToggleSwitch Margin="20,10,0,10" Name="OnOffButton" Toggled="ToggleSwitch_Toggled" IsOn="False">
|
||||
<ToggleSwitch.OffContent>Off</ToggleSwitch.OffContent>
|
||||
<ToggleSwitch.OnContent>On</ToggleSwitch.OnContent>
|
||||
</ToggleSwitch>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Row="4">
|
||||
<StackPanel Margin="20,10,20,0" Visibility="Visible">
|
||||
<TextBlock FontSize="18">Hue</TextBlock>
|
||||
<Slider Maximum="65535" Name="HueSlider" Value="30000" ValueChanged="Slider_ValueChanged" PointerCaptureLost="Slider_Released"/>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Margin="20,10,20,0" Visibility="Visible">
|
||||
<TextBlock FontSize="18">Saturation</TextBlock>
|
||||
<Slider Maximum="254" Name="SaturationSlider" Value="254" ValueChanged="Slider_ValueChanged" PointerCaptureLost="Slider_Released" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Margin="20,10,20,0">
|
||||
<TextBlock FontSize="18">Brightness</TextBlock>
|
||||
<Slider Maximum="254" Name="BrightnessSlider" Value="254" ValueChanged="Slider_ValueChanged" PointerCaptureLost="Slider_Released"/>
|
||||
</StackPanel>
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Page>
|
||||
@@ -0,0 +1,85 @@
|
||||
using HueUWP.Helpers;
|
||||
using HueUWP.Lights;
|
||||
using HueUWP.Views;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
|
||||
|
||||
namespace HueUWP
|
||||
{
|
||||
/// <summary>
|
||||
/// An empty page that can be used on its own or navigated to within a Frame.
|
||||
/// </summary>
|
||||
public sealed partial class MultiEdit : Page
|
||||
{
|
||||
IList<Light> lights = new List<Light>();
|
||||
LightsView main;
|
||||
|
||||
public MultiEdit()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||
{
|
||||
main = e.Parameter as LightsView;
|
||||
|
||||
HueSlider.Value = 0;
|
||||
SaturationSlider.Value = 0;
|
||||
BrightnessSlider.Value = 0;
|
||||
OnOffButton.IsOn = false;
|
||||
|
||||
//foreach (var v in main.GetListView().SelectedItems)
|
||||
//{
|
||||
// Light l = (Light)v;
|
||||
// lights.Add(l);
|
||||
//}
|
||||
|
||||
LightsSelectedField.Text = lights.ToDelimitedString(l => l.Name);
|
||||
}
|
||||
|
||||
|
||||
private void Slider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
|
||||
{
|
||||
//l.UpdateColor();
|
||||
}
|
||||
|
||||
private void Slider_Released(object sender, PointerRoutedEventArgs e)
|
||||
{
|
||||
foreach (var l in lights)
|
||||
{
|
||||
l.Hue = (int)HueSlider.Value;
|
||||
l.Saturation = (int)SaturationSlider.Value;
|
||||
l.Brightness = (int)BrightnessSlider.Value;
|
||||
ColorRectangle.Fill = new SolidColorBrush(ColorUtil.getColor(l));
|
||||
l.SetColor();
|
||||
}
|
||||
}
|
||||
|
||||
private void ToggleSwitch_Toggled(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ToggleSwitch button = ((ToggleSwitch)sender);
|
||||
foreach (var l in lights)
|
||||
{
|
||||
|
||||
l.SetState();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.UI.Popups;
|
||||
using Windows.Web.Http;
|
||||
|
||||
namespace HueUWP
|
||||
{
|
||||
public class NetworkHandler
|
||||
{
|
||||
public NetworkHandler()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private static async Task<String> Put(string path, string json)
|
||||
{
|
||||
var cts = new CancellationTokenSource();
|
||||
cts.CancelAfter(5000);
|
||||
|
||||
//System.Diagnostics.Debug.WriteLine("PUT:\n" + path +"\n"+json);
|
||||
|
||||
try
|
||||
{
|
||||
HttpClient client = new HttpClient();
|
||||
HttpStringContent content = new HttpStringContent(json, Windows.Storage.Streams.UnicodeEncoding.Utf8, "application /json");
|
||||
|
||||
Uri uriLampState = new Uri($"http://{(string) App.LOCAL_SETTINGS.Values["ip"]}:{(int)App.LOCAL_SETTINGS.Values["port"]}/api/" + path);
|
||||
var response = await client.PutAsync(uriLampState, content).AsTask(cts.Token);
|
||||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
return "error";
|
||||
}
|
||||
|
||||
string jsonResponse = await response.Content.ReadAsStringAsync();
|
||||
|
||||
//System.Diagnostics.Debug.WriteLine(jsonResponse);
|
||||
|
||||
return jsonResponse;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(ex.Message);
|
||||
return "error";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static async Task<String> Post(string path, string json)
|
||||
{
|
||||
var cts = new CancellationTokenSource();
|
||||
cts.CancelAfter(5000);
|
||||
|
||||
try
|
||||
{
|
||||
HttpClient client = new HttpClient();
|
||||
HttpStringContent content = new HttpStringContent(json, Windows.Storage.Streams.UnicodeEncoding.Utf8, "application /json");
|
||||
|
||||
Uri uriLampState = new Uri($"http://{(string) App.LOCAL_SETTINGS.Values["ip"]}:{(int)App.LOCAL_SETTINGS.Values["port"]}/api/" + path);
|
||||
var response = await client.PostAsync(uriLampState, content).AsTask(cts.Token);
|
||||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
return "error";
|
||||
}
|
||||
|
||||
string jsonResponse = await response.Content.ReadAsStringAsync();
|
||||
|
||||
//System.Diagnostics.Debug.WriteLine(jsonResponse);
|
||||
|
||||
return jsonResponse;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(ex.Message);
|
||||
return "error";
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<String> Get(string path)
|
||||
{
|
||||
var cts = new CancellationTokenSource();
|
||||
cts.CancelAfter(5000);
|
||||
|
||||
try
|
||||
{
|
||||
HttpClient client = new HttpClient();
|
||||
//HttpStringContent content = new HttpStringContent($"{{\"devicetype\":\"Test#Test\"}}", Windows.Storage.Streams.UnicodeEncoding.Utf8, "application /json");
|
||||
|
||||
Uri uriLampState = new Uri($"http://{(string) App.LOCAL_SETTINGS.Values["ip"]}:{(int)App.LOCAL_SETTINGS.Values["port"]}/api/" + path);
|
||||
var response = await client.GetAsync(uriLampState).AsTask(cts.Token);
|
||||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
return "error";
|
||||
}
|
||||
|
||||
string jsonResponse = await response.Content.ReadAsStringAsync();
|
||||
|
||||
//System.Diagnostics.Debug.WriteLine(jsonResponse);
|
||||
|
||||
return jsonResponse;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(ex.Message);
|
||||
return "error";
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<String> Lights()
|
||||
{
|
||||
var response = await Get($"{(String)App.LOCAL_SETTINGS.Values["id"]}/lights");
|
||||
if (string.IsNullOrEmpty(response))
|
||||
return "error";
|
||||
return response;
|
||||
}
|
||||
|
||||
public static async Task<String> Light(int id)
|
||||
{
|
||||
var response = await Get($"{(String)App.LOCAL_SETTINGS.Values["id"]}/lights/{id}");
|
||||
if (string.IsNullOrEmpty(response))
|
||||
return "error";
|
||||
return response;
|
||||
}
|
||||
|
||||
public static async Task<String> SetLight(int lightid, string json)
|
||||
{
|
||||
var response = await Put($"{(String)App.LOCAL_SETTINGS.Values["id"]}/lights/{lightid}/state", json);
|
||||
return response;
|
||||
}
|
||||
|
||||
public static async Task<String> SetLight(int lightid, bool state)
|
||||
{
|
||||
string json = $"{{\"on\": { ((state) ? "true" : "false") }}}";
|
||||
var response = await Put($"{(String)App.LOCAL_SETTINGS.Values["id"]}/lights/{lightid}/state", json);
|
||||
return response;
|
||||
}
|
||||
|
||||
public static async Task<String> SetLight(int lightid, int hue, int saturation, int brightness, bool instant = false)
|
||||
{
|
||||
string json = $"{{\"hue\": {(hue)},\"bri\": {brightness},\"sat\": {saturation} {(instant ? ",\"transitiontime\":0" : "")}}}";
|
||||
var response = await Put($"{(String)App.LOCAL_SETTINGS.Values["id"]}/lights/{lightid}/state", json);
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static async Task<String> RegisterName(string AppName, string UserName)
|
||||
{
|
||||
var response = await Post("",$"{{\"devicetype\":\"{AppName}#{UserName}\"}}");
|
||||
if (string.IsNullOrEmpty(response))
|
||||
return "error";
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static async Task<String> Groups()
|
||||
{
|
||||
var response = await Get($"{(String)App.LOCAL_SETTINGS.Values["id"]}/groups");
|
||||
if (string.IsNullOrEmpty(response))
|
||||
return "error";
|
||||
return response;
|
||||
}
|
||||
|
||||
public static async Task<String> Group(int id)
|
||||
{
|
||||
var response = await Get($"{(String)App.LOCAL_SETTINGS.Values["id"]}/groups/{id}");
|
||||
if (string.IsNullOrEmpty(response))
|
||||
return "error";
|
||||
return response;
|
||||
}
|
||||
|
||||
public static async Task<String> SetGroup(int groupid, string json)
|
||||
{
|
||||
var response = await Put($"{(String)App.LOCAL_SETTINGS.Values["id"]}/groups/{groupid}/action", json);
|
||||
return response;
|
||||
}
|
||||
|
||||
public static async Task<String> SetGroup(int groupid, bool state)
|
||||
{
|
||||
string json = $"{{\"on\": { ((state) ? "true" : "false") }}}";
|
||||
var response = await Put($"{(String)App.LOCAL_SETTINGS.Values["id"]}/groups/{groupid}/action", json);
|
||||
return response;
|
||||
}
|
||||
|
||||
public static async Task<String> SetGroup(int groupid, int hue, int saturation, int brightness, bool instant = false)
|
||||
{
|
||||
string json = $"{{\"hue\": {(hue)},\"bri\": {brightness},\"sat\": {saturation} {(instant ? ",\"transitiontime\":0" : "")}}}";
|
||||
var response = await Put($"{(String)App.LOCAL_SETTINGS.Values["id"]}/groups/{groupid}/action", json);
|
||||
return response;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" IgnorableNamespaces="uap mp">
|
||||
<Identity Name="ce9a0222-308a-470c-a219-f3b5a133de19" Publisher="CN=Paul de Mast" Version="1.0.0.0" />
|
||||
<mp:PhoneIdentity PhoneProductId="ce9a0222-308a-470c-a219-f3b5a133de19" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
|
||||
<Properties>
|
||||
<DisplayName>CarCheckInUWP</DisplayName>
|
||||
<PublisherDisplayName>Paul de Mast</PublisherDisplayName>
|
||||
<Logo>Assets\StoreLogo.png</Logo>
|
||||
</Properties>
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
|
||||
</Dependencies>
|
||||
<Resources>
|
||||
<Resource Language="x-generate" />
|
||||
</Resources>
|
||||
<Applications>
|
||||
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="HueUWP.App">
|
||||
<uap:VisualElements DisplayName="YK Hue" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" Description="Philips Hue Light UWP Application" BackgroundColor="transparent">
|
||||
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png">
|
||||
</uap:DefaultTile>
|
||||
<uap:SplashScreen Image="Assets\SplashScreen.png" BackgroundColor="white" />
|
||||
</uap:VisualElements>
|
||||
</Application>
|
||||
</Applications>
|
||||
<Capabilities>
|
||||
<Capability Name="internetClient" />
|
||||
</Capabilities>
|
||||
</Package>
|
||||
@@ -0,0 +1,29 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("HueUWP")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("HueUWP")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2015")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: ComVisible(false)]
|
||||
@@ -0,0 +1,31 @@
|
||||
<!--
|
||||
This file contains Runtime Directives used by .NET Native. The defaults here are suitable for most
|
||||
developers. However, you can modify these parameters to modify the behavior of the .NET Native
|
||||
optimizer.
|
||||
|
||||
Runtime Directives are documented at http://go.microsoft.com/fwlink/?LinkID=391919
|
||||
|
||||
To fully enable reflection for App1.MyClass and all of its public/private members
|
||||
<Type Name="App1.MyClass" Dynamic="Required All"/>
|
||||
|
||||
To enable dynamic creation of the specific instantiation of AppClass<T> over System.Int32
|
||||
<TypeInstantiation Name="App1.AppClass" Arguments="System.Int32" Activate="Required Public" />
|
||||
|
||||
Using the Namespace directive to apply reflection policy to all the types in a particular namespace
|
||||
<Namespace Name="DataClasses.ViewModels" Seralize="All" />
|
||||
-->
|
||||
|
||||
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
|
||||
<Application>
|
||||
<!--
|
||||
An Assembly element with Name="*Application*" applies to all assemblies in
|
||||
the application package. The asterisks are not wildcards.
|
||||
-->
|
||||
<Assembly Name="*Application*" Dynamic="Required All" />
|
||||
|
||||
|
||||
<!-- Add your application specific runtime directives here. -->
|
||||
|
||||
|
||||
</Application>
|
||||
</Directives>
|
||||
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage;
|
||||
|
||||
namespace HueUWP
|
||||
{
|
||||
public class SettingsViewModel : INotifyPropertyChanged
|
||||
{
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
private void NotifyPropertyChanged(string propertyName)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
public string IP
|
||||
{
|
||||
get { return App.LOCAL_SETTINGS.Values["ip"] as string; }
|
||||
set { App.LOCAL_SETTINGS.Values["ip"] = value; NotifyPropertyChanged(nameof(IP)); }
|
||||
}
|
||||
|
||||
public string PORT
|
||||
{
|
||||
get { return Convert.ToInt32(App.LOCAL_SETTINGS.Values["port"]).ToString(); }
|
||||
set { App.LOCAL_SETTINGS.Values["port"] = int.Parse(value); NotifyPropertyChanged(nameof(PORT)); }
|
||||
}
|
||||
|
||||
public bool AUTOREFRESH
|
||||
{
|
||||
get { return (bool)(App.LOCAL_SETTINGS.Values["autorefresh"]); }
|
||||
set { App.LOCAL_SETTINGS.Values["autorefresh"] = value; NotifyPropertyChanged(nameof(AUTOREFRESH)); }
|
||||
}
|
||||
|
||||
public string ID
|
||||
{
|
||||
get { return App.LOCAL_SETTINGS.Values["id"] as string; }
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
NotifyPropertyChanged(nameof(ID));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:HueUWP.Themes">
|
||||
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="White" />
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
@@ -0,0 +1,5 @@
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:HueUWP.Themes">
|
||||
</ResourceDictionary>
|
||||
@@ -0,0 +1,4 @@
|
||||
Todo
|
||||
- About pagina mooier maken.
|
||||
- Group view pagina -> Mainpage moet dan eigenlijk een lamp list ding worden, en die kan je dan ook aanroepen met een group.
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
<Page
|
||||
x:Class="HueUWP.Views.AboutView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:HueUWP.Views"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<RelativePanel Grid.Row="0">
|
||||
<TextBlock RelativePanel.AlignLeftWithPanel="True" FontSize="24" Margin="20,10,0,0">About</TextBlock>
|
||||
</RelativePanel>
|
||||
|
||||
<StackPanel Grid.Row="1">
|
||||
<TextBlock Margin="20,10,20,0">Made by Kenneth and Yorick.</TextBlock>
|
||||
<HyperlinkButton Margin="20,10,20,0" Content="Yorick Rommers" NavigateUri="http://imegumii.space"/>
|
||||
<HyperlinkButton Margin="20,10,20,0" Content="Kenneth van Ewijk" NavigateUri="http://kvanewijk.nl/"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Page>
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
|
||||
|
||||
namespace HueUWP.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// An empty page that can be used on its own or navigated to within a Frame.
|
||||
/// </summary>
|
||||
public sealed partial class AboutView : Page
|
||||
{
|
||||
public AboutView()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<Page
|
||||
x:Class="HueUWP.Views.DetailView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:HueUWP.Views"
|
||||
xmlns:convert="using:HueUWP.Helpers"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ctrl="using:Windows.UI.Xaml.Controls.Control"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Page.Resources>
|
||||
<convert:NullableBooleanConverter x:Key="BoolConverter"/>
|
||||
<convert:VisibilityConverter x:Key="VisibilityConverter"/>
|
||||
</Page.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<RelativePanel Grid.Row="0">
|
||||
<TextBlock RelativePanel.AlignLeftWithPanel="True" FontSize="24" Margin="20,10,0,0" Text="{Binding Name}"/>
|
||||
</RelativePanel>
|
||||
<RelativePanel Grid.Row="1">
|
||||
<TextBlock RelativePanel.AlignLeftWithPanel="True" FontSize="14" Margin="20,10,0,0" Text="{Binding Type}" TextWrapping="WrapWholeWords"/>
|
||||
</RelativePanel>
|
||||
<RelativePanel Grid.Row="2">
|
||||
<Rectangle Fill="{Binding Color}" RelativePanel.AlignLeftWithPanel="True" RelativePanel.AlignRightWithPanel="True" Height="20" Margin="0,10,0,10" />
|
||||
</RelativePanel>
|
||||
|
||||
<StackPanel Grid.Row="3">
|
||||
<ToggleSwitch Margin="20,10,0,10" Toggled="ToggleSwitch_Toggled" IsOn="{Binding IsOn, Mode=TwoWay, Converter={StaticResource BoolConverter}}">
|
||||
<ToggleSwitch.OffContent>Off</ToggleSwitch.OffContent>
|
||||
<ToggleSwitch.OnContent>On</ToggleSwitch.OnContent>
|
||||
</ToggleSwitch>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Row="4">
|
||||
<StackPanel Margin="20,10,20,0" Visibility="{Binding HueEnabled, Converter={StaticResource VisibilityConverter}}">
|
||||
<TextBlock FontSize="18">Hue</TextBlock>
|
||||
<Slider Maximum="65535" Value="{Binding Hue, Mode=TwoWay}" PointerCaptureLost="Slider_Released"/>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Margin="20,10,20,0" Visibility="{Binding SaturationEnabled, Converter={StaticResource VisibilityConverter}}">
|
||||
<TextBlock FontSize="18">Saturation</TextBlock>
|
||||
<Slider Maximum="254" Value="{Binding Saturation, Mode=TwoWay}" PointerCaptureLost="Slider_Released" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Margin="20,10,20,0" Visibility="{Binding BrightnessEnabled, Converter={StaticResource VisibilityConverter}}">
|
||||
<TextBlock FontSize="18">Brightness</TextBlock>
|
||||
<Slider Maximum="254" Value="{Binding Brightness, Mode=TwoWay}" PointerCaptureLost="Slider_Released"/>
|
||||
</StackPanel>
|
||||
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Page>
|
||||
@@ -0,0 +1,68 @@
|
||||
using HueUWP.Lights;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
|
||||
|
||||
namespace HueUWP.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// An empty page that can be used on its own or navigated to within a Frame.
|
||||
/// </summary>
|
||||
public sealed partial class DetailView : Page
|
||||
{
|
||||
Light l;
|
||||
DispatcherTimer timer;
|
||||
|
||||
public DetailView()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
timer = new DispatcherTimer();
|
||||
timer.Interval = TimeSpan.FromSeconds(3);
|
||||
timer.Tick += Timer_Tick;
|
||||
}
|
||||
|
||||
private void Timer_Tick(object sender, object e)
|
||||
{
|
||||
l.Update();
|
||||
}
|
||||
|
||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||
{
|
||||
l = e.Parameter as Light;
|
||||
this.DataContext = l;
|
||||
timer.Start();
|
||||
}
|
||||
|
||||
protected override void OnNavigatedFrom(NavigationEventArgs e)
|
||||
{
|
||||
timer.Stop();
|
||||
}
|
||||
|
||||
private void Slider_Released(object sender, PointerRoutedEventArgs e)
|
||||
{
|
||||
l.SetColor();
|
||||
}
|
||||
|
||||
private void ToggleSwitch_Toggled(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ToggleSwitch button = ((ToggleSwitch)sender);
|
||||
Light light = (Light)button.DataContext;
|
||||
if (light != null)
|
||||
light.SetState();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<Page
|
||||
x:Class="HueUWP.Views.GroupsView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:HueUWP.Views"
|
||||
xmlns:convert="using:HueUWP.Helpers"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Page.Resources>
|
||||
<convert:NullableBooleanConverter x:Key="BoolConverter"/>
|
||||
</Page.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<RelativePanel Grid.Row="0">
|
||||
<TextBlock RelativePanel.AlignLeftWithPanel="True" FontSize="24" Margin="20,10,0,0">Hue Groups</TextBlock>
|
||||
</RelativePanel>
|
||||
|
||||
<RelativePanel Grid.Row="1" Visibility="Visible" Name="FeedbackPanel">
|
||||
<ProgressRing Height="60" Width="60" RelativePanel.AlignHorizontalCenterWithPanel="True" Margin=" 0,10,0,10" IsActive="True" Name="Loading" />
|
||||
<TextBlock RelativePanel.AlignLeftWithPanel="True" Name="ErrorMessage" Margin="20,10,0,10"/>
|
||||
</RelativePanel>
|
||||
|
||||
|
||||
<RelativePanel Grid.Row="2" Margin="0,10,0,0" Name="GroupListPanel">
|
||||
<ListView x:Name="GroupsList" ItemsSource="{Binding}" IsItemClickEnabled="True" ItemClick="GroupsList_ItemClick" SelectionMode="Extended" RelativePanel.AlignBottomWithPanel="True" RelativePanel.AlignTopWithPanel="True" RelativePanel.AlignLeftWithPanel="True" RelativePanel.AlignRightWithPanel="True">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate x:Name="ListViewDataTemplate">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Rectangle Width="30" Height="30" Fill="{Binding Color}" Margin="10,0,0,0"/>
|
||||
|
||||
<StackPanel Orientation="Vertical" Width="140" Margin="10,0,0,0" >
|
||||
<TextBlock Text="{Binding Name}" FontSize="24" />
|
||||
<TextBlock Text="{Binding Type}" FontSize="14" />
|
||||
</StackPanel>
|
||||
|
||||
<ToggleSwitch Margin="10,0,00,0" Toggled="ToggleSwitch_Toggled" IsOn="{Binding IsOn, Mode=TwoWay, Converter={StaticResource BoolConverter}}">
|
||||
<ToggleSwitch.OffContent>Off</ToggleSwitch.OffContent>
|
||||
<ToggleSwitch.OnContent>On</ToggleSwitch.OnContent>
|
||||
</ToggleSwitch>
|
||||
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
|
||||
</ListView>
|
||||
</RelativePanel>
|
||||
|
||||
</Grid>
|
||||
</Page>
|
||||
@@ -0,0 +1,124 @@
|
||||
using HueUWP.Lights;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
|
||||
|
||||
namespace HueUWP.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// An empty page that can be used on its own or navigated to within a Frame.
|
||||
/// </summary>
|
||||
public sealed partial class GroupsView : Page
|
||||
{
|
||||
|
||||
private LightGroupListDataSource _groupsViewModel;
|
||||
public ObservableCollection<Light> GroupsViewModel
|
||||
{
|
||||
get { return _groupsViewModel.GetGroups(); }
|
||||
}
|
||||
|
||||
DispatcherTimer timer;
|
||||
|
||||
public GroupsView()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.NavigationCacheMode = NavigationCacheMode.Enabled;
|
||||
|
||||
_groupsViewModel = new LightGroupListDataSource();
|
||||
|
||||
timer = new DispatcherTimer();
|
||||
timer.Interval = TimeSpan.FromSeconds(60);
|
||||
timer.Tick += Timer_Tick;
|
||||
}
|
||||
|
||||
private void Timer_Tick(object sender, object e)
|
||||
{
|
||||
QuietReloadGroups();
|
||||
}
|
||||
|
||||
private void StartTimer()
|
||||
{
|
||||
if ((bool)App.LOCAL_SETTINGS.Values["autorefresh"])
|
||||
{
|
||||
QuietReloadGroups();
|
||||
timer.Start();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||
{
|
||||
if (e.NavigationMode == NavigationMode.New)
|
||||
ReloadGroups();
|
||||
else
|
||||
{
|
||||
GroupsList.SelectedItems.Clear();
|
||||
StartTimer();
|
||||
}
|
||||
this.DataContext = GroupsViewModel;
|
||||
}
|
||||
|
||||
protected override void OnNavigatedFrom(NavigationEventArgs e)
|
||||
{
|
||||
timer.Stop();
|
||||
}
|
||||
|
||||
private async void ReloadGroups()
|
||||
{
|
||||
timer.Stop();
|
||||
ErrorMessage.Text = "";
|
||||
FeedbackPanel.Visibility = Visibility.Visible;
|
||||
_groupsViewModel.Clear();
|
||||
|
||||
|
||||
Loading.IsActive = true;
|
||||
string s = await _groupsViewModel.LoadGroups();
|
||||
|
||||
if (s == "error")
|
||||
ErrorMessage.Text = "There was a problem connecting...";
|
||||
else if (_groupsViewModel.GetGroups().Count < 1)
|
||||
ErrorMessage.Text = "No groups found...";
|
||||
else
|
||||
{
|
||||
FeedbackPanel.Visibility = Visibility.Collapsed;
|
||||
StartTimer();
|
||||
}
|
||||
|
||||
Loading.IsActive = false;
|
||||
}
|
||||
|
||||
private async void QuietReloadGroups()
|
||||
{
|
||||
string s = await _groupsViewModel.UpdateGroups();
|
||||
}
|
||||
|
||||
private void GroupsList_ItemClick(object sender, ItemClickEventArgs e)
|
||||
{
|
||||
Light g = e.ClickedItem as Light;
|
||||
Frame rootframe = Window.Current.Content as Frame;
|
||||
if (g != null)
|
||||
rootframe.Navigate(typeof(DetailView), g);
|
||||
}
|
||||
|
||||
private void ToggleSwitch_Toggled(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ToggleSwitch button = ((ToggleSwitch)sender);
|
||||
Light group = (Light)button.DataContext;
|
||||
if (group != null)
|
||||
group.SetState();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
<Page
|
||||
x:Class="HueUWP.Views.LightsView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:HueUWP.Views"
|
||||
xmlns:convert="using:HueUWP.Helpers"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Page.Resources>
|
||||
<convert:NullableBooleanConverter x:Key="BoolConverter"/>
|
||||
</Page.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<RelativePanel Grid.Row="0">
|
||||
<TextBlock RelativePanel.AlignLeftWithPanel="True" FontSize="24" Margin="20,10,0,0">Hue Lights</TextBlock>
|
||||
</RelativePanel>
|
||||
|
||||
<RelativePanel Grid.Row="1" Visibility="Visible" Name="FeedbackPanel">
|
||||
<ProgressRing Height="60" Width="60" RelativePanel.AlignHorizontalCenterWithPanel="True" Margin=" 0,10,0,10" IsActive="True" Name="Loading" />
|
||||
<TextBlock RelativePanel.AlignLeftWithPanel="True" Name="ErrorMessage" Margin="20,10,0,10"/>
|
||||
</RelativePanel>
|
||||
|
||||
|
||||
<RelativePanel Grid.Row="2" Margin="0,10,0,0" Name="LightListPanel">
|
||||
<ListView x:Name="LightsList" ItemsSource="{Binding}" IsItemClickEnabled="True" ItemClick="LightsList_ItemClick" SelectionMode="Extended" RelativePanel.AlignBottomWithPanel="True" RelativePanel.AlignTopWithPanel="True" RelativePanel.AlignLeftWithPanel="True" RelativePanel.AlignRightWithPanel="True">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate x:Name="ListViewDataTemplate">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Rectangle Width="30" Height="30" Fill="{Binding Color}" Margin="10,0,0,0"/>
|
||||
|
||||
<StackPanel Orientation="Vertical" Width="140" Margin="10,0,0,0" >
|
||||
<TextBlock Text="{Binding Name}" FontSize="24" />
|
||||
<TextBlock Text="{Binding Type}" FontSize="14" />
|
||||
</StackPanel>
|
||||
|
||||
<ToggleSwitch Margin="10,0,00,0" Toggled="ToggleSwitch_Toggled" IsOn="{Binding IsOn, Mode=TwoWay, Converter={StaticResource BoolConverter}}">
|
||||
<ToggleSwitch.OffContent>Off</ToggleSwitch.OffContent>
|
||||
<ToggleSwitch.OnContent>On</ToggleSwitch.OnContent>
|
||||
</ToggleSwitch>
|
||||
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
|
||||
</ListView>
|
||||
</RelativePanel>
|
||||
|
||||
</Grid>
|
||||
|
||||
<Page.BottomAppBar>
|
||||
<CommandBar>
|
||||
<!-- Update values -->
|
||||
<AppBarButton Label="Change values" Name="ValuesButton" Click="ValuesButton_Click" Visibility="Collapsed">
|
||||
<AppBarButton.Icon>
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph=""/>
|
||||
</AppBarButton.Icon>
|
||||
</AppBarButton>
|
||||
<!-- Update on/off -->
|
||||
<AppBarButton Label="On" Name="OnOffButton" Click="OnOffButton_Click" Visibility="Collapsed">
|
||||
<AppBarButton.Icon>
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph=""/>
|
||||
</AppBarButton.Icon>
|
||||
</AppBarButton>
|
||||
<!-- Group -->
|
||||
<AppBarToggleButton Label="Select" Name="GroupButton" Click="GroupButton_Click">
|
||||
<AppBarToggleButton.Icon>
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph=""/>
|
||||
</AppBarToggleButton.Icon>
|
||||
</AppBarToggleButton>
|
||||
|
||||
<AppBarSeparator Name="Seperator" />
|
||||
|
||||
<!-- Disco -->
|
||||
<AppBarToggleButton Label="Disco" Name="DiscoButton" Click="DiscoButton_Click">
|
||||
<AppBarToggleButton.Icon>
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph=""/>
|
||||
</AppBarToggleButton.Icon>
|
||||
</AppBarToggleButton>
|
||||
|
||||
<!-- Settings -->
|
||||
<AppBarButton Label="Settings" Name="SettingsButton" Click="SettingsButton_Click">
|
||||
<AppBarButton.Icon>
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph=""/>
|
||||
</AppBarButton.Icon>
|
||||
</AppBarButton>
|
||||
<!-- Refresh -->
|
||||
<AppBarButton Label="Refresh" Name="RefreshButton" Click="RefreshButton_Click">
|
||||
<AppBarButton.Icon>
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph=""/>
|
||||
</AppBarButton.Icon>
|
||||
</AppBarButton>
|
||||
|
||||
|
||||
<CommandBar.SecondaryCommands>
|
||||
<AppBarButton Label="About" Click="AboutButton_Click"/>
|
||||
<AppBarButton Label="Groups" Click="GroupsButton_Click"/>
|
||||
</CommandBar.SecondaryCommands>
|
||||
</CommandBar>
|
||||
</Page.BottomAppBar>
|
||||
|
||||
</Page>
|
||||
|
||||
@@ -0,0 +1,249 @@
|
||||
using HueUWP.Lights;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using Windows.Storage;
|
||||
using Windows.UI.Core;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
namespace HueUWP.Views
|
||||
{
|
||||
public sealed partial class LightsView : Page
|
||||
{
|
||||
private LightListDataSource _lightsViewModel;
|
||||
public ObservableCollection<Light> LightsViewModel
|
||||
{
|
||||
get { return _lightsViewModel.GetLights(); }
|
||||
}
|
||||
|
||||
DispatcherTimer timer;
|
||||
|
||||
public LightsView()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.NavigationCacheMode = NavigationCacheMode.Enabled;
|
||||
|
||||
SystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested;
|
||||
Application.Current.Suspending += Current_Suspending;
|
||||
Application.Current.Resuming += Current_Resuming;
|
||||
|
||||
_lightsViewModel = new LightListDataSource();
|
||||
|
||||
timer = new DispatcherTimer();
|
||||
timer.Interval = TimeSpan.FromSeconds(8);
|
||||
timer.Tick += Timer_Tick;
|
||||
}
|
||||
|
||||
private void Current_Resuming(object sender, object e)
|
||||
{
|
||||
if ((bool)DiscoButton.IsChecked)
|
||||
App.api.DiscoMode(_lightsViewModel.GetLights());
|
||||
}
|
||||
|
||||
private void Current_Suspending(object sender, Windows.ApplicationModel.SuspendingEventArgs e)
|
||||
{
|
||||
App.api.DiscoMode(false);
|
||||
}
|
||||
|
||||
private void OnBackRequested(object sender, BackRequestedEventArgs e)
|
||||
{
|
||||
if((bool)GroupButton.IsChecked)
|
||||
{
|
||||
GroupButton.IsChecked = false;
|
||||
GroupButton_Click(this, new RoutedEventArgs());
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void Timer_Tick(object sender, object e)
|
||||
{
|
||||
QuietReloadLights();
|
||||
}
|
||||
|
||||
private void StartTimer()
|
||||
{
|
||||
if ((bool)App.LOCAL_SETTINGS.Values["autorefresh"])
|
||||
{
|
||||
QuietReloadLights();
|
||||
timer.Start();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||
{
|
||||
if (e.NavigationMode == NavigationMode.New)
|
||||
ReloadLights();
|
||||
else
|
||||
{
|
||||
LightsList.SelectedItems.Clear();
|
||||
StartTimer();
|
||||
}
|
||||
|
||||
this.DataContext = LightsViewModel;
|
||||
}
|
||||
|
||||
protected override void OnNavigatedFrom(NavigationEventArgs e)
|
||||
{
|
||||
timer.Stop();
|
||||
}
|
||||
|
||||
private async void QuietReloadLights()
|
||||
{
|
||||
string s = await _lightsViewModel.UpdateLights();
|
||||
}
|
||||
|
||||
private async void ReloadLights()
|
||||
{
|
||||
timer.Stop();
|
||||
ErrorMessage.Text = "";
|
||||
FeedbackPanel.Visibility = Visibility.Visible;
|
||||
_lightsViewModel.Clear();
|
||||
|
||||
Loading.IsActive = true;
|
||||
string s = await _lightsViewModel.LoadLights();
|
||||
|
||||
if (s == "error")
|
||||
ErrorMessage.Text = "There was a problem connecting...";
|
||||
else if (_lightsViewModel.GetLights().Count < 1)
|
||||
ErrorMessage.Text = "No lights found...";
|
||||
else
|
||||
{
|
||||
FeedbackPanel.Visibility = Visibility.Collapsed;
|
||||
StartTimer();
|
||||
}
|
||||
|
||||
Loading.IsActive = false;
|
||||
}
|
||||
|
||||
private void ToggleSwitch_Toggled(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ToggleSwitch button = ((ToggleSwitch)sender);
|
||||
Light light = (Light)button.DataContext;
|
||||
if(light != null)
|
||||
light.SetState();
|
||||
}
|
||||
|
||||
private void SettingsButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Frame rootframe = Window.Current.Content as Frame;
|
||||
rootframe.Navigate(typeof(SettingsView));
|
||||
}
|
||||
|
||||
private void RefreshButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ReloadLights();
|
||||
}
|
||||
|
||||
private void LightsList_ItemClick(object sender, ItemClickEventArgs e)
|
||||
{
|
||||
Light l = e.ClickedItem as Light;
|
||||
Frame rootframe = Window.Current.Content as Frame;
|
||||
if (l != null)
|
||||
rootframe.Navigate(typeof(DetailView), l);
|
||||
}
|
||||
|
||||
private void AboutButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Frame rootframe = Window.Current.Content as Frame;
|
||||
rootframe.Navigate(typeof(AboutView));
|
||||
}
|
||||
|
||||
private void GroupsButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Frame rootframe = Window.Current.Content as Frame;
|
||||
rootframe.Navigate(typeof(GroupsView));
|
||||
}
|
||||
|
||||
private void DiscoButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if ((bool)DiscoButton.IsChecked)
|
||||
App.api.DiscoMode(_lightsViewModel.GetLights());
|
||||
else
|
||||
App.api.DiscoMode(false);
|
||||
}
|
||||
|
||||
private void GroupButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
|
||||
if ((bool)GroupButton.IsChecked)
|
||||
{
|
||||
LightsList.IsItemClickEnabled = false;
|
||||
LightsList.SelectionMode = ListViewSelectionMode.Multiple;
|
||||
OnOffButton.Visibility = Visibility.Visible;
|
||||
ValuesButton.Visibility = Visibility.Visible;
|
||||
|
||||
Seperator.Visibility = Visibility.Collapsed;
|
||||
DiscoButton.Visibility = Visibility.Collapsed;
|
||||
RefreshButton.Visibility = Visibility.Collapsed;
|
||||
SettingsButton.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
else
|
||||
{
|
||||
LightsList.IsItemClickEnabled = true;
|
||||
LightsList.SelectionMode = ListViewSelectionMode.Single;
|
||||
OnOffButton.Visibility = Visibility.Collapsed;
|
||||
ValuesButton.Visibility = Visibility.Collapsed;
|
||||
|
||||
Seperator.Visibility = Visibility.Visible;
|
||||
DiscoButton.Visibility = Visibility.Visible;
|
||||
RefreshButton.Visibility = Visibility.Visible;
|
||||
SettingsButton.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void OnOffButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
bool toggle = false;
|
||||
|
||||
if(OnOffButton.Label == "Off")
|
||||
{
|
||||
toggle = false;
|
||||
OnOffButton.Label = "On";
|
||||
}
|
||||
else
|
||||
{
|
||||
toggle = true;
|
||||
OnOffButton.Label = "Off";
|
||||
}
|
||||
|
||||
if ((bool)GroupButton.IsChecked)
|
||||
{
|
||||
foreach(var v in LightsList.SelectedItems)
|
||||
{
|
||||
((Light)v).IsOn = toggle;
|
||||
((Light)v).SetState();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ValuesButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if ((bool)GroupButton.IsChecked)
|
||||
{
|
||||
Frame rootframe = Window.Current.Content as Frame;
|
||||
if (LightsList.SelectedItems != null)
|
||||
{
|
||||
Light multilight = new LightMulti( LightsList.SelectedItems.Cast<Light>().ToList() );
|
||||
rootframe.Navigate(typeof(DetailView), multilight);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<Page
|
||||
x:Class="HueUWP.Views.SettingsView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:HueUWP.Views"
|
||||
xmlns:convert="using:HueUWP.Helpers"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
<!--DataContext="{Binding SettingsViewModel, RelativeSource={RelativeSource Self}}"-->
|
||||
|
||||
<Page.Resources>
|
||||
<convert:NullableBooleanConverter x:Key="BoolConverter"/>
|
||||
</Page.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<RelativePanel Grid.Row="0">
|
||||
<TextBlock RelativePanel.AlignLeftWithPanel="True" FontSize="24" Margin="20,10,0,0">Settings</TextBlock>
|
||||
</RelativePanel>
|
||||
|
||||
<RelativePanel Grid.Row="1">
|
||||
<ScrollViewer RelativePanel.AlignBottomWithPanel="True" RelativePanel.AlignTopWithPanel="True">
|
||||
<StackPanel>
|
||||
|
||||
<StackPanel Margin="20, 10, 20, 0">
|
||||
<TextBlock FontSize="16">Automatic Refreshing</TextBlock>
|
||||
<ToggleSwitch Margin="0,10,0,10" IsOn="{x:Bind SettingsViewModel.AUTOREFRESH, Mode=TwoWay, Converter={StaticResource BoolConverter}}">
|
||||
<ToggleSwitch.OffContent>Off</ToggleSwitch.OffContent>
|
||||
<ToggleSwitch.OnContent>On</ToggleSwitch.OnContent>
|
||||
</ToggleSwitch>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Margin="20, 10, 20, 0">
|
||||
<TextBlock FontSize="16">Server IP</TextBlock>
|
||||
<TextBox Margin="0,10,0,10" Text="{x:Bind SettingsViewModel.IP, Mode=TwoWay}" PlaceholderText="145.48.205.190"/>
|
||||
</StackPanel>
|
||||
<StackPanel Margin="20, 10, 20, 0">
|
||||
<TextBlock FontSize="16">Server Port</TextBlock>
|
||||
<TextBox Margin="0,10,0,10" Text="{x:Bind SettingsViewModel.PORT, Mode=TwoWay}" PlaceholderText="80" />
|
||||
</StackPanel>
|
||||
<StackPanel Margin="20, 10, 20, 0">
|
||||
<TextBlock FontSize="16">User ID</TextBlock>
|
||||
<TextBox Name="IDBox" Margin="0,10,0,10" Text="{x:Bind SettingsViewModel.ID, Mode=OneWay}" IsEnabled="False"/>
|
||||
<StackPanel Orientation="Horizontal" Margin="0,10,0,10">
|
||||
<Button Click="UpdateID_Click">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock FontFamily="Segoe MDL2 Assets" FontSize="15" Margin="5, 9, 5, 5" Text="" />
|
||||
<TextBlock FontSize="15" Margin="5" Text="Request new" />
|
||||
</StackPanel>
|
||||
</Button>
|
||||
|
||||
<ProgressRing Height="35" Width="35" Margin="20, 0, 0, 0" IsActive="False" Name="UserIdProgress" />
|
||||
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</RelativePanel>
|
||||
</Grid>
|
||||
</Page>
|
||||
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using Windows.UI;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
|
||||
|
||||
namespace HueUWP.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// An empty page that can be used on its own or navigated to within a Frame.
|
||||
/// </summary>
|
||||
public sealed partial class SettingsView : Page
|
||||
{
|
||||
public SettingsViewModel SettingsViewModel = new SettingsViewModel();
|
||||
|
||||
public SettingsView()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
//SettingsViewModel = new SettingsViewModel();
|
||||
}
|
||||
|
||||
private async void UpdateID_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
IDBox.Background = default(Brush);
|
||||
|
||||
UserIdProgress.IsActive = true;
|
||||
string s = await App.api.Register();
|
||||
if (s == "error")
|
||||
IDBox.Background = new SolidColorBrush(Colors.Red);
|
||||
else
|
||||
SettingsViewModel.Update();
|
||||
UserIdProgress.IsActive = false;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.UniversalWindowsPlatform": "5.0.0",
|
||||
"Newtonsoft.Json": "7.0.1"
|
||||
},
|
||||
"frameworks": {
|
||||
"uap10.0": {}
|
||||
},
|
||||
"runtimes": {
|
||||
"win10-arm": {},
|
||||
"win10-arm-aot": {},
|
||||
"win10-x86": {},
|
||||
"win10-x86-aot": {},
|
||||
"win10-x64": {},
|
||||
"win10-x64-aot": {}
|
||||
}
|
||||
}
|
||||