///////////////////////////////////////////////////////////////////////////////
// $Id: PushButton.cxx,v 1.1 1995/01/08 06:51:20 bmott Exp $
///////////////////////////////////////////////////////////////////////////////
//
// PushButton.hxx - Push button widget
//
//
// Bradford W. Mott
// Copyright (C) 1994
// December 12,1994
//
///////////////////////////////////////////////////////////////////////////////
// $Log: PushButton.cxx,v $
// Revision 1.1  1995/01/08  06:51:20  bmott
// Initial revision
//
///////////////////////////////////////////////////////////////////////////////

#include "PushButton.hxx"
#include "UIApplication.hxx"
#include "ContainerWidget.hxx"
#include "misc.hxx"

///////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////
PushButton::PushButton(ContainerWidget *const parent, 
    const char *const widgetName,
    int x, int y, int width, int height, 
    const char* label, Command* pushCommand)
    : BasicWidget(parent, widgetName, x, y, width, height),
      myLabel(label),
      myCommand(pushCommand)
{
  // Create window for widget
  myWindow = XCreateSimpleWindow(application->display(), myParent->window(),
      x, y, width, height,
      0, 0, 0);

  // PushButtons have to respond to several event types
  XSelectInput(application->display(), myWindow, 
      ButtonPressMask | ExposureMask | EnterWindowMask | 
      LeaveWindowMask | ButtonReleaseMask );
}


///////////////////////////////////////////////////////////////////////////////
// Destructor
///////////////////////////////////////////////////////////////////////////////
PushButton::~PushButton()
{
  // Delete my command
  delete myCommand;
}

///////////////////////////////////////////////////////////////////////////////
// Update the graphical view of the push button
///////////////////////////////////////////////////////////////////////////////
void PushButton::updateView()
{
  // Setup GC and Font
  XFontStruct* fontInfo = application->font();

  XGCValues gcValues;
  gcValues.foreground = foreground();
  gcValues.background = background();
  gcValues.font = fontInfo->fid;
  GC gc = XCreateGC(application->display(), myWindow,
      GCForeground | GCBackground | GCFont, &gcValues); 

  Draw3DBorder(this, 3, Raised);
   
  // Center label in widget
  int x = (width() - XTextWidth(fontInfo, myLabel, strlen(myLabel)) ) / 2;
  int y = height()/2 - ((fontInfo->ascent+fontInfo->descent)/2) + fontInfo->ascent;

  XDrawString(application->display(), myWindow, gc,
    x, y, myLabel, strlen(myLabel));

  // Free the GC
  XFreeGC(application->display(), gc); 
}

///////////////////////////////////////////////////////////////////////////////
// Called whenever an event arrives for me (I override the default)
///////////////////////////////////////////////////////////////////////////////
void PushButton::handleEvent(XEvent* event)
{
  // Handle the event
  if (event->type == Expose)
  {
    updateView();
  }
  else if ((event->type == ButtonPress) && (event->xbutton.button == Button1))
  {
    // Flag to tell if the button was really pressed
    int pressed = 1;

    // Push the button in
    Draw3DBorder(this, 3, Sunken);

    // Track the mouse until the button is released
    int done = 0;
    while(!done)
    {
      XEvent event;
    
      XNextEvent(application->display(), &event);
      switch(event.type)
      {
        case EnterNotify:
          // Push the button in
          Draw3DBorder(this, 3, Sunken);
          pressed = 1;
          break;

        case LeaveNotify:
          // Pop the button back out
          Draw3DBorder(this, 3, Raised);
          pressed = 0;
          break;

        case ButtonRelease:
          // Pop the button back out
          Draw3DBorder(this, 3, Raised);

          done = 1;
          break;

        default:
          break;
      }
    }

    // Execute my command if the button was pressed
    if(pressed)
    {
      myCommand->execute(NULL);
    }
  } 
}

