#include "compiler.h" #include "strres.h" #include "fontmng.h" #include "vramhdl.h" #include "vrammix.h" #include "menudeco.inc" #include "menubase.h" typedef struct _dprm { struct _dprm *next; UINT16 width; UINT16 num; VRAMHDL icon; OEMCHAR str[96]; } _DLGPRM, *DLGPRM; #define PRMNEXT_EMPTY ((DLGPRM)-1) typedef struct { POINT_T pt; void *font; } DLGTEXT; typedef struct { void *font; int fontsize; } DLGTAB; typedef struct { void *font; SINT16 fontsize; SINT16 scrollbar; SINT16 dispmax; SINT16 basepos; } DLGLIST; typedef struct { SINT16 minval; SINT16 maxval; int pos; UINT8 type; UINT8 moving; UINT8 sldh; UINT8 sldv; } DLGSLD; typedef struct { VRAMHDL vram; } DLGVRAM; typedef struct _ditem { int type; MENUID id; MENUFLG flag; MENUID page; MENUID group; RECT_T rect; DLGPRM prm; int prmcnt; int val; VRAMHDL vram; union { DLGTEXT dt; DLGTAB dtl; DLGLIST dl; DLGSLD ds; DLGVRAM dv; } c; } _DLGHDL, *DLGHDL; typedef struct { VRAMHDL vram; LISTARRAY dlg; LISTARRAY res; int locked; int closing; int sx; int sy; void *font; MENUID page; MENUID group; int (*proc)(int msg, MENUID id, long param); int dragflg; int btn; int lastx; int lasty; MENUID lastid; } _MENUDLG, *MENUDLG; static _MENUDLG menudlg; static void drawctrls(MENUDLG dlg, DLGHDL hdl); // ---- static BOOL seaprmempty(void *vpItem, void *vpArg) { if (((DLGPRM)vpItem)->next == PRMNEXT_EMPTY) { menuicon_unlock(((DLGPRM)vpItem)->icon); ((DLGPRM)vpItem)->icon = NULL; return(TRUE); } (void)vpArg; return(FALSE); } static DLGPRM resappend(MENUDLG dlg, const OEMCHAR *str) { DLGPRM prm; prm = listarray_enum(dlg->res, seaprmempty, NULL); if (prm == NULL) { prm = (DLGPRM)listarray_append(dlg->res, NULL); } if (prm) { prm->next = NULL; prm->width = 0; prm->num = 0; prm->icon = NULL; prm->str[0] = '\0'; if (str) { milstr_ncpy(prm->str, str, NELEMENTS(prm->str)); } } return(prm); } static void resattachicon(MENUDLG dlg, DLGPRM prm, UINT16 icon, int width, int height) { if (prm) { menuicon_unlock(prm->icon); prm->num = icon; prm->icon = menuicon_lock(icon, width, height, dlg->vram->bpp); } } static DLGPRM ressea(DLGHDL hdl, int pos) { DLGPRM prm; if (pos >= 0) { prm = hdl->prm; while(prm) { if (!pos) { return(prm); } pos--; prm = prm->next; } } return(NULL); } static BOOL dsbyid(void *vpItem, void *vpArg) { if (((DLGHDL)vpItem)->id == (MENUID)(unsigned long)vpArg) { return(TRUE); } return(FALSE); } static DLGHDL dlghdlsea(MENUDLG dlg, MENUID id) { return((DLGHDL)listarray_enum(dlg->dlg, dsbyid, (void *)(long)id)); } static BRESULT gettextsz(DLGHDL hdl, POINT_T *sz) { DLGPRM prm; prm = hdl->prm; if (prm == NULL) { goto gts_err; } *sz = hdl->c.dt.pt; if (prm->icon) { if (sz->x) { #if defined(SIZE_QVGA) sz->x += 1; #else sz->x += 2; #endif } sz->x += sz->y; } return(SUCCESS); gts_err: return(FAILURE); } static void getleft(POINT_T *pt, const RECT_T *rect, const POINT_T *sz) { pt->x = rect->left; pt->y = rect->top; (void)sz; } static void getcenter(POINT_T *pt, const RECT_T *rect, const POINT_T *sz) { pt->x = rect->left; pt->x += (rect->right - rect->left - sz->x) >> 1; pt->y = rect->top; } static void getright(POINT_T *pt, const RECT_T *rect, const POINT_T *sz) { pt->x = rect->right - sz->x - MENU_DSTEXT; pt->y = rect->top; } static void getmid(POINT_T *pt, const RECT_T *rect, const POINT_T *sz) { pt->x = rect->left; pt->x += (rect->right - rect->left - sz->x) >> 1; pt->y = rect->top; pt->y += (rect->bottom - rect->top - sz->y) >> 1; } static BRESULT _cre_settext(MENUDLG dlg, DLGHDL hdl, const void *arg) { const OEMCHAR *str; str = (OEMCHAR *)arg; if (str == NULL) { str = str_null; } hdl->prm = resappend(dlg, str); hdl->c.dt.font = dlg->font; fontmng_getsize(dlg->font, str, &hdl->c.dt.pt); return(SUCCESS); } static void dlg_text(MENUDLG dlg, DLGHDL hdl, const POINT_T *pt, const RECT_T *rect) { VRAMHDL icon; const OEMCHAR *string; int color; POINT_T fp; POINT_T p; if (hdl->prm == NULL) { return; } fp = *pt; icon = hdl->prm->icon; if (icon) { if (icon->alpha) { vramcpy_cpyex(dlg->vram, &fp, icon, NULL); } else { vramcpy_cpy(dlg->vram, &fp, icon, NULL); } fp.x += icon->width; #if defined(SIZE_QVGA) fp.x += 1; #else fp.x += 2; #endif } string = hdl->prm->str; if (string) { if (!(hdl->flag & MENU_GRAY)) { color = MVC_TEXT; } else { p.x = fp.x + MENU_DSTEXT; p.y = fp.y + MENU_DSTEXT; vrammix_text(dlg->vram, hdl->c.dt.font, string, menucolor[MVC_GRAYTEXT2], &p, rect); color = MVC_GRAYTEXT1; } vrammix_text(dlg->vram, hdl->c.dt.font, string, menucolor[color], &fp, rect); } } // ---- base static BRESULT dlgbase_create(MENUDLG dlg, DLGHDL hdl, const void *arg) { RECT_T rct; rct.right = hdl->rect.right - hdl->rect.left - ((MENU_FBORDER + MENU_BORDER) * 2); hdl->vram = vram_create(rct.right, MENUDLG_CYCAPTION, FALSE, menubase.bpp); if (hdl->vram == NULL) { goto dbcre_err; } hdl->vram->posx = (MENU_FBORDER + MENU_BORDER); hdl->vram->posy = (MENU_FBORDER + MENU_BORDER); rct.left = 0; rct.top = 0; rct.bottom = MENUDLG_CYCAPTION; menuvram_caption(hdl->vram, &rct, MICON_NULL, (OEMCHAR *)arg); return(SUCCESS); dbcre_err: (void)dlg; return(FAILURE); } static void dlgbase_paint(MENUDLG dlg, DLGHDL hdl) { OEMCHAR *title; title = NULL; if (hdl->prm) { title = hdl->prm->str; } menuvram_base(dlg->vram); vrammix_cpy(dlg->vram, NULL, hdl->vram, NULL); menubase_setrect(dlg->vram, NULL); } static void dlgbase_onclick(MENUDLG dlg, DLGHDL hdl, int x, int y) { RECT_T rct; vram_getrect(hdl->vram, &rct); dlg->dragflg = rect_in(&rct, x, y); dlg->lastx = x; dlg->lasty = y; } static void dlgbase_move(MENUDLG dlg, DLGHDL hdl, int x, int y, int focus) { if (dlg->dragflg) { x -= dlg->lastx; y -= dlg->lasty; if ((x) || (y)) { menubase_clrrect(dlg->vram); dlg->vram->posx += x; dlg->vram->posy += y; menubase_setrect(dlg->vram, NULL); } } (void)hdl; (void)focus; } // ---- close static void dlgclose_paint(MENUDLG dlg, DLGHDL hdl) { menuvram_closebtn(dlg->vram, &hdl->rect, hdl->val); } static void dlgclose_onclick(MENUDLG dlg, DLGHDL hdl, int x, int y) { hdl->val = 1; drawctrls(dlg, hdl); (void)x; (void)y; } static void dlgclose_move(MENUDLG dlg, DLGHDL hdl, int x, int y, int focus) { if (hdl->val != focus) { hdl->val = focus; drawctrls(dlg, hdl); } (void)x; (void)y; } static void dlgclose_rel(MENUDLG dlg, DLGHDL hdl, int focus) { if (focus) { dlg->proc(DLGMSG_CLOSE, 0, 0); } (void)hdl; } // ---- button static void dlgbtn_paint(MENUDLG dlg, DLGHDL hdl) { POINT_T sz; POINT_T pt; UINT c; vram_filldat(dlg->vram, &hdl->rect, menucolor[MVC_BTNFACE]); if (!hdl->val) { c = MVC4(MVC_HILIGHT, MVC_DARK, MVC_LIGHT, MVC_SHADOW); } else { c = MVC4(MVC_DARK, MVC_DARK, MVC_SHADOW, MVC_SHADOW); } menuvram_box2(dlg->vram, &hdl->rect, c); if (gettextsz(hdl, &sz) == SUCCESS) { getmid(&pt, &hdl->rect, &sz); if (hdl->val) { pt.x += MENU_DSTEXT; pt.y += MENU_DSTEXT; } dlg_text(dlg, hdl, &pt, &hdl->rect); } } static void dlgbtn_onclick(MENUDLG dlg, DLGHDL hdl, int x, int y) { hdl->val = 1; drawctrls(dlg, hdl); (void)x; (void)y; } static void dlgbtn_move(MENUDLG dlg, DLGHDL hdl, int x, int y, int focus) { if (hdl->val != focus) { hdl->val = focus; drawctrls(dlg, hdl); } (void)x; (void)y; } static void dlgbtn_rel(MENUDLG dlg, DLGHDL hdl, int focus) { if (hdl->val != 0) { hdl->val = 0; drawctrls(dlg, hdl); } if (focus) { dlg->proc(DLGMSG_COMMAND, hdl->id, 0); } } // ---- list static void *dlglist_setfont(DLGHDL hdl, void *font) { // 後でスクロールバーの調整をすべし void *ret; POINT_T pt; ret = hdl->c.dl.font; hdl->c.dl.font = font; fontmng_getsize(font, mstr_fontcheck, &pt); if ((pt.y <= 0) || (pt.y >= 65536)) { pt.y = 16; } hdl->c.dl.fontsize = (SINT16)pt.y; hdl->c.dl.dispmax = (SINT16)(hdl->vram->height / pt.y); return(ret); } static void dlglist_reset(MENUDLG dlg, DLGHDL hdl) { DLGPRM dp; DLGPRM next; vram_filldat(hdl->vram, NULL, 0xffffff); dp = hdl->prm; while(dp) { next = dp->next; dp->next = PRMNEXT_EMPTY; dp = next; } hdl->prm = NULL; hdl->prmcnt = 0; hdl->val = -1; hdl->c.dl.scrollbar = 0; hdl->c.dl.basepos = 0; } static BRESULT dlglist_create(MENUDLG dlg, DLGHDL hdl, const void *arg) { int width; int height; width = hdl->rect.right - hdl->rect.left - (MENU_LINE * 4); height = hdl->rect.bottom - hdl->rect.top - (MENU_LINE * 4); hdl->vram = vram_create(width, height, FALSE, menubase.bpp); if (hdl->vram == NULL) { goto dlcre_err; } hdl->vram->posx = hdl->rect.left + (MENU_LINE * 2); hdl->vram->posy = hdl->rect.top + (MENU_LINE * 2); dlglist_setfont(hdl, dlg->font); dlglist_reset(dlg, hdl); return(SUCCESS); dlcre_err: (void)dlg; (void)arg; return(FAILURE); } static void dlglist_paint(MENUDLG dlg, DLGHDL hdl) { menuvram_box2(dlg->vram, &hdl->rect, MVC4(MVC_SHADOW, MVC_HILIGHT, MVC_DARK, MVC_LIGHT)); vrammix_cpy(dlg->vram, NULL, hdl->vram, NULL); } static void dlglist_drawitem(DLGHDL hdl, DLGPRM prm, int focus, POINT_T *pt, RECT_T *rct) { VRAMHDL icon; POINT_T fp; vram_filldat(hdl->vram, rct, menucolor[focus?MVC_CURBACK:MVC_HILIGHT]); fp.x = pt->x; fp.y = pt->y; icon = prm->icon; if (icon) { if (icon->alpha) { vramcpy_cpyex(hdl->vram, &fp, icon, NULL); } else { vramcpy_cpy(hdl->vram, &fp, icon, NULL); } fp.x += icon->width; #if defined(SIZE_QVGA) fp.x += 1; #else fp.x += 2; #endif } vrammix_text(hdl->vram, hdl->c.dl.font, prm->str, menucolor[focus?MVC_CURTEXT:MVC_TEXT], &fp, rct); } static BOOL dlglist_drawsub(DLGHDL hdl, int pos, int focus) { DLGPRM prm; POINT_T pt; RECT_T rct; prm = ressea(hdl, pos); if (prm == NULL) { return(FALSE); } pos -= hdl->c.dl.basepos; if (pos < 0) { return(FALSE); } pt.x = 0; pt.y = pos * hdl->c.dl.fontsize; if (pt.y >= hdl->vram->height) { return(FALSE); } rct.left = 0; rct.top = pt.y; rct.right = hdl->vram->width; if (hdl->prmcnt > hdl->c.dl.dispmax) { rct.right -= MENUDLG_CXVSCR; } rct.bottom = rct.top + hdl->c.dl.fontsize; dlglist_drawitem(hdl, prm, focus, &pt, &rct); return(TRUE); } static void dlglist_setbtn(DLGHDL hdl, int flg) { RECT_T rct; POINT_T pt; UINT mvc4; const MENURES2 *res; res = menures_scrbtn; rct.right = hdl->vram->width; rct.left = rct.right - MENUDLG_CXVSCR; if (!(flg & 2)) { rct.top = 0; } else { rct.top = hdl->vram->height - MENUDLG_CYVSCR; if (rct.top < MENUDLG_CYVSCR) { rct.top = MENUDLG_CYVSCR; } res++; } rct.bottom = rct.top + MENUDLG_CYVSCR; vram_filldat(hdl->vram, &rct, menucolor[MVC_BTNFACE]); if (flg & 1) { mvc4 = MVC4(MVC_SHADOW, MVC_SHADOW, MVC_LIGHT, MVC_LIGHT); } else { mvc4 = MVC4(MVC_LIGHT, MVC_DARK, MVC_HILIGHT, MVC_SHADOW); } menuvram_box2(hdl->vram, &rct, mvc4); pt.x = rct.left + (MENU_LINE * 2); pt.y = rct.top + (MENU_LINE * 2); if (flg & 1) { pt.x += MENU_DSTEXT; pt.y += MENU_DSTEXT; } menuvram_res3put(hdl->vram, res, &pt, MVC_TEXT); } static void dlglist_drawall(DLGHDL hdl) { DLGPRM prm; POINT_T pt; RECT_T rct; int pos; rct.left = 0; rct.top = 0 - (hdl->c.dl.basepos * hdl->c.dl.fontsize); rct.right = hdl->vram->width; if (hdl->prmcnt > hdl->c.dl.dispmax) { rct.right -= MENUDLG_CXVSCR; } prm = hdl->prm; pos = 0; while(prm) { if (rct.top >= hdl->vram->height) { break; } if (rct.top >= 0) { rct.bottom = rct.top + hdl->c.dl.fontsize; pt.x = 0; pt.y = rct.top; dlglist_drawitem(hdl, prm, (pos == hdl->val), &pt, &rct); } prm = prm->next; pos++; rct.top += hdl->c.dl.fontsize; } rct.bottom = hdl->vram->height; vram_filldat(hdl->vram, &rct, menucolor[MVC_HILIGHT]); } static int dlglist_barpos(DLGHDL hdl) { int ret; ret = hdl->vram->height - (MENUDLG_CYVSCR * 2); ret -= hdl->c.dl.scrollbar; ret *= hdl->c.dl.basepos; ret /= (hdl->prmcnt - hdl->c.dl.dispmax); return(ret); } static void dlglist_drawbar(DLGHDL hdl) { RECT_T rct; rct.right = hdl->vram->width; rct.left = rct.right - MENUDLG_CXVSCR; rct.top = MENUDLG_CYVSCR; rct.bottom = hdl->vram->height - MENUDLG_CYVSCR; vram_filldat(hdl->vram, &rct, menucolor[MVC_SCROLLBAR]); rct.top += dlglist_barpos(hdl); rct.bottom = rct.top + hdl->c.dl.scrollbar; vram_filldat(hdl->vram, &rct, menucolor[MVC_BTNFACE]); menuvram_box2(hdl->vram, &rct, MVC4(MVC_LIGHT, MVC_DARK, MVC_HILIGHT, MVC_SHADOW)); } static BOOL dlglist_append(MENUDLG dlg, DLGHDL hdl, const void *arg) { BOOL r; DLGPRM *sto; int barsize; r = FALSE; sto = &hdl->prm; while(*sto) { sto = &((*sto)->next); } *sto = resappend(dlg, (OEMCHAR *)arg); if (*sto) { r = dlglist_drawsub(hdl, hdl->prmcnt, FALSE); hdl->prmcnt++; if (hdl->prmcnt > hdl->c.dl.dispmax) { barsize = hdl->vram->height - (MENUDLG_CYVSCR * 2); if (barsize >= 8) { barsize *= hdl->c.dl.dispmax; barsize /= hdl->prmcnt; barsize = max(barsize, 6); if (!hdl->c.dl.scrollbar) { dlglist_drawall(hdl); dlglist_setbtn(hdl, 0); dlglist_setbtn(hdl, 2); } hdl->c.dl.scrollbar = barsize; dlglist_drawbar(hdl); } } } return(r); } static BOOL dlglist_setex(MENUDLG dlg, DLGHDL hdl, const ITEMEXPRM *arg) { DLGPRM dp; UINT cnt; if ((arg == NULL) || (arg->pos >= hdl->prmcnt)) { return(FALSE); } cnt = arg->pos; dp = hdl->prm; while((cnt) && (dp)) { cnt--; dp = dp->next; } if (dp == NULL) { return(FALSE); } resattachicon(dlg, dp, arg->icon, hdl->c.dl.fontsize, hdl->c.dl.fontsize); milstr_ncpy(dp->str, arg->str, NELEMENTS(dp->str)); return(dlglist_drawsub(hdl, arg->pos, (arg->pos == hdl->val))); } static int dlglist_getpos(DLGHDL hdl, int y) { int val; val = (y / hdl->c.dl.fontsize) + hdl->c.dl.basepos; if ((unsigned int)val < (unsigned int)hdl->prmcnt) { return(val); } else { return(-1); } } enum { DLCUR_OUT = -1, DLCUR_INLIST = 0, DLCUR_UP = 1, DLCUR_INBAR = 2, DLCUR_DOWN = 3, DLCUR_PGUP = 4, DLCUR_PGDN = 5, DLCUR_INCUR = 6 }; static int dlglist_getpc(DLGHDL hdl, int x, int y) { if ((unsigned int)x >= (unsigned int)hdl->vram->width) { goto dlgp_out; } if ((unsigned int)y >= (unsigned int)hdl->vram->height) { goto dlgp_out; } if ((hdl->prmcnt < hdl->c.dl.dispmax) || (x < (hdl->vram->width - MENUDLG_CXVSCR))) { return(DLCUR_INLIST); } else if (y < MENUDLG_CYVSCR) { return(DLCUR_UP); } else if (y >= (hdl->vram->height - MENUDLG_CYVSCR)) { return(DLCUR_DOWN); } y -= MENUDLG_CYVSCR; y -= dlglist_barpos(hdl); if (y < 0) { return(DLCUR_PGUP); } else if (y < (int)hdl->c.dl.scrollbar) { return(DLCUR_INBAR); } else { return(DLCUR_PGDN); } dlgp_out: return(DLCUR_OUT); } static void dlglist_setval(MENUDLG dlg, DLGHDL hdl, int val) { BOOL r; if ((unsigned int)val >= (unsigned int)hdl->prmcnt) { val = -1; } if (val != hdl->val) { r = dlglist_drawsub(hdl, hdl->val, FALSE); r |= dlglist_drawsub(hdl, val, TRUE); hdl->val = val; if (r) { drawctrls(dlg, hdl); } } } static void dlglist_setbasepos(MENUDLG dlg, DLGHDL hdl, int pos) { int displimit; if (pos < 0) { pos = 0; } else { displimit = hdl->prmcnt - hdl->c.dl.dispmax; if (displimit < 0) { displimit = 0; } if (pos > displimit) { pos = displimit; } } if (hdl->c.dl.basepos != pos) { hdl->c.dl.basepos = pos; dlglist_drawall(hdl); dlglist_drawbar(hdl); } (void)dlg; } static void dlglist_onclick(MENUDLG dlg, DLGHDL hdl, int x, int y) { int flg; int val; x -= (MENU_LINE * 2); y -= (MENU_LINE * 2); flg = dlglist_getpc(hdl, x, y); dlg->dragflg = flg; switch(flg) { case DLCUR_INLIST: val = dlglist_getpos(hdl, y); if ((val == hdl->val) && (val != -1)) { dlg->dragflg = DLCUR_INCUR; } dlglist_setval(dlg, hdl, val); dlg->proc(DLGMSG_COMMAND, hdl->id, 0); break; case 1: case 3: dlglist_setbtn(hdl, flg); dlglist_setbasepos(dlg, hdl, hdl->c.dl.basepos + flg - 2); drawctrls(dlg, hdl); break; case DLCUR_INBAR: y -= MENUDLG_CYVSCR; y -= dlglist_barpos(hdl); if ((unsigned int)y < (unsigned int)hdl->c.dl.scrollbar) { dlg->lasty = y; } else { dlg->lasty = -1; } break; case DLCUR_PGUP: dlglist_setbasepos(dlg, hdl, hdl->c.dl.basepos - hdl->c.dl.dispmax); drawctrls(dlg, hdl); break; case DLCUR_PGDN: dlglist_setbasepos(dlg, hdl, hdl->c.dl.basepos + hdl->c.dl.dispmax); drawctrls(dlg, hdl); break; } } static void dlglist_move(MENUDLG dlg, DLGHDL hdl, int x, int y, int focus) { int flg; int val; int height; x -= (MENU_LINE * 2); y -= (MENU_LINE * 2); flg = dlglist_getpc(hdl, x, y); switch(dlg->dragflg) { case DLCUR_INLIST: case DLCUR_INCUR: if (flg == DLCUR_INLIST) { val = dlglist_getpos(hdl, y); if (val != hdl->val) { dlg->dragflg = DLCUR_INLIST; dlglist_setval(dlg, hdl, val); dlg->proc(DLGMSG_COMMAND, hdl->id, 0); } } break; case 1: case 3: dlglist_setbtn(hdl, dlg->dragflg - ((dlg->dragflg == flg)?0:1)); drawctrls(dlg, hdl); break; case DLCUR_INBAR: if (dlg->lasty >= 0) { y -= MENUDLG_CYVSCR; y -= dlg->lasty; height = hdl->vram->height - (MENUDLG_CYVSCR * 2); height -= hdl->c.dl.scrollbar; if (y < 0) { y = 0; } else if (y > height) { y = height; } y *= (hdl->prmcnt - hdl->c.dl.dispmax); y /= height; dlglist_setbasepos(dlg, hdl, y); drawctrls(dlg, hdl); } break; } (void)focus; } static void dlglist_rel(MENUDLG dlg, DLGHDL hdl, int focus) { switch(dlg->dragflg) { case 1: case 3: dlglist_setbtn(hdl, dlg->dragflg - 1); drawctrls(dlg, hdl); break; case DLCUR_INCUR: dlg->proc(DLGMSG_COMMAND, hdl->id, 1); break; } (void)focus; } // ---- slider static void dlgslider_setflag(DLGHDL hdl) { int size; UINT type; if (!(hdl->flag & MSS_VERT)) { size = hdl->rect.bottom - hdl->rect.top; } else { size = hdl->rect.right - hdl->rect.left; } if (size < 13) { type = 0 + (9 << 8) + (5 << 16); } else if (size < 21) { type = 1 + (13 << 8) + (7 << 16); } else { type = 2 + (21 << 8) + (11 << 16); } hdl->c.ds.type = (UINT8)type; if (!(hdl->flag & MSS_VERT)) { hdl->c.ds.sldh = (UINT8)(type >> 16); hdl->c.ds.sldv = (UINT8)(type >> 8); } else { hdl->c.ds.sldh = (UINT8)(type >> 8); hdl->c.ds.sldv = (UINT8)(type >> 16); } } static int dlgslider_setpos(DLGHDL hdl, int val) { int range; int width; int dir; range = hdl->c.ds.maxval - hdl->c.ds.minval; if (range) { dir = (range > 0)?1:-1; val -= hdl->c.ds.minval; val *= dir; range *= dir; if (val < 0) { val = 0; } else if (val >= range) { val = range; } hdl->val = hdl->c.ds.minval + (val * dir); if (!(hdl->flag & MSS_VERT)) { width = hdl->rect.right - hdl->rect.left; width -= hdl->c.ds.sldh; } else { width = hdl->rect.bottom - hdl->rect.top; width -= hdl->c.ds.sldv; } if ((width > 0) || (range)) { val *= width; val /= range; } else { val = 0; } } else { val = 0; } return(val); } static BRESULT dlgslider_create(MENUDLG dlg, DLGHDL hdl, const void *arg) { hdl->c.ds.minval = (SINT16)(long)arg; hdl->c.ds.maxval = (SINT16)((long)arg >> 16); hdl->c.ds.moving = 0; dlgslider_setflag(hdl); hdl->c.ds.pos = dlgslider_setpos(hdl, 0); (void)dlg; return(SUCCESS); } static void dlgslider_paint(MENUDLG dlg, DLGHDL hdl) { UINT flag; int ptr; RECT_U rct; POINT_T pt; MENURES2 src; flag = hdl->flag; switch(flag & MSS_POSMASK) { case MSS_BOTH: ptr = 1; break; case MSS_TOP: ptr = 2; break; default: ptr = 0; break; } vram_filldat(dlg->vram, &hdl->rect, menucolor[MVC_STATIC]); if (!(hdl->flag & MSS_VERT)) { rct.r.left = hdl->rect.left; rct.r.right = hdl->rect.right; rct.r.top = hdl->rect.top + ptr + (hdl->c.ds.sldv / 2) - (MENU_LINE * 2); rct.r.bottom = rct.r.top + (MENU_LINE * 4); menuvram_box2(dlg->vram, &rct.r, MVC4(MVC_SHADOW, MVC_HILIGHT, MVC_DARK, MVC_LIGHT)); pt.x = hdl->rect.left + hdl->c.ds.pos; pt.y = hdl->rect.top; } else { rct.r.left = hdl->rect.left + ptr + (hdl->c.ds.sldh / 2) - (MENU_LINE * 2); rct.r.right = rct.r.left + (MENU_LINE * 4); rct.r.top = hdl->rect.top; rct.r.bottom = hdl->rect.bottom; menuvram_box2(dlg->vram, &rct.r, MVC4(MVC_SHADOW, MVC_HILIGHT, MVC_DARK, MVC_LIGHT)); pt.x = hdl->rect.left; pt.y = hdl->rect.top + hdl->c.ds.pos; ptr += 3; } ptr *= 2; if ((hdl->flag & MENU_GRAY) || (hdl->c.ds.moving)) { ptr++; } src.width = hdl->c.ds.sldh; src.height = hdl->c.ds.sldv; src.pat = menures_slddat + menures_sldpos[hdl->c.ds.type][ptr]; menuvram_res2put(dlg->vram, &src, &pt); } static void dlgslider_setval(MENUDLG dlg, DLGHDL hdl, int val) { int pos; pos = dlgslider_setpos(hdl, val); if (hdl->c.ds.pos != pos) { hdl->c.ds.pos = pos; drawctrls(dlg, hdl); } } static void dlgslider_onclick(MENUDLG dlg, DLGHDL hdl, int x, int y) { int width; int range; int dir; if (!(hdl->flag & MSS_VERT)) { width = hdl->c.ds.sldh; } else { width = hdl->c.ds.sldv; x = y; } x -= hdl->c.ds.pos; if ((x >= -1) && (x <= width)) { dlg->dragflg = x; hdl->c.ds.moving = 1; drawctrls(dlg, hdl); } else { dlg->dragflg = -1; dir = (x > 0)?1:0; range = hdl->c.ds.maxval - hdl->c.ds.minval; if (range < 0) { range = 0 - range; dir ^= 1; } if (range < 16) { range = 16; } range >>= 4; if (!dir) { range = 0 - range; } dlgslider_setval(dlg, hdl, hdl->val + range); dlg->proc(DLGMSG_COMMAND, hdl->id, 0); } } static void dlgslider_move(MENUDLG dlg, DLGHDL hdl, int x, int y, int focus) { int range; int width; int dir; if (hdl->c.ds.moving) { range = hdl->c.ds.maxval - hdl->c.ds.minval; if (range) { dir = (range > 0)?1:-1; range *= dir; if (!(hdl->flag & MSS_VERT)) { width = hdl->rect.right - hdl->rect.left; width -= hdl->c.ds.sldh; } else { width = hdl->rect.bottom - hdl->rect.top; width -= hdl->c.ds.sldv; x = y; } x -= dlg->dragflg; if ((x < 0) || (width <= 0)) { x = 0; } else if (x >= width) { x = range; } else { x *= range; x += (width >> 1); x /= width; } x = hdl->c.ds.minval + (x * dir); dlgslider_setval(dlg, hdl, x); dlg->proc(DLGMSG_COMMAND, hdl->id, 0); } } (void)focus; } static void dlgslider_rel(MENUDLG dlg, DLGHDL hdl, int focus) { if (hdl->c.ds.moving) { hdl->c.ds.moving = 0; drawctrls(dlg, hdl); } (void)focus; } // ---- tablist static void *dlgtablist_setfont(DLGHDL hdl, void *font) { void *ret; POINT_T pt; DLGPRM prm; ret = hdl->c.dtl.font; hdl->c.dtl.font = font; fontmng_getsize(font, mstr_fontcheck, &pt); if ((pt.y <= 0) || (pt.y >= 65536)) { pt.y = 16; } hdl->c.dtl.fontsize = pt.y; prm = hdl->prm; while(prm) { fontmng_getsize(hdl->c.dtl.font, prm->str, &pt); prm->width = pt.x; prm = prm->next; } return(ret); } static BRESULT dlgtablist_create(MENUDLG dlg, DLGHDL hdl, const void *arg) { RECT_T rct; rct.right = hdl->rect.right - hdl->rect.left; hdl->val = -1; dlgtablist_setfont(hdl, dlg->font); (void)arg; return(SUCCESS); } static void dlgtablist_paint(MENUDLG dlg, DLGHDL hdl) { VRAMHDL dst; DLGPRM prm; POINT_T pt; RECT_T rct; int posx; int lx; int cnt; int tabey; int tabdy; dst = dlg->vram; rct = hdl->rect; vram_filldat(dst, &rct, menucolor[MVC_STATIC]); tabey = rct.top + hdl->c.dtl.fontsize + MENUDLG_SYTAB + MENUDLG_TYTAB + MENUDLG_EYTAB; rct.top = tabey; menuvram_box2(dst, &rct, MVC4(MVC_HILIGHT, MVC_DARK, MVC_LIGHT, MVC_SHADOW)); posx = hdl->rect.left + (MENU_LINE * 2); prm = hdl->prm; cnt = hdl->val; while(prm) { if (cnt) { pt.x = posx; pt.y = hdl->rect.top + MENUDLG_SYTAB; menuvram_liney(dst, pt.x, pt.y + (MENU_LINE * 2), tabey, MVC_HILIGHT); pt.x += MENU_LINE; menuvram_liney(dst, pt.x, pt.y + MENU_LINE, pt.y + (MENU_LINE * 2), MVC_HILIGHT); menuvram_liney(dst, pt.x, pt.y + (MENU_LINE * 2), tabey, MVC_LIGHT); pt.x += MENU_LINE; lx = pt.x + prm->width + (MENUDLG_TXTAB * 2); menuvram_linex(dst, pt.x, pt.y, lx, MVC_HILIGHT); menuvram_linex(dst, pt.x, pt.y + MENU_LINE, lx, MVC_LIGHT); menuvram_liney(dst, lx, pt.y + MENU_LINE, pt.y + (MENU_LINE * 2), MVC_DARK); menuvram_liney(dst, lx, pt.y + (MENU_LINE * 2), tabey, MVC_SHADOW); lx++; menuvram_liney(dst, lx, pt.y + (MENU_LINE * 2), tabey, MVC_DARK); pt.x += MENUDLG_TXTAB; pt.y += MENUDLG_TYTAB; vrammix_text(dst, hdl->c.dtl.font, prm->str, menucolor[MVC_TEXT], &pt, NULL); } cnt--; posx += prm->width + (MENU_LINE * 4) + (MENUDLG_TXTAB) * 2; prm = prm->next; } posx = hdl->rect.left; prm = hdl->prm; cnt = hdl->val; while(prm) { if (!cnt) { pt.x = posx; pt.y = hdl->rect.top; if (posx == hdl->rect.left) { tabdy = tabey + 2; } else { tabdy = tabey + 1; menuvram_linex(dst, pt.x, tabdy, pt.x + (MENU_LINE * 2), MVC_STATIC); } menuvram_liney(dst, pt.x, pt.y + (MENU_LINE * 2), tabdy, MVC_HILIGHT); pt.x += MENU_LINE; menuvram_liney(dst, pt.x, pt.y + MENU_LINE, pt.y + (MENU_LINE * 2), MVC_HILIGHT); menuvram_liney(dst, pt.x, pt.y + (MENU_LINE * 2), tabdy, MVC_LIGHT); pt.x += MENU_LINE; lx = pt.x + prm->width + (MENU_LINE * 4) + (MENUDLG_TXTAB * 2); menuvram_linex(dst, pt.x, pt.y, lx, MVC_HILIGHT); menuvram_linex(dst, pt.x, pt.y + MENU_LINE, lx, MVC_LIGHT); menuvram_linex(dst, pt.x, tabey, lx, MVC_STATIC); menuvram_linex(dst, pt.x, tabey + MENU_LINE, lx, MVC_STATIC); tabdy = tabey + 1; menuvram_liney(dst, lx, pt.y + MENU_LINE, pt.y + (MENU_LINE * 2), MVC_DARK); menuvram_liney(dst, lx, pt.y + (MENU_LINE * 2), tabdy, MVC_SHADOW); lx++; menuvram_liney(dst, lx, pt.y + (MENU_LINE * 2), tabdy, MVC_DARK); pt.x += MENUDLG_TXTAB + (MENU_LINE * 2); pt.y += MENUDLG_TYTAB; vrammix_text(dst, hdl->c.dtl.font, prm->str, menucolor[MVC_TEXT], &pt, NULL); break; } cnt--; posx += prm->width + (MENU_LINE * 4) + (MENUDLG_TXTAB * 2); prm = prm->next; } } static void dlgtablist_setval(MENUDLG dlg, DLGHDL hdl, int val) { if (hdl->val != val) { hdl->val = val; drawctrls(dlg, hdl); } } static void dlgtablist_append(MENUDLG dlg, DLGHDL hdl, const void *arg) { DLGPRM res; DLGPRM *sto; POINT_T pt; sto = &hdl->prm; while(*sto) { sto = &((*sto)->next); } res = resappend(dlg, (OEMCHAR *)arg); if (res) { *sto = res; fontmng_getsize(hdl->c.dtl.font, (OEMCHAR *)arg, &pt); res->width = pt.x; hdl->prmcnt++; } } static void dlgtablist_onclick(MENUDLG dlg, DLGHDL hdl, int x, int y) { DLGPRM prm; int pos; if (y < (hdl->c.dtl.fontsize + MENUDLG_SYTAB + MENUDLG_TYTAB + MENUDLG_EYTAB)) { pos = 0; prm = hdl->prm; while(prm) { x -= (MENU_LINE * 4); if (x < 0) { break; } x -= prm->width + (MENUDLG_TXTAB * 2); if (x < 0) { dlgtablist_setval(dlg, hdl, pos); dlg->proc(DLGMSG_COMMAND, hdl->id, 0); break; } pos++; prm = prm->next; } } } // ---- edit static void dlgedit_paint(MENUDLG dlg, DLGHDL hdl) { RECT_T rct; POINT_T pt; const OEMCHAR *string; rct = hdl->rect; menuvram_box2(dlg->vram, &rct, MVC4(MVC_SHADOW, MVC_HILIGHT, MVC_DARK, MVC_LIGHT)); rct.left += (MENU_LINE * 2); rct.top += (MENU_LINE * 2); rct.right -= (MENU_LINE * 2); rct.bottom -= (MENU_LINE * 2); vram_filldat(dlg->vram, &rct, menucolor[ (hdl->flag & MENU_GRAY)?MVC_STATIC:MVC_HILIGHT]); if (hdl->prm == NULL) { goto dged_exit; } string = hdl->prm->str; if (string == NULL) { goto dged_exit; } pt.x = rct.left + MENU_LINE; pt.y = rct.top + MENU_LINE; vrammix_text(dlg->vram, hdl->c.dt.font, string, menucolor[MVC_TEXT], &pt, &rct); dged_exit: return; } // ---- frame static void dlgframe_paint(MENUDLG dlg, DLGHDL hdl) { RECT_T rct; POINT_T pt; rct.left = hdl->rect.left; rct.top = hdl->rect.top + MENUDLG_SYFRAME; rct.right = hdl->rect.right; rct.bottom = hdl->rect.bottom; menuvram_box2(dlg->vram, &rct, MVC4(MVC_SHADOW, MVC_HILIGHT, MVC_HILIGHT, MVC_SHADOW)); rct.left += MENUDLG_SXFRAME; rct.top = hdl->rect.top; rct.right = rct.left + (MENUDLG_PXFRAME * 2) + hdl->c.dt.pt.x; rct.bottom = rct.top + hdl->c.dt.pt.y + MENU_DSTEXT; vram_filldat(dlg->vram, &rct, menucolor[MVC_STATIC]); if (hdl->prm) { pt.x = rct.left + MENUDLG_PXFRAME; pt.y = rct.top; dlg_text(dlg, hdl, &pt, &rct); } } // ---- radio typedef struct { MENUDLG dlg; MENUID group; } MDCB1; static void dlgradio_paint(MENUDLG dlg, DLGHDL hdl) { POINT_T pt; const MENURES2 *src; int pat; vram_filldat(dlg->vram, &hdl->rect, menucolor[MVC_STATIC]); pt.x = hdl->rect.left; pt.y = hdl->rect.top; src = menures_radio; pat = (hdl->flag & MENU_GRAY)?1:0; menuvram_res2put(dlg->vram, src + pat, &pt); if (hdl->val) { menuvram_res3put(dlg->vram, src + 2, &pt, (hdl->flag & MENU_GRAY)?MVC_GRAYTEXT1:MVC_TEXT); } pt.x += MENUDLG_SXRADIO; dlg_text(dlg, hdl, &pt, &hdl->rect); } static BOOL drsv_cb(void *vpItem, void *vpArg) { DLGHDL item; item = (DLGHDL)vpItem; if ((item->type == DLGTYPE_RADIO) && (item->val) && (item->group == ((MDCB1 *)vpArg)->group)) { item->val = 0; drawctrls(((MDCB1 *)vpArg)->dlg, item); } return(FALSE); } static void dlgradio_setval(MENUDLG dlg, DLGHDL hdl, int val) { MDCB1 mdcb; if (hdl->val != val) { if (val) { mdcb.dlg = dlg; mdcb.group = hdl->group; listarray_enum(dlg->dlg, drsv_cb, &mdcb); } hdl->val = val; drawctrls(dlg, hdl); } } static void dlgradio_onclick(MENUDLG dlg, DLGHDL hdl, int x, int y) { if (x < (hdl->c.dt.pt.x + MENUDLG_SXRADIO)) { dlgradio_setval(dlg, hdl, 1); dlg->proc(DLGMSG_COMMAND, hdl->id, 0); } (void)y; } // ---- check static void dlgcheck_paint(MENUDLG dlg, DLGHDL hdl) { POINT_T pt; RECT_T rct; UINT32 basecol; UINT32 txtcol; vram_filldat(dlg->vram, &hdl->rect, menucolor[MVC_STATIC]); rct.left = hdl->rect.left; rct.top = hdl->rect.top; rct.right = rct.left + MENUDLG_CXCHECK; rct.bottom = rct.top + MENUDLG_CYCHECK; if (!(hdl->flag & MENU_GRAY)) { basecol = MVC_HILIGHT; txtcol = MVC_TEXT; } else { basecol = MVC_STATIC; txtcol = MVC_GRAYTEXT1; } vram_filldat(dlg->vram, &rct, menucolor[basecol]); menuvram_box2(dlg->vram, &rct, MVC4(MVC_SHADOW, MVC_HILIGHT, MVC_DARK, MVC_LIGHT)); if (hdl->val) { pt.x = rct.left + (MENU_LINE * 2); pt.y = rct.top + (MENU_LINE * 2); menuvram_res3put(dlg->vram, &menures_check, &pt, txtcol); } pt.x = rct.left + MENUDLG_SXCHECK; pt.y = rct.top; dlg_text(dlg, hdl, &pt, &hdl->rect); } static void dlgcheck_setval(MENUDLG dlg, DLGHDL hdl, int val) { if (hdl->val != val) { hdl->val = val; drawctrls(dlg, hdl); } } static void dlgcheck_onclick(MENUDLG dlg, DLGHDL hdl, int x, int y) { if (x < (hdl->c.dt.pt.x + MENUDLG_SXCHECK)) { dlgcheck_setval(dlg, hdl, !hdl->val); dlg->proc(DLGMSG_COMMAND, hdl->id, 0); } (void)y; } // ---- text static void dlgtext_paint(MENUDLG dlg, DLGHDL hdl) { POINT_T sz; POINT_T pt; void (*getpt)(POINT_T *pt, const RECT_T *rect, const POINT_T *sz); vram_filldat(dlg->vram, &hdl->rect, menucolor[MVC_STATIC]); if (gettextsz(hdl, &sz) == SUCCESS) { switch(hdl->flag & MST_POSMASK) { case MST_LEFT: default: getpt = getleft; break; case MST_CENTER: getpt = getcenter; break; case MST_RIGHT: getpt = getright; break; } getpt(&pt, &hdl->rect, &sz); dlg_text(dlg, hdl, &pt, &hdl->rect); } } static void dlgtext_itemset(MENUDLG dlg, DLGHDL hdl, const void *arg) { const OEMCHAR *str; if (hdl->prm) { str = (OEMCHAR *)arg; if (str == NULL) { str = str_null; } milstr_ncpy(hdl->prm->str, str, NELEMENTS(hdl->prm->str)); fontmng_getsize(hdl->c.dt.font, str, &hdl->c.dt.pt); } (void)dlg; } static void dlgtext_iconset(MENUDLG dlg, DLGHDL hdl, const void *arg) { if (hdl->prm) { resattachicon(dlg, hdl->prm, (UINT16)(long)arg, hdl->c.dt.pt.y, hdl->c.dt.pt.y); } (void)dlg; } // ---- icon/vram static void iconpaint(MENUDLG dlg, DLGHDL hdl, VRAMHDL src) { RECT_U r; UINT32 bgcol; r.p.x = hdl->rect.left; r.p.y = hdl->rect.top; bgcol = menucolor[MVC_STATIC]; if (src) { if (src->alpha) { r.r.right = r.r.left + src->width; r.r.bottom = r.r.top + src->height; vram_filldat(dlg->vram, &r.r, bgcol); vramcpy_cpyex(dlg->vram, &r.p, src, NULL); } else { vramcpy_cpy(dlg->vram, &r.p, src, NULL); } } else { vram_filldat(dlg->vram, &hdl->rect, bgcol); } } static BRESULT dlgicon_create(MENUDLG dlg, DLGHDL hdl, const void *arg) { hdl->prm = resappend(dlg, NULL); resattachicon(dlg, hdl->prm, (UINT16)(long)arg, hdl->rect.right - hdl->rect.left, hdl->rect.bottom - hdl->rect.top); return(SUCCESS); } static void dlgicon_paint(MENUDLG dlg, DLGHDL hdl) { DLGPRM prm; prm = hdl->prm; if (prm) { iconpaint(dlg, hdl, prm->icon); } } static BRESULT dlgvram_create(MENUDLG dlg, DLGHDL hdl, const void *arg) { hdl->c.dv.vram = (VRAMHDL)arg; (void)dlg; return(SUCCESS); } static void dlgvram_paint(MENUDLG dlg, DLGHDL hdl) { iconpaint(dlg, hdl, hdl->c.dv.vram); } // ---- line static void dlgline_paint(MENUDLG dlg, DLGHDL hdl) { if (!(hdl->flag & MSL_VERT)) { menuvram_linex(dlg->vram, hdl->rect.left, hdl->rect.top, hdl->rect.right, MVC_SHADOW); menuvram_linex(dlg->vram, hdl->rect.left, hdl->rect.top + MENU_LINE, hdl->rect.right, MVC_HILIGHT); } else { menuvram_liney(dlg->vram, hdl->rect.left, hdl->rect.top, hdl->rect.bottom, MVC_SHADOW); menuvram_liney(dlg->vram, hdl->rect.left+MENU_LINE, hdl->rect.top, hdl->rect.bottom, MVC_HILIGHT); } } // ---- box static void dlgbox_paint(MENUDLG dlg, DLGHDL hdl) { menuvram_box2(dlg->vram, &hdl->rect, MVC4(MVC_SHADOW, MVC_HILIGHT, MVC_HILIGHT, MVC_SHADOW)); } // ---- procs static BRESULT _cre(MENUDLG dlg, DLGHDL hdl, const void *arg) { (void)dlg; (void)hdl; (void)arg; return(SUCCESS); } #if 0 // not used static void _paint(MENUDLG dlg, DLGHDL hdl) { (void)dlg; (void)hdl; } #endif #if 0 // not used static void _onclick(MENUDLG dlg, DLGHDL hdl, int x, int y) { (void)dlg; (void)hdl; (void)x; (void)y; } #endif static void _setval(MENUDLG dlg, DLGHDL hdl, int val) { (void)dlg; (void)hdl; (void)val; } static void _moverel(MENUDLG dlg, DLGHDL hdl, int focus) { (void)dlg; (void)hdl; (void)focus; } typedef BRESULT (*DLGCRE)(MENUDLG dlg, DLGHDL hdl, const void *arg); typedef void (*DLGPAINT)(MENUDLG dlg, DLGHDL hdl); typedef void (*DLGSETVAL)(MENUDLG dlg, DLGHDL hdl, int val); typedef void (*DLGCLICK)(MENUDLG dlg, DLGHDL hdl, int x, int y); typedef void (*DLGMOV)(MENUDLG dlg, DLGHDL hdl, int x, int y, int focus); typedef void (*DLGREL)(MENUDLG dlg, DLGHDL hdl, int focus); static const DLGCRE dlgcre[] = { dlgbase_create, // DLGTYPE_BASE _cre, // DLGTYPE_CLOSE _cre_settext, // DLGTYPE_BUTTON dlglist_create, // DLGTYPE_LIST dlgslider_create, // DLGTYPE_SLIDER dlgtablist_create, // DLGTYPE_TABLIST _cre_settext, // DLGTYPE_RADIO _cre_settext, // DLGTYPE_CHECK _cre_settext, // DLGTYPE_FRAME _cre_settext, // DLGTYPE_EDIT _cre_settext, // DLGTYPE_TEXT dlgicon_create, // DLGTYPE_ICON dlgvram_create, // DLGTYPE_VRAM _cre, // DLGTYPE_LINE _cre // DLGTYPE_BOX }; static const DLGPAINT dlgpaint[] = { dlgbase_paint, // DLGTYPE_BASE dlgclose_paint, // DLGTYPE_CLOSE dlgbtn_paint, // DLGTYPE_BUTTON dlglist_paint, // DLGTYPE_LIST dlgslider_paint, // DLGTYPE_SLIDER dlgtablist_paint, // DLGTYPE_TABLIST dlgradio_paint, // DLGTYPE_RADIO dlgcheck_paint, // DLGTYPE_CHECK dlgframe_paint, // DLGTYPE_FRAME dlgedit_paint, // DLGTYPE_EDIT dlgtext_paint, // DLGTYPE_TEXT dlgicon_paint, // DLGTYPE_ICON dlgvram_paint, // DLGTYPE_VRAM dlgline_paint, // DLGTYPE_LINE dlgbox_paint // DLGTYPE_BOX }; static const DLGSETVAL dlgsetval[] = { _setval, // DLGTYPE_BASE _setval, // DLGTYPE_CLOSE _setval, // DLGTYPE_BUTTON dlglist_setval, // DLGTYPE_LIST dlgslider_setval, // DLGTYPE_SLIDER dlgtablist_setval, // DLGTYPE_TABLIST dlgradio_setval, // DLGTYPE_RADIO dlgcheck_setval // DLGTYPE_CHECK }; static const DLGCLICK dlgclick[] = { dlgbase_onclick, // DLGTYPE_BASE dlgclose_onclick, // DLGTYPE_CLOSE dlgbtn_onclick, // DLGTYPE_BUTTON dlglist_onclick, // DLGTYPE_LIST dlgslider_onclick, // DLGTYPE_SLIDER dlgtablist_onclick, // DLGTYPE_TABLIST dlgradio_onclick, // DLGTYPE_RADIO dlgcheck_onclick // DLGTYPE_CHECK }; static const DLGMOV dlgmov[] = { dlgbase_move, // DLGTYPE_BASE dlgclose_move, // DLGTYPE_CLOSE dlgbtn_move, // DLGTYPE_BUTTON dlglist_move, // DLGTYPE_LIST dlgslider_move // DLGTYPE_SLIDER }; static const DLGREL dlgrel[] = { _moverel, // DLGTYPE_BASE dlgclose_rel, // DLGTYPE_CLOSE dlgbtn_rel, // DLGTYPE_BUTTON dlglist_rel, // DLGTYPE_LIST dlgslider_rel // DLGTYPE_SLIDER }; // ---- draw static void draw(VRAMHDL dst, const RECT_T *rect, void *arg) { MENUDLG dlg; dlg = (MENUDLG)arg; vrammix_cpy2(dst, rect, dlg->vram, NULL, 2); } typedef struct { MENUDLG dlg; DLGHDL hdl; RECT_T rect; } MDCB2; static BOOL dc_cb(void *vpItem, void *vpArg) { DLGHDL hdl; MDCB2 *mdcb; hdl = (DLGHDL)vpItem; mdcb = (MDCB2 *)vpArg; if (hdl == mdcb->hdl) { mdcb->hdl = NULL; } if ((mdcb->hdl != NULL) || (hdl->flag & MENU_DISABLE)) { goto dccb_exit; } if (rect_isoverlap(&mdcb->rect, &hdl->rect)) { hdl->flag |= MENU_REDRAW; } dccb_exit: return(FALSE); } static BOOL dc_cb2(void *vpItem, void *vpArg) { MENUDLG dlg; DLGHDL hdl; hdl = (DLGHDL)vpItem; dlg = (MENUDLG)vpArg; if (hdl->flag & MENU_REDRAW) { hdl->flag &= ~MENU_REDRAW; if ((!(hdl->flag & MENU_DISABLE)) && ((UINT)hdl->type < NELEMENTS(dlgpaint))) { dlgpaint[hdl->type](dlg, hdl); menubase_setrect(dlg->vram, &hdl->rect); } } return(FALSE); } static void drawctrls(MENUDLG dlg, DLGHDL hdl) { MDCB2 mdcb; if (hdl) { if (hdl->flag & MENU_DISABLE) { goto dcs_end; } mdcb.rect = hdl->rect; } else { mdcb.rect.left = 0; mdcb.rect.top = 0; mdcb.rect.right = dlg->vram->width; mdcb.rect.bottom = dlg->vram->height; } mdcb.dlg = dlg; mdcb.hdl = hdl; listarray_enum(dlg->dlg, dc_cb, &mdcb); if (!dlg->locked) { listarray_enum(dlg->dlg, dc_cb2, dlg); menubase_draw(draw, dlg); } dcs_end: return; } static void drawlock(BOOL lock) { MENUDLG dlg; dlg = &menudlg; if (lock) { dlg->locked++; } else { dlg->locked--; if (!dlg->locked) { listarray_enum(dlg->dlg, dc_cb2, dlg); menubase_draw(draw, dlg); } } } // ---- static int defproc(int msg, MENUID id, long param) { if (msg == DLGMSG_CLOSE) { menubase_close(); } (void)id; (void)param; return(0); } BRESULT menudlg_create(int width, int height, const OEMCHAR *str, int (*proc)(int msg, MENUID id, long param)) { MENUBASE *mb; MENUDLG dlg; dlg = &menudlg; if (menubase_open(2) != SUCCESS) { goto mdcre_err; } ZeroMemory(dlg, sizeof(_MENUDLG)); if ((width <= 0) || (height <= 0)) { goto mdcre_err; } width += (MENU_FBORDER + MENU_BORDER) * 2; height += ((MENU_FBORDER + MENU_BORDER) * 2) + MENUDLG_CYCAPTION + MENUDLG_BORDER; mb = &menubase; dlg->font = mb->font; dlg->vram = vram_create(width, height, FALSE, mb->bpp); if (dlg->vram == NULL) { goto mdcre_err; } dlg->vram->posx = (mb->width - width) >> 1; dlg->vram->posy = (mb->height - height) >> 1; dlg->dlg = listarray_new(sizeof(_DLGHDL), 32); if (dlg->dlg == NULL) { goto mdcre_err; } dlg->res = listarray_new(sizeof(_DLGPRM), 32); if (dlg->res == NULL) { goto mdcre_err; } if (menudlg_append(DLGTYPE_BASE, SID_CAPTION, 0, str, 0, 0, width, height) != SUCCESS) { goto mdcre_err; } if (menudlg_append(DLGTYPE_CLOSE, SID_CLOSE, 0, NULL, width - (MENU_FBORDER + MENU_BORDER) - (MENUDLG_CXCLOSE + MENUDLG_PXCAPTION), (MENU_FBORDER + MENU_BORDER) + ((MENUDLG_CYCAPTION - MENUDLG_CYCLOSE) / 2), MENUDLG_CXCLOSE, MENUDLG_CYCLOSE) != SUCCESS) { goto mdcre_err; } dlg->sx = (MENU_FBORDER + MENU_BORDER); dlg->sy = (MENU_FBORDER + MENU_BORDER) + (MENUDLG_CYCAPTION + MENUDLG_BORDER); if (proc == NULL) { proc = defproc; } dlg->proc = proc; dlg->locked = 0; drawlock(TRUE); proc(DLGMSG_CREATE, 0, 0); drawctrls(dlg, NULL); drawlock(FALSE); return(SUCCESS); mdcre_err: menubase_close(); return(FAILURE); } static BOOL mdds_cb(void *vpItem, void *vpArg) { vram_destroy(((DLGHDL)vpItem)->vram); (void)vpArg; return(FALSE); } static BOOL delicon(void *vpItem, void *vpArg) { menuicon_unlock(((DLGPRM)vpItem)->icon); (void)vpArg; return(FALSE); } void menudlg_destroy(void) { MENUDLG dlg; dlg = &menudlg; if (dlg->closing) { return; } dlg->closing = 1; dlg->proc(DLGMSG_DESTROY, 0, 0); listarray_enum(dlg->dlg, mdds_cb, NULL); menubase_clrrect(dlg->vram); vram_destroy(dlg->vram); dlg->vram = NULL; listarray_destroy(dlg->dlg); dlg->dlg = NULL; listarray_enum(dlg->res, delicon, NULL); listarray_destroy(dlg->res); dlg->res = NULL; } // ---- BRESULT menudlg_appends(const MENUPRM *res, int count) { BRESULT r; r = SUCCESS; while(count--) { r |= menudlg_append(res->type, res->id, res->flg, res->arg, res->posx, res->posy, res->width, res->height); res++; } return(r); } BRESULT menudlg_append(int type, MENUID id, MENUFLG flg, const void *arg, int posx, int posy, int width, int height) { MENUDLG dlg; DLGHDL hdl; _DLGHDL dhdl; dlg = &menudlg; if (flg & MENU_TABSTOP) { dlg->group++; } switch(type) { case DLGTYPE_LTEXT: type = DLGTYPE_TEXT; flg &= ~MST_POSMASK; flg |= MST_LEFT; break; case DLGTYPE_CTEXT: type = DLGTYPE_TEXT; flg &= ~MST_POSMASK; flg |= MST_CENTER; break; case DLGTYPE_RTEXT: type = DLGTYPE_TEXT; flg &= ~MST_POSMASK; flg |= MST_RIGHT; break; } ZeroMemory(&dhdl, sizeof(dhdl)); dhdl.type = type; dhdl.id = id; dhdl.flag = flg; dhdl.page = dlg->page; dhdl.group = dlg->group; dhdl.rect.left = dlg->sx + posx; dhdl.rect.top = dlg->sy + posy; dhdl.rect.right = dhdl.rect.left + width; dhdl.rect.bottom = dhdl.rect.top + height; dhdl.prm = NULL; dhdl.prmcnt = 0; dhdl.val = 0; if (((UINT)type >= NELEMENTS(dlgcre)) || (dlgcre[type](dlg, &dhdl, arg))) { goto mda_err; } drawlock(TRUE); hdl = (DLGHDL)listarray_append(dlg->dlg, &dhdl); drawctrls(dlg, hdl); drawlock(FALSE); return(SUCCESS); mda_err: return(FAILURE); } // ---- moving typedef struct { int x; int y; DLGHDL ret; } MDCB3; static BOOL hps_cb(void *vpItem, void *vpArg) { DLGHDL hdl; MDCB3 *mdcb; hdl = (DLGHDL)vpItem; mdcb = (MDCB3 *)vpArg; if ((!(hdl->flag & (MENU_DISABLE | MENU_GRAY))) && (rect_in(&hdl->rect, mdcb->x, mdcb->y))) { mdcb->ret = hdl; } return(FALSE); } static DLGHDL hdlpossea(MENUDLG dlg, int x, int y) { MDCB3 mdcb; mdcb.x = x; mdcb.y = y; mdcb.ret = NULL; listarray_enum(dlg->dlg, hps_cb, &mdcb); return(mdcb.ret); } void menudlg_moving(int x, int y, int btn) { MENUDLG dlg; DLGHDL hdl; int focus; drawlock(TRUE); dlg = &menudlg; x -= dlg->vram->posx; y -= dlg->vram->posy; if (!dlg->btn) { if (btn == 1) { hdl = hdlpossea(dlg, x, y); if (hdl) { x -= hdl->rect.left; y -= hdl->rect.top; dlg->btn = 1; dlg->lastid = hdl->id; if ((UINT)hdl->type < NELEMENTS(dlgclick)) { dlgclick[hdl->type](dlg, hdl, x, y); } } } } else { hdl = dlghdlsea(dlg, dlg->lastid); if (hdl) { focus = rect_in(&hdl->rect, x, y); x -= hdl->rect.left; y -= hdl->rect.top; if ((UINT)hdl->type < NELEMENTS(dlgmov)) { dlgmov[hdl->type](dlg, hdl, x, y, focus); } if (btn == 2) { dlg->btn = 0; if ((UINT)hdl->type < NELEMENTS(dlgrel)) { dlgrel[hdl->type](dlg, hdl, focus); } } } } drawlock(FALSE); } // ---- ctrl void *menudlg_msg(int ctrl, MENUID id, void *arg) { void *ret; MENUDLG dlg; DLGHDL hdl; int flg; ret = NULL; dlg = &menudlg; hdl = dlghdlsea(dlg, id); if (hdl == NULL) { goto mdm_exit; } drawlock(TRUE); switch(ctrl) { case DMSG_SETHIDE: ret = (void *)((hdl->flag & MENU_DISABLE)?1:0); flg = (arg)?MENU_DISABLE:0; if ((hdl->flag ^ flg) & MENU_DISABLE) { hdl->flag ^= MENU_DISABLE; if (flg) { drawctrls(dlg, NULL); } else { drawctrls(dlg, hdl); } } break; case DMSG_GETHIDE: ret = (void *)((hdl->flag & MENU_DISABLE)?1:0); break; case DMSG_SETENABLE: ret = (void *)((hdl->flag & MENU_GRAY)?0:1); flg = (arg)?0:MENU_GRAY; if ((hdl->flag ^ flg) & MENU_GRAY) { hdl->flag ^= MENU_GRAY; drawctrls(dlg, hdl); } break; case DMSG_GETENABLE: ret = (void *)((hdl->flag & MENU_GRAY)?0:1); break; case DMSG_SETVAL: ret = (void *)hdl->val; if ((UINT)hdl->type < NELEMENTS(dlgsetval)) { dlgsetval[hdl->type](dlg, hdl, (int)arg); } break; case DMSG_GETVAL: ret = (void *)hdl->val; break; case DMSG_SETVRAM: if (hdl->type == DLGTYPE_VRAM) { ret = hdl->c.dv.vram; hdl->c.dv.vram = (VRAMHDL)arg; drawctrls(dlg, hdl); } break; case DMSG_SETTEXT: switch(hdl->type) { case DLGTYPE_BUTTON: case DLGTYPE_RADIO: case DLGTYPE_CHECK: case DLGTYPE_EDIT: case DLGTYPE_TEXT: dlgtext_itemset(dlg, hdl, arg); drawctrls(dlg, hdl); break; } break; case DMSG_SETICON: switch(hdl->type) { case DLGTYPE_BUTTON: case DLGTYPE_RADIO: case DLGTYPE_CHECK: case DLGTYPE_EDIT: case DLGTYPE_TEXT: dlgtext_iconset(dlg, hdl, arg); drawctrls(dlg, hdl); break; } break; case DMSG_ITEMAPPEND: switch(hdl->type) { case DLGTYPE_LIST: if (dlglist_append(dlg, hdl, arg)) { drawctrls(dlg, hdl); } break; case DLGTYPE_TABLIST: dlgtablist_append(dlg, hdl, arg); drawctrls(dlg, hdl); break; } break; case DMSG_ITEMRESET: if ((dlg->btn) && (dlg->lastid == hdl->id)) { dlg->btn = 0; if ((UINT)hdl->type < NELEMENTS(dlgrel)) { dlgrel[hdl->type](dlg, hdl, FALSE); } } if (hdl->type == DLGTYPE_LIST) { dlglist_reset(dlg, hdl); drawctrls(dlg, hdl); } break; case DMSG_ITEMSETEX: if (hdl->type == DLGTYPE_LIST) { if (dlglist_setex(dlg, hdl, (ITEMEXPRM *)arg)) { drawctrls(dlg, hdl); } } break; case DMSG_SETLISTPOS: if (hdl->type == DLGTYPE_LIST) { ret = (void *)(long)hdl->c.dl.basepos; dlglist_setbasepos(dlg, hdl, (int)arg); drawctrls(dlg, hdl); } break; case DMSG_GETRECT: ret = &hdl->rect; break; case DMSG_SETRECT: ret = &hdl->rect; if ((hdl->type == DLGTYPE_TEXT) && (arg)) { drawctrls(dlg, hdl); hdl->rect = *(RECT_T *)arg; drawctrls(dlg, hdl); } break; case DMSG_SETFONT: if (hdl->type == DLGTYPE_LIST) { ret = dlglist_setfont(hdl, arg); drawctrls(dlg, hdl); } else if (hdl->type == DLGTYPE_TABLIST) { ret = dlgtablist_setfont(hdl, arg); drawctrls(dlg, hdl); } else if (hdl->type == DLGTYPE_TEXT) { ret = hdl->c.dt.font; hdl->c.dt.font = arg; drawctrls(dlg, hdl); } break; case DMSG_GETFONT: if (hdl->type == DLGTYPE_LIST) { ret = hdl->c.dl.font; } else if (hdl->type == DLGTYPE_TABLIST) { ret = hdl->c.dtl.font; } else if (hdl->type == DLGTYPE_TEXT) { ret = hdl->c.dt.font; } break; } drawlock(FALSE); mdm_exit: return(ret); } // --- page void menudlg_setpage(MENUID page) { MENUDLG dlg; dlg = &menudlg; dlg->page = page; } typedef struct { MENUID page; MENUFLG flag; } MDCB4; static BOOL mddph_cb(void *vpItem, void *vpArg) { DLGHDL hdl; MDCB4 *mdcb; hdl = (DLGHDL)vpItem; mdcb = (MDCB4 *)vpArg; if ((hdl->page == mdcb->page) && ((hdl->flag ^ mdcb->flag) & MENU_DISABLE)) { hdl->flag ^= MENU_DISABLE; } return(FALSE); } void menudlg_disppagehidden(MENUID page, BOOL hidden) { MENUDLG dlg; MDCB4 mdcb; dlg = &menudlg; mdcb.page = page; mdcb.flag = (hidden)?MENU_DISABLE:0; listarray_enum(dlg->dlg, mddph_cb, &mdcb); drawlock(TRUE); drawctrls(dlg, NULL); drawlock(FALSE); }