1 namespace gui::controls;
5 #define ISLEAP(y) (!((y)%4) && (((y) % 100) || (!((y)% 400))))
7 /*static */Array<String> veryShortDaysNames
9 $"Sunday"."S", $"Monday"."M", $"Tuesday"."T", $"Wednesday"."W",
10 $"Thursday"."T", $"Friday"."F", $"Saturday"."S"
13 public class CalendarControl : CommonControl
15 class_property(icon) = "<:ecere>controls/calendar.png";
18 virtual void Window::NotifyChanged(CalendarControl calendarControl, bool close);
24 background = { 195, 217, 255 };
25 clientSize = { 168, 198 };
30 if(!dateValue.year && !dateValue.day && !dateValue.month)
34 dateValue.day = now.day;
35 dateValue.month = now.month;
36 shownYear = dateValue.year = now.year;
37 shownMonth = dateValue.month;
49 background = background;
50 font = { $"Verdana", 8.25f, true };
56 bool NotifyClicked(Button button, int x, int y, ecere::gui::Modifiers mods)
59 if(shownMonth < january) { shownMonth = december; shownYear--; yearBox.Refresh(); }
69 anchor = { right = 8, top = 8 };
74 background = background;
75 font = { $"Verdana", 8.25f, true };
80 bool NotifyClicked(Button button, int x, int y, ecere::gui::Modifiers mods)
83 if(shownMonth > december) { shownMonth = january; shownYear++; yearBox.Refresh(); }
93 this, type = class(Month), data = &shownMonth, position = { 25, 5 }, size = { 75, 20 };
94 background = background;
96 font = { $"Verdana", 8.25f, true };
100 DataBox::OnPostCreate();
101 ((DropBox)editor).showButton = false;
102 ((DropBox)editor).alignment = right;
106 bool NotifyChanged(DataBox dataBox, bool closingDropDown)
116 this, type = class(int), data = &shownYear, position = { 100, 5 }, size = { 38, 20 };
117 font = { $"Verdana", 8.25f, true };
118 background = background;
121 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
132 DataBox::OnPostCreate();
133 ((EditBox)editor).textHorzScroll = false;
137 bool NotifyChanged(DataBox dataBox, bool closingDropDown)
143 shownYear += (time.year / 100) * 100;
144 if(Abs(shownYear - time.year) >= 50)
155 void FindDate(int mx, int my, bool changeMonth, bool close)
160 Date day = { shownYear, shownMonth, 1 };
161 d = day.dayOfTheWeek;
162 day.day -= 7 + (d % 7);
165 if(--day.month < january)
167 day.month = december;
170 day.day += monthLengths[ISLEAP(day.year)][day.month];
174 for(w = 0; w<7; w++, y += Height)
176 for(x = Width / 2, d = sunday; d <= saturday; d++, x += Width)
178 if(mx >= x-10 && my >= y && mx <= x+10 && my <= y+15 && (day.month == shownMonth || changeMonth))
180 bool closeCalendar = close && dateValue.day == day.day && dateValue.month == day.month && dateValue.year == day.year;
182 shownMonth = day.month;
183 shownYear = day.year;
188 NotifyChanged(master, this, closeCalendar);
191 if(++day.day > monthLengths[ISLEAP(day.year)][day.month])
194 if(++day.month > december)
205 this, anchor = { top = 30, left = 0, right = 0, bottom = 0 };
207 bool OnMouseMove(int x, int y, Modifiers mods)
209 if(mods.left && !mods.isSideEffect)
210 ((CalendarControl)master).FindDate(x, y, false, false);
213 bool OnLeftButtonDown(int x, int y, Modifiers mods)
215 ((CalendarControl)master).FindDate(x, y, false, true);
218 bool OnLeftButtonUp(int x, int y, Modifiers mods)
220 ((CalendarControl)master).FindDate(x, y, true, false);
224 void OnRedraw(Surface surface)
226 CalendarControl dateEditor = (CalendarControl)master;
230 Date day = { dateEditor.shownYear, dateEditor.shownMonth, 1 };
231 d = day.dayOfTheWeek;
232 day.day -= 7 + (d % 7);
235 if(--day.month < january)
237 day.month = december;
240 day.day += monthLengths[ISLEAP(day.year)][day.month];
243 surface.SetBackground(dateEditor.background);
244 surface.Area(0, 0, clientSize.w, Height-1);
246 surface.SetForeground(black);
247 for(d = sunday; d <= saturday; d++)
249 surface.CenterTextf(Width / 2 + d * Width, 0, "%s", veryShortDaysNames[d]);
252 surface.SetBackground(Color { 238, 238, 238 } /*whiteSmoke*/);
253 surface.Area(0, Height, Width, clientSize.h);
254 surface.Area(6 * Width, Height, 7*Width, clientSize.h);
256 surface.SetForeground(lightGray);
257 surface.DrawLine(0, Height, clientSize.w, Height);
258 surface.DrawLine(0, Height, 0, clientSize.h);
259 surface.SetForeground(dateEditor.background);
260 surface.DrawLine(clientSize.w-1, Height, clientSize.w-1, clientSize.h);
261 surface.DrawLine(0, clientSize.h-1, clientSize.w, clientSize.h-1);
264 for(w = 0; w<7; w++, y += Height)
266 for(x = Width / 2, d = sunday; d <= saturday; d++, x += Width)
268 if(day.year == dateEditor.dateValue.year && day.month == dateEditor.dateValue.month && day.day == dateEditor.dateValue.day)
270 surface.SetBackground(navy);
271 surface.Area(x - 10, y, x + 10, y + 15);
272 if(day.month == dateEditor.shownMonth)
273 surface.SetForeground(white);
275 surface.SetForeground(gray);
277 else if(day.month == dateEditor.shownMonth)
278 surface.SetForeground(black);
280 surface.SetForeground(gray);
282 surface.CenterTextf(x, y, "%d", day.day);
283 if(++day.day > monthLengths[ISLEAP(day.year)][day.month])
286 if(++day.month > december)
297 bool OnKeyHit(Key key, unichar ch)
299 switch((Key)(SmartKey) key) // Because it's inside ecere.dll and no property interpretation yet
307 if(shownMonth != dateValue.month || shownYear != dateValue.year)
309 dateValue.month = shownMonth;
310 dateValue.year = shownYear;
313 else if(key == left) dateValue.day--;
314 else if(key == right) dateValue.day++;
315 else if(key == up) dateValue.day-=7;
316 else if(key == down) dateValue.day+=7;
317 if(dateValue.day < 1)
319 if(--dateValue.month < january)
321 dateValue.month = december;
324 dateValue.day += monthLengths[ISLEAP(dateValue.year)][dateValue.month];
326 else if(dateValue.day > monthLengths[ISLEAP(dateValue.year)][dateValue.month])
328 dateValue.day -= monthLengths[ISLEAP(dateValue.year)][dateValue.month];
329 if(++dateValue.month > december)
332 dateValue.month = january;
335 shownMonth = dateValue.month;
336 shownYear = dateValue.year;
337 NotifyChanged(master, this, false);