Significant changes to the window redrawing methodology.
Move and Resize should probably work for containers now Still to be tested - nested containers, progressbar timers while redrawing its container, move/resize on containers.
This commit is contained in:
parent
7afe4e78b7
commit
34e23320b4
14 changed files with 834 additions and 638 deletions
|
@ -50,14 +50,14 @@ static void SendButtonEvent(GWidgetObject *gw) {
|
||||||
static void MouseDown(GWidgetObject *gw, coord_t x, coord_t y) {
|
static void MouseDown(GWidgetObject *gw, coord_t x, coord_t y) {
|
||||||
(void) x; (void) y;
|
(void) x; (void) y;
|
||||||
gw->g.flags |= GBUTTON_FLG_PRESSED;
|
gw->g.flags |= GBUTTON_FLG_PRESSED;
|
||||||
_gwidgetUpdate((GHandle)gw);
|
_gwinUpdate((GHandle)gw);
|
||||||
}
|
}
|
||||||
|
|
||||||
// A mouse up has occurred (it may or may not be over the button)
|
// A mouse up has occurred (it may or may not be over the button)
|
||||||
static void MouseUp(GWidgetObject *gw, coord_t x, coord_t y) {
|
static void MouseUp(GWidgetObject *gw, coord_t x, coord_t y) {
|
||||||
(void) x; (void) y;
|
(void) x; (void) y;
|
||||||
gw->g.flags &= ~GBUTTON_FLG_PRESSED;
|
gw->g.flags &= ~GBUTTON_FLG_PRESSED;
|
||||||
_gwidgetUpdate((GHandle)gw);
|
_gwinUpdate((GHandle)gw);
|
||||||
|
|
||||||
#if !GWIN_BUTTON_LAZY_RELEASE
|
#if !GWIN_BUTTON_LAZY_RELEASE
|
||||||
// If the mouse up was not over the button then cancel the event
|
// If the mouse up was not over the button then cancel the event
|
||||||
|
@ -74,14 +74,14 @@ static void SendButtonEvent(GWidgetObject *gw) {
|
||||||
static void ToggleOff(GWidgetObject *gw, uint16_t role) {
|
static void ToggleOff(GWidgetObject *gw, uint16_t role) {
|
||||||
(void) role;
|
(void) role;
|
||||||
gw->g.flags &= ~GBUTTON_FLG_PRESSED;
|
gw->g.flags &= ~GBUTTON_FLG_PRESSED;
|
||||||
_gwidgetUpdate((GHandle)gw);
|
_gwinUpdate((GHandle)gw);
|
||||||
}
|
}
|
||||||
|
|
||||||
// A toggle on has occurred
|
// A toggle on has occurred
|
||||||
static void ToggleOn(GWidgetObject *gw, uint16_t role) {
|
static void ToggleOn(GWidgetObject *gw, uint16_t role) {
|
||||||
(void) role;
|
(void) role;
|
||||||
gw->g.flags |= GBUTTON_FLG_PRESSED;
|
gw->g.flags |= GBUTTON_FLG_PRESSED;
|
||||||
_gwidgetUpdate((GHandle)gw);
|
_gwinUpdate((GHandle)gw);
|
||||||
// Trigger the event on button down (different than for mouse/touch)
|
// Trigger the event on button down (different than for mouse/touch)
|
||||||
SendButtonEvent(gw);
|
SendButtonEvent(gw);
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ static void SendCheckboxEvent(GWidgetObject *gw) {
|
||||||
static void MouseDown(GWidgetObject *gw, coord_t x, coord_t y) {
|
static void MouseDown(GWidgetObject *gw, coord_t x, coord_t y) {
|
||||||
(void) x; (void) y;
|
(void) x; (void) y;
|
||||||
gw->g.flags ^= GCHECKBOX_FLG_CHECKED;
|
gw->g.flags ^= GCHECKBOX_FLG_CHECKED;
|
||||||
_gwidgetUpdate((GHandle)gw);
|
_gwinUpdate((GHandle)gw);
|
||||||
SendCheckboxEvent(gw);
|
SendCheckboxEvent(gw);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -52,7 +52,7 @@ static void SendCheckboxEvent(GWidgetObject *gw) {
|
||||||
static void ToggleOn(GWidgetObject *gw, uint16_t role) {
|
static void ToggleOn(GWidgetObject *gw, uint16_t role) {
|
||||||
(void) role;
|
(void) role;
|
||||||
gw->g.flags ^= GCHECKBOX_FLG_CHECKED;
|
gw->g.flags ^= GCHECKBOX_FLG_CHECKED;
|
||||||
_gwidgetUpdate((GHandle)gw);
|
_gwinUpdate((GHandle)gw);
|
||||||
SendCheckboxEvent(gw);
|
SendCheckboxEvent(gw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ void gwinCheckboxCheck(GHandle gh, bool_t isChecked) {
|
||||||
if (!(gh->flags & GCHECKBOX_FLG_CHECKED)) return;
|
if (!(gh->flags & GCHECKBOX_FLG_CHECKED)) return;
|
||||||
gh->flags &= ~GCHECKBOX_FLG_CHECKED;
|
gh->flags &= ~GCHECKBOX_FLG_CHECKED;
|
||||||
}
|
}
|
||||||
_gwidgetUpdate(gh);
|
_gwinUpdate(gh);
|
||||||
SendCheckboxEvent((GWidgetObject *)gh);
|
SendCheckboxEvent((GWidgetObject *)gh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,12 +34,14 @@
|
||||||
#define GWIN_FLG_SYSENABLED 0x00000800 // @< The window is enabled after parents are tested
|
#define GWIN_FLG_SYSENABLED 0x00000800 // @< The window is enabled after parents are tested
|
||||||
#define GWIN_FLG_DYNAMIC 0x00001000 // @< The GWIN structure is allocated
|
#define GWIN_FLG_DYNAMIC 0x00001000 // @< The GWIN structure is allocated
|
||||||
#define GWIN_FLG_ALLOCTXT 0x00002000 // @< The text/label is allocated
|
#define GWIN_FLG_ALLOCTXT 0x00002000 // @< The text/label is allocated
|
||||||
#define GWIN_FLG_MOUSECAPTURE 0x00004000 // @< The window has captured the mouse
|
#define GWIN_FLG_NEEDREDRAW 0x00004000 // @< Redraw is needed but has been delayed
|
||||||
|
#define GWIN_FLG_BGREDRAW 0x00008000 // @< On redraw, if not visible redraw the revealed under-side
|
||||||
#define GWIN_FLG_SUPERMASK 0x000F0000 // @< The bit mask to leave just the window superclass type
|
#define GWIN_FLG_SUPERMASK 0x000F0000 // @< The bit mask to leave just the window superclass type
|
||||||
#define GWIN_FLG_WIDGET 0x00010000 // @< This is a widget
|
#define GWIN_FLG_WIDGET 0x00010000 // @< This is a widget
|
||||||
#define GWIN_FLG_CONTAINER 0x00020000 // @< This is a container
|
#define GWIN_FLG_CONTAINER 0x00020000 // @< This is a container
|
||||||
#define GWIN_FLG_MINIMIZED 0x00100000 // @< The window is minimized
|
#define GWIN_FLG_MINIMIZED 0x00100000 // @< The window is minimized
|
||||||
#define GWIN_FLG_MAXIMIZED 0x00200000 // @< The window is maximized
|
#define GWIN_FLG_MAXIMIZED 0x00200000 // @< The window is maximized
|
||||||
|
#define GWIN_FLG_MOUSECAPTURE 0x00400000 // @< The window has captured the mouse
|
||||||
#define GWIN_FIRST_WM_FLAG 0x01000000 // @< 8 bits free for the window manager to use
|
#define GWIN_FIRST_WM_FLAG 0x01000000 // @< 8 bits free for the window manager to use
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
@ -131,17 +133,6 @@ typedef struct gwinVMT {
|
||||||
/** @} */
|
/** @} */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// These flags are needed whether or not we are running a window manager.
|
|
||||||
/**
|
|
||||||
* @brief Flags for redrawing after a visibility change
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
#define GWIN_WMFLG_PRESERVE 0x0001 // @< Preserve whatever existing contents possible if a window can't redraw
|
|
||||||
#define GWIN_WMFLG_NOBGCLEAR 0x0002 // @< Don't clear the area if the window is not visible
|
|
||||||
#define GWIN_WMFLG_KEEPCLIP 0x0004 // @< Don't modify the preset clipping area
|
|
||||||
#define GWIN_WMFLG_NOZORDER 0x0008 // @< Don't redraw higher z-order windows that overlap
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
#if GWIN_NEED_WINDOWMANAGER || defined(__DOXYGEN__)
|
#if GWIN_NEED_WINDOWMANAGER || defined(__DOXYGEN__)
|
||||||
// @note There is only ever one instance of each GWindowManager type
|
// @note There is only ever one instance of each GWindowManager type
|
||||||
typedef struct GWindowManager {
|
typedef struct GWindowManager {
|
||||||
|
@ -157,7 +148,7 @@ typedef struct gwinVMT {
|
||||||
void (*DeInit) (void); // @< The window manager has just been removed as the current window manager
|
void (*DeInit) (void); // @< The window manager has just been removed as the current window manager
|
||||||
bool_t (*Add) (GHandle gh, const GWindowInit *pInit); // @< A window has been added
|
bool_t (*Add) (GHandle gh, const GWindowInit *pInit); // @< A window has been added
|
||||||
void (*Delete) (GHandle gh); // @< A window has been deleted
|
void (*Delete) (GHandle gh); // @< A window has been deleted
|
||||||
void (*Redraw) (GHandle gh, int visflags); // @< A window needs to be redraw (or undrawn)
|
void (*Redraw) (GHandle gh); // @< A window needs to be redraw (or undrawn)
|
||||||
void (*Size) (GHandle gh, coord_t w, coord_t h); // @< A window wants to be resized
|
void (*Size) (GHandle gh, coord_t w, coord_t h); // @< A window wants to be resized
|
||||||
void (*Move) (GHandle gh, coord_t x, coord_t y); // @< A window wants to be moved
|
void (*Move) (GHandle gh, coord_t x, coord_t y); // @< A window wants to be moved
|
||||||
void (*Raise) (GHandle gh); // @< A window wants to be on top
|
void (*Raise) (GHandle gh); // @< A window wants to be on top
|
||||||
|
@ -190,6 +181,62 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
GHandle _gwindowCreate(GDisplay *g, GWindowObject *pgw, const GWindowInit *pInit, const gwinVMT *vmt, uint32_t flags);
|
GHandle _gwindowCreate(GDisplay *g, GWindowObject *pgw, const GWindowInit *pInit, const gwinVMT *vmt, uint32_t flags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Redraw the window after a status change.
|
||||||
|
*
|
||||||
|
* @param[in] gh The widget to redraw
|
||||||
|
*
|
||||||
|
* @note Mark a window for redraw.
|
||||||
|
* @note The window will get redrawn at some later time.
|
||||||
|
* @note This call is designed to be fast and non-blocking
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void _gwinUpdate(GHandle gh);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Flush any pending redraws in the system.
|
||||||
|
*
|
||||||
|
* @param[in] doWait Do we wait for the lock?
|
||||||
|
*
|
||||||
|
* @note This call will attempt to flush any pending redraws
|
||||||
|
* in the system. The doWait parameter tells this call
|
||||||
|
* how to handle someone already holding the drawing lock.
|
||||||
|
* If doWait is TRUE it waits to obtain the lock. If FALSE
|
||||||
|
* and the drawing lock is free then the redraw is done
|
||||||
|
* immediately. If the drawing lock was taken it will postpone the flush
|
||||||
|
* on the basis that someone else will do it for us later.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void _gwinFlushRedraws(bool_t doWait);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Obtain a drawing session
|
||||||
|
* @return TRUE if the drawing session was obtained, FALSE if the window is not visible
|
||||||
|
*
|
||||||
|
* @param[in] gh The window
|
||||||
|
*
|
||||||
|
* @note This function blocks until a drawing session is available if the window is visible
|
||||||
|
*/
|
||||||
|
bool_t _gwinDrawStart(GHandle gh);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Release a drawing session
|
||||||
|
*
|
||||||
|
* @param[in] gh The window
|
||||||
|
*/
|
||||||
|
void _gwinDrawEnd(GHandle gh);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Add a window to the window manager and set its position and size
|
||||||
|
* @return TRUE if successful
|
||||||
|
*
|
||||||
|
* @param[in] gh The window
|
||||||
|
* @param[in] pInit The window init structure
|
||||||
|
*/
|
||||||
|
bool_t _gwinWMAdd(GHandle gh, const GWindowInit *pInit);
|
||||||
|
|
||||||
#if GWIN_NEED_WIDGET || defined(__DOXYGEN__)
|
#if GWIN_NEED_WIDGET || defined(__DOXYGEN__)
|
||||||
/**
|
/**
|
||||||
* @brief Initialise (and allocate if necessary) the base Widget object
|
* @brief Initialise (and allocate if necessary) the base Widget object
|
||||||
|
@ -220,24 +267,12 @@ GHandle _gwindowCreate(GDisplay *g, GWindowObject *pgw, const GWindowInit *pInit
|
||||||
* @param[in] gh The widget to redraw
|
* @param[in] gh The widget to redraw
|
||||||
*
|
*
|
||||||
* @note Do not use this routine to update a widget after a status change.
|
* @note Do not use this routine to update a widget after a status change.
|
||||||
* Use @p _gwidgetUpdate() instead. The difference is that this routine
|
* Use @p _gwinUpdate() instead. This routine should only be used in the
|
||||||
* does not set the clip region. This routine should only be used in the
|
|
||||||
* VMT.
|
* VMT.
|
||||||
*
|
*
|
||||||
* @notapi
|
* @notapi
|
||||||
*/
|
*/
|
||||||
void _gwidgetRedraw(GHandle gh);
|
void _gwidgetRedraw(GHandle gh);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Redraw the Widget object after a widget status change.
|
|
||||||
*
|
|
||||||
* @param[in] gh The widget to redraw
|
|
||||||
*
|
|
||||||
* @note Use this routine to update a widget after a status change.
|
|
||||||
*
|
|
||||||
* @notapi
|
|
||||||
*/
|
|
||||||
void _gwidgetUpdate(GHandle gh);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if GWIN_NEED_CONTAINERS || defined(__DOXYGEN__)
|
#if GWIN_NEED_CONTAINERS || defined(__DOXYGEN__)
|
||||||
|
@ -270,38 +305,12 @@ GHandle _gwindowCreate(GDisplay *g, GWindowObject *pgw, const GWindowInit *pInit
|
||||||
* @param[in] gh The container to redraw
|
* @param[in] gh The container to redraw
|
||||||
*
|
*
|
||||||
* @note Do not use this routine to update a container after a status change.
|
* @note Do not use this routine to update a container after a status change.
|
||||||
* Use @p _gcontainerUpdate() instead. The difference is that this routine
|
* Use @p _gwinUpdate() instead. This routine should only be used in the
|
||||||
* does not set the clip region. This routine should only be used in the
|
|
||||||
* VMT.
|
* VMT.
|
||||||
*
|
*
|
||||||
* @notapi
|
* @notapi
|
||||||
*/
|
*/
|
||||||
void _gcontainerRedraw(GHandle gh);
|
#define _gcontainerRedraw _gwidgetRedraw
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Redraw the Container object after a container status change.
|
|
||||||
*
|
|
||||||
* @param[in] gh The container to redraw
|
|
||||||
*
|
|
||||||
* @note Use this routine to update a container after a status change.
|
|
||||||
*
|
|
||||||
* @notapi
|
|
||||||
*/
|
|
||||||
void _gcontainerUpdate(GHandle gh);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Apply the specified action to a window and its children.
|
|
||||||
* @note The action is applied to the parent first and then its children.
|
|
||||||
* @note This routine is built to keep stack usage from recursing to a minimum.
|
|
||||||
*
|
|
||||||
* @param[in] gh The window to recurse through
|
|
||||||
* @param[in] fn The function to apply. If it returns TRUE any children it has should also have the function applied
|
|
||||||
*
|
|
||||||
* @notapi
|
|
||||||
*/
|
|
||||||
void _gwinRecurse(GHandle gh, bool_t (*fn)(GHandle gh));
|
|
||||||
#else
|
|
||||||
#define _gwinRecurse(gh, fn) fn(gh)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -399,6 +399,18 @@ GHandle gwinGConsoleCreate(GDisplay *g, GConsoleObject *gc, const GWindowInit *p
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We can get into gwinPutChar() 2 ways -
|
||||||
|
* 1. when the user calls us, and
|
||||||
|
* 2. when the redraw uses us to redraw the display.
|
||||||
|
* When called by option 2 we MUST not try to obtain a draw session
|
||||||
|
* as we already have one.
|
||||||
|
*
|
||||||
|
* We use these macro's below to make sure we do that safely
|
||||||
|
*/
|
||||||
|
#define DrawStart(gh) ((gh->flags & GCONSOLE_FLG_NOSTORE) || _gwinDrawStart(gh))
|
||||||
|
#define DrawEnd(gh) { if (!(gh->flags & GCONSOLE_FLG_NOSTORE)) _gwinDrawEnd(gh); }
|
||||||
|
|
||||||
void gwinPutChar(GHandle gh, char c) {
|
void gwinPutChar(GHandle gh, char c) {
|
||||||
#define gcw ((GConsoleObject *)gh)
|
#define gcw ((GConsoleObject *)gh)
|
||||||
uint8_t width, fy;
|
uint8_t width, fy;
|
||||||
|
@ -406,16 +418,8 @@ void gwinPutChar(GHandle gh, char c) {
|
||||||
if (gh->vmt != &consoleVMT || !gh->font)
|
if (gh->vmt != &consoleVMT || !gh->font)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// only render new character if the console is visible
|
|
||||||
if (!gwinGetVisible(gh))
|
|
||||||
return;
|
|
||||||
|
|
||||||
fy = gdispGetFontMetric(gh->font, fontHeight);
|
fy = gdispGetFontMetric(gh->font, fontHeight);
|
||||||
|
|
||||||
#if GDISP_NEED_CLIP
|
|
||||||
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if GWIN_CONSOLE_ESCSEQ
|
#if GWIN_CONSOLE_ESCSEQ
|
||||||
/**
|
/**
|
||||||
* Handle escape sequences
|
* Handle escape sequences
|
||||||
|
@ -444,7 +448,10 @@ void gwinPutChar(GHandle gh, char c) {
|
||||||
case 'J':
|
case 'J':
|
||||||
// Clear the console and reset the cursor
|
// Clear the console and reset the cursor
|
||||||
clearBuffer(gcw);
|
clearBuffer(gcw);
|
||||||
|
if (DrawStart(gh)) {
|
||||||
gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, gh->bgcolor);
|
gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, gh->bgcolor);
|
||||||
|
DrawEnd(gh);
|
||||||
|
}
|
||||||
gcw->cx = 0;
|
gcw->cx = 0;
|
||||||
gcw->cy = 0;
|
gcw->cy = 0;
|
||||||
gcw->startattr = gcw->currattr;
|
gcw->startattr = gcw->currattr;
|
||||||
|
@ -469,8 +476,10 @@ void gwinPutChar(GHandle gh, char c) {
|
||||||
case '\n':
|
case '\n':
|
||||||
// clear to the end of the line
|
// clear to the end of the line
|
||||||
#if GWIN_CONSOLE_USE_CLEAR_LINES
|
#if GWIN_CONSOLE_USE_CLEAR_LINES
|
||||||
if (gcw->cx == 0 && gcw->cy+fy < gh->height)
|
if (gcw->cx == 0 && gcw->cy+fy < gh->height && DrawStart(gh)) {
|
||||||
gdispGFillArea(gh->display, gh->x, gh->y + gcw->cy, gh->width, fy, gh->bgcolor);
|
gdispGFillArea(gh->display, gh->x, gh->y + gcw->cy, gh->width, fy, gh->bgcolor);
|
||||||
|
DrawEnd(gh);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
// update the cursor
|
// update the cursor
|
||||||
gcw->cx = 0;
|
gcw->cx = 0;
|
||||||
|
@ -513,14 +522,20 @@ void gwinPutChar(GHandle gh, char c) {
|
||||||
if (gcw->buffer) {
|
if (gcw->buffer) {
|
||||||
// Scroll the buffer and then redraw using the buffer
|
// Scroll the buffer and then redraw using the buffer
|
||||||
scrollBuffer(gcw);
|
scrollBuffer(gcw);
|
||||||
|
if (DrawStart(gh)) {
|
||||||
HistoryRedraw(gh);
|
HistoryRedraw(gh);
|
||||||
|
DrawEnd(gh);
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
#if GDISP_NEED_SCROLL
|
#if GDISP_NEED_SCROLL
|
||||||
{
|
{
|
||||||
// Scroll the console using hardware
|
// Scroll the console using hardware
|
||||||
scrollBuffer(gcw);
|
scrollBuffer(gcw);
|
||||||
|
if (DrawStart(gh)) {
|
||||||
gdispGVerticalScroll(gh->display, gh->x, gh->y, gh->width, gh->height, fy, gh->bgcolor);
|
gdispGVerticalScroll(gh->display, gh->x, gh->y, gh->width, gh->height, fy, gh->bgcolor);
|
||||||
|
DrawEnd(gh);
|
||||||
|
}
|
||||||
|
|
||||||
// Set the cursor to the start of the last line
|
// Set the cursor to the start of the last line
|
||||||
gcw->cx = 0;
|
gcw->cx = 0;
|
||||||
|
@ -530,7 +545,10 @@ void gwinPutChar(GHandle gh, char c) {
|
||||||
{
|
{
|
||||||
// Clear the console and reset the cursor
|
// Clear the console and reset the cursor
|
||||||
clearBuffer(gcw);
|
clearBuffer(gcw);
|
||||||
|
if (DrawStart(gh)) {
|
||||||
gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, gh->bgcolor);
|
gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, gh->bgcolor);
|
||||||
|
DrawEnd(gh);
|
||||||
|
}
|
||||||
gcw->cx = 0;
|
gcw->cx = 0;
|
||||||
gcw->cy = 0;
|
gcw->cy = 0;
|
||||||
#if GWIN_CONSOLE_ESCSEQ
|
#if GWIN_CONSOLE_ESCSEQ
|
||||||
|
@ -540,19 +558,23 @@ void gwinPutChar(GHandle gh, char c) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save the char
|
||||||
|
putCharInBuffer(gcw, c);
|
||||||
|
|
||||||
|
// Draw the character
|
||||||
|
if (DrawStart(gh)) {
|
||||||
|
|
||||||
// If we are at the beginning of a new line clear the line
|
// If we are at the beginning of a new line clear the line
|
||||||
#if GWIN_CONSOLE_USE_CLEAR_LINES
|
#if GWIN_CONSOLE_USE_CLEAR_LINES
|
||||||
if (gcw->cx == 0)
|
if (gcw->cx == 0)
|
||||||
gdispGFillArea(gh->display, gh->x, gh->y + gcw->cy, gh->width, fy, gh->bgcolor);
|
gdispGFillArea(gh->display, gh->x, gh->y + gcw->cy, gh->width, fy, gh->bgcolor);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Draw the character
|
|
||||||
#if GWIN_CONSOLE_USE_FILLED_CHARS
|
#if GWIN_CONSOLE_USE_FILLED_CHARS
|
||||||
gdispGFillChar(gh->display, gh->x + gcw->cx, gh->y + gcw->cy, c, gh->font, ESCPrintColor(gcw), gh->bgcolor);
|
gdispGFillChar(gh->display, gh->x + gcw->cx, gh->y + gcw->cy, c, gh->font, ESCPrintColor(gcw), gh->bgcolor);
|
||||||
#else
|
#else
|
||||||
gdispGDrawChar(gh->display, gh->x + gcw->cx, gh->y + gcw->cy, c, gh->font, ESCPrintColor(gcw));
|
gdispGDrawChar(gh->display, gh->x + gcw->cx, gh->y + gcw->cy, c, gh->font, ESCPrintColor(gcw));
|
||||||
#endif
|
#endif
|
||||||
putCharInBuffer(gcw, c);
|
|
||||||
|
|
||||||
#if GWIN_CONSOLE_ESCSEQ
|
#if GWIN_CONSOLE_ESCSEQ
|
||||||
// Draw the underline
|
// Draw the underline
|
||||||
|
@ -565,6 +587,9 @@ void gwinPutChar(GHandle gh, char c) {
|
||||||
gdispGDrawChar(gh->display, gh->x + gcw->cx + 1, gh->y + gcw->cy, c, gh->font, ESCPrintColor(gcw));
|
gdispGDrawChar(gh->display, gh->x + gcw->cx + 1, gh->y + gcw->cy, c, gh->font, ESCPrintColor(gcw));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
DrawEnd(gh);
|
||||||
|
}
|
||||||
|
|
||||||
// Update the cursor
|
// Update the cursor
|
||||||
gcw->cx += width + gdispGetFontMetric(gh->font, fontCharPadding);
|
gcw->cx += width + gdispGetFontMetric(gh->font, fontCharPadding);
|
||||||
|
|
||||||
|
|
|
@ -41,46 +41,6 @@ void _gcontainerDestroy(GHandle gh) {
|
||||||
_gwidgetDestroy(gh);
|
_gwidgetDestroy(gh);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _gcontainerRedraw(GHandle gh) {
|
|
||||||
GHandle child;
|
|
||||||
|
|
||||||
if (!(gh->flags & GWIN_FLG_SYSVISIBLE))
|
|
||||||
return;
|
|
||||||
|
|
||||||
((GWidgetObject *)gh)->fnDraw((GWidgetObject *)gh, ((GWidgetObject *)gh)->fnParam);
|
|
||||||
|
|
||||||
for(child = gwinGetFirstChild(gh); child; child = gwinGetSibling(child))
|
|
||||||
gwinRedraw(child);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _gcontainerUpdate(GHandle gh) {
|
|
||||||
GHandle child;
|
|
||||||
|
|
||||||
if (!(gh->flags & GWIN_FLG_SYSVISIBLE))
|
|
||||||
return;
|
|
||||||
|
|
||||||
#if GDISP_NEED_CLIP
|
|
||||||
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
|
||||||
#endif
|
|
||||||
((GWidgetObject *)gh)->fnDraw((GWidgetObject *)gh, ((GWidgetObject *)gh)->fnParam);
|
|
||||||
|
|
||||||
for(child = gwinGetFirstChild(gh); child; child = gwinGetSibling(child))
|
|
||||||
gwinRedraw(child);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _gwinRecurse(GHandle gh, bool_t (*fn)(GHandle gh)) {
|
|
||||||
if (fn(gh) && (gh->flags & GWIN_FLG_CONTAINER)) {
|
|
||||||
// Apply to this windows children
|
|
||||||
for(gh = gwinGetFirstChild(gh); gh; gh = gwinGetSibling(gh)) {
|
|
||||||
// Only recurse when we have to. Otherwise apply it directly
|
|
||||||
if ((gh->flags & GWIN_FLG_CONTAINER))
|
|
||||||
_gwinRecurse(gh, fn);
|
|
||||||
else
|
|
||||||
fn(gh);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GHandle gwinGetFirstChild(GHandle gh) {
|
GHandle gwinGetFirstChild(GHandle gh) {
|
||||||
GHandle child;
|
GHandle child;
|
||||||
|
|
||||||
|
|
|
@ -24,22 +24,8 @@ static void _destroy(GWindowObject *gh) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GWIN_NEED_IMAGE_ANIMATION
|
#if GWIN_NEED_IMAGE_ANIMATION
|
||||||
static void _redraw(GHandle gh);
|
|
||||||
|
|
||||||
static void _timer(void *param) {
|
static void _timer(void *param) {
|
||||||
#define gh ((GHandle)param)
|
_gwinUpdate((GHandle)param);
|
||||||
|
|
||||||
// We need to re-test the visibility in case it has been made invisible since the last frame.
|
|
||||||
if ((gh->flags & GWIN_FLG_SYSVISIBLE)) {
|
|
||||||
// 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
|
|
||||||
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
|
||||||
#endif
|
|
||||||
_redraw(gh);
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef gh
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -160,14 +146,7 @@ bool_t gwinImageOpenGFile(GHandle gh, GFILE *f) {
|
||||||
if ((gdispImageOpenGFile(&widget(gh)->image, f) & GDISP_IMAGE_ERR_UNRECOVERABLE))
|
if ((gdispImageOpenGFile(&widget(gh)->image, f) & GDISP_IMAGE_ERR_UNRECOVERABLE))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if ((gh->flags & GWIN_FLG_SYSVISIBLE)) {
|
_gwinUpdate(gh);
|
||||||
// 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
|
|
||||||
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
|
||||||
#endif
|
|
||||||
_redraw(gh);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -208,7 +208,7 @@ void gwinGraphDrawAxis(GHandle gh) {
|
||||||
#define gg ((GGraphObject *)gh)
|
#define gg ((GGraphObject *)gh)
|
||||||
coord_t i, xmin, ymin, xmax, ymax;
|
coord_t i, xmin, ymin, xmax, ymax;
|
||||||
|
|
||||||
if (gh->vmt != &graphVMT)
|
if (gh->vmt != &graphVMT || !_gwinDrawStart(gh))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
xmin = -gg->xorigin;
|
xmin = -gg->xorigin;
|
||||||
|
@ -262,6 +262,7 @@ void gwinGraphDrawAxis(GHandle gh) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_gwinDrawEnd(gh);
|
||||||
#undef gg
|
#undef gg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,7 +276,7 @@ void gwinGraphStartSet(GHandle gh) {
|
||||||
void gwinGraphDrawPoint(GHandle gh, coord_t x, coord_t y) {
|
void gwinGraphDrawPoint(GHandle gh, coord_t x, coord_t y) {
|
||||||
#define gg ((GGraphObject *)gh)
|
#define gg ((GGraphObject *)gh)
|
||||||
|
|
||||||
if (gh->vmt != &graphVMT)
|
if (gh->vmt != &graphVMT || !_gwinDrawStart(gh))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ((gh->flags & GGRAPH_FLG_CONNECTPOINTS)) {
|
if ((gh->flags & GGRAPH_FLG_CONNECTPOINTS)) {
|
||||||
|
@ -295,6 +296,7 @@ void gwinGraphDrawPoint(GHandle gh, coord_t x, coord_t y) {
|
||||||
// Draw this point.
|
// Draw this point.
|
||||||
pointto(gg, x, y, &gg->style.point);
|
pointto(gg, x, y, &gg->style.point);
|
||||||
|
|
||||||
|
_gwinDrawEnd(gh);
|
||||||
#undef gg
|
#undef gg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,7 +305,7 @@ void gwinGraphDrawPoints(GHandle gh, const point *points, unsigned count) {
|
||||||
unsigned i;
|
unsigned i;
|
||||||
const point *p;
|
const point *p;
|
||||||
|
|
||||||
if (gh->vmt != &graphVMT)
|
if (gh->vmt != &graphVMT || !_gwinDrawStart(gh))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Draw the connecting lines
|
// Draw the connecting lines
|
||||||
|
@ -329,6 +331,7 @@ void gwinGraphDrawPoints(GHandle gh, const point *points, unsigned count) {
|
||||||
for(p = points, i = 0; i < count; p++, i++)
|
for(p = points, i = 0; i < count; p++, i++)
|
||||||
pointto(gg, p->x, p->y, &gg->style.point);
|
pointto(gg, p->x, p->y, &gg->style.point);
|
||||||
|
|
||||||
|
_gwinDrawEnd(gh);
|
||||||
#undef gg
|
#undef gg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -292,16 +292,6 @@ void _gwidgetRedraw(GHandle gh) {
|
||||||
gw->fnDraw(gw, gw->fnParam);
|
gw->fnDraw(gw, gw->fnParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _gwidgetUpdate(GHandle gh) {
|
|
||||||
if (!(gh->flags & GWIN_FLG_SYSVISIBLE))
|
|
||||||
return;
|
|
||||||
|
|
||||||
#if GDISP_NEED_CLIP
|
|
||||||
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
|
||||||
#endif
|
|
||||||
gw->fnDraw(gw, gw->fnParam);
|
|
||||||
}
|
|
||||||
|
|
||||||
void gwinWidgetClearInit(GWidgetInit *pwi) {
|
void gwinWidgetClearInit(GWidgetInit *pwi) {
|
||||||
char *p;
|
char *p;
|
||||||
unsigned len;
|
unsigned len;
|
||||||
|
@ -364,7 +354,7 @@ void gwinSetText(GHandle gh, const char *text, bool_t useAlloc) {
|
||||||
gw->text = (const char *)str;
|
gw->text = (const char *)str;
|
||||||
} else
|
} else
|
||||||
gw->text = text;
|
gw->text = text;
|
||||||
_gwidgetUpdate(gh);
|
_gwinUpdate(gh);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *gwinGetText(GHandle gh) {
|
const char *gwinGetText(GHandle gh) {
|
||||||
|
@ -380,7 +370,7 @@ void gwinSetStyle(GHandle gh, const GWidgetStyle *pstyle) {
|
||||||
gw->pstyle = pstyle ? pstyle : defaultStyle;
|
gw->pstyle = pstyle ? pstyle : defaultStyle;
|
||||||
gh->bgcolor = pstyle->background;
|
gh->bgcolor = pstyle->background;
|
||||||
gh->color = pstyle->enabled.text;
|
gh->color = pstyle->enabled.text;
|
||||||
_gwidgetUpdate(gh);
|
_gwinUpdate(gh);
|
||||||
}
|
}
|
||||||
|
|
||||||
const GWidgetStyle *gwinGetStyle(GHandle gh) {
|
const GWidgetStyle *gwinGetStyle(GHandle gh) {
|
||||||
|
@ -396,7 +386,7 @@ void gwinSetCustomDraw(GHandle gh, CustomWidgetDrawFunction fn, void *param) {
|
||||||
|
|
||||||
gw->fnDraw = fn ? fn : wvmt->DefaultDraw;
|
gw->fnDraw = fn ? fn : wvmt->DefaultDraw;
|
||||||
gw->fnParam = param;
|
gw->fnParam = param;
|
||||||
_gwidgetUpdate(gh);
|
_gwinUpdate(gh);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool_t gwinAttachListener(GListener *pl) {
|
bool_t gwinAttachListener(GListener *pl) {
|
||||||
|
|
385
src/gwin/gwin.c
385
src/gwin/gwin.c
|
@ -11,10 +11,6 @@
|
||||||
|
|
||||||
#include "src/gwin/class_gwin.h"
|
#include "src/gwin/class_gwin.h"
|
||||||
|
|
||||||
// Needed if there is no window manager
|
|
||||||
#define MIN_WIN_WIDTH 1
|
|
||||||
#define MIN_WIN_HEIGHT 1
|
|
||||||
|
|
||||||
/*-----------------------------------------------
|
/*-----------------------------------------------
|
||||||
* Data
|
* Data
|
||||||
*-----------------------------------------------*/
|
*-----------------------------------------------*/
|
||||||
|
@ -37,64 +33,15 @@ static color_t defaultBgColor = Black;
|
||||||
* Helper Routines
|
* Helper Routines
|
||||||
*-----------------------------------------------*/
|
*-----------------------------------------------*/
|
||||||
|
|
||||||
#if GWIN_NEED_WINDOWMANAGER
|
|
||||||
#define _gwm_redraw(gh, flags) _GWINwm->vmt->Redraw(gh, flags)
|
|
||||||
#define _gwm_move(gh,x,y) _GWINwm->vmt->Move(gh,x,y);
|
|
||||||
#define _gwm_resize(gh,w,h) _GWINwm->vmt->Size(gh,w,h);
|
|
||||||
#else
|
|
||||||
static void _gwm_redraw(GHandle gh, int flags) {
|
|
||||||
if ((gh->flags & GWIN_FLG_SYSVISIBLE)) {
|
|
||||||
if (gh->vmt->Redraw) {
|
|
||||||
#if GDISP_NEED_CLIP
|
|
||||||
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
|
||||||
#endif
|
|
||||||
gh->vmt->Redraw(gh);
|
|
||||||
} else if (!(flags & GWIN_WMFLG_PRESERVE)) {
|
|
||||||
#if GDISP_NEED_CLIP
|
|
||||||
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
|
||||||
#endif
|
|
||||||
gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, gh->bgcolor);
|
|
||||||
if (gh->vmt->AfterClear)
|
|
||||||
gh->vmt->AfterClear(gh);
|
|
||||||
}
|
|
||||||
} else if (!(flags & GWIN_WMFLG_NOBGCLEAR)) {
|
|
||||||
#if GDISP_NEED_CLIP
|
|
||||||
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
|
||||||
#endif
|
|
||||||
gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, defaultBgColor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static void _gwm_resize(GHandle gh, coord_t width, coord_t height) {
|
|
||||||
gh->width = width; gh->height = height;
|
|
||||||
if (gh->width < MIN_WIN_WIDTH) { gh->width = MIN_WIN_WIDTH; }
|
|
||||||
if (gh->height < MIN_WIN_HEIGHT) { gh->height = MIN_WIN_HEIGHT; }
|
|
||||||
if (gh->x+gh->width > gdispGetWidth()) gh->width = gdispGetWidth() - gh->x;
|
|
||||||
if (gh->y+gh->height > gdispGetHeight()) gh->height = gdispGetHeight() - gh->y;
|
|
||||||
_gwm_redraw(gh, GWIN_WMFLG_PRESERVE|GWIN_WMFLG_NOBGCLEAR);
|
|
||||||
}
|
|
||||||
static void _gwm_move(GHandle gh, coord_t x, coord_t y) {
|
|
||||||
gh->x = x; gh->y = y;
|
|
||||||
if (gh->x < 0) gh->x = 0;
|
|
||||||
if (gh->y < 0) gh->y = 0;
|
|
||||||
if (gh->x > gdispGetWidth()-MIN_WIN_WIDTH) gh->x = gdispGetWidth()-MIN_WIN_WIDTH;
|
|
||||||
if (gh->y > gdispGetHeight()-MIN_WIN_HEIGHT) gh->y = gdispGetHeight()-MIN_WIN_HEIGHT;
|
|
||||||
if (gh->x+gh->width > gdispGetWidth()) gh->width = gdispGetWidth() - gh->x;
|
|
||||||
if (gh->y+gh->height > gdispGetHeight()) gh->height = gdispGetHeight() - gh->y;
|
|
||||||
_gwm_redraw(gh, GWIN_WMFLG_PRESERVE|GWIN_WMFLG_NOBGCLEAR);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*-----------------------------------------------
|
/*-----------------------------------------------
|
||||||
* Class Routines
|
* Class Routines
|
||||||
*-----------------------------------------------*/
|
*-----------------------------------------------*/
|
||||||
|
|
||||||
void _gwinInit(void)
|
void _gwinInit(void)
|
||||||
{
|
{
|
||||||
#if GWIN_NEED_WINDOWMANAGER
|
|
||||||
extern void _gwmInit(void);
|
extern void _gwmInit(void);
|
||||||
|
|
||||||
_gwmInit();
|
_gwmInit();
|
||||||
#endif
|
|
||||||
#if GWIN_NEED_WIDGET
|
#if GWIN_NEED_WIDGET
|
||||||
extern void _gwidgetInit(void);
|
extern void _gwidgetInit(void);
|
||||||
|
|
||||||
|
@ -109,6 +56,8 @@ void _gwinInit(void)
|
||||||
|
|
||||||
void _gwinDeinit(void)
|
void _gwinDeinit(void)
|
||||||
{
|
{
|
||||||
|
extern void _gwmDeinit(void);
|
||||||
|
|
||||||
#if GWIN_NEED_CONTAINERS
|
#if GWIN_NEED_CONTAINERS
|
||||||
extern void _gcontainerDeinit(void);
|
extern void _gcontainerDeinit(void);
|
||||||
|
|
||||||
|
@ -119,11 +68,8 @@ void _gwinDeinit(void)
|
||||||
|
|
||||||
_gwidgetDeinit();
|
_gwidgetDeinit();
|
||||||
#endif
|
#endif
|
||||||
#if GWIN_NEED_WINDOWMANAGER
|
|
||||||
extern void _gwmDeinit(void);
|
|
||||||
|
|
||||||
_gwmDeinit();
|
_gwmDeinit();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal routine for use by GWIN components only
|
// Internal routine for use by GWIN components only
|
||||||
|
@ -146,35 +92,11 @@ GHandle _gwindowCreate(GDisplay *g, GWindowObject *pgw, const GWindowInit *pInit
|
||||||
pgw->font = defaultFont;
|
pgw->font = defaultFont;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if GWIN_NEED_CONTAINERS
|
if (!_gwinWMAdd(pgw, pInit)) {
|
||||||
if (pInit->parent) {
|
|
||||||
if (!(pInit->parent->flags & GWIN_FLG_CONTAINER) || pgw->display != pInit->parent->display) {
|
|
||||||
if ((pgw->flags & GWIN_FLG_DYNAMIC))
|
if ((pgw->flags & GWIN_FLG_DYNAMIC))
|
||||||
gfxFree(pgw);
|
gfxFree(pgw);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
pgw->parent = pInit->parent;
|
|
||||||
} else
|
|
||||||
pgw->parent = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if GWIN_NEED_WINDOWMANAGER
|
|
||||||
if (!_GWINwm->vmt->Add(pgw, pInit)) {
|
|
||||||
if ((pgw->flags & GWIN_FLG_DYNAMIC))
|
|
||||||
gfxFree(pgw);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
pgw->x = pgw->y = pgw->width = pgw->height = 0;
|
|
||||||
_gwm_move(pgw, pInit->x, pInit->y);
|
|
||||||
_gwm_resize(pgw, pInit->width, pInit->height);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if GWIN_NEED_CONTAINERS
|
|
||||||
// Notify the parent it has been added
|
|
||||||
if (pgw->parent && ((gcontainerVMT *)pgw->parent->vmt)->NotifyAdd)
|
|
||||||
((gcontainerVMT *)pgw->parent->vmt)->NotifyAdd(pgw->parent, pgw);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return (GHandle)pgw;
|
return (GHandle)pgw;
|
||||||
}
|
}
|
||||||
|
@ -264,126 +186,14 @@ const char *gwinGetClassName(GHandle gh) {
|
||||||
return gh->vmt->classname;
|
return gh->vmt->classname;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GWIN_NEED_CONTAINERS
|
|
||||||
// These two sub-functions set/clear system visibility recursively.
|
|
||||||
static bool_t setSysVisFlag(GHandle gh) {
|
|
||||||
// If we are now visible and our parent is visible
|
|
||||||
if ((gh->flags & GWIN_FLG_VISIBLE) && (!gh->parent || (gh->parent->flags & GWIN_FLG_SYSVISIBLE))) {
|
|
||||||
gh->flags |= GWIN_FLG_SYSVISIBLE;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
static bool_t clrSysVisFlag(GHandle gh) {
|
|
||||||
// If we are now not visible but our parent is visible
|
|
||||||
if (!(gh->flags & GWIN_FLG_VISIBLE) || (gh->parent && !(gh->parent->flags & GWIN_FLG_SYSVISIBLE))) {
|
|
||||||
gh->flags &= ~GWIN_FLG_SYSVISIBLE;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
void gwinSetVisible(GHandle gh, bool_t visible) {
|
|
||||||
if (visible) {
|
|
||||||
if (!(gh->flags & GWIN_FLG_VISIBLE)) {
|
|
||||||
gh->flags |= GWIN_FLG_VISIBLE;
|
|
||||||
_gwinRecurse(gh, setSysVisFlag);
|
|
||||||
_gwm_redraw(gh, 0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ((gh->flags & GWIN_FLG_VISIBLE)) {
|
|
||||||
gh->flags &= ~GWIN_FLG_VISIBLE;
|
|
||||||
_gwinRecurse(gh, clrSysVisFlag);
|
|
||||||
_gwm_redraw(gh, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
void gwinSetVisible(GHandle gh, bool_t visible) {
|
|
||||||
if (visible) {
|
|
||||||
if (!(gh->flags & GWIN_FLG_VISIBLE)) {
|
|
||||||
gh->flags |= (GWIN_FLG_VISIBLE|GWIN_FLG_SYSVISIBLE);
|
|
||||||
_gwm_redraw(gh, 0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ((gh->flags & GWIN_FLG_VISIBLE)) {
|
|
||||||
gh->flags &= ~(GWIN_FLG_VISIBLE|GWIN_FLG_SYSVISIBLE);
|
|
||||||
_gwm_redraw(gh, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool_t gwinGetVisible(GHandle gh) {
|
bool_t gwinGetVisible(GHandle gh) {
|
||||||
return (gh->flags & GWIN_FLG_SYSVISIBLE) ? TRUE : FALSE;
|
return (gh->flags & GWIN_FLG_SYSVISIBLE) ? TRUE : FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GWIN_NEED_CONTAINERS
|
|
||||||
// These two sub-functions set/clear system enable recursively.
|
|
||||||
static bool_t setSysEnaFlag(GHandle gh) {
|
|
||||||
// If we are now enabled and our parent is enabled
|
|
||||||
if ((gh->flags & GWIN_FLG_ENABLED) && (!gh->parent || (gh->parent->flags & GWIN_FLG_SYSENABLED))) {
|
|
||||||
gh->flags |= GWIN_FLG_SYSENABLED;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
static bool_t clrSysEnaFlag(GHandle gh) {
|
|
||||||
// If we are now not enabled but our parent is enabled
|
|
||||||
if (!(gh->flags & GWIN_FLG_ENABLED) || (gh->parent && !(gh->parent->flags & GWIN_FLG_SYSENABLED))) {
|
|
||||||
gh->flags &= ~GWIN_FLG_SYSENABLED;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
void gwinSetEnabled(GHandle gh, bool_t enabled) {
|
|
||||||
if (enabled) {
|
|
||||||
if (!(gh->flags & GWIN_FLG_ENABLED)) {
|
|
||||||
gh->flags |= GWIN_FLG_ENABLED;
|
|
||||||
_gwinRecurse(gh, setSysEnaFlag);
|
|
||||||
if ((gh->flags & GWIN_FLG_SYSVISIBLE))
|
|
||||||
_gwm_redraw(gh, GWIN_WMFLG_PRESERVE);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ((gh->flags & GWIN_FLG_ENABLED)) {
|
|
||||||
gh->flags &= ~GWIN_FLG_ENABLED;
|
|
||||||
_gwinRecurse(gh, clrSysEnaFlag);
|
|
||||||
if ((gh->flags & GWIN_FLG_SYSVISIBLE))
|
|
||||||
_gwm_redraw(gh, GWIN_WMFLG_PRESERVE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
void gwinSetEnabled(GHandle gh, bool_t enabled) {
|
|
||||||
if (enabled) {
|
|
||||||
if (!(gh->flags & GWIN_FLG_ENABLED)) {
|
|
||||||
gh->flags |= (GWIN_FLG_ENABLED|GWIN_FLG_SYSENABLED);
|
|
||||||
_gwm_redraw(gh, GWIN_WMFLG_PRESERVE|GWIN_WMFLG_NOBGCLEAR);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ((gh->flags & GWIN_FLG_ENABLED)) {
|
|
||||||
gh->flags &= ~(GWIN_FLG_ENABLED|GWIN_FLG_SYSENABLED);
|
|
||||||
_gwm_redraw(gh, GWIN_WMFLG_PRESERVE|GWIN_WMFLG_NOBGCLEAR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool_t gwinGetEnabled(GHandle gh) {
|
bool_t gwinGetEnabled(GHandle gh) {
|
||||||
return (gh->flags & GWIN_FLG_SYSENABLED) ? TRUE : FALSE;
|
return (gh->flags & GWIN_FLG_SYSENABLED) ? TRUE : FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gwinMove(GHandle gh, coord_t x, coord_t y) {
|
|
||||||
_gwm_move(gh, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void gwinResize(GHandle gh, coord_t width, coord_t height) {
|
|
||||||
_gwm_resize(gh, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
void gwinRedraw(GHandle gh) {
|
|
||||||
_gwm_redraw(gh, GWIN_WMFLG_PRESERVE|GWIN_WMFLG_NOBGCLEAR);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if GDISP_NEED_TEXT
|
#if GDISP_NEED_TEXT
|
||||||
void gwinSetFont(GHandle gh, font_t font) {
|
void gwinSetFont(GHandle gh, font_t font) {
|
||||||
gh->font = font;
|
gh->font = font;
|
||||||
|
@ -396,247 +206,154 @@ void gwinClear(GHandle gh) {
|
||||||
* still call the AfterClear() routine as some widgets will
|
* still call the AfterClear() routine as some widgets will
|
||||||
* need this to clear internal buffers or similar
|
* need this to clear internal buffers or similar
|
||||||
*/
|
*/
|
||||||
if (!(gh->flags & GWIN_FLG_SYSVISIBLE)) {
|
if (_gwinDrawStart(gh)) {
|
||||||
if (gh->vmt->AfterClear)
|
|
||||||
gh->vmt->AfterClear(gh);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
#if GDISP_NEED_CLIP
|
|
||||||
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, gh->bgcolor);
|
gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, gh->bgcolor);
|
||||||
|
_gwinDrawEnd(gh);
|
||||||
|
}
|
||||||
if (gh->vmt->AfterClear)
|
if (gh->vmt->AfterClear)
|
||||||
gh->vmt->AfterClear(gh);
|
gh->vmt->AfterClear(gh);
|
||||||
}
|
|
||||||
|
|
||||||
#if GWIN_NEED_CONTAINERS
|
|
||||||
for (gh = gwinGetFirstChild(gh); gh; gh = gwinGetSibling(gh))
|
|
||||||
gwinRedraw(gh);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void gwinDrawPixel(GHandle gh, coord_t x, coord_t y) {
|
void gwinDrawPixel(GHandle gh, coord_t x, coord_t y) {
|
||||||
if (!(gh->flags & GWIN_FLG_SYSVISIBLE))
|
if (!_gwinDrawStart(gh)) return;
|
||||||
return;
|
|
||||||
|
|
||||||
#if GDISP_NEED_CLIP
|
|
||||||
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
|
||||||
#endif
|
|
||||||
gdispGDrawPixel(gh->display, gh->x+x, gh->y+y, gh->color);
|
gdispGDrawPixel(gh->display, gh->x+x, gh->y+y, gh->color);
|
||||||
|
_gwinDrawEnd(gh);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gwinDrawLine(GHandle gh, coord_t x0, coord_t y0, coord_t x1, coord_t y1) {
|
void gwinDrawLine(GHandle gh, coord_t x0, coord_t y0, coord_t x1, coord_t y1) {
|
||||||
if (!(gh->flags & GWIN_FLG_SYSVISIBLE))
|
if (!_gwinDrawStart(gh)) return;
|
||||||
return;
|
|
||||||
|
|
||||||
#if GDISP_NEED_CLIP
|
|
||||||
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
|
||||||
#endif
|
|
||||||
gdispGDrawLine(gh->display, gh->x+x0, gh->y+y0, gh->x+x1, gh->y+y1, gh->color);
|
gdispGDrawLine(gh->display, gh->x+x0, gh->y+y0, gh->x+x1, gh->y+y1, gh->color);
|
||||||
|
_gwinDrawEnd(gh);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gwinDrawBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy) {
|
void gwinDrawBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy) {
|
||||||
if (!(gh->flags & GWIN_FLG_SYSVISIBLE))
|
if (!_gwinDrawStart(gh)) return;
|
||||||
return;
|
|
||||||
|
|
||||||
#if GDISP_NEED_CLIP
|
|
||||||
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
|
||||||
#endif
|
|
||||||
gdispGDrawBox(gh->display, gh->x+x, gh->y+y, cx, cy, gh->color);
|
gdispGDrawBox(gh->display, gh->x+x, gh->y+y, cx, cy, gh->color);
|
||||||
|
_gwinDrawEnd(gh);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gwinFillArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy) {
|
void gwinFillArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy) {
|
||||||
if (!(gh->flags & GWIN_FLG_SYSVISIBLE))
|
if (!_gwinDrawStart(gh)) return;
|
||||||
return;
|
|
||||||
|
|
||||||
#if GDISP_NEED_CLIP
|
|
||||||
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
|
||||||
#endif
|
|
||||||
gdispGFillArea(gh->display, gh->x+x, gh->y+y, cx, cy, gh->color);
|
gdispGFillArea(gh->display, gh->x+x, gh->y+y, cx, cy, gh->color);
|
||||||
|
_gwinDrawEnd(gh);
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
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) {
|
||||||
if (!(gh->flags & GWIN_FLG_SYSVISIBLE))
|
if (!_gwinDrawStart(gh)) return;
|
||||||
return;
|
|
||||||
|
|
||||||
#if GDISP_NEED_CLIP
|
|
||||||
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
|
||||||
#endif
|
|
||||||
gdispGBlitArea(gh->display, gh->x+x, gh->y+y, cx, cy, srcx, srcy, srccx, buffer);
|
gdispGBlitArea(gh->display, gh->x+x, gh->y+y, cx, cy, srcx, srcy, srccx, buffer);
|
||||||
|
_gwinDrawEnd(gh);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GDISP_NEED_CIRCLE
|
#if GDISP_NEED_CIRCLE
|
||||||
void gwinDrawCircle(GHandle gh, coord_t x, coord_t y, coord_t radius) {
|
void gwinDrawCircle(GHandle gh, coord_t x, coord_t y, coord_t radius) {
|
||||||
if (!(gh->flags & GWIN_FLG_SYSVISIBLE))
|
if (!_gwinDrawStart(gh)) return;
|
||||||
return;
|
|
||||||
|
|
||||||
#if GDISP_NEED_CLIP
|
|
||||||
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
|
||||||
#endif
|
|
||||||
gdispGDrawCircle(gh->display, gh->x+x, gh->y+y, radius, gh->color);
|
gdispGDrawCircle(gh->display, gh->x+x, gh->y+y, radius, gh->color);
|
||||||
|
_gwinDrawEnd(gh);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gwinFillCircle(GHandle gh, coord_t x, coord_t y, coord_t radius) {
|
void gwinFillCircle(GHandle gh, coord_t x, coord_t y, coord_t radius) {
|
||||||
if (!(gh->flags & GWIN_FLG_SYSVISIBLE))
|
if (!_gwinDrawStart(gh)) return;
|
||||||
return;
|
|
||||||
|
|
||||||
#if GDISP_NEED_CLIP
|
|
||||||
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
|
||||||
#endif
|
|
||||||
gdispGFillCircle(gh->display, gh->x+x, gh->y+y, radius, gh->color);
|
gdispGFillCircle(gh->display, gh->x+x, gh->y+y, radius, gh->color);
|
||||||
|
_gwinDrawEnd(gh);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if GDISP_NEED_ELLIPSE
|
#if GDISP_NEED_ELLIPSE
|
||||||
void gwinDrawEllipse(GHandle gh, coord_t x, coord_t y, coord_t a, coord_t b) {
|
void gwinDrawEllipse(GHandle gh, coord_t x, coord_t y, coord_t a, coord_t b) {
|
||||||
if (!(gh->flags & GWIN_FLG_SYSVISIBLE))
|
if (!_gwinDrawStart(gh)) return;
|
||||||
return;
|
|
||||||
|
|
||||||
#if GDISP_NEED_CLIP
|
|
||||||
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
|
||||||
#endif
|
|
||||||
gdispGDrawEllipse(gh->display, gh->x+x, gh->y+y, a, b, gh->color);
|
gdispGDrawEllipse(gh->display, gh->x+x, gh->y+y, a, b, gh->color);
|
||||||
|
_gwinDrawEnd(gh);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gwinFillEllipse(GHandle gh, coord_t x, coord_t y, coord_t a, coord_t b) {
|
void gwinFillEllipse(GHandle gh, coord_t x, coord_t y, coord_t a, coord_t b) {
|
||||||
if (!(gh->flags & GWIN_FLG_SYSVISIBLE))
|
if (!_gwinDrawStart(gh)) return;
|
||||||
return;
|
|
||||||
|
|
||||||
#if GDISP_NEED_CLIP
|
|
||||||
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
|
||||||
#endif
|
|
||||||
gdispGFillEllipse(gh->display, gh->x+x, gh->y+y, a, b, gh->color);
|
gdispGFillEllipse(gh->display, gh->x+x, gh->y+y, a, b, gh->color);
|
||||||
|
_gwinDrawEnd(gh);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if GDISP_NEED_ARC
|
#if GDISP_NEED_ARC
|
||||||
void gwinDrawArc(GHandle gh, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle) {
|
void gwinDrawArc(GHandle gh, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle) {
|
||||||
if (!(gh->flags & GWIN_FLG_SYSVISIBLE))
|
if (!_gwinDrawStart(gh)) return;
|
||||||
return;
|
|
||||||
|
|
||||||
#if GDISP_NEED_CLIP
|
|
||||||
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
|
||||||
#endif
|
|
||||||
gdispGDrawArc(gh->display, gh->x+x, gh->y+y, radius, startangle, endangle, gh->color);
|
gdispGDrawArc(gh->display, gh->x+x, gh->y+y, radius, startangle, endangle, gh->color);
|
||||||
|
_gwinDrawEnd(gh);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gwinFillArc(GHandle gh, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle) {
|
void gwinFillArc(GHandle gh, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle) {
|
||||||
if (!(gh->flags & GWIN_FLG_SYSVISIBLE))
|
if (!_gwinDrawStart(gh)) return;
|
||||||
return;
|
|
||||||
|
|
||||||
#if GDISP_NEED_CLIP
|
|
||||||
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
|
||||||
#endif
|
|
||||||
gdispGFillArc(gh->display, gh->x+x, gh->y+y, radius, startangle, endangle, gh->color);
|
gdispGFillArc(gh->display, gh->x+x, gh->y+y, radius, startangle, endangle, gh->color);
|
||||||
|
_gwinDrawEnd(gh);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if GDISP_NEED_PIXELREAD
|
#if GDISP_NEED_PIXELREAD
|
||||||
color_t gwinGetPixelColor(GHandle gh, coord_t x, coord_t y) {
|
color_t gwinGetPixelColor(GHandle gh, coord_t x, coord_t y) {
|
||||||
if (!(gh->flags & GWIN_FLG_SYSVISIBLE))
|
if (!_gwinDrawStart(gh)) return;
|
||||||
return defaultBgColor;
|
|
||||||
|
|
||||||
#if GDISP_NEED_CLIP
|
|
||||||
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
|
||||||
#endif
|
|
||||||
return gdispGGetPixelColor(gh->display, gh->x+x, gh->y+y);
|
return gdispGGetPixelColor(gh->display, gh->x+x, gh->y+y);
|
||||||
|
_gwinDrawEnd(gh);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if GDISP_NEED_TEXT
|
#if GDISP_NEED_TEXT
|
||||||
void gwinDrawChar(GHandle gh, coord_t x, coord_t y, char c) {
|
void gwinDrawChar(GHandle gh, coord_t x, coord_t y, char c) {
|
||||||
if (!(gh->flags & GWIN_FLG_SYSVISIBLE) || !gh->font)
|
if (!gh->font || !_gwinDrawStart(gh)) return;
|
||||||
return;
|
|
||||||
|
|
||||||
#if GDISP_NEED_CLIP
|
|
||||||
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
|
||||||
#endif
|
|
||||||
gdispGDrawChar(gh->display, gh->x+x, gh->y+y, c, gh->font, gh->color);
|
gdispGDrawChar(gh->display, gh->x+x, gh->y+y, c, gh->font, gh->color);
|
||||||
|
_gwinDrawEnd(gh);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gwinFillChar(GHandle gh, coord_t x, coord_t y, char c) {
|
void gwinFillChar(GHandle gh, coord_t x, coord_t y, char c) {
|
||||||
if (!(gh->flags & GWIN_FLG_SYSVISIBLE) || !gh->font)
|
if (!gh->font || !_gwinDrawStart(gh)) return;
|
||||||
return;
|
|
||||||
|
|
||||||
#if GDISP_NEED_CLIP
|
|
||||||
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
|
||||||
#endif
|
|
||||||
gdispGFillChar(gh->display, gh->x+x, gh->y+y, c, gh->font, gh->color, gh->bgcolor);
|
gdispGFillChar(gh->display, gh->x+x, gh->y+y, c, gh->font, gh->color, gh->bgcolor);
|
||||||
|
_gwinDrawEnd(gh);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gwinDrawString(GHandle gh, coord_t x, coord_t y, const char *str) {
|
void gwinDrawString(GHandle gh, coord_t x, coord_t y, const char *str) {
|
||||||
if (!(gh->flags & GWIN_FLG_SYSVISIBLE) || !gh->font)
|
if (!gh->font || !_gwinDrawStart(gh)) return;
|
||||||
return;
|
|
||||||
|
|
||||||
#if GDISP_NEED_CLIP
|
|
||||||
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
|
||||||
#endif
|
|
||||||
gdispGDrawString(gh->display, gh->x+x, gh->y+y, str, gh->font, gh->color);
|
gdispGDrawString(gh->display, gh->x+x, gh->y+y, str, gh->font, gh->color);
|
||||||
|
_gwinDrawEnd(gh);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gwinFillString(GHandle gh, coord_t x, coord_t y, const char *str) {
|
void gwinFillString(GHandle gh, coord_t x, coord_t y, const char *str) {
|
||||||
if (!(gh->flags & GWIN_FLG_SYSVISIBLE) || !gh->font)
|
if (!gh->font || !_gwinDrawStart(gh)) return;
|
||||||
return;
|
|
||||||
|
|
||||||
#if GDISP_NEED_CLIP
|
|
||||||
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
|
||||||
#endif
|
|
||||||
gdispGFillString(gh->display, gh->x+x, gh->y+y, str, gh->font, gh->color, gh->bgcolor);
|
gdispGFillString(gh->display, gh->x+x, gh->y+y, str, gh->font, gh->color, gh->bgcolor);
|
||||||
|
_gwinDrawEnd(gh);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gwinDrawStringBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, justify_t justify) {
|
void gwinDrawStringBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, justify_t justify) {
|
||||||
if (!(gh->flags & GWIN_FLG_SYSVISIBLE) || !gh->font)
|
if (!gh->font || !_gwinDrawStart(gh)) return;
|
||||||
return;
|
|
||||||
|
|
||||||
#if GDISP_NEED_CLIP
|
|
||||||
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
|
||||||
#endif
|
|
||||||
gdispGDrawStringBox(gh->display, gh->x+x, gh->y+y, cx, cy, str, gh->font, gh->color, justify);
|
gdispGDrawStringBox(gh->display, gh->x+x, gh->y+y, cx, cy, str, gh->font, gh->color, justify);
|
||||||
|
_gwinDrawEnd(gh);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gwinFillStringBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, justify_t justify) {
|
void gwinFillStringBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, justify_t justify) {
|
||||||
if (!(gh->flags & GWIN_FLG_SYSVISIBLE) || !gh->font)
|
if (!gh->font || !_gwinDrawStart(gh)) return;
|
||||||
return;
|
|
||||||
|
|
||||||
#if GDISP_NEED_CLIP
|
|
||||||
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
|
||||||
#endif
|
|
||||||
gdispGFillStringBox(gh->display, gh->x+x, gh->y+y, cx, cy, str, gh->font, gh->color, gh->bgcolor, justify);
|
gdispGFillStringBox(gh->display, gh->x+x, gh->y+y, cx, cy, str, gh->font, gh->color, gh->bgcolor, justify);
|
||||||
|
_gwinDrawEnd(gh);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if GDISP_NEED_CONVEX_POLYGON
|
#if GDISP_NEED_CONVEX_POLYGON
|
||||||
void gwinDrawPoly(GHandle gh, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt) {
|
void gwinDrawPoly(GHandle gh, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt) {
|
||||||
if (!(gh->flags & GWIN_FLG_SYSVISIBLE))
|
if (!_gwinDrawStart(gh)) return;
|
||||||
return;
|
|
||||||
|
|
||||||
#if GDISP_NEED_CLIP
|
|
||||||
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
|
||||||
#endif
|
|
||||||
gdispGDrawPoly(gh->display, tx+gh->x, ty+gh->y, pntarray, cnt, gh->color);
|
gdispGDrawPoly(gh->display, tx+gh->x, ty+gh->y, pntarray, cnt, gh->color);
|
||||||
|
_gwinDrawEnd(gh);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gwinFillConvexPoly(GHandle gh, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt) {
|
void gwinFillConvexPoly(GHandle gh, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt) {
|
||||||
if (!(gh->flags & GWIN_FLG_SYSVISIBLE))
|
if (!_gwinDrawStart(gh)) return;
|
||||||
return;
|
|
||||||
|
|
||||||
#if GDISP_NEED_CLIP
|
|
||||||
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
|
||||||
#endif
|
|
||||||
gdispGFillConvexPoly(gh->display, tx+gh->x, ty+gh->y, pntarray, cnt, gh->color);
|
gdispGFillConvexPoly(gh->display, tx+gh->x, ty+gh->y, pntarray, cnt, gh->color);
|
||||||
|
_gwinDrawEnd(gh);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if GDISP_NEED_IMAGE
|
#if GDISP_NEED_IMAGE
|
||||||
gdispImageError gwinDrawImage(GHandle gh, gdispImage *img, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t sx, coord_t sy) {
|
gdispImageError gwinDrawImage(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_SYSVISIBLE))
|
gdispImageError ret;
|
||||||
return GDISP_IMAGE_ERR_OK;
|
|
||||||
|
|
||||||
#if GDISP_NEED_CLIP
|
if (!_gwinDrawStart(gh)) return GDISP_IMAGE_ERR_OK;
|
||||||
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
ret = gdispGImageDraw(gh->display, img, gh->x+x, gh->y+y, cx, cy, sx, sy);
|
||||||
#endif
|
_gwinDrawEnd(gh);
|
||||||
return gdispGImageDraw(gh->display, img, gh->x+x, gh->y+y, cx, cy, sx, sy);
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
697
src/gwin/gwm.c
697
src/gwin/gwm.c
|
@ -7,55 +7,165 @@
|
||||||
|
|
||||||
#include "gfx.h"
|
#include "gfx.h"
|
||||||
|
|
||||||
// Used by the NULL window manager
|
#if GFX_USE_GWIN && !GWIN_NEED_WINDOWMANAGER
|
||||||
#define MIN_WIN_WIDTH 3
|
/**
|
||||||
#define MIN_WIN_HEIGHT 3
|
* A really nasty default implementation for the simplest of systems
|
||||||
|
*/
|
||||||
|
|
||||||
/*-----------------------------------------------
|
|
||||||
* The default window manager (GNullWindowManager)
|
#include "src/gwin/class_gwin.h"
|
||||||
*-----------------------------------------------*/
|
|
||||||
|
// Needed if there is no window manager
|
||||||
|
#define MIN_WIN_WIDTH 1
|
||||||
|
#define MIN_WIN_HEIGHT 1
|
||||||
|
|
||||||
|
static gfxMutex gmutex;
|
||||||
|
|
||||||
|
void _gwmInit(void) {
|
||||||
|
gfxMutexInit(&gmutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _gwmDeinit(void) {
|
||||||
|
gfxMutexDestroy(&gmutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t _gwinWMAdd(GHandle gh, const GWindowInit *pInit) {
|
||||||
|
gh->x = gh->y = gh->width = gh->height = 0;
|
||||||
|
gwinMove(gh, pInit->x, pInit->y);
|
||||||
|
gwinResize(gh, pInit->width, pInit->height);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _gwinFlushRedraws(bool_t doWait) {
|
||||||
|
(void) doWait;
|
||||||
|
|
||||||
|
// We are always flushed
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if GDISP_NEED_CLIP
|
||||||
|
static void getLock(GHandle gh) {
|
||||||
|
gfxMutexEnter(&gmutex);
|
||||||
|
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
||||||
|
}
|
||||||
|
static void exitLock(GHandle gh) {
|
||||||
|
gdispGUnsetClip(gh->display);
|
||||||
|
gfxMutexExit(&gmutex);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define getLock(gh) gfxMutexEnter(&gmutex)
|
||||||
|
#define exitLock(gh) gfxMutexExit(&gmutex)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void _gwinUpdate(GHandle gh) {
|
||||||
|
if ((gh->flags & GWIN_FLG_SYSVISIBLE)) {
|
||||||
|
if (gh->vmt->Redraw) {
|
||||||
|
getLock(gh);
|
||||||
|
gh->vmt->Redraw(gh);
|
||||||
|
exitLock(gh);
|
||||||
|
} else if ((gh->flags & GWIN_FLG_BGREDRAW)) {
|
||||||
|
getLock(gh);
|
||||||
|
gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, gh->bgcolor);
|
||||||
|
exitLock(gh);
|
||||||
|
if (gh->vmt->AfterClear)
|
||||||
|
gh->vmt->AfterClear(gh);
|
||||||
|
}
|
||||||
|
} else if ((gh->flags & GWIN_FLG_BGREDRAW)) {
|
||||||
|
getLock(gh);
|
||||||
|
gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, gwinGetDefaultBgColor());
|
||||||
|
exitLock(gh);
|
||||||
|
}
|
||||||
|
gh->flags &= ~(GWIN_FLG_NEEDREDRAW|GWIN_FLG_BGREDRAW);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t _gwinDrawStart(GHandle gh) {
|
||||||
|
if (!(gh->flags & GWIN_FLG_SYSVISIBLE))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
getLock(gh);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _gwinDrawEnd(GHandle gh) {
|
||||||
|
(void) gh;
|
||||||
|
exitLock(gh);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gwinSetVisible(GHandle gh, bool_t visible) {
|
||||||
|
if (visible) {
|
||||||
|
if (!(gh->flags & GWIN_FLG_VISIBLE)) {
|
||||||
|
gh->flags |= (GWIN_FLG_VISIBLE|GWIN_FLG_SYSVISIBLE|GWIN_FLG_BGREDRAW);
|
||||||
|
_gwinUpdate(gh);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((gh->flags & GWIN_FLG_VISIBLE)) {
|
||||||
|
gh->flags &= ~(GWIN_FLG_VISIBLE|GWIN_FLG_SYSVISIBLE);
|
||||||
|
gh->flags |= GWIN_FLG_BGREDRAW;
|
||||||
|
_gwinUpdate(gh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gwinSetEnabled(GHandle gh, bool_t enabled) {
|
||||||
|
if (enabled) {
|
||||||
|
if (!(gh->flags & GWIN_FLG_ENABLED)) {
|
||||||
|
gh->flags |= (GWIN_FLG_ENABLED|GWIN_FLG_SYSENABLED);
|
||||||
|
_gwinUpdate(gh);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((gh->flags & GWIN_FLG_ENABLED)) {
|
||||||
|
gh->flags &= ~(GWIN_FLG_ENABLED|GWIN_FLG_SYSENABLED);
|
||||||
|
_gwinUpdate(gh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gwinMove(GHandle gh, coord_t x, coord_t y) {
|
||||||
|
gh->x = x; gh->y = y;
|
||||||
|
if (gh->x < 0) gh->x = 0;
|
||||||
|
if (gh->y < 0) gh->y = 0;
|
||||||
|
if (gh->x > gdispGGetWidth(gh->display)-MIN_WIN_WIDTH) gh->x = gdispGGetWidth(gh->display)-MIN_WIN_WIDTH;
|
||||||
|
if (gh->y > gdispGGetHeight(gh->display)-MIN_WIN_HEIGHT) gh->y = gdispGGetHeight(gh->display)-MIN_WIN_HEIGHT;
|
||||||
|
if (gh->x+gh->width > gdispGGetWidth(gh->display)) gh->width = gdispGGetWidth(gh->display) - gh->x;
|
||||||
|
if (gh->y+gh->height > gdispGGetHeight(gh->display)) gh->height = gdispGGetHeight(gh->display) - gh->y;
|
||||||
|
_gwinUpdate(gh);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gwinResize(GHandle gh, coord_t width, coord_t height) {
|
||||||
|
gh->width = width; gh->height = height;
|
||||||
|
if (gh->width < MIN_WIN_WIDTH) { gh->width = MIN_WIN_WIDTH; }
|
||||||
|
if (gh->height < MIN_WIN_HEIGHT) { gh->height = MIN_WIN_HEIGHT; }
|
||||||
|
if (gh->x+gh->width > gdispGGetWidth(gh->display)) gh->width = gdispGGetWidth(gh->display) - gh->x;
|
||||||
|
if (gh->y+gh->height > gdispGGetHeight(gh->display)) gh->height = gdispGGetHeight(gh->display) - gh->y;
|
||||||
|
_gwinUpdate(gh);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gwinRedraw(GHandle gh) {
|
||||||
|
_gwinUpdate(gh);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if GFX_USE_GWIN && GWIN_NEED_WINDOWMANAGER
|
#if GFX_USE_GWIN && GWIN_NEED_WINDOWMANAGER
|
||||||
|
|
||||||
|
// Do we redraw all windows at once?
|
||||||
|
#define GWIN_LONG_REDRAW TRUE
|
||||||
|
|
||||||
#include "src/gwin/class_gwin.h"
|
#include "src/gwin/class_gwin.h"
|
||||||
|
|
||||||
/*-----------------------------------------------
|
/*-----------------------------------------------
|
||||||
* Data
|
* Data
|
||||||
*-----------------------------------------------*/
|
*-----------------------------------------------*/
|
||||||
|
|
||||||
static void WM_Init(void);
|
// The default window manager
|
||||||
static void WM_DeInit(void);
|
extern const GWindowManager GNullWindowManager;
|
||||||
static bool_t WM_Add(GHandle gh, const GWindowInit *pInit);
|
|
||||||
static void WM_Delete(GHandle gh);
|
|
||||||
static void WM_Redraw(GHandle gh, int flags);
|
|
||||||
static void WM_Size(GHandle gh, coord_t w, coord_t h);
|
|
||||||
static void WM_Move(GHandle gh, coord_t x, coord_t y);
|
|
||||||
static void WM_Raise(GHandle gh);
|
|
||||||
static void WM_MinMax(GHandle gh, GWindowMinMax minmax);
|
|
||||||
|
|
||||||
static const gwmVMT GNullWindowManagerVMT = {
|
|
||||||
WM_Init,
|
|
||||||
WM_DeInit,
|
|
||||||
WM_Add,
|
|
||||||
WM_Delete,
|
|
||||||
WM_Redraw,
|
|
||||||
WM_Size,
|
|
||||||
WM_Move,
|
|
||||||
WM_Raise,
|
|
||||||
WM_MinMax,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const GWindowManager GNullWindowManager = {
|
|
||||||
&GNullWindowManagerVMT,
|
|
||||||
};
|
|
||||||
|
|
||||||
static gfxQueueASync _GWINList;
|
|
||||||
GWindowManager * _GWINwm;
|
GWindowManager * _GWINwm;
|
||||||
|
|
||||||
|
static gfxSem gwinsem;
|
||||||
|
static gfxQueueASync _GWINList;
|
||||||
|
static volatile bool_t RedrawPending;
|
||||||
#if GFX_USE_GTIMER
|
#if GFX_USE_GTIMER
|
||||||
static GTimer RedrawTimer;
|
static GTimer RedrawTimer;
|
||||||
static GDisplay * RedrawDisplay;
|
static void RedrawTimerFn(void *param);
|
||||||
static bool_t RedrawPreserve;
|
|
||||||
static void _gwinRedrawDisplay(void * param);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-----------------------------------------------
|
/*-----------------------------------------------
|
||||||
|
@ -64,18 +174,178 @@ GWindowManager * _GWINwm;
|
||||||
|
|
||||||
void _gwmInit(void)
|
void _gwmInit(void)
|
||||||
{
|
{
|
||||||
|
gfxSemInit(&gwinsem, 1, 1);
|
||||||
gfxQueueASyncInit(&_GWINList);
|
gfxQueueASyncInit(&_GWINList);
|
||||||
_GWINwm = (GWindowManager *)&GNullWindowManager;
|
|
||||||
_GWINwm->vmt->Init();
|
|
||||||
#if GFX_USE_GTIMER
|
#if GFX_USE_GTIMER
|
||||||
gtimerInit(&RedrawTimer);
|
gtimerInit(&RedrawTimer);
|
||||||
gtimerStart(&RedrawTimer, _gwinRedrawDisplay, 0, TRUE, TIME_INFINITE);
|
gtimerStart(&RedrawTimer, RedrawTimerFn, 0, TRUE, TIME_INFINITE);
|
||||||
#endif
|
#endif
|
||||||
|
_GWINwm = (GWindowManager *)&GNullWindowManager;
|
||||||
|
_GWINwm->vmt->Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _gwmDeinit(void)
|
void _gwmDeinit(void)
|
||||||
{
|
{
|
||||||
/* ToDo */
|
GHandle gh;
|
||||||
|
|
||||||
|
while((gh = gwinGetNextWindow(0)))
|
||||||
|
gwinDestroy(gh);
|
||||||
|
|
||||||
|
_GWINwm->vmt->DeInit();
|
||||||
|
#if GFX_USE_GTIMER
|
||||||
|
gtimerDeinit(&RedrawTimer);
|
||||||
|
#endif
|
||||||
|
gfxQueueASyncDeinit(&_GWINList);
|
||||||
|
gfxSemDestroy(&gwinsem);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if GFX_USE_GTIMER
|
||||||
|
#define TriggerRedraw() gtimerJab(&RedrawTimer);
|
||||||
|
|
||||||
|
static void RedrawTimerFn(void *param) {
|
||||||
|
(void) param;
|
||||||
|
_gwinFlushRedraws(FALSE);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define TriggerRedraw(void) _gwinFlushRedraws(FALSE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void _gwinFlushRedraws(bool_t doWait) {
|
||||||
|
GHandle gh;
|
||||||
|
|
||||||
|
// Do we really need to do anything?
|
||||||
|
if (!RedrawPending)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Obtain the drawing lock
|
||||||
|
if (doWait)
|
||||||
|
gfxSemWait(&gwinsem, TIME_INFINITE);
|
||||||
|
else if (!gfxSemWait(&gwinsem, TIME_IMMEDIATE))
|
||||||
|
// Someone is drawing - They will do the redraw when they are finished
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Look for something to redraw
|
||||||
|
while(RedrawPending) {
|
||||||
|
// Catch any new redraw requests from here on
|
||||||
|
RedrawPending = FALSE;
|
||||||
|
|
||||||
|
for(gh = gwinGetNextWindow(0); gh; gh = gwinGetNextWindow(gh)) {
|
||||||
|
if (!(gh->flags & GWIN_FLG_NEEDREDRAW))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Do the redraw
|
||||||
|
#if GDISP_NEED_CLIP
|
||||||
|
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
||||||
|
_GWINwm->vmt->Redraw(gh);
|
||||||
|
gdispGUnsetClip(gh->display);
|
||||||
|
#else
|
||||||
|
_GWINwm->vmt->Redraw(gh);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Postpone further redraws (if there are any and the options are set right)
|
||||||
|
#if GFX_USE_GTIMER && !GWIN_LONG_REDRAW
|
||||||
|
if (!doWait) {
|
||||||
|
while((gh = gwinGetNextWindow(gh))) {
|
||||||
|
if ((gh->flags & GWIN_FLG_NEEDREDRAW)) {
|
||||||
|
gtimerJab(&RedrawTimer);
|
||||||
|
RedrawPending = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Release the lock
|
||||||
|
gfxSemSignal(&gwinsem);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _gwinUpdate(GHandle gh) {
|
||||||
|
// Only redraw if visible
|
||||||
|
if (!(gh->flags & GWIN_FLG_SYSVISIBLE))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Mark for redraw
|
||||||
|
gh->flags |= GWIN_FLG_NEEDREDRAW;
|
||||||
|
RedrawPending = TRUE;
|
||||||
|
|
||||||
|
// Asynchronous redraw
|
||||||
|
TriggerRedraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t _gwinDrawStart(GHandle gh) {
|
||||||
|
// This test should occur inside the lock. We do this
|
||||||
|
// here as well as an early out (more efficient).
|
||||||
|
if (!(gh->flags & GWIN_FLG_SYSVISIBLE))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
// Obtain the drawing lock
|
||||||
|
gfxSemWait(&gwinsem, TIME_INFINITE);
|
||||||
|
|
||||||
|
// Re-test visibility as we may have waited a while
|
||||||
|
if (!(gh->flags & GWIN_FLG_SYSVISIBLE)) {
|
||||||
|
_gwinDrawEnd(gh);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// OK - we are ready to draw.
|
||||||
|
#if GDISP_NEED_CLIP
|
||||||
|
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
||||||
|
#endif
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _gwinDrawEnd(GHandle gh) {
|
||||||
|
// Ensure there is no clip set
|
||||||
|
#if GDISP_NEED_CLIP
|
||||||
|
gdispGUnsetClip(gh->display);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Look for something to redraw
|
||||||
|
while(RedrawPending) {
|
||||||
|
RedrawPending = FALSE;
|
||||||
|
for(gh = gwinGetNextWindow(0); gh; gh = gwinGetNextWindow(gh)) {
|
||||||
|
if (!(gh->flags & GWIN_FLG_NEEDREDRAW))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Do the redraw
|
||||||
|
#if GDISP_NEED_CLIP
|
||||||
|
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
||||||
|
_GWINwm->vmt->Redraw(gh);
|
||||||
|
gdispGUnsetClip(gh->display);
|
||||||
|
#else
|
||||||
|
_GWINwm->vmt->Redraw(gh);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Release the lock
|
||||||
|
gfxSemSignal(&gwinsem);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t _gwinWMAdd(GHandle gh, const GWindowInit *pInit) {
|
||||||
|
#if GWIN_NEED_CONTAINERS
|
||||||
|
// Save the parent
|
||||||
|
gh->parent = pInit->parent;
|
||||||
|
|
||||||
|
// Ensure the display is consistent with any parents
|
||||||
|
if (gh->parent && (!(gh->parent->flags & GWIN_FLG_CONTAINER) || gh->display != gh->parent->display))
|
||||||
|
return FALSE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Add to the window manager
|
||||||
|
if (!_GWINwm->vmt->Add(gh, pInit))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
#if GWIN_NEED_CONTAINERS
|
||||||
|
// Notify the parent it has been added
|
||||||
|
if (gh->parent && ((gcontainerVMT *)gh->parent->vmt)->NotifyAdd)
|
||||||
|
((gcontainerVMT *)gh->parent->vmt)->NotifyAdd(gh->parent, gh);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gwinSetWindowManager(struct GWindowManager *gwm) {
|
void gwinSetWindowManager(struct GWindowManager *gwm) {
|
||||||
|
@ -88,6 +358,142 @@ void gwinSetWindowManager(struct GWindowManager *gwm) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gwinRedraw(GHandle gh) {
|
||||||
|
// Only redraw if visible
|
||||||
|
if (!(gh->flags & GWIN_FLG_SYSVISIBLE))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Mark for redraw
|
||||||
|
gh->flags |= GWIN_FLG_NEEDREDRAW;
|
||||||
|
RedrawPending = TRUE;
|
||||||
|
|
||||||
|
// Synchronous redraw
|
||||||
|
_gwinFlushRedraws(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if GWIN_NEED_CONTAINERS
|
||||||
|
void gwinSetVisible(GHandle gh, bool_t visible) {
|
||||||
|
if (visible) {
|
||||||
|
// Mark us as visible
|
||||||
|
gh->flags |= GWIN_FLG_VISIBLE;
|
||||||
|
|
||||||
|
// Do we want to be added to the display
|
||||||
|
if (!(gh->flags & GWIN_FLG_SYSVISIBLE) && (!gh->parent || (gh->parent->flags & GWIN_FLG_SYSVISIBLE))) {
|
||||||
|
// Check each window's visibility is consistent with its parents
|
||||||
|
for(gh = gwinGetNextWindow(0); gh; gh = gwinGetNextWindow(gh)) {
|
||||||
|
if ((gh->flags & (GWIN_FLG_SYSVISIBLE|GWIN_FLG_VISIBLE)) == GWIN_FLG_VISIBLE && (!gh->parent || (gh->parent->flags & GWIN_FLG_SYSVISIBLE)))
|
||||||
|
gh->flags |= (GWIN_FLG_SYSVISIBLE|GWIN_FLG_NEEDREDRAW|GWIN_FLG_BGREDRAW); // Fix it and mark for redraw
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark for redraw
|
||||||
|
RedrawPending = TRUE;
|
||||||
|
TriggerRedraw();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Mark us as not visible
|
||||||
|
gh->flags &= ~GWIN_FLG_VISIBLE;
|
||||||
|
|
||||||
|
// Do we need to be removed from the display
|
||||||
|
if ((gh->flags & GWIN_FLG_SYSVISIBLE)) {
|
||||||
|
gh->flags |= (GWIN_FLG_NEEDREDRAW|GWIN_FLG_BGREDRAW);
|
||||||
|
|
||||||
|
// Check each window's visibility is consistent with its parents
|
||||||
|
for(gh = gwinGetNextWindow(0); gh; gh = gwinGetNextWindow(gh)) {
|
||||||
|
if ((gh->flags & GWIN_FLG_SYSVISIBLE) && (!(gh->flags & GWIN_FLG_VISIBLE) || (gh->parent && !(gh->parent->flags & GWIN_FLG_SYSVISIBLE))))
|
||||||
|
gh->flags &= ~GWIN_FLG_SYSVISIBLE; // Fix it
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark for redraw - no need to redraw children
|
||||||
|
RedrawPending = TRUE;
|
||||||
|
TriggerRedraw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void gwinSetVisible(GHandle gh, bool_t visible) {
|
||||||
|
if (visible) {
|
||||||
|
if (!(gh->flags & GWIN_FLG_VISIBLE)) {
|
||||||
|
gh->flags |= (GWIN_FLG_VISIBLE|GWIN_FLG_SYSVISIBLE|GWIN_FLG_NEEDREDRAW|GWIN_FLG_BGREDRAW);
|
||||||
|
RedrawPending = TRUE;
|
||||||
|
TriggerRedraw();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((gh->flags & GWIN_FLG_VISIBLE)) {
|
||||||
|
gh->flags &= ~(GWIN_FLG_VISIBLE|GWIN_FLG_SYSVISIBLE);
|
||||||
|
gh->flags |= (GWIN_FLG_NEEDREDRAW|GWIN_FLG_BGREDRAW);
|
||||||
|
RedrawPending = TRUE;
|
||||||
|
TriggerRedraw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if GWIN_NEED_CONTAINERS
|
||||||
|
// These two sub-functions set/clear system enable recursively.
|
||||||
|
void gwinSetEnabled(GHandle gh, bool_t enabled) {
|
||||||
|
if (enabled) {
|
||||||
|
// Mark us as enabled
|
||||||
|
gh->flags |= GWIN_FLG_ENABLED;
|
||||||
|
|
||||||
|
// Do we change our real enabled state
|
||||||
|
if (!(gh->flags & GWIN_FLG_SYSENABLED) && (!gh->parent || (gh->parent->flags & GWIN_FLG_SYSENABLED))) {
|
||||||
|
// Check each window's enabled state is consistent with its parents
|
||||||
|
for(gh = gwinGetNextWindow(0); gh; gh = gwinGetNextWindow(gh)) {
|
||||||
|
if ((gh->flags & (GWIN_FLG_SYSENABLED|GWIN_FLG_ENABLED)) == GWIN_FLG_ENABLED && (!gh->parent || (gh->parent->flags & GWIN_FLG_SYSENABLED))) {
|
||||||
|
gh->flags |= GWIN_FLG_SYSENABLED; // Fix it
|
||||||
|
if ((gh->flags & GWIN_FLG_SYSVISIBLE)) { // Mark for redraw
|
||||||
|
gh->flags |= GWIN_FLG_NEEDREDRAW;
|
||||||
|
RedrawPending = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (RedrawPending)
|
||||||
|
TriggerRedraw();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
gh->flags &= ~GWIN_FLG_ENABLED;
|
||||||
|
|
||||||
|
// Do we need to change our real enabled state
|
||||||
|
if ((gh->flags & GWIN_FLG_SYSENABLED)) {
|
||||||
|
// Check each window's visibility is consistent with its parents
|
||||||
|
for(gh = gwinGetNextWindow(0); gh; gh = gwinGetNextWindow(gh)) {
|
||||||
|
if ((gh->flags & GWIN_FLG_SYSENABLED) && (!(gh->flags & GWIN_FLG_ENABLED) || (gh->parent && !(gh->parent->flags & GWIN_FLG_SYSENABLED)))) {
|
||||||
|
gh->flags &= ~GWIN_FLG_SYSENABLED; // Fix it
|
||||||
|
if ((gh->flags & GWIN_FLG_SYSVISIBLE)) { // Mark for redraw
|
||||||
|
gh->flags |= GWIN_FLG_NEEDREDRAW;
|
||||||
|
RedrawPending = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (RedrawPending)
|
||||||
|
TriggerRedraw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void gwinSetEnabled(GHandle gh, bool_t enabled) {
|
||||||
|
if (enabled) {
|
||||||
|
if (!(gh->flags & GWIN_FLG_ENABLED)) {
|
||||||
|
gh->flags |= (GWIN_FLG_ENABLED|GWIN_FLG_SYSENABLED);
|
||||||
|
_gwinUpdate(gh);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((gh->flags & GWIN_FLG_ENABLED)) {
|
||||||
|
gh->flags &= ~(GWIN_FLG_ENABLED|GWIN_FLG_SYSENABLED);
|
||||||
|
_gwinUpdate(gh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void gwinMove(GHandle gh, coord_t x, coord_t y) {
|
||||||
|
_GWINwm->vmt->Move(gh, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gwinResize(GHandle gh, coord_t width, coord_t height) {
|
||||||
|
_GWINwm->vmt->Size(gh, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
void gwinSetMinMax(GHandle gh, GWindowMinMax minmax) {
|
void gwinSetMinMax(GHandle gh, GWindowMinMax minmax) {
|
||||||
_GWINwm->vmt->MinMax(gh, minmax);
|
_GWINwm->vmt->MinMax(gh, minmax);
|
||||||
}
|
}
|
||||||
|
@ -105,31 +511,73 @@ GWindowMinMax gwinGetMinMax(GHandle gh) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void gwinRedrawDisplay(GDisplay *g, bool_t preserve) {
|
void gwinRedrawDisplay(GDisplay *g, bool_t preserve) {
|
||||||
#if GFX_USE_GTIMER
|
|
||||||
RedrawDisplay = g;
|
|
||||||
RedrawPreserve = preserve;
|
|
||||||
gtimerJab(&RedrawTimer);
|
|
||||||
}
|
|
||||||
static void _gwinRedrawDisplay(void * param) {
|
|
||||||
GDisplay *g = RedrawDisplay;
|
|
||||||
bool_t preserve = RedrawPreserve;
|
|
||||||
(void) param;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
GHandle gh;
|
GHandle gh;
|
||||||
|
|
||||||
for(gh = gwinGetNextWindow(0); gh; gh = gwinGetNextWindow(gh)) {
|
for(gh = gwinGetNextWindow(0); gh; gh = gwinGetNextWindow(gh)) {
|
||||||
if (!g || gh->display == g)
|
|
||||||
_GWINwm->vmt->Redraw(gh,
|
// Skip if it is for a different display
|
||||||
preserve ? (GWIN_WMFLG_PRESERVE|GWIN_WMFLG_NOBGCLEAR|GWIN_WMFLG_NOZORDER)
|
if (g && gh->display != g)
|
||||||
: (GWIN_WMFLG_NOBGCLEAR|GWIN_WMFLG_NOZORDER));
|
continue;
|
||||||
|
|
||||||
|
#if GWIN_NEED_CONTAINERS
|
||||||
|
// Skip if it is not a top level window (parents internally take care of their children)
|
||||||
|
if (gh->parent)
|
||||||
|
continue;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Only visible windows are to be redrawn
|
||||||
|
if (!(gh->flags & GWIN_FLG_SYSVISIBLE))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!preserve)
|
||||||
|
gh->flags |= GWIN_FLG_BGREDRAW;
|
||||||
|
|
||||||
|
_gwinUpdate(gh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GHandle gwinGetNextWindow(GHandle gh) {
|
||||||
|
return gh ? (GHandle)gfxQueueASyncNext(&gh->wmq) : (GHandle)gfxQueueASyncPeek(&_GWINList);
|
||||||
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------
|
/*-----------------------------------------------
|
||||||
* "Null" Window Manager Routines
|
* "Null" Window Manager Routines
|
||||||
*-----------------------------------------------*/
|
*-----------------------------------------------*/
|
||||||
|
|
||||||
|
// This is a parent reveal operation
|
||||||
|
#define GWIN_FLG_PARENTREVEAL (GWIN_FIRST_WM_FLAG << 0)
|
||||||
|
|
||||||
|
// Minimum dimensions
|
||||||
|
#define MIN_WIN_WIDTH 3
|
||||||
|
#define MIN_WIN_HEIGHT 3
|
||||||
|
|
||||||
|
|
||||||
|
static void WM_Init(void);
|
||||||
|
static void WM_DeInit(void);
|
||||||
|
static bool_t WM_Add(GHandle gh, const GWindowInit *pInit);
|
||||||
|
static void WM_Delete(GHandle gh);
|
||||||
|
static void WM_Redraw(GHandle gh);
|
||||||
|
static void WM_Size(GHandle gh, coord_t w, coord_t h);
|
||||||
|
static void WM_Move(GHandle gh, coord_t x, coord_t y);
|
||||||
|
static void WM_Raise(GHandle gh);
|
||||||
|
static void WM_MinMax(GHandle gh, GWindowMinMax minmax);
|
||||||
|
|
||||||
|
static const gwmVMT GNullWindowManagerVMT = {
|
||||||
|
WM_Init,
|
||||||
|
WM_DeInit,
|
||||||
|
WM_Add,
|
||||||
|
WM_Delete,
|
||||||
|
WM_Redraw,
|
||||||
|
WM_Size,
|
||||||
|
WM_Move,
|
||||||
|
WM_Raise,
|
||||||
|
WM_MinMax,
|
||||||
|
};
|
||||||
|
|
||||||
|
const GWindowManager GNullWindowManager = {
|
||||||
|
&GNullWindowManagerVMT,
|
||||||
|
};
|
||||||
|
|
||||||
static void WM_Init(void) {
|
static void WM_Init(void) {
|
||||||
// We don't need to do anything here.
|
// We don't need to do anything here.
|
||||||
// A full window manager would move the windows around, add borders etc
|
// A full window manager would move the windows around, add borders etc
|
||||||
|
@ -163,48 +611,56 @@ static void WM_Delete(GHandle gh) {
|
||||||
gfxQueueASyncRemove(&_GWINList, &gh->wmq);
|
gfxQueueASyncRemove(&_GWINList, &gh->wmq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WM_Redraw(GHandle gh, int flags) {
|
static void WM_Redraw(GHandle gh) {
|
||||||
#if GWIN_NEED_CONTAINERS
|
#if GWIN_NEED_CONTAINERS
|
||||||
redo_redraw:
|
redo_redraw:
|
||||||
#endif
|
#endif
|
||||||
if ((gh->flags & GWIN_FLG_SYSVISIBLE)) {
|
if ((gh->flags & GWIN_FLG_SYSVISIBLE)) {
|
||||||
if (gh->vmt->Redraw) {
|
if (gh->vmt->Redraw)
|
||||||
#if GDISP_NEED_CLIP
|
|
||||||
if (!(flags & GWIN_WMFLG_KEEPCLIP))
|
|
||||||
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
|
||||||
#endif
|
|
||||||
gh->vmt->Redraw(gh);
|
gh->vmt->Redraw(gh);
|
||||||
} else if (!(flags & GWIN_WMFLG_PRESERVE)) {
|
else if ((gh->flags & GWIN_FLG_BGREDRAW)) {
|
||||||
#if GDISP_NEED_CLIP
|
// We can't redraw but we want full coverage so just clear the area
|
||||||
if (!(flags & GWIN_WMFLG_KEEPCLIP))
|
|
||||||
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
|
||||||
#endif
|
|
||||||
gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, gh->bgcolor);
|
gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, gh->bgcolor);
|
||||||
if (gh->vmt->AfterClear)
|
|
||||||
|
// Only do an after clear if this is not a parent reveal
|
||||||
|
if (!(gh->flags & GWIN_FLG_PARENTREVEAL) && gh->vmt->AfterClear)
|
||||||
gh->vmt->AfterClear(gh);
|
gh->vmt->AfterClear(gh);
|
||||||
}
|
}
|
||||||
|
|
||||||
// A real window manager would also redraw the borders here
|
// A real window manager would also redraw frame borders here for top level windows
|
||||||
|
// For non-top level windows their parent is responsible for any borders
|
||||||
|
|
||||||
// A real window manager would then redraw any higher z-order windows
|
// Redraw is done
|
||||||
// if (!(flags & GWIN_WMFLG_NOZORDER))
|
gh->flags &= ~(GWIN_FLG_NEEDREDRAW|GWIN_FLG_BGREDRAW|GWIN_FLG_PARENTREVEAL);
|
||||||
// ...
|
|
||||||
|
|
||||||
} else if (!(flags & GWIN_WMFLG_NOBGCLEAR)) {
|
#if GWIN_NEED_CONTAINERS
|
||||||
#if GDISP_NEED_CLIP
|
// If this is container but not a parent reveal, mark any visible children for redraw
|
||||||
if (!(flags & GWIN_WMFLG_KEEPCLIP))
|
// We redraw our children here as we have overwritten them in redrawing the parent
|
||||||
gdispGSetClip(gh->display, gh->x, gh->y, gh->width, gh->height);
|
// as GDISP/GWIN doesn't yet support complex clipping regions.
|
||||||
|
if ((gh->flags & (GWIN_FLG_CONTAINER|GWIN_FLG_PARENTREVEAL)) == GWIN_FLG_CONTAINER) {
|
||||||
|
for(gh = gwinGetFirstChild(gh); gh; gh = gwinGetSibling(gh))
|
||||||
|
_gwinUpdate(gh);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
} else {
|
||||||
|
if ((gh->flags & GWIN_FLG_BGREDRAW)) {
|
||||||
#if GWIN_NEED_CONTAINERS
|
#if GWIN_NEED_CONTAINERS
|
||||||
if (gh->parent) {
|
if (gh->parent) {
|
||||||
|
// Child redraw is done
|
||||||
|
gh->flags &= ~(GWIN_FLG_NEEDREDRAW|GWIN_FLG_BGREDRAW|GWIN_FLG_PARENTREVEAL);
|
||||||
|
|
||||||
// Get the parent to redraw the area
|
// Get the parent to redraw the area
|
||||||
gh = gh->parent;
|
gh = gh->parent;
|
||||||
flags |= GWIN_WMFLG_KEEPCLIP;
|
gh->flags |= (GWIN_FLG_BGREDRAW|GWIN_FLG_PARENTREVEAL);
|
||||||
goto redo_redraw;
|
goto redo_redraw;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, gwinGetDefaultBgColor());
|
gdispGFillArea(gh->display, gh->x, gh->y, gh->width, gh->height, gwinGetDefaultBgColor());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Redraw is done
|
||||||
|
gh->flags &= ~(GWIN_FLG_NEEDREDRAW|GWIN_FLG_BGREDRAW|GWIN_FLG_PARENTREVEAL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WM_Size(GHandle gh, coord_t w, coord_t h) {
|
static void WM_Size(GHandle gh, coord_t w, coord_t h) {
|
||||||
|
@ -234,15 +690,49 @@ static void WM_Size(GHandle gh, coord_t w, coord_t h) {
|
||||||
if (gh->width == w && gh->height == h)
|
if (gh->width == w && gh->height == h)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Clear the old area and then redraw
|
// Set the new size and redraw
|
||||||
if ((gh->flags & GWIN_FLG_SYSVISIBLE)) {
|
if ((gh->flags & GWIN_FLG_SYSVISIBLE)) {
|
||||||
gh->flags &= ~GWIN_FLG_SYSVISIBLE;
|
if (w >= gh->width && h >= gh->height) {
|
||||||
WM_Redraw(gh, 0);
|
|
||||||
|
// The new size is larger - just redraw
|
||||||
gh->width = w; gh->height = h;
|
gh->width = w; gh->height = h;
|
||||||
gh->flags |= GWIN_FLG_SYSVISIBLE;
|
_gwinUpdate(gh);
|
||||||
WM_Redraw(gh, 0);
|
|
||||||
|
} else {
|
||||||
|
// We need to make this window invisible and ensure that has been drawn
|
||||||
|
gwinSetVisible(gh, FALSE);
|
||||||
|
_gwinFlushRedraws(TRUE);
|
||||||
|
|
||||||
|
// Resize
|
||||||
|
gh->width = w; gh->height = h;
|
||||||
|
|
||||||
|
#if GWIN_NEED_CONTAINERS
|
||||||
|
// Any children outside the new area need to be moved
|
||||||
|
if ((gh->flags & GWIN_FLG_CONTAINER)) {
|
||||||
|
GHandle child;
|
||||||
|
|
||||||
|
// Move to their old relative location. THe WM_Move() will adjust as necessary
|
||||||
|
for(child = gwinGetFirstChild(gh); child; child = gwinGetSibling(child))
|
||||||
|
WM_Move(gh, child->x-gh->x-((const gcontainerVMT *)gh->parent->vmt)->LeftBorder(gh->parent), child->y-gh->y-((const gcontainerVMT *)gh->parent->vmt)->TopBorder(gh->parent));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Mark it visible again in its new location
|
||||||
|
gwinSetVisible(gh, TRUE);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
gh->width = w; gh->height = h;
|
gh->width = w; gh->height = h;
|
||||||
|
|
||||||
|
#if GWIN_NEED_CONTAINERS
|
||||||
|
// Any children outside the new area need to be moved
|
||||||
|
if ((gh->flags & GWIN_FLG_CONTAINER)) {
|
||||||
|
GHandle child;
|
||||||
|
|
||||||
|
// Move to their old relative location. THe WM_Move() will adjust as necessary
|
||||||
|
for(child = gwinGetFirstChild(gh); child; child = gwinGetSibling(child))
|
||||||
|
WM_Move(gh, child->x-gh->x-((const gcontainerVMT *)gh->parent->vmt)->LeftBorder(gh->parent), child->y-gh->y-((const gcontainerVMT *)gh->parent->vmt)->TopBorder(gh->parent));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,13 +769,40 @@ static void WM_Move(GHandle gh, coord_t x, coord_t y) {
|
||||||
|
|
||||||
// Clear the old area and then redraw
|
// Clear the old area and then redraw
|
||||||
if ((gh->flags & GWIN_FLG_SYSVISIBLE)) {
|
if ((gh->flags & GWIN_FLG_SYSVISIBLE)) {
|
||||||
gh->flags &= ~GWIN_FLG_SYSVISIBLE;
|
// We need to make this window invisible and ensure that has been drawn
|
||||||
WM_Redraw(gh, 0);
|
gwinSetVisible(gh, FALSE);
|
||||||
gh->x = x; gh->y = y;
|
_gwinFlushRedraws(TRUE);
|
||||||
gh->flags |= GWIN_FLG_SYSVISIBLE;
|
|
||||||
WM_Redraw(gh, 0);
|
// Do the move
|
||||||
|
v = gh->x; gh->x = x; x = v;
|
||||||
|
v = gh->y; gh->y = y; y = v;
|
||||||
|
|
||||||
|
#if GWIN_NEED_CONTAINERS
|
||||||
|
// Any children need to be moved
|
||||||
|
if ((gh->flags & GWIN_FLG_CONTAINER)) {
|
||||||
|
GHandle child;
|
||||||
|
|
||||||
|
// Move to their old relative location. THe WM_Move() will adjust as necessary
|
||||||
|
for(child = gwinGetFirstChild(gh); child; child = gwinGetSibling(child))
|
||||||
|
WM_Move(gh, child->x-x-((const gcontainerVMT *)gh->parent->vmt)->LeftBorder(gh->parent), child->y-y-((const gcontainerVMT *)gh->parent->vmt)->TopBorder(gh->parent));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
gwinSetVisible(gh, TRUE);
|
||||||
} else {
|
} else {
|
||||||
gh->x = x; gh->y = y;
|
v = gh->x; gh->x = x; x = v;
|
||||||
|
v = gh->y; gh->y = y; y = v;
|
||||||
|
|
||||||
|
#if GWIN_NEED_CONTAINERS
|
||||||
|
// Any children need to be moved
|
||||||
|
if ((gh->flags & GWIN_FLG_CONTAINER)) {
|
||||||
|
GHandle child;
|
||||||
|
|
||||||
|
// Move to their old relative location. THe WM_Move() will adjust as necessary
|
||||||
|
for(child = gwinGetFirstChild(gh); child; child = gwinGetSibling(child))
|
||||||
|
WM_Move(gh, child->x-x-((const gcontainerVMT *)gh->parent->vmt)->LeftBorder(gh->parent), child->y-y-((const gcontainerVMT *)gh->parent->vmt)->TopBorder(gh->parent));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,11 +819,7 @@ static void WM_Raise(GHandle gh) {
|
||||||
gfxQueueASyncPut(&_GWINList, &gh->wmq);
|
gfxQueueASyncPut(&_GWINList, &gh->wmq);
|
||||||
|
|
||||||
// Redraw the window
|
// Redraw the window
|
||||||
WM_Redraw(gh, GWIN_WMFLG_PRESERVE|GWIN_WMFLG_NOBGCLEAR);
|
_gwinUpdate(gh);
|
||||||
}
|
|
||||||
|
|
||||||
GHandle gwinGetNextWindow(GHandle gh) {
|
|
||||||
return gh ? (GHandle)gfxQueueASyncNext(&gh->wmq) : (GHandle)gfxQueueASyncPeek(&_GWINList);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* GFX_USE_GWIN && GWIN_NEED_WINDOWMANAGER */
|
#endif /* GFX_USE_GWIN && GWIN_NEED_WINDOWMANAGER */
|
||||||
|
|
|
@ -102,7 +102,7 @@ static void gwinListDefaultDraw(GWidgetObject* gw, void* param);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_gwidgetUpdate(&gw->g);
|
_gwinUpdate(&gw->g);
|
||||||
sendListEvent(gw, item);
|
sendListEvent(gw, item);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -131,14 +131,14 @@ static void gwinListDefaultDraw(GWidgetObject* gw, void* param);
|
||||||
gw2obj->top -= iheight;
|
gw2obj->top -= iheight;
|
||||||
if (gw2obj->top < 0)
|
if (gw2obj->top < 0)
|
||||||
gw2obj->top = 0;
|
gw2obj->top = 0;
|
||||||
_gwidgetUpdate(&gw->g);
|
_gwinUpdate(&gw->g);
|
||||||
}
|
}
|
||||||
} else if (y >= gw->g.height - 2*ARROW) {
|
} else if (y >= gw->g.height - 2*ARROW) {
|
||||||
if (gw2obj->top < gw2obj->cnt * iheight - pgsz) {
|
if (gw2obj->top < gw2obj->cnt * iheight - pgsz) {
|
||||||
gw2obj->top += iheight;
|
gw2obj->top += iheight;
|
||||||
if (gw2obj->top > gw2obj->cnt * iheight - pgsz)
|
if (gw2obj->top > gw2obj->cnt * iheight - pgsz)
|
||||||
gw2obj->top = gw2obj->cnt * iheight - pgsz;
|
gw2obj->top = gw2obj->cnt * iheight - pgsz;
|
||||||
_gwidgetUpdate(&gw->g);
|
_gwinUpdate(&gw->g);
|
||||||
}
|
}
|
||||||
} else if (y < gw->g.height/2) {
|
} else if (y < gw->g.height/2) {
|
||||||
if (gw2obj->top > 0) {
|
if (gw2obj->top > 0) {
|
||||||
|
@ -146,7 +146,7 @@ static void gwinListDefaultDraw(GWidgetObject* gw, void* param);
|
||||||
gw2obj->top -= pgsz;
|
gw2obj->top -= pgsz;
|
||||||
else
|
else
|
||||||
gw2obj->top = 0;
|
gw2obj->top = 0;
|
||||||
_gwidgetUpdate(&gw->g);
|
_gwinUpdate(&gw->g);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (gw2obj->top < gw2obj->cnt * iheight - pgsz) {
|
if (gw2obj->top < gw2obj->cnt * iheight - pgsz) {
|
||||||
|
@ -154,7 +154,7 @@ static void gwinListDefaultDraw(GWidgetObject* gw, void* param);
|
||||||
gw2obj->top += pgsz;
|
gw2obj->top += pgsz;
|
||||||
else
|
else
|
||||||
gw2obj->top = gw2obj->cnt * iheight - pgsz;
|
gw2obj->top = gw2obj->cnt * iheight - pgsz;
|
||||||
_gwidgetUpdate(&gw->g);
|
_gwinUpdate(&gw->g);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -192,7 +192,7 @@ static void gwinListDefaultDraw(GWidgetObject* gw, void* param);
|
||||||
gw2obj->top = 0;
|
gw2obj->top = 0;
|
||||||
gw2obj->last_mouse_y = y;
|
gw2obj->last_mouse_y = y;
|
||||||
if (oldtop != gw2obj->top)
|
if (oldtop != gw2obj->top)
|
||||||
_gwidgetUpdate(&gw->g);
|
_gwinUpdate(&gw->g);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -213,7 +213,7 @@ static void gwinListDefaultDraw(GWidgetObject* gw, void* param);
|
||||||
if (qix) {
|
if (qix) {
|
||||||
qi2li->flags &=~ GLIST_FLG_SELECTED;
|
qi2li->flags &=~ GLIST_FLG_SELECTED;
|
||||||
qix2li->flags |= GLIST_FLG_SELECTED;
|
qix2li->flags |= GLIST_FLG_SELECTED;
|
||||||
_gwidgetUpdate(&gw->g);
|
_gwinUpdate(&gw->g);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -230,7 +230,7 @@ static void gwinListDefaultDraw(GWidgetObject* gw, void* param);
|
||||||
if (qix) {
|
if (qix) {
|
||||||
qi2li->flags &=~ GLIST_FLG_SELECTED;
|
qi2li->flags &=~ GLIST_FLG_SELECTED;
|
||||||
qix2li->flags |= GLIST_FLG_SELECTED;
|
qix2li->flags |= GLIST_FLG_SELECTED;
|
||||||
_gwidgetUpdate(&gw->g);
|
_gwinUpdate(&gw->g);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -383,7 +383,7 @@ int gwinListAddItem(GHandle gh, const char* item_name, bool_t useAlloc) {
|
||||||
// increment the total amount of entries in the list widget
|
// increment the total amount of entries in the list widget
|
||||||
gh2obj->cnt++;
|
gh2obj->cnt++;
|
||||||
|
|
||||||
_gwidgetUpdate(gh);
|
_gwinUpdate(gh);
|
||||||
|
|
||||||
// return the position in the list (-1 because we start with index 0)
|
// return the position in the list (-1 because we start with index 0)
|
||||||
return gh2obj->cnt-1;
|
return gh2obj->cnt-1;
|
||||||
|
@ -481,7 +481,7 @@ void gwinListDeleteAll(GHandle gh) {
|
||||||
gh->flags &= ~GLIST_FLG_HASIMAGES;
|
gh->flags &= ~GLIST_FLG_HASIMAGES;
|
||||||
gh2obj->cnt = 0;
|
gh2obj->cnt = 0;
|
||||||
gh2obj->top = 0;
|
gh2obj->top = 0;
|
||||||
_gwidgetUpdate(gh);
|
_gwinUpdate(gh);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gwinListItemDelete(GHandle gh, int item) {
|
void gwinListItemDelete(GHandle gh, int item) {
|
||||||
|
@ -502,7 +502,7 @@ void gwinListItemDelete(GHandle gh, int item) {
|
||||||
gfxFree((void *)qi);
|
gfxFree((void *)qi);
|
||||||
if (gh2obj->top >= item && gh2obj->top)
|
if (gh2obj->top >= item && gh2obj->top)
|
||||||
gh2obj->top--;
|
gh2obj->top--;
|
||||||
_gwidgetUpdate(gh);
|
_gwinUpdate(gh);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,7 +123,7 @@ void gwinProgressbarSetPosition(GHandle gh, int pos) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ResetDisplayPos(gsw);
|
ResetDisplayPos(gsw);
|
||||||
_gwidgetUpdate(gh);
|
_gwinUpdate(gh);
|
||||||
|
|
||||||
#undef gsw
|
#undef gsw
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,7 @@ void gwinProgressbarIncrement(GHandle gh) {
|
||||||
gsw->pos = gsw->max;
|
gsw->pos = gsw->max;
|
||||||
|
|
||||||
ResetDisplayPos(gsw);
|
ResetDisplayPos(gsw);
|
||||||
_gwidgetUpdate(gh);
|
_gwinUpdate(gh);
|
||||||
|
|
||||||
#undef gsw
|
#undef gsw
|
||||||
}
|
}
|
||||||
|
@ -173,7 +173,7 @@ void gwinProgressbarDecrement(GHandle gh) {
|
||||||
gsw->pos -= gsw->res;
|
gsw->pos -= gsw->res;
|
||||||
|
|
||||||
ResetDisplayPos(gsw);
|
ResetDisplayPos(gsw);
|
||||||
_gwidgetUpdate(gh);
|
_gwinUpdate(gh);
|
||||||
|
|
||||||
#undef gsw
|
#undef gsw
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,10 +128,10 @@ void gwinRadioPress(GHandle gh) {
|
||||||
|
|
||||||
if ((gx = gwinRadioGetActive(((GRadioObject *)gh)->group))) {
|
if ((gx = gwinRadioGetActive(((GRadioObject *)gh)->group))) {
|
||||||
gx->flags &= ~GRADIO_FLG_PRESSED;
|
gx->flags &= ~GRADIO_FLG_PRESSED;
|
||||||
_gwidgetUpdate(gx);
|
_gwinUpdate(gx);
|
||||||
}
|
}
|
||||||
gh->flags |= GRADIO_FLG_PRESSED;
|
gh->flags |= GRADIO_FLG_PRESSED;
|
||||||
_gwidgetUpdate(gh);
|
_gwinUpdate(gh);
|
||||||
SendRadioEvent((GWidgetObject *)gh);
|
SendRadioEvent((GWidgetObject *)gh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,7 @@ static void ResetDisplayPos(GSliderObject *gsw) {
|
||||||
if (x < 0 || x >= gh->width || y < 0 || y >= gh->height) {
|
if (x < 0 || x >= gh->width || y < 0 || y >= gh->height) {
|
||||||
// No - restore the slider
|
// No - restore the slider
|
||||||
ResetDisplayPos(gsw);
|
ResetDisplayPos(gsw);
|
||||||
_gwidgetUpdate(gh);
|
_gwinUpdate(gh);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -92,7 +92,7 @@ static void ResetDisplayPos(GSliderObject *gsw) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ResetDisplayPos(gsw);
|
ResetDisplayPos(gsw);
|
||||||
_gwidgetUpdate(gh);
|
_gwinUpdate(gh);
|
||||||
|
|
||||||
// Generate the event
|
// Generate the event
|
||||||
SendSliderEvent(gw);
|
SendSliderEvent(gw);
|
||||||
|
@ -122,7 +122,7 @@ static void ResetDisplayPos(GSliderObject *gsw) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the display
|
// Update the display
|
||||||
_gwidgetUpdate(&gw->g);
|
_gwinUpdate(&gw->g);
|
||||||
#undef gsw
|
#undef gsw
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -164,7 +164,7 @@ static void ResetDisplayPos(GSliderObject *gsw) {
|
||||||
gsw->pos = (uint16_t)((uint32_t)value*(gsw->max-gsw->min)/max + gsw->min);
|
gsw->pos = (uint16_t)((uint32_t)value*(gsw->max-gsw->min)/max + gsw->min);
|
||||||
|
|
||||||
ResetDisplayPos(gsw);
|
ResetDisplayPos(gsw);
|
||||||
_gwidgetUpdate((GHandle)gw);
|
_gwinUpdate((GHandle)gw);
|
||||||
|
|
||||||
// Generate the event
|
// Generate the event
|
||||||
SendSliderEvent(gw);
|
SendSliderEvent(gw);
|
||||||
|
@ -267,7 +267,7 @@ void gwinSliderSetPosition(GHandle gh, int pos) {
|
||||||
else gsw->pos = pos;
|
else gsw->pos = pos;
|
||||||
}
|
}
|
||||||
ResetDisplayPos(gsw);
|
ResetDisplayPos(gsw);
|
||||||
_gwidgetUpdate(gh);
|
_gwinUpdate(gh);
|
||||||
|
|
||||||
#undef gsw
|
#undef gsw
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue