0ad/source/tools/atlas/AtlasUI/CustomControls/VirtualDirTreeCtrl/virtualdirtreectrl.h
2005-04-29 18:46:48 +00:00

472 lines
19 KiB
C++

/////////////////////////////////////////////////////////////////////////////
// Name: wxVirtualDirTreeCtrl.h
// Author: XX
// Created: Saturday, March 27, 2004 14:15:56
// Copyright: XX
/////////////////////////////////////////////////////////////////////////////
#ifndef __WXVIRTUALDIRTREECTRL_H__
#define __WXVIRTUALDIRTREECTRL_H__
//#ifdef __GNUG__
// #pragma interface "virtualdirtreectrl.cpp"
//#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include <wx/dynarray.h>
#include <wx/treectrl.h>
#include <wx/filesys.h>
#include <wx/imaglist.h>
enum
{
VDTC_TI_ROOT = 0,
VDTC_TI_DIR,
VDTC_TI_FILE
};
#ifndef LINUX
#define VDTC_DIR_FILESPEC _T("*.*")
#else
#define VDTC_DIR_FILESPEC _T("*")
#endif
/// Icon number for root
#define VDTC_ICON_ROOT 0
/// Icon number for a folder
#define VDTC_ICON_DIR 1
/// Icon number for file
#define VDTC_ICON_FILE 2
/// Minimal amount of levels to scan per run
#define VDTC_MIN_SCANDEPTH 2
/// No settings, take default
#define wxVDTC_DEFAULT 0
/** Instead of performing a smart reload per collapsed node, all items are loaded
into memory. NOTE: This can take a while! */
#define wxVDTC_RELOAD_ALL 1
/** Show a busy dialog to inform user, only valid when wxVDTC_RELOAD_ALL is set. Showing
a busy dialog on every smart expansion is not useful anyway */
#define wxVDTC_SHOW_BUSYDLG 2
/// Do not expand the root node after reloading
#define wxVDTC_NO_EXPAND 4
/// Do not call sort. Simply display files as they are located
#define wxVDTC_NO_SORT 8
/// Do not add files, only directories
#define wxVDTC_NO_FILES 16
/** \class VdtcTreeItemBase
This class is used to link the information of a file/root or folder node to a wxTreeItem
in the wxTreeCtrl.
To use more information in this class, inherit this with your own copy, and in the handler
wxVirtualDirTreeCtrl::OnCreateTreeItem, return your own class. This allows you to store more
information in this class.
For example; to return a different caption instead of the standard filename / directory, inherit this, and
redefine the VdtcTreeItemBase::GetCaption() member. The same goes for the VdtcTreeItemBase::GetIconId()
and VdtcTreeItemBase::GetSelectedIconId() functions if you redefined the bitmaps in the imagelist.
*/
class VdtcTreeItemBase : public wxTreeItemData
{
protected:
wxString _name;
int _type;
public:
/** Default constructor. Pass the parent of this node as a VdtcTreeItemBase object, the type
of this object (VDTC_TI_ROOT,VDTC_TI_DIR, VDTC_TI_FILE or added types but leave these
three in place), and the name of the object (i.e. filename or dir name). When deriving this
class make sure you call the constructor propertly. The types are of essence for some
internal functions. For example:
\code
class MyOwnData : public VdtcTreeItemBase
{
MyOwnData(int type, const wxString &name)
: VdtcTreeItemBase(type, name)
{
// do initialisation
}
}
\endcode
*/
VdtcTreeItemBase(int type, const wxString &name)
: _type(type)
, _name(name)
{
};
/** Default destructor */
~VdtcTreeItemBase()
{
// NOTE: do not delete the tree item
// because the tree item deletes this item data
};
/** Virtual function to report the caption back to the wxTreeCtrl to be added. If the caption should be
something else then the default name it gets from the file (or the root path when this node points
to a root item, inherit this class and redefine GetCaption
*/
virtual const wxString &GetCaption() const {
return _name;
};
/** Virtual function to return the icon ID this node should get. Per default it gets the ID of the
default image list. If you assigned more bitmaps (or different bitmaps) to the image list, return
the proper indices based upon the class it refers to. The ID's returned are:
- VDTC_ICON_ROOT: For root
- VDTC_ICON_DIR: For a directory
- VDTC_ICON_FILE: For a file
*/
virtual int GetIconId() const {
switch(_type)
{
case VDTC_TI_ROOT:
return VDTC_ICON_ROOT;
case VDTC_TI_DIR:
return VDTC_ICON_DIR;
case VDTC_TI_FILE:
return VDTC_ICON_FILE;
}
return -1;
};
/** Virtual function to return the selected icon ID this node should get. Per default there is no icon
associated with a selection. If you would like a selection, inherit this class and redefine this function
to return a proper id.
*/
virtual int GetSelectedIconId() const {
return -1;
};
/** Gets this name. The name of the root is the base path of the whole directory, the
name of a file node is the filename, and from a dir node the directory name.
\sa IsDir, IsFile, IsRoot */
const wxString &GetName() {
return _name;
};
/** Returns true if this is of type VDTC_TI_DIR */
bool IsDir() const {
return _type == VDTC_TI_DIR;
};
/** Returns true if this is of type VDTC_TI_ROOT */
bool IsRoot() const {
return _type == VDTC_TI_ROOT;
};
/** Returns true if this is of type VDTC_TI_FILE */
bool IsFile() const {
return _type == VDTC_TI_FILE;
};
};
// the formal definition of the array of pointers for tree item base
WX_DEFINE_ARRAY(VdtcTreeItemBase *, VdtcTreeItemBaseArray);
/**
\class wxVirtualDirTreeCtrl
A class which allows the user to browse through a 'virtual' treectrl, fully customizable when it's derived.
The wxVirtualDirTreeCtrl can be used for displaying the directory structure in a tree ctrl just like the
wxDirCtrl, but has much more advantages and flexibility for the developer. A list of some of the functionality
embedded:
See the main page to read more about this control.
*/
class wxVirtualDirTreeCtrl : public wxTreeCtrl
{
private:
/** File extensions list */
wxArrayString _extensions;
/** Icons image list */
wxImageList *_iconList;
/** Extra flags */
int _flags;
/** Scans from given dir, for 'level' depth and with present extensions. This will
reload the directory on that level. If there are tree items associated with the 'reloaded'
items they will be deleted first. */
int ScanFromDir(VdtcTreeItemBase *item, const wxFileName &path, int level);
/** Get files for current dir */
void GetFiles(VdtcTreeItemBase *parent, VdtcTreeItemBaseArray &items, const wxFileName &path);
/** get dirs in current dir */
void GetDirectories(VdtcTreeItemBase *parent, VdtcTreeItemBaseArray &items, const wxFileName &path);
void AppendPathRecursively(VdtcTreeItemBase *b, wxFileName &dir, bool useRoot = true);
/** Adds items on this level to the parent dir associated wxTreeCtrl item */
void AddItemsToTreeCtrl(VdtcTreeItemBase *item, VdtcTreeItemBaseArray &items);
/** Sorts items with qsort algorithm */
void SortItems(VdtcTreeItemBaseArray &items, int left, int right);
/** Built in swap algoritm */
void SwapItem(VdtcTreeItemBaseArray &items, int a, int b);
// -- event handlers --
void OnExpanding(wxTreeEvent &event);
protected:
/** This method can be used in the method OnAssignIcons. It returns a pointer to a newly created bitmap
holding the default icon image for a root node. NOTE: When this bitmap is assigned to the icon list,
don't forget to delete it! */
wxBitmap *CreateRootBitmap();
/** This method can be used in the method OnAssignIcons. It returns a pointer to a newly created bitmap
holding the default icon image for a folder node. NOTE: When this bitmap is assigned to the icon list,
don't forget to delete it! */
wxBitmap *CreateFolderBitmap();
/** This method can be used in the method OnAssignIcons. It returns a pointer to a newly created bitmap
holding the default icon image for a file node. NOTE: When this bitmap is assigned to the icon list,
don't forget to delete it! */
wxBitmap *CreateFileBitmap();
/** Inherited virtual function for SortChildren */
int OnCompareItems(const wxTreeItemId& item1, const wxTreeItemId& item2);
public:
/** Default constructor of this control. It is similar to the wxTreeCtrl */
wxVirtualDirTreeCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize, long style = wxTR_HAS_BUTTONS | wxTR_FULL_ROW_HIGHLIGHT,
const wxValidator& validator = wxDefaultValidator,
const wxString& name = _T("wxVirtualDirTreeCtrl"));
virtual ~wxVirtualDirTreeCtrl();
/** Returns the extra flags currently set set for wxVirtualDirTreeCtrl.
\sa SetRootPath */
int GetExtraFlags() const {
return _flags;
};
/** Sets the root path of the wxVirtualDirTreeCtrl. This will reset the view and restart the
process of notification, and all events that need to be called. Returns false when this
root path does not lead to any valid filesystem or directory. Set extra flags for
wxVirtualDirTreeCtrl when needed. The following flags are possible
- wxVDTC_DEFAULT
- wxVDTC_RELOAD_ALL
- wxVDTC_NO_EXPAND
- wxVDTC_SHOW_BUSYDLG
- wxVDTC_NO_SORT
- wxVDTC_NO_FILES */
bool SetRootPath(const wxString &root, int flags = wxVDTC_DEFAULT);
/** Resets the extensions to "*.*" as default (or "*" under linux). The extension will be used
upon next reload of the directory tree. In between extensions can be changed but will have
no effect upon the directory scanning mechanism until the next SetRootPath */
void ResetExtensions() {
_extensions.Clear();
_extensions.Add(VDTC_DIR_FILESPEC);
};
/** Returns the relative path of the item with the given wxTreeItemId. This doesn't include the
root node. This can be used in ExpandToPath(). A check is made if the object belonging to this
wxTreeItemId is of the type directory or file. In both cases the relative path (plus filename if
it is a file) is returned. When the object pointed out by wxTreeItemId is of the type root, an
empty wxFileName is returned. Be warned, these functions can take some time because the whole tree
structure is iterated from the top node down to the root */
wxFileName GetRelativePath(const wxTreeItemId &id);
/** Return full path of given node. This can also include the name of the file. This will be returned as
a wxFileName (with path and possible name) to be used further. Be warned, these functions can take some time because the whole tree
structure is iterated from the top node down to the root. */
wxFileName GetFullPath(const wxTreeItemId &id);
/** Returns TRUE when the item pointed out by wxTreeItemId is a root node internally, this means the
assigned VdtcTreeItemBase class is of type VDTC_TI_ROOT.
\sa VdtcTreeItemBase::IsRoot */
bool IsRootNode(const wxTreeItemId &id);
/** Returns TRUE when the item pointed out by wxTreeItemId is a directory node internally, this means the
assigned VdtcTreeItemBase class is of type VDTC_TI_DIR. For these types of nodes you can use i.e.
GetRelativePath() or GetFullPath() to retrieve the directory.
\sa VdtcTreeItemBase::IsDir, GetRelativePath, GetFullPath */
bool IsDirNode(const wxTreeItemId &id);
/** Returns TRUE when the item pointed out by wxTreeItemId is a file node internally, this means the
assigned VdtcTreeItemBase class is of type VDTC_TI_DIR. For these types of nodes you can use i.e.
GetRelativePath() or GetFullPath() to retrieve the directory plus filename.
\sa VdtcTreeItemBase::IsFile, GetRelativePath, GetFullPath */
bool IsFileNode(const wxTreeItemId &id);
/** Expands from root, to the given path. Every path in the wxFileName is looked up and expanded. When
a path section is not found, this method aborts and returns a wxTreeItemId with value 0. When it succeeds
the wxTreeItemId is returned of the last tree item that was expanded.
<b>A special note:</b> Don't include the root path of the current tree in the filename. This part of the path
is not used to scan. Use GetRelativePath to get the path up until a specific node. This method is useful
to expand earlier paths after restoring the window state.
\sa GetRelativePath */
wxTreeItemId ExpandToPath(const wxFileName &path);
/** Adds a file item. Be aware that this call does not add it to the wxTreeCtrl. This only creates an instance
of a VtdcTreeItemBase file node. The handler OnCreateTreeItem is called to allow the proper initialisation
of every newly created instance of the (inherited) VdtcTreeItemBase class. */
VdtcTreeItemBase *AddFileItem(const wxString &name);
/** Adds a directory item. Be aware that this call does not add it to the wxTreeCtrl. This only creates an instance
of a VtdcTreeItemBase directory node. The handler OnCreateTreeItem is called to allow the proper initialisation
of every newly created instance of the (inherited) VdtcTreeItemBase class. */
VdtcTreeItemBase *AddDirItem(const wxString &name);
/** Returns parent of the passed VdtcItemBase object. It will fetch the wxTreeItemId of this parent,
and return the VdtcTreeItemBase parent associated with it. If the associated item is nil, there is no
parent, this is most likely the root else an assertion failure occurs */
VdtcTreeItemBase *GetParent(VdtcTreeItemBase *item) const {
wxCHECK(item, 0);
wxTreeItemId p = GetItemParent(item->GetId());
if (! p.IsOk()) return NULL;
return (VdtcTreeItemBase *)GetItemData(p);
};
// --- handlers ---
/** This handler is called when the SetRootPath function is called. This call causes a re-initialisation of
the wxVirtualDirTreeCtrl. It can be useful to initialise the class that derived this class as well. The
root is passed as parameter to inform which root is going to be set. NOTE: When this method is called,
the following criteria is true:
- The tree is completely empty
- The path parameter is valid. When it's not valid this call is not made */
void OnSetRootPath(const wxString &root);
/** This virtual handler is used to allow the developer to assign custom icons to the
image list. Override this method to assign your own icons to the wxTreeCtrl. The default method
will assign a root bitmap, a folder bitmap and a file bitmap. The icons assigned can be
refered to in the OnFileName and OnDirectory handlers, to specify what icon should be used.
The default images can be used by these constants:
- VDTC_ICON_ROOT
- VDTC_ICON_DIR
- VDTC_ICON_FILE
The icon list contains icons which are 16x16 in size.
*/
virtual void OnAssignIcons(wxImageList &icons);
/** This handler provides must provide a VdtcTreeItemBase* instance to be used upon creation. If you
override this handler, you can return your own class, which might embed more information.
The type tells you what kind of element is created, a root item (VDTC_TI_ROOT), a dir item (VDTC_TI_DIR)
or a file item (VDTC_TI_FILE). Dependent upon the type you can return a different class based upon
VdtcTreeItemBase.
For example, this is the standard implementation:
\code
return new VdtcTreeItemBase(type, name);
\endcode
You could derive the wxVirtualDirTreeCtrl and VdtcTreeItemBase object and make this:
\code
switch(type)
{
case VDTC_TI_ROOT:
return new MyRootItem(type, name); // MyRootItem = class derived VdtcTreeItemBase
case VDTC_TI_DIR:
return new MyDirItem(type, name); // MyDirItem = class derived VdtcTreeItemBase
case VDTC_TI_FILE:
return new MyFileItem(type, name); // MyFileItem = class derived VdtcTreeItemBase
}
return 0;
\endcode
\sa VdtcTreeItemBase
*/
virtual VdtcTreeItemBase *OnCreateTreeItem(int type, const wxString &name);
/** This handler is called before the VdtcTreeItemBase item is added to the root. This will be the first item to be added
before all else is added.
If for some reason this root is denied to be added, return FALSE. If it may be added, return TRUE. If false is returned
then no other items are created, and the SetRootPath() function returns with FALSE notifying the caller that something
went wrong.
\sa VdtcTreeItemBase
*/
virtual bool OnAddRoot(VdtcTreeItemBase &item, const wxFileName &name);
/** This handler is called before a file VdtcTreeItemBase item is added to the tree. For every file added in the tree this
handler is called. It allows you to change the name or caption of the item, and also gain more information
or change the contents of the associated VdtcTreeItemBase class. The wxFileName contains the full path
of the item to be added, so it can be easily inspected, and tested for specific extensions, parts of the
name and what else.
If for some reason this item is denied to be added, return FALSE. If it may be added, return TRUE.
*/
virtual bool OnAddFile(VdtcTreeItemBase &item, const wxFileName &name);
/** This handler is called before a directory item is added to the tree. For every dir added in the tree this
handler is called. It allows you to change the name of the item or the caption, and also gain more information of the
directory, and check if specific files are present. The wxFileName contains the full path of the directory
to be added, so it can be easily inspected, and tested for specific criteria, parts of the name and what else.
If for some reason this item is denied to be added, return FALSE. If it may be added, return TRUE.
*/
virtual bool OnAddDirectory(VdtcTreeItemBase &item, const wxFileName &name);
/** This handler is called before the directory specified by 'path' is scanned. You can veto this scan by
returning 'false'. This way the scanning of all files and directories in this path is skipped. After this
handler, subsequent calls to OnAddFile, OnAddDirectory will be made for every file and directory
encountered in this level to be scanned. NOTE: When this scan is veto'd there will be no call
to OnDirectoryScanEnd because there was no scan. Also OnAddedItems is not called */
virtual bool OnDirectoryScanBegin(const wxFileName &path);
/** This handler is called when all files and all directories are scanned in the current dir and iterated in
the array passed to this method. Before the sorting algorithm is initiated, the developer is allowed to
take one last look at all the files, maybe delete some or act upon other criteria. The items parameter
contains the pointer array of all the items that are in the list, and the path parameter contains the
current path investigated. NOTE: If you want to delete an item from the array, delete it with delete
operator and remove the pointer from the list. */
virtual void OnDirectoryScanEnd(VdtcTreeItemBaseArray &items, const wxFileName &path);
/** This handler is called the very moment after all items are added to the tree control. The parent parameter
contains the tree node to which the items are added. They are already sorted and ready. E.g. when you don't
want to use the internal sort algoritm this is a nice place to call SortChildren on the parent node */
virtual void OnAddedItems(const wxTreeItemId &parent);
/** This handler is called during the sorting of the tree control items. Return < 0 when a < b, > 0 when a > b
and 0 when a == b.
*/
virtual int OnCompareItems(const VdtcTreeItemBase *a, const VdtcTreeItemBase *b);
private:
// WDR: member variable declarations for wxVirtualDirTreeCtrl
private:
// WDR: handler declarations for wxVirtualDirTreeCtrl
private:
DECLARE_EVENT_TABLE()
};
#endif