diff --git a/src/uifc/uifc.h b/src/uifc/uifc.h index 88d7d43492d1a140ee72223e388722382347fd95..f43d8b0a5196514aa48f25bbb5c771de8de10705 100644 --- a/src/uifc/uifc.h +++ b/src/uifc/uifc.h @@ -304,6 +304,14 @@ typedef struct { char helpdatfile[MAX_PATH+1]; char helpixbfile[MAX_PATH+1]; /****************************************************************************/ +/* Help and exit button locations for current/last window */ +/****************************************************************************/ + int buttony; + int exitstart; + int exitend; + int helpstart; + int helpend; +/****************************************************************************/ /* Exit/uninitialize function. */ /****************************************************************************/ void (*bail) (void); diff --git a/src/uifc/uifc32.c b/src/uifc/uifc32.c index a5f7fc1ff3cc33a09f06ceb32675aebbaea16d46..1780633beb84e40b3fc359c80c68443c86bff4ac 100644 --- a/src/uifc/uifc32.c +++ b/src/uifc/uifc32.c @@ -106,6 +106,13 @@ static int *last_menu_bar=NULL; static int save_menu_cur=-1; static int save_menu_bar=-1; +/* Internal Structs */ +struct uifc_mouse_event { + int x; + int y; + int button; +}; + static void reset_dynamic(void) { last_menu_cur=NULL; last_menu_bar=NULL; @@ -203,11 +210,23 @@ int uifcini32(uifcapi_t* uifcapi) if(api->esc_delay < 10) api->esc_delay=25; +#ifdef PDCURSES + if(mouse_set(BUTTON1_CLICKED|BUTTON3_CLICKED)==0) + api->mode|=UIFC_MOUSE; + else + mouse_set(0); +#endif #ifdef __unix__ initciowrap(api->mode); #ifdef NCURSES_VERSION_MAJOR ESCDELAY=api->esc_delay; + + if(mousemask(BUTTON1_CLICKED|BUTTON3_CLICKED,NULL)==BUTTON1_CLICKED|BUTTON3_CLICKED) + api->mode|=UIFC_MOUSE; + else + mousemask(0,NULL); #endif + #else if(api->scrn_len!=0) { switch(api->scrn_len) { @@ -318,10 +337,89 @@ int uifcini32(uifcapi_t* uifcapi) return(0); } +static void hidemouse(void) +{ + if(api->mode&UIFC_MOUSE) { + #ifdef XCURSES + mouse_set(0); + #endif + #ifdef NCURSES_VERSION_MAJOR + mousemask(0,NULL); + #endif + } +} + +static void showmouse(void) +{ + if(api->mode&UIFC_MOUSE) { + #ifdef XCURSES + mouse_set(BUTTON1_CLICKED|BUTTON3_CLICKED); + #endif + #ifdef NCURSES_VERSION_MAJOR + mousemask(BUTTON1_CLICKED|BUTTON3_CLICKED,NULL); + #endif + } +} + +static int uifc_getmouse(struct uifc_mouse_event *mevent) +{ + mevent->x=0; + mevent->y=0; + mevent->button=0; + if(api->mode&UIFC_MOUSE) { + #ifdef NCURSES_VERSION_MAJOR + MEVENT mevnt; + + if(getmouse(&mevnt)==OK) { + mevent->x=mevnt.x; + mevent->y=mevnt.y; + switch(mevnt.bstate) { + case BUTTON1_CLICKED: + mevent->button=1; + break; + case BUTTON3_CLICKED: + mevent->button=2; + break; + } + } + else + return(-1); + #endif + #ifdef XCURSES + if(getmouse()==0) { + mevent->x=Mouse_status.x; + mevent->y=Mouse_status.y; + if(Mouse_status.button[1]==BUTTON_CLICKED) + mevent->button=1; + if(Mouse_status.button[3]==BUTTON_CLICKED) + mevent->button=3; + } + else + return(-1); + #endif + if(mevent->y==api->buttony) { + if((mevent->x>=api->exitstart + && mevent->x<=api->exitend + && mevent->button==1) + || mevent->button==2) { + return(ESC); + } + if(mevent->x>=api->helpstart + && mevent->x<=api->helpend + && mevent->button==1) { + return(KEY_F(1)); + } + } + return(0); + } + return(-1); +} + void uifcbail(void) { _setcursortype(_NORMALCURSOR); textattr(LIGHTGRAY); + hidemouse(); clrscr(); #ifdef __unix__ nl(); @@ -329,6 +427,9 @@ void uifcbail(void) noraw(); refresh(); endwin(); +#ifdef XCURSES + XCursesExit(); +#endif #endif FREE(blk_scrn); FREE(tmp_buffer); @@ -401,7 +502,7 @@ int ulist(int mode, int left, int top, int width, int *cur, int *bar , char *title, char **option) { uchar line[256],shade[256],*ptr,a,b,c,longopt - ,search[MAX_OPLN],bline=0; + ,search[MAX_OPLN],bline=0,*win; int height,y; int i,j,opts=0,s=0; /* s=search index into options */ int is_redraw=0; @@ -409,6 +510,12 @@ int ulist(int mode, int left, int top, int width, int *cur, int *bar uint s_left=SCRN_LEFT; uint s_right=SCRN_RIGHT; uint s_bottom=api->scrn_len-3; + uint title_len; + struct uifc_mouse_event mevnt; + + hidemouse(); + + title_len=strlen(title); if(mode&WIN_FAT) { s_top=1; @@ -432,8 +539,8 @@ int ulist(int mode, int left, int top, int width, int *cur, int *bar height=opts+4; if(top+height>s_bottom) height=(s_bottom)-top; - if(!width || width<strlen(title)+6) { - width=strlen(title)+6; + if(!width || width<title_len+6) { + width=title_len+6; for(i=0;i<opts;i++) { truncsp(option[i]); if((j=strlen(option[i])+5)>width) @@ -442,7 +549,7 @@ int ulist(int mode, int left, int top, int width, int *cur, int *bar } if(width>(s_right+1)-s_left) { width=(s_right+1)-s_left; - if(strlen(title)>(width-4)) { + if(title_len>(width-4)) { *(title+width-7)='.'; *(title+width-6)='.'; *(title+width-5)='.'; @@ -530,7 +637,30 @@ int ulist(int mode, int left, int top, int width, int *cur, int *bar *(ptr++)='�'; *(ptr++)=hclr|(bclr<<4); - i=0; + if(api->mode&UIFC_MOUSE) { + *(ptr++)='['; + *(ptr++)=hclr|(bclr<<4); + /* *(ptr++)='�'; */ + *(ptr++)='X'; + *(ptr++)=lclr|(bclr<<4); + *(ptr++)=']'; + *(ptr++)=hclr|(bclr<<4); + *(ptr++)='['; + *(ptr++)=hclr|(bclr<<4); + *(ptr++)='?'; + *(ptr++)=lclr|(bclr<<4); + *(ptr++)=']'; + *(ptr++)=hclr|(bclr<<4); + i=6; + api->buttony=s_top+top-1; + api->exitstart=s_left+left; + api->exitend=s_left+left+2; + api->helpstart=s_left+left+3; + api->helpend=s_left+left+5; + } + else + i=0; + for(;i<width-2;i++) { *(ptr++)='�'; *(ptr++)=hclr|(bclr<<4); @@ -539,7 +669,7 @@ int ulist(int mode, int left, int top, int width, int *cur, int *bar *(ptr++)=hclr|(bclr<<4); *(ptr++)='�'; *(ptr++)=hclr|(bclr<<4); - a=strlen(title); + a=title_len; b=(width-a-1)/2; for(i=0;i<b;i++) { *(ptr++)=' '; @@ -709,6 +839,9 @@ int ulist(int mode, int left, int top, int width, int *cur, int *bar last_menu_bar=bar; if(mode&WIN_IMM) return(-2); + + showmouse(); + while(1) { #if 0 /* debug */ gotoxy(30,1); @@ -721,6 +854,120 @@ int ulist(int mode, int left, int top, int width, int *cur, int *bar i=inkey(); if(i==KEY_BACKSPACE || i==BS) i=ESC; +#ifdef KEY_MOUSE + if(i==KEY_MOUSE) { +#else + if(0) { +#endif + if((i=uifc_getmouse(&mevnt))==0) { + /* Clicked in menu */ + if(mevnt.x>=s_left+left+2 + && mevnt.x<=s_left+left+width + && mevnt.y>=s_top+top+2 + && mevnt.y<=(s_top+top+height)-3 + && mevnt.button==1) { + + (*cur)=(mevnt.y)-(s_top+top+2); + if(bar) + (*bar)=(*cur); + y=top+3+((mevnt.y)-(s_top+top+2)); + + if(!opts || (mode&WIN_XTR && (*cur)==opts-1)) + continue; + + if(mode&WIN_ACT) { + hidemouse(); + if((win=(char *)MALLOC((width+3)*(height+2)*2))==NULL) { + cprintf("UIFC line %d: error allocating %u bytes." + ,__LINE__,(width+3)*(height+2)*2); + return(-1); + } + gettext(s_left+left,s_top+top,s_left + +left+width-1,s_top+top+height-1,win); + for(i=1;i<(width*height*2);i+=2) + win[i]=lclr|(cclr<<4); + j=(((y-top)*width)*2)+7+((width-4)*2); + for(i=(((y-top)*width)*2)+7;i<j;i+=2) + win[i]=hclr|(cclr<<4); + + puttext(s_left+left,s_top+top,s_left + +left+width-1,s_top+top+height-1,win); + free(win); + showmouse(); + } + else if(mode&WIN_SAV) { + hidemouse(); + puttext(sav[api->savnum].left,sav[api->savnum].top + ,sav[api->savnum].right,sav[api->savnum].bot + ,sav[api->savnum].buf); + showmouse(); + free(sav[api->savnum].buf); + api->savdepth--; + } + return(*cur); + } + /* Clicked Scroll Up */ + if(mevnt.x==s_left+left + && mevnt.y==s_top+top+2 + && mevnt.button==1) { + if(!opts) + continue; + *cur -= (height-5); + if(*cur<0) + *cur = 0; + if(bar) + *bar=0; + y=s_top+top; + gotoxy(s_left+left+1,s_top+top+3); + textattr(lclr|(bclr<<4)); + if(*cur && opts>height-3) /* Scroll mode */ + putch(30); /* put the up arrow */ + else + putch(' '); /* delete the up arrow */ + gotoxy(s_left+left+1,s_top+top+height-2); + if(opts > height-3 && *cur + height - 4 < opts) + putch(31); /* put the down arrow */ + else + putch(' '); /* delete the down arrow */ + for(i=*cur,j=0;i<=*cur-5+height;i++,j++) + uprintf(s_left+left+3,s_top+top+3+j + ,i==*cur ? lbclr + : lclr|(bclr<<4) + ,"%-*.*s",width-4,width-4,option[i]); + continue; + } + /* Clicked Scroll Down */ + if(mevnt.x=s_left+left + && mevnt.y==(s_top+top+height)-3 + && mevnt.button==1) { + if(!opts) + continue; + *cur += (height-5); + if(*cur>opts-1) + *cur = opts-1; + if(bar) + *bar = height-5; + y=height-5+s_top+top; + gotoxy(s_left+left+1,s_top+top+3); + textattr(lclr|(bclr<<4)); + if(*cur>height-5) /* Scroll mode */ + putch(30); /* put the up arrow */ + else + putch(' '); /* delete the up arrow */ + gotoxy(s_left+left+1,s_top+top+height-2); + if(*cur < opts-1) + putch(31); /* put the down arrow */ + else + putch(' '); /* delete the down arrow */ + for(i=*cur+5-height,j=0;i<=*cur;i++,j++) + uprintf(s_left+left+3,s_top+top+3+j + ,i==*cur ? lbclr + : lclr|(bclr<<4) + ,"%-*.*s",width-4,width-4,option[i]); + continue; + } + } + } if(i>255) { s=0; switch(i) { @@ -1235,8 +1482,29 @@ int uinput(int mode, int left, int top, char *prompt, char *str, in_win[i++]=hclr|(bclr<<4); for(c=1;c<width-1;c++) { in_win[i++]='�'; - in_win[i++]=hclr|(bclr<<4); + in_win[i++]=hclr|(bclr<<4); } + if(api->mode&UIFC_MOUSE && width>6) { + in_win[2]='['; + in_win[3]=hclr|(bclr<<4); + /* in_win[4]='�'; */ + in_win[4]='X'; + in_win[5]=lclr|(bclr<<4); + in_win[6]=']'; + in_win[7]=hclr|(bclr<<4); + in_win[8]='['; + in_win[9]=hclr|(bclr<<4); + in_win[10]='?'; + in_win[11]=lclr|(bclr<<4); + in_win[12]=']'; + in_win[13]=hclr|(bclr<<4); + api->buttony=SCRN_TOP+top-1; + api->exitstart=SCRN_LEFT+left; + api->exitend=SCRN_LEFT+left+2; + api->helpstart=SCRN_LEFT+left+3; + api->helpend=SCRN_LEFT+left+5; + } + in_win[i++]='�'; in_win[i++]=hclr|(bclr<<4); in_win[i++]='�'; @@ -1345,6 +1613,7 @@ int ugetstr(int left, int top, int width, char *outstr, int max, long mode, int int i,j,k,f=0; /* i=offset, j=length */ BOOL gotdecimal=FALSE; int soffset=0; + struct uifc_mouse_event mevnt; if((str=(uchar *)malloc(max+1))==NULL) { cprintf("UIFC line %d: error allocating %u bytes\r\n" @@ -1378,11 +1647,27 @@ int ugetstr(int left, int top, int width, char *outstr, int max, long mode, int } #endif f=inkey(); +#ifdef KEY_MOUSE + if(f==KEY_MOUSE) { +#else + if(0) { +#endif + if((f=uifc_getmouse(&mevnt))==0) { + if(mevnt.x>=left-1 + && mevnt.x<=left+width-1 + && mevnt.button==1) { + i=mevnt.x-left+soffset+1; + if(i>j) + i=j; + } + } + } if(f == CR || (f >= 0xff && f != KEY_DC) || (f == '\t' && mode&K_TABEXIT) - || (f == '%' && mode&K_SCANNING)) + || (f == '%' && mode&K_SCANNING) + || f==0) { getstrupd(left, top, width, str, i, &soffset); } @@ -1405,8 +1690,24 @@ int ugetstr(int left, int top, int width, char *outstr, int max, long mode, int { if(f) ch=f; - else + else { ch=inkey(); +#ifdef KEY_MOUSE + if(ch==KEY_MOUSE) { +#else + if(0) { +#endif + if((ch=uifc_getmouse(&mevnt))==0) { + if(mevnt.x>=left-1 + && mevnt.x<=left+width-1 + && mevnt.button==1) { + i=mevnt.x-left+soffset+1; + if(i>j) + i=j; + } + } + } + } if(lastkey != NULL) *lastkey=ch; f=0; @@ -1783,13 +2084,19 @@ void showbuf(int mode, int left, int top, int width, int height, char *title, ch int lines; int pad=1; int is_redraw=0; + uint title_len=0; + struct uifc_mouse_event mevnt; _setcursortype(_NOCURSOR); + + title_len=strlen(title); + if(api->mode&UIFC_MOUSE) + title_len+=6; if(top+height>api->scrn_len-3) height=(api->scrn_len-3)-top; - if(!width || width<strlen(title)+6) - width=strlen(title)+6; + if(!width || width<title_len+6) + width=title_len+6; if(width>api->scrn_width) width=api->scrn_width; if(mode&WIN_L2R) @@ -1829,11 +2136,21 @@ void showbuf(int mode, int left, int top, int width, int height, char *title, ch for(i=1;i<width*height*2;i+=2) tmp_buffer2[i]=(hclr|(bclr<<4)); tmp_buffer2[0]='�'; - j=strlen(title); + j=title_len; if(j>width-6) *(title+width-6)=0; for(i=2;i<((width-6)/2-(j/2))*2;i+=2) tmp_buffer2[i]='�'; + if(api->mode&UIFC_MOUSE && !mode&WIN_DYN) { + tmp_buffer2[2]='['; + tmp_buffer2[3]=hclr|(bclr<<4); + /* tmp_buffer2[4]='�'; */ + tmp_buffer2[4]='X'; + tmp_buffer2[5]=lclr|(bclr<<4); + tmp_buffer2[6]=']'; + tmp_buffer2[7]=hclr|(bclr<<4); + /* Buttons are ignored - leave it this way to not confuse stuff from help() */ + } tmp_buffer2[i]='�'; i+=4; for(p=title;*p;p++) { tmp_buffer2[i]=*p; @@ -1912,8 +2229,10 @@ void showbuf(int mode, int left, int top, int width, int height, char *title, ch memset(textbuf,' ',(width-2-pad-pad)*lines*2); for(i=1;i<(width-2-pad-pad)*lines*2;i+=2) textbuf[i]=(hclr|(bclr<<4)); + i=0; - for(j=0;j<len;j++,i+=2) { + + for(j=i;j<len;j++,i+=2) { if(hbuf[j]==LF) { i+=2; while(i%((width-2-pad-pad)*2)) i++; i-=2; @@ -1930,7 +2249,7 @@ void showbuf(int mode, int left, int top, int width, int height, char *title, ch textbuf[i]=hbuf[j]; textbuf[i+1]=inverse ? (bclr|(cclr<<4)) : high ? (hclr|(bclr<<4)) : (lclr|(bclr<<4)); - } + } } i=0; p=textbuf; @@ -1941,7 +2260,43 @@ void showbuf(int mode, int left, int top, int width, int height, char *title, ch while(i==0) { puttext(left+1+pad,top+2+pad,left+width-2-pad,top+height-1-pad,p); if(kbwait()) { - switch(inkey()) { + j=inkey(); +#ifdef KEY_MOUSE + if(j==KEY_MOUSE) { +#else + if(0) { +#endif + /* Ignores return value to avoid hitting help/exit hotspots */ + if(uifc_getmouse(&mevnt)>=0) { + /* Clicked Scroll Up */ + if(mevnt.x>=left+pad-1 + && mevnt.x<=left+pad+width-4 + && mevnt.y>=top+pad + && mevnt.y<=top+pad+(height/2)-3 + && mevnt.button==1) { + p = p-((width-4)*2*(height-5)); + if(p<textbuf) + p=textbuf; + continue; + } + /* Clicked Scroll Down */ + if(mevnt.x>=left+pad-1 + && mevnt.x<=left+pad+width-1 + && mevnt.y<=top+pad+height-3 + && mevnt.y>=top+pad+height-(height/2+1)-3 + && mevnt.button==1) { + p=p+(width-4)*2*(height-5); + if(p > textbuf+(lines-height+1)*(width-4)*2) + p=textbuf+(lines-height+1)*(width-4)*2; + if(p<textbuf) + p=textbuf; + continue; + } + i=1; + } + continue; + } + switch(j) { case KEY_HOME: /* home */ p=textbuf; break; @@ -2046,7 +2401,7 @@ static void help(void) fseek(fp,l,SEEK_SET); fread(hbuf,HELPBUF_SIZE,1,fp); fclose(fp); - } + } } } }