Complete rewrite of binding. Added groups. Added auto refresh and background updating. Better handling of multiple lights.

This commit is contained in:
2015-12-11 01:16:39 +01:00
parent a65ae57d7b
commit b0e77c3fb8
29 changed files with 1403 additions and 840 deletions
+174 -60
View File
@@ -1,4 +1,5 @@
using Newtonsoft.Json.Linq;
using HueUWP.Helpers;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
@@ -8,6 +9,7 @@ using System.Text;
using System.Threading.Tasks;
using System.Threading;
using Windows.Storage;
using HueUWP.Lights;
namespace HueUWP
{
@@ -15,21 +17,19 @@ namespace HueUWP
{
bool discomode = false;
NetworkHandler nwh;
public APIHandler(NetworkHandler nwh)
public APIHandler()
{
this.nwh = nwh;
}
public async Task<String> Register()
{
try
{
var json = await nwh.RegisterName("YK Hue", "YK");
var json = await NetworkHandler.RegisterName("YK Hue", "YK");
json = json.Replace("[", "").Replace("]", "");
JObject o = JObject.Parse(json);
string id = o["success"]["username"].ToString();
MainPage.LOCAL_SETTINGS.Values["id"] = id;
App.LOCAL_SETTINGS.Values["id"] = id;
return "success";
}
catch (Exception e)
@@ -39,90 +39,183 @@ namespace HueUWP
}
}
public async void SetLightState(Light l)
public async Task<String> UpdateGroup(Light g)
{
var json = await nwh.SetLightInfo(l.ID, $"{{\"on\": {((l.IsOn) ? "true" : "false")}}}");
Debug.WriteLine(json);
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;
g.Hue = (int)state["hue"];
g.Brightness = (int)state["bri"];
g.Saturation = (int)state["sat"];
return "success";
}
public async void SetLightState(List<Light> lights)
public async Task<String> UpdateLight(Light l)
{
lights.ForEach(l => SetLightState(l));
string json = await NetworkHandler.Light(l.ID);
JObject o = JObject.Parse(json);
var state = o["state"];
l.IsOn = ((string)state["on"]).ToLower() == "true" ? true : false;
l.Hue = (int)state["hue"];
l.Brightness = (int)state["bri"];
l.Saturation = (int)state["sat"];
return "success";
}
public async void DiscoMode(ObservableCollection<Light> lights)
public async Task<String> SetLightState(Light l)
{
discomode = true;
Random rnd = new Random();
while(discomode)
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)
{
lights.ToList().ForEach(l =>
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)
{
l.Hue = rnd.Next(0, 65535);
l.Brightness = rnd.Next(128, 254);
l.Saturation = 254;
l.UpdateColorDisco();
});
//"transitiontime": 0
await Task.Delay(TimeSpan.FromMilliseconds(400));
}
}
var groupjson = await NetworkHandler.Group(Int32.Parse(i.Key));
JObject o2 = JObject.Parse(groupjson);
var state = o2["action"];
public async void DiscoMode(bool on)
{
discomode = on;
}
Light g = new LightGroup(Int32.Parse(i.Key), (string)o2["name"]);
public async Task<String> SetLightValues(Light l)
{
if(l.IsOn)
{
Debug.WriteLine(l.Hue);
var json = await nwh.SetLightInfo(l.ID, $"{{\"bri\": {l.Brightness},\"hue\": {(l.Hue)},\"sat\": {l.Saturation}}}");
Debug.WriteLine(json);
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";
}
return "error";
}
public async Task<String> SetInstantLightValues(Light l)
{
if (l.IsOn)
catch (Exception e)
{
Debug.WriteLine(l.Hue);
var json = await nwh.SetLightInfo(l.ID, $"{{\"bri\": {l.Brightness},\"hue\": {(l.Hue)},\"sat\": {l.Saturation}, \"transitiontime\" : 0}}");
Debug.WriteLine(json);
return "success";
Debug.WriteLine(e.StackTrace);
Debug.WriteLine("Could not get all groups.");
return "error";
}
return "error";
}
public async void SetLightValues(List<Light> lights)
public async Task<String> Lights(ObservableCollection<Light> lights)
{
lights.ForEach(l => SetLightValues(l));
}
public async Task<String> GetAllLights(ObservableCollection<Light> alllights)
{
// List<Light> lightlist = new List<Light>();
//List<Light> _lights = new List<Light>();
try {
var json = await nwh.AllLights();
var json = await NetworkHandler.Lights();
JObject o = JObject.Parse(json);
foreach(var i in o)
{
var light = o["" + i.Key];
var state = light["state"];
if ((String)light["type"] != "Dimmable light")
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())
{
alllights.Add(new Light() { api = this, ID = Int32.Parse(i.Key), Brightness = (int)state["bri"], SaturationEnabled = true, HueEnabled = true, IsOn = ((string)state["on"]).ToLower() == "true" ? true : false, Hue = (int)state["hue"], Saturation = (int)state["sat"], Name = (string)light["name"], Type = (string)light["type"] });
l.HueEnabled = true;
l.Hue = (int)state["hue"];
}
else
l.HueEnabled = false;
//Brightness
if (!state["bri"].IsNullOrEmpty())
{
alllights.Add(new Light() { api = this, ID = Int32.Parse(i.Key), Brightness = (int)state["bri"], SaturationEnabled = false,HueEnabled = false,IsOn = ((string)state["on"]).ToLower() == "true" ? true : false, Hue =0, Saturation = 0, Name = (string)light["name"], Type = (string)light["type"] });
}//Debug.WriteLine("Added light number " + i + " " + state["on"]);
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)
@@ -133,6 +226,27 @@ namespace HueUWP
}
}
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;
}
}
}
+15 -2
View File
@@ -1,4 +1,5 @@
using System;
using HueUWP.Views;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -37,6 +38,18 @@ namespace HueUWP
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.
@@ -79,7 +92,7 @@ namespace HueUWP
// 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(MainPage), e.Arguments);
rootFrame.Navigate(typeof(LightsView), e.Arguments);
}
if(LOCAL_SETTINGS.Values["ip"] == null)
+198 -197
View File
@@ -1,197 +1,198 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI;
namespace HueUWP
{
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));
}
}
}
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));
}
}
}
@@ -1,10 +1,11 @@
using System;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HueUWP
namespace HueUWP.Helpers
{
public static class Extensions
{
@@ -17,5 +18,14 @@ namespace HueUWP
{
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);
}
}
}
@@ -5,7 +5,7 @@ using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml.Data;
namespace HueUWP.Converters
namespace HueUWP.Helpers
{
public class NullableBooleanConverter : IValueConverter
{
@@ -6,7 +6,7 @@ using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Data;
namespace HueUWP.Converters
namespace HueUWP.Helpers
{
class VisibilityConverter : IValueConverter
{
+26 -14
View File
@@ -93,30 +93,38 @@
<None Include="project.json" />
</ItemGroup>
<ItemGroup>
<Compile Include="AboutView.xaml.cs">
<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="ColorUtil.cs" />
<Compile Include="Converters\NullableBooleanConverter.cs" />
<Compile Include="Converters\VisibilityConverter.cs" />
<Compile Include="DetailView.xaml.cs">
<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="Extensions.cs" />
<Compile Include="Light.cs" />
<Compile Include="MainPage.xaml.cs">
<DependentUpon>MainPage.xaml</DependentUpon>
<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="SettingsView.xaml.cs">
<Compile Include="Views\SettingsView.xaml.cs">
<DependentUpon>SettingsView.xaml</DependentUpon>
</Compile>
<Compile Include="SettingsViewModel.cs" />
@@ -143,15 +151,19 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Page Include="AboutView.xaml">
<Page Include="Views\AboutView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="DetailView.xaml">
<Page Include="Views\DetailView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="MainPage.xaml">
<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>
@@ -159,7 +171,7 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="SettingsView.xaml">
<Page Include="Views\SettingsView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
-119
View File
@@ -1,119 +0,0 @@
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
{
public class Light : INotifyPropertyChanged
{
public int ID { get; set; }
public string Name { get; set; }
public string Type { get; set; }
public bool HueEnabled
{
get; set;
}
public bool SaturationEnabled { get; set; }
private bool _isOn;
public bool IsOn
{
get { return _isOn; }
set { _isOn = value; NotifyPropertyChanged(nameof(IsOn)); }
}
//Hue
private double _hue;
public double Hue
{
get { return _hue; }
set { _hue = value; NotifyPropertyChanged(nameof(Hue)); NotifyPropertyChanged(nameof(Color)); }
}
//Brightness
private double _brightness;
public double Brightness
{
get { return _brightness; }
set { _brightness = value; NotifyPropertyChanged(nameof(Brightness)); NotifyPropertyChanged(nameof(Color)); }
}
//Saturation
private double _saturation;
public double Saturation
{
get { return _saturation; }
set { _saturation = value; NotifyPropertyChanged(nameof(Saturation)); NotifyPropertyChanged(nameof(Color)); }
}
public APIHandler api { get; set; }
public SolidColorBrush Color
{
get { return new SolidColorBrush(HueUWP.ColorUtil.HsvToRgb(Hue, Saturation, Brightness)); }
}
public Light()
{
}
public void UpdateState(bool on)
{
NotifyPropertyChanged(nameof(UpdateState));
this.IsOn = on;
api.SetLightState(this);
}
public void UpdateColor()
{
api.SetLightValues(this);
}
public void UpdateColorDisco()
{
api.SetInstantLightValues(this);
}
public void UpdateColor(int h, int s, int b)
{
//double h; double s; double v;
//ColorUtil.RGBtoHSV(r,g,b, out h,out s,out v);
this.Hue = h; this.Saturation = s; this.Brightness = b;
api.SetLightValues(this);
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public class LightDataSource
{
private static ObservableCollection<Light> _lights
= new ObservableCollection<Light>();
public static ObservableCollection<Light> GetLights()
{
return _lights;
}
}
}
+85
View File
@@ -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));
}
}
}
+31
View File
@@ -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);
}
}
}
+44
View File
@@ -0,0 +1,44 @@
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();
}
return "success";
}
}
}
+45
View File
@@ -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
{
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();
}
return "success";
}
}
}
+58
View File
@@ -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; });
}
}
}
+37
View File
@@ -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);
}
public override async Task<String> Update()
{
return await App.api.UpdateLight(this);
}
}
}
+1 -1
View File
@@ -3,7 +3,7 @@
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.Converters"
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"
+24 -21
View File
@@ -1,4 +1,7 @@
using Newtonsoft.Json;
using HueUWP.Helpers;
using HueUWP.Lights;
using HueUWP.Views;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -25,7 +28,7 @@ namespace HueUWP
public sealed partial class MultiEdit : Page
{
IList<Light> lights = new List<Light>();
MainPage main;
LightsView main;
public MultiEdit()
{
@@ -34,18 +37,18 @@ namespace HueUWP
protected override void OnNavigatedTo(NavigationEventArgs e)
{
main = e.Parameter as MainPage;
main = e.Parameter as LightsView;
HueSlider.Value = ((Light) main.GetListView().SelectedItems[0]).Hue;
SaturationSlider.Value = ((Light)main.GetListView().SelectedItems[0]).Saturation;
BrightnessSlider.Value = ((Light)main.GetListView().SelectedItems[0]).Brightness;
OnOffButton.IsOn = ((Light)main.GetListView().SelectedItems[0]).IsOn;
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);
}
//foreach (var v in main.GetListView().SelectedItems)
//{
// Light l = (Light)v;
// lights.Add(l);
//}
LightsSelectedField.Text = lights.ToDelimitedString(l => l.Name);
}
@@ -58,25 +61,25 @@ namespace HueUWP
private void Slider_Released(object sender, PointerRoutedEventArgs e)
{
foreach(var l in lights)
foreach (var l in lights)
{
l.Hue = HueSlider.Value;
l.Saturation = SaturationSlider.Value;
l.Brightness = BrightnessSlider.Value;
l.Hue = (int)HueSlider.Value;
l.Saturation = (int)SaturationSlider.Value;
l.Brightness = (int)BrightnessSlider.Value;
ColorRectangle.Fill = new SolidColorBrush(ColorUtil.getColor(l));
l.UpdateColor();
l.SetColor();
}
}
private void ToggleSwitch_Toggled(object sender, RoutedEventArgs e)
{
ToggleSwitch button = ((ToggleSwitch)sender);
foreach(var l in lights)
foreach (var l in lights)
{
l.UpdateState(button.IsOn);
l.SetState();
}
}
}
}
+75 -15
View File
@@ -11,15 +11,12 @@ namespace HueUWP
{
public class NetworkHandler
{
//string (string) MainPage.LOCAL_SETTINGS.Values["ip"];
//int (int)MainPage.LOCAL_SETTINGS.Values["port"];
public NetworkHandler()
{
//this.(string) MainPage.LOCAL_SETTINGS.Values["ip"] = (string) MainPage.LOCAL_SETTINGS.Values["(string) MainPage.LOCAL_SETTINGS.Values["ip"]"];
//this.(int)MainPage.LOCAL_SETTINGS.Values["port"] = (int)MainPage.LOCAL_SETTINGS.Values["(int)MainPage.LOCAL_SETTINGS.Values["port"]"];
}
private async Task<String> Put(string path, string json)
private static async Task<String> Put(string path, string json)
{
var cts = new CancellationTokenSource();
cts.CancelAfter(5000);
@@ -31,7 +28,7 @@ namespace HueUWP
HttpClient client = new HttpClient();
HttpStringContent content = new HttpStringContent(json, Windows.Storage.Streams.UnicodeEncoding.Utf8, "application /json");
Uri uriLampState = new Uri($"http://{(string) MainPage.LOCAL_SETTINGS.Values["ip"]}:{(int)MainPage.LOCAL_SETTINGS.Values["port"]}/api/" + path);
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)
@@ -53,7 +50,7 @@ namespace HueUWP
}
private async Task<String> Post(string path, string json)
private static async Task<String> Post(string path, string json)
{
var cts = new CancellationTokenSource();
cts.CancelAfter(5000);
@@ -63,7 +60,7 @@ namespace HueUWP
HttpClient client = new HttpClient();
HttpStringContent content = new HttpStringContent(json, Windows.Storage.Streams.UnicodeEncoding.Utf8, "application /json");
Uri uriLampState = new Uri($"http://{(string) MainPage.LOCAL_SETTINGS.Values["ip"]}:{(int)MainPage.LOCAL_SETTINGS.Values["port"]}/api/" + path);
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)
@@ -84,7 +81,7 @@ namespace HueUWP
}
}
private async Task<String> Get(string path)
private static async Task<String> Get(string path)
{
var cts = new CancellationTokenSource();
cts.CancelAfter(5000);
@@ -94,7 +91,7 @@ namespace HueUWP
HttpClient client = new HttpClient();
//HttpStringContent content = new HttpStringContent($"{{\"devicetype\":\"Test#Test\"}}", Windows.Storage.Streams.UnicodeEncoding.Utf8, "application /json");
Uri uriLampState = new Uri($"http://{(string) MainPage.LOCAL_SETTINGS.Values["ip"]}:{(int)MainPage.LOCAL_SETTINGS.Values["port"]}/api/" + path);
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)
@@ -115,14 +112,46 @@ namespace HueUWP
}
}
public async Task<String> SetLightInfo(int lightid, string json)
public static async Task<String> Lights()
{
var response = await Put($"{(String)MainPage.LOCAL_SETTINGS.Values["id"]}/lights/{lightid}/state", json);
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 async Task<String> RegisterName(string AppName, string UserName)
public static async Task<String> RegisterName(string AppName, string UserName)
{
var response = await Post("",$"{{\"devicetype\":\"{AppName}#{UserName}\"}}");
if (string.IsNullOrEmpty(response))
@@ -130,13 +159,44 @@ namespace HueUWP
return response;
}
public async Task<String> AllLights()
public static async Task<String> Groups()
{
var response = await Get($"{(String)MainPage.LOCAL_SETTINGS.Values["id"]}/lights");
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}", 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}", 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}", json);
return response;
}
}
}
+5 -7
View File
@@ -11,8 +11,6 @@ namespace HueUWP
{
public class SettingsViewModel : INotifyPropertyChanged
{
private static ApplicationDataContainer LOCAL_SETTINGS = ApplicationData.Current.LocalSettings;
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
@@ -22,19 +20,19 @@ namespace HueUWP
public string IP
{
get { Debug.WriteLine(LOCAL_SETTINGS.Values["ip"]); return LOCAL_SETTINGS.Values["ip"] as string; }
set { LOCAL_SETTINGS.Values["ip"] = value; NotifyPropertyChanged(nameof(IP)); }
get { Debug.WriteLine(App.LOCAL_SETTINGS.Values["ip"]); return App.LOCAL_SETTINGS.Values["ip"] as string; }
set { App.LOCAL_SETTINGS.Values["ip"] = value; NotifyPropertyChanged(nameof(IP)); }
}
public string PORT
{
get { Debug.WriteLine(LOCAL_SETTINGS.Values["port"]); return Convert.ToInt32(LOCAL_SETTINGS.Values["port"]).ToString(); }
set { LOCAL_SETTINGS.Values["port"] = int.Parse(value); NotifyPropertyChanged(nameof(PORT)); }
get { Debug.WriteLine(App.LOCAL_SETTINGS.Values["port"]); return Convert.ToInt32(App.LOCAL_SETTINGS.Values["port"]).ToString(); }
set { App.LOCAL_SETTINGS.Values["port"] = int.Parse(value); NotifyPropertyChanged(nameof(PORT)); }
}
public string ID
{
get { Debug.WriteLine(LOCAL_SETTINGS.Values["id"]); return LOCAL_SETTINGS.Values["id"] as string; }
get { Debug.WriteLine(App.LOCAL_SETTINGS.Values["id"]); return App.LOCAL_SETTINGS.Values["id"] as string; }
}
public void Update()
+1 -3
View File
@@ -1,6 +1,4 @@
Todo
- Binding in multiple edit mode. Doen door meerdere soorten models mee te geven bij het navigeren naar de detail pagina.
- 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.
- Disco mode beter maken.
- Automatisch refreshing.
@@ -1,8 +1,8 @@
<Page
x:Class="HueUWP.AboutView"
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"
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">
@@ -15,7 +15,7 @@ using Windows.UI.Xaml.Navigation;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
namespace HueUWP
namespace HueUWP.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
@@ -1,9 +1,9 @@
<Page
x:Class="HueUWP.DetailView"
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"
xmlns:convert="using:HueUWP.Converters"
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"
@@ -27,14 +27,14 @@
<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}"/>
<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, Converter={StaticResource BoolConverter}}">
<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>
@@ -43,17 +43,17 @@
<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}" ValueChanged="Slider_ValueChanged" PointerCaptureLost="Slider_Released"/>
<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}" ValueChanged="Slider_ValueChanged" PointerCaptureLost="Slider_Released" />
<Slider Maximum="254" Value="{Binding Saturation, Mode=TwoWay}" PointerCaptureLost="Slider_Released" />
</StackPanel>
<StackPanel Margin="20,10,20,0">
<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}" ValueChanged="Slider_ValueChanged" PointerCaptureLost="Slider_Released"/>
<Slider Maximum="254" Value="{Binding Brightness, Mode=TwoWay}" PointerCaptureLost="Slider_Released"/>
</StackPanel>
</StackPanel>
@@ -1,58 +1,68 @@
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 DetailView : Page
{
Light l;
public DetailView()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
l = e.Parameter as Light;
this.DataContext = l;
}
private void Slider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
{
//l.UpdateColor();
}
private void Slider_Released(object sender, PointerRoutedEventArgs e)
{
l.UpdateColor();
}
private void ToggleSwitch_Toggled(object sender, RoutedEventArgs e)
{
ToggleSwitch button = ((ToggleSwitch)sender);
Light light = (Light)button.DataContext;
if (light != null)
light.UpdateState(button.IsOn);
}
}
}
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();
}
}
}
+58
View File
@@ -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>
+109
View File
@@ -0,0 +1,109 @@
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();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
ReloadGroups();
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;
timer.Start();
}
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();
}
}
}
@@ -1,113 +1,111 @@
<Page
x:Class="HueUWP.MainPage"
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.Converters"
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"
DataContext="{Binding LightsViewModel, RelativeSource={RelativeSource Self}}"
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">
<ScrollViewer RelativePanel.AlignBottomWithPanel="True" RelativePanel.AlignTopWithPanel="True">
<ListView x:Name="myListView" ItemsSource="{Binding}" IsItemClickEnabled="True" ItemClick="myListView_ItemClick" SelectionMode="Extended">
<ListView.ItemTemplate>
<DataTemplate x:Name="dataTemplate">
<StackPanel Orientation="Horizontal" >
<Rectangle Width="30" Height="30" Fill="{Binding Color}" Margin="20,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,0,0" Toggled="ToggleSwitch_Toggled" IsOn="{Binding IsOn, Converter={StaticResource BoolConverter}}">
<ToggleSwitch.OffContent>Off</ToggleSwitch.OffContent>
<ToggleSwitch.OnContent>On</ToggleSwitch.OnContent>
</ToggleSwitch>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ScrollViewer>
</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="&#xE70F;"/>
</AppBarButton.Icon>
</AppBarButton>
<!-- Update on/off -->
<AppBarButton Label="On" Name="OnOffButton" Click="OnOffButton_Click" Visibility="Collapsed">
<AppBarButton.Icon>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE8B1;"/>
</AppBarButton.Icon>
</AppBarButton>
<!-- Group -->
<AppBarToggleButton Label="Group" Name="GroupButton" Click="GroupButton_Click">
<AppBarToggleButton.Icon>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE73A;"/>
</AppBarToggleButton.Icon>
</AppBarToggleButton>
<AppBarSeparator Name="Seperator" />
<!-- Disco -->
<AppBarToggleButton Label="Disco" Name="DiscoButton" Click="DiscoButton_Click">
<AppBarToggleButton.Icon>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE8D6;"/>
</AppBarToggleButton.Icon>
</AppBarToggleButton>
<!-- Settings -->
<AppBarButton Label="Settings" Name="SettingsButton" Click="SettingsButton_Click">
<AppBarButton.Icon>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE713;"/>
</AppBarButton.Icon>
</AppBarButton>
<!-- Refresh -->
<AppBarButton Label="Refresh" Name="RefreshButton" Click="RefreshButton_Click">
<AppBarButton.Icon>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE72C;"/>
</AppBarButton.Icon>
</AppBarButton>
<CommandBar.SecondaryCommands>
<AppBarButton Label="About" Click="AboutButton_Click"/>
</CommandBar.SecondaryCommands>
</CommandBar>
</Page.BottomAppBar>
</Page>
<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="&#xE70F;"/>
</AppBarButton.Icon>
</AppBarButton>
<!-- Update on/off -->
<AppBarButton Label="On" Name="OnOffButton" Click="OnOffButton_Click" Visibility="Collapsed">
<AppBarButton.Icon>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE8B1;"/>
</AppBarButton.Icon>
</AppBarButton>
<!-- Group -->
<AppBarToggleButton Label="Select" Name="GroupButton" Click="GroupButton_Click">
<AppBarToggleButton.Icon>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE73A;"/>
</AppBarToggleButton.Icon>
</AppBarToggleButton>
<AppBarSeparator Name="Seperator" />
<!-- Disco -->
<AppBarToggleButton Label="Disco" Name="DiscoButton" Click="DiscoButton_Click">
<AppBarToggleButton.Icon>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE8D6;"/>
</AppBarToggleButton.Icon>
</AppBarToggleButton>
<!-- Settings -->
<AppBarButton Label="Settings" Name="SettingsButton" Click="SettingsButton_Click">
<AppBarButton.Icon>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE713;"/>
</AppBarButton.Icon>
</AppBarButton>
<!-- Refresh -->
<AppBarButton Label="Refresh" Name="RefreshButton" Click="RefreshButton_Click">
<AppBarButton.Icon>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE72C;"/>
</AppBarButton.Icon>
</AppBarButton>
<CommandBar.SecondaryCommands>
<AppBarButton Label="About" Click="AboutButton_Click"/>
<AppBarButton Label="Groups" Click="GroupsButton_Click"/>
</CommandBar.SecondaryCommands>
</CommandBar>
</Page.BottomAppBar>
</Page>
@@ -1,202 +1,207 @@
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.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=402352&clcid=0x409
namespace HueUWP
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public static ApplicationDataContainer LOCAL_SETTINGS = ApplicationData.Current.LocalSettings;
private ObservableCollection<Light> _lightsViewModel = LightDataSource.GetLights();
public APIHandler api;
public ObservableCollection<Light> LightsViewModel
{
get { return this._lightsViewModel; }
}
public MainPage()
{
this.InitializeComponent();
//LOCAL_SETTINGS.Values["ip"] = "localhost";
//LOCAL_SETTINGS.Values["port"] = 8000;
NetworkHandler nwh = new NetworkHandler();
api = new APIHandler(nwh);
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
Load_Lights();
}
private async void Load_Lights()
{
ErrorMessage.Text = "";
FeedbackPanel.Visibility = Visibility.Visible;
_lightsViewModel.Clear();
Loading.IsActive = true;
await Task.Delay(TimeSpan.FromMilliseconds(200));
string s = await api.GetAllLights(_lightsViewModel);
if (s == "error")
ErrorMessage.Text = "There was a problem connecting...";
else if (_lightsViewModel.Count < 1)
ErrorMessage.Text = "No lights found...";
else
FeedbackPanel.Visibility = Visibility.Collapsed;
Loading.IsActive = false;
}
public void ToggleSwitch_Tapped(object sender, TappedRoutedEventArgs e)
{
Debug.WriteLine("Hello again");
ToggleSwitch button = ((ToggleSwitch)sender);
Light light = (Light)button.DataContext;
Debug.WriteLine("Hello");
if(light != null)
light.UpdateState(button.IsOn);
}
private void ToggleSwitch_Toggled(object sender, RoutedEventArgs e)
{
ToggleSwitch button = ((ToggleSwitch)sender);
Light light = (Light)button.DataContext;
if(light != null)
light.UpdateState(button.IsOn);
}
private void SettingsButton_Click(object sender, RoutedEventArgs e)
{
Frame rootframe = Window.Current.Content as Frame;
rootframe.Navigate(typeof(SettingsView), api);
}
private void RefreshButton_Click(object sender, RoutedEventArgs e)
{
Load_Lights();
}
private void myListView_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 DiscoButton_Click(object sender, RoutedEventArgs e)
{
if ((bool)DiscoButton.IsChecked)
api.DiscoMode(_lightsViewModel);
else
api.DiscoMode(false);
}
private void GroupButton_Click(object sender, RoutedEventArgs e)
{
if ((bool)GroupButton.IsChecked)
{
myListView.IsItemClickEnabled = false;
myListView.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
{
myListView.IsItemClickEnabled = true;
myListView.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 first = false;
if(OnOffButton.Label == "Off")
{
first = false;
OnOffButton.Label = "On";
}
else
{
first = true;
OnOffButton.Label = "Off";
}
if ((bool)GroupButton.IsChecked)
{
foreach(var v in myListView.SelectedItems)
{
((Light)v).UpdateState(first);
}
}
}
public ListView GetListView()
{
return myListView;
}
//hue.imegumii.space
private void ValuesButton_Click(object sender, RoutedEventArgs e)
{
if ((bool)GroupButton.IsChecked)
{
Frame rootframe = Window.Current.Content as Frame;
if (myListView.SelectedItems != null)
rootframe.Navigate(typeof(MultiEdit), this);
}
}
}
}
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.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;
_lightsViewModel = new LightListDataSource();
timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(8);
timer.Tick += Timer_Tick;
}
private void Timer_Tick(object sender, object e)
{
QuietReloadLights();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
ReloadLights();
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;
timer.Start();
}
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);
}
}
}
}
}
@@ -1,8 +1,8 @@
<Page
x:Class="HueUWP.SettingsView"
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"
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">
@@ -17,7 +17,7 @@ using Windows.UI.Xaml.Navigation;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
namespace HueUWP
namespace HueUWP.Views
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
@@ -26,8 +26,6 @@ namespace HueUWP
{
public SettingsViewModel SettingsViewModel = new SettingsViewModel();
private APIHandler api;
public SettingsView()
{
this.InitializeComponent();
@@ -39,7 +37,7 @@ namespace HueUWP
IDBox.Background = default(Brush);
UserIdProgress.IsActive = true;
string s = await api.Register();
string s = await App.api.Register();
if (s == "error")
IDBox.Background = new SolidColorBrush(Colors.Red);
else
@@ -47,10 +45,5 @@ namespace HueUWP
UserIdProgress.IsActive = false;
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
api = e.Parameter as APIHandler;
}
}
}