diff --git a/include/gwin/gwin.h b/include/gwin/gwin.h index b4be6a83..16ce9cf5 100644 --- a/include/gwin/gwin.h +++ b/include/gwin/gwin.h @@ -700,35 +700,6 @@ extern "C" { void gwinFillConvexPoly(GHandle gh, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt); #endif -/*------------------------------------------------- - * Image functions - *-------------------------------------------------*/ - - #if GDISP_NEED_IMAGE || defined(__DOXYGEN__) - /** - * @brief Draw the image - * @return GDISP_IMAGE_ERR_OK (0) on success or an error code. - * - * @param[in] gh The window handle - * @param[in] img The image structure - * @param[in] x,y The window location to draw the image - * @param[in] cx,cy The area on the screen to draw - * @param[in] sx,sy The image position to start drawing at - * - * @pre gdispImageOpen() must have returned successfully. - * - * @note If sx,sy + cx,cy is outside the image boundaries the area outside the image - * is simply not drawn. - * @note If @p gdispImageCache() has been called first for this frame, this routine will draw using a - * fast blit from the cached frame. If not, it reads the input and decodes it as it - * is drawing. This may be significantly slower than if the image has been cached (but - * uses a lot less RAM) - * - * @api - */ - gdispImageError gwinImageDraw(GHandle gh, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy); - #endif - #ifdef __cplusplus } #endif diff --git a/include/gwin/image.h b/include/gwin/image.h index 1626b15c..1a8ada3d 100644 --- a/include/gwin/image.h +++ b/include/gwin/image.h @@ -15,8 +15,11 @@ * @details GWIN allos it to create an image widget. The widget * takes no user input. * + * @pre GFX_USE_GDISP must be set to TRUE in your gfxconf.h * @pre GFX_USE_GWIN must be set to TRUE in your gfxconf.h + * @pre GDISP_NEED_IMAGE must be set to TRUE in your gfxconf.h * @pre GWIN_NEED_IMAGE must be set to TRUE in your gfxconf.h + * @pre At least one image type must be enabled in your gfxconf.h * * @{ */ @@ -29,14 +32,96 @@ // An image window typedef struct GImageWidget_t { GWindowObject g; + + gdispImage *image; + color_t bgColor; } GImageWidget; #ifdef __cplusplus extern "C" { #endif +/** + * @brief Create an image widget. + * @details A console widget allows to display a picture. + * @return NULL if there is no resultant drawing area, otherwise the widget handle. + * + * @param[in] widget The image widget structure to initialise. If this is NULL, the structure is dynamically allocated. + * @param[in] pInit The initialization parameters to use. + * + * @note The default background color gets set to the current default one. + * @note An image widget does not save the current drawing state. It is not automatically redrawn if the window + * is moved or its visibility state is changed. + * + * @api + */ GHandle gwinImageCreate(GImageWidget *widget, GWindowInit *pInit); -void gwinImageDisplay(GImageWidget *widget, gdispImage *image); + +/** + * @brief Sets the sets the io fields in the image structure to routines that support reading from an image stored + * in RAM or flash. + * @return TRUE if the IO open function succeeds + * + * @param[in] gh The widget (must be an image widget) + * @param[in[ memory A pointer to the image in RAM or Flash + * + * @api + */ +bool_t gwinImageOpenMemory(GHandle gh, const void* memory); + +#if defined(WIN32) || GFX_USE_OS_WIN32 || GFX_USE_OS_POSIX || defined(__DOXYGEN__) + /** + * @brief Sets the sets the io fields in the image structure to routines that support reading from an image stored + * in a simulators native file system. + * @return TRUE if the IO open function succeeds + * + * @param[in] gh The widget (must be an image widget) + * @param[in[ memory The filename to open + * + * @api + */ + bool_t gwinImageOpenFile(GHandle gh, const char* filename); +#endif + +#if GFX_USE_OS_CHIBIOS || defined(__DOXYGEN__) + /** + * @brief Sets the sets the io fields in the image structure to routines that support reading from an image stored + * on a BaseFileStream (eg. an SD-Card). + * @return TRUE if the IO open function succeeds + * + * @param[in] gh The widget (must be an image widget) + * @param[in[ memory A pointer to the (open) BaseFileStream object. + * + * @api + */ + bool_t gwinImageOpenStream(GHandle gh, void *streamPtr); +#endif + +/** + * @brief Cache an image. + * @details Decodes and caches the current frame into RAM. + * + * param[in] gh The widget (must be an image widget) + * + * @return GDISP_IMAGE_ERR_OK (0) on success or an error code. + * + * @api + */ +gdispImageError gwinImageCache(GHandle gh); + +/** + * @brief Set the background color of an image widget. + * @details Transparent images need a background color. If no background color has been set, the current default + * on is used. + * + * @param[in] gh The widget (must be an image widget) + * @param[in] bgColor The background color to be set + * + * @api + */ +void gwinImageSetBgColor(GHandle gh, color_t bgColor); + +void gwinImageDraw(GHandle gh); #ifdef __cplusplus } diff --git a/src/gwin/gwin.c b/src/gwin/gwin.c index c1122b3f..75f1b2d3 100644 --- a/src/gwin/gwin.c +++ b/src/gwin/gwin.c @@ -479,18 +479,6 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor } #endif -#if GDISP_NEED_IMAGE - gdispImageError gwinImageDraw(GHandle gh, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy) { - if (!((gh->flags & GWIN_FLG_VISIBLE))) - return GDISP_IMAGE_ERR_OK; - - #if GDISP_NEED_CLIP - gdispSetClip(gh->x, gh->y, gh->width, gh->height); - #endif - return gdispImageDraw(img, gh->x+x, gh->y+y, cx, cy, sx, sy); - } -#endif - #endif /* GFX_USE_GWIN */ /** @} */ diff --git a/src/gwin/image.c b/src/gwin/image.c index 35a0471d..64a27840 100644 --- a/src/gwin/image.c +++ b/src/gwin/image.c @@ -16,21 +16,17 @@ #include "gwin/class_gwin.h" +#define widget(gh) ((GImageWidget*)gh) + static void _destroy(GWindowObject *gh) { - (void)gh; - - return; -} - -static void _redraw(GWindowObject *gh) { - (void)gh; + if (gdispImageIsOpen(&widget(gh)->image)) + gdispImageClose(&widget(gh)->image); return; } static void _afterClear(GWindowObject *gh) { - ((GImageWidget *)gh)->cx = 0; - ((GImageWidget *)gh)->cy = 0; + (void)gh; return; } @@ -39,7 +35,7 @@ static const gwinVMT imageVMT = { "Image", // The class name sizeof(GImageWidget), // The object size _destroy, // The destroy routine - _redraw, // The redraw routine + 0, _afterClear, // The after-clear routine }; @@ -47,17 +43,53 @@ GHandle gwinImageCreate(GImageWidget *widget, GWindowInit *pInit) { if (!(widget = (GImageWidget *)_gwindowCreate(&widget->g, pInit, &imageVMT, 0))) return 0; - widget->cx = 0; - widget->cy = 0; + widget->image = gfxAlloc(sizeof(gdispImage)); + if (widget->image == NULL) + return 0; + + widget->g.x = pInit->x; + widget->g.y = pInit->y; + widget->g.width = pInit->width; + widget->g.height = pInit->height; + widget->bgColor = Black; gwinSetVisible((GHandle)widget, pInit->show); return (GHandle)widget; } -void gwinImageDisplay(GImageWidget *widget, gdispImage *image) { +bool_t gwinImageOpenMemory(GHandle gh, const void* memory) { + bool_t err; + err = gdispImageSetMemoryReader(widget(gh)->image, memory); + gdispImageOpen(widget(gh)->image); + + return err; } +#if defined(WIN32) || GFX_USE_OS_WIN32 || GFX_USE_OS_POSIX || defined(__DOXYGEN__) +bool_t gwinImageOpenFile(GHandle gh, const char* filename) { + return gdispImageSetFileReader(widget(gh)->image, filename); +} +#endif + +#if GFX_USE_OS_CHIBIOS || defined(__DOXYGEN__) +bool_t gwinImageOpenStream(GHandle gh, void *streamPtr) { + return gdispImageSetBaseFileStreamReader(widget(gh)->image, streamPtr); +} +#endif + +gdispImageError gwinImageCache(GHandle gh) { + return gdispImageCache(widget(gh)->image); +} + +void gwinImageSetBgColor(GHandle gh, color_t bgColor) { + widget(gh)->bgColor = bgColor; +} + +void gwinImageDraw(GHandle gh) { + gdispImageDraw(widget(gh)->image, widget(gh)->g.x, widget(gh)->g.y, widget(gh)->g.width, widget(gh)->g.height, 0, 0); +} + #endif // GFX_USE_GWIN && GWIN_NEED_IMAGE /** @} */