Browse Source

Added a new settings window to manage options for GPMDP

Fix #28 - Clear cache and settings
Fix #27 - Moved theme setting to settings window
Fix #26 - Choose the highlight color of the dark theme
pull/52/head
Samuel Attard 7 years ago
parent
commit
4dc3474ea2
  1. 3
      Google Play Music/App.config
  2. 572
      Google Play Music/ColorWheel.cs
  3. 2
      Google Play Music/CoreMusicApp.States.cs
  4. 12
      Google Play Music/Google Play Music.csproj
  5. 43
      Google Play Music/JSBound.cs
  6. 12
      Google Play Music/Properties/Settings.Designer.cs
  7. 3
      Google Play Music/Properties/Settings.settings
  8. 7
      Google Play Music/ResourceHandlerFactory.cs
  9. 15
      Google Play Music/Resources/custom-interface.js
  10. 24
      Google Play Music/Resources/dark-theme.js
  11. 133
      Google Play Music/SettingsDialog.Designer.cs
  12. 77
      Google Play Music/SettingsDialog.cs
  13. 6293
      Google Play Music/SettingsDialog.resx
  14. 110
      Material Skin/Controls/MaterialForm.cs
  15. 14
      Material Skin/MaterialSkinManager.cs

3
Google Play Music/App.config

@ -25,6 +25,9 @@
<setting name="CustomTheme" serializeAs="String">
<value>False</value>
</setting>
<setting name="CustomColor" serializeAs="String">
<value>30, 215, 96</value>
</setting>
</Google_Play_Music.Properties.Settings>
</userSettings>
<runtime>

572
Google Play Music/ColorWheel.cs

@ -0,0 +1,572 @@
// Copyright (c) 2012, Yves Goergen, http://unclassified.software/source/colormath
//
// Copying and distribution of this file, with or without modification, are permitted provided the
// copyright notice and this notice are preserved. This file is offered as-is, without any warranty.
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
namespace Google_Play_Music
{
public class ColorWheel : Control
{
private Bitmap wheelBitmap;
private Bitmap slBitmap;
private byte hue;
private byte saturation;
private byte lightness;
private byte[] secondaryHues;
private bool draggingHue;
private bool draggingSL;
public event EventHandler HueChanged;
public event EventHandler SLChanged;
public byte Hue
{
get
{
return hue;
}
set
{
if (value != hue)
{
hue = value;
PrepareSLBitmap();
Invalidate();
}
}
}
public byte Saturation
{
get
{
return saturation;
}
set
{
if (value != saturation)
{
saturation = value;
Invalidate();
}
}
}
public byte Lightness
{
get
{
return lightness;
}
set
{
if (value != lightness)
{
lightness = value;
Invalidate();
}
}
}
public byte[] SecondaryHues
{
get
{
return secondaryHues;
}
set
{
if ((value == null) != (secondaryHues == null) ||
value == null ||
value != null && value.Length != secondaryHues.Length) // implies: secondaryHues != null
{
secondaryHues = value;
Invalidate();
}
else if (value != null)
{
for (int i = 0; i < value.Length; i++)
{
if (value[i] != secondaryHues[i])
{
secondaryHues = value;
Invalidate();
break;
}
}
}
}
}
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new bool TabStop
{
get { return base.TabStop; }
set { base.TabStop = false; }
}
public ColorWheel()
{
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
DoubleBuffered = true;
TabStop = false;
PrepareWheelBitmap();
}
protected override void OnSizeChanged(EventArgs e)
{
PrepareWheelBitmap();
PrepareSLBitmap();
base.OnSizeChanged(e);
}
//protected override void OnPaintBackground(PaintEventArgs pevent)
//{
// if (VisualStyleRenderer.IsSupported)
// {
// // The VisualStyleElement does not matter, we're only drawing the parent's background
// VisualStyleRenderer r = new VisualStyleRenderer(VisualStyleElement.Window.Dialog.Normal);
// r.DrawParentBackground(pevent.Graphics, ClientRectangle, this);
// }
// else
// {
// base.OnPaintBackground(pevent);
// }
//}
// NOTE: Other solution: http://dotnetrix.co.uk/custom.htm#tip3
protected override void OnPaint(PaintEventArgs pe)
{
// Draw outer color wheel bitmap
if (wheelBitmap != null)
pe.Graphics.DrawImage(wheelBitmap, new Point());
// Draw inner color bitmap
if (slBitmap != null)
pe.Graphics.DrawImage(slBitmap, new Point(slBitmap.Width / 2, slBitmap.Width / 2));
pe.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
// Draw hue marker
double radAngle = (double)hue / 128 * Math.PI + Math.PI / 2;
// sin(angle) = y / d
// cos(angle) = x / d
double d = 0.89 * wheelBitmap.Width / 2;
int x = (int)Math.Round(d * Math.Cos(radAngle));
int y = (int)-Math.Round(d * Math.Sin(radAngle));
// Map center-relative coordinates to window coordinates
x += wheelBitmap.Width / 2;
y += wheelBitmap.Width / 2;
Color c = ColorMath.ToGray(ColorMath.HslToRgb(new HslColor(hue, 255, 128))) > 128 ? Color.Black : Color.White;
using (Pen p = new Pen(c))
{
pe.Graphics.DrawEllipse(p, x - 3, y - 3, 6, 6);
}
// Draw secondary hue markers
if (secondaryHues != null)
{
foreach (byte sHue in secondaryHues)
{
radAngle = (double)sHue / 128 * Math.PI + Math.PI / 2;
// sin(angle) = y / d
// cos(angle) = x / d
d = 0.89 * wheelBitmap.Width / 2;
x = (int)Math.Round(d * Math.Cos(radAngle));
y = (int)-Math.Round(d * Math.Sin(radAngle));
// Map center-relative coordinates to window coordinates
x += wheelBitmap.Width / 2;
y += wheelBitmap.Width / 2;
c = ColorMath.ToGray(ColorMath.HslToRgb(new HslColor(sHue, 255, 128))) > 128 ? Color.Black : Color.White;
//using (Pen p = new Pen(Color.FromArgb(128, c)))
//{
// pe.Graphics.DrawRectangle(p, x - 2, y - 2, 4, 4);
//}
using (Brush b = new SolidBrush(Color.FromArgb(128, c)))
{
pe.Graphics.FillRectangle(b, x - 2, y - 2, 4, 4);
}
}
}
// Draw inner color marker
x = slBitmap.Width / 2 + saturation * (slBitmap.Width - 1) / 255;
y = slBitmap.Width / 2 + lightness * (slBitmap.Width - 1) / 255;
c = ColorMath.ToGray(ColorMath.HslToRgb(new HslColor(hue, saturation, lightness))) > 128 ? Color.Black : Color.White;
using (Pen p = new Pen(c))
{
pe.Graphics.DrawEllipse(p, x - 3, y - 3, 6, 6);
}
}
protected override void OnMouseDown(MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
int halfSLWidth = slBitmap.Width / 2;
if (e.X >= halfSLWidth && e.X < halfSLWidth * 3 &&
e.Y >= halfSLWidth && e.Y < halfSLWidth * 3)
{
draggingSL = true;
OnMouseMove(e);
}
else
{
int halfWheelWidth = wheelBitmap.Width / 2;
Point center = new Point(halfWheelWidth, halfWheelWidth);
double dist = GetDistance(new Point(e.X, e.Y), center);
if (dist >= halfWheelWidth * 0.78 && dist < halfWheelWidth)
{
draggingHue = true;
OnMouseMove(e);
}
}
}
base.OnMouseDown(e);
}
protected override void OnMouseUp(MouseEventArgs e)
{
draggingSL = false;
draggingHue = false;
base.OnMouseUp(e);
}
protected override void OnMouseMove(MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (draggingSL)
{
int halfSLWidth = slBitmap.Width / 2;
Saturation = (byte)Math.Max(0, Math.Min(255, (e.X - halfSLWidth) * 255 / slBitmap.Width));
Lightness = (byte)Math.Max(0, Math.Min(255, (e.Y - halfSLWidth) * 255 / slBitmap.Width));
OnSLChanged();
}
else if (draggingHue)
{
int halfWheelWidth = wheelBitmap.Width / 2;
Point center = new Point(halfWheelWidth, halfWheelWidth);
double radAngle = Math.Atan2(e.Y - center.Y, e.X - center.X);
double factor = 128.0 / Math.PI; // map -pi...pi to 0...255 => map 0...pi to 0...128
// Calculation notes see PrepareWheelBitmap()
Hue = (byte)Mod((int)(-factor * radAngle + 192), 256);
OnHueChanged();
}
}
base.OnMouseMove(e);
}
private void PrepareWheelBitmap()
{
if (wheelBitmap != null)
wheelBitmap.Dispose();
int width = Math.Min(ClientSize.Width, ClientSize.Height);
Point center = new Point(width / 2, width / 2);
if (width < 10)
{
wheelBitmap = null;
return;
}
// Prepare Bitmap
wheelBitmap = new Bitmap(width, width);
// Fill background
Graphics g = Graphics.FromImage(wheelBitmap);
using (Brush b = new SolidBrush(Color.Transparent))
{
g.FillRectangle(b, 0, 0, width, width);
}
// Paint outer color wheel
double minDist = width / 2 * 0.78;
double maxDist = width / 2 - 1;
double factor = 128.0 / Math.PI; // map -pi...pi to 0...255 => map 0...pi to 0...128
BitmapData bmData;
byte[] bytes;
BitmapReadBytes(wheelBitmap, out bytes, out bmData);
for (int y = 0; y < width; y++)
{
for (int x = 0; x < width; x++)
{
double dist = GetDistance(new Point(x, y), center);
byte alpha;
if (dist < minDist - 0.5)
alpha = 0;
else if (dist < minDist + 0.5)
alpha = (byte)((0.5 - minDist + dist) * 255);
else if (dist < maxDist - 0.5)
alpha = 255;
else if (dist < maxDist + 0.5)
alpha = (byte)((0.5 + maxDist - dist) * 255);
else
alpha = 0;
if (alpha > 0)
{
double radAngle = Math.Atan2(y - center.Y, x - center.X);
// -pi -> -180° -> 192
// -pi/2 -> -90° -> 128
// 0 -> 0° -> 64
// pi/2 -> 90° -> 0
// pi -> 180° -> 192
//
// y = a * x + t;
// a = -1
// t = 192
byte hue = (byte)Mod((int)(-factor * radAngle + 192), 256);
Color c = Color.FromArgb(alpha, ColorMath.HslToRgb(new HslColor(hue, 255, 128)));
BitmapSetPixel(bytes, bmData, x, y, c);
}
}
}
BitmapWriteBytes(wheelBitmap, bytes, bmData);
}
private void PrepareSLBitmap()
{
if (slBitmap != null)
slBitmap.Dispose();
int width = Math.Min(ClientSize.Width, ClientSize.Height) / 2;
if (width < 10)
{
slBitmap = null;
return;
}
// Prepare Bitmap
slBitmap = new Bitmap(width, width);
BitmapData bmData;
byte[] bytes;
BitmapReadBytes(slBitmap, out bytes, out bmData);
for (int y = 0; y < width; y++)
{
for (int x = 0; x < width; x++)
{
Color c = ColorMath.HslToRgb(new HslColor(hue, (byte)(x * 255 / width), (byte)(y * 255 / width)));
BitmapSetPixel(bytes, bmData, x, y, c);
}
}
BitmapWriteBytes(slBitmap, bytes, bmData);
}
private void BitmapReadBytes(Bitmap bmp, out byte[] bytes, out BitmapData bmData)
{
bmData = bmp.LockBits(
new Rectangle(0, 0, bmp.Width, bmp.Height),
ImageLockMode.ReadWrite,
PixelFormat.Format32bppArgb);
const int bpp = 4;
bytes = new byte[bmp.Width * bmp.Height * bpp];
Marshal.Copy(bmData.Scan0, bytes, 0, bytes.Length);
}
private void BitmapSetPixel(byte[] bytes, BitmapData bmData, int x, int y, Color c)
{
int i = y * bmData.Stride + x * 4;
bytes[i] = c.B;
bytes[i + 1] = c.G;
bytes[i + 2] = c.R;
bytes[i + 3] = c.A;
}
private void BitmapWriteBytes(Bitmap bmp, byte[] bytes, BitmapData bmData)
{
Marshal.Copy(bytes, 0, bmData.Scan0, bytes.Length);
bmp.UnlockBits(bmData);
}
private double GetDistance(Point a, Point b)
{
return Math.Sqrt((a.X - b.X) * (a.X - b.X) + (a.Y - b.Y) * (a.Y - b.Y));
}
/// <summary>
/// Computes the real modulus value, not the division remainder.
/// This differs from the % operator only for negative numbers.
/// </summary>
/// <param name="dividend">Dividend.</param>
/// <param name="divisor">Divisor.</param>
/// <returns></returns>
private static int Mod(int dividend, int divisor)
{
if (divisor <= 0) throw new ArgumentOutOfRangeException("divisor", "The divisor cannot be zero or negative.");
int i = dividend % divisor;
if (i < 0) i += divisor;
return i;
}
protected void OnHueChanged()
{
if (HueChanged != null)
HueChanged(this, EventArgs.Empty);
}
protected void OnSLChanged()
{
if (SLChanged != null)
SLChanged(this, EventArgs.Empty);
}
}
public static class ColorMath
{
/// <summary>
/// Blends two colors in the specified ratio.
/// </summary>
/// <param name="color1">First color.</param>
/// <param name="color2">Second color.</param>
/// <param name="ratio">Ratio between both colors. 0 for first color, 1 for second color.</param>
/// <returns></returns>
public static Color Blend(Color color1, Color color2, double ratio)
{
int a = (int)Math.Round(color1.A * (1 - ratio) + color2.A * ratio);
int r = (int)Math.Round(color1.R * (1 - ratio) + color2.R * ratio);
int g = (int)Math.Round(color1.G * (1 - ratio) + color2.G * ratio);
int b = (int)Math.Round(color1.B * (1 - ratio) + color2.B * ratio);
return Color.FromArgb(a, r, g, b);
}
public static Color Darken(Color color, double ratio)
{
return Blend(color, Color.Black, ratio);
}
public static Color Lighten(Color color, double ratio)
{
return Blend(color, Color.White, ratio);
}
public static HslColor RgbToHsl(Color rgb)
{
// Translated from JavaScript, part of coati
double h, s, l;
double r = (double)rgb.R / 255;
double g = (double)rgb.G / 255;
double b = (double)rgb.B / 255;
double min = Math.Min(Math.Min(r, g), b);
double max = Math.Max(Math.Max(r, g), b);
l = (max + min) / 2;
if (max == min)
h = 0;
else if (max == r)
h = (60 * (g - b) / (max - min)) % 360;
else if (max == g)
h = (60 * (b - r) / (max - min) + 120) % 360;
else //if (max == b)
h = (60 * (r - g) / (max - min) + 240) % 360;
if (h < 0)
h += 360;
if (max == min)
s = 0;
else if (l <= 0.5)
s = (max - min) / (2 * l);
else
s = (max - min) / (2 - 2 * l);
return new HslColor((byte)Math.Round((h / 360 * 256) % 256), (byte)Math.Round(s * 255), (byte)Math.Round(l * 255));
}
public static Color HslToRgb(HslColor hsl)
{
// Translated from JavaScript, part of coati
double h = (double)hsl.H / 256;
double s = (double)hsl.S / 255;
double l = (double)hsl.L / 255;
double q;
if (l < 0.5)
q = l * (1 + s);
else
q = l + s - l * s;
double p = 2 * l - q;
double[] t = new double[] { h + 1.0 / 3, h, h - 1.0 / 3 };
byte[] rgb = new byte[3];
for (int i = 0; i < 3; i++)
{
if (t[i] < 0) t[i]++;
if (t[i] > 1) t[i]--;
if (t[i] < 1.0 / 6)
rgb[i] = (byte)Math.Round((p + ((q - p) * 6 * t[i])) * 255);
else if (t[i] < 1.0 / 2)
rgb[i] = (byte)Math.Round(q * 255);
else if (t[i] < 2.0 / 3)
rgb[i] = (byte)Math.Round((p + ((q - p) * 6 * (2.0 / 3 - t[i]))) * 255);
else
rgb[i] = (byte)Math.Round(p * 255);
}
return Color.FromArgb(rgb[0], rgb[1], rgb[2]);
}
/// <summary>
/// Computes the real modulus value, not the division remainder.
/// This differs from the % operator only for negative numbers.
/// </summary>
/// <param name="dividend">Dividend.</param>
/// <param name="divisor">Divisor.</param>
/// <returns></returns>
private static int Mod(int dividend, int divisor)
{
if (divisor <= 0) throw new ArgumentOutOfRangeException("divisor", "The divisor cannot be zero or negative.");
int i = dividend % divisor;
if (i < 0) i += divisor;
return i;
}
/// <summary>
/// Computes the grey value value of a color.
/// </summary>
/// <param name="c"></param>
/// <returns></returns>
public static byte ToGray(Color c)
{
return (byte)(c.R * 0.3 + c.G * 0.59 + c.B * 0.11);
}
/// <summary>
/// Determines whether the color is dark or light.
/// </summary>
/// <param name="c"></param>
/// <returns></returns>
public static bool IsDarkColor(Color c)
{
return ToGray(c) < 0x90;
}
}
public struct HslColor
{
private byte h, s, l;
public byte H { get { return h; } set { h = value; } }
public byte S { get { return s; } set { s = value; } }
public byte L { get { return l; } set { l = value; } }
public HslColor(byte h, byte s, byte l)
{
this.h = h;
this.s = s;
this.l = l;
}
}
}

2
Google Play Music/CoreMusicApp.States.cs

@ -8,7 +8,7 @@ namespace Google_Play_Music
{
partial class CoreMusicApp
{
private Boolean mini = false;
public Boolean mini = false;
public void restoreMaxiState()
{

12
Google Play Music/Google Play Music.csproj

@ -164,6 +164,9 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ColorWheel.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="CoreMusicApp.cs">
<SubType>Form</SubType>
</Compile>
@ -192,6 +195,12 @@
<Compile Include="JSBound.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SettingsDialog.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="SettingsDialog.Designer.cs">
<DependentUpon>SettingsDialog.cs</DependentUpon>
</Compile>
<Compile Include="SongAlert.cs">
<SubType>Form</SubType>
</Compile>
@ -206,6 +215,9 @@
<SubType>Designer</SubType>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Include="SettingsDialog.resx">
<DependentUpon>SettingsDialog.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="UpdateDialog.resx">
<DependentUpon>UpdateDialog.cs</DependentUpon>
</EmbeddedResource>

43
Google Play Music/JSBound.cs

@ -1,6 +1,7 @@
using CefSharp;
using System;
using System.Drawing;
using System.IO;
using System.Threading.Tasks;
using System.Windows.Forms;
@ -138,5 +139,47 @@ namespace Google_Play_Music
};
}
}
private SettingsDialog settings;
public void showSettings()
{
mainForm.Invoke((MethodInvoker)delegate
{
if (settings == null)
{
settings = new SettingsDialog(mainForm);
}
DialogResult test = settings.open(mainForm.Location.X + (mainForm.Size.Width / 2), mainForm.Location.Y + (mainForm.Size.Height / 2));
if (test == DialogResult.Abort)
{
if (mainForm.mini)
{
mainForm.restoreMiniState();
} else
{
mainForm.restoreMaxiState();
}
settings.Dispose();
mainForm.GPMBrowser.GetBrowser().CloseBrowser(true);
mainForm.Close();
mainForm.Dispose();
// mainForm.GPMBrowser.Delete();
Cef.Shutdown();
string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "/GPMDP";
System.IO.DirectoryInfo downloadedMessageInfo = new DirectoryInfo(path);
foreach (FileInfo file in downloadedMessageInfo.GetFiles())
{
file.Delete();
}
foreach (DirectoryInfo dir in downloadedMessageInfo.GetDirectories())
{
dir.Delete(true);
}
}
});
}
}
}

12
Google Play Music/Properties/Settings.Designer.cs

@ -82,5 +82,17 @@ namespace Google_Play_Music.Properties {
this["CustomTheme"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("30, 215, 96")]
public global::System.Drawing.Color CustomColor {
get {
return ((global::System.Drawing.Color)(this["CustomColor"]));
}
set {
this["CustomColor"] = value;
}
}
}
}

3
Google Play Music/Properties/Settings.settings

@ -17,5 +17,8 @@
<Setting Name="CustomTheme" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">False</Value>
</Setting>
<Setting Name="CustomColor" Type="System.Drawing.Color" Scope="User">
<Value Profile="(Default)">30, 215, 96</Value>
</Setting>
</Settings>
</SettingsFile>

7
Google Play Music/ResourceHandlerFactory.cs

@ -1,4 +1,5 @@
using CefSharp;
using System.Drawing;
using System.IO;
using System.Net;
using System.Text;
@ -20,7 +21,11 @@ namespace Google_Play_Music
string dark_theme = Google_Play_Music.Properties.Resources.dark_theme;
string custom_interface = Google_Play_Music.Properties.Resources.custom_interface;
string mini_player = Google_Play_Music.Properties.Resources.mini_player;
return ResourceHandler.FromStream(new MemoryStream(Encoding.UTF8.GetBytes(webClient.DownloadString(request.Url) + ";" + dark_theme + custom_interface + mini_player)), webClient.ResponseHeaders["Content-Type"]);
Color c = Properties.Settings.Default.CustomColor;
string RGB = "#" + c.R.ToString("X2") + c.G.ToString("X2") + c.B.ToString("X2");
string custom_color = ";(function() {window.CustomColor = '" + RGB + "';})();";
return ResourceHandler.FromStream(new MemoryStream(Encoding.UTF8.GetBytes(webClient.DownloadString(request.Url) + ";" + custom_color + dark_theme + custom_interface + mini_player)), webClient.ResponseHeaders["Content-Type"]);
}
}
return null;

15
Google Play Music/Resources/custom-interface.js

@ -61,5 +61,20 @@ var check = setInterval(function () {
'<paper-icon-button data-id="prev-history" icon="arrow-back" role="button" tabindex="0" title="Navigate Back" aria-label="Navigate Back" style="color: white" onclick="window.history.back()"></paper-icon-button>' +
'<paper-icon-button data-id="next-history" icon="arrow-forward" role="button" tabindex="0" title="Navigate Forward" aria-label="Navigate Forward" style="color: white" onclick="window.history.forward()"></paper-icon-button>' +
e.innerHTML;
// Desktop Settings Trigger
var d_settings = document.createElement('a');
d_settings.setAttribute('data-type', 'desktopsettings');
d_settings.setAttribute('class', 'nav-item-container tooltip');
d_settings.setAttribute('href', "");
d_settings.setAttribute('no-focus', "");
d_settings.innerHTML = '<iron-icon icon="settings" alt="" class="x-scope iron-icon-0"><svg viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" class="style-scope iron-icon" style="pointer-events: none; display: block; width: 100%; height: 100%;"><g class="style-scope iron-icon"><path d="M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z" class="style-scope iron-icon"></path></g></svg></iron-icon>Desktop Settings';
d_settings.addEventListener('click', function (e) {
csharpinterface.showSettings();
e.preventDefault();
e.stopPropagation();
return false;
});
document.querySelectorAll('.nav-section.material')[0].insertBefore(d_settings, document.querySelectorAll('.nav-section.material > a')[2])
}
}, 10);

24
Google Play Music/Resources/dark-theme.js

@ -5,7 +5,7 @@ var BACK_PRIMARY = '#222326',
FORE_SECONDARY = '#EF6C00';
// Custom
FORE_SECONDARY = '#1ED760';
FORE_SECONDARY = window.CustomColor || '#1ED760';
var GLOBAL_STYLES = "";
@ -31,6 +31,7 @@ var setStyle = function (selector, style, imp) {
var flushStyles = function () {
var s = document.createElement('style');
s.setAttribute('id', 'custom-theme-style');
s.innerHTML = GLOBAL_STYLES;
document.body.appendChild(s);
};
@ -39,21 +40,14 @@ if (localStorage.getItem("custom-theme") === null) {
localStorage.setItem("custom-theme", "false");
}
setInterval(function () {
var labsCard = document.querySelectorAll('.labs-card.settings-card');
if (labsCard.length > 0) {
labsCard = labsCard[0];
var labsList = labsCard.querySelectorAll('.labs-list')[0],
exists = labsList.querySelectorAll('.lab-list-item.black-custom-gpm');
if (exists.length === 0) {
var darkOn = localStorage.getItem("custom-theme"),
blackDiv = document.createElement('div');
blackDiv.className = "lab-list-item black-custom-gpm";
blackDiv.innerHTML = '<div class="lab-info"><div class="lab-name">Custom Theme</div><div class="lab-description">Changes the look of Google Play Music to a Custom Theme</div></div><paper-toggle-button data-id="custom_theme" title="Custom Theme" tabindex="0" style="touch-action: none;" toggles="" onclick="window.turn' + (darkOn === "false" ? "On" : "Off") + 'Custom(this);return false;" ' + (darkOn === 'true' ? 'checked' : '') + ' class="x-scope paper-toggle-button-0"></paper-toggle-button>';
labsList.appendChild(blackDiv);
}
window.ReDrawTheme = function () {
var t = document.getElementById('custom-theme-style');
if (t) {
t.remove();
}
}, 10);
FORE_SECONDARY = window.CustomColor || '#1ED760';
BlackTheme();
};
var BlackTheme = function () {
setStyle('#material-app-bar', ['background-color: {{BACK_SECONDARY}}']);

133
Google Play Music/SettingsDialog.Designer.cs

@ -0,0 +1,133 @@
namespace Google_Play_Music
{
partial class SettingsDialog
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SettingsDialog));
this.materialLabel1 = new MaterialSkin.Controls.MaterialLabel();
this.materialCheckBox1 = new MaterialSkin.Controls.MaterialCheckBox();
this.materialLabel2 = new MaterialSkin.Controls.MaterialLabel();
this.colorWheel1 = new Google_Play_Music.ColorWheel();
this.materialRaisedButton1 = new MaterialSkin.Controls.MaterialRaisedButton();
this.SuspendLayout();
//
// materialLabel1
//
this.materialLabel1.AutoSize = true;
this.materialLabel1.Depth = 0;
this.materialLabel1.Font = new System.Drawing.Font("Roboto", 11F);
this.materialLabel1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(222)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))));
this.materialLabel1.Location = new System.Drawing.Point(411, 72);
this.materialLabel1.MouseState = MaterialSkin.MouseState.HOVER;
this.materialLabel1.Name = "materialLabel1";
this.materialLabel1.Size = new System.Drawing.Size(176, 19);
this.materialLabel1.TabIndex = 1;
this.materialLabel1.Text = "Custom Theme Highlight";
//
// materialCheckBox1
//
this.materialCheckBox1.AutoSize = true;
this.materialCheckBox1.Depth = 0;
this.materialCheckBox1.Font = new System.Drawing.Font("Roboto", 10F);
this.materialCheckBox1.Location = new System.Drawing.Point(13, 97);
this.materialCheckBox1.Margin = new System.Windows.Forms.Padding(0);
this.materialCheckBox1.MouseLocation = new System.Drawing.Point(-1, -1);
this.materialCheckBox1.MouseState = MaterialSkin.MouseState.HOVER;
this.materialCheckBox1.Name = "materialCheckBox1";
this.materialCheckBox1.Ripple = true;
this.materialCheckBox1.Size = new System.Drawing.Size(124, 30);
this.materialCheckBox1.TabIndex = 2;
this.materialCheckBox1.Text = "Custom Theme";
this.materialCheckBox1.UseVisualStyleBackColor = true;
//
// materialLabel2
//
this.materialLabel2.AutoSize = true;
this.materialLabel2.Depth = 0;
this.materialLabel2.Font = new System.Drawing.Font("Roboto", 11F);
this.materialLabel2.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(222)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))));
this.materialLabel2.Location = new System.Drawing.Point(12, 71);
this.materialLabel2.MouseState = MaterialSkin.MouseState.HOVER;
this.materialLabel2.Name = "materialLabel2";
this.materialLabel2.Size = new System.Drawing.Size(119, 19);
this.materialLabel2.TabIndex = 3;
this.materialLabel2.Text = "General Settings";
//
// colorWheel1
//
this.colorWheel1.Hue = ((byte)(0));
this.colorWheel1.Lightness = ((byte)(0));
this.colorWheel1.Location = new System.Drawing.Point(405, 97);
this.colorWheel1.Name = "colorWheel1";
this.colorWheel1.Saturation = ((byte)(0));
this.colorWheel1.SecondaryHues = null;
this.colorWheel1.Size = new System.Drawing.Size(183, 191);
this.colorWheel1.TabIndex = 0;
this.colorWheel1.Text = "colorWheel1";
//
// materialRaisedButton1
//
this.materialRaisedButton1.Depth = 0;
this.materialRaisedButton1.Location = new System.Drawing.Point(15, 250);
this.materialRaisedButton1.MouseState = MaterialSkin.MouseState.HOVER;
this.materialRaisedButton1.Name = "materialRaisedButton1";
this.materialRaisedButton1.Primary = true;
this.materialRaisedButton1.Size = new System.Drawing.Size(249, 38);
this.materialRaisedButton1.TabIndex = 4;
this.materialRaisedButton1.Text = "Reset and Close Application";
this.materialRaisedButton1.UseVisualStyleBackColor = true;
//
// SettingsDialog
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(600, 300);
this.Controls.Add(this.materialRaisedButton1);
this.Controls.Add(this.materialLabel2);
this.Controls.Add(this.materialCheckBox1);
this.Controls.Add(this.materialLabel1);
this.Controls.Add(this.colorWheel1);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "SettingsDialog";
this.Text = "Settings";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private ColorWheel colorWheel1;
private MaterialSkin.Controls.MaterialLabel materialLabel1;
private MaterialSkin.Controls.MaterialCheckBox materialCheckBox1;
private MaterialSkin.Controls.MaterialLabel materialLabel2;
private MaterialSkin.Controls.MaterialRaisedButton materialRaisedButton1;
}
}

77
Google Play Music/SettingsDialog.cs

@ -0,0 +1,77 @@
using System;
using System.Drawing;
using System.Windows.Forms;
using MaterialSkin;
using MaterialSkin.Controls;
using System.Diagnostics;
using CefSharp;
namespace Google_Play_Music
{
public partial class SettingsDialog : MaterialForm
{
CoreMusicApp app;
public SettingsDialog(CoreMusicApp main)
{
app = main;
InitializeComponent();
Resize_Enabled = false;
var skin = MaterialSkinManager.Instance;
skin.AddFormToManage(this);
colorWheel1.MouseUp += Color_Changed;
HslColor set = ColorMath.RgbToHsl(Properties.Settings.Default.CustomColor);
colorWheel1.Hue = set.H;
colorWheel1.Saturation = set.S;
colorWheel1.Lightness = set.L;
materialCheckBox1.CheckStateChanged += (res, send) =>
{
string command;
if (materialCheckBox1.Checked)
{
command = "window.turnOnCustom()";
} else
{
command = "window.turnOffCustom()";
}
app.Invoke((MethodInvoker)delegate
{
app.GPMBrowser.EvaluateScriptAsync("(function() {" + command + ";})();");
});
};
materialRaisedButton1.Click += (res, send) =>
{
Properties.Settings.Default.Reset();
Debug.WriteLine(Properties.Settings.Default.MaxiPoint);
Properties.Settings.Default.Save();
DialogResult = DialogResult.Abort;
Close();
};
}
private void Color_Changed(object sender, EventArgs e)
{
Properties.Settings.Default.CustomColor = ColorMath.HslToRgb(new HslColor(colorWheel1.Hue, colorWheel1.Saturation, colorWheel1.Lightness));
Color c = Properties.Settings.Default.CustomColor;
string RGB = "#" + c.R.ToString("X2") + c.G.ToString("X2") + c.B.ToString("X2");
app.Invoke((MethodInvoker)delegate
{
app.GPMBrowser.EvaluateScriptAsync("(function() {window.CustomColor = '" + RGB + "'; window.ReDrawTheme();})();");
});
}
public DialogResult open(int X, int Y)
{
Activated += (res, send) =>
{
Location = new Point(X - 300, Y - 125);
};
var result = ShowDialog();
return result;
}
}
}

6293
Google Play Music/SettingsDialog.resx

File diff suppressed because it is too large

110
Material Skin/Controls/MaterialForm.cs

@ -286,6 +286,8 @@ namespace MaterialSkin.Controls
Invalidate();
}
public bool Resize_Enabled = true;
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
@ -296,57 +298,69 @@ namespace MaterialSkin.Controls
{
//True if the mouse is hovering over a child control
bool isChildUnderMouse = GetChildAtPoint(e.Location) != null;
if (e.Location.X < BORDER_WIDTH && e.Location.Y > Height - BORDER_WIDTH && !isChildUnderMouse && !Maximized)
{
resizeDir = ResizeDirection.BottomLeft;
Cursor = Cursors.SizeNESW;
}
else if (e.Location.Y < BORDER_WIDTH && e.Location.X < BORDER_WIDTH && !isChildUnderMouse && !Maximized)
{
resizeDir = ResizeDirection.TopLeft;
Cursor = Cursors.SizeNWSE;
}
else if (e.Location.Y < BORDER_WIDTH && e.Location.X > Width - BORDER_WIDTH && !isChildUnderMouse && !Maximized)
if (!Resize_Enabled)
{
resizeDir = ResizeDirection.TopRight;
Cursor = Cursors.SizeNESW;
resizeDir = ResizeDirection.None;
//Only reset the cursur when needed, this prevents it from flickering when a child control changes the cursor to its own needs
if (resizeCursors.Contains(Cursor))
{
Cursor = Cursors.Default;
}
}
else if (e.Location.X < BORDER_WIDTH && !isChildUnderMouse && !Maximized)
{
resizeDir = ResizeDirection.Left;
Cursor = Cursors.SizeWE;
}
else if (e.Location.X > Width - BORDER_WIDTH && e.Location.Y > Height - BORDER_WIDTH && !isChildUnderMouse && !Maximized)
{
resizeDir = ResizeDirection.BottomRight;
Cursor = Cursors.SizeNWSE;
}
else if (e.Location.X > Width - BORDER_WIDTH && !isChildUnderMouse && !Maximized)
{
resizeDir = ResizeDirection.Right;
Cursor = Cursors.SizeWE;
}
else if (e.Location.Y > Height - BORDER_WIDTH && !isChildUnderMouse && !Maximized)
{
resizeDir = ResizeDirection.Bottom;
Cursor = Cursors.SizeNS;
}
else if (e.Location.Y < BORDER_WIDTH && !isChildUnderMouse && !Maximized)
else
{
resizeDir = ResizeDirection.Top;
Cursor = Cursors.SizeNS;
if (e.Location.X < BORDER_WIDTH && e.Location.Y > Height - BORDER_WIDTH && !isChildUnderMouse && !Maximized)
{
resizeDir = ResizeDirection.BottomLeft;
Cursor = Cursors.SizeNESW;
}
else if (e.Location.Y < BORDER_WIDTH && e.Location.X < BORDER_WIDTH && !isChildUnderMouse && !Maximized)
{
resizeDir = ResizeDirection.TopLeft;
Cursor = Cursors.SizeNWSE;
}
else if (e.Location.Y < BORDER_WIDTH && e.Location.X > Width - BORDER_WIDTH && !isChildUnderMouse && !Maximized)
{
resizeDir = ResizeDirection.TopRight;
Cursor = Cursors.SizeNESW;
}
else if (e.Location.X < BORDER_WIDTH && !isChildUnderMouse && !Maximized)
{
resizeDir = ResizeDirection.Left;
Cursor = Cursors.SizeWE;
}
else if (e.Location.X > Width - BORDER_WIDTH && e.Location.Y > Height - BORDER_WIDTH && !isChildUnderMouse && !Maximized)
{
resizeDir = ResizeDirection.BottomRight;
Cursor = Cursors.SizeNWSE;
}
else if (e.Location.X > Width - BORDER_WIDTH && !isChildUnderMouse && !Maximized)
{
resizeDir = ResizeDirection.Right;
Cursor = Cursors.SizeWE;
}
else if (e.Location.Y > Height - BORDER_WIDTH && !isChildUnderMouse && !Maximized)
{
resizeDir = ResizeDirection.Bottom;
Cursor = Cursors.SizeNS;
}
else if (e.Location.Y < BORDER_WIDTH && !isChildUnderMouse && !Maximized)
{
resizeDir = ResizeDirection.Top;
Cursor = Cursors.SizeNS;
}
else
{
resizeDir = ResizeDirection.None;
//Only reset the cursur when needed, this prevents it from flickering when a child control changes the cursor to its own needs
if (resizeCursors.Contains(Cursor))
{
Cursor = Cursors.Default;
}
}
}
else
{
resizeDir = ResizeDirection.None;
//Only reset the cursur when needed, this prevents it from flickering when a child control changes the cursor to its own needs
if (resizeCursors.Contains(Cursor))
{
Cursor = Cursors.Default;
}
}
}
UpdateButtons(e);
@ -512,7 +526,7 @@ namespace MaterialSkin.Controls
var g = e.Graphics;
g.TextRenderingHint = TextRenderingHint.AntiAlias;
g.Clear(SkinManager.GetApplicationBackgroundColor());
g.Clear(SkinManager.GetApplicationBackgroundColor(Resize_Enabled));
g.FillRectangle(SkinManager.ColorScheme.DarkPrimaryBrush, statusBarBounds);
g.FillRectangle(SkinManager.ColorScheme.PrimaryBrush, actionBarBounds);

14
Material Skin/MaterialSkinManager.cs

@ -225,6 +225,15 @@ namespace MaterialSkin
return (Theme == Themes.LIGHT ? BACKGROUND_LIGHT : BACKGROUND_DARK);
}
public Color GetApplicationBackgroundColor(bool re)
{
if (!re && Theme == Themes.LIGHT)
{
return Color.FromArgb(255, 255, 255, 255);
}
return GetApplicationBackgroundColor();
}
//Roboto font
public Font ROBOTO_MEDIUM_12;
public Font ROBOTO_REGULAR_11;
@ -283,6 +292,11 @@ namespace MaterialSkin
var newBackColor = GetApplicationBackgroundColor();
foreach (var materialForm in formsToManage)
{
if (!materialForm.Resize_Enabled && Theme == Themes.LIGHT)
{
newBackColor = Color.FromArgb(255, 255, 255, 255);
}
materialForm.BackColor = newBackColor;
UpdateControl(materialForm, newBackColor);
}

Loading…
Cancel
Save