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
@@ -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}}
|
||||
\constfunc{int}{GetItemImage}{\param{const wxTreeItemId\& }{item},
|
||||
\param{wxTreeItemIcon }{which = wxTreeItemIcon\_Normal}}
|
||||
|
||||
Gets the normal item image.
|
||||
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}
|
||||
|
||||
|
@@ -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 );
|
||||
|
62
include/wx/generic/wizard.h
Normal file
@@ -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 <zeitlin@dptmaths.ens-cachan.fr>
|
||||
// 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 "<Back" button
|
||||
*m_btnNext; // the "Next>" or "Finish" button
|
||||
|
||||
DECLARE_DYNAMIC_CLASS(wxWizard)
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -18,20 +18,11 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _DYNARRAY_H
|
||||
#include <wx/dynarray.h>
|
||||
#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
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@@ -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)
|
||||
};
|
||||
|
||||
|
@@ -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
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@@ -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);
|
||||
wxWizardEvent(wxEventType type = wxEVT_NULL,
|
||||
int id = -1,
|
||||
bool direction = TRUE);
|
||||
|
||||
// get the previously active page or -1 if none
|
||||
int GetOldPage() const { return m_pageOld; }
|
||||
|
||||
// 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 "<Back" or "Next>" button and the page is going to be
|
||||
|
@@ -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");
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
|
BIN
samples/treectrl/bitmaps/file2.bmp
Normal file
After Width: | Height: | Size: 246 B |
BIN
samples/treectrl/bitmaps/file2.ico
Normal file
After Width: | Height: | Size: 318 B |
Before Width: | Height: | Size: 318 B After Width: | Height: | Size: 318 B |
BIN
samples/treectrl/bitmaps/folder2.bmp
Normal file
After Width: | Height: | Size: 246 B |
BIN
samples/treectrl/bitmaps/folder2.ico
Normal file
After Width: | Height: | Size: 318 B |
BIN
samples/treectrl/bitmaps/folder3.bmp
Normal file
After Width: | Height: | Size: 246 B |
BIN
samples/treectrl/bitmaps/folder3.ico
Normal file
After Width: | Height: | Size: 318 B |
45
samples/treectrl/icon3.xpm
Normal file
@@ -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##",
|
||||
"....############################",
|
||||
"....############################",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................"
|
||||
};
|
@@ -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);
|
||||
}
|
||||
|
@@ -34,7 +34,10 @@ public:
|
||||
enum
|
||||
{
|
||||
TreeCtrlIcon_File,
|
||||
TreeCtrlIcon_Folder
|
||||
TreeCtrlIcon_FileSelected,
|
||||
TreeCtrlIcon_Folder,
|
||||
TreeCtrlIcon_FolderSelected,
|
||||
TreeCtrlIcon_FolderOpened
|
||||
};
|
||||
|
||||
MyTreeCtrl() { }
|
||||
|
@@ -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"
|
||||
|
||||
|
@@ -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);
|
||||
|
||||
if ( wizard->RunWizard() )
|
||||
// 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(page1) )
|
||||
{
|
||||
wxMessageBox("The wizard successfully completed", "That's all",
|
||||
wxICON_INFORMATION | wxOK);
|
||||
|
@@ -56,6 +56,7 @@
|
||||
#include "wx/choicdlg.h"
|
||||
#include "wx/docview.h"
|
||||
#include "wx/confbase.h"
|
||||
#include "wx/file.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@@ -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<uri.Len()) {
|
||||
int code;
|
||||
if (uri[i] == _T('%')) {
|
||||
i++;
|
||||
if (uri[i] >= _T('A') && uri[i] <= _T('F'))
|
||||
|
@@ -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 ;
|
||||
}
|
||||
|
@@ -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 "<Back" button
|
||||
*m_btnNext; // the "Next>" 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
|
||||
// ---------------
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
panel->Hide();
|
||||
// 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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// send the event to the new page now
|
||||
wxWizardEvent event(wxEVT_WIZARD_PAGE_CHANGED, GetId(), goingForward);
|
||||
(void)m_page->GetEventHandler()->ProcessEvent(event);
|
||||
|
||||
// position and show the new page
|
||||
(void)m_page->TransferDataToWindow();
|
||||
m_page->SetSize(m_x, m_y, m_width, m_height);
|
||||
m_page->Show();
|
||||
|
||||
// and update the buttons state
|
||||
m_btnPrev->Enable(m_page->GetPrev() != (wxWizardPage *)NULL);
|
||||
|
||||
if ( btnLabelWasNext != (m_page->GetNext() != (wxWizardPage *)NULL) )
|
||||
{
|
||||
// need to update
|
||||
m_btnNext->SetLabel(btnLabelWasNext ? _("&Finish") : _("&Next >"));
|
||||
}
|
||||
// nothing to do: the label was already correct
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void wxWizardGeneric::DoAddPage(wxPanel *page)
|
||||
bool wxWizard::RunWizard(wxWizardPage *firstPage)
|
||||
{
|
||||
page->Hide();
|
||||
page->SetSize(m_x, m_y, m_width, m_height);
|
||||
}
|
||||
|
||||
void wxWizardGeneric::AddPage(wxPanel *page)
|
||||
{
|
||||
m_pages.Add(page);
|
||||
|
||||
DoAddPage(page);
|
||||
}
|
||||
|
||||
void wxWizardGeneric::InsertPage(int nPage, wxPanel *page)
|
||||
{
|
||||
m_pages.Insert(page, nPage);
|
||||
if ( nPage < m_page )
|
||||
{
|
||||
// the indices of all pages after the inserted one are shifted by 1
|
||||
m_page++;
|
||||
}
|
||||
|
||||
DoAddPage(page);
|
||||
}
|
||||
|
||||
bool wxWizardGeneric::RunWizard()
|
||||
{
|
||||
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!") );
|
||||
wxWizardPage *page;
|
||||
if ( forward )
|
||||
{
|
||||
page = m_page->GetNext();
|
||||
}
|
||||
else // back
|
||||
{
|
||||
page = m_page->GetPrev();
|
||||
|
||||
if ( (size_t)page == m_pages.GetCount() )
|
||||
{
|
||||
// check that we have valid data in the last page too
|
||||
if ( m_pages.Last()->TransferDataFromWindow() )
|
||||
{
|
||||
// that's all, folks!
|
||||
EndModal(wxID_OK);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// just pass to the next page (or may be not - but we don't care here)
|
||||
(void)ShowPage(page);
|
||||
wxASSERT_MSG( page, _T("\"<Back\" button should have been disabled") );
|
||||
}
|
||||
|
||||
// just pass to the new page (or may be not - but we don't care here)
|
||||
(void)ShowPage(page, forward);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// our public interface
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/* static */ wxWizard *wxWizard::Create(wxWindow *parent,
|
||||
int id,
|
||||
const wxString& title,
|
||||
const wxBitmap& bitmap,
|
||||
const wxPoint& pos,
|
||||
const wxSize& size)
|
||||
/* static */
|
||||
wxWizard *wxWizardBase::Create(wxWindow *parent,
|
||||
int id,
|
||||
const wxString& title,
|
||||
const wxBitmap& bitmap,
|
||||
const wxPoint& pos,
|
||||
const wxSize& size)
|
||||
{
|
||||
return new wxWizardGeneric(parent, id, title, bitmap, pos, size);
|
||||
return new wxWizard(parent, id, title, bitmap, pos, size);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxWizardEvent
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
wxWizardEvent::wxWizardEvent(wxEventType type, int id)
|
||||
wxWizardEvent::wxWizardEvent(wxEventType type, int id, bool direction)
|
||||
: wxNotifyEvent(type, id)
|
||||
{
|
||||
m_page = m_pageOld = -1;
|
||||
m_direction = direction;
|
||||
}
|
||||
|
||||
|
@@ -58,7 +58,8 @@ friend class WXDLLEXPORT wxFont;
|
||||
public:
|
||||
wxFontRefData()
|
||||
{
|
||||
Init();
|
||||
Init(12, wxDEFAULT, wxNORMAL, wxNORMAL, FALSE,
|
||||
"", wxFONTENCODING_DEFAULT);
|
||||
}
|
||||
|
||||
wxFontRefData(const wxFontRefData& data)
|
||||
|
@@ -241,15 +241,6 @@ void wxFrame::DoGetPosition(int *x, int *y) const
|
||||
*y = point.y;
|
||||
}
|
||||
|
||||
void wxFrame::DoSetSize(int x, int y, int width, int height, int sizeFlags)
|
||||
{
|
||||
wxWindow::DoSetSize(x, y, width, height, sizeFlags);
|
||||
|
||||
wxSizeEvent event(wxSize(width, height), m_windowId);
|
||||
event.SetEventObject( this );
|
||||
GetEventHandler()->ProcessEvent(event);
|
||||
}
|
||||
|
||||
bool wxFrame::Show(bool show)
|
||||
{
|
||||
int cshow;
|
||||
|
@@ -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
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@@ -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);
|
||||
if ( HasIndirectData(item) )
|
||||
{
|
||||
return DoGetItemImageFromData(item, which);
|
||||
}
|
||||
|
||||
UINT mask;
|
||||
switch ( which )
|
||||
{
|
||||
default:
|
||||
wxFAIL_MSG( _T("unknown tree item image type") );
|
||||
|
||||
case wxTreeItemIcon_Normal:
|
||||
mask = TVIF_IMAGE;
|
||||
break;
|
||||
|
||||
case wxTreeItemIcon_Selected:
|
||||
mask = TVIF_SELECTEDIMAGE;
|
||||
break;
|
||||
|
||||
case wxTreeItemIcon_Expanded:
|
||||
case wxTreeItemIcon_SelectedExpanded:
|
||||
return -1;
|
||||
}
|
||||
|
||||
wxTreeViewItem tvItem(item, mask);
|
||||
DoGetItem(&tvItem);
|
||||
|
||||
return tvItem.iImage;
|
||||
return mask == TVIF_IMAGE ? tvItem.iImage : tvItem.iSelectedImage;
|
||||
}
|
||||
|
||||
void wxTreeCtrl::SetItemImage(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, image, GetItemSelectedImage(item));
|
||||
}
|
||||
|
||||
int wxTreeCtrl::GetItemSelectedImage(const wxTreeItemId& item) const
|
||||
{
|
||||
wxTreeViewItem tvItem(item, TVIF_SELECTEDIMAGE);
|
||||
DoGetItem(&tvItem);
|
||||
|
||||
return tvItem.iSelectedImage;
|
||||
}
|
||||
|
||||
void wxTreeCtrl::SetItemSelectedImage(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, 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
|
||||
|