Files correlati : xvaga.dll Ricompilazione Demo : [ ] Commento : Support per file di help in formato PDF git-svn-id: svn://10.65.10.50/trunk@20561 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			1259 lines
		
	
	
		
			29 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1259 lines
		
	
	
		
			29 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
#include "wxinc.h"
 | 
						|
 | 
						|
#define XTWIN_CPP 1
 | 
						|
#include "xvt.h"
 | 
						|
#include "xvtart.h"
 | 
						|
#include "xvtwin.h"
 | 
						|
 | 
						|
#include <wx/artprov.h>
 | 
						|
#include <wx/aui/aui.h>
 | 
						|
//#include <wx/dcbuffer.h>
 | 
						|
#include <wx/process.h>
 | 
						|
#include <wx/taskbar.h>
 | 
						|
#include <wx/treectrl.h>
 | 
						|
#include <wx/vlbox.h>
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// Utilities
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
wxHashTable   _nice_windows;
 | 
						|
wxFrame*      _task_win = NULL;
 | 
						|
EVENT_HANDLER _task_win_handler = NULL;
 | 
						|
 | 
						|
wxRect RCT2Rect(const RCT* prct)
 | 
						|
{
 | 
						|
	wxRect rct;
 | 
						|
	if (prct != NULL)
 | 
						|
  {
 | 
						|
	  rct.x = min(prct->left, prct->right);
 | 
						|
	  rct.y = min(prct->top, prct->bottom);
 | 
						|
	  rct.width = abs(prct->right - prct->left);
 | 
						|
	  rct.height = abs(prct->bottom - prct->top);
 | 
						|
  }
 | 
						|
	return rct;
 | 
						|
}
 | 
						|
 | 
						|
void Rect2RCT(const wxRect& r, RCT* rct)
 | 
						|
{ xvt_rect_set(rct, r.x, r.y, r.GetRight()+1, r.GetBottom()+1); }
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// Caret emulation
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
class TwxCaret : private wxTimer
 | 
						|
{
 | 
						|
	WINDOW _owner;
 | 
						|
  PNT _pos;
 | 
						|
	wxSize _size;
 | 
						|
  bool _visible;
 | 
						|
	bool _drawn;
 | 
						|
 | 
						|
protected:
 | 
						|
	void Toggle();
 | 
						|
  virtual void Notify() { Toggle(); }
 | 
						|
 | 
						|
public:
 | 
						|
	void SetPos(int x, int y);
 | 
						|
	void SetSize(int x, int y) { _size.x = x; _size.y = y; }
 | 
						|
	void Show(WINDOW w, bool on = true);
 | 
						|
	void Hide() { Show(NULL_WIN, false); }
 | 
						|
	bool IsVisible() const { return _visible; }
 | 
						|
	WINDOW Owner() const { return _owner; }
 | 
						|
	void Kill();
 | 
						|
 | 
						|
	TwxCaret() :  _owner(NULL_WIN), _visible(false) { }
 | 
						|
	virtual ~TwxCaret() { Kill(); }
 | 
						|
} _TheCaret;
 | 
						|
 | 
						|
void TwxCaret::Kill()
 | 
						|
{ _owner = NULL_WIN; }
 | 
						|
 | 
						|
void TwxCaret::SetPos(int x, int y) 
 | 
						|
{ 
 | 
						|
  if (_visible && _drawn) // Lo cancella se necessario
 | 
						|
	  Toggle();  
 | 
						|
  _pos.h = x; _pos.v = y; 
 | 
						|
}
 | 
						|
 | 
						|
