From: Vadim Zeitlin Date: Wed, 29 Sep 1999 22:47:56 +0000 (+0000) Subject: 1. Implemented support for different icons for different states (expanded, X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/74b31181b345aaaef0c967cc5707bef72ce0a405 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 --- 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 0000000000..e812d6925f Binary files /dev/null and b/samples/treectrl/bitmaps/file2.bmp differ diff --git a/samples/treectrl/bitmaps/file2.ico b/samples/treectrl/bitmaps/file2.ico new file mode 100644 index 0000000000..b1059f953a Binary files /dev/null and b/samples/treectrl/bitmaps/file2.ico differ diff --git a/samples/treectrl/bitmaps/folder1.ico b/samples/treectrl/bitmaps/folder1.ico index 387080ef43..a84318433d 100644 Binary files a/samples/treectrl/bitmaps/folder1.ico and b/samples/treectrl/bitmaps/folder1.ico differ diff --git a/samples/treectrl/bitmaps/folder2.bmp b/samples/treectrl/bitmaps/folder2.bmp new file mode 100644 index 0000000000..35fedba962 Binary files /dev/null and b/samples/treectrl/bitmaps/folder2.bmp differ diff --git a/samples/treectrl/bitmaps/folder2.ico b/samples/treectrl/bitmaps/folder2.ico new file mode 100644 index 0000000000..ca50cdcdd7 Binary files /dev/null and b/samples/treectrl/bitmaps/folder2.ico differ diff --git a/samples/treectrl/bitmaps/folder3.bmp b/samples/treectrl/bitmaps/folder3.bmp new file mode 100644 index 0000000000..dfc3c4fb8c Binary files /dev/null and b/samples/treectrl/bitmaps/folder3.bmp differ diff --git a/samples/treectrl/bitmaps/folder3.ico b/samples/treectrl/bitmaps/folder3.ico new file mode 100644 index 0000000000..ebbb9dbfbf Binary files /dev/null and b/samples/treectrl/bitmaps/folder3.ico differ 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