760 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			760 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include <checks.h>
 | 
						|
#include <urldefid.h>
 | 
						|
#include <utility.h>
 | 
						|
 | 
						|
#define __WINDOW_CPP
 | 
						|
#include <window.h>
 | 
						|
#include <colors.h>
 | 
						|
 | 
						|
 | 
						|
#if XVT_OS == XVT_OS_WIN
 | 
						|
#include <windows.h>
 | 
						|
#endif
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TWindow_manager
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// @C
 | 
						|
// Classe TWindow_manager
 | 
						|
//
 | 
						|
// @END
 | 
						|
 | 
						|
class TWindow_manager
 | 
						|
{
 | 
						|
  // @DPRIV
 | 
						|
  enum { MAX_WIN = 4 }; // Max number of modal windows
 | 
						|
 | 
						|
  TWindow* _window[MAX_WIN];    // Stack of active windows
 | 
						|
  char _current;                // Stack pointer
 | 
						|
  void menu_enable(bool) const;  // Abilita o disabilita il menu della task window
 | 
						|
 | 
						|
public:
 | 
						|
  // @FPUB
 | 
						|
  TWindow_manager(); // Costruttore
 | 
						|
  ~TWindow_manager() { destroy(); }
 | 
						|
 | 
						|
  void reg(TWindow* m);
 | 
						|
  // Registra la finestra corrente
 | 
						|
  void unreg(const TWindow* m);
 | 
						|
  // De-registra la finestra corrente
 | 
						|
 | 
						|
  TWindow* cur_win() const { return (_current < 0) ? NULL : _window[_current]; } // Ritorna il puntatore alla finestra corrente
 | 
						|
  void destroy();
 | 
						|
  bool can_close() const;
 | 
						|
} WinManager;
 | 
						|
 | 
						|
 | 
						|
