diff --git a/executecmd.c b/executecmd.c index d8a7355..04441c3 100644 --- a/executecmd.c +++ b/executecmd.c @@ -21,6 +21,8 @@ #endif #include "drawinfo.h" +#include "gadget_button.h" +#include "gadget_textinput.h" #ifdef AMIGAOS #include @@ -30,27 +32,14 @@ extern struct Library *XLibBase; #define MAX_CMD_CHARS 256 #define VISIBLE_CMD_CHARS 35 -#define BOT_SPACE 4 -#define TEXT_SIDE 8 -#define BUT_SIDE 12 -#define TOP_SPACE 4 -#define INT_SPACE 7 -#define BUT_VSPACE 2 -#define BUT_HSPACE 8 - static const char ok_txt[]="Ok", cancel_txt[]="Cancel"; static const char enter_txt[]="Enter Command and its Arguments:"; static const char cmd_txt[]="Command:"; static int selected=0, depressed=0, stractive=1; -static Window button[3]; -static const char *buttxt[]={ NULL, ok_txt, cancel_txt }; -char cmdline[MAX_CMD_CHARS+1]; -int buf_len=0; -int cur_pos=0; -int left_pos=0; -int cur_x=6; +struct gadget_button *buttons[3]; +struct gadget_textinput *text_input; char *progname; @@ -58,368 +47,121 @@ Display *dpy; struct DrawInfo dri; -Window root, mainwin, strwin; +Window root, mainwin; GC gc; -int strgadw, strgadh, fh, mainw, mainh, butw; +int strgadw, strgadh; + +int fh; +int mainw, mainh, butw; #ifdef USE_FONTSETS static XIM xim = (XIM) NULL; static XIC xic = (XIC) NULL; #endif -int getchoice(Window w) +/* + * Loop through the button list and see if we find + * a button. Return 0 if we don't find a button. + * + * Yeah, ideally we'd do this in some gadget / intuition + * UI layer thing, but we're not there yet. + */ +static int +getchoice(Window w) { - int i; - for(i=1; i<3; i++) - if(button[i]==w) - return i; - return 0; -} - -void refresh_button(Window w, const char *txt, int idx) -{ - int h=fh+2*BUT_VSPACE, l=strlen(txt); -#ifdef USE_FONTSETS - int tw=XmbTextEscapement(dri.dri_FontSet, txt, l); -#else - int tw=XTextWidth(dri.dri_Font, txt, l); -#endif - XSetForeground(dpy, gc, dri.dri_Pens[TEXTPEN]); -#ifdef USE_FONTSETS - XmbDrawString(dpy, w, dri.dri_FontSet, gc, (butw-tw)>>1, - dri.dri_Ascent+BUT_VSPACE, txt, l); -#else - XDrawString(dpy, w, gc, (butw-tw)>>1, - dri.dri_Ascent+BUT_VSPACE, txt, l); -#endif - XSetForeground(dpy, gc, dri.dri_Pens[(selected==idx && depressed)? - SHADOWPEN:SHINEPEN]); - XDrawLine(dpy, w, gc, 0, 0, butw-2, 0); - XDrawLine(dpy, w, gc, 0, 0, 0, h-2); - XSetForeground(dpy, gc, dri.dri_Pens[(selected==idx && depressed)? - SHINEPEN:SHADOWPEN]); - XDrawLine(dpy, w, gc, 1, h-1, butw-1, h-1); - XDrawLine(dpy, w, gc, butw-1, 1, butw-1, h-1); - XSetForeground(dpy, gc, dri.dri_Pens[BACKGROUNDPEN]); - XDrawPoint(dpy, w, gc, butw-1, 0); - XDrawPoint(dpy, w, gc, 0, h-1); -} - -void refresh_main(void) -{ - int w; - - XSetForeground(dpy, gc, dri.dri_Pens[TEXTPEN]); -#ifdef USE_FONTSETS - XmbDrawString(dpy, mainwin, dri.dri_FontSet, gc, TEXT_SIDE, - TOP_SPACE+dri.dri_Ascent, enter_txt, strlen(enter_txt)); -#else - XDrawString(dpy, mainwin, gc, TEXT_SIDE, TOP_SPACE+dri.dri_Ascent, - enter_txt, strlen(enter_txt)); -#endif - XSetForeground(dpy, gc, dri.dri_Pens[HIGHLIGHTTEXTPEN]); -#ifdef USE_FONTSETS - w=XmbTextEscapement(dri.dri_FontSet, cmd_txt, strlen(cmd_txt)); - XmbDrawString(dpy, mainwin, dri.dri_FontSet, gc, - mainw-strgadw-w-TEXT_SIDE-BUT_SIDE, - TOP_SPACE+fh+INT_SPACE+dri.dri_Ascent, - cmd_txt, strlen(cmd_txt)); -#else - w=XTextWidth(dri.dri_Font, cmd_txt, strlen(cmd_txt)); - XDrawString(dpy, mainwin, gc, mainw-strgadw-w-TEXT_SIDE-BUT_SIDE, - TOP_SPACE+fh+INT_SPACE+dri.dri_Ascent, - cmd_txt, strlen(cmd_txt)); -#endif -} - -void refresh_str_text(void) -{ - int l, mx=6; - XSetForeground(dpy, gc, dri.dri_Pens[TEXTPEN]); - if(buf_len>left_pos) { -#ifdef USE_FONTSETS - int w, c; - for(l=0; lstrgadw-6) - break; - mx=w; - l+=c; - } - XmbDrawImageString(dpy, strwin, dri.dri_FontSet, gc, 6, 3+dri.dri_Ascent, - cmdline+left_pos, l); -#else - mx+=XTextWidth(dri.dri_Font, cmdline+left_pos, l=buf_len-left_pos); - while(mx>strgadw-6) - mx-=XTextWidth(dri.dri_Font, cmdline+left_pos+--l, 1); - XDrawImageString(dpy, strwin, gc, 6, 3+dri.dri_Ascent, - cmdline+left_pos, l); -#endif - } - XSetForeground(dpy, gc, dri.dri_Pens[BACKGROUNDPEN]); - XFillRectangle(dpy, strwin, gc, mx, 3, strgadw-mx-6, fh); - if(stractive) { - if(cur_pos - max_logical_extent.width, fh); -#else - XFillRectangle(dpy, strwin, gc, cur_x, 3, - dri.dri_Font->max_bounds.width, fh); -#endif - } - } -} - -void refresh_str(void) -{ - refresh_str_text(); - XSetForeground(dpy, gc, dri.dri_Pens[SHINEPEN]); - XDrawLine(dpy, strwin, gc, 0, strgadh-1, 0, 0); - XDrawLine(dpy, strwin, gc, 0, 0, strgadw-2, 0); - XDrawLine(dpy, strwin, gc, 3, strgadh-2, strgadw-4, strgadh-2); - XDrawLine(dpy, strwin, gc, strgadw-4, strgadh-2, strgadw-4, 2); - XDrawLine(dpy, strwin, gc, 1, 1, 1, strgadh-2); - XDrawLine(dpy, strwin, gc, strgadw-3, 1, strgadw-3, strgadh-2); - XSetForeground(dpy, gc, dri.dri_Pens[SHADOWPEN]); - XDrawLine(dpy, strwin, gc, 1, strgadh-1, strgadw-1, strgadh-1); - XDrawLine(dpy, strwin, gc, strgadw-1, strgadh-1, strgadw-1, 0); - XDrawLine(dpy, strwin, gc, 3, strgadh-3, 3, 1); - XDrawLine(dpy, strwin, gc, 3, 1, strgadw-4, 1); - XDrawLine(dpy, strwin, gc, 2, 1, 2, strgadh-2); - XDrawLine(dpy, strwin, gc, strgadw-2, 1, strgadw-2, strgadh-2); -} - -void strkey(XKeyEvent *e) -{ - void endchoice(void); -#ifdef USE_FONTSETS - Status stat; -#else - static XComposeStatus stat; -#endif - KeySym ks; - char buf[256]; - int x, i, n; -#ifndef USE_FONTSETS - n=XLookupString(e, buf, sizeof(buf), &ks, &stat); -#else - n=XmbLookupString(xic, e, buf, sizeof(buf), &ks, &stat); - if(stat == XLookupKeySym || stat == XLookupBoth) -#endif - switch(ks) { - case XK_Return: - case XK_Linefeed: - selected=1; - endchoice(); - break; - case XK_Left: - if(cur_pos) { -#ifdef USE_FONTSETS - int p=cur_pos; -// int z; - while(p>0) { - --p; - if(((int)mbrlen(cmdline+p, cur_pos-p, NULL))>0) { - cur_pos=p; - break; + int i; + for (i=1; i<3; i++) { + if (buttons[i]->w == w) + return i; } - } + return 0; +} + +static void +refresh_main(void) +{ + int w; + + XSetForeground(dpy, gc, dri.dri_Pens[TEXTPEN]); +#ifdef USE_FONTSETS + XmbDrawString(dpy, mainwin, dri.dri_FontSet, gc, TEXT_SIDE, + TOP_SPACE+dri.dri_Ascent, enter_txt, strlen(enter_txt)); #else - --cur_pos; + XDrawString(dpy, mainwin, gc, TEXT_SIDE, TOP_SPACE+dri.dri_Ascent, + enter_txt, strlen(enter_txt)); #endif - } - break; - case XK_Right: - if(cur_pos0) - cur_pos+=l; + w = XmbTextEscapement(dri.dri_FontSet, cmd_txt, strlen(cmd_txt)); + XmbDrawString(dpy, mainwin, dri.dri_FontSet, gc, + mainw-strgadw-w-TEXT_SIDE-BUT_SIDE, + TOP_SPACE+fh+INT_SPACE+dri.dri_Ascent, + cmd_txt, strlen(cmd_txt)); #else - cur_pos++; + w = XTextWidth(dri.dri_Font, cmd_txt, strlen(cmd_txt)); + XDrawString(dpy, mainwin, gc, mainw-strgadw-w-TEXT_SIDE-BUT_SIDE, + TOP_SPACE+fh+INT_SPACE+dri.dri_Ascent, + cmd_txt, strlen(cmd_txt)); #endif - } - break; - case XK_Begin: - cur_pos=0; - break; - case XK_End: - cur_pos=buf_len; - break; - case XK_Delete: - if(cur_pos0) { - int l=1; -#ifdef USE_FONTSETS - int p=cur_pos; - while(p>0) { - --p; - if(((int)mbrlen(cmdline+p, cur_pos-p, NULL))>0) { - l=cur_pos-p; - break; +} + +static void +toggle(int c) +{ + if (c == 0) + return; + gadget_button_toggle(buttons[c]); +} + +static void +abortchoice(void) +{ + if(depressed) { + depressed=0; + if (selected > 0) { + gadget_button_set_depressed(buttons[selected], 0); + } + toggle(selected); } - } -#endif - buf_len-=l; - for(x=(cur_pos-=l); xcur_pos; --x) - cmdline[x]=cmdline[x-1]; - cmdline[cur_pos++]=buf[i]; - buf_len++; - } - if(ileft_pos) - cur_x+=XmbTextEscapement(dri.dri_FontSet, cmdline+left_pos, cur_pos-left_pos); - if(cur_posmax_logical_extent.width; -#else - if(cur_pos>left_pos) - cur_x+=XTextWidth(dri.dri_Font, cmdline+left_pos, cur_pos-left_pos); - if(cur_posmax_bounds.width; -#endif - if((x+=cur_x-(strgadw-6))>0) { - cur_x-=x; - while(x>0) { -#ifdef USE_FONTSETS - int l=mbrlen(cmdline+left_pos, buf_len-left_pos, NULL); - x-=XmbTextEscapement(dri.dri_FontSet, cmdline+left_pos, l); - left_pos += l; -#else - x-=XTextWidth(dri.dri_Font, cmdline+left_pos++, 1); -#endif - } - cur_x+=x; - } - refresh_str_text(); + selected = 0; } -void strbutton(XButtonEvent *e) +static void +endchoice(void) { - int w, l=1; - stractive=1; - cur_pos=left_pos; - cur_x=6; - while(cur_xx && cur_posbuf); + } + exit(0); +} + +int +main(int argc, char *argv[]) +{ + XWindowAttributes attr; + static XSizeHints size_hints; + static XTextProperty txtprop1, txtprop2; + int w2, c; #ifdef USE_FONTSETS - l=mbrlen(cmdline+cur_pos, buf_len-cur_pos, NULL); - if(l<=0) - break; - w=XmbTextEscapement(dri.dri_FontSet, cmdline+cur_pos, l); -#else - w=XTextWidth(dri.dri_Font, cmdline+cur_pos, 1); + char *p; + + setlocale(LC_CTYPE, ""); #endif - if(cur_x+w>e->x) - break; - cur_x+=w; - cur_pos+=l; - } - refresh_str(); -} + progname=argv[0]; + if(!(dpy = XOpenDisplay(NULL))) { + fprintf(stderr, "%s: cannot connect to X server %s\n", + progname, XDisplayName(NULL)); + exit(1); + } -void toggle(int c) -{ - XSetWindowBackground(dpy, button[c], dri.dri_Pens[(depressed&&c==selected)? - FILLPEN:BACKGROUNDPEN]); - XClearWindow(dpy, button[c]); - refresh_button(button[c], buttxt[c], c); -} - -void abortchoice() -{ - if(depressed) { - depressed=0; - toggle(selected); - } - selected=0; -} - -void endchoice() -{ - int c=selected; - - abortchoice(); - XCloseDisplay(dpy); - if(c==1) - system(cmdline); - exit(0); -} - -int main(int argc, char *argv[]) -{ - XWindowAttributes attr; - static XSizeHints size_hints; - static XTextProperty txtprop1, txtprop2; - Window ok, cancel; - int w2, c; -#ifdef USE_FONTSETS - char *p; - - setlocale(LC_CTYPE, ""); -#endif - progname=argv[0]; - if(!(dpy = XOpenDisplay(NULL))) { - fprintf(stderr, "%s: cannot connect to X server %s\n", progname, - XDisplayName(NULL)); - exit(1); - } - root = RootWindow(dpy, DefaultScreen(dpy)); - XGetWindowAttributes(dpy, root, &attr); - init_dri(&dri, dpy, root, attr.colormap, False); + root = RootWindow(dpy, DefaultScreen(dpy)); + XGetWindowAttributes(dpy, root, &attr); + init_dri(&dri, dpy, root, attr.colormap, False); #ifdef USE_FONTSETS strgadw=VISIBLE_CMD_CHARS*XExtentsOfFontSet(dri.dri_FontSet)-> @@ -458,39 +200,6 @@ int main(int argc, char *argv[]) mainw=w2; mainh=3*fh+TOP_SPACE+BOT_SPACE+2*INT_SPACE+2*BUT_VSPACE; - - mainwin=XCreateSimpleWindow(dpy, root, 20, 20, mainw, mainh, 1, - dri.dri_Pens[SHADOWPEN], - dri.dri_Pens[BACKGROUNDPEN]); - strwin=XCreateSimpleWindow(dpy, mainwin, mainw-BUT_SIDE-strgadw, - TOP_SPACE+fh+INT_SPACE-3, - strgadw, strgadh, 0, - dri.dri_Pens[SHADOWPEN], - dri.dri_Pens[BACKGROUNDPEN]); - ok=XCreateSimpleWindow(dpy, mainwin, BUT_SIDE, - mainh-BOT_SPACE-2*BUT_VSPACE-fh, - butw, fh+2*BUT_VSPACE, 0, - dri.dri_Pens[SHADOWPEN], - dri.dri_Pens[BACKGROUNDPEN]); - cancel=XCreateSimpleWindow(dpy, mainwin, mainw-butw-BUT_SIDE, - mainh-BOT_SPACE-2*BUT_VSPACE-fh, - butw, fh+2*BUT_VSPACE, 0, - dri.dri_Pens[SHADOWPEN], - dri.dri_Pens[BACKGROUNDPEN]); - button[0]=None; - button[1]=ok; - button[2]=cancel; - XSelectInput(dpy, mainwin, ExposureMask|KeyPressMask|ButtonPressMask); - XSelectInput(dpy, strwin, ExposureMask|ButtonPressMask); - XSelectInput(dpy, ok, ExposureMask|ButtonPressMask|ButtonReleaseMask| - EnterWindowMask|LeaveWindowMask); - XSelectInput(dpy, cancel, ExposureMask|ButtonPressMask|ButtonReleaseMask| - EnterWindowMask|LeaveWindowMask); - gc=XCreateGC(dpy, mainwin, 0, NULL); - XSetBackground(dpy, gc, dri.dri_Pens[BACKGROUNDPEN]); -#ifndef USE_FONTSETS - XSetFont(dpy, gc, dri.dri_Font->fid); -#endif #ifdef USE_FONTSETS if ((p = XSetLocaleModifiers("@im=none")) != NULL && *p) @@ -510,6 +219,40 @@ int main(int argc, char *argv[]) exit(1); #endif + /* Main window */ + mainwin=XCreateSimpleWindow(dpy, root, 20, 20, mainw, mainh, 1, + dri.dri_Pens[SHADOWPEN], + dri.dri_Pens[BACKGROUNDPEN]); + gc=XCreateGC(dpy, mainwin, 0, NULL); + XSetBackground(dpy, gc, dri.dri_Pens[BACKGROUNDPEN]); +#ifndef USE_FONTSETS + XSetFont(dpy, gc, dri.dri_Font->fid); +#endif + + /* Text input window */ + text_input = gadget_textinput_create(dpy, &dri, gc, mainwin, + mainw-BUT_SIDE-strgadw, + TOP_SPACE+fh+INT_SPACE-3, + strgadw, strgadh, 256); +#ifdef USE_FONTSETS + gadget_textinput_set_xic(text_input, xic); +#endif + + + /* Create OK button */ + buttons[1] = gadget_button_init(dpy, &dri, gc, mainwin, + BUT_SIDE, mainh-BOT_SPACE-2*BUT_VSPACE-fh, /* x, y */ + butw, fh+2*BUT_VSPACE); /* width, height */ + gadget_button_set_text(buttons[1], ok_txt); + + /* Create cancel button */ + buttons[2] = gadget_button_init(dpy, &dri, gc, mainwin, + mainw-butw-BUT_SIDE, mainh-BOT_SPACE-2*BUT_VSPACE-fh, /* x, y */ + butw, fh+2*BUT_VSPACE); /* width, height */ + gadget_button_set_text(buttons[2], cancel_txt); + + XSelectInput(dpy, mainwin, ExposureMask|KeyPressMask|ButtonPressMask); + size_hints.flags = PResizeInc; txtprop1.value=(unsigned char *)"Execute a File"; txtprop2.value=(unsigned char *)"ExecuteCmd"; @@ -532,37 +275,51 @@ int main(int argc, char *argv[]) if(!event.xexpose.count) { if(event.xexpose.window == mainwin) refresh_main(); - else if(event.xexpose.window == strwin) - refresh_str(); - else if(event.xexpose.window == ok) - refresh_button(ok, ok_txt, 1); - else if(event.xexpose.window == cancel) - refresh_button(cancel, cancel_txt, 2); + else if(event.xexpose.window == text_input->w) + gadget_textinput_repaint(text_input); + else if(event.xexpose.window == buttons[1]->w) { + gadget_button_refresh(buttons[1]); + } else if(event.xexpose.window == buttons[2]->w) { + gadget_button_refresh(buttons[2]); + } } case LeaveNotify: - if(depressed && event.xcrossing.window==button[selected]) { - depressed=0; - toggle(selected); + if (depressed) { + if ((selected > 0) && event.xcrossing.window == buttons[selected]->w) { + depressed = 0; + gadget_button_set_depressed(buttons[selected], 0); + toggle(selected); + } } + break; case EnterNotify: - if((!depressed) && selected && event.xcrossing.window==button[selected]) { - depressed=1; - toggle(selected); + if((!depressed) && selected && event.xcrossing.window == buttons[selected]->w) { + depressed = 1; + gadget_button_set_depressed(buttons[selected], 1); + toggle(selected); } break; case ButtonPress: if(event.xbutton.button==Button1) { - if(stractive && event.xbutton.window!=strwin) { + if(stractive && event.xbutton.window!= text_input->w) { stractive=0; - refresh_str(); + gadget_textinput_selected(text_input, 0); + gadget_textinput_repaint(text_input); } if((c=getchoice(event.xbutton.window))) { abortchoice(); - depressed=1; - toggle(selected=c); - } else if(event.xbutton.window==strwin) - strbutton(&event.xbutton); + depressed = 1; + selected = c; + if (selected > 0) { + gadget_button_set_depressed(buttons[selected], 1); + } + toggle(selected); + } else if(event.xbutton.window== text_input->w) { + gadget_textinput_selected(text_input, 1); + gadget_textinput_buttonevent(text_input, &event.xbutton); + gadget_textinput_repaint(text_input); + } } break; case ButtonRelease: @@ -574,8 +331,15 @@ int main(int argc, char *argv[]) } break; case KeyPress: - if(stractive) - strkey(&event.xkey); + if(stractive) { + gadget_textinput_keyevent(text_input, &event.xkey); + gadget_textinput_repaint(text_input); + if (gadget_textinput_crlf(text_input)) { + selected = 1; + endchoice(); + exit(1); + } + } } } } diff --git a/libami/Makefile.in b/libami/Makefile.in index ddc82c4..c53816f 100644 --- a/libami/Makefile.in +++ b/libami/Makefile.in @@ -21,12 +21,12 @@ RM = -rm -f OBJS = drawinfo.o module.o broker.o eventdispatcher.o mdscreen.o \ mdicon.o mdwindow.o kbdsupport.o hotkey.o \ lists.o readargs.o iconlib.o iconutil.o error.o strutil.o \ - iffparse.o + iffparse.o gadget_button.o gadget_textbox.o gadget_textinput.o SRCS = drawinfo.c module.c broker.c eventdispatcher.c mdscreen.c \ mdicon.c mdwindow.c kbdsupport.c hotkey.c \ lists.c readargs.c iconlib.c iconutil.c error.c strutil.c \ - iffparse.c + iffparse.c gadget_button.c gadget_textbox.c gadget_textinput.c all : libami.a diff --git a/libami/gadget_button.c b/libami/gadget_button.c new file mode 100644 index 0000000..c336d60 --- /dev/null +++ b/libami/gadget_button.c @@ -0,0 +1,136 @@ +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_FCNTL_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_SYS_STAT_H +#include +#endif +#include +#ifdef USE_FONTSETS +#include +#include +#endif + +#include "drawinfo.h" + +#include "gadget_button.h" + +#ifdef AMIGAOS +#include +extern struct Library *XLibBase; +#endif + +/* + * This is the button code from the executecmd.c tool. + */ + +struct gadget_button * +gadget_button_init(Display *dpy, struct DrawInfo *dri, GC gc, Window mainwin, + int x, int y, int butw, int buth) +{ + struct gadget_button *b; + + b = calloc(1, sizeof(*b)); + if (b == NULL) { + return (NULL); + } + b->dpy = dpy; + b->dri = dri; + b->x = x; + b->y = y; + b->butw = butw; + b->buth = buth; + b->txt = strdup(""); + b->gc = gc; + + b->w = XCreateSimpleWindow(dpy, mainwin, + x, y, + butw, /* width */ + buth, /* height */ + 0, /* depth */ + dri->dri_Pens[SHADOWPEN], + dri->dri_Pens[BACKGROUNDPEN]); + + XSelectInput(dpy, b->w, ExposureMask | ButtonPressMask + | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask); + + return (b); +} + +void +gadget_button_set_text(struct gadget_button *b, const char *txt) +{ + if (b->txt != NULL) + free(b->txt); + b->txt = strdup(txt); +} + +void +gadget_button_refresh(struct gadget_button *b) +{ + int fh = b->dri->dri_Ascent + b->dri->dri_Descent; + int h = fh + (2 * BUT_VSPACE); + int l=strlen(b->txt); +#ifdef USE_FONTSETS + int tw = XmbTextEscapement(b->dri->dri_FontSet, b->txt, l); +#else + int tw = XTextWidth(b->dri->dri_Font, b->txt, l); +#endif + XSetForeground(b->dpy, b->gc, b->dri->dri_Pens[TEXTPEN]); +#ifdef USE_FONTSETS + XmbDrawString(b->dpy, b->w, b->dri->dri_FontSet, b->gc, + (b->butw-tw)>>1, b->dri->dri_Ascent+BUT_VSPACE, b->txt, l); +#else + XDrawString(b->dpy, b->w, b->gc, (b->butw-tw)>>1, + b->dri->dri_Ascent+BUT_VSPACE, b->txt, l); +#endif + XSetForeground(b->dpy, b->gc, + b->dri->dri_Pens[b->depressed ? SHADOWPEN:SHINEPEN]); + + XDrawLine(b->dpy, b->w, b->gc, 0, 0, b->butw-2, 0); + XDrawLine(b->dpy, b->w, b->gc, 0, 0, 0, h-2); + XSetForeground(b->dpy, b->gc, + b->dri->dri_Pens[b->depressed ? SHINEPEN:SHADOWPEN]); + + XDrawLine(b->dpy, b->w, b->gc, 1, h-1, b->butw-1, h-1); + XDrawLine(b->dpy, b->w, b->gc, b->butw-1, 1, b->butw-1, h-1); + XSetForeground(b->dpy, b->gc, b->dri->dri_Pens[BACKGROUNDPEN]); + XDrawPoint(b->dpy, b->w, b->gc, b->butw-1, 0); + XDrawPoint(b->dpy, b->w, b->gc, 0, h-1); +} + +void +gadget_button_set_depressed(struct gadget_button *b, int depressed) +{ + b->depressed = depressed; +} + +void +gadget_button_toggle(struct gadget_button *b) +{ + int pen; + + pen = (b->depressed) ? FILLPEN : BACKGROUNDPEN; + + + XSetWindowBackground(b->dpy, b->w, b->dri->dri_Pens[pen]); + XClearWindow(b->dpy, b->w); + gadget_button_refresh(b); +} + +void +gadget_button_free(struct gadget_button *b) +{ + XDestroyWindow(b->dpy, b->w); + free(b->txt); + free(b); +} diff --git a/libami/gadget_button.h b/libami/gadget_button.h new file mode 100644 index 0000000..d33c9d8 --- /dev/null +++ b/libami/gadget_button.h @@ -0,0 +1,35 @@ +#ifndef __LIBAMI__GADGET_BUTTON_H__ +#define __LIBAMI__GADGET_BUTTON_H__ + +#define BOT_SPACE 4 +#define TEXT_SIDE 8 +#define BUT_SIDE 12 +#define TOP_SPACE 4 +#define INT_SPACE 7 +#define BUT_VSPACE 2 +#define BUT_HSPACE 8 + +struct gadget_button { + Display *dpy; + struct DrawInfo *dri; + Window w; + GC gc; + int x; + int y; + int buth; + int butw; + char *txt; + int depressed; +}; + +extern struct gadget_button * gadget_button_init(Display *dpy, + struct DrawInfo *dri, GC gc, Window mainwin, + int x, int y, int butw, int buth); +extern void gadget_button_set_text(struct gadget_button *b, const char *txt); +extern void gadget_button_refresh(struct gadget_button *b); +extern void gadget_button_set_depressed(struct gadget_button *b, + int depressed); +extern void gadget_button_toggle(struct gadget_button *b); +extern void gadget_button_free(struct gadget_button *b); + +#endif /* __LIBAMI__GADGET_BUTTON_H__ */ diff --git a/libami/gadget_textbox.c b/libami/gadget_textbox.c new file mode 100644 index 0000000..087e706 --- /dev/null +++ b/libami/gadget_textbox.c @@ -0,0 +1,123 @@ +#include +#include +#include +#include +#include +#include + +#include "drawinfo.h" +#include "libami.h" + +#ifdef AMIGAOS +#include +extern struct Library *XLibBase; +#endif + +#include "gadget_textbox.h" + +#if 0 +struct gadget_textbox_line { + struct line *next; + const char *text; + int l, w, h; +}; +#endif + +#if 0 +struct gadget_textbox { + struct gadget_textbox_line *firstline, *lastline; +}; +#endif + + +struct gadget_textbox * +gadget_textbox_create(Display *dpy, struct DrawInfo *dri, GC gc, + Window mainwin, int x, int y, int width, int height) +{ + struct gadget_textbox *g; + + g = calloc(1, sizeof(*g)); + if (g == NULL) { + return (NULL); + } + g->dpy = dpy; + g->dri = dri; + g->gc = gc; + g->x = x; + g->y = y; + g->width = width; + g->height = height; + + g->w = XCreateSimpleWindow(g->dpy, mainwin, + g->x, g->y, + g->width, g->height, + 0, + g->dri->dri_Pens[SHADOWPEN], + g->dri->dri_Pens[BACKGROUNDPEN]); + XSelectInput(g->dpy, g->w, ExposureMask); + + return (g); +} + +void +gadget_textbox_free(struct gadget_textbox *g) +{ + /* XXX TODO */ +} + +struct gadget_textbox_line * +gadget_textbox_addline(struct gadget_textbox *g, const char *text) +{ + struct gadget_textbox_line *l; + + l = calloc(1, sizeof(*l)); + if (l == NULL) { + return (NULL); + } + if(g->lastline) + g->lastline->next = l; + else + g->firstline = l; + g->lastline = l; + l->text = strdup(text); + l->l = strlen(text); +#ifdef USE_FONTSETS + l->w = XmbTextEscapement(g->dri->dri_FontSet, l->text, l->l); +#else + l->w = XTextWidth(g->dri->dri_Font, l->text, l->l); +#endif + l->h = g->dri->dri_Ascent + g->dri->dri_Descent; + + return (l); +} + +void +gadget_textbox_refresh(struct gadget_textbox *g) +{ + // This is OBVIOUSLY the wrong value for x here, but let's get it going + int x = TXT_HSPACE / 2; + int y = ((g->dri->dri_Ascent+g->dri->dri_Descent)>>1)+g->dri->dri_Ascent; + + struct gadget_textbox_line *l; + + /* Draw the bounding box */ + XSetForeground(g->dpy, g->gc, g->dri->dri_Pens[SHADOWPEN]); + XDrawLine(g->dpy, g->w, g->gc, 0, 0, g->width-2, 0); + XDrawLine(g->dpy, g->w, g->gc, 0, 0, 0, g->height-2); + + XSetForeground(g->dpy, g->gc, g->dri->dri_Pens[SHINEPEN]); + XDrawLine(g->dpy, g->w, g->gc, 0, g->height-1, g->width-1, g->height-1); + XDrawLine(g->dpy, g->w, g->gc, g->width-1, 0, g->width-1, g->height-1); + + /* Draw text lines */ + XSetForeground(g->dpy, g->gc, g->dri->dri_Pens[TEXTPEN]); + for(l = g->firstline; l; l=l->next) { +#ifdef USE_FONTSETS + XmbDrawString(g->dpy, g->w, g->dri->dri_FontSet, g->gc, + x, y, l->text, l->l); +#else + XDrawString(g->dpy, g->w, g->gc, x, y, l->text, l->l); +#endif + y+=g->dri->dri_Ascent + g->dri->dri_Descent; + } +} diff --git a/libami/gadget_textbox.h b/libami/gadget_textbox.h new file mode 100644 index 0000000..2087951 --- /dev/null +++ b/libami/gadget_textbox.h @@ -0,0 +1,35 @@ +#ifndef __LIBAMI_GADGET_TEXTBOX_H__ +#define __LIBAMI_GADGET_TEXTBOX_H__ + +// These are for the text box widget +#define TXT_HSPACE 48 +#define TXT_TOPSPACE 4 +#define TXT_MIDSPACE 3 +#define TXT_BOTSPACE 4 + +struct gadget_textbox_line { + struct gadget_textbox_line *next; + const char *text; + int l, w, h; +}; + +struct gadget_textbox { + Display *dpy; + struct DrawInfo *dri; + GC gc; + Window w; + int x, y; + int width, height; + + struct gadget_textbox_line *firstline, *lastline; +}; + +extern struct gadget_textbox *gadget_textbox_create(Display *dpy, + struct DrawInfo *dri, GC gc, Window mainwin, int x, int y, + int width, int height); +extern void gadget_textbox_free(struct gadget_textbox *g); +extern struct gadget_textbox_line * gadget_textbox_addline( + struct gadget_textbox *g, const char *text); +extern void gadget_textbox_refresh(struct gadget_textbox *g); + +#endif /* __LIBAMI_GADGET_TEXTBOX_H__ */ diff --git a/libami/gadget_textinput.c b/libami/gadget_textinput.c new file mode 100644 index 0000000..2ac6c66 --- /dev/null +++ b/libami/gadget_textinput.c @@ -0,0 +1,349 @@ +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_FCNTL_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_SYS_STAT_H +#include +#endif +#include +#ifdef USE_FONTSETS +#include +#include +#endif + +#include "drawinfo.h" + +#include "gadget_textinput.h" + +#ifdef AMIGAOS +#include +extern struct Library *XLibBase; +#endif + +struct gadget_textinput * +gadget_textinput_create(Display *dpy, struct DrawInfo *dri, + GC gc, Window mainwin, int x, int y, int width, int height, + int textsize) +{ + struct gadget_textinput *b; + + b = calloc(1, sizeof(*b)); + if (b == NULL) + return (NULL); + b->dpy = dpy; + b->dri = dri; + b->gc = gc; + b->x = x; + b->y = y; + b->width = width; + b->height = height; + b->buf = calloc(textsize + 1, sizeof(char)); + if (b->buf == NULL) { + free(b); + return (NULL); + } + b->cur_x = 6; + b->size = textsize; + b->w = XCreateSimpleWindow(dpy, mainwin, x, y, + width, height, 0, + b->dri->dri_Pens[SHADOWPEN], + b->dri->dri_Pens[BACKGROUNDPEN]); + + XSelectInput(dpy, b->w, ExposureMask|ButtonPressMask); + + return (b); +} + +#ifdef USE_FONTSETS +void +gadget_textinput_set_xic(struct gadget_textinput *g, XIC xic) +{ + g->xic = xic; +} +#endif + +static void +gadget_textinput_repaint_str(struct gadget_textinput *b) +{ + int l, mx=6; + + XSetForeground(b->dpy, b->gc, b->dri->dri_Pens[TEXTPEN]); + if(b->len > b->left_pos) { +#ifdef USE_FONTSETS + int w, c; + + for (l=0; llen - b->left_pos; ) { + c=mbrlen(b->buf+b->left_pos+l, b->len-b->left_pos-l, NULL); + w=6+XmbTextEscapement(b->dri->dri_FontSet, b->buf+b->left_pos, l+c); + if(w>b->width-6) + break; + mx=w; + l+=c; + } + + XmbDrawImageString(b->dpy, b->w, b->dri->dri_FontSet, b->gc, + 6, 3+b->dri->dri_Ascent, + b->buf+b->left_pos, l); +#else + mx+=XTextWidth(b->dri->dri_Font, b->buf+b->left_pos, l=b->len-b->left_pos); + while(mx>b->width-6) + mx-=XTextWidth(b->dri->dri_Font, b->buf+b->left_pos + --l, 1); + XDrawImageString(b->dpy, b->w, b->gc, 6, 3+b->dri->dri_Ascent, + b->buf+b->left_pos, l); +#endif + } + XSetForeground(b->dpy, b->gc, b->dri->dri_Pens[BACKGROUNDPEN]); + XFillRectangle(b->dpy, b->w, b->gc, mx, 3, b->width-mx-6, b->width - 6); + if(b->selected) { + if(b->cur_poslen) { + XSetBackground(b->dpy, b->gc, ~0); +#ifdef USE_FONTSETS + l=mbrlen(b->buf+b->cur_pos, b->len-b->cur_pos, NULL); + XmbDrawImageString(b->dpy, b->w, b->dri->dri_FontSet, b->gc, b->cur_x, + 3+b->dri->dri_Ascent, b->buf+b->cur_pos, l); +#else + XDrawImageString(b->dpy, b->w, b->gc, cur_x, 3+b->dri->dri_Ascent, + b->buf+b->cur_pos, 1); +#endif + XSetBackground(b->dpy, b->gc, b->dri->dri_Pens[BACKGROUNDPEN]); + } else { + XSetForeground(b->dpy, b->gc, ~0); +#ifdef USE_FONTSETS + XFillRectangle(b->dpy, b->w, b->gc, b->cur_x, 3, + XExtentsOfFontSet(b->dri->dri_FontSet)-> + max_logical_extent.width, b->height - 6); +#else + XFillRectangle(b->dpy, b->w, b->gc, cur_x, 3, + b->dri->dri_Font->max_bounds.width, b->height - 6); +#endif + } + } +} + +void +gadget_textinput_repaint(struct gadget_textinput *b) +{ + + gadget_textinput_repaint_str(b); + + XSetForeground(b->dpy, b->gc, b->dri->dri_Pens[SHINEPEN]); + XDrawLine(b->dpy, b->w, b->gc, 0, b->height-1, 0, 0); + XDrawLine(b->dpy, b->w, b->gc, 0, 0, b->width-2, 0); + XDrawLine(b->dpy, b->w, b->gc, 3, b->height-2, b->width-4, + b->height-2); + XDrawLine(b->dpy, b->w, b->gc, b->width-4, b->height-2, b->width-4, 2); + XDrawLine(b->dpy, b->w, b->gc, 1, 1, 1, b->height-2); + XDrawLine(b->dpy, b->w, b->gc, b->width-3, 1, b->width-3, b->height-2); + XSetForeground(b->dpy, b->gc, b->dri->dri_Pens[SHADOWPEN]); + XDrawLine(b->dpy, b->w, b->gc, 1, b->height-1, b->width-1, + b->height-1); + XDrawLine(b->dpy, b->w, b->gc, b->width-1, b->height-1, b->width-1, 0); + XDrawLine(b->dpy, b->w, b->gc, 3, b->height-3, 3, 1); + XDrawLine(b->dpy, b->w, b->gc, 3, 1, b->width-4, 1); + XDrawLine(b->dpy, b->w, b->gc, 2, 1, 2, b->height-2); + XDrawLine(b->dpy, b->w, b->gc, b->width-2, 1, b->width-2, b->height-2); +} + +void +gadget_textinput_free(struct gadget_textinput *b) +{ + if (b->buf) + free(b->buf); + XDestroyWindow(b->dpy, b->w); + free(b); +} + +void +gadget_textinput_keyevent(struct gadget_textinput *b, XKeyEvent *e) +{ +#ifdef USE_FONTSETS + Status stat; +#else + static XComposeStatus stat; +#endif + KeySym ks; + char buf[256]; + int x, i, n; +#ifndef USE_FONTSETS + n=XLookupString(e, buf, sizeof(buf), &ks, &stat); +#else + n=XmbLookupString(b->xic, e, buf, sizeof(buf), &ks, &stat); + if(stat == XLookupKeySym || stat == XLookupBoth) +#endif + switch(ks) { + case XK_Return: + case XK_Linefeed: + b->crlf = 1; + break; + case XK_Left: + if(b->cur_pos) { +#ifdef USE_FONTSETS + int p=b->cur_pos; +// int z; + while(p>0) { + --p; + if(((int)mbrlen(b->buf+p, b->cur_pos-p, NULL))>0) { + b->cur_pos=p; + break; + } + } +#else + --cur_pos; +#endif + } + break; + case XK_Right: + if(b->cur_poslen) { +#ifdef USE_FONTSETS + int l=mbrlen(b->buf+b->cur_pos, b->len-b->cur_pos, NULL); + if(l>0) + b->cur_pos+=l; +#else + b->cur_pos++; +#endif + } + break; + case XK_Begin: + b->cur_pos=0; + break; + case XK_End: + b->cur_pos=b->len; + break; + case XK_Delete: + if(b->cur_poslen) { + int l=1; +#ifdef USE_FONTSETS + l=mbrlen(b->buf+b->cur_pos, b->len-b->cur_pos, NULL); + if(l<=0) + break; +#endif + b->len-=l; + for(x=b->cur_pos; xlen; x++) + b->buf[x]=b->buf[x+l]; + b->buf[x] = 0; + } else XBell(b->dpy, 100); + break; + case XK_BackSpace: + if(b->cur_pos>0) { + int l=1; +#ifdef USE_FONTSETS + int p=b->cur_pos; + while(p>0) { + --p; + if(((int)mbrlen(b->buf+p, b->len-p, NULL))>0) { + l= b->cur_pos - p; + break; + } + } +#endif + b->len -= l; + for(x=(b->cur_pos-=l); xlen; x++) + b->buf[x]=b->buf[x+l]; + b->buf[x] = 0; + } else XBell(b->dpy, 100); + break; +#ifdef USE_FONTSETS + default: + if(stat == XLookupBoth) + stat = XLookupChars; + } + if(stat == XLookupChars) { +#else + default: +#endif + for(i=0; ilensize-1; i++) { + for(x=b->len; x>b->cur_pos; --x) + b->buf[x]=b->buf[x-1]; + b->buf[b->cur_pos++]=buf[i]; + b->len++; + } + if(idpy, 100); + } + if(b->cur_posleft_pos) + b->left_pos=b->cur_pos; + b->cur_x=6; +#ifdef USE_FONTSETS + if(b->cur_pos>b->left_pos) + b->cur_x+=XmbTextEscapement(b->dri->dri_FontSet, b->buf+b->left_pos, + b->cur_pos-b->left_pos); + if(b->cur_pos < b->len) { + int l=mbrlen(b->buf+b->cur_pos, b->len-b->cur_pos, NULL); + x=XmbTextEscapement(b->dri->dri_FontSet, b->buf+b->cur_pos, l); + } else + x=XExtentsOfFontSet(b->dri->dri_FontSet)->max_logical_extent.width; +#else + if(b->cur_pos > b->left_pos) + b->cur_x+=XTextWidth(b->dri->dri_Font, b->buf+b->left_pos, b->cur_pos-b->left_pos); + if(b->cur_posbuf_len) + x=XTextWidth(b->dri->dri_Font, b->buf+b->cur_pos, 1); + else + x=b->dri->dri_Font->max_bounds.width; +#endif + if((x+=b->cur_x-(b->width-6))>0) { + b->cur_x-=x; + while(x>0) { +#ifdef USE_FONTSETS + int l=mbrlen(b->buf+b->left_pos, b->len-b->left_pos, NULL); + x-=XmbTextEscapement(b->dri->dri_FontSet, b->buf+b->left_pos, l); + b->left_pos += l; +#else + x-=XTextWidth(b->dri->dri_Font, b->buf+b->left_pos++, 1); +#endif + } + b->cur_x+=x; + } +} + + +void +gadget_textinput_buttonevent(struct gadget_textinput *b, XButtonEvent *e) +{ + int w, l=1; + b->cur_pos=b->left_pos; + b->cur_x=6; + while(b->cur_xx && b->cur_poslen) { +#ifdef USE_FONTSETS + l=mbrlen(b->buf+b->cur_pos, b->len-b->cur_pos, NULL); + if(l<=0) + break; + w=XmbTextEscapement(b->dri->dri_FontSet, b->buf+b->cur_pos, l); +#else + w=XTextWidth(b->dri->dri_Font, b->buf+b->cur_pos, 1); +#endif + if(b->cur_x+w>e->x) + break; + b->cur_x+=w; + b->cur_pos+=l; + } +} + +#if 0 + +void strbutton(XButtonEvent *e) +{ + refresh_str(); +} + +#endif + +void +gadget_textinput_selected(struct gadget_textinput *b, int selected) +{ + b->selected = selected; +} + +int +gadget_textinput_crlf(struct gadget_textinput *b) +{ + return (b->crlf); +} diff --git a/libami/gadget_textinput.h b/libami/gadget_textinput.h new file mode 100644 index 0000000..283e874 --- /dev/null +++ b/libami/gadget_textinput.h @@ -0,0 +1,46 @@ +#ifndef __LIBAMI__GADGET_TEXTINPUT_H__ +#define __LIBAMI__GADGET_TEXTINPUT_H__ + +struct gadget_textinput { + Display *dpy; + struct DrawInfo *dri; + Window w; + GC gc; +#ifdef USE_FONTSETS + XIC xic; +#endif + int x; + int y; + int width; + int height; + + /* XXX TODO: create a string representation here already */ + char *buf; + int len; + int size; + + /* Position of textbox cursor and rendering start */ + int cur_pos; + int left_pos; + int cur_x; + + int selected; + int crlf; +}; + +extern struct gadget_textinput * gadget_textinput_create(Display *dpy, + struct DrawInfo *dri, GC gc, Window mainwin, + int x, int y, int width, int height, int text_size); +#ifdef USE_FONTSETS +extern void gadget_textinput_set_xic(struct gadget_textinput *g, XIC xic); +#endif +extern void gadget_textinput_repaint(struct gadget_textinput *b); +extern void gadget_textinput_free(struct gadget_textinput *b); +extern void gadget_textinput_keyevent(struct gadget_textinput *b, + XKeyEvent *e); +extern void gadget_textinput_buttonevent(struct gadget_textinput *b, + XButtonEvent *e); +extern void gadget_textinput_selected(struct gadget_textinput *b, int selected); +extern int gadget_textinput_crlf(struct gadget_textinput *b); + +#endif /* __LIBAMI__GADGET_TEXTINPUT_H__ */ diff --git a/requestchoice.c b/requestchoice.c index 6990f48..83242f9 100644 --- a/requestchoice.c +++ b/requestchoice.c @@ -13,30 +13,33 @@ extern struct Library *XLibBase; #endif +// These are used for button spacing, not the button itself #define BUT_BUTSPACE (2*(2+5)) #define BUT_INTSPACE 12 #define BUT_EXTSPACE 4 -#define BUT_VSPACE 6 -#define TXT_HSPACE 48 -#define TXT_TOPSPACE 4 -#define TXT_MIDSPACE 3 -#define TXT_BOTSPACE 4 + +#include "gadget_button.h" +#include "gadget_textbox.h" struct choice { - struct choice *next; - const char *text; - int l, w; - Window win; + struct choice *next; + const char *text; + int l, w; + struct gadget_button *b; } *firstchoice=NULL, *lastchoice=NULL; struct line { - struct line *next; - const char *text; - int l, w, h; + struct line *next; + const char *text; + int l, w, h; } *firstline=NULL, *lastline=NULL; Display *dpy; -Window root, mainwin, textwin; +Window root, mainwin; + +//Window textwin; +struct gadget_textbox *g_textbox; + char *progname; GC gc; Pixmap stipple; @@ -49,43 +52,59 @@ struct DrawInfo dri; struct RDArgs *ra=NULL; -void selection(int n) +static void +selection(int n) { - printf("%d\n", n); - XDestroyWindow(dpy, mainwin); - XCloseDisplay(dpy); - FreeArgs(ra); - exit(0); + printf("%d\n", n); + XDestroyWindow(dpy, mainwin); + XCloseDisplay(dpy); + FreeArgs(ra); + exit(0); } -void *myalloc(size_t s) +static void +*myalloc(size_t s) { - void *p=calloc(s,1); - if(p) - return p; - fprintf(stderr, "%s: out of memory!\n", progname); - FreeArgs(ra); - exit(1); + void *p=calloc(s,1); + if(p) + return p; + fprintf(stderr, "%s: out of memory!\n", progname); + FreeArgs(ra); + 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)); - if(lastchoice) - lastchoice->next=c; - else - firstchoice=c; - lastchoice=c; - c->l=strlen(c->text=txt); + struct choice *c=myalloc(sizeof(struct choice)); + if(lastchoice) + lastchoice->next=c; + else + firstchoice=c; + lastchoice=c; + + c->l = strlen(txt); + c->text = txt; + #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 - 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 - 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)); if(lastline) @@ -94,6 +113,13 @@ void addline(const char *txt) firstline=l; lastline=l; 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 l->w=XmbTextEscapement(dri.dri_FontSet, l->text, l->l); #else @@ -104,57 +130,13 @@ void addline(const char *txt) 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) { - int w=c->w+BUT_BUTSPACE; - 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); + gadget_button_refresh(c->b); } -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; if((p=strtok(str, delim))) @@ -167,23 +149,21 @@ struct choice *getchoice(Window w) { struct choice *c; for(c=firstchoice; c; c=c->next) - if(w == c->win) + if(w == c->b->w) return c; return NULL; } void toggle(struct choice *c) { - XSetWindowBackground(dpy, c->win, dri.dri_Pens[(depressed&&c==selected)? - FILLPEN:BACKGROUNDPEN]); - XClearWindow(dpy, c->win); - refresh_choice(c); + gadget_button_toggle(c->b); } void abortchoice() { if(depressed) { depressed=0; + gadget_button_set_depressed(selected->b, 0); toggle(selected); } selected=NULL; @@ -210,6 +190,7 @@ int main(int argc, char *argv[]) static XTextProperty txtprop1, txtprop2; int x, y, extra=0, n=0; struct choice *c; + struct line *l; Argtype array[3], *atp; progname=argv[0]; @@ -258,28 +239,41 @@ int main(int argc, char *argv[]) XDrawPoint(dpy, stipple, gc, 0, 1); XDrawPoint(dpy, stipple, gc, 1, 0); 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- - BUT_EXTSPACE-BUT_EXTSPACE, toth-TXT_TOPSPACE- - TXT_MIDSPACE-TXT_BOTSPACE-BUT_VSPACE- - (dri.dri_Ascent+dri.dri_Descent), + BUT_EXTSPACE-BUT_EXTSPACE, 0, dri.dri_Pens[SHADOWPEN], dri.dri_Pens[BACKGROUNDPEN]); XSelectInput(dpy, textwin, ExposureMask); +#endif + + /* Lay out + create buttons */ x=BUT_EXTSPACE; y=toth-TXT_BOTSPACE-(dri.dri_Ascent+dri.dri_Descent)-BUT_VSPACE; for(c=firstchoice; c; c=c->next) { - c->win=XCreateSimpleWindow(dpy, mainwin, - x+(nchoices==1? (extra>>1): - n++*extra/(nchoices-1)), - y, c->w+BUT_BUTSPACE, - dri.dri_Ascent+dri.dri_Descent+ - BUT_VSPACE, 0, - dri.dri_Pens[SHADOWPEN], - dri.dri_Pens[BACKGROUNDPEN]); - XSelectInput(dpy, c->win, ExposureMask|ButtonPressMask|ButtonReleaseMask| - EnterWindowMask|LeaveWindowMask); + c->b = gadget_button_init(dpy, &dri, gc, mainwin, + x + (nchoices == 1 ? (extra >> 1) : n++*extra/(nchoices-1)), + y, + c->w + BUT_BUTSPACE, + // Note: the original code didn't need a +2 here, but + // when using the ported button gadget it's needed or + // the bottom of the button isn't shown. Figure out why! + dri.dri_Ascent+dri.dri_Descent + BUT_VSPACE + 2); + gadget_button_set_text(c->b, c->text); 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; txtprop1.value=(unsigned char *)array[0].ptr; txtprop2.value=(unsigned char *)"RequestChoice"; @@ -297,20 +291,22 @@ int main(int argc, char *argv[]) switch(event.type) { case Expose: if(!event.xexpose.count) { - if(event.xexpose.window == textwin) - refresh_text(); + if(event.xexpose.window == g_textbox->w) + gadget_textbox_refresh(g_textbox); else if((c=getchoice(event.xexpose.window))) refresh_choice(c); } break; case LeaveNotify: - if(depressed && event.xcrossing.window==selected->win) { + if(depressed && event.xcrossing.window==selected->b->w) { depressed=0; + gadget_button_set_depressed(selected->b, 0); toggle(selected); } break; 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; toggle(selected); } @@ -320,6 +316,7 @@ int main(int argc, char *argv[]) (c=getchoice(event.xbutton.window))) { abortchoice(); depressed=1; + gadget_button_set_depressed(c->b, 1); toggle(selected=c); } break;