Files correlati : db0.exe Ricompilazione Demo : [ ] Commento : Corretta libreria sheet per sistemare controlli in immissione distinta base git-svn-id: svn://10.65.10.50/branches/R_10_00@22145 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			2389 lines
		
	
	
		
			63 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			2389 lines
		
	
	
		
			63 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#define XI_INTERNAL           
 | 
						|
#include <xinclude.h>
 | 
						|
 | 
						|
#ifndef STX_DATA
 | 
						|
extern "C" 
 | 
						|
{
 | 
						|
#include <xitext.h>
 | 
						|
#include <xistx.h>
 | 
						|
#include <xiutils.h>
 | 
						|
}
 | 
						|
#endif
 | 
						|
   
 | 
						|
#include <colors.h>
 | 
						|
#include <config.h>
 | 
						|
#include <controls.h>
 | 
						|
#include <image.h>
 | 
						|
#include <mask.h>
 | 
						|
#include <urldefid.h>
 | 
						|
#include <utility.h>
 | 
						|
#include <xvtility.h>
 | 
						|
 | 
						|
#include <statbar.h>
 | 
						|
 | 
						|
COLOR MASK_BACK_COLOR = XVT_MAKE_COLOR(201,194,188); // COLOR_LTGRAY;
 | 
						|
COLOR MASK_LIGHT_COLOR = COLOR_WHITE;
 | 
						|
COLOR MASK_DARK_COLOR = COLOR_GRAY;
 | 
						|
COLOR BTN_BACK_COLOR = COLOR_LTGRAY;
 | 
						|
COLOR BTN_LIGHT_COLOR = COLOR_WHITE;
 | 
						|
COLOR BTN_DARK_COLOR = COLOR_GRAY;
 | 
						|
COLOR NORMAL_COLOR = COLOR_BLACK;
 | 
						|
COLOR NORMAL_BACK_COLOR = COLOR_WHITE;
 | 
						|
COLOR PROMPT_COLOR = NORMAL_COLOR;
 | 
						|
COLOR DISABLED_COLOR = COLOR_DKGRAY;
 | 
						|
COLOR DISABLED_BACK_COLOR = MASK_BACK_COLOR;
 | 
						|
COLOR FOCUS_COLOR = NORMAL_COLOR;
 | 
						|
COLOR FOCUS_BACK_COLOR = COLOR_YELLOW;
 | 
						|
COLOR REQUIRED_BACK_COLOR = XVT_MAKE_COLOR(255,255,156);
 | 
						|
COLOR EASY_RIDER_COLOR = XVT_MAKE_COLOR(228,225,221);
 | 
						|
 | 
						|
bool CAMPI_SCAVATI     = true;
 | 
						|
bool AUTOSELECT        = false;
 | 
						|
bool ADVANCED_GRAPHICS = true;
 | 
						|
bool AUTOZOOM          = false;
 | 
						|
bool AUTOEND           = false;
 | 
						|
bool NATIVE_CONTROLS   = false;
 | 
						|
int  TOOL_SIZE         = 24;
 | 
						|
bool TOOL_TEXT         = true;
 | 
						|
bool EASY_RIDER        = true;
 | 
						|
bool ENTER_AS_TAB      = false;  
 | 
						|
int  INTERLINE         = 0;
 | 
						|
bool ANIMATED_BOXES    = false;
 | 
						|
 | 
						|
HIDDEN bool _ddl_shown = false;
 | 
						|
HIDDEN int  _last_mouse_button = 0;
 | 
						|
HIDDEN const int ITF_CID = 30000;
 | 
						|
 | 
						|
short low_get_focus_id(WINDOW win)
 | 
						|
{
 | 
						|
  XI_OBJ * itf = xi_get_itf((XinWindow)win);
 | 
						|
  XI_OBJ * obj = xi_get_focus(itf);
 | 
						|
 | 
						|
  if (obj == NULL || obj->type == XIT_ITF)
 | 
						|
    return -1;
 | 
						|
  if (obj->type == XIT_CELL || (obj->type == XIT_BTN && obj->parent != obj->itf))
 | 
						|
    obj = obj->parent;
 | 
						|
  
 | 
						|
  return obj->cid;
 | 
						|
}
 | 
						|
 | 
						|
void low_set_focus_id(WINDOW win, short id)
 | 
						|
{
 | 
						|
  XI_OBJ * itf = xi_get_itf((XinWindow)win);
 | 
						|
  if (id > 0)
 | 
						|
  {
 | 
						|
    // TO BE IMPLEMENTED
 | 
						|
  }
 | 
						|
  else
 | 
						|
    xi_set_focus(itf);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
KEY TControl::xiev_to_key(const XI_EVENT* xiev)
 | 
						|
{ 
 | 
						|
  const int k = xiev->v.chr.ch;
 | 
						|
  KEY key = k;
 | 
						|
  if (key < K_INS || key > K_HELP)
 | 
						|
  {
 | 
						|
    if (xiev->v.chr.shift && (k < ' ' || k >= K_UP)) key += K_SHIFT;
 | 
						|
    //if (xiev->v.chr.control && k >= ' ') key += K_CTRL;
 | 
						|
//  Correzione per gestire i tasti AltGr sulle tastiere non U.S.A.     
 | 
						|
    if (xiev->v.chr.control && (k > K_SHIFT || (k >= K_F1 && k <= K_F12) || xvt_chr_is_alnum(k) || strchr("\r+-*/",k) != NULL)) 
 | 
						|
      key += K_CTRL;
 | 
						|
  }
 | 
						|
  return key;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// @doc INTERNAL
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TPicture_array
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
class TPicture_array
 | 
						|
{
 | 
						|
  TArray _enabled, _disabled;
 | 
						|
 | 
						|
public:
 | 
						|
  bool add(int id);
 | 
						|
  int add(const char* n);
 | 
						|
  int add_icon(int id);
 | 
						|
 | 
						|
  const TImage& image(int id) const { return (const TImage&)_enabled[id]; }
 | 
						|
  const TImage& disabled_image(int id) const { return (const TImage&)_disabled[id]; }
 | 
						|
  bool exist(int id) const { return _enabled.objptr(id) != NULL; }
 | 
						|
  void reload();
 | 
						|
 | 
						|
  TPicture_array() {}
 | 
						|
  virtual ~TPicture_array() {}
 | 
						|
};
 | 
						|
 | 
						|
int TPicture_array::add(const char* n)
 | 
						|
{
 | 
						|
	int id;  // calcola il prossimo identificatore di immagine libero
 | 
						|
	for (id = 30000; _enabled.objptr(id) != NULL; id++);
 | 
						|
 | 
						|
  TImage* i = new TImage(n);
 | 
						|
	_enabled.add(i, id);
 | 
						|
 | 
						|
  TImage* d = new TImage(*i);
 | 
						|
  d->fade_to_gray(true);
 | 
						|
  _disabled.add(d, id);
 | 
						|
 | 
						|
  return id;
 | 
						|
}
 | 
						|
 | 
						|
int TPicture_array::add_icon(int id)
 | 
						|
{
 | 
						|
  const int rid = 50000+id;
 | 
						|
  TImage* i = (TImage*)_enabled.objptr(rid);
 | 
						|
  if (i == NULL)
 | 
						|
  {
 | 
						|
    TImage* i = new TImage(id, true); // id is an icon identifier!
 | 
						|
	  _enabled.add(i, rid);
 | 
						|
    TImage* d = new TImage(*i);
 | 
						|
    d->fade_to_gray(true);
 | 
						|
    _disabled.add(d, rid);
 | 
						|
  }
 | 
						|
  return rid;
 | 
						|
}
 | 
						|
 | 
						|
bool TPicture_array::add(int id)
 | 
						|
{
 | 
						|
  TImage* i = (TImage*)_enabled.objptr(id);
 | 
						|
  if (i == NULL)
 | 
						|
  {
 | 
						|
    i = new TImage(id);
 | 
						|
		if (i->ok())
 | 
						|
		{
 | 
						|
      i->convert_transparent_color(BTN_BACK_COLOR);
 | 
						|
      _enabled.add(i, id);
 | 
						|
 | 
						|
      TImage* d = new TImage(*i);
 | 
						|
      d->fade_to_gray(true);
 | 
						|
      _disabled.add(d, id);
 | 
						|
		}
 | 
						|
		else
 | 
						|
		{
 | 
						|
			delete i;
 | 
						|
			i = NULL;
 | 
						|
		}
 | 
						|
  }
 | 
						|
  return i != NULL;
 | 
						|
}   
 | 
						|
 | 
						|
void TPicture_array::reload()
 | 
						|
{    
 | 
						|
  _disabled.destroy();
 | 
						|
  for (int id = _enabled.last(); id > 0; id = _enabled.pred(id))
 | 
						|
  {
 | 
						|
    _enabled.destroy(id);
 | 
						|
    add(id);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// Utility functions
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
HIDDEN TPicture_array* _picture = NULL;
 | 
						|
HIDDEN XVT_FNTID DEF_FONT = NULL;
 | 
						|
HIDDEN XVT_FNTID FAT_FONT = NULL;
 | 
						|
HIDDEN XVT_FNTID BIG_FONT = NULL;
 | 
						|
HIDDEN XVT_FNTID BIGFAT_FONT = NULL;
 | 
						|
 | 
						|
bool is_xvt_font(const char * nome_font)
 | 
						|
{
 | 
						|
  const int max_fonts = 1024;
 | 
						|
  char * fonts[max_fonts];
 | 
						|
  const int num_fonts = xvt_fmap_get_families(NULL, fonts, max_fonts);
 | 
						|
  bool found = false;
 | 
						|
  for (int i = num_fonts-1; i >= 0; i--)
 | 
						|
  {
 | 
						|
    if (!found && xvt_str_compare_ignoring_case(fonts[i], nome_font) == 0)
 | 
						|
      found = true;
 | 
						|
    xvt_mem_free(fonts[i]);
 | 
						|
  }
 | 
						|
  return found;
 | 
						|
}
 | 
						|
 | 
						|
XVT_FNTID xvtil_default_font(bool bold, bool big)
 | 
						|
{
 | 
						|
  if (DEF_FONT == NULL)
 | 
						|
  {
 | 
						|
    DEF_FONT = xvt_dwin_get_font(TASK_WIN);
 | 
						|
 | 
						|
    TConfig font(CONFIG_GUI, "Colors");
 | 
						|
    TString font_ser_desc = font.get("FontDesc");    // Modernamente e' nel paragrafo Colors
 | 
						|
    INTERLINE = font.get_int("InterLine", NULL, -1, -1); 
 | 
						|
 | 
						|
    if (font_ser_desc.empty())
 | 
						|
    {
 | 
						|
      const char* name = "Verdana";
 | 
						|
      font_ser_desc.format("01\\%s\\0\\8\\WIN01/8/0/0/0/400/0/0/0/0/1/2/1/49/%s", name, name);
 | 
						|
      font.set("FontDesc", font_ser_desc, "Colors", true); // Salva definitivamente il font
 | 
						|
    }
 | 
						|
 | 
						|
    xvt_font_deserialize(DEF_FONT, font_ser_desc);
 | 
						|
    xvt_font_map_using_default(DEF_FONT);
 | 
						|
    CHECK(xvt_font_is_mapped(DEF_FONT), "Can't map native font");
 | 
						|
 | 
						|
    xvt_dwin_set_font(TASK_WIN, DEF_FONT);
 | 
						|
  
 | 
						|
    xi_set_font_id(DEF_FONT);
 | 
						|
  	xi_init_sysvals();  // Ricalcola i FU units
 | 
						|
 | 
						|
    CHARX = xi_get_fu_width(NULL);
 | 
						|
    CHARY = xi_get_fu_height(NULL);
 | 
						|
 | 
						|
    // Compute suitable text size
 | 
						|
    if (xvt_sys_is_pda()) // Schermo piccolo da terminalino
 | 
						|
    {    
 | 
						|
      ROWY = CHARY;
 | 
						|
    }
 | 
						|
    else      
 | 
						|
    {
 | 
						|
      //calcolo interlinea se non specificata dall'utente
 | 
						|
      if (INTERLINE < 0)  //interlinea automatica
 | 
						|
      {
 | 
						|
        const PNT pnt = xvtil_taskwin_size();
 | 
						|
        ROWY = max(CHARY, pnt.v/MAX_MASK_ROWS);
 | 
						|
      }
 | 
						|
      else
 | 
						|
        ROWY = CHARY + INTERLINE;
 | 
						|
    }
 | 
						|
    XI_PNT fu = { ROWY, CHARX };
 | 
						|
    xi_pu_to_fu(NULL, &fu, 1);
 | 
						|
    xi_fu_to_pu(NULL, &fu, 1);
 | 
						|
    CHARX = fu.h;
 | 
						|
    ROWY = fu.v;
 | 
						|
 | 
						|
    xvt_menu_set_font_sel(TASK_WIN, DEF_FONT);
 | 
						|
 | 
						|
    FAT_FONT = xvt_font_create();
 | 
						|
    xvt_font_copy(FAT_FONT, DEF_FONT, XVT_FA_ALL);
 | 
						|
    xvt_font_set_style(FAT_FONT, XVT_FS_BOLD);
 | 
						|
    xvt_font_map_using_default(FAT_FONT);
 | 
						|
    CHECK(xvt_font_is_mapped(FAT_FONT), "Can't map native font");
 | 
						|
 | 
						|
    BIG_FONT = xvt_font_create();
 | 
						|
    xvt_font_copy(BIG_FONT, DEF_FONT, XVT_FA_ALL);
 | 
						|
    xvt_font_set_size(BIG_FONT, xvt_font_get_size(DEF_FONT) * 2);
 | 
						|
    xvt_font_map_using_default(BIG_FONT);
 | 
						|
    CHECK(xvt_font_is_mapped(BIG_FONT), "Can't map native font");
 | 
						|
 | 
						|
    BIGFAT_FONT = xvt_font_create();
 | 
						|
    xvt_font_copy(BIGFAT_FONT, FAT_FONT, XVT_FA_ALL);
 | 
						|
    xvt_font_set_size(BIGFAT_FONT, xvt_font_get_size(FAT_FONT) * 2);
 | 
						|
    xvt_font_map_using_default(BIGFAT_FONT);
 | 
						|
    CHECK(xvt_font_is_mapped(BIGFAT_FONT), "Can't map native font");
 | 
						|
  }
 | 
						|
 | 
						|
  XVT_FNTID f = NULL;
 | 
						|
	if (bold)
 | 
						|
  	f = big ? BIGFAT_FONT : FAT_FONT;
 | 
						|
	else
 | 
						|
		f = big ? BIG_FONT : DEF_FONT;
 | 
						|
	return f;
 | 
						|
}
 | 
						|
 | 
						|
XVT_FNTID xvtil_load_default_font()
 | 
						|
{
 | 
						|
  if (DEF_FONT)
 | 
						|
  {
 | 
						|
    xvt_font_destroy(DEF_FONT);
 | 
						|
    DEF_FONT = NULL;
 | 
						|
  }
 | 
						|
  if (FAT_FONT)
 | 
						|
  {
 | 
						|
    xvt_font_destroy(FAT_FONT);
 | 
						|
    FAT_FONT = NULL;
 | 
						|
  }           
 | 
						|
  if (BIG_FONT)
 | 
						|
  {
 | 
						|
    xvt_font_destroy(BIG_FONT);
 | 
						|
    BIG_FONT = NULL;
 | 
						|
  }           
 | 
						|
  if (BIGFAT_FONT)
 | 
						|
  {
 | 
						|
    xvt_font_destroy(BIGFAT_FONT);
 | 
						|
    BIGFAT_FONT = NULL;
 | 
						|
  }           
 | 
						|
  
 | 
						|
  XVT_FNTID font =  xvtil_default_font();
 | 
						|
  statbar_set_fontid(TASK_WIN, font);
 | 
						|
  
 | 
						|
  return font;
 | 
						|
}
 | 
						|
 | 
						|
#define XI_INVALID_BITMAP ((XI_BITMAP*)-1)
 | 
						|
 | 
						|
HIDDEN XI_BITMAP* get_background_bitmap(bool reload)
 | 
						|
{
 | 
						|
  static XI_BITMAP* bmp = XI_INVALID_BITMAP;
 | 
						|
  if (reload || bmp == XI_INVALID_BITMAP)
 | 
						|
  {
 | 
						|
    if (bmp != NULL && bmp != XI_INVALID_BITMAP)
 | 
						|
      xi_bitmap_destroy(bmp);
 | 
						|
    bmp = NULL;
 | 
						|
    if (ADVANCED_GRAPHICS && !xi_get_pref(XI_PREF_NATIVE_CTRLS))
 | 
						|
    {
 | 
						|
      TFilename back = ini_get_string(CONFIG_GUI, "Colors", "Tile");
 | 
						|
      if (back.custom_path())
 | 
						|
      {
 | 
						|
        bmp = xi_bitmap_create(back.get_buffer(), XI_BITMAP_TILE);
 | 
						|
        if (bmp != NULL)
 | 
						|
        {
 | 
						|
          XVT_IMAGE img = (XVT_IMAGE)bmp->xin_bitmap->x;
 | 
						|
          short k, w, h; xvt_image_get_dimensions(img, &w, &h);
 | 
						|
 | 
						|
          unsigned long r=0, g=0, b=0;
 | 
						|
          for (k = 0; k < w && k < h; k++)
 | 
						|
          {
 | 
						|
            const COLOR col = xvt_image_get_pixel(img, k, k);
 | 
						|
            r += XVT_COLOR_GET_RED(col);
 | 
						|
            g += XVT_COLOR_GET_GREEN(col);
 | 
						|
            b += XVT_COLOR_GET_BLUE(col);
 | 
						|
          }
 | 
						|
          r = (r+k/2)/k; g = (g+k/2)/k; b = (b+k/2)/k;
 | 
						|
          MASK_BACK_COLOR = XVT_MAKE_COLOR(r, g, b); // Mean texture color
 | 
						|
          MASK_LIGHT_COLOR = blend_colors(COLOR_WHITE, MASK_BACK_COLOR);
 | 
						|
          MASK_DARK_COLOR = blend_colors(COLOR_BLACK, MASK_BACK_COLOR);
 | 
						|
 | 
						|
          if (w > 512 || h > 512)
 | 
						|
          {
 | 
						|
            bmp->mode = XI_BITMAP_NORMAL;
 | 
						|
            bmp->hcenter = bmp->vcenter = TRUE;
 | 
						|
            bmp->background = MASK_BACK_COLOR;
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return bmp;
 | 
						|
}
 | 
						|
 | 
						|
XVT_IMAGE get_background_texture()
 | 
						|
{
 | 
						|
  XVT_IMAGE img = NULL;
 | 
						|
  XI_BITMAP* bmp = get_background_bitmap(false);
 | 
						|
  if (bmp != NULL)
 | 
						|
    img = (XVT_IMAGE)bmp->xin_bitmap->x;
 | 
						|
  return img;
 | 
						|
}
 | 
						|
 | 
						|
static byte event_map[XIE_LAST_EVENT];
 | 
						|
 | 
						|
enum event_action { a_ignore, a_xvt, a_xvt_post, a_obj, a_child, a_update, a_select, a_post, a_debug };
 | 
						|
 | 
						|
 | 
						|
// @func Permette di aggiornare i colori attivi del programma
 | 
						|
void customize_colors()
 | 
						|
 | 
						|
  // @comm Legge dal file di configurazione i colori scelti dall'utente e
 | 
						|
  //       ne setta le variabili in modo da poter personalizzare i colori
 | 
						|
  //
 | 
						|
  // @xref <c TConfig>
 | 
						|
  
 | 
						|
{    
 | 
						|
  TConfig colors(CONFIG_GUI, "Colors");
 | 
						|
  
 | 
						|
  MASK_BACK_COLOR = colors.get_color("MaskBack", NULL, -1, MASK_BACK_COLOR);
 | 
						|
  MASK_LIGHT_COLOR = colors.get_color("MaskLight", NULL, -1, MASK_LIGHT_COLOR);
 | 
						|
  MASK_DARK_COLOR = colors.get_color("MaskDark", NULL, -1, MASK_DARK_COLOR);
 | 
						|
  NORMAL_COLOR = colors.get_color("Normal", NULL, -1, NORMAL_COLOR);
 | 
						|
  NORMAL_BACK_COLOR = colors.get_color("NormalBack", NULL, -1, NORMAL_BACK_COLOR);
 | 
						|
  PROMPT_COLOR = colors.get_color("Prompt", NULL, -1, PROMPT_COLOR);
 | 
						|
  REQUIRED_BACK_COLOR = colors.get_color("RequiredBack", NULL, -1, REQUIRED_BACK_COLOR);
 | 
						|
  DISABLED_COLOR = colors.get_color("Disabled", NULL, -1, DISABLED_COLOR);
 | 
						|
  DISABLED_BACK_COLOR = colors.get_color("DisabledBack", NULL, -1, DISABLED_BACK_COLOR);
 | 
						|
  FOCUS_COLOR = colors.get_color("Focus", NULL, -1, FOCUS_COLOR);
 | 
						|
  FOCUS_BACK_COLOR = colors.get_color("FocusBack", NULL, -1, FOCUS_BACK_COLOR);
 | 
						|
  CAMPI_SCAVATI = colors.get_bool("Campi3D", NULL, -1, CAMPI_SCAVATI);
 | 
						|
  AUTOSELECT = colors.get_bool("AutoSelect", NULL, -1, AUTOSELECT);
 | 
						|
  AUTOZOOM = colors.get_bool("AutoZoom", NULL, -1, AUTOZOOM);
 | 
						|
  ADVANCED_GRAPHICS = colors.get_bool("AdvancedGraphics", NULL, -1, ADVANCED_GRAPHICS);
 | 
						|
  EASY_RIDER = colors.get_bool("EasyRider", NULL, -1, EASY_RIDER);
 | 
						|
  EASY_RIDER_COLOR = blend_colors(NORMAL_BACK_COLOR, DISABLED_BACK_COLOR, 0.5);
 | 
						|
  NATIVE_CONTROLS = colors.get_bool("NativeControls", NULL, -1, NATIVE_CONTROLS);
 | 
						|
  xi_set_pref(XI_PREF_NATIVE_CTRLS, ADVANCED_GRAPHICS && NATIVE_CONTROLS);
 | 
						|
  ENTER_AS_TAB = colors.get_bool("EnterAsTab", NULL, -1, ENTER_AS_TAB);
 | 
						|
  ANIMATED_BOXES = is_power_reseller() && colors.get_bool("AnimatedBoxes", NULL, -1, ANIMATED_BOXES);
 | 
						|
 | 
						|
  TOOL_SIZE = colors.get_int("ToolSize", NULL, -1, TOOL_SIZE);
 | 
						|
  TOOL_TEXT = colors.get_bool("ToolText", NULL, -1, TOOL_TEXT);
 | 
						|
  get_background_bitmap(true); // Reload background bitmap
 | 
						|
 | 
						|
  const int SPEECH_MODE = is_power_reseller() ? colors.get_int("SpeechMode", NULL, -1, 0) : 0;
 | 
						|
  xvt_vobj_set_attr(NULL_WIN, ATTR_SPEECH_MODE, SPEECH_MODE);
 | 
						|
 | 
						|
  xi_set_pref(XI_PREF_COLOR_LIGHT,    MASK_LIGHT_COLOR);
 | 
						|
  xi_set_pref(XI_PREF_COLOR_CTRL,     MASK_BACK_COLOR);
 | 
						|
  xi_set_pref(XI_PREF_COLOR_DARK,     MASK_DARK_COLOR);
 | 
						|
  xi_set_pref(XI_PREF_COLOR_DISABLED, DISABLED_COLOR);
 | 
						|
 | 
						|
  XVT_COLOR_COMPONENT xcc[8]; memset(xcc, 0, sizeof(xcc));
 | 
						|
  xcc[0].type = XVT_COLOR_BACKGROUND;	xcc[0].color = NORMAL_BACK_COLOR;
 | 
						|
  xcc[1].type = XVT_COLOR_FOREGROUND;	xcc[1].color = NORMAL_COLOR;
 | 
						|
  xcc[2].type = XVT_COLOR_HIGHLIGHT;	xcc[2].color = FOCUS_COLOR;
 | 
						|
  xcc[3].type = XVT_COLOR_SELECT;	    xcc[3].color = FOCUS_BACK_COLOR;
 | 
						|
  xvt_vobj_set_attr(TASK_WIN, ATTR_APP_CTL_COLORS, (long)xcc);
 | 
						|
 | 
						|
  BTN_BACK_COLOR = colors.get_color("ButtonBack", NULL, -1, BTN_BACK_COLOR);
 | 
						|
  aga_set_pref(AGA_PREF_BTN_COLOR_CTRL, BTN_BACK_COLOR);
 | 
						|
 | 
						|
  BTN_LIGHT_COLOR = colors.get_color("ButtonLight", NULL, -1, BTN_LIGHT_COLOR);
 | 
						|
  aga_set_pref(AGA_PREF_BTN_COLOR_LIGHT, BTN_LIGHT_COLOR);
 | 
						|
 | 
						|
  BTN_DARK_COLOR = colors.get_color("ButtonDark", NULL, -1, BTN_DARK_COLOR);
 | 
						|
  aga_set_pref(AGA_PREF_BTN_COLOR_DARK, BTN_DARK_COLOR);
 | 
						|
  
 | 
						|
  if (_picture)
 | 
						|
    _picture->reload();
 | 
						|
    
 | 
						|
  xvtil_load_default_font(); // Aggiorna anche il font!  
 | 
						|
}
 | 
						|
 | 
						|
static bool campi_scavati() { return CAMPI_SCAVATI && ADVANCED_GRAPHICS; }
 | 
						|
 | 
						|
void init_controls()
 | 
						|
{
 | 
						|
  xi_set_font_id(xvtil_load_default_font());
 | 
						|
 | 
						|
  xi_set_pref(XI_PREF_NATIVE_CTRLS, NATIVE_CONTROLS && ADVANCED_GRAPHICS);
 | 
						|
  xi_set_pref(XI_PREF_3D_LOOK,      campi_scavati());
 | 
						|
  xi_set_pref(XI_PREF_CARET_WIDTH,  2);
 | 
						|
  xi_set_pref(XI_PREF_COMBO_ICON,   ICO_COMBO);
 | 
						|
  xi_set_pref(XI_PREF_OPTIMIZE_CELL_REQUESTS, TRUE);
 | 
						|
 | 
						|
  xi_init();
 | 
						|
 | 
						|
  memset(event_map, a_ignore, sizeof(event_map));
 | 
						|
  event_map[XIE_CHAR_FIELD]     = a_obj;
 | 
						|
  event_map[XIE_DBL_FIELD]      = a_obj;
 | 
						|
  event_map[XIE_CHG_FIELD]      = a_obj;
 | 
						|
  event_map[XIE_OFF_FIELD]      = a_obj;
 | 
						|
  event_map[XIE_ON_FIELD]       = a_obj;
 | 
						|
  event_map[XIE_OFF_GROUP]      = a_ignore;
 | 
						|
  event_map[XIE_ON_GROUP]       = a_ignore;
 | 
						|
  event_map[XIE_OFF_FORM]       = a_ignore;
 | 
						|
  event_map[XIE_ON_FORM]        = a_ignore;
 | 
						|
  event_map[XIE_VIR_PAN]        = a_ignore;
 | 
						|
  event_map[XIE_XVT_EVENT]      = a_xvt;
 | 
						|
  event_map[XIE_XVT_POST_EVENT] = a_xvt_post;
 | 
						|
  event_map[XIE_INIT]           = a_ignore;
 | 
						|
  event_map[XIE_BUTTON]         = a_obj;
 | 
						|
  event_map[XIE_CHAR_CELL]      = a_child;
 | 
						|
  event_map[XIE_CLEANUP]        = a_ignore;
 | 
						|
  event_map[XIE_CLOSE]          = a_ignore;
 | 
						|
  event_map[XIE_COMMAND]        = a_ignore;
 | 
						|
  event_map[XIE_DBL_CELL]       = a_child;
 | 
						|
  event_map[XIE_GET_FIRST]      = a_obj;
 | 
						|
  event_map[XIE_GET_LAST]       = a_obj;
 | 
						|
  event_map[XIE_GET_NEXT]       = a_obj;
 | 
						|
  event_map[XIE_GET_PERCENT]    = a_obj;
 | 
						|
  event_map[XIE_GET_PREV]       = a_obj;
 | 
						|
  event_map[XIE_CELL_REQUEST]   = a_obj;
 | 
						|
  event_map[XIE_CHG_CELL]       = a_child;
 | 
						|
  event_map[XIE_OFF_CELL]       = a_child;
 | 
						|
  event_map[XIE_ON_CELL]        = a_child;
 | 
						|
  event_map[XIE_OFF_ROW]        = a_child;
 | 
						|
  event_map[XIE_ON_ROW]         = a_child;
 | 
						|
  event_map[XIE_OFF_COLUMN]     = a_ignore;
 | 
						|
  event_map[XIE_ON_COLUMN]      = a_ignore;
 | 
						|
  event_map[XIE_OFF_LIST]       = a_obj;
 | 
						|
  event_map[XIE_ON_LIST]        = a_obj;
 | 
						|
  event_map[XIE_REC_ALLOCATE]   = a_ignore;
 | 
						|
  event_map[XIE_REC_FREE]       = a_ignore;
 | 
						|
  event_map[XIE_ROW_SIZE]       = a_ignore;
 | 
						|
  event_map[XIE_SELECT]         = a_select;
 | 
						|
  event_map[XIE_UPDATE]         = a_update;
 | 
						|
  event_map[XIE_COL_DELETE]     = a_ignore;
 | 
						|
  event_map[XIE_COL_MOVE]       = a_obj;
 | 
						|
  event_map[XIE_COL_SIZE]       = a_obj;
 | 
						|
  event_map[XIE_POST_NAVIGATION]= a_post;
 | 
						|
 | 
						|
  if (_picture == NULL)
 | 
						|
    _picture = new TPicture_array;
 | 
						|
}
 | 
						|
 | 
						|
void free_controls()
 | 
						|
{
 | 
						|
  if (_picture)
 | 
						|
  {
 | 
						|
    delete _picture;
 | 
						|
    _picture = NULL;
 | 
						|
  }
 | 
						|
  if (DEF_FONT)
 | 
						|
  {
 | 
						|
    xvt_font_destroy(DEF_FONT);
 | 
						|
    DEF_FONT = NULL;
 | 
						|
  }
 | 
						|
  if (FAT_FONT)
 | 
						|
  {
 | 
						|
    xvt_font_destroy(FAT_FONT);
 | 
						|
    FAT_FONT = NULL;
 | 
						|
  }
 | 
						|
  if (BIG_FONT)
 | 
						|
  {
 | 
						|
    xvt_font_destroy(BIG_FONT);
 | 
						|
    BIG_FONT = NULL;
 | 
						|
  }           
 | 
						|
}
 | 
						|
 | 
						|
bool has_virtual_keyboard()
 | 
						|
{
 | 
						|
  static bool hvk = ini_get_bool(CONFIG_INSTALL, "Main", "VirtualKeyboard");
 | 
						|
  return hvk;
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// Interface creation
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
HIDDEN void xi_event_handler(XI_OBJ *itf, XI_EVENT *xiev);
 | 
						|
 | 
						|
WINDOW create_interface(WINDOW parent, short x, short y, short dx, short dy,
 | 
						|
                        const char* caption, TWindow* msk)
 | 
						|
{
 | 
						|
  if (parent == NULL_WIN)
 | 
						|
    parent = TASK_WIN;
 | 
						|
 | 
						|
  short left   =  x * CHARX;
 | 
						|
  short top    =  y * ROWY;
 | 
						|
  short width  = dx * CHARX + (dx > 0 ? CHARX : 0);
 | 
						|
  short height = dy * ROWY  + (dy > 0 ? ROWY  : 0);
 | 
						|
 | 
						|
  if (x <= 0 || y <= 0 || dx <= 0 || dy <= 0)
 | 
						|
  {
 | 
						|
    RCT max_rct; xvt_vobj_get_client_rect(parent, &max_rct);
 | 
						|
    if (dy <= 0)
 | 
						|
    {
 | 
						|
      // Gestisce centrature e caso particolare di bottombar di una riga
 | 
						|
      if (y < -1 || (y == -1 && (dy == 0 || dy == 1))) 
 | 
						|
      { 
 | 
						|
        height = -top;
 | 
						|
        top += max_rct.bottom;
 | 
						|
        y = (max_rct.bottom-height)/ROWY;   // MAX_MASK_ROWS - height/ROWY;
 | 
						|
      }
 | 
						|
      else
 | 
						|
        height = max_rct.bottom - top + dy * ROWY;
 | 
						|
    }
 | 
						|
 | 
						|
    if (dx <= 0)
 | 
						|
    {
 | 
						|
      width = max_rct.right + dx * CHARX;
 | 
						|
      if (left > 0) 
 | 
						|
        width -= left;
 | 
						|
    }
 | 
						|
 | 
						|
    if (x < 0 && dx != 0) left = (max_rct.right - width) / 2;
 | 
						|
    if (y < 0 && dy != 0) top = (max_rct.bottom - height) / 2;
 | 
						|
  }
 | 
						|
  RCT r; xvt_rect_set(&r, left, top, left+width, top+height);
 | 
						|
 | 
						|
  const WIN_TYPE wt = (dx == 0) ? W_PLAIN : W_DOC;
 | 
						|
  long wsf = WSF_INVISIBLE | WSF_NO_MENUBAR;
 | 
						|
 | 
						|
  WINDOW win = xvt_win_create(wt, &r, caption, 0L, parent, wsf,
 | 
						|
                             EM_ALL, (EVENT_HANDLER)xi_event, (long)msk);
 | 
						|
  CHECK(win, "Can't create an XVT window for an interface");
 | 
						|
	xvtil_set_font(win, NULL, 0, 0);
 | 
						|
 | 
						|
  XI_RCT xrct; xrct = (XI_RCT&)r; xi_pu_to_fu(NULL, (XI_PNT*)&xrct, 2);
 | 
						|
  XI_OBJ_DEF* def = xi_create_itf_def(ITF_CID, xi_event_handler, &xrct, (char*)caption, (long)msk);
 | 
						|
  CHECK(def, "Can't define an interface");
 | 
						|
 | 
						|
  def->v.itf->automatic_back_color = false;
 | 
						|
  def->v.itf->back_color = MASK_BACK_COLOR;
 | 
						|
  def->v.itf->font_id = xvtil_default_font();
 | 
						|
  def->v.itf->tab_on_enter = true;
 | 
						|
  def->v.itf->win = (XinWindow)win;
 | 
						|
  def->v.itf->edit_menu = true;                 // Update edit menu items
 | 
						|
  def->v.itf->menu_win = (XinWindow)TASK_WIN;   // Window that owns the menu
 | 
						|
 | 
						|
  XI_BITMAP* bmpback = get_background_bitmap(false);
 | 
						|
  if (bmpback != NULL)
 | 
						|
  {
 | 
						|
    def->v.itf->back_color = 0;
 | 
						|
    def->v.itf->bitmap = bmpback;
 | 
						|
  }
 | 
						|
 | 
						|
  XI_OBJ* itf = xi_create(NULL, def);
 | 
						|
  CHECK(itf, "Can't create an interface");
 | 
						|
 | 
						|
  xi_dequeue();
 | 
						|
  xi_tree_free(def);
 | 
						|
 | 
						|
  if (dx > 0 && dy > 0)
 | 
						|
  {
 | 
						|
    xi_pu_to_fu(itf, (XI_PNT*)&r, 2);
 | 
						|
    r.right  = r.left + (dx+1) * XI_FU_MULTIPLE;
 | 
						|
    r.bottom = r.top  + (dy+1) * XI_FU_MULTIPLE;
 | 
						|
    xi_fu_to_pu(itf, (XI_PNT*)&r, 2);
 | 
						|
    xvt_vobj_move(win, &r); // Forza dimensioni corrette client area
 | 
						|
  }
 | 
						|
  return win;
 | 
						|
}
 | 
						|
 | 
						|
void attach_interface(WINDOW win, COLOR back)
 | 
						|
{
 | 
						|
  xvt_win_set_handler(win, (EVENT_HANDLER)xi_event);
 | 
						|
 | 
						|
  RCT rc; xvt_vobj_get_outer_rect(win, &rc);
 | 
						|
 | 
						|
  char caption[80]; xvt_vobj_get_title(win, caption, 80);
 | 
						|
  TWindow* parent = (TWindow*)xvt_vobj_get_data(win);
 | 
						|
  XI_OBJ_DEF* def = xi_create_itf_def(ITF_CID, xi_event_handler, (XI_RCT*)&rc, caption, (long)parent);
 | 
						|
  CHECK(def, "Can't define an interface");
 | 
						|
 | 
						|
  def->v.itf->automatic_back_color = false;
 | 
						|
  def->v.itf->back_color = back;
 | 
						|
  def->v.itf->tab_on_enter = true;
 | 
						|
  def->v.itf->win = (XinWindow)win;
 | 
						|
 | 
						|
  XI_OBJ* itf = xi_create(NULL, def);
 | 
						|
  CHECK(itf, "Can't create an interface");
 | 
						|
 | 
						|
  xi_dequeue();
 | 
						|
  xi_tree_free(def);
 | 
						|
}
 | 
						|
 | 
						|
HIDDEN void xi_event_handler(XI_OBJ* itf, XI_EVENT* xiev)
 | 
						|
{
 | 
						|
  static bool notify_xvt = true;
 | 
						|
 | 
						|
  TControl* ctl = NULL;
 | 
						|
 | 
						|
  switch (event_map[xiev->type])
 | 
						|
  {
 | 
						|
  case a_obj:
 | 
						|
    if (xiev->v.xi_obj)
 | 
						|
      ctl = (TControl*)xi_get_app_data(xiev->v.xi_obj);
 | 
						|
    break;
 | 
						|
  case a_child:
 | 
						|
    ctl = (TControl*)xi_get_app_data(xiev->v.xi_obj->parent);
 | 
						|
    break;
 | 
						|
  case a_update:
 | 
						|
    {
 | 
						|
      int num;
 | 
						|
      XI_OBJ** button = xi_get_member_list(itf, &num);
 | 
						|
      for (int i = num-1; i >= 0; i--)
 | 
						|
      {
 | 
						|
        XI_OBJ* b = button[i];
 | 
						|
        if (b->type == XIT_BTN && b->v.btn->drawable)
 | 
						|
        {
 | 
						|
          if (xvt_rect_intersect(NULL, (RCT*)&b->v.btn->rct, &xiev->v.xvte.v.update.rct))
 | 
						|
          {
 | 
						|
            TPushbutton_control* p = (TPushbutton_control*)b->app_data;
 | 
						|
            p->update();
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case a_select:
 | 
						|
    switch(xiev->v.xi_obj->type)
 | 
						|
    {
 | 
						|
    case XIT_LIST: ctl = (TControl*)xi_get_app_data(xiev->v.xi_obj); break;
 | 
						|
    case XIT_ROW :
 | 
						|
    case XIT_CELL: ctl = (TControl*)xi_get_app_data(xiev->v.xi_obj->parent); break;
 | 
						|
    default      : break;
 | 
						|
    }
 | 
						|
    break;  
 | 
						|
  case a_xvt:
 | 
						|
    switch (xiev->v.xvte.type)
 | 
						|
    {
 | 
						|
    case E_MOUSE_DOWN:
 | 
						|
      _last_mouse_button = xiev->v.xvte.v.mouse.button;
 | 
						|
      break;
 | 
						|
    case E_CHAR:
 | 
						|
      {
 | 
						|
        XI_OBJ* fo = xi_get_focus(itf);
 | 
						|
        if (fo != NULL && fo->type == XIT_CELL)
 | 
						|
          ctl = (TControl*)xi_get_app_data(fo->parent);
 | 
						|
      }
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      break;  
 | 
						|
    }  
 | 
						|
    break;
 | 
						|
  case a_xvt_post:
 | 
						|
    if (notify_xvt && xiev->v.xvte.type != 0)
 | 
						|
    {
 | 
						|
      TWindow* w = (TWindow*)xi_get_app_data(itf);
 | 
						|
      WINDOW win = NULL_WIN;
 | 
						|
      if (w != NULL)
 | 
						|
      {
 | 
						|
        if (w->is_kind_of(CLASS_MASK))
 | 
						|
          win = ((TMask*)w)->curr_win();
 | 
						|
        else
 | 
						|
          win = w->win();
 | 
						|
      }
 | 
						|
      if (win != NULL_WIN)
 | 
						|
      {
 | 
						|
        switch (xiev->v.xvte.type)
 | 
						|
        {
 | 
						|
        case E_CONTROL:
 | 
						|
          switch (xiev->v.xvte.v.ctl.ci.type)
 | 
						|
          {
 | 
						|
          case WC_PUSHBUTTON:
 | 
						|
          case WC_RADIOBUTTON:
 | 
						|
          case WC_CHECKBOX:
 | 
						|
            break; // Ignora i bottoni altrimenti li preme due volte se nativi
 | 
						|
          default:
 | 
						|
            w->handler(win, &xiev->v.xvte);
 | 
						|
            break;
 | 
						|
          }
 | 
						|
          break;
 | 
						|
        default:
 | 
						|
          w->handler(win, &xiev->v.xvte);
 | 
						|
          break;
 | 
						|
        }          
 | 
						|
      }
 | 
						|
    }
 | 
						|
    else
 | 
						|
      notify_xvt = true;
 | 
						|
    break;
 | 
						|
  case a_post:
 | 
						|
    {
 | 
						|
      XI_OBJ * obj = xi_get_focus(itf);
 | 
						|
 | 
						|
      if ((obj != NULL && obj->type != XIT_ITF))
 | 
						|
      {
 | 
						|
        if ((obj->type == XIT_CELL || (obj->type == XIT_BTN && obj->v.btn->type == XIBT_RADIOBTN)))
 | 
						|
          obj = obj->parent;
 | 
						|
        CHECK(obj != NULL, "Unexpected null obj");
 | 
						|
        ctl = (TControl*)xi_get_app_data(obj);
 | 
						|
      }
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case a_debug:
 | 
						|
    break;         // Put your breakpoint here
 | 
						|
  default:
 | 
						|
    break;
 | 
						|
  }
 | 
						|
 | 
						|
  if (ctl != NULL)
 | 
						|
  {
 | 
						|
    const bool ok = ctl->event_handler(itf, xiev);
 | 
						|
    if (!ok)
 | 
						|
    {
 | 
						|
      xiev->refused = true;
 | 
						|
      if (xiev->type == XIE_CHAR_FIELD || xiev->type == XIE_CHAR_CELL ||
 | 
						|
          xiev->type == XIE_XVT_EVENT || xiev->type == XIE_BUTTON)
 | 
						|
        notify_xvt = false;
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TControl
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
TControl::TControl()
 | 
						|
        : _obj(NULL), _fld(NULL)
 | 
						|
{}
 | 
						|
 | 
						|
// Virtual destructor needed to make derived descrutors live!
 | 
						|
TControl::~TControl()
 | 
						|
{}
 | 
						|
 | 
						|
XI_OBJ* TControl::get_interface(WINDOW win) const
 | 
						|
{
 | 
						|
  XI_OBJ* itf;
 | 
						|
  if (win == NULL_WIN)
 | 
						|
  {
 | 
						|
    CHECK(_obj, "Can't get the interface from NULL XI object");
 | 
						|
    itf = _obj->itf;
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    itf = xi_get_itf((XinWindow)win);
 | 
						|
    CHECK(itf, "Can't get the interface from a window");
 | 
						|
  }
 | 
						|
  return itf;
 | 
						|
}
 | 
						|
 | 
						|
void TControl::set_tab_cid(XI_OBJ* obj, short cid) const
 | 
						|
{
 | 
						|
  CHECK(obj, "Can't set tab cid to null control");
 | 
						|
    
 | 
						|
  switch(obj->type)
 | 
						|
  {
 | 
						|
  case XIT_BTN:
 | 
						|
    obj->v.btn->tab_cid = cid; 
 | 
						|
    break;
 | 
						|
  case XIT_CONTAINER:
 | 
						|
    obj->v.container->tab_cid = cid; 
 | 
						|
    break;
 | 
						|
  case XIT_FIELD:
 | 
						|
    obj->v.field->tab_cid = cid;
 | 
						|
    break;
 | 
						|
  case XIT_FORM:
 | 
						|
    obj->v.form->tab_cid = cid; 
 | 
						|
    break;
 | 
						|
  case XIT_LIST:
 | 
						|
    obj->v.list->tab_cid = cid; 
 | 
						|
    break;
 | 
						|
  case XIT_COLUMN:     
 | 
						|
    obj->parent->v.list->tab_cid = cid;
 | 
						|
    break;  
 | 
						|
  default:
 | 
						|
    NFCHECK(0, "Can't set tab_cid to a static control: ", _obj->cid); break;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
HIDDEN bool is_container(const XI_OBJ* obj)
 | 
						|
{
 | 
						|
  return obj->type == XIT_CONTAINER || obj->type == XIT_FORM || obj->type == XIT_GROUP;
 | 
						|
}
 | 
						|
 | 
						|
XI_OBJ* TControl::find_operable(XI_OBJ* container, bool forward, bool normal) const
 | 
						|
{
 | 
						|
  int num; 
 | 
						|
  XI_OBJ** child = xi_get_member_list(container, &num);
 | 
						|
  CHECK(num > 0, "Container too empty");
 | 
						|
  
 | 
						|
  const int first = forward ? 0 : num-2;
 | 
						|
  const int last  = forward ? num-1 : -1;
 | 
						|
  const int delta = forward ? +1 : -1;
 | 
						|
  
 | 
						|
  XI_OBJ* found = NULL;
 | 
						|
  for (int c = first; c != last && found == NULL; c += delta)
 | 
						|
  {
 | 
						|
    XI_OBJ* obj = child[c];
 | 
						|
    switch (obj->type) 
 | 
						|
    {
 | 
						|
    case XIT_LIST:
 | 
						|
    case XIT_BTN:
 | 
						|
    case XIT_FIELD:
 | 
						|
      if (normal && obj->cid > 0)
 | 
						|
        found = obj;
 | 
						|
      break;        
 | 
						|
    case XIT_CONTAINER:
 | 
						|
    case XIT_FORM:  
 | 
						|
    case XIT_GROUP:
 | 
						|
      if (obj->cid > 0)
 | 
						|
      {
 | 
						|
        if (normal)
 | 
						|
        {
 | 
						|
          int num;
 | 
						|
          XI_OBJ** child = xi_get_member_list(obj, &num);
 | 
						|
          found = forward ? child[0] : child[num-1];
 | 
						|
        }  
 | 
						|
        else
 | 
						|
          found = obj;
 | 
						|
      }  
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      break;      
 | 
						|
    }  
 | 
						|
  }
 | 
						|
  
 | 
						|
  if (found == NULL)
 | 
						|
  {   
 | 
						|
    found = child[num-1];
 | 
						|
    if (is_container(found) && normal) 
 | 
						|
    {
 | 
						|
      int num;
 | 
						|
      XI_OBJ** child = xi_get_member_list(found, &num);
 | 
						|
      found = forward ? child[0] : child[num-1];
 | 
						|
    }
 | 
						|
  }  
 | 
						|
  
 | 
						|
  return found;  
 | 
						|
}
 | 
						|
 | 
						|
void TControl::update_tab_cid()
 | 
						|
{                            
 | 
						|
  const bool is_cont = is_container(_obj);
 | 
						|
  
 | 
						|
  XI_OBJ *first = find_operable(_obj->itf, true, !is_cont);
 | 
						|
  set_tab_cid(_obj, first->cid);
 | 
						|
  
 | 
						|
  XI_OBJ *last = find_operable(_obj->itf, false, !is_cont);
 | 
						|
  set_tab_cid(last, _obj->cid);
 | 
						|
 | 
						|
  if (is_cont)
 | 
						|
  {
 | 
						|
    XI_OBJ* fi = find_operable(_obj->itf, true,  true);
 | 
						|
    XI_OBJ* la = find_operable(_obj->itf, false, true);
 | 
						|
    int num; 
 | 
						|
    XI_OBJ** child = xi_get_member_list(_obj, &num);
 | 
						|
    set_tab_cid(child[num-1], fi->cid);
 | 
						|
    set_tab_cid(la, child[0]->cid);
 | 
						|
  } else 
 | 
						|
  if (_obj->parent != _obj->itf)
 | 
						|
  {
 | 
						|
    XI_OBJ* fi = find_operable(_obj->itf, true,  false);
 | 
						|
    XI_OBJ* la = find_operable(_obj->itf, false, false);
 | 
						|
    set_tab_cid(_obj->parent, fi->cid);
 | 
						|
    set_tab_cid(la, _obj->parent->cid);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
XI_RCT TControl::coord2rct(XI_OBJ* itf, short x, short y, short dx, short dy) const
 | 
						|
{
 | 
						|
  // Spazio da lasciare prima di toccare i bordi
 | 
						|
  const int X_DELTA = CHARX / 4;
 | 
						|
  const int Y_DELTA = CHARY / 8;
 | 
						|
  XI_RCT rct;
 | 
						|
 | 
						|
  RCT max_rct; xvt_vobj_get_client_rect((WINDOW)xi_get_window(itf), &max_rct);
 | 
						|
  const short MAXX = max_rct.right;
 | 
						|
  const short MAXY = max_rct.bottom;
 | 
						|
 | 
						|
  int width = CHARX;
 | 
						|
  if (dx > 0)
 | 
						|
    width = dx * CHARX;
 | 
						|
 | 
						|
  int height = CHARY;
 | 
						|
  if (dy > 1)
 | 
						|
    height += (dy-1) * ROWY;
 | 
						|
 | 
						|
  if (x < 0)
 | 
						|
  {
 | 
						|
    x = -x;
 | 
						|
    if (x > 10)
 | 
						|
    {
 | 
						|
      const int num = x / 10 -1;
 | 
						|
      const int tot = x % 10;
 | 
						|
      const int spc = (MAXX - tot*width) / (tot+1);
 | 
						|
      rct.left = spc + num * (spc+width);
 | 
						|
    }
 | 
						|
    else
 | 
						|
      rct.left = MAXX - width - x * CHARX - X_DELTA;
 | 
						|
  }
 | 
						|
  else
 | 
						|
  {
 | 
						|
    rct.left = x * CHARX + X_DELTA;
 | 
						|
 | 
						|
    if (dx > 0 && MAXX > 80 * CHARX)
 | 
						|
      rct.left += (MAXX - 80 * CHARX) / 2;
 | 
						|
  }
 | 
						|
 | 
						|
  if (y < 0)
 | 
						|
  {
 | 
						|
    y = -y;
 | 
						|
    if (y > 10)
 | 
						|
    {
 | 
						|
      const int num = y / 10 -1;
 | 
						|
      const int tot = y % 10;
 | 
						|
      const int spc = (MAXY - tot*height) / (tot+1);
 | 
						|
      rct.top = spc + num * (spc+height);
 | 
						|
    }
 | 
						|
    else
 | 
						|
      rct.top = MAXY - height - (y-1) * ROWY - Y_DELTA;
 | 
						|
  }
 | 
						|
  else
 | 
						|
    rct.top = y * ROWY + Y_DELTA;
 | 
						|
 | 
						|
  if (dx > 0)
 | 
						|
    rct.right = rct.left + width;
 | 
						|
  else
 | 
						|
    rct.right = MAXX + (dx-1) * CHARX - X_DELTA;
 | 
						|
 | 
						|
  if (dy > 0)
 | 
						|
    rct.bottom = rct.top + height;
 | 
						|
  else
 | 
						|
    rct.bottom = MAXY + dy * ROWY - Y_DELTA;
 | 
						|
 | 
						|
  xi_pu_to_fu(itf, (XI_PNT*)&rct, 2);
 | 
						|
  return rct;
 | 
						|
}
 | 
						|
 | 
						|
short TControl::id() const 
 | 
						|
{ return _obj->cid; }       
 | 
						|
 | 
						|
int TControl::type() const 
 | 
						|
{ return _obj->type; }
 | 
						|
 | 
						|
RCT& TControl::get_rect(RCT& r) const
 | 
						|
{
 | 
						|
  xi_get_rect(_obj, (XI_RCT*) &r);
 | 
						|
  return r;
 | 
						|
}
 | 
						|
 | 
						|
void TControl::set_rect(const RCT& r)
 | 
						|
{
 | 
						|
  xi_set_rect(_obj, (XI_RCT*)&r, false);
 | 
						|
  
 | 
						|
  if ( _obj->type == XIT_BTN )
 | 
						|
  {
 | 
						|
    // Dovevano pensarci quelli di XI, ma sono morti!
 | 
						|
    if (xi_get_native_controls(_obj)) 
 | 
						|
      xvt_vobj_move((WINDOW)_obj->v.btn->btnctl, &r);
 | 
						|
  }
 | 
						|
}
 | 
						|
  
 | 
						|
void TControl::set_rect(short cx, short cy, short cwidth, short cheight, short clen)
 | 
						|
{
 | 
						|
	XI_RCT rct = coord2rct(_obj->itf, cx, cy, cwidth + 1, cheight);
 | 
						|
 | 
						|
  xi_fu_to_pu(_obj->itf, (XI_PNT*)&rct, 2);
 | 
						|
	set_rect((const RCT &)rct);
 | 
						|
 | 
						|
	if ( _obj->type == XIT_FIELD)
 | 
						|
	{
 | 
						|
		if (_obj->v.field->button)
 | 
						|
		{
 | 
						|
			const short delta = _obj->v.field->btn_rct.left - (_obj->v.field->rct.right + CAMPI_SCAVATI);
 | 
						|
 | 
						|
			_obj->v.field->btn_rct.left -= delta;
 | 
						|
			_obj->v.field->btn_rct.right -= delta;
 | 
						|
		}
 | 
						|
 | 
						|
		if (clen > 0)
 | 
						|
			(( STX_DATA * ) _obj->v.field->stx)->text_size = clen + 1;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
unsigned long TControl::flags2attr(const char* flags) const
 | 
						|
{
 | 
						|
  unsigned long attrib = XI_ATR_VISIBLE | XI_ATR_ENABLED;
 | 
						|
  for (const char* f = flags; *f; f++)
 | 
						|
  {
 | 
						|
    switch(toupper(*f))
 | 
						|
    {
 | 
						|
    case '*': attrib |= XI_ATR_PASSWORD; break;
 | 
						|
    case 'C': attrib |= XI_ATR_HCENTER;  break;
 | 
						|
    case 'D': attrib &= ~XI_ATR_ENABLED; break;
 | 
						|
    case 'H': attrib &= ~XI_ATR_VISIBLE; break;
 | 
						|
    case 'L': attrib |= XI_ATR_READONLY; break;
 | 
						|
    case 'R': attrib |= XI_ATR_RJUST;    break;
 | 
						|
    default : break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return attrib;
 | 
						|
}
 | 
						|
 | 
						|
const char* TControl::parse_caption(const char* cap, bool& bold, bool& big, COLOR& color) const
 | 
						|
{
 | 
						|
  bold = false;
 | 
						|
  big = false;
 | 
						|
  color = PROMPT_COLOR;
 | 
						|
  
 | 
						|
  const char* t;
 | 
						|
  
 | 
						|
  for (t = cap; *t == '@' || *t == '$'; t++)
 | 
						|
  {
 | 
						|
    if (*t == '@')
 | 
						|
    {
 | 
						|
      const char code = toupper(*(t+1));
 | 
						|
      if (code == 'B')
 | 
						|
      {
 | 
						|
        bold = true;
 | 
						|
        t++;
 | 
						|
      }
 | 
						|
			else
 | 
						|
      if (code == 'G')
 | 
						|
      {
 | 
						|
        big = true;
 | 
						|
        t++;
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
        NFCHECK("Bad character (%c) after @ in %s", code, cap);
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      if (*(t+1) == '[')
 | 
						|
      {
 | 
						|
        t += 2;                          // Skip [
 | 
						|
        if (isalpha(*t))
 | 
						|
           color = trans_color(*t);
 | 
						|
        else
 | 
						|
        {
 | 
						|
          int r = 0, g = 0, b = 0;
 | 
						|
          if (sscanf(t, "%d,%d,%d", &r, &g, &b) == 3)
 | 
						|
            color = XVT_MAKE_COLOR(r, g, b);
 | 
						|
        }
 | 
						|
        while (*t && *t != ']') t++;
 | 
						|
      }
 | 
						|
      else
 | 
						|
      {
 | 
						|
        NFCHECK(0, "Bad character after $ in prompt");
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return t;
 | 
						|
}
 | 
						|
 | 
						|
WINDOW TControl::parent() const
 | 
						|
{
 | 
						|
  return (WINDOW)xi_get_window(_obj->itf);
 | 
						|
}
 | 
						|
 | 
						|
void TControl::set_focus() const
 | 
						|
{
 | 
						|
  xi_set_focus(_obj);
 | 
						|
}
 | 
						|
 | 
						|
bool TControl::notify_key(KEY k)
 | 
						|
{
 | 
						|
  bool ok = true;
 | 
						|
 | 
						|
  if (_fld == NULL)
 | 
						|
  {
 | 
						|
    TWindow* msk = (TWindow*)xi_get_app_data(get_interface());
 | 
						|
    CHECK(msk, "Can't get TMask from XI interface");
 | 
						|
    if (msk->is_kind_of(CLASS_MASK))
 | 
						|
    {
 | 
						|
      const TMask& m = (TMask&)*msk;
 | 
						|
      const int pos = m.id2pos(id());
 | 
						|
      if (pos >= 0)
 | 
						|
        _fld = &m.fld(pos);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  if (_fld)
 | 
						|
    ok = _fld->on_key(k);
 | 
						|
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
bool TControl::is_edit_key(KEY k) const
 | 
						|
{
 | 
						|
  return k >= ' ' && k < 255 && k != K_DEL;
 | 
						|
}
 | 
						|
 | 
						|
bool TControl::event_handler(XI_OBJ* itf, XI_EVENT* xiev)
 | 
						|
{
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
void TControl::change_attrib(unsigned long mask, bool on, XI_OBJ* obj)
 | 
						|
{
 | 
						|
  if (obj == NULL) obj = _obj;
 | 
						|
  const unsigned long old_attr = xi_get_attrib(obj);
 | 
						|
  unsigned long attr = old_attr;
 | 
						|
  if (on) attr |= mask;
 | 
						|
  else    attr &= ~mask;
 | 
						|
  if (attr != old_attr)     // C'e' un vero cambiamento d'attributo
 | 
						|
    xi_set_attrib(obj, attr);
 | 
						|
}
 | 
						|
 | 
						|
// @doc INTERNAL
 | 
						|
 | 
						|
// @mfunc Mostra/Nasconde il controllo
 | 
						|
void TControl::show(
 | 
						|
     bool on)  // @parm Operazione da svolgere sul controllo:
 | 
						|
         // @flag true | Il controllo viene mostrato
 | 
						|
         // @flag false | Il controllo viene nascosto
 | 
						|
{
 | 
						|
  change_attrib(XI_ATR_VISIBLE, on);
 | 
						|
}
 | 
						|
 | 
						|
// @doc INTERNAL
 | 
						|
 | 
						|
// @mfunc Abilita/disabilita il controllo
 | 
						|
void TControl::enable(
 | 
						|
     bool on)  // @parm Operazione da svolgere sul controllo:
 | 
						|
         // @flag true | Il controllo viene abilitato
 | 
						|
         // @flag false | Il controllo viene disabilitato
 | 
						|
{
 | 
						|
  change_attrib(XI_ATR_ENABLED, on);
 | 
						|
}
 | 
						|
 | 
						|
// @mfunc Abilita/disabilita l'autoselezione del testo
 | 
						|
void TControl::autoselect(bool on)
 | 
						|
{
 | 
						|
  change_attrib(XI_ATR_AUTOSELECT, on);
 | 
						|
}
 | 
						|
 | 
						|
// @mfunc Allineamento a destra del testo
 | 
						|
void TControl::set_rjust(bool on)
 | 
						|
{
 | 
						|
  change_attrib(XI_ATR_RJUST, on);
 | 
						|
}
 | 
						|
 | 
						|
// @doc INTERNAL
 | 
						|
 | 
						|
// @mfunc Flag di sola lettura
 | 
						|
bool TControl::read_only() const
 | 
						|
{
 | 
						|
  return (xi_get_attrib(_obj) & XI_ATR_READONLY) != 0;
 | 
						|
}
 | 
						|
 | 
						|
// @mfunc Flag di sola lettura
 | 
						|
void TControl::set_read_only(bool on)
 | 
						|
{
 | 
						|
  change_attrib(XI_ATR_READONLY, on);
 | 
						|
}
 | 
						|
 | 
						|
void TControl::set_caret_pos(int pos)
 | 
						|
{
 | 
						|
	xi_lowlevel_focus(_obj, TRUE);
 | 
						|
	if (pos >= 0)
 | 
						|
		xi_aga_field_set_caret_pos(_obj, pos);
 | 
						|
}
 | 
						|
 | 
						|
const char* TControl::caption() const
 | 
						|
{
 | 
						|
  const char* c = xi_get_text(_obj, NULL, 512);
 | 
						|
  return c;
 | 
						|
}
 | 
						|
 | 
						|
void TControl::set_caption(const char* c)
 | 
						|
{
 | 
						|
  xi_set_text(_obj, (char*)c);
 | 
						|
}
 | 
						|
 | 
						|
void TControl::destroy()
 | 
						|
{
 | 
						|
  if (_obj != NULL)
 | 
						|
  {
 | 
						|
    xi_delete(_obj);
 | 
						|
    _obj = NULL;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TText
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
TText_control::TText_control(WINDOW win, short cid,
 | 
						|
                             short left, short top, short width, short height,
 | 
						|
                             const char* flags, const char* text)
 | 
						|
{
 | 
						|
  bool bold, big;
 | 
						|
  COLOR color;
 | 
						|
  TString t = parse_caption(text, bold, big, color);
 | 
						|
  t.rtrim();
 | 
						|
  if (width <= 0)
 | 
						|
    width = t.len();
 | 
						|
 | 
						|
  XI_OBJ* itf = get_interface(win);
 | 
						|
  XI_RCT rct = coord2rct(itf, left, top, width, height);
 | 
						|
  rct.right += bold ? (width*XI_FU_MULTIPLE/4) : XI_FU_MULTIPLE;
 | 
						|
	if (big)
 | 
						|
	{
 | 
						|
		rct.right += (rct.right - rct.left);
 | 
						|
		rct.bottom += short(xvt_font_get_size(BIG_FONT) - xvt_font_get_size(DEF_FONT));
 | 
						|
	}
 | 
						|
 | 
						|
  const unsigned long attrib = flags2attr(flags);
 | 
						|
  XI_OBJ_DEF* def = xi_add_text_def(NULL, cid, &rct, attrib, t.get_buffer());
 | 
						|
  CHECKS(def, "Can't create the definition of TText_control:", text);
 | 
						|
  def->v.text->fore_color = color;
 | 
						|
  if (bold || big)
 | 
						|
	  def->v.text->font_id = xvtil_default_font(bold, big);
 | 
						|
  _obj = xi_create(itf, def);
 | 
						|
  CHECKS(_obj, "Can't create TText_control ", text);
 | 
						|
 | 
						|
  xi_dequeue();
 | 
						|
  xi_tree_free(def);
 | 
						|
}
 | 
						|
 | 
						|
void TText_control::set_caption(const char* text)
 | 
						|
{
 | 
						|
  bool bold, big;
 | 
						|
  COLOR color;
 | 
						|
  const char* c = parse_caption(text, bold, big, color);
 | 
						|
  xi_set_text(_obj, (char*)c);
 | 
						|
  _obj->v.text->fore_color = color;    
 | 
						|
  xi_set_obj_font_id(_obj, xvtil_default_font(bold, big));
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TGroupbox_control
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
TGroupbox_control::TGroupbox_control(WINDOW win, short cid,
 | 
						|
                                     short left, short top, short width, short height,
 | 
						|
                                     const char* flags, const char* text)
 | 
						|
                 : TText_control(win, cid, left, top, width, 1, flags, text)
 | 
						|
{
 | 
						|
  XI_OBJ* itf = get_interface(win);
 | 
						|
  XI_RCT rct = coord2rct(itf, left, top, width, height);
 | 
						|
  rct.top = _obj->v.text->xi_rct.bottom - 2;
 | 
						|
  rct.bottom -= XI_FU_MULTIPLE / 2;
 | 
						|
 | 
						|
  XI_OBJ_DEF* def = xi_add_rect_def(NULL, cid, &rct, XI_ATR_VISIBLE, 0, 0); // Ignore colors
 | 
						|
  CHECKS(def, "Can't create the definition of TGroupbox_control ", text);
 | 
						|
  def->v.rect->hilight_color = MASK_LIGHT_COLOR;
 | 
						|
  def->v.rect->back_color    = MASK_BACK_COLOR;
 | 
						|
  def->v.rect->shadow_color  = MASK_DARK_COLOR;
 | 
						|
  def->v.rect->bitmap        = get_background_bitmap(false);
 | 
						|
 | 
						|
  const bool erre = strchr(flags, 'R') != NULL;
 | 
						|
  if (erre)
 | 
						|
    change_attrib(XI_ATR_RJUST, false, _obj);  // Toglie l'erroneo allineamento a destra del titolo
 | 
						|
 | 
						|
  if (campi_scavati())
 | 
						|
    def->v.rect->well = erre;  // Mette eventualmente in rilievo il rettangolo
 | 
						|
  else
 | 
						|
    def->v.rect->ridge = true; // Angoli arrotondati in caso di stile piatto
 | 
						|
 | 
						|
  _rct = xi_create(itf, def);
 | 
						|
  CHECKD(_rct, "Can't create Groupbox_control ", cid);
 | 
						|
 | 
						|
  XI_RCT& rt = _obj->v.text->rct;
 | 
						|
  rt.top--; rt.bottom--;
 | 
						|
 | 
						|
  xi_dequeue();
 | 
						|
  xi_tree_free(def);
 | 
						|
}
 | 
						|
 | 
						|
void TGroupbox_control::show(bool on)
 | 
						|
{
 | 
						|
  TText_control::show(on);
 | 
						|
  change_attrib(XI_ATR_VISIBLE, on, _rct);
 | 
						|
}
 | 
						|
 | 
						|
RCT& TGroupbox_control::get_rect(RCT& r) const
 | 
						|
{
 | 
						|
  xi_get_rect(_rct, (XI_RCT*)&r);
 | 
						|
  return r;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TField
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
static bool in_create = false;
 | 
						|
 | 
						|
TField_control::TField_control(WINDOW win, short cid,
 | 
						|
                               short left, short top, short width, short maxlen,
 | 
						|
                               const char* flags, const char* text)
 | 
						|
{
 | 
						|
  const bool button = strchr(flags, 'B') != NULL;
 | 
						|
  create(win, cid, left, top, width, 1, maxlen, flags, text, button ? 2 : 0);
 | 
						|
}
 | 
						|
 | 
						|
void TField_control::create(WINDOW win, short cid,
 | 
						|
                       short left, short top, short width, short height, short maxlen,
 | 
						|
                       const char* flags, const char* text, int button)
 | 
						|
{
 | 
						|
  CHECK(!in_create, "Nested control creation");
 | 
						|
  in_create = true;
 | 
						|
  bool big = false;
 | 
						|
	bool bold = false;
 | 
						|
  const short fcid = cid > 0 ? cid + 2000 : cid - 2000;
 | 
						|
  XI_OBJ_DEF* frm_def = xi_add_form_def(NULL, fcid, fcid);
 | 
						|
  frm_def->app_data = (long)this;
 | 
						|
 | 
						|
  for (const char* s = flags; *s; s++)
 | 
						|
	{
 | 
						|
    if (*s == '{')
 | 
						|
			big = true;	else
 | 
						|
	  if (*s == '}')
 | 
						|
			bold = true;
 | 
						|
	}
 | 
						|
 | 
						|
  XI_OBJ* itf = get_interface(win);
 | 
						|
	XI_RCT rct = coord2rct(itf, left, top, width, height);
 | 
						|
 | 
						|
  rct.right += bold ? (width*XI_FU_MULTIPLE/4) : XI_FU_MULTIPLE/4;
 | 
						|
 | 
						|
	if (big)
 | 
						|
	{
 | 
						|
		rct.right += (rct.right - rct.left);
 | 
						|
		rct.bottom += short(xvt_font_get_size(BIG_FONT) - xvt_font_get_size(DEF_FONT));
 | 
						|
	}
 | 
						|
 | 
						|
  unsigned long attrib = flags2attr(flags) | XI_ATR_EDITMENU;
 | 
						|
  if (AUTOSELECT) 
 | 
						|
    attrib |= XI_ATR_AUTOSELECT;
 | 
						|
  if (AUTOEND) 
 | 
						|
    attrib |= XI_AGA_ATR_AUTOEND;
 | 
						|
  if (!campi_scavati())
 | 
						|
    attrib |= XI_ATR_BORDER;
 | 
						|
  if (maxlen > width)
 | 
						|
    attrib |= XI_ATR_AUTOSCROLL;
 | 
						|
 | 
						|
  XI_OBJ_DEF* def = xi_add_field_def(frm_def, cid,
 | 
						|
                                     rct.top, rct.left,
 | 
						|
                                     rct.right - rct.left,
 | 
						|
                                     attrib, cid, maxlen+1,
 | 
						|
                                     NORMAL_COLOR, NORMAL_BACK_COLOR,
 | 
						|
                                     NORMAL_COLOR, DISABLED_BACK_COLOR,
 | 
						|
                                     FOCUS_COLOR);
 | 
						|
 | 
						|
  def->app_data = (long)this;
 | 
						|
  XI_FIELD_DEF* f = def->v.field;
 | 
						|
  if (big || bold)
 | 
						|
		f->font_id = xvtil_default_font(bold, big);
 | 
						|
  f->well = campi_scavati();
 | 
						|
  f->active_back_color = FOCUS_BACK_COLOR;
 | 
						|
 | 
						|
	if (height == 1)
 | 
						|
	{
 | 
						|
		f->auto_tab = true;
 | 
						|
		if (button != 0)
 | 
						|
		{
 | 
						|
			f->button = true;
 | 
						|
      switch (button)
 | 
						|
      {
 | 
						|
      case  2: f->icon_rid = ICO_SEARCH; break;  // Bottone per ricerche
 | 
						|
      default: break; // Bottone standard ICO_COMBO
 | 
						|
      }
 | 
						|
			f->pixel_button_distance = 1;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	else   // E' un multiline, quindi setto il rettangolo
 | 
						|
	{
 | 
						|
		f->xi_rct.top = rct.top;
 | 
						|
		f->xi_rct.bottom = rct.bottom;
 | 
						|
		f->xi_rct.right = rct.right;
 | 
						|
		f->xi_rct.left = rct.left;
 | 
						|
		f->cr_ok = true;
 | 
						|
		f->var_len_text = true;
 | 
						|
	}
 | 
						|
 | 
						|
  XI_OBJ* form = xi_create(itf, frm_def);
 | 
						|
  CHECKD(form, "Can't create the form for field ", cid);
 | 
						|
  _obj = xi_get_obj(form, cid);
 | 
						|
  CHECKD(_obj, "Can't create field ", cid);
 | 
						|
  STX_DATA* stx = (STX_DATA*)_obj->v.field->stx;
 | 
						|
  CHECKD(stx, "NULL stx for field ", cid);
 | 
						|
 
 | 
						|
  if (_obj->v.field->button) 
 | 
						|
  {
 | 
						|
    // Aggiusta il rettangolo del bottone in modo da allinearlo al testo
 | 
						|
    XI_RCT& br = (XI_RCT&)_obj->v.field->btn_rct;
 | 
						|
    const int offset = stx->rct.right - br.left - 1;
 | 
						|
    br.left  += offset; 
 | 
						|
    br.right += offset;
 | 
						|
    br.top = stx->rct.top + (campi_scavati() ? 1 : 0);
 | 
						|
    br.bottom = stx->rct.bottom;
 | 
						|
  }
 | 
						|
 | 
						|
  update_tab_cid();
 | 
						|
  xi_dequeue();
 | 
						|
  xi_tree_free(frm_def);
 | 
						|
 | 
						|
  in_create = false;
 | 
						|
}
 | 
						|
 | 
						|
void TField_control::show_button(bool on)
 | 
						|
{
 | 
						|
  XI_FIELD_DATA* f = _obj->v.field;
 | 
						|
  const bool has_button = f->button != 0;
 | 
						|
  if (has_button != on)
 | 
						|
  {
 | 
						|
    f->button = on;
 | 
						|
    xi_invalidate_rect((XinWindow)parent(), &f->btn_rct);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
bool TField_control::event_handler(XI_OBJ* itf, XI_EVENT* xiev)
 | 
						|
{
 | 
						|
  if (in_create)
 | 
						|
    return false;
 | 
						|
 | 
						|
  bool ok = true;
 | 
						|
 | 
						|
  switch(xiev->type)
 | 
						|
  {
 | 
						|
  case XIE_OFF_FIELD:
 | 
						|
    ok = notify_key(K_TAB);
 | 
						|
    break;
 | 
						|
  case XIE_ON_FIELD:
 | 
						|
    notify_key(K_CTRL+K_TAB);
 | 
						|
    break;
 | 
						|
  case XIE_DBL_FIELD:
 | 
						|
		if (!read_only())
 | 
						|
      notify_key(has_virtual_keyboard() ? K_F12 : K_F9);
 | 
						|
   break;
 | 
						|
  case XIE_CHAR_FIELD:
 | 
						|
    {
 | 
						|
      KEY k = xiev_to_key(xiev);
 | 
						|
      if (k == K_PREV || k == K_NEXT || k > K_CTRL)
 | 
						|
      {
 | 
						|
        k = K_TAB;
 | 
						|
        xiev->refused = true;
 | 
						|
      }  
 | 
						|
      if (k == K_TAB || is_edit_key(k) || (k > K_F1 && k < K_F12))
 | 
						|
        ok = notify_key(k);
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case XIE_CHG_FIELD:
 | 
						|
    notify_key(K_CTRL+K_SPACE);
 | 
						|
    break;
 | 
						|
  case XIE_BUTTON:
 | 
						|
    notify_key(K_F9);
 | 
						|
    break;
 | 
						|
  default:
 | 
						|
    ok = TControl::event_handler(itf, xiev);
 | 
						|
    break;
 | 
						|
  }
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
void TField_control::set_focus() const
 | 
						|
{
 | 
						|
  TControl::set_focus();
 | 
						|
}
 | 
						|
 | 
						|
void TField_control::set_back_color(COLOR col)
 | 
						|
{
 | 
						|
  xi_set_color(_obj, XIC_BACK, col);
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TMultiline_control
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
TMultiline_control::TMultiline_control(WINDOW win, short cid,
 | 
						|
                                       short left, short top,
 | 
						|
                                       short width, short height, short maxlen,
 | 
						|
                                       const char* flags, const char* text)
 | 
						|
{
 | 
						|
  create(win, cid, left, top, width, height, maxlen, flags, text, false);
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TButton_control
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
void TButton_control::create(WINDOW win, short cid,
 | 
						|
                             short left, short top, short width, short height,
 | 
						|
                             const char* flags, const char* text,
 | 
						|
                             WIN_TYPE wc, XI_OBJ* container, bool drawable)
 | 
						|
{
 | 
						|
  bool bold, big;
 | 
						|
  COLOR color;
 | 
						|
  TString txt(text); txt.trim();
 | 
						|
  
 | 
						|
  char mnemonic = '\0';
 | 
						|
  int underscore = -1;
 | 
						|
  if (wc == WC_PUSHBUTTON || wc == WC_CHECKBUTTON)
 | 
						|
  {
 | 
						|
    underscore = txt.find('~');
 | 
						|
    if (underscore < 0)
 | 
						|
      underscore = txt.find('&');
 | 
						|
    if (underscore >= 0)
 | 
						|
      mnemonic = txt[underscore+1];
 | 
						|
    txt.strip("&~");
 | 
						|
  }
 | 
						|
  const char* t = parse_caption(txt, bold, big, color);
 | 
						|
  if (width <= 0) width = strlen(t)+3;
 | 
						|
 | 
						|
  XI_RCT rct = coord2rct(get_interface(win), left, top, width, height);
 | 
						|
 | 
						|
  const unsigned long attrib = flags2attr(flags);
 | 
						|
  XI_OBJ_DEF* def = xi_add_button_def(NULL, cid, &rct, attrib, (char*)t, cid);
 | 
						|
  CHECKD(def, "Can't create the interface of TButton_control ", cid);
 | 
						|
  def->v.btn->fore_color = color;
 | 
						|
  def->app_data = (long)this;
 | 
						|
  switch (wc)
 | 
						|
  {
 | 
						|
    case WC_PUSHBUTTON :
 | 
						|
			def->v.btn->type = XIBT_BUTTON;
 | 
						|
			if (bold)
 | 
						|
				def->v.btn->font = (XinFont *)BIG_FONT;
 | 
						|
      if (drawable)
 | 
						|
        def->v.btn->text = ""; // Nasceranno icone successivamente
 | 
						|
			break;
 | 
						|
    case WC_CHECKBOX   : def->v.btn->type = XIBT_CHECKBOX; break;
 | 
						|
    case WC_RADIOBUTTON: def->v.btn->type = XIBT_RADIOBTN; break;
 | 
						|
    case WC_CHECKBUTTON: def->v.btn->type = XIBT_BUTTON_CHECKBOX; break;
 | 
						|
    default            : def->v.btn->type = XIBT_TABBTN; break;
 | 
						|
  }        
 | 
						|
  
 | 
						|
  if (mnemonic)
 | 
						|
  {
 | 
						|
    int mnemonic_instance = 1;
 | 
						|
    for (int c = underscore-1; c >= 0; c--)
 | 
						|
      if (t[c] == mnemonic)
 | 
						|
        mnemonic_instance++;
 | 
						|
    def->v.btn->mnemonic = mnemonic;
 | 
						|
    def->v.btn->mnemonic_instance = mnemonic_instance;
 | 
						|
  }         
 | 
						|
  
 | 
						|
  if (container == NULL)
 | 
						|
    container = get_interface(win);
 | 
						|
  _obj = xi_create(container, def);
 | 
						|
  CHECKD(_obj, "Can't create TButton_control ", cid);
 | 
						|
 | 
						|
  // Aggiusta bottoni
 | 
						|
  switch (wc)
 | 
						|
  {
 | 
						|
  case WC_PUSHBUTTON:
 | 
						|
    if (height == 1)
 | 
						|
    {
 | 
						|
      XI_RCT& r = _obj->v.btn->rct;
 | 
						|
      // r.top--; Commentata di recente 
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case WC_CHECKBUTTON:
 | 
						|
    if (height == 1)
 | 
						|
    {
 | 
						|
      XI_RCT& r = _obj->v.btn->rct;
 | 
						|
      r.top -= 2;
 | 
						|
      r.bottom++;
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case WC_CHECKBOX:
 | 
						|
  case WC_RADIOBUTTON:
 | 
						|
    { 
 | 
						|
      XI_RCT& r = _obj->v.btn->rct;
 | 
						|
      r.top++; r.bottom -= 2;
 | 
						|
      r.right += XI_FU_MULTIPLE / 2;
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  default:
 | 
						|
    break;
 | 
						|
  }
 | 
						|
 | 
						|
  xi_dequeue();
 | 
						|
  xi_tree_free(def);
 | 
						|
 | 
						|
  update_tab_cid();
 | 
						|
}
 | 
						|
 | 
						|
int TButton_control::button_type() const
 | 
						|
{
 | 
						|
  return _obj->v.btn->type;
 | 
						|
}
 | 
						|
 | 
						|
XI_OBJ* TButton_control::container() const
 | 
						|
{
 | 
						|
  return _obj->parent;
 | 
						|
}
 | 
						|
 | 
						|
void TButton_control::check(bool on)
 | 
						|
{
 | 
						|
  xi_check(_obj, on);
 | 
						|
}
 | 
						|
 | 
						|
bool TButton_control::checked() const
 | 
						|
{
 | 
						|
  return xi_is_checked(_obj) ? true : false;
 | 
						|
}
 | 
						|
 | 
						|
bool TButton_control::toggle()
 | 
						|
{
 | 
						|
  const bool on = !checked();
 | 
						|
  check(on);
 | 
						|
  return on;
 | 
						|
}
 | 
						|
 | 
						|
bool TButton_control::event_handler(XI_OBJ* itf, XI_EVENT* xiev)
 | 
						|
{
 | 
						|
  bool ok = true;
 | 
						|
 | 
						|
  if (xiev->type == XIE_BUTTON)
 | 
						|
  {
 | 
						|
    if (_last_mouse_button == 0)
 | 
						|
    {                           
 | 
						|
      if (id() != DLG_CANCEL && id() != DLG_QUIT) 
 | 
						|
        ok = xi_move_focus(_obj) ? true : false;
 | 
						|
       
 | 
						|
      if (ok) 
 | 
						|
      {
 | 
						|
        switch (_obj->v.btn->type)
 | 
						|
        {
 | 
						|
          case XIBT_CHECKBOX:
 | 
						|
          case XIBT_BUTTON_CHECKBOX:
 | 
						|
            toggle();
 | 
						|
            break;
 | 
						|
          default:
 | 
						|
            break;
 | 
						|
        }
 | 
						|
        ok = notify_key(K_SPACE);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  else
 | 
						|
    if (xiev->type == XIE_POST_NAVIGATION)
 | 
						|
      ok = notify_key(K_CTRL + K_TAB);
 | 
						|
    else
 | 
						|
      ok = TControl::event_handler(itf, xiev);
 | 
						|
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
void TButton_control::set_icon(unsigned int icon_up, unsigned int icon_dn)
 | 
						|
{
 | 
						|
  if (icon_dn <= 0)
 | 
						|
    icon_dn = icon_up;
 | 
						|
  xi_set_icon(_obj, icon_up, icon_dn);
 | 
						|
  _obj->v.btn->drawable = false;
 | 
						|
  
 | 
						|
  const XI_RCT& rct = _obj->v.btn->rct;
 | 
						|
  _obj->v.btn->icon_x = short(rct.right - rct.left - xvt_vobj_get_attr(NULL_WIN, ATTR_ICON_WIDTH)) / 2 - 5;
 | 
						|
  _obj->v.btn->icon_y = short(rct.bottom - rct.top - xvt_vobj_get_attr(NULL_WIN, ATTR_ICON_HEIGHT)) / 2 - 5;
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TPushbutton_control
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
TPushbutton_control::TPushbutton_control(WINDOW win, short cid,
 | 
						|
                                         short left, short top, short width, short height,
 | 
						|
                                         const char* flags, const char* text,
 | 
						|
                                         int bmp_up, int bmp_dn)
 | 
						|
                   : _bmp_up(bmp_up), _bmp_dn(bmp_dn)
 | 
						|
{
 | 
						|
  const bool drawable = bmp_up > 0;
 | 
						|
  create(win, cid, left, top, width, height, flags, text, WC_PUSHBUTTON, NULL, drawable);
 | 
						|
  set_bmp(bmp_up, bmp_dn);
 | 
						|
}
 | 
						|
 | 
						|
TPushbutton_control::~TPushbutton_control() 
 | 
						|
{            
 | 
						|
}
 | 
						|
 | 
						|
char TPushbutton_control::mnemonic() const
 | 
						|
{
 | 
						|
  return _obj->v.btn->mnemonic;
 | 
						|
}
 | 
						|
 | 
						|
void TPushbutton_control::set_caption(const char* c)
 | 
						|
{ 
 | 
						|
  bool bold, big;
 | 
						|
  COLOR color;
 | 
						|
  const char* cap = parse_caption(c, bold, big, color);
 | 
						|
			
 | 
						|
  if (*cap)
 | 
						|
  {       
 | 
						|
    TControl::set_caption(cap);
 | 
						|
    set_icon(0);
 | 
						|
    set_bmp(0, 0);
 | 
						|
    _obj->v.btn->drawable = false;
 | 
						|
    _obj->v.btn->fore_color = color;
 | 
						|
		xi_set_obj_font_id(_obj, xvtil_default_font(bold, big));
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void TPushbutton_control::set_bmp(int bmp_up, int bmp_dn)
 | 
						|
{
 | 
						|
  if (bmp_up > 0)
 | 
						|
  {
 | 
						|
    set_icon(0);  
 | 
						|
		_bmp_up = (bmp_up > 0 && _picture->add(bmp_up)) ? bmp_up : 0;
 | 
						|
    _bmp_dn = (bmp_dn > 0 && _picture->add(bmp_dn)) ? bmp_dn : _bmp_up;
 | 
						|
  }
 | 
						|
  else
 | 
						|
    _bmp_up = _bmp_dn = 0;
 | 
						|
 | 
						|
  if (xi_get_native_controls(_obj))
 | 
						|
  {
 | 
						|
    _obj->v.btn->drawable = FALSE; // Non disegnarci a mano e lascia fare ad XVT!
 | 
						|
 | 
						|
    XVT_IMAGE img_up = NULL, img_dn = NULL;
 | 
						|
    if (bmp_up > 0)
 | 
						|
      img_up = _picture->image(_bmp_up).xvt_image();
 | 
						|
    if (bmp_dn > 0)
 | 
						|
      img_dn = _picture->image(_bmp_dn).xvt_image();
 | 
						|
    xvt_btn_set_images((WINDOW)_obj->v.btn->btnctl, img_up, img_dn);
 | 
						|
  }
 | 
						|
  else
 | 
						|
    _obj->v.btn->drawable = _bmp_up > 0;
 | 
						|
}
 | 
						|
 | 
						|
void TPushbutton_control::set_icon(int icon_up, int icon_dn)
 | 
						|
{
 | 
						|
  if (xi_get_native_controls(_obj))
 | 
						|
  {
 | 
						|
    TButton_control::set_icon(0, 0);
 | 
						|
    if (icon_up > 0)
 | 
						|
    {
 | 
						|
      const int bmp_up = _picture->add_icon(icon_up);
 | 
						|
      const int bmp_dn = _picture->add_icon(icon_dn > 0 ? icon_dn : icon_up);
 | 
						|
      set_bmp(bmp_up, bmp_dn);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  else
 | 
						|
    TButton_control::set_icon(icon_up, icon_dn);
 | 
						|
}
 | 
						|
 | 
						|
void TPushbutton_control::set_bmp(const char* bmp_up, const char* bmp_dn)
 | 
						|
{
 | 
						|
  if (bmp_up && *bmp_up)
 | 
						|
	{
 | 
						|
    set_icon(0);  
 | 
						|
  	_bmp_up = _picture->add(bmp_up);
 | 
						|
	  if (bmp_dn && *bmp_dn)
 | 
						|
			_bmp_dn = _picture->add(bmp_dn);
 | 
						|
		else
 | 
						|
			_bmp_dn = _bmp_up;
 | 
						|
	}
 | 
						|
	else
 | 
						|
		_bmp_up = _bmp_dn = 0;
 | 
						|
  
 | 
						|
  // Chiamo qui la gestione di basso livello per gestire i native controls
 | 
						|
  set_bmp(_bmp_up, _bmp_dn); 
 | 
						|
}
 | 
						|
 | 
						|
void TPushbutton_control::update()
 | 
						|
{
 | 
						|
  // Dovrebbe passare di qui solo per i controlli NON nativi, ma non si sa mai
 | 
						|
  if (!xi_get_native_controls(_obj)) 
 | 
						|
  {
 | 
						|
    const long attrib = xi_get_attrib(_obj);
 | 
						|
    if (attrib & XI_ATR_VISIBLE)
 | 
						|
    { 
 | 
						|
      XinWindow win = xi_get_window(_obj);
 | 
						|
      XI_RCT rct; xi_get_rect(_obj, &rct); // = _obj->v.btn->rct;
 | 
						|
      xi_inflate_rect(&rct, -3);
 | 
						|
      xi_set_clip(win, &rct);
 | 
						|
 | 
						|
      // Cancello il testo sottostante
 | 
						|
      CBRUSH brush = { PAT_SOLID, BTN_BACK_COLOR };
 | 
						|
      xvt_dwin_set_cbrush((WINDOW)win, &brush);
 | 
						|
      xvt_dwin_set_std_cpen((WINDOW)win, TL_PEN_HOLLOW);
 | 
						|
      xi_draw_rect(win, &rct);
 | 
						|
       
 | 
						|
      const int bmp = (_bmp_dn > 0 && _obj->v.btn->down) ? _bmp_dn : _bmp_up;
 | 
						|
      if (bmp > 0)
 | 
						|
      {
 | 
						|
        const TImage& i = attrib & XI_ATR_ENABLED ? _picture->image(bmp) : _picture->disabled_image(bmp);
 | 
						|
        RCT& dst = xvtil_align_rect(i.rect(), (RCT&)rct, 'C', 'C', '-');
 | 
						|
			  if (_obj->v.btn->down)
 | 
						|
          xvt_rect_offset(&dst, 2, 2);
 | 
						|
 	      i.draw((WINDOW)win, dst);
 | 
						|
      }
 | 
						|
      xi_set_clip(win, NULL);
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
bool TPushbutton_control::event_handler(XI_OBJ* itf, XI_EVENT* xiev)
 | 
						|
{
 | 
						|
  bool ok = TButton_control::event_handler(itf, xiev);
 | 
						|
 | 
						|
  switch (xiev->type)
 | 
						|
  {
 | 
						|
    case XIE_BUTTON:
 | 
						|
      {
 | 
						|
        TWindow* w = (TWindow*)xi_get_app_data(get_interface());
 | 
						|
        w->on_button(id());
 | 
						|
      }
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      break;
 | 
						|
  }
 | 
						|
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TCheckbox_control
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
TCheckbox_control::TCheckbox_control(WINDOW win, short cid,
 | 
						|
                                     short left, short top, short width,
 | 
						|
                                     const char* flags, const char* text)
 | 
						|
{ create(win, cid, left, top, width, 1, flags, text, WC_CHECKBOX); }
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TCheckbutton_control
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
void TCheckbutton_control::check(bool on)
 | 
						|
{
 | 
						|
  TButton_control::check(on);
 | 
						|
  if (xi_get_native_controls(_obj))
 | 
						|
  {
 | 
						|
    XVT_IMAGE img_up = _picture->image(on ? _pic_dn : _pic_up).xvt_image();
 | 
						|
    XVT_IMAGE img_dn = _picture->image(on ? _pic_up : _pic_dn).xvt_image();
 | 
						|
    xvt_btn_set_images((WINDOW)_obj->v.btn->btnctl, img_up, img_dn);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void TCheckbutton_control::set_icon(int icon_up, int icon_dn)
 | 
						|
{
 | 
						|
  if (xi_get_native_controls(_obj))
 | 
						|
  {
 | 
						|
    TButton_control::set_icon(0, 0);
 | 
						|
    if (icon_up > 0)
 | 
						|
    {
 | 
						|
      _pic_up = _picture->add_icon(icon_up);
 | 
						|
      _pic_dn = _picture->add_icon(icon_dn > 0 ? icon_dn : icon_up);
 | 
						|
      XVT_IMAGE img_up = _pic_up > 0 ? _picture->image(_pic_up).xvt_image() : NULL;
 | 
						|
      XVT_IMAGE img_dn = _pic_dn > 0 ? _picture->image(_pic_dn).xvt_image() : NULL;
 | 
						|
      xvt_btn_set_images((WINDOW)_obj->v.btn->btnctl, img_up, img_dn);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  else
 | 
						|
    TButton_control::set_icon(icon_up, icon_dn);
 | 
						|
}
 | 
						|
 | 
						|
TCheckbutton_control::TCheckbutton_control(WINDOW win, short cid,
 | 
						|
                                           short left, short top, short width, int height,
 | 
						|
                                           const char* flags, const char* text,
 | 
						|
                                           int icon_up, int icon_dn)
 | 
						|
{ 
 | 
						|
  create(win, cid, left, top, width, height, flags, text, WC_CHECKBUTTON, NULL); 
 | 
						|
  set_icon(icon_up, icon_dn);
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TRadiobutton_control
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
TRadiobutton_control::TRadiobutton_control(WINDOW win, short cid,
 | 
						|
                                           short left, short top, short width, short height,
 | 
						|
                                           const char* flags, const char* text)
 | 
						|
{
 | 
						|
  TToken_string testo(text); testo.strip("&~");
 | 
						|
  const int tot = testo.items();
 | 
						|
 | 
						|
  const XI_CONTAINER_ORIENTATION orient = height == 1 ? XI_STACK_HORIZONTAL : XI_STACK_VERTICAL;
 | 
						|
  XI_OBJ* itf = get_interface(win);
 | 
						|
  XI_RCT rct = coord2rct(itf, left, top, width, height);
 | 
						|
 | 
						|
  XI_OBJ_DEF* def = xi_add_container_def(NULL, cid, &rct, orient, cid);
 | 
						|
  def->app_data = (long)this;
 | 
						|
 | 
						|
  const unsigned long attrib = flags2attr(flags);
 | 
						|
  for (int b = 1; b <= tot; b++)
 | 
						|
  {
 | 
						|
    bool bold, big;
 | 
						|
    COLOR color;
 | 
						|
    const char* t = parse_caption(testo.get(), bold, big, color);
 | 
						|
 | 
						|
    const int next = cid + (b+1)*1000;
 | 
						|
    XI_OBJ_DEF* btn_def = xi_add_button_def(def, cid + b*1000, NULL, attrib, (char*)t, next);
 | 
						|
    CHECKD(btn_def, "Can't create definition for radio-button ", cid);
 | 
						|
    btn_def->app_data = (long)this;
 | 
						|
    XI_BTN_DEF* btn = btn_def->v.btn;
 | 
						|
    btn->type = XIBT_RADIOBTN;
 | 
						|
    btn->fore_color = color;
 | 
						|
    btn->checked = b == 1;
 | 
						|
  }
 | 
						|
 | 
						|
  _obj = xi_create(itf, def);
 | 
						|
  CHECKD(_obj, "Can't create radio-button container ", cid);
 | 
						|
 | 
						|
  if (height > 1 && tot > 1)
 | 
						|
  {
 | 
						|
    xi_get_rect(_obj, &rct);
 | 
						|
 | 
						|
    int children;
 | 
						|
    XI_OBJ** child = xi_get_member_list(_obj, &children);
 | 
						|
    
 | 
						|
    XI_RCT brct; xi_get_rect(child[0], &brct);
 | 
						|
    const int bheight = brct.bottom-brct.top;
 | 
						|
    const int delta = rct.bottom-rct.top - children*bheight;
 | 
						|
    for (int c = 0; c < children; c++)
 | 
						|
    {
 | 
						|
      XI_RCT& brct = child[c]->v.btn->rct;
 | 
						|
      brct.top = rct.top + delta*c/(tot-1) + bheight*c;
 | 
						|
      brct.bottom = brct.top + bheight;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  update_tab_cid();
 | 
						|
 | 
						|
  xi_dequeue();
 | 
						|
  xi_tree_free(def);
 | 
						|
}
 | 
						|
 | 
						|
void TRadiobutton_control::show(bool on)
 | 
						|
{
 | 
						|
  int children;
 | 
						|
  XI_OBJ** child = xi_get_member_list(_obj, &children);
 | 
						|
  for (int c = children-1; c >= 0; c--)
 | 
						|
    change_attrib(XI_ATR_VISIBLE, on, child[c]);
 | 
						|
}
 | 
						|
 | 
						|
void TRadiobutton_control::enable(bool on)
 | 
						|
{
 | 
						|
  int children;
 | 
						|
  XI_OBJ** child = xi_get_member_list(_obj, &children);
 | 
						|
  for (int c = children-1; c >= 0; c--)
 | 
						|
    change_attrib(XI_ATR_ENABLED, on, child[c]);
 | 
						|
}
 | 
						|
 | 
						|
byte TRadiobutton_control::get_checked() const
 | 
						|
{
 | 
						|
  int children;
 | 
						|
  XI_OBJ** child = xi_get_member_list(_obj, &children);
 | 
						|
  int c;
 | 
						|
  for (c = children-1; c > 0; c--)
 | 
						|
    if (xi_is_checked(child[c])) break;
 | 
						|
  return (byte)c;
 | 
						|
}
 | 
						|
 | 
						|
void TRadiobutton_control::check_button(byte c)
 | 
						|
{
 | 
						|
  int children;
 | 
						|
  XI_OBJ** child = xi_get_member_list(_obj, &children);
 | 
						|
  if (child != NULL && c < children)
 | 
						|
    xi_check(child[c], true);
 | 
						|
  else
 | 
						|
    NFCHECK("This radio is rather old, it doesn't have a button");
 | 
						|
}
 | 
						|
 | 
						|
void TRadiobutton_control::show_button(byte c, bool on)
 | 
						|
{
 | 
						|
  int children;
 | 
						|
  XI_OBJ** child = xi_get_member_list(_obj, &children);
 | 
						|
  if (child != NULL && c < children)
 | 
						|
    change_attrib(XI_ATR_VISIBLE, on, child[c]);
 | 
						|
  else
 | 
						|
    NFCHECK("This radio is rather old, it doesn't have a button");
 | 
						|
}
 | 
						|
 | 
						|
bool TRadiobutton_control::event_handler(XI_OBJ* itf, XI_EVENT* xiev)
 | 
						|
{
 | 
						|
  bool ok = true;
 | 
						|
  if (xiev->type == XIE_BUTTON)
 | 
						|
  {
 | 
						|
    XI_OBJ* obj = xiev->v.xi_obj;       // Elemento del gruppo di radio buttons da premere
 | 
						|
    if (xi_move_focus(obj))             // Tenta di dargli il focus
 | 
						|
    {
 | 
						|
      if (!xi_is_checked(obj) || xi_get_native_controls(obj))          
 | 
						|
      {                                 // Se non e' gia' premuto ... 
 | 
						|
        xi_check(obj, true);            // ... allora premilo e ...
 | 
						|
        ok = notify_key(K_SPACE);       // ... avverti il mask_field proprietario
 | 
						|
      }
 | 
						|
    }
 | 
						|
    else
 | 
						|
      ok = false;
 | 
						|
  }
 | 
						|
  else
 | 
						|
    ok = TButton_control::event_handler(itf, xiev);
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
void TRadiobutton_control::set_focus() const
 | 
						|
{
 | 
						|
  int children;
 | 
						|
  XI_OBJ** child = xi_get_member_list(_obj, &children);
 | 
						|
  int c;
 | 
						|
  for (c = children-1; c > 0; c--)
 | 
						|
    if (xi_is_checked(child[c])) 
 | 
						|
      break;
 | 
						|
  xi_set_focus(child[c]);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TTagbutton_control
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
 | 
						|
TTagbutton_control::TTagbutton_control(WINDOW win, short cid,
 | 
						|
                                       short left, short top, short width, short height,
 | 
						|
                                       const char* flags, const char* text, int tag)
 | 
						|
{
 | 
						|
  XI_OBJ* itf = get_interface(win);
 | 
						|
  XI_RCT rct; xi_get_xi_rct(itf, &rct);
 | 
						|
  rct.bottom = rct.top + XI_FU_MULTIPLE;
 | 
						|
  XI_OBJ_DEF* cnt_def = xi_add_container_def(NULL, cid, &rct, XI_STACK_HORIZONTAL, cid);
 | 
						|
  cnt_def->app_data = (long)this;
 | 
						|
 | 
						|
  const unsigned long attrib = flags2attr(flags);
 | 
						|
 | 
						|
  TToken_string titolo(text);
 | 
						|
  const int tot = titolo.items();
 | 
						|
 | 
						|
  for (int b = 1; b <= tot; b++)
 | 
						|
  {
 | 
						|
    bool bold, big;
 | 
						|
    COLOR color;
 | 
						|
    const char* t = parse_caption(titolo.get(), bold, big, color);
 | 
						|
 | 
						|
    const int next_bid = b == tot ? cid+1 : cid+b+1;
 | 
						|
    XI_OBJ_DEF* btn_def = xi_add_button_def(cnt_def, cid+b, NULL, attrib, (char*)t, next_bid);
 | 
						|
    btn_def->v.btn->type = XIBT_TABBTN;
 | 
						|
    btn_def->v.btn->fore_color = color;
 | 
						|
    btn_def->v.btn->checked = tag == b-1;
 | 
						|
    btn_def->app_data = (long)this;
 | 
						|
    btn_def->v.btn->draw_as = XIBT_EMULATED; // Disegna le orecchie a mano!
 | 
						|
  }
 | 
						|
 | 
						|
  _obj = xi_create(itf, cnt_def);
 | 
						|
  CHECKD(_obj, "Can't create tab-button container ", cid);
 | 
						|
  
 | 
						|
  update_tab_cid();
 | 
						|
 | 
						|
  xi_dequeue();
 | 
						|
  xi_tree_free(cnt_def);
 | 
						|
}
 | 
						|
 | 
						|
bool TTagbutton_control::event_handler(XI_OBJ* itf, XI_EVENT* xiev)
 | 
						|
{                         
 | 
						|
  bool ok = true;    
 | 
						|
  if (xiev->type == XIE_BUTTON)
 | 
						|
  {                          
 | 
						|
    XI_OBJ* obj = xiev->v.xi_obj;        // Elemento del gruppo di radio buttons da premere
 | 
						|
    if (!xi_is_checked(obj))             // Se e' gia' selezionato ignoralo completamente
 | 
						|
    {
 | 
						|
      if (xi_move_focus(itf))            // Controlla se si puo' cambiare pagina
 | 
						|
      {
 | 
						|
        TWindow* w = (TWindow*)xi_get_app_data(itf);                       
 | 
						|
        const KEY k = K_CTRL + K_F1 + xiev->v.xi_obj->cid - id() - 1;
 | 
						|
        w->on_key(k);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  else
 | 
						|
    ok = TRadiobutton_control::event_handler(itf, xiev);
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
void TTagbutton_control::set_caption(const char* text)
 | 
						|
{
 | 
						|
  TToken_string cap = text;
 | 
						|
  int num;
 | 
						|
  XI_OBJ** tag = xi_get_member_list(_obj, &num);
 | 
						|
  for (int i = 0; i < num; i++)
 | 
						|
  {
 | 
						|
    text = cap.get();
 | 
						|
    if (text == NULL)
 | 
						|
      text = cap.get(0);
 | 
						|
    xi_set_text(tag[i], (char*)text);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TListbox_control
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
const char* xvtil_get_cell_selection(XI_OBJ* field_or_cell, int sel, const char* cod, const char* val)
 | 
						|
{
 | 
						|
  if (sel < 0)
 | 
						|
    sel = 0;
 | 
						|
  TToken_string values(val);
 | 
						|
  if (field_or_cell->type != XIT_FIELD)
 | 
						|
  {
 | 
						|
    XI_RCT ownrct; xi_get_rect(field_or_cell, &ownrct);
 | 
						|
    const int max_width = (ownrct.right-ownrct.left) - 20; // Larghezza cella stimata senza bottone
 | 
						|
 | 
						|
    WINDOW parent = (WINDOW)xi_get_window(field_or_cell);
 | 
						|
    const char* txt = values.get(sel);
 | 
						|
    int text_width = xvt_dwin_get_text_width(parent, txt, -1);
 | 
						|
    if (text_width <= max_width)
 | 
						|
    {
 | 
						|
      int maxlen = strlen(txt);
 | 
						|
      FOR_EACH_TOKEN(values, tok)
 | 
						|
      {
 | 
						|
        const int len = strlen(tok);
 | 
						|
        if (len > maxlen)
 | 
						|
        {
 | 
						|
          maxlen = len;
 | 
						|
          text_width = xvt_dwin_get_text_width(parent, tok, -1);
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (text_width > max_width)
 | 
						|
    {
 | 
						|
      TToken_string codes(cod);
 | 
						|
      return codes.get(sel);
 | 
						|
    }
 | 
						|
  }  
 | 
						|
  
 | 
						|
  return values.get(sel);
 | 
						|
}
 | 
						|
 | 
						|
int xvtil_drop_down_list(XI_OBJ* field_or_cell, const char* codes, const char* values)
 | 
						|
{
 | 
						|
  if (_ddl_shown)
 | 
						|
    return -1;
 | 
						|
  _ddl_shown = true;
 | 
						|
 | 
						|
  TToken_string val(values);
 | 
						|
  int sel = -1;
 | 
						|
  if (!val.empty_items())
 | 
						|
  {
 | 
						|
    const int TAGDDL = 1000; // Tag della prima voce della lista
 | 
						|
    TString current;         // Carico l'eventuale testo corrente
 | 
						|
    xi_get_text(field_or_cell, current.get_buffer(), current.size());
 | 
						|
 | 
						|
    const int maxi = val.items()+1; // Alloco sempre un item in piu' che fa da fine lista
 | 
						|
    MENU_ITEM* menu = new MENU_ITEM[maxi]; 
 | 
						|
    memset(menu, 0, sizeof(MENU_ITEM)*maxi);
 | 
						|
 | 
						|
    int items = 0;
 | 
						|
    FOR_EACH_TOKEN(val, tok)
 | 
						|
    {
 | 
						|
      MENU_ITEM& mi = menu[items];
 | 
						|
      mi.text = xvt_str_duplicate(tok);
 | 
						|
      mi.tag = TAGDDL+items;
 | 
						|
      mi.enabled = true;
 | 
						|
      if (sel < 0 && current == tok)
 | 
						|
        sel = items;
 | 
						|
      items++;
 | 
						|
    }
 | 
						|
 | 
						|
    if (items > 0)
 | 
						|
    {
 | 
						|
      WINDOW parent = (WINDOW)xi_get_window(field_or_cell);
 | 
						|
 | 
						|
      XVT_COLOR_COMPONENT xcc[8]; memset(&xcc, 0, sizeof(xcc));
 | 
						|
	    xcc[0].type = XVT_COLOR_BACKGROUND;	xcc[0].color = NORMAL_BACK_COLOR;
 | 
						|
      xcc[1].type = XVT_COLOR_FOREGROUND;	xcc[1].color = NORMAL_COLOR;
 | 
						|
	    xcc[2].type = XVT_COLOR_HIGHLIGHT;	xcc[2].color = FOCUS_COLOR;
 | 
						|
      xcc[3].type = XVT_COLOR_SELECT;	    xcc[3].color = FOCUS_BACK_COLOR;
 | 
						|
      xvt_dwin_set_font(parent, xvtil_default_font()); // Prepara il font da copiare nel popup
 | 
						|
     
 | 
						|
      RCT ownrct; xi_get_rect(field_or_cell, (XI_RCT*)&ownrct);
 | 
						|
      const MENU_TAG tag = xvt_list_popup(parent, &ownrct, menu, xcc, sel >= 0 ? TAGDDL+sel : -1);
 | 
						|
      if (tag >= TAGDDL)
 | 
						|
      {
 | 
						|
        sel = tag-TAGDDL;
 | 
						|
        const char* txt = xvtil_get_cell_selection(field_or_cell, sel, codes, values);
 | 
						|
        xi_set_text(field_or_cell, (char*)txt);
 | 
						|
      }
 | 
						|
    }    
 | 
						|
 | 
						|
    // Free menu data
 | 
						|
    for (int i = items-1; i >= 0; i--)
 | 
						|
      xvt_mem_free(menu[i].text);
 | 
						|
    delete menu;
 | 
						|
  }
 | 
						|
  _ddl_shown = false;
 | 
						|
  
 | 
						|
  return sel;
 | 
						|
}
 | 
						|
  
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TListbox_control
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
bool TListbox_control::event_handler(XI_OBJ* itf, XI_EVENT* xiev)
 | 
						|
{
 | 
						|
  bool ok = true;
 | 
						|
  switch (xiev->type)
 | 
						|
  {
 | 
						|
    case XIE_DBL_FIELD:
 | 
						|
    case XIE_BUTTON:
 | 
						|
      if (!_ddl_shown && !read_only())
 | 
						|
      {
 | 
						|
        const int sel = xvtil_drop_down_list(_obj, _codes, _values);
 | 
						|
        if (sel >= 0)
 | 
						|
        {
 | 
						|
          select(sel);
 | 
						|
          notify_key(K_SPACE);
 | 
						|
        }
 | 
						|
      }
 | 
						|
      break;
 | 
						|
    case XIE_CHAR_FIELD:
 | 
						|
      {
 | 
						|
				const KEY k = xiev_to_key(xiev);
 | 
						|
				
 | 
						|
				if (!read_only())
 | 
						|
				{
 | 
						|
					if (k >= ' ' && k <= 'z')
 | 
						|
						select_by_initial(char(k));
 | 
						|
					else
 | 
						|
						if (k == K_F9)
 | 
						|
            {
 | 
						|
              const int sel = xvtil_drop_down_list(_obj, _codes, _values);
 | 
						|
              if (sel >= 0)
 | 
						|
              {
 | 
						|
                select(sel);
 | 
						|
                notify_key(K_SPACE);
 | 
						|
              }
 | 
						|
            }
 | 
						|
						else
 | 
						|
							if (k == K_RIGHT)  // poor man's substitute for down arrow
 | 
						|
								select_by_ofs(1);
 | 
						|
							else
 | 
						|
								if (k == K_LEFT)   // poor man's substitute for up arrow
 | 
						|
									select_by_ofs(-1);                                      
 | 
						|
								else
 | 
						|
									if (k == K_F2 || k == K_F11 || k == K_F12)
 | 
						|
										notify_key(k);
 | 
						|
				}
 | 
						|
				else
 | 
						|
					if (k == K_F11 || k == K_F12)
 | 
						|
						notify_key(k);
 | 
						|
 | 
						|
				xiev->refused = true;
 | 
						|
      }
 | 
						|
      break;
 | 
						|
    case XIE_CHG_FIELD:
 | 
						|
      // Ignore changes: they are notified by the drop-down list
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      ok =  TField_control::event_handler(itf, xiev);
 | 
						|
      break;
 | 
						|
  }
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
void TListbox_control::set_values(const char* cod, const char* val)
 | 
						|
{
 | 
						|
  _codes = cod;
 | 
						|
  _values = val;
 | 
						|
  if (_current >= items())
 | 
						|
    _current = 0;
 | 
						|
  if (_values.full())
 | 
						|
    xi_set_text(_obj, (char*)_values.get(_current));
 | 
						|
  else
 | 
						|
    xi_set_text(_obj, "");
 | 
						|
}
 | 
						|
 | 
						|
int TListbox_control::items() const             
 | 
						|
{ 
 | 
						|
  return _codes.items(); 
 | 
						|
}
 | 
						|
 | 
						|
bool TListbox_control::select(int i)             
 | 
						|
{ 
 | 
						|
  const bool ok = i >= 0 && i < items();
 | 
						|
  if (ok)
 | 
						|
  {
 | 
						|
    if (_current != i)
 | 
						|
    {
 | 
						|
      _current = i;
 | 
						|
      xi_set_text(_obj, ""); // Senno' a volte disegna male
 | 
						|
      xi_set_text(_obj, (char*)_values.get(i));
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return ok;            
 | 
						|
}
 | 
						|
 | 
						|
bool TListbox_control::select_by_initial(char c) 
 | 
						|
{ 
 | 
						|
  int i = _current;
 | 
						|
  const int tot = items();
 | 
						|
  for (i = (i+1)%tot; i != _current; i = (i+1)%tot)
 | 
						|
  {
 | 
						|
    if (toupper(_values.get_char(i)) == toupper(c))
 | 
						|
      break;
 | 
						|
  }
 | 
						|
  const bool changed = i != _current;
 | 
						|
  if (changed)
 | 
						|
  {
 | 
						|
    select(i);
 | 
						|
    notify_key(K_SPACE);
 | 
						|
  }
 | 
						|
  return changed; 
 | 
						|
}
 | 
						|
 | 
						|
bool TListbox_control::select_by_ofs(int i)      
 | 
						|
{ 
 | 
						|
  const int last = items()-1;
 | 
						|
  i += _current;
 | 
						|
  if (i < 0)
 | 
						|
    i = last; else
 | 
						|
  if (i > last)
 | 
						|
    i = last;
 | 
						|
  const bool changed = i != _current;
 | 
						|
  if (changed)
 | 
						|
  {
 | 
						|
    select(i);
 | 
						|
    notify_key(K_SPACE);
 | 
						|
  }
 | 
						|
  return changed;
 | 
						|
}
 | 
						|
 | 
						|
int TListbox_control::selected() const          
 | 
						|
{ return _current; }
 | 
						|
 | 
						|
TListbox_control::TListbox_control(WINDOW win, short cid,
 | 
						|
                                   short left, short top, short width,
 | 
						|
                                   const char* flags, const char* text,
 | 
						|
                                   const char* codes, const char* values)
 | 
						|
                : _codes(codes), _values(values), _current(-1)
 | 
						|
{
 | 
						|
  create(win, cid, left, top, width , 1, width, flags, text, true);
 | 
						|
}
 | 
						|
 | 
						|
TListbox_control::~TListbox_control()
 | 
						|
{ }
 |