1 namespace gui::controls;
5 #define ISLEAP(y) (!((y)%4) && (((y) % 100) || (!((y)% 400))))
7 public class CalendarControl : CommonControl
9 class_property(icon) = "<:ecere>controls/calendar.png";
12 virtual void Window::NotifyChanged(bool close);
18 background = { 195, 217, 255 };
19 clientSize = { 168, 198 };
24 if(!dateValue.year && !dateValue.day && !dateValue.month)
28 dateValue.day = now.day;
29 dateValue.month = now.month;
30 shownYear = dateValue.year = now.year;
31 shownMonth = dateValue.month;
43 background = background;
44 font = { $"Verdana", 8.25f, true };
50 bool NotifyClicked(Button button, int x, int y, ecere::gui::Modifiers mods)
53 if(shownMonth < january) { shownMonth = december; shownYear--; yearBox.Refresh(); }
63 anchor = { right = 8, top = 8 };
68 background = background;
69 font = { $"Verdana", 8.25f, true };
74 bool NotifyClicked(Button button, int x, int y, ecere::gui::Modifiers mods)
77 if(shownMonth > december) { shownMonth = january; shownYear++; yearBox.Refresh(); }
87 this, type = class(Month), data = &shownMonth, position = { 25, 5 }, size = { 75, 20 };
88 background = background;
90 font = { $"Verdana", 8.25f, true };
94 DataBox::OnPostCreate();
95 ((DropBox)editor).showButton = false;
96 ((DropBox)editor).alignment = right;
100 bool NotifyChanged(bool closingDropDown)
110 this, type = class(int), data = &shownYear, position = { 100, 5 }, size = { 38, 20 };
111 font = { $"Verdana", 8.25f, true };
112 background = background;
115 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
126 DataBox::OnPostCreate();
127 ((EditBox)editor).textHorzScroll = false;
131 bool NotifyChanged(bool closingDropDown)
137 shownYear += (time.year / 100) * 100;
138 if(Abs(shownYear - time.year) >= 50)
149 void FindDate(int mx, int my, bool changeMonth, bool close)
154 Date day = { shownYear, shownMonth, 1 };
155 d = day.dayOfTheWeek;
156 day.day -= 7 + (d % 7);
159 if(--day.month < january)
161 day.month = december;
164 day.day += monthLengths[ISLEAP(day.year)][day.month];
168 for(w = 0; w<7; w++, y += Height)
170 for(x = Width / 2, d = sunday; d <= saturday; d++, x += Width)
172 if(mx >= x-10 && my >= y && mx <= x+10 && my <= y+15 && (day.month == shownMonth || changeMonth))
174 bool closeCalendar = close && dateValue.day == day.day && dateValue.month == day.month && dateValue.year == day.year;
176 shownMonth = day.month;
177 shownYear = day.year;
182 NotifyChanged(master, closeCalendar);
185 if(++day.day > monthLengths[ISLEAP(day.year)][day.month])
188 if(++day.month > december)
199 this, anchor = { top = 30, left = 0, right = 0, bottom = 0 };
201 bool OnMouseMove(int x, int y, Modifiers mods)
203 if(mods.left && !mods.isSideEffect)
204 ((CalendarControl)master).FindDate(x, y, false, false);
207 bool OnLeftButtonDown(int x, int y, Modifiers mods)
209 ((CalendarControl)master).FindDate(x, y, false, true);
212 bool OnLeftButtonUp(int x, int y, Modifiers mods)
214 ((CalendarControl)master).FindDate(x, y, true, false);
218 void OnRedraw(Surface surface)
220 CalendarControl dateEditor = (CalendarControl)master;
224 Date day = { dateEditor.shownYear, dateEditor.shownMonth, 1 };
225 d = day.dayOfTheWeek;
226 day.day -= 7 + (d % 7);
229 if(--day.month < january)
231 day.month = december;
234 day.day += monthLengths[ISLEAP(day.year)][day.month];
237 surface.SetBackground(dateEditor.background);
238 surface.Area(0, 0, clientSize.w, Height-1);
240 surface.SetForeground(black);
241 for(d = sunday; d <= saturday; d++)
242 surface.CenterTextf(Width / 2 + d * Width, 0, "%c", toupper(daysNames[d][0]));
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);
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);
256 for(w = 0; w<7; w++, y += Height)
258 for(x = Width / 2, d = sunday; d <= saturday; d++, x += Width)
260 if(day.year == dateEditor.dateValue.year && day.month == dateEditor.dateValue.month && day.day == dateEditor.dateValue.day)
262 surface.SetBackground(navy);
263 surface.Area(x - 10, y, x + 10, y + 15);
264 if(day.month == dateEditor.shownMonth)
265 surface.SetForeground(white);
267 surface.SetForeground(gray);
269 else if(day.month == dateEditor.shownMonth)
270 surface.SetForeground(black);
272 surface.SetForeground(gray);
274 surface.CenterTextf(x, y, "%d", day.day);
275 if(++day.day > monthLengths[ISLEAP(day.year)][day.month])
278 if(++day.month > december)
289 bool OnKeyHit(Key key, unichar ch)
291 switch((Key)(SmartKey) key) // Because it's inside ecere.dll and no property interpretation yet
299 if(shownMonth != dateValue.month || shownYear != dateValue.year)
301 dateValue.month = shownMonth;
302 dateValue.year = shownYear;
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)
311 if(--dateValue.month < january)
313 dateValue.month = december;
316 dateValue.day += monthLengths[ISLEAP(dateValue.year)][dateValue.month];
318 else if(dateValue.day > monthLengths[ISLEAP(dateValue.year)][dateValue.month])
320 dateValue.day -= monthLengths[ISLEAP(dateValue.year)][dateValue.month];
321 if(++dateValue.month > december)
324 dateValue.month = january;
327 shownMonth = dateValue.month;
328 shownYear = dateValue.year;
329 NotifyChanged(master, false);