Index: heromesh.h ================================================================== --- heromesh.h +++ heromesh.h @@ -87,10 +87,12 @@ void draw_picture(int x,int y,Uint16 img); void draw_text(int x,int y,const unsigned char*t,int bg,int fg); void draw_cell(int x,int y); const char*screen_prompt(const char*txt); void load_pictures(void); + +int scrollbar(int*cur,int page,int max,SDL_Event*ev,SDL_Rect*re); // == class == #define CF_PLAYER 0x01 #define CF_INPUT 0x02 Index: main.c ================================================================== --- main.c +++ main.c @@ -595,10 +595,11 @@ Uint32 n=0; SDLKey k; SDL_Event ev; char buf[32]; const UserCommand*uc; + int i; set_cursor(XC_tcross); SDL_LockSurface(screen); draw_text(0,0,"Hello, World!",0xF0,0xFF); SDL_UnlockSurface(screen); SDL_Flip(screen); @@ -633,10 +634,12 @@ sqlite3_exec(userdb,"SELECT * FROM `PICTURES`;",test_sql_callback,0,0); break; case SDLK_q: exit(0); break; + case SDLK_s: + goto scrolltest; case SDLK_t: puts(screen_prompt("Testing screen_prompt()")?:"No output."); break; } break; @@ -679,10 +682,45 @@ break; case SDL_QUIT: exit(0); break; } + fatal("An error occurred waiting for events.\n"); +scrolltest: + SDL_FillRect(screen,0,0xF2); + i=0; + scrollbar(&i,10,n,0,0); + draw_picture(16,screen->h/10,1); + draw_picture(16,(2*screen->h)/10,2); + draw_picture(16,(3*screen->h)/10,3); + SDL_Flip(screen); + set_cursor(XC_arrow); + while(SDL_WaitEvent(&ev)) switch(ev.type) { + case SDL_KEYDOWN: + if(ev.key.keysym.sym==SDLK_SPACE) exit(0); + break; + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + scrollbar(&i,10,n,&ev,0); + printf("scroll %d %d\n",i,n); + break; + case SDL_MOUSEMOTION: + if(!scrollbar(&i,10,n,&ev,0)) set_cursor(XC_arrow); + break; + case SDL_VIDEOEXPOSE: + SDL_FillRect(screen,0,0xF2); + scrollbar(&i,10,n,&ev,0); + draw_picture(16,screen->h/10,1); + draw_picture(16,(2*screen->h)/10,2); + draw_picture(16,(3*screen->h)/10,3); + SDL_Flip(screen); + break; + case SDL_QUIT: + exit(0); + break; + } + fatal("An error occurred waiting for events.\n"); } static void do_sql_mode(void) { int m=sqlite3_limit(userdb,SQLITE_LIMIT_SQL_LENGTH,-1); char*txt; Index: picture.c ================================================================== --- picture.c +++ picture.c @@ -427,5 +427,86 @@ } SDL_EnableUNICODE(1); optionquery[1]=Q_margin; left_margin=strtol(xrm_get_resource(resourcedb,optionquery,optionquery,2)?:"65",0,10); } + +// Widgets + +static void draw_scrollbar(int*cur,int page,int max,int x0,int y0,int x1,int y1) { + Uint8*pix=screen->pixels; + Uint16 pitch=screen->pitch; + int x,y,m0,m1; + double f; + f=(y1-y0)/(double)(max+page); + if(*cur<0) *cur=0; else if(*cur>max) *cur=max; + m0=*cur*f+y0; + m1=(*cur+page)*f+y0; + pix+=y0*pitch; + SDL_LockSurface(screen); + for(y=y0;ym1?0xFF:(y^x)&1?0xF0:0xFF; + pix[x1]=0xFF; + pix+=pitch; + } + SDL_UnlockSurface(screen); +} + +int scrollbar(int*cur,int page,int max,SDL_Event*ev,SDL_Rect*re) { + int x0=re?re->x:0; + int y0=re?re->y:0; + int x1=re?re->x+12:12; + int y1=re?re->y+re->h:screen->h; + int y; + double f; + switch(ev?ev->type:SDL_VIDEOEXPOSE) { + case SDL_MOUSEMOTION: + if(ev->motion.xmotion.x>x1 || ev->motion.ymotion.y>=y1) return 0; + if(ev->motion.state&SDL_BUTTON(2)) { + y=ev->motion.y; + goto move; + } else if(ev->motion.state&SDL_BUTTON(1)) { + set_cursor(XC_sb_up_arrow); + } else if(ev->motion.state&SDL_BUTTON(3)) { + set_cursor(XC_sb_down_arrow); + } else { + set_cursor(XC_sb_v_double_arrow); + } + return 1; + case SDL_MOUSEBUTTONDOWN: + if(ev->button.xbutton.x>x1 || ev->button.ybutton.y>=y1) return 0; + if(ev->button.button==2) { + y=ev->button.y; + goto move; + } else if(ev->button.button==1) { + set_cursor(XC_sb_up_arrow); + } else if(ev->button.button==3) { + set_cursor(XC_sb_down_arrow); + } + return 1; + case SDL_MOUSEBUTTONUP: + if(ev->button.xbutton.x>x1 || ev->button.ybutton.y>=y1) return 0; + f=(y1-y0)/(double)page; + y=(ev->button.y-y0+0.5)/f; + if(ev->button.button==1) { + *cur+=y; + } else if(ev->button.button==3) { + *cur-=y; + } + draw_scrollbar(cur,page,max,x0,y0,x1,y1); + SDL_Flip(screen); + set_cursor(XC_sb_v_double_arrow); + return 1; + case SDL_VIDEOEXPOSE: + draw_scrollbar(cur,page,max,x0,y0,x1,y1); + return 0; + default: + return 0; + } + move: + f=(y1-y0)/(double)(max+page); + *cur=(y-y0+0.5)/f; + draw_scrollbar(cur,page,max,x0,y0,x1,y1); + SDL_Flip(screen); + set_cursor(XC_sb_right_arrow); + return 1; +}