Files correlati : *.* Ricompilazione Demo : [ ] Commento : ccustio.c Cambiato oridne di inclusione per far contento Visual Studio >= 2008 colors.h Aggiunto flag NATIVE_CONTROLS e tolto flag SMALL_ICONS controls.* Aggiunto supporto per bottoni nativi al posto dei simulacri XI dongle.cpp Aggiunta in modo DBG la simulazione chiave master per Power Station expr.cpp TRUE -> true FALSE -> false image.h Reso accessibile handle XVT_IMAGE per bottoni nativi isam.cpp Corretta segnalazione campi mancanti acceduti tramite TRecfield maskfld.* Supporto per controlli nativi printapp.cpp Eliminate funzioni DEPRECATED per Visual Studio >= 2005 relacpp.cpp Corretto posizionamento bottoni per controli nativi e non tree.cpp Supporto per Tree controls nativi ed eliminati quelli fatti "in casa" window.* Reso virtuale metodoto TWindow::force_update, necessario ai TTree_field git-svn-id: svn://10.65.10.50/trunk@15851 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1186 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1186 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#define XVT_INCL_NATIVE
 | 
						|
 | 
						|
#define XI_INTERNAL
 | 
						|
#include <xinclude.h>
 | 
						|
 | 
						|
#include <applicat.h>
 | 
						|
#include <colors.h>
 | 
						|
#include <urldefid.h>
 | 
						|
 | 
						|
#define __WINDOW_CPP
 | 
						|
#include <window.h>  
 | 
						|
#include <xvtility.h>
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TRectangle
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
void TRectangle::copy(const TRectangle& r)
 | 
						|
{
 | 
						|
  x = r.x; y = r.y;
 | 
						|
  _size = r._size;
 | 
						|
}
 | 
						|
 | 
						|
