/*****************************************************************************

    Copyright (C) 1994,1997 Ivan A. Curtis.  All rights reserved.

This code must not be re-distributed without these copyright notices intact.

*******************************************************************************
*******************************************************************************

Filename:	~icurtis/src/mx/buttons.c

Description:	

Update History:   (most recent first)
   I. Curtis   9-Apr-97 12:02 -- Updated
   I. Curtis  22-Mar-94 23:11 -- Created.

******************************************************************************/
#include "basic.h"
#include "alert.h"
#include "menu.h"
#include "buttons.h"

/**************************************
 * Handle an event for a button panel *
 **************************************/
int mx_button_event(Display *display, int screen, XEvent *event,
		    mx_button *button, int *done, int *x, int *y)
{
  int bx, by, bit, mask;
  switch(event->type) {
  case Expose:
    if (event->xexpose.window == button->window) {
      mx_items_draw(display, button->window, button->app,
		    button->item, button->first_item, 
		    button->last_item - button->first_item + 1, 
		    button->width, button->height,
		    button->app->button_width + 2 * button->app->item_border,
		    0);
      bx = button->app->item_border,
      by = (button->height - button->app->button_height) / 2;
      mask = 1;
      for (bit = 0; bit < button->last_item - button->first_item; bit ++) {
	if (button->value & mask)
	  XCopyPlane(display, button->app->button, button->window, 
		     button->app->gcd, 0, 0,
		     button->app->button_width, button->app->button_height,
		     bx, by, 0x01);
	mask = mask << 1;
	by += button->height;
      }
      return True;
    }
    break;
  case ButtonPress:
    if (event->xbutton.window == button->window) {
      button->cur_y = event->xbutton.y / button->height;
      bit = button->cur_y + button->first_item;
      mask = 1 << bit;
      if (!(button->item[button->cur_y + button->first_item].flag &
	    MXItemFlag_Disabled)) {
	button->value ^= mask;
	XCopyPlane(display, button->app->button, button->window, 
		   button->app->gcf, 0, 0,
		   button->app->button_width, button->app->button_height,
		   button->app->item_border,
		   (button->height - button->app->button_height) / 2 +
		   button->height * button->cur_y, 
		   0x01);
      }
      return True;
    }
    break;
  default:
    break;
  }
  return False;
}

/***********************************************
 * Pop up a list of buttons on the root window *
 * at position x, y                            *
 ***********************************************/
int mx_popup_button(Display *display, int screen, mx_panel *panel,
		    unsigned int value, int *x, int *y)
{
  XEvent event;
  mx_alert title;
  mx_button button;
  int done;

  if (!panel)
    return -1;

  button.app = panel->app;
  button.width = panel->width + panel->app->button_width +
    3 * panel->app->item_border;
  if (button.app->button_height > panel->height)
    button.height = button.app->button_height + 2 * panel->app->item_border;
  else
    button.height = panel->height + 2 * panel->app->item_border;
  button.first_item = 0;
  button.last_item = panel->last_item - panel->first_item - 1;
  button.item = panel->item + panel->first_item + 1;
  button.value = value;

  title.app = panel->app;
  title.width = button.width;
  title.height = panel->height + 2 * panel->app->item_border;
  title.start_item = panel->first_item;;
  title.max_items = 1;
  title.item = panel->item;

				/* make sure the windows are on screen */
  mx_adjust_xy(display, title.width + 2 * title.app->win_border,
	       (title.height +
		button.height * (button.last_item - button.first_item + 1) +
		3 * title.app->win_border),
	       x, y);
				/* open the title window */
  title.window =
    mx_transient_window_open(display, screen, panel->app->win_border, *x, *y,
			  title.width, title.height);
  XSelectInput(display, title.window, ExposureMask | OwnerGrabButtonMask |
	       ButtonPressMask | ButtonReleaseMask |
	       EnterWindowMask | LeaveWindowMask);
  title.inside = -1;
  title.momentary = 0;
				/* open the button window */
  button.window =
    mx_transient_window_open(display, screen, panel->app->win_border, 
			     *x, *y + title.height + title.app->win_border,
			     button.width,
			     button.height * (button.last_item - button.first_item + 1));
  XSelectInput(display, button.window, ExposureMask | OwnerGrabButtonMask |
	       ButtonPressMask | ButtonReleaseMask |
	       EnterWindowMask | LeaveWindowMask);
  button.inside = False;

  done = 0;
  while (!done) {
    XNextEvent(display, &event);
    if (mx_alert_event(display, screen, &event, &title, &done, x, y))
      continue;
    if (mx_button_event(display, screen, &event, &button, &done, x, y))
      continue;
    if (event.type == Expose && panel->app->expose_fun) {
      if ((*(panel->app->expose_fun))(&event))
	continue;
    }
  }
  mx_window_close(display, title.window);
  mx_window_close(display, button.window);
  return button.value;
}

