campo-sirio/xvaga/xvtctl.cpp
luca 09bcf1c189 Patch level :10.0 252
Files correlati     :
Ricompilazione Demo : [ ]
Commento            :piccole modifiche per migliorare la gestione immagini sui bottoni


git-svn-id: svn://10.65.10.50/trunk@18430 c028cbd2-c16b-5b4b-a496-9718f37d4682
2009-03-06 11:48:12 +00:00

2079 lines
53 KiB
C++
Executable File

#include "wxinc.h"
#include "xvt.h"
#include "xvtwin.h"
#include "statbar.h"
#include <wx/filename.h>
#include <wx/treectrl.h>
#include <wx/vlbox.h>
#include <wx/aui/aui.h>
///////////////////////////////////////////////////////////
// Utility functions
///////////////////////////////////////////////////////////
static wxBitmap Image2Bitmap(XVT_IMAGE image, int maxx, int maxy, BOOLEAN trans)
{
if (image == NULL)
return wxNullBitmap;
wxImage img = *(wxImage*)image;
int w = img.GetWidth(), h = img.GetHeight();
if (w > maxx || h > maxy)
{
const double mx = (maxx / 4) * 4, my = (maxy / 4) * 4;
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;
}
const wxBitmap& _GetToolResource(int nIcon, int nDesiredSize)
{
static wxHashTable _tool_icons;
if (nDesiredSize < 16) nDesiredSize = 16; else
if (nDesiredSize > 128) nDesiredSize = 128;
const long nCode = 1000*nIcon + nDesiredSize;
wxBitmap* bmp = wxDynamicCast(_tool_icons.Get(nCode), wxBitmap);
if (bmp == NULL)
{
const int nIco[] = { nIcon, 100, ICON_RSRC, 0 };
for (int i = 0; nIco[i]; i++)
{
wxString strName = _GetResourceName("Tool", nIco[i]).Lower();
if (!strName.IsEmpty() && ::wxFileExists(strName))
{
if (strName.EndsWith(".ico"))
{
const wxIcon ico(strName, wxBITMAP_TYPE_ICO);
bmp = new wxBitmap(ico);
}
else
{
wxImage img(strName, wxBITMAP_TYPE_ANY);
img.Rescale(nDesiredSize, nDesiredSize, wxIMAGE_QUALITY_HIGH);
bmp = new wxBitmap(img);
}
break;
}
}
_tool_icons.Put(nCode, bmp);
}
return *bmp;
}
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);
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();
};
class TwxTreeCtrl : public wxTreeCtrl
{
WX_DECLARE_VOIDPTR_HASH_MAP(int, XVT_IMAGE_Map);
XVT_IMAGE_Map m_img;
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);
public:
void SetNodeImages(const wxTreeItemId& id, XVT_IMAGE item_image,
XVT_IMAGE collapsed_image, XVT_IMAGE expanded_image);
void Suspend();
void Resume();
TwxTreeCtrl(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size);
};
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
{
wxArrayString m_menu;
int m_nHovering;
wxCoord m_nRowHeight;
wxColour m_clrBack, m_clrFore;
DECLARE_EVENT_TABLE()
void NotifySelection();
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);
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);
};
WINDOW xvt_ctl_create_def(WIN_DEF* win_def_p, WINDOW parent_win, long app_data)
{
wxASSERT(win_def_p != NULL);
const wxRect rct = NormalizeRCT(&win_def_p->rct);
wxWindow* pParent = 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_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_POPUP:
{
TwxPopUp* tpu = new TwxPopUp(pParent, id, rct.GetPosition(), rct.GetSize());
win = (WINDOW)tpu;
}
break;
case WC_OUTLOOKBAR:
{
long style = 0;
TwxOutlookBar* tob = new TwxOutlookBar(pParent, id, rct.GetPosition(), rct.GetSize(), style);
win = (WINDOW)tob;
}
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(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)
{
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
{
public:
void SetBackgroundColour(const wxColor& colour) { m_base_colour = colour; }
virtual wxAuiTabArt* Clone();
};
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;
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_CHANGED(wxID_ANY, OnPageChanged)
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;
}
void TwxNoteBook::OnPageChanged(wxAuiNotebookEvent& evt)
{
if (!m_bSuspended)
{
m_bSuspended = true;
EVENT e; memset(&e, 0, sizeof(EVENT));
e.type = E_CONTROL;
e.v.ctl.id = evt.GetId();
e.v.ctl.ci.type = WC_NOTEBK;
e.v.ctl.ci.win = WINDOW(this);
e.v.ctl.ci.v.notebk.face = (WINDOW)GetPage(evt.GetSelection());
e.v.ctl.ci.v.notebk.tab_no = evt.GetSelection();
e.v.ctl.ci.v.notebk.page_no = 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;
if (xvt_img != NULL)
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)
{
if (img != NULL)
{
wxImage ico(*wxStaticCast(img, wxImage));
ico.Rescale(BOOK_ICO_SIZE, BOOK_ICO_SIZE, wxIMAGE_QUALITY_HIGH);
const wxBitmap bmp(ico);
SetPageBitmap(idx, bmp);
}
else
SetPageBitmap(idx, wxNullBitmap);
}
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
}
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);
}
}
}
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 = _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();
EVENT e; memset(&e, 0, sizeof(EVENT));
e.type = E_CONTROL;
e.v.ctl.id = evt.GetId();
e.v.ctl.ci.type = WC_TREE;
e.v.ctl.ci.win = WINDOW(this);
e.v.ctl.ci.v.treeview.node = id.m_pItem;
e.v.ctl.ci.v.treeview.expanded = TRUE;
if (GetChildrenCount(id) == 0) // Trucco perfido ...
e.v.ctl.ci.v.treeview.collapsed = TRUE; // ... stato indeterminato = EXPANDING
TwxWindow* win = 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();
EVENT e; memset(&e, 0, sizeof(EVENT));
e.type = E_CONTROL;
e.v.ctl.id = evt.GetId();
e.v.ctl.ci.type = WC_TREE;
e.v.ctl.ci.win = WINDOW(this);
e.v.ctl.ci.v.treeview.node = evt.GetItem().m_pItem;
e.v.ctl.ci.v.treeview.collapsed = TRUE;
TwxWindow* win = wxStaticCast(GetParent(), TwxWindow);
win->DoXvtEvent(e);
Resume();
}
}
void TwxTreeCtrl::OnClick(wxTreeEvent& evt, bool bDouble)
{
if (!m_nFrozen)
{
Suspend();
EVENT e; memset(&e, 0, sizeof(EVENT));
e.type = E_CONTROL;
e.v.ctl.id = evt.GetId();
e.v.ctl.ci.type = WC_TREE;
e.v.ctl.ci.win = WINDOW(this);
e.v.ctl.ci.v.treeview.node = evt.GetItem().m_pItem;
if (bDouble)
e.v.ctl.ci.v.treeview.dbl_click = TRUE;
else
e.v.ctl.ci.v.treeview.sgl_click = TRUE;
TwxWindow* win = wxStaticCast(GetParent(), TwxWindow);
win->DoXvtEvent(e);
Resume();
}
}
void TwxTreeCtrl::OnSelected(wxTreeEvent& evt)
{ OnClick(evt, false); }
void TwxTreeCtrl::OnActivated(wxTreeEvent& evt)
{ OnClick(evt, true); }
void TwxTreeCtrl::OnRightDown(wxMouseEvent& evt)
{
TwxWindow* pParent = wxDynamicCast(GetParent(), TwxWindow);
if (pParent != NULL)
{
EVENT e; memset(&e, 0, sizeof(EVENT));
e.type = 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::Suspend()
{ m_nFrozen++; }
void TwxTreeCtrl::Resume()
{
wxASSERT(m_nFrozen > 0);
if (m_nFrozen > 0)
m_nFrozen--;
}
TwxTreeCtrl::TwxTreeCtrl(wxWindow *parent, wxWindowID id,
const wxPoint& pos, const wxSize& size)
: wxTreeCtrl(parent, id, pos, size, wxTR_HAS_BUTTONS | wxTR_HIDE_ROOT),
m_nFrozen(0)
{
AddRoot("Root");
}
WINDOW xvt_treeview_create(WINDOW parent_win,
RCT * rct_p, char * title, long ctl_flags,
long app_data, int ctl_id, XVT_IMAGE 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_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;
}
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_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);
}
/*
static const wxColour MeanColour(const wxColour& c1, const wxColour& c2, int percent = 50)
{
const double p = percent / 100.0;
const double i = 1.0-p;
return wxColour(c1.Red()*i+c2.Red()*p, c1.Green()*i+c2.Green()*p, c1.Blue()*i+c2.Blue()*p);
}
*/
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);
}
}
}
dc.GradientFillLinear(rect, color1, color2, wxDOWN);
}
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 wxIcon& ico = _GetIconResource(oi.m_nIconId);
const wxSize szIco(ico.GetWidth(), ico.GetHeight());
dc.DrawIcon(ico, rect.x+nTextOffset, rect.y+(nSide-szIco.y)/2);
nTextOffset += nTextOffset+szIco.x;
}
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 wxSize szText = dc.GetTextExtent(oi.m_strText);
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)
{
EVENT e; memset(&e, 0, sizeof(EVENT));
e.type = 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
///////////////////////////////////////////////////////////
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_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::OnKillFocus(wxFocusEvent& WXUNUSED(e))
{
Hide();
}
void TwxPopUp::NotifySelection()
{
TwxWindow* win = wxDynamicCast(GetParent(), TwxWindow);
if (win != NULL)
{
EVENT e; memset(&e, 0, sizeof(EVENT));
e.type = 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) + 8;
}
static int RoundPopupHeight(int list_h, int row_h)
{
const int rem = list_h % row_h;
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)+8;
const wxRect rctClient = parent->GetClientRect();
const int nBottom = rctClient.GetBottom();
wxPoint pos(ownrct->right-width, ownrct->bottom);
wxSize size(width, items*nRowHeight);
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();
while (lb->IsShown())
{
wxApp* a = wxTheApp; // Memorizzo il risultato di wxGetInstance
while (a->Pending())
a->Dispatch();
lb->Raise();
wxMilliSleep(50);
}
sel = lb->GetSelection();
delete lb;
}
}
return sel >= 0 && sel < items ? menu[sel].tag : 0;
}
///////////////////////////////////////////////////////////
// ToolBar
///////////////////////////////////////////////////////////
#if wxCHECK_VERSION(8,8,3)
#include <wx/aui/auibar.h>
#define TwxToolBarBase wxAuiToolBar
#else
#define TwxToolBarBase wxToolBar
#endif
class TwxToolBar : public TwxToolBarBase
{
DECLARE_DYNAMIC_CLASS(TwxToolBar)
protected:
DECLARE_EVENT_TABLE()
void OnTool(wxCommandEvent& evt);
virtual bool SetBackgroundColour(const wxColour& colour);
TwxToolBar() : TwxToolBarBase(NULL, wxID_ANY) { wxASSERT(false); }
public:
void ShowTool(int id, bool on);
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)
END_EVENT_TABLE();
void TwxToolBar::OnTool(wxCommandEvent& evt)
{
EVENT e; memset(&e, 0, sizeof(EVENT));
e.type = E_CONTROL;
e.v.ctl.id = evt.GetId();
e.v.ctl.ci.type = WC_ICON; // WC_PUSHBUTTON entra in conflitto coi bottoni
e.v.ctl.ci.win = WINDOW(this);
TwxWindow* win = wxStaticCast(GetParent(), TwxWindow);
win->DoXvtEvent(e);
}
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;
}
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 = _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)
{
// ????
}
*/
}
}
// Funzione di utilita' un po' fuori posto (per poter accedere alla _GetToolResource)
void xvt_dwin_draw_tool(WINDOW win, int x, int y, int rid, int size)
{
const wxBitmap& bmp = _GetToolResource(rid, size);
if (bmp.IsOk())
{
wxDC& dc = GetTDCMapper().GetDC(win);
dc.DrawBitmap(bmp, x, y);
}
}