1
0
Files
2022-09-29 17:59:04 +03:00

263 lines
5.3 KiB
C

/* Button code
*/
#ident "$Revision: 1.13 $"
#include <stand_htport.h>
#include <gfxgui.h>
#include <guicore.h>
#include <style.h>
#include <libsc.h>
#include <libsc_internal.h>
#include <pcbm/pcbm.h>
static void drawButton(struct Button *b);
void drawBitmap(unsigned short *, int, int);
/* data for "enter" arrow on default buttons */
#define default_width 14
#define default_height 12
static unsigned short default_bits[] = {
0x0400, 0x0c00, 0x1c00, 0x3c00, 0x7c00, 0xfffc, 0x7c04, 0x3c04,
0x1c04, 0x0c04, 0x0404, 0x0004};
#define defaulthl_width 6
#define defaulthl_height 6
static unsigned short defaulthl_bits[] = {
0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000};
static void
buttonEventHandler(struct gui_obj *obj, int event)
{
struct Button *b = (struct Button *)obj;
switch(event) {
case _REDRAW:
drawButton(b);
break;
case _BUTTON_UP:
if (b->cb) (*b->cb)(b,b->value); /* call callback */
break;
case _FREE:
free(b);
break;
}
return;
}
struct Button *
createButton(int x, int y, int w, int h)
{
struct Button *b;
b = (struct Button *)guimalloc(sizeof(struct Button));
b->gui.type = GBUTTON;
b->gui.flags = (_WANT_BUTTON_UP|_WANT_MOTION_RD);
b->gui.state = 0;
b->gui.x1 = x;
b->gui.y1 = y;
b->gui.x2 = x+w-1;
b->gui.y2 = y+h-1;
b->gui.eventHandler = buttonEventHandler;
b->fg = BLACK;
b->cb = 0;
b->text = 0;
b->pcbm = 0;
addObject(guiobj(b));
return(b);
}
void
addButtonText(struct Button *b, const char *c)
{
int tw = textWidth(c,BUTTONFONT) + 2*BUTTONMINMARGIN;
int width = b->gui.x2 - b->gui.x1;
b->text = c;
if (tw > width) {
/* move button x1 over so text fits */
b->gui.x1 -= (tw-width);
}
}
void
addButtonImage(struct Button *b, struct pcbm *map)
{
b->pcbm = map;
}
void
changeButtonFg(struct Button *b, int color)
{
b->fg = color;
}
/* set little "enter" arrow on button */
void
setDefaultButton(struct Button *b, int keepright)
{
int tw = b->text ? textWidth(b->text,BUTTONFONT) : 0;
int width = b->gui.x2 - b->gui.x1;
b->gui.flags |= _DEFAULT;
tw += BUTTONAMARGIN + default_width + 2*BUTTONMINMARGIN;
if (tw > width) {
int move = tw - width;
if (keepright)
b->gui.x1 -= move;
else
b->gui.x2 += move;
}
}
void
invalidateButton(struct Button *b, int on)
{
if (on) {
b->gui.flags |= _INVALID;
b->gui.flags &= ~(_WANT_MOTION_RD|_WANT_BUTTON_UP);
}
else {
b->gui.flags &= ~_INVALID;
b->gui.flags |= (_WANT_MOTION_RD|_WANT_BUTTON_UP);
}
}
void
stickButton(struct Button *b, int on)
{
if (on)
b->gui.flags |= _FORCE_PRESSED;
else
b->gui.flags &= ~_FORCE_PRESSED;
}
void
addButtonCallBack(struct Button *b,
void (*func)(struct Button *,__scunsigned_t),
__scunsigned_t value)
{
b->cb = func;
b->value = value;
}
#define NBRAMP 4 /* number of colors in button ramp */
static char bltod[] = {DarkGray, White, VeryLightGray, VeryLightGray};
static char bltod_h[] = {DarkGray, White, White, White};
static char bltod_p[] = {VeryDarkGray, DarkGray, LightGray, White};
static char bdtol[] = {VeryDarkGray, DarkGray, MediumGray, MediumGray};
static char bdtol_h[] = {VeryDarkGray, DarkGray, LightGray, LightGray};
static char bdtol_p[] = {White, White, Black, LightGray};
static char inv_ltod[] = {MediumGray,LightGray,LightGray,LightGray};
static char *ba_ltod[] = {
bltod, /* normal (neurtral) */
bltod_h, /* highlight (located) */
bltod, /* pressed (selected) */
bltod_p /* pressed highlight (loc+sel) */
};
static char *ba_dtol[] = { /* same states as above */
bdtol,
bdtol_h,
bdtol,
bdtol_p
};
static void
drawButton(struct Button *b)
{
int x1, y1, x2, y2;
register int i;
char *ltod, *dtol;
int bx, by;
int fg;
x1 = b->gui.x1; y1 = b->gui.y1;
x2 = b->gui.x2; y2 = b->gui.y2;
if ((b->gui.flags & _INVALID) == 0) {
int index = b->gui.state&0x03;
if ((b->gui.flags & _FORCE_PRESSED)) {
ltod = bltod_p;
dtol = bdtol_p;
}
else {
ltod = ba_ltod[index];
dtol = ba_dtol[index];
}
color((b->gui.state&ST_HIGHL) ? VeryLightGray : LightGray);
fg = b->fg;
}
else {
ltod = inv_ltod;
dtol = inv_ltod;
color(LightGray);
fg = DarkGray;
}
sboxfi(x1,y1,x2,y2);
#define bbd(ramp,X1,Y1,X2,Y2) \
for (i=0; i < NBRAMP; i++) { \
color(ramp[i]); \
sboxfi(X1 i, Y1 i, X2 i, Y2 i); \
}
bbd(dtol,x1+,y1+,x2-,y1+); /* bottom */
bbd(dtol,x2-,y1+,x2-,y2-); /* right */
bbd(ltod,x1+,y1+,x1+,y2-); /* left */
bbd(ltod,x1+,y2-,x2-,y2-); /* top */
if (b->pcbm) {
bx = x1 + (x2 - x1 + 1 - b->pcbm->w) / 2;
by = y1 + (y2 - y1 + 1 - b->pcbm->h) / 2;
drawPcbm(b->pcbm,bx,by);
}
if (b->text) {
bx = x1 + (x2 - x1 + 1 - (i=textWidth(b->text,BUTTONFONT)))/2;
by = y1 + 9;
if (b->gui.flags & _DEFAULT) {
int arrowx;
bx -= default_width - BUTTONAMARGIN;
arrowx = bx+i+BUTTONAMARGIN;
color(fg);
cmov2i(arrowx,by);
drawBitmap(default_bits,default_width,default_height);
color(YELLOW);
cmov2i(arrowx,by-1);
drawBitmap(defaulthl_bits,defaulthl_width,
defaulthl_height);
color(DarkGray);
sboxfi(arrowx+6,by+4,arrowx+13,by+4);
}
cmov2i(bx, by);
color(fg);
puttext(b->text, BUTTONFONT);
}
}
void
drawBitmap(unsigned short *bits, int w, int h)
{
struct htp_bitmap bm;
bm.buf = bits;
bm.xsize = (short) w;
bm.ysize = (short) h;
bm.xorig = bm.yorig = bm.xmove = bm.ymove = 0;
bm.sper = (short) ((w + 15) / 16);
drawbitmap(&bm);
}