#include "wxinc.h" #include "xvt.h" #include "xvtart.h" #include "xvtwin.h" #include "statbar.h" #include "treelistctrl.h" #include #include #include #include #include #include #include /////////////////////////////////////////////////////////// // 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_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è 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 #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 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; } /////////////////////////////////////////////////////////// // 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(wxTreeCtrl))) return WC_TREE; if (ctl->IsKindOf(CLASSINFO(wxTreeListCtrl))) return WC_TREELIST; if (ctl->IsKindOf(CLASSINFO(wxPropertyGrid))) return WC_PROPGRID; // Siamo fiduciosi, ma ... } // ... non deriva da wxControl :-) const wxPropertyGrid* pg = wxDynamicCast((wxObject*)win, wxPropertyGrid); if (pg != NULL) return WC_PROPGRID; return WO_TE; // Unknown custom control }