From 74b31181b345aaaef0c967cc5707bef72ce0a405 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 29 Sep 1999 22:47:56 +0000 Subject: [PATCH] 1. Implemented support for different icons for different states (expanded, selected, combination of them) for the tree control (and doc'd it) 2. removed code which was sending extra event if wxFrame::SetSize() was used 3. important changes to wxWizard interface 4. small compilation corrections git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@3756 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/latex/wx/treectrl.tex | 30 +- include/wx/generic/treectrl.h | 24 +- include/wx/generic/wizard.h | 62 +++++ include/wx/msw/font.h | 3 + include/wx/msw/frame.h | 3 - include/wx/msw/notebook.h | 11 +- include/wx/msw/treectrl.h | 49 ++-- include/wx/treectrl.h | 15 +- include/wx/wizard.h | 122 +++++++-- samples/listctrl/listtest.cpp | 16 +- samples/mdi/mdi.cpp | 2 +- samples/treectrl/bitmaps/file2.bmp | Bin 0 -> 246 bytes samples/treectrl/bitmaps/file2.ico | Bin 0 -> 318 bytes samples/treectrl/bitmaps/folder1.ico | Bin 318 -> 318 bytes samples/treectrl/bitmaps/folder2.bmp | Bin 0 -> 246 bytes samples/treectrl/bitmaps/folder2.ico | Bin 0 -> 318 bytes samples/treectrl/bitmaps/folder3.bmp | Bin 0 -> 246 bytes samples/treectrl/bitmaps/folder3.ico | Bin 0 -> 318 bytes samples/treectrl/icon3.xpm | 45 +++ samples/treectrl/treetest.cpp | 44 ++- samples/treectrl/treetest.h | 5 +- samples/treectrl/treetest.rc | 11 +- samples/wizard/wiztest.cpp | 130 ++++++++- src/common/docview.cpp | 1 + src/common/url.cpp | 7 +- src/generic/prop.cpp | 4 +- src/generic/wizard.cpp | 262 ++++++++---------- src/msw/font.cpp | 3 +- src/msw/frame.cpp | 9 - src/msw/notebook.cpp | 17 ++ src/msw/treectrl.cpp | 396 +++++++++++++++++++++------ 31 files changed, 927 insertions(+), 344 deletions(-) create mode 100644 include/wx/generic/wizard.h create mode 100644 samples/treectrl/bitmaps/file2.bmp create mode 100644 samples/treectrl/bitmaps/file2.ico create mode 100644 samples/treectrl/bitmaps/folder2.bmp create mode 100644 samples/treectrl/bitmaps/folder2.ico create mode 100644 samples/treectrl/bitmaps/folder3.bmp create mode 100644 samples/treectrl/bitmaps/folder3.ico create mode 100644 samples/treectrl/icon3.xpm diff --git a/docs/latex/wx/treectrl.tex b/docs/latex/wx/treectrl.tex index 47f182a800..fafe593cbc 100644 --- a/docs/latex/wx/treectrl.tex +++ b/docs/latex/wx/treectrl.tex @@ -287,9 +287,20 @@ associated with the wxTreeItemData for the given item Id.} \membersection{wxTreeCtrl::GetItemImage}\label{wxtreectrlgetitemimage} -\constfunc{int}{GetItemImage}{\param{const wxTreeItemId\& }{item}} - -Gets the normal item image. +\constfunc{int}{GetItemImage}{\param{const wxTreeItemId\& }{item}, +\param{wxTreeItemIcon }{which = wxTreeItemIcon\_Normal}} + +Gets the specified item image. The value of {\it which} may be: +\begin{itemize}\itemsep=0pt +\item{wxTreeItemIcon\_Normal} to get the normal item image +\item{wxTreeItemIcon\_Selected} to get the selected item image (i.e. the image +which is shown when the item is currently selected) +\item{wxTreeItemIcon\_Expanded} to get the expanded image (this only +makes sense for items which have children - then this image is shown when the +item is expanded and the normal image is shown when it is collapsed) +\item{wxTreeItemIcon\_SelectedExpanded} to get the selected expanded image +(which is shown when an expanded item is currently selected) +\end{itemize} \membersection{wxTreeCtrl::GetItemText}\label{wxtreectrlgetitemtext} @@ -381,7 +392,8 @@ Returns the root item for the tree control. \constfunc{int}{GetItemSelectedImage}{\param{const wxTreeItemId\& }{item}} -Gets the selected item image. +Gets the selected item image (this function is obsolete, use +{\tt GetItemImage(item, wxTreeItemIcon\_Selected} instead). \membersection{wxTreeCtrl::GetSelection}\label{wxtreectrlgetselection} @@ -546,15 +558,19 @@ usage and loading time. \membersection{wxTreeCtrl::SetItemImage}\label{wxtreectrlsetitemimage} -\func{void}{SetItemImage}{\param{const wxTreeItemId\&}{ item}, \param{int }{image}} +\func{void}{SetItemImage}{\param{const wxTreeItemId\&}{ item}, +\param{int }{image}, +\param{wxTreeItemIcon }{which = wxTreeItemIcon\_Normal}} -Sets the normal item image. This is an index into the assciated image list. +Sets the specified item image. See \helpref{GetItemImage}{wxtreectrlgetitemimage} +for the description of {\it which} parameter. \membersection{wxTreeCtrl::SetItemSelectedImage}\label{wxtreectrlsetitemselectedimage} \func{void}{SetItemSelectedImage}{\param{const wxTreeItemId\&}{ item}, \param{int }{selImage}} -Sets the item selected image. This is an index into the assciated image list. +Sets the selected item image (this function is obsolete, use +{\tt SetItemImage(item, wxTreeItemIcon\_Selected} instead). \membersection{wxTreeCtrl::SetItemText}\label{wxtreectrlsetitemtext} diff --git a/include/wx/generic/treectrl.h b/include/wx/generic/treectrl.h index 1a42b69ef2..38994404ba 100644 --- a/include/wx/generic/treectrl.h +++ b/include/wx/generic/treectrl.h @@ -258,10 +258,9 @@ public: // retrieve items label wxString GetItemText(const wxTreeItemId& item) const; - // get the normal item image - int GetItemImage(const wxTreeItemId& item) const; - // get the selected item image - int GetItemSelectedImage(const wxTreeItemId& item) const; + // get one of the images associated with the item (normal by default) + int GetItemImage(const wxTreeItemId& item, + wxTreeItemIcon which = wxTreeItemIcon_Normal) const; // get the data associated with the item wxTreeItemData *GetItemData(const wxTreeItemId& item) const; @@ -270,10 +269,9 @@ public: // set items label void SetItemText(const wxTreeItemId& item, const wxString& text); - // set the normal item image - void SetItemImage(const wxTreeItemId& item, int image); - // set the selected item image - void SetItemSelectedImage(const wxTreeItemId& item, int image); + // get one of the images associated with the item (normal by default) + void SetItemImage(const wxTreeItemId& item, int image, + wxTreeItemIcon which = wxTreeItemIcon_Normal) const; // associate some data with the item void SetItemData(const wxTreeItemId& item, wxTreeItemData *data); @@ -433,6 +431,16 @@ public: // NB: this function is not reentrant and not MT-safe (FIXME)! void SortChildren(const wxTreeItemId& item); + // deprecated functions: use Set/GetItemImage directly + // get the selected item image + int GetItemSelectedImage(const wxTreeItemId& item) const + { return GetItemImage(item, wxTreeItemIcon_Selected); } + // set the selected item image + void SetItemSelectedImage(const wxTreeItemId& item, int image) + { SetItemImage(item, image, wxTreeItemIcon_Selected); } + + // implementation + // callbacks void OnPaint( wxPaintEvent &event ); void OnSetFocus( wxFocusEvent &event ); diff --git a/include/wx/generic/wizard.h b/include/wx/generic/wizard.h new file mode 100644 index 0000000000..987113b877 --- /dev/null +++ b/include/wx/generic/wizard.h @@ -0,0 +1,62 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: generic/wizard.h +// Purpose: declaration of generic wxWizard class +// Author: Vadim Zeitlin +// Modified by: +// Created: 28.09.99 +// RCS-ID: $Id$ +// Copyright: (c) 1999 Vadim Zeitlin +// Licence: wxWindows license +/////////////////////////////////////////////////////////////////////////////// + +// ---------------------------------------------------------------------------- +// wxWizard +// ---------------------------------------------------------------------------- + +class wxWizard : public wxWizardBase +{ +public: + // ctor + wxWizard(wxWindow *parent = NULL, + int id = -1, + const wxString& title = wxEmptyString, + const wxBitmap& bitmap = wxNullBitmap, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize); + + // implement base class pure virtuals + virtual bool RunWizard(wxWizardPage *firstPage); + virtual wxWizardPage *GetCurrentPage() const; + + // implementation only from now on + // ------------------------------- + + // is the wizard running? + bool IsRunning() const { return m_page != NULL; } + + // show the prev/next page, but call TransferDataFromWindow on the current + // page first and return FALSE without changing the page if it returns + // FALSE + bool ShowPage(wxWizardPage *page, bool goingForward = TRUE); + +private: + // event handlers + void OnCancel(wxCommandEvent& event); + void OnBackOrNext(wxCommandEvent& event); + + // wizard dimensions + int m_x, m_y; // the origin for the pages + int m_width, // the size of the page itself + m_height; // (total width is m_width + m_x) + + // wizard state + wxWizardPage *m_page; // the current page or NULL + + // wizard controls + wxButton *m_btnPrev, // the "" or "Finish" button + + DECLARE_DYNAMIC_CLASS(wxWizard) + DECLARE_EVENT_TABLE() +}; + diff --git a/include/wx/msw/font.h b/include/wx/msw/font.h index 36642fd414..78a836caac 100644 --- a/include/wx/msw/font.h +++ b/include/wx/msw/font.h @@ -54,6 +54,9 @@ public: virtual ~wxFont(); + // assignment + wxFont& operator=(const wxFont& font); + // implement base class pure virtuals virtual int GetPointSize() const; virtual int GetFamily() const; diff --git a/include/wx/msw/frame.h b/include/wx/msw/frame.h index f5df0290d1..722f4bf695 100644 --- a/include/wx/msw/frame.h +++ b/include/wx/msw/frame.h @@ -177,9 +177,6 @@ protected: virtual void DoGetSize(int *width, int *height) const; virtual void DoGetPosition(int *x, int *y) const; - virtual void DoSetSize(int x, int y, - int width, int height, - int sizeFlags = wxSIZE_AUTO); virtual void DoSetClientSize(int width, int height); // a plug in for MDI frame classes which need to do something special when diff --git a/include/wx/msw/notebook.h b/include/wx/msw/notebook.h index 1a5dde10c1..265274a036 100644 --- a/include/wx/msw/notebook.h +++ b/include/wx/msw/notebook.h @@ -18,20 +18,11 @@ // ---------------------------------------------------------------------------- // headers // ---------------------------------------------------------------------------- + #ifndef _DYNARRAY_H #include #endif //_DYNARRAY_H -// This is a work-around for missing defines in gcc-2.95 headers -#ifndef TCS_RIGHT -#define TCS_RIGHT 0x0002 -#endif -#ifndef TCS_VERTICAL -#define TCS_VERTICAL 0x0080 -#endif -#ifndef TCS_BOTTOM -#define TCS_BOTTOM TCS_RIGHT -#endif // ---------------------------------------------------------------------------- // types // ---------------------------------------------------------------------------- diff --git a/include/wx/msw/treectrl.h b/include/wx/msw/treectrl.h index 313018797d..b193782490 100644 --- a/include/wx/msw/treectrl.h +++ b/include/wx/msw/treectrl.h @@ -149,11 +149,7 @@ public: // accessors: set/get the item associated with this node void SetId(const wxTreeItemId& id) { m_itemId = id; } -#ifdef __WATCOMC__ - const wxTreeItemId GetId() const { return m_itemId; } -#else - const wxTreeItemId& GetId() const { return (wxTreeItemId&) m_itemId; } -#endif + const wxTreeItemId GetId() const { return *this; } }; // ---------------------------------------------------------------------------- @@ -197,10 +193,10 @@ public: unsigned int GetIndent() const; void SetIndent(unsigned int indent); - // spacing is the number of pixels between the start and the Text - // not implemented under wxMSW + // spacing is the number of pixels between the start and the Text + // not implemented under wxMSW unsigned int GetSpacing() const { return 18; } // return wxGTK default - void SetSpacing(unsigned int ) {} + void SetSpacing(unsigned int WXUNUSED(spacing)) { } // image list: these functions allow to associate an image list with // the control and retrieve it. Note that the control does _not_ delete @@ -228,10 +224,9 @@ public: // retrieve items label wxString GetItemText(const wxTreeItemId& item) const; - // get the normal item image - int GetItemImage(const wxTreeItemId& item) const; - // get the selected item image - int GetItemSelectedImage(const wxTreeItemId& item) const; + // get one of the images associated with the item (normal by default) + int GetItemImage(const wxTreeItemId& item, + wxTreeItemIcon which = wxTreeItemIcon_Normal) const; // get the data associated with the item wxTreeItemData *GetItemData(const wxTreeItemId& item) const; @@ -240,10 +235,9 @@ public: // set items label void SetItemText(const wxTreeItemId& item, const wxString& text); - // set the normal item image - void SetItemImage(const wxTreeItemId& item, int image); - // set the selected item image - void SetItemSelectedImage(const wxTreeItemId& item, int image); + // get one of the images associated with the item (normal by default) + void SetItemImage(const wxTreeItemId& item, int image, + wxTreeItemIcon which = wxTreeItemIcon_Normal); // associate some data with the item void SetItemData(const wxTreeItemId& item, wxTreeItemData *data); @@ -452,6 +446,14 @@ public: void SetImageList(wxImageList *imageList, int) { SetImageList(imageList); } + // use Set/GetItemImage directly + // get the selected item image + int GetItemSelectedImage(const wxTreeItemId& item) const + { return GetItemImage(item, wxTreeItemIcon_Selected); } + // set the selected item image + void SetItemSelectedImage(const wxTreeItemId& item, int image) + { SetItemImage(item, image, wxTreeItemIcon_Selected); } + // implementation // -------------- virtual bool MSWCommand(WXUINT param, WXWORD id); @@ -465,7 +467,7 @@ protected: // SetImageList helper void SetAnyImageList(wxImageList *imageList, int which); - wxTextCtrl* m_textCtrl; // used while editing the item label + wxTextCtrl *m_textCtrl; // used while editing the item label wxImageList *m_imageListNormal, // images for tree elements *m_imageListState; // special images for app defined states @@ -485,10 +487,23 @@ private: int image, int selectedImage, wxTreeItemData *data); + int DoGetItemImageFromData(const wxTreeItemId& item, + wxTreeItemIcon which) const; + void DoSetItemImageFromData(const wxTreeItemId& item, + int image, + wxTreeItemIcon which) const; void DoSetItemImages(const wxTreeItemId& item, int image, int imageSel); void DeleteTextCtrl(); + // support for additional item images + friend class wxTreeItemIndirectData; + void SetIndirectItemData(const wxTreeItemId& item, + wxTreeItemIndirectData *data); + bool HasIndirectData(const wxTreeItemId& item) const; + + wxArrayTreeItemIds m_itemsWithIndirectData; + DECLARE_DYNAMIC_CLASS(wxTreeCtrl) }; diff --git a/include/wx/treectrl.h b/include/wx/treectrl.h index b6d81ef686..631c3393ac 100644 --- a/include/wx/treectrl.h +++ b/include/wx/treectrl.h @@ -12,10 +12,21 @@ // constants // ---------------------------------------------------------------------------- +// enum for different images associated with a treectrl item +enum wxTreeItemIcon +{ + wxTreeItemIcon_Normal, // not selected, not expanded + wxTreeItemIcon_Selected, // selected, not expanded + wxTreeItemIcon_Expanded, // not selected, expanded + wxTreeItemIcon_SelectedExpanded, // selected, expanded + wxTreeItemIcon_Max +}; + +// tree ctrl default name #ifdef __WXMSW__ -WXDLLEXPORT_DATA(extern const char*) wxTreeCtrlNameStr; + WXDLLEXPORT_DATA(extern const char*) wxTreeCtrlNameStr; #else -#define wxTreeCtrlNameStr "wxTreeCtrl" + #define wxTreeCtrlNameStr "wxTreeCtrl" #endif // ---------------------------------------------------------------------------- diff --git a/include/wx/wizard.h b/include/wx/wizard.h index 0c9e577700..10f124d7dc 100644 --- a/include/wx/wizard.h +++ b/include/wx/wizard.h @@ -15,7 +15,7 @@ #define _WX_WIZARD_H_ // ---------------------------------------------------------------------------- -// headers +// headers and other simple declarations // ---------------------------------------------------------------------------- #ifndef WX_PRECOMP @@ -24,11 +24,87 @@ #include "wx/event.h" // wxEVT_XXX constants #endif // WX_PRECOMP +// forward declarations +class WXDLLEXPORT wxWizard; + +// ---------------------------------------------------------------------------- +// wxWizardPage is one of the wizards screen: it must know what are the +// following and preceding pages (which may be NULL for the first/last page). +// +// Other than GetNext/Prev() functions, wxWizardPage is just a panel and may be +// used as such (i.e. controls may be placed directly on it &c). +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxWizardPage : public wxPanel +{ +public: + // ctor: no other parameters are needed because the wizard will resize and + // reposition the page anyhow + wxWizardPage(wxWizard *parent); + + // these functions are used by the wizard to show another page when the + // user chooses "Back" or "Next" button + virtual wxWizardPage *GetPrev() const = 0; + virtual wxWizardPage *GetNext() const = 0; + +private: + DECLARE_ABSTRACT_CLASS(wxWizardPage) +}; + +// ---------------------------------------------------------------------------- +// wxWizardPageSimple just returns the pointers given to the ctor and is useful +// to create a simple wizard where the order of pages never changes. +// +// OTOH, it is also possible to dynamicly decide which page to return (i.e. +// depending on the user's choices) as the wizard sample shows - in order to do +// this, you must derive from wxWizardPage directly. +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxWizardPageSimple : public wxWizardPage +{ +public: + // ctor takes the previous and next pages + wxWizardPageSimple(wxWizard *parent = NULL, // let it be default ctor too + wxWizardPage *prev = (wxWizardPage *)NULL, + wxWizardPage *next = (wxWizardPage *)NULL) + : wxWizardPage(parent) + { + m_prev = prev; + m_next = next; + } + + // the pointers may be also set later - but before starting the wizard + void SetPrev(wxWizardPage *prev) { m_prev = prev; } + void SetNext(wxWizardPage *next) { m_next = next; } + + // a convenience function to make the pages follow each other + static void Chain(wxWizardPageSimple *first, wxWizardPageSimple *second) + { + wxCHECK_RET( first && second, + _T("NULL passed to wxWizardPageSimple::Chain") ); + + first->SetNext(second); + second->SetPrev(first); + } + + // base class pure virtuals + virtual wxWizardPage *GetPrev() const; + virtual wxWizardPage *GetNext() const; + +private: + // pointers are private, the derived classes shouldn't mess with them - + // just derive from wxWizardPage directly to implement different behaviour + wxWizardPage *m_prev, + *m_next; + + DECLARE_DYNAMIC_CLASS(wxWizardPageSimple) +}; + // ---------------------------------------------------------------------------- // wxWizard // ---------------------------------------------------------------------------- -class WXDLLEXPORT wxWizard : public wxDialog +class WXDLLEXPORT wxWizardBase : public wxDialog { public: // create the wizard control @@ -39,40 +115,38 @@ public: const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize); - // wizard construction: add/insert new page into it - // adds a page at the end - virtual void AddPage(wxPanel *page) = 0; - // adds a page before the page nPage (the new page will have this index) - virtual void InsertPage(int nPage, wxPanel *page) = 0; - - // executes the wizard, returns TRUE if it was successfully finished, FALSE - // if user cancelled it - virtual bool RunWizard() = 0; + // executes the wizard starting from the given page, returns TRUE if it was + // successfully finished, FALSE if user cancelled it + virtual bool RunWizard(wxWizardPage *firstPage) = 0; // get the current page (NULL if RunWizard() isn't running) - virtual wxPanel *GetCurrentPage() const = 0; - -private: - DECLARE_DYNAMIC_CLASS(wxWizard) + virtual wxWizardPage *GetCurrentPage() const = 0; }; +// include the real class declaration +#include "wx/generic/wizard.h" + // ---------------------------------------------------------------------------- -// wxWizardEvent class represents an event generated by the wizard +// wxWizardEvent class represents an event generated by the wizard: this event +// is first sent to the page itself and, if not processed there, goes up the +// window hierarchy as usual // ---------------------------------------------------------------------------- class WXDLLEXPORT wxWizardEvent : public wxNotifyEvent { public: - wxWizardEvent(wxEventType type = wxEVT_NULL, int id = 0); - - // get the previously active page or -1 if none - int GetOldPage() const { return m_pageOld; } + wxWizardEvent(wxEventType type = wxEVT_NULL, + int id = -1, + bool direction = TRUE); - // get the current page or -1 if none - int GetPage() const { return m_page; } + // for EVT_WIZARD_PAGE_CHANGING, return TRUE if we're going forward or + // FALSE otherwise and for EVT_WIZARD_PAGE_CHANGED return TRUE if we came + // from the previous page and FALSE if we returned from the next one + // (this function doesn't make sense for CANCEL events) + bool GetDirection() const { return m_direction; } private: - int m_pageOld, m_page; + bool m_direction; DECLARE_DYNAMIC_CLASS(wxWizardEvent) }; @@ -83,7 +157,7 @@ private: typedef void (wxEvtHandler::*wxWizardEventFunction)(wxWizardEvent&); -// notifies that the page has just been changed +// notifies that the page has just been changed (can't be vetoed) #define EVT_WIZARD_PAGE_CHANGED(id, fn) { wxEVT_WIZARD_PAGE_CHANGED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxWizardEventFunction) & fn, (wxObject *)NULL }, // the user pressed "" button and the page is going to be diff --git a/samples/listctrl/listtest.cpp b/samples/listctrl/listtest.cpp index 13731a6ed3..f8a8a18f3a 100644 --- a/samples/listctrl/listtest.cpp +++ b/samples/listctrl/listtest.cpp @@ -482,7 +482,7 @@ void MyListCtrl::OnSetInfo(wxListEvent& WXUNUSED(event)) text->WriteText("OnSetInfo\n"); } -void MyListCtrl::OnSelected(wxListEvent& WXUNUSED(event)) +void MyListCtrl::OnSelected(wxListEvent& event) { if ( !wxGetApp().GetTopWindow() ) return; @@ -491,6 +491,20 @@ void MyListCtrl::OnSelected(wxListEvent& WXUNUSED(event)) if ( !text ) return; + wxListItem info; + info.m_itemId = event.m_itemIndex; + info.m_col = 1; + info.m_mask = wxLIST_MASK_TEXT; + if ( GetItem(info) ) + { + *text << "Value of the 2nd field of the selected item: " + << info.m_text << '\n'; + } + else + { + wxFAIL_MSG("wxListCtrl::GetItem() failed"); + } + text->WriteText("OnSelected\n"); } diff --git a/samples/mdi/mdi.cpp b/samples/mdi/mdi.cpp index 45474995f1..d22f58af32 100644 --- a/samples/mdi/mdi.cpp +++ b/samples/mdi/mdi.cpp @@ -255,7 +255,7 @@ void MyFrame::OnNewWindow(wxCommandEvent& WXUNUSED(event) ) subframe->Show(TRUE); } -void MyFrame::OnSize(wxSizeEvent& WXUNUSED(event) ) +void MyFrame::OnSize(wxSizeEvent& WXUNUSED(event)) { int w, h; GetClientSize(&w, &h); diff --git a/samples/treectrl/bitmaps/file2.bmp b/samples/treectrl/bitmaps/file2.bmp new file mode 100644 index 0000000000000000000000000000000000000000..e812d6925f40c96dd60a70391dffcc325671aabf GIT binary patch literal 246 zcmb77u?>JQ3^Ni-#Q@?8?qKH~=AO{C-}EFV)?gPQ|vY5syfFq)-GNQHlM{HwKiPD_E1e*gdg literal 0 HcmV?d00001 diff --git a/samples/treectrl/bitmaps/file2.ico b/samples/treectrl/bitmaps/file2.ico new file mode 100644 index 0000000000000000000000000000000000000000..b1059f953ac241d4603e4d4a3945bf391fac006b GIT binary patch literal 318 zcma)$yA6Oa3`8#y5~3m%EtG7*Y8inx+him*2=9`H0wm79^DmAp1uVuWV-M2e2;JFW z(11#%>6;`8S4usgq$;HlJ*dr9t22nXW%Px# literal 0 HcmV?d00001 diff --git a/samples/treectrl/bitmaps/folder1.ico b/samples/treectrl/bitmaps/folder1.ico index 387080ef43b64d5dfd834aa2cb1c487d459f5230..a84318433d48337a6ec69fd4b7eeb3a5b904fd8d 100644 GIT binary patch literal 318 zcmbVFISzm@409zO(21FmKX%DjiGk<9*k2Keq1f$$5Cg)Aol8l8K#MU#m;*2>lIl!k zz(55`(>F1I4znJpOi@Z<)Sxy;t;$H6TB@JmT=3jrekQ^E*o5zOziZB=J?FJ9DXr@9 K@cm`~_FpfKR&uof literal 318 zcma)&F%m*C2t;3IEK;Vjw)Bp_kTNqKNK205Ei5eZcaz3KM;BNKOn?N6q_u`|E^xG$ zIdhT~4r0j3pC~{|#BySVWTw0eV=7}fl1ZF0eL?LLQD2)8^?5V?KdZSARhRC)2Uj)m WEH!=~x%OCZbN#33fARv4xj*bZ8&yI8 diff --git a/samples/treectrl/bitmaps/folder2.bmp b/samples/treectrl/bitmaps/folder2.bmp new file mode 100644 index 0000000000000000000000000000000000000000..35fedba962e0accf24a09879b654eafe8a6e0380 GIT binary patch literal 246 zcmZ?r{l)+RWk5;;hy|dSk%0v)(EuccxFHxO2bN#}%77#r8Xy#q1Tq;895?`^K@$JL z2t)u`VDdjm2uJ`iDgerZz>f|vX!!BF8Uz}CeBTZN#PcDhHv9l;+R@R`|G&Gsx*sG4 IG#J@J0LHU(N&o-= literal 0 HcmV?d00001 diff --git a/samples/treectrl/bitmaps/folder2.ico b/samples/treectrl/bitmaps/folder2.ico new file mode 100644 index 0000000000000000000000000000000000000000..ca50cdcdd75ecdd4f9b9c59ef3fca785b013f942 GIT binary patch literal 318 zcmbV_trEi^5QLYRm^xH-WZw~kJSHNRC?2Dgyj9z&AiL1Ih)%xa_Wp)Dz|p+-5H|;0 z73u2Cbccxw)UHPo0Y1by0+lIht&AG9{?M8-I!!Ig_NA~O@4`8`Wb35-2_og^UHo5< YeJS(P!z`60gjM@rX1epcJIU}W zJbS@LCD6d+kw&PsvY;KcfvIP8_9LweY>}jB7{$$SiK`)t$xxgT#Xpb|=Ral^ylYuU E4~Mx*tN;K2 literal 0 HcmV?d00001 diff --git a/samples/treectrl/bitmaps/folder3.ico b/samples/treectrl/bitmaps/folder3.ico new file mode 100644 index 0000000000000000000000000000000000000000..ebbb9dbfbfbb8c152414eb75ee07d0a369f72a56 GIT binary patch literal 318 zcmbu2u?>JQ3bJ7lt>J~Y8eTMGEGME2Ik*LG(g2C{)-)31`beX3zit literal 0 HcmV?d00001 diff --git a/samples/treectrl/icon3.xpm b/samples/treectrl/icon3.xpm new file mode 100644 index 0000000000..a6b8b5feb5 --- /dev/null +++ b/samples/treectrl/icon3.xpm @@ -0,0 +1,45 @@ +/* XPM */ +static char *icon2_xpm[] = { +/* width height num_colors chars_per_pixel */ +" 32 32 6 1", +/* colors */ +". c #b2c0dc", +"# c #000000", +"a c #c0c0c0", +"b c #808080", +"c c #ffff00", +"d c #ffffff", +/* pixels */ +"................................", +"................................", +"......bbbbbbbbbb................", +"......bbbbbbbbbb................", +"....bbccaaccaaccbb..............", +"....bbccaaccaaccbb..............", +"..bbccaaccaaccaaccbbbbbbbbbbbb..", +"..bbccaaccaaccaaccbbbbbbbbbbbb..", +"..bbddddddddddddddddddddddddbb##", +"..bbddddddddddddddddddddddddbb##", +"..bbddccaaccaaccaaccaaccaaccbb##", +"..bbddccaaccaaccaaccaaccaaccbb##", +"..bbddaaccaaccaaccaaccaaccaabb##", +"..bbddaaccaaccaaccaaccaaccaabb##", +"..bbddccaaccaaccaaccaaccaaccbb##", +"..bbddccaaccaaccaaccaaccaaccbb##", +"..bbddaaccaaccaaccaaccaaccaabb##", +"..bbddaaccaaccaaccaaccaaccaabb##", +"..bbddccaaccaaccaaccaaccaaccbb##", +"..bbddccaaccaaccaaccaaccaaccbb##", +"..bbddaaccaaccaaccaaccaaccaabb##", +"..bbddaaccaaccaaccaaccaaccaabb##", +"..bbddccaaccaaccaaccaaccaaccbb##", +"..bbddccaaccaaccaaccaaccaaccbb##", +"..bbbbbbbbbbbbbbbbbbbbbbbbbbbb##", +"..bbbbbbbbbbbbbbbbbbbbbbbbbbbb##", +"....############################", +"....############################", +"................................", +"................................", +"................................", +"................................" +}; diff --git a/samples/treectrl/treetest.cpp b/samples/treectrl/treetest.cpp index 8335f176b7..873b881083 100644 --- a/samples/treectrl/treetest.cpp +++ b/samples/treectrl/treetest.cpp @@ -33,19 +33,19 @@ #include "math.h" -//#ifdef __WXMSW__ +#ifdef __WXMSW__ #define NO_MULTIPLE_SELECTION #define NO_VARIABLE_HEIGHT -//#endif +#endif #include "treetest.h" // under Windows the icons are in the .rc file #ifndef __WXMSW__ -#ifdef NO_VARIABLE_HEIGHT #include "icon1.xpm" -#endif #include "icon2.xpm" + #include "icon3.xpm" + #include "icon4.xpm" #include "mondrian.xpm" #endif @@ -92,7 +92,9 @@ BEGIN_EVENT_TABLE(MyTreeCtrl, wxTreeCtrl) EVT_TREE_BEGIN_LABEL_EDIT(TreeTest_Ctrl, MyTreeCtrl::OnBeginLabelEdit) EVT_TREE_END_LABEL_EDIT(TreeTest_Ctrl, MyTreeCtrl::OnEndLabelEdit) EVT_TREE_DELETE_ITEM(TreeTest_Ctrl, MyTreeCtrl::OnDeleteItem) +#if 0 // there are so many of those that logging them causes flicker EVT_TREE_GET_INFO(TreeTest_Ctrl, MyTreeCtrl::OnGetInfo) +#endif EVT_TREE_SET_INFO(TreeTest_Ctrl, MyTreeCtrl::OnSetInfo) EVT_TREE_ITEM_EXPANDED(TreeTest_Ctrl, MyTreeCtrl::OnItemExpanded) EVT_TREE_ITEM_EXPANDING(TreeTest_Ctrl, MyTreeCtrl::OnItemExpanding) @@ -187,12 +189,12 @@ MyFrame::MyFrame(const wxString& title, int x, int y, int w, int h) wxTR_HAS_BUTTONS | wxTR_EDIT_LABELS | #ifndef NO_MULTIPLE_SELECTION - wxTR_MULTIPLE | + wxTR_MULTIPLE | #endif #ifndef NO_VARIABLE_HEIGHT - wxTR_HAS_VARIABLE_ROW_HEIGHT | + wxTR_HAS_VARIABLE_ROW_HEIGHT | #endif - wxSUNKEN_BORDER); + wxSUNKEN_BORDER); wxTextCtrl *textCtrl = new wxTextCtrl(this, -1, "", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxSUNKEN_BORDER); @@ -440,6 +442,9 @@ MyTreeCtrl::MyTreeCtrl(wxWindow *parent, const wxWindowID id, m_imageListNormal->Add(wxBitmap("bitmap1", wxBITMAP_TYPE_BMP_RESOURCE)); # endif m_imageListNormal->Add(wxBitmap("bitmap2", wxBITMAP_TYPE_BMP_RESOURCE)); + m_imageListNormal->Add(wxBitmap("bitmap3", wxBITMAP_TYPE_BMP_RESOURCE)); + m_imageListNormal->Add(wxBitmap("bitmap4", wxBITMAP_TYPE_BMP_RESOURCE)); + m_imageListNormal->Add(wxBitmap("bitmap5", wxBITMAP_TYPE_BMP_RESOURCE)); #else # ifndef NO_VARIABLE_HEIGHT m_imageListNormal->Add(image.ConvertToBitmap()); @@ -447,6 +452,9 @@ MyTreeCtrl::MyTreeCtrl(wxWindow *parent, const wxWindowID id, m_imageListNormal->Add(wxICON(icon1)); # endif m_imageListNormal->Add(wxICON(icon2)); + m_imageListNormal->Add(wxICON(icon3)); + m_imageListNormal->Add(wxICON(icon4)); + m_imageListNormal->Add(wxICON(icon5)); #endif SetImageList(m_imageListNormal); @@ -481,21 +489,32 @@ void MyTreeCtrl::AddItemsRecursively(const wxTreeItemId& idParent, { if ( depth > 0 ) { + bool hasChildren = depth > 1; + wxString str; for ( size_t n = 0; n < numChildren; n++ ) { // at depth 1 elements won't have any more children - if (depth == 1) - str.Printf("%s child %d.%d", "File", folder, n + 1); - else + if ( hasChildren ) str.Printf("%s child %d", "Folder", n + 1); + else + str.Printf("%s child %d.%d", "File", folder, n + 1); + // here we pass to AppendItem() normal and selected item images (we + // suppose that selected image follows the normal one in the enum) int image = depth == 1 ? TreeCtrlIcon_File : TreeCtrlIcon_Folder; - wxTreeItemId id = AppendItem(idParent, str, image, image, + wxTreeItemId id = AppendItem(idParent, str, image, image + 1, new MyTreeItemData(str)); + // and now we also set the expanded one (only for the folders) + if ( hasChildren ) + { + SetItemImage(id, TreeCtrlIcon_FolderOpened, + wxTreeItemIcon_Expanded); + } + // remember the last child for OnEnsureVisible() - if ( depth == 1 && n == numChildren - 1 ) + if ( !hasChildren && n == numChildren - 1 ) { m_lastItem = id; } @@ -512,6 +531,7 @@ void MyTreeCtrl::AddTestItemsToTree(size_t numChildren, wxTreeItemId rootId = AddRoot("Root", TreeCtrlIcon_Folder, TreeCtrlIcon_Folder, new MyTreeItemData("Root item")); + SetItemImage(rootId, TreeCtrlIcon_FolderOpened, wxTreeItemIcon_Expanded); AddItemsRecursively(rootId, numChildren, depth, 0); } diff --git a/samples/treectrl/treetest.h b/samples/treectrl/treetest.h index dec33dc30a..67562e087b 100644 --- a/samples/treectrl/treetest.h +++ b/samples/treectrl/treetest.h @@ -34,7 +34,10 @@ public: enum { TreeCtrlIcon_File, - TreeCtrlIcon_Folder + TreeCtrlIcon_FileSelected, + TreeCtrlIcon_Folder, + TreeCtrlIcon_FolderSelected, + TreeCtrlIcon_FolderOpened }; MyTreeCtrl() { } diff --git a/samples/treectrl/treetest.rc b/samples/treectrl/treetest.rc index 550dc2f135..f055b67d4f 100644 --- a/samples/treectrl/treetest.rc +++ b/samples/treectrl/treetest.rc @@ -1,10 +1,17 @@ mondrian ICON "mondrian.ico" aaaa ICON "mondrian.ico" + #include "wx/msw/wx.rc" icon1 ICON "bitmaps\\file1.ico" -icon2 ICON "bitmaps\\folder1.ico" +icon2 ICON "bitmaps\\file2.ico" +icon3 ICON "bitmaps\\folder1.ico" +icon4 ICON "bitmaps\\folder2.ico" +icon5 ICON "bitmaps\\folder3.ico" bitmap1 BITMAP "bitmaps\\file1.bmp" -bitmap2 BITMAP "bitmaps\\folder1.bmp" +bitmap2 BITMAP "bitmaps\\file2.bmp" +bitmap3 BITMAP "bitmaps\\folder1.bmp" +bitmap4 BITMAP "bitmaps\\folder2.bmp" +bitmap5 BITMAP "bitmaps\\folder3.bmp" diff --git a/samples/wizard/wiztest.cpp b/samples/wizard/wiztest.cpp index df1c8f3aff..3d94b0c929 100644 --- a/samples/wizard/wiztest.cpp +++ b/samples/wizard/wiztest.cpp @@ -63,19 +63,19 @@ IMPLEMENT_APP(MyApp) // overriding TransferDataFromWindow() - of course, in a real program, the // check wouldn't be so trivial and the data will be probably saved somewhere // too -class wxCheckboxPage : public wxPanel +class wxValidationPage : public wxWizardPageSimple { public: - wxCheckboxPage(wxWizard *parent) : wxPanel(parent) + wxValidationPage(wxWizard *parent) : wxWizardPageSimple(parent) { - m_checkbox = new wxCheckBox(this, -1, "Check me", wxPoint(20, 20)); + m_checkbox = new wxCheckBox(this, -1, "&Check me"); } virtual bool TransferDataFromWindow() { - if ( m_checkbox->GetValue() ) + if ( !m_checkbox->GetValue() ) { - wxMessageBox("Clear the checkbox first", "No way", + wxMessageBox("Check the checkbox first!", "No way", wxICON_WARNING | wxOK, this); return FALSE; @@ -88,10 +88,108 @@ private: wxCheckBox *m_checkbox; }; +// This is a more complicated example of validity checking: using events we may +// allow to return to the previous page, but not to proceed. It also +// demonstrates how to intercept [Cancel] button press. +class wxRadioboxPage : public wxWizardPageSimple +{ +public: + // directions in which we allow the user to proceed from this page + enum + { + Forward, Backward, Both, Neither + }; + + wxRadioboxPage(wxWizard *parent) : wxWizardPageSimple(parent) + { + // should correspond to the enum above + static wxString choices[] = { "forward", "backward", "both", "neither" }; + + m_radio = new wxRadioBox(this, -1, "Allow to proceed:", + wxPoint(5, 5), wxDefaultSize, + WXSIZEOF(choices), choices, + 1, wxRA_SPECIFY_COLS); + m_radio->SetSelection(Both); + } + + // wizard event handlers + void OnWizardCancel(wxWizardEvent& event) + { + if ( wxMessageBox("Do you really want to cancel?", "Question", + wxICON_QUESTION | wxYES_NO, this) != wxYES ) + { + // not confirmed + event.Veto(); + } + } + + void OnWizardPageChanging(wxWizardEvent& event) + { + int sel = m_radio->GetSelection(); + + if ( sel == Both ) + return; + + if ( event.GetDirection() && sel == Forward ) + return; + + if ( !event.GetDirection() && sel == Backward ) + return; + + wxMessageBox("You can't go there", "Not allowed", + wxICON_WARNING | wxOK, this); + + event.Veto(); + } + +private: + wxRadioBox *m_radio; + + DECLARE_EVENT_TABLE() +}; + +// this shows how to dynamically (i.e. during run-time) arrange the page order +class wxCheckboxPage : public wxWizardPage +{ +public: + wxCheckboxPage(wxWizard *parent, + wxWizardPage *prev, + wxWizardPage *next) + : wxWizardPage(parent) + { + m_prev = prev; + m_next = next; + + (void)new wxStaticText(this, -1, "Try checking the box below and\n" + "then going back and clearing it"); + + m_checkbox = new wxCheckBox(this, -1, "&Skip the next page", + wxPoint(5, 30)); + } + + // implement wxWizardPage functions + virtual wxWizardPage *GetPrev() const { return m_prev; } + virtual wxWizardPage *GetNext() const + { + return m_checkbox->GetValue() ? m_next->GetNext() : m_next; + } + +private: + wxWizardPage *m_prev, + *m_next; + + wxCheckBox *m_checkbox; +}; + // ============================================================================ // implementation // ============================================================================ +BEGIN_EVENT_TABLE(wxRadioboxPage, wxWizardPageSimple) + EVT_WIZARD_PAGE_CHANGING(-1, wxRadioboxPage::OnWizardPageChanging) + EVT_WIZARD_CANCEL(-1, wxRadioboxPage::OnWizardCancel) +END_EVENT_TABLE() + // ---------------------------------------------------------------------------- // the application class // ---------------------------------------------------------------------------- @@ -109,18 +207,30 @@ bool MyApp::OnInit() "Absolutely Useless Wizard", bmpWizard); - wxPanel *panel = new wxPanel(wizard); - (void)new wxStaticText(panel, -1, + // a wizard page may be either an object of predefined class + wxWizardPageSimple *page1 = new wxWizardPageSimple(wizard); + (void)new wxStaticText(page1, -1, "This wizard doesn't help you to do anything at " "all.\n" "\n" "The next pages will present you with more useless " "controls."); - wizard->AddPage(panel); - wizard->AddPage(new wxCheckboxPage(wizard)); + // ... or a derived class + wxRadioboxPage *page3 = new wxRadioboxPage(wizard); + wxValidationPage *page4 = new wxValidationPage(wizard); + + // set the page order using a convenience function - could also use + // SetNext/Prev directly as below + wxWizardPageSimple::Chain(page3, page4); + + // this page is not a wxWizardPageSimple, so we use SetNext/Prev to insert + // it into the chain of pages + wxCheckboxPage *page2 = new wxCheckboxPage(wizard, page1, page3); + page1->SetNext(page2); + page3->SetPrev(page2); - if ( wizard->RunWizard() ) + if ( wizard->RunWizard(page1) ) { wxMessageBox("The wizard successfully completed", "That's all", wxICON_INFORMATION | wxOK); diff --git a/src/common/docview.cpp b/src/common/docview.cpp index b0e3db14b2..0f16972439 100644 --- a/src/common/docview.cpp +++ b/src/common/docview.cpp @@ -56,6 +56,7 @@ #include "wx/choicdlg.h" #include "wx/docview.h" #include "wx/confbase.h" +#include "wx/file.h" #include #include diff --git a/src/common/url.cpp b/src/common/url.cpp index 6c735d5599..1e142f1ef1 100644 --- a/src/common/url.cpp +++ b/src/common/url.cpp @@ -387,14 +387,11 @@ wxString wxURL::ConvertToValidURI(const wxString& uri) wxString wxURL::ConvertFromURI(const wxString& uri) { - int code; - int i; wxString new_uri; - new_uri.Empty(); - - i = 0; + size_t i = 0; while (i= _T('A') && uri[i] <= _T('F')) diff --git a/src/generic/prop.cpp b/src/generic/prop.cpp index 3aa479d8e4..a44800754d 100644 --- a/src/generic/prop.cpp +++ b/src/generic/prop.cpp @@ -379,9 +379,7 @@ void wxPropertyValue::Copy(wxPropertyValue& copyFrom) #endif #endif // if 0 - // TODO: check if this is right. MB - // - (*this) = s; + (*this) = (bool)(s != 0); return ; } diff --git a/src/generic/wizard.cpp b/src/generic/wizard.cpp index 2131e993d3..4d70f33f01 100644 --- a/src/generic/wizard.cpp +++ b/src/generic/wizard.cpp @@ -44,95 +44,57 @@ WX_DEFINE_ARRAY(wxPanel *, wxArrayPages); -// ---------------------------------------------------------------------------- -// wxWizardGeneric - generic implementation of wxWizard -// ---------------------------------------------------------------------------- - -class wxWizardGeneric : public wxWizard -{ -public: - // ctor - wxWizardGeneric(wxWindow *parent, - int id, - const wxString& title, - const wxBitmap& bitmap, - const wxPoint& pos, - const wxSize& size); - - // implement base class pure virtuals - virtual void AddPage(wxPanel *page); - virtual void InsertPage(int nPage, wxPanel *page); - virtual bool RunWizard(); - virtual wxPanel *GetCurrentPage() const; - - // implementation only from now on - // ------------------------------- - - // is the wizard running? - bool IsRunning() const { return m_page != -1; } - - // show the given page calling TransferDataFromWindow - if it returns - // FALSE, the old page is not hidden and the function returns FALSE - bool ShowPage(size_t page); - - // get the current page assuming the wizard is running - wxPanel *DoGetCurrentPage() const - { - wxASSERT_MSG( IsRunning(), _T("no current page!") ); - - return m_pages[(size_t)m_page]; - } - - // place the given page correctly and hide it - void DoAddPage(wxPanel *page); - -private: - // event handlers - void OnCancel(wxCommandEvent& event); - void OnBackOrNext(wxCommandEvent& event); - - // wizard dimensions - int m_x, m_y; // the origin for the pages - int m_width, // the size of the page itself - m_height; // (total width is m_width + m_x) - - // wizard state - int m_page; // the current page or -1 - wxArrayPages m_pages; // the array with all wizards pages - - // wizard controls - wxButton *m_btnPrev, // the "" or "Finish" button - - DECLARE_EVENT_TABLE() -}; - // ---------------------------------------------------------------------------- // event tables and such // ---------------------------------------------------------------------------- -BEGIN_EVENT_TABLE(wxWizardGeneric, wxDialog) - EVT_BUTTON(wxID_CANCEL, wxWizardGeneric::OnCancel) - EVT_BUTTON(-1, wxWizardGeneric::OnBackOrNext) +BEGIN_EVENT_TABLE(wxWizard, wxDialog) + EVT_BUTTON(wxID_CANCEL, wxWizard::OnCancel) + EVT_BUTTON(-1, wxWizard::OnBackOrNext) END_EVENT_TABLE() -IMPLEMENT_ABSTRACT_CLASS(wxWizard, wxDialog) +IMPLEMENT_DYNAMIC_CLASS(wxWizard, wxDialog) +IMPLEMENT_ABSTRACT_CLASS(wxWizardPage, wxPanel) +IMPLEMENT_DYNAMIC_CLASS(wxWizardPageSimple, wxWizardPage) IMPLEMENT_DYNAMIC_CLASS(wxWizardEvent, wxNotifyEvent) // ============================================================================ // implementation // ============================================================================ +// ---------------------------------------------------------------------------- +// wxWizardPage +// ---------------------------------------------------------------------------- + +wxWizardPage::wxWizardPage(wxWizard *parent) : wxPanel(parent) +{ + // initially the page is hidden, it's shown only when it becomes current + Hide(); +} + +// ---------------------------------------------------------------------------- +// wxWizardPageSimple +// ---------------------------------------------------------------------------- + +wxWizardPage *wxWizardPageSimple::GetPrev() const +{ + return m_prev; +} + +wxWizardPage *wxWizardPageSimple::GetNext() const +{ + return m_next; +} // ---------------------------------------------------------------------------- // generic wxWizard implementation // ---------------------------------------------------------------------------- -wxWizardGeneric::wxWizardGeneric(wxWindow *parent, - int id, - const wxString& title, - const wxBitmap& bitmap, - const wxPoint& pos, - const wxSize& size) +wxWizard::wxWizard(wxWindow *parent, + int id, + const wxString& title, + const wxBitmap& bitmap, + const wxPoint& pos, + const wxSize& size) { // constants defining the dialog layout // ------------------------------------ @@ -161,7 +123,7 @@ wxWizardGeneric::wxWizardGeneric(wxWindow *parent, // init members // ------------ - m_page = -1; + m_page = (wxWizardPage *)NULL; // create controls // --------------- @@ -191,12 +153,12 @@ wxWizardGeneric::wxWizardGeneric(wxWindow *parent, int x = X_MARGIN; int y = m_y + m_height + BITMAP_Y_MARGIN; - -#if wxUSE_STATLINE + +#if wxUSE_STATLINE (void)new wxStaticLine(this, -1, wxPoint(x, y), wxSize(m_x + m_width - x, 2)); #endif - + x = m_x + m_width - 3*sizeBtn.x - BUTTON_MARGIN; y += SEPARATOR_LINE_MARGIN; m_btnPrev = new wxButton(this, -1, _("< &Back"), wxPoint(x, y), sizeBtn); @@ -223,83 +185,94 @@ wxWizardGeneric::wxWizardGeneric(wxWindow *parent, } } -bool wxWizardGeneric::ShowPage(size_t page) +bool wxWizard::ShowPage(wxWizardPage *page, bool goingForward) { - wxCHECK_MSG( page < m_pages.GetCount(), FALSE, - _T("invalid wizard page index") ); + wxASSERT_MSG( page != m_page, _T("this is useless") ); - wxASSERT_MSG( page != (size_t)m_page, _T("this is useless") ); + // we'll use this to decide whether we have to change the label of this + // button or not (initially the label is "Next") + bool btnLabelWasNext = TRUE; - size_t last = m_pages.GetCount() - 1; - bool mustChangeNextBtnLabel = (size_t)m_page == last || page == last; - - if ( m_page != -1 ) + if ( m_page ) { - wxPanel *panel = DoGetCurrentPage(); - if ( !panel->TransferDataFromWindow() ) + // ask the current page first + if ( !m_page->TransferDataFromWindow() ) + { + // the page data is incorrect + return FALSE; + } + + // send the event to the old page + wxWizardEvent event(wxEVT_WIZARD_PAGE_CHANGING, GetId(), goingForward); + if ( m_page->GetEventHandler()->ProcessEvent(event) && + !event.IsAllowed() ) + { + // vetoed by the page return FALSE; + } - panel->Hide(); + m_page->Hide(); + + btnLabelWasNext = m_page->GetNext() != (wxWizardPage *)NULL; } + // set the new one m_page = page; - DoGetCurrentPage()->Show(); - // update the buttons state - m_btnPrev->Enable(m_page != 0); - if ( mustChangeNextBtnLabel ) + // is this the end? + if ( !m_page ) { - m_btnNext->SetLabel((size_t)m_page == last ? _("&Finish") - : _("&Next >")); - } + // terminate successfully + EndModal(wxID_OK); - return TRUE; -} + return TRUE; + } -void wxWizardGeneric::DoAddPage(wxPanel *page) -{ - page->Hide(); - page->SetSize(m_x, m_y, m_width, m_height); -} + // send the event to the new page now + wxWizardEvent event(wxEVT_WIZARD_PAGE_CHANGED, GetId(), goingForward); + (void)m_page->GetEventHandler()->ProcessEvent(event); -void wxWizardGeneric::AddPage(wxPanel *page) -{ - m_pages.Add(page); + // position and show the new page + (void)m_page->TransferDataToWindow(); + m_page->SetSize(m_x, m_y, m_width, m_height); + m_page->Show(); - DoAddPage(page); -} + // and update the buttons state + m_btnPrev->Enable(m_page->GetPrev() != (wxWizardPage *)NULL); -void wxWizardGeneric::InsertPage(int nPage, wxPanel *page) -{ - m_pages.Insert(page, nPage); - if ( nPage < m_page ) + if ( btnLabelWasNext != (m_page->GetNext() != (wxWizardPage *)NULL) ) { - // the indices of all pages after the inserted one are shifted by 1 - m_page++; + // need to update + m_btnNext->SetLabel(btnLabelWasNext ? _("&Finish") : _("&Next >")); } + // nothing to do: the label was already correct - DoAddPage(page); + return TRUE; } -bool wxWizardGeneric::RunWizard() +bool wxWizard::RunWizard(wxWizardPage *firstPage) { - wxCHECK_MSG( m_pages.GetCount() != 0, FALSE, _T("can't run empty wizard") ); + wxCHECK_MSG( firstPage, FALSE, _T("can't run empty wizard") ); // can't return FALSE here because there is no old page - (void)ShowPage(0u); + (void)ShowPage(firstPage, TRUE /* forward */); return ShowModal() == wxID_OK; } -wxPanel *wxWizardGeneric::GetCurrentPage() const +wxWizardPage *wxWizard::GetCurrentPage() const { - return IsRunning() ? DoGetCurrentPage() : (wxPanel *)NULL; + return m_page; } -void wxWizardGeneric::OnCancel(wxCommandEvent& WXUNUSED(event)) +void wxWizard::OnCancel(wxCommandEvent& WXUNUSED(event)) { + // this function probably can never be called when we don't have an active + // page, but a small extra check won't hurt + wxWindow *win = m_page ? (wxWindow *)m_page : (wxWindow *)this; + wxWizardEvent event(wxEVT_WIZARD_CANCEL, GetId()); - if ( !GetEventHandler()->ProcessEvent(event) || event.IsAllowed() ) + if ( !win->GetEventHandler()->ProcessEvent(event) || event.IsAllowed() ) { // no objections - close the dialog EndModal(wxID_CANCEL); @@ -307,53 +280,52 @@ void wxWizardGeneric::OnCancel(wxCommandEvent& WXUNUSED(event)) //else: request to Cancel ignored } -void wxWizardGeneric::OnBackOrNext(wxCommandEvent& event) +void wxWizard::OnBackOrNext(wxCommandEvent& event) { wxASSERT_MSG( (event.GetEventObject() == m_btnNext) || (event.GetEventObject() == m_btnPrev), _T("unknown button") ); - int delta = event.GetEventObject() == m_btnNext ? 1 : -1; - int page = m_page + delta; + bool forward = event.GetEventObject() == m_btnNext; - wxASSERT_MSG( page >= 0, _T("'Back' button should have been disabled!") ); - - if ( (size_t)page == m_pages.GetCount() ) + wxWizardPage *page; + if ( forward ) { - // check that we have valid data in the last page too - if ( m_pages.Last()->TransferDataFromWindow() ) - { - // that's all, folks! - EndModal(wxID_OK); - } + page = m_page->GetNext(); } - else + else // back { - // just pass to the next page (or may be not - but we don't care here) - (void)ShowPage(page); + page = m_page->GetPrev(); + + wxASSERT_MSG( page, _T("\"ProcessEvent(event); -} - bool wxFrame::Show(bool show) { int cshow; diff --git a/src/msw/notebook.cpp b/src/msw/notebook.cpp index fe431a1234..67cc03440b 100644 --- a/src/msw/notebook.cpp +++ b/src/msw/notebook.cpp @@ -62,6 +62,23 @@ // hide the ugly cast #define m_hwnd (HWND)GetHWND() +// ---------------------------------------------------------------------------- +// constants +// ---------------------------------------------------------------------------- + +// This is a work-around for missing defines in gcc-2.95 headers +#ifndef TCS_RIGHT + #define TCS_RIGHT 0x0002 +#endif + +#ifndef TCS_VERTICAL + #define TCS_VERTICAL 0x0080 +#endif + +#ifndef TCS_BOTTOM + #define TCS_BOTTOM TCS_RIGHT +#endif + // ---------------------------------------------------------------------------- // event table // ---------------------------------------------------------------------------- diff --git a/src/msw/treectrl.cpp b/src/msw/treectrl.cpp index 8171cae0a3..a6eb5f572f 100644 --- a/src/msw/treectrl.cpp +++ b/src/msw/treectrl.cpp @@ -110,6 +110,115 @@ private: const wxTreeCtrl *m_tree; }; +// internal class for getting the selected items +class TraverseSelections : public wxTreeTraversal +{ +public: + TraverseSelections(const wxTreeCtrl *tree, + wxArrayTreeItemIds& selections) + : wxTreeTraversal(tree), m_selections(selections) + { + m_selections.Empty(); + + DoTraverse(tree->GetRootItem()); + } + + virtual bool OnVisit(const wxTreeItemId& item) + { + if ( GetTree()->IsItemChecked(item) ) + { + m_selections.Add(item); + } + + return TRUE; + } + +private: + wxArrayTreeItemIds& m_selections; +}; + +// internal class for counting tree items +class TraverseCounter : public wxTreeTraversal +{ +public: + TraverseCounter(const wxTreeCtrl *tree, + const wxTreeItemId& root, + bool recursively) + : wxTreeTraversal(tree) + { + m_count = 0; + + DoTraverse(root, recursively); + } + + virtual bool OnVisit(const wxTreeItemId& item) + { + m_count++; + + return TRUE; + } + + size_t GetCount() const { return m_count; } + +private: + size_t m_count; +}; + +// ---------------------------------------------------------------------------- +// This class is needed for support of different images: the Win32 common +// control natively supports only 2 images (the normal one and another for the +// selected state). We wish to provide support for 2 more of them for folder +// items (i.e. those which have children): for expanded state and for expanded +// selected state. For this we use this structure to store the additional items +// images. +// +// There is only one problem with this: when we retrieve the item's data, we +// don't know whether we get a pointer to wxTreeItemData or +// wxTreeItemIndirectData. So we have to maintain a list of all items which +// have indirect data inside the listctrl itself. +// ---------------------------------------------------------------------------- +class wxTreeItemIndirectData +{ +public: + // ctor associates this data with the item and the real item data becomes + // available through our GetData() method + wxTreeItemIndirectData(wxTreeCtrl *tree, const wxTreeItemId& item) + { + for ( size_t n = 0; n < WXSIZEOF(m_images); n++ ) + { + m_images[n] = -1; + } + + // save the old data + m_data = tree->GetItemData(item); + + // and set ourselves as the new one + tree->SetIndirectItemData(item, this); + } + + // dtor deletes the associated data as well + ~wxTreeItemIndirectData() { delete m_data; } + + // accessors + // get the real data associated with the item + wxTreeItemData *GetData() const { return m_data; } + // change it + void SetData(wxTreeItemData *data) { m_data = data; } + + // do we have such image? + bool HasImage(wxTreeItemIcon which) const { return m_images[which] != -1; } + // get image + int GetImage(wxTreeItemIcon which) const { return m_images[which]; } + // change it + void SetImage(int image, wxTreeItemIcon which) { m_images[which] = image; } + +private: + // all the images associated with the item + int m_images[wxTreeItemIcon_Max]; + + wxTreeItemData *m_data; +}; + // ---------------------------------------------------------------------------- // macros // ---------------------------------------------------------------------------- @@ -216,7 +325,6 @@ bool wxTreeCtrl::Create(wxWindow *parent, SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW)); SetForegroundColour(wxWindow::GetParent()->GetForegroundColour()); - // VZ: this is some experimental code which may be used to get the // TVS_CHECKBOXES style functionality for comctl32.dll < 4.71. // AFAIK, the standard DLL does about the same thing anyhow. @@ -350,35 +458,6 @@ void wxTreeCtrl::SetStateImageList(wxImageList *imageList) SetAnyImageList(m_imageListState = imageList, TVSIL_STATE); } -// internal class for counting tree items - -class TraverseCounter : public wxTreeTraversal -{ -public: - TraverseCounter(const wxTreeCtrl *tree, - const wxTreeItemId& root, - bool recursively) - : wxTreeTraversal(tree) - { - m_count = 0; - - DoTraverse(root, recursively); - } - - virtual bool OnVisit(const wxTreeItemId& item) - { - m_count++; - - return TRUE; - } - - size_t GetCount() const { return m_count; } - -private: - size_t m_count; -}; - - size_t wxTreeCtrl::GetChildrenCount(const wxTreeItemId& item, bool recursively) const { @@ -414,6 +493,46 @@ void wxTreeCtrl::SetItemText(const wxTreeItemId& item, const wxString& text) DoSetItem(&tvItem); } +int wxTreeCtrl::DoGetItemImageFromData(const wxTreeItemId& item, + wxTreeItemIcon which) const +{ + wxTreeViewItem tvItem(item, TVIF_PARAM); + if ( !DoGetItem(&tvItem) ) + { + return -1; + } + + return ((wxTreeItemIndirectData *)tvItem.lParam)->GetImage(which); +} + +void wxTreeCtrl::DoSetItemImageFromData(const wxTreeItemId& item, + int image, + wxTreeItemIcon which) const +{ + wxTreeViewItem tvItem(item, TVIF_PARAM); + if ( !DoGetItem(&tvItem) ) + { + return; + } + + wxTreeItemIndirectData *data = ((wxTreeItemIndirectData *)tvItem.lParam); + + data->SetImage(image, which); + + // make sure that we have selected images as well + if ( which == wxTreeItemIcon_Normal && + !data->HasImage(wxTreeItemIcon_Selected) ) + { + data->SetImage(image, wxTreeItemIcon_Selected); + } + + if ( which == wxTreeItemIcon_Expanded && + !data->HasImage(wxTreeItemIcon_SelectedExpanded) ) + { + data->SetImage(image, wxTreeItemIcon_SelectedExpanded); + } +} + void wxTreeCtrl::DoSetItemImages(const wxTreeItemId& item, int image, int imageSel) @@ -424,36 +543,90 @@ void wxTreeCtrl::DoSetItemImages(const wxTreeItemId& item, DoSetItem(&tvItem); } -int wxTreeCtrl::GetItemImage(const wxTreeItemId& item) const +int wxTreeCtrl::GetItemImage(const wxTreeItemId& item, + wxTreeItemIcon which) const { - wxTreeViewItem tvItem(item, TVIF_IMAGE); - DoGetItem(&tvItem); + if ( HasIndirectData(item) ) + { + return DoGetItemImageFromData(item, which); + } - return tvItem.iImage; -} + UINT mask; + switch ( which ) + { + default: + wxFAIL_MSG( _T("unknown tree item image type") ); -void wxTreeCtrl::SetItemImage(const wxTreeItemId& item, int image) -{ - // NB: at least in version 5.00.0518.9 of comctl32.dll we need to always - // change both normal and selected image - otherwise the change simply - // doesn't take place! - DoSetItemImages(item, image, GetItemSelectedImage(item)); -} + case wxTreeItemIcon_Normal: + mask = TVIF_IMAGE; + break; -int wxTreeCtrl::GetItemSelectedImage(const wxTreeItemId& item) const -{ - wxTreeViewItem tvItem(item, TVIF_SELECTEDIMAGE); + case wxTreeItemIcon_Selected: + mask = TVIF_SELECTEDIMAGE; + break; + + case wxTreeItemIcon_Expanded: + case wxTreeItemIcon_SelectedExpanded: + return -1; + } + + wxTreeViewItem tvItem(item, mask); DoGetItem(&tvItem); - return tvItem.iSelectedImage; + return mask == TVIF_IMAGE ? tvItem.iImage : tvItem.iSelectedImage; } -void wxTreeCtrl::SetItemSelectedImage(const wxTreeItemId& item, int image) +void wxTreeCtrl::SetItemImage(const wxTreeItemId& item, int image, + wxTreeItemIcon which) { + int imageNormal, imageSel; + switch ( which ) + { + default: + wxFAIL_MSG( _T("unknown tree item image type") ); + + case wxTreeItemIcon_Normal: + imageNormal = image; + imageSel = GetItemSelectedImage(item); + break; + + case wxTreeItemIcon_Selected: + imageNormal = GetItemImage(item); + imageSel = image; + break; + + case wxTreeItemIcon_Expanded: + case wxTreeItemIcon_SelectedExpanded: + if ( !HasIndirectData(item) ) + { + // we need to get the old images first, because after we create + // the wxTreeItemIndirectData GetItemXXXImage() will use it to + // get the images + imageNormal = GetItemImage(item); + imageSel = GetItemSelectedImage(item); + + // if it doesn't have it yet, add it + wxTreeItemIndirectData *data = new + wxTreeItemIndirectData(this, item); + + // copy the data to the new location + data->SetImage(imageNormal, wxTreeItemIcon_Normal); + data->SetImage(imageSel, wxTreeItemIcon_Selected); + } + + DoSetItemImageFromData(item, image, which); + + // reset the normal/selected images because we won't use them any + // more - now they're stored inside the indirect data + imageNormal = + imageSel = I_IMAGECALLBACK; + break; + } + // NB: at least in version 5.00.0518.9 of comctl32.dll we need to always // change both normal and selected image - otherwise the change simply // doesn't take place! - DoSetItemImages(item, GetItemImage(item), image); + DoSetItemImages(item, imageNormal, imageSel); } wxTreeItemData *wxTreeCtrl::GetItemData(const wxTreeItemId& item) const @@ -464,14 +637,55 @@ wxTreeItemData *wxTreeCtrl::GetItemData(const wxTreeItemId& item) const return NULL; } - return (wxTreeItemData *)tvItem.lParam; + if ( HasIndirectData(item) ) + { + return ((wxTreeItemIndirectData *)tvItem.lParam)->GetData(); + } + else + { + return (wxTreeItemData *)tvItem.lParam; + } } void wxTreeCtrl::SetItemData(const wxTreeItemId& item, wxTreeItemData *data) { wxTreeViewItem tvItem(item, TVIF_PARAM); - tvItem.lParam = (LPARAM)data; - DoSetItem(&tvItem); + + if ( HasIndirectData(item) ) + { + if ( DoGetItem(&tvItem) ) + { + ((wxTreeItemIndirectData *)tvItem.lParam)->SetData(data); + } + else + { + wxFAIL_MSG( _T("failed to change tree items data") ); + } + } + else + { + tvItem.lParam = (LPARAM)data; + DoSetItem(&tvItem); + } +} + +void wxTreeCtrl::SetIndirectItemData(const wxTreeItemId& item, + wxTreeItemIndirectData *data) +{ + // this should never happen because it's unnecessary and will probably lead + // to crash too because the code elsewhere supposes that the pointer the + // wxTreeItemIndirectData has is a real wxItemData and not + // wxTreeItemIndirectData as well + wxASSERT_MSG( !HasIndirectData(item), _T("setting indirect data twice?") ); + + SetItemData(item, (wxTreeItemData *)data); + + m_itemsWithIndirectData.Add(item); +} + +bool wxTreeCtrl::HasIndirectData(const wxTreeItemId& item) const +{ + return m_itemsWithIndirectData.Index(item) != wxNOT_FOUND; } void wxTreeCtrl::SetItemHasChildren(const wxTreeItemId& item, bool has) @@ -655,34 +869,6 @@ void wxTreeCtrl::SetItemCheck(const wxTreeItemId& item, bool check) DoSetItem(&tvItem); } -// internal class for getting the selected - -class TraverseSelections : public wxTreeTraversal -{ -public: - TraverseSelections(const wxTreeCtrl *tree, - wxArrayTreeItemIds& selections) - : wxTreeTraversal(tree), m_selections(selections) - { - m_selections.Empty(); - - DoTraverse(tree->GetRootItem()); - } - - virtual bool OnVisit(const wxTreeItemId& item) - { - if ( GetTree()->IsItemChecked(item) ) - { - m_selections.Add(item); - } - - return TRUE; - } - -private: - wxArrayTreeItemIds& m_selections; -}; - size_t wxTreeCtrl::GetSelections(wxArrayTreeItemIds& selections) const { TraverseSelections selector(this, selections); @@ -704,8 +890,9 @@ wxTreeItemId wxTreeCtrl::DoInsertItem(const wxTreeItemId& parent, tvIns.hParent = (HTREEITEM) (WXHTREEITEM)parent; tvIns.hInsertAfter = (HTREEITEM) (WXHTREEITEM) hInsertAfter; - // This is how we insert the item as the first child: supply a NULL hInsertAfter - if (tvIns.hInsertAfter == (HTREEITEM) 0) + // this is how we insert the item as the first child: supply a NULL + // hInsertAfter + if ( !tvIns.hInsertAfter ) { tvIns.hInsertAfter = TVI_FIRST; } @@ -1302,8 +1489,21 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) // prefer to do it here ourself (otherwise deleting a tree // with many items is just too slow) NM_TREEVIEW* tv = (NM_TREEVIEW *)lParam; - wxTreeItemData *data = (wxTreeItemData *)tv->itemOld.lParam; - delete data; // may be NULL, ok + + wxTreeItemId item = event.m_item; + if ( HasIndirectData(item) ) + { + wxTreeItemIndirectData *data = (wxTreeItemIndirectData *) + tv->itemOld.lParam; + delete data; // can't be NULL here + + m_itemsWithIndirectData.Remove(item); + } + else + { + wxTreeItemData *data = (wxTreeItemData *)tv->itemOld.lParam; + delete data; // may be NULL, ok + } processed = TRUE; // Make sure we don't get called twice } @@ -1329,6 +1529,36 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) *result = !event.IsAllowed(); break; + case TVN_GETDISPINFO: + // NB: so far the user can't set the image himself anyhow, so do it + // anyway - but this may change later + if ( /* !processed && */ 1 ) + { + wxTreeItemId item = event.m_item; + TV_DISPINFO *info = (TV_DISPINFO *)lParam; + if ( info->item.mask & TVIF_IMAGE ) + { + info->item.iImage = + DoGetItemImageFromData + ( + item, + IsExpanded(item) ? wxTreeItemIcon_Expanded + : wxTreeItemIcon_Normal + ); + } + if ( info->item.mask & TVIF_SELECTEDIMAGE ) + { + info->item.iSelectedImage = + DoGetItemImageFromData + ( + item, + IsExpanded(item) ? wxTreeItemIcon_SelectedExpanded + : wxTreeItemIcon_Selected + ); + } + } + break; + //default: // for the other messages the return value is ignored and there is // nothing special to do -- 2.45.2