Overview
Comment: | Add the possibility to use SQL queries in the picture editor. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
7e6d0f4f80c22e9c96928403cf4111f7 |
User & Date: | user on 2021-05-05 02:33:08 |
Other Links: | manifest | tags |
Context
2021-05-05
| ||
20:03 | Add the possibility to edit Misc/Dir of existing objects. check-in: acca5b95d3 user: user tags: trunk | |
02:33 | Add the possibility to use SQL queries in the picture editor. check-in: 7e6d0f4f80 user: user tags: trunk | |
2021-05-02
| ||
20:13 | When adding a new object to the MRU list, ensure that it is selected as the current MRU. check-in: aaae541d8a user: user tags: trunk | |
Changes
Modified picedit.c from [1befa9e779] to [8c2ed17c26].
︙ | ︙ | |||
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | } Filter; typedef struct { char basename[64]; Filter filters[64]; Uint8 nfilters; } DependentPicture; static Uint8 cur_type; static Uint8 gsizes[16]; static void fn_valid_name(sqlite3_context*cxt,int argc,sqlite3_value**argv) { const char*s=sqlite3_value_text(*argv); if(!s || !*s || s[strspn(s,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-0123456789")]) { sqlite3_result_error(cxt,"Invalid name",-1); return; } sqlite3_result_value(cxt,*argv); } static int load_picture_file(void) { sqlite3_stmt*st=0; FILE*fp; char*nam; char*buf=0; int r=0; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | } Filter; typedef struct { char basename[64]; Filter filters[64]; Uint8 nfilters; } DependentPicture; typedef struct { sqlite3_vtab_cursor super; int pos; } Cursor; static Uint8 cur_type; static Uint8 gsizes[16]; static Picture*cur_pic; static void fn_valid_name(sqlite3_context*cxt,int argc,sqlite3_value**argv) { const char*s=sqlite3_value_text(*argv); if(!s || !*s || s[strspn(s,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-0123456789")]) { sqlite3_result_error(cxt,"Invalid name",-1); return; } sqlite3_result_value(cxt,*argv); } static int vt_graph_close(sqlite3_vtab_cursor*cur) { sqlite3_free(cur); return SQLITE_OK; } static int vt_graph_eof(sqlite3_vtab_cursor*cc) { Cursor*cur=(void*)cc; return (!cur_pic || cur->pos>=cur_pic->size*cur_pic->size); } static int vt_graph_open(sqlite3_vtab*vt,sqlite3_vtab_cursor**cur) { *cur=sqlite3_malloc(sizeof(Cursor)); return *cur?SQLITE_OK:SQLITE_NOMEM; } static int vt_graph_connect(sqlite3*db,void*aux,int argc,const char*const*argv,sqlite3_vtab**vt,char**ex) { *vt=sqlite3_malloc(sizeof(sqlite3_vtab)); if(!*vt) return SQLITE_NOMEM; sqlite3_declare_vtab(db,"CREATE TABLE `GRID`(`X` INT, `Y` INT, `C` INT);"); return SQLITE_OK; } static int vt_graph_disconnect(sqlite3_vtab*vt) { sqlite3_free(vt); return SQLITE_OK; } static int vt_graph_filter(sqlite3_vtab_cursor*cc,int n,const char*s,int c,sqlite3_value**v) { Cursor*cur=(void*)cc; cur->pos=0; return SQLITE_OK; } static int vt_graph_index(sqlite3_vtab*vt,sqlite3_index_info*inf) { return SQLITE_OK; } static int vt_graph_column(sqlite3_vtab_cursor*cc,sqlite3_context*cxt,int n) { Cursor*cur=(void*)cc; sqlite3_result_int(cxt,n==0?cur->pos%cur_pic->size:n==1?cur->pos/cur_pic->size:cur_pic->data[cur->pos+cur_pic->size]); return SQLITE_OK; } static int vt_graph_next(sqlite3_vtab_cursor*cc) { Cursor*cur=(void*)cc; cur->pos++; return SQLITE_OK; } static int vt_graph_rowid(sqlite3_vtab_cursor*cc,sqlite3_int64*p) { Cursor*cur=(void*)cc; *p=cur->pos; return SQLITE_OK; } static int vt_graph_update(sqlite3_vtab*vt,int argc,sqlite3_value**argv,sqlite3_int64*rowid) { if(argc!=5 || sqlite3_value_type(argv[0])==SQLITE_NULL) return SQLITE_ERROR; cur_pic->data[cur_pic->size+sqlite3_value_int(argv[0])]=sqlite3_value_int(argv[4]); return SQLITE_OK; } static const sqlite3_module vt_graph={ .iVersion=1, .xBestIndex=vt_graph_index, .xClose=vt_graph_close, .xColumn=vt_graph_column, .xConnect=vt_graph_connect, .xDisconnect=vt_graph_disconnect, .xEof=vt_graph_eof, .xFilter=vt_graph_filter, .xNext=vt_graph_next, .xOpen=vt_graph_open, .xRowid=vt_graph_rowid, .xUpdate=vt_graph_update, }; static int load_picture_file(void) { sqlite3_stmt*st=0; FILE*fp; char*nam; char*buf=0; int r=0; |
︙ | ︙ | |||
516 517 518 519 520 521 522 523 524 525 526 527 528 529 | fputc(pal[c].r,fp); fputc(pal[c].r,fp); fputc(pal[c].g,fp); fputc(pal[c].g,fp); fputc(pal[c].b,fp); fputc(pal[c].b,fp); fputc(c?255:0,fp); fputc(c?255:0,fp); } pclose(fp); } static inline void edit_picture_1(Picture**pict,const char*name) { static const Uint8 shade[64]= "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" | > > > > > | 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 | fputc(pal[c].r,fp); fputc(pal[c].r,fp); fputc(pal[c].g,fp); fputc(pal[c].g,fp); fputc(pal[c].b,fp); fputc(pal[c].b,fp); fputc(c?255:0,fp); fputc(c?255:0,fp); } pclose(fp); } static int response_cb(void*aux,int argc,char**argv,char**names) { if(argc && *argv) screen_message(*argv); return 1; } static inline void edit_picture_1(Picture**pict,const char*name) { static const Uint8 shade[64]= "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" |
︙ | ︙ | |||
556 557 558 559 560 561 562 563 564 565 566 567 568 569 | int xx=-1; int yy=-1; unsigned char buf[256]; m.x=m.y=m.w=m.h=0; set_cursor(XC_arrow); redraw: if((sel&~15) || !pict[sel]) sel=0; z=screen->w-pict[sel]->size-169; if(z>screen->h-49) z=screen->h-49; z/=pict[sel]->size; if(z<3) return; if(z>32) z=32; SDL_LockSurface(screen); p=screen->pixels; | > | 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 | int xx=-1; int yy=-1; unsigned char buf[256]; m.x=m.y=m.w=m.h=0; set_cursor(XC_arrow); redraw: if((sel&~15) || !pict[sel]) sel=0; cur_pic=pict[sel]; z=screen->w-pict[sel]->size-169; if(z>screen->h-49) z=screen->h-49; z/=pict[sel]->size; if(z<3) return; if(z>32) z=32; SDL_LockSurface(screen); p=screen->pixels; |
︙ | ︙ | |||
900 901 902 903 904 905 906 907 908 909 910 911 912 913 | do_export(pict[sel]); goto redraw; case SDLK_LEFT: case SDLK_KP4: --cc; goto redraw; case SDLK_RIGHT: case SDLK_KP6: ++cc; goto redraw; case SDLK_UP: case SDLK_KP8: cc-=16; goto redraw; case SDLK_DOWN: case SDLK_KP2: cc+=16; goto redraw; case SDLK_HOME: case SDLK_KP7: cc=0; goto redraw; } break; case SDL_VIDEOEXPOSE: goto redraw; } } } | > > > > | 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 | do_export(pict[sel]); goto redraw; case SDLK_LEFT: case SDLK_KP4: --cc; goto redraw; case SDLK_RIGHT: case SDLK_KP6: ++cc; goto redraw; case SDLK_UP: case SDLK_KP8: cc-=16; goto redraw; case SDLK_DOWN: case SDLK_KP2: cc+=16; goto redraw; case SDLK_HOME: case SDLK_KP7: cc=0; goto redraw; case SDLK_F12: p=(Uint8*)screen_prompt("<SQL>"); if(p) sqlite3_exec(userdb,p,response_cb,0,0); goto redraw; } break; case SDL_VIDEOEXPOSE: goto redraw; } } } |
︙ | ︙ | |||
1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 | pict[i]=malloc(sizeof(Picture)+(gsizes[i]+1)*gsizes[i]); if(!pict[i]) fatal("Allocation failed\n"); pict[i]->size=gsizes[i]; memset(pict[i]->data,0,(gsizes[i]+1)*gsizes[i]); } } edit_picture_1(pict,name); fp=open_memstream((char**)&buf,&size); if(!fp) fatal("Cannot open memory stream\n"); for(i=n=0;i<16;i++) if(pict[i]) n++; fputc(n,fp); for(i=0;i<n;i++) fputc(pict[i]->size,fp); for(i=0;i<n>>1;i++) fputc(0,fp); for(i=0;i<n;i++) compress_picture(fp,pict[i]); | > | 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 | pict[i]=malloc(sizeof(Picture)+(gsizes[i]+1)*gsizes[i]); if(!pict[i]) fatal("Allocation failed\n"); pict[i]->size=gsizes[i]; memset(pict[i]->data,0,(gsizes[i]+1)*gsizes[i]); } } edit_picture_1(pict,name); cur_pic=0; fp=open_memstream((char**)&buf,&size); if(!fp) fatal("Cannot open memory stream\n"); for(i=n=0;i<16;i++) if(pict[i]) n++; fputc(n,fp); for(i=0;i<n;i++) fputc(pict[i]->size,fp); for(i=0;i<n>>1;i++) fputc(0,fp); for(i=0;i<n;i++) compress_picture(fp,pict[i]); |
︙ | ︙ | |||
1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 | SDL_Event ev; SDL_Rect r; sqlite3_stmt*st; int sc=0; int max=load_picture_file(); int i,n; sqlite3_create_function(userdb,"VALID_NAME",1,SQLITE_UTF8|SQLITE_DETERMINISTIC,0,fn_valid_name,0,0); init_palette(); optionquery[1]=Q_imageSize; *gsizes=picture_size=strtol(xrm_get_resource(resourcedb,optionquery,optionquery,2)?:"16",0,10); set_cursor(XC_arrow); set_caption(); i=sqlite3_prepare_v3(userdb,"SELECT `ID`,SUBSTR(`NAME`,1,LENGTH(`NAME`)-4),`TYPE` FROM `PICEDIT` WHERE `TYPE` ORDER BY `NAME` LIMIT ?1 OFFSET ?2;",-1,SQLITE_PREPARE_PERSISTENT,&st,0); if(i) fatal("SQL error (%d): %s\n",i,sqlite3_errmsg(userdb)); | > | 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 | SDL_Event ev; SDL_Rect r; sqlite3_stmt*st; int sc=0; int max=load_picture_file(); int i,n; sqlite3_create_function(userdb,"VALID_NAME",1,SQLITE_UTF8|SQLITE_DETERMINISTIC,0,fn_valid_name,0,0); sqlite3_create_module(userdb,"GRAPH",&vt_graph,0); init_palette(); optionquery[1]=Q_imageSize; *gsizes=picture_size=strtol(xrm_get_resource(resourcedb,optionquery,optionquery,2)?:"16",0,10); set_cursor(XC_arrow); set_caption(); i=sqlite3_prepare_v3(userdb,"SELECT `ID`,SUBSTR(`NAME`,1,LENGTH(`NAME`)-4),`TYPE` FROM `PICEDIT` WHERE `TYPE` ORDER BY `NAME` LIMIT ?1 OFFSET ?2;",-1,SQLITE_PREPARE_PERSISTENT,&st,0); if(i) fatal("SQL error (%d): %s\n",i,sqlite3_errmsg(userdb)); |
︙ | ︙ |
Modified picedit.doc from [daa21e621e] to [87de92095b].
︙ | ︙ | |||
117 118 119 120 121 122 123 124 125 126 127 128 129 130 | will produce a square farbfeld picture on stdout. The imported picture will replace the current picture variant. F10 Export a picture. At the prompt, you must enter a system command which will read a farbfeld picture from stdin. Click in the colour palette on the right to select a colour. With the left button, that colour is selected as the current colour. The middle button will replace everything of the current colour with the clicked colour, and the right button will exchange pixels between the current colour and the clicked colour; in either case, if any block is marked, only the marked block will be affected. | > > > > > > > > | 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | will produce a square farbfeld picture on stdout. The imported picture will replace the current picture variant. F10 Export a picture. At the prompt, you must enter a system command which will read a farbfeld picture from stdin. F12 Enter a SQL statement to edit the current picture. This should be a UPDATE statement which updates the column called "C" of the table called "GRAPH". It has columns "X" and "Y" which are the coordinates of the pixel, and "C" which is the colour of the pixel. It may also be a SELECT statement in order to query it, and the response is then displayed (which must be a single row and single column only). Click in the colour palette on the right to select a colour. With the left button, that colour is selected as the current colour. The middle button will replace everything of the current colour with the clicked colour, and the right button will exchange pixels between the current colour and the clicked colour; in either case, if any block is marked, only the marked block will be affected. |
︙ | ︙ |