Skip to content

Commit b7cea1e

Browse files
committed
add floodfill tool, add toolmode enum, rename drawmode to blendmode
1 parent 9b3f7f7 commit b7cea1e

File tree

2 files changed

+122
-23
lines changed

2 files changed

+122
-23
lines changed

PixelArtTool/MainWindow.xaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@
2626
</ToolBar>
2727

2828
<ToolBar Band="1" BandIndex="1" VerticalAlignment="Top">
29-
<RadioButton GroupName="Toolbar" ToolTip="Test" Style="{StaticResource {x:Type ToggleButton}}">
29+
<RadioButton GroupName="Toolbar" Tag="Draw" ToolTip="Pencil" Style="{StaticResource {x:Type ToggleButton}}" IsChecked="True" Click="OnToolChanged">
3030
<Image Source="/Resources/Buttons/drawmode.png" />
3131
</RadioButton>
32-
<RadioButton GroupName="Toolbar" ToolTip="Test" Style="{StaticResource {x:Type ToggleButton}}">
33-
<Image Source="/Resources/Buttons/drawmode.png" />
32+
<RadioButton GroupName="Toolbar" Tag="Fill" ToolTip="Flood Fill" Style="{StaticResource {x:Type ToggleButton}}" Click="OnToolChanged">
33+
<Image Source="/Resources/Buttons/emptybutton.png" />
3434
</RadioButton>
3535
</ToolBar>
3636

PixelArtTool/MainWindow.xaml.cs

Lines changed: 119 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using Microsoft.Win32;
22
using System;
3+
using System.Collections.Generic;
34
using System.IO;
45
using System.Runtime.InteropServices;
56
using System.Windows;
@@ -11,12 +12,18 @@
1112
namespace PixelArtTool
1213
{
1314

14-
public enum DrawMode : byte
15+
public enum BlendMode : byte
1516
{
1617
Default = 0,
1718
Additive = 1
1819
}
1920

21+
public enum ToolMode : byte
22+
{
23+
Draw = 0,
24+
Fill = 1
25+
}
26+
2027
/// <summary>
2128
/// Interaction logic for MainWindow.xaml
2229
/// </summary>
@@ -62,7 +69,8 @@ public partial class MainWindow : Window
6269
WriteableBitmap[] undoBufferBitmap = new WriteableBitmap[maxUndoCount];
6370

6471
// modes
65-
DrawMode drawMode;
72+
BlendMode blendMode;
73+
ToolMode currentTool;
6674

6775
public MainWindow()
6876
{
@@ -327,12 +335,12 @@ void DrawPixel(int x, int y)
327335

328336
PixelColor draw = new PixelColor();
329337

330-
switch (drawMode)
338+
switch (blendMode)
331339
{
332-
case DrawMode.Default: // replace
340+
case BlendMode.Default: // replace
333341
draw = currentColor;
334342
break;
335-
case DrawMode.Additive:
343+
case BlendMode.Additive:
336344
// get old color from undo buffer
337345
var oc = GetPixelColor(x, y, undoBufferBitmap[currentUndoIndex]);
338346
// mix colors ADDITIVE mode
@@ -404,7 +412,7 @@ void PickPalette(MouseEventArgs e)
404412

405413

406414
// return canvas pixel color from x,y
407-
unsafe PixelColor GetPixelColor(int x, int y)
415+
unsafe PixelColor GetPixel(int x, int y)
408416
{
409417
var pix = new PixelColor();
410418
byte[] ColorData = { 0, 0, 0, 0 }; // B G R !
@@ -464,7 +472,7 @@ void DrawingMiddleButtonDown(object sender, MouseButtonEventArgs e)
464472
int x = (int)(e.GetPosition(drawingImage).X / canvasScaleX);
465473
int y = (int)(e.GetPosition(drawingImage).Y / canvasScaleX);
466474

467-
currentColor = GetPixelColor(x, y);
475+
currentColor = GetPixel(x, y);
468476
UpdateCurrentColor();
469477
}
470478
}
@@ -479,18 +487,30 @@ void DrawingLeftButtonDown(object sender, MouseButtonEventArgs e)
479487

480488
int x = (int)(e.GetPosition(drawingImage).X / canvasScaleX);
481489
int y = (int)(e.GetPosition(drawingImage).Y / canvasScaleX);
482-
DrawPixel(x, y);
483490

484-
if (chkOutline.IsChecked == true)
491+
492+
switch (currentTool)
485493
{
486-
UpdateOutline();
494+
case ToolMode.Draw:
495+
DrawPixel(x, y);
496+
// mirror
497+
if (chkMirrorX.IsChecked == true)
498+
{
499+
DrawPixel(canvasResolutionX - x - 1, y);
500+
}
501+
break;
502+
case ToolMode.Fill:
503+
FloodFill(x, y, (int)currentColor.ColorBGRA);
504+
break;
505+
default:
506+
break;
487507
}
488508

489-
// mirror
490-
if (chkMirrorX.IsChecked == true)
509+
if (chkOutline.IsChecked == true)
491510
{
492-
DrawPixel(canvasResolutionX - x - 1, y);
511+
UpdateOutline();
493512
}
513+
494514
}
495515

496516
void DrawingMouseUp(object sender, MouseButtonEventArgs e)
@@ -506,12 +526,23 @@ void DrawingAreaMouseMoved(object sender, MouseEventArgs e)
506526

507527
if (e.LeftButton == MouseButtonState.Pressed)
508528
{
509-
DrawPixel(x, y);
510-
// mirror
511-
if (chkMirrorX.IsChecked == true)
529+
switch (currentTool)
512530
{
513-
DrawPixel(canvasResolutionX - x - 1, y);
531+
case ToolMode.Draw:
532+
DrawPixel(x, y);
533+
// mirror
534+
if (chkMirrorX.IsChecked == true)
535+
{
536+
DrawPixel(canvasResolutionX - x - 1, y);
537+
}
538+
break;
539+
case ToolMode.Fill:
540+
FloodFill(x, y, (int)currentColor.ColorBGRA);
541+
break;
542+
default:
543+
break;
514544
}
545+
515546
}
516547
else if (e.RightButton == MouseButtonState.Pressed)
517548
{
@@ -524,7 +555,7 @@ void DrawingAreaMouseMoved(object sender, MouseEventArgs e)
524555
}
525556
else if (e.MiddleButton == MouseButtonState.Pressed)
526557
{
527-
currentColor = GetPixelColor(x, y);
558+
currentColor = GetPixel(x, y);
528559
}
529560

530561
ShowMousePos(x, y);
@@ -544,7 +575,7 @@ void ShowMousePos(int x, int y)
544575

545576
void ShowMousePixelColor(int x, int y)
546577
{
547-
var col = GetPixelColor(x, y);
578+
var col = GetPixel(x, y);
548579
//lblPixelColor.Content = palette[currentColorIndex].Red + "," + palette[currentColorIndex].Green + "," + palette[currentColorIndex].Blue + "," + palette[currentColorIndex].Alpha;
549580
lblPixelColor.Content = col.Red + "," + col.Green + "," + col.Blue + "," + col.Alpha;
550581
}
@@ -638,7 +669,7 @@ private void OnUndoButtonDown(object sender, RoutedEventArgs e)
638669
private void OnModeSelectionChanged(object sender, SelectionChangedEventArgs e)
639670
{
640671
var s = sender as ComboBox;
641-
drawMode = (DrawMode)s.SelectedIndex;
672+
blendMode = (BlendMode)s.SelectedIndex;
642673
}
643674

644675
bool leftShiftDown = false;
@@ -694,6 +725,68 @@ public void CanExecute_Undo(object sender, CanExecuteRoutedEventArgs e)
694725
e.CanExecute = true;
695726
}
696727

728+
void FloodFill(int x, int y, int fillColor)
729+
{
730+
// get hit color pixel
731+
var hitColor = GetPixel(x, y);
732+
733+
// if same as current color, exit
734+
if (hitColor.ColorBGRA == fillColor) return;
735+
736+
SetPixel(canvasBitmap, x, y, (int)hitColor.ColorBGRA);
737+
738+
List<int> ptsx = new List<int>();
739+
ptsx.Add(x);
740+
List<int> ptsy = new List<int>();
741+
ptsy.Add(y);
742+
743+
int maxLoop = canvasResolutionX * canvasResolutionY + canvasResolutionX;
744+
while (ptsx.Count > 0 && maxLoop > 0)
745+
{
746+
maxLoop--;
747+
748+
if (ptsx[0] - 1 >= 0)
749+
{
750+
if (GetPixel(ptsx[0] - 1, ptsy[0]).ColorBGRA == hitColor.ColorBGRA)
751+
{
752+
ptsx.Add(ptsx[0] - 1); ptsy.Add(ptsy[0]);
753+
SetPixel(canvasBitmap, ptsx[0] - 1, ptsy[0], fillColor);
754+
}
755+
}
756+
757+
if (ptsy[0] - 1 >= 0)
758+
{
759+
if (GetPixel(ptsx[0], ptsy[0] - 1).ColorBGRA == hitColor.ColorBGRA)
760+
{
761+
ptsx.Add(ptsx[0]); ptsy.Add(ptsy[0] - 1);
762+
SetPixel(canvasBitmap, ptsx[0], ptsy[0] - 1, fillColor);
763+
}
764+
}
765+
766+
if (ptsx[0] + 1 < canvasResolutionX)
767+
{
768+
if (GetPixel(ptsx[0] + 1, ptsy[0]).ColorBGRA == hitColor.ColorBGRA)
769+
{
770+
ptsx.Add(ptsx[0] + 1); ptsy.Add(ptsy[0]);
771+
SetPixel(canvasBitmap, ptsx[0] + 1, ptsy[0], fillColor);
772+
}
773+
}
774+
775+
if (ptsy[0] + 1 < canvasResolutionY)
776+
{
777+
if (GetPixel(ptsx[0], ptsy[0] + 1).ColorBGRA == hitColor.ColorBGRA)
778+
{
779+
ptsx.Add(ptsx[0]); ptsy.Add(ptsy[0] + 1);
780+
SetPixel(canvasBitmap, ptsx[0], ptsy[0] + 1, fillColor);
781+
}
782+
}
783+
ptsx.RemoveAt(0);
784+
ptsy.RemoveAt(0);
785+
} // while can floodfill
786+
787+
} // floodfill
788+
789+
697790
void DrawBackgroundGrid()
698791
{
699792
PixelColor c = new PixelColor();
@@ -811,5 +904,11 @@ int Repeat(int val, int max)
811904
return result;
812905
}
813906

907+
private void OnToolChanged(object sender, RoutedEventArgs e)
908+
{
909+
string tag = (string)((RadioButton)sender).Tag;
910+
Enum.TryParse(tag, out currentTool);
911+
}
912+
814913
} // class
815914
} // namespace

0 commit comments

Comments
 (0)