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

Reply via email to