TWindow_manager::TWindow_manager() : _current(-1)
 | 
						|
{}
 | 
						|
 | 
						|
 | 
						|
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 MENU_FILE:
 | 
						|
      if (m->child)
 | 
						|
        xvt_menu_enable(m->child, on);
 | 
						|
      break;
 | 
						|
    case 65535:          // Separator
 | 
						|
    case M_FILE_NEW:
 | 
						|
    case M_FILE_REVERT:
 | 
						|
    case M_FILE_QUIT:
 | 
						|
    case M_FILE_ABOUT:
 | 
						|
    case M_FILE_PRINT:
 | 
						|
    case M_FILE_PG_SETUP:
 | 
						|
    case (M_FILE+11):
 | 
						|
      break;             // Leave them as they are
 | 
						|
    default:
 | 
						|
      win_menu_enable(TASK_WIN, m->tag, on);
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    m++;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TWindow_manager::menu_enable(bool on) const
 | 
						|
{
 | 
						|
  MENU_ITEM *mi = win_menu_fetch(TASK_WIN);
 | 
						|
  xvt_menu_enable(mi, on);
 | 
						|
  win_update_menu_bar(TASK_WIN);
 | 
						|
  menu_free(mi);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TWindow_manager::reg(TWindow* m)
 | 
						|
{
 | 
						|
  _current++;
 | 
						|
  CHECK(_current < MAX_WIN, "Too many windows");
 | 
						|
 | 
						|
  switch (_current)
 | 
						|
  {
 | 
						|
  case 0 : 
 | 
						|
    menu_enable(FALSE);
 | 
						|
    break;
 | 
						|
  case 1 : 
 | 
						|
    win_menu_enable(TASK_WIN, M_FILE_QUIT, 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
 | 
						|
  {
 | 
						|
    cur_win()->activate();
 | 
						|
    win_menu_enable(TASK_WIN, M_FILE_QUIT, _current == 0);
 | 
						|
    win_update_menu_bar(TASK_WIN);
 | 
						|
    cur_win()->set_focus();
 | 
						|
  }     
 | 
						|
}
 | 
						|
 | 
						|
void close_all_dialogs()
 | 
						|
{
 | 
						|
  WinManager.destroy();
 | 
						|
}
 | 
						|
 | 
						|
bool can_close()
 | 
						|
{
 | 
						|
  return WinManager.can_close();
 | 
						|
}
 | 
						|
 | 
						|
WINDOW cur_win()
 | 
						|
{
 | 
						|
  const TWindow* w = WinManager.cur_win();
 | 
						|
  return w ? w->win() : NULL_WIN;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TWindow
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
DRAW_CTOOLS TWindow::_ct;
 | 
						|
bool TWindow::_ctools_saved;
 | 
						|
 | 
						|
 | 
						|
TWindow::TWindow()
 | 
						|
: _win(NULL_WIN), _open(FALSE), _modal(FALSE), _active(TRUE),
 | 
						|
  _running(FALSE), _pixmap(FALSE), _lastkey(0)
 | 
						|
{}
 | 
						|
 | 
						|
 | 
						|
long TWindow::window_handler(WINDOW win, EVENT* ep)
 | 
						|
{
 | 
						|
  TWindow* w = (TWindow*)get_app_data(win);
 | 
						|
  CHECK(w != NULL, "Invalid window");
 | 
						|
  w->handler(win, ep);
 | 
						|
 | 
						|
  return 0L;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
WINDOW TWindow::create(short x, short y, short dx, short dy,
 | 
						|
                       const char* title, long flags, WIN_TYPE wt, 
 | 
						|
                       WINDOW parent, int menu)
 | 
						|
{
 | 
						|
  if (menu == 0) flags |= WSF_NO_MENUBAR;
 | 
						|
 | 
						|
  if (parent == NULL_WIN) parent = TASK_WIN;
 | 
						|
  if (parent == TASK_WIN) flags |= WSF_INVISIBLE;
 | 
						|
 | 
						|
  _win = xvt_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)
 | 
						|
  {
 | 
						|
    close_window(_win);
 | 
						|
    _win = NULL_WIN;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TWindow::open()
 | 
						|
{
 | 
						|
  CHECK(win() != NULL_WIN, "Can't open a NULL window");
 | 
						|
  show_window(win(), _open = TRUE);
 | 
						|
  set_front_window(win());
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
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");
 | 
						|
  show_window(_win, _open = FALSE);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TWindow::close_modal()
 | 
						|
{
 | 
						|
  WinManager.unreg(this);
 | 
						|
  close();
 | 
						|
  _open = 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;
 | 
						|
}
 | 
						|
 | 
						|
KEY TWindow::run()
 | 
						|
{
 | 
						|
  const bool was_open = is_open();
 | 
						|
 | 
						|
  start_run();
 | 
						|
  _running = TRUE;
 | 
						|
 | 
						|
  if (!was_open) open_modal();
 | 
						|
  else  open();
 | 
						|
 | 
						|
  while (_running)
 | 
						|
    do_events();
 | 
						|
 | 
						|
  if (!was_open) close_modal();
 | 
						|
 | 
						|
  return last_key();
 | 
						|
}
 | 
						|
 | 
						|
void TWindow::handler(WINDOW win, EVENT* ep)
 | 
						|
{
 | 
						|
  switch(ep->type)
 | 
						|
  {
 | 
						|
  case E_CLOSE:
 | 
						|
    stop_run(K_ESC);
 | 
						|
    break;
 | 
						|
  case E_UPDATE:
 | 
						|
    clear_window(win, NORMAL_BACK_COLOR);
 | 
						|
    update();
 | 
						|
    break;
 | 
						|
  case E_CHAR:
 | 
						|
    on_key(e_char_to_key(ep));
 | 
						|
    break;
 | 
						|
  case E_DESTROY:
 | 
						|
    _win = NULL_WIN;
 | 
						|
    break;
 | 
						|
  default:
 | 
						|
    break;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
TPoint TWindow::size() const
 | 
						|
{
 | 
						|
  RCT r;
 | 
						|
  get_client_rect(_win ? _win : TASK_WIN, &r);
 | 
						|
  return TPoint(r.right / CHARX, r.bottom / CHARY);
 | 
						|
}
 | 
						|
 | 
						|
WINDOW TWindow::parent() const
 | 
						|
{
 | 
						|
  return get_parent(win());
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TWindow::set_focus()
 | 
						|
{
 | 
						|
  if (_win)
 | 
						|
    set_front_window(_win);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TWindow::iconize() const
 | 
						|
{
 | 
						|
#if XVTWS != WMWS
 | 
						|
  HWND hwnd = (HWND)get_value(win(), ATTR_NATIVE_WINDOW);
 | 
						|
  ShowWindow(hwnd, SW_MINIMIZE);
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
void TWindow::maximize() const
 | 
						|
{
 | 
						|
#if XVTWS != WMWS
 | 
						|
  HWND hwnd = (HWND)get_value(win(), ATTR_NATIVE_WINDOW);
 | 
						|
  ShowWindow(hwnd, SW_SHOWMAXIMIZED);
 | 
						|
#else            
 | 
						|
  RCT r; set_rect(&r, 1,1,79,23);
 | 
						|
  move_window(win(),&r);
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
void TWindow::activate(bool on)
 | 
						|
{
 | 
						|
  enable_window(win(), _active = on);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TWindow::set_caption(const char* title)
 | 
						|
{
 | 
						|
  set_title(win(), (char*)title);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
const char* TWindow::get_caption() const
 | 
						|
{
 | 
						|
  char* title = &__tmp_string[512];
 | 
						|
  get_title(win(), title, 80);
 | 
						|
  return title;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TWindow::force_update()
 | 
						|
{
 | 
						|
  if (win() != NULL_WIN)
 | 
						|
    invalidate_rect(win(), NULL);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool TWindow::save_ctools()
 | 
						|
{
 | 
						|
  if (_ctools_saved == FALSE)
 | 
						|
  {
 | 
						|
    win_get_draw_ctools(win(), &_ct);
 | 
						|
    return _ctools_saved = TRUE;
 | 
						|
  }
 | 
						|
  return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool TWindow::restore_ctools()
 | 
						|
{
 | 
						|
  if (_ctools_saved)
 | 
						|
  {
 | 
						|
    win_set_draw_ctools(win(), &_ct);
 | 
						|
    _ctools_saved = FALSE;
 | 
						|
    return TRUE;
 | 
						|
  }
 | 
						|
  return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TWindow::set_color(COLOR fore, COLOR back)
 | 
						|
{
 | 
						|
  win_set_fore_color(win(), fore);
 | 
						|
  win_set_back_color(win(), back);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TWindow::set_pen(COLOR color, int width, PAT_STYLE pat, PEN_STYLE style)
 | 
						|
{
 | 
						|
  CPEN pen;
 | 
						|
 | 
						|
  pen.width = width;
 | 
						|
  pen.pat   = pat;
 | 
						|
  pen.style = style;
 | 
						|
  pen.color = color;
 | 
						|
 | 
						|
  win_set_cpen(win(), &pen);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TWindow::hide_pen()
 | 
						|
{
 | 
						|
  win_set_std_cpen(win(), TL_PEN_HOLLOW);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TWindow::set_brush(COLOR color, PAT_STYLE pat)
 | 
						|
{
 | 
						|
  CBRUSH brush = { pat, color };
 | 
						|
  win_set_cbrush(win(), &brush);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TWindow::hide_brush()
 | 
						|
{
 | 
						|
  CBRUSH brush = { PAT_HOLLOW, COLOR_WHITE };
 | 
						|
  win_set_cbrush(win(), &brush);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
HIDDEN void swap(short& a, short& b)
 | 
						|
{
 | 
						|
  short tmp = a;
 | 
						|
  a = b;
 | 
						|
  b = tmp;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TWindow::frame(short left, short top, short right, short bottom,
 | 
						|
                    int flag)
 | 
						|
{
 | 
						|
  if (left > right) swap(left, right);
 | 
						|
  if (top > bottom) swap(top, bottom);
 | 
						|
 | 
						|
  const bool saved = flag && save_ctools();
 | 
						|
 | 
						|
  if (flag & 1) hide_pen();
 | 
						|
  if (flag & 2) hide_brush();
 | 
						|
  if (flag & 4)
 | 
						|
  {
 | 
						|
    set_mode(M_XOR);
 | 
						|
    set_brush(COLOR_BLACK);     // Needed for Windows
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
  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 XVTWS != WMWS
 | 
						|
  if (flag & 2)
 | 
						|
  {
 | 
						|
    r.left += CHARX>>1; r.top += CHARY>>1;
 | 
						|
    r.right-= CHARX>>1; r.bottom -= CHARY>>1;
 | 
						|
  }
 | 
						|
#endif
 | 
						|
 | 
						|
  win_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);
 | 
						|
}
 | 
						|
 | 
						|
void TWindow::set_opaque_text(bool o)
 | 
						|
{
 | 
						|
  DRAW_CTOOLS ct;
 | 
						|
  win_get_draw_ctools(win(), &ct);
 | 
						|
  ct.opaque_text = o;
 | 
						|
  win_set_draw_ctools(win(), &ct);
 | 
						|
}
 | 
						|
 | 
						|
void TWindow::set_font(int family, int style, int dim)
 | 
						|
{
 | 
						|
  xvt_set_font(win(), family, style, dim);
 | 
						|
}
 | 
						|
 | 
						|
PNT TWindow::log2dev(long x, long y) const
 | 
						|
{
 | 
						|
  PNT pnt;
 | 
						|
 | 
						|
  pnt.h = (int)x;
 | 
						|
  pnt.v = (int)y;
 | 
						|
 | 
						|
  if (!_pixmap)
 | 
						|
  {
 | 
						|
    pnt.h *= CHARX;
 | 
						|
    pnt.v *= CHARY;
 | 
						|
  }
 | 
						|
  
 | 
						|
  return pnt;
 | 
						|
}
 | 
						|
 | 
						|
TPoint TWindow::dev2log(const PNT& p) const
 | 
						|
{
 | 
						|
  TPoint pnt(_pixmap ? p.h : p.h/CHARX, _pixmap ? p.v : p.v/CHARY);
 | 
						|
  return pnt;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TWindow::stringat(short x, short y, const char* str)
 | 
						|
{
 | 
						|
  PNT pnt = log2dev(x,y);
 | 
						|
#if XVTWS != WMWS
 | 
						|
  pnt.v += BASEY;
 | 
						|
#endif
 | 
						|
 | 
						|
  win_draw_text(win(), pnt.h, pnt.v, (char *)str, -1);
 | 
						|
}
 | 
						|
 | 
						|
void TWindow::printat(short x, short y, const char* fmt, ...)
 | 
						|
{
 | 
						|
  va_list argptr;
 | 
						|
  va_start(argptr, fmt);
 | 
						|
  vsprintf(__tmp_string, fmt, argptr);
 | 
						|
  va_end(argptr);
 | 
						|
  stringat(x, y, __tmp_string);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void TWindow::line(short x0, short y0, short x1, short y1)
 | 
						|
{
 | 
						|
  PNT f = log2dev(x0,y0);
 | 
						|
  PNT t = log2dev(x1,y1);
 | 
						|
 | 
						|
#if XVTWS != WMWS
 | 
						|
  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;
 | 
						|
#endif
 | 
						|
 | 
						|
  win_move_to(_win, f);
 | 
						|
  win_draw_line(_win, t);
 | 
						|
}
 | 
						|
 | 
						|
void TWindow::icon(short x0, short y0, int iconid)
 | 
						|
{
 | 
						|
#if XVTWS == WMWS
 | 
						|
  bar(x0, y0, x0+1, y0+1);
 | 
						|
#else
 | 
						|
  PNT f = log2dev(x0,y0);
 | 
						|
  if (iconid < 0) iconid = ICON_RSRC;
 | 
						|
  win_draw_icon(win(), f.h, f.v, iconid);
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
void TWindow::clear(COLOR color)
 | 
						|
{ clear_window(win(), color); }
 | 
						|
 | 
						|
void TWindow::set_mode(DRAW_MODE mode)
 | 
						|
{ win_set_draw_mode(win(), mode); }
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// 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)
 | 
						|
  {
 | 
						|
    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;
 | 
						|
    set_scroll_range(win(), HSCROLL, 0, int(maxx));
 | 
						|
  }
 | 
						|
  if (_has_vscroll && maxy >= 0)
 | 
						|
  {
 | 
						|
    _shift = 0;
 | 
						|
    while ((maxy >> _shift) > 0x7FFF) _shift++;
 | 
						|
    _max.y = maxy;
 | 
						|
    set_scroll_range(win(), VSCROLL, 0, int(maxy >> _shift));
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void TScroll_window::update_thumb(long x, long y)
 | 
						|
{
 | 
						|
  if (x >= 0 && x <= _max.x) _origin.x = x;
 | 
						|
  if (y >= 0 && y <= _max.y) _origin.y = y;
 | 
						|
 | 
						|
  if (_has_hscroll)
 | 
						|
    set_scroll_pos(win(), HSCROLL, int(_origin.x));
 | 
						|
  if (_has_vscroll)
 | 
						|
    set_scroll_pos(win(), VSCROLL, int(_origin.y >> _shift));
 | 
						|
}
 | 
						|
 | 
						|
void TScroll_window::handler(WINDOW win, EVENT* ep)
 | 
						|
{
 | 
						|
  bool up = FALSE;
 | 
						|
 | 
						|
  switch (ep->type)
 | 
						|
  {
 | 
						|
  case E_HSCROLL:
 | 
						|
  case E_VSCROLL:
 | 
						|
  {
 | 
						|
    long& pos = (ep->type == E_HSCROLL) ? _origin.x : _origin.y;
 | 
						|
    long& max = (ep->type == E_HSCROLL) ? _max.x : _max.y;
 | 
						|
    short pag = (ep->type == E_HSCROLL) ? columns()/2+1 : rows()/2+1;
 | 
						|
    switch(ep->v.scroll.what)
 | 
						|
    {
 | 
						|
    case SC_PAGE_UP:
 | 
						|
      pos -= pag;
 | 
						|
      up = TRUE;
 | 
						|
      break;
 | 
						|
    case SC_LINE_UP:
 | 
						|
      pos--;
 | 
						|
      up = TRUE;
 | 
						|
      break;
 | 
						|
    case SC_PAGE_DOWN:
 | 
						|
      pos += pag;
 | 
						|
      up = TRUE;
 | 
						|
      break;
 | 
						|
    case SC_LINE_DOWN:
 | 
						|
      pos++;
 | 
						|
      up = TRUE;
 | 
						|
      break;
 | 
						|
    case SC_THUMB:
 | 
						|
      pos = ep->v.scroll.pos;
 | 
						|
      up = TRUE;
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    if (pos < 0) pos = 0;
 | 
						|
    if (pos > max) pos = max;
 | 
						|
  }
 | 
						|
  break;
 | 
						|
default:
 | 
						|
  break;
 | 
						|
}
 | 
						|
 | 
						|
  if (up)
 | 
						|
  {
 | 
						|
    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);
 | 
						|
}
 | 
						|
 |