samples: fixed warnings
[sdk] / samples / guiAndGfx / floodFill / floodFill.ec
1 import "ecere"
2
3 enum DrawingMode { line, fill };
4 public struct ShortPoint { uint16 x, y; };
5
6 class PointStack : Array<ShortPoint>
7 {
8    // How to implement a Pop in Array?
9    ShortPoint Pop()
10    {
11       ShortPoint value;
12       Iterator<ShortPoint> it { this, pointer = GetLast() };
13       value = it.data;
14       it.Remove();
15       return value;
16    }
17 }
18
19 void FloodFill(Surface surface, int x0, int y0, ColorAlpha newColor)
20 {
21    Bitmap bitmap = surface.bitmap;
22    ColorAlpha * picture = (ColorAlpha *)bitmap.picture + (y0 * bitmap.stride) + x0;
23    ColorAlpha oldColor = *picture;
24
25    if(oldColor != newColor)
26    {
27       PointStack stack { minAllocSize = 16 };
28       stack.Add({ (uint16)x0, (uint16)y0 });
29       while(stack.count > 0)
30       {
31          ShortPoint point = stack.Pop();
32
33          picture = (ColorAlpha *)bitmap.picture + (point.y * bitmap.stride) + point.x;
34          if(*picture == oldColor)
35          {
36             ColorAlpha * pic, * pictureUp, * pictureDown;
37             int x = point.x, sx = point.x;
38             int y = point.y;
39             bool upIn = false, downIn = false;
40
41             while(x > 0)
42             {
43                x--;
44                picture--;
45                if(*picture != oldColor) break;
46                sx = x;
47             }
48
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;
52
53             for(x = sx; x < bitmap.width; x++)
54             {
55                if(pictureUp)
56                {
57                   if(*pictureUp == oldColor)
58                   {
59                      if(!upIn)
60                         stack.Add({ (uint16)x, (uint16)(y - 1)});
61                      upIn = true;
62                   }
63                   else
64                      upIn = false;
65                   pictureUp++;
66                }
67                if(pictureDown)
68                {
69                   if(*pictureDown == oldColor)
70                   {
71                      if(!downIn)
72                         stack.Add({ (uint16)x, (uint16)(y + 1)});
73                      downIn = true;
74                   }
75                   else
76                      downIn = false;
77                   pictureDown++;
78                }
79                pic++;
80                if(*pic != oldColor) break;
81             }
82             if(x == bitmap.width) x--;
83             FillBytesBy4(picture, newColor, x - sx + 1);
84          }
85       }
86       delete stack;
87    }
88 }
89
90 class DrawingArea : Window
91 {
92    bool drawing;
93    Color color;
94    DrawingMode drawingMode;
95
96    Point start, end;
97
98    color = black;
99
100    hasVertScroll = true;
101    hasHorzScroll = true;
102    borderStyle = deep;
103
104    Bitmap bitmap
105    {
106
107    };
108
109    void OnRedraw(Surface surface)
110    {
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);
114       if(drawing)
115       {
116          surface.foreground = color;
117          surface.DrawLine(start.x - scroll.x, start.y - scroll.y, end.x - scroll.x, end.y - scroll.y);
118       }
119    }
120
121    void OnVScroll(ScrollBarAction action, int position, Key key)
122    {
123       Update(null);
124    }
125
126    void OnHScroll(ScrollBarAction action, int position, Key key)
127    {
128       Update(null);
129    }
130
131    bool OnLeftButtonDown(int x, int y, Modifiers mods)
132    {
133       if(x >= 0 && y >= 0 && x < bitmap.width && y < bitmap.height)
134       {
135          switch(drawingMode)
136          {
137             case line:
138                end = start = { x + scroll.x, y + scroll.y };
139                drawing = true;
140                Capture();
141                break;
142             case fill:
143             {
144                Surface surface = bitmap.GetSurface(0,0,null);
145                surface.background = color;
146                FloodFill(surface, x + scroll.x, y + scroll.y, color);
147                delete surface;
148                Update(null);
149                break;
150             }
151          }
152       }
153       return true;
154    }
155
156    bool OnMouseMove(int x, int y, Modifiers mods)
157    {
158       end = { x + scroll.x, y + scroll.y };
159       if(drawing) Update(null);
160       return true;
161    }
162
163    bool OnLeftButtonUp(int x, int y, Modifiers mods)
164    {
165       end = { x + scroll.x, y + scroll.y };
166       if(drawing)
167       {
168          Surface surface = bitmap.GetSurface(0,0,null);
169          surface.foreground = color;
170          surface.DrawLine(start.x, start.y, end.x, end.y);
171          delete surface;
172          Update(null);
173          drawing = false;
174          ReleaseCapture();
175       }
176       return true;
177    }
178
179    void Clear()
180    {
181       Surface surface;
182       surface = bitmap.GetSurface(0,0,null);
183       surface.background = white;
184       surface.Clear(colorBuffer);
185       delete surface;
186       Update(null);
187    }
188
189    DrawingArea()
190    {
191       bitmap.Allocate(null, 800, 600, 0, pixelFormat888, false);
192       Clear();
193       scrollArea = { bitmap.width, bitmap.height };
194    }
195 }
196
197 class PaintWindow : Window
198 {
199    text = "Ecere Paint";
200    background = activeBorder;
201    borderStyle = sizable;
202    hasMaximize = true;
203    hasMinimize = true;
204    hasClose = true;
205    size = { 640, 480 };
206
207    Window colorBox
208    {
209       this,
210       position = { 18, 150 }, size = { 64, 64 };
211       borderStyle = deep;
212       background = black;
213
214       bool OnLeftButtonDown(int x, int y, Modifiers mods)
215       {
216          ColorPicker dialog { color = paintWindow.drawingArea.color };
217          incref dialog;
218          if(dialog.Modal() == ok)
219          {
220             paintWindow.drawingArea.color = dialog.color;
221             paintWindow.colorBox.background = paintWindow.drawingArea.color;
222             paintWindow.colorBox.Update(null);
223          }
224          delete dialog;
225          return true;
226       }
227
228    };
229    DrawingArea drawingArea
230    {
231       this,
232       anchor = { 100, 8, 8, 8 };
233    };
234
235    Button lineBtn
236    {
237       this, text = "Line", position = { 24, 24 };
238       toggle = true; checked = true;
239
240       bool NotifyClicked(Button button, int x, int y, Modifiers mods)
241       {
242          fillBtn.checked = false;
243          drawingArea.drawingMode = line;
244          return true;
245       }
246    };
247    Button fillBtn
248    {
249       this, text = "Fill", position = { 24, 64 };
250       toggle = true;
251
252       bool NotifyClicked(Button button, int x, int y, Modifiers mods)
253       {
254          lineBtn.checked = false;
255          drawingArea.drawingMode = fill;
256          return true;
257       }
258    };
259    Button clearBtn
260    {
261       this, text = "Clear", position = { 24, 104 };
262
263       bool NotifyClicked(Button button, int x, int y, Modifiers mods)
264       {
265          lineBtn.checked = false;
266          drawingArea.Clear();
267          return true;
268       }
269    };
270 }
271
272 PaintWindow paintWindow {};