void TRectangle::normalize()
 | 
						|
{
 | 
						|
  if (_size.x < 0)
 | 
						|
  {
 | 
						|
    x += _size.x;
 | 
						|
    _size.x = -_size.x;
 | 
						|
  }
 | 
						|
  if (_size.y < 0)
 | 
						|
  {
 | 
						|
    y += _size.y;
 | 
						|
    _size.y = -_size.y;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void TRectangle::set(long cx, long cy, long dx, long dy)
 | 
						|
{
 | 
						|
  x = cx; y = cy;
 | 
						|
  _size.set(dx, dy);
 | 
						|
  normalize();
 | 
						|
}
 | 
						|
 | 
						|
void TRectangle::set(const TPoint& pt, const TPoint& sz)
 | 
						|
{
 | 
						|
  set(pt.x, pt.y, sz.x, sz.y);
 | 
						|
}
 | 
						|
 | 
						|
void TRectangle::set_bounds(long left, long top, long right, long bottom)
 | 
						|
{
 | 
						|
  set(left, top, right-left, bottom-top);
 | 
						|
}
 | 
						|
 | 
						|
bool TRectangle::contains(const TPoint& p) const
 | 
						|
{
 | 
						|
  if (p.x < left())   return false;
 | 
						|
  if (p.y < top())    return false;
 | 
						|
  if (p.x > right())  return false;
 | 
						|
  if (p.y > bottom()) return false;
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
bool TRectangle::contains(const TRectangle& r) const
 | 
						|
{
 | 
						|
  return r.left() >= left() && r.right() <= right() && r.top() >= top() && r.bottom() < bottom();
 | 
						|
}
 | 
						|
 | 
						|
bool TRectangle::intersects(const TRectangle& r) const
 | 
						|
{
 | 
						|
  if (left() > r.right()) return false; 
 | 
						|
  if (right() < r.left()) return false;
 | 
						|
  if (top() > r.bottom()) return false; 
 | 
						|
  if (bottom() < r.top()) return false; 
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
void TRectangle::merge(const TRectangle& rct)
 | 
						|
{
 | 
						|
  long l = x, t = y, r = right(), b = bottom();
 | 
						|
  if (rct.x < l) l = rct.x;
 | 
						|
  if (rct.y < t) t = rct.y;
 | 
						|
  if (rct.right() > r) r = rct.right();
 | 
						|
  if (rct.bottom() > b) b = rct.bottom();
 | 
						|
  set_bounds(l, t, r, b);
 | 
						|
}
 | 
						|
 | 
						|
void TRectangle::inflate(int dx, int dy)
 | 
						|
{
 | 
						|
  x -= dx; y -= dy;
 | 
						|
  _size.x += 2*dx;
 | 
						|
  _size.y += 2*dy;
 | 
						|
  normalize();
 | 
						|
}
 | 
						|
 | 
						|
void TRectangle::deflate(int dx, int dy)
 | 
						|
{
 | 
						|
  inflate(-dx, -dy);
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// Utilities
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
HIDDEN MENU_ITEM* find_menu_item(MENU_ITEM* menu, MENU_TAG id, bool ismbar)
 | 
						|
{                                               
 | 
						|
  MENU_ITEM* fnd = NULL;  
 | 
						|
  MENU_ITEM* mn  = ismbar ? &menu[0] : &menu->child[0];
 | 
						|
 | 
						|
  for (int m = 0; mn != NULL && mn->tag != 0; m++, mn=ismbar?&menu[m]:&menu->child[m])
 | 
						|
  {
 | 
						|
    fnd = mn->tag == id ? mn : find_menu_item(mn, id, FALSE);
 | 
						|
    if (fnd != NULL) break;
 | 
						|
  } 
 | 
						|
  
 | 
						|
  return fnd;
 | 
						|
}
 | 
						|
 | 
						|
HIDDEN bool remove_menu_item(MENU_ITEM* menu, MENU_TAG id, bool ismbar)
 | 
						|
{                                               
 | 
						|
  MENU_ITEM* mn  = ismbar ? &menu[0] : &menu->child[0];
 | 
						|
 | 
						|
  for (int m = 0; mn != NULL && mn->tag != 0; m++, mn=ismbar?&menu[m]:&menu->child[m])
 | 
						|
  {
 | 
						|
    if (mn->tag == id) 
 | 
						|
    { 
 | 
						|
      do    
 | 
						|
      {
 | 
						|
        xvt_mem_rep((DATA_PTR)mn, (DATA_PTR)(mn+1), sizeof(MENU_ITEM), 1);
 | 
						|
        mn++;
 | 
						|
      } 
 | 
						|
      while (mn->tag != 0); 
 | 
						|
      return TRUE;
 | 
						|
    }
 | 
						|
    else if (remove_menu_item(mn, id, FALSE)) 
 | 
						|
      return TRUE;
 | 
						|
  }
 | 
						|
  
 | 
						|
  return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
HIDDEN void set_menu_item(MENU_ITEM& m, TToken_string& tt)
 | 
						|
{                        
 | 
						|
  MENU_TAG tag  = tt.get_int(0);
 | 
						|
  TString flag = tt.items() <=  2 ? "": tt.get(2);
 | 
						|
  char* text = NULL; 
 | 
						|
  if (strlen(tt.get(1)) > 0)
 | 
						|
  {
 | 
						|
    text = (char*)xvt_mem_alloc(strlen(tt.get(1)) + 1);
 | 
						|
    strcpy(text, tt.get(1));  
 | 
						|
  }
 | 
						|
 | 
						|
  m.tag       = tag;
 | 
						|
  m.text      = text;
 | 
						|
  m.enabled   = flag.find('D') < 0;
 | 
						|
  m.checkable = flag.find('C') >= 0 || flag.find('c') >= 0;
 | 
						|
  m.checked   = flag.find('c') >= 0;      
 | 
						|
  m.separator = text == NULL;
 | 
						|
} 
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TWindow_manager
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
          
 | 
						|
// @doc INTERNAL          
 | 
						|
          
 | 
						|
// @class TWindow_manager | Classe per la gestione di un array di finestre modali
 | 
						|
class TWindow_manager
 | 
						|
{
 | 
						|
  // @author:(INTERNAL) Guido
 | 
						|
 | 
						|
  // @access:(INTERNAL) Private Member
 | 
						|
  
 | 
						|
  // @ccost:(INTERNAL) MAX_WIN | 8 | Numero massimo di finestre modali
 | 
						|
  enum { MAX_WIN = 8 };         
 | 
						|
 | 
						|
  // @cmember:(INTERNAL) Stack contenente la finestra attiva
 | 
						|
  TWindow* _window[MAX_WIN];    
 | 
						|
  // @cmember:(INTERNAL) Stack pointer
 | 
						|
  short _current;                
 | 
						|
  // @cmember:(INTERNAL) Permette di abilitare/disabilitare il menu' della task window (stesso 
 | 
						|
  //                                    funzionamento della <mf TMask::enable>)
 | 
						|
  void menu_enable(bool) const; 
 | 
						|
  
 | 
						|
  // @cmember:(INTERNAL) Tiene sempre disponibile un file con un numero di handle inferiore a 20
 | 
						|
  //                                    (per sopperire ad una mancanza di XVT)
 | 
						|
  FILE* _lowhandle;
 | 
						|
 | 
						|
// @access Public Member  
 | 
						|
public:
 | 
						|
  // @cmember Costruttore
 | 
						|
  TWindow_manager(); 
 | 
						|
  // @cmember Distruttore
 | 
						|
  ~TWindow_manager();
 | 
						|
  
 | 
						|
  // @cmember Registra la finestra <p m> corrente 
 | 
						|
  void reg(TWindow* m);
 | 
						|
  // @cmember De-registra la finestra corrente
 | 
						|
  void unreg(const TWindow* m);
 | 
						|
  
 | 
						|
  // @cmember Ritorna il puntatore alla finestra corrente
 | 
						|
  TWindow* cur_win() const 
 | 
						|
  { return (_current < 0) ? NULL : _window[_current]; } 
 | 
						|
 | 
						|
  // @cmember Chiude tutte le finestre modali aperte
 | 
						|
  void destroy();
 | 
						|
  // @cmember Ritorna TRUE se la finestra corrente puo' essere chiusa
 | 
						|
  bool can_close() const; 
 | 
						|
} WinManager;
 | 
						|
 | 
						|
 | 
						|
 | 
						|
TWindow_manager::TWindow_manager() : _current(-1), _lowhandle(NULL)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
TWindow_manager::~TWindow_manager()
 | 
						|
{ 
 | 
						|
  destroy(); 
 | 
						|
}  
 | 
						|
 | 
						|
void TWindow_manager::destroy()
 | 
						|
{
 | 
						|
  while (_current >= 0)
 | 
						|
  {
 | 
						|
    TWindow* w = cur_win();
 | 
						|
    w->stop_run(K_FORCE_CLOSE);
 | 
						|
    w->close_modal();
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
bool TWindow_manager::can_close() const 
 | 
						|
{ 
 | 
						|
  bool ok = true;
 | 
						|
  if (_current >= 0)
 | 
						|
    ok = cur_win()->can_be_closed();
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
// Dis/abilitazione del menu principale
 | 
						|
HIDDEN void xvt_menu_enable(MENU_ITEM* m, bool on)
 | 
						|
{
 | 
						|
  while (m->tag)
 | 
						|
  {
 | 
						|
    switch(m->tag)
 | 
						|
    {
 | 
						|
			case M_FILE:      // Leave it as is
 | 
						|
			case M_EDIT:
 | 
						|
			case M_FONT:
 | 
						|
			case M_STYLE:
 | 
						|
			case M_HELP:
 | 
						|
			case -1:             // Separator
 | 
						|
				break;             
 | 
						|
			default:
 | 
						|
				xvt_menu_set_item_enabled(TASK_WIN, m->tag, on);
 | 
						|
		}
 | 
						|
    m++;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TWindow_manager::menu_enable(bool on) const
 | 
						|
{
 | 
						|
  MENU_ITEM *mi = xvt_menu_get_tree(TASK_WIN);
 | 
						|
	if (mi)
 | 
						|
	{
 | 
						|
		xvt_menu_enable(mi, on);
 | 
						|
		xvt_menu_update(TASK_WIN);
 | 
						|
		xvt_res_free_menu_tree(mi);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TWindow_manager::reg(TWindow* m)
 | 
						|
{
 | 
						|
  _current++;
 | 
						|
  CHECK(_current < MAX_WIN, "Too many windows");
 | 
						|
 | 
						|
  switch (_current)
 | 
						|
  {
 | 
						|
  case 0 : 
 | 
						|
    menu_enable(FALSE);                      
 | 
						|
    {                                                                                   
 | 
						|
      const bool on = main_app().firm_change_enabled();
 | 
						|
      xvt_menu_set_item_enabled(TASK_WIN, M_FILE_NEW, on);
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  case 1 : 
 | 
						|
    xvt_menu_set_item_enabled(TASK_WIN, M_FILE_QUIT, FALSE); 
 | 
						|
    xvt_menu_set_item_enabled(TASK_WIN, M_FILE_NEW, FALSE);  
 | 
						|
  default: 
 | 
						|
    _window[_current-1]->deactivate(); break;
 | 
						|
  }
 | 
						|
 | 
						|
  _window[_current] = m;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TWindow_manager::unreg(const TWindow* m)
 | 
						|
{
 | 
						|
#ifdef DBG
 | 
						|
  if (m != cur_win())
 | 
						|
  {
 | 
						|
    yesnofatal_box("E' successo un casino nel Window Manager");
 | 
						|
    return;
 | 
						|
  }
 | 
						|
#endif
 | 
						|
 | 
						|
  _current--;
 | 
						|
  
 | 
						|
  if (_current < 0)
 | 
						|
  {
 | 
						|
    menu_enable(TRUE);
 | 
						|
  }  
 | 
						|
  else
 | 
						|
  {
 | 
						|
    TWindow& w = *cur_win();
 | 
						|
    w.activate();
 | 
						|
    
 | 
						|
    xvt_menu_set_item_enabled(TASK_WIN, M_FILE_QUIT, _current == 0);
 | 
						|
    const bool cf = _current == 0 && main_app().firm_change_enabled();
 | 
						|
    xvt_menu_set_item_enabled(TASK_WIN, M_FILE_NEW, cf);
 | 
						|
    
 | 
						|
    xvt_menu_update(TASK_WIN);
 | 
						|
    w.set_focus();
 | 
						|
    w.force_update();
 | 
						|
  }     
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// @func Chiude tutte le finestre aperte
 | 
						|
void close_all_dialogs()
 | 
						|
{
 | 
						|
  WinManager.destroy();
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @func Indica se l'applicazione puo' essere terminata
 | 
						|
//
 | 
						|
// @rdesc Ritorna il risultato della ricerca:
 | 
						|
//
 | 
						|
// @flag TRUE | Se l'aplicazione puo' essere chiusa
 | 
						|
// @flag FALSE | Se l'applicazione non puo' essere chiusa
 | 
						|
bool can_close()
 | 
						|
{
 | 
						|
  return WinManager.can_close();
 | 
						|
}
 | 
						|
 | 
						|
bool is_valid_window(WINDOW w)
 | 
						|
{
 | 
						|
  bool ok = FALSE;
 | 
						|
  if (w != NULL_WIN)
 | 
						|
    ok = (xvt_vobj_get_attr(w, ATTR_NATIVE_WINDOW) != 0L);
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
// @func Ritorna l'handle della finestra corrente
 | 
						|
//
 | 
						|
// @rdesc Restituisce l'handle della finestra corrente.
 | 
						|
WINDOW cur_win()
 | 
						|
 | 
						|
  // @comm Se non esiste una finestra corrente allora ritorna NULL_WIN
 | 
						|
{
 | 
						|
  WINDOW win = NULL_WIN;
 | 
						|
  TWindow* w = WinManager.cur_win();
 | 
						|
  if (w != NULL)
 | 
						|
  { 
 | 
						|
    win = w->win();
 | 
						|
    if (!is_valid_window(w->win()))
 | 
						|
    {
 | 
						|
      w->stop_run(K_FORCE_CLOSE);
 | 
						|
      win = NULL_WIN;
 | 
						|
    }  
 | 
						|
  }  
 | 
						|
  return win;  
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TWindow
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
DRAW_CTOOLS TWindow::_ct;
 | 
						|
bool TWindow::_ctools_saved;
 | 
						|
 | 
						|
 | 
						|
TWindow::TWindow()
 | 
						|
: _win(NULL_WIN), _lastkey(0),
 | 
						|
  _base_char_width(0L), _open(FALSE), _modal(FALSE), 
 | 
						|
  _active(TRUE), _running(FALSE), _pixmap(FALSE)
 | 
						|
{}
 | 
						|
 | 
						|
word TWindow::class_id() const
 | 
						|
{ return CLASS_WINDOW; }
 | 
						|
 | 
						|
long TWindow::window_handler(WINDOW win, EVENT* ep)
 | 
						|
{
 | 
						|
  TWindow* w = (TWindow*)xvt_vobj_get_data(win);
 | 
						|
  CHECK(w != NULL, "Invalid window");
 | 
						|
  w->handler(win, ep);
 | 
						|
 | 
						|
  return 0L;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Crea la finestra
 | 
						|
//
 | 
						|
// @rdesc Ritorna l'handle della finestra creata
 | 
						|
WINDOW TWindow::create(
 | 
						|
  short x,           // @parm Coordinata x della finestra
 | 
						|
  short y,           // @parm Coordinata y della finestra
 | 
						|
  short dx,          // @parm Larghezza della finestra
 | 
						|
  short dy,          // @parm Altezza della finestra
 | 
						|
  const char* title, // @parm Titolo da assegnare alla finestra (default "")
 | 
						|
  long flags,        // @parm Flag della finestra (default WSF_NONE)
 | 
						|
  WIN_TYPE wt,       // @parm Tipo di finestra da creare (default W_DOC)
 | 
						|
  WINDOW parent,     // @parm Handler della finestra padre (default NULL_WIN)
 | 
						|
  int menu)          // @parm Menu' da assegnare alla finestra (default 0)
 | 
						|
{
 | 
						|
  if (menu == 0) flags |= WSF_NO_MENUBAR;
 | 
						|
 | 
						|
  if (parent == NULL_WIN) parent = TASK_WIN;
 | 
						|
  if (parent == TASK_WIN) flags |= WSF_INVISIBLE;
 | 
						|
 | 
						|
  _win = xvtil_create_window(
 | 
						|
    wt,
 | 
						|
    x, y, dx, dy,
 | 
						|
    title, 
 | 
						|
    menu, parent,
 | 
						|
    flags, 
 | 
						|
    window_handler,
 | 
						|
    PTR_LONG(this)
 | 
						|
    );
 | 
						|
 | 
						|
  CHECK(_win, "Can't create a window");
 | 
						|
 | 
						|
  return _win;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
TWindow::~TWindow()
 | 
						|
{
 | 
						|
  if (_win != NULL_WIN)
 | 
						|
  {   
 | 
						|
    if (is_valid_window(_win))
 | 
						|
      xvt_vobj_destroy(_win);
 | 
						|
    _win = NULL_WIN;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TWindow::open()
 | 
						|
{
 | 
						|
  WINDOW w = win();
 | 
						|
  CHECK(is_valid_window(w), "Can't open a NULL window");
 | 
						|
  xvt_vobj_set_visible(w, _open = TRUE);
 | 
						|
  xvt_scr_set_focus_vobj(w);  
 | 
						|
  xvt_vobj_raise(w);          
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TWindow::open_modal()
 | 
						|
{
 | 
						|
  set_modal(TRUE);
 | 
						|
  _open = TRUE;
 | 
						|
  open();
 | 
						|
 | 
						|
  WinManager.reg(this);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TWindow::close()
 | 
						|
{
 | 
						|
  CHECK(_win != NULL_WIN, "Can't close a NULL window");
 | 
						|
  if (is_valid_window(_win))
 | 
						|
    xvt_vobj_set_visible(_win, _open = FALSE);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TWindow::close_modal()
 | 
						|
{            
 | 
						|
  if (is_modal())
 | 
						|
  {
 | 
						|
    WinManager.unreg(this);
 | 
						|
    close();
 | 
						|
    _open = FALSE;
 | 
						|
    set_modal(FALSE);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
bool TWindow::stop_run(KEY key)
 | 
						|
{
 | 
						|
  _running = FALSE;
 | 
						|
  _lastkey = key;     
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
bool TWindow::can_be_closed() const
 | 
						|
{
 | 
						|
  const bool ok = !is_modal();
 | 
						|
  if (!ok) 
 | 
						|
    error_box("Chiudere la finestra attiva prima di uscire dal programma");
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Esegue la finestra
 | 
						|
//
 | 
						|
// @rdesc Ritorna l'ultimo tasto premuto nella finestra
 | 
						|
KEY TWindow::run()
 | 
						|
 | 
						|
  // @comm Se la finestra non era aperta la apre in modo modale
 | 
						|
{
 | 
						|
  const bool was_open = is_open();
 | 
						|
 | 
						|
  start_run();
 | 
						|
  _running = TRUE;
 | 
						|
 | 
						|
  if (!was_open) 
 | 
						|
    open_modal();
 | 
						|
  else 
 | 
						|
    open();
 | 
						|
 | 
						|
  while (_running)
 | 
						|
  {
 | 
						|
    do_events();
 | 
						|
  	xvt_sys_sleep(50);
 | 
						|
	}
 | 
						|
 | 
						|
  if (!was_open) 
 | 
						|
    close_modal();
 | 
						|
  do_events();
 | 
						|
 | 
						|
  return last_key();
 | 
						|
}
 | 
						|
 | 
						|
void TWindow::on_button(short dlg)
 | 
						|
{   
 | 
						|
  switch(dlg)
 | 
						|
  {
 | 
						|
  case DLG_OK: 
 | 
						|
    stop_run(K_ENTER); 
 | 
						|
    break;
 | 
						|
  case DLG_CANCEL: 
 | 
						|
    stop_run(K_ESC); 
 | 
						|
    break;
 | 
						|
  case DLG_QUIT: 
 | 
						|
    stop_run(K_QUIT); 
 | 
						|
    break;
 | 
						|
  default:
 | 
						|
    break;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Gestisce l'handler della finestra
 | 
						|
void TWindow::handler(
 | 
						|
  WINDOW win, // @parm Finestra da gestire
 | 
						|
  EVENT* ep)  // @parm Evento da gestire nella finestra
 | 
						|
{
 | 
						|
  switch(ep->type)
 | 
						|
  {
 | 
						|
  case E_CHAR:
 | 
						|
    on_key(e_char_to_key(ep));
 | 
						|
    break;
 | 
						|
  case E_CLOSE:
 | 
						|
    stop_run(K_ESC);
 | 
						|
    break;
 | 
						|
  case E_CREATE:
 | 
						|
    if (_win == NULL_WIN)
 | 
						|
      _win = win;   // Gestisco meglio gli eventi che avvengono durante la creazione
 | 
						|
    break;
 | 
						|
  case E_CONTROL:
 | 
						|
    if (ep->v.ctl.ci.type == WC_PUSHBUTTON)
 | 
						|
      on_button(ep->v.ctl.id);
 | 
						|
    break;  
 | 
						|
  case E_DESTROY:
 | 
						|
    _win = NULL_WIN;
 | 
						|
    break;
 | 
						|
  case E_UPDATE:
 | 
						|
    update();
 | 
						|
    break;
 | 
						|
  default:
 | 
						|
    break;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void TWindow::on_idle()
 | 
						|
{
 | 
						|
  // Non c'e' niente da fare qui, ma non si puo' mai sapere
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
TPoint TWindow::size() const
 | 
						|
{
 | 
						|
  RCT r;
 | 
						|
  xvt_vobj_get_client_rect(win() ? win() : TASK_WIN, &r);
 | 
						|
//  return TPoint(r.right / CHARX, r.bottom / CHARY);
 | 
						|
  TPoint pnt;
 | 
						|
  pnt.x = int(80L * r.right / char2pixel(80));
 | 
						|
  pnt.y = r.bottom / CHARY;
 | 
						|
  return pnt;
 | 
						|
}
 | 
						|
 | 
						|
WINDOW TWindow::parent() const
 | 
						|
{
 | 
						|
  return xvt_vobj_get_parent(win());
 | 
						|
}
 | 
						|
 | 
						|
void TWindow::set_focus()
 | 
						|
{ 
 | 
						|
  WINDOW w = win();
 | 
						|
  if (w)
 | 
						|
  {
 | 
						|
    xvt_scr_set_focus_vobj(w);
 | 
						|
    xvt_vobj_raise(w);        
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void TWindow::maximize() const
 | 
						|
{
 | 
						|
  xvt_vobj_maximize(win());
 | 
						|
} 
 | 
						|
 | 
						|
void TWindow::minimize() const
 | 
						|
{
 | 
						|
  xvt_vobj_minimize(win());
 | 
						|
} 
 | 
						|
 | 
						|
void TWindow::set_background_color(COLOR col)
 | 
						|
{
 | 
						|
  XI_OBJ* itf = xi_get_itf((XinWindow)win());
 | 
						|
  itf->v.itf->back_color = col;
 | 
						|
  force_update();
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Attiva/disattiva la finestra
 | 
						|
void TWindow::activate(
 | 
						|
  bool on) // @parm Indica l'operazione da svolgere sulla finestra:
 | 
						|
  //
 | 
						|
  // @flag TRUE | Abilita la finestra (default)
 | 
						|
  // @flag FALSE | Disabilita la finestra
 | 
						|
{
 | 
						|
  xvt_vobj_set_enabled(win(), _active = on);
 | 
						|
}
 | 
						|
 | 
						|
void TWindow::set_caption(const char* title)
 | 
						|
{
 | 
						|
  xvt_vobj_set_title(win(), title);
 | 
						|
}
 | 
						|
 | 
						|
const char* TWindow::get_caption(TString& str) const
 | 
						|
{
 | 
						|
  char* title = str.get_buffer(128);
 | 
						|
  xvt_vobj_get_title(win(), title, str.size());
 | 
						|
  return title;
 | 
						|
}
 | 
						|
 | 
						|
void TWindow::force_update()
 | 
						|
{
 | 
						|
  if (win() != NULL_WIN)
 | 
						|
    xvt_dwin_invalidate_rect(win(), NULL);
 | 
						|
}
 | 
						|
 | 
						|
bool TWindow::save_ctools()
 | 
						|
{
 | 
						|
  if (_ctools_saved == FALSE)
 | 
						|
  {
 | 
						|
    xvt_dwin_get_draw_ctools(win(), &_ct);
 | 
						|
    return _ctools_saved = TRUE;
 | 
						|
  }
 | 
						|
  return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
bool TWindow::restore_ctools()
 | 
						|
{
 | 
						|
  if (_ctools_saved)
 | 
						|
  {
 | 
						|
    xvt_dwin_set_draw_ctools(win(), &_ct);
 | 
						|
    _ctools_saved = FALSE;
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
  return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TWindow::set_color(COLOR fore, COLOR back)
 | 
						|
{
 | 
						|
  WINDOW w = win();
 | 
						|
  xvt_dwin_set_fore_color(w, fore);
 | 
						|
  xvt_dwin_set_back_color(w, back);
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Sceglie la penna da utilizzare nella finestra
 | 
						|
void TWindow::set_pen(
 | 
						|
  COLOR color,     // @parm Colore della penna
 | 
						|
  int width,       // @parm Larghezza del tratto (default 1)
 | 
						|
  PAT_STYLE pat,   // @parm Stile del pattern (default PAT_SOLID)
 | 
						|
  PEN_STYLE style) // @parm Stile della penna (default P_SOLID)
 | 
						|
{
 | 
						|
  CPEN pen;
 | 
						|
 | 
						|
  pen.width = width;
 | 
						|
  pen.pat   = pat;
 | 
						|
  pen.style = style;
 | 
						|
  pen.color = color;
 | 
						|
 | 
						|
  xvt_dwin_set_cpen(win(), &pen);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TWindow::hide_pen()
 | 
						|
{
 | 
						|
  xvt_dwin_set_std_cpen(win(), TL_PEN_HOLLOW);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TWindow::set_brush(COLOR color, PAT_STYLE pat)
 | 
						|
{
 | 
						|
  CBRUSH brush = { pat, color };
 | 
						|
  xvt_dwin_set_cbrush(win(), &brush);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TWindow::hide_brush()
 | 
						|
{
 | 
						|
  CBRUSH brush = { PAT_HOLLOW, COLOR_WHITE };
 | 
						|
  xvt_dwin_set_cbrush(win(), &brush);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
HIDDEN void swap(short& a, short& b)
 | 
						|
{
 | 
						|
  short tmp = a;
 | 
						|
  a = b;
 | 
						|
  b = tmp;
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Disegna un rettangolo con la possibilita' di settare la penna e il draw_mode
 | 
						|
void TWindow::frame(
 | 
						|
  short left,   // @parm Lato sinistro del rettangolo
 | 
						|
  short top,    // @parm Lato superiore del rettangolo
 | 
						|
  short right,  // @parm Lato destro del rettangolo
 | 
						|
  short bottom, // @parm Lato inferiore del rettangolo
 | 
						|
  int flag)     // @parm Flag da assegnare per il disegno del rettangolo
 | 
						|
 | 
						|
  // @comm Se <p left> <gt> <p right> oppure <p top> <gt> <p bottom> i valori
 | 
						|
  //       vengono scambiati per permettere il disegno corretto del rettangolo
 | 
						|
{
 | 
						|
  if (left > right) swap(left, right);
 | 
						|
  if (top > bottom) swap(top, bottom);
 | 
						|
 | 
						|
  const bool saved = flag != 0 && save_ctools();
 | 
						|
 | 
						|
  if (flag & 1) hide_pen();
 | 
						|
  if (flag & 2) hide_brush();
 | 
						|
  if (flag & 4)
 | 
						|
  {
 | 
						|
    set_mode(M_XOR);
 | 
						|
#ifdef XVAGA
 | 
						|
		set_brush(COLOR_WHITE);
 | 
						|
#else
 | 
						|
    set_brush(COLOR_BLACK);     // Needed for Windows
 | 
						|
#endif
 | 
						|
  }
 | 
						|
 | 
						|
  const PNT f = log2dev(left,top);
 | 
						|
  const PNT t = log2dev(right,bottom);
 | 
						|
  RCT r;
 | 
						|
  r.top = f.v; r.left = f.h;
 | 
						|
  r.bottom = t.v; r.right = t.h;
 | 
						|
 | 
						|
  if (!_pixmap && (flag & 2))
 | 
						|
  {
 | 
						|
    r.left += CHARX>>1; r.top += CHARY>>1;
 | 
						|
    r.right-= CHARX>>1; r.bottom -= CHARY>>1;
 | 
						|
  }
 | 
						|
 | 
						|
  xvt_dwin_draw_rect(win(), &r);
 | 
						|
 | 
						|
  if (saved) restore_ctools();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TWindow::rect(short left, short top, short right, short bottom)
 | 
						|
{
 | 
						|
  frame(left, top, right, bottom, 2);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TWindow::bar(short left, short top, short right, short bottom)
 | 
						|
{
 | 
						|
  frame(left, top, right, bottom, 1);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TWindow::invert_bar(short left, short top, short right, short bottom)
 | 
						|
{
 | 
						|
  frame(left, top, right, bottom, 5);
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Setta opaque_text
 | 
						|
void TWindow::set_opaque_text(
 | 
						|
  bool o) // @parm Indica la modalita' di scrittura dell'opaque_text
 | 
						|
{
 | 
						|
  // @comm Quando <p o> e' FALSE il testo viene scritto in modo trasparente
 | 
						|
  DRAW_CTOOLS ct;
 | 
						|
  xvt_dwin_get_draw_ctools(win(), &ct);
 | 
						|
  ct.opaque_text = o;
 | 
						|
  xvt_dwin_set_draw_ctools(win(), &ct);
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Sceglie il font da utilizzare nella finestra
 | 
						|
void TWindow::set_font(
 | 
						|
  const char* family, // @parm Famiglia di appartenenza del font (default XVT_FFN_FIXED)
 | 
						|
  int style,          // @parm Stile del font (default 0)
 | 
						|
  int dim)            // @parm Dimensione del font (default 0)
 | 
						|
{
 | 
						|
  xvtil_set_font(win(), family, style, dim);
 | 
						|
  _base_char_width = 0L;
 | 
						|
}
 | 
						|
 | 
						|
int TWindow::char2pixel(int len) const
 | 
						|
{
 | 
						|
	const int quantem = 80;
 | 
						|
  if (_base_char_width == 0L)
 | 
						|
  {
 | 
						|
    const TString emme(quantem, 'M');
 | 
						|
    long& bcw = (long&)_base_char_width;
 | 
						|
    bcw = xvt_dwin_get_text_width(win(), emme, quantem);
 | 
						|
  }
 | 
						|
  const int pix = int(len * _base_char_width / quantem);
 | 
						|
  return pix;
 | 
						|
}
 | 
						|
 | 
						|
PNT TWindow::log2dev(long x, long y) const
 | 
						|
{
 | 
						|
  PNT pnt = { short(y), short(x) };
 | 
						|
  if (!_pixmap)
 | 
						|
  {
 | 
						|
    pnt.h = char2pixel(pnt.h);
 | 
						|
    pnt.v *= CHARY;
 | 
						|
  }
 | 
						|
  return pnt;
 | 
						|
}
 | 
						|
 | 
						|
TPoint TWindow::dev2log(const PNT& p) const
 | 
						|
{
 | 
						|
  TPoint pnt(p.h, p.v);
 | 
						|
  if (!_pixmap)
 | 
						|
  {
 | 
						|
    pnt.x = int(128L * p.h / char2pixel(128));
 | 
						|
    pnt.y /= CHARY;
 | 
						|
  }
 | 
						|
  return pnt;
 | 
						|
}
 | 
						|
 | 
						|
void TWindow::log2dev(const TRectangle& lrct, RCT& drct) const
 | 
						|
{
 | 
						|
  const PNT dp0 = log2dev(lrct.x, lrct.y);
 | 
						|
  const PNT dp1 = log2dev(lrct.right(), lrct.bottom());
 | 
						|
  drct.left = dp0.h; drct.top = dp0.v; 
 | 
						|
  drct.right = dp1.h; drct.bottom = dp1.v; 
 | 
						|
}
 | 
						|
 | 
						|
void TWindow::dev2log(const RCT& rctd, TRectangle& rctl) const
 | 
						|
{
 | 
						|
  const PNT dp0 = { rctd.top, rctd.left };
 | 
						|
  const PNT dp1 = { rctd.bottom, rctd.right };
 | 
						|
  const TPoint lp0 = dev2log(dp0);
 | 
						|
  const TPoint lp1 = dev2log(dp1);
 | 
						|
  rctl.set_bounds(lp0.x, lp0.y, lp1.x, lp1.y);
 | 
						|
}
 | 
						|
 | 
						|
void TWindow::stringat(short x, short y, const char* str)
 | 
						|
{
 | 
						|
  PNT pnt = log2dev(x,y);
 | 
						|
  pnt.v += BASEY;
 | 
						|
  xvt_dwin_draw_text(win(), pnt.h, pnt.v, str, -1);
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Scrive il testo formattato nella finestra alla posizione indicata
 | 
						|
void TWindow::printat(
 | 
						|
  short x,         // @parm Coordinata x della finestra in cui scrivere il testo
 | 
						|
  short y,         // @parm Coordinata y della finestra in cui scrivere il testo
 | 
						|
  const char* fmt, // @parm Formato che deve essere dato al testo
 | 
						|
  ...)             // @parmvar Uno o piu' parametri corrispondenti ai codici in <p fmt>
 | 
						|
{      
 | 
						|
  if (fmt && *fmt)
 | 
						|
  {
 | 
						|
    if (strchr(fmt, '%') != NULL)
 | 
						|
    {
 | 
						|
      TString256 str;  // TString str(256);
 | 
						|
      char* tmp = str.get_buffer();
 | 
						|
      va_list argptr;
 | 
						|
      va_start(argptr, fmt);    
 | 
						|
      vsprintf(tmp, fmt, argptr);
 | 
						|
      va_end(argptr);
 | 
						|
      stringat(x, y, tmp);
 | 
						|
    }
 | 
						|
    else
 | 
						|
      stringat(x, y, fmt);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void TWindow::line(short x0, short y0, short x1, short y1)
 | 
						|
{
 | 
						|
  PNT f = log2dev(x0,y0);
 | 
						|
  PNT t = log2dev(x1,y1);
 | 
						|
 | 
						|
  if (!_pixmap) 
 | 
						|
  {
 | 
						|
    if (f.h == 0) f.h = -CHARX; else f.h += CHARX>>1;
 | 
						|
    if (f.v == 0) f.v = -CHARY; else f.v += CHARY>>1;
 | 
						|
    if (t.h == 0) t.h = -CHARX; else t.h += CHARX>>1;
 | 
						|
    if (t.v == 0) t.v = -CHARY; else t.v += CHARY>>1;
 | 
						|
  }
 | 
						|
 | 
						|
  xvt_dwin_draw_set_pos(win(), f);
 | 
						|
  xvt_dwin_draw_line(win(), t);
 | 
						|
}
 | 
						|
 | 
						|
void TWindow::icon(short x0, short y0, int iconid)
 | 
						|
{
 | 
						|
  PNT f = log2dev(x0,y0);
 | 
						|
  if (iconid < 0) iconid = ICON_RSRC;
 | 
						|
  xvt_dwin_draw_icon(win(), f.h, f.v, iconid);
 | 
						|
}
 | 
						|
 | 
						|
void TWindow::clear(COLOR color)
 | 
						|
{ xvt_dwin_clear(win(), color); }
 | 
						|
 | 
						|
void TWindow::set_mode(DRAW_MODE mode)
 | 
						|
{ xvt_dwin_set_draw_mode(win(), mode); }
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Aggiunge voci di menu' durante l'esecuzione di una finestra
 | 
						|
//
 | 
						|
// @rdesc Ritorna se e' riuscito ad aggiungere la voce al menu':
 | 
						|
//
 | 
						|
// @flag TRUE | Se ha ggiunto la voce
 | 
						|
// @flag FALSE | Se non ha ggiunto la voce
 | 
						|
bool TWindow::add_menu(
 | 
						|
  TString_array& menu, // @parm Array da aggiungere al menu'
 | 
						|
  MENU_TAG id,         // @parm Identificatore del menu' a cui aggiungere le voci
 | 
						|
  bool force)          // @parm Mai usato
 | 
						|
  
 | 
						|
  // @comm Nel caso <p id> sia uguale a 0 la voce veine aggiunte nella barra dei menu'
 | 
						|
{ 
 | 
						|
  CHECK(menu.items() > 0, "TWindow::add_menu: no menus to add");
 | 
						|
 | 
						|
  // get menu tree
 | 
						|
  MENU_ITEM* menubar = xvt_menu_get_tree(win());
 | 
						|
  
 | 
						|
  if (id == 0)  // add to menubar
 | 
						|
  {
 | 
						|
    // count menus
 | 
						|
    int nmen;
 | 
						|
    for (nmen = 0; menubar[nmen].tag != 0; nmen++);           
 | 
						|
    menubar = (MENU_ITEM*)xvt_mem_realloc((DATA_PTR)menubar, 
 | 
						|
                                          sizeof(MENU_ITEM)*(nmen+menu.items()+1));
 | 
						|
    // zero new
 | 
						|
    xvt_mem_rep((DATA_PTR)&menubar[nmen], "\0", 1, sizeof(MENU_ITEM)*(menu.items()+1));
 | 
						|
 | 
						|
    // add new menus
 | 
						|
    for (int i = 0; i < menu.items(); i++)
 | 
						|
      set_menu_item(menubar[nmen+i], menu.row(i));
 | 
						|
  }   
 | 
						|
  else  // add to menu
 | 
						|
  {
 | 
						|
    MENU_ITEM* father = find_menu_item(menubar, id, TRUE);
 | 
						|
    CHECK(father != NULL, "TWindow::add_menu: you're adding to a NULL menu item");
 | 
						|
    
 | 
						|
    // count children
 | 
						|
    int nmen;
 | 
						|
    for (nmen = 0; father->child != NULL && father->child[nmen].tag != 0; nmen++);           
 | 
						|
    father->child = (MENU_ITEM*)xvt_mem_realloc((DATA_PTR)father->child, 
 | 
						|
                                                sizeof(MENU_ITEM)*(nmen+menu.items()+1));
 | 
						|
    // zero new
 | 
						|
    xvt_mem_rep((DATA_PTR)&(father->child[nmen]), "\0", 1, sizeof(MENU_ITEM)*(menu.items()+1));
 | 
						|
 | 
						|
    // add new menus
 | 
						|
    for (int i = 0; i < menu.items(); i++)
 | 
						|
      set_menu_item(father->child[nmen+i], menu.row(i));    
 | 
						|
  }
 | 
						|
  
 | 
						|
  xvt_menu_set_tree(win(), menubar);              
 | 
						|
  xvt_res_free_menu_tree(menubar);
 | 
						|
  
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
bool TWindow::remove_menu(MENU_TAG id)
 | 
						|
{
 | 
						|
  MENU_ITEM* menubar = xvt_menu_get_tree(win());
 | 
						|
  if (remove_menu_item(menubar, id, TRUE))
 | 
						|
  {
 | 
						|
    xvt_menu_set_tree(win(),menubar);
 | 
						|
    xvt_res_free_menu_tree(menubar);
 | 
						|
  }                                 
 | 
						|
  return TRUE;
 | 
						|
}                                                          
 | 
						|
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TTemp_window
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
TTemp_window::TTemp_window(WINDOW w)
 | 
						|
{
 | 
						|
  set_win(w);
 | 
						|
}
 | 
						|
 | 
						|
TTemp_window::~TTemp_window()
 | 
						|
{
 | 
						|
  set_win(NULL_WIN);    // I don't want to be closed!
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TScroll_window
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
TScroll_window::TScroll_window()
 | 
						|
: _origin(0, 0), _max(0, 0), _shift(0), _autoscroll(TRUE),
 | 
						|
  _has_hscroll(TRUE), _has_vscroll(TRUE)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
WINDOW TScroll_window::create(short x, short y, short dx, short dy,
 | 
						|
                              const char* title, long flags, WIN_TYPE wt, WINDOW parent, int menu)
 | 
						|
{
 | 
						|
  _has_hscroll = (flags & WSF_HSCROLL) != 0;
 | 
						|
  _has_vscroll = (flags & WSF_VSCROLL) != 0 ;
 | 
						|
  return TWindow::create(x, y, dx, dy, title, flags, wt, parent, menu);
 | 
						|
}
 | 
						|
 | 
						|
PNT TScroll_window::log2dev(long x, long y) const
 | 
						|
{                                                 
 | 
						|
  if (_autoscroll)
 | 
						|
  {
 | 
						|
    if (_pixmap)
 | 
						|
    {
 | 
						|
      x -= _origin.x * CHARX;
 | 
						|
      y -= (_origin.y >> _shift) * CHARY;
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
      x -= _origin.x;
 | 
						|
      y -= _origin.y >> _shift;
 | 
						|
    } 
 | 
						|
  }
 | 
						|
  return TWindow::log2dev(x,y);
 | 
						|
}
 | 
						|
 | 
						|
void TScroll_window::set_scroll_max(long maxx, long maxy)
 | 
						|
{
 | 
						|
  if (_has_hscroll && maxx >= 0)
 | 
						|
  {
 | 
						|
    _max.x = maxx;
 | 
						|
    xvt_sbar_set_range(win(), HSCROLL, 0, int(maxx));
 | 
						|
  }
 | 
						|
  if (_has_vscroll && maxy >= 0)
 | 
						|
  {
 | 
						|
    _shift = 0;
 | 
						|
    while ((maxy >> _shift) > 0x7FFF) _shift++;
 | 
						|
    _max.y = maxy;
 | 
						|
    xvt_sbar_set_range(win(), VSCROLL, 0, int(maxy >> _shift));
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
// @doc EXTERNAL
 | 
						|
 | 
						|
// @mfunc Aggiorna la scrollbar
 | 
						|
void TScroll_window::update_thumb(
 | 
						|
  long x, // @parm Indica la posizione in x in cui spostare la finestra (default -1)
 | 
						|
  long y) // @parm Indica la posizione in x in cui spostare la finestra (default -1)
 | 
						|
  
 | 
						|
  // @comm Nel caso si voglia aggiornare solamente una coordinata l'altra dovra' essere
 | 
						|
  //                     settata a -1     
 | 
						|
{
 | 
						|
  if (x >= 0 && x <= _max.x) _origin.x = x;
 | 
						|
  if (y >= 0 && y <= _max.y) _origin.y = y;
 | 
						|
 | 
						|
  if (_has_hscroll)
 | 
						|
    xvt_sbar_set_pos(win(), HSCROLL, int(_origin.x));
 | 
						|
  if (_has_vscroll)
 | 
						|
    xvt_sbar_set_pos(win(), VSCROLL, int(_origin.y >> _shift));
 | 
						|
}
 | 
						|
 | 
						|
void TScroll_window::handler(WINDOW win, EVENT* ep)
 | 
						|
{
 | 
						|
  if (ep->type == E_HSCROLL || ep->type == E_VSCROLL)
 | 
						|
  {
 | 
						|
    long& pos = (ep->type == E_HSCROLL) ? _origin.x : _origin.y;
 | 
						|
    const long oldpos = pos;
 | 
						|
    const long max = (ep->type == E_HSCROLL) ? _max.x : _max.y;
 | 
						|
    const short pag = (ep->type == E_HSCROLL) ? columns()/2+1 : rows()/2+1;
 | 
						|
    switch(ep->v.scroll.what)
 | 
						|
    {
 | 
						|
    case SC_PAGE_UP:
 | 
						|
      pos -= pag;
 | 
						|
      break;
 | 
						|
    case SC_LINE_UP:
 | 
						|
      pos--;
 | 
						|
      break;
 | 
						|
    case SC_PAGE_DOWN:
 | 
						|
      pos += pag;
 | 
						|
      break;
 | 
						|
    case SC_LINE_DOWN:
 | 
						|
      pos++;
 | 
						|
      break;
 | 
						|
    case SC_THUMB:
 | 
						|
      pos = ep->v.scroll.pos;
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    if (pos < 0) pos = 0;
 | 
						|
    if (pos > max) pos = max;
 | 
						|
 | 
						|
    if (pos != oldpos)
 | 
						|
    {
 | 
						|
      update_thumb();
 | 
						|
      force_update();
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  TWindow::handler(win, ep);
 | 
						|
}
 | 
						|
 | 
						|
bool TScroll_window::on_key(KEY key)
 | 
						|
{
 | 
						|
  switch(key)
 | 
						|
  {
 | 
						|
  case K_LHOME:
 | 
						|
    update_thumb(0,0);
 | 
						|
    force_update();
 | 
						|
    break;
 | 
						|
  case K_LEND:
 | 
						|
    update_thumb(0,range().y);
 | 
						|
    force_update();
 | 
						|
    break;
 | 
						|
  case K_TAB:
 | 
						|
    update_thumb(origin().x+8);
 | 
						|
    force_update();
 | 
						|
    break;
 | 
						|
  case K_BTAB:
 | 
						|
  {
 | 
						|
    long x = origin().x-8;
 | 
						|
    if (x < 0) x = 0;
 | 
						|
    update_thumb(x);
 | 
						|
    force_update();
 | 
						|
  }
 | 
						|
    break;
 | 
						|
  case K_UP:
 | 
						|
  case K_DOWN:
 | 
						|
  case K_PREV:
 | 
						|
  case K_NEXT:
 | 
						|
  case K_LEFT:
 | 
						|
  case K_RIGHT:
 | 
						|
    dispatch_e_scroll(win(), key);
 | 
						|
    break;
 | 
						|
  default:
 | 
						|
    break;
 | 
						|
  }
 | 
						|
  return TWindow::on_key(key);
 | 
						|
}
 |