campo-sirio/xvaga/xvtwin.cpp
luca 9c3428c116 Patch level :10.0
Files correlati     :
Ricompilazione Demo : [ ]
Commento            :avviato il programma!!!


git-svn-id: svn://10.65.10.50/trunk@15879 c028cbd2-c16b-5b4b-a496-9718f37d4682
2007-12-14 12:24:58 +00:00

1667 lines
40 KiB
C++
Executable File

#include "wxinc.h"
#define XTWIN_CPP 1
#include "xvt.h"
#include "xvtwin.h"
#include "wx/notebook.h"
#include "wx/treectrl.h"
///////////////////////////////////////////////////////////
// Utilities
///////////////////////////////////////////////////////////
wxHashTable _nice_windows;
wxWindow* _task_win = NULL;
EVENT_HANDLER _task_win_handler = NULL;
wxRect NormalizeRCT(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;
}
///////////////////////////////////////////////////////////
// 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)
{
_TheCaret.SetSize(width, height);
}
void xvt_win_set_caret_pos(WINDOW win, PNT p)
{
_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_RUBBER:
case PAT_SPECIAL:
default: 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 dc->IsKindOf(CLASSINFO(wxPostScriptDC));
}
#endif
wxDC& TDC::GetDC(bool bPaint)
{
if (bPaint)
{
KillDC();
_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("Campo", NULL, &height, &desc, &lead);
_deltaf = height-desc;
}
if (_dirty < 0 || ClipChanged())
{
_dc->DestroyClippingRegion();
if (_clip.bottom < 4096)
_dc->SetClippingRegion(NormalizeRCT(&_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)
{
const wxRect rct = NormalizeRCT(pRct);
_clip.left = rct.x; _clip.top = rct.y;
_clip.right = rct.GetRight(); _clip.bottom = rct.GetBottom();
}
else
{
_clip.left = _clip.top = 0;
_clip.right = _clip.bottom = 4096;
}
}
bool TDC::GetClippingBox(RCT* pRct) const
{
*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)
{
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)
bool TwxWindowBase::CreateBase(wxWindow *parent, wxWindowID id, const wxString &title,
const wxPoint &pos, const wxSize &size, long style)
{
// Evita inutili sfarfallamenti in quanto wxWidgets crea le finestre visibili per default
wxWindowBase::Show(false);
bool ok = Create(parent, id, pos, size, style, title);
return ok;
}
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)
#if wxCHECK_VERSION(2,8,0)
EVT_MOUSE_CAPTURE_LOST(TwxWindow::OnMouseCaptureLost)
#endif
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_RANGE(1, 9999, wxEVT_COMMAND_BUTTON_CLICKED, TwxWindow::OnButton)
EVT_COMMAND_RANGE(1, 9999, wxEVT_COMMAND_CHECKBOX_CLICKED, TwxWindow::OnCheckBox)
EVT_COMMAND_RANGE(1, 9999, wxEVT_COMMAND_RADIOBUTTON_SELECTED, TwxWindow::OnRadioButton)
END_EVENT_TABLE()
void TwxWindow::DoXvtEvent(EVENT& e)
{
if (this != NULL && _eh != NULL)
_eh((WINDOW)this, &e);
}
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
}
EVENT e; memset(&e, 0, sizeof(EVENT));
e.type = 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 3.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))
{
EVENT e; memset(&e, 0, sizeof(EVENT));
e.type = E_DESTROY;
DoXvtEvent(e);
Destroy();
}
void TwxWindow::OnKillFocus(wxFocusEvent& WXUNUSED(e))
{
if (_TheCaret.Owner() == (WINDOW)this)
_TheCaret.Hide();
EVENT e; memset(&e, 0, sizeof(EVENT));
e.type = E_FOCUS;
e.v.active = 0;
DoXvtEvent(e);
}
void TwxWindow::OnMenu(wxCommandEvent& evt)
{
EVENT e; memset(&e, 0, sizeof(EVENT));
e.type = E_COMMAND;
e.v.cmd.control = 0; e.v.cmd.shift = 0;
e.v.cmd.tag = evt.GetId();
DoXvtEvent(e);
}
#if wxCHECK_VERSION(2,8,0)
void TwxWindow::OnMouseCaptureLost(wxMouseCaptureLostEvent& WXUNUSED(e))
{
xvt_win_release_pointer();
}
#endif
void TwxWindow::OnMouseDouble(wxMouseEvent& evt)
{
EVENT e; memset(&e, 0, sizeof(EVENT));
e.type = 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)
{
EVENT e; memset(&e, 0, sizeof(EVENT));
e.type = 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)
{
EVENT e; memset(&e, 0, sizeof(EVENT));
e.type = 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)
{
EVENT e; memset(&e, 0, sizeof(EVENT));
e.type = 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)
{
EVENT e; memset(&e, 0, sizeof(EVENT));
e.type = 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))
{
EVENT e; memset(&e, 0, sizeof(EVENT));
e.type = E_UPDATE;
RCT& rct = e.v.update.rct;
wxRect rctDamaged = GetUpdateRegion().GetBox();
rct.left = rctDamaged.x;
rct.top = rctDamaged.y;
rct.right = rctDamaged.GetRight()+1;
rct.bottom = rctDamaged.GetBottom()+1;
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)
{
const wxScrollBar* sb = (wxScrollBar*)evt.GetEventObject();
const wxSize sz = sb->GetSize();
EVENT e; memset(&e, 0, sizeof(EVENT));
e.type = E_CONTROL;
e.v.ctl.id = evt.GetId();
e.v.ctl.ci.type = sz.x > sz.y ? WC_HSCROLL : WC_VSCROLL;
e.v.ctl.ci.win = (WINDOW)sb;
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)
{
EVENT e; memset(&e, 0, sizeof(EVENT));
e.type = 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))
{
EVENT e; memset(&e, 0, sizeof(EVENT));
e.type = E_FOCUS;
e.v.active = 1;
DoXvtEvent(e);
}
void TwxWindow::OnSize(wxSizeEvent& evt)
{
EVENT e; memset(&e, 0, sizeof(EVENT));
e.type = E_SIZE;
e.v.size.height = evt.GetSize().x;
e.v.size.width = evt.GetSize().y;
DoXvtEvent(e);
}
void TwxWindow::OnTimer(wxTimerEvent& WXUNUSED(evt))
{
EVENT e; memset(&e, 0, sizeof(EVENT));
e.type = E_TIMER;
e.v.timer.id = (WINDOW)this;
DoXvtEvent(e);
}
void TwxWindow::OnButton(wxCommandEvent& evt)
{
EVENT e; memset(&e, 0, sizeof(EVENT));
e.type = E_CONTROL;
e.v.ctl.id = evt.GetId();
e.v.ctl.ci.type = WC_PUSHBUTTON;
DoXvtEvent(e);
}
void TwxWindow::OnCheckBox(wxCommandEvent& evt)
{
EVENT e; memset(&e, 0, sizeof(EVENT));
e.type = E_CONTROL;
e.v.ctl.id = evt.GetId();
e.v.ctl.ci.type = WC_CHECKBOX;
DoXvtEvent(e);
}
void TwxWindow::OnRadioButton(wxCommandEvent& evt)
{
EVENT e; memset(&e, 0, sizeof(EVENT));
e.type = 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*)_task_win)->PushMenuTree(tree, this);
}
}
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), _timer(NULL)
{
_nice_windows.Put((WINDOW)this, this);
}
TwxWindow::~TwxWindow()
{
if (_timer)
delete _timer;
if (m_menu)
{
xvt_res_free_menu_tree(m_menu);
((TTaskWin*)_task_win)->PopMenuTree();
}
_nice_windows.Delete((WINDOW)this);
}
///////////////////////////////////////////////////////////
// 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)
END_EVENT_TABLE()
void TTaskWin::OnClose(wxCloseEvent& evt)
{
if (evt.CanVeto())
{
EVENT e; memset(&e, 0, sizeof(EVENT));
e.type = E_CLOSE;
int veto = _task_win_handler((WINDOW)this, &e);
evt.Veto(veto != 0);
}
else
evt.Skip();
}
void TTaskWin::OnMenu(wxCommandEvent& evt)
{
EVENT e; memset(&e, 0, sizeof(EVENT));
e.type = 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*)m_MenuOwner)->_eh((WINDOW)m_MenuOwner, &e);
}
void TTaskWin::OnPaint(wxPaintEvent& WXUNUSED(evt))
{
EVENT e; memset(&e, 0, sizeof(EVENT));
e.type = E_UPDATE;
RCT& rct = e.v.update.rct;
wxRect rctDamaged = GetUpdateRegion().GetBox();
rct.left = rctDamaged.x;
rct.top = rctDamaged.y;
rct.right = rctDamaged.GetRight()+1;
rct.bottom = rctDamaged.GetBottom()+1;
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)
{
EVENT e; memset(&e, 0, sizeof(EVENT));
e.type = E_SIZE;
e.v.size.height = evt.GetSize().x;
e.v.size.width = evt.GetSize().y;
_task_win_handler((WINDOW)this, &e);
}
void TTaskWin::SetMenuTree(const MENU_ITEM* tree)
{
if (m_menu)
xvt_res_free_menu_tree(m_menu);
m_menu = xvt_menu_duplicate_tree(tree);
wxMenuBar* bar = GetMenuBar();
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;
}
TTaskWin::TTaskWin(wxWindow *parent, wxWindowID id,
const wxString& title, const wxPoint& pos,
const wxSize& size, long style)
: wxFrame(parent, id, title, pos, size, style), m_menu(NULL), m_pOldBar(NULL), m_MenuOwner(NULL)
{
wxIcon* ico = _GetIconResource(ICON_RSRC);
if (ico)
SetIcon(*ico);
_nice_windows.Put((WINDOW)this, this);
}
TTaskWin::~TTaskWin()
{
if (m_menu)
{
xvt_res_free_menu_tree(m_menu);
m_menu = NULL;
}
_nice_windows.Delete((WINDOW)this);
}
///////////////////////////////////////////////////////////
// Controls functions
///////////////////////////////////////////////////////////
class TwxScrollBar : public wxScrollBar
{
protected:
virtual bool AcceptsFocus() const { return false; } // Altrimenti mette il flag wxTAB_TRAVERSAL
public:
TwxScrollBar(wxWindow *parent, wxWindowID id,
const wxPoint& pos, const wxSize& size, long style)
{ Create(parent, id, pos, size, style); }
};
class TwxNoteBook : public wxNotebook
{
public:
wxNotebookPage* AddTab(int idx, const wxString text, wxBitmap* bmp);
TwxNoteBook(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size);
};
class TwxTreeCtrl : public wxTreeCtrl
{
WX_DECLARE_VOIDPTR_HASH_MAP(int, XVT_IMAGE_Map);
XVT_IMAGE_Map m_img;
wxFont m_font;
int m_nFrozen;
private:
int img2int(XVT_IMAGE img); // Store img into internal image list
void OnClick(wxTreeEvent& evt, bool bDouble);
protected:
DECLARE_EVENT_TABLE();
void OnExpanding(wxTreeEvent& e); // Called when node in about to be expanded
void OnCollapsed(wxTreeEvent& e); // Called when node is collapsed
void OnSelected(wxTreeEvent& e); // Calls OnClick(e, false)
void OnActivated(wxTreeEvent& e); // Calls OnClick(e, true)
public:
void SetNodeImages(const wxTreeItemId& id, XVT_IMAGE item_image,
XVT_IMAGE collapsed_image, XVT_IMAGE expanded_image);
virtual bool SetFont(const wxFont& font) { m_font = font; return font.IsOk(); }
virtual wxFont GetFont() const;
void Suspend();
void Resume();
TwxTreeCtrl(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size);
};
WINDOW xvt_ctl_create_def(WIN_DEF *win_def_p, WINDOW parent_win, long app_data)
{
wxASSERT(win_def_p != NULL);
const wxRect rct = NormalizeRCT(&win_def_p->rct);
wxWindow* pParent = (wxWindow*)parent_win;
const wxWindowID id = win_def_p->v.ctl.ctrl_id;
WINDOW win = NULL_WIN;
switch (win_def_p->wtype)
{
case WC_HSCROLL: /* horizontal scrollbar control */
case WC_VSCROLL: /* vertical scrollbar control */
{
const long style = win_def_p->wtype == WC_HSCROLL ? wxSB_HORIZONTAL : wxSB_VERTICAL;
TwxScrollBar* sb = new TwxScrollBar(pParent, id, rct.GetPosition(), rct.GetSize(), style);
win = (WINDOW)sb;
}
break;
case WC_HGAUGE: /* horizontal progress bar control */
case WC_VGAUGE: /* vertical progress bar control */
{
const long style = (win_def_p->wtype == WC_HGAUGE) ? wxGA_HORIZONTAL : wxGA_VERTICAL;
wxGauge* pg = new wxGauge(pParent, id, app_data,
rct.GetPosition(), rct.GetSize(), style);
win = (WINDOW)pg;
}
break;
case WC_PUSHBUTTON: /* bottone normale */
{
wxButton* pb = NULL;
if (win_def_p->text && *win_def_p->text) // Bottone normale con label
{
pb = new wxButton(pParent, id, win_def_p->text, rct.GetPosition(), rct.GetSize());
}
else
{ // Bottone figo con immagini
wxBitmap bmp;
pb = new wxBitmapButton(pParent, id, bmp, rct.GetPosition(), rct.GetSize());
}
win = (WINDOW)pb;
}
break;
case WC_CHECKBOX: /* check box */
{
long style = wxCHK_2STATE | wxTRANSPARENT_WINDOW;
if (win_def_p->wtype == CTL_FLAG_RIGHT_JUST)
style |= wxALIGN_RIGHT;
wxCheckBox* cb = new wxCheckBox(pParent, id, win_def_p->text,
rct.GetPosition(), rct.GetSize(), style);
win = (WINDOW)cb;
}
break;
case WC_RADIOBUTTON: /* radio button */
{
wxRadioButton* rb = new wxRadioButton(pParent, id, win_def_p->text,
rct.GetPosition(), rct.GetSize());
win = (WINDOW)rb;
}
break;
case WC_NOTEBK:
{
TwxNoteBook* nb = new TwxNoteBook(pParent, id, rct.GetPosition(), rct.GetSize());
win = (WINDOW)nb;
}
break;
case WC_TREE:
{
TwxTreeCtrl* tv = new TwxTreeCtrl(pParent, id, rct.GetPosition(), rct.GetSize());
win = (WINDOW)tv;
XVT_FNTID font_id = win_def_p->v.ctl.font_id;
if (font_id == NULL)
font_id = xvt_dwin_get_font(parent_win);
if (font_id != NULL)
{
const wxFont& font = ((TFontId*)font_id)->Font(NULL, win);
tv->SetFont(font);
}
}
break;
default:
SORRY_BOX(); break;
}
if (win != NULL)
{
wxWindow& w = *(wxWindow*)win;
const long flags = win_def_p->v.ctl.flags;
if (flags & CTL_FLAG_INVISIBLE) w.Hide();
if (flags & CTL_FLAG_DISABLED) w.Disable();
}
return win;
}
void xvt_ctl_check_radio_button(WINDOW win, WINDOW* wins, int NbrWindows)
{
wxASSERT(NbrWindows >= 2);
for (int i = 0; i < NbrWindows; i++)
{
wxRadioButton* rb = (wxRadioButton*)wins[i];
wxASSERT(rb != NULL && rb->IsKindOf(CLASSINFO(wxRadioButton)));
rb->SetValue(win == wins[i]);
}
}
void xvt_ctl_set_checked(WINDOW win, BOOLEAN bCheck)
{
wxCheckBox* cb = (wxCheckBox*)win;
wxASSERT(cb != NULL);
cb->SetValue(bCheck != 0);
}
///////////////////////////////////////////////////////////
// Notebook interface
///////////////////////////////////////////////////////////
#define CAST_NOTEBOOK(win, nb) wxASSERT(win); TwxNoteBook& nb = *(TwxNoteBook*)win;
wxNotebookPage* TwxNoteBook::AddTab(int idx, const wxString text, wxBitmap* bmp)
{
int imageId = -1;
if (bmp != NULL)
{
wxImageList* il = GetImageList();
if (il == NULL)
AssignImageList(il = new wxImageList(16,16));
imageId = il->Add(*bmp);
}
wxNotebookPage* nbp = new TwxWindow(this, wxID_ANY, text,
wxDefaultPosition, wxDefaultSize, 0);
if (idx < 0 || idx >= (int)GetPageCount())
AddPage(nbp, text, false, imageId);
else
InsertPage(idx, nbp, text, false, imageId);
return nbp;
}
TwxNoteBook::TwxNoteBook(wxWindow *parent, wxWindowID id,
const wxPoint& pos, const wxSize& size)
: wxNotebook(parent, id, pos, size)
{}
void xvt_notebk_add_page(WINDOW notebk, short tab_no, short page_no,
const char* title, long page_data)
{
wxASSERT(page_no == 0);
CAST_NOTEBOOK(notebk, nb);
if (tab_no < 0 || tab_no >= (int)nb.GetPageCount())
{
tab_no = nb.GetPageCount();
xvt_notebk_add_tab(notebk, tab_no, title, NULL);
}
TwxWindow* nbp = (TwxWindow*)nb.GetPage(tab_no);
nbp->SetLabel(title);
nbp->_app_data = page_data;
nbp->SetBackgroundStyle(wxBG_STYLE_CUSTOM); // Lo sfondo viene disegnato nella OnPaint
}
void xvt_notebk_add_tab(WINDOW notebk, short tab_no, const char* title, XVT_IMAGE image)
{
CAST_NOTEBOOK(notebk, nb);
nb.AddTab(tab_no, title, NULL);
}
WINDOW xvt_notebk_create_face(WINDOW notebk, short tab_no, short page_no,
EVENT_MASK mask, EVENT_HANDLER face_eh, long app_data)
{
return xvt_notebk_create_face_def(notebk, tab_no, page_no, NULL, mask, face_eh, app_data);
}
WINDOW xvt_notebk_create_face_def(WINDOW notebk, short tab_no, short WXUNUSED(page_no),
WIN_DEF* win_def_p, EVENT_MASK WXUNUSED(mask),
EVENT_HANDLER face_eh, long app_data)
{
wxASSERT(tab_no >= 0 && tab_no < xvt_notebk_get_num_tabs(notebk));
CAST_NOTEBOOK(notebk, nb);
TwxWindow* nbp = (TwxWindow*)nb.GetPage(tab_no);
wxWindowID id = 10001+tab_no;
wxString text;
long style = 0;
if (win_def_p != NULL)
{
id = win_def_p->v.ctl.ctrl_id;
text = win_def_p->text;
style = win_def_p->v.ctl.flags;
}
if (!text.IsEmpty())
nbp->SetLabel(text);
if (id > 0)
nbp->SetId(id);
nbp->_eh = face_eh;
nbp->_app_data = app_data;
return (WINDOW)nbp;
}
WINDOW xvt_notebk_get_face(WINDOW notebk, short tab_no, short page_no)
{
wxASSERT(tab_no >= 0 && tab_no < xvt_notebk_get_num_tabs(notebk));
wxASSERT(page_no == 0);
CAST_NOTEBOOK(notebk, nb);
return (WINDOW)nb.GetPage(tab_no);
}
short xvt_notebk_get_num_tabs(WINDOW notebk)
{
CAST_NOTEBOOK(notebk, nb);
return nb.GetPageCount();
}
void xvt_notebk_set_front_page(WINDOW notebk, short tab_no, short page_no)
{
CAST_NOTEBOOK(notebk, nb);
nb.ChangeSelection(tab_no); // Non generare eventi di cambio pagina!
}
void xvt_notebk_set_tab_title(WINDOW notebk, short tab_no, const char* title)
{
CAST_NOTEBOOK(notebk, nb);
nb.SetPageText(tab_no, title);
}
///////////////////////////////////////////////////////////
// TreeCtrl interface
///////////////////////////////////////////////////////////
BEGIN_EVENT_TABLE(TwxTreeCtrl, wxTreeCtrl)
EVT_TREE_ITEM_EXPANDING(wxID_ANY, TwxTreeCtrl::OnExpanding)
EVT_TREE_ITEM_COLLAPSED(wxID_ANY, TwxTreeCtrl::OnCollapsed)
EVT_TREE_SEL_CHANGED(wxID_ANY, TwxTreeCtrl::OnSelected)
EVT_TREE_ITEM_ACTIVATED(wxID_ANY, TwxTreeCtrl::OnActivated)
END_EVENT_TABLE();
#define CAST_TREEVIEW(win, tv) wxASSERT(win); TwxTreeCtrl& tv = *(TwxTreeCtrl*)win;
struct TwxTreeItemData : public wxTreeItemData
{
wxString m_strData; // Assumo sempre una stringa come dati
};
void TwxTreeCtrl::OnExpanding(wxTreeEvent& evt)
{
if (!m_nFrozen)
{
const wxTreeItemId id = evt.GetItem();
EVENT e; memset(&e, 0, sizeof(EVENT));
e.type = E_CONTROL;
e.v.ctl.id = evt.GetId();
e.v.ctl.ci.type = WC_TREE;
e.v.ctl.ci.win = WINDOW(this);
e.v.ctl.ci.v.treeview.node = id.m_pItem;
e.v.ctl.ci.v.treeview.expanded = TRUE;
if (GetChildrenCount(id) == 0) // Trucco perfido ...
e.v.ctl.ci.v.treeview.collapsed = TRUE; // ... stato indeterminato = EXPANDING
TwxWindow* win = (TwxWindow*)GetParent();
win->DoXvtEvent(e);
if (GetChildrenCount(id) == 0) // Allora e' proprio vero ...
SetItemHasChildren(id, false);
}
}
void TwxTreeCtrl::OnCollapsed(wxTreeEvent& evt)
{
if (!m_nFrozen)
{
Suspend();
EVENT e; memset(&e, 0, sizeof(EVENT));
e.type = E_CONTROL;
e.v.ctl.id = evt.GetId();
e.v.ctl.ci.type = WC_TREE;
e.v.ctl.ci.win = WINDOW(this);
e.v.ctl.ci.v.treeview.node = evt.GetItem().m_pItem;
e.v.ctl.ci.v.treeview.collapsed = TRUE;
TwxWindow* win = (TwxWindow*)GetParent();
win->DoXvtEvent(e);
Resume();
}
}
void TwxTreeCtrl::OnClick(wxTreeEvent& evt, bool bDouble)
{
if (!m_nFrozen)
{
Suspend();
EVENT e; memset(&e, 0, sizeof(EVENT));
e.type = E_CONTROL;
e.v.ctl.id = evt.GetId();
e.v.ctl.ci.type = WC_TREE;
e.v.ctl.ci.win = WINDOW(this);
e.v.ctl.ci.v.treeview.node = evt.GetItem().m_pItem;
if (bDouble)
e.v.ctl.ci.v.treeview.dbl_click = TRUE;
else
e.v.ctl.ci.v.treeview.sgl_click = TRUE;
TwxWindow* win = (TwxWindow*)GetParent();
win->DoXvtEvent(e);
Resume();
}
}
void TwxTreeCtrl::OnSelected(wxTreeEvent& evt)
{ OnClick(evt, false); }
void TwxTreeCtrl::OnActivated(wxTreeEvent& evt)
{ OnClick(evt, true); }
int TwxTreeCtrl::img2int(XVT_IMAGE xvt_img)
{
int i = -1;
if (xvt_img != NULL)
{
i = m_img[xvt_img] - 1; // Ho memorizzato indice+1
if (i < 0) // Immagine sconosciuta
{
const wxImage& img = *(wxImage*)xvt_img;
wxImageList* il = GetImageList();
if (il == NULL) // Lista non ancora creata
{
il = new wxImageList;
il->Create(img.GetWidth(), img.GetHeight(), true, 3);
AssignImageList(il); // DON'T CALL SetImageList!
}
i = il->Add(wxBitmap(img));
m_img[xvt_img] = i+1; // Memorizzo indice+1
}
if (i < 0)
SORRY_BOX();
}
return i;
}
void TwxTreeCtrl::SetNodeImages(const wxTreeItemId& id, XVT_IMAGE item_image,
XVT_IMAGE collapsed_image, XVT_IMAGE expanded_image)
{
const int ii = img2int(item_image);
if (ii >= 0)
SetItemImage(id, ii);
else
{
const int ic = img2int(collapsed_image);
if (ic >= 0)
{
SetItemImage(id, ic);
const int ie = img2int(expanded_image);
if (ie >= 0)
SetItemImage(id, ie, wxTreeItemIcon_Selected);
}
}
}
wxFont TwxTreeCtrl::GetFont() const
{ return m_font.IsOk() ? m_font : wxTreeCtrl::GetFont(); }
void TwxTreeCtrl::Suspend()
{ m_nFrozen++; }
void TwxTreeCtrl::Resume()
{
wxASSERT(m_nFrozen > 0);
if (m_nFrozen > 0)
m_nFrozen--;
}
TwxTreeCtrl::TwxTreeCtrl(wxWindow *parent, wxWindowID id,
const wxPoint& pos, const wxSize& size)
: wxTreeCtrl(parent, id, pos, size, wxTR_HAS_BUTTONS | wxTR_HIDE_ROOT),
m_nFrozen(0)
{
AddRoot("Root");
}
WINDOW xvt_treeview_create(WINDOW parent_win,
RCT * rct_p, char * title, long ctl_flags,
long app_data, int ctl_id, XVT_IMAGE item_image,
XVT_IMAGE collapsed_image, XVT_IMAGE expanded_image,
long attrs, int line_height)
{
WIN_DEF win_def; memset(&win_def, 0, sizeof(WIN_DEF));
win_def.wtype = WC_TREE;
win_def.rct = *rct_p;
win_def.text = title;
win_def.v.ctl.ctrl_id = ctl_id;
win_def.v.ctl.flags = ctl_flags;
WINDOW win = xvt_ctl_create_def(&win_def, parent_win, app_data);
return win;
}
XVT_TREEVIEW_NODE xvt_treeview_add_child_node(WINDOW win,
XVT_TREEVIEW_NODE parent, XVT_TREEVIEW_NODE_TYPE type,
XVT_IMAGE item_image, XVT_IMAGE collapsed_image, XVT_IMAGE expanded_image,
const char* string, XVT_TREEVIEW_CALLBACK callback, const char* data)
{
XVT_TREEVIEW_NODE node = NULL;
if (win != NULL_WIN)
{
CAST_TREEVIEW(win, tv);
TwxTreeItemData* pData = new TwxTreeItemData;
pData->m_strData = data;
wxTreeItemId pa(parent);
if (!pa.IsOk())
pa = tv.GetRootItem();
wxTreeItemId id = tv.AppendItem(pa, string, -1, -1, pData);
if (id.IsOk())
{
tv.SetItemHasChildren(pa, true);
tv.SetItemHasChildren(id, type == XVT_TREEVIEW_NODE_NONTERMINAL);
tv.SetNodeImages(id, item_image, collapsed_image, expanded_image);
tv.SetItemFont(id, tv.GetFont());
node = id.m_pItem;
}
}
return node;
}
XVT_TREEVIEW_NODE xvt_treeview_get_child_node(WINDOW win, XVT_TREEVIEW_NODE parent_node,
int position)
{
XVT_TREEVIEW_NODE child_node = NULL;
if (win != NULL_WIN && position >= 0)
{
CAST_TREEVIEW(win, tv);
wxTreeItemId parent(parent_node);
if (!parent.IsOk())
parent = tv.GetRootItem();
if (position < (int)tv.GetChildrenCount(parent))
{
wxTreeItemIdValue cookie;
wxTreeItemId id;
int i = -1;
for (id = tv.GetFirstChild(parent, cookie), i = -1;
i < position && id.IsOk(); id = tv.GetNextChild(parent, cookie), i++);
child_node = id.m_pItem;
}
}
return child_node;
}
const char* xvt_treeview_get_node_data(WINDOW win, XVT_TREEVIEW_NODE node)
{
const char* data = NULL;
if (win != NULL_WIN && node != NULL)
{
CAST_TREEVIEW(win, tv);
const wxTreeItemId id(node);
TwxTreeItemData* pData = (TwxTreeItemData*)tv.GetItemData(id);
if (pData != NULL)
data = (const char*)pData->m_strData;
}
return data;
}
void xvt_treeview_destroy_node(WINDOW win, XVT_TREEVIEW_NODE node)
{
if (win != NULL_WIN && node != NULL)
{
CAST_TREEVIEW(win, tv);
wxTreeItemId id(node);
tv.Delete(id);
}
}
BOOLEAN xvt_treeview_expand_node(WINDOW win, XVT_TREEVIEW_NODE node, BOOLEAN recurse)
{
BOOLEAN ok = (win != NULL_WIN) && (node != NULL);
if (ok)
{
CAST_TREEVIEW(win, tv);
const wxTreeItemId id(node);
if (recurse)
tv.ExpandAllChildren(id);
else
tv.Expand(id);
}
return ok;
}
XVT_TREEVIEW_NODE xvt_treeview_get_root_node(WINDOW win)
{
XVT_TREEVIEW_NODE pRoot = NULL;
if (win != NULL_WIN)
{
CAST_TREEVIEW(win, tv);
const wxTreeItemId id = tv.GetRootItem();
pRoot = id.m_pItem;
}
return pRoot;
}
XVT_TREEVIEW_NODE xvt_treeview_get_selected_node(WINDOW win)
{
CAST_TREEVIEW(win, tv);
const wxTreeItemId id = tv.GetSelection();
return id.m_pItem;
}
BOOLEAN xvt_treeview_remove_child_node(WINDOW win, XVT_TREEVIEW_NODE node)
{
BOOLEAN ok = (win != NULL_WIN) && (node != NULL);
if (ok)
{
CAST_TREEVIEW(win, tv);
const wxTreeItemId id(node);
tv.Delete(id);
}
return ok;
}
BOOLEAN xvt_treeview_remove_node_children(WINDOW win, XVT_TREEVIEW_NODE node)
{
BOOLEAN ok = FALSE;
if (win != NULL_WIN)
{
CAST_TREEVIEW(win, tv);
wxTreeItemId id(node);
if (!id.IsOk())
id = tv.GetRootItem();
tv.DeleteChildren(id);
ok = TRUE;
}
return ok;
}
void xvt_treeview_resume(WINDOW win)
{
CAST_TREEVIEW(win, tv);
tv.Resume();
}
void xvt_treeview_select_node(WINDOW win, XVT_TREEVIEW_NODE node, BOOLEAN sel)
{
if (win != NULL_WIN && node != NULL)
{
CAST_TREEVIEW(win, tv);
const wxTreeItemId id(node);
tv.SelectItem(id, sel != 0);
if (sel)
tv.EnsureVisible(id);
}
}
void xvt_treeview_set_node_images(WINDOW win, XVT_TREEVIEW_NODE node, XVT_IMAGE item_image,
XVT_IMAGE collapsed_image, XVT_IMAGE expanded_image)
{
if (win != NULL_WIN && node != NULL)
{
CAST_TREEVIEW(win, tv);
const wxTreeItemId id(node);
tv.SetNodeImages(id, item_image, collapsed_image, expanded_image);
}
}
void xvt_treeview_set_node_string(WINDOW win, XVT_TREEVIEW_NODE node, const char* text)
{
if (win != NULL_WIN && node != NULL)
{
CAST_TREEVIEW(win, tv);
const wxTreeItemId id(node);
tv.SetItemText(id, text);
}
}
void xvt_treeview_suspend(WINDOW win)
{
CAST_TREEVIEW(win, tv);
tv.Suspend();
}