I've built a graphics library and I'm coming up with some examples.
The trick is making them understandable. I can't judge my own code, like my API for usability because I wrote it.
The test of code, IMO, is how self evident it is. I'd like you to look at a section of code in "what I have tried" and tell me how you feel in terms of its readability, and what could be improved. If the API seems complicated I want to know that especially.
There is a weirdness I want to explain that I explain somewhat in my documentation, and that is the templatization of this function.
GFX doesn't use inheritance. It binds at the source level, not the binary level, using templates.
Destination& dst
is a draw target - think of it as a canvas of sorts. That way you can pass something in and it will draw to that.
What I have tried:
template<typename Destination>
void draw_clock(Destination& dst, tm& time,const srect16& bounds) {
srect16 b = bounds.normalize();
uint16_t w = min(b.width(),b.height());
using view_t = viewport<Destination>;
view_t view(dst);
view.center(spoint16(w/2,w/2));
srect16 sr(0,0,w/16,w/2);
sr.center_horizontal_inplace(b);
view.rotation((time.tm_sec/60.0)*360);
spoint16 second_points[] = {
view.translate(spoint16(sr.x1,sr.y1)),
view.translate(spoint16(sr.x2,sr.y1)),
view.translate(spoint16(sr.x2,sr.y2)),
view.translate(spoint16(sr.x1,sr.y2))
};
spath16 second_path(4,second_points);
view.rotation((time.tm_min/60.0)*360);
spoint16 minute_points[] = {
view.translate(spoint16(sr.x1,sr.y1)),
view.translate(spoint16(sr.x2,sr.y1)),
view.translate(spoint16(sr.x2,sr.y2)),
view.translate(spoint16(sr.x1,sr.y2))
};
spath16 minute_path(4,minute_points);
sr.y1 += w/8; view.rotation((time.tm_hour/24.0)*360);
spoint16 hour_points[] = {
view.translate(spoint16(sr.x1,sr.y1)),
view.translate(spoint16(sr.x2,sr.y1)),
view.translate(spoint16(sr.x2,sr.y2)),
view.translate(spoint16(sr.x1,sr.y2))
};
spath16 hour_path(4,hour_points);
draw::filled_polygon(dst,minute_path,color<typename Destination::pixel_type>::black);
draw::filled_polygon(dst,hour_path,color<typename Destination::pixel_type>::black);
draw::filled_polygon(dst,second_path,color<typename Destination::pixel_type>::red);
}