void TwxCaret::Show(WINDOW w, bool on)
 | 
						|
{
 | 
						|
  if (_visible && _drawn)
 | 
						|
		Toggle();  // Lo cancella
 | 
						|
 | 
						|
	_visible = on;
 | 
						|
	if (on)
 | 
						|
	{
 | 
						|
		_owner = w;
 | 
						|
		Toggle();
 | 
						|
		wxTimer::Start(500); // Lampeggia ogni mezzo secondo
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
    if (w == _owner || w == NULL_WIN)
 | 
						|
			Kill();
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void TwxCaret::Toggle()
 | 
						|
{
 | 
						|
	if (!_visible || _owner == NULL_WIN)
 | 
						|
		return;
 | 
						|
		
 | 
						|
	_drawn = !_drawn;
 | 
						|
 | 
						|
	DRAW_CTOOLS dct;
 | 
						|
	xvt_dwin_get_draw_ctools(_owner, &dct);
 | 
						|
 | 
						|
	CPEN pen;
 | 
						|
	pen.width = _size.x;
 | 
						|
	pen.pat = PAT_SOLID;
 | 
						|
	pen.style = P_SOLID;
 | 
						|
  pen.color = dct.fore_color;
 | 
						|
	xvt_dwin_set_draw_mode(_owner, M_NOT_XOR);
 | 
						|
	
 | 
						|
  xvt_dwin_set_cpen(_owner, &pen);
 | 
						|
	xvt_dwin_draw_set_pos(_owner, _pos);
 | 
						|
	PNT p = _pos;	p.v -= _size.y-1;
 | 
						|
 | 
						|
	xvt_dwin_set_clip(_owner, NULL);  // Non si sa mai!
 | 
						|
	xvt_dwin_draw_line(_owner, p);
 | 
						|
	xvt_dwin_set_draw_ctools(_owner, &dct);
 | 
						|
}
 | 
						|
 | 
						|
void xvt_win_set_caret_size(WINDOW win, int width, int height)
 | 
						|
{
 | 
						|
  if (win != NULL_WIN)
 | 
						|
	  _TheCaret.SetSize(width, height);
 | 
						|
}
 | 
						|
 | 
						|
void xvt_win_set_caret_pos(WINDOW win, PNT p)
 | 
						|
{
 | 
						|
  if (win != NULL_WIN)
 | 
						|
	  _TheCaret.SetPos(p.h, p.v-1);
 | 
						|
}
 | 
						|
 | 
						|
void xvt_win_set_caret_visible(WINDOW win, BOOLEAN on)
 | 
						|
{
 | 
						|
	_TheCaret.Show(win, on != 0);
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// Generic Display context
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
TDC::TDC(wxWindow* owner) : _dc(NULL)
 | 
						|
{
 | 
						|
  _owner = owner;
 | 
						|
 | 
						|
	memset(&_dct, 0, sizeof(_dct));
 | 
						|
	_dct.pen.width = 0;
 | 
						|
	_dct.pen.pat = PAT_SOLID;
 | 
						|
  _dct.pen.style = P_SOLID;
 | 
						|
  _dct.pen.color = COLOR_BLACK;
 | 
						|
	_dct.brush.pat = PAT_HOLLOW;
 | 
						|
  _dct.brush.color = COLOR_WHITE;
 | 
						|
	_dct.mode = M_COPY;
 | 
						|
	_dct.fore_color = COLOR_BLACK;
 | 
						|
	_dct.back_color = COLOR_WHITE;
 | 
						|
	_dct.opaque_text = FALSE;
 | 
						|
 | 
						|
  _font.SetPointSize(9);  // Default font
 | 
						|
  _deltaf = 0;
 | 
						|
 | 
						|
  // Reset clip area
 | 
						|
  SetClippingBox(NULL);
 | 
						|
  _real_clip = _clip;
 | 
						|
 | 
						|
	_dirty = -1;  // Absolutely force setting
 | 
						|
}
 | 
						|
 | 
						|
TDC::~TDC()
 | 
						|
{
 | 
						|
	KillDC();
 | 
						|
}
 | 
						|
 | 
						|
void TDC::SetDirty(int d)
 | 
						|
{
 | 
						|
	if (_dirty >= 0)
 | 
						|
		_dirty = d;
 | 
						|
}
 | 
						|
 | 
						|
static int PatternToStyle(PAT_STYLE pat)
 | 
						|
{
 | 
						|
	int style = wxSOLID;
 | 
						|
	switch (pat)
 | 
						|
	{
 | 
						|
  case PAT_NONE:
 | 
						|
  case PAT_HOLLOW:    style = wxTRANSPARENT; break;
 | 
						|
  case PAT_SOLID:	    style = wxSOLID; break;
 | 
						|
  case PAT_HORZ:      style = wxHORIZONTAL_HATCH; break;
 | 
						|
  case PAT_VERT:      style = wxVERTICAL_HATCH; break;
 | 
						|
  case PAT_FDIAG:	    style = wxFDIAGONAL_HATCH; break;
 | 
						|
  case PAT_BDIAG:     style = wxBDIAGONAL_HATCH; break;
 | 
						|
  case PAT_CROSS:     style = wxCROSS_HATCH; break;
 | 
						|
  case PAT_DIAGCROSS: style = wxCROSSDIAG_HATCH; break;
 | 
						|
  case PAT_SPECIAL:		style = wxSOLID; break; //  Used for gradient
 | 
						|
  case PAT_RUBBER:	
 | 
						|
  default: style = wxSOLID; SORRY_BOX(); break;
 | 
						|
	}
 | 
						|
	return style;
 | 
						|
}
 | 
						|
 | 
						|
static int PenStyleToStyle(PEN_STYLE s, PAT_STYLE p)
 | 
						|
{
 | 
						|
	int style = wxSOLID;
 | 
						|
	if (p != PAT_HOLLOW)
 | 
						|
	{
 | 
						|
		switch (s)
 | 
						|
		{
 | 
						|
		case P_DOT : style = wxDOT;        break;
 | 
						|
		case P_DASH: style = wxSHORT_DASH; break;
 | 
						|
		default: break;
 | 
						|
		}
 | 
						|
	}
 | 
						|
	else
 | 
						|
		style = wxTRANSPARENT;
 | 
						|
 | 
						|
	return style;
 | 
						|
}
 | 
						|
 | 
						|
bool TDC::PenChanged() const
 | 
						|
{
 | 
						|
	const int diff = memcmp(&_dct.pen, &_real_dct.pen, sizeof(_dct.pen));
 | 
						|
  return diff != 0;
 | 
						|
}
 | 
						|
 | 
						|
bool TDC::BrushChanged() const
 | 
						|
{
 | 
						|
	const int diff = memcmp(&_dct.brush, &_real_dct.brush, sizeof(_dct.brush));
 | 
						|
  return diff != 0;
 | 
						|
}
 | 
						|
 | 
						|
bool TDC::FontChanged() const
 | 
						|
{
 | 
						|
  return _font != _real_font;
 | 
						|
}
 | 
						|
 | 
						|
bool TDC::ClipChanged() const
 | 
						|
{
 | 
						|
	const int diff = memcmp(&_clip, &_real_clip, sizeof(_clip));
 | 
						|
  return diff != 0;
 | 
						|
}
 | 
						|
 | 
						|
#ifdef LINUX
 | 
						|
bool is_printer_dc(wxDC * dc)
 | 
						|
{
 | 
						|
	return wxDynamicCast(dc, wxPostScriptDC) != NULL;
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
wxDC& TDC::GetDC(bool bPaint)
 | 
						|
{
 | 
						|
  if (bPaint)
 | 
						|
	{
 | 
						|
		KillDC();
 | 
						|
    //_dc = new wxAutoBufferedPaintDC(_owner); // Funziona ma si vedono cose strane temporanee
 | 
						|
	  _dc = new wxPaintDC(_owner);
 | 
						|
  	_dirty = -1;
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		if (_dc == NULL)
 | 
						|
		{
 | 
						|
      if (_owner == NULL || (unsigned long)_owner == SCREEN_WIN)
 | 
						|
        _dc = new wxScreenDC();
 | 
						|
      else  
 | 
						|
		    _dc = new wxClientDC(_owner);
 | 
						|
    	_dirty = -1;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	if (_dirty)
 | 
						|
	{
 | 
						|
		if (_dirty < 0 || PenChanged())
 | 
						|
		{
 | 
						|
		  CAST_COLOR(_dct.pen.color, pen_color);
 | 
						|
  		wxPen* pen = wxThePenList->FindOrCreatePen(pen_color, _dct.pen.width, PenStyleToStyle(_dct.pen.style, _dct.pen.pat));
 | 
						|
	  	_dc->SetPen(*pen);
 | 
						|
			_real_dct.pen = _dct.pen;
 | 
						|
		}
 | 
						|
 | 
						|
		if (_dirty < 0 || BrushChanged())
 | 
						|
		{
 | 
						|
 		  CAST_COLOR(_dct.brush.color, brush_color);
 | 
						|
		  wxBrush* brush = wxTheBrushList->FindOrCreateBrush(brush_color, PatternToStyle(_dct.brush.pat));
 | 
						|
		  _dc->SetBrush(*brush);
 | 
						|
			_real_dct.brush = _dct.brush;
 | 
						|
		}
 | 
						|
 | 
						|
		if (_dirty < 0 || _dct.mode != _real_dct.mode)
 | 
						|
		{
 | 
						|
#ifdef LINUX
 | 
						|
			if(!is_printer_dc(_dc))
 | 
						|
			{ 
 | 
						|
#endif
 | 
						|
			switch(_dct.mode)
 | 
						|
			{
 | 
						|
			case M_COPY:     _dc->SetLogicalFunction(wxCOPY); break;
 | 
						|
			case M_OR:       _dc->SetLogicalFunction(wxOR); break;
 | 
						|
			case M_XOR:      _dc->SetLogicalFunction(wxXOR); break;
 | 
						|
			case M_CLEAR:    _dc->SetLogicalFunction(wxCLEAR); break;
 | 
						|
			case M_NOT_COPY: _dc->SetLogicalFunction(wxSRC_INVERT); break;
 | 
						|
			case M_NOT_OR:   _dc->SetLogicalFunction(wxNOR); break;
 | 
						|
			case M_NOT_XOR:  _dc->SetLogicalFunction(wxEQUIV); break;
 | 
						|
			case M_NOT_CLEAR:_dc->SetLogicalFunction(wxSET); break;
 | 
						|
			default: SORRY_BOX();
 | 
						|
			}
 | 
						|
#ifdef LINUX
 | 
						|
			}
 | 
						|
#endif
 | 
						|
			_real_dct.mode = _dct.mode;
 | 
						|
		}
 | 
						|
 | 
						|
		if (_dirty < 0 || _dct.fore_color != _real_dct.fore_color)
 | 
						|
		{
 | 
						|
 		  CAST_COLOR(_dct.fore_color, fore_color);
 | 
						|
		  _dc->SetTextForeground(fore_color);
 | 
						|
			_real_dct.fore_color = _dct.fore_color;
 | 
						|
		}
 | 
						|
 | 
						|
		if (_dirty < 0 || _dct.back_color != _real_dct.back_color)
 | 
						|
		{
 | 
						|
 		  CAST_COLOR(_dct.back_color, back_color);
 | 
						|
		  _dc->SetTextBackground(back_color);
 | 
						|
			_real_dct.back_color = _dct.back_color;
 | 
						|
		}
 | 
						|
 | 
						|
		if (_dirty < 0 || _dct.opaque_text != _real_dct.opaque_text)
 | 
						|
		{
 | 
						|
		  _dc->SetBackgroundMode(_dct.opaque_text ? wxSOLID : wxTRANSPARENT);
 | 
						|
			_real_dct.opaque_text = _dct.opaque_text;
 | 
						|
		}
 | 
						|
 | 
						|
		if (_dirty < 0 || FontChanged())
 | 
						|
		{
 | 
						|
      const wxFont& f = _font.Font(_dc, (WINDOW)_owner);
 | 
						|
 		  _dc->SetFont(f);
 | 
						|
			_real_font = _font;
 | 
						|
 | 
						|
		  int height, desc, lead; 	
 | 
						|
      _dc->GetTextExtent("Mg", NULL, &height, &desc, &lead);
 | 
						|
		  _deltaf = height-desc+1;
 | 
						|
		}
 | 
						|
 | 
						|
    if (_dirty < 0 || ClipChanged())
 | 
						|
    {
 | 
						|
      _dc->DestroyClippingRegion();
 | 
						|
      if (_clip.bottom < 4096)
 | 
						|
        _dc->SetClippingRegion(RCT2Rect(&_clip));
 | 
						|
      _real_clip = _clip;
 | 
						|
    }
 | 
						|
		
 | 
						|
		_dirty = false;
 | 
						|
	}
 | 
						|
	return *_dc;
 | 
						|
}
 | 
						|
 | 
						|
void TDC::KillDC()
 | 
						|
{
 | 
						|
	if (_dc != NULL)
 | 
						|
	{
 | 
						|
  	SetClippingBox(NULL);
 | 
						|
    _real_clip = _clip;
 | 
						|
		delete _dc;
 | 
						|
  	_dc = NULL;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void TDC::SetClippingBox(const RCT* pRct)
 | 
						|
{
 | 
						|
	if (pRct != NULL)
 | 
						|
	{
 | 
						|
    // Normalizza posizione e dimensioni invece di limitarsi a fare _clip=*pRct
 | 
						|
		const wxRect rct = RCT2Rect(pRct); 
 | 
						|
    Rect2RCT(rct, &_clip);
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		_clip.left = _clip.top = 0;
 | 
						|
		_clip.right = _clip.bottom = 32000;  // 32000 serve per i TDC di stampa (aumentare quando possibile) per il video basterebbe 4096
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
bool TDC::GetClippingBox(RCT* pRct) const
 | 
						|
{
 | 
						|
	if (pRct != NULL) 
 | 
						|
    *pRct = _clip;
 | 
						|
	return _clip.right > _clip.left;
 | 
						|
}
 | 
						|
 | 
						|
TDCMapper& GetTDCMapper()
 | 
						|
{
 | 
						|
  static TDCMapper* _dc_map = NULL;
 | 
						|
  if (_dc_map == NULL)
 | 
						|
    _dc_map = new TDCMapper;
 | 
						|
  return *_dc_map;
 | 
						|
}
 | 
						|
 | 
						|
void TDCMapper::DestroyDC(WINDOW owner)
 | 
						|
{
 | 
						|
	if (owner)
 | 
						|
	{
 | 
						|
	  TDC* pTDC = (*this)[owner];
 | 
						|
	  if (pTDC)
 | 
						|
		  pTDC->KillDC();
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		for (TDCMapper::iterator it = begin(); it != end(); ++it)
 | 
						|
		{
 | 
						|
  	  TDC* pTDC = it->second;
 | 
						|
	  	if (pTDC)
 | 
						|
   		  pTDC->KillDC();
 | 
						|
		}
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void TDCMapper::DestroyTDC(WINDOW owner)
 | 
						|
{
 | 
						|
	if (owner != NULL_WIN)
 | 
						|
	{
 | 
						|
	  TDC* pTDC = (*this)[owner];
 | 
						|
	  if (pTDC)
 | 
						|
		  delete pTDC;
 | 
						|
    erase(owner);
 | 
						|
	}
 | 
						|
	else
 | 
						|
	{
 | 
						|
		TDCMapper::iterator it;
 | 
						|
		for (it = begin(); it != end(); ++it)
 | 
						|
		{
 | 
						|
  	  TDC* pTDC = it->second;
 | 
						|
	  	if (pTDC)
 | 
						|
				delete pTDC;
 | 
						|
		}
 | 
						|
		clear();
 | 
						|
	}
 | 
						|
	_pLastOwner = NULL_WIN;
 | 
						|
}
 | 
						|
 | 
						|
TDC& TDCMapper::GetTDC(WINDOW owner)
 | 
						|
{
 | 
						|
	if (owner != _pLastOwner)
 | 
						|
  {
 | 
						|
    wxASSERT(owner != NULL_WIN); 
 | 
						|
	  TDC* pTDC = (*this)[owner];
 | 
						|
	  if (pTDC == NULL)
 | 
						|
	  {
 | 
						|
		  if (owner == PRINTER_WIN)
 | 
						|
			  pTDC = new TPrintDC((wxWindow*)owner);
 | 
						|
		  else
 | 
						|
		    pTDC = new TDC((wxWindow*)owner);
 | 
						|
		  (*this)[owner] = pTDC;
 | 
						|
	  }
 | 
						|
	  _pLastOwner = owner;
 | 
						|
	  _pLastTDC = pTDC;
 | 
						|
  }
 | 
						|
	return *_pLastTDC;
 | 
						|
}
 | 
						|
 | 
						|
bool TDCMapper::HasValidDC(WINDOW owner) const
 | 
						|
{
 | 
						|
  if (owner == NULL_WIN)
 | 
						|
		return false;
 | 
						|
 | 
						|
	if (owner == (WINDOW)_pLastOwner)
 | 
						|
		return true;
 | 
						|
	
 | 
						|
	TDC* pTDC = (*((TDCMapper *) this))[owner];
 | 
						|
	return pTDC != NULL;
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// Generic window class
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
IMPLEMENT_DYNAMIC_CLASS(TwxWindowBase, wxWindow)
 | 
						|
 | 
						|
#ifdef WIN32
 | 
						|
WXLRESULT TwxWindowBase::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
 | 
						|
{
 | 
						|
  WXLRESULT rc = 0;
 | 
						|
  bool processed = false;
 | 
						|
 | 
						|
  switch (nMsg)
 | 
						|
  {
 | 
						|
  case WM_CLOSE: 
 | 
						|
    processed = !Close(); 
 | 
						|
    break;
 | 
						|
  default: 
 | 
						|
    break;
 | 
						|
  }
 | 
						|
 | 
						|
  if ( !processed )
 | 
						|
    rc = wxWindow::MSWWindowProc(nMsg, wParam, lParam);
 | 
						|
 | 
						|
  return rc;
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
bool TwxWindowBase::CreateBase(wxWindow *parent, wxWindowID id, const wxString &title,
 | 
						|
		    								       const wxPoint &pos, const wxSize &size, long style)
 | 
						|
{
 | 
						|
  wxWindowBase::Show(false);  // Evita inutili sfarfallamenti
 | 
						|
  return Create(parent, id, pos, size, style, title);
 | 
						|
}
 | 
						|
 | 
						|
TwxWindowBase::TwxWindowBase(wxWindow *parent, wxWindowID id, const wxString &title,
 | 
						|
													   const wxPoint &pos, const wxSize &size, long style)
 | 
						|
{
 | 
						|
  CreateBase(parent, id, title, pos, size, style);
 | 
						|
}
 | 
						|
 | 
						|
IMPLEMENT_DYNAMIC_CLASS(TwxWindow, TwxWindowBase)
 | 
						|
 | 
						|
BEGIN_EVENT_TABLE(TwxWindow, TwxWindowBase)
 | 
						|
  EVT_CHAR(TwxWindow::OnChar)
 | 
						|
  EVT_KEY_DOWN(TwxWindow::OnKeyDown)
 | 
						|
	EVT_CLOSE(TwxWindow::OnClose)
 | 
						|
	EVT_KILL_FOCUS(TwxWindow::OnKillFocus)
 | 
						|
  EVT_LEFT_DCLICK(TwxWindow::OnMouseDouble)
 | 
						|
  EVT_LEFT_DOWN(TwxWindow::OnMouseDown)
 | 
						|
  EVT_LEFT_UP(TwxWindow::OnMouseUp)
 | 
						|
  EVT_MENU_RANGE(1000, 32766, TwxWindow::OnMenu)
 | 
						|
  EVT_MIDDLE_DOWN(TwxWindow::OnMouseDown)
 | 
						|
  EVT_MIDDLE_UP(TwxWindow::OnMouseUp)
 | 
						|
	EVT_MOTION(TwxWindow::OnMouseMove)
 | 
						|
  EVT_MOUSE_CAPTURE_LOST(TwxWindow::OnMouseCaptureLost)
 | 
						|
  EVT_MOUSEWHEEL(TwxWindow::OnMouseWheel)
 | 
						|
  EVT_PAINT(TwxWindow::OnPaint)
 | 
						|
  EVT_RIGHT_DOWN(TwxWindow::OnMouseDown)
 | 
						|
  EVT_RIGHT_UP(TwxWindow::OnMouseUp)
 | 
						|
	EVT_SCROLL(TwxWindow::OnScroll)
 | 
						|
	EVT_SCROLLWIN(TwxWindow::OnScrollWin)
 | 
						|
	EVT_SET_FOCUS(TwxWindow::OnSetFocus)
 | 
						|
	EVT_SIZE(TwxWindow::OnSize)
 | 
						|
	EVT_TIMER(TIMER_ID, TwxWindow::OnTimer)
 | 
						|
  EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, TwxWindow::OnButton)
 | 
						|
  EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, TwxWindow::OnCheckBox)
 | 
						|
  EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_RADIOBUTTON_SELECTED, TwxWindow::OnRadioButton)
 | 
						|
END_EVENT_TABLE()
 | 
						|
 | 
						|
long TwxWindow::DoXvtEvent(EVENT& e)
 | 
						|
{
 | 
						|
  long ret = 0;
 | 
						|
	if (this != NULL && _eh != NULL)
 | 
						|
  	ret = _eh((WINDOW)this, &e);
 | 
						|
  return ret;
 | 
						|
}
 | 
						|
 | 
						|
void TwxWindow::OnChar(wxKeyEvent& evt)
 | 
						|
{
 | 
						|
  static int nSkipNextDotKey = -883; // Valore indefinito
 | 
						|
  if (nSkipNextDotKey == -883)       // Devo stabilire se attivare la gestione o no
 | 
						|
  {
 | 
						|
    const char* campoini = xvt_fsys_get_campo_ini();
 | 
						|
    char str[2];
 | 
						|
    xvt_sys_get_profile_string(campoini, "Main", "Point2Comma", "1", str, sizeof(str));
 | 
						|
    nSkipNextDotKey = strchr("1XY", *str) != NULL ? 0 : -1; // Dis/Abilita conversione punto in virgola
 | 
						|
  }
 | 
						|
 | 
						|
  XVT_EVENT e(E_CHAR);
 | 
						|
	int k = evt.GetKeyCode();
 | 
						|
 | 
						|
	if (nSkipNextDotKey == 1)
 | 
						|
	{
 | 
						|
    nSkipNextDotKey = 0;
 | 
						|
		if (k == '.')
 | 
						|
		{
 | 
						|
		  evt.Skip();
 | 
						|
		  return;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	switch (k)
 | 
						|
	{
 | 
						|
	case WXK_ALT:
 | 
						|
	case WXK_MENU:
 | 
						|
  case WXK_NUMPAD0:
 | 
						|
  case WXK_NUMPAD1:
 | 
						|
  case WXK_NUMPAD2:
 | 
						|
  case WXK_NUMPAD3:
 | 
						|
  case WXK_NUMPAD4:
 | 
						|
  case WXK_NUMPAD5:
 | 
						|
  case WXK_NUMPAD6:
 | 
						|
  case WXK_NUMPAD7:
 | 
						|
  case WXK_NUMPAD8:
 | 
						|
  case WXK_NUMPAD9:
 | 
						|
		evt.Skip();
 | 
						|
		return;
 | 
						|
  case WXK_NUMPAD_DECIMAL:   // Arriva solo dalla 2.6.3 in poi
 | 
						|
	case WXK_DECIMAL:          // ??? Arriva sia '.' sia WXK_DECIMAL=340
 | 
						|
    if (nSkipNextDotKey == 0)
 | 
						|
    {
 | 
						|
		  k = ','; // Trasformo il punto in virgola
 | 
						|
		  nSkipNextDotKey = 1;
 | 
						|
    }
 | 
						|
		break;
 | 
						|
  case WXK_NUMPAD_ADD: k = '+';break;
 | 
						|
	case WXK_DOWN : k = K_DOWN;  break;
 | 
						|
  case WXK_END  : k = K_LEND;  break;
 | 
						|
  case WXK_HOME : k = K_LHOME; break;
 | 
						|
	case WXK_LEFT : k = K_LEFT;  break;
 | 
						|
	case WXK_NEXT : k = K_NEXT;  break;
 | 
						|
	case WXK_PRIOR: k = K_PREV;  break;
 | 
						|
	case WXK_RIGHT: k = K_RIGHT; break;
 | 
						|
	case WXK_UP   : k = K_UP;	   break;
 | 
						|
	case WXK_TAB:
 | 
						|
    if (evt.ShiftDown())
 | 
						|
			k = K_BTAB;
 | 
						|
		break;
 | 
						|
	default:
 | 
						|
	  if (k >= WXK_F1 && k <= WXK_F24)
 | 
						|
		  k = K_F1 + k - WXK_F1;
 | 
						|
		break;
 | 
						|
	}
 | 
						|
	
 | 
						|
	e.v.chr.shift = evt.ShiftDown();
 | 
						|
	e.v.chr.control = evt.ControlDown();
 | 
						|
	if (evt.AltDown())
 | 
						|
	{
 | 
						|
		e.v.chr.control = TRUE;
 | 
						|
    if (xvt_chr_is_alnum(k))
 | 
						|
			k = toupper(k);
 | 
						|
		else
 | 
						|
		{
 | 
						|
      if (strchr("+-", k) == NULL) // Aggiungere qui vari testi eventuali
 | 
						|
      {
 | 
						|
			  evt.Skip();
 | 
						|
			  return;
 | 
						|
      }
 | 
						|
		}
 | 
						|
	}
 | 
						|
	e.v.chr.ch = k;
 | 
						|
	
 | 
						|
	DoXvtEvent(e);
 | 
						|
}
 | 
						|
 | 
						|
void TwxWindow::OnKeyDown(wxKeyEvent& e)
 | 
						|
{
 | 
						|
#ifdef WIN32
 | 
						|
  // Triste necessita' per gestire corretamente Alt+'+' del tasterino
 | 
						|
	const int k = e.GetKeyCode();
 | 
						|
  if (k == WXK_NUMPAD_ADD)
 | 
						|
  {
 | 
						|
    if (e.AltDown())
 | 
						|
    {
 | 
						|
      OnChar(e);
 | 
						|
      return;
 | 
						|
    }
 | 
						|
  }
 | 
						|
#else
 | 
						|
  if (e.AltDown() || e.ControlDown())
 | 
						|
  {
 | 
						|
    OnChar(event);
 | 
						|
    return;
 | 
						|
  }
 | 
						|
#endif
 | 
						|
  e.Skip();
 | 
						|
}
 | 
						|
 | 
						|
void TwxWindow::OnClose(wxCloseEvent& WXUNUSED(e))
 | 
						|
{
 | 
						|
  XVT_EVENT e(E_CLOSE);
 | 
						|
	DoXvtEvent(e);
 | 
						|
}
 | 
						|
 | 
						|
void TwxWindow::OnKillFocus(wxFocusEvent& WXUNUSED(e))
 | 
						|
{
 | 
						|
  if (_TheCaret.Owner() == (WINDOW)this)
 | 
						|
    _TheCaret.Hide();
 | 
						|
 | 
						|
  XVT_EVENT e(E_FOCUS);
 | 
						|
	e.v.active = 0;
 | 
						|
	DoXvtEvent(e);
 | 
						|
}
 | 
						|
 | 
						|
void TwxWindow::OnMenu(wxCommandEvent& evt)
 | 
						|
{
 | 
						|
  XVT_EVENT e(E_COMMAND);
 | 
						|
	e.v.cmd.control = 0; e.v.cmd.shift = 0;
 | 
						|
	e.v.cmd.tag = evt.GetId();
 | 
						|
	DoXvtEvent(e);
 | 
						|
}
 | 
						|
 | 
						|
void TwxWindow::OnMouseCaptureLost(wxMouseCaptureLostEvent& WXUNUSED(e))
 | 
						|
{
 | 
						|
  xvt_win_release_pointer();
 | 
						|
}
 | 
						|
 | 
						|
void TwxWindow::OnMouseDouble(wxMouseEvent& evt)
 | 
						|
{
 | 
						|
  XVT_EVENT e(E_MOUSE_DBL);
 | 
						|
	e.v.mouse.button = (evt.RightDown() ? 1 : 0) + (evt.MiddleDown() ? 2 : 0);
 | 
						|
	e.v.mouse.control = evt.ControlDown();
 | 
						|
	e.v.mouse.shift = evt.ShiftDown();
 | 
						|
	e.v.mouse.where.h = evt.GetX();
 | 
						|
	e.v.mouse.where.v = evt.GetY();
 | 
						|
	DoXvtEvent(e);
 | 
						|
}
 | 
						|
 | 
						|
void TwxWindow::OnMouseDown(wxMouseEvent& evt)
 | 
						|
{
 | 
						|
  XVT_EVENT e(E_MOUSE_DOWN);
 | 
						|
  e.v.mouse.button = (evt.RightDown() ? 1 : 0) + (evt.MiddleDown() ? 2 : 0);
 | 
						|
  e.v.mouse.control = evt.ControlDown();
 | 
						|
  e.v.mouse.shift = evt.ShiftDown();
 | 
						|
  e.v.mouse.where.h = evt.GetX();
 | 
						|
  e.v.mouse.where.v = evt.GetY();
 | 
						|
  DoXvtEvent(e);
 | 
						|
  SetFocus();   // Triste necessita'
 | 
						|
}
 | 
						|
 | 
						|
void TwxWindow::OnMouseMove(wxMouseEvent& evt)
 | 
						|
{
 | 
						|
  XVT_EVENT e(E_MOUSE_MOVE);
 | 
						|
	e.v.mouse.button = (evt.RightIsDown() ? 1 : 0) + (evt.MiddleIsDown() ? 2 : 0);
 | 
						|
	e.v.mouse.control = evt.ControlDown();
 | 
						|
	e.v.mouse.shift = evt.m_shiftDown;
 | 
						|
	e.v.mouse.where.h = evt.GetX();
 | 
						|
	e.v.mouse.where.v = evt.GetY();
 | 
						|
	DoXvtEvent(e);
 | 
						|
}
 | 
						|
 | 
						|
void TwxWindow::OnMouseUp(wxMouseEvent& evt)
 | 
						|
{
 | 
						|
  XVT_EVENT e(E_MOUSE_UP);
 | 
						|
	e.v.mouse.button = (evt.RightUp() ? 1 : 0) + (evt.MiddleUp() ? 2 : 0);
 | 
						|
	e.v.mouse.control = evt.ControlDown();
 | 
						|
	e.v.mouse.shift = evt.ShiftDown();
 | 
						|
	e.v.mouse.where.h = evt.GetX();
 | 
						|
	e.v.mouse.where.v = evt.GetY();
 | 
						|
	DoXvtEvent(e);
 | 
						|
}
 | 
						|
 | 
						|
void TwxWindow::OnMouseWheel(wxMouseEvent& evt)
 | 
						|
{
 | 
						|
  const int nRot = evt.GetWheelRotation();
 | 
						|
  if (nRot != 0)
 | 
						|
  {
 | 
						|
    XVT_EVENT e(E_VSCROLL);
 | 
						|
	  e.v.scroll.pos = evt.GetY();
 | 
						|
    e.v.scroll.what = nRot > 0 ? SC_LINE_UP : SC_LINE_DOWN;
 | 
						|
	  DoXvtEvent(e);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void TwxWindow::OnPaint(wxPaintEvent& WXUNUSED(evt))
 | 
						|
{
 | 
						|
  const wxRect rctDamaged = GetUpdateRegion().GetBox();
 | 
						|
 | 
						|
	XVT_EVENT e(E_UPDATE);
 | 
						|
  Rect2RCT(rctDamaged, &e.v.update.rct);
 | 
						|
 | 
						|
  TDC& tdc = GetTDCMapper().GetTDC((WINDOW)this);
 | 
						|
  tdc.GetDC(true); // Forza la creazione di un wxPaintDC
 | 
						|
  DoXvtEvent(e);
 | 
						|
  tdc.KillDC();    // Distrugge il wxPaintDC
 | 
						|
  GetTDCMapper().DestroyDC(NULL_WIN); // Distrugge davvero tutti i wxClientDC residui (risolve molte "porcate" del video)
 | 
						|
}
 | 
						|
 | 
						|
static SCROLL_CONTROL ConvertScrollToXVT(wxEventType et)
 | 
						|
{
 | 
						|
  if (et == wxEVT_SCROLL_TOP)
 | 
						|
		return SC_THUMB; // Meglio di niente
 | 
						|
  if (et == wxEVT_SCROLL_BOTTOM)
 | 
						|
		return SC_THUMB; // Meglio di niente
 | 
						|
  if (et == wxEVT_SCROLL_LINEUP)
 | 
						|
		return SC_LINE_UP;
 | 
						|
  if (et == wxEVT_SCROLL_LINEDOWN)
 | 
						|
		return SC_LINE_DOWN;
 | 
						|
  if (et == wxEVT_SCROLL_PAGEUP)
 | 
						|
		return SC_PAGE_UP;
 | 
						|
  if (et == wxEVT_SCROLL_PAGEDOWN)
 | 
						|
		return SC_PAGE_DOWN;
 | 
						|
  if (et == wxEVT_SCROLL_THUMBTRACK)
 | 
						|
		return SC_THUMBTRACK;
 | 
						|
  if (et == wxEVT_SCROLL_THUMBRELEASE)
 | 
						|
		return SC_THUMB;
 | 
						|
	return SC_NONE;
 | 
						|
}
 | 
						|
 | 
						|
void TwxWindow::OnScroll(wxScrollEvent& evt)
 | 
						|
{
 | 
						|
  SCROLL_CONTROL sc = ConvertScrollToXVT(evt.GetEventType());
 | 
						|
  if (sc != SC_NONE)
 | 
						|
  {
 | 
						|
    XVT_EVENT e(E_CONTROL);
 | 
						|
	  e.v.ctl.id = evt.GetId();
 | 
						|
	  e.v.ctl.ci.type = evt.GetOrientation()==wxHORIZONTAL ? WC_HSCROLL : WC_VSCROLL;
 | 
						|
	  e.v.ctl.ci.win = (WINDOW)evt.GetEventObject();
 | 
						|
	  e.v.ctl.ci.v.scroll.pos = evt.GetPosition();
 | 
						|
    e.v.ctl.ci.v.scroll.what = sc;
 | 
						|
	  DoXvtEvent(e);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void TwxWindow::OnScrollWin(wxScrollWinEvent& evt)
 | 
						|
{
 | 
						|
	wxEventType et = evt.GetEventType();
 | 
						|
  et -= (wxEVT_SCROLLWIN_TOP - wxEVT_SCROLL_TOP);
 | 
						|
  const SCROLL_CONTROL sc = ConvertScrollToXVT(et);
 | 
						|
  if (sc != SC_NONE)
 | 
						|
  {
 | 
						|
    XVT_EVENT e(evt.GetOrientation() == wxHORIZONTAL ? E_HSCROLL : E_VSCROLL);
 | 
						|
	  e.v.scroll.pos = evt.GetPosition();
 | 
						|
	  e.v.scroll.what = sc;
 | 
						|
	  DoXvtEvent(e);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void TwxWindow::OnSetFocus(wxFocusEvent& WXUNUSED(e))
 | 
						|
{
 | 
						|
  XVT_EVENT e(E_FOCUS);
 | 
						|
	e.v.active = TRUE;
 | 
						|
	DoXvtEvent(e);
 | 
						|
}
 | 
						|
 | 
						|
void TwxWindow::OnSize(wxSizeEvent& evt)
 | 
						|
{
 | 
						|
  XVT_EVENT e(E_SIZE);
 | 
						|
	e.v.size.width = evt.GetSize().x;
 | 
						|
	e.v.size.height = evt.GetSize().y;
 | 
						|
	DoXvtEvent(e);
 | 
						|
}
 | 
						|
 | 
						|
void TwxWindow::OnTimer(wxTimerEvent& WXUNUSED(evt))
 | 
						|
{
 | 
						|
  XVT_EVENT e(E_TIMER);
 | 
						|
	e.v.timer.id = (WINDOW)this;
 | 
						|
	DoXvtEvent(e);
 | 
						|
}
 | 
						|
 | 
						|
void TwxWindow::OnButton(wxCommandEvent& evt)
 | 
						|
{
 | 
						|
  XVT_EVENT e(E_CONTROL);
 | 
						|
	e.v.ctl.id = evt.GetId();
 | 
						|
  e.v.ctl.ci.type = WC_PUSHBUTTON;
 | 
						|
	DoXvtEvent(e);
 | 
						|
}
 | 
						|
 | 
						|
void TwxWindow::OnCheckBox(wxCommandEvent& evt)
 | 
						|
{
 | 
						|
  XVT_EVENT e(E_CONTROL);
 | 
						|
	e.v.ctl.id = evt.GetId();
 | 
						|
  e.v.ctl.ci.type = WC_CHECKBOX;
 | 
						|
	DoXvtEvent(e);
 | 
						|
}
 | 
						|
 | 
						|
void TwxWindow::OnRadioButton(wxCommandEvent& evt)
 | 
						|
{
 | 
						|
  XVT_EVENT e(E_CONTROL);
 | 
						|
	e.v.ctl.id = evt.GetId();
 | 
						|
  e.v.ctl.ci.type = WC_RADIOBUTTON;
 | 
						|
	DoXvtEvent(e);
 | 
						|
}
 | 
						|
 | 
						|
void TwxWindow::SetMenuTree(const MENU_ITEM* tree)
 | 
						|
{
 | 
						|
	wxASSERT(tree != NULL);
 | 
						|
	if (tree != NULL)
 | 
						|
	{
 | 
						|
		if (m_menu)
 | 
						|
			xvt_res_free_menu_tree(m_menu);
 | 
						|
		m_menu = xvt_menu_duplicate_tree(tree);
 | 
						|
    TTaskWin* tw = wxStaticCast(_task_win, TTaskWin);
 | 
						|
		tw->PushMenuTree(tree, this);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
BOOLEAN TwxWindow::AddPane(wxWindow* wnd, const char* caption, int nDock, int nFlags)
 | 
						|
{
 | 
						|
  BOOLEAN ok = wnd != NULL;
 | 
						|
  if (ok)
 | 
						|
  {
 | 
						|
    if (m_pManager == NULL)
 | 
						|
      m_pManager = new wxAuiManager(this);
 | 
						|
    wxAuiPaneInfo pane;
 | 
						|
    pane.DefaultPane(); pane.Dockable(false); 
 | 
						|
    const wxSize sz = wnd->GetSize();
 | 
						|
    switch (nDock)
 | 
						|
    {
 | 
						|
    case  1: // Left
 | 
						|
      pane.Left().Floatable(true).LeftDockable().RightDockable();
 | 
						|
      pane.MinSize(sz.x/2, -1).BestSize(sz.x, -1).MaxSize(3*sz.x/2, -1); 
 | 
						|
      break;
 | 
						|
    case  2: // Top
 | 
						|
      pane.Top().Floatable(true).TopDockable().BottomDockable().MinSize(-1, sz.y/2); 
 | 
						|
      break;
 | 
						|
    case  3: // Right
 | 
						|
      pane.Right().Floatable(true).LeftDockable().RightDockable();
 | 
						|
      pane.MinSize(sz.x/2, -1).BestSize(sz.x, -1).MaxSize(3*sz.x/2, -1); 
 | 
						|
      break;
 | 
						|
    case  4: // Bottom
 | 
						|
      pane.Bottom().Floatable(true).TopDockable().BottomDockable().MinSize(-1, sz.y/2); 
 | 
						|
      break;
 | 
						|
    case 52: // Center Top
 | 
						|
      pane.CentrePane().CaptionVisible(true).TopDockable(); 
 | 
						|
      break;
 | 
						|
    case 54: // Center Bottom
 | 
						|
      pane.CentrePane().CaptionVisible(true).BottomDockable(); 
 | 
						|
      break;
 | 
						|
    case 62: // Top toolbar
 | 
						|
      pane.ToolbarPane().Top().MinSize(wxSize(-1,sz.y)).Gripper(false); 
 | 
						|
      break;
 | 
						|
    default: // Center
 | 
						|
      pane.CentrePane().Floatable(false); 
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    pane.CloseButton(false);
 | 
						|
    if (caption && *caption)
 | 
						|
    {
 | 
						|
      pane.Caption(caption);
 | 
						|
      pane.Name(caption);
 | 
						|
    }
 | 
						|
    if (nFlags)
 | 
						|
      pane.SetFlag(nFlags, true);
 | 
						|
 | 
						|
    ok = m_pManager->AddPane(wnd, pane);
 | 
						|
    if (ok)
 | 
						|
      m_pManager->Update();
 | 
						|
  }
 | 
						|
  return ok;
 | 
						|
}
 | 
						|
 | 
						|
TwxWindow::TwxWindow() 
 | 
						|
         : m_menu(NULL), _type(W_DOC), _eh(NULL), _app_data(0L), 
 | 
						|
           _timer(NULL), m_pManager(NULL)
 | 
						|
{ }
 | 
						|
 | 
						|
TwxWindow::TwxWindow(wxWindow *parent, wxWindowID id, const wxString& title,
 | 
						|
										 const wxPoint& pos, const wxSize& size, long style)
 | 
						|
  			 : TwxWindowBase(parent, id, title, pos, size, style),
 | 
						|
           m_menu(NULL), _eh(NULL), _app_data(0L), _timer(NULL), 
 | 
						|
           m_pManager(NULL), m_bInDestroy(false)
 | 
						|
{
 | 
						|
  _nice_windows.Put((WINDOW)this, this);
 | 
						|
}
 | 
						|
 | 
						|
TwxWindow::~TwxWindow()
 | 
						|
{
 | 
						|
  if (!m_bInDestroy) // Controllo di non essere RIchiamato dalla gestione di E_DESTROY
 | 
						|
  {
 | 
						|
    m_bInDestroy = true;               
 | 
						|
    XVT_EVENT e(E_DESTROY);
 | 
						|
    DoXvtEvent(e);
 | 
						|
 | 
						|
    // Rendo praticamente impossibile risalire a questo oggetto d'ora in poi
 | 
						|
    _nice_windows.Delete((WINDOW)this);
 | 
						|
    _eh = NULL;
 | 
						|
    _app_data = 0L;
 | 
						|
 | 
						|
    GetTDCMapper().DestroyTDC((WINDOW)this); // Elimina dalla lista dei display context
 | 
						|
 | 
						|
    if (HasCapture())
 | 
						|
    {
 | 
						|
		  ReleaseMouse();
 | 
						|
      xvt_win_release_pointer(); // Paranoid?
 | 
						|
    }
 | 
						|
    
 | 
						|
    if (_timer != NULL)
 | 
						|
		  delete _timer;
 | 
						|
 | 
						|
    if (m_pManager != NULL)
 | 
						|
    {
 | 
						|
      m_pManager->UnInit(); // Obbligatorio ma, chissa' perche', non gestito dal distruttore!
 | 
						|
      delete m_pManager;
 | 
						|
    }
 | 
						|
 | 
						|
	  if (m_menu)
 | 
						|
	  {
 | 
						|
		  xvt_res_free_menu_tree(m_menu);
 | 
						|
      m_menu = NULL;
 | 
						|
		  ((TTaskWin*)_task_win)->PopMenuTree();
 | 
						|
	  }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// Main application = TASK_WIN functions
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
IMPLEMENT_DYNAMIC_CLASS(TTaskWin, wxFrame)
 | 
						|
 | 
						|
BEGIN_EVENT_TABLE(TTaskWin, wxFrame)
 | 
						|
  EVT_CLOSE(TTaskWin::OnClose)
 | 
						|
  EVT_MENU_RANGE(1000, 32766, TTaskWin::OnMenu)
 | 
						|
	EVT_PAINT(TTaskWin::OnPaint)
 | 
						|
	EVT_SIZE(TTaskWin::OnSize)
 | 
						|
  EVT_END_SESSION(TTaskWin::OnClose)
 | 
						|
  EVT_END_PROCESS(wxID_ANY, TTaskWin::OnEndProcess)
 | 
						|
END_EVENT_TABLE()
 | 
						|
 | 
						|
void TTaskWin::OnClose(wxCloseEvent& evt)
 | 
						|
{
 | 
						|
	if (evt.CanVeto())
 | 
						|
	{
 | 
						|
	  XVT_EVENT e(E_CLOSE);
 | 
						|
	  const int veto = _task_win_handler((WINDOW)this, &e);
 | 
						|
		evt.Veto(veto != 0);
 | 
						|
	}
 | 
						|
	else
 | 
						|
		evt.Skip();
 | 
						|
}
 | 
						|
 | 
						|
void TTaskWin::OnMenu(wxCommandEvent& evt)
 | 
						|
{
 | 
						|
	XVT_EVENT e(E_COMMAND);
 | 
						|
	e.v.cmd.control = 0; e.v.cmd.shift = 0;
 | 
						|
	e.v.cmd.tag = evt.GetId();
 | 
						|
 | 
						|
	if (m_MenuOwner == NULL || m_MenuOwner == this)
 | 
						|
  	_task_win_handler((WINDOW)this, &e);
 | 
						|
	else
 | 
						|
  {
 | 
						|
    TwxWindow* w = wxDynamicCast(m_MenuOwner, TwxWindow);
 | 
						|
    if (w != NULL)
 | 
						|
		  w->_eh((WINDOW)m_MenuOwner, &e);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void TTaskWin::OnPaint(wxPaintEvent& WXUNUSED(evt))
 | 
						|
{
 | 
						|
  const wxRect rctDamaged = GetUpdateRegion().GetBox();
 | 
						|
 | 
						|
	XVT_EVENT e(E_UPDATE);
 | 
						|
  Rect2RCT(rctDamaged, &e.v.update.rct);
 | 
						|
  
 | 
						|
  TDC& dc = GetTDCMapper().GetTDC((WINDOW)this);
 | 
						|
  dc.GetDC(true); // Forza la creazione di un wxPaintDC
 | 
						|
  _task_win_handler((WINDOW)this, &e);
 | 
						|
  dc.KillDC();
 | 
						|
}
 | 
						|
 | 
						|
void TTaskWin::OnSize(wxSizeEvent& evt)
 | 
						|
{
 | 
						|
  XVT_EVENT e(E_SIZE);
 | 
						|
	e.v.size.width  = evt.GetSize().x;
 | 
						|
	e.v.size.height = evt.GetSize().y;
 | 
						|
	_task_win_handler((WINDOW)this, &e);
 | 
						|
}
 | 
						|
 | 
						|
void TTaskWin::OnEndProcess(wxProcessEvent& evt)
 | 
						|
{
 | 
						|
  if (_task_win_handler != NULL)
 | 
						|
  {
 | 
						|
    XVT_EVENT e(E_PROCESS);
 | 
						|
    e.v.process.msg_id = E_DESTROY;
 | 
						|
    e.v.process.pid = evt.GetPid();
 | 
						|
    e.v.process.exit_code = evt.GetExitCode();
 | 
						|
  	_task_win_handler((WINDOW)this, &e);
 | 
						|
    delete evt.GetEventObject(); // delete wxProcess
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void TTaskWin::SetMenuTree(const MENU_ITEM* tree)
 | 
						|
{
 | 
						|
	wxMenuBar* bar = GetMenuBar();
 | 
						|
  if (bar != NULL && tree != NULL)
 | 
						|
  {
 | 
						|
	  if (m_menu)
 | 
						|
		  xvt_res_free_menu_tree(m_menu);
 | 
						|
	  m_menu = xvt_menu_duplicate_tree(tree);
 | 
						|
 | 
						|
	  for ( ; tree != NULL && tree->tag != 0; tree++)
 | 
						|
	  {
 | 
						|
		  wxMenu* pMenu = new wxMenu;
 | 
						|
		  for (MENU_ITEM* mi = tree->child; mi != NULL && mi->tag != 0; mi++)
 | 
						|
		  {
 | 
						|
			  wxMenuItem* item = NULL;
 | 
						|
			  if (mi->separator)
 | 
						|
				  item = new wxMenuItem(pMenu, wxID_SEPARATOR);
 | 
						|
			  else
 | 
						|
				  item = new wxMenuItem(pMenu, mi->tag, mi->text, wxEmptyString, mi->checkable);
 | 
						|
        pMenu->Append(item);
 | 
						|
		  }
 | 
						|
		  const int nLast = bar->GetMenuCount()-1;
 | 
						|
		  int m;
 | 
						|
		  for (m = 2; m < nLast; m++)
 | 
						|
		  {
 | 
						|
			  wxMenu* pMenu = bar->GetMenu(m);
 | 
						|
			  if (pMenu->FindItem(tree->child->tag))
 | 
						|
			  {
 | 
						|
				  bar->Remove(m);
 | 
						|
  //				delete pMenu;
 | 
						|
				  break;
 | 
						|
			  }
 | 
						|
		  }
 | 
						|
		  bar->Insert(m, pMenu, tree->text);
 | 
						|
	  }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void TTaskWin::PushMenuTree(const MENU_ITEM* tree, wxWindow* owner)
 | 
						|
{
 | 
						|
	if(m_pOldBar != NULL)
 | 
						|
    PopMenuTree();
 | 
						|
  m_pOldBar = GetMenuBar();
 | 
						|
 | 
						|
	wxMenuBar* pBar = new wxMenuBar;
 | 
						|
	for (; tree && tree->tag != 0; tree++)
 | 
						|
	{
 | 
						|
		wxMenu* pMenu = new wxMenu;
 | 
						|
		for (MENU_ITEM* mi = tree->child; mi != NULL && mi->tag != 0; mi++)
 | 
						|
		{
 | 
						|
			wxMenuItem* item = NULL;
 | 
						|
			if (mi->separator)
 | 
						|
				item = new wxMenuItem(pMenu, wxID_SEPARATOR);
 | 
						|
			else
 | 
						|
				item = new wxMenuItem(pMenu, mi->tag, mi->text, wxEmptyString, mi->checkable);
 | 
						|
      pMenu->Append(item);
 | 
						|
		}
 | 
						|
		pBar->Append(pMenu, tree->text);
 | 
						|
	}
 | 
						|
	SetMenuBar(pBar);
 | 
						|
	m_MenuOwner = owner;
 | 
						|
}
 | 
						|
 | 
						|
void TTaskWin::PopMenuTree()
 | 
						|
{
 | 
						|
	wxASSERT(m_pOldBar != NULL);
 | 
						|
  wxMenuBar* pBar = GetMenuBar();
 | 
						|
	SetMenuBar(m_pOldBar);
 | 
						|
	delete pBar;
 | 
						|
	m_pOldBar = NULL;
 | 
						|
	m_MenuOwner = NULL;  // = this;
 | 
						|
}
 | 
						|
 | 
						|
const XVT_COLOR_COMPONENT* TTaskWin::GetCtlColors() const
 | 
						|
{
 | 
						|
  if (m_xcc == NULL)
 | 
						|
    ((TTaskWin*)this)->m_xcc = (XVT_COLOR_COMPONENT*)xvt_vobj_get_attr(NULL_WIN, ATTR_APP_CTL_COLORS);
 | 
						|
  return m_xcc;
 | 
						|
}
 | 
						|
 | 
						|
COLOR TTaskWin::GetCtlColor(XVT_COLOR_TYPE ct) const
 | 
						|
{
 | 
						|
  COLOR croma = COLOR_INVALID;
 | 
						|
  const XVT_COLOR_COMPONENT* xcc = GetCtlColors();
 | 
						|
  for (int i = 0; i < 16 && xcc[i].type != XVT_COLOR_NULL; i++)
 | 
						|
  {
 | 
						|
    if (xcc[i].type == ct)
 | 
						|
    {
 | 
						|
      croma = xcc[i].color;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return croma;
 | 
						|
}
 | 
						|
 | 
						|
void TTaskWin::SetCtlColors(const XVT_COLOR_COMPONENT* colors)
 | 
						|
{
 | 
						|
  GetCtlColors(); // Ensure m_xcc is not NULL
 | 
						|
  for (int c = 0; colors[c].type != XVT_COLOR_NULL; c++)
 | 
						|
  {
 | 
						|
    int k = -1;
 | 
						|
    for (k = 0; m_xcc[k].type != colors[c].type; k++);
 | 
						|
    if (k < 15)
 | 
						|
    {
 | 
						|
      m_xcc[k].type  = colors[c].type;
 | 
						|
      m_xcc[k].color = colors[c].color;
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
TTaskWin::TTaskWin(wxWindowID id, const wxString& title, 
 | 
						|
                   const wxPoint& pos, const wxSize& size, long style)
 | 
						|
				: wxFrame(NULL, id, title, pos, size, style), m_menu(NULL), m_pOldBar(NULL), m_MenuOwner(NULL), m_xcc(NULL)
 | 
						|
{
 | 
						|
	SetIcon(xvtart_GetIconResource(ICON_RSRC));
 | 
						|
  _nice_windows.Put((WINDOW)this, this);
 | 
						|
}
 | 
						|
 | 
						|
TTaskWin::~TTaskWin()
 | 
						|
{
 | 
						|
  _task_win = NULL;
 | 
						|
  _nice_windows.Delete((WINDOW)this);
 | 
						|
	if (m_menu)
 | 
						|
	{
 | 
						|
		xvt_res_free_menu_tree(m_menu);
 | 
						|
		m_menu = NULL;
 | 
						|
	}
 | 
						|
  if (m_xcc)
 | 
						|
  {
 | 
						|
    xvt_mem_free((DATA_PTR)m_xcc);
 | 
						|
    m_xcc = NULL;
 | 
						|
  }
 | 
						|
  wxExit(); // Exits main loop in the "rare" case it's still running
 | 
						|
}
 | 
						|
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
// TwxTaskBarIcon
 | 
						|
///////////////////////////////////////////////////////////
 | 
						|
 | 
						|
class TwxTaskBarIcon : public wxTaskBarIcon
 | 
						|
{
 | 
						|
  wxWindow* _owned;
 | 
						|
  DECLARE_EVENT_TABLE();
 | 
						|
 | 
						|
protected:  
 | 
						|
  void OnClick(wxTaskBarIconEvent& e);
 | 
						|
 | 
						|
public:
 | 
						|
  TwxTaskBarIcon(wxWindow* owned, short icon, wxString strTip);
 | 
						|
};
 | 
						|
 | 
						|
BEGIN_EVENT_TABLE(TwxTaskBarIcon, wxTaskBarIcon)
 | 
						|
  EVT_TASKBAR_LEFT_DOWN(OnClick)
 | 
						|
  EVT_TASKBAR_RIGHT_DOWN(OnClick)
 | 
						|
END_EVENT_TABLE()
 | 
						|
 | 
						|
void TwxTaskBarIcon::OnClick(wxTaskBarIconEvent& WXUNUSED(e))
 | 
						|
{
 | 
						|
  if (_owned != NULL)
 | 
						|
  {
 | 
						|
    if (_owned->IsShown())
 | 
						|
      _owned->Show(false);
 | 
						|
    else
 | 
						|
    {
 | 
						|
      _owned->Show();
 | 
						|
      _owned->Raise();
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
TwxTaskBarIcon::TwxTaskBarIcon(wxWindow* owned, short icon, wxString strTip) 
 | 
						|
              : _owned(owned) 
 | 
						|
{ 
 | 
						|
  wxIcon ico;
 | 
						|
  if (icon <= 0 && _owned != NULL)
 | 
						|
  {
 | 
						|
    const wxFrame* pFrame = wxDynamicCast(_owned, wxFrame);
 | 
						|
    if (pFrame != NULL)
 | 
						|
      ico = pFrame->GetIcon();
 | 
						|
  }
 | 
						|
  else
 | 
						|
    ico = xvtart_GetIconResource(icon);
 | 
						|
 | 
						|
  if (strTip.IsEmpty())
 | 
						|
    strTip = _owned->GetLabel();
 | 
						|
 | 
						|
  SetIcon(ico, strTip);
 | 
						|
}
 | 
						|
 | 
						|
WINDOW xvt_trayicon_create(WINDOW owned, short icon, const char* tooltip)
 | 
						|
{
 | 
						|
  WINDOW ti = NULL_WIN;
 | 
						|
  if (owned != NULL_WIN)
 | 
						|
    ti = (WINDOW)new TwxTaskBarIcon((wxWindow*)owned, icon, tooltip);
 | 
						|
  return ti;
 | 
						|
}
 | 
						|
 | 
						|
void xvt_trayicon_destroy(WINDOW tray)
 | 
						|
{
 | 
						|
  wxTaskBarIcon* pTray = wxDynamicCast((wxObject*)tray, wxTaskBarIcon);
 | 
						|
  if (pTray != NULL)
 | 
						|
    delete pTray;
 | 
						|
}
 |