Blame button.c

Packit 4d380f
#include <slang.h>
Packit 4d380f
#include <stdlib.h>
Packit 4d380f
#include <string.h>
Packit 4d380f
Packit 4d380f
#include "newt.h"
Packit 4d380f
#include "newt_pr.h"
Packit 4d380f
Packit 4d380f
struct button {
Packit 4d380f
    char * text;
Packit 4d380f
    int compact;
Packit 4d380f
};
Packit 4d380f
Packit 4d380f
static void buttonDrawIt(newtComponent co, int active, int pushed);
Packit 4d380f
static void buttonDrawText(newtComponent co, int active, int pushed);
Packit 4d380f
Packit 4d380f
static void buttonDraw(newtComponent c);
Packit 4d380f
static void buttonDestroy(newtComponent co);
Packit 4d380f
static struct eventResult buttonEvent(newtComponent c,
Packit 4d380f
				      struct event ev);
Packit 4d380f
static void buttonPlace(newtComponent co, int newLeft, int newTop);
Packit 4d380f
Packit 4d380f
static struct componentOps buttonOps = {
Packit 4d380f
    buttonDraw,
Packit 4d380f
    buttonEvent,
Packit 4d380f
    buttonDestroy,
Packit 4d380f
    buttonPlace,
Packit 4d380f
    newtDefaultMappedHandler,
Packit 4d380f
} ;
Packit 4d380f
Packit 4d380f
/* 
Packit 4d380f
 * return NULL on malloc error.
Packit 4d380f
 *  FIXME: all createButton calls should check for error
Packit 4d380f
 */
Packit 4d380f
static newtComponent createButton(int left, int row, const char * text, int compact) {
Packit 4d380f
    newtComponent co;
Packit 4d380f
    struct button * bu;
Packit 4d380f
    int width = wstrlen(text,-1);
Packit 4d380f
Packit 4d380f
    co = malloc(sizeof(*co));
Packit 4d380f
    if (co == NULL) 
Packit 4d380f
	return NULL;
Packit 4d380f
    bu = malloc(sizeof(struct button));
Packit 4d380f
    if (bu == NULL)  {
Packit 4d380f
	free (co);
Packit 4d380f
	return NULL;
Packit 4d380f
    }
Packit 4d380f
    co->data = bu;
Packit 4d380f
    co->destroyCallback = NULL;
Packit 4d380f
Packit 4d380f
    bu->text = strdup(text);
Packit 4d380f
    bu->compact = compact;
Packit 4d380f
    co->ops = &buttonOps;
Packit 4d380f
Packit 4d380f
    if (bu->compact) {
Packit 4d380f
	co->height = 1;
Packit 4d380f
	co->width = width + 3;
Packit 4d380f
    } else {
Packit 4d380f
	co->height = 4;
Packit 4d380f
	co->width = width + 5;
Packit 4d380f
    }
Packit 4d380f
Packit 4d380f
    co->top = row;
Packit 4d380f
    co->left = left;
Packit 4d380f
    co->takesFocus = 1;
Packit 4d380f
    co->isMapped = 0;
Packit 4d380f
Packit 4d380f
    newtGotorc(co->top, co->left);
Packit 4d380f
Packit 4d380f
    return co;
Packit 4d380f
Packit 4d380f
}
Packit 4d380f
Packit 4d380f
newtComponent newtCompactButton(int left, int row, const char * text) {
Packit 4d380f
    return createButton(left, row, text, 1);
Packit 4d380f
}
Packit 4d380f
Packit 4d380f
newtComponent newtButton(int left, int row, const char * text) {
Packit 4d380f
    return createButton(left, row, text, 0);
Packit 4d380f
}
Packit 4d380f
Packit 4d380f
static void buttonDestroy(newtComponent co) {
Packit 4d380f
    struct button * bu = co->data;
Packit 4d380f
Packit 4d380f
    free(bu->text);
Packit 4d380f
    free(bu);
Packit 4d380f
    free(co);
Packit 4d380f
}
Packit 4d380f
Packit 4d380f
static void buttonPlace(newtComponent co, int newLeft, int newTop) {
Packit 4d380f
    co->top = newTop;
Packit 4d380f
    co->left = newLeft;
Packit 4d380f
Packit 4d380f
    newtGotorc(co->top, co->left);
Packit 4d380f
}
Packit 4d380f
Packit 4d380f
static void buttonDraw(newtComponent co) {
Packit 4d380f
    buttonDrawIt(co, 0, 0);
Packit 4d380f
}
Packit 4d380f
Packit 4d380f
static void buttonDrawIt(newtComponent co, int active, int pushed) {
Packit 4d380f
    struct button * bu = co->data;
Packit 4d380f
Packit 4d380f
    if (!co->isMapped) return;
Packit 4d380f
Packit 4d380f
    SLsmg_set_color(NEWT_COLORSET_BUTTON);
Packit 4d380f
Packit 4d380f
    if (bu->compact) {
Packit 4d380f
	if (!active)
Packit 4d380f
	    SLsmg_set_color(NEWT_COLORSET_COMPACTBUTTON);
Packit 4d380f
	else if (SLtt_Use_Ansi_Colors)
Packit 4d380f
	    SLsmg_set_color(NEWT_COLORSET_BUTTON);
Packit 4d380f
	else
Packit 4d380f
	    SLsmg_set_color(NEWT_COLORSET_ACTBUTTON);
Packit 4d380f
	newtGotorc(co->top+ pushed, co->left + 1 + pushed);
Packit 4d380f
	SLsmg_write_char('<');
Packit 4d380f
	SLsmg_write_string(bu->text);
Packit 4d380f
	SLsmg_write_char('>');
Packit 4d380f
    } else {
Packit 4d380f
	if (pushed) {
Packit 4d380f
	    SLsmg_set_color(NEWT_COLORSET_BUTTON);
Packit 4d380f
	    newtDrawBox(co->left + 1, co->top + 1, co->width - 1, 3, 0);
Packit 4d380f
Packit 4d380f
	    SLsmg_set_color(NEWT_COLORSET_WINDOW);
Packit 4d380f
	    newtClearBox(co->left, co->top, co->width, 1);
Packit 4d380f
	    newtClearBox(co->left, co->top, 1, co->height);
Packit 4d380f
	} else {
Packit 4d380f
	    newtDrawBox(co->left, co->top, co->width - 1, 3, 1);
Packit 4d380f
	}
Packit 4d380f
Packit 4d380f
	buttonDrawText(co, active, pushed);
Packit 4d380f
    }
Packit 4d380f
    /* put cursor at beginning of text for better accessibility */
Packit 4d380f
    newtGotorc(co->top + (bu->compact ? 0 : 1) + pushed, co->left + 1 + pushed + 1);
Packit 4d380f
}
Packit 4d380f
Packit 4d380f
static void buttonDrawText(newtComponent co, int active, int pushed) {
Packit 4d380f
    struct button * bu = co->data;
Packit 4d380f
Packit 4d380f
    if (pushed) pushed = 1;
Packit 4d380f
Packit 4d380f
    if (active)
Packit 4d380f
	SLsmg_set_color(NEWT_COLORSET_ACTBUTTON);
Packit 4d380f
    else
Packit 4d380f
	SLsmg_set_color(NEWT_COLORSET_BUTTON);
Packit 4d380f
Packit 4d380f
    newtGotorc(co->top + 1 + pushed, co->left + 1 + pushed);
Packit 4d380f
    SLsmg_write_char(' ');
Packit 4d380f
    SLsmg_write_string(bu->text);
Packit 4d380f
    SLsmg_write_char(' ');
Packit 4d380f
}
Packit 4d380f
Packit 4d380f
static struct eventResult buttonEvent(newtComponent co,
Packit 4d380f
				      struct event ev) {
Packit 4d380f
    struct eventResult er;
Packit 4d380f
    struct button * bu = co->data;
Packit 4d380f
Packit 4d380f
    er.result = ER_IGNORED;
Packit 4d380f
Packit 4d380f
    if (ev.when == EV_NORMAL) {
Packit 4d380f
	switch (ev.event) {
Packit 4d380f
	  case EV_FOCUS:
Packit 4d380f
	    buttonDrawIt(co, 1, 0);
Packit 4d380f
	    er.result = ER_SWALLOWED;
Packit 4d380f
	    break;
Packit 4d380f
Packit 4d380f
	  case EV_UNFOCUS:
Packit 4d380f
	    buttonDrawIt(co, 0, 0);
Packit 4d380f
	    er.result = ER_SWALLOWED;
Packit 4d380f
	    break;
Packit 4d380f
Packit 4d380f
	  case EV_KEYPRESS:
Packit 4d380f
	    if (ev.u.key == ' ' || ev.u.key == '\r') {
Packit 4d380f
		if (!bu->compact) {
Packit 4d380f
		    /* look pushed */
Packit 4d380f
		    buttonDrawIt(co, 1, 1);
Packit 4d380f
		    newtRefresh();
Packit 4d380f
		    newtDelay(150000);
Packit 4d380f
		    buttonDrawIt(co, 1, 0);
Packit 4d380f
		    newtRefresh();
Packit 4d380f
		    newtDelay(150000);
Packit 4d380f
		}
Packit 4d380f
Packit 4d380f
		er.result = ER_EXITFORM;
Packit 4d380f
	    } else
Packit 4d380f
		er.result = ER_IGNORED;
Packit 4d380f
	    break;
Packit 4d380f
	  case EV_MOUSE:
Packit 4d380f
	      if (ev.u.mouse.type == MOUSE_BUTTON_DOWN &&
Packit 4d380f
		  co->top <= ev.u.mouse.y &&
Packit 4d380f
		  co->top + co->height - !bu->compact > ev.u.mouse.y &&
Packit 4d380f
		  co->left <= ev.u.mouse.x &&
Packit 4d380f
		  co->left + co->width - !bu->compact > ev.u.mouse.x) {
Packit 4d380f
		  if (!bu->compact) {
Packit 4d380f
		      buttonDrawIt(co, 1, 1);
Packit 4d380f
		      newtRefresh();
Packit 4d380f
		      newtDelay(150000);
Packit 4d380f
		      buttonDrawIt(co, 1, 0);
Packit 4d380f
		      newtRefresh();
Packit 4d380f
		      newtDelay(150000);
Packit 4d380f
		  }
Packit 4d380f
		  er.result = ER_EXITFORM;
Packit 4d380f
	      }
Packit 4d380f
	    break;
Packit 4d380f
	}
Packit 4d380f
    }
Packit 4d380f
Packit 4d380f
    return er;
Packit 4d380f
}