i18n: ide, ecere, documentor: New strings, Chinese
[sdk] / ecere / src / gui / controls / CalendarControl.ec
1 namespace gui::controls;
2
3 import "Window"
4
5 #define ISLEAP(y) (!((y)%4) && (((y) % 100) || (!((y)% 400))))
6
7 public class CalendarControl : CommonControl
8 {
9    class_property(icon) = "<:ecere>controls/calendar.png";
10
11 public:
12    virtual void Window::NotifyChanged(bool close);      
13    Date dateValue;
14    Month shownMonth;
15    int shownYear;
16
17 private:
18    background = { 195, 217, 255 };
19    clientSize = { 168, 198 };
20    tabCycle = true;
21
22    bool OnCreate()
23    {
24       if(!dateValue.year && !dateValue.day && !dateValue.month)
25       {
26          DateTime now;
27          now.GetLocalTime();
28          dateValue.day = now.day;
29          dateValue.month = now.month;
30          shownYear = dateValue.year = now.year;
31          shownMonth = dateValue.month;         
32       }
33       return true;
34    }
35    
36    RepButton leftArrow
37    {
38       this, 
39       position = { 3, 8 };
40       size = { 16, 16 };
41       bevel = false;
42       inactive = true;
43       background = background;
44       font = { $"Verdana", 8.25f, true };
45       foreground = navy;
46       offset = false;
47       text = "«";
48       hotKey = pageUp;
49       
50       bool NotifyClicked(Button button, int x, int y, ecere::gui::Modifiers mods)
51       {
52          shownMonth--;
53          if(shownMonth < january) { shownMonth = december; shownYear--; yearBox.Refresh(); }
54          monthBox.Refresh();         
55          Update(null);
56          dateBox.Activate();
57          return true;
58       }
59    };
60    RepButton rightArrow
61    {
62       this, 
63       anchor = { right = 8, top = 8 };
64       size = { 16, 16 };
65       bevel = false;
66       inactive = true;
67       offset = false;
68       background = background;
69       font = { $"Verdana", 8.25f, true };
70       foreground = navy;
71       text = "»";
72       hotKey = pageDown;
73
74       bool NotifyClicked(Button button, int x, int y, ecere::gui::Modifiers mods)
75       {
76          shownMonth++;
77          if(shownMonth > december) { shownMonth = january; shownYear++; yearBox.Refresh(); }
78          monthBox.Refresh();
79          Update(null);
80          dateBox.Activate();
81          return true;
82       }
83    };   
84
85    DataBox monthBox
86    {
87       this, type = class(Month), data = &shownMonth, position = { 25, 5 }, size = { 75, 20 };
88       background = background;
89       foreground = navy;
90       font = { $"Verdana", 8.25f, true };
91
92       bool OnPostCreate()
93       {
94          DataBox::OnPostCreate();
95          ((DropBox)editor).showButton = false;
96          ((DropBox)editor).alignment = right;
97          return true;
98       }
99
100       bool NotifyChanged(bool closingDropDown)
101       {
102          Update(null);
103          if(closingDropDown)
104             dateBox.Activate();
105          return true;
106       }
107    };
108    DataBox yearBox
109    {
110       this, type = class(int), data = &shownYear, position = { 100, 5 }, size = { 38, 20 };
111       font = { $"Verdana", 8.25f, true };
112       background = background;
113       foreground = navy;
114
115       bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
116       {
117          if(!active)
118          {
119             SaveData();
120          }
121          return true;
122       }
123       
124       bool OnPostCreate()
125       {
126          DataBox::OnPostCreate();
127          ((EditBox)editor).textHorzScroll = false;
128          return true;
129       }
130
131       bool NotifyChanged(bool closingDropDown)
132       {
133          if(shownYear < 100)
134          {
135             DateTime time;
136             time.GetLocalTime();
137             shownYear += (time.year / 100) * 100;
138             if(Abs(shownYear - time.year) >= 50)
139                shownYear -= 100;
140             yearBox.Refresh();           
141          }
142          Update(null);
143          dateBox.Activate();
144          return true;
145       }
146    };
147 #define  Height   20
148 #define  Width    24
149    void FindDate(int mx, int my, bool changeMonth, bool close)
150    {
151       DayOfTheWeek d;
152       int x, y;
153       int w;
154       Date day = { shownYear, shownMonth, 1 };
155       d = day.dayOfTheWeek;
156       day.day -= 7 + (d % 7);
157       if(day.day < 1)
158       {
159          if(--day.month < january)
160          {
161             day.month = december;
162             day.year--;
163          }
164          day.day += monthLengths[ISLEAP(day.year)][day.month];
165       }
166
167       y = 5 + Height;
168       for(w = 0; w<7; w++, y += Height)
169       {
170          for(x = Width / 2, d = sunday; d <= saturday; d++, x += Width)
171          {
172             if(mx >= x-10 && my >= y && mx <= x+10 && my <= y+15 && (day.month == shownMonth || changeMonth))
173             {
174                bool closeCalendar = close && dateValue.day == day.day && dateValue.month == day.month && dateValue.year == day.year;
175                dateValue = day;
176                shownMonth = day.month;
177                shownYear = day.year;
178                Update(null);
179                monthBox.Refresh();
180                yearBox.Refresh();
181
182                NotifyChanged(master, closeCalendar);
183                return;
184             }
185             if(++day.day > monthLengths[ISLEAP(day.year)][day.month])
186             {
187                day.day = 1;
188                if(++day.month > december)
189                {
190                   day.year++;
191                   day.month = january;
192                }
193             }
194          }
195       }
196    }
197    Window dateBox
198    {
199       this, anchor = { top = 30, left = 0, right = 0, bottom = 0 };
200
201       bool OnMouseMove(int x, int y, Modifiers mods)
202       {
203          if(mods.left && !mods.isSideEffect)
204             ((CalendarControl)master).FindDate(x, y, false, false);
205          return true;         
206       }
207       bool OnLeftButtonDown(int x, int y, Modifiers mods)
208       {
209          ((CalendarControl)master).FindDate(x, y, false, true);
210          return true;
211       }
212       bool OnLeftButtonUp(int x, int y, Modifiers mods)
213       {
214          ((CalendarControl)master).FindDate(x, y, true, false);
215          return true;
216       }
217
218       void OnRedraw(Surface surface)
219       {
220          CalendarControl dateEditor = (CalendarControl)master;
221          DayOfTheWeek d;
222          int x, y;
223          int w;
224          Date day = { dateEditor.shownYear, dateEditor.shownMonth, 1 };
225          d = day.dayOfTheWeek;
226          day.day -= 7 + (d % 7);
227          if(day.day < 1)
228          {
229             if(--day.month < january)
230             {
231                day.month = december;
232                day.year--;
233             }
234             day.day += monthLengths[ISLEAP(day.year)][day.month];
235          }
236
237          surface.SetBackground(dateEditor.background);
238          surface.Area(0, 0, clientSize.w, Height-1);
239
240          surface.SetForeground(black);
241          for(d = sunday; d <= saturday; d++)
242             surface.CenterTextf(Width / 2 + d * Width, 0, "%c", toupper(daysNames[d][0]));
243
244          surface.SetBackground(Color { 238, 238, 238 } /*whiteSmoke*/);
245          surface.Area(0, Height, Width, clientSize.h);
246          surface.Area(6 * Width, Height, 7*Width, clientSize.h);
247          
248          surface.SetForeground(lightGray);
249          surface.DrawLine(0, Height, clientSize.w, Height);
250          surface.DrawLine(0, Height, 0, clientSize.h);
251          surface.SetForeground(dateEditor.background);
252          surface.DrawLine(clientSize.w-1, Height, clientSize.w-1, clientSize.h);
253          surface.DrawLine(0, clientSize.h-1, clientSize.w, clientSize.h-1);
254
255          y = 5 + Height;
256          for(w = 0; w<7; w++, y += Height)
257          {
258             for(x = Width / 2, d = sunday; d <= saturday; d++, x += Width)
259             {
260                if(day.year == dateEditor.dateValue.year && day.month == dateEditor.dateValue.month && day.day == dateEditor.dateValue.day)
261                {
262                   surface.SetBackground(navy);
263                   surface.Area(x - 10, y, x + 10, y + 15);
264                   if(day.month == dateEditor.shownMonth)
265                      surface.SetForeground(white);
266                   else
267                      surface.SetForeground(gray);
268                }
269                else if(day.month == dateEditor.shownMonth)
270                   surface.SetForeground(black);
271                else
272                   surface.SetForeground(gray);
273
274                surface.CenterTextf(x, y, "%d", day.day);
275                if(++day.day > monthLengths[ISLEAP(day.year)][day.month])
276                {
277                   day.day = 1;
278                   if(++day.month > december)
279                   {
280                      day.year++;
281                      day.month = january;
282                   }
283                }
284             }
285          }      
286       }
287    };
288
289    bool OnKeyHit(Key key, unichar ch)
290    {
291       switch((Key)(SmartKey) key)         // Because it's inside ecere.dll and no property interpretation yet
292       {
293          case left:
294          case up:
295          case right:
296          case down:
297             if(dateBox.active)
298             {
299                if(shownMonth != dateValue.month || shownYear != dateValue.year)
300                {
301                   dateValue.month = shownMonth;
302                   dateValue.year = shownYear;
303                   dateValue.day = 1;
304                }
305                else if(key == left) dateValue.day--;
306                else if(key == right) dateValue.day++;
307                else if(key == up) dateValue.day-=7;
308                else if(key == down) dateValue.day+=7;
309                if(dateValue.day < 1)
310                {
311                   if(--dateValue.month < january)
312                   {
313                      dateValue.month = december;
314                      dateValue.year--;
315                   }
316                   dateValue.day += monthLengths[ISLEAP(dateValue.year)][dateValue.month];
317                }
318                else if(dateValue.day > monthLengths[ISLEAP(dateValue.year)][dateValue.month])
319                {
320                   dateValue.day -= monthLengths[ISLEAP(dateValue.year)][dateValue.month];
321                   if(++dateValue.month > december)
322                   {
323                      dateValue.year++;
324                      dateValue.month = january;
325                   }
326                }
327                shownMonth = dateValue.month;
328                shownYear = dateValue.year;
329                NotifyChanged(master, false);
330
331                monthBox.Refresh();
332                yearBox.Refresh();
333                Update(null);
334             }
335             return false;
336       }
337       return true;
338    }
339
340    bool OnPostCreate()
341    {
342       if(active)
343          dateBox.Activate();
344       return true;
345    }
346 }