1 /****************************************************************************
4 Copyright (c) 2003 Jerome Jacovella-St-Louis
7 pictureEdit.ec - Picture Editor Control
8 ****************************************************************************/
15 #define ID_IMAGE_MODE_COLORTABLE 9
16 #define ID_IMAGE_MODE_INDEXED 10
17 #define ID_IMAGE_MODE_RGB 11
19 static FileFilter filters[] =
22 "Image Files (*.jpg, *.jpeg, *.bmp, *.pcx, *.png, *.gif)",
23 "jpg, jpeg, bmp, pcx, png, gif"
28 static FileType types[] =
30 { "Based on extension", null, never },
31 { "JPG Image", "jpg", always },
32 { "BMP Image", "bmp", always },
33 { "PCX Image", "pcx", always },
34 { "PNG Image", "png", always },
35 { "GIF Image", "gif", always }
38 FileDialog pictureEditFileDialog { filters = filters, sizeFilters = sizeof(filters), types = types, sizeTypes = sizeof(types) };
40 class PictureEdit : Window
44 isActiveClient = true;
51 char fileName[MAX_LOCATION];
54 //saveDialog = pictureEditFileDialog;
56 Menu fileMenu { menu, "File", f }
57 MenuItem { fileMenu, "Save", s, ctrlS, NotifySelect = MenuFileSave };
58 MenuItem { fileMenu, "Save As...", a, NotifySelect = MenuFileSaveAs };
59 Menu imageMenu { menu, "Image", i };
60 Menu modeMenu { imageMenu, "Mode", m };
61 MenuItem imageModeIndexedItem
63 modeMenu, "Indexed Color...", i, isRadio = true;
64 bool NotifySelect(MenuItem selection, Modifiers mods)
66 ColorAlpha * palette = bitmap.Quantize(0, 255);
68 eBitmap_Convert(null, bitmap, PixelFormat8, palette);
69 bitmap.allocatePalette = true;
72 imageModeColorTableItem.disabled = false;
74 modifiedDocument = true;
78 MenuItem imageModeRGBItem
80 modeMenu, "RGB Color", r, isRadio = true;
81 bool NotifySelect(MenuItem selection, Modifiers mods)
83 bitmap.Convert(null, pixelFormat888, null);
84 imageModeColorTableItem.disabled = true;
86 modifiedDocument = true;
90 MenuDivider { modeMenu };
91 MenuItem imageModeColorTableItem
93 modeMenu, "Color Table", r;
94 bool NotifySelect(MenuItem selection, Modifiers mods)
96 PictureEditColorTable colorTable { master = this };
103 MenuDivider { imageMenu };
104 MenuItem adjustHSVItem
106 imageMenu, "Adjust Hue, Saturation, Value", h;
107 bool NotifySelect(MenuItem selection, Modifiers mods)
109 AdjustHSV adjustHSV { master = this };
117 property char * bitmapFile
123 strcpy(fileName, value);
128 if(bitmap.Load(fileName, null, null))
130 if(bitmap.pixelFormat == pixelFormatRGBA)
131 bitmap.Convert(null, pixelFormat888, null);
133 //if(!eWindow_GetStartWidth(window) || !eWindow_GetStartHeight(window))
135 Size size = initSize; // what's the use of retrieving initSize
136 size.w = bitmap.width;
137 size.h = bitmap.height;
141 Move(eWindow_GetStartX(window), eWindow_GetStartY(window),
142 (!eWindow_GetStartWidth(window)) ? (A_CLIENT|bitmap.width) : eWindow_GetStartWidth(window),
143 (!eWindow_GetStartHeight(window)) ? (A_CLIENT|bitmap.height) : eWindow_GetStartHeight(window));
147 Move(eWindow_GetStartX(window), eWindow_GetStartY(window),
148 (!) ? (A_CLIENT|bitmap.width) : eWindow_GetStartWidth(window),
149 (!eWindow_GetStartHeight(window)) ? (A_CLIENT|bitmap.height) : eWindow_GetStartHeight(window));
152 scrollArea = Size {bitmap.width, bitmap.height };
160 switch(bitmap.pixelFormat)
163 imageModeIndexedItem.checked = true;
166 imageModeRGBItem.checked = true;
167 imageModeColorTableItem.disabled = true;
174 void OnRedraw(Surface surface)
178 int w = (int)(bitmap.width * zoomFactor);
179 int h = (int)(bitmap.height * zoomFactor);
180 if(w == bitmap.width && h == bitmap.height)
183 Max(0, (clientSize.w - w) / 2), Max(0, (clientSize.h - h) / 2),
184 scroll.x, scroll.y, w, h);
188 surface.Filter(bitmap,
189 Max(0, (clientSize.w - w) / 2), Max(0, (clientSize.h - h) / 2),
190 (int)(scroll.x / zoomFactor), (int)(scroll.y / zoomFactor), w, h,
191 bitmap.width, bitmap.height);
196 void OnScroll(ScrollBarAction action, int position, Key key)
201 bool OnKeyHit(Key key, unichar ch)
209 float x = 0.5f, y = 0.5f;
210 if(bitmap.width * zoomFactor > clientSize.w)
211 x = scroll.x / (bitmap.width * zoomFactor - clientSize.w);
212 if(bitmap.height * zoomFactor > clientSize.h)
213 y = scroll.y / (bitmap.height * zoomFactor - clientSize.h);
216 scrollArea = Size { bitmap.width * zoomFactor, bitmap.height * zoomFactor };
219 (int)(Max(0, bitmap.width * zoomFactor - clientSize.w) * x),
220 (int)(Max(0, bitmap.height * zoomFactor - clientSize.h) * y) };
227 if(zoomFactor > 0.05)
229 float x = 0.5f, y = 0.5f;
230 if(bitmap.width * zoomFactor > clientSize.w)
231 x = scroll.x / (bitmap.width * zoomFactor - clientSize.w);
232 if(bitmap.height * zoomFactor > clientSize.w)
233 y = scroll.y / (bitmap.height * zoomFactor - clientSize.h);
236 scrollArea = Size { bitmap.width * zoomFactor, bitmap.height * zoomFactor };
239 (int)(Max(0, bitmap.width * zoomFactor - clientSize.w) * x),
240 (int)(Max(0, bitmap.height * zoomFactor - clientSize.h) * y) };
249 bool OnSaveFile(char * fileName)
254 if(bitmap.Save(fileName,
255 ((FileType *)pictureEditFileDialog.types)[pictureEditFileDialog.fileType].typeExtension, (void *) bool::true))
257 modifiedDocument = false;
272 class PictureEditColorTable : Window
275 text = "Color Table";
276 background = activeBorder;
277 minClientSize = Size { 400, 400 };
281 parent = this, hotKey = escape, size = { 80 }, text = "Close";
282 anchor = Anchor { right = 10, bottom = 10 };
283 NotifyClicked = ButtonCloseDialog;
286 void OnRedraw(Surface surface)
288 PictureEdit picture = (PictureEdit)master;
289 Bitmap bitmap = picture.bitmap;
291 for(c = 0; c < 256; c++)
293 int x = (c % 16) * 16;
294 int y = (c / 16) * 16;
295 surface.SetBackground(bitmap.palette[c]);
296 surface.Area(10 + x, 30 + y, 10 + x + 15, 30 + y + 15);
301 class ColorBox : Window
304 borderStyle = deepContour;
308 class AdjustHSV : Window
312 background = activeBorder;
315 replace = { 248, 100, 71 }; //Color { 26, 0, 183 };
316 target = { 207, 61, 71 };
321 this, text = "Go", position = { 296, 104 }, isDefault = true;
323 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
325 PictureEdit picture = (PictureEdit)master;
326 Bitmap bitmap = picture.bitmap;
327 double h = 1.0f, s = 0.80f, v = 1.24f;
332 h = target.h - replace.h;
333 s = target.s / replace.s;
334 v = target.v / replace.v;
336 for(y = 0; y<bitmap.height; y++)
338 for(x = 0; x<bitmap.width; x++)
340 ColorAlpha color = ((ColorAlpha *)bitmap.picture)[y * bitmap.stride + x];
341 ColorHSV hsv = color;
342 double diffH = Abs(hsv.h/360 - replace.h/360);
343 double diffS = Abs(hsv.s - replace.s)/100.0;
344 double diffV = Abs(hsv.v - replace.v)/100.0;
345 if(diffH <= tolH && diffS <= tolS && diffV <= tolV)
351 ((ColorAlpha *)bitmap.picture)[y * bitmap.stride + x] = color;
355 picture.Update(null);
356 picture.modifiedDocument = true;
362 EditBox hBox { this, text = "H", size = { 78, 19 }, position = { 176, 80 } };
363 EditBox sBox { this, text = "S", size = { 78, 19 }, position = { 176, 120 } };
364 EditBox vBox { this, text = "V", size = { 78, 19 }, position = { 176, 160 } };
365 Label label1 { this, size = { 7, 13 }, position = { 152, 80 }, labeledWindow = hBox };
366 Label label2 { this, size = { 6, 13 }, position = { 152, 120 }, labeledWindow = sBox };
367 Label label3 { this, size = { 6, 13 }, position = { 152, 168 }, labeledWindow = vBox };
368 ColorBox original { this, position = { 10, 10 }, background = replace };
369 ColorBox result { this, position = { 10, 100 }, background = target };