sdk: const correctness
[sdk] / ecere / src / gfx / BitmapResource.ec
1 namespace gfx;
2
3 import "Window"
4
5 static Array<FileFilter> filters
6 { [
7    {
8       $"Image Files (*.jpg, *.jpeg, *.bmp, *.pcx, *.png, *.gif)",
9       "jpg, jpeg, bmp, pcx, png, gif"
10    }
11 ] };
12 static Array<FileType> types
13 { [
14    { $"Image",              "jpg" }
15 ] };
16
17 static FileDialog fileDialog { autoCreate = false, filters = filters.array, sizeFilters = filters.count * sizeof(FileFilter), types = types.array, sizeTypes = types.count * sizeof(FileType), text = $"Select Image" };
18
19 public class BitmapResource : Resource
20 {
21    char * fileName;
22    Bitmap bitmap;
23    bool grayed, mono, transparent;
24    bool alphaBlend;
25    int count;
26    bool keepData;
27
28    BitmapResource()
29    {
30       transparent = true;
31    }
32
33    ~BitmapResource()
34    {
35       if(bitmap != null)
36       {
37          //if(!grayed)
38             // Logf("Freeing %s (%d)\n", fileName, bitmap.picture);
39          // bitmap.Free(bitmap);
40          delete bitmap;
41       }
42       if(fileName)
43          delete fileName;
44    }
45
46    void Load(BitmapResource copy, DisplaySystem displaySystem)
47    {
48       delete fileName;
49       fileName = CopyString(copy.fileName);
50       grayed = copy.grayed;
51       mono = copy.mono;
52       transparent = copy.transparent;
53       alphaBlend = copy.alphaBlend;
54       keepData = copy.keepData;
55
56       if(fileName)
57       {
58          DisplaySystem ds = displaySystem;
59
60          bitmap = Bitmap { alphaBlend = (alphaBlend && displaySystem.pixelFormat != pixelFormat8), keepData = keepData };
61 #if defined(__WIN32__)
62          // if(bitmap.alphaBlend) ds = null;
63 #endif
64          if((mono && !bitmap.LoadMonochrome(fileName, null, ds)) ||
65             (!mono && grayed && !bitmap.LoadGrayed(fileName, null, ds)) ||
66             (!mono && !grayed && transparent && !bitmap.LoadT(fileName, null, ds)) ||
67             (!mono && !grayed && !transparent && !bitmap.Load(fileName, null, ds)))
68                delete bitmap;
69          if(bitmap && bitmap.alphaBlend)
70          {
71             bitmap.Convert(null, pixelFormat888, null);
72             bitmap.displaySystem = displaySystem;
73          }
74       }
75    }
76
77    void Reference(BitmapResource reference)
78    {
79       bitmap = reference.bitmap;
80       count++;
81    }
82
83    void Dereference()
84    {
85       count--;
86       if(!count)
87          bitmap = null;
88    }
89
90    Window OnEdit(DataBox window, DataBox master, int x, int y, int w, int h, void * userData)
91    {
92       Window editData = class::OnEdit(window, master, x + 24, y, w - 48, h, userData);
93       Button browse
94       {
95          window, master = editData, inactive = true, text = "...", hotKey = f2,
96          position = { Max(x + 24, x + w - 24), y }, size = { 24, h };
97
98          bool NotifyClicked(Button button, int x, int y, Modifiers mods)
99          {
100             DataBox master = (DataBox)this.master;
101             fileDialog.master = rootWindow;
102             if(fileDialog.Modal() == ok)
103             {
104                const char * filePath = fileDialog.filePath;
105                BitmapResource resource { fileName = filePath };
106
107                master.SetData(resource, false);
108                // TOCHECK: Why do we need to Refresh here?
109                master.Refresh();
110
111                // TODO: This is a Button?
112                // contents = filePath;
113             }
114             return true;
115          }
116       };
117       editData.anchor.right = 24;
118       browse.Create();
119
120       return editData;
121    }
122
123    void OnDisplay(Surface surface, int x, int y, int width, void * fieldData, Alignment alignment, DataDisplayFlags displayFlags)
124    {
125       char * string = this ? fileName : null;
126       Bitmap bitmap = this ? this.bitmap : null;
127       // TODO: This isn't an ideal way of obtaining the clipped height, will fail on hidden areas
128       int yOffset = (1+surface.box.bottom - surface.box.top - 17)/2;
129
130 /* GCC-4.4 Bug!!
131       if(!string) string = "(none)";
132       surface.WriteTextDots(alignment, x + 24, y + 1, width - 24, string, strlen(string));
133 */
134       if(string)
135          surface.WriteTextDots(alignment, x + 24, y + 1, width - 24, string, strlen(string));
136       else
137          surface.WriteTextDots(alignment, x + 24, y + 1, width - 24, "(none)", 6);
138
139       y += yOffset-1;
140       surface.SetBackground(white);
141       surface.Area(x - 4, y, x + 20, y + 15);
142       if(bitmap)
143          surface.Filter(bitmap, x, y + 2, 0,0, 18, 12, bitmap.width, bitmap.height);
144
145       surface.SetForeground(black);
146       surface.Rectangle(x-1, y + 1, x + 18, y + 14);
147    }
148
149 public:
150    property const char * fileName
151    {
152       set
153       {
154          delete fileName;
155          fileName = CopyString(value);
156          if(value && SearchString(value, 0, ".png", false, true))
157             alphaBlend = true;
158       }
159       get { return this ? fileName : null; }
160    };
161    property bool grayed { set { grayed = value; } get { return this ? grayed : false; } };
162    property bool monochrome
163    {
164       set
165       {
166          mono = value;
167       }
168       get { return this ? mono : false; }
169    };
170    property bool transparent { set { transparent = value; } get { return this ? transparent : false; } isset { return (this && !transparent) ? true : false; } };
171    property bool alphaBlend
172    {
173       set { alphaBlend = value; }
174       get { return this ? alphaBlend : false; }
175       isset { return alphaBlend && (!fileName || !SearchString(fileName, 0, ".png", false, true)); }
176    };
177    property bool keepData { set { keepData = value; } get { return this ? keepData : false; } };
178    property Bitmap bitmap { get { return this ? bitmap : null; } set { bitmap = value; if(bitmap) incref bitmap; } };
179    property Window window { set { if(value) value.AddResource(this); } };
180 };