Custom canvas based controls - How to track X,Y mouse hotspots?

I have created a pretty specialized calendar selector widget using the canvas control. Of course at the heart of a calendar widget is selecting a day. The widget looks awesome (well, compared to our old one) but now I need to make it respond to clicking with the mouse on a given date. What I am thinking right now is when I paint a given day, record the x, y, width and height along with the date representing within those coordinates. Then on a mouse down, loop through that array.

Is there a better way to accomplish tracking something like this? i.e. when someone presses on X/Y looking up what is actually represented under the pressed mouse location.

That’s straightforward. Implement it and benchmark the click processing. Having an array of rectangles (or rectangle coordinates) where the array length <= 31 will be a quick linear lookup. If it works, and isn’t taking appreciable time, no need to be too clever.

But if you wanted to start clever, keep a list of row starts and column starts. On a click, figure out which row and column, then compute the date from that. You’d have 7 comparisons for the column, up to 5 for the rows. So 12-ish plus some math to find the date. Your cell by cell approach will need 120-ish comparisons worst case, 60-ish average case.

It may get a little more complicated than that because each row might now have the same number of dates in it, so there are no fixed columns. With your idea, however, I could track rows as an array and just compute which row the Y click was on and then loop through the dates on that row instead of all the dates. It isn’t uncommon to have 200-300 dates represented in the widget and on the display at the same time, so this is probably a much better idea.

Benchmarking the simple For loop, from click to knowing which date was pressed, when clicking on the 300th date takes 0.0464ms. I’m not going to worry about optimizing right now :slight_smile:

BTW… Here is a screen shot of the widget:

Green dates represent dates where all the items under that date have been processed, yellow dates are those that still need work, the slightly darker yellow/green blocks are processed/not processed but represent a weekend day, red blocks with numbers indicate a missing span of days w/no procedures done on those days and of course the blue is the month. This represents an itemized bill from a hospital, BTW. The dates are fictitious, generated in a random sequence for testing the widget.