3 enum DrawingMode { line, fill };
4 public struct ShortPoint { uint16 x, y; };
6 class PointStack : Array<ShortPoint>
8 // How to implement a Pop in Array?
12 Iterator<ShortPoint> it { this, pointer = GetLast() };
19 void FloodFill(Surface surface, int x0, int y0, ColorAlpha newColor)
21 Bitmap bitmap = surface.bitmap;
22 ColorAlpha * picture = (ColorAlpha *)bitmap.picture + (y0 * bitmap.stride) + x0;
23 ColorAlpha oldColor = *picture;
25 if(oldColor != newColor)
27 PointStack stack { minAllocSize = 16 };
28 stack.Add({ (uint16)x0, (uint16)y0 });
29 while(stack.count > 0)
31 ShortPoint point = stack.Pop();
33 picture = (ColorAlpha *)bitmap.picture + (point.y * bitmap.stride) + point.x;
34 if(*picture == oldColor)
36 ColorAlpha * pic, * pictureUp, * pictureDown;
37 int x = point.x, sx = point.x;
39 bool upIn = false, downIn = false;
45 if(*picture != oldColor) break;
49 pic = picture = (ColorAlpha *)bitmap.picture + (y * bitmap.stride) + sx;
50 pictureUp = (y > 0) ? (picture - bitmap.stride) : null;
51 pictureDown = (y < bitmap.height - 1) ? (picture + bitmap.stride) : null;
53 for(x = sx; x < bitmap.width; x++)
57 if(*pictureUp == oldColor)
60 stack.Add({ (uint16)x, (uint16)(y - 1)});
69 if(*pictureDown == oldColor)
72 stack.Add({ (uint16)x, (uint16)(y + 1)});
80 if(*pic != oldColor) break;
82 if(x == bitmap.width) x--;
83 FillBytesBy4(picture, newColor, x - sx + 1);
90 class DrawingArea : Window
94 DrawingMode drawingMode;
100 hasVertScroll = true;
101 hasHorzScroll = true;
109 void OnRedraw(Surface surface)
111 surface.Blit(bitmap, 0, 0, scroll.x, scroll.y, clientSize.w, clientSize.h);
112 surface.foreground = black;
113 surface.Rectangle(-1, -1, bitmap.width, bitmap.height);
116 surface.foreground = color;
117 surface.DrawLine(start.x - scroll.x, start.y - scroll.y, end.x - scroll.x, end.y - scroll.y);
121 void OnVScroll(ScrollBarAction action, int position, Key key)
126 void OnHScroll(ScrollBarAction action, int position, Key key)
131 bool OnLeftButtonDown(int x, int y, Modifiers mods)
133 if(x >= 0 && y >= 0 && x < bitmap.width && y < bitmap.height)
138 end = start = { x + scroll.x, y + scroll.y };
144 Surface surface = bitmap.GetSurface(0,0,null);
145 surface.background = color;
146 FloodFill(surface, x + scroll.x, y + scroll.y, color);
156 bool OnMouseMove(int x, int y, Modifiers mods)
158 end = { x + scroll.x, y + scroll.y };
159 if(drawing) Update(null);
163 bool OnLeftButtonUp(int x, int y, Modifiers mods)
165 end = { x + scroll.x, y + scroll.y };
168 Surface surface = bitmap.GetSurface(0,0,null);
169 surface.foreground = color;
170 surface.DrawLine(start.x, start.y, end.x, end.y);
182 surface = bitmap.GetSurface(0,0,null);
183 surface.background = white;
184 surface.Clear(colorBuffer);
191 bitmap.Allocate(null, 800, 600, 0, pixelFormat888, false);
193 scrollArea = { bitmap.width, bitmap.height };
197 class PaintWindow : Window
199 text = "Ecere Paint";
200 background = activeBorder;
201 borderStyle = sizable;
210 position = { 18, 150 }, size = { 64, 64 };
214 bool OnLeftButtonDown(int x, int y, Modifiers mods)
216 ColorPicker dialog { color = paintWindow.drawingArea.color };
218 if(dialog.Modal() == ok)
220 paintWindow.drawingArea.color = dialog.color;
221 paintWindow.colorBox.background = paintWindow.drawingArea.color;
222 paintWindow.colorBox.Update(null);
229 DrawingArea drawingArea
232 anchor = { 100, 8, 8, 8 };
237 this, text = "Line", position = { 24, 24 };
238 toggle = true; checked = true;
240 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
242 fillBtn.checked = false;
243 drawingArea.drawingMode = line;
249 this, text = "Fill", position = { 24, 64 };
252 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
254 lineBtn.checked = false;
255 drawingArea.drawingMode = fill;
261 this, text = "Clear", position = { 24, 104 };
263 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
265 lineBtn.checked = false;
272 PaintWindow paintWindow {};