Hi Stephen,
Please find attached a proposed patch against Agar 1.6.0 which adds the
AG_RADIO_HOMOGENOUS flag option to divide space equally between radio
items (similar to the AG_BOX_HOMOGENOUS option of AG_Box).
The feature could use some further cosmetic improvements (such as word
wrapping or reducing the font size of labels in case space becomes
insufficient).
Let me know if that fixes the problem for you.
On 2/7/21 7:07 AM, Stephen Meatheringham wrote:
Good Evening
I have recently begun looking into the feasibility of using the AGAR
library to work with x-windows under Linux Mint (19.3). I have made and
installed AGAR 1.6.0 without problems. Looking at the examples in the
tests directory plus the online documentation it all looks fairly
straightforward.
I am having a problem with radio buttons. Hence, I think there must be
something I am not understanding. I will include some code below,
however, firstly I will explain what I am trying to achieve.
I create a window of a certain size (300x400). I divide the window
vertically into two panes. The upper pane will have a series of 4 radio
buttons; the lower pane a notebook with two pages.
I have an array of 4 text strings that I use as labels on the radio
buttons. I would like the 4 radio buttons aligned horizontally and
filling the x-direction. I can get them aligned horizontally, however, I
cannot get them to fill the available space in the x-direction. I have
tried both placing them in a horizontal box and not. It makes no difference.
The code is below. Please note that it is minimal. There are other
items that will be displayed within other horizontal and vertical panes
and divisions. I have simply deleted that code as it is extraneous to
this test.
Any thoughts/suggestions would be most appreciated.
regards
Stephen Meatheringham
Canberra, Australia
///////////////////////////////////////////////////////////////////////////
#include <agar/core.h>
#include <agar/gui.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
int i;
AG_Window *win;
char *driver = NULL;
AG_Pane *vPane;
AG_Box *hBox, *div;
AG_Notebook *nb;
AG_NotebookTab *nt;
AG_Radio *rad;
if (AG_InitCore(NULL, 0) == -1 || AG_InitGraphics(driver) == -1)
return (1);
AG_BindStdGlobalKeys();
win = AG_WindowNew(AG_WINDOW_MAIN);
AG_WindowSetGeometry(win, 100, 100, 300, 400);
// Divide the window into two panes
vPane = AG_PaneNewVert(win, AG_PANE_UNMOVABLE | AG_PANE_HFILL);
div = vPane->div[0];
// In the upper pane
// Create a horizontal box
// Add 4 radio buttons, horizontally-oriented and filling the x-direction
hBox = AG_BoxNewHoriz(div, AG_BOX_HOMOGENOUS | AG_BOX_HFILL);
const char *radioItems[] = {
"String1", "String2", "String3", "String4", NULL };
rad = AG_RadioNewFn(hBox, AG_RADIO_HFILL, NULL, AGWINDETACH(win));
AG_RadioSetDisposition(rad, AG_RADIO_HORIZ);
AG_RadioItemsFromArray(rad, radioItems);
// In the lower pane
// Create a notebook with two pages in the bottom section of the window
nb = AG_NotebookNew(vPane->div[1], AG_NOTEBOOK_EXPAND);
nt = AG_NotebookAdd(nb, "Some text", AG_BOX_VERT);
nt = AG_NotebookAdd(nb, "Empty tab", AG_BOX_VERT);
AG_NotebookSelect(nb, nt);
AG_WindowShow(win);
AG_EventLoop();
return (0);
}
_______________________________________________
Agar mailing list
[email protected]
http://libagar.org/lists.html
Index: gui/radio.c
===================================================================
--- gui/radio.c (revision 10922)
+++ gui/radio.c (working copy)
@@ -324,8 +324,14 @@
const int radius = (WFONT(rad)->lineskip >> 1);
const int x = WIDGET(rad)->paddingLeft + WFONT(rad)->lineskip;
const int value = AG_GetInt(rad, "value");
- int i, y;
+ int i, y, wDiv;
+ if ((rad->flags & AG_RADIO_HOMOGENOUS) && rad->nItems > 0) {
+ wDiv = HEIGHT(rad) / rad->nItems;
+ } else {
+ wDiv = 0;
+ }
+
for (i = 0, y = WIDGET(rad)->paddingTop;
i < rad->nItems;
i++) {
@@ -339,16 +345,16 @@
AG_TextRender(radi->text));
}
S = WSURFACE(rad, radi->surface);
+ r.h = (wDiv > 0) ? wDiv : S->h;
if (i == rad->hoverItem) {
r.x = WIDGET(rad)->paddingLeft;
r.y = y;
r.w = WIDTH(rad) - (WIDGET(rad)->paddingLeft +
WIDGET(rad)->paddingRight);
- r.h = S->h;
AG_DrawRect(rad, &r, &WCOLOR_HOVER(rad,BG_COLOR));
}
xc = WIDGET(rad)->paddingLeft + radius;
- yc = y + (S->h >> 1);
+ yc = y + (r.h >> 1);
AG_DrawCircleFilled(rad, xc,yc, radius, cFg);
AG_DrawCircle(rad, xc,yc, radius, cLine);
if (i == value) {
@@ -358,8 +364,11 @@
AG_DrawCircle(rad, xc,yc, radius-2,
&WCOLOR_HOVER(rad, LINE_COLOR));
}
- AG_WidgetBlitSurface(rad, radi->surface, x + WIDGET(rad)->spacingHoriz, y);
- y += S->h + WIDGET(rad)->spacingVert;
+ AG_WidgetBlitSurface(rad, radi->surface,
+ x + WIDGET(rad)->spacingHoriz,
+ y + ((wDiv > 0) ? ((wDiv >> 1) - (S->h >> 1)) : 0));
+
+ y += r.h + WIDGET(rad)->spacingVert;
}
}
@@ -372,8 +381,14 @@
const int radius = (WFONT(rad)->lineskip >> 1);
const int y = WIDGET(rad)->paddingTop + WFONT(rad)->lineskip;
const int value = AG_GetInt(rad, "value");
- int i, x;
+ int i, x, wDiv;
+ if ((rad->flags & AG_RADIO_HOMOGENOUS) && rad->nItems > 0) {
+ wDiv = WIDTH(rad) / rad->nItems;
+ } else {
+ wDiv = 0;
+ }
+
for (i = 0, x = WIDGET(rad)->paddingLeft;
i < rad->nItems;
i++) {
@@ -387,15 +402,15 @@
AG_TextRender(radi->text));
}
S = WSURFACE(rad, radi->surface);
+ r.w = (wDiv > 0) ? wDiv : S->w;
if (i == rad->hoverItem) {
r.x = x;
r.y = WIDGET(rad)->paddingTop;
- r.w = S->w;
r.h = HEIGHT(rad) - (WIDGET(rad)->paddingTop +
WIDGET(rad)->paddingBottom);
AG_DrawRect(rad, &r, &WCOLOR_HOVER(rad,BG_COLOR));
}
- xc = x + (S->w >> 1);
+ xc = x + (r.w >> 1);
yc = WIDGET(rad)->paddingTop + radius;
AG_DrawCircleFilled(rad, xc,yc, radius, cFg);
AG_DrawCircle(rad, xc,yc, radius, cLine);
@@ -406,9 +421,11 @@
AG_DrawCircle(rad, xc,yc, radius-2,
&WCOLOR_HOVER(rad, LINE_COLOR));
}
- AG_WidgetBlitSurface(rad, radi->surface, x,
+ AG_WidgetBlitSurface(rad, radi->surface,
+ x + ((wDiv > 0) ? ((wDiv >> 1) - (S->w >> 1)) : 0),
y + WIDGET(rad)->spacingVert);
- x += S->w + WIDGET(rad)->spacingHoriz;
+
+ x += r.w + WIDGET(rad)->spacingHoriz;
}
}
@@ -485,7 +502,7 @@
AG_Radio *rad = AG_RADIO_SELF();
const int x = AG_INT(1);
const int y = AG_INT(2);
- int i, cur, itemNew = -1;
+ int i, cur, itemNew = -1, wDiv;
if (x < 0 || x > WIDTH(rad) ||
y < 0 || y > HEIGHT(rad))
@@ -493,6 +510,11 @@
switch (rad->type) {
case AG_RADIO_VERT:
+ if ((rad->flags & AG_RADIO_HOMOGENOUS) && rad->nItems > 0) {
+ wDiv = HEIGHT(rad) / rad->nItems;
+ } else {
+ wDiv = 0;
+ }
for (i=0, cur=WIDGET(rad)->paddingTop;
i < rad->nItems;
i++) {
@@ -499,10 +521,14 @@
const AG_RadioItem *radi = &rad->items[i];
int h;
- if (radi->surface != -1) {
- h = WSURFACE(rad,radi->surface)->h;
+ if (wDiv > 0) {
+ h = wDiv;
} else {
- AG_TextSize(radi->text, NULL, &h);
+ if (radi->surface != -1) {
+ h = WSURFACE(rad,radi->surface)->h;
+ } else {
+ AG_TextSize(radi->text, NULL, &h);
+ }
}
if (y >= cur && y <= cur+h) {
itemNew = i;
@@ -512,6 +538,11 @@
}
break;
case AG_RADIO_HORIZ:
+ if ((rad->flags & AG_RADIO_HOMOGENOUS) && rad->nItems > 0) {
+ wDiv = WIDTH(rad) / rad->nItems;
+ } else {
+ wDiv = 0;
+ }
for (i=0, cur=WIDGET(rad)->paddingLeft;
i < rad->nItems;
i++) {
@@ -518,10 +549,14 @@
const AG_RadioItem *radi = &rad->items[i];
int w;
- if (radi->surface != -1) {
- w = WSURFACE(rad,radi->surface)->w;
+ if (wDiv > 0) {
+ w = wDiv;
} else {
- AG_TextSize(radi->text, &w, NULL);
+ if (radi->surface != -1) {
+ w = WSURFACE(rad,radi->surface)->w;
+ } else {
+ AG_TextSize(radi->text, &w, NULL);
+ }
}
if (x >= cur && x <= cur+w) {
itemNew = i;
@@ -548,7 +583,7 @@
const int button = AG_INT(1);
const int x = AG_INT(2);
const int y = AG_INT(3);
- int i, cur, *sel, selNew = -1;
+ int i, cur, *sel, selNew = -1, wDiv;
AG_Variable *value;
if (!AG_WidgetIsFocused(rad))
@@ -561,6 +596,11 @@
switch (rad->type) {
case AG_RADIO_VERT:
+ if ((rad->flags & AG_RADIO_HOMOGENOUS) && rad->nItems > 0) {
+ wDiv = HEIGHT(rad) / rad->nItems;
+ } else {
+ wDiv = 0;
+ }
for (i=0, cur=WIDGET(rad)->paddingTop;
i < rad->nItems;
i++) {
@@ -567,10 +607,14 @@
const AG_RadioItem *radi = &rad->items[i];
int h;
- if (radi->surface != -1) {
- h = WSURFACE(rad,radi->surface)->h;
+ if (wDiv > 0) {
+ h = wDiv;
} else {
- AG_TextSize(radi->text, NULL, &h);
+ if (radi->surface != -1) {
+ h = WSURFACE(rad,radi->surface)->h;
+ } else {
+ AG_TextSize(radi->text, NULL, &h);
+ }
}
if (y >= cur && y <= cur+h) {
selNew = i;
@@ -580,6 +624,11 @@
}
break;
case AG_RADIO_HORIZ:
+ if ((rad->flags & AG_RADIO_HOMOGENOUS) && rad->nItems > 0) {
+ wDiv = WIDTH(rad) / rad->nItems;
+ } else {
+ wDiv = 0;
+ }
for (i=0, cur = WIDGET(rad)->paddingLeft;
i < rad->nItems;
i++) {
@@ -586,10 +635,14 @@
const AG_RadioItem *radi = &rad->items[i];
int w;
- if (radi->surface != -1) {
- w = WSURFACE(rad,radi->surface)->w;
+ if (wDiv > 0) {
+ w = wDiv;
} else {
- AG_TextSize(radi->text, &w, NULL);
+ if (radi->surface != -1) {
+ w = WSURFACE(rad,radi->surface)->w;
+ } else {
+ AG_TextSize(radi->text, &w, NULL);
+ }
}
if (x >= cur && x <= cur+w) {
selNew = i;
Index: gui/radio.h
===================================================================
--- gui/radio.h (revision 10922)
+++ gui/radio.h (working copy)
@@ -27,9 +27,10 @@
struct ag_widget wid; /* AG_Widget -> AG_Radio */
AG_RadioType type; /* Disposition */
Uint flags;
-#define AG_RADIO_HFILL 0x01
-#define AG_RADIO_VFILL 0x02
-#define AG_RADIO_EXPAND (AG_RADIO_HFILL | AG_RADIO_VFILL)
+#define AG_RADIO_HFILL 0x01
+#define AG_RADIO_VFILL 0x02
+#define AG_RADIO_HOMOGENOUS 0x04 /* Divide space equally between items */
+#define AG_RADIO_EXPAND (AG_RADIO_HFILL | AG_RADIO_VFILL)
AG_RadioItem *_Nullable items; /* Array of radio items */
int nItems;
Index: gui/AG_Radio.3
===================================================================
--- gui/AG_Radio.3 (revision 10922)
+++ gui/AG_Radio.3 (working copy)
@@ -94,7 +94,10 @@
Acceptable
.Fa flags
include:
-.Bl -tag -width "AG_RADIO_EXPAND "
+.Pp
+.Bl -tag -width "AG_RADIO_HOMOGENOUS " -compact
+.It AG_RADIO_HOMOGENOUS
+Divide space equally between radio items.
.It AG_RADIO_HFILL
Expand horizontally in parent container.
.It AG_RADIO_VFILL
@@ -225,3 +228,6 @@
and
.Fn AG_RadioSizeHint
appeared in Agar 1.6.0.
+The
+.Dv AG_RADIO_HOMOGENOUS
+option appeared in Agar 1.6.1.
_______________________________________________
Agar mailing list
[email protected]
http://libagar.org/lists.html