3338 lines
91 KiB
C++
Executable File
3338 lines
91 KiB
C++
Executable File
#include "wxinc.h"
|
||
#include "xvt.h"
|
||
#include "xvtart.h"
|
||
#include "xvtwin.h"
|
||
#include "statbar.h"
|
||
#include "treelistctrl.h"
|
||
|
||
#include <wx/artprov.h>
|
||
#include <wx/wxhtml.h>
|
||
#include <wx/filename.h>
|
||
#include <wx/tokenzr.h>
|
||
#include <wx/treectrl.h>
|
||
#include <wx/vlbox.h>
|
||
#include <wx/aui/aui.h>
|
||
#include <wx/propgrid/propgrid.h>
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Utility functions
|
||
///////////////////////////////////////////////////////////
|
||
|
||
static wxBitmap Image2Bitmap(XVT_IMAGE image, int maxx, int maxy, BOOLEAN trans)
|
||
{
|
||
if (image == NULL || !((wxImage*)image)->IsOk())
|
||
return wxNullBitmap;
|
||
|
||
wxImage img = *(wxImage*)image;
|
||
|
||
int w = img.GetWidth(), h = img.GetHeight();
|
||
if (w > maxx || h > maxy)
|
||
{
|
||
const double mx = (maxx / 2) * 2, my = (maxy / 2) * 2;
|
||
const double rx = mx / w, ry = my / h;
|
||
const double r = rx < ry ? rx : ry;
|
||
w = int(w * r); h = int(h * r);
|
||
img.Rescale(w, h, wxIMAGE_QUALITY_HIGH);
|
||
}
|
||
|
||
if (trans && !img.HasMask())
|
||
{
|
||
const int r = img.GetRed(0,0);
|
||
const int g = img.GetGreen(0,0);
|
||
const int b = img.GetBlue(0,0);
|
||
img.SetMask();
|
||
img.SetMaskColour(r, g, b);
|
||
}
|
||
return wxBitmap(img);
|
||
}
|
||
|
||
static int RoundToIcon(int nSize)
|
||
{
|
||
nSize = ((nSize+3) / 8) * 8;
|
||
if (nSize < 16) nSize = 16;
|
||
if (nSize > 128) nSize = 128;
|
||
return nSize;
|
||
}
|
||
|
||
void Image2Colors(const wxImage& img, wxColour& mean, wxColour& dark, wxColour& light)
|
||
{
|
||
dark = *wxWHITE;
|
||
mean = *wxLIGHT_GREY;
|
||
light = *wxBLACK;
|
||
double r=0, g=0, b=0;
|
||
|
||
const int h = min(img.GetWidth(), img.GetHeight());
|
||
for (int i = 0; i < h; i++)
|
||
{
|
||
const wxColourBase::ChannelType cr = img.GetRed(i,i);
|
||
const wxColourBase::ChannelType cg = img.GetGreen(i,i);
|
||
const wxColourBase::ChannelType cb = img.GetBlue(i,i);
|
||
r += cr; g += cg; b += cb;
|
||
}
|
||
r/=h; g/=h; b/=h;
|
||
mean = wxColour(r, g, b);
|
||
dark = wxColour(r*0.8, g*0.8, b*0.8);
|
||
light = wxColour(min(r*1.2,255), min(g*1.2,255), min(b*1.2,255));
|
||
}
|
||
|
||
|
||
static wxAuiDockArt* FindArtist(wxWindow* pWindow)
|
||
{
|
||
wxAuiDockArt* pArtist = NULL;
|
||
const wxAuiManager* pManager = wxAuiManager::GetManager(pWindow);
|
||
if (pManager != NULL)
|
||
pArtist = pManager->GetArtProvider();
|
||
return pArtist;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// 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 wxAuiNotebook
|
||
{
|
||
enum { BOOK_ICO_SIZE = 16 };
|
||
bool m_bSuspended;
|
||
|
||
DECLARE_EVENT_TABLE()
|
||
DECLARE_DYNAMIC_CLASS(TwxNoteBook)
|
||
|
||
protected:
|
||
virtual bool SetBackgroundColour(const wxColour& col);
|
||
virtual bool SetForegroundColour(const wxColour& col);
|
||
|
||
void OnChar(wxKeyEvent& evt);
|
||
void OnPageChanging(wxAuiNotebookEvent& e);
|
||
void OnPageChanged(wxAuiNotebookEvent& e);
|
||
long Flags2Style(long flags) const;
|
||
|
||
TwxNoteBook() {}
|
||
|
||
public:
|
||
int ChangeSelection(size_t tab_no); // wxNotebook had it!
|
||
void SetTabImage(size_t tab_no, XVT_IMAGE img);
|
||
|
||
short AddTab(wxWindow* pPage, const wxString text, XVT_IMAGE img = NULL, short idx = -1);
|
||
TwxNoteBook(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style);
|
||
~TwxNoteBook();
|
||
};
|
||
|
||
WX_DECLARE_VOIDPTR_HASH_MAP(int, XVT_IMAGE_Map);
|
||
|
||
class TwxTreeCtrl : public wxTreeCtrl
|
||
{
|
||
XVT_IMAGE_Map m_img;
|
||
wxColour m_clrSelFore, m_clrSelBack, m_clrDisFore;
|
||
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)
|
||
void OnRightDown(wxMouseEvent& e);
|
||
|
||
virtual wxColour GetItemTextColour(const wxTreeItemId& id) const;
|
||
virtual wxColour GetItemBackgroundColour(const wxTreeItemId& id) const;
|
||
|
||
public:
|
||
void SetNodeImages(const wxTreeItemId& id, XVT_IMAGE item_image,
|
||
XVT_IMAGE collapsed_image, XVT_IMAGE expanded_image);
|
||
void SetColors(const XVT_COLOR_COMPONENT* colors);
|
||
void Suspend();
|
||
void Resume();
|
||
void Enable(const wxTreeItemId& id, bool on);
|
||
TwxTreeCtrl(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size);
|
||
};
|
||
|
||
class TwxTreeListCtrl : public wxTreeListCtrl
|
||
{
|
||
XVT_IMAGE_Map m_img;
|
||
wxColour m_clrSelFore, m_clrSelBack, m_clrDisFore;
|
||
int m_nFrozen;
|
||
|
||
private:
|
||
int img2int(XVT_IMAGE img); // Store img into internal image list
|
||
|
||
protected:
|
||
DECLARE_EVENT_TABLE();
|
||
void OnExpanding(wxTreeEvent& e); // Called when node is about to be expanded
|
||
void OnExpanded(wxTreeEvent& e); // Called when node has been expanded
|
||
void OnCollapsed(wxTreeEvent& e); // Called when node has been collapsed
|
||
void OnSelChanged(wxTreeEvent& e); // Called when node has been selected
|
||
|
||
public:
|
||
void SetNodeImages(const wxTreeItemId& id, XVT_IMAGE item_image,
|
||
XVT_IMAGE collapsed_image, XVT_IMAGE expanded_image);
|
||
void SetColors(const XVT_COLOR_COMPONENT* colors);
|
||
void Suspend();
|
||
void Resume();
|
||
void Enable(const wxTreeItemId& id, bool on);
|
||
TwxTreeListCtrl(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, bool multisel);
|
||
};
|
||
|
||
struct TwxOutlookItem
|
||
{
|
||
wxString m_strText;
|
||
short m_nIconId;
|
||
int m_nFlags;
|
||
};
|
||
|
||
class TwxOutlookBar : public wxVListBox
|
||
{
|
||
enum { MAX_ITEMS = 32 };
|
||
TwxOutlookItem m_item[MAX_ITEMS];
|
||
int m_nHovering;
|
||
|
||
DECLARE_EVENT_TABLE()
|
||
|
||
protected:
|
||
virtual void OnDrawBackground(wxDC& dc, const wxRect& rect, size_t n) const;
|
||
virtual void OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const;
|
||
virtual wxCoord OnMeasureItem(size_t n) const;
|
||
virtual void OnMouseMove(wxMouseEvent& e);
|
||
virtual void OnMouseLeave(wxMouseEvent& e);
|
||
virtual void OnSelected(wxCommandEvent& e);
|
||
|
||
public:
|
||
int Add(short nIconId, const wxString strText, int nFlags);
|
||
|
||
TwxOutlookBar(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style);
|
||
~TwxOutlookBar();
|
||
};
|
||
|
||
class TwxPopUp : public wxVListBox
|
||
{
|
||
DECLARE_DYNAMIC_CLASS(TwxPopUp);
|
||
|
||
wxArrayString m_menu;
|
||
int m_nHovering;
|
||
wxCoord m_nRowHeight;
|
||
wxColour m_clrBack, m_clrFore;
|
||
|
||
DECLARE_EVENT_TABLE()
|
||
void NotifySelection();
|
||
TwxPopUp() { wxFAIL; }
|
||
|
||
protected:
|
||
virtual void OnDrawBackground(wxDC& dc, const wxRect& rect, size_t n) const;
|
||
virtual void OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const;
|
||
virtual wxCoord OnMeasureItem(size_t n) const;
|
||
virtual void OnMouseMove(wxMouseEvent& e);
|
||
virtual void OnKillFocus(wxFocusEvent& e);
|
||
virtual void OnSelected(wxCommandEvent& e);
|
||
virtual void OnKeyDown(wxKeyEvent& e);
|
||
virtual void OnLeftDown(wxMouseEvent& e);
|
||
|
||
public:
|
||
int Add(const wxString str);
|
||
void SetSelectForeColor(const wxColour& rgb) { m_clrFore = rgb; }
|
||
void SetSelectBackColor(const wxColour& rgb) { m_clrBack= rgb; }
|
||
TwxPopUp(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size);
|
||
};
|
||
|
||
class TwxPropertyGrid : public wxPropertyGrid
|
||
{
|
||
DECLARE_EVENT_TABLE()
|
||
protected:
|
||
void OnPropertyChanged(wxPropertyGridEvent& evt);
|
||
public:
|
||
void SetColors(const XVT_COLOR_COMPONENT* colors);
|
||
TwxPropertyGrid(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style);
|
||
};
|
||
|
||
WINDOW xvt_ctl_create_def(WIN_DEF* win_def_p, WINDOW parent_win, long app_data)
|
||
{
|
||
wxASSERT(win_def_p != NULL);
|
||
const wxRect rct = RCT2Rect(&win_def_p->rct);
|
||
wxWindow* pParent = wxStaticCast((wxObject*)parent_win, wxWindow);
|
||
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 */
|
||
{
|
||
long style = win_def_p->wtype == WC_HSCROLL ? wxSB_HORIZONTAL : wxSB_VERTICAL;
|
||
style |= wxCLIP_SIBLINGS;
|
||
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_HSLIDER: /* horizontal slider control */
|
||
case WC_VSLIDER: /* vertical slider control */
|
||
{
|
||
const long style = win_def_p->wtype == WC_HSLIDER ? wxSL_HORIZONTAL : wxSL_VERTICAL;
|
||
wxSlider* sc = new wxSlider(pParent, id, 0, 0, app_data, rct.GetPosition(), rct.GetSize(), style);
|
||
win = (WINDOW)sc;
|
||
}
|
||
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
|
||
pb = new wxBitmapButton(pParent, id, wxNullBitmap, rct.GetPosition(), rct.GetSize());
|
||
win = (WINDOW)pb;
|
||
}
|
||
break;
|
||
case WC_CHECKBOX: /* check box */
|
||
{
|
||
long style = wxCHK_2STATE | wxCLIP_SIBLINGS;
|
||
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 */
|
||
{
|
||
const long style = wxRB_SINGLE | wxCLIP_SIBLINGS;
|
||
wxRadioButton* rb = new wxRadioButton(pParent, id, win_def_p->text,
|
||
rct.GetPosition(), rct.GetSize(), style);
|
||
win = (WINDOW)rb;
|
||
}
|
||
break;
|
||
case WC_NOTEBK:
|
||
{
|
||
TwxNoteBook* nb = new TwxNoteBook(pParent, id, rct.GetPosition(), rct.GetSize(), win_def_p->v.ctl.flags);
|
||
win = (WINDOW)nb;
|
||
}
|
||
break;
|
||
case WC_HTML:
|
||
{
|
||
wxHtmlWindow* hw = new wxHtmlWindow(pParent, id, rct.GetPosition(), rct.GetSize());
|
||
win = (WINDOW)hw;
|
||
}
|
||
break;
|
||
case WC_TREE:
|
||
{
|
||
TwxTreeCtrl* tv = new TwxTreeCtrl(pParent, id, rct.GetPosition(), rct.GetSize());
|
||
win = (WINDOW)tv;
|
||
}
|
||
break;
|
||
case WC_LBOX:
|
||
{
|
||
wxListBox* tlb = new wxListBox(pParent, id, rct.GetPosition(), rct.GetSize());
|
||
win = (WINDOW)tlb;
|
||
}
|
||
break;
|
||
case WC_OUTLOOKBAR:
|
||
{
|
||
long style = 0;
|
||
TwxOutlookBar* tob = new TwxOutlookBar(pParent, id, rct.GetPosition(), rct.GetSize(), style);
|
||
win = (WINDOW)tob;
|
||
}
|
||
break;
|
||
case WC_POPUP:
|
||
{
|
||
TwxPopUp* tpu = new TwxPopUp(pParent, id, rct.GetPosition(), rct.GetSize());
|
||
win = (WINDOW)tpu;
|
||
}
|
||
break;
|
||
case WC_PROPGRID:
|
||
{
|
||
long flags = wxPG_BOLD_MODIFIED | wxPG_SPLITTER_AUTO_CENTER | wxPG_DESCRIPTION | wxPG_TOOLTIPS;
|
||
TwxPropertyGrid* pg = new TwxPropertyGrid(pParent, id, rct.GetPosition(), rct.GetSize(), flags);
|
||
win = (WINDOW)pg;
|
||
}
|
||
break;
|
||
case WC_TREELIST:
|
||
{
|
||
const bool multisel = (win_def_p->v.ctl.flags & CTL_FLAG_MULTIPLE) != 0;
|
||
TwxTreeListCtrl* tv = new TwxTreeListCtrl(pParent, id, rct.GetPosition(), rct.GetSize(), multisel);
|
||
win = (WINDOW)tv;
|
||
}
|
||
break;
|
||
default:
|
||
SORRY_BOX(); break;
|
||
}
|
||
|
||
if (win != NULL_WIN)
|
||
{
|
||
wxWindow& w = *wxStaticCast((wxObject*)win, wxWindow);
|
||
const long flags = win_def_p->v.ctl.flags;
|
||
if (flags & CTL_FLAG_INVISIBLE) w.Hide();
|
||
if (flags & CTL_FLAG_DISABLED) w.Disable();
|
||
|
||
XVT_FNTID font_id = win_def_p->v.ctl.font_id;
|
||
const bool bDestroyFont = font_id == NULL;
|
||
if (bDestroyFont)
|
||
font_id = xvt_dwin_get_font(parent_win);
|
||
if (font_id != NULL)
|
||
{
|
||
const wxFont& font = wxStaticCast(font_id, TFontId)->Font(NULL, win);
|
||
w.SetFont(font);
|
||
if (bDestroyFont)
|
||
xvt_font_destroy(font_id);
|
||
}
|
||
xvt_ctl_set_colors(win, win_def_p->ctlcolors, XVT_COLOR_ACTION_SET);
|
||
}
|
||
|
||
return win;
|
||
}
|
||
|
||
void xvt_ctl_check_radio_button(WINDOW win, WINDOW* wins, int NbrWindows)
|
||
{
|
||
wxASSERT(wins != NULL_WIN && NbrWindows >= 2);
|
||
for (int i = 0; i < NbrWindows; i++)
|
||
{
|
||
wxRadioButton* rb = wxDynamicCast((wxObject*)wins[i], wxRadioButton);
|
||
if (rb != NULL)
|
||
rb->SetValue(win == wins[i]);
|
||
}
|
||
}
|
||
|
||
void xvt_ctl_set_checked(WINDOW win, BOOLEAN bCheck)
|
||
{
|
||
wxCheckBox* cb = wxDynamicCast((wxObject*)win, wxCheckBox);
|
||
if (cb != NULL)
|
||
cb->SetValue(bCheck != 0);
|
||
}
|
||
|
||
void xvt_ctl_set_colors(WINDOW win, const XVT_COLOR_COMPONENT* colors, XVT_COLOR_ACTION action)
|
||
{
|
||
// Non posso usare wxControl in quanto certi controlli derivano da wxWindow
|
||
wxWindow* w = wxDynamicCast((wxObject*)win, wxWindow);
|
||
if (w != NULL && colors != NULL)
|
||
{
|
||
if (action == XVT_COLOR_ACTION_SET)
|
||
{
|
||
switch (xvt_vobj_get_type(win))
|
||
{
|
||
case WC_TREE : wxStaticCast(w, TwxTreeCtrl)->SetColors(colors); return;
|
||
case WC_PROPGRID: wxStaticCast(w, TwxPropertyGrid)->SetColors(colors); return;
|
||
case WC_TREELIST: wxStaticCast(w, TwxTreeListCtrl)->SetColors(colors); return;
|
||
default: break;;
|
||
}
|
||
for (int i = 0; colors[i].type; i++)
|
||
{
|
||
CAST_COLOR(colors[i].color, rgb);
|
||
switch(colors[i].type)
|
||
{
|
||
case XVT_COLOR_BACKGROUND: w->SetOwnBackgroundColour(rgb); break;
|
||
case XVT_COLOR_FOREGROUND: w->SetOwnForegroundColour(rgb); break;
|
||
case XVT_COLOR_HIGHLIGHT:
|
||
{
|
||
TwxPopUp* tpu = wxDynamicCast(w, TwxPopUp);
|
||
if (tpu != NULL)
|
||
tpu->SetSelectForeColor(rgb);
|
||
}
|
||
break;
|
||
case XVT_COLOR_SELECT:
|
||
{
|
||
TwxPopUp* tpu = wxDynamicCast(w, TwxPopUp);
|
||
if (tpu != NULL)
|
||
tpu->SetSelectBackColor(rgb);
|
||
}
|
||
break;
|
||
case XVT_COLOR_BLEND:
|
||
if (!w->IsKindOf(CLASSINFO(wxButton)))
|
||
w->SetOwnBackgroundColour(rgb);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// ???
|
||
}
|
||
}
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Buttons
|
||
///////////////////////////////////////////////////////////
|
||
|
||
void xvt_btn_set_images(WINDOW win, XVT_IMAGE up, XVT_IMAGE down)
|
||
{
|
||
if (win != NULL_WIN && up != NULL)
|
||
{
|
||
wxBitmapButton* pb = wxDynamicCast((wxObject*)win, wxBitmapButton);
|
||
if (pb != NULL)
|
||
{
|
||
int mx, my; pb->GetSize(&mx, &my);
|
||
wxBitmap bmpUp = Image2Bitmap(up, mx, my, TRUE);
|
||
if (bmpUp.Ok())
|
||
{
|
||
pb->SetBitmapLabel(bmpUp);
|
||
const wxImage imgGay = ((wxImage*)up)->ConvertToGreyscale();
|
||
wxBitmap bmpGay(imgGay);
|
||
pb->SetBitmapDisabled(bmpGay);
|
||
}
|
||
if (down != NULL)
|
||
{
|
||
wxBitmap bmpDown = Image2Bitmap(down, mx, my, TRUE);
|
||
if (bmpDown.Ok())
|
||
pb->SetBitmapSelected(bmpDown);
|
||
}
|
||
else
|
||
{
|
||
if (bmpUp.Ok())
|
||
pb->SetBitmapSelected(bmpUp);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Pane interface
|
||
///////////////////////////////////////////////////////////
|
||
|
||
static wxAuiManager* FindPaneManager(WINDOW win)
|
||
{
|
||
wxAuiManager* pManager = NULL;
|
||
if (win != NULL_WIN)
|
||
{
|
||
wxWindow* pwin = wxStaticCast((wxObject*)win, wxWindow);
|
||
pManager = wxAuiManager::GetManager(pwin);
|
||
}
|
||
return pManager;
|
||
}
|
||
|
||
static wxAuiPaneInfo* LockPane(WINDOW win)
|
||
{
|
||
wxAuiManager* pManager = FindPaneManager(win);
|
||
if (pManager != NULL)
|
||
{
|
||
wxAuiPaneInfo& pane = pManager->GetPane((wxWindow*)win);
|
||
if (pane.IsOk())
|
||
return &pane;
|
||
}
|
||
return NULL;
|
||
}
|
||
|
||
static void UnlockPane(WINDOW win)
|
||
{
|
||
wxAuiManager* pManager = FindPaneManager(win);
|
||
if (pManager != NULL)
|
||
pManager->Update();
|
||
}
|
||
|
||
BOOLEAN xvt_pane_add(WINDOW win, WINDOW pane, const char* name, int dock, int flags)
|
||
{
|
||
BOOLEAN done = FALSE;
|
||
if (win != NULL_WIN && pane != NULL_WIN && name && *name)
|
||
{
|
||
TwxWindow* owner = wxStaticCast((wxObject*)win, TwxWindow);
|
||
wxWindow* child = wxStaticCast((wxObject*)pane, wxWindow);
|
||
done = owner->AddPane(child, name, dock, flags);
|
||
}
|
||
return done;
|
||
}
|
||
|
||
BOOLEAN xvt_pane_set_title(WINDOW win, const char* title)
|
||
{
|
||
wxAuiPaneInfo* pane = LockPane(win);
|
||
if (pane != NULL)
|
||
{
|
||
pane->Caption(title);
|
||
UnlockPane(win);
|
||
}
|
||
return pane != NULL;
|
||
}
|
||
|
||
XVTDLL BOOLEAN xvt_pane_change_flags(WINDOW win, int set, int rst)
|
||
{
|
||
wxAuiPaneInfo* pane = LockPane(win);
|
||
if (pane != NULL && (set || rst))
|
||
{
|
||
if (set) pane->SetFlag(set, true);
|
||
if (rst) pane->SetFlag(rst, false);
|
||
UnlockPane(win);
|
||
}
|
||
return pane != NULL;
|
||
}
|
||
|
||
XVTDLL BOOLEAN xvt_pane_detach(WINDOW win)
|
||
{
|
||
BOOLEAN ok = FALSE;
|
||
wxAuiManager* pManager = FindPaneManager(win);
|
||
if (pManager != NULL)
|
||
{
|
||
ok = pManager->DetachPane((wxWindow*)win);
|
||
pManager->Update();
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
XVTDLL BOOLEAN xvt_pane_manager_load_perspective(WINDOW win, const char* perspective)
|
||
{
|
||
BOOLEAN ok = FALSE;
|
||
if (perspective && *perspective)
|
||
{
|
||
wxAuiManager* pManager = FindPaneManager(win);
|
||
if (pManager != NULL)
|
||
{
|
||
const wxString str = perspective;
|
||
ok = pManager->LoadPerspective(str, true);
|
||
}
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
XVTDLL int xvt_pane_manager_save_perspective(WINDOW win, char* perspective, int max_size)
|
||
{
|
||
int nSize = 0;
|
||
wxAuiManager* pManager = FindPaneManager(win);
|
||
if (pManager != NULL)
|
||
{
|
||
const wxString str = pManager->SavePerspective();
|
||
nSize = str.Len()+1;
|
||
if (perspective != NULL && max_size > 0)
|
||
wxStrncpy(perspective, str, max_size);
|
||
}
|
||
return nSize;
|
||
}
|
||
|
||
XVTDLL BOOLEAN xvt_pane_set_size_range(WINDOW win, int min_size, int best_size, int max_size)
|
||
{
|
||
BOOLEAN ok = FALSE;
|
||
wxAuiPaneInfo* pane = LockPane(win);
|
||
if (pane != NULL)
|
||
{
|
||
if (min_size > 0 || max_size > 0)
|
||
{
|
||
if (best_size <= 0)
|
||
{
|
||
if (min_size > 0)
|
||
best_size = max_size > 0 ? (min_size+max_size) / 2 : min_size;
|
||
else
|
||
best_size = max_size;
|
||
}
|
||
wxSize szMin(-1, -1), szBst(-1, -1), szMax(-1, -1);
|
||
if (pane->IsTopDockable() || pane->IsBottomDockable())
|
||
{
|
||
szMin.y = min_size;
|
||
szBst.y = best_size;
|
||
szMax.y = max_size;
|
||
}
|
||
else
|
||
{
|
||
szMin.x = min_size;
|
||
szBst.x = best_size;
|
||
szMax.x = max_size;
|
||
}
|
||
pane->MinSize(szMin);
|
||
pane->BestSize(szBst);
|
||
pane->MaxSize(szMax);
|
||
}
|
||
pane->Resizable(min_size != max_size);
|
||
pane->DockFixed(min_size == max_size);
|
||
UnlockPane(win);
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Notebook interface
|
||
///////////////////////////////////////////////////////////
|
||
|
||
class TwxAuiDefaultTabArt : public wxAuiDefaultTabArt
|
||
{
|
||
wxColour m_fore_colour;
|
||
|
||
protected:
|
||
virtual void DrawTab(wxDC& dc, wxWindow* wnd, const wxAuiNotebookPage& pane,
|
||
const wxRect& in_rect, int close_button_state,
|
||
wxRect* out_tab_rect, wxRect* out_button_rect, int* x_extent);
|
||
|
||
public:
|
||
void SetBackgroundColour(const wxColor& colour) { m_base_colour = colour; }
|
||
void SetForegroundColour(const wxColor& colour) { m_fore_colour = colour; }
|
||
virtual wxAuiTabArt* Clone();
|
||
};
|
||
|
||
void TwxAuiDefaultTabArt::DrawTab(wxDC& dc, wxWindow* wnd, const wxAuiNotebookPage& pane,
|
||
const wxRect& in_rect, int close_button_state,
|
||
wxRect* out_tab_rect, wxRect* out_button_rect, int* x_extent)
|
||
{
|
||
dc.SetTextForeground(m_fore_colour);
|
||
wxAuiDefaultTabArt::DrawTab(dc, wnd, pane, in_rect, close_button_state,
|
||
out_tab_rect, out_button_rect, x_extent);
|
||
}
|
||
|
||
|
||
wxAuiTabArt* TwxAuiDefaultTabArt::Clone()
|
||
{
|
||
TwxAuiDefaultTabArt* art = new TwxAuiDefaultTabArt();
|
||
|
||
// Copy'n'paste from aui/auibook.cpp
|
||
art->SetNormalFont(m_normal_font);
|
||
art->SetSelectedFont(m_selected_font);
|
||
art->SetMeasuringFont(m_measuring_font);
|
||
|
||
// My own addition
|
||
art->m_base_colour = m_base_colour;
|
||
art->m_fore_colour = m_fore_colour;
|
||
|
||
return art;
|
||
}
|
||
|
||
IMPLEMENT_DYNAMIC_CLASS(TwxNoteBook, wxAuiNotebook)
|
||
|
||
#define CAST_NOTEBOOK(win, nb) TwxNoteBook& nb = *wxStaticCast((wxObject*)win, TwxNoteBook);
|
||
|
||
inline bool VALID_NOTEBOOK(WINDOW notebk, short page_no)
|
||
{ return page_no >= 0 && wxDynamicCast((wxObject*)notebk, TwxNoteBook)!=NULL; }
|
||
|
||
BEGIN_EVENT_TABLE(TwxNoteBook, wxAuiNotebook)
|
||
EVT_AUINOTEBOOK_PAGE_CHANGING(wxID_ANY, TwxNoteBook::OnPageChanging)
|
||
EVT_AUINOTEBOOK_PAGE_CHANGED(wxID_ANY, TwxNoteBook::OnPageChanged)
|
||
EVT_CHAR(TwxNoteBook::OnChar)
|
||
END_EVENT_TABLE();
|
||
|
||
bool TwxNoteBook::SetBackgroundColour(const wxColour& col)
|
||
{
|
||
const bool ok = wxAuiNotebook::SetBackgroundColour(col);
|
||
if (ok) // Se cambio lo sfondo del tab control devo notificarlo all'art provider
|
||
{
|
||
TwxAuiDefaultTabArt* pArtist = (TwxAuiDefaultTabArt*)GetArtProvider();
|
||
if (pArtist != NULL)
|
||
pArtist->SetBackgroundColour(col);
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
bool TwxNoteBook::SetForegroundColour(const wxColour& col)
|
||
{
|
||
const bool ok = wxAuiNotebook::SetForegroundColour(col);
|
||
if (ok) // Se cambio il colore del testo del tab control devo notificarlo all'art provider
|
||
{
|
||
TwxAuiDefaultTabArt* pArtist = (TwxAuiDefaultTabArt*)GetArtProvider();
|
||
if (pArtist != NULL)
|
||
pArtist->SetForegroundColour(col);
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
|
||
void TwxNoteBook::OnChar(wxKeyEvent& evt)
|
||
{
|
||
// Ridirige i tasti che non sono certamente di navigazione alla finestra nonna
|
||
const int kc = evt.GetKeyCode();
|
||
if (kc >= WXK_F1 && kc <= WXK_F24 || kc == WXK_ESCAPE || kc == WXK_RETURN)
|
||
{
|
||
TwxWindow* gp = wxDynamicCast(GetGrandParent(), TwxWindow);
|
||
if (gp != NULL)
|
||
gp->ProcessEvent(evt);
|
||
else
|
||
evt.Skip();
|
||
}
|
||
}
|
||
|
||
void TwxNoteBook::OnPageChanging(wxAuiNotebookEvent& evt)
|
||
{
|
||
if (!m_bSuspended)
|
||
{
|
||
m_bSuspended = true;
|
||
XVT_EVENT e(E_CONTROL);
|
||
CONTROL_INFO& ci = e.v.ctl.ci;
|
||
e.v.ctl.id = evt.GetId();
|
||
ci.type = WC_NOTEBK;
|
||
ci.win = WINDOW(this);
|
||
// page == NULL_WIN -> changing page; page != NULL_WIN -> page changed.
|
||
ci.v.notebk.page = NULL_WIN;
|
||
ci.v.notebk.page_new = evt.GetSelection();
|
||
ci.v.notebk.page_old = evt.GetOldSelection();
|
||
|
||
TwxWindow* win = wxStaticCast(GetParent(), TwxWindow);
|
||
const bool refused = win->DoXvtEvent(e) != 0;
|
||
if (refused)
|
||
evt.Veto(); // Vieta il passaggio alla pagina nuova
|
||
else
|
||
evt.Skip(); // Permette la notifica dell'evento PageChanged
|
||
|
||
m_bSuspended = false;
|
||
}
|
||
}
|
||
|
||
void TwxNoteBook::OnPageChanged(wxAuiNotebookEvent& evt)
|
||
{
|
||
// Mando la notifica solo al book in basso di ba0
|
||
//if (m_flags & wxAUI_NB_BOTTOM) // Perch<63> mai solo a ba0?
|
||
|
||
if (!m_bSuspended)
|
||
{
|
||
m_bSuspended = true;
|
||
XVT_EVENT e(E_CONTROL);
|
||
CONTROL_INFO& ci = e.v.ctl.ci;
|
||
e.v.ctl.id = evt.GetId();
|
||
ci.type = WC_NOTEBK;
|
||
ci.win = WINDOW(this);
|
||
// page == NULL_WIN -> changing page; page != NULL_WIN -> page changed.
|
||
ci.v.notebk.page = (WINDOW)GetPage(evt.GetSelection());
|
||
ci.v.notebk.page_new = evt.GetSelection();
|
||
ci.v.notebk.page_old = evt.GetOldSelection();
|
||
|
||
TwxWindow* win = wxStaticCast(GetParent(), TwxWindow);
|
||
win->DoXvtEvent(e);
|
||
m_bSuspended = false;
|
||
}
|
||
}
|
||
|
||
short TwxNoteBook::AddTab(wxWindow* pPage, const wxString text, XVT_IMAGE xvt_img, short idx)
|
||
{
|
||
wxBitmap bmp = Image2Bitmap(xvt_img, BOOK_ICO_SIZE, BOOK_ICO_SIZE, TRUE);
|
||
|
||
if (idx < 0 || idx >= (int)GetPageCount())
|
||
{
|
||
AddPage(pPage, text, false, bmp);
|
||
idx = GetPageCount()-1;
|
||
}
|
||
else
|
||
InsertPage(idx, pPage, text, false, bmp);
|
||
|
||
return idx;
|
||
}
|
||
|
||
void TwxNoteBook::SetTabImage(size_t idx, XVT_IMAGE img)
|
||
{
|
||
wxBitmap bmp = Image2Bitmap(img, BOOK_ICO_SIZE, BOOK_ICO_SIZE, TRUE);
|
||
SetPageBitmap(idx, bmp);
|
||
}
|
||
|
||
int TwxNoteBook::ChangeSelection(size_t tab_no)
|
||
{
|
||
const size_t nSel = GetSelection();
|
||
if (!m_bSuspended && tab_no != nSel)
|
||
{
|
||
m_bSuspended = true;
|
||
SetSelection(tab_no);
|
||
m_bSuspended = false;
|
||
}
|
||
return nSel;
|
||
}
|
||
|
||
long TwxNoteBook::Flags2Style(long flags) const
|
||
{
|
||
long style = wxAUI_NB_TAB_MOVE | wxAUI_NB_SCROLL_BUTTONS;
|
||
bool bottom = false;
|
||
|
||
#if wxCHECK_VERSION(2,8,9)
|
||
if (flags & (CTL_FLAG_TAB_TOP|CTL_FLAG_TAB_BOTTOM|CTL_FLAG_TAB_LEFT|CTL_FLAG_TAB_RIGHT))
|
||
{
|
||
bottom = (flags & CTL_FLAG_TAB_BOTTOM) != 0;
|
||
}
|
||
else
|
||
#endif
|
||
{
|
||
bottom = (flags & CTL_FLAG_CENTER_JUST) != 0;
|
||
}
|
||
|
||
if (bottom)
|
||
style |= wxAUI_NB_BOTTOM;
|
||
else
|
||
style |= wxAUI_NB_TOP;
|
||
|
||
return style;
|
||
}
|
||
|
||
TwxNoteBook::TwxNoteBook(wxWindow *parent, wxWindowID id,
|
||
const wxPoint& pos, const wxSize& size, long flags)
|
||
: wxAuiNotebook(parent, id, pos, size, Flags2Style(flags)), m_bSuspended(false)
|
||
{
|
||
SetArtProvider(new TwxAuiDefaultTabArt);
|
||
_nice_windows.Put((WINDOW)this, this); // Serve per poter fare la xvt_vobj_destroy
|
||
|
||
wxAuiTabCtrl* atc = GetActiveTabCtrl();
|
||
if (atc != NULL)
|
||
#if wxCHECK_VERSION(2,9,0)
|
||
atc->GetEventHandler().Bind(wxEVT_CHAR, (functor)&TwxNoteBook::OnChar);
|
||
#else
|
||
atc->Connect(wxEVT_CHAR, (wxObjectEventFunction)&TwxNoteBook::OnChar);
|
||
#endif
|
||
}
|
||
|
||
TwxNoteBook::~TwxNoteBook()
|
||
{
|
||
m_bSuspended = true;
|
||
_nice_windows.Delete((WINDOW)this);
|
||
}
|
||
|
||
short xvt_notebk_add_page(WINDOW notebk, WINDOW page, const char* title, XVT_IMAGE image, short tab_no)
|
||
{
|
||
short idx = -1;
|
||
if (notebk != NULL_WIN)
|
||
{
|
||
CAST_NOTEBOOK(notebk, nb);
|
||
wxString strTitle = title;
|
||
if (strTitle.IsEmpty() && page != NULL_WIN)
|
||
{
|
||
wxWindow* pg = wxStaticCast((wxObject*)page, wxWindow);
|
||
strTitle = pg->GetLabel();
|
||
}
|
||
idx = nb.AddTab((wxWindow*)page, strTitle, image, tab_no);
|
||
}
|
||
return idx;
|
||
}
|
||
|
||
WINDOW xvt_notebk_get_page(WINDOW notebk, short tab_no)
|
||
{
|
||
WINDOW page = NULL_WIN;
|
||
if (VALID_NOTEBOOK(notebk, tab_no))
|
||
{
|
||
CAST_NOTEBOOK(notebk, nb);
|
||
page = (WINDOW)nb.GetPage(tab_no);
|
||
}
|
||
return page;
|
||
}
|
||
|
||
short xvt_notebk_get_num_tabs(WINDOW notebk)
|
||
{
|
||
short pg = 0;
|
||
if (notebk != NULL_WIN)
|
||
{
|
||
CAST_NOTEBOOK(notebk, nb);
|
||
pg = nb.GetPageCount();
|
||
}
|
||
return pg;
|
||
}
|
||
|
||
void xvt_notebk_rem_page(WINDOW notebk, short page_no)
|
||
{
|
||
WINDOW win = xvt_notebk_get_page(notebk, page_no);
|
||
if (win != NULL_WIN)
|
||
{
|
||
xvt_notebk_rem_tab(notebk, page_no);
|
||
xvt_vobj_destroy(win);
|
||
}
|
||
}
|
||
|
||
void xvt_notebk_rem_tab(WINDOW notebk, short tab_no)
|
||
{
|
||
if (VALID_NOTEBOOK(notebk, tab_no))
|
||
{
|
||
CAST_NOTEBOOK(notebk, nb);
|
||
nb.RemovePage(tab_no);
|
||
}
|
||
}
|
||
|
||
void xvt_notebk_set_front_page(WINDOW notebk, short tab_no)
|
||
{
|
||
if (VALID_NOTEBOOK(notebk, tab_no))
|
||
{
|
||
CAST_NOTEBOOK(notebk, nb);
|
||
wxWindow* w = nb.GetPage(tab_no);
|
||
if (w != NULL)
|
||
{
|
||
nb.ChangeSelection(tab_no); // Non genera evento di cambio pagina!
|
||
if (!w->IsShown()) // A volte succede che la prima pagina sia nascosta!
|
||
w->Show(true);
|
||
}
|
||
}
|
||
}
|
||
|
||
short xvt_notebk_get_front_page(WINDOW notebk)
|
||
{
|
||
short idx = -1;
|
||
if (notebk != NULL_WIN)
|
||
{
|
||
CAST_NOTEBOOK(notebk, nb);
|
||
idx = nb.GetSelection();
|
||
}
|
||
return idx;
|
||
}
|
||
|
||
|
||
char* xvt_notebk_get_tab_title(WINDOW notebk, short tab_no, char* title, int sz_title)
|
||
{
|
||
if (VALID_NOTEBOOK(notebk, tab_no))
|
||
{
|
||
CAST_NOTEBOOK(notebk, nb);
|
||
wxStrncpy(title, nb.GetPageText(tab_no), sz_title);
|
||
title[sz_title-1] = '\0';
|
||
}
|
||
else
|
||
*title = '\0';
|
||
return title;
|
||
}
|
||
|
||
void xvt_notebk_set_page_title(WINDOW notebk, short tab_no, const char* title)
|
||
{
|
||
WINDOW win = xvt_notebk_get_page(notebk, tab_no);
|
||
if (win != NULL_WIN)
|
||
xvt_vobj_set_title(win, title);
|
||
}
|
||
|
||
void xvt_notebk_set_tab_image(WINDOW notebk, short tab_no, XVT_IMAGE img)
|
||
{
|
||
if (notebk != NULL_WIN && tab_no >= 0)
|
||
{
|
||
CAST_NOTEBOOK(notebk, nb);
|
||
nb.SetTabImage(tab_no, img); // Se img=NULL toglie l'immagine
|
||
}
|
||
}
|
||
|
||
void xvt_notebk_set_tab_icon(WINDOW notebk, short tab_no, int rid)
|
||
{
|
||
const wxString strName = xvtart_GetResourceName("Icon", rid);
|
||
XVT_IMAGE img = xvt_image_read(strName);
|
||
xvt_notebk_set_tab_image(notebk, tab_no, img);
|
||
xvt_image_destroy(img);
|
||
}
|
||
|
||
void xvt_notebk_set_tab_title(WINDOW notebk, short tab_no, const char* title)
|
||
{
|
||
if (VALID_NOTEBOOK(notebk, tab_no))
|
||
{
|
||
CAST_NOTEBOOK(notebk, nb);
|
||
const short pc = nb.GetPageCount();
|
||
if (tab_no >= pc)
|
||
nb.AddTab(nb.GetPage(pc-1), title, NULL, pc);
|
||
else
|
||
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)
|
||
EVT_RIGHT_DOWN(TwxTreeCtrl::OnRightDown)
|
||
END_EVENT_TABLE();
|
||
|
||
#define CAST_TREEVIEW(win, tv) TwxTreeCtrl& tv = *wxStaticCast((wxObject*)win, TwxTreeCtrl);
|
||
|
||
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();
|
||
XVT_EVENT e(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 = wxStaticCast(GetParent(), TwxWindow);
|
||
win->DoXvtEvent(e);
|
||
if (GetChildrenCount(id) == 0) // Allora e' proprio vero ...
|
||
SetItemHasChildren(id, false);
|
||
}
|
||
}
|
||
|
||
void TwxTreeCtrl::OnCollapsed(wxTreeEvent& evt)
|
||
{
|
||
if (!m_nFrozen)
|
||
{
|
||
Suspend();
|
||
XVT_EVENT e(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 = wxStaticCast(GetParent(), TwxWindow);
|
||
win->DoXvtEvent(e);
|
||
Resume();
|
||
}
|
||
}
|
||
|
||
void TwxTreeCtrl::OnClick(wxTreeEvent& evt, bool bDouble)
|
||
{
|
||
if (!m_nFrozen)
|
||
{
|
||
Suspend();
|
||
XVT_EVENT e(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 = wxStaticCast(GetParent(), TwxWindow);
|
||
win->DoXvtEvent(e);
|
||
Resume();
|
||
}
|
||
}
|
||
|
||
wxColour TwxTreeCtrl::GetItemTextColour(const wxTreeItemId& id) const
|
||
{
|
||
if (IsSelected(id))
|
||
return m_clrSelFore;
|
||
return wxTreeCtrl::GetItemTextColour(id);
|
||
}
|
||
|
||
wxColour TwxTreeCtrl::GetItemBackgroundColour(const wxTreeItemId& id) const
|
||
{
|
||
if (IsSelected(id))
|
||
return m_clrSelBack;
|
||
return wxTreeCtrl::GetItemBackgroundColour(id);
|
||
}
|
||
|
||
void TwxTreeCtrl::OnSelected(wxTreeEvent& evt)
|
||
{
|
||
OnClick(evt, false);
|
||
}
|
||
|
||
void TwxTreeCtrl::OnActivated(wxTreeEvent& evt)
|
||
{
|
||
#if wxCHECK_VERSION(2,8,10)
|
||
const wxTreeItemId id = evt.GetItem();
|
||
if (ItemHasChildren(id))
|
||
{
|
||
if (IsExpanded(id))
|
||
Collapse(id);
|
||
else
|
||
Expand(id);
|
||
}
|
||
#endif
|
||
OnClick(evt, true);
|
||
}
|
||
|
||
void TwxTreeCtrl::OnRightDown(wxMouseEvent& evt)
|
||
{
|
||
TwxWindow* pParent = wxDynamicCast(GetParent(), TwxWindow);
|
||
if (pParent != NULL)
|
||
{
|
||
XVT_EVENT e(E_MOUSE_DOWN);
|
||
e.v.mouse.button = 1;
|
||
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();
|
||
pParent->DoXvtEvent(e);
|
||
}
|
||
}
|
||
|
||
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!
|
||
}
|
||
else
|
||
{
|
||
int old_w, old_h; il->GetSize(0, old_w, old_h);
|
||
const int new_w = img.GetWidth(), new_h = img.GetHeight();
|
||
if (new_w > old_w) // L'immagine nuova e' troppo grande?
|
||
{
|
||
const int old_ratio = old_w * 100 / old_h;
|
||
const int new_ratio = new_w * 100 / new_h;
|
||
const int old_count = il->GetImageCount();
|
||
wxImageList* nil = new wxImageList;
|
||
nil->Create(new_w, new_h, true, 3*old_count/2);
|
||
for (int k = 0; k < old_count; k++)
|
||
{
|
||
wxImage old = il->GetBitmap(k).ConvertToImage();
|
||
if (old_ratio == new_ratio)
|
||
old.Rescale(new_w, new_h, wxIMAGE_QUALITY_HIGH);
|
||
else
|
||
old.Resize(wxSize(new_w, new_h), wxPoint((new_w-old_w)/2, (new_h-old_h)/2));
|
||
nil->Add(old);
|
||
}
|
||
AssignImageList(il = nil);
|
||
}
|
||
}
|
||
|
||
if (!img.HasMask())
|
||
{
|
||
wxImage& trans = (wxImage&)img;
|
||
const int r = img.GetRed(0,0);
|
||
const int g = img.GetGreen(0,0);
|
||
const int b = img.GetBlue(0,0);
|
||
trans.SetMask();
|
||
trans.SetMaskColour(r, g, b);
|
||
}
|
||
const wxBitmap bmp(img);
|
||
i = il->Add(bmp);
|
||
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);
|
||
}
|
||
}
|
||
}
|
||
|
||
void TwxTreeCtrl::Enable(const wxTreeItemId& id, bool on)
|
||
{
|
||
SetItemTextColour(id, on ? m_clrSelFore : m_clrDisFore);
|
||
}
|
||
|
||
void TwxTreeCtrl::Suspend()
|
||
{ m_nFrozen++; }
|
||
|
||
void TwxTreeCtrl::Resume()
|
||
{
|
||
wxASSERT(m_nFrozen > 0);
|
||
if (m_nFrozen > 0)
|
||
m_nFrozen--;
|
||
}
|
||
|
||
void TwxTreeCtrl::SetColors(const XVT_COLOR_COMPONENT* colors)
|
||
{
|
||
for (int i = 0; colors[i].type; i++)
|
||
{
|
||
CAST_COLOR(colors[i].color, rgb);
|
||
switch(colors[i].type)
|
||
{
|
||
case XVT_COLOR_BACKGROUND: SetOwnBackgroundColour(rgb); break;
|
||
case XVT_COLOR_FOREGROUND: SetOwnForegroundColour(rgb); break;
|
||
case XVT_COLOR_HIGHLIGHT : m_clrSelBack = rgb; break;
|
||
case XVT_COLOR_SELECT : m_clrSelFore = rgb; break;
|
||
case XVT_COLOR_TROUGH : m_clrDisFore = rgb; break;
|
||
default : break;
|
||
}
|
||
}
|
||
}
|
||
|
||
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 WXUNUSED(item_image),
|
||
XVT_IMAGE WXUNUSED(collapsed_image), XVT_IMAGE WXUNUSED(expanded_image),
|
||
long WXUNUSED(attrs), int WXUNUSED(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 WXUNUSED(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 (parent.IsOk() && 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_enable_node(WINDOW win, XVT_TREEVIEW_NODE node, BOOLEAN on)
|
||
{
|
||
BOOLEAN ok = (win != NULL_WIN) && (node != NULL);
|
||
if (ok)
|
||
{
|
||
CAST_TREEVIEW(win, tv);
|
||
wxTreeItemId id(node);
|
||
tv.Enable(id, on != FALSE);
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
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);
|
||
tv.Suspend();
|
||
const wxTreeItemId id(node);
|
||
if (recurse)
|
||
tv.ExpandAllChildren(id);
|
||
else
|
||
tv.Expand(id);
|
||
tv.Resume();
|
||
}
|
||
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;
|
||
}
|
||
|
||
SLIST xvt_treeview_get_selected_list(WINDOW win)
|
||
{
|
||
SLIST list = NULL;
|
||
CAST_TREEVIEW(win, tv);
|
||
wxArrayTreeItemIds selections;
|
||
const size_t nSel = tv.GetSelections(selections);
|
||
if (nSel > 0)
|
||
{
|
||
list = xvt_slist_create();
|
||
for (size_t i = 0; i < nSel; i++)
|
||
{
|
||
const wxTreeItemId& id = selections[i];
|
||
const TwxTreeItemData* pData = (const TwxTreeItemData*)tv.GetItemData(id);
|
||
if (pData != NULL)
|
||
xvt_slist_add_at_elt(list, NULL, pData->m_strData, (long)id.m_pItem);
|
||
else
|
||
xvt_slist_add_at_elt(list, NULL, "", (long)id.m_pItem);
|
||
}
|
||
}
|
||
return list;
|
||
}
|
||
|
||
|
||
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);
|
||
if (id == tv.GetRootItem())
|
||
tv.DeleteAllItems();
|
||
else
|
||
{
|
||
tv.Suspend();
|
||
tv.Delete(id);
|
||
tv.Resume();
|
||
}
|
||
}
|
||
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);
|
||
tv.Suspend();
|
||
wxTreeItemId id(node);
|
||
if (!id.IsOk())
|
||
id = tv.GetRootItem();
|
||
tv.DeleteChildren(id);
|
||
tv.Resume();
|
||
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);
|
||
if (sel)
|
||
{
|
||
tv.Suspend();
|
||
tv.SelectItem(id, true);
|
||
tv.EnsureVisible(id);
|
||
tv.Resume();
|
||
}
|
||
else
|
||
tv.SelectItem(id, false);
|
||
}
|
||
}
|
||
|
||
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_bold(WINDOW win, XVT_TREEVIEW_NODE node, BOOLEAN bold)
|
||
{
|
||
if (win != NULL_WIN && node != NULL)
|
||
{
|
||
CAST_TREEVIEW(win, tv);
|
||
const wxTreeItemId id(node);
|
||
tv.SetItemBold(id, bold != FALSE);
|
||
}
|
||
}
|
||
|
||
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();
|
||
}
|
||
|
||
static XVT_TREEVIEW_NODE FindTreeNodeString(wxTreeCtrl& tv, const wxTreeItemId& parent,
|
||
const char*text)
|
||
{
|
||
if (parent.IsOk())
|
||
{
|
||
TwxTreeItemData* pData = (TwxTreeItemData*)tv.GetItemData(parent);
|
||
if (pData != NULL && pData->m_strData == text)
|
||
return parent.m_pItem;
|
||
|
||
wxTreeItemIdValue cookie;
|
||
for (wxTreeItemId id = tv.GetFirstChild(parent, cookie); id.IsOk();
|
||
id = tv.GetNextChild(parent, cookie))
|
||
{
|
||
XVT_TREEVIEW_NODE node = FindTreeNodeString(tv, id, text);
|
||
if (node != NULL)
|
||
return node;
|
||
}
|
||
}
|
||
return NULL;
|
||
}
|
||
|
||
XVT_TREEVIEW_NODE xvt_treeview_find_node_string(WINDOW win, const char* text)
|
||
{
|
||
XVT_TREEVIEW_NODE node = NULL;
|
||
if (win != NULL_WIN && text && *text)
|
||
{
|
||
CAST_TREEVIEW(win, tv);
|
||
node = FindTreeNodeString(tv, tv.GetSelection(), text);
|
||
if (node == NULL)
|
||
node = FindTreeNodeString(tv, tv.GetRootItem(), text);
|
||
}
|
||
return node;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TwxOutlookBar
|
||
///////////////////////////////////////////////////////////
|
||
|
||
BEGIN_EVENT_TABLE(TwxOutlookBar, wxVListBox)
|
||
EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_LISTBOX_SELECTED, TwxOutlookBar::OnSelected)
|
||
EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, TwxOutlookBar::OnSelected)
|
||
EVT_MOTION(TwxOutlookBar::OnMouseMove)
|
||
EVT_LEAVE_WINDOW(TwxOutlookBar::OnMouseLeave)
|
||
END_EVENT_TABLE()
|
||
|
||
static const wxColour ModulateColour(const wxColour& col, int percent)
|
||
{
|
||
int k = 0;
|
||
if (percent > 0)
|
||
k = 255;
|
||
else
|
||
percent = -percent;
|
||
const int inverse = 100-percent;
|
||
int r = ((k * percent) + (col.Red() * inverse)) / 100;
|
||
int g = ((k * percent) + (col.Green() * inverse)) / 100;
|
||
int b = ((k * percent) + (col.Blue() * inverse)) / 100;
|
||
return wxColour(r, g, b);
|
||
}
|
||
|
||
void TwxOutlookBar::OnDrawBackground(wxDC& dc, const wxRect& rect, size_t u) const
|
||
{
|
||
const int n = u; // Anti warning
|
||
wxColour color1, color2;
|
||
if (n == m_nHovering)
|
||
{
|
||
if (n == GetSelection())
|
||
{
|
||
color1 = wxColour(232,127,8);
|
||
color2 = wxColour(247,218,124);
|
||
}
|
||
else
|
||
{
|
||
color1 = wxColour(255,255,220);
|
||
color2 = wxColour(247,192,91);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (n == GetSelection())
|
||
{
|
||
color1 = wxColour(251,230,148); // Colori predefiniti di Outlook
|
||
color2 = wxColour(238,149, 21);
|
||
}
|
||
else
|
||
{
|
||
if (InheritsBackgroundColour())
|
||
{
|
||
color1 = ModulateColour(wxSystemSettings::GetColour(wxSYS_COLOUR_INACTIVECAPTION), +20);
|
||
color2 = ModulateColour(wxSystemSettings::GetColour(wxSYS_COLOUR_ACTIVECAPTION), -20);
|
||
}
|
||
else
|
||
{
|
||
const wxColour bkg = GetBackgroundColour();
|
||
color1 = ModulateColour(bkg, +20);
|
||
color2 = ModulateColour(bkg, -20);
|
||
}
|
||
}
|
||
}
|
||
|
||
#if wxCHECK_VERSION(2,8,12)
|
||
{
|
||
const wxColour color0 = ModulateColour(color2, +20);
|
||
const int delta = 2*rect.height/5;
|
||
wxRect r1 = rect, r2 = rect;
|
||
r1.height = delta;
|
||
r2.y += delta; r2.height -= delta;
|
||
dc.GradientFillLinear(r1, color0, color0, wxDOWN);
|
||
dc.GradientFillLinear(r2, color2, color1, wxDOWN);
|
||
|
||
wxPen pen1(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNHIGHLIGHT));
|
||
dc.SetPen(pen1);
|
||
dc.DrawLine(rect.x, rect.y, rect.GetRight(), rect.y);
|
||
|
||
wxPen pen2(wxSystemSettings::GetColour(wxSYS_COLOUR_3DDKSHADOW));
|
||
dc.SetPen(pen2);
|
||
dc.DrawLine(rect.x, rect.GetBottom(), rect.GetRight(), rect.GetBottom());
|
||
}
|
||
#else
|
||
dc.GradientFillLinear(rect, color1, color2, wxDOWN);
|
||
#endif
|
||
}
|
||
|
||
void TwxOutlookBar::OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const
|
||
{
|
||
const int nSide = rect.height;
|
||
const TwxOutlookItem& oi = m_item[n];
|
||
int nTextOffset = 4;
|
||
if (oi.m_nIconId > 0)
|
||
{
|
||
const int sz = nSide > 16 ? (nSide < 48 ? (nSide/16*16) : 48) : 16;
|
||
const wxIcon ico = xvtart_GetIconResource(oi.m_nIconId, wxART_TOOLBAR, sz);
|
||
if (ico.IsOk())
|
||
{
|
||
const wxSize szIco(ico.GetWidth(), ico.GetHeight());
|
||
dc.DrawIcon(ico, rect.x+nTextOffset, rect.y+(nSide-szIco.y)/2);
|
||
nTextOffset += nTextOffset+szIco.x;
|
||
}
|
||
else
|
||
nTextOffset += nTextOffset+sz;
|
||
}
|
||
|
||
dc.SetFont(GetFont()); // Imposta il font predefinito per questo controllo
|
||
|
||
wxColour color = GetForegroundColour();
|
||
if (InheritsBackgroundColour())
|
||
color = wxSystemSettings::GetColour(wxSYS_COLOUR_CAPTIONTEXT);
|
||
dc.SetTextForeground(color);
|
||
|
||
const wxString& str = oi.m_strText;
|
||
const int nMaxX = rect.width - nTextOffset;
|
||
const wxSize szText = dc.GetTextExtent(str);
|
||
if (szText.x > nMaxX && szText.y*2 < nSide)
|
||
{
|
||
const int nMid = str.Len() / 2;
|
||
int nBest = nMid, nDist = nMid;
|
||
for (int i = 0; i < 2*nMid; i++) if (str[i] <= wxChar(' '))
|
||
{
|
||
const int d = abs(nMid-i);
|
||
if (d < nDist)
|
||
{
|
||
nBest = i;
|
||
nDist = d;
|
||
}
|
||
}
|
||
dc.DrawText(str.Left(nBest+1), rect.x+nTextOffset, rect.y+nSide/2-szText.y);
|
||
dc.DrawText(str.Mid(nBest+1), rect.x+nTextOffset, rect.y+nSide/2);
|
||
}
|
||
else
|
||
dc.DrawText(oi.m_strText, rect.x+nTextOffset, rect.y+(nSide-szText.y)/2);
|
||
}
|
||
|
||
wxCoord TwxOutlookBar::OnMeasureItem(size_t WXUNUSED(n)) const
|
||
{
|
||
const int nItems = GetItemCount();
|
||
wxCoord nHeight = 32 + 4; // Icon size + gap
|
||
if (nItems > 1)
|
||
{
|
||
const wxSize sz = GetSize();
|
||
nHeight = max(sz.y / nItems, nHeight);
|
||
}
|
||
return nHeight;
|
||
}
|
||
|
||
void TwxOutlookBar::OnMouseMove(wxMouseEvent& evt)
|
||
{
|
||
const int nWasHovering = m_nHovering;
|
||
m_nHovering = HitTest(evt.GetPosition());
|
||
if (m_nHovering != nWasHovering)
|
||
{
|
||
if (nWasHovering != wxNOT_FOUND)
|
||
RefreshLine(nWasHovering);
|
||
if (m_nHovering != wxNOT_FOUND)
|
||
RefreshLine(m_nHovering);
|
||
}
|
||
}
|
||
|
||
void TwxOutlookBar::OnMouseLeave(wxMouseEvent& WXUNUSED(e))
|
||
{
|
||
if (m_nHovering != wxNOT_FOUND)
|
||
{
|
||
const int nWasHovering = m_nHovering;
|
||
m_nHovering = wxNOT_FOUND;
|
||
RefreshLine(nWasHovering);
|
||
}
|
||
}
|
||
|
||
void TwxOutlookBar::OnSelected(wxCommandEvent& evt)
|
||
{
|
||
TwxWindow* win = wxDynamicCast(GetParent(), TwxWindow);
|
||
if (win != NULL)
|
||
{
|
||
XVT_EVENT e(E_CONTROL);
|
||
e.v.ctl.id = evt.GetId();
|
||
e.v.ctl.ci.type = WC_OUTLOOKBAR;
|
||
e.v.ctl.ci.win = WINDOW(this);
|
||
e.v.ctl.ci.v.lbox.dbl_click = evt.GetEventType() == wxEVT_COMMAND_LISTBOX_DOUBLECLICKED;
|
||
win->DoXvtEvent(e);
|
||
}
|
||
}
|
||
|
||
int TwxOutlookBar::Add(short nIconId, const wxString strText, int nFlags)
|
||
{
|
||
int i = GetItemCount();
|
||
const bool ok = i < MAX_ITEMS-1;
|
||
if (ok)
|
||
{
|
||
m_item[i].m_nIconId = nIconId;
|
||
m_item[i].m_strText = strText;
|
||
m_item[i].m_nFlags = nFlags;
|
||
SetItemCount(i+1);
|
||
}
|
||
else
|
||
i = -1;
|
||
return i;
|
||
}
|
||
|
||
TwxOutlookBar::TwxOutlookBar(wxWindow *parent, wxWindowID id,
|
||
const wxPoint& pos, const wxSize& size, long style)
|
||
: wxVListBox(parent, id, pos, size, style), m_nHovering(wxNOT_FOUND)
|
||
{
|
||
SetItemCount(0);
|
||
}
|
||
|
||
TwxOutlookBar::~TwxOutlookBar()
|
||
{ }
|
||
|
||
BOOLEAN xvt_list_add(WINDOW win, int index, const char* text)
|
||
{
|
||
wxListBox* lb = wxDynamicCast((wxObject*)win, wxListBox);
|
||
BOOLEAN ok = lb != NULL;
|
||
if (ok)
|
||
{
|
||
const wxString str = text;
|
||
if (index < 0 || index >= (int)lb->GetCount())
|
||
lb->AppendString(str);
|
||
else
|
||
lb->Insert(str, index);
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
int xvt_list_add_item(WINDOW win, short icon, const char* text, int flags)
|
||
{
|
||
int n = -1;
|
||
if (win != NULL_WIN)
|
||
{
|
||
TwxOutlookBar* olb = wxDynamicCast((wxObject*)win, TwxOutlookBar);
|
||
if (olb != NULL)
|
||
n = olb->Add(icon, text, flags);
|
||
}
|
||
return n;
|
||
}
|
||
|
||
BOOLEAN xvt_list_clear(WINDOW win)
|
||
{
|
||
BOOLEAN ok = win != NULL_WIN;
|
||
if (ok)
|
||
{
|
||
wxVListBox* olb = wxDynamicCast((wxObject*)win, wxVListBox);
|
||
if (olb != NULL)
|
||
olb->Clear();
|
||
else
|
||
{
|
||
wxListBox* lb = wxDynamicCast((wxObject*)win, wxListBox);
|
||
if (lb != NULL)
|
||
lb->Clear();
|
||
}
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
int xvt_list_get_sel_index(WINDOW win)
|
||
{
|
||
int sel = -1;
|
||
if (win != NULL_WIN)
|
||
{
|
||
wxVListBox* olb = wxDynamicCast((wxObject*)win, wxVListBox);
|
||
if (olb != NULL)
|
||
sel = olb->GetSelection();
|
||
else
|
||
{
|
||
wxListBox* lb = wxDynamicCast((wxObject*)win, wxListBox);
|
||
if (lb != NULL)
|
||
sel = lb->GetSelection();
|
||
}
|
||
}
|
||
return sel;
|
||
}
|
||
|
||
BOOLEAN xvt_list_set_sel(WINDOW win, int index, BOOLEAN select)
|
||
{
|
||
BOOLEAN ok = win != NULL_WIN;
|
||
if (ok)
|
||
{
|
||
wxVListBox* olb = wxDynamicCast((wxObject*)win, wxVListBox);
|
||
if (olb != NULL)
|
||
{
|
||
if (select)
|
||
olb->SetSelection(index);
|
||
}
|
||
else
|
||
{
|
||
wxListBox* lb = wxDynamicCast((wxObject*)win, wxListBox);
|
||
if (lb != NULL)
|
||
lb->SetSelection(index, select != 0);
|
||
}
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
int xvt_list_count(WINDOW win)
|
||
{
|
||
int n = 0;
|
||
if (win != NULL_WIN)
|
||
{
|
||
wxVListBox* olb = wxDynamicCast((wxObject*)win, wxVListBox);
|
||
if (olb != NULL)
|
||
n = olb->GetItemCount();
|
||
else
|
||
{
|
||
wxListBox* lb = wxDynamicCast((wxObject*)win, wxListBox);
|
||
if (lb != NULL)
|
||
n = lb->GetCount();
|
||
}
|
||
}
|
||
return n;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TwxPopUp
|
||
///////////////////////////////////////////////////////////
|
||
|
||
IMPLEMENT_DYNAMIC_CLASS(TwxPopUp, wxVListBox)
|
||
|
||
BEGIN_EVENT_TABLE(TwxPopUp, wxVListBox)
|
||
EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_LISTBOX_SELECTED, TwxPopUp::OnSelected)
|
||
EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, TwxPopUp::OnSelected)
|
||
EVT_MOTION(TwxPopUp::OnMouseMove)
|
||
EVT_LEFT_DOWN(TwxPopUp::OnLeftDown)
|
||
EVT_KILL_FOCUS(TwxPopUp::OnKillFocus)
|
||
EVT_KEY_DOWN(TwxPopUp::OnKeyDown)
|
||
END_EVENT_TABLE()
|
||
|
||
|
||
void TwxPopUp::OnDrawBackground(wxDC& dc, const wxRect& rect, size_t u) const
|
||
{
|
||
const int n = u; // Anti warning
|
||
if (n == m_nHovering || (m_nHovering == wxNOT_FOUND && IsCurrent(u)))
|
||
{
|
||
wxBrush brush(m_clrBack);
|
||
dc.SetBrush(brush);
|
||
dc.SetPen(*wxTRANSPARENT_PEN);
|
||
dc.DrawRectangle(rect);
|
||
}
|
||
}
|
||
|
||
void TwxPopUp::OnDrawItem(wxDC& dc, const wxRect& rect, size_t u) const
|
||
{
|
||
const int n = u; // Anti warning
|
||
wxColour color;
|
||
if (n == m_nHovering || (m_nHovering == wxNOT_FOUND && IsCurrent(u)))
|
||
color = m_clrFore;
|
||
else
|
||
color = GetForegroundColour();
|
||
dc.SetTextForeground(color);
|
||
dc.SetFont(GetFont());
|
||
dc.DrawText(m_menu[n], rect.x, rect.y);
|
||
}
|
||
|
||
wxCoord TwxPopUp::OnMeasureItem(size_t WXUNUSED(n)) const
|
||
{
|
||
return m_nRowHeight;
|
||
}
|
||
|
||
void TwxPopUp::OnMouseMove(wxMouseEvent& evt)
|
||
{
|
||
int nHover = wxNOT_FOUND;
|
||
|
||
const wxRect rect = GetClientRect();
|
||
if (rect.Contains(evt.GetPosition()))
|
||
nHover = HitTest(evt.GetPosition());
|
||
|
||
if (nHover != m_nHovering)
|
||
{
|
||
const int nWasHovering = m_nHovering;
|
||
m_nHovering = nHover;
|
||
if (nWasHovering != wxNOT_FOUND)
|
||
RefreshLine(nWasHovering);
|
||
if (m_nHovering != wxNOT_FOUND)
|
||
RefreshLine(m_nHovering);
|
||
}
|
||
}
|
||
|
||
void TwxPopUp::OnLeftDown(wxMouseEvent& evt)
|
||
{
|
||
const wxRect rect = GetClientRect();
|
||
const wxPoint pt = evt.GetPosition();
|
||
if (rect.Contains(evt.GetPosition()))
|
||
wxVListBox::OnLeftDown(evt);
|
||
else
|
||
Hide();
|
||
}
|
||
|
||
void TwxPopUp::OnKillFocus(wxFocusEvent& WXUNUSED(e))
|
||
{
|
||
Hide();
|
||
}
|
||
|
||
void TwxPopUp::NotifySelection()
|
||
{
|
||
TwxWindow* win = wxDynamicCast(GetParent(), TwxWindow);
|
||
if (win != NULL)
|
||
{
|
||
XVT_EVENT e(E_CONTROL);
|
||
e.v.ctl.id = GetId();
|
||
e.v.ctl.ci.type = WC_LISTEDIT;
|
||
e.v.ctl.ci.win = WINDOW(this);
|
||
e.v.ctl.ci.v.listedit.active = GetSelection();
|
||
win->DoXvtEvent(e);
|
||
}
|
||
Hide();
|
||
}
|
||
|
||
void TwxPopUp::OnSelected(wxCommandEvent& WXUNUSED(evt))
|
||
{
|
||
if (m_nHovering >= 0)
|
||
NotifySelection();
|
||
}
|
||
|
||
int TwxPopUp::Add(const wxString str)
|
||
{
|
||
m_menu.Add(str);
|
||
const int i = m_menu.GetCount();
|
||
SetItemCount(i);
|
||
return i;
|
||
}
|
||
|
||
void TwxPopUp::OnKeyDown(wxKeyEvent& evt)
|
||
{
|
||
m_nHovering = wxNOT_FOUND; // Evita chiusura involontaria della lista
|
||
int key = evt.GetKeyCode();
|
||
switch (key)
|
||
{
|
||
case WXK_RETURN:
|
||
NotifySelection();
|
||
break;
|
||
default:
|
||
if (key > ' ' && key <= 'z')
|
||
{
|
||
key = toupper(key);
|
||
const int curr = max(GetSelection(), 0);
|
||
const int tot = m_menu.GetCount();
|
||
int i = curr;
|
||
for (i = (i+1)%tot; i != curr; i = (i+1)%tot)
|
||
{
|
||
if (toupper(m_menu[i][0]) == key)
|
||
break;
|
||
}
|
||
SetSelection(i);
|
||
}
|
||
else
|
||
evt.Skip();
|
||
break;
|
||
}
|
||
}
|
||
|
||
TwxPopUp::TwxPopUp(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size)
|
||
: wxVListBox(parent, id, pos, size, wxBORDER|wxCLIP_SIBLINGS),
|
||
m_nHovering(wxNOT_FOUND)
|
||
{
|
||
m_clrFore = wxSystemSettings::GetColour(wxSYS_COLOUR_HOTLIGHT);
|
||
m_clrBack = GetSelectionBackground();
|
||
|
||
const wxFont font = parent->GetFont();
|
||
m_nRowHeight = abs(font.GetPixelSize().y) + 4;
|
||
}
|
||
|
||
static int RoundPopupHeight(int list_h, int row_h)
|
||
{
|
||
const int rem = list_h % (row_h+1);
|
||
if (rem > 0)
|
||
list_h -= rem;
|
||
return list_h;
|
||
}
|
||
|
||
MENU_TAG xvt_list_popup(WINDOW parent_win, const RCT* ownrct, const MENU_ITEM* menu,
|
||
const XVT_COLOR_COMPONENT* colors, MENU_TAG first)
|
||
{
|
||
int sel = -1;
|
||
int items = 0;
|
||
if (parent_win != NULL_WIN && ownrct != NULL && menu != NULL)
|
||
{
|
||
wxWindow* parent = wxStaticCast((wxObject*)parent_win, wxWindow);
|
||
int width = ownrct->right - ownrct->left;
|
||
for (items = 0; menu[items].tag != 0; items++) if (menu[items].tag > 0 && menu[items].text)
|
||
{
|
||
const wxString str = menu[items].text;
|
||
int w = 0, h = 0; parent->GetTextExtent(str, &w, &h);
|
||
w += 24;
|
||
if (w > width)
|
||
width = w;
|
||
}
|
||
|
||
const wxFont font = parent->GetFont();
|
||
const int nRowHeight = abs(font.GetPixelSize().y)+4;
|
||
const wxRect rctClient = parent->GetClientRect();
|
||
const int nBottom = rctClient.GetBottom();
|
||
|
||
wxPoint pos(ownrct->right-width, ownrct->bottom);
|
||
wxSize size(width, items*nRowHeight+2);
|
||
|
||
if (pos.y + size.y > nBottom) // La lista deborda di sotto?
|
||
{
|
||
if (ownrct->top > nBottom-ownrct->bottom) // Ho piu' spazio sopra che sotto?
|
||
{
|
||
pos.y = ownrct->top - size.y; // Sposto la lista sopra al campo di testo
|
||
if (pos.y < 0)
|
||
{
|
||
size.y = RoundPopupHeight(size.y + pos.y, nRowHeight);
|
||
pos.y = ownrct->top - size.y;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// Accorcio la lista in basso
|
||
size.y = RoundPopupHeight(nBottom-pos.y, nRowHeight);
|
||
}
|
||
}
|
||
if (pos.x < 0)
|
||
pos.x = 0;
|
||
|
||
WIN_DEF wd; memset(&wd, 0, sizeof(wd));
|
||
wd.ctlcolors = (XVT_COLOR_COMPONENT*)colors;
|
||
xvt_rect_set(&wd.rct, pos.x, pos.y, pos.x+size.x, pos.y+size.y);
|
||
wd.v.ctl.ctrl_id = wxID_ANY;
|
||
wd.v.ctl.flags = CTL_FLAG_INVISIBLE;
|
||
wd.wtype = WC_POPUP;
|
||
WINDOW win = xvt_ctl_create_def(&wd, parent_win, 0);
|
||
|
||
TwxPopUp* lb = wxDynamicCast((wxObject*)win, TwxPopUp);
|
||
if (lb != NULL)
|
||
{
|
||
for (int i = 0; menu[i].tag != 0; i++)
|
||
{
|
||
const MENU_ITEM& mi = menu[i];
|
||
if (mi.tag > 0)
|
||
{
|
||
lb->Add(mi.text);
|
||
if (mi.tag == first)
|
||
sel = i;
|
||
}
|
||
}
|
||
if (sel >= 0)
|
||
lb->SetSelection(sel);
|
||
lb->Show();
|
||
lb->SetFocus();
|
||
|
||
lb->CaptureMouse();
|
||
wxApp* a = wxTheApp; // Memorizzo il risultato di wxGetInstance
|
||
while (lb->IsShown())
|
||
{
|
||
while (a->Pending())
|
||
a->Dispatch();
|
||
lb->Raise();
|
||
a->ProcessIdle();
|
||
wxMilliSleep(50);
|
||
}
|
||
sel = lb->GetSelection();
|
||
lb->ReleaseMouse();
|
||
|
||
delete lb;
|
||
}
|
||
}
|
||
return sel >= 0 && sel < items ? menu[sel].tag : 0;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// ToolBar
|
||
///////////////////////////////////////////////////////////
|
||
|
||
#if wxCHECK_VERSION(3,8,9)
|
||
#include <wx/aui/auibar.h>
|
||
#define TwxToolBarBase wxAuiToolBar
|
||
#else
|
||
#define TwxToolBarBase wxToolBar
|
||
#endif
|
||
|
||
class TwxToolBar : public TwxToolBarBase
|
||
{
|
||
DECLARE_DYNAMIC_CLASS(TwxToolBar)
|
||
wxBitmap m_texture;
|
||
|
||
protected:
|
||
DECLARE_EVENT_TABLE()
|
||
void OnTool(wxCommandEvent& evt);
|
||
void OnEraseBackground(wxEraseEvent& evt);
|
||
virtual bool SetBackgroundColour(const wxColour& colour);
|
||
virtual bool SetForegroundColour(const wxColour& colour);
|
||
|
||
TwxToolBar() : TwxToolBarBase(NULL, wxID_ANY) { wxASSERT(false); }
|
||
|
||
public:
|
||
void ShowTool(int id, bool on);
|
||
void SetBackgroundTexture(XVT_IMAGE img);
|
||
TwxToolBar(wxWindow* parent, wxWindowID id, const wxPoint& pos,
|
||
const wxSize& size, long style);
|
||
};
|
||
|
||
IMPLEMENT_DYNAMIC_CLASS(TwxToolBar, TwxToolBarBase)
|
||
|
||
BEGIN_EVENT_TABLE(TwxToolBar, TwxToolBarBase)
|
||
EVT_TOOL(wxID_ANY, TwxToolBar::OnTool)
|
||
EVT_ERASE_BACKGROUND(TwxToolBar::OnEraseBackground)
|
||
END_EVENT_TABLE();
|
||
|
||
void TwxToolBar::OnTool(wxCommandEvent& evt)
|
||
{
|
||
XVT_EVENT e(E_CONTROL);
|
||
e.v.ctl.id = evt.GetId();
|
||
e.v.ctl.ci.type = WC_ICON; // WC_PUSHBUTTON entra in conflitto coi bottoni
|
||
e.v.ctl.ci.win = WINDOW(this);
|
||
TwxWindow* win = wxStaticCast(GetParent(), TwxWindow);
|
||
win->DoXvtEvent(e);
|
||
}
|
||
|
||
void TwxToolBar::OnEraseBackground(wxEraseEvent& evt)
|
||
{
|
||
wxDC& dc = *evt.GetDC();
|
||
if (m_texture.IsOk())
|
||
{
|
||
const wxCoord tw = m_texture.GetWidth();
|
||
const wxCoord th = m_texture.GetHeight();
|
||
wxCoord cw, ch; dc.GetSize(&cw, &ch);
|
||
for (wxCoord y = 0; y < ch; y += th)
|
||
for (wxCoord x = 0; x < cw; x += tw)
|
||
dc.DrawBitmap(m_texture, x, y);
|
||
}
|
||
else
|
||
{
|
||
const wxColour b0 = GetBackgroundColour();
|
||
const wxColour b1 = ModulateColour(b0, -10);
|
||
const wxColour b2 = ModulateColour(b0, +70);
|
||
wxCoord cw, ch; dc.GetSize(&cw, &ch);
|
||
#if wxCHECK_VERSION(2,8,12)
|
||
// Nuovo modo: effetto acqua in stile TwxOutlookBar
|
||
const wxColour b3 = ModulateColour(b1, +20);
|
||
const int delta = 2*ch/5;
|
||
wxRect r1(0,0,cw,ch), r2(0,0,cw,ch);
|
||
r1.height = delta;
|
||
r2.y += delta; r2.height -= delta;
|
||
dc.GradientFillLinear(r1, b3, b3, wxDOWN);
|
||
dc.GradientFillLinear(r2, b1, b2, wxDOWN);
|
||
#else
|
||
// Vecchio modo: gradiente classico
|
||
dc.GradientFillLinear(wxRect(0,0,cw,ch),b1,b2,wxSOUTH);
|
||
#endif
|
||
}
|
||
}
|
||
|
||
bool TwxToolBar::SetBackgroundColour(const wxColour& colour)
|
||
{
|
||
const bool ok = TwxToolBarBase::SetBackgroundColour(colour);
|
||
if (ok) // Se cambio lo sfondo della toolbar devo aggiornare anche quello del gripper
|
||
{
|
||
wxAuiDockArt* pArtist = FindArtist(this);
|
||
if (pArtist != NULL)
|
||
pArtist->SetColor(wxAUI_DOCKART_GRIPPER_COLOUR, colour);
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
bool TwxToolBar::SetForegroundColour(const wxColour& colour)
|
||
{
|
||
const bool ok = TwxToolBarBase::SetForegroundColour(colour);
|
||
if (ok) // Se cambio lo sfondo della toolbar devo aggiornare anche quello del gripper
|
||
{
|
||
wxAuiDockArt* pArtist = FindArtist(this);
|
||
if (pArtist != NULL)
|
||
pArtist->SetColor(wxAUI_DOCKART_ACTIVE_CAPTION_TEXT_COLOUR, colour);
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
|
||
void TwxToolBar::SetBackgroundTexture(XVT_IMAGE xvt_img)
|
||
{
|
||
if (xvt_img != NULL)
|
||
{
|
||
const wxImage& img = *(wxImage*)xvt_img;
|
||
wxColour mean, dark, light;
|
||
Image2Colors(img, mean, dark, light);
|
||
SetBackgroundColour(mean);
|
||
|
||
m_texture = wxBitmap(img);
|
||
}
|
||
else
|
||
m_texture = wxNullBitmap;
|
||
}
|
||
|
||
TwxToolBar::TwxToolBar(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style)
|
||
: TwxToolBarBase(parent, id, pos, size, style)
|
||
{ }
|
||
|
||
static TwxToolBar* Win2Bar(WINDOW win)
|
||
{
|
||
wxASSERT(win != NULL_WIN);
|
||
return wxDynamicCast((wxObject*)win, TwxToolBar);
|
||
}
|
||
|
||
BOOLEAN xvt_toolbar_add_control(WINDOW win, int cid, TOOL_TYPE type, const char *title,
|
||
int ico, int WXUNUSED(cust_width), int idx)
|
||
{
|
||
BOOLEAN ok = FALSE;
|
||
TwxToolBar* ptb = Win2Bar(win);
|
||
if (ptb != NULL)
|
||
{
|
||
TwxToolBar& tb = *ptb;
|
||
switch (type)
|
||
{
|
||
case TOOL_SEPARATOR:
|
||
#ifdef wxAuiToolBar
|
||
tb.AddSeparator();
|
||
ok = idx < 0;
|
||
#else
|
||
if (idx < 0)
|
||
ok = tb.AddSeparator() != NULL;
|
||
else
|
||
ok = tb.InsertSeparator(idx) != NULL;
|
||
#endif
|
||
break;
|
||
default:
|
||
{
|
||
const wxBitmap bmp = xvtart_GetToolResource(ico, tb.GetToolBitmapSize().y);
|
||
wxString cap, tip;
|
||
wxChar acc = 0;
|
||
for (const char* t = title; *t; t++)
|
||
{
|
||
if (*t == '~' || *t == '&')
|
||
{
|
||
cap << '&';
|
||
acc = toupper(*(t+1));
|
||
}
|
||
else
|
||
{
|
||
cap << *t;
|
||
tip << *t;
|
||
}
|
||
}
|
||
if (acc > '\0')
|
||
{
|
||
if (acc >= 'A' && acc <= 'Z')
|
||
tip << "\n(Alt+" << acc << ")";
|
||
}
|
||
else
|
||
{
|
||
switch (ico) // Gestione bottoni speciali
|
||
{
|
||
case 102: tip << "\n(Esc)"; break;
|
||
case 114: tip << "\n(Alt+F4)"; break;
|
||
case 162: tip << "\n(F2)"; break;
|
||
case 163: tip << "\n(F1)"; break;
|
||
default: break;
|
||
}
|
||
}
|
||
|
||
#ifdef wxAuiToolBar
|
||
tb.AddTool(cid, cap, bmp, wxNullBitmap, wxItemKind(type), tip, tip, NULL);
|
||
ok = idx < 0;
|
||
#else
|
||
if (idx < 0)
|
||
ok = tb.AddTool(cid, cap, bmp, wxNullBitmap, wxItemKind(type), tip) != NULL;
|
||
else
|
||
ok = tb.InsertTool(idx, cid, cap, bmp, wxNullBitmap, wxItemKind(type), tip) != NULL;
|
||
#endif
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
WINDOW xvt_toolbar_create(int cid, int left, int top, int right, int bottom, long nFlags, WINDOW parent)
|
||
{
|
||
#ifdef wxAuiToolBar
|
||
long nStyle = wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_GRIPPER;
|
||
if (nFlags & CTL_FLAG_PASSWORD)
|
||
nStyle |= wxAUI_TB_TEXT;
|
||
|
||
const wxPoint ptPos(left, top);
|
||
wxSize szSize(right-left, bottom-top);
|
||
|
||
int nIcoSize = 24;
|
||
if (bottom > 0)
|
||
{
|
||
nIcoSize = RoundToIcon(szSize.y);
|
||
}
|
||
else
|
||
{
|
||
nStyle |= wxAUI_TB_VERTICAL;
|
||
nIcoSize = RoundToIcon(szSize.x);
|
||
}
|
||
#else
|
||
long nStyle = wxNO_BORDER | wxTB_NODIVIDER;
|
||
if (nFlags & CTL_FLAG_PASSWORD)
|
||
nStyle |= wxTB_TEXT | wxTB_FLAT;
|
||
|
||
const wxPoint ptPos(left, top);
|
||
wxSize szSize(right-left, bottom-top);
|
||
|
||
int nIcoSize = 24;
|
||
if (bottom > 0)
|
||
{
|
||
nStyle |= wxTB_HORIZONTAL;
|
||
nIcoSize = RoundToIcon(szSize.y);
|
||
}
|
||
else
|
||
{
|
||
nStyle |= wxTB_VERTICAL;
|
||
nIcoSize = RoundToIcon(szSize.x);
|
||
}
|
||
#endif
|
||
|
||
wxWindow* pParent = wxStaticCast((wxObject*)parent, wxWindow);
|
||
TwxToolBar* tb = new TwxToolBar(pParent, cid, ptPos, wxDefaultSize, nStyle);
|
||
tb->SetToolBitmapSize(wxSize(nIcoSize, nIcoSize));
|
||
|
||
return (WINDOW)tb;
|
||
}
|
||
|
||
void xvt_toolbar_enable_control(WINDOW win, int cid, BOOLEAN on)
|
||
{
|
||
TwxToolBar* ptb = Win2Bar(win);
|
||
if (ptb != NULL && cid > 0)
|
||
ptb->EnableTool(cid, on != 0);
|
||
}
|
||
|
||
BOOLEAN xvt_toolbar_set_last_tool(WINDOW win, int id)
|
||
{
|
||
BOOLEAN bMoved = FALSE;
|
||
TwxToolBar* ptb = Win2Bar(win);
|
||
if (ptb != NULL) // Is a valid toolbar?
|
||
{
|
||
const int pos = ptb->GetToolPos(id);
|
||
if (pos >= 0)
|
||
{
|
||
#ifdef wxAuiToolBar
|
||
// TBI
|
||
#else
|
||
const int nCount = ptb->GetToolsCount();
|
||
if (pos < nCount-1)
|
||
{
|
||
wxToolBarToolBase* tool = ptb->RemoveTool(id);
|
||
ptb->InsertTool(nCount-1, tool);
|
||
}
|
||
bMoved = TRUE;
|
||
#endif
|
||
}
|
||
}
|
||
return bMoved;
|
||
}
|
||
|
||
void xvt_toolbar_realize(WINDOW win)
|
||
{
|
||
TwxToolBar* ptb = Win2Bar(win);
|
||
if (ptb != NULL) // Is a valid toolbar?
|
||
{
|
||
ptb->Realize(); // Update tools
|
||
wxAuiPaneInfo* pi = LockPane(win);
|
||
if (pi != NULL)
|
||
{
|
||
const wxSize szBar = ptb->GetSize();
|
||
if (pi->min_size.x < szBar.x || pi->min_size.y < szBar.y)
|
||
{
|
||
pi->MinSize(szBar);
|
||
pi->BestSize(szBar);
|
||
UnlockPane(win);
|
||
}
|
||
}
|
||
|
||
// Iucunde repetita juvant: forzo il colore del gripper che viene spesso dimenticato
|
||
wxAuiDockArt* pArtist = FindArtist(ptb);
|
||
if (pArtist != NULL)
|
||
pArtist->SetColor(wxAUI_DOCKART_GRIPPER_COLOUR, ptb->GetBackgroundColour());
|
||
}
|
||
}
|
||
|
||
void xvt_toolbar_show_control(WINDOW win, int cid, BOOLEAN on)
|
||
{
|
||
if (win != NULL_WIN && cid > 0)
|
||
{
|
||
wxASSERT(on);// Per ora non so come si faccia
|
||
/*
|
||
TwxToolBar* ptb = Win2Bar(win);
|
||
if (ptb != NULL && cid > 0)
|
||
{
|
||
// ????
|
||
}
|
||
*/
|
||
}
|
||
}
|
||
|
||
void xvt_dwin_draw_tool(WINDOW win, int x, int y, int rid, int size)
|
||
{
|
||
const wxBitmap bmp = xvtart_GetToolResource(rid, size);
|
||
if (bmp.IsOk())
|
||
{
|
||
wxDC& dc = GetTDCMapper().GetDC(win);
|
||
dc.DrawBitmap(bmp, x, y);
|
||
}
|
||
}
|
||
|
||
void xvt_ctl_set_texture(WINDOW win, XVT_IMAGE xvt_img)
|
||
{
|
||
TwxToolBar* w = wxDynamicCast((wxObject*)win, TwxToolBar);
|
||
if (w != NULL)
|
||
w->SetBackgroundTexture(xvt_img);
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// wxPropertyGrid
|
||
///////////////////////////////////////////////////////////
|
||
|
||
#include <wx/propgrid/advprops.h>
|
||
|
||
BEGIN_EVENT_TABLE(TwxPropertyGrid, wxPropertyGrid)
|
||
EVT_PG_CHANGED(wxID_ANY, TwxPropertyGrid::OnPropertyChanged)
|
||
END_EVENT_TABLE();
|
||
|
||
void TwxPropertyGrid::SetColors(const XVT_COLOR_COMPONENT* colors)
|
||
{
|
||
for (int i = 0; colors[i].type; i++)
|
||
{
|
||
CAST_COLOR(colors[i].color, rgb);
|
||
switch(colors[i].type)
|
||
{
|
||
case XVT_COLOR_BACKGROUND : SetCellBackgroundColour(rgb); break;
|
||
case XVT_COLOR_FOREGROUND : SetCellTextColour(rgb); break;
|
||
case XVT_COLOR_HIGHLIGHT : SetSelectionBackground(rgb); break;
|
||
case XVT_COLOR_SELECT : SetSelectionForeground(rgb); break;
|
||
case XVT_COLOR_BLEND : SetCaptionBackgroundColour(rgb); SetMarginColour(rgb); break;
|
||
case XVT_COLOR_TROUGH : SetEmptySpaceColour(rgb); break;
|
||
case XVT_COLOR_CAPTIONTEXT: SetCaptionForegroundColour(rgb); break;
|
||
default : break;
|
||
}
|
||
}
|
||
}
|
||
|
||
void TwxPropertyGrid::OnPropertyChanged(wxPropertyGridEvent& evt)
|
||
{
|
||
TwxWindow* win = wxDynamicCast(GetParent(), TwxWindow);
|
||
if (win != NULL && !IsFrozen())
|
||
{
|
||
XVT_EVENT e(E_CONTROL);
|
||
e.v.ctl.id = evt.GetId();
|
||
e.v.ctl.ci.v.treeview.sgl_click = TRUE;
|
||
e.v.ctl.ci.v.treeview.node = evt.GetProperty();
|
||
e.v.ctl.ci.type = WC_PROPGRID;
|
||
e.v.ctl.ci.win = WINDOW(this);
|
||
win->DoXvtEvent(e);
|
||
}
|
||
}
|
||
|
||
TwxPropertyGrid::TwxPropertyGrid(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style)
|
||
: wxPropertyGrid(parent, id, pos, size, style)
|
||
{ }
|
||
|
||
static BOOLEAN xvt_prop_freeze(WINDOW win, BOOLEAN on)
|
||
{
|
||
wxPropertyGrid* pg = wxDynamicCast((wxObject*)win, wxPropertyGrid);
|
||
const BOOLEAN ok = pg != NULL && on != BOOLEAN(pg->IsFrozen());
|
||
if (ok)
|
||
{
|
||
if (on)
|
||
pg->Freeze();
|
||
else
|
||
{
|
||
pg->Thaw();
|
||
pg->Refresh();
|
||
}
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
BOOLEAN xvt_prop_restart(WINDOW win)
|
||
{ return xvt_prop_freeze(win, FALSE); }
|
||
|
||
BOOLEAN xvt_prop_suspend(WINDOW win)
|
||
{ return xvt_prop_freeze(win, TRUE); }
|
||
|
||
static wxColour STR2COLOUR(const char* value)
|
||
{
|
||
wxColour col;
|
||
|
||
if (value && *value)
|
||
{
|
||
if (*value == '(')
|
||
value++;
|
||
if (isdigit(*value))
|
||
{
|
||
int r, g, b;
|
||
const int n = sscanf(value, "%d,%d,%d", &r, &g, &b);
|
||
if (n == 3)
|
||
col = wxColour(r, g, b);
|
||
else
|
||
{
|
||
CAST_COLOR(r, w); // NON usare wxColour(r) in quanto si aspetta un numero in formato BGR
|
||
col = w;
|
||
}
|
||
}
|
||
else
|
||
col = wxColour(value); // Black, White, Yellow, ...
|
||
}
|
||
return col;
|
||
}
|
||
|
||
BOOLEAN xvt_prop_set_data(WINDOW win, XVT_TREEVIEW_NODE node, const char* value)
|
||
{
|
||
wxPropertyGrid* pg = wxDynamicCast((wxObject*)win, wxPropertyGrid);
|
||
if (pg != NULL)
|
||
{
|
||
wxPGProperty* pgp = wxDynamicCast((wxObject*)node, wxPGProperty);
|
||
if (pgp != NULL)
|
||
{
|
||
const wxString strType = pgp->GetType();
|
||
if (strType == "wxColour")
|
||
{
|
||
wxColourPropertyValue val(STR2COLOUR(value));
|
||
wxVariant& var = pgp->GetValueRef();
|
||
var = ((wxColourProperty*)pgp)->DoTranslateVal(val);
|
||
}
|
||
else
|
||
{
|
||
if (strType == "long" || strType == "int")
|
||
pgp->SetValue(atol(value)); else
|
||
if (strType == "bool")
|
||
pgp->SetValue(*value > '0' && strchr("1TXY", *value) != NULL);
|
||
else
|
||
pgp->SetValue(value);
|
||
}
|
||
return TRUE;
|
||
}
|
||
}
|
||
return FALSE;
|
||
}
|
||
|
||
XVT_TREEVIEW_NODE xvt_prop_add(WINDOW win, const char* type, const char* name, const char* value, const char* label)
|
||
{
|
||
wxPropertyGrid* pg = wxDynamicCast((wxObject*)win, wxPropertyGrid);
|
||
if (pg != NULL)
|
||
{
|
||
wxPGProperty* pgp = pg->GetPropertyByName(name);
|
||
if (pgp == NULL)
|
||
{
|
||
const wxString strLabel = (label && *label) ? label : name;
|
||
if (type && *type > ' ')
|
||
{
|
||
switch (toupper(*type))
|
||
{
|
||
case 'B':
|
||
pgp = new wxBoolProperty(strLabel, name, *value > '0' && strchr("1TXY", *value) != NULL);
|
||
pgp->SetAttribute(wxString("UseCheckbox"), true);
|
||
break;
|
||
case 'C':
|
||
pgp = new wxColourProperty(strLabel, name, STR2COLOUR(value));
|
||
break;
|
||
case 'I':
|
||
case 'L':
|
||
pgp = new wxIntProperty(strLabel, name, atol(value));
|
||
break;
|
||
default :
|
||
pgp = new wxStringProperty(strLabel, name, value);
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
pgp = new wxPropertyCategory(strLabel, name);
|
||
pg->Append(pgp);
|
||
}
|
||
else
|
||
xvt_prop_set_data(win, pgp, value);
|
||
return pgp;
|
||
}
|
||
return NULL;
|
||
}
|
||
|
||
XVT_TREEVIEW_NODE xvt_prop_current(WINDOW win)
|
||
{
|
||
XVT_TREEVIEW_NODE node = NULL;
|
||
wxPropertyGrid* pg = wxDynamicCast((wxObject*)win, wxPropertyGrid);
|
||
if (pg != NULL)
|
||
node = pg->GetSelection();
|
||
return node;
|
||
}
|
||
|
||
XVT_TREEVIEW_NODE xvt_prop_find(WINDOW win, const char* name)
|
||
{
|
||
XVT_TREEVIEW_NODE node = NULL;
|
||
wxPropertyGrid* pg = wxDynamicCast((wxObject*)win, wxPropertyGrid);
|
||
if (pg != NULL)
|
||
node = pg->GetPropertyByName(name);
|
||
return node;
|
||
}
|
||
|
||
void xvt_prop_fit_columns(WINDOW win)
|
||
{
|
||
wxPropertyGrid* pg = wxDynamicCast((wxObject*)win, wxPropertyGrid);
|
||
if (pg != NULL)
|
||
pg->FitColumns();
|
||
}
|
||
|
||
BOOLEAN xvt_prop_remove(WINDOW win, XVT_TREEVIEW_NODE node)
|
||
{
|
||
wxPropertyGrid* pg = wxDynamicCast((wxObject*)win, wxPropertyGrid);
|
||
if (pg != NULL)
|
||
{
|
||
wxPGProperty* pgp = wxDynamicCast((wxObject*)node, wxPGProperty);
|
||
if (pgp != NULL)
|
||
{
|
||
pg->DeleteProperty(pgp->GetId());
|
||
return TRUE;
|
||
}
|
||
}
|
||
return FALSE;
|
||
}
|
||
|
||
int xvt_prop_get_string(WINDOW win, XVT_TREEVIEW_NODE node, char* label, int maxlen)
|
||
{
|
||
int len = -1;
|
||
wxPropertyGrid* pg = wxDynamicCast((wxObject*)win, wxPropertyGrid);
|
||
if (pg != NULL)
|
||
{
|
||
const wxPGProperty* pgp = wxDynamicCast((wxObject*)node, wxPGProperty);
|
||
if (pgp != NULL)
|
||
{
|
||
const wxString& str = pgp->GetLabel();
|
||
if (label && maxlen > 0)
|
||
{
|
||
wxStrncpy(label, str, maxlen);
|
||
label[maxlen-1] = '\0';
|
||
}
|
||
len = str.Len();
|
||
}
|
||
}
|
||
return len;
|
||
}
|
||
|
||
int xvt_prop_get_type(WINDOW win, XVT_TREEVIEW_NODE node, char* type, int maxlen)
|
||
{
|
||
int len = 0;
|
||
wxPropertyGrid* pg = wxDynamicCast((wxObject*)win, wxPropertyGrid);
|
||
if (pg != NULL)
|
||
{
|
||
const wxPGProperty* pgp = wxDynamicCast((wxObject*)node, wxPGProperty);
|
||
if (pgp != NULL)
|
||
{
|
||
wxString strType = pgp->GetType();
|
||
if (strType == "wxColour")
|
||
strType = "color";
|
||
wxStrncpy(type, strType, maxlen);
|
||
len = strType.Len();
|
||
}
|
||
}
|
||
return len;
|
||
}
|
||
|
||
int xvt_prop_get_data(WINDOW win, XVT_TREEVIEW_NODE node, char* value, int maxlen)
|
||
{
|
||
int len = -1;
|
||
wxPropertyGrid* pg = wxDynamicCast((wxObject*)win, wxPropertyGrid);
|
||
if (pg != NULL)
|
||
{
|
||
const wxPGProperty* pgp = wxDynamicCast((wxObject*)node, wxPGProperty);
|
||
if (pgp != NULL)
|
||
{
|
||
wxString str = pgp->GetValueAsString();
|
||
wxString strType = pgp->GetType();
|
||
|
||
if (strType == "wxColour")
|
||
{
|
||
strType = "color";
|
||
str.RemoveLast(1); // Toglie la )
|
||
str.Remove(0, 1); // Toglie la (
|
||
}
|
||
len = str.Len();
|
||
if (value != NULL && maxlen > 0)
|
||
{
|
||
wxStrncpy(value, str, maxlen);
|
||
value[maxlen-1] = '\0';
|
||
}
|
||
}
|
||
}
|
||
return len;
|
||
}
|
||
|
||
static BOOLEAN xvt_for_each_property(WINDOW pg, const wxPGProperty* prop, PROP_CALLBACK pcb, void* jolly)
|
||
{
|
||
BOOLEAN ok = prop != NULL && pcb != NULL;
|
||
if (ok && !prop->IsRoot())
|
||
ok = pcb(pg, (XVT_TREEVIEW_NODE)prop, jolly);
|
||
if (ok)
|
||
{
|
||
const int nc = prop->GetChildCount();
|
||
for (int c = 0; c < nc && ok; c++)
|
||
ok = xvt_for_each_property(pg, prop->Item(c), pcb, jolly);
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
BOOLEAN xvt_prop_for_each(WINDOW win, PROP_CALLBACK pcb, void* jolly)
|
||
{
|
||
BOOLEAN ok = FALSE;
|
||
wxPropertyGrid* pg = wxDynamicCast((wxObject*)win, wxPropertyGrid);
|
||
if (pg != NULL)
|
||
ok = xvt_for_each_property(win, pg->GetRoot(), pcb, jolly);
|
||
return ok;
|
||
}
|
||
|
||
BOOLEAN xvt_prop_set_read_only(WINDOW win, XVT_TREEVIEW_NODE node, BOOLEAN ro)
|
||
{
|
||
wxPropertyGrid* pg = wxDynamicCast((wxObject*)win, wxPropertyGrid);
|
||
if (pg != NULL)
|
||
{
|
||
wxPGProperty* pgp = wxDynamicCast((wxObject*)node, wxPGProperty);
|
||
if (pgp == NULL)
|
||
pgp = pg->GetRoot();
|
||
pgp->SetFlagRecursively(wxPG_PROP_DISABLED, ro != 0);
|
||
}
|
||
return pg != NULL;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TwxTreeListCtrl
|
||
///////////////////////////////////////////////////////////
|
||
|
||
BEGIN_EVENT_TABLE(TwxTreeListCtrl, wxTreeListCtrl)
|
||
EVT_TREE_ITEM_EXPANDING(wxID_ANY, TwxTreeListCtrl::OnExpanding)
|
||
EVT_TREE_ITEM_EXPANDED (wxID_ANY, TwxTreeListCtrl::OnExpanded)
|
||
EVT_TREE_ITEM_COLLAPSED(wxID_ANY, TwxTreeListCtrl::OnCollapsed)
|
||
EVT_TREE_SEL_CHANGED (wxID_ANY, TwxTreeListCtrl::OnSelChanged)
|
||
END_EVENT_TABLE();
|
||
|
||
int TwxTreeListCtrl::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!
|
||
}
|
||
else
|
||
{
|
||
int old_w, old_h; il->GetSize(0, old_w, old_h);
|
||
const int new_w = img.GetWidth(), new_h = img.GetHeight();
|
||
if (new_w > old_w) // L'immagine nuova e' troppo grande?
|
||
{
|
||
const int old_ratio = old_w * 100 / old_h;
|
||
const int new_ratio = new_w * 100 / new_h;
|
||
const int old_count = il->GetImageCount();
|
||
wxImageList* nil = new wxImageList;
|
||
nil->Create(new_w, new_h, true, 3*old_count/2);
|
||
for (int k = 0; k < old_count; k++)
|
||
{
|
||
wxImage old = il->GetBitmap(k).ConvertToImage();
|
||
if (old_ratio == new_ratio)
|
||
old.Rescale(new_w, new_h, wxIMAGE_QUALITY_HIGH);
|
||
else
|
||
old.Resize(wxSize(new_w, new_h), wxPoint((new_w-old_w)/2, (new_h-old_h)/2));
|
||
nil->Add(old);
|
||
}
|
||
AssignImageList(il = nil);
|
||
}
|
||
}
|
||
|
||
if (!img.HasMask())
|
||
{
|
||
wxImage& trans = (wxImage&)img;
|
||
const int r = img.GetRed(0,0);
|
||
const int g = img.GetGreen(0,0);
|
||
const int b = img.GetBlue(0,0);
|
||
trans.SetMask();
|
||
trans.SetMaskColour(r, g, b);
|
||
}
|
||
const wxBitmap bmp(img);
|
||
i = il->Add(bmp);
|
||
m_img[xvt_img] = i+1; // Memorizzo indice+1
|
||
}
|
||
if (i < 0)
|
||
SORRY_BOX();
|
||
}
|
||
return i;
|
||
}
|
||
|
||
void TwxTreeListCtrl::OnExpanding(wxTreeEvent& evt)
|
||
{
|
||
const wxTreeItemId id = evt.GetItem();
|
||
XVT_EVENT e(E_CONTROL);
|
||
e.v.ctl.id = evt.GetId();
|
||
e.v.ctl.ci.type = WC_TREELIST;
|
||
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 = wxStaticCast(GetParent(), TwxWindow);
|
||
win->DoXvtEvent(e);
|
||
if (GetChildrenCount(id) == 0) // Allora e' proprio vero ...
|
||
SetItemHasChildren(id, false);
|
||
}
|
||
|
||
void TwxTreeListCtrl::OnExpanded(wxTreeEvent& WXUNUSED(evt))
|
||
{ Refresh(false); } // Non dovrebbe servire ma ...
|
||
|
||
void TwxTreeListCtrl::OnCollapsed(wxTreeEvent& WXUNUSED(evt))
|
||
{ Refresh(false); } // Non dovrebbe servire ma ...
|
||
|
||
void TwxTreeListCtrl::OnSelChanged(wxTreeEvent& evt)
|
||
{
|
||
if (!m_nFrozen)
|
||
{
|
||
Suspend();
|
||
XVT_EVENT e(E_CONTROL);
|
||
e.v.ctl.id = evt.GetId();
|
||
e.v.ctl.ci.type = WC_TREELIST;
|
||
e.v.ctl.ci.win = WINDOW(this);
|
||
e.v.ctl.ci.v.treeview.node = evt.GetItem().m_pItem;
|
||
e.v.ctl.ci.v.treeview.sgl_click = TRUE;
|
||
TwxWindow* win = wxStaticCast(GetParent(), TwxWindow);
|
||
win->DoXvtEvent(e);
|
||
Resume();
|
||
}
|
||
Refresh(false); // Non dovrebbe servire ma ...
|
||
}
|
||
|
||
void TwxTreeListCtrl::Enable(const wxTreeItemId& id, bool on)
|
||
{ SetItemTextColour(id, on ? m_clrSelFore : m_clrDisFore); }
|
||
|
||
void TwxTreeListCtrl::Suspend()
|
||
{ m_nFrozen++; }
|
||
|
||
void TwxTreeListCtrl::Resume()
|
||
{
|
||
wxASSERT(m_nFrozen > 0);
|
||
if (m_nFrozen > 0)
|
||
m_nFrozen--;
|
||
}
|
||
|
||
void TwxTreeListCtrl::SetColors(const XVT_COLOR_COMPONENT* colors)
|
||
{
|
||
for (int i = 0; colors[i].type; i++)
|
||
{
|
||
CAST_COLOR(colors[i].color, rgb);
|
||
switch(colors[i].type)
|
||
{
|
||
case XVT_COLOR_BACKGROUND: SetOwnBackgroundColour(rgb); break;
|
||
case XVT_COLOR_FOREGROUND: SetOwnForegroundColour(rgb); break;
|
||
case XVT_COLOR_HIGHLIGHT : m_clrSelBack = rgb; break;
|
||
case XVT_COLOR_SELECT : m_clrSelFore = rgb; break;
|
||
case XVT_COLOR_TROUGH : m_clrDisFore = rgb; break;
|
||
default : break;
|
||
}
|
||
}
|
||
}
|
||
|
||
void TwxTreeListCtrl::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);
|
||
}
|
||
}
|
||
}
|
||
|
||
TwxTreeListCtrl::TwxTreeListCtrl(wxWindow *parent, wxWindowID id,
|
||
const wxPoint& pos, const wxSize& size, bool multisel)
|
||
: wxTreeListCtrl(parent, id, pos, size,
|
||
wxTR_HAS_BUTTONS|wxTR_HIDE_ROOT|wxTR_ROW_LINES|wxTR_COLUMN_LINES|(multisel ? wxTR_MULTIPLE : wxTR_SINGLE)),
|
||
m_nFrozen(0)
|
||
{
|
||
AddColumn(wxEmptyString, size.x);
|
||
AddRoot("Root");
|
||
SetIndent(GetIndent()/2);
|
||
}
|
||
|
||
#define CAST_TREELIST(win, tv) TwxTreeListCtrl& tv = *wxStaticCast((wxObject*)win, TwxTreeListCtrl);
|
||
|
||
WINDOW xvt_treelist_create(WINDOW parent_win,
|
||
RCT * rct_p, char * title, long ctl_flags,
|
||
long app_data, int ctl_id, XVT_IMAGE WXUNUSED(item_image),
|
||
XVT_IMAGE WXUNUSED(collapsed_image), XVT_IMAGE WXUNUSED(expanded_image),
|
||
long WXUNUSED(attrs), int line_height)
|
||
{
|
||
wxASSERT(parent_win != NULL_WIN);
|
||
// La xvt_ctl_create_def accetta un array di controlli da inizializzare,
|
||
// per cui le passero' un elemento valido ed uno nullo che funga da terminatore
|
||
WIN_DEF win_def[2]; memset(win_def, 0, sizeof(WIN_DEF));
|
||
win_def->wtype = WC_TREELIST;
|
||
if (xvt_rect_is_empty(rct_p))
|
||
xvt_vobj_get_client_rect(parent_win, &win_def->rct);
|
||
else
|
||
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);
|
||
|
||
if (win != NULL_WIN && line_height > 12)
|
||
{
|
||
CAST_TREELIST(win, tv);
|
||
tv.SetLineSpacing(line_height);
|
||
}
|
||
return win;
|
||
}
|
||
|
||
XVT_TREEVIEW_NODE xvt_treelist_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 WXUNUSED(callback), const char* data)
|
||
{
|
||
XVT_TREEVIEW_NODE node = NULL;
|
||
if (win != NULL_WIN)
|
||
{
|
||
CAST_TREELIST(win, tv);
|
||
TwxTreeItemData* pData = new TwxTreeItemData;
|
||
pData->m_strData = data;
|
||
wxTreeItemId pa(parent);
|
||
if (!pa.IsOk())
|
||
pa = tv.GetRootItem();
|
||
|
||
wxStringTokenizer tok(string, "\t", wxTOKEN_RET_EMPTY);
|
||
|
||
wxTreeItemId id = tv.AppendItem(pa, tok.GetNextToken(), -1, -1, pData);
|
||
if (id.IsOk())
|
||
{
|
||
const int nColumns = tv.GetColumnCount();
|
||
for (int c = 1; c < nColumns && tok.HasMoreTokens(); c++)
|
||
tv.SetItemText(id, c, tok.GetNextToken());
|
||
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_treelist_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_TREELIST(win, tv);
|
||
wxTreeItemId parent(parent_node);
|
||
if (!parent.IsOk())
|
||
parent = tv.GetRootItem();
|
||
|
||
if (parent.IsOk() && 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_treelist_get_node_data(WINDOW win, XVT_TREEVIEW_NODE node)
|
||
{
|
||
const char* data = NULL;
|
||
if (win != NULL_WIN && node != NULL)
|
||
{
|
||
CAST_TREELIST(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_treelist_destroy_node(WINDOW win, XVT_TREEVIEW_NODE node)
|
||
{
|
||
if (win != NULL_WIN && node != NULL)
|
||
{
|
||
CAST_TREELIST(win, tv);
|
||
wxTreeItemId id(node);
|
||
tv.Delete(id);
|
||
}
|
||
}
|
||
|
||
BOOLEAN xvt_treelist_enable_node(WINDOW win, XVT_TREEVIEW_NODE node, BOOLEAN on)
|
||
{
|
||
BOOLEAN ok = (win != NULL_WIN) && (node != NULL);
|
||
if (ok)
|
||
{
|
||
CAST_TREELIST(win, tv);
|
||
wxTreeItemId id(node);
|
||
tv.Enable(id, on != FALSE);
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
BOOLEAN xvt_treelist_expand_node(WINDOW win, XVT_TREEVIEW_NODE node, BOOLEAN recurse)
|
||
{
|
||
BOOLEAN ok = (win != NULL_WIN) && (node != NULL);
|
||
if (ok)
|
||
{
|
||
CAST_TREELIST(win, tv);
|
||
tv.Suspend();
|
||
const wxTreeItemId id(node);
|
||
if (recurse)
|
||
tv.ExpandAll(id);
|
||
else
|
||
tv.Expand(id);
|
||
tv.Resume();
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
XVT_TREEVIEW_NODE xvt_treelist_get_root_node(WINDOW win)
|
||
{
|
||
XVT_TREEVIEW_NODE pRoot = NULL;
|
||
if (win != NULL_WIN)
|
||
{
|
||
CAST_TREELIST(win, tv);
|
||
const wxTreeItemId id = tv.GetRootItem();
|
||
pRoot = id.m_pItem;
|
||
}
|
||
return pRoot;
|
||
}
|
||
|
||
XVT_TREEVIEW_NODE xvt_treelist_get_selected_node(WINDOW win)
|
||
{
|
||
CAST_TREELIST(win, tv);
|
||
const wxTreeItemId id = tv.GetSelection();
|
||
return id.m_pItem;
|
||
}
|
||
|
||
SLIST xvt_treelist_get_selected_list(WINDOW win)
|
||
{
|
||
SLIST list = NULL;
|
||
CAST_TREELIST(win, tv);
|
||
wxArrayTreeItemIds selections;
|
||
const size_t nSel = tv.GetSelections(selections);
|
||
if (nSel > 0)
|
||
{
|
||
list = xvt_slist_create();
|
||
for (size_t i = 0; i < nSel; i++)
|
||
{
|
||
const wxTreeItemId& id = selections[i];
|
||
const TwxTreeItemData* pData = (const TwxTreeItemData*)tv.GetItemData(id);
|
||
if (pData != NULL)
|
||
xvt_slist_add_at_elt(list, NULL, pData->m_strData, (long)id.m_pItem);
|
||
else
|
||
xvt_slist_add_at_elt(list, NULL, "", (long)id.m_pItem);
|
||
}
|
||
}
|
||
return list;
|
||
}
|
||
|
||
|
||
BOOLEAN xvt_treelist_remove_child_node(WINDOW win, XVT_TREEVIEW_NODE node)
|
||
{
|
||
BOOLEAN ok = (win != NULL_WIN) && (node != NULL);
|
||
if (ok)
|
||
{
|
||
CAST_TREELIST(win, tv);
|
||
const wxTreeItemId id(node);
|
||
if (id == tv.GetRootItem())
|
||
tv.DeleteChildren(id);
|
||
else
|
||
{
|
||
tv.Suspend();
|
||
tv.Delete(id);
|
||
tv.Resume();
|
||
}
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
BOOLEAN xvt_treelist_remove_node_children(WINDOW win, XVT_TREEVIEW_NODE node)
|
||
{
|
||
BOOLEAN ok = FALSE;
|
||
if (win != NULL_WIN)
|
||
{
|
||
CAST_TREELIST(win, tv);
|
||
tv.Suspend();
|
||
wxTreeItemId id(node);
|
||
if (!id.IsOk())
|
||
id = tv.GetRootItem();
|
||
tv.DeleteChildren(id);
|
||
tv.Resume();
|
||
ok = TRUE;
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
void xvt_treelist_resume(WINDOW win)
|
||
{
|
||
CAST_TREELIST(win, tv);
|
||
tv.Resume();
|
||
}
|
||
|
||
void xvt_treelist_select_node(WINDOW win, XVT_TREEVIEW_NODE node, BOOLEAN sel)
|
||
{
|
||
if (win != NULL_WIN && node != NULL)
|
||
{
|
||
CAST_TREELIST(win, tv);
|
||
const wxTreeItemId id(node);
|
||
if (sel)
|
||
{
|
||
tv.Suspend();
|
||
tv.SelectItem(id, id, true);
|
||
tv.EnsureVisible(id);
|
||
tv.Resume();
|
||
}
|
||
else
|
||
tv.UnselectAll();
|
||
}
|
||
}
|
||
|
||
void xvt_treelist_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_TREELIST(win, tv);
|
||
const wxTreeItemId id(node);
|
||
tv.SetNodeImages(id, item_image, collapsed_image, expanded_image);
|
||
}
|
||
}
|
||
|
||
void xvt_treelist_set_node_string(WINDOW win, XVT_TREEVIEW_NODE node, const char* text)
|
||
{
|
||
if (win != NULL_WIN)
|
||
{
|
||
CAST_TREELIST(win, tv);
|
||
const int cc = tv.GetColumnCount();
|
||
wxStringTokenizer tok(text, "\t", wxTOKEN_RET_EMPTY);
|
||
if (node != NULL)
|
||
{
|
||
const wxTreeItemId id(node);
|
||
for (int c = 0; c < cc && tok.HasMoreTokens(); c++)
|
||
tv.SetItemText(id, c, tok.GetNextToken());
|
||
}
|
||
else
|
||
{
|
||
for (int c = 0; tok.HasMoreTokens(); c++)
|
||
{
|
||
wxString str = tok.GetNextToken();
|
||
int width = 0;
|
||
bool bRightAlign = false;
|
||
const int a = str.Find('@');
|
||
if (a > 0)
|
||
{
|
||
width = 10*wxAtoi(str.Mid(a+1));
|
||
bRightAlign = str.Find('R', true) > a;
|
||
str.Truncate(a);
|
||
}
|
||
else
|
||
width = 10*str.Len();
|
||
if (c >= cc)
|
||
tv.AddColumn(str, width, bRightAlign ? wxALIGN_RIGHT : wxALIGN_LEFT);
|
||
else
|
||
{
|
||
tv.SetColumnText(c, str);
|
||
const int oldw = tv.GetColumnWidth(c);
|
||
if (width < 2*oldw/3 || width > 3*oldw/2)
|
||
tv.SetColumnWidth(c, width);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void xvt_treelist_suspend(WINDOW win)
|
||
{
|
||
CAST_TREELIST(win, tv);
|
||
tv.Suspend();
|
||
}
|
||
|
||
void xvt_treelist_set_node_bold(WINDOW win, XVT_TREEVIEW_NODE node, BOOLEAN bold)
|
||
{
|
||
if (win != NULL_WIN && node != NULL)
|
||
{
|
||
CAST_TREELIST(win, tv);
|
||
const wxTreeItemId id(node);
|
||
tv.SetItemBold(id, bold != FALSE);
|
||
}
|
||
}
|
||
|
||
static XVT_TREEVIEW_NODE FindTreeListNodeString(wxTreeListCtrl& tv, const wxTreeItemId& parent, const char* text)
|
||
{
|
||
if (parent.IsOk())
|
||
{
|
||
TwxTreeItemData* pData = (TwxTreeItemData*)tv.GetItemData(parent);
|
||
if (pData != NULL && pData->m_strData == text)
|
||
return parent.m_pItem;
|
||
|
||
wxTreeItemIdValue cookie;
|
||
for (wxTreeItemId id = tv.GetFirstChild(parent, cookie); id.IsOk();
|
||
id = tv.GetNextChild(parent, cookie))
|
||
{
|
||
XVT_TREEVIEW_NODE node = FindTreeListNodeString(tv, id, text);
|
||
if (node != NULL)
|
||
return node;
|
||
}
|
||
}
|
||
return NULL;
|
||
}
|
||
|
||
XVT_TREEVIEW_NODE xvt_treelist_find_node_string(WINDOW win, const char* text)
|
||
{
|
||
XVT_TREEVIEW_NODE node = NULL;
|
||
if (win != NULL_WIN && text && *text)
|
||
{
|
||
CAST_TREELIST(win, tv);
|
||
node = FindTreeListNodeString(tv, tv.GetSelection(), text);
|
||
if (node == NULL)
|
||
node = FindTreeListNodeString(tv, tv.GetRootItem(), text);
|
||
}
|
||
return node;
|
||
}
|
||
|
||
BOOLEAN xvt_html_set_url(WINDOW win, const char* url)
|
||
{
|
||
BOOLEAN done = FALSE;
|
||
wxHtmlWindow* w = win ? wxDynamicCast((wxObject*)win, wxHtmlWindow) : NULL;
|
||
if (w)
|
||
{
|
||
wxString strLocation = url;
|
||
if (strLocation.IsEmpty() || strLocation.StartsWith("<"))
|
||
done = w->SetPage(strLocation);
|
||
else
|
||
done = w->LoadPage(strLocation);
|
||
}
|
||
return done;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Sad but needed migration from xvaga.cpp
|
||
///////////////////////////////////////////////////////////
|
||
|
||
WIN_TYPE xvt_vobj_get_type(WINDOW win)
|
||
{
|
||
if (win == NULL_WIN)
|
||
return W_NONE;
|
||
if (win == TASK_WIN)
|
||
return W_TASK;
|
||
if (win == SCREEN_WIN)
|
||
return W_SCREEN;
|
||
if (win == PRINTER_WIN)
|
||
return W_PRINT;
|
||
|
||
const TwxWindow* w = wxDynamicCast((wxObject*)win, TwxWindow);
|
||
if (w != NULL)
|
||
return w->_type;
|
||
|
||
const wxControl* ctl = wxDynamicCast((wxObject*)win, wxControl);
|
||
if (ctl != NULL)
|
||
{
|
||
if (ctl->IsKindOf(CLASSINFO(wxHtmlWindow))) return WC_HTML;
|
||
if (ctl->IsKindOf(CLASSINFO(wxTreeCtrl))) return WC_TREE;
|
||
if (ctl->IsKindOf(CLASSINFO(wxTreeListCtrl))) return WC_TREELIST;
|
||
if (ctl->IsKindOf(CLASSINFO(wxPropertyGrid))) return WC_PROPGRID; // Siamo fiduciosi, ma ...
|
||
}
|
||
else
|
||
{
|
||
// ... non deriva da wxControl :-)
|
||
const wxPropertyGrid* pg = wxDynamicCast((wxObject*)win, wxPropertyGrid);
|
||
if (pg != NULL)
|
||
return WC_PROPGRID;
|
||
}
|
||
|
||
return WO_TE; // Unknown custom control
|
||
}
|
||
|