[GB.NCURSES]

* NEW: Allow to apply attributes and colours to a particular
  Window.Print{,Center}()
* NEW: Change Window.Attributes into a bitmask (Integer)
* NEW: .Window.Attrs isn't anymore. The Attr static class now provides
  OR-able constants to assign to Window.Attributes. .Char.Attrs, however,
  remains a virtual object to manage attributes on a per character basis
* NEW: Provide Window.Pair to set the colour pair for all *subsequent*
  writes, as opposed to Foreground and Background which set the colours
  of all that is and will be

[EXAMPLES]
* NEW: Pong: Use gb.ncurses improvements



git-svn-id: svn://localhost/gambas/trunk@5625 867c0c6c-44f3-4631-809d-bfa615b0a4ec
This commit is contained in:
Tobias Boege 2013-04-30 10:57:44 +00:00
parent b913263661
commit 5c640cd4d4
2 changed files with 78 additions and 80 deletions

View file

@ -167,10 +167,8 @@ Private Sub Redraw()
Dim iX As Integer = Window.Width / 4 Dim iX As Integer = Window.Width / 4
' Scores and net ' Scores and net
Window.Attributes.Reverse = True Window.Print(" " & Str$($iS1) & " ", iX, 1, Attr.Reverse)
Window.Print(" " & Str$($iS1) & " ", iX, 1) Window.Print(" " & Str$($iS2) & " ", iX * 3, 1, Attr.Reverse)
Window.Print(" " & Str$($iS2) & " ", iX * 3, 1)
Window.Attributes.Reverse = False
Window.DrawVLine(Window.Width / 2 + 1, 0, Window.Height, ".") Window.DrawVLine(Window.Width / 2 + 1, 0, Window.Height, ".")
' Players and ball may overwrite the unimportant stuff above ' Players and ball may overwrite the unimportant stuff above
$hP1.Draw() $hP1.Draw()

View file

@ -305,10 +305,15 @@ BEGIN_METHOD_VOID(Window_Center)
END_METHOD END_METHOD
static void CWINDOW_print(CWINDOW *win, char *str, int x, int y) static void CWINDOW_print(CWINDOW *win, char *str, int x, int y,
attr_t attr, int pair)
{ {
int width; int width;
char *p, *q; char *p, *q;
attr_t asave; short psave;
wattr_get(win->content, &asave, &psave, NULL);
wattr_set(win->content, attr, pair, NULL);
p = str; p = str;
do { do {
@ -338,15 +343,18 @@ static void CWINDOW_print(CWINDOW *win, char *str, int x, int y)
x = 0; x = 0;
} while (*p); } while (*p);
CWINDOW_locate(win, x, y); CWINDOW_locate(win, x, y);
wattr_set(win->content, asave, psave, NULL);
} }
BEGIN_METHOD(Window_Print, GB_STRING text; GB_INTEGER x; GB_INTEGER y) BEGIN_METHOD(Window_Print, GB_STRING text; GB_INTEGER x; GB_INTEGER y;
GB_INTEGER attr; GB_INTEGER pair)
char text[LENGTH(text) + 1]; char text[LENGTH(text) + 1];
strncpy(text, STRING(text), LENGTH(text)); strncpy(text, STRING(text), LENGTH(text));
text[LENGTH(text)] = 0; text[LENGTH(text)] = 0;
CWINDOW_print(THIS, text, VARGOPT(x, -1), VARGOPT(y, -1)); CWINDOW_print(THIS, text, VARGOPT(x, -1), VARGOPT(y, -1),
VARGOPT(attr, A_NORMAL), VARGOPT(pair, 0));
REFRESH(); REFRESH();
END_METHOD END_METHOD
@ -358,12 +366,15 @@ BEGIN_METHOD_VOID(Window_Raise)
END_METHOD END_METHOD
BEGIN_METHOD(Window_PrintCenter, GB_STRING text) BEGIN_METHOD(Window_PrintCenter, GB_STRING text; GB_INTEGER attr;
GB_INTEGER pair)
int lines = 1; int lines = 1;
int x, y; int x, y;
char text[LENGTH(text) + 1]; char text[LENGTH(text) + 1];
char *p, *q; char *p, *q;
attr_t attr = VARGOPT(attr, A_NORMAL);
short pair = VARGOPT(pair, 0);
memcpy(text, STRING(text), LENGTH(text)); memcpy(text, STRING(text), LENGTH(text));
text[LENGTH(text)] = 0; text[LENGTH(text)] = 0;
@ -378,7 +389,7 @@ BEGIN_METHOD(Window_PrintCenter, GB_STRING text)
while (lines--) { while (lines--) {
if (!lines) { if (!lines) {
x = (getmaxx(THIS->content) - strlen(p)) / 2; x = (getmaxx(THIS->content) - strlen(p)) / 2;
CWINDOW_print(THIS, p, x, y); CWINDOW_print(THIS, p, x, y, attr, pair);
} else { } else {
q = strchr(p, '\n'); q = strchr(p, '\n');
if (q == p + 1) { if (q == p + 1) {
@ -387,7 +398,7 @@ BEGIN_METHOD(Window_PrintCenter, GB_STRING text)
} }
*q = 0; *q = 0;
x = (getmaxx(THIS->content) - (q - p)) / 2; x = (getmaxx(THIS->content) - (q - p)) / 2;
CWINDOW_print(THIS, p, x, y); CWINDOW_print(THIS, p, x, y, attr, pair);
y++; y++;
p = q + 1; p = q + 1;
*q = '\n'; *q = '\n';
@ -506,6 +517,43 @@ BEGIN_METHOD_VOID(Window_SetFocus)
END_METHOD END_METHOD
BEGIN_PROPERTY(Window_Attributes)
if (READ_PROPERTY) {
attr_t attr;
short pair;
/* XXX: My ncurses header produces a GCC warning here
* because apparently wattr_get() is macro which does a
* NULL pointer check on its arguments of which two lay
* on the stack. So GCC correctly detects the non-
* necessity of that check. */
wattr_get(THIS->content, &attr, &pair, NULL);
GB.ReturnInteger(attr);
return;
}
wattrset(THIS->content, VPROP(GB_INTEGER));
END_PROPERTY
/* This is *not* a shortcut to setting Window.{Fore,Back}ground. The latter
* two set the colour of everything in the window. This function only sets
* the colour pair for all subsequent writes! */
BEGIN_PROPERTY(Window_Pair)
chtype bkgd;
bkgd = getbkgd(THIS->content);
if (READ_PROPERTY) {
GB.ReturnInteger(PAIR_NUMBER(bkgd & A_COLOR));
return;
}
bkgd = COLOR_PAIR(VPROP(GB_INTEGER));
wbkgdset(THIS->content, bkgd);
END_PROPERTY
#define COLOR_METHOD(r, f, b) \ #define COLOR_METHOD(r, f, b) \
short pair = PAIR_NUMBER(getbkgd(THIS->content)); \ short pair = PAIR_NUMBER(getbkgd(THIS->content)); \
short fg, bg; \ short fg, bg; \
@ -523,6 +571,16 @@ if (pair == -1) { \
wbkgd(THIS->content, COLOR_PAIR(pair) | ' '); \ wbkgd(THIS->content, COLOR_PAIR(pair) | ' '); \
REFRESH(); REFRESH();
/*
* One should be careful when using these two properties. wbkgd() changes
* fore- *and* background of *all* characters in the window. So setting
* the background may result in resetting even the foreground of differently
* coloured characters.
*
* Best is to only set Background/Foreground once at the beginning of the
* program when using colours extensively during the program.
*/
BEGIN_PROPERTY(Window_Background) BEGIN_PROPERTY(Window_Background)
COLOR_METHOD(bg, fg, VPROP(GB_INTEGER)); COLOR_METHOD(bg, fg, VPROP(GB_INTEGER));
@ -677,8 +735,8 @@ GB_DESC CWindowDesc[] = {
GB_METHOD("DrawHLine", NULL, Window_DrawHLine,"(X)i(Y)i(Len)i(C)s"), GB_METHOD("DrawHLine", NULL, Window_DrawHLine,"(X)i(Y)i(Len)i(C)s"),
GB_METHOD("DrawVLine", NULL, Window_DrawVLine,"(X)i(Y)i(Len)i(C)s"), GB_METHOD("DrawVLine", NULL, Window_DrawVLine,"(X)i(Y)i(Len)i(C)s"),
GB_METHOD("Print", NULL, Window_Print, "(Text)s[(X)i(Y)i]"), GB_METHOD("Print", NULL, Window_Print, "(Text)s[(X)i(Y)i(Attr)i(Pair)i]"),
GB_METHOD("PrintCenter", NULL, Window_PrintCenter, "(Text)s"), GB_METHOD("PrintCenter", NULL, Window_PrintCenter, "(Text)s[(Attr)i(Pair)i]"),
GB_METHOD("Locate", NULL, Window_Locate, "(X)i(Y)i"), GB_METHOD("Locate", NULL, Window_Locate, "(X)i(Y)i"),
@ -689,12 +747,13 @@ GB_DESC CWindowDesc[] = {
GB_METHOD("SetFocus", NULL, Window_SetFocus, NULL), GB_METHOD("SetFocus", NULL, Window_SetFocus, NULL),
GB_PROPERTY_SELF("Attributes", ".Window.Attrs"), GB_PROPERTY("Attributes", "i", Window_Attributes),
GB_PROPERTY("Background", "i", Window_Background), GB_PROPERTY("Background", "i", Window_Background),
GB_PROPERTY("Paper", "i", Window_Background), GB_PROPERTY("Paper", "i", Window_Background),
GB_PROPERTY("Foreground", "i", Window_Foreground), GB_PROPERTY("Foreground", "i", Window_Foreground),
GB_PROPERTY("Pen", "i", Window_Foreground), GB_PROPERTY("Pen", "i", Window_Foreground),
GB_PROPERTY("Pair", "i", Window_Pair),
GB_PROPERTY("Border", "i", Window_Border), GB_PROPERTY("Border", "i", Window_Border),
GB_PROPERTY("Buffered", "b", Window_Buffered), GB_PROPERTY("Buffered", "b", Window_Buffered),
@ -718,77 +777,18 @@ GB_DESC CWindowDesc[] = {
}; };
/* /*
* .Window.Attrs * Attrs
*/ */
#define WIN_ATTR_METHOD(a) \
if (READ_PROPERTY) { \
GB.ReturnBoolean(getattrs(THIS->content) & a); \
return; \
} \
if (VPROP(GB_BOOLEAN)) \
wattron(THIS->content, a); \
else \
wattroff(THIS->content, a); \
REFRESH();
BEGIN_PROPERTY(WindowAttrs_Normal)
/* Normal is special because it turns off all other attributes and can't itself been turned off */
if (READ_PROPERTY)
GB.ReturnBoolean(getattrs(THIS->content) == A_NORMAL);
if (VPROP(GB_BOOLEAN))
wattrset(THIS->content, A_NORMAL);
REFRESH();
END_PROPERTY
BEGIN_PROPERTY(WindowAttrs_Underline)
WIN_ATTR_METHOD(A_UNDERLINE);
END_PROPERTY
BEGIN_PROPERTY(WindowAttrs_Reverse)
WIN_ATTR_METHOD(A_REVERSE);
END_PROPERTY
BEGIN_PROPERTY(WindowAttrs_Blink)
WIN_ATTR_METHOD(A_BLINK);
END_PROPERTY
BEGIN_PROPERTY(WindowAttrs_Bold)
WIN_ATTR_METHOD(A_BOLD);
END_PROPERTY
/* Set background and foreground at once, more efficiently */
BEGIN_PROPERTY(WindowAttrs_ColorPair)
if (READ_PROPERTY) {
GB.ReturnInteger(PAIR_NUMBER(getbkgd(THIS->content)));
return;
}
wbkgd(THIS->content, COLOR_PAIR(VPROP(GB_INTEGER)) | ' ');
END_PROPERTY
GB_DESC CWindowAttrsDesc[] = { GB_DESC CWindowAttrsDesc[] = {
GB_DECLARE(".Window.Attrs", 0), GB_DECLARE("Attr", 0),
GB_VIRTUAL_CLASS(), GB_NOT_CREATABLE(),
GB_PROPERTY("Normal", "b", WindowAttrs_Normal), GB_CONSTANT("Normal", "i", A_NORMAL),
GB_PROPERTY("Underline", "b", WindowAttrs_Underline), GB_CONSTANT("Underline", "i", A_UNDERLINE),
GB_PROPERTY("Reverse", "b", WindowAttrs_Reverse), GB_CONSTANT("Reverse", "i", A_REVERSE),
GB_PROPERTY("Blink", "b", WindowAttrs_Blink), GB_CONSTANT("Blink", "i", A_BLINK),
GB_PROPERTY("Bold", "b", WindowAttrs_Bold), GB_CONSTANT("Bold", "i", A_BOLD),
GB_PROPERTY("ColorPair", "i", WindowAttrs_ColorPair),
GB_END_DECLARE GB_END_DECLARE
}; };