-
-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
268 additions
and
67 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
|
||
<Grid xmlns="http://schemas.microsoft.com/dotnet/2021/maui" | ||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" | ||
x:Class="Orbit.Studio.Controls.ColorPicker" | ||
RowDefinitions="*,*,*,*,*" | ||
ColumnDefinitions="*,Auto"> | ||
|
||
<Slider Minimum="0" Maximum="255" Value="255" x:Name="Red" ValueChanged="OnColorSliderValueChanged" /> | ||
<Entry Text="{Binding Value, Source={x:Reference Red}}" Grid.Column="1" /> | ||
|
||
<Slider Minimum="0" Maximum="255" Value="0" x:Name="Blue" ValueChanged="OnColorSliderValueChanged" Grid.Row="1" /> | ||
<Entry Text="{Binding Value, Source={x:Reference Blue}}" Grid.Column="1" Grid.Row="1" /> | ||
|
||
<Slider Minimum="0" Maximum="255" Value="0" x:Name="Green" ValueChanged="OnColorSliderValueChanged" Grid.Row="2" /> | ||
<Entry Text="{Binding Value, Source={x:Reference Green}}" Grid.Column="1" Grid.Row="2" /> | ||
|
||
<Slider Minimum="0" Maximum="255" Value="255" x:Name="Alpha" ValueChanged="OnColorSliderValueChanged" Grid.Row="3" /> | ||
<Entry Text="{Binding Value, Source={x:Reference Alpha}}" Grid.Column="1" Grid.Row="3" /> | ||
|
||
<BoxView x:Name="ColorPreview" WidthRequest="50" HeightRequest="50" Grid.Row="4" /> | ||
|
||
</Grid> |
42 changes: 42 additions & 0 deletions
42
games/Orbit.Studio/Orbit.Studio/Controls/ColorPicker.xaml.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
namespace Orbit.Studio.Controls; | ||
|
||
public partial class ColorPicker : Grid | ||
{ | ||
public ColorPicker() | ||
{ | ||
InitializeComponent(); | ||
} | ||
|
||
private void OnColorSliderValueChanged(object? sender, ValueChangedEventArgs e) | ||
{ | ||
SelectedColor = Color.FromRgba( | ||
Red.Value / 255d, | ||
Blue.Value / 255d, | ||
Green.Value / 255d, | ||
Alpha.Value / 255d); | ||
} | ||
|
||
public static readonly BindableProperty SelectedColorProperty = | ||
BindableProperty.Create( | ||
nameof(SelectedColor), | ||
typeof(Color), | ||
typeof(ColorPicker), | ||
Colors.Black, | ||
propertyChanged: OnSelectedColorPropertyChanged); | ||
|
||
private static void OnSelectedColorPropertyChanged(BindableObject sender, object oldValue, object newValue) | ||
{ | ||
((ColorPicker)sender).UpdatePreviewColor(); | ||
} | ||
|
||
private void UpdatePreviewColor() | ||
{ | ||
ColorPreview.BackgroundColor = SelectedColor; | ||
} | ||
|
||
public Color SelectedColor | ||
{ | ||
get => (Color)GetValue(SelectedColorProperty); | ||
set => SetValue(SelectedColorProperty, value); | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 52 additions & 0 deletions
52
games/Orbit.Studio/Orbit.Studio/Sprites/SpriteEditorPage.xaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
|
||
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" | ||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" | ||
xmlns:controls="clr-namespace:Orbit.Studio.Controls" | ||
x:Class="Orbit.Studio.Sprites.SpriteEditorPage" | ||
Title="Sprite Editor"> | ||
|
||
<Grid ColumnDefinitions="2*,*"> | ||
<VerticalStackLayout Grid.Column="1" Spacing="10"> | ||
<HorizontalStackLayout> | ||
<Label Text="Width" VerticalOptions="Center"/> | ||
<Entry Keyboard="Numeric" Text="16" TextChanged="WidthEntry_OnTextChanged" /> | ||
</HorizontalStackLayout> | ||
<HorizontalStackLayout> | ||
<Label Text="Height" VerticalOptions="Center"/> | ||
<Entry Keyboard="Numeric" Text="16" TextChanged="HeightEntry_OnTextChanged" /> | ||
</HorizontalStackLayout> | ||
|
||
<Label Text="Zoom" /> | ||
<Slider | ||
x:Name="Zoom" | ||
Minimum="1" | ||
Maximum="50" | ||
Value="1" | ||
ValueChanged="Zoom_OnValueChanged"/> | ||
|
||
<HorizontalStackLayout> | ||
<Label Text="Show grid lines" VerticalOptions="Center"/> | ||
<CheckBox x:Name="ShowGridLines" CheckedChanged="ShowGridLines_OnCheckedChanged" /> | ||
</HorizontalStackLayout> | ||
|
||
<HorizontalStackLayout> | ||
<Label Text="Show chessboard" VerticalOptions="Center"/> | ||
<CheckBox x:Name="ShowChessboard" CheckedChanged="ShowChessboard_OnCheckedChanged" /> | ||
</HorizontalStackLayout> | ||
|
||
<Button Text="Undo" Clicked="OnUndoClicked" /> | ||
|
||
<controls:ColorPicker x:Name="ColorPicker" /> | ||
|
||
<Button Clicked="Button_OnClicked" Text="Export" /> | ||
</VerticalStackLayout> | ||
|
||
<GraphicsView | ||
x:Name="Canvas" | ||
Drawable="{Binding}" | ||
MoveHoverInteraction="Canvas_OnMoveHoverInteraction" | ||
EndInteraction="GraphicsView_OnEndInteraction"/> | ||
</Grid> | ||
|
||
</ContentPage> |
145 changes: 145 additions & 0 deletions
145
games/Orbit.Studio/Orbit.Studio/Sprites/SpriteEditorPage.xaml.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
using Microsoft.Maui.Graphics.Skia; | ||
|
||
using SkiaSharp; | ||
|
||
namespace Orbit.Studio.Sprites; | ||
|
||
public partial class SpriteEditorPage : ContentPage, IDrawable | ||
{ | ||
public SpriteEditorPage() | ||
{ | ||
InitializeComponent(); | ||
BindingContext = this; | ||
} | ||
|
||
private int width = 16; | ||
private int height = 16; | ||
private IList<Pixel> pixels = []; | ||
private float mouseX; | ||
private float mouseY; | ||
|
||
private void GraphicsView_OnEndInteraction(object? sender, TouchEventArgs e) | ||
{ | ||
pixels.Add(new Pixel { Color = ColorPicker.SelectedColor, Location = new PointF(mouseX, mouseY) }); | ||
} | ||
|
||
public void Draw(ICanvas canvas, RectF dirtyRect) | ||
{ | ||
Render(canvas, dirtyRect, (float)Zoom.Value, ShowGridLines.IsChecked, ShowChessboard.IsChecked); | ||
} | ||
|
||
private void Render(ICanvas canvas, RectF bounds, float zoomFactor, bool showGridLines, bool showChessboard) | ||
{ | ||
var renderedWidth = width * zoomFactor; | ||
var renderedHeight = height * zoomFactor; | ||
|
||
if (showChessboard) | ||
{ | ||
for (int x = 0; x < width; x++) | ||
{ | ||
for (int y = 0; y < height; y++) | ||
{ | ||
var number = y % 2 == 0 ? 1 : 0; | ||
canvas.FillColor = x % 2 == number ? Colors.White : Color.FromRgb(192 / 255d, 192 / 255d, 192 / 255d); | ||
canvas.FillRectangle(x * zoomFactor, y * zoomFactor, 1 * zoomFactor, 1 * zoomFactor); | ||
} | ||
} | ||
} | ||
|
||
if (showGridLines) | ||
{ | ||
var lineColor = Color.FromRgb(192 / 255d, 192 / 255d, 192 / 255d); | ||
|
||
for (int x = 1; x < width; x++) | ||
{ | ||
canvas.StrokeColor = lineColor; | ||
canvas.DrawLine(x * zoomFactor, 0, x * zoomFactor, height * zoomFactor); | ||
} | ||
|
||
for (int y = 1; y < height; y++) | ||
{ | ||
canvas.StrokeColor = lineColor; | ||
canvas.DrawLine(0, y * zoomFactor, width * zoomFactor, y * zoomFactor); | ||
} | ||
} | ||
|
||
foreach (var tile in pixels) | ||
{ | ||
canvas.FillColor = tile.Color; | ||
canvas.FillRectangle(tile.Location.X * zoomFactor, tile.Location.Y * zoomFactor, zoomFactor, zoomFactor); | ||
} | ||
|
||
canvas.FillColor = ColorPicker.SelectedColor; | ||
canvas.FillRectangle(mouseX * zoomFactor, mouseY * zoomFactor, zoomFactor, zoomFactor); | ||
} | ||
|
||
private void Zoom_OnValueChanged(object? sender, ValueChangedEventArgs e) | ||
{ | ||
Canvas.Invalidate(); | ||
} | ||
|
||
private void Canvas_OnMoveHoverInteraction(object? sender, TouchEventArgs e) | ||
{ | ||
var touch = e.Touches.First(); | ||
|
||
var zoomFactor = (float)Zoom.Value; | ||
|
||
mouseX = MathF.Floor(touch.X / zoomFactor); | ||
mouseY = MathF.Floor(touch.Y / zoomFactor); | ||
|
||
Canvas.Invalidate(); | ||
} | ||
|
||
private void Export() | ||
{ | ||
using var canvas = new SkiaCanvas(); | ||
using var bitmap = new SKBitmap(new SKImageInfo(width, height)); | ||
canvas.Canvas = new SKCanvas(bitmap); | ||
|
||
Render(canvas, new RectF(0, 0, width, height), 1f, false, false); | ||
|
||
var path = Path.Combine(FileSystem.AppDataDirectory, @"sprite.png"); | ||
using var stream = File.Create(path); | ||
bitmap.Encode(stream, SKEncodedImageFormat.Png, 100); | ||
} | ||
|
||
private void Button_OnClicked(object? sender, EventArgs e) | ||
{ | ||
Export(); | ||
} | ||
|
||
private void ShowGridLines_OnCheckedChanged(object? sender, CheckedChangedEventArgs e) | ||
{ | ||
Canvas.Invalidate(); | ||
} | ||
|
||
private void ShowChessboard_OnCheckedChanged(object? sender, CheckedChangedEventArgs e) | ||
{ | ||
Canvas.Invalidate(); | ||
} | ||
|
||
private void OnUndoClicked(object? sender, EventArgs e) | ||
{ | ||
pixels.RemoveAt(pixels.Count - 1); | ||
Canvas.Invalidate(); | ||
} | ||
|
||
private void WidthEntry_OnTextChanged(object? sender, TextChangedEventArgs e) | ||
{ | ||
int.TryParse(e.NewTextValue, out width); | ||
Canvas.Invalidate(); | ||
} | ||
|
||
private void HeightEntry_OnTextChanged(object? sender, TextChangedEventArgs e) | ||
{ | ||
int.TryParse(e.NewTextValue, out height); | ||
Canvas.Invalidate(); | ||
} | ||
} | ||
|
||
public class Pixel | ||
{ | ||
public Color Color { get; init; } | ||
|
||
public PointF Location { get; init; } | ||
} |