btn.cc

/*************************************************************************
*  MODULE : Btn - Class Body						 *
*  AUTHOR : Ron Chernich						 *
*  PURPOSE: Class actions used to build "button" like objects used in	 *
*	     RCOS system.  These actions support button construction and *
*	     activation only.  All visual aspects are handled by a class *
*	     based on this class.					 *
*  HISTORY:								 *
*   18-JAN-93  First (MSC/C++ 7.00) version				 *
*   04-JUN-93  Allocation of button label made conditional		 *
*   29-MAR-94  Button class being deleted twice (allow to DblList do it) *
*************************************************************************/


#include "btn.hh"


/////////////////
// table used to lookup the raw key values returned by ALT keys
//
static unsigned char RawKey[] = {
  ALT_A, ALT_B, ALT_C, ALT_D, ALT_E, ALT_F, ALT_G, ALT_H, ALT_I,
  ALT_J, ALT_K, ALT_L, ALT_M, ALT_N, ALT_O, ALT_P, ALT_Q, ALT_R,
  ALT_S, ALT_T, ALT_U, ALT_V, ALT_W, ALT_X, ALT_Y, ALT_Z, ALT_0,
  ALT_1, ALT_2, ALT_3, ALT_4, ALT_5, ALT_6, ALT_7, ALT_8, ALT_9
};


//////////////////////////////////////////////////////////////////////////
// Class destructor:  Kills off all buttons in a linked list,
// and then the list itself
//
Btn::~Btn()
{

  pb = (btn*)DblGetHead();
  while (pb) {
    if (pb->pst)
      delete pb->pst;
    pb = (btn*)DblGetNext();
  }
  DblDrop();
  pb = NULL;
};

/////////////////
// Add a new button to the linked list.  The params decode as:
//     n .. the ID to be returned when the button is activated
//   str .. Button label (with optional hot key char prefixed by "&")
// x1,y1 .. Upper-Left boundary for "hot reigon"
// x2,y2 .. width and height of hot area from upper-left reference
// RETURNS: TRUE  .. action complete (Btn::pb references new data object)
//	    FALSE .. unable to allocate storage for item
//
BOOL Btn::BtnNew(const UINT16 n, char *str, rect &r)
{
  btn  *p;
  int  idx;
  char *cp;
  BOOL bOk = FALSE;

  if (p = new btn) {
    p->r  = r;
    p->Id = n;
    p->status = 0;
    if (strlen(str) == 0)
      p->pst = NULL;
    else {
      p->pst = new Str(str);
      if (cp = strchr(str, '&')) {
	++cp;
	idx = (((*cp >= 'a') && (*cp <= 'z')) ? (int)(*cp - 'a') :
	      ((*cp >= 'A') && (*cp <= 'Z')) ? (int)(*cp - 'A') :
	      ((*cp >= '0') && (*cp <= '9')) ? (26 + (int)(*cp - '0')) : -1);
	p->HotKey = ((idx >= 0) ? RawKey[idx] : 0);
      }
    }
    if (DblAppend((void*)p, (UINT16)sizeof(btn)))
      bOk = TRUE;
    else
      delete p->pst;
  }
  if (pb = p)  // bit naughty: combined assignment and test (not comparison!)
    delete p;
  return bOk;
}

///////////////
// See if a member button has the passed Hot Key code
// RETURNS:  button reference (or NULL if Hot Key unsegistered)
//
btn *Btn::BtnHit (const char ch)
{
  pb = (btn*)DblGetHead();
  while (pb) {
    if (ch == pb->HotKey)
      break;
    pb = (btn*)DblGetNext();
  }
  return pb;
}

///////////////
// See if the passed point lies in a member button Hot Zone
// RETURNS:  button reference (or NULL if point unsegistered)
//
btn *Btn::BtnHit (point &pt)
{

  pb = (btn*)DblGetHead();
  while (pb) {
    if (pb->r.InRect(pt))
      break;
    pb = (btn*)DblGetNext();
  }
  return pb;
}

/////////////
// Locate button by ID
// RETURNS: TRUE  .. ID found, pb -> data
//	    FALSE .. unknown ID
//
BOOL Btn::BtnFind (const UINT16 id)
{

  pb = (btn*)DblGetHead();
  while (pb) {
    if (pb->Id == id)
      return TRUE;
    pb = (btn*)DblGetNext();
  }
  return FALSE;
}

/////////////
// Delete string label of button with passed ID from list, then allow
// the linked list class to free the rest.  If the passed ID is ZERO
// (an illegal ID), kill off all controls in the list.
//
void Btn::BtnKill (const UINT16 nTarg)
{

  pb = (btn*)DblGetHead();
  while (pb) {
    if (!nTarg || (pb->Id == nTarg)) {
      if (pb->pst)
        delete pb->pst;
      DblDelete();
      break;
    }
    pb = (btn*)DblGetNext();
  }
}

/************************************ EOF ********************************/