0eaeb2dc31f355ee16cbb3262129a29666daf0e4
[sdk] / ecere / src / gui / controls / StatusBar.ec
1 namespace gui::controls;
2
3 import "Window"
4
5 #include <stdarg.h>
6
7 #define MIN_INFO_WIDTH  300
8
9 public class StatusBar : Window
10 {
11    class_property(icon) = "<:ecere>controls/statusBar.png";
12
13    background = formColor;
14    nonClient = true;
15    inactive = true;
16    anchor = Anchor { left = 0, right = 0, bottom = 0 };
17
18 public:
19    void AddField(StatusField field)
20    {
21       if(this && field)
22       {
23          field._statusBar = this;
24          incref field;
25          width += field.width + (guiApp.textMode ? 0 : 6);
26          fields.Add(field);
27          Update(null);
28       }
29    }
30
31    void RemoveField(StatusField field)
32    {
33       if(this && field)
34       {
35          field._statusBar = null;
36          width -= field.width + (guiApp.textMode ? 0 : 6);
37          fields.Remove(field);
38          delete field;
39
40          Update(null);
41       }
42    }
43
44    void Clear()
45    {
46       if(this)
47       {
48          while(fields.first)
49             RemoveField(fields.first);
50       }
51    }
52
53 private:
54    StatusBar()
55    {
56       fields.offset = (uint)(uintptr)&((StatusField)0).prev;
57    }
58
59    ~StatusBar()
60    {
61       Clear();
62    }
63
64    FontResource boldFont { font.faceName, font.size, true, window = this };
65
66    bool OnLoadGraphics()
67    {
68       StatusField field;
69       width = 0;
70       for(field = fields.first; field; field = field.next)
71          width += field.width + (guiApp.textMode ? 0 : 6);
72       return true;
73    }
74
75    bool OnResizing(int * w, int * h)
76    {
77       *h = Max(*h, statusBarHeight);
78       if(!*w) *w = 80;
79       return true;
80    }
81
82    void OnRedraw(Surface surface)
83    {
84       StatusField field;
85       int position = Max(clientSize.w, MIN_INFO_WIDTH + width)-1-2;
86       Box clip { 2, 2, MIN_INFO_WIDTH, statusBarHeight-1 };
87       Window parent = this.parent;
88
89       if(!guiApp.textMode)
90          surface.ThinBevel(false, -1,0, clientSize.w+2, clientSize.h+1);
91
92       for(field = fields.first; field; field = field.next)
93       {
94          int x = position - field.width;
95
96          surface.SetBackground(white);
97          if(!guiApp.textMode)
98          {
99             surface.ThinBevel(true, x - 2, 2, field.width + 4, statusBarHeight-2);
100             surface.SetForeground(field.colorSet ? field.color : foreground);
101          }
102          else
103          {
104             if(parent.borderStyle == sizable && parent.state == normal)
105                surface.SetForeground(field.colorSet ? (field.color == black ? white : field.color) : (foreground == black ? white : foreground));
106             else
107                surface.SetForeground(field.colorSet ? field.color : foreground);
108          }
109          if(field.text)
110          {
111             Box clip { x, 2, x + field.width - 1, statusBarHeight-3 };
112             int tw;
113             surface.Clip(clip);
114             if(field.backColor)
115             {
116                surface.SetBackground(field.backColor);
117                surface.Clear(colorBuffer);
118             }
119             surface.font = field.bold ? boldFont.font : fontObject;
120             surface.TextExtent(field.text, strlen(field.text), &tw, null);
121             surface.WriteTextf(x + (field.width - tw) / 2, 2, field.text);
122             surface.Clip(null);
123          }
124          position -= field.width + (guiApp.textMode ? 0 : 6);
125       }
126
127       // TESTING THIS HERE!
128       clip.right = position;
129       surface.Clip(clip);
130       if(guiApp.textMode && parent.borderStyle == sizable && parent.state == normal)
131          surface.SetForeground(white);
132       else
133          surface.SetForeground(foreground);
134
135       surface.WriteTextf(2, 2, text);
136       surface.Clip(null);
137    }
138
139    watch(caption)
140    {
141       text = property::text;
142       Update(null);
143    };
144
145    char * text;
146    OldList fields;
147    int width;
148 };
149
150 public class StatusField
151 {
152 public:
153
154    property StatusBar statusBar
155    {
156       set
157       {
158          if(this)
159          {
160             if(_statusBar)
161                _statusBar.RemoveField(this);
162             if(value)
163                value.AddField(this);
164             _statusBar = value;
165          }
166       }
167    }
168    property Color color
169    {
170       set
171       {
172          if(this)
173          {
174             color = value;
175             colorSet = true;
176             if(_statusBar)
177                _statusBar.Update(null);
178          }
179       }
180    }
181    property ColorAlpha backColor
182    {
183       set
184       {
185          if(this)
186          {
187             backColor = value;
188             colorSet = true;
189             if(_statusBar)
190                _statusBar.Update(null);
191          }
192       }
193    }
194    property bool bold
195    {
196       set
197       {
198          if(this) this.bold = value;
199       }
200    }
201
202    property char * text
203    {
204       set
205       {
206          if(this)
207          {
208             if(value)
209             {
210                int len = strlen(value);
211                text = renew text char[len + 1];
212                CopyBytes(text, value, len + 1);
213             }
214             else
215                delete text;
216             if(_statusBar)
217                _statusBar.Update(null);
218          }
219       }
220    }
221
222    property int width
223    {
224       set
225       {
226          if(this)
227          {
228             if(_statusBar)
229             {
230                _statusBar.width += value - width;
231                _statusBar.Update(null);
232             }
233             width = value;
234          }
235       }
236    }
237
238    void SetTextf(char * format, ...)
239    {
240       if(this)
241       {
242          delete text;
243          if(format)
244          {
245             char tempText[MAX_F_STRING];
246             va_list args;
247             va_start(args, format);
248             vsnprintf(tempText, sizeof(tempText), format, args);
249             tempText[sizeof(tempText)-1] = 0;
250             va_end(args);
251             text = CopyString(tempText);
252          }
253          if(_statusBar)
254             _statusBar.Update(null);
255       }
256    }
257
258 private:
259    ~StatusField()
260    {
261       delete text;
262    }
263
264    StatusField prev, next;
265    char * text;
266    int width;
267    Color color;
268    ColorAlpha backColor;
269    StatusBar _statusBar;
270    bool colorSet;
271    bool bold;
272 };