The official µGFX library repository.

gwin.c 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. /*
  2. * This file is subject to the terms of the GFX License. If a copy of
  3. * the license was not distributed with this file, you can obtain one at:
  4. *
  5. * http://ugfx.org/license.html
  6. */
  7. /**
  8. * @file src/gwin/gwin.c
  9. * @brief GWIN sub-system code
  10. */
  11. #include "../../gfx.h"
  12. #if GFX_USE_GWIN
  13. #include "gwin_class.h"
  14. #include <string.h>
  15. /*-----------------------------------------------
  16. * Data
  17. *-----------------------------------------------*/
  18. static const gwinVMT basegwinVMT = {
  19. "GWIN", // The classname
  20. sizeof(GWindowObject), // The object size
  21. 0, // The destroy routine
  22. 0, // The redraw routine
  23. 0, // The after-clear routine
  24. };
  25. static color_t defaultFgColor = White;
  26. static color_t defaultBgColor = Black;
  27. #if GDISP_NEED_TEXT
  28. static font_t defaultFont;
  29. #endif
  30. /* These init functions are defined by each module but not published */
  31. extern void _gwmInit(void);
  32. extern void _gwmDeinit(void);
  33. #if GWIN_NEED_WIDGET
  34. extern void _gwidgetInit(void);
  35. extern void _gwidgetDeinit(void);
  36. #endif
  37. #if GWIN_NEED_CONTAINERS
  38. extern void _gcontainerInit(void);
  39. extern void _gcontainerDeinit(void);
  40. #endif
  41. /*-----------------------------------------------
  42. * Helper Routines
  43. *-----------------------------------------------*/
  44. /*-----------------------------------------------
  45. * Class Routines
  46. *-----------------------------------------------*/
  47. void _gwinInit(void)
  48. {
  49. _gwmInit();
  50. #if GWIN_NEED_WIDGET
  51. _gwidgetInit();
  52. #endif
  53. #if GWIN_NEED_CONTAINERS
  54. _gcontainerInit();
  55. #endif
  56. }
  57. void _gwinDeinit(void)
  58. {
  59. #if GWIN_NEED_CONTAINERS
  60. _gcontainerDeinit();
  61. #endif
  62. #if GWIN_NEED_WIDGET
  63. _gwidgetDeinit();
  64. #endif
  65. _gwmDeinit();
  66. }
  67. // Internal routine for use by GWIN components only
  68. // Initialise a window creating it dynamically if required.
  69. GHandle _gwindowCreate(GDisplay *g, GWindowObject *pgw, const GWindowInit *pInit, const gwinVMT *vmt, uint32_t flags) {
  70. // Allocate the structure if necessary
  71. if (!pgw) {
  72. if (!(pgw = gfxAlloc(vmt->size)))
  73. return 0;
  74. pgw->flags = flags|GWIN_FLG_DYNAMIC;
  75. } else
  76. pgw->flags = flags;
  77. // Initialise all basic fields
  78. pgw->display = g;
  79. pgw->vmt = vmt;
  80. pgw->color = defaultFgColor;
  81. pgw->bgcolor = defaultBgColor;
  82. #if GDISP_NEED_TEXT
  83. pgw->font = defaultFont;
  84. #endif
  85. // Make sure we don't create nasty problems for ourselves
  86. if (vmt->size > sizeof(GWindowObject))
  87. memset(pgw+1, 0, vmt->size - sizeof(GWindowObject));
  88. if (!_gwinWMAdd(pgw, pInit)) {
  89. if ((pgw->flags & GWIN_FLG_DYNAMIC))
  90. gfxFree(pgw);
  91. return 0;
  92. }
  93. return (GHandle)pgw;
  94. }
  95. // Internal routine for use by GWIN components only
  96. void _gwinDestroy(GHandle gh, GRedrawMethod how) {
  97. if (!gh)
  98. return;
  99. // Make the window invisible
  100. gwinSetVisible(gh, FALSE);
  101. // Make sure it is flushed first - must be REDRAW_WAIT or REDRAW_INSESSION
  102. _gwinFlushRedraws(how);
  103. #if GWIN_NEED_CONTAINERS
  104. // Notify the parent it is about to be deleted
  105. if (gh->parent && ((gcontainerVMT *)gh->parent->vmt)->NotifyDelete)
  106. ((gcontainerVMT *)gh->parent->vmt)->NotifyDelete(gh->parent, gh);
  107. #endif
  108. // Remove from the window manager
  109. #if GWIN_NEED_WINDOWMANAGER
  110. _GWINwm->vmt->Delete(gh);
  111. #endif
  112. // Class destroy routine
  113. if (gh->vmt->Destroy)
  114. gh->vmt->Destroy(gh);
  115. // Clean up the structure
  116. if (gh->flags & GWIN_FLG_DYNAMIC) {
  117. gh->flags = 0; // To be sure, to be sure
  118. gfxFree((void *)gh);
  119. } else
  120. gh->flags = 0; // To be sure, to be sure
  121. }
  122. /*-----------------------------------------------
  123. * Routines that affect all windows
  124. *-----------------------------------------------*/
  125. void gwinClearInit(GWindowInit *pwi) {
  126. char *p;
  127. unsigned len;
  128. for(p = (char *)pwi, len = sizeof(GWindowInit); len; len--)
  129. *p++ = 0;
  130. }
  131. void gwinSetDefaultColor(color_t clr) {
  132. defaultFgColor = clr;
  133. }
  134. color_t gwinGetDefaultColor(void) {
  135. return defaultFgColor;
  136. }
  137. void gwinSetDefaultBgColor(color_t bgclr) {
  138. defaultBgColor = bgclr;
  139. }
  140. color_t gwinGetDefaultBgColor(void) {
  141. return defaultBgColor;
  142. }
  143. #if GDISP_NEED_TEXT
  144. void gwinSetDefaultFont(font_t font) {
  145. defaultFont = font;
  146. }
  147. font_t gwinGetDefaultFont(void) {
  148. return defaultFont;
  149. }
  150. #endif
  151. /*-----------------------------------------------
  152. * The GWindow Routines
  153. *-----------------------------------------------*/
  154. GHandle gwinGWindowCreate(GDisplay *g, GWindowObject *pgw, const GWindowInit *pInit) {
  155. if (!(pgw = _gwindowCreate(g, pgw, pInit, &basegwinVMT, 0)))
  156. return 0;
  157. gwinSetVisible(pgw, pInit->show);
  158. _gwinFlushRedraws(REDRAW_WAIT);
  159. return pgw;
  160. }
  161. void gwinDestroy(GHandle gh) {
  162. _gwinDestroy(gh, REDRAW_WAIT);
  163. }
  164. const char *gwinGetClassName(GHandle gh) {
  165. return gh->vmt->classname;
  166. }
  167. bool_t gwinGetVisible(GHandle gh) {
  168. return (gh->flags & GWIN_FLG_SYSVISIBLE) ? TRUE : FALSE;
  169. }
  170. bool_t gwinGetEnabled(GHandle gh) {
  171. return (gh->flags & GWIN_FLG_SYSENABLED) ? TRUE : FALSE;
  172. }
  173. #if GDISP_NEED_TEXT
  174. void gwinSetFont(GHandle gh, font_t font) {
  175. gh->font = font;
  176. }
  177. #endif
  178. void gwinClear(GHandle gh) {
  179. /*
  180. * Don't render anything when the window is not visible but
  181. * still call the AfterClear() routine as some widgets will
  182. * need this to clear internal buffers or similar
  183. */
  184. if (_gwinDrawStart(gh)) {
  185. gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, gh->bgcolor);
  186. _gwinDrawEnd(gh);
  187. }
  188. if (gh->vmt->AfterClear)
  189. gh->vmt->AfterClear(gh);
  190. }
  191. void gwinDrawPixel(GHandle gh, coord_t x, coord_t y) {
  192. if (!_gwinDrawStart(gh)) return;
  193. gdispGDrawPixel(gh->display, gh->x+x, gh->y+y, gh->color);
  194. _gwinDrawEnd(gh);
  195. }
  196. void gwinDrawLine(GHandle gh, coord_t x0, coord_t y0, coord_t x1, coord_t y1) {
  197. if (!_gwinDrawStart(gh)) return;
  198. gdispGDrawLine(gh->display, gh->x+x0, gh->y+y0, gh->x+x1, gh->y+y1, gh->color);
  199. _gwinDrawEnd(gh);
  200. }
  201. void gwinDrawBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy) {
  202. if (!_gwinDrawStart(gh)) return;
  203. gdispGDrawBox(gh->display, gh->x+x, gh->y+y, cx, cy, gh->color);
  204. _gwinDrawEnd(gh);
  205. }
  206. void gwinFillArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy) {
  207. if (!_gwinDrawStart(gh)) return;
  208. gdispGFillArea(gh->display, gh->x+x, gh->y+y, cx, cy, gh->color);
  209. _gwinDrawEnd(gh);
  210. }
  211. void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) {
  212. if (!_gwinDrawStart(gh)) return;
  213. gdispGBlitArea(gh->display, gh->x+x, gh->y+y, cx, cy, srcx, srcy, srccx, buffer);
  214. _gwinDrawEnd(gh);
  215. }
  216. #if GDISP_NEED_CIRCLE
  217. void gwinDrawCircle(GHandle gh, coord_t x, coord_t y, coord_t radius) {
  218. if (!_gwinDrawStart(gh)) return;
  219. gdispGDrawCircle(gh->display, gh->x+x, gh->y+y, radius, gh->color);
  220. _gwinDrawEnd(gh);
  221. }
  222. void gwinFillCircle(GHandle gh, coord_t x, coord_t y, coord_t radius) {
  223. if (!_gwinDrawStart(gh)) return;
  224. gdispGFillCircle(gh->display, gh->x+x, gh->y+y, radius, gh->color);
  225. _gwinDrawEnd(gh);
  226. }
  227. #endif
  228. #if GDISP_NEED_DUALCIRCLE
  229. void gwinFillDualCircle(GHandle gh, coord_t x, coord_t y, coord_t radius1, coord_t radius2) {
  230. if (!_gwinDrawStart(gh)) return;
  231. gdispGFillDualCircle(gh->display, gh->x+x, gh->y+y, radius1, gh->bgcolor, radius2, gh->color);
  232. _gwinDrawEnd(gh);
  233. }
  234. #endif
  235. #if GDISP_NEED_ELLIPSE
  236. void gwinDrawEllipse(GHandle gh, coord_t x, coord_t y, coord_t a, coord_t b) {
  237. if (!_gwinDrawStart(gh)) return;
  238. gdispGDrawEllipse(gh->display, gh->x+x, gh->y+y, a, b, gh->color);
  239. _gwinDrawEnd(gh);
  240. }
  241. void gwinFillEllipse(GHandle gh, coord_t x, coord_t y, coord_t a, coord_t b) {
  242. if (!_gwinDrawStart(gh)) return;
  243. gdispGFillEllipse(gh->display, gh->x+x, gh->y+y, a, b, gh->color);
  244. _gwinDrawEnd(gh);
  245. }
  246. #endif
  247. #if GDISP_NEED_ARC
  248. void gwinDrawArc(GHandle gh, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle) {
  249. if (!_gwinDrawStart(gh)) return;
  250. gdispGDrawArc(gh->display, gh->x+x, gh->y+y, radius, startangle, endangle, gh->color);
  251. _gwinDrawEnd(gh);
  252. }
  253. void gwinFillArc(GHandle gh, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle) {
  254. if (!_gwinDrawStart(gh)) return;
  255. gdispGFillArc(gh->display, gh->x+x, gh->y+y, radius, startangle, endangle, gh->color);
  256. _gwinDrawEnd(gh);
  257. }
  258. void gwinDrawThickArc(GHandle gh, coord_t x, coord_t y, coord_t startradius, coord_t endradius, coord_t startangle, coord_t endangle) {
  259. if (!_gwinDrawStart(gh)) return;
  260. gdispGDrawThickArc(gh->display, gh->x+x, gh->y+y, startradius, endradius, startangle, endangle, gh->color);
  261. _gwinDrawEnd(gh);
  262. }
  263. #endif
  264. #if GDISP_NEED_ARCSECTORS
  265. void gwinDrawArcSectors(GHandle gh, coord_t x, coord_t y, coord_t radius, uint8_t sectors) {
  266. if (!_gwinDrawStart(gh)) return;
  267. gdispGDrawArcSectors(gh->display, gh->x+x, gh->y+y, radius, sectors, gh->color);
  268. _gwinDrawEnd(gh);
  269. }
  270. void gwinFillArcSectors(GHandle gh, coord_t x, coord_t y, coord_t radius, uint8_t sectors) {
  271. if (!_gwinDrawStart(gh)) return;
  272. gdispGFillArcSectors(gh->display, gh->x+x, gh->y+y, radius, sectors, gh->color);
  273. _gwinDrawEnd(gh);
  274. }
  275. #endif
  276. #if GDISP_NEED_PIXELREAD
  277. color_t gwinGetPixelColor(GHandle gh, coord_t x, coord_t y) {
  278. if (!_gwinDrawStart(gh)) return (color_t)0;
  279. return gdispGGetPixelColor(gh->display, gh->x+x, gh->y+y);
  280. _gwinDrawEnd(gh);
  281. }
  282. #endif
  283. #if GDISP_NEED_TEXT
  284. void gwinDrawChar(GHandle gh, coord_t x, coord_t y, char c) {
  285. if (!gh->font || !_gwinDrawStart(gh)) return;
  286. gdispGDrawChar(gh->display, gh->x+x, gh->y+y, c, gh->font, gh->color);
  287. _gwinDrawEnd(gh);
  288. }
  289. void gwinFillChar(GHandle gh, coord_t x, coord_t y, char c) {
  290. if (!gh->font || !_gwinDrawStart(gh)) return;
  291. gdispGFillChar(gh->display, gh->x+x, gh->y+y, c, gh->font, gh->color, gh->bgcolor);
  292. _gwinDrawEnd(gh);
  293. }
  294. void gwinDrawString(GHandle gh, coord_t x, coord_t y, const char *str) {
  295. if (!gh->font || !_gwinDrawStart(gh)) return;
  296. gdispGDrawString(gh->display, gh->x+x, gh->y+y, str, gh->font, gh->color);
  297. _gwinDrawEnd(gh);
  298. }
  299. void gwinFillString(GHandle gh, coord_t x, coord_t y, const char *str) {
  300. if (!gh->font || !_gwinDrawStart(gh)) return;
  301. gdispGFillString(gh->display, gh->x+x, gh->y+y, str, gh->font, gh->color, gh->bgcolor);
  302. _gwinDrawEnd(gh);
  303. }
  304. void gwinDrawStringBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, justify_t justify) {
  305. if (!gh->font || !_gwinDrawStart(gh)) return;
  306. gdispGDrawStringBox(gh->display, gh->x+x, gh->y+y, cx, cy, str, gh->font, gh->color, justify);
  307. _gwinDrawEnd(gh);
  308. }
  309. void gwinFillStringBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, justify_t justify) {
  310. if (!gh->font || !_gwinDrawStart(gh)) return;
  311. gdispGFillStringBox(gh->display, gh->x+x, gh->y+y, cx, cy, str, gh->font, gh->color, gh->bgcolor, justify);
  312. _gwinDrawEnd(gh);
  313. }
  314. #endif
  315. #if GDISP_NEED_CONVEX_POLYGON
  316. void gwinDrawPoly(GHandle gh, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt) {
  317. if (!_gwinDrawStart(gh)) return;
  318. gdispGDrawPoly(gh->display, tx+gh->x, ty+gh->y, pntarray, cnt, gh->color);
  319. _gwinDrawEnd(gh);
  320. }
  321. void gwinFillConvexPoly(GHandle gh, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt) {
  322. if (!_gwinDrawStart(gh)) return;
  323. gdispGFillConvexPoly(gh->display, tx+gh->x, ty+gh->y, pntarray, cnt, gh->color);
  324. _gwinDrawEnd(gh);
  325. }
  326. void gwinDrawThickLine(GHandle gh, coord_t x0, coord_t y0, coord_t x1, coord_t y1, coord_t width, bool_t round) {
  327. if (!_gwinDrawStart(gh)) return;
  328. gdispGDrawThickLine(gh->display, gh->x+x0, gh->y+y0, gh->x+x1, gh->y+y1, gh->color, width, round);
  329. _gwinDrawEnd(gh);
  330. }
  331. #endif
  332. #if GDISP_NEED_IMAGE
  333. gdispImageError gwinDrawImage(GHandle gh, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy) {
  334. gdispImageError ret;
  335. if (!_gwinDrawStart(gh)) return GDISP_IMAGE_ERR_OK;
  336. ret = gdispGImageDraw(gh->display, img, gh->x+x, gh->y+y, cx, cy, sx, sy);
  337. _gwinDrawEnd(gh);
  338. return ret;
  339. }
  340. #endif
  341. #endif /* GFX_USE_GWIN */
  342. /** @} */