diff --git a/xvaga/xvaga.cpp b/xvaga/xvaga.cpp index 380a81b1e..70d165839 100755 --- a/xvaga/xvaga.cpp +++ b/xvaga/xvaga.cpp @@ -264,14 +264,17 @@ const wxIcon& _GetIconResource(int rid) if (::wxFileExists(strName)) { icon = new wxIcon(strName, wxBITMAP_TYPE_ICO); - _nice_icons.Put(rid, icon); } else { icon = (wxIcon*)_nice_icons.Get(ICON_RSRC); if (icon == NULL) - icon = new wxIcon; // Icona nulla di salvezza + { + strName.Printf("%d", ICON_RSRC); + icon = new wxIcon(strName); // Icona di salvezza + } } + _nice_icons.Put(rid, icon); } return *icon; } @@ -1360,9 +1363,12 @@ void xvt_dwin_draw_gradient_linear(WINDOW win, const RCT* r, COLOR col1, COLOR c void xvt_dwin_draw_icon(WINDOW win, int x, int y, int rid) { - CAST_DC(win, dc); const wxIcon& ico = _GetIconResource(rid); - dc.DrawIcon(ico, x, y); + if (ico.IsOk()) + { + CAST_DC(win, dc); + dc.DrawIcon(ico, x, y); + } } static wxRect ComputeRect(const wxRect& rct, int h, int v, int k) diff --git a/xvaga/xvtctl.cpp b/xvaga/xvtctl.cpp new file mode 100755 index 000000000..1a9bfcd30 --- /dev/null +++ b/xvaga/xvtctl.cpp @@ -0,0 +1,1310 @@ +#include "wxinc.h" +#include "xvt.h" +#include "xvtwin.h" +#include "statbar.h" + +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////// +// Utility functions +/////////////////////////////////////////////////////////// + +static wxBitmap Image2Bitmap(XVT_IMAGE image, BOOLEAN trans) +{ + if (image == NULL) + return wxNullBitmap; + + wxImage& img = *(wxImage*)image; + 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 <= 0) nDesiredSize = 32; else + if (nDesiredSize > 512) nDesiredSize = 512; + const long nCode = 1000*nIcon + nDesiredSize; + wxBitmap* bmp = (wxBitmap*)_tool_icons.Get(nCode); + 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 + if (strName.EndsWith(".png")) + { + wxImage img(strName, wxBITMAP_TYPE_PNG); + img.Rescale(nDesiredSize, nDesiredSize, wxIMAGE_QUALITY_HIGH); + bmp = new wxBitmap(img); + } + break; + } + } + _tool_icons.Put(nCode, bmp); + } + return *bmp; +} + +/////////////////////////////////////////////////////////// +// Controls functions +/////////////////////////////////////////////////////////// + +class TwxScrollBar : public wxScrollBar +{ +protected: + virtual bool AcceptsFocus() const { return false; } // Altrimenti mette il flag wxTAB_TRAVERSAL + +public: + TwxScrollBar(wxWindow *parent, wxWindowID id, + const wxPoint& pos, const wxSize& size, long style) + { Create(parent, id, pos, size, style); } +}; + +class TwxNoteBook : public wxNotebook +{ +protected: + DECLARE_EVENT_TABLE() + void OnPageChanged(wxNotebookEvent& e); + + +public: + short AddTab(wxWindow* pPage, const wxString text, wxBitmap* bmp = NULL, short idx = -1); + TwxNoteBook(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style); + ~TwxNoteBook(); +}; + +class TwxTreeCtrl : public wxTreeCtrl +{ +#if wxCHECK_VERSION(2,8,7) + WX_DECLARE_VOIDPTR_HASH_MAP(int, XVT_IMAGE_Map); + XVT_IMAGE_Map m_img; +#else + wxHashTable m_img; +#endif + wxFont m_font; + int m_nFrozen; + +private: + int img2int(XVT_IMAGE img); // Store img into internal image list + void OnClick(wxTreeEvent& evt, bool bDouble); + +protected: + DECLARE_EVENT_TABLE(); + void OnExpanding(wxTreeEvent& e); // Called when node in about to be expanded + void OnCollapsed(wxTreeEvent& e); // Called when node is collapsed + void OnSelected(wxTreeEvent& e); // Calls OnClick(e, false) + void OnActivated(wxTreeEvent& e); // Calls OnClick(e, true) + +public: + void SetNodeImages(const wxTreeItemId& id, XVT_IMAGE item_image, + XVT_IMAGE collapsed_image, XVT_IMAGE expanded_image); +#if wxCHECK_VERSION(2,8,7) + virtual bool SetFont(const wxFont& font) { m_font = font; return font.IsOk(); } +#else + virtual bool SetFont(const wxFont& font) { m_font = font; return true; } +#endif + virtual wxFont GetFont() const; + + 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]; + bool m_bCaptured; + 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 OnMouseCaptureLost(wxMouseCaptureLostEvent& 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); +}; + +WINDOW xvt_ctl_create_def(WIN_DEF *win_def_p, WINDOW parent_win, long app_data) +{ + wxASSERT(win_def_p != NULL); + const wxRect rct = NormalizeRCT(&win_def_p->rct); + wxWindow* pParent = (wxWindow*)parent_win; + const wxWindowID id = win_def_p->v.ctl.ctrl_id; + + WINDOW win = NULL_WIN; + switch (win_def_p->wtype) + { + case WC_HSCROLL: /* horizontal scrollbar control */ + case WC_VSCROLL: /* vertical scrollbar control */ + { + const long style = win_def_p->wtype == WC_HSCROLL ? wxSB_HORIZONTAL : wxSB_VERTICAL; + TwxScrollBar* sb = new TwxScrollBar(pParent, id, rct.GetPosition(), rct.GetSize(), style); + win = (WINDOW)sb; + } + break; + case WC_HGAUGE: /* horizontal progress bar control */ + case WC_VGAUGE: /* vertical progress bar control */ + { + const long style = (win_def_p->wtype == WC_HGAUGE) ? wxGA_HORIZONTAL : wxGA_VERTICAL; + wxGauge* pg = new wxGauge(pParent, id, app_data, + rct.GetPosition(), rct.GetSize(), style); + win = (WINDOW)pg; + } + break; + case WC_PUSHBUTTON: /* bottone normale */ + { + wxButton* pb = NULL; + if (win_def_p->text && *win_def_p->text) // Bottone normale con label + { + pb = new wxButton(pParent, id, win_def_p->text, rct.GetPosition(), rct.GetSize()); + } + else + { // Bottone figo con immagini + wxBitmap bmp; + pb = new wxBitmapButton(pParent, id, bmp, rct.GetPosition(), rct.GetSize()); + } + win = (WINDOW)pb; + } + break; + case WC_CHECKBOX: /* check box */ + { + long style = wxCHK_2STATE | wxTRANSPARENT_WINDOW; + if (win_def_p->wtype == CTL_FLAG_RIGHT_JUST) + style |= wxALIGN_RIGHT; + wxCheckBox* cb = new wxCheckBox(pParent, id, win_def_p->text, + rct.GetPosition(), rct.GetSize(), style); + win = (WINDOW)cb; + } + break; + case WC_RADIOBUTTON: /* radio button */ + { + wxRadioButton* rb = new wxRadioButton(pParent, id, win_def_p->text, + rct.GetPosition(), rct.GetSize()); + win = (WINDOW)rb; + } + break; + case WC_NOTEBK: + { + const long flags = win_def_p->v.ctl.flags; + long style = 0; + if (flags & CTL_FLAG_LEFT_JUST) style |= wxNB_LEFT; + if (flags & CTL_FLAG_RIGHT_JUST) style |= wxNB_RIGHT; + if (flags & CTL_FLAG_CENTER_JUST) style |= wxNB_BOTTOM; + TwxNoteBook* nb = new TwxNoteBook(pParent, id, rct.GetPosition(), rct.GetSize(), style); + win = (WINDOW)nb; + } + break; + case WC_TREE: + { + TwxTreeCtrl* tv = new TwxTreeCtrl(pParent, id, rct.GetPosition(), rct.GetSize()); + win = (WINDOW)tv; + XVT_FNTID font_id = win_def_p->v.ctl.font_id; + if (font_id == NULL) + font_id = xvt_dwin_get_font(parent_win); + if (font_id != NULL) + { + const wxFont& font = ((TFontId*)font_id)->Font(NULL, win); + tv->SetFont(font); + } + } + break; + 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) + { + wxWindow& w = *(wxWindow*)win; + const long flags = win_def_p->v.ctl.flags; + if (flags & CTL_FLAG_INVISIBLE) w.Hide(); + if (flags & CTL_FLAG_DISABLED) w.Disable(); + } + + return win; +} + +void xvt_ctl_check_radio_button(WINDOW win, WINDOW* wins, int NbrWindows) +{ + wxASSERT(NbrWindows >= 2); + for (int i = 0; i < NbrWindows; i++) + { + wxRadioButton* rb = (wxRadioButton*)wins[i]; + wxASSERT(rb != NULL && rb->IsKindOf(CLASSINFO(wxRadioButton))); + rb->SetValue(win == wins[i]); + } +} + +void xvt_ctl_set_checked(WINDOW win, BOOLEAN bCheck) +{ + wxCheckBox* cb = (wxCheckBox*)win; + wxASSERT(cb != NULL); + cb->SetValue(bCheck != 0); +} + +/////////////////////////////////////////////////////////// +// Buttons +/////////////////////////////////////////////////////////// + +void xvt_btn_set_images(WINDOW win, XVT_IMAGE up, XVT_IMAGE down) +{ + if (win != NULL_WIN && up != NULL) + { + wxBitmapButton* pb = (wxBitmapButton*)win; + wxASSERT(pb->IsKindOf(CLASSINFO(wxBitmapButton))); + wxBitmap bmpUp(Image2Bitmap(up, 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, TRUE)); + if (bmpDown.Ok()) + pb->SetBitmapSelected(bmpDown); + } + else + { + if (bmpUp.Ok()) + pb->SetBitmapSelected(bmpUp); + } + } +} + +/////////////////////////////////////////////////////////// +// Pane interface +/////////////////////////////////////////////////////////// + +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) + { + done = ((TwxWindow*)win)->AddPane((wxWindow*)pane, name, dock, flags); + } + return done; +} + +static wxAuiPaneInfo* Win2Pane(WINDOW win) +{ + wxWindow* pwin = (wxWindow*)win; + wxAuiManager* pManager = wxAuiManager::GetManager(pwin); + if (pManager != NULL) + { + wxAuiPaneInfo& pane = pManager->GetPane(pwin); + if (pane.IsOk()) + { + pManager->Update(); + return &pane; + } + } + return NULL; +} + +BOOLEAN xvt_pane_set_title(WINDOW win, const char* title) +{ + wxAuiPaneInfo* pane = Win2Pane(win); + if (pane != NULL) + pane->Caption(title); + return pane != NULL; +} + +XVTDLL BOOLEAN xvt_pane_change_flags(WINDOW win, int set, int rst) +{ + wxAuiPaneInfo* pane = Win2Pane(win); + if (pane != NULL && (set || rst)) + { + if (set) pane->SetFlag(set, true); + if (rst) pane->SetFlag(rst, false); + } + return pane != NULL; +} + +XVTDLL BOOLEAN xvt_pane_detach(WINDOW win) +{ + BOOLEAN ok = FALSE; + if (win != NULL_WIN) + { + wxWindow* pwin = (wxWindow*)win; + wxAuiManager* pManager = wxAuiManager::GetManager(pwin); + if (pManager != NULL) + ok = pManager->DetachPane(pwin); + } + return ok; +} + +/////////////////////////////////////////////////////////// +// Notebook interface +/////////////////////////////////////////////////////////// + +#define CAST_NOTEBOOK(win, nb) wxASSERT(win); TwxNoteBook& nb = *(TwxNoteBook*)win; + +inline bool VALID_NOTEBOOK(WINDOW notebk, short page_no) +{ return notebk != NULL_WIN && page_no >= 0; } + +BEGIN_EVENT_TABLE(TwxNoteBook, wxNotebook) + EVT_NOTEBOOK_PAGE_CHANGED(wxID_ANY, TwxNoteBook::OnPageChanged) +END_EVENT_TABLE(); + +void TwxNoteBook::OnPageChanged(wxNotebookEvent& evt) +{ + 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 = (TwxWindow*)GetParent(); + win->DoXvtEvent(e); +} + +short TwxNoteBook::AddTab(wxWindow* pPage, const wxString text, wxBitmap* bmp, short idx) +{ + int imageId = -1; + if (bmp != NULL) + { + wxImageList* il = GetImageList(); + if (il == NULL) + AssignImageList(il = new wxImageList(bmp->GetWidth(), bmp->GetHeight())); + imageId = il->Add(*bmp); + } + if (pPage->GetParent() != this) + pPage->Reparent(this); + if (idx < 0 || idx >= (int)GetPageCount()) + { + AddPage(pPage, text, false, imageId); + idx = GetPageCount()-1; + } + else + InsertPage(idx, pPage, text, false, imageId); + + return idx; +} + +TwxNoteBook::TwxNoteBook(wxWindow *parent, wxWindowID id, + const wxPoint& pos, const wxSize& size, long style) + : wxNotebook(parent, id, pos, size, style) +{ _nice_windows.Put((WINDOW)this, this); } + +TwxNoteBook::~TwxNoteBook() +{ + _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); + wxBitmap* bmp = NULL; + wxString strTitle = title; + if (strTitle.IsEmpty() && page != NULL_WIN) + strTitle = ((wxWindow*)page)->GetLabel(); + idx = nb.AddTab((wxWindow*)page, strTitle, bmp, 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 generare eventi 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_title(WINDOW notebk, short tab_no, const char* title) +{ + if (notebk != NULL_WIN && tab_no >= 0) + { + 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) +END_EVENT_TABLE(); + +#define CAST_TREEVIEW(win, tv) wxASSERT(win); TwxTreeCtrl& tv = *(TwxTreeCtrl*)win; + +struct TwxTreeItemData : public wxTreeItemData +{ + wxString m_strData; // Assumo sempre una stringa come dati +}; + +void TwxTreeCtrl::OnExpanding(wxTreeEvent& evt) +{ + if (!m_nFrozen) + { + const wxTreeItemId id = evt.GetItem(); + EVENT e; memset(&e, 0, sizeof(EVENT)); + e.type = E_CONTROL; + e.v.ctl.id = evt.GetId(); + e.v.ctl.ci.type = WC_TREE; + e.v.ctl.ci.win = WINDOW(this); + e.v.ctl.ci.v.treeview.node = id.m_pItem; + e.v.ctl.ci.v.treeview.expanded = TRUE; + if (GetChildrenCount(id) == 0) // Trucco perfido ... + e.v.ctl.ci.v.treeview.collapsed = TRUE; // ... stato indeterminato = EXPANDING + TwxWindow* win = (TwxWindow*)GetParent(); + win->DoXvtEvent(e); + if (GetChildrenCount(id) == 0) // Allora e' proprio vero ... + SetItemHasChildren(id, false); + } +} + +void TwxTreeCtrl::OnCollapsed(wxTreeEvent& evt) +{ + if (!m_nFrozen) + { + Suspend(); + EVENT e; memset(&e, 0, sizeof(EVENT)); + e.type = E_CONTROL; + e.v.ctl.id = evt.GetId(); + e.v.ctl.ci.type = WC_TREE; + e.v.ctl.ci.win = WINDOW(this); + e.v.ctl.ci.v.treeview.node = evt.GetItem().m_pItem; + e.v.ctl.ci.v.treeview.collapsed = TRUE; + TwxWindow* win = (TwxWindow*)GetParent(); + win->DoXvtEvent(e); + Resume(); + } +} + +void TwxTreeCtrl::OnClick(wxTreeEvent& evt, bool bDouble) +{ + if (!m_nFrozen) + { + Suspend(); + EVENT e; memset(&e, 0, sizeof(EVENT)); + e.type = E_CONTROL; + e.v.ctl.id = evt.GetId(); + e.v.ctl.ci.type = WC_TREE; + e.v.ctl.ci.win = WINDOW(this); + e.v.ctl.ci.v.treeview.node = evt.GetItem().m_pItem; + if (bDouble) + e.v.ctl.ci.v.treeview.dbl_click = TRUE; + else + e.v.ctl.ci.v.treeview.sgl_click = TRUE; + TwxWindow* win = (TwxWindow*)GetParent(); + win->DoXvtEvent(e); + Resume(); + } +} + +void TwxTreeCtrl::OnSelected(wxTreeEvent& evt) +{ OnClick(evt, false); } + +void TwxTreeCtrl::OnActivated(wxTreeEvent& evt) +{ OnClick(evt, true); } + +int TwxTreeCtrl::img2int(XVT_IMAGE xvt_img) +{ + int i = -1; + if (xvt_img != NULL) + { +#if wxCHECK_VERSION(2,8,7) + i = m_img[xvt_img] - 1; // Ho memorizzato indice+1 +#else + i = (int)m_img.Get((long)xvt_img) - 1; +#endif + 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); + } + } + i = il->Add(wxBitmap(img)); +#if wxCHECK_VERSION(2,8,7) + m_img[xvt_img] = i+1; // Memorizzo indice+1 +#else + m_img.Put((long)xvt_img, (wxObject*)(i+1)); // Memorizzo indice+1 +#endif + } + if (i < 0) + SORRY_BOX(); + } + return i; +} + +void TwxTreeCtrl::SetNodeImages(const wxTreeItemId& id, XVT_IMAGE item_image, + XVT_IMAGE collapsed_image, XVT_IMAGE expanded_image) +{ + const int ii = img2int(item_image); + if (ii >= 0) + SetItemImage(id, ii); + else + { + const int ic = img2int(collapsed_image); + if (ic >= 0) + { + SetItemImage(id, ic); + const int ie = img2int(expanded_image); + if (ie >= 0) + SetItemImage(id, ie, wxTreeItemIcon_Selected); + } + } +} + +wxFont TwxTreeCtrl::GetFont() const +{ +#if wxCHECK_VERSION(2,8,7) + return m_font.IsOk() ? m_font : wxTreeCtrl::GetFont(); +#else + return wxTreeCtrl::GetFont(); +#endif +} + +void TwxTreeCtrl::Suspend() +{ m_nFrozen++; } + +void TwxTreeCtrl::Resume() +{ + wxASSERT(m_nFrozen > 0); + if (m_nFrozen > 0) + m_nFrozen--; +} + +TwxTreeCtrl::TwxTreeCtrl(wxWindow *parent, wxWindowID id, + const wxPoint& pos, const wxSize& size) + : wxTreeCtrl(parent, id, pos, size, wxTR_HAS_BUTTONS | wxTR_HIDE_ROOT), + m_nFrozen(0) +{ + AddRoot("Root"); +} + +WINDOW xvt_treeview_create(WINDOW parent_win, + RCT * rct_p, char * title, long ctl_flags, + long app_data, int ctl_id, XVT_IMAGE item_image, + XVT_IMAGE collapsed_image, XVT_IMAGE expanded_image, + long attrs, int line_height) +{ + WIN_DEF win_def; memset(&win_def, 0, sizeof(WIN_DEF)); + win_def.wtype = WC_TREE; + win_def.rct = *rct_p; + win_def.text = title; + win_def.v.ctl.ctrl_id = ctl_id; + win_def.v.ctl.flags = ctl_flags; + WINDOW win = xvt_ctl_create_def(&win_def, parent_win, app_data); + return win; +} + +XVT_TREEVIEW_NODE xvt_treeview_add_child_node(WINDOW win, + XVT_TREEVIEW_NODE parent, XVT_TREEVIEW_NODE_TYPE type, + XVT_IMAGE item_image, XVT_IMAGE collapsed_image, XVT_IMAGE expanded_image, + const char* string, XVT_TREEVIEW_CALLBACK callback, const char* data) +{ + XVT_TREEVIEW_NODE node = NULL; + if (win != NULL_WIN) + { + CAST_TREEVIEW(win, tv); + TwxTreeItemData* pData = new TwxTreeItemData; + pData->m_strData = data; + wxTreeItemId pa(parent); + if (!pa.IsOk()) + pa = tv.GetRootItem(); + wxTreeItemId id = tv.AppendItem(pa, string, -1, -1, pData); + if (id.IsOk()) + { + tv.SetItemHasChildren(pa, true); + tv.SetItemHasChildren(id, type == XVT_TREEVIEW_NODE_NONTERMINAL); + tv.SetNodeImages(id, item_image, collapsed_image, expanded_image); + tv.SetItemFont(id, tv.GetFont()); + node = id.m_pItem; + } + } + return node; +} + +XVT_TREEVIEW_NODE xvt_treeview_get_child_node(WINDOW win, XVT_TREEVIEW_NODE parent_node, + int position) +{ + XVT_TREEVIEW_NODE child_node = NULL; + if (win != NULL_WIN && position >= 0) + { + CAST_TREEVIEW(win, tv); + wxTreeItemId parent(parent_node); + if (!parent.IsOk()) + parent = tv.GetRootItem(); + + if (position < (int)tv.GetChildrenCount(parent)) + { + wxTreeItemIdValue cookie; + wxTreeItemId id; + int i = -1; + for (id = tv.GetFirstChild(parent, cookie), i = -1; + i < position && id.IsOk(); id = tv.GetNextChild(parent, cookie), i++); + child_node = id.m_pItem; + } + } + return child_node; +} + +const char* xvt_treeview_get_node_data(WINDOW win, XVT_TREEVIEW_NODE node) +{ + const char* data = NULL; + if (win != NULL_WIN && node != NULL) + { + CAST_TREEVIEW(win, tv); + const wxTreeItemId id(node); + TwxTreeItemData* pData = (TwxTreeItemData*)tv.GetItemData(id); + if (pData != NULL) + data = (const char*)pData->m_strData; + } + return data; +} + +void xvt_treeview_destroy_node(WINDOW win, XVT_TREEVIEW_NODE node) +{ + if (win != NULL_WIN && node != NULL) + { + CAST_TREEVIEW(win, tv); + wxTreeItemId id(node); + tv.Delete(id); + } +} + +BOOLEAN xvt_treeview_expand_node(WINDOW win, XVT_TREEVIEW_NODE node, BOOLEAN recurse) +{ + BOOLEAN ok = (win != NULL_WIN) && (node != NULL); + if (ok) + { + CAST_TREEVIEW(win, tv); + const wxTreeItemId id(node); +#if wxCHECK_VERSION(2,8,7) + if (recurse) + tv.ExpandAllChildren(id); + else +#endif + tv.Expand(id); + } + return ok; +} + +XVT_TREEVIEW_NODE xvt_treeview_get_root_node(WINDOW win) +{ + XVT_TREEVIEW_NODE pRoot = NULL; + if (win != NULL_WIN) + { + CAST_TREEVIEW(win, tv); + const wxTreeItemId id = tv.GetRootItem(); + pRoot = id.m_pItem; + } + return pRoot; +} + +XVT_TREEVIEW_NODE xvt_treeview_get_selected_node(WINDOW win) +{ + CAST_TREEVIEW(win, tv); + const wxTreeItemId id = tv.GetSelection(); + return id.m_pItem; +} + +BOOLEAN xvt_treeview_remove_child_node(WINDOW win, XVT_TREEVIEW_NODE node) +{ + BOOLEAN ok = (win != NULL_WIN) && (node != NULL); + if (ok) + { + CAST_TREEVIEW(win, tv); + const wxTreeItemId id(node); + tv.Delete(id); + } + return ok; +} + +BOOLEAN xvt_treeview_remove_node_children(WINDOW win, XVT_TREEVIEW_NODE node) +{ + BOOLEAN ok = FALSE; + if (win != NULL_WIN) + { + CAST_TREEVIEW(win, tv); + wxTreeItemId id(node); + if (!id.IsOk()) + id = tv.GetRootItem(); + tv.DeleteChildren(id); + ok = TRUE; + } + return ok; +} + +void xvt_treeview_resume(WINDOW win) +{ + CAST_TREEVIEW(win, tv); + tv.Resume(); +} + +void xvt_treeview_select_node(WINDOW win, XVT_TREEVIEW_NODE node, BOOLEAN sel) +{ + if (win != NULL_WIN && node != NULL) + { + CAST_TREEVIEW(win, tv); + const wxTreeItemId id(node); + tv.SelectItem(id, sel != 0); + if (sel) + tv.EnsureVisible(id); + } +} + +void xvt_treeview_set_node_images(WINDOW win, XVT_TREEVIEW_NODE node, XVT_IMAGE item_image, + XVT_IMAGE collapsed_image, XVT_IMAGE expanded_image) +{ + if (win != NULL_WIN && node != NULL) + { + CAST_TREEVIEW(win, tv); + const wxTreeItemId id(node); + tv.SetNodeImages(id, item_image, collapsed_image, expanded_image); + } +} + +void xvt_treeview_set_node_string(WINDOW win, XVT_TREEVIEW_NODE node, const char* text) +{ + if (win != NULL_WIN && node != NULL) + { + CAST_TREEVIEW(win, tv); + const wxTreeItemId id(node); + tv.SetItemText(id, text); + } +} + +void xvt_treeview_suspend(WINDOW win) +{ + CAST_TREEVIEW(win, tv); + tv.Suspend(); +} + +/////////////////////////////////////////////////////////// +// 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_MOUSE_CAPTURE_LOST(TwxOutlookBar::OnMouseCaptureLost) +END_EVENT_TABLE() + +static wxAuiDockArt* GetArtist(const wxWindow* pWindow) +{ + wxAuiDockArt* pArtist = NULL; + const wxAuiManager* pManager = wxAuiManager::GetManager(pWindow->GetParent()); + if (pManager != NULL) + pArtist = pManager->GetArtProvider(); + return pArtist; +} + +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 wxColour DarkerColor(const wxColour& col, int percent = 20) +{ return ModulateColour(col, -percent); } + +static wxColour LighterColor(const wxColour& col, int percent = 20) +{ return ModulateColour(col, +percent); } + +void TwxOutlookBar::OnDrawBackground(wxDC& dc, const wxRect& rect, size_t n) const +{ + 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 + { + color1 = LighterColor(wxSystemSettings::GetColour(wxSYS_COLOUR_INACTIVECAPTION)); + color2 = DarkerColor(wxSystemSettings::GetColour(wxSYS_COLOUR_ACTIVECAPTION)); + } + } + 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; + } + + wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); + font.SetWeight(wxFONTWEIGHT_BOLD); + dc.SetFont(font); + + wxColour 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 n) const +{ + const int nItems = GetItemCount(); + wxCoord nHeight = 36; + if (nItems > 1) + { + const wxSize sz = GetSize(); + nHeight = max(sz.y / nItems, nHeight); + } + return nHeight; +} + +void TwxOutlookBar::OnMouseMove(wxMouseEvent& evt) +{ + int nHover = HitTest(evt.GetPosition()); + if (m_bCaptured && nHover != wxNOT_FOUND) + { + const wxRect rect = GetClientRect(); + if (!rect.Contains(evt.GetPosition())) + nHover = wxNOT_FOUND; + } + + if (nHover == wxNOT_FOUND) + { + if (m_bCaptured) + { + m_bCaptured = false; + ReleaseMouse(); + } + } + else + { + if (!m_bCaptured) + { + m_bCaptured = true; + CaptureMouse(); + } + } + + 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 TwxOutlookBar::OnMouseCaptureLost(wxMouseCaptureLostEvent&) +{ + m_bCaptured = false; + if (m_nHovering != wxNOT_FOUND) + { + const int nWasHovering = m_nHovering; + m_nHovering = wxNOT_FOUND; + RefreshLine(nWasHovering); + } +} + +void TwxOutlookBar::OnSelected(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_OUTLOOKBAR; + e.v.ctl.ci.win = WINDOW(this); + e.v.ctl.ci.v.lbox.dbl_click = evt.GetEventType() == wxEVT_COMMAND_LISTBOX_DOUBLECLICKED; + TwxWindow* win = (TwxWindow*)GetParent(); + 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_bCaptured(false), m_nHovering(wxNOT_FOUND) +{ + SetItemCount(0); +} + +int xvt_list_add_item(WINDOW win, short icon, const char* text, int flags) +{ + int n = -1; + if (win != NULL_WIN) + { + TwxOutlookBar* olb = (TwxOutlookBar*)win; + n = olb->Add(icon, text, flags); + } + return n; +} + +BOOLEAN xvt_list_clear(WINDOW win) +{ + BOOLEAN ok = win != NULL_WIN; + if (ok) + { + TwxOutlookBar* olb = (TwxOutlookBar*)win; + olb->Clear(); + } + return ok; +} + +BOOLEAN xvt_list_get_sel_index(WINDOW win) +{ + int sel = -1; + BOOLEAN ok = win != NULL_WIN; + if (ok) + { + TwxOutlookBar* olb = (TwxOutlookBar*)win; + sel = olb->GetSelection(); + } + return sel; +} + +BOOLEAN xvt_list_set_sel(WINDOW win, int index, BOOLEAN select) +{ + BOOLEAN ok = win != NULL_WIN; + if (ok) + { + TwxOutlookBar* olb = (TwxOutlookBar*)win; + if (select) + olb->SetSelection(index); + } + return ok; +} + +/////////////////////////////////////////////////////////// +// ToolBar +/////////////////////////////////////////////////////////// + +class TwxToolBar : public wxToolBar +{ +protected: + DECLARE_EVENT_TABLE() + void OnTool(wxCommandEvent& evt); + +public: + TwxToolBar(wxWindow* parent, wxWindowID id, const wxPoint& pos, + const wxSize& size, long style); +}; + +BEGIN_EVENT_TABLE(TwxToolBar, wxToolBar) + 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_PUSHBUTTON; + e.v.ctl.ci.win = WINDOW(this); + TwxWindow* win = (TwxWindow*)GetParent(); + win->DoXvtEvent(e); +} + +TwxToolBar::TwxToolBar(wxWindow* parent, wxWindowID id, const wxPoint& pos, + const wxSize& size, long style) + : wxToolBar(parent, id, pos, size, style) +{ } + +static wxToolBar* Win2Bar(WINDOW win) +{ + wxWindow* wnd = (wxWindow*)win; + if (wnd != NULL && wnd->IsKindOf(CLASSINFO(wxToolBar))) + return (wxToolBar*)wnd; + return NULL; +} + +BOOLEAN xvt_toolbar_add_control(WINDOW win, int cid, TOOL_TYPE type, const char *title, + int ico, int cust_width, int idx) +{ + BOOLEAN ok = FALSE; + wxToolBar* ptb = Win2Bar(win); + if (ptb != NULL) + { + wxToolBar& tb = *ptb; + switch (type) + { + case TOOL_SEPARATOR: + if (idx < 0) + tb.AddSeparator(); + else + tb.InsertSeparator(idx); + ok = TRUE; + break; + default: + { + const wxBitmap& bmp = _GetToolResource(ico, tb.GetToolBitmapSize().y); + wxString tip; + for (const char* t = title; *t; t++) if (*t != '~' && *t != '&') + tip << *t; + if (idx < 0) + ok = tb.AddTool(cid, title, bmp, wxNullBitmap, wxItemKind(type), tip) != NULL; + else + ok = tb.InsertTool(idx, cid, title, bmp, wxNullBitmap, wxItemKind(type), tip) != NULL; + } + break; + } + } + return ok; +} + +WINDOW xvt_toolbar_create(int cid, int left, int top, int right, int bottom, long nStyle, WINDOW parent) +{ + const wxPoint ptPos(left, top); + wxSize szSize(right-left, bottom-top); + nStyle |= wxNO_BORDER | wxTB_FLAT | wxTB_NODIVIDER; + int nIcoSize = 16; + if (bottom > 0) + { + nStyle |= wxTB_HORIZONTAL; + nIcoSize = RoundToIcon(szSize.y); + szSize.y = nIcoSize; + } + else + { + nStyle |= wxTB_VERTICAL; + nIcoSize = RoundToIcon(szSize.x); + szSize.x = nIcoSize; + } + + TwxToolBar* tb = new TwxToolBar((wxWindow*)parent, cid, ptPos, szSize, nStyle); + tb->SetToolBitmapSize(wxSize(nIcoSize, nIcoSize)); + return (WINDOW)tb; +} + +void xvt_toolbar_enable_control(WINDOW win, int cid, BOOLEAN on) +{ + wxToolBar* ptb = Win2Bar(win); + if (ptb != NULL && cid > 0) + ptb->EnableTool(cid, on != 0); +} + +void xvt_toolbar_realize(WINDOW win) +{ + wxToolBar* ptb = Win2Bar(win); + if (ptb != NULL) // Is a valid toolbar? + { + ptb->Realize(); // Update tools + wxAuiPaneInfo* pi = Win2Pane(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); + Win2Pane(win); // calls wxAuiManager::Update() + } + } + } +} + +void xvt_toolbar_show_control(WINDOW win, int cid, BOOLEAN on) +{ + wxToolBar* ptb = Win2Bar(win); + if (ptb != NULL && cid > 0) + ptb->EnableTool(cid, on != 0); // Per ora non so come si faccia +}