[requestchoice] refactor out gadget code

This calls the gadget code that I've refactored into libami/ .
.
This commit is contained in:
Adrian Chadd
2022-04-09 17:35:05 -07:00
parent 48f15595a4
commit e73f47e1fb

View File

@@ -13,30 +13,33 @@
extern struct Library *XLibBase; extern struct Library *XLibBase;
#endif #endif
// These are used for button spacing, not the button itself
#define BUT_BUTSPACE (2*(2+5)) #define BUT_BUTSPACE (2*(2+5))
#define BUT_INTSPACE 12 #define BUT_INTSPACE 12
#define BUT_EXTSPACE 4 #define BUT_EXTSPACE 4
#define BUT_VSPACE 6
#define TXT_HSPACE 48 #include "gadget_button.h"
#define TXT_TOPSPACE 4 #include "gadget_textbox.h"
#define TXT_MIDSPACE 3
#define TXT_BOTSPACE 4
struct choice { struct choice {
struct choice *next; struct choice *next;
const char *text; const char *text;
int l, w; int l, w;
Window win; struct gadget_button *b;
} *firstchoice=NULL, *lastchoice=NULL; } *firstchoice=NULL, *lastchoice=NULL;
struct line { struct line {
struct line *next; struct line *next;
const char *text; const char *text;
int l, w, h; int l, w, h;
} *firstline=NULL, *lastline=NULL; } *firstline=NULL, *lastline=NULL;
Display *dpy; Display *dpy;
Window root, mainwin, textwin; Window root, mainwin;
//Window textwin;
struct gadget_textbox *g_textbox;
char *progname; char *progname;
GC gc; GC gc;
Pixmap stipple; Pixmap stipple;
@@ -49,43 +52,59 @@ struct DrawInfo dri;
struct RDArgs *ra=NULL; struct RDArgs *ra=NULL;
void selection(int n) static void
selection(int n)
{ {
printf("%d\n", n); printf("%d\n", n);
XDestroyWindow(dpy, mainwin); XDestroyWindow(dpy, mainwin);
XCloseDisplay(dpy); XCloseDisplay(dpy);
FreeArgs(ra); FreeArgs(ra);
exit(0); exit(0);
} }
void *myalloc(size_t s) static void
*myalloc(size_t s)
{ {
void *p=calloc(s,1); void *p=calloc(s,1);
if(p) if(p)
return p; return p;
fprintf(stderr, "%s: out of memory!\n", progname); fprintf(stderr, "%s: out of memory!\n", progname);
FreeArgs(ra); FreeArgs(ra);
exit(1); exit(1);
} }
void addchoice(const char *txt) /*
* Add a choice to the list of choices, but don't create
* the button just yet. This'll be done once all of them
* are known and the math to create the window sizing/layout
* can be done.
*/
static void
addchoice(const char *txt)
{ {
struct choice *c=myalloc(sizeof(struct choice)); struct choice *c=myalloc(sizeof(struct choice));
if(lastchoice) if(lastchoice)
lastchoice->next=c; lastchoice->next=c;
else else
firstchoice=c; firstchoice=c;
lastchoice=c; lastchoice=c;
c->l=strlen(c->text=txt);
c->l = strlen(txt);
c->text = txt;
#ifdef USE_FONTSETS #ifdef USE_FONTSETS
totw+=(c->w=XmbTextEscapement(dri.dri_FontSet, c->text, c->l))+BUT_BUTSPACE; totw+=(c->w=XmbTextEscapement(dri.dri_FontSet, c->text, c->l))+BUT_BUTSPACE;
#else #else
totw+=(c->w=XTextWidth(dri.dri_Font, c->text, c->l))+BUT_BUTSPACE; totw+=(c->w=XTextWidth(dri.dri_Font, c->text, c->l))+BUT_BUTSPACE;
#endif #endif
nchoices++; nchoices++;
} }
void addline(const char *txt) /*
* Add a line to the text box that we can draw.
*/
static void
addline(const char *txt)
{ {
struct line *l=myalloc(sizeof(struct line)); struct line *l=myalloc(sizeof(struct line));
if(lastline) if(lastline)
@@ -94,6 +113,13 @@ void addline(const char *txt)
firstline=l; firstline=l;
lastline=l; lastline=l;
l->l=strlen(l->text=txt); l->l=strlen(l->text=txt);
/* These are used to find the size, which we want
* to use in order to determine how big our window
* should be. It's a bit of a chicken/egg problem
* for now whilst this is figured out - it's also
* done in gadget_textbox_addline().
*/
#ifdef USE_FONTSETS #ifdef USE_FONTSETS
l->w=XmbTextEscapement(dri.dri_FontSet, l->text, l->l); l->w=XmbTextEscapement(dri.dri_FontSet, l->text, l->l);
#else #else
@@ -104,57 +130,13 @@ void addline(const char *txt)
maxw=l->w; maxw=l->w;
} }
void refresh_text()
{
int w=totw-BUT_EXTSPACE-BUT_EXTSPACE;
int h=toth-TXT_TOPSPACE-TXT_MIDSPACE-TXT_BOTSPACE-BUT_VSPACE-
(dri.dri_Ascent+dri.dri_Descent);
int x=(totw-maxw+TXT_HSPACE)>>1;
int y=((dri.dri_Ascent+dri.dri_Descent)>>1)+dri.dri_Ascent;
struct line *l;
XSetForeground(dpy, gc, dri.dri_Pens[SHADOWPEN]);
XDrawLine(dpy, textwin, gc, 0, 0, w-2, 0);
XDrawLine(dpy, textwin, gc, 0, 0, 0, h-2);
XSetForeground(dpy, gc, dri.dri_Pens[SHINEPEN]);
XDrawLine(dpy, textwin, gc, 0, h-1, w-1, h-1);
XDrawLine(dpy, textwin, gc, w-1, 0, w-1, h-1);
XSetForeground(dpy, gc, dri.dri_Pens[TEXTPEN]);
for(l=firstline; l; l=l->next) {
#ifdef USE_FONTSETS
XmbDrawString(dpy, textwin, dri.dri_FontSet, gc, x, y, l->text, l->l);
#else
XDrawString(dpy, textwin, gc, x, y, l->text, l->l);
#endif
y+=dri.dri_Ascent+dri.dri_Descent;
}
}
void refresh_choice(struct choice *c) void refresh_choice(struct choice *c)
{ {
int w=c->w+BUT_BUTSPACE; gadget_button_refresh(c->b);
int h=dri.dri_Ascent+dri.dri_Descent+BUT_VSPACE;
XSetForeground(dpy, gc, dri.dri_Pens[TEXTPEN]);
#ifdef USE_FONTSETS
XmbDrawString(dpy, c->win, dri.dri_FontSet, gc, BUT_BUTSPACE/2,
dri.dri_Ascent+BUT_VSPACE/2, c->text, c->l);
#else
XDrawString(dpy, c->win, gc, BUT_BUTSPACE/2,
dri.dri_Ascent+BUT_VSPACE/2, c->text, c->l);
#endif
XSetForeground(dpy, gc, dri.dri_Pens[(c==selected && depressed)?
SHADOWPEN:SHINEPEN]);
XDrawLine(dpy, c->win, gc, 0, 0, w-2, 0);
XDrawLine(dpy, c->win, gc, 0, 0, 0, h-2);
XSetForeground(dpy, gc, dri.dri_Pens[(c==selected && depressed)?
SHINEPEN:SHADOWPEN]);
XDrawLine(dpy, c->win, gc, 1, h-1, w-1, h-1);
XDrawLine(dpy, c->win, gc, w-1, 1, w-1, h-1);
XSetForeground(dpy, gc, dri.dri_Pens[BACKGROUNDPEN]);
XDrawPoint(dpy, c->win, gc, w-1, 0);
XDrawPoint(dpy, c->win, gc, 0, h-1);
} }
void split(char *str, const char *delim, void (*func)(const char *)) static void
split(char *str, const char *delim, void (*func)(const char *))
{ {
char *p; char *p;
if((p=strtok(str, delim))) if((p=strtok(str, delim)))
@@ -167,23 +149,21 @@ struct choice *getchoice(Window w)
{ {
struct choice *c; struct choice *c;
for(c=firstchoice; c; c=c->next) for(c=firstchoice; c; c=c->next)
if(w == c->win) if(w == c->b->w)
return c; return c;
return NULL; return NULL;
} }
void toggle(struct choice *c) void toggle(struct choice *c)
{ {
XSetWindowBackground(dpy, c->win, dri.dri_Pens[(depressed&&c==selected)? gadget_button_toggle(c->b);
FILLPEN:BACKGROUNDPEN]);
XClearWindow(dpy, c->win);
refresh_choice(c);
} }
void abortchoice() void abortchoice()
{ {
if(depressed) { if(depressed) {
depressed=0; depressed=0;
gadget_button_set_depressed(selected->b, 0);
toggle(selected); toggle(selected);
} }
selected=NULL; selected=NULL;
@@ -210,6 +190,7 @@ int main(int argc, char *argv[])
static XTextProperty txtprop1, txtprop2; static XTextProperty txtprop1, txtprop2;
int x, y, extra=0, n=0; int x, y, extra=0, n=0;
struct choice *c; struct choice *c;
struct line *l;
Argtype array[3], *atp; Argtype array[3], *atp;
progname=argv[0]; progname=argv[0];
@@ -258,28 +239,41 @@ int main(int argc, char *argv[])
XDrawPoint(dpy, stipple, gc, 0, 1); XDrawPoint(dpy, stipple, gc, 0, 1);
XDrawPoint(dpy, stipple, gc, 1, 0); XDrawPoint(dpy, stipple, gc, 1, 0);
XSetWindowBackgroundPixmap(dpy, mainwin, stipple); XSetWindowBackgroundPixmap(dpy, mainwin, stipple);
g_textbox = gadget_textbox_create(dpy, &dri, gc, mainwin,
BUT_EXTSPACE,
TXT_TOPSPACE,
totw - BUT_EXTSPACE - BUT_EXTSPACE,
toth-TXT_TOPSPACE- TXT_MIDSPACE-TXT_BOTSPACE-BUT_VSPACE- (dri.dri_Ascent+dri.dri_Descent));
#if 0
textwin=XCreateSimpleWindow(dpy, mainwin, BUT_EXTSPACE, TXT_TOPSPACE, totw- textwin=XCreateSimpleWindow(dpy, mainwin, BUT_EXTSPACE, TXT_TOPSPACE, totw-
BUT_EXTSPACE-BUT_EXTSPACE, toth-TXT_TOPSPACE- BUT_EXTSPACE-BUT_EXTSPACE,
TXT_MIDSPACE-TXT_BOTSPACE-BUT_VSPACE-
(dri.dri_Ascent+dri.dri_Descent),
0, dri.dri_Pens[SHADOWPEN], 0, dri.dri_Pens[SHADOWPEN],
dri.dri_Pens[BACKGROUNDPEN]); dri.dri_Pens[BACKGROUNDPEN]);
XSelectInput(dpy, textwin, ExposureMask); XSelectInput(dpy, textwin, ExposureMask);
#endif
/* Lay out + create buttons */
x=BUT_EXTSPACE; x=BUT_EXTSPACE;
y=toth-TXT_BOTSPACE-(dri.dri_Ascent+dri.dri_Descent)-BUT_VSPACE; y=toth-TXT_BOTSPACE-(dri.dri_Ascent+dri.dri_Descent)-BUT_VSPACE;
for(c=firstchoice; c; c=c->next) { for(c=firstchoice; c; c=c->next) {
c->win=XCreateSimpleWindow(dpy, mainwin, c->b = gadget_button_init(dpy, &dri, gc, mainwin,
x+(nchoices==1? (extra>>1): x + (nchoices == 1 ? (extra >> 1) : n++*extra/(nchoices-1)),
n++*extra/(nchoices-1)), y,
y, c->w+BUT_BUTSPACE, c->w + BUT_BUTSPACE,
dri.dri_Ascent+dri.dri_Descent+ // Note: the original code didn't need a +2 here, but
BUT_VSPACE, 0, // when using the ported button gadget it's needed or
dri.dri_Pens[SHADOWPEN], // the bottom of the button isn't shown. Figure out why!
dri.dri_Pens[BACKGROUNDPEN]); dri.dri_Ascent+dri.dri_Descent + BUT_VSPACE + 2);
XSelectInput(dpy, c->win, ExposureMask|ButtonPressMask|ButtonReleaseMask| gadget_button_set_text(c->b, c->text);
EnterWindowMask|LeaveWindowMask);
x+=c->w+BUT_BUTSPACE+BUT_INTSPACE; x+=c->w+BUT_BUTSPACE+BUT_INTSPACE;
} }
/* Lay out + create text box contents */
for (l = firstline; l; l = l->next) {
gadget_textbox_addline(g_textbox, l->text);
}
size_hints.flags = PResizeInc; size_hints.flags = PResizeInc;
txtprop1.value=(unsigned char *)array[0].ptr; txtprop1.value=(unsigned char *)array[0].ptr;
txtprop2.value=(unsigned char *)"RequestChoice"; txtprop2.value=(unsigned char *)"RequestChoice";
@@ -297,20 +291,22 @@ int main(int argc, char *argv[])
switch(event.type) { switch(event.type) {
case Expose: case Expose:
if(!event.xexpose.count) { if(!event.xexpose.count) {
if(event.xexpose.window == textwin) if(event.xexpose.window == g_textbox->w)
refresh_text(); gadget_textbox_refresh(g_textbox);
else if((c=getchoice(event.xexpose.window))) else if((c=getchoice(event.xexpose.window)))
refresh_choice(c); refresh_choice(c);
} }
break; break;
case LeaveNotify: case LeaveNotify:
if(depressed && event.xcrossing.window==selected->win) { if(depressed && event.xcrossing.window==selected->b->w) {
depressed=0; depressed=0;
gadget_button_set_depressed(selected->b, 0);
toggle(selected); toggle(selected);
} }
break; break;
case EnterNotify: case EnterNotify:
if((!depressed) && selected && event.xcrossing.window==selected->win) { if((!depressed) && selected && event.xcrossing.window==selected->b->w) {
gadget_button_set_depressed(selected->b, 1);
depressed=1; depressed=1;
toggle(selected); toggle(selected);
} }
@@ -320,6 +316,7 @@ int main(int argc, char *argv[])
(c=getchoice(event.xbutton.window))) { (c=getchoice(event.xbutton.window))) {
abortchoice(); abortchoice();
depressed=1; depressed=1;
gadget_button_set_depressed(c->b, 1);
toggle(selected=c); toggle(selected=c);
} }
break; break;