#include "paint.h" typedef struct Icon { void (*action)(Widget *canvas); uchar *upbits; uchar *downbits; Image *up; Image *down; } Icon; typedef struct Aux { int nicons; Icon *icons; Widget *canvas; } Aux; static Point dim = {32, 32}; static uchar getupbits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x30, 0x01, 0xFF, 0xFC, 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0x40, 0x07, 0xFF, 0xFA, 0x40, 0x08, 0x00, 0x06, 0x5F, 0xF0, 0x00, 0x02, 0x60, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0x7F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; static uchar putupbits[] = { 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xF8, 0x3F, 0x80, 0x00, 0x7C, 0x3F, 0x80, 0x1E, 0x7E, 0x3F, 0x80, 0x1E, 0x7E, 0x3F, 0x80, 0x1E, 0x7E, 0x3F, 0x80, 0x1E, 0x7E, 0x3F, 0x80, 0x1E, 0x7E, 0x3F, 0x80, 0x1E, 0x7E, 0x3F, 0x80, 0x1E, 0x7E, 0x3F, 0x80, 0x00, 0x7E, 0x3F, 0xFF, 0xFF, 0xFE, 0x3F, 0xFF, 0xFF, 0xFE, 0x3F, 0xFF, 0xFF, 0xFE, 0x3F, 0xFF, 0xFF, 0xFE, 0x3E, 0x00, 0x00, 0x3E, 0x3C, 0x00, 0x00, 0x1E, 0x3C, 0x00, 0x00, 0x1E, 0x3C, 0xAA, 0xAA, 0x9E, 0x3C, 0x00, 0x00, 0x1E, 0x3C, 0x00, 0x00, 0x1E, 0x3C, 0x00, 0x00, 0x1E, 0x3C, 0xAA, 0xAA, 0x9E, 0x3C, 0x00, 0x00, 0x1E, 0x3C, 0x00, 0x00, 0x1E, 0x3C, 0x00, 0x00, 0x1E, 0x24, 0xAA, 0xAA, 0x92, 0x24, 0x00, 0x00, 0x12, 0x3E, 0x00, 0x00, 0x3E, 0x3F, 0xFF, 0xFF, 0xFE, 0x3F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, }; static uchar putdownbits[] = { 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFE, 0x78, 0x3C, 0x00, 0x03, 0x7C, 0x3C, 0x00, 0xF3, 0xFE, 0x3C, 0x00, 0x93, 0xFE, 0x3C, 0x00, 0xF3, 0xFE, 0x3C, 0x00, 0xF3, 0xFE, 0x3C, 0x00, 0xF3, 0xFE, 0x3C, 0x00, 0xF3, 0xFE, 0x3C, 0x00, 0xF3, 0xFE, 0x3C, 0x00, 0x03, 0xFE, 0x3F, 0xFF, 0xFF, 0xFE, 0x3F, 0xFF, 0xFF, 0xFE, 0x3F, 0xFF, 0xFF, 0xFE, 0x3F, 0xFF, 0xFF, 0xFE, 0x3E, 0x00, 0x00, 0x3E, 0x3C, 0x00, 0x00, 0x1E, 0x3C, 0x00, 0x00, 0x1E, 0x3C, 0xAA, 0xAA, 0x9E, 0x3C, 0x00, 0x00, 0x1E, 0x3C, 0x00, 0x00, 0x1E, 0x3C, 0x00, 0x00, 0x1E, 0x3C, 0xAA, 0xAA, 0x9E, 0x3C, 0x00, 0x00, 0x1E, 0x3C, 0x00, 0x00, 0x1E, 0x3C, 0x00, 0x00, 0x1E, 0x24, 0xAA, 0xAA, 0x92, 0x24, 0x00, 0x00, 0x12, 0x3E, 0x00, 0x00, 0x3E, 0x3F, 0xFF, 0xFF, 0xFE, 0x3F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, }; enum { IGet, IPut, }; static void get(Widget *cw) { Canvas *c; int fd; c = cw->aux; if((fd = open("masterpiece.bit", OREAD)) < 0) { fprint(2, "open masterpiece.bit: %r\n"); return; } if(loadcanvas(c, fd) < 0) fprint(2, "%r\n"); close(fd); rootfanout->redraw(rootfanout, RDall); } static void put(Widget *cw) { Canvas *c; int fd; c = cw->aux; if((fd = create("masterpiece.bit", OWRITE, 0666)) < 0) { fprint(2, "create masterpiece.bit: %r\n"); return; } if(writememimage(fd, c->s->mem) < 0) fprint(2, "writememimage: %r\n"); close(fd); } static Icon icons[] = { [IGet] {get, getupbits}, [IPut] {put, putupbits, putdownbits}, }; static Image *lite; static Image *dark; static int mouse(Widget *w, Mousectl *mctl) { Aux *aux; Point m; int selection, y0, y1; Rectangle r; Icon icon; if((mctl->buttons & 7) == 0) return 0; aux = w->aux; m = subpt(mctl->xy, w->r.min); selection = m.y / dim.y; y0 = selection * dim.y + selection; y1 = y0 + dim.y; r = rectaddpt(Rect(0, y0, dim.x, y1), w->r.min); icon = aux->icons[selection]; if(icon.down == nil) icon.down = icon.up; do { if(ptinrect(mctl->xy, r)) { draw(screen, r, dark, nil, ZP); draw(screen, r, lite, icon.down, ZP); do { readmouse(mctl); } while(mctl->buttons && ptinrect(mctl->xy, r)); } else { draw(screen, r, lite, nil, ZP); draw(screen, r, dark, icon.up, ZP); do { readmouse(mctl); } while(mctl->buttons && !ptinrect(mctl->xy, r)); } } while(mctl->buttons); if(ptinrect(mctl->xy, r)) icon.action(aux->canvas); draw(screen, r, lite, nil, ZP); draw(screen, r, dark, icon.up, ZP); return 0; } static void redraw(Widget *w, RedrawMode redrawmode) { Aux *aux; int i, y0, y1; Rectangle r; if(redrawmode != RDall) return; aux = w->aux; draw(w->screen, w->r, lite, nil, ZP); for(i = 1; i < aux->nicons; i++) { y0 = i*dim.y + i-1; y1 = y0 + 1; r = rectaddpt(Rect(0, y0, dim.x, y1), w->r.min); draw(w->screen, r, dark, nil, ZP); } for(i = 0; i < aux->nicons; i++) { y0 = i*dim.y + i; y1 = y0 + dim.y; r = rectaddpt(Rect(0, y0, dim.x, y1), w->r.min); draw(w->screen, r, dark, aux->icons[i].up, ZP); } } static void wfree(Widget *w) { free(w->aux); free(w); } Widget * mkfileopswidget(Widget *canvas) { Widget *w; Aux *aux; int i; Rectangle r; if((lite = allocimage(display, Rect(0, 0, 1, 1), GREY8, 1, 0xD7D7D7FF)) == nil || (dark = allocimage(display, Rect(0, 0, 1, 1), GREY8, 1, 0x000000FF)) == nil ) sysfatal("mkfileopswidget: alloc colors: %r"); for(i = 0; i < nelem(icons); i++) { if((icons[i].up = loadbitmap((Bitmap){32, 32, GREY1, icons[i].upbits})) == nil) sysfatal("mkfileopswidget: load bitmap %d: %r", i); if(icons[i].downbits == nil) continue; if((icons[i].down = loadbitmap((Bitmap){32, 32, GREY1, icons[i].downbits})) == nil) sysfatal("mkfileopswidget: load bitmap %d: %r", i); } aux = emalloc(sizeof(*aux)); aux->nicons = nelem(icons); aux->icons = icons; aux->canvas = canvas; r = Rect(0, 0, dim.x, dim.y * aux->nicons + aux->nicons-1); if((w = mkwidget(r, mouse, widgetsyncnop, redraw, widgetdimsnop, widgetresizenop, wfree, aux)) == nil ) sysfatal("mkfileopswidget: %r"); return w; }