Posted
over 9 years
ago
by
Agar-SVN
Author: vedge
Date: 2015-02-19 10:06:48 -0500 (Thu, 19 Feb 2015)
New Revision: 9767
Modified:
trunk/core/error.c
Log:
if USE_WIN32_CONSOLE is defined (not default), use AttachConsole() and
redirect AG_Verbose() / AG_Debug() output to the parent
... [More]
process's console..
Modified: trunk/core/error.c
===================================================================
--- trunk/core/error.c2015-02-12 13:12:43 UTC (rev 9766)
trunk/core/error.c2015-02-19 15:06:48 UTC (rev 9767)
< at >< at > -1,5 1,5 < at >< at >
/*
- * Copyright (c) 2002-2012 Hypertriton, Inc. <http://hypertriton.com/>
* Copyright (c) 2002-2015 Hypertriton, Inc. <http://hypertriton.com/>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
< at >< at > -45,6 45,15 < at >< at >
AG_ThreadKey agErrorCodeKey;
#endif
/* Redirect Verbose() output to "foo-out.txt" file */
/* #define VERBOSE_TO_FILE */
/* Redirect Debug() output to "foo-debug.txt" file */
/* #define DEBUG_TO_FILE */
/* Use AttachConsole() on Windows */
/* #define USE_WIN32_CONSOLE */
int agDebugLvl = 1;/* Default debug level */
static void (*agErrorCallback)(const char *) = NULL;
< at >< at > -69,12 78,19 < at >< at >
AG_ThreadKeySet(agErrorMsgKey, NULL);
AG_ThreadKeySet(agErrorCodeKey, NULL);
#endif
#if defined(_WIN32) && defined(USE_WIN32_CONSOLE)
AttachConsole(ATTACH_PARENT_PROCESS);
#endif
return (0);
}
void
AG_DestroyErrorSubsystem(void)
{
#if defined(_WIN32) && defined(USE_WIN32_CONSOLE)
FreeConsole();
#endif
Free(agErrorMsg);
agErrorMsg = NULL;
agErrorCode = AG_EUNDEFINED;
< at >< at > -121,7 137,7 < at >< at >
const char *
AG_Strerror(int error)
{
-#if defined(_WIN32) && !defined (_XBOX)
#if defined(_WIN32) && !defined(_XBOX)
static char *str = NULL;
char *p;
< at >< at > -193,7 209,8 < at >< at >
}
if (agDebugLvl >= 1 || (obj != NULL && OBJECT_DEBUG(obj))) {
va_start(args, fmt);
-# ifdef _WIN32
# if defined(DEBUG_TO_FILE)
/* Redirect output to foo-debug.txt */
{
char path[AG_FILENAME_MAX];
FILE *f;
< at >< at > -205,10 222,35 < at >< at >
Strlcpy(path, "debug.txt", sizeof(path));
}
if ((f = fopen(path, "a")) != NULL) {
if (obj != NULL) {
if (OBJECT(obj)->name[0] != '\0') {
fprintf(f, "%s: ", OBJECT(obj)->name);
} else {
fprintf(f, "<%p>: ", obj);
}
}
vfprintf(f, fmt, args);
fclose(f);
}
}
# elif defined(_WIN32) && defined(USE_WIN32_CONSOLE)
{
HANDLE cons;
char *buf;
cons = GetStdHandle(STD_ERROR_HANDLE);
if (cons != NULL && cons != INVALID_HANDLE_VALUE) {
if (obj != NULL &&
OBJECT(obj)->name[0] != '\0') {
WriteConsole(cons, OBJECT(obj)->name,
strlen(OBJECT(obj)->name), NULL, NULL);
WriteConsole(cons, ": ", 2, NULL, NULL);
}
Vasprintf(&buf, fmt, args);
WriteConsole(cons, buf, strlen(buf), NULL, NULL);
free(buf);
}
}
# else /* _WIN32 */
if (obj != NULL) {
if (OBJECT(obj)->name[0] != '\0') {
< at >< at > -218,7 260,7 < at >< at >
}
}
vprintf(fmt, args);
-# endif /* !_WIN32 */
#endif
va_end(args);
}
#endif /* AG_DEBUG */
< at >< at > -246,7 288,8 < at >< at >
}
va_start(args, fmt);
-#ifdef _WIN32
#if defined(VERBOSE_TO_FILE)
/* Redirect output to foo-out.txt */
{
char path[AG_FILENAME_MAX];
FILE *f;
< at >< at > -262,6 305,18 < at >< at >
fclose(f);
}
}
#elif defined(_WIN32) && defined(USE_WIN32_CONSOLE)
{
HANDLE cons;
char *buf;
cons = GetStdHandle(STD_ERROR_HANDLE);
if (cons != NULL && cons != INVALID_HANDLE_VALUE) {
Vasprintf(&buf, fmt, args);
WriteConsole(cons, buf, strlen(buf), NULL, NULL);
free(buf);
}
}
#else
vprintf(fmt, args);
#endif
[Less]
|
Posted
over 9 years
ago
by
Agar-SVN
Author: vedge
Date: 2015-02-12 08:12:43 -0500 (Thu, 12 Feb 2015)
New Revision: 9766
Modified:
trunk/gui/window.c
Log:
- clean up detach-related code. in Detach(), insert the window in both Hide
and Detach queues.
- send widget "detached"
... [More]
notification in event context, after the detach has
been processed.
- update window's AG_WIDGET_VISIBLE flag in addition to "visible" member.
- remove redundant locks in AG_WindowProcess*Queue().
- in AG_WindowShow() / AG_WindowHide(), acquire the agDrivers VFS lock in
addition to the window's lock.
Modified: trunk/gui/window.c
===================================================================
--- trunk/gui/window.c2015-02-12 12:53:16 UTC (rev 9765)
trunk/gui/window.c2015-02-12 13:12:43 UTC (rev 9766)
< at >< at > -1,5 1,5 < at >< at >
/*
- * Copyright (c) 2001-2012 Hypertriton, Inc. <http://hypertriton.com/>
* Copyright (c) 2001-2015 Hypertriton, Inc. <http://hypertriton.com/>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
< at >< at > -69,6 69,9 < at >< at >
"_NET_WM_WINDOW_TYPE_DND"
};
/* #define DEBUG_VISIBILITY */
/* #define DEBUG_FOCUS */
void
AG_InitWindowSystem(void)
{
< at >< at > -285,7 288,7 < at >< at >
{
AG_Window *win = AG_SELF();
AG_Driver *drv = OBJECT(win)->parent, *odrv;
-AG_Window *owin, *subwin;
AG_Window *other, *subwin;
AG_Timer *to, *toNext;
#ifdef AG_DEBUG
< at >< at > -297,10 300,6 < at >< at >
/* Mark window detach in progress */
win->flags |= AG_WINDOW_DETACHING;
-/* Cancel any planned focus change to this window. */
-if (win == agWindowToFocus)
-agWindowToFocus = NULL;
-
/* Cancel any running timer attached to the window. */
AG_LockTiming();
for (to = TAILQ_FIRST(&OBJECT(win)->timers);
< at >< at > -310,48 309,40 < at >< at >
AG_DelTimer(win, to);
}
AG_UnlockTiming();
-
-if (win->visible)
-AG_WindowHide(win);
/* Implicitely detach window dependencies. */
AGOBJECT_FOREACH_CHILD(odrv, &agDrivers, ag_driver) {
-AG_FOREACH_WINDOW(owin, odrv) {
-if (owin == win) {
AG_FOREACH_WINDOW(other, odrv) {
if (other == win) {
continue;
}
-if (owin->parent == win) {
-AG_ObjectDetach(owin);
-}
-TAILQ_FOREACH(subwin, &owin->subwins, swins) {
AG_ObjectLock(other);
TAILQ_FOREACH(subwin, &other->subwins, swins) {
if (subwin == win)
break;
}
-if (subwin != NULL)
-TAILQ_REMOVE(&owin->subwins, subwin, swins);
if (subwin != NULL) {
TAILQ_REMOVE(&other->subwins, subwin, swins);
}
if (other->pinnedTo == win) {
AG_WindowUnpin(other);
}
if (other->parent == win ||
other->transientFor == win) {
AG_ObjectDetach(other);
}
AG_ObjectUnlock(other);
}
}
-#if 1
-goto out;
-#endif
-/* if (AGDRIVER_SINGLE(drv)) { */
-win->tbar = NULL;/* No longer safe to use */
-win->icon = NULL;
-/* } */
-
-/*
- * Notify all child widgets of the window detach request. Widgets will
- * acknowledge the request by resetting their drv and drvOps to NULL.
- */
-AG_PostEvent(drv, win, "detached", NULL);
/*
- * For a window detach operation to be free-threaded and safe in event
- * context, the window list cannot be directly altered. We place the
- * window in a detach queue which will be processed at the end of the
- * event processing cycle.
* For the AG_ObjectDetach() call to be safe in (free-threaded) event
* context, we must defer the actual window hide / detach operation
* until the end of the current event processing cycle.
*/
TAILQ_INSERT_TAIL(&agWindowHideQ, win, visibility);
TAILQ_INSERT_TAIL(&agWindowDetachQ, win, detach);
-out:
AG_UnlockVFS(&agDrivers);
}
< at >< at > -377,6 368,8 < at >< at >
return (to->ival);
} else {
AG_WindowSetOpacity(win, 1.0);
/* Defer operation until AG_WindowProcessQueued(). */
AG_LockVFS(&agDrivers);
TAILQ_INSERT_TAIL(&agWindowHideQ, win, visibility);
AG_UnlockVFS(&agDrivers);
< at >< at > -707,6 700,12 < at >< at >
Uint mwFlags = 0;
AG_Variable V;
#ifdef DEBUG_VISIBILITY
Debug(win, "Window \"%s\" now visible\n", win->caption);
#endif
win->visible = 1;
WIDGET(win)->flags |= AG_WIDGET_VISIBLE;
/* Compile the globally inheritable style attributes. */
AG_WidgetCompileStyle(win);
< at >< at > -750,15 749,14 < at >< at >
switch (AGDRIVER_CLASS(drv)->wm) {
case AG_WM_SINGLE:
-if (win->flags & AG_WINDOW_MODAL) {
-/* Use the per-driver modal window stack. */
if (win->flags & AG_WINDOW_MODAL) {/* Per-driver stack */
AG_InitPointer(&V, win);
AG_ListAppend(AGDRIVER_SW(drv)->Lmodal, &V);
}
AG_WidgetUpdateCoords(win, WIDGET(win)->x, WIDGET(win)->y);
break;
case AG_WM_MULTIPLE:
-if (win->flags & AG_WINDOW_MODAL) {
if (win->flags & AG_WINDOW_MODAL) {/* Global stack */
AG_InitPointer(&V, win);
AG_ListAppend(agModalWindows, &V);
}
< at >< at > -783,15 781,15 < at >< at >
}
break;
}
-
-if (!(win->flags & AG_WINDOW_DENYFOCUS))
-AG_WindowFocus(win);
-/* Notify that the window is now visible. */
/* Notify widgets that the window is now visible. */
AG_PostEvent(NULL, win, "window-shown", NULL);
-/* Assume we gained focus. XXX */
-AG_PostEvent(NULL, win, "window-gainfocus", NULL);
/* Implicit focus change. */
if (!(win->flags & AG_WINDOW_DENYFOCUS)) {
agWindowFocused = win;
AG_PostEvent(NULL, win, "window-gainfocus", NULL);
}
/* Mark for redraw */
win->dirty = 1;
< at >< at > -813,16 811,23 < at >< at >
AG_Driver *drv = WIDGET(win)->drv;
AG_DriverSw *dsw;
int i;
-
-/* Cancel any pending redraw. */
#ifdef DEBUG_VISIBILITY
Debug(win, "Window \"%s\" now hidden\n", win->caption);
#endif
win->visible = 0;
WIDGET(win)->flags &= ~(AG_WIDGET_VISIBLE);
win->dirty = 0;
win->flags |= AG_WINDOW_NOCURSORCHG;
-/* Disallow cursor changes. */
-win->flags |= AG_WINDOW_NOCURSORCHG;
-
-/* Cancel any pending focus change to this window. */
-if (win == agWindowToFocus)
/* Cancel focus state or any focus change requests. */
if (win == agWindowToFocus) {
agWindowToFocus = NULL;
}
if (win == agWindowFocused) {
AG_PostEvent(NULL, win, "window-lostfocus", NULL);
agWindowFocused = NULL;
}
switch (AGDRIVER_CLASS(drv)->wm) {
case AG_WM_SINGLE:
< at >< at > -831,8 836,7 < at >< at >
if (OBJECT(drv)->parent == NULL)
break;
-if (win->flags & AG_WINDOW_MODAL) {
-/* Remove from per-driver modal window stack. */
if (win->flags & AG_WINDOW_MODAL) {/* Per-driver stack */
for (i = 0; i < dsw->Lmodal->n; i ) {
if (dsw->Lmodal->v[i].data.p == win)
break;
< at >< at > -841,7 845,6 < at >< at >
AG_ListRemove(dsw->Lmodal, i);
}
if (AGDRIVER_CLASS(drv)->type == AG_FRAMEBUFFER) {
-/* Update the background. */
AG_DrawRectFilled(win,
AG_RECT(0,0, WIDTH(win), HEIGHT(win)), dsw->bgColor);
if (AGDRIVER_CLASS(drv)->updateRegion != NULL)
< at >< at > -851,8 854,7 < at >< at >
}
break;
case AG_WM_MULTIPLE:
-if (win->flags & AG_WINDOW_MODAL) {
-/* Remove from global modal window stack. */
if (win->flags & AG_WINDOW_MODAL) {/* Global stack */
for (i = 0; i < agModalWindows->n; i ) {
if (agModalWindows->v[i].data.p == win)
break;
< at >< at > -866,6 868,8 < at >< at >
}
break;
}
/* Notify widgets that the window is now hidden. */
AG_PostEvent(NULL, win, "window-hidden", NULL);
}
< at >< at > -900,19 904,30 < at >< at >
static void
OnFocusGain(AG_Event *event)
{
-WidgetGainFocus(WIDGET(AG_SELF()));
AG_Window *win = AG_SELF();
#ifdef DEBUG_FOCUS
Debug(win, "Window \"%s\" gained focus\n", win->caption);
#endif
WidgetGainFocus(WIDGET(win));
}
static void
OnFocusLoss(AG_Event *event)
{
-WidgetLostFocus(WIDGET(AG_SELF()));
AG_Window *win = AG_SELF();
#ifdef DEBUG_FOCUS
Debug(win, "Window \"%s\" lost focus\n", win->caption);
#endif
WidgetLostFocus(WIDGET(win));
}
/* Make a window visible to the user. */
void
AG_WindowShow(AG_Window *win)
{
AG_LockVFS(&agDrivers);
AG_ObjectLock(win);
if (!win->visible) {
#ifdef AG_THREADS
< at >< at > -924,40 939,44 < at >< at >
#endif
{
AG_PostEvent(NULL, win, "widget-shown", NULL);
-win->visible = 1;
-WIDGET(win)->flags |= AG_WIDGET_VISIBLE;
}
}
AG_ObjectUnlock(win);
AG_UnlockVFS(&agDrivers);
}
/* Make a window invisible to the user. */
void
AG_WindowHide(AG_Window *win)
{
AG_LockVFS(&agDrivers);
AG_ObjectLock(win);
-if (win->visible) {
-if ((win->flags & AG_WINDOW_FADEOUT) &&
- !(win->flags & AG_WINDOW_DETACHING)) {
-AG_AddTimer(win, &win->fadeTo,
- (Uint32)((win->fadeOutTime*1000.0)/(1.0/win->fadeOutIncr)),
- FadeTimeout, "%i", -1);
-} else {
if (!win->visible) {
goto out;
}
if ((win->flags & AG_WINDOW_FADEOUT) &&
!(win->flags & AG_WINDOW_DETACHING)) {
AG_AddTimer(win, &win->fadeTo,
(Uint32)((win->fadeOutTime*1000.0)/(1.0/win->fadeOutIncr)),
FadeTimeout, "%i", -1);
} else {
#ifdef AG_THREADS
-if (!AG_ThreadEqual(AG_ThreadSelf(), agEventThread)) {
-AG_LockVFS(&agDrivers);
-TAILQ_INSERT_TAIL(&agWindowHideQ, win, visibility);
-AG_UnlockVFS(&agDrivers);
-} else
if (!AG_ThreadEqual(AG_ThreadSelf(), agEventThread)) {
AG_LockVFS(&agDrivers);
TAILQ_INSERT_TAIL(&agWindowHideQ, win, visibility);
AG_UnlockVFS(&agDrivers);
} else
#endif
-{
-AG_PostEvent(NULL, win, "widget-hidden", NULL);
-win->visible = 0;
-WIDGET(win)->flags &= ~(AG_WIDGET_VISIBLE);
-}
{
AG_PostEvent(NULL, win, "widget-hidden", NULL);
win->visible = 0;
WIDGET(win)->flags &= ~(AG_WIDGET_VISIBLE);
}
}
out:
AG_ObjectUnlock(win);
AG_UnlockVFS(&agDrivers);
}
/* Build an ordered list of the focusable widgets in a window. */
< at >< at > -1040,11 1059,8 < at >< at >
}
/*
- * Give focus to a window. For single-window drivers, the operation only takes
- * effect at the end of the current event cycle. For multiple-window drivers,
- * the change takes effect immediately. If the window is not attached to a
- * driver, the operation is deferred until the next attach. If NULL is given,
- * cancel any planned focus change.
* Give input focus to a window. The actual focus change will take effect at
* the end of the current event cycle.
*/
void
AG_WindowFocus(AG_Window *win)
< at >< at > -1107,8 1123,8 < at >< at >
}
/*
- * Place focus on a Window following a click at the given coordinates,
- * in the video context of a specified single-display driver.
* Focus the window at specified display coordinates x,y
* (single-window drivers only).
*
* Returns 1 if the focus state has changed as a result.
*/
< at >< at > -1117,8 1133,11 < at >< at >
{
AG_Window *win;
AG_LockVFS(&agDrivers);
AG_ASSERT_CLASS(dsw, "AG_Driver:AG_DriverSw:*");
agWindowToFocus = NULL;
AG_FOREACH_WINDOW_REVERSE(win, dsw) {
AG_ObjectLock(win);
if (!win->visible ||
< at >< at > -1129,8 1148,10 < at >< at >
}
agWindowToFocus = win;
AG_ObjectUnlock(win);
AG_UnlockVFS(&agDrivers);
return (1);
}
AG_UnlockVFS(&agDrivers);
return (0);
}
< at >< at > -1888,43 1909,40 < at >< at >
agWindowToFocus = NULL;
}
-/* Make windows on the show queue visible. */
/*
* Make windows on the show queue visible.
* The agDrivers VFS must be locked.
*/
void
AG_WindowProcessShowQueue(void)
{
-AG_Window *win, *winNext;
AG_Window *win;
-AG_LockVFS(&agDrivers);
-for (win = TAILQ_FIRST(&agWindowShowQ);
- win != TAILQ_END(&agWindowShowQ);
- win = winNext) {
-winNext = TAILQ_NEXT(win, visibility);
TAILQ_FOREACH(win, &agWindowShowQ, visibility) {
AG_PostEvent(NULL, win, "widget-shown", NULL);
-win->visible = 1;
}
TAILQ_INIT(&agWindowShowQ);
-AG_UnlockVFS(&agDrivers);
}
-/* Make windows on the hide queue invisible. */
/*
* Make windows on the hide queue invisible.
* The agDrivers VFS must be locked.
*/
void
AG_WindowProcessHideQueue(void)
{
-AG_Window *win, *winNext;
AG_Window *win;
-AG_LockVFS(&agDrivers);
-for (win = TAILQ_FIRST(&agWindowHideQ);
- win != TAILQ_END(&agWindowHideQ);
- win = winNext) {
-winNext = TAILQ_NEXT(win, visibility);
-win->visible = 0;
TAILQ_FOREACH(win, &agWindowHideQ, visibility) {
AG_PostEvent(NULL, win, "widget-hidden", NULL);
}
TAILQ_INIT(&agWindowHideQ);
-AG_UnlockVFS(&agDrivers);
}
-/* Close and destroy windows on the detach queue. */
/*
* Close and destroy windows on the detach queue.
* The agDrivers VFS must be locked.
*/
void
AG_WindowProcessDetachQueue(void)
{
< at >< at > -1932,38 1950,39 < at >< at >
AG_Driver *drv;
int closedMain = 0;
-AG_LockVFS(&agDrivers);
for (win = TAILQ_FIRST(&agWindowDetachQ);
win != TAILQ_END(&agWindowDetachQ);
win = winNext) {
winNext = TAILQ_NEXT(win, detach);
drv = WIDGET(win)->drv;
-/* Cancel any planned focus change to this window. */
-if (win == agWindowFocused)
-agWindowFocused = NULL;
#ifdef AG_DEBUG
if (win->visible) { AG_FatalError("Detach on visible window"); }
#endif
/* Notify all widgets of the window detach. */
AG_PostEvent(drv, win, "detached", NULL);
/* Release the cursor areas and associated cursors. */
AG_UnmapAllCursors(win, NULL);
-
-/* Close the associated window in MW mode. */
-drv = WIDGET(win)->drv;
-if (AGDRIVER_MULTIPLE(drv) &&
- AGDRIVER_MW(drv)->flags & AG_DRIVER_MW_OPEN) {
-AGDRIVER_MW_CLASS(drv)->closeWindow(win);
-AGDRIVER_MW(drv)->flags &= ~(AG_DRIVER_MW_OPEN);
if (AGDRIVER_MULTIPLE(drv)) {
if (AGDRIVER_MW(drv)->flags & AG_DRIVER_MW_OPEN) {
AGDRIVER_MW_CLASS(drv)->closeWindow(win);
AGDRIVER_MW(drv)->flags &= ~(AG_DRIVER_MW_OPEN);
}
} else {
win->tbar = NULL;/* No longer safe to use */
win->icon = NULL;
}
-/* Remove the Window detach handler and free the object. */
/* We can now perform the standard AG_ObjectDetach(). */
AG_ObjectSetDetachFn(win, NULL, NULL);
AG_ObjectDetach(win);
if (AGDRIVER_MULTIPLE(drv)) {
-/*
- * In multiple-window mode, free the driver instance
- * associated with the window.
- */
AG_UnlockVFS(&agDrivers);
-AG_DriverClose(drv);
AG_DriverClose(drv);/* Free this driver instance */
AG_LockVFS(&agDrivers);
}
if (win->flags & AG_WINDOW_MAIN) {
< at >< at > -1986,7 2005,6 < at >< at >
AG_Terminate(0);
}
}
-AG_UnlockVFS(&agDrivers);
}
int
[Less]
|
Posted
over 9 years
ago
by
Agar-SVN
Author: vedge
Date: 2015-02-12 07:53:16 -0500 (Thu, 12 Feb 2015)
New Revision: 9765
Modified:
trunk/gui/widget.c
Log:
add missing lock in AG_WidgetShow() / AG_WidgetHide()
Modified: trunk/gui/widget.c
... [More]
===================================================================
--- trunk/gui/widget.c2015-02-12 12:52:41 UTC (rev 9764)
+++ trunk/gui/widget.c2015-02-12 12:53:16 UTC (rev 9765)
< at >< at > -1417,9 +1417,11 < at >< at >
{
AG_Widget *wid = obj;
+AG_ObjectLock(wid);
wid->flags &= ~(AG_WIDGET_HIDE);
AG_PostEvent(NULL, wid, "widget-shown", NULL);
AG_WindowUpdate(wid->window);
+AG_ObjectUnlock(wid);
}
/* Hide a widget */
< at >< at > -1428,9 +1430,11 < at >< at >
{
AG_Widget *wid = obj;
+AG_ObjectLock(wid);
wid->flags |= AG_WIDGET_HIDE;
AG_PostEvent(NULL, wid, "widget-hidden", NULL);
AG_WindowUpdate(wid->window);
+AG_ObjectUnlock(wid);
}
/* Make a widget and all of its children visible. */
[Less]
|
Posted
over 9 years
ago
by
Agar-SVN
Author: vedge
Date: 2015-02-12 07:52:41 -0500 (Thu, 12 Feb 2015)
New Revision: 9764
Modified:
trunk/gui/drv_glx.c
trunk/gui/drv_wgl.c
Log:
prevent spurious double "window-gainfocus" and "window-lostfocus" events.
Modified:
... [More]
trunk/gui/drv_glx.c
===================================================================
--- trunk/gui/drv_glx.c2015-02-12 12:51:10 UTC (rev 9763)
+++ trunk/gui/drv_glx.c2015-02-12 12:52:41 UTC (rev 9764)
< at >< at > -1,5 +1,5 < at >< at >
/*
- * Copyright (c) 2009-2013 Hypertriton, Inc. <http://hypertriton.com/>
+ * Copyright (c) 2009-2015 Hypertriton, Inc. <http://hypertriton.com/>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
< at >< at > -666,8 +666,6 < at >< at >
#ifdef DEBUG_XEVENTS
Debug(win, "FocusIn\n");
#endif
-agWindowFocused = win;
-AG_PostEvent(NULL, win, "window-gainfocus", NULL);
dev->type = AG_DRIVER_FOCUS_IN;
dev->win = win;
break;
< at >< at > -678,10 +676,6 < at >< at >
#ifdef DEBUG_XEVENTS
Debug(win, "FocusOut\n");
#endif
-if (agWindowFocused == win) {
-AG_PostEvent(NULL, win, "window-lostfocus", NULL);
-agWindowFocused = NULL;
-}
dev->type = AG_DRIVER_FOCUS_OUT;
dev->win = win;
break;
< at >< at > -806,11 +800,13 < at >< at >
AG_PostEvent(NULL, dev->win, "window-leave", NULL);
break;
case AG_DRIVER_FOCUS_IN:
-agWindowFocused = dev->win;
-AG_PostEvent(NULL, dev->win, "window-gainfocus", NULL);
+if (agWindowFocused != dev->win) {
+agWindowFocused = dev->win;
+AG_PostEvent(NULL, dev->win, "window-gainfocus", NULL);
+}
break;
case AG_DRIVER_FOCUS_OUT:
-if (dev->win == agWindowFocused) {
+if (agWindowFocused == dev->win) {
AG_PostEvent(NULL, dev->win, "window-lostfocus", NULL);
agWindowFocused = NULL;
}
< at >< at > -858,7 +854,7 < at >< at >
AG_GL_Context *gl = &glx->gl;
AG_Color c = WCOLOR(win,0);
-if (!glx->w)
+if (!glx->w)/* XXX is this needed? */
return;
gl->clipStates[0] = glIsEnabled(GL_CLIP_PLANE0); glEnable(GL_CLIP_PLANE0);
< at >< at > -1423,7 +1419,7 < at >< at >
AG_MutexUnlock(&glx->lock);
AG_MutexUnlock(&agDisplayLock);
-
+
XFree(xvi);
return (0);
fail_ctx:
Modified: trunk/gui/drv_wgl.c
===================================================================
--- trunk/gui/drv_wgl.c2015-02-12 12:51:10 UTC (rev 9763)
+++ trunk/gui/drv_wgl.c2015-02-12 12:52:41 UTC (rev 9764)
< at >< at > -859,8 +859,10 < at >< at >
AG_PostEvent(NULL, dev->win, "window-leave", NULL);
break;
case AG_DRIVER_FOCUS_IN:
-agWindowFocused = dev->win;
-AG_PostEvent(NULL, dev->win, "window-gainfocus", NULL);
+if (dev->win != agWindowFocused) {
+agWindowFocused = dev->win;
+AG_PostEvent(NULL, dev->win, "window-gainfocus", NULL);
+}
break;
case AG_DRIVER_FOCUS_OUT:
if (dev->win == agWindowFocused) {
[Less]
|
Posted
over 9 years
ago
by
Agar-SVN
Author: vedge
Date: 2015-02-12 07:51:10 -0500 (Thu, 12 Feb 2015)
New Revision: 9763
Modified:
trunk/gui/AG_Window.3
Log:
elaborate on detach operations and dependencies
Modified: trunk/gui/AG_Window.3
... [More]
===================================================================
--- trunk/gui/AG_Window.32015-02-07 04:52:43 UTC (rev 9762)
+++ trunk/gui/AG_Window.32015-02-12 12:51:10 UTC (rev 9763)
< at >< at > -43,18 +43,23 < at >< at >
The
.Xr AG_Widget 3
objects form a tree structure attached to a parent
-.Nm ,
-and the windows themselves are attached to some parent
+.Nm .
+Agar windows are attached to some parent
.Xr AG_Driver 3
-instance.
-The parent driver provides an interface to some underlying window system..
+which provides a bridge between the Agar GUI system and the user's preferred
+graphics platform / backend.
.Pp
-Widgets can be attached directly to the
+Widgets can be attached to the
.Nm
-object, in which case
-.Nm
-will behave like a standard, vertical
-.Xr AG_Box 3 .
+object itself (it will behave like a standard, vertical
+.Xr AG_Box 3 ) .
+Agar's standard toolkit includes a variety of other container widgets, such as
+.Xr AG_Box 3 ,
+.Xr AG_Fixed 3 ,
+.Xr AG_Pane 3 ,
+.Xr AG_Notebook 3
+and
+.Xr AG_Scrollview 3 .
.Pp
The dimensions of new Agar windows is best determined automatically (using
recursive widget size requests which take resolution, font sizes, etc. into
< at >< at > -63,16 +68,14 < at >< at >
it can be determined automatically, or otherwise provide a suitable
application-level API for "size hints".
.Pp
-In addition to
-.Nm ,
-other widgets in the standard toolkit which are solely designed as
-containers include
-.Xr AG_Box 3 ,
-.Xr AG_Fixed 3 ,
-.Xr AG_Pane 3 ,
-.Xr AG_Notebook 3
-and
-.Xr AG_Scrollview 3 .
+Newly created windows (as returned by
+.Fn AG_WindowNew )
+must be made visible using
+.Fn AG_WindowShow .
+To close a window and free its allocated resources, one call to
+.Xr AG_ObjectDetach 3
+is sufficient (Agar will defer the actual destruction of the window
+until it becomes safe to do so).
.Sh INHERITANCE HIERARCHY
.Xr AG_Object 3 ->
.Xr AG_Widget 3 ->
< at >< at > -433,27 +436,35 < at >< at >
.Pp
The
.Fn AG_WindowAttach
-function makes
+function registers
.Fa winChld
-a logical child window of
-.Fa winParent ,
-such that whenever the parent window is destroyed, Agar will automatically
-destroy the child window as well.
-Logical child windows also inherit the style properties from their parent.
+as a child window dependent of
+.Fa winParent .
+Detaching the parent window (using
+.Xr AG_ObjectDetach 3 )
+will cause dependent child windows to be detached implicitely.
+Child windows also inherit the style properties from their parent.
+The
.Fn AG_WindowDetach
-detaches the window from its logical parent window.
+function detaches the window from its parent window.
.Pp
-The
.Fn AG_WindowMakeTransient
-function makes
+registers
.Fa winTrans
-a "transient" window for
+as a dependent and transient window for
.Fa winParent .
The effects of transient window state are dependent on the underlying
-window manager.
-For example, under Motif, transient windows have no titlebar buttons.
-Under TWM, transient windows are created without requesting the initial
-size from the user.
+window system and window manager.
+Under Motif, transient windows have no titlebar buttons.
+Under TWM, transient windows are created without requesting that the user
+select an initial geometry.
+Detaching
+.Fa winParent
+(using
+.Xr AG_ObjectDetach 3 )
+will cause
+.Fa winTrans
+to be detached implicitely.
.Pp
The
.Fn AG_WindowPin
< at >< at > -689,13 +700,13 < at >< at >
Read-only (use
.Fn AG_WindowSetMinSize ) .
.It Ft AG_Window *parent
-Pointer to "logical" parent window, or NULL if there isn't any.
+Pointer to parent window, or NULL if there isn't any.
Read-only (see
.Fn AG_WindowAttach
and
.Fn AG_WindowDetach ) .
.It Ft TAILQ subwins
-List of "logical" child windows.
+List of dependent child windows.
Read-only (see
.Fn AG_WindowAttach
and
[Less]
|
Posted
over 9 years
ago
by
Agar-SVN
Author: vedge
Date: 2015-02-06 23:52:43 -0500 (Fri, 06 Feb 2015)
New Revision: 9762
Modified:
trunk/gui/window.c
Log:
- in Detach(), cancel any running timers attached to the window just
like AG_ObjectDetach() normally does.
- in AG_WindowHide()
... [More]
, ignore FADEOUT if a detach is in progress.
Modified: trunk/gui/window.c
===================================================================
--- trunk/gui/window.c2015-02-07 04:50:55 UTC (rev 9761)
trunk/gui/window.c2015-02-07 04:52:43 UTC (rev 9762)
< at >< at > -222,11 222,7 < at >< at >
return AG_WindowNewNamedS(flags, s);
}
-/*
- * Window attach function (we don't use the default Object attach function
- * because AG_WINDOW_KEEPBELOW windows have to be inserted at the head of
- * the list).
- */
/* Special implementation of AG_ObjectAttach() for AG_Window. */
static void
Attach(AG_Event *event)
{
< at >< at > -283,14 279,14 < at >< at >
AG_WindowFocus(win);
}
-/* Window detach function. */
/* Special implementation of AG_ObjectDetach() for AG_Window. */
static void
Detach(AG_Event *event)
{
AG_Window *win = AG_SELF();
AG_Driver *drv = OBJECT(win)->parent, *odrv;
-AG_Window *subwin;
-AG_Window *owin;
AG_Window *owin, *subwin;
AG_Timer *to, *toNext;
#ifdef AG_DEBUG
if (drv == NULL || !AG_OfClass(drv, "AG_Driver:*"))
< at >< at > -300,19 296,31 < at >< at >
/* Mark window detach in progress */
win->flags |= AG_WINDOW_DETACHING;
/* Cancel any planned focus change to this window. */
if (win == agWindowToFocus)
agWindowToFocus = NULL;
/* Cancel any running timer attached to the window. */
AG_LockTiming();
for (to = TAILQ_FIRST(&OBJECT(win)->timers);
to != TAILQ_END(&OBJECT(win)->timers);
to = toNext) {
toNext = TAILQ_NEXT(to, timers);
AG_DelTimer(win, to);
}
AG_UnlockTiming();
-/*
- * Remove all dependencies toward this window. Child windows are
- * reparented to NULL and sent a `window-close' event.
- */
if (win->visible)
AG_WindowHide(win);
AGOBJECT_FOREACH_CHILD(odrv, &agDrivers, ag_driver) {
AG_FOREACH_WINDOW(owin, odrv) {
if (owin == win) {
continue;
}
if (owin->parent == win) {
-AG_PostEvent(NULL, owin, "window-close", NULL);
-owin->parent = NULL;
AG_ObjectDetach(owin);
}
TAILQ_FOREACH(subwin, &owin->subwins, swins) {
if (subwin == win)
< at >< at > -322,22 330,17 < at >< at >
TAILQ_REMOVE(&owin->subwins, subwin, swins);
}
}
#if 1
goto out;
#endif
/* if (AGDRIVER_SINGLE(drv)) { */
win->tbar = NULL;/* No longer safe to use */
win->icon = NULL;
/* } */
-/* Cancel any planned focus change to this window. */
-if (win == agWindowToFocus)
-agWindowToFocus = NULL;
-
-if (win->visible)
-AG_WindowHide(win);
-
-/* Titlebar and icons are no longer safe to reference. */
-if (win->tbar != NULL) { win->tbar = NULL; }
-if (win->icon != NULL) { win->icon = NULL; }
-
/*
- * Notify all child widgets of the window detach request. Widgets
- * acknowledge the request by resetting their drv and drvOps pointers
- * to NULL.
* Notify all child widgets of the window detach request. Widgets will
* acknowledge the request by resetting their drv and drvOps to NULL.
*/
AG_PostEvent(drv, win, "detached", NULL);
< at >< at > -348,7 351,7 < at >< at >
* event processing cycle.
*/
TAILQ_INSERT_TAIL(&agWindowDetachQ, win, detach);
-
out:
AG_UnlockVFS(&agDrivers);
}
< at >< at > -837,13 840,10 < at >< at >
if (i < dsw->Lmodal->n)
AG_ListRemove(dsw->Lmodal, i);
}
-
-/* Update the background. */
-/* XXX XXX XXX no need for the fill rect? */
if (AGDRIVER_CLASS(drv)->type == AG_FRAMEBUFFER) {
/* Update the background. */
AG_DrawRectFilled(win,
- AG_RECT(0,0, WIDTH(win), HEIGHT(win)),
- dsw->bgColor);
AG_RECT(0,0, WIDTH(win), HEIGHT(win)), dsw->bgColor);
if (AGDRIVER_CLASS(drv)->updateRegion != NULL)
AGDRIVER_CLASS(drv)->updateRegion(drv,
AG_RECT(WIDGET(win)->x, WIDGET(win)->y,
< at >< at > -937,7 937,8 < at >< at >
{
AG_ObjectLock(win);
if (win->visible) {
-if (win->flags & AG_WINDOW_FADEOUT) {
if ((win->flags & AG_WINDOW_FADEOUT) &&
!(win->flags & AG_WINDOW_DETACHING)) {
AG_AddTimer(win, &win->fadeTo,
(Uint32)((win->fadeOutTime*1000.0)/(1.0/win->fadeOutIncr)),
FadeTimeout, "%i", -1);
[Less]
|
Posted
over 9 years
ago
by
Agar-SVN
Author: vedge
Date: 2015-02-06 23:50:28 -0500 (Fri, 06 Feb 2015)
New Revision: 9760
Modified:
trunk/core/AG_Object.3
trunk/core/object.c
Log:
AG_TIMER_SURVIVE_DETACH is not needed
Modified: trunk/core/AG_Object.3
... [More]
===================================================================
--- trunk/core/AG_Object.32015-02-06 13:54:29 UTC (rev 9759)
+++ trunk/core/AG_Object.32015-02-07 04:50:28 UTC (rev 9760)
< at >< at > -215,9 +215,7 < at >< at >
.Fn AG_ObjectDetach
cancels any scheduled
.Xr AG_Timer 3
-callback (unless the timer has the
-.Dv AG_TIMER_SURVIVE_DETACH
-flag).
+callback.
If
.Fa parent
is NULL,
Modified: trunk/core/object.c
===================================================================
--- trunk/core/object.c2015-02-06 13:54:29 UTC (rev 9759)
+++ trunk/core/object.c2015-02-07 04:50:28 UTC (rev 9760)
< at >< at > -501,17 +501,13 < at >< at >
goto out;
}
-/*
- * Cancel any running timers. This behavior can be overridden with
- * the AG_TIMER_SURVIVE_DETACH flag.
- */
+/* Cancel any running timer associated with the object. */
AG_LockTiming();
for (to = TAILQ_FIRST(&chld->timers);
to != TAILQ_END(&chld->timers);
to = toNext) {
toNext = TAILQ_NEXT(to, timers);
-if ((to->flags & AG_TIMER_SURVIVE_DETACH) == 0)
-AG_DelTimer(chld, to);
+AG_DelTimer(chld, to);
}
AG_UnlockTiming();
[Less]
|
Posted
over 9 years
ago
by
Agar-SVN
Author: vedge
Date: 2015-02-06 08:54:29 -0500 (Fri, 06 Feb 2015)
New Revision: 9759
Modified:
trunk/dev/browser.c
trunk/dev/config.c
trunk/dev/object.c
trunk/math/m_plotter.c
trunk/vg/vg_view.c
Log:
- use AG_WidgetShowAll() /
... [More]
AG_WidgetHideAll()
- use AG_NotebookAdd()
Modified: trunk/dev/browser.c
===================================================================
--- trunk/dev/browser.c2015-02-06 13:53:55 UTC (rev 9758)
trunk/dev/browser.c2015-02-06 13:54:29 UTC (rev 9759)
< at >< at > -771,7 771,7 < at >< at >
#endif /* AG_DEBUG */
nb = AG_NotebookNew(win, AG_NOTEBOOK_HFILL|AG_NOTEBOOK_VFILL);
-ntab = AG_NotebookAddTab(nb, _("Working copy"), AG_BOX_VERT);
ntab = AG_NotebookAdd(nb, _("Working copy"), AG_BOX_VERT);
{
AG_MenuItem *mi;
Modified: trunk/dev/config.c
===================================================================
--- trunk/dev/config.c2015-02-06 13:53:55 UTC (rev 9758)
trunk/dev/config.c2015-02-06 13:54:29 UTC (rev 9759)
< at >< at > -235,13 235,13 < at >< at >
AG_WindowSetCloseAction(win, AG_WINDOW_DETACH);
nb = AG_NotebookNew(win, AG_NOTEBOOK_HFILL|AG_NOTEBOOK_VFILL);
-tab = AG_NotebookAddTab(nb, _("Video"), AG_BOX_VERT);
tab = AG_NotebookAdd(nb, _("Video"), AG_BOX_VERT);
{
AG_NumericalNewIntR(tab, 0, "%", _("Screenshot quality: "),
&agScreenshotQuality, 1, 100);
}
-tab = AG_NotebookAddTab(nb, _("GUI"), AG_BOX_VERT);
tab = AG_NotebookAdd(nb, _("GUI"), AG_BOX_VERT);
{
AG_CheckboxNewInt(tab, 0, _("Built-in key composition"),
&agTextComposition);
< at >< at > -262,7 262,7 < at >< at >
&agKbdRepeat, 1, 500);
}
-tab = AG_NotebookAddTab(nb, _("Directories"), AG_BOX_VERT);
tab = AG_NotebookAdd(nb, _("Directories"), AG_BOX_VERT);
{
hb = AG_BoxNewHoriz(tab, AG_BOX_HFILL);
tbox = AG_TextboxNewS(hb, AG_TEXTBOX_HFILL, _("Temporary file directory: "));
< at >< at > -292,7 292,7 < at >< at >
AG_SetEvent(tbox, "textbox-return", SetPath, "%s", "font-path");
}
#if 0
-tab = AG_NotebookAddTab(nb, _("Colors"), AG_BOX_VERT);
tab = AG_NotebookAdd(nb, _("Colors"), AG_BOX_VERT);
{
AG_Pane *hPane;
AG_HSVPal *hsv;
< at >< at > -333,7 333,7 < at >< at >
#endif
#ifdef AG_DEBUG
-tab = AG_NotebookAddTab(nb, _("Debug"), AG_BOX_VERT);
tab = AG_NotebookAdd(nb, _("Debug"), AG_BOX_VERT);
{
AG_NumericalNewIntR(tab, 0, NULL, _("Debug level: "),
&agDebugLvl, 0, 255);
Modified: trunk/dev/object.c
===================================================================
--- trunk/dev/object.c2015-02-06 13:53:55 UTC (rev 9758)
trunk/dev/object.c2015-02-06 13:54:29 UTC (rev 9759)
< at >< at > -211,7 211,7 < at >< at >
AG_WindowSetPosition(win, AG_WINDOW_UPPER_RIGHT, 1);
nb = AG_NotebookNew(win, AG_NOTEBOOK_HFILL|AG_NOTEBOOK_VFILL);
-ntab = AG_NotebookAddTab(nb, _("Infos"), AG_BOX_VERT);
ntab = AG_NotebookAdd(nb, _("Infos"), AG_BOX_VERT);
{
AG_Textbox *tbMD5, *tbSHA1, *tbRMD160;
< at >< at > -255,20 255,20 < at >< at >
}
}
-ntab = AG_NotebookAddTab(nb, _("Deps"), AG_BOX_VERT);
ntab = AG_NotebookAdd(nb, _("Deps"), AG_BOX_VERT);
{
tl = AG_TlistNew(ntab, AG_TLIST_POLL|AG_TLIST_EXPAND);
AG_TlistSizeHint(tl, "XXXXXXXXXXXX", 6);
AG_SetEvent(tl, "tlist-poll", PollDeps, "%p", ob);
}
-ntab = AG_NotebookAddTab(nb, _("Events"), AG_BOX_VERT);
ntab = AG_NotebookAdd(nb, _("Events"), AG_BOX_VERT);
{
tl = AG_TlistNew(ntab, AG_TLIST_POLL|AG_TLIST_EXPAND);
AG_SetEvent(tl, "tlist-poll", PollEvents, "%p", ob);
}
-ntab = AG_NotebookAddTab(nb, _("Variables"), AG_BOX_VERT);
ntab = AG_NotebookAdd(nb, _("Variables"), AG_BOX_VERT);
{
tl = AG_TlistNew(ntab, AG_TLIST_POLL|AG_TLIST_EXPAND);
AG_SetEvent(tl, "tlist-poll", PollVariables, "%p", ob);
Modified: trunk/math/m_plotter.c
===================================================================
--- trunk/math/m_plotter.c2015-02-06 13:53:55 UTC (rev 9758)
trunk/math/m_plotter.c2015-02-06 13:54:29 UTC (rev 9759)
< at >< at > -214,7 214,7 < at >< at >
AG_WindowSetPosition(win, AG_WINDOW_MIDDLE_LEFT, 0);
nb = AG_NotebookNew(win, AG_NOTEBOOK_EXPAND);
-ntab = AG_NotebookAddTab(nb, _("Trace"), AG_BOX_VERT);
ntab = AG_NotebookAdd(nb, _("Trace"), AG_BOX_VERT);
{
AG_RadioNewUint(ntab, 0, type_names, (void *)&pl->type);
M_NumericalNewReal(ntab, 0, NULL, _("X-scale: "), &pl->xScale);
< at >< at > -223,7 223,7 < at >< at >
AG_NumericalNewInt(ntab, 0, "px", _("X-offset: "), &pl->xOffs);
AG_NumericalNewInt(ntab, 0, "px", _("Y-offset: "), &pl->yOffs);
}
-ntab = AG_NotebookAddTab(nb, _("Color"), AG_BOX_VERT);
ntab = AG_NotebookAdd(nb, _("Color"), AG_BOX_VERT);
{
AG_HSVPal *pal;
< at >< at > -232,7 232,7 < at >< at >
AG_SetEvent(pal, "h-changed", UpdateLabel, "%p", pl);
AG_SetEvent(pal, "sv-changed", UpdateLabel, "%p", pl);
}
-ntab = AG_NotebookAddTab(nb, _("Table"), AG_BOX_VERT);
ntab = AG_NotebookAdd(nb, _("Table"), AG_BOX_VERT);
{
AG_Table *tbl;
Modified: trunk/vg/vg_view.c
===================================================================
--- trunk/vg/vg_view.c2015-02-06 13:53:55 UTC (rev 9758)
trunk/vg/vg_view.c2015-02-06 13:54:29 UTC (rev 9759)
< at >< at > -892,7 892,7 < at >< at >
AG_ObjectFreeChildren(editArea);
AG_WidgetUpdate(editArea);
-AG_WidgetHiddenRecursive(editArea);
AG_WidgetHideAll(editArea);
}
AG_ObjectUnlock(vv);
}
< at >< at > -909,7 909,7 < at >< at >
AG_ObjectFreeChildren(vv->editAreas[editArea]);
AG_ObjectAttach(vv->editAreas[editArea], wEdit);
AG_WidgetUpdate(vv->editAreas[editArea]);
-AG_WidgetShownRecursive(vv->editAreas[editArea]);
AG_WidgetShowAll(vv->editAreas[editArea]);
}
}
[Less]
|
Posted
over 9 years
ago
by
Agar-SVN
Author: vedge
Date: 2015-02-06 08:53:55 -0500 (Fri, 06 Feb 2015)
New Revision: 9758
Modified:
trunk/tests/agartest.c
trunk/tests/charsets.c
trunk/tests/compositing.c
trunk/tests/customwidget.c
trunk/tests/fixedres.c
... [More]
trunk/tests/glview.c
trunk/tests/loader.c
trunk/tests/objsystem.c
trunk/tests/sockets.c
trunk/tests/threads.c
trunk/tests/widgets.c
Log:
plug some memleaks in the testsuite itself
Modified: trunk/tests/agartest.c
===================================================================
--- trunk/tests/agartest.c2015-02-06 13:53:00 UTC (rev 9757)
trunk/tests/agartest.c2015-02-06 13:53:55 UTC (rev 9758)
< at >< at > -273,6 273,9 < at >< at >
AG_ConsoleMsg(console, _("Test %s: terminated"), ti->name);
AG_ObjectDetach(ti->win);
TAILQ_REMOVE(&tests, ti, instances);
if (ti->tc->destroy != NULL) {
ti->tc->destroy(ti);
}
free(ti);
}
Modified: trunk/tests/charsets.c
===================================================================
--- trunk/tests/charsets.c2015-02-06 13:53:00 UTC (rev 9757)
trunk/tests/charsets.c2015-02-06 13:53:55 UTC (rev 9758)
< at >< at > -10,36 10,40 < at >< at >
#include <agar/config/have_iconv.h>
-char myASCII[20*4];
-char myUTF[30*4];
-char myLat1[30*4];
typedef struct {
AG_TestInstance _inherit;
char myASCII[20*4];
char myUTF[30*4];
char myLat1[30*4];
AG_Text *myTxt;
} MyTestInstance;
static int
TestGUI(void *obj, AG_Window *win)
{
-AG_Text *myTxt;
MyTestInstance *ti = obj;
AG_Textbox *tb;
/* Bind to a C string in US-ASCII */
-AG_Strlcpy(myASCII, "ASCII!", sizeof(myASCII));
AG_Strlcpy(ti->myASCII, "ASCII!", sizeof(ti->myASCII));
tb = AG_TextboxNew(win, AG_TEXTBOX_HFILL|AG_TEXTBOX_EXCL,
- "ASCII Buffer: \n(%lu bytes)", sizeof(myASCII));
-AG_TextboxBindASCII(tb, myASCII, sizeof(myASCII));
"ASCII Buffer: \n(%lu bytes)", sizeof(ti->myASCII));
AG_TextboxBindASCII(tb, ti->myASCII, sizeof(ti->myASCII));
AG_TextboxSizeHintLines(tb, 2);
/* Bind to a C string in UTF-8 */
-AG_Strlcpy(myUTF, "\xc3\x85ngstrom!", sizeof(myUTF));
AG_Strlcpy(ti->myUTF, "\xc3\x85ngstrom!", sizeof(ti->myUTF));
tb = AG_TextboxNew(win, AG_TEXTBOX_HFILL|AG_TEXTBOX_EXCL,
- "UTF-8 Buffer: \n(%lu bytes)", sizeof(myUTF));
-AG_TextboxBindUTF8(tb, myUTF, sizeof(myUTF));
"UTF-8 Buffer: \n(%lu bytes)", sizeof(ti->myUTF));
AG_TextboxBindUTF8(tb, ti->myUTF, sizeof(ti->myUTF));
AG_TextboxSizeHintLines(tb, 2);
/* Bind to a C string in any iconv-supported encoding */
#ifdef HAVE_ICONV
-AG_Strlcpy(myLat1, "Overv\xE5knign for feils\xF8king!", sizeof(myLat1));
AG_Strlcpy(ti->myLat1, "Overv\xE5knign for feils\xF8king!", sizeof(ti->myLat1));
tb = AG_TextboxNew(win, AG_TEXTBOX_HFILL|AG_TEXTBOX_EXCL,
- "LATIN-1 Buffer: \n(%lu bytes)", sizeof(myLat1));
-AG_TextboxBindEncoded(tb, "ISO-8859-1", myLat1, sizeof(myLat1));
"LATIN-1 Buffer: \n(%lu bytes)", sizeof(ti->myLat1));
AG_TextboxBindEncoded(tb, "ISO-8859-1", ti->myLat1, sizeof(ti->myLat1));
AG_TextboxSizeHintLines(tb, 2);
AG_LabelNewS(win, 0, "iconv support: YES");
#else
< at >< at > -50,30 54,39 < at >< at >
AG_SeparatorNewHoriz(win);
/* Bind to a multilingual AG_Text(3) element. */
-myTxt = AG_TextNew(0);
-AG_TextSetEnt(myTxt, AG_LANG_FR, "Fran\xc3\xa7\x61is!");
-AG_TextSetEnt(myTxt, AG_LANG_EN, "English!");
-AG_TextSetEnt(myTxt, AG_LANG_NO, "Norsk!");
-AG_LabelNewS(win, 0, "Multilingual AG_Text(3) buffer:");
-tb = AG_TextboxNewS(win,
- AG_TEXTBOX_MULTILINGUAL|AG_TEXTBOX_EXPAND|AG_TEXTBOX_MULTILINE,
- NULL);
-AG_TextboxBindText(tb, myTxt);
-AG_TextboxSetLang(tb, AG_LANG_FR);
-AG_TextboxSizeHint(tb, "XXXXXXXXXXXXXXXXXXXXXXXXX");
-AG_TextboxSizeHintLines(tb, 5);
-AG_TextboxSetCursorPos(tb, -1);/* End of string */
if ((ti->myTxt = AG_TextNew(0)) != NULL) {
AG_TextSetEnt(ti->myTxt, AG_LANG_FR, "Fran\xc3\xa7\x61is!");
AG_TextSetEnt(ti->myTxt, AG_LANG_EN, "English!");
AG_TextSetEnt(ti->myTxt, AG_LANG_NO, "Norsk!");
AG_LabelNewS(win, 0, "Multilingual AG_Text(3) buffer:");
tb = AG_TextboxNewS(win,
AG_TEXTBOX_MULTILINGUAL|AG_TEXTBOX_EXPAND|AG_TEXTBOX_MULTILINE,
NULL);
AG_TextboxBindText(tb, ti->myTxt);
AG_TextboxSetLang(tb, AG_LANG_FR);
AG_TextboxSizeHint(tb, "XXXXXXXXXXXXXXXXXXXXXXXXX");
AG_TextboxSizeHintLines(tb, 5);
AG_TextboxSetCursorPos(tb, -1);/* End of string */
}
return (0);
}
static void
Destroy(void *obj)
{
MyTestInstance *ti = obj;
AG_TextFree(ti->myTxt);
}
const AG_TestCase charsetsTest = {
"charsets",
N_("Test AG_Editable(3) bound to buffers in different character sets"),
-"1.4.2",
"1.5.0",
0,
-sizeof(AG_TestInstance),
sizeof(MyTestInstance),
NULL,/* init */
-NULL,/* destroy */
Destroy,
NULL,/* test */
TestGUI,
NULL/* bench */
Modified: trunk/tests/compositing.c
===================================================================
--- trunk/tests/compositing.c2015-02-06 13:53:00 UTC (rev 9757)
trunk/tests/compositing.c2015-02-06 13:53:55 UTC (rev 9758)
< at >< at > -28,7 28,7 < at >< at >
AG_WindowSetFadeIn(win, 1.0f, 0.1f);
if (!AG_ConfigFile("load-path", "agar", "bmp", path, sizeof(path))) {
-AG_PixmapFromBMP(win, 0, path);
AG_PixmapFromFile(win, 0, path);
}
AG_LabelNew(win, 0, "Testing AG_WINDOW_FADEIN");
< at >< at > -45,9 45,9 < at >< at >
hb = AG_BoxNewHoriz(win, AG_BOX_HFILL);
if (!AG_ConfigFile("load-path", "agar", "bmp", path, sizeof(path))) {
-AG_PixmapFromBMP(hb, 0, path);
-AG_PixmapFromBMP(hb, 0, path);
-AG_PixmapFromBMP(hb, 0, path);
AG_PixmapFromFile(hb, 0, path);
AG_PixmapFromFile(hb, 0, path);
AG_PixmapFromFile(hb, 0, path);
}
hb = AG_BoxNewHoriz(win, AG_BOX_HFILL);
{
Modified: trunk/tests/customwidget.c
===================================================================
--- trunk/tests/customwidget.c2015-02-06 13:53:00 UTC (rev 9757)
trunk/tests/customwidget.c2015-02-06 13:53:55 UTC (rev 9758)
< at >< at > -11,22 11,12 < at >< at >
static int
Init(void *obj)
{
-if (inited > 0) {
-return (0);
if (inited == 0) {
AG_RegisterClass(&myWidgetClass);
}
-AG_RegisterClass(&myWidgetClass);
return (0);
}
-static void
-Destroy(void *obj)
-{
-if (--inited > 0) {
-return;
-}
-AG_UnregisterClass(&myWidgetClass);
-}
-
static int
TestGUI(void *obj, AG_Window *win)
{
< at >< at > -43,11 33,11 < at >< at >
const AG_TestCase customWidgetTest = {
"customWidget",
N_("Test registering a custom Agar widget"),
-"1.4.2",
"1.5.0",
0,
sizeof(AG_TestInstance),
Init,
-Destroy,
NULL,/* destroy */
NULL,/* test */
TestGUI,
NULL/* bench */
Modified: trunk/tests/fixedres.c
===================================================================
--- trunk/tests/fixedres.c2015-02-06 13:53:00 UTC (rev 9757)
trunk/tests/fixedres.c2015-02-06 13:53:55 UTC (rev 9758)
< at >< at > -28,7 28,7 < at >< at >
/* Create some background pixmap from an image file. */
if (!AG_ConfigFile("load-path", "menubg", "bmp", path, sizeof(path))) {
-if ((px = AG_PixmapFromBMP(fx, 0, path)) == NULL) {
if ((px = AG_PixmapFromFile(fx, 0, path)) == NULL) {
AG_LabelNewS(win, 0, AG_GetError());
fprintf(stderr, "%s\n", AG_GetError());
exit(1);
Modified: trunk/tests/glview.c
===================================================================
--- trunk/tests/glview.c2015-02-06 13:53:00 UTC (rev 9757)
trunk/tests/glview.c2015-02-06 13:53:55 UTC (rev 9758)
< at >< at > -194,7 194,7 < at >< at >
UpdateRotation(AG_Timer *to, AG_Event *event)
{
MyTestInstance *ti = AG_PTR(1);
-
if ( ti->spin > 360.0f) { ti->spin -= 360.0f; }
return (to->ival);
}
< at >< at > -290,7 290,7 < at >< at >
nb = AG_NotebookNew(pa->div[0], AG_NOTEBOOK_EXPAND);
for (i = 0; i < 2; i ) {
-ntab = AG_NotebookAddTab(nb, "Test tab", AG_BOX_VERT);
ntab = AG_NotebookAdd(nb, "Test tab", AG_BOX_VERT);
/* Create the AG_GLView widget. */
glv = AG_GLViewNew(ntab, AG_GLVIEW_EXPAND);
< at >< at > -305,23 305,24 < at >< at >
AG_GLViewButtondownFn(glv, ButtonDown, "%p", ti);
/* Update the rotation 30 times per second. */
-AG_AddTimerAuto(glv, 1000/30, UpdateRotation, "%p", ti);
AG_AddTimerAuto(win, 1000/30,
UpdateRotation, "%p", ti);
}
/* Edit ambient and diffuse color components. */
nbColor = AG_NotebookNew(pa->div[1], AG_NOTEBOOK_EXPAND);
{
-ntab = AG_NotebookAddTab(nbColor, "Amb", AG_BOX_VERT);
ntab = AG_NotebookAdd(nbColor, "Amb", AG_BOX_VERT);
pal = AG_HSVPalNew(ntab,
AG_HSVPAL_NOALPHA|AG_HSVPAL_EXPAND);
AG_BindFloat(pal, "RGBAv", ti->ambient);
-ntab = AG_NotebookAddTab(nbColor, "Dif", AG_BOX_VERT);
ntab = AG_NotebookAdd(nbColor, "Dif", AG_BOX_VERT);
pal = AG_HSVPalNew(ntab,
AG_HSVPAL_NOALPHA|AG_HSVPAL_EXPAND);
AG_BindFloat(pal, "RGBAv", ti->diffuse);
-ntab = AG_NotebookAddTab(nbColor, "Spe", AG_BOX_VERT);
ntab = AG_NotebookAdd(nbColor, "Spe", AG_BOX_VERT);
pal = AG_HSVPalNew(ntab,
AG_HSVPAL_NOALPHA|AG_HSVPAL_EXPAND);
AG_BindFloat(pal, "RGBAv", ti->specular);
< at >< at > -349,7 350,7 < at >< at >
#ifdef HAVE_OPENGL
sizeof(MyTestInstance),
Init,
-NULL,/* destroy */
NULL,
NULL,/* test */
TestGUI,
#else
Modified: trunk/tests/loader.c
===================================================================
--- trunk/tests/loader.c2015-02-06 13:53:00 UTC (rev 9757)
trunk/tests/loader.c2015-02-06 13:53:55 UTC (rev 9758)
< at >< at > -85,7 85,7 < at >< at >
int i;
nb = AG_NotebookNew(win, AG_NOTEBOOK_EXPAND);
-ntab = AG_NotebookAddTab(nb, "Load file", AG_BOX_VERT);
ntab = AG_NotebookAdd(nb, "Load file", AG_BOX_VERT);
{
/* Create the file loader widget. */
fd = AG_FileDlgNew(ntab, AG_FILEDLG_EXPAND);
< at >< at > -126,7 126,7 < at >< at >
AG_BoxSetPadding(box, 10);
AG_FileDlgSetOptionContainer(fd, box);
}
-ntab = AG_NotebookAddTab(nb, "Select directory", AG_BOX_VERT);
ntab = AG_NotebookAdd(nb, "Select directory", AG_BOX_VERT);
{
/* Create the directory selector widget. */
dd = AG_DirDlgNew(ntab, AG_DIRDLG_EXPAND);
Modified: trunk/tests/objsystem.c
===================================================================
--- trunk/tests/objsystem.c2015-02-06 13:53:00 UTC (rev 9757)
trunk/tests/objsystem.c2015-02-06 13:53:55 UTC (rev 9758)
< at >< at > -13,6 13,7 < at >< at >
#include "objsystem_mammal.h"
typedef struct {
AG_TestInstance _inherit;
AG_Object vfsRoot;/* Our test VFS */
} MyTestInstance;
Modified: trunk/tests/sockets.c
===================================================================
--- trunk/tests/sockets.c2015-02-06 13:53:00 UTC (rev 9757)
trunk/tests/sockets.c2015-02-06 13:53:55 UTC (rev 9758)
< at >< at > -77,7 77,7 < at >< at >
/* Create a pixmap */
if (!AG_ConfigFile("load-path", "menubg", "bmp", path, sizeof(path))) {
-if ((px = AG_PixmapFromBMP(fx, 0, path)) == NULL) {
if ((px = AG_PixmapFromFile(fx, 0, path)) == NULL) {
TestMsg(obj, "%s: %s", path, AG_GetError());
exit(1);
}
< at >< at > -92,7 92,7 < at >< at >
if (AG_ConfigFile("load-path", imageFiles[i], "bmp", path, sizeof(path)) != 0) {
continue;
}
-pixmaps[i] = AG_SurfaceFromBMP(path);
pixmaps[i] = AG_SurfaceFromFile(path);
AG_SurfaceSetColorKey(pixmaps[i], AG_SRCCOLORKEY,
AG_MapPixelRGB(pixmaps[i]->format, 0,255,0));
}
Modified: trunk/tests/threads.c
===================================================================
--- trunk/tests/threads.c2015-02-06 13:53:00 UTC (rev 9757)
trunk/tests/threads.c2015-02-06 13:53:55 UTC (rev 9758)
< at >< at > -11,6 11,7 < at >< at >
#include <math.h>
typedef struct {
AG_TestInstance _inherit;
AG_Object workerMgr;
int nWorkers;
AG_Window *winParent;
Modified: trunk/tests/widgets.c
===================================================================
--- trunk/tests/widgets.c2015-02-06 13:53:00 UTC (rev 9757)
trunk/tests/widgets.c2015-02-06 13:53:55 UTC (rev 9758)
< at >< at > -15,7 15,11 < at >< at >
#include <agar/config/ag_debug.h>
#include <agar/config/version.h>
-char textBuffer[30];
typedef struct {
AG_TestInstance _inherit;
char textBuffer[30];
char *someText;
} MyTestInstance;
/* Example callback for combo-selected. */
static void
< at >< at > -45,6 49,7 < at >< at >
static int
TestGUI(void *obj, AG_Window *win)
{
MyTestInstance *ti = obj;
char path[AG_PATHNAME_MAX];
AG_Box *hBox, *vBox;
AG_Pane *pane;
< at >< at > -67,9 72,9 < at >< at >
char path[AG_PATHNAME_MAX];
AG_Label *lbl;
-/* The Pixmap widget displays a raster surface. */
/* The Pixmap widget can display an image surface. */
if (!AG_ConfigFile("load-path", "agar", "bmp", path, sizeof(path)))
-AG_PixmapFromBMP(div1, 0, path);
AG_PixmapFromFile(div1, 0, path);
/*
* The Label widget provides a simple static or polled label
< at >< at > -189,13 194,13 < at >< at >
* encoding.
*/
{
-AG_Strlcpy(textBuffer, "Foo bar baz bezo", sizeof(textBuffer));
AG_Strlcpy(ti->textBuffer, "Foo bar baz bezo", sizeof(ti->textBuffer));
/* Create a textbox bound to a fixed-size buffer */
tbox = AG_TextboxNew(div1,
AG_TEXTBOX_EXCL|AG_TEXTBOX_HFILL,
"Fixed text buffer: ");
-AG_TextboxBindUTF8(tbox, textBuffer, sizeof(textBuffer));
AG_TextboxBindUTF8(tbox, ti->textBuffer, sizeof(ti->textBuffer));
/* Create a textbox bound to a built-in AG_Text element */
tbox = AG_TextboxNew(div1,
< at >< at > -269,7 274,7 < at >< at >
nb = AG_NotebookNew(div2, AG_NOTEBOOK_EXPAND);
-ntab = AG_NotebookAddTab(nb, "Some table", AG_BOX_VERT);
ntab = AG_NotebookAdd(nb, "Some table", AG_BOX_VERT);
{
float f;
< at >< at > -294,9 299,8 < at >< at >
}
}
-ntab = AG_NotebookAddTab(nb, "Some text", AG_BOX_VERT);
ntab = AG_NotebookAdd(nb, "Some text", AG_BOX_VERT);
{
-char *someText;
size_t size, bufSize;
FILE *f;
< at >< at > -322,13 326,13 < at >< at >
size = ftell(f);
fseek(f, 0, SEEK_SET);
bufSize = size 1024;
-someText = AG_Malloc(bufSize);
-(void)fread(someText, size, 1, f);
ti->someText = AG_Malloc(bufSize);
(void)fread(ti->someText, size, 1, f);
fclose(f);
-someText[size] = '\0';
ti->someText[size] = '\0';
} else {
-someText = AG_Strdup("Failed to load loss.txt");
-bufSize = strlen(someText) 1;
ti->someText = AG_Strdup("Failed to load loss.txt");
bufSize = strlen(ti->someText) 1;
}
/*
< at >< at > -336,14 340,14 < at >< at >
* size argument to AG_TextboxBindUTF8() must include
* space for the terminating NUL.
*/
-AG_TextboxBindUTF8(tbox, someText, bufSize);
AG_TextboxBindUTF8(tbox, ti->someText, bufSize);
/* Add a word wrapping control */
AG_CheckboxNewFn(ntab, 0, "Word wrapping",
SetWordWrap, "%p", tbox);
}
-ntab = AG_NotebookAddTab(nb, "Empty tab", AG_BOX_VERT);
ntab = AG_NotebookAdd(nb, "Empty tab", AG_BOX_VERT);
}
return (0);
}
< at >< at > -351,6 355,10 < at >< at >
static int
Init(void *obj)
{
MyTestInstance *ti = obj;
ti->textBuffer[0] = '\0';
ti->someText = NULL;
DEV_InitSubsystem(0);
return (0);
}
< at >< at > -358,6 366,9 < at >< at >
static void
Destroy(void *obj)
{
MyTestInstance *ti = obj;
Free(ti->someText);
DEV_DestroySubsystem();
}
< at >< at > -366,7 377,7 < at >< at >
N_("Display various standard Agar widgets"),
"1.5.0",
0,
-sizeof(AG_TestInstance),
sizeof(MyTestInstance),
Init,
Destroy,
NULL,/* test */
[Less]
|
Posted
over 9 years
ago
by
Agar-SVN
Author: vedge
Date: 2015-01-14 02:21:37 -0500 (Wed, 14 Jan 2015)
New Revision: 9728
Added:
trunk/tests/widgets.c
Removed:
trunk/tests/themes.c
Modified:
trunk/tests/Makefile
trunk/tests/agartest.c
Log:
rename "themes" -> "widgets"
... [More]
Modified: trunk/tests/Makefile
===================================================================
--- trunk/tests/Makefile2015-01-14 07:18:48 UTC (rev 9727)
trunk/tests/Makefile2015-01-14 07:21:37 UTC (rev 9728)
< at >< at > -60,10 60,10 < at >< at >
table.c \
textbox.c \
textdlg.c \
-themes.c \
threads.c \
timeouts.c \
unitconv.c \
widgets.c \
windows.c
all: all-subdir ${PROG}
Modified: trunk/tests/agartest.c
===================================================================
--- trunk/tests/agartest.c2015-01-14 07:18:48 UTC (rev 9727)
trunk/tests/agartest.c2015-01-14 07:21:37 UTC (rev 9728)
< at >< at > -43,10 43,10 < at >< at >
extern const AG_TestCase tableTest;
extern const AG_TestCase textboxTest;
extern const AG_TestCase textDlgTest;
-extern const AG_TestCase themesTest;
extern const AG_TestCase threadsTest;
extern const AG_TestCase timeoutsTest;
extern const AG_TestCase unitconvTest;
extern const AG_TestCase widgetsTest;
extern const AG_TestCase windowsTest;
const AG_TestCase *testCases[] = {
< at >< at > -84,10 84,10 < at >< at >
&tableTest,
&textboxTest,
&textDlgTest,
-&themesTest,
&threadsTest,
&timeoutsTest,
&unitconvTest,
&widgetsTest,
&windowsTest,
NULL
};
Copied: trunk/tests/widgets.c (from rev 9727, trunk/tests/themes.c)
===================================================================
--- trunk/tests/widgets.c (rev 0)
trunk/tests/widgets.c2015-01-14 07:21:37 UTC (rev 9728)
< at >< at > -0,0 1,375 < at >< at >
/*Public domain*/
/*
* This application displays a set of standard Agar-GUI widgets.
*/
#include "agartest.h"
#include <agar/dev.h>
#include <stdio.h>
#include <math.h>
#include <agar/core/types.h>
#include <agar/config/ag_debug.h>
#include <agar/config/version.h>
char textBuffer[30];
/* Example callback for combo-selected. */
static void
ComboSelected(AG_Event *event)
{
AG_TlistItem *ti = AG_PTR(1);
AG_TextMsg(AG_MSG_INFO, "Selected Item: %s", ti->text);
}
/* Show the agar-dev "Preferences" dialog. */
static void
Preferences(AG_Event *event)
{
DEV_ConfigShow();
}
static void
SetWordWrap(AG_Event *event)
{
AG_Textbox *textbox = AG_PTR(1);
int flag = AG_INT(2);
AG_TextboxSetWordWrap(textbox, flag);
}
static int
TestGUI(void *obj, AG_Window *win)
{
char path[AG_PATHNAME_MAX];
AG_Box *hBox, *vBox;
AG_Pane *pane;
AG_Combo *com;
AG_UCombo *ucom;
AG_Box *div1, *div2;
AG_Textbox *tbox;
int i;
/*
* Pane provides two Box containers which can be resized using
* a control placed in the middle.
*/
pane = AG_PaneNewHoriz(win, AG_PANE_EXPAND);
AG_PaneSetDivisionMin(pane, 0, 50, 100);
AG_PaneMoveDividerPct(pane, 40);
div1 = pane->div[0];
div2 = pane->div[1];
{
char path[AG_PATHNAME_MAX];
AG_Label *lbl;
/* The Pixmap widget displays a raster surface. */
if (!AG_ConfigFile("load-path", "agar", "bmp", path, sizeof(path)))
AG_PixmapFromBMP(div1, 0, path);
/*
* The Label widget provides a simple static or polled label
* (polled labels use special format strings; see AG_Label(3)
* for details).
*/
AG_LabelNewS(div1, 0, "This is a static label");
lbl = AG_LabelNewPolled(div1, AG_LABEL_FRAME|AG_LABEL_EXPAND,
"This is a polled label.\n"
"Window is at %i,%i (%ux%u)",
&AGWIDGET(win)->x,
&AGWIDGET(win)->y,
&AGWIDGET(win)->w,
&AGWIDGET(win)->h);
AG_LabelSizeHint(lbl, 1,
"This is a polled label\n"
"Window is at 0000,0000 (0000x0000)");
AG_LabelJustify(lbl, AG_TEXT_CENTER);
}
/*
* Box is a general-purpose widget container. We use AG_BoxNewHoriz()
* for horizontal widget packing.
*/
hBox = AG_BoxNewHoriz(div1, AG_BOX_HOMOGENOUS|AG_BOX_HFILL);
{
/*
* The Button widget is a simple push-button. It is typically
* used to trigger events, but it can also bind its state to
* an boolean (integer) value or a bitmask.
*/
for (i = 0; i < 5; i )
AG_ButtonNewS(hBox, 0, AG_Printf("%c", 0x41 i));
}
hBox = AG_BoxNewHoriz(div1, AG_BOX_HFILL);
AG_BoxSetHorizAlign(hBox, AG_BOX_CENTER);
AG_BoxSetVertAlign(hBox, AG_BOX_CENTER);
{
/* The Radio checkbox is a group of radio buttons. */
{
const char *radioItems[] = {
"Radio1",
"Radio2",
NULL
};
AG_RadioNew(hBox, 0, radioItems);
}
vBox = AG_BoxNewVert(hBox, 0);
AG_BoxSetLabel(vBox, "Some checkboxes");
{
/*
* The Checkbox widget can bind to boolean values
* and bitmasks.
*/
AG_CheckboxNew(vBox, 0, "Checkbox 1");
AG_CheckboxNew(vBox, 0, "Checkbox 2");
}
}
/* Separator simply renders horizontal or vertical line. */
AG_SeparatorNew(div1, AG_SEPARATOR_HORIZ);
/*
* The Combo widget is a textbox widget with a expander button next
* to it. The button triggers a popup window which displays a list
* (using the AG_Tlist(3) widget).
*/
com = AG_ComboNew(div1, AG_COMBO_HFILL, "Combo: ");
AG_ComboSizeHint(com, "Item #00 ", 10);
AG_SetEvent(com, "combo-selected", ComboSelected, NULL);
/* UCombo is a variant of Combo which looks like a single button. */
ucom = AG_UComboNew(div1, AG_UCOMBO_HFILL);
AG_UComboSizeHint(ucom, "Item #1234", 5);
/* Populate the Tlist displayed by the combo widgets we just created. */
for (i = 0; i < 50; i ) {
char text[32];
/* This is more efficient than AG_Printf() */
AG_Strlcpy(text, "Item #", sizeof(text));
AG_StrlcatInt(text, i, sizeof(text));
AG_TlistAddS(com->list, NULL, text);
AG_TlistAddS(ucom->list, NULL, text);
}
/*
* Numerical binds to an integral or floating-point number.
* It can also provides built-in unit conversion (see AG_Units(3)).
*/
{
AG_Numerical *num;
static float myFloat = 1.0f;
static int myInt = 50;
num = AG_NumericalNewS(div1,
AG_NUMERICAL_EXCL|AG_NUMERICAL_HFILL,
"cm", "Real: ");
AG_BindFloat(num, "value", &myFloat);
AG_SetFloat(num, "inc", 1.0f);
num = AG_NumericalNewS(div1,
AG_NUMERICAL_EXCL|AG_NUMERICAL_HFILL,
NULL, "Int: ");
AG_BindInt(num, "value", &myInt);
AG_SetInt(num, "min", -100);
AG_SetInt(num, "max", 100);
}
/*
* Textbox is a single or multiline text edition widget. It can bind
* to fixed-size or dynamically-sized buffers in any character set
* encoding.
*/
{
AG_Strlcpy(textBuffer, "Foo bar baz bezo", sizeof(textBuffer));
/* Create a textbox bound to a fixed-size buffer */
tbox = AG_TextboxNew(div1,
AG_TEXTBOX_EXCL|AG_TEXTBOX_HFILL,
"Fixed text buffer: ");
AG_TextboxBindUTF8(tbox, textBuffer, sizeof(textBuffer));
/* Create a textbox bound to a built-in AG_Text element */
tbox = AG_TextboxNew(div1,
AG_TEXTBOX_EXCL|AG_TEXTBOX_MULTILINGUAL|AG_TEXTBOX_HFILL,
"AG_Text element: ");
AG_TextboxSetString(tbox, "Foo");
}
AG_SeparatorNewHoriz(div1);
/*
* Scrollbar provides three bindings, "value", "min" and "max",
* which we can bind to integers or floating-point variables.
* Progressbar and Slider have similar interfaces.
*/
{
static int myVal = 50, myMin = -100, myMax = 100, myVisible = 0;
AG_Scrollbar *sb;
AG_Slider *sl;
AG_ProgressBar *pb;
sb = AG_ScrollbarNew(div1, AG_SCROLLBAR_HORIZ,
AG_SCROLLBAR_NOAUTOHIDE|AG_SCROLLBAR_EXCL|AG_SCROLLBAR_HFILL);
AG_BindInt(sb, "value", &myVal);
AG_BindInt(sb, "min", &myMin);
AG_BindInt(sb, "max", &myMax);
AG_BindInt(sb, "visible", &myVisible);
AG_SetInt(sb, "inc", 10);
sl = AG_SliderNew(div1, AG_SLIDER_HORIZ,
AG_SLIDER_EXCL|AG_SLIDER_HFILL);
AG_BindInt(sl, "value", &myVal);
AG_BindInt(sl, "min", &myMin);
AG_BindInt(sl, "max", &myMax);
AG_SetInt(sl, "inc", 10);
pb = AG_ProgressBarNew(div1, AG_PROGRESS_BAR_HORIZ,
AG_PROGRESS_BAR_EXCL|AG_PROGRESS_BAR_SHOW_PCT);
AG_BindInt(pb, "value", &myVal);
AG_BindInt(pb, "min", &myMin);
AG_BindInt(pb, "max", &myMax);
}
/*
* Notebook provides multiple containers which can be selected by
* the user.
*/
{
AG_Notebook *nb;
AG_NotebookTab *ntab;
AG_Table *table;
AG_Menu *menu;
AG_MenuItem *m;
/* Create a test menu */
menu = AG_MenuNew(div2, AG_MENU_HFILL);
m = AG_MenuNode(menu->root, "File", NULL);
{
AG_MenuAction(m, "Agar Preferences...", agIconGear.s,
Preferences, NULL);
}
m = AG_MenuNode(menu->root, "Test Menu", NULL);
{
AG_MenuNode(m, "Submenu A", NULL);
AG_MenuSeparator(m);
m = AG_MenuNode(m, "Submenu B", NULL);
AG_MenuNode(m, "Submenu C", NULL);
AG_MenuNode(m, "Submenu D", NULL);
AG_MenuNode(m, "Submenu E", NULL);
}
nb = AG_NotebookNew(div2, AG_NOTEBOOK_EXPAND);
ntab = AG_NotebookAddTab(nb, "Some table", AG_BOX_VERT);
{
float f;
/*
* AG_Table displays a set of cells organized in
* rows and columns. It is optimized for cases where
* the table is static or needs to be repopulated
* periodically.
*/
table = AG_TableNew(ntab, AG_TABLE_EXPAND);
AG_TableAddCol(table, "x", "33%", NULL);
AG_TableAddCol(table, "sin(x)", "33%", NULL);
AG_TableAddCol(table, "cos(x)", "33%", NULL);
for (f = 0.0f; f < 60.0f; f = 0.3f) {
/*
* Insert a Table row for sin(f) and cos(f).
* The directives of the format string are
* documented in AG_Table(3).
*/
AG_TableAddRow(table, "%.02f:%.02f:%.02f",
f, sin(f), cos(f));
}
}
ntab = AG_NotebookAddTab(nb, "Some text", AG_BOX_VERT);
{
char *someText;
size_t size, bufSize;
FILE *f;
/*
* Textboxes with the MULTILINE flag provide basic
* text edition functionality. The CATCH_TAB flag
* causes the widget to receive TAB key events
* (normally used to focus other widgets).
*/
tbox = AG_TextboxNewS(ntab,
AG_TEXTBOX_MULTILINE|AG_TEXTBOX_CATCH_TAB|
AG_TEXTBOX_EXPAND|AG_TEXTBOX_EXCL, NULL);
AG_WidgetSetFocusable(tbox, 1);
/*
* Load the contents of this file into a buffer. Make
* the buffer a bit larger so the user can try
* entering text.
*/
if (!AG_ConfigFile("load-path", "loss", "txt", path, sizeof(path)) &&
(f = fopen(path, "r")) != NULL) {
fseek(f, 0, SEEK_END);
size = ftell(f);
fseek(f, 0, SEEK_SET);
bufSize = size 1024;
someText = AG_Malloc(bufSize);
(void)fread(someText, size, 1, f);
fclose(f);
someText[size] = '\0';
} else {
someText = AG_Strdup("Failed to load loss.txt");
bufSize = strlen(someText) 1;
}
/*
* Bind the buffer's contents to the Textbox. The
* size argument to AG_TextboxBindUTF8() must include
* space for the terminating NUL.
*/
AG_TextboxBindUTF8(tbox, someText, bufSize);
/* Add a word wrapping control */
AG_CheckboxNewFn(ntab, 0, "Word wrapping",
SetWordWrap, "%p", tbox);
}
ntab = AG_NotebookAddTab(nb, "Empty tab", AG_BOX_VERT);
}
return (0);
}
static int
Init(void *obj)
{
DEV_InitSubsystem(0);
return (0);
}
static void
Destroy(void *obj)
{
DEV_DestroySubsystem();
}
const AG_TestCase widgetsTest = {
"widgets",
N_("Display various standard Agar widgets"),
"1.5.0",
0,
sizeof(AG_TestInstance),
Init,
Destroy,
NULL,/* test */
TestGUI,
NULL/* bench */
};
[Less]
|