/* newbutton.c */
/*
* New push/toggle button widget
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lui.h"
#define LMARGIN 2
static void draw_button( LUI_NEWBUTTON *b )
{
int x, y, texty, width, height;
GC backgc;
if (b->highlight) {
backgc = LUI_GC_highgray;
}
else {
backgc = LUI_GC_gray;
}
/* background area */
x = b->framewidth;
y = b->framewidth;
width = b->width - 2 * b->framewidth;
height = b->height - 2 * b->framewidth;
/* center label vertically */
texty = b->framewidth + (b->height - 2*b->framewidth - LUI_Font_height) / 2
+ LUI_Font_yoff;
if (b->toggle==2) {
/* a toggle button with a red light */
int hgt = height - 8;
/* draw on/off light indicator next to label */
XFillRectangle( LUI_Display, b->window, backgc, x, y, width, height );
if (b->state==1) {
/* lit */
XFillRectangle( LUI_Display, b->window, LUI_GC_red,
x+4, y+4, height/2-3, height-8 );
}
XDrawRectangle( LUI_Display, b->window, LUI_GC_black,
x+2, y+2, height/2, height-5 );
XDrawString( LUI_Display, b->window, LUI_GC_black,
x+LMARGIN+4+height/2, texty, b->label, strlen(b->label) );
LUI_DrawFrame( b->window, 0, 0, b->width, b->height,
b->framewidth, 1 );
}
else {
if (b->state==0) {
/* off */
XFillRectangle( LUI_Display, b->window, backgc, x, y, width, height );
XDrawString( LUI_Display, b->window, LUI_GC_black,
x+LMARGIN, texty, b->label, strlen(b->label) );
}
else {
/* on */
XSetForeground( LUI_Display, LUI_Gc, b->color );
XFillRectangle( LUI_Display, b->window, LUI_Gc,
x, y, width, height );
/* MJK 12.04.98 */
/* 03Feb98 Phil McDonald use white on dark or blue-dominated colors */
if ((b->red < 0.6) && (b->green < 0.6)) {
#ifdef JOHAN
if (b->red+b->green+b->blue < 0.6) {
#endif
/* white text */
XDrawString( LUI_Display, b->window, LUI_GC_white,
x+LMARGIN, texty, b->label, strlen(b->label) );
}
else {
/* black text */
XDrawString( LUI_Display, b->window, LUI_GC_black,
x+LMARGIN, texty, b->label, strlen(b->label) );
}
}
LUI_DrawFrame( b->window, 0, 0, b->width, b->height,
b->framewidth, !b->state );
}
}
static int button_process( LUI_NEWBUTTON *b, XEvent *event )
{
int x, y;
switch (event->type) {
case Expose:
draw_button( b );
break;
case ButtonPress:
b->mousebutton = event->xbutton.button;
if (event->xbutton.button==Button1 ||
(b->special==1 && event->xbutton.button==Button3)) {
if (b->toggle) {
b->state = !b->state;
if (b->callback) {
(*b->callback)( b, b->state );
}
}
else {
b->state = 1;
}
draw_button( b );
}
else if (b->callback) {
/* other button */
(*b->callback)( b, b->state );
}
break;
case ButtonRelease:
b->mousebutton = event->xbutton.button;
if (event->xbutton.button==Button1 ||
(b->special==1 && event->xbutton.button==Button3)) {
if (b->toggle) {
/* nothing */
}
else {
/* push button now released -> activate */
b->state = 0;
draw_button( b );
x = event->xbutton.x;
y = event->xbutton.y;
if (b->callback && x>=0 && x<=b->width && y>=0 && y<=b->height) {
(*b->callback)( b, b->state );
}
}
}
break;
case EnterNotify:
b->highlight = 1;
draw_button( b );
break;
case LeaveNotify:
b->highlight = 0;
draw_button( b );
break;
default:
printf("Error in button_process: unexpected event\n");
}
return 1;
}
/*
* Destroy a button.
*/
void LUI_NewButtonDestroy( LUI_NEWBUTTON *button )
{
LUI_EventRemove( button->window );
XDestroyWindow( LUI_Display, button->window );
button->window = 0;
free( button->label );
button->label = NULL;
free( button );
button = NULL;
}
/*
* Create a push or toggle button.
* Input: toggle - 0=push button, 1=toggle button, 2=lighted toggle button
*/
static LUI_NEWBUTTON *new_button( Window parent, int x, int y,
int width, int height, char *label,
int toggle )
{
LUI_NEWBUTTON *b;
LUI_LayoutCheck( &x, &y, &width, &height );
b = (LUI_NEWBUTTON *) malloc( sizeof(LUI_NEWBUTTON) );
if (!b) {
return NULL;
}
b->window = XCreateSimpleWindow( LUI_Display, parent,
x, y, width-2, height-2,
1, LUI_Color_black, LUI_Color_gray );
LUI_EventAdd2( b->window,
ExposureMask | ButtonPressMask | ButtonReleaseMask |
EnterWindowMask | LeaveWindowMask,
(LUI_FNCP) button_process, b );
XMapWindow( LUI_Display, b->window );
b->x = x;
b->y = y;
b->width = width - 2;
b->height = height - 2;
b->framewidth = LUI_Border;
b->toggle = toggle;
b->label = strdup( label );
b->state = 0;
b->highlight = 0;
b->color = LUI_Color_white /*darkgray*/; /*black;*/
/* MJK 12.04.98 */
/* 03Feb98 Phil McDonald default button color is white */
b->red = b->green = b->blue = 1.0;
#ifdef JOHAN
b->red = b->green = b->blue = 0.3;
#endif
b->callback = NULL;
LUI_AddWidgetToWindow( parent, b, (LUI_FNCP) LUI_NewButtonDestroy );
return b;
}
LUI_NEWBUTTON *LUI_PushButtonCreate( Window parent, int x, int y,
int width, int height, char *label )
{
return new_button( parent, x, y, width, height, label, 0 );
}
LUI_NEWBUTTON *LUI_ToggleButtonCreate( Window parent, int x, int y,
int width, int height, char *label )
{
return new_button( parent, x, y, width, height, label, 1 );
}
LUI_NEWBUTTON *LUI_CheckButtonCreate( Window parent, int x, int y,
int width, int height, char *label )
{
return new_button( parent, x, y, width, height, label, 2 );
}
/*
* Set the "on" color for a button.
*/
void LUI_ButtonColor( LUI_NEWBUTTON *b, double red, double green, double blue )
{
if (b->color!=LUI_Color_white/*darkgray*/) {
LUI_FreeColor( b->color );
/* XFreeColors( LUI_Display, LUI_Colormap, &b->color, 1, 0 );*/
}
b->red = red;
b->green = green;
b->blue =blue;
b->color = LUI_AllocateColor( red, green, blue );
if (b->state) {
draw_button(b);
}
}
/*
* Set the state of a toggle button. 0=off, 1=on
*/
void LUI_ButtonSetState( LUI_NEWBUTTON *b, int state )
{
if (b && b->toggle) {
b->state = state;
draw_button( b );
}
}
/*
* Get the state of a button.
* Return: 1 = on, 0 = off
*/
int LUI_ButtonGetState( LUI_NEWBUTTON *b )
{
return b->state;
}
/*
* Specify the callback function for a button.
* The callback function should be declared as:
* int callback( LUI_NEWBUTTON *b, int state )
*
*/
void LUI_ButtonCallback( LUI_NEWBUTTON *b,
int (*callback)( LUI_NEWBUTTON *, int) )
{
b->callback = callback;
b->context_index = context_index;
}
/*
* Store a user specified index value in a button.
*/
void LUI_ButtonIndex( LUI_NEWBUTTON *b, int index )
{
b->index = index;
}
void LUI_ButtonContextIndex( LUI_NEWBUTTON *b, int index )
{
b->context_index = index;
}
syntax highlighted by Code2HTML, v. 0.9.1