diff options
| author | Pietro Gagliardi <[email protected]> | 2014-10-10 11:43:12 -0400 |
|---|---|---|
| committer | Pietro Gagliardi <[email protected]> | 2014-10-10 11:43:12 -0400 |
| commit | 8a74b95fcf8cadd851e839b60962e46b3bb8a6fd (patch) | |
| tree | 306148c142c05527be3626bb161f4bb505d222b2 /windowspopover/main.c | |
| parent | 96895004cd856cac716ebc78961e7b216a8f341f (diff) | |
Genericized the popover code to allow pointing in any direction and at any point. This only affects the shaping; everything else needs to be done now.
Diffstat (limited to 'windowspopover/main.c')
| -rw-r--r-- | windowspopover/main.c | 117 |
1 files changed, 99 insertions, 18 deletions
diff --git a/windowspopover/main.c b/windowspopover/main.c index e924d41..b8351e5 100644 --- a/windowspopover/main.c +++ b/windowspopover/main.c @@ -39,30 +39,111 @@ void xpanic(char *msg, DWORD err) #define ARROWHEIGHT 8 #define ARROWWIDTH 8 /* should be the same for smooth lines */ +struct popover { + void *gopopover; + + // a nice consequence of this design is that it allows four arrowheads to jut out at once; in practice only one will ever be used, but hey — simple implementation! + LONG arrowLeft; + LONG arrowRight; + LONG arrowTop; + LONG arrowBottom; +}; + HRGN makePopoverRegion(HDC dc, LONG width, LONG height) { - POINT pt[8]; + POINT pt[20]; + int n; HRGN region; + struct popover _p = { NULL, -1, -1, 20, -1 }; + struct popover *p = &_p; + LONG xmax, ymax; if (BeginPath(dc) == 0) xpanic("error beginning path for Popover shape", GetLastError()); - pt[0].x = 0; - pt[0].y = ARROWHEIGHT; - pt[1].x = pt[0].x; - pt[1].y = pt[0].y + (height - ARROWHEIGHT); - pt[2].x = pt[1].x + width; - pt[2].y = pt[1].y; - pt[3].x = pt[2].x; - pt[3].y = pt[2].y - (height - ARROWHEIGHT); - pt[4].x = pt[3].x - ((width / 2) - ARROWWIDTH); - pt[4].y = pt[3].y; - pt[5].x = pt[4].x - ARROWWIDTH; - pt[5].y = pt[4].y - ARROWHEIGHT; - pt[6].x = pt[5].x - ARROWWIDTH; - pt[6].y = pt[5].y + ARROWHEIGHT; - pt[7].x = pt[0].x; - pt[7].y = pt[0].y; - if (Polyline(dc, pt, 8) == 0) + n = 0; + + // figure out the xmax and ymax of the box + xmax = width; + if (p->arrowRight >= 0) + xmax -= ARROWWIDTH; + ymax = height; + if (p->arrowBottom >= 0) + ymax -= ARROWHEIGHT; + + // the first point is either at (0,0), (0,arrowHeight), (arrowWidth,0), or (arrowWidth,arrowHeight) + pt[n].x = 0; + if (p->arrowLeft >= 0) + pt[n].x = ARROWWIDTH; + pt[n].y = 0; + if (p->arrowTop >= 0) + pt[n].y = ARROWHEIGHT; + n++; + + // the left side + pt[n].x = pt[n - 1].x; + if (p->arrowLeft >= 0) { + pt[n].y = pt[n - 1].y + p->arrowLeft; + n++; + pt[n].x = pt[n - 1].x - ARROWWIDTH; + pt[n].y = pt[n - 1].y + ARROWHEIGHT; + n++; + pt[n].x = pt[n - 1].x + ARROWWIDTH; + pt[n].y = pt[n - 1].y + ARROWHEIGHT; + n++; + pt[n].x = pt[n - 1].x; + } + pt[n].y = ymax; + n++; + + // the bottom side + pt[n].y = pt[n - 1].y; + if (p->arrowBottom >= 0) { + pt[n].x = pt[n - 1].x + p->arrowBottom; + n++; + pt[n].x = pt[n - 1].x + ARROWWIDTH; + pt[n].y = pt[n - 1].y + ARROWHEIGHT; + n++; + pt[n].x = pt[n - 1].x + ARROWWIDTH; + pt[n].y = pt[n - 1].y - ARROWHEIGHT; + n++; + pt[n].y = pt[n - 1].y; + } + pt[n].x = xmax; + n++; + + // the right side + pt[n].x = pt[n - 1].x; + if (p->arrowRight >= 0) { + pt[n].y = pt[0].y + p->arrowRight + (ARROWHEIGHT * 2); + n++; + pt[n].x = pt[n - 1].x + ARROWWIDTH; + pt[n].y = pt[n - 1].y - ARROWHEIGHT; + n++; + pt[n].x = pt[n - 1].x - ARROWWIDTH; + pt[n].y = pt[n - 1].y - ARROWHEIGHT; + n++; + pt[n].x = pt[n - 1].x; + } + pt[n].y = pt[0].y; + n++; + + // the top side + pt[n].y = pt[n - 1].y; + if (p->arrowTop >= 0) { + pt[n].x = pt[0].x + p->arrowTop + (ARROWWIDTH * 2); + n++; + pt[n].x = pt[n - 1].x - ARROWWIDTH; + pt[n].y = pt[n - 1].y - ARROWHEIGHT; + n++; + pt[n].x = pt[n - 1].x - ARROWWIDTH; + pt[n].y = pt[n - 1].y + ARROWHEIGHT; + n++; + pt[n].y = pt[n - 1].y; + } + pt[n].x = pt[0].x; + n++; + + if (Polyline(dc, pt, n) == 0) xpanic("error drawing lines in Popover shape", GetLastError()); if (EndPath(dc) == 0) xpanic("error ending path for Popover shape", GetLastError()); |
