The calendar now has a resize method, which is another item off the list of things-to-do.
The bitmap class introduced in the last post is now part of the SuperBitmap. The SuperBitmap class has retained the same API, but it now is just a facade wrapped around an instance of the Bitmap class. The Bitmap does all of the hard work.
I’ve made a couple of amendments to the Calendar and Date classes, too. The Date class now has its equals and not-equals operators overloaded, whilst the Calendar now shows Monday as the first column (instead of Sunday). It also handles clicks on buttons correctly if that button represents the currently-selected day in a different month/year.
Following on from the last post, the Date class now works correctly (as far as I’ve tested). I’ve tidied it up a bit too, and moved most of the code out of the header file and into the cpp file. I’ve also fixed rounding errors in the MultiLineTextBox’s vertical alignment option (centred) - it moves around as you’d expect now. Lastly, the WoopsiString class doesn’t crash if you try to insert text into an empty string. This was causing the demo released the other day to lock up if you deleted all of the text and then pressed a key.
In other news, there are now examples illustrating the use of the Date class and ProgressBar gadget. I’m hoping to get examples done for all of the gadgets, where possible, because they double as unit tests as well as providing guidance for users.
I think it’s about time for another release…
EDIT: Oh, and the cursor in the MultiLineTextBox is hidden by default, now that I’ve got the preliminary work done.
Here’s a new gadget that might prove useful to those people determined to create a replacement for DSOrganise:
Yep, it’s a calendar/date picker. It raises EVENT_ACTION events each time a new day is clicked. The left and right arrows page through the months and years.
Working out the layout of a calendar is actually very simple. It’s much simpler than I was expecting it to be. First of all, we make a few assumptions:
- We will only show one month at a time (though we will show days that border the start and end of the current month)
- We will always have 7 columns (7 days in the week)
- We will always have 6 rows (this caters for the worst-case scenario, or largest number of visible days, and sticking to this reduces the complexity of the algorithms we need to use)
Once we’ve got that set up, we need to know what day of the week the current month starts on. The magic for this is handled inside a new Date class that can manipulate the days, months and years of a given date, the logic for which came from here (note that the rest of that site seems to be totally bonkers). If we know what day of the week the month starts on, we can generate all of the preceding day buttons, then the buttons for the current month, and finally any buttons from the next month.
Using the Calendar gadget is simple. It automatically grows and shrinks to fit within the dimensions specified in its constructor, it raises an EVENT_ACTION event when a day is clicked (as noted previously), and it has methods to set and get the date. It doesn’t inherit from the Window class, so it can be added to screens or an existing window alongside other gadges. There’s an example in the “examples” folder.
Two caveats with the Calendar and Date classes at the moment. I’m not sure that Date::addDays() works correctly for negative days (need to write a test, but as it’s not used by the Calendar it’s not a problem right now) and the Calendar doesn’t have a resize() function.