Logo Search packages:      
Sourcecode: xblast-tnt version File versions  Download package

mi_combo.c

/*
 * file mi_combo.c - simple box box 
 *
 * $Id: mi_combo.c,v 1.3 2004/05/14 10:00:35 alfie Exp $
 *
 * Program XBLAST 
 * (C) by Oliver Vogel (e-mail: m.vogel@ndh.net)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation; either version 2; or (at your option)
 * any later version
 *
 * This program is distributed in the hope that it will be entertaining,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILTY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 * Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#include "mi_combo.h"

#include "mi_map.h"
#include "gui.h"

/*
 * local macros
 */ 
#define FF_COMBO_TEXT_FOCUS       (FF_Medium | FF_Black | FF_Left   | FF_Outlined)
#define FF_COMBO_TEXT_NO_FOCUS    (FF_Medium | FF_White | FF_Left)
#define FF_COMBO_VALUE_SELECT     (FF_Medium | FF_Black | FF_Center | FF_Boxed )
#define FF_COMBO_VALUE_NO_SELECT  (FF_Medium | FF_White | FF_Center | FF_Boxed )

/*
 * local types
 */
/* simple combo box */
typedef struct {
  XBMenuItem         item;
  const char          *text;
  int                 *value;
  void         **data;
  XBAtom            *atom;
  XBComboEntryList  *table;
  int                  index;
  Sprite              *t_sprite;
  Sprite              *v_sprite;
} XBMenuComboItem;

/*
 * a combo item receives the focus
 */
static void
MenuComboFocus (XBMenuItem *ptr, XBBool flag)
{
  XBMenuComboItem *combo = (XBMenuComboItem *) ptr;

  assert (combo != NULL);
  assert (combo->t_sprite != NULL);
  SetSpriteAnime (combo->t_sprite, flag ? FF_COMBO_TEXT_FOCUS : FF_COMBO_TEXT_NO_FOCUS);
} /* MenuComboFocus */

/*
 * Menu Combo Item
 */
static void
MenuComboPoll (XBMenuItem *ptr)
{
  int index = 0;
  XBMenuComboItem *combo = (XBMenuComboItem *) ptr;

  assert (combo != NULL);
  assert (combo->table != NULL);
  assert (combo->v_sprite != NULL);
  /* find current value in table */
  if (combo->value != NULL) {
    for (index = 0; combo->table[index].text != NULL; index ++) {
      if (combo->table[index].value == *combo->value) {
      break;
      }
    }
  }
  if (combo->data != NULL) {
    for (index = 0; combo->table[index].text != NULL; index ++) {
      if (combo->table[index].data == *combo->data) {
      break;
      }
    }
  }
  if (combo->atom != NULL) {
    for (index = 0; combo->table[index].text != NULL; index ++) {
      if (combo->table[index].atom == *combo->atom) {
      break;
      }
    }
  }
  /* check if index has changed */
  if (index != combo->index) {
    combo->index = index;
    /* set values according entry */
    if (combo->value != NULL) {
      *combo->value = combo->table[index].value;
    }
    if (combo->data != NULL) {
      *combo->data = combo->table[index].data;
    }
    if (combo->atom != NULL) {
      *combo->atom = combo->table[index].atom;
    }
    /* change value display */
    SetSpriteText (combo->v_sprite, combo->table[index].text);
  }
} /* MenuComboPoll */

/*
 * combo item: select new element
 */
static void
SetCombo (XBMenuComboItem *combo, XBBool next)
{
  if (next) {
    /* go forward in table */
    combo->index ++;
    if (NULL == combo->table[combo->index].text) {
      /* reched end of table */
      combo->index = 0;
    }
  } else {
    /* go backward in table */
    if (combo->index <= 0) {
      /* search for last entry */
      for (combo->index = 0; combo->table[combo->index].text != NULL; combo->index ++) continue;
    } 
    combo->index --;
  }
  /* set new text for sprite */
  SetSpriteText (combo->v_sprite, combo->table[combo->index].text);
  /* set new value */
  if (NULL != combo->value) {
    *combo->value = combo->table[combo->index].value;
  }
  if (NULL != combo->data) {
    *combo->data = combo->table[combo->index].data;
  }
  if (NULL != combo->atom) {
    *combo->atom = combo->table[combo->index].atom;
  }
} /* SetCombo */

/*
 *
 */
static void
MenuComboMouse (XBMenuItem *ptr, XBEventCode code)
{
  switch (code) {
  case XBE_MOUSE_1:
    SetCombo ((XBMenuComboItem *) ptr, XBTrue);
    break;
  case XBE_MOUSE_2:
    SetCombo ((XBMenuComboItem *) ptr, XBFalse);
    break;
  default:
    break;
  }    
} /* MenuComboMouse */

/*
 * event handling whiule combo is selected
 */
static void
ComboEventLoop (XBMenuItem *ptr)
{
  XBEventCode event;
  XBEventData data;
  XBMenuComboItem *combo = (XBMenuComboItem * )ptr;
  
  assert (combo != NULL);
  assert (combo->v_sprite != NULL);
  
  SetSpriteAnime (combo->v_sprite, FF_COMBO_VALUE_SELECT);
  /* event loop */
  while (1) {
    /* update window contents */
    MenuUpdateWindow ();
    /* get event from gui */
    while (XBE_TIMER != (event = GUI_WaitEvent (&data) ) ) {
      if (event == XBE_MENU) {
      switch (data.value) {
      case XBMK_PREV:   
      case XBMK_UP:   
        SetCombo (combo, XBFalse); 
        break;
      case XBMK_NEXT:   
      case XBMK_DOWN:   
        SetCombo (combo, XBTrue); 
        break;
      case XBMK_SELECT: 
      case XBMK_ABORT:  
        SetSpriteAnime (combo->v_sprite, FF_COMBO_VALUE_NO_SELECT);
        return;
      default:  
        break;
      }
      }
    }
  }
} /* ComboEventLoop */

/*
 *
 */
XBMenuItem *
MenuCreateCombo (int x, int y, int w, const char *text, int w_val, 
             int *value, void **data, XBAtom *atom, XBComboEntryList *table)
{
  XBMenuComboItem *combo;
  
  assert (w - w_val > 0);
  combo = calloc (1, sizeof (*combo) );
  assert (combo != NULL);
  MenuSetItem (&combo->item, MIT_Combo, x, y, w, CELL_H, MenuComboFocus, ComboEventLoop, MenuComboMouse, MenuComboPoll);
  /* set label */
  combo->text     = text;
  combo->t_sprite = CreateTextSprite (text, (x + 1) * BASE_X, (y + 1) * BASE_Y, (w - w_val - 2) * BASE_X, (CELL_H - 2) * BASE_Y,
                              FF_COMBO_TEXT_NO_FOCUS, SPM_MAPPED);
  /* find index of value in table */
  combo->value = value;
  combo->data  = data;
  combo->atom  = atom;
  combo->table = table;
  combo->index = 0;
  /* find valid entry in table */
  if (combo->value != NULL) {
    for (combo->index = 0; table[combo->index].text != NULL; combo->index ++) {
      if (table[combo->index].value == *value) {
      break;
      }
    }
  }
  if (combo->data != NULL) {
    for (combo->index = 0; table[combo->index].text != NULL; combo->index ++) {
      if (table[combo->index].data == *data) {
      break;
      }
    }
  }
  if (combo->atom != NULL) {
    for (combo->index = 0; table[combo->index].text != NULL; combo->index ++) {
      if (table[combo->index].atom == *atom) {
      break;
      }
    }
  }
  if (NULL == table[combo->index].text) {
    combo->index = 0;
  }
  /* set values according entry */
  if (combo->value != NULL) {
    *combo->value = table[combo->index].value;
  }
  if (combo->data != NULL) {
    *combo->data = table[combo->index].data;
  }
  if (combo->atom != NULL) {
    *combo->atom = table[combo->index].atom;
  }
  /* create sprite */
  combo->v_sprite 
    = CreateTextSprite (table[combo->index].text, (x + w - w_val + 1) * BASE_X, (y + 2) * BASE_Y,
                  (w_val - 2) * BASE_X, (CELL_H - 4) * BASE_Y,
                  FF_COMBO_VALUE_NO_SELECT, SPM_MAPPED);
  /* graphics */
  MenuAddLargeFrame ((x - CELL_W/2) / CELL_W, (x + w + CELL_W/2 - 1) / CELL_W, y / CELL_H);
  return &combo->item;
}

/*
 * delete a combo 
 */
void
MenuDeleteCombo (XBMenuItem *item)
{
  XBMenuComboItem *combo = (XBMenuComboItem *) item;

  assert (combo != NULL);
  assert (combo->t_sprite != NULL);
  assert (combo->v_sprite != NULL);
  DeleteSprite (combo->t_sprite);
  DeleteSprite (combo->v_sprite);
} /* DeleteComboItem */


/*
 * end of file mi_bombo.c
 */

Generated by  Doxygen 1.6.0   Back to index