diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b1376f4
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+.vs/
+Pixerys/bin/
+Pixerys/obj/
\ No newline at end of file
diff --git a/Pixerys.sln b/Pixerys.sln
new file mode 100644
index 0000000..3897b98
--- /dev/null
+++ b/Pixerys.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.13.35913.81 d17.13
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pixerys", "Pixerys\Pixerys.csproj", "{5E93EA21-7256-486B-89D9-D2B744C67C72}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {5E93EA21-7256-486B-89D9-D2B744C67C72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5E93EA21-7256-486B-89D9-D2B744C67C72}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5E93EA21-7256-486B-89D9-D2B744C67C72}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5E93EA21-7256-486B-89D9-D2B744C67C72}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {45B69ACE-620D-40CC-B414-84CCF3F216B9}
+ EndGlobalSection
+EndGlobal
diff --git a/Pixerys/App.axaml b/Pixerys/App.axaml
new file mode 100644
index 0000000..44d99c7
--- /dev/null
+++ b/Pixerys/App.axaml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Pixerys/App.axaml.cs b/Pixerys/App.axaml.cs
new file mode 100644
index 0000000..958b9d0
--- /dev/null
+++ b/Pixerys/App.axaml.cs
@@ -0,0 +1,28 @@
+using Avalonia;
+using Avalonia.Controls.ApplicationLifetimes;
+using Avalonia.Markup.Xaml;
+using Pixerys.ViewModels;
+
+namespace Pixerys
+{
+ public partial class App : Application
+ {
+ public override void Initialize()
+ {
+ AvaloniaXamlLoader.Load(this);
+ }
+
+ public override void OnFrameworkInitializationCompleted()
+ {
+ if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
+ {
+ desktop.MainWindow = new MainWindow()
+ {
+ DataContext = new PaletteSelectorViewModel(),
+ };
+ }
+
+ base.OnFrameworkInitializationCompleted();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Pixerys/Controls/FrameColorPicker.axaml b/Pixerys/Controls/FrameColorPicker.axaml
new file mode 100644
index 0000000..c4a5098
--- /dev/null
+++ b/Pixerys/Controls/FrameColorPicker.axaml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Pixerys/Controls/FrameColorPicker.axaml.cs b/Pixerys/Controls/FrameColorPicker.axaml.cs
new file mode 100644
index 0000000..8427f1b
--- /dev/null
+++ b/Pixerys/Controls/FrameColorPicker.axaml.cs
@@ -0,0 +1,7 @@
+using Avalonia.Controls.Primitives;
+
+namespace Pixerys.Controls;
+
+public class FrameColorPicker : TemplatedControl
+{
+}
\ No newline at end of file
diff --git a/Pixerys/Controls/RingColorPicker.axaml b/Pixerys/Controls/RingColorPicker.axaml
new file mode 100644
index 0000000..d28256d
--- /dev/null
+++ b/Pixerys/Controls/RingColorPicker.axaml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Pixerys/Controls/RingColorPicker.axaml.cs b/Pixerys/Controls/RingColorPicker.axaml.cs
new file mode 100644
index 0000000..9248975
--- /dev/null
+++ b/Pixerys/Controls/RingColorPicker.axaml.cs
@@ -0,0 +1,215 @@
+using Avalonia.Controls.Metadata;
+using Avalonia;
+using Avalonia.Controls.Primitives;
+using Avalonia.Controls.Shapes;
+using Avalonia.Data;
+using Avalonia.Media;
+using System;
+
+namespace Pixerys.Controls;
+
+[TemplatePart("PART_Selector", typeof(Ellipse))]
+public class RingColorPicker : TemplatedControl
+{
+ Ellipse? selector;
+
+ private double centerX;
+ private double centerY;
+
+ private bool IsToggled = false;
+
+ public static readonly DirectProperty ShowProperty =
+ AvaloniaProperty.RegisterDirect(
+ nameof(Show),
+ o => o.Show,
+ (o, v) => o.Show = v,
+ defaultBindingMode: BindingMode.TwoWay);
+
+ private bool _show;
+
+ public bool Show
+ {
+ get { return _show; }
+ set { SetAndRaise(ShowProperty, ref _show, value); }
+ }
+
+ public static readonly DirectProperty PosXProperty =
+ AvaloniaProperty.RegisterDirect(
+ nameof(PosX),
+ o => o.PosX,
+ (o, v) => o.PosX = v,
+ defaultBindingMode: BindingMode.TwoWay);
+
+ private double _posX;
+
+ public double PosX
+ {
+ get { return _posX; }
+ set { SetAndRaise(PosXProperty, ref _posX, value); }
+ }
+
+ public static readonly DirectProperty PosYProperty =
+ AvaloniaProperty.RegisterDirect(
+ nameof(PosY),
+ o => o.PosY,
+ (o, v) => o.PosY = v,
+ defaultBindingMode: BindingMode.TwoWay);
+
+ private double _posY;
+
+ public double PosY
+ {
+ get { return _posY; }
+ set { SetAndRaise(PosYProperty, ref _posY, value); }
+ }
+
+ public static readonly DirectProperty SelectorAngleProperty =
+ AvaloniaProperty.RegisterDirect(
+ nameof(SelectorAngle),
+ o => o.SelectorAngle,
+ (o, v) => o.SelectorAngle = v,
+ defaultBindingMode: BindingMode.TwoWay);
+
+ private double _selectorAngle;
+
+ public double SelectorAngle
+ {
+ get { return _selectorAngle; }
+ set { SetAndRaise(SelectorAngleProperty, ref _selectorAngle, value); }
+ }
+
+ public static readonly DirectProperty SnappedAngleProperty =
+ AvaloniaProperty.RegisterDirect(
+ nameof(SnappedAngle),
+ o => o.SnappedAngle,
+ (o, v) => o.SnappedAngle = v,
+ defaultBindingMode: BindingMode.TwoWay);
+
+ private double _snappedAngle;
+
+ public double SnappedAngle
+ {
+ get { return _selectorAngle; }
+ set { SetAndRaise(SnappedAngleProperty, ref _snappedAngle, value); }
+ }
+
+ public static readonly DirectProperty GetColorProperty =
+ AvaloniaProperty.RegisterDirect(
+ nameof(GetColor),
+ o => o.GetColor,
+ (o, v) => o.GetColor = v,
+ defaultBindingMode: BindingMode.TwoWay);
+
+ private Color _getColor;
+
+ public Color GetColor
+ {
+ get { return _getColor; }
+ set { SetAndRaise(GetColorProperty, ref _getColor, value); }
+ }
+
+ public static readonly DirectProperty RComponentProperty =
+ AvaloniaProperty.RegisterDirect(
+ nameof(RComponent),
+ o => o.RComponent,
+ defaultBindingMode: BindingMode.OneWayToSource);
+
+ private byte _rComponent = 0;
+
+ public byte RComponent
+ {
+ get { return _rComponent; }
+ private set { SetAndRaise(RComponentProperty, ref _rComponent, value); }
+ }
+
+ public static readonly DirectProperty GComponentProperty =
+ AvaloniaProperty.RegisterDirect(
+ nameof(GComponent),
+ o => o.GComponent,
+ defaultBindingMode: BindingMode.OneWayToSource);
+
+ private byte _gComponent = 0;
+
+ public byte GComponent
+ {
+ get { return _gComponent; }
+ private set { SetAndRaise(GComponentProperty, ref _gComponent, value); }
+ }
+
+ public static readonly DirectProperty BComponentProperty =
+ AvaloniaProperty.RegisterDirect(
+ nameof(BComponent),
+ o => o.BComponent,
+ defaultBindingMode: BindingMode.OneWayToSource);
+
+ private byte _bComponent = 0;
+
+ public byte BComponent
+ {
+ get { return _bComponent; }
+ private set { SetAndRaise(BComponentProperty, ref _bComponent, value); }
+ }
+
+ private readonly ConicGradientBrush RingRGBConicGradientBrush = new()
+ {
+ GradientStops =
+ [
+ new GradientStop(new Color(255,255,255,0), 0.0),
+ new GradientStop(new Color(255,0,255,0), 0.165),
+ new GradientStop(new Color(255,0,255,255), 0.33),
+ new GradientStop(new Color(255,0,0,255), 0.495),
+ new GradientStop(new Color(255,255,0,255), 0.66),
+ new GradientStop(new Color(255,255,0,0), 0.825),
+ new GradientStop(new Color(255,255,255,0), 1.0),
+ ],
+ };
+
+ protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
+ {
+ base.OnApplyTemplate(e);
+
+ selector = e.NameScope.Find("PART_Selector") as Ellipse;
+
+ if (selector != null)
+ {
+ selector.Stroke = RingRGBConicGradientBrush;
+ selector.IsVisible = Show;
+ selector.StrokeThickness = selector.Width / 10.5;
+ selector.PointerPressed += Selector_PointerPressed;
+ selector.PointerMoved += Selector_PointerMoved;
+ selector.PointerReleased += Selector_PointerReleased;
+ centerX = (selector.Width / 2);
+ centerY = (selector.Height / 2);
+ SelectorAngle = 89;
+ RComponent = (byte)(GetColor.R >> 3);
+ GComponent = (byte)(GetColor.G >> 3);
+ BComponent = (byte)(GetColor.B >> 3);
+ }
+ }
+
+ private void Selector_PointerPressed(object? sender, Avalonia.Input.PointerPressedEventArgs e)
+ {
+ IsToggled = true;
+ }
+
+ private void Selector_PointerMoved(object? sender, Avalonia.Input.PointerEventArgs e)
+ {
+ Point pos = e.GetPosition(this);
+ double angle = Math.Atan2(pos.Y - centerY, pos.X - centerY) * (180 / Math.PI);
+
+ if (IsToggled == true)
+ {
+ PosX = pos.X - centerX;
+ PosY = pos.Y - centerY;
+ SelectorAngle = 360 - (180 - angle);
+ RComponent = (byte)(GetColor.R >> 3);
+ GComponent = (byte)(GetColor.G >> 3);
+ BComponent = (byte)(GetColor.B >> 3);
+ }
+ }
+
+ private void Selector_PointerReleased(object? sender, Avalonia.Input.PointerReleasedEventArgs e)
+ {
+ IsToggled = false;
+ }
+}
\ No newline at end of file
diff --git a/Pixerys/Controls/SaturationColorPicker.axaml b/Pixerys/Controls/SaturationColorPicker.axaml
new file mode 100644
index 0000000..9840c0c
--- /dev/null
+++ b/Pixerys/Controls/SaturationColorPicker.axaml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Pixerys/Controls/SaturationColorPicker.axaml.cs b/Pixerys/Controls/SaturationColorPicker.axaml.cs
new file mode 100644
index 0000000..dee9147
--- /dev/null
+++ b/Pixerys/Controls/SaturationColorPicker.axaml.cs
@@ -0,0 +1,124 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Controls.Metadata;
+using Avalonia.Controls.Primitives;
+using Avalonia.Data;
+using Avalonia.Media;
+
+namespace Pixerys.Controls;
+
+[TemplatePart("PART_SaturationPicker", typeof(ContentControl))]
+public class SaturationColorPicker : TemplatedControl
+{
+ ContentControl? saturationPicker;
+
+ private bool IsToggled = false;
+
+ public static readonly DirectProperty PosXProperty =
+ AvaloniaProperty.RegisterDirect(
+ nameof(PosX),
+ o => o.PosX,
+ (o, v) => o.PosX = v,
+ defaultBindingMode: BindingMode.TwoWay);
+
+ private double _posX;
+
+ public double PosX
+ {
+ get { return _posX; }
+ set { SetAndRaise(PosXProperty, ref _posX, value); }
+ }
+
+ public static readonly DirectProperty PosYProperty =
+ AvaloniaProperty.RegisterDirect(
+ nameof(PosY),
+ o => o.PosY,
+ (o, v) => o.PosY = v,
+ defaultBindingMode: BindingMode.TwoWay);
+
+ private double _posY;
+
+ public double PosY
+ {
+ get { return _posY; }
+ set { SetAndRaise(PosYProperty, ref _posY, value); }
+ }
+
+ public static readonly DirectProperty LinearGradientBlackProperty =
+ AvaloniaProperty.RegisterDirect(
+ nameof(LinearGradientBlack),
+ o => o.LinearGradientBlack);
+
+ private LinearGradientBrush _linearGradientBlack = new()
+ {
+ StartPoint = new RelativePoint(new Point(0, 1), RelativeUnit.Relative),
+ EndPoint = new RelativePoint(new Point(0, 0), RelativeUnit.Relative),
+
+ GradientStops = [
+ new GradientStop(new Color(255, 0, 0, 0), 0.0),
+ new GradientStop(new Color(0, 0, 0, 0), 1.0),
+ ],
+ };
+
+ public LinearGradientBrush LinearGradientBlack
+ {
+ get { return _linearGradientBlack; }
+ set { SetAndRaise(LinearGradientBlackProperty, ref _linearGradientBlack, value); }
+ }
+
+ public static readonly DirectProperty LinearGradientWhiteProperty =
+ AvaloniaProperty.RegisterDirect(
+ nameof(LinearGradientWhite),
+ o => o.LinearGradientWhite);
+
+ private LinearGradientBrush _linearGradientWhite = new()
+ {
+ StartPoint = new RelativePoint(new Point(0, 0), RelativeUnit.Relative),
+ EndPoint = new RelativePoint(new Point(1, 0), RelativeUnit.Relative),
+
+ GradientStops = [
+ new GradientStop(new Color(255, 255, 255, 255), 0.0),
+ new GradientStop(new Color(0, 255, 255, 255), 1.0),
+ ],
+ };
+
+ public LinearGradientBrush LinearGradientWhite
+ {
+ get { return _linearGradientWhite; }
+ set { SetAndRaise(LinearGradientWhiteProperty, ref _linearGradientWhite, value); }
+ }
+ protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
+ {
+ base.OnApplyTemplate(e);
+
+ saturationPicker = e.NameScope.Find("PART_SaturationPicker") as ContentControl;
+
+ if (saturationPicker != null)
+ {
+ saturationPicker.PointerPressed += SaturationPicker_PointerPressed;
+ saturationPicker.PointerMoved += SaturationPicker_PointerMoved;
+ saturationPicker.PointerReleased += SaturationPicker_PointerReleased;
+ }
+ }
+
+ private void SaturationPicker_PointerReleased(object? sender, Avalonia.Input.PointerReleasedEventArgs e)
+ {
+ IsToggled = false;
+ }
+
+ private void SaturationPicker_PointerMoved(object? sender, Avalonia.Input.PointerEventArgs e)
+ {
+ Point pos = e.GetPosition(saturationPicker);
+
+ if (IsToggled == true)
+ {
+ PosX = pos.X;
+ PosY = pos.Y;
+ }
+ }
+
+ private void SaturationPicker_PointerPressed(object? sender, Avalonia.Input.PointerPressedEventArgs e)
+ {
+ IsToggled = true;
+ }
+}
\ No newline at end of file
diff --git a/Pixerys/Controls/SelectorColorPicker.axaml b/Pixerys/Controls/SelectorColorPicker.axaml
new file mode 100644
index 0000000..e22b78a
--- /dev/null
+++ b/Pixerys/Controls/SelectorColorPicker.axaml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Pixerys/Controls/SelectorColorPicker.axaml.cs b/Pixerys/Controls/SelectorColorPicker.axaml.cs
new file mode 100644
index 0000000..7c1b862
--- /dev/null
+++ b/Pixerys/Controls/SelectorColorPicker.axaml.cs
@@ -0,0 +1,59 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Controls.Metadata;
+using Avalonia.Controls.Primitives;
+using Avalonia.Controls.Shapes;
+using Avalonia.Data;
+using Avalonia.Media;
+using Avalonia.Metadata;
+
+namespace Pixerys.Controls;
+
+[TemplatePart("PART_SelectorPresenter", typeof(Ellipse))]
+public class SelectorColorPicker : TemplatedControl
+{
+ Ellipse? selectorPresenter;
+
+ public static readonly DirectProperty CenterXProperty =
+ AvaloniaProperty.RegisterDirect(
+ nameof(CenterX),
+ o => o.CenterX,
+ (o, v) => o.CenterX = v,
+ defaultBindingMode: BindingMode.TwoWay);
+
+ private double _centerX;
+
+ public double CenterX
+ {
+ get { return _centerX; }
+ set { SetAndRaise(CenterXProperty, ref _centerX, value); }
+ }
+
+ public static readonly DirectProperty CenterYProperty =
+ AvaloniaProperty.RegisterDirect(
+ nameof(CenterY),
+ o => o.CenterY,
+ (o, v) => o.CenterY = v,
+ defaultBindingMode: BindingMode.TwoWay);
+
+ private double _centerY;
+
+ public double CenterY
+ {
+ get { return _centerY; }
+ set { SetAndRaise(CenterYProperty, ref _centerY, value); }
+ }
+ protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
+ {
+ base.OnApplyTemplate(e);
+
+ selectorPresenter = e.NameScope.Find("PART_SelectorPresenter") as Ellipse;
+
+ if (selectorPresenter != null)
+ {
+ CenterX = selectorPresenter.Width / 2;
+ CenterY = selectorPresenter.Height / 2;
+ selectorPresenter.StrokeThickness = selectorPresenter.Width * 0.2;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Pixerys/Converters/AngleToRGB.cs b/Pixerys/Converters/AngleToRGB.cs
new file mode 100644
index 0000000..bb6e5c8
--- /dev/null
+++ b/Pixerys/Converters/AngleToRGB.cs
@@ -0,0 +1,119 @@
+using Avalonia.Data.Converters;
+using Avalonia.Media;
+using System;
+using System.Globalization;
+
+namespace Pixerys.Converters
+{
+ internal class AngleToRGB : IValueConverter
+ {
+ public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
+ {
+ if(value is double inputAngle)
+ {
+ const double baseAngle = 0.9375;
+ const double step = 1.875;
+ const int maxIndex = 191;
+ int index = (int)Math.Round((inputAngle - baseAngle) / step);
+ index = Math.Clamp(index, 0, maxIndex);
+ double snappedAngle = baseAngle + index * step;
+
+ byte r = 0;
+ byte g = 0;
+ byte b = 0;
+
+ switch (index)
+ {
+ case < 15:
+ r = 31;
+ b = (byte)(15 - index);
+ g = 0;
+ break;
+ case 15:
+ r = 31;
+ b = 0;
+ g = 0;
+ break;
+ case < 47:
+ r = 31;
+ g = (byte)(index - 15);
+ b = 0;
+ break;
+ case 47:
+ r = 31;
+ g = 31;
+ b = 0;
+ break;
+ case < 78:
+ r = (byte)(78 - index);
+ g = 31;
+ b = 0;
+ break;
+ case 78:
+ r = 0;
+ g = 31;
+ b = 0;
+ break;
+ case < 109:
+ r = 0;
+ g = 31;
+ b = (byte)(index - 78);
+ break;
+ case 109:
+ r = 0;
+ g = 31;
+ b = 31;
+ break;
+ case < 140:
+ r = 0;
+ g = (byte)(140 - index);
+ b = 31;
+ break;
+ case 140:
+ r = 0;
+ g = 0;
+ b = 31;
+ break;
+ case < 171:
+ r = (byte)(index - 140);
+ g = 0;
+ b = 31;
+ break;
+ case 171:
+ r = 31;
+ g = 0;
+ b = 31;
+ break;
+ case < 192:
+ r = 31;
+ g = 0;
+ b = (byte)(202 - index);
+ break;
+ }
+
+ if(targetType == typeof(double))
+ {
+ return snappedAngle;
+ }
+ if(targetType == typeof(string))
+ {
+ return snappedAngle;
+ }
+ if(targetType == typeof(IBrush) || targetType == typeof(Brush))
+ {
+ return new SolidColorBrush(Color.FromRgb((byte)(r << 3), (byte)(g << 3), (byte)(b << 3)));
+ }
+ if(targetType == typeof(Color))
+ {
+ return new Color(255, (byte)(r << 3), (byte)(g << 3), (byte)(b << 3));
+ }
+ }
+ return 0;
+ }
+
+ public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/Pixerys/Pixerys.csproj b/Pixerys/Pixerys.csproj
new file mode 100644
index 0000000..ef2293d
--- /dev/null
+++ b/Pixerys/Pixerys.csproj
@@ -0,0 +1,27 @@
+
+
+ WinExe
+ net8.0
+ enable
+ true
+ app.manifest
+ true
+
+
+
+
+
+
+
+
+
+ None
+ All
+
+
+
+
+
+
+
+
diff --git a/Pixerys/Program.cs b/Pixerys/Program.cs
new file mode 100644
index 0000000..002e2f8
--- /dev/null
+++ b/Pixerys/Program.cs
@@ -0,0 +1,22 @@
+using System;
+using Avalonia;
+
+namespace Pixerys
+{
+ internal class Program
+ {
+ // Initialization code. Don't use any Avalonia, third-party APIs or any
+ // SynchronizationContext-reliant code before AppMain is called: things aren't initialized
+ // yet and stuff might break.
+ [STAThread]
+ public static void Main(string[] args) => BuildAvaloniaApp()
+ .StartWithClassicDesktopLifetime(args);
+
+ // Avalonia configuration, don't remove; also used by visual designer.
+ public static AppBuilder BuildAvaloniaApp()
+ => AppBuilder.Configure()
+ .UsePlatformDetect()
+ .WithInterFont()
+ .LogToTrace();
+ }
+}
diff --git a/Pixerys/UserControls/PaletteSelector.axaml b/Pixerys/UserControls/PaletteSelector.axaml
new file mode 100644
index 0000000..c11557d
--- /dev/null
+++ b/Pixerys/UserControls/PaletteSelector.axaml
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Pixerys/UserControls/PaletteSelector.axaml.cs b/Pixerys/UserControls/PaletteSelector.axaml.cs
new file mode 100644
index 0000000..3bd97bc
--- /dev/null
+++ b/Pixerys/UserControls/PaletteSelector.axaml.cs
@@ -0,0 +1,13 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+
+namespace Pixerys;
+
+public partial class PaletteSelector : UserControl
+{
+ public PaletteSelector()
+ {
+ InitializeComponent();
+ }
+}
\ No newline at end of file
diff --git a/Pixerys/ViewModels/MainWindowViewModel.cs b/Pixerys/ViewModels/MainWindowViewModel.cs
new file mode 100644
index 0000000..8ecff39
--- /dev/null
+++ b/Pixerys/ViewModels/MainWindowViewModel.cs
@@ -0,0 +1,24 @@
+using CommunityToolkit.Mvvm.ComponentModel;
+using CommunityToolkit.Mvvm.Input;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Pixerys.ViewModels
+{
+ internal partial class MainWindowViewModel : ViewModelBase
+ {
+ [ObservableProperty]
+ private string _name = "Kaerys";
+
+ [RelayCommand]
+ public void ButtonOnClick()
+ {
+ Name = "Kaerys Diaz";
+ }
+ }
+}
diff --git a/Pixerys/ViewModels/PaletteSelectorViewModel.cs b/Pixerys/ViewModels/PaletteSelectorViewModel.cs
new file mode 100644
index 0000000..f19a13f
--- /dev/null
+++ b/Pixerys/ViewModels/PaletteSelectorViewModel.cs
@@ -0,0 +1,31 @@
+using CommunityToolkit.Mvvm.ComponentModel;
+
+namespace Pixerys.ViewModels
+{
+ internal partial class PaletteSelectorViewModel : ViewModelBase
+ {
+ [ObservableProperty]
+ private double _posX = 10;
+
+ [ObservableProperty]
+ private double _posY = 8;
+
+ [ObservableProperty]
+ private double _selectorAngle = 0.9375;
+
+ [ObservableProperty]
+ private double _posXSaturation = 0;
+
+ [ObservableProperty]
+ private double _posYSaturation = 0;
+
+ [ObservableProperty]
+ private byte _rComponent;
+
+ [ObservableProperty]
+ private byte _gComponent;
+
+ [ObservableProperty]
+ private byte _bComponent;
+ }
+}
diff --git a/Pixerys/ViewModels/ViewModelBase.cs b/Pixerys/ViewModels/ViewModelBase.cs
new file mode 100644
index 0000000..7e1efb0
--- /dev/null
+++ b/Pixerys/ViewModels/ViewModelBase.cs
@@ -0,0 +1,9 @@
+
+using CommunityToolkit.Mvvm.ComponentModel;
+
+namespace Pixerys.ViewModels
+{
+ internal class ViewModelBase : ObservableObject
+ {
+ }
+}
diff --git a/Pixerys/Views/MainWindow.axaml b/Pixerys/Views/MainWindow.axaml
new file mode 100644
index 0000000..95a59c4
--- /dev/null
+++ b/Pixerys/Views/MainWindow.axaml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
diff --git a/Pixerys/Views/MainWindow.axaml.cs b/Pixerys/Views/MainWindow.axaml.cs
new file mode 100644
index 0000000..3efa33a
--- /dev/null
+++ b/Pixerys/Views/MainWindow.axaml.cs
@@ -0,0 +1,12 @@
+using Avalonia.Controls;
+
+namespace Pixerys
+{
+ public partial class MainWindow : Window
+ {
+ public MainWindow()
+ {
+ InitializeComponent();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Pixerys/app.manifest b/Pixerys/app.manifest
new file mode 100644
index 0000000..4fe4c8a
--- /dev/null
+++ b/Pixerys/app.manifest
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+