Label, Image and Window Manager changes
This commit is contained in:
parent
3f80e1f89d
commit
09a359813f
9 changed files with 275 additions and 147 deletions
|
@ -46,7 +46,12 @@
|
||||||
#warning "GWIN: Drawing can occur outside the defined windows as GDISP_NEED_CLIP is FALSE"
|
#warning "GWIN: Drawing can occur outside the defined windows as GDISP_NEED_CLIP is FALSE"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if GWIN_NEED_BUTTON || GWIN_NEED_SLIDER || GWIN_NEED_CHECKBOX
|
#if GWIN_NEED_IMAGE
|
||||||
|
#if !GDISP_NEED_IMAGE
|
||||||
|
#error "GWIN: GDISP_NEED_IMAGE is required when GWIN_NEED_IMAGE is TRUE."
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if GWIN_NEED_BUTTON || GWIN_NEED_SLIDER || GWIN_NEED_CHECKBOX || GWIN_NEED_LABEL
|
||||||
#if !GWIN_NEED_WIDGET
|
#if !GWIN_NEED_WIDGET
|
||||||
#if GFX_DISPLAY_RULE_WARNINGS
|
#if GFX_DISPLAY_RULE_WARNINGS
|
||||||
#warning "GWIN: GWIN_NEED_WIDGET is required when a Widget is used. It has been turned on for you."
|
#warning "GWIN: GWIN_NEED_WIDGET is required when a Widget is used. It has been turned on for you."
|
||||||
|
|
|
@ -111,6 +111,13 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
void gwinSetDefaultColor(color_t clr);
|
void gwinSetDefaultColor(color_t clr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the default foreground color for all new GWIN windows
|
||||||
|
*
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
color_t gwinGetDefaultColor(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the default background color for all new GWIN windows
|
* @brief Set the default background color for all new GWIN windows
|
||||||
*
|
*
|
||||||
|
@ -120,6 +127,13 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
void gwinSetDefaultBgColor(color_t bgclr);
|
void gwinSetDefaultBgColor(color_t bgclr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the default background color for all new GWIN windows
|
||||||
|
*
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
color_t gwinGetDefaultBgColor(void);
|
||||||
|
|
||||||
#if GDISP_NEED_TEXT || defined(__DOXYGEN__)
|
#if GDISP_NEED_TEXT || defined(__DOXYGEN__)
|
||||||
/**
|
/**
|
||||||
* @brief Set the default font for all new GWIN windows
|
* @brief Set the default font for all new GWIN windows
|
||||||
|
|
|
@ -32,9 +32,7 @@
|
||||||
// An image window
|
// An image window
|
||||||
typedef struct GImageWidget_t {
|
typedef struct GImageWidget_t {
|
||||||
GWindowObject g;
|
GWindowObject g;
|
||||||
|
gdispImage image;
|
||||||
gdispImage *image;
|
|
||||||
color_t bgColor;
|
|
||||||
} GImageWidget;
|
} GImageWidget;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -50,11 +48,10 @@ extern "C" {
|
||||||
* @param[in] pInit The initialization parameters to use.
|
* @param[in] pInit The initialization parameters to use.
|
||||||
*
|
*
|
||||||
* @note The default background color gets set to the current default one.
|
* @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
|
* @note An image window knows how to redraw.
|
||||||
* is moved or its visibility state is changed.
|
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
GHandle gwinImageCreate(GImageWidget *widget, GWindowInit *pInit);
|
GHandle gwinImageCreate(GImageWidget *widget, GWindowInit *pInit);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -98,7 +95,7 @@ bool_t gwinImageOpenMemory(GHandle gh, const void* memory);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Cache an image.
|
* @brief Cache the image.
|
||||||
* @details Decodes and caches the current frame into RAM.
|
* @details Decodes and caches the current frame into RAM.
|
||||||
*
|
*
|
||||||
* param[in] gh The widget (must be an image widget)
|
* param[in] gh The widget (must be an image widget)
|
||||||
|
@ -109,20 +106,6 @@ bool_t gwinImageOpenMemory(GHandle gh, const void* memory);
|
||||||
*/
|
*/
|
||||||
gdispImageError gwinImageCache(GHandle gh);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
173
src/gwin/gimage.c
Normal file
173
src/gwin/gimage.c
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
/*
|
||||||
|
* This file is subject to the terms of the GFX License. If a copy of
|
||||||
|
* the license was not distributed with this file, you can obtain one at:
|
||||||
|
*
|
||||||
|
* http://chibios-gfx.com/license.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file src/gwin/image.c
|
||||||
|
* @brief GWIN sub-system image code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gfx.h"
|
||||||
|
|
||||||
|
#if GFX_USE_GWIN && GWIN_NEED_IMAGE
|
||||||
|
|
||||||
|
#include "gwin/class_gwin.h"
|
||||||
|
|
||||||
|
#define widget(gh) ((GImageWidget*)gh)
|
||||||
|
|
||||||
|
static void _destroy(GWindowObject *gh) {
|
||||||
|
if (gdispImageIsOpen(&widget(gh)->image))
|
||||||
|
gdispImageClose(&widget(gh)->image);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _redraw(GHandle gh) {
|
||||||
|
coord_t x, y, w, h, dx, dy;
|
||||||
|
|
||||||
|
// The default display area
|
||||||
|
x = gh->x;
|
||||||
|
y = gh->y;
|
||||||
|
w = gh->width;
|
||||||
|
h = gh->height;
|
||||||
|
|
||||||
|
// If the image isn't open just clear the area
|
||||||
|
if (!gdispImageIsOpen(&widget(gh)->image)) {
|
||||||
|
gdispFillArea(x, y, w, h, gh->bgcolor);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Center horizontally if the area is larger than the image
|
||||||
|
if (widget(gh)->image.width < w) {
|
||||||
|
w = widget(gh)->image.width;
|
||||||
|
dx = (gh->width-w)/2;
|
||||||
|
x += dx;
|
||||||
|
if (dx)
|
||||||
|
gdispFillArea(gh->x, y, dx, h, gh->bgcolor);
|
||||||
|
gdispFillArea(x+w, y, gh->width-dx-w, h, gh->bgcolor);
|
||||||
|
dx = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Center image horizontally if the area is smaller than the image
|
||||||
|
else if (widget(gh)->image.width > w) {
|
||||||
|
dx = (widget(gh)->image.width - w)/2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Center vertically if the area is larger than the image
|
||||||
|
if (widget(gh)->image.height < h) {
|
||||||
|
h = widget(gh)->image.height;
|
||||||
|
dy = (gh->height-h)/2;
|
||||||
|
y += dy;
|
||||||
|
if (dy)
|
||||||
|
gdispFillArea(x, gh->y, w, dy, gh->bgcolor);
|
||||||
|
gdispFillArea(x, y+h, w, gh->height-dy-h, gh->bgcolor);
|
||||||
|
dy = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Center image vertically if the area is smaller than the image
|
||||||
|
else if (widget(gh)->image.height > h) {
|
||||||
|
dy = (widget(gh)->image.height - h)/2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the background color in case it has changed
|
||||||
|
gdispImageSetBgColor(&widget(gh)->image, gh->bgcolor);
|
||||||
|
|
||||||
|
// Display the image
|
||||||
|
gdispImageDraw(&widget(gh)->image, x, y, w, h, dx, dy);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const gwinVMT imageVMT = {
|
||||||
|
"Image", // The class name
|
||||||
|
sizeof(GImageWidget), // The object size
|
||||||
|
_destroy, // The destroy routine
|
||||||
|
_redraw, // The redraw routine
|
||||||
|
0, // The after-clear routine
|
||||||
|
};
|
||||||
|
|
||||||
|
GHandle gwinImageCreate(GImageWidget *gobj, GWindowInit *pInit) {
|
||||||
|
if (!(gobj = (GImageWidget *)_gwindowCreate(&gobj->g, pInit, &imageVMT, 0)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Ensure the gdispImageIsOpen() gives valid results
|
||||||
|
gobj->image.type = 0;
|
||||||
|
|
||||||
|
gwinSetVisible((GHandle)gobj, pInit->show);
|
||||||
|
|
||||||
|
return (GHandle)gobj;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t gwinImageOpenMemory(GHandle gh, const void* memory) {
|
||||||
|
if (gdispImageIsOpen(&widget(gh)->image))
|
||||||
|
gdispImageClose(&widget(gh)->image);
|
||||||
|
|
||||||
|
if (!gdispImageSetMemoryReader(&widget(gh)->image, memory))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (gdispImageOpen(&widget(gh)->image) != GDISP_IMAGE_ERR_OK)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if ((gh->flags & GWIN_FLG_VISIBLE)) {
|
||||||
|
// Setting the clip here shouldn't be necessary if the redraw doesn't overdraw
|
||||||
|
// but we put it in for safety anyway
|
||||||
|
#if GDISP_NEED_CLIP
|
||||||
|
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
|
||||||
|
#endif
|
||||||
|
_redraw(gh);
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(WIN32) || GFX_USE_OS_WIN32 || GFX_USE_OS_POSIX || defined(__DOXYGEN__)
|
||||||
|
bool_t gwinImageOpenFile(GHandle gh, const char* filename) {
|
||||||
|
if (gdispImageIsOpen(&widget(gh)->image))
|
||||||
|
gdispImageClose(&widget(gh)->image);
|
||||||
|
|
||||||
|
if (!gdispImageSetFileReader(&widget(gh)->image, filename))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (gdispImageOpen(&widget(gh)->image) != GDISP_IMAGE_ERR_OK)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if ((gh->flags & GWIN_FLG_VISIBLE)) {
|
||||||
|
// Setting the clip here shouldn't be necessary if the redraw doesn't overdraw
|
||||||
|
// but we put it in for safety anyway
|
||||||
|
#if GDISP_NEED_CLIP
|
||||||
|
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
|
||||||
|
#endif
|
||||||
|
_redraw(gh);
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if GFX_USE_OS_CHIBIOS || defined(__DOXYGEN__)
|
||||||
|
bool_t gwinImageOpenStream(GHandle gh, void *streamPtr) {
|
||||||
|
if (gdispImageIsOpen(&widget(gh)->image))
|
||||||
|
gdispImageClose(&widget(gh)->image);
|
||||||
|
|
||||||
|
if (!gdispImageSetBaseFileStreamReader(&widget(gh)->image, streamPtr))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (gdispImageOpen(&widget(gh)->image) != GDISP_IMAGE_ERR_OK)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if ((gh->flags & GWIN_FLG_VISIBLE)) {
|
||||||
|
// Setting the clip here shouldn't be necessary if the redraw doesn't overdraw
|
||||||
|
// but we put it in for safety anyway
|
||||||
|
#if GDISP_NEED_CLIP
|
||||||
|
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
|
||||||
|
#endif
|
||||||
|
_redraw(gh);
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
gdispImageError gwinImageCache(GHandle gh) {
|
||||||
|
return gdispImageCache(&widget(gh)->image);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // GFX_USE_GWIN && GWIN_NEED_IMAGE
|
||||||
|
/** @} */
|
|
@ -63,6 +63,16 @@ static color_t defaultBgColor = Black;
|
||||||
if (gh->height < MIN_WIN_HEIGHT) { gh->height = MIN_WIN_HEIGHT; }
|
if (gh->height < MIN_WIN_HEIGHT) { gh->height = MIN_WIN_HEIGHT; }
|
||||||
if (gh->x+gh->width > gdispGetWidth()) gh->width = gdispGetWidth() - gh->x;
|
if (gh->x+gh->width > gdispGetWidth()) gh->width = gdispGetWidth() - gh->x;
|
||||||
if (gh->y+gh->height > gdispGetHeight()) gh->height = gdispGetHeight() - gh->y;
|
if (gh->y+gh->height > gdispGetHeight()) gh->height = gdispGetHeight() - gh->y;
|
||||||
|
|
||||||
|
// Redraw the window
|
||||||
|
if ((gh->flags & GWIN_FLG_VISIBLE)) {
|
||||||
|
if (gh->vmt->Redraw) {
|
||||||
|
#if GDISP_NEED_CLIP
|
||||||
|
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
|
||||||
|
#endif
|
||||||
|
gh->vmt->Redraw(gh);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -135,10 +145,18 @@ void gwinSetDefaultColor(color_t clr) {
|
||||||
defaultFgColor = clr;
|
defaultFgColor = clr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
color_t gwinGetDefaultColor(void) {
|
||||||
|
return defaultFgColor;
|
||||||
|
}
|
||||||
|
|
||||||
void gwinSetDefaultBgColor(color_t bgclr) {
|
void gwinSetDefaultBgColor(color_t bgclr) {
|
||||||
defaultBgColor = bgclr;
|
defaultBgColor = bgclr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
color_t gwinGetDefaultBgColor(void) {
|
||||||
|
return defaultBgColor;
|
||||||
|
}
|
||||||
|
|
||||||
#if GDISP_NEED_TEXT
|
#if GDISP_NEED_TEXT
|
||||||
void gwinSetDefaultFont(font_t font) {
|
void gwinSetDefaultFont(font_t font) {
|
||||||
defaultFont = font;
|
defaultFont = font;
|
||||||
|
|
|
@ -6,6 +6,6 @@ GFXSRC += $(GFXLIB)/src/gwin/gwin.c \
|
||||||
$(GFXLIB)/src/gwin/button.c \
|
$(GFXLIB)/src/gwin/button.c \
|
||||||
$(GFXLIB)/src/gwin/slider.c \
|
$(GFXLIB)/src/gwin/slider.c \
|
||||||
$(GFXLIB)/src/gwin/checkbox.c \
|
$(GFXLIB)/src/gwin/checkbox.c \
|
||||||
$(GFXLIB)/src/gwin/image.c \
|
$(GFXLIB)/src/gwin/gimage.c \
|
||||||
$(GFXLIB)/src/gwin/label.c \
|
$(GFXLIB)/src/gwin/label.c \
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
static void WM_Init(void);
|
static void WM_Init(void);
|
||||||
static void WM_DeInit(void);
|
static void WM_DeInit(void);
|
||||||
static bool_t WM_Add(GHandle gh, GWindowInit *pInit);
|
static bool_t WM_Add(GHandle gh, const GWindowInit *pInit);
|
||||||
static void WM_Delete(GHandle gh);
|
static void WM_Delete(GHandle gh);
|
||||||
static void WM_Visible(GHandle gh);
|
static void WM_Visible(GHandle gh);
|
||||||
static void WM_Redim(GHandle gh, coord_t x, coord_t y, coord_t w, coord_t h);
|
static void WM_Redim(GHandle gh, coord_t x, coord_t y, coord_t w, coord_t h);
|
||||||
|
@ -65,23 +65,25 @@ static void WM_DeInit(void) {
|
||||||
// A full window manager would remove any borders etc
|
// A full window manager would remove any borders etc
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool_t WM_Add(GHandle gh, GWindowInit *pInit) {
|
static bool_t WM_Add(GHandle gh, const GWindowInit *pInit) {
|
||||||
|
// Note the window will not be marked as visible yet
|
||||||
|
|
||||||
// Put it on the queue
|
// Put it on the queue
|
||||||
gfxQueueASyncPut(&_GWINList, &gh->wmq);
|
gfxQueueASyncPut(&_GWINList, &gh->wmq);
|
||||||
|
|
||||||
// Make sure the size is valid
|
// Make sure the size is valid
|
||||||
WM_Redim(gh, pInit->x, pInit->y, pInit->width, pInit->height);
|
WM_Redim(gh, pInit->x, pInit->y, pInit->width, pInit->height);
|
||||||
|
|
||||||
// Display it if it is visible
|
|
||||||
WM_Visible(gh);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WM_Delete(GHandle gh) {
|
static void WM_Delete(GHandle gh) {
|
||||||
// A real window manager would make the window invisible
|
// Make the window invisible and clear the area underneath
|
||||||
// (and then clear the area underneath)
|
if ((gh->flags & GWIN_FLG_VISIBLE)) {
|
||||||
|
gh->flags &= ~GWIN_FLG_VISIBLE;
|
||||||
|
gdispFillArea(gh->x, gh->y, gh->width, gh->height, gwinGetDefaultBgColor());
|
||||||
|
}
|
||||||
|
|
||||||
// Just remove it from the queue
|
// Remove it from the queue
|
||||||
gfxQueueASyncRemove(&_GWINList, &gh->wmq);
|
gfxQueueASyncRemove(&_GWINList, &gh->wmq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,10 +99,8 @@ static void WM_Visible(GHandle gh) {
|
||||||
// A real window manager would also redraw the borders
|
// A real window manager would also redraw the borders
|
||||||
}
|
}
|
||||||
|
|
||||||
// else
|
else
|
||||||
// A real window manager would make the window invisible
|
gdispFillArea(gh->x, gh->y, gh->width, gh->height, gwinGetDefaultBgColor());
|
||||||
// (and then clear the area underneath)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WM_Redim(GHandle gh, coord_t x, coord_t y, coord_t w, coord_t h) {
|
static void WM_Redim(GHandle gh, coord_t x, coord_t y, coord_t w, coord_t h) {
|
||||||
|
@ -114,8 +114,28 @@ static void WM_Redim(GHandle gh, coord_t x, coord_t y, coord_t w, coord_t h) {
|
||||||
if (h < MIN_WIN_HEIGHT) { h = MIN_WIN_HEIGHT; }
|
if (h < MIN_WIN_HEIGHT) { h = MIN_WIN_HEIGHT; }
|
||||||
if (x+w > gdispGetWidth()) w = gdispGetWidth() - x;
|
if (x+w > gdispGetWidth()) w = gdispGetWidth() - x;
|
||||||
if (y+h > gdispGetHeight()) h = gdispGetHeight() - y;
|
if (y+h > gdispGetHeight()) h = gdispGetHeight() - y;
|
||||||
|
|
||||||
|
// If there has been no resize just exit
|
||||||
|
if (gh->x == x && gh->y == y && gh->width == w && gh->height == h)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Clear the old area
|
||||||
|
if ((gh->flags & GWIN_FLG_VISIBLE))
|
||||||
|
gdispFillArea(gh->x, gh->y, gh->width, gh->height, gwinGetDefaultBgColor());
|
||||||
|
|
||||||
|
// Set the new size
|
||||||
gh->x = x; gh->y = y;
|
gh->x = x; gh->y = y;
|
||||||
gh->width = w; gh->height = h;
|
gh->width = w; gh->height = h;
|
||||||
|
|
||||||
|
// Redraw the window (if possible)
|
||||||
|
if ((gh->flags & GWIN_FLG_VISIBLE)) {
|
||||||
|
if (gh->vmt->Redraw) {
|
||||||
|
#if GDISP_NEED_CLIP
|
||||||
|
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
|
||||||
|
#endif
|
||||||
|
gh->vmt->Redraw(gh);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WM_MinMax(GHandle gh, GWindowMinMax minmax) {
|
static void WM_MinMax(GHandle gh, GWindowMinMax minmax) {
|
||||||
|
|
|
@ -1,95 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is subject to the terms of the GFX License. If a copy of
|
|
||||||
* the license was not distributed with this file, you can obtain one at:
|
|
||||||
*
|
|
||||||
* http://chibios-gfx.com/license.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file src/gwin/image.c
|
|
||||||
* @brief GWIN sub-system image code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "gfx.h"
|
|
||||||
|
|
||||||
#if GFX_USE_GWIN && GWIN_NEED_IMAGE
|
|
||||||
|
|
||||||
#include "gwin/class_gwin.h"
|
|
||||||
|
|
||||||
#define widget(gh) ((GImageWidget*)gh)
|
|
||||||
|
|
||||||
static void _destroy(GWindowObject *gh) {
|
|
||||||
if (gdispImageIsOpen(&widget(gh)->image))
|
|
||||||
gdispImageClose(&widget(gh)->image);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _afterClear(GWindowObject *gh) {
|
|
||||||
(void)gh;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const gwinVMT imageVMT = {
|
|
||||||
"Image", // The class name
|
|
||||||
sizeof(GImageWidget), // The object size
|
|
||||||
_destroy, // The destroy routine
|
|
||||||
0,
|
|
||||||
_afterClear, // The after-clear routine
|
|
||||||
};
|
|
||||||
|
|
||||||
GHandle gwinImageCreate(GImageWidget *widget, GWindowInit *pInit) {
|
|
||||||
if (!(widget = (GImageWidget *)_gwindowCreate(&widget->g, pInit, &imageVMT, 0)))
|
|
||||||
return 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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)->image->width, widget(gh)->image->height, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // GFX_USE_GWIN && GWIN_NEED_IMAGE
|
|
||||||
/** @} */
|
|
||||||
|
|
|
@ -21,26 +21,36 @@
|
||||||
|
|
||||||
#include "gwin/class_gwin.h"
|
#include "gwin/class_gwin.h"
|
||||||
|
|
||||||
#define widget(gh) ((GLabelWidget*)gh)
|
|
||||||
#define GLABEL_FLG_WAUTO (GWIN_FIRST_CONTROL_FLAG<<0)
|
#define GLABEL_FLG_WAUTO (GWIN_FIRST_CONTROL_FLAG<<0)
|
||||||
#define GLABEL_FLG_HAUTO (GWIN_FIRST_CONTROL_FLAG<<1)
|
#define GLABEL_FLG_HAUTO (GWIN_FIRST_CONTROL_FLAG<<1)
|
||||||
|
|
||||||
static void gwinLabelDefaultDraw(GHandle gh) {
|
// Simple: single line with no wrapping
|
||||||
// if( check if auto flag is set )
|
static coord_t getwidth(const char *txt, font_t font, coord_t maxwidth) {
|
||||||
// if( call current size != font size )
|
(void) maxwidth;
|
||||||
// gwinResize();
|
return gdispGetStringWidth(txt, font)+2; // Allow one pixel of padding on each side
|
||||||
|
}
|
||||||
|
|
||||||
gdispFillString( widget(gh)->w.g.x,
|
// Simple: single line with no wrapping
|
||||||
widget(gh)->w.g.y,
|
static coord_t getheight(const char *txt, font_t font, coord_t maxwidth) {
|
||||||
widget(gh)->w.txt,
|
(void) txt;
|
||||||
widget(gh)->w.g.font,
|
(void) maxwidth;
|
||||||
widget(gh)->w.g.color,
|
|
||||||
widget(gh)->w.g.bgcolor
|
|
||||||
);
|
|
||||||
|
|
||||||
gdispFillArea( widget(gh)->w.g.x, widget(gh)->w.g.y, widget(gh)->w.g.width, widget(gh)->w.g.height, Green);
|
return gdispGetFontMetric(font, fontHeight);
|
||||||
|
}
|
||||||
|
|
||||||
printf("Text: %s\r\n", widget(gh)->w.txt);
|
static void gwinLabelDefaultDraw(GWidgetObject *gw, void *param) {
|
||||||
|
(void) param;
|
||||||
|
coord_t w, h;
|
||||||
|
|
||||||
|
w = (gw->g.flags & GLABEL_FLG_WAUTO) ? getwidth(gw->txt, gw->g.font, gdispGetWidth() - gw->g.x) : gw->g.width;
|
||||||
|
h = (gw->g.flags & GLABEL_FLG_HAUTO) ? getheight(gw->txt, gw->g.font, gdispGetWidth() - gw->g.x) : gw->g.height;
|
||||||
|
|
||||||
|
if (gw->g.width != w || gw->g.height != h) {
|
||||||
|
gwinResize(&gw->g, w, h);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gdispFillStringBox(gw->g.x, gw->g.y, gw->g.width, gw->g.height, gw->txt, gw->g.font, gw->g.color, gw->g.bgcolor, justifyLeft);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const gwidgetVMT labelVMT = {
|
static const gwidgetVMT labelVMT = {
|
||||||
|
@ -78,21 +88,21 @@ GHandle gwinLabelCreate(GLabelWidget *widget, GWidgetInit *pInit) {
|
||||||
// auto assign width
|
// auto assign width
|
||||||
if (pInit->g.width <= 0) {
|
if (pInit->g.width <= 0) {
|
||||||
flags |= GLABEL_FLG_WAUTO;
|
flags |= GLABEL_FLG_WAUTO;
|
||||||
pInit->g.width = gdispGetStringWidth(pInit->text, gwinGetDefaultFont());
|
pInit->g.width = getwidth(pInit->text, gwinGetDefaultFont(), gdispGetWidth() - pInit->g.x);
|
||||||
}
|
}
|
||||||
|
|
||||||
// auto assign height
|
// auto assign height
|
||||||
if (pInit->g.height <= 0) {
|
if (pInit->g.height <= 0) {
|
||||||
flags |= GLABEL_FLG_HAUTO;
|
flags |= GLABEL_FLG_HAUTO;
|
||||||
pInit->g.height = gdispGetFontMetric(gwinGetDefaultFont(), fontHeight);
|
pInit->g.height = getheight(pInit->text, gwinGetDefaultFont(), gdispGetWidth() - pInit->g.x);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(widget = (GLabelWidget *)_gwidgetCreate(&widget->w, pInit, &labelVMT)))
|
if (!(widget = (GLabelWidget *)_gwidgetCreate(&widget->w, pInit, &labelVMT)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
gwinLabelDefaultDraw((GHandle)widget);
|
|
||||||
widget->w.g.flags |= flags;
|
widget->w.g.flags |= flags;
|
||||||
|
|
||||||
|
gwinSetVisible(&widget->w.g, pInit->g.show);
|
||||||
return (GHandle)widget;
|
return (GHandle)widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue