------------------------------------------------------------ revno: 2810 committer: Jacek Sieka <arnethed...@gmail.com> branch nick: dcplusplus timestamp: Wed 2012-01-11 21:53:02 +0100 message: Play with trees added: dwt/include/dwt/widgets/Header.h dwt/src/widgets/Header.cpp dwt/test/TreeTest.cpp modified: dwt/include/dwt/forward.h dwt/include/dwt/widgets/ModalDialog.h dwt/include/dwt/widgets/ModelessDialog.h dwt/include/dwt/widgets/Tree.h dwt/src/widgets/ModalDialog.cpp dwt/src/widgets/ModelessDialog.cpp dwt/src/widgets/Tree.cpp test/SConscript win32/TypedTree.h
-- lp:dcplusplus https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk Your team Dcplusplus-team is subscribed to branch lp:dcplusplus. To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'dwt/include/dwt/forward.h' --- dwt/include/dwt/forward.h 2011-05-07 18:52:09 +0000 +++ dwt/include/dwt/forward.h 2012-01-11 20:53:02 +0000 @@ -66,6 +66,9 @@ class Container; typedef Container* ContainerPtr; +class Control; +typedef Control* ControlPtr; + class CoolBar; typedef CoolBar* CoolBarPtr; @@ -89,6 +92,9 @@ class GroupBox; typedef GroupBox* GroupBoxPtr; +class Header; +typedef Header* HeaderPtr; + class Icon; typedef boost::intrusive_ptr<Icon> IconPtr; === added file 'dwt/include/dwt/widgets/Header.h' --- dwt/include/dwt/widgets/Header.h 1970-01-01 00:00:00 +0000 +++ dwt/include/dwt/widgets/Header.h 2012-01-11 20:53:02 +0000 @@ -0,0 +1,129 @@ +/* + DC++ Widget Toolkit + + Copyright (c) 2007-2011, Jacek Sieka + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the DWT nor SmartWin++ nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef DWT_HEADER_H_ +#define DWT_HEADER_H_ + +#include "Control.h" + +#include "../aspects/Collection.h" +#include "../aspects/Data.h" + +namespace dwt { + +/** Header control like the one used for Table */ +class Header : + public CommonControl, + public aspects::Collection<Header, int>, + public aspects::Data<Header, int> +{ + typedef CommonControl BaseType; + + friend class WidgetCreator<Header>; + friend class aspects::Collection<Header, int>; + friend class aspects::Data<Header, int>; +public: + /// Class type + typedef Header ThisType; + + /// Object type + typedef ThisType* ObjectType; + + /// Seed class + /** This class contains all of the values needed to create the widget. It also + * knows the type of the class whose seed values it contains. Every widget + * should define one of these. + */ + struct Seed : public BaseType::Seed { + typedef ThisType WidgetType; + + /// Fills with default parameters + Seed(); + }; + + /// Actually creates the Header + void create( const Seed & cs = Seed() ); + + int insert(const tstring& header, int width, LPARAM lParam = 0, int after = -1); + + virtual Point getPreferredSize(); + +protected: + /// Constructor Taking pointer to parent + explicit Header( Widget * parent ); + + // Protected to avoid direct instantiation, you can inherit and use + // WidgetFactory class which is friend + virtual ~Header() + {} + +private: + friend class ChainingDispatcher; + static const TCHAR windowClass[]; + + // aspects::Collection + void eraseImpl(int row); + void clearImpl(); + size_t sizeImpl() const; + + // aspects::Data + int findDataImpl(LPARAM data, int start = -1); + LPARAM getDataImpl(int idx); + void setDataImpl(int i, LPARAM data); + +}; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Implementation of class +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +inline Header::Header( Widget * parent ) + : BaseType(parent, ChainingDispatcher::superClass<Header>()) +{ +} + +inline void Header::eraseImpl( int row ) { + Header_DeleteItem(handle(), row); +} + +inline size_t Header::sizeImpl() const { + return Header_GetItemCount(handle()); +} + +inline void Header::clearImpl() { + for(size_t i = 0, iend = size(); i < iend; ++i) { + erase(0); + } +} + +} + +#endif /* HEADER_H_ */ === modified file 'dwt/include/dwt/widgets/ModalDialog.h' --- dwt/include/dwt/widgets/ModalDialog.h 2011-11-07 22:11:39 +0000 +++ dwt/include/dwt/widgets/ModalDialog.h 2012-01-11 20:53:02 +0000 @@ -129,7 +129,7 @@ virtual void kill(); private: friend class ChainingDispatcher; - static LPCTSTR windowClass; + static const TCHAR* windowClass; bool quit; int ret; === modified file 'dwt/include/dwt/widgets/ModelessDialog.h' --- dwt/include/dwt/widgets/ModelessDialog.h 2011-11-07 20:53:49 +0000 +++ dwt/include/dwt/widgets/ModelessDialog.h 2012-01-11 20:53:02 +0000 @@ -79,7 +79,7 @@ private: friend class ChainingDispatcher; - static LPCTSTR windowClass; + static const TCHAR *windowClass; }; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// === modified file 'dwt/include/dwt/widgets/Tree.h' --- dwt/include/dwt/widgets/Tree.h 2011-11-19 00:10:54 +0000 +++ dwt/include/dwt/widgets/Tree.h 2012-01-11 20:53:02 +0000 @@ -3,10 +3,6 @@ Copyright (c) 2007-2011, Jacek Sieka - SmartWin++ - - Copyright (c) 2005 Thomas Hansen - All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -33,13 +29,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef DWT_Tree_h -#define DWT_Tree_h +#ifndef DWT_TREE_H +#define DWT_TREE_H #include "../Rectangle.h" #include "../resources/ImageList.h" #include "../aspects/Clickable.h" #include "../aspects/Collection.h" +#include "../aspects/Columns.h" #include "../aspects/CustomDraw.h" #include "../aspects/Data.h" #include "../aspects/Selection.h" @@ -60,29 +57,48 @@ HTREEITEM handle; }; -/// TreeView class /** \ingroup WidgetControls * \WidgetUsageInfo - * \image html treeview.PNG - * A Tree is a treview control, like for instance the documentation to - * dwt which you are probably reading right now would ( in the web version ) - * have a tree view to the left. <br> - * Another good example of a tree view is the Explorer of Windows, it has a tree - * view to the left where you can see the different directories. */ class Tree : - public CommonControl, + public Control, public aspects::Clickable<Tree>, public aspects::Collection<Tree, HTREEITEM>, - public aspects::CustomDraw<Tree, NMTVCUSTOMDRAW>, + public aspects::Columns<Tree>, public aspects::Data<Tree, HTREEITEM>, public aspects::Selection<Tree, HTREEITEM> { - typedef CommonControl BaseType; + typedef Control BaseType; + + class TreeView : + public Control, + public aspects::CustomDraw<TreeView, NMTVCUSTOMDRAW> + { + friend class WidgetCreator<TreeView>; + public: + typedef Tree::Seed Seed; + typedef Control BaseType; + + /// Class type + typedef TreeView ThisType; + + /// Object type + typedef ThisType* ObjectType; + + static const TCHAR windowClass[]; + + TreeView(Widget* parent); + + /// Returns true if handled, else false + virtual bool handleMessage(const MSG &msg, LRESULT &retVal); + }; + + typedef TreeView* TreeViewPtr; protected: friend class WidgetCreator<Tree>; friend class aspects::Collection<Tree, HTREEITEM>; + friend class aspects::Columns<Tree>; friend class aspects::Data<Tree, HTREEITEM>; friend class aspects::Selection<Tree, HTREEITEM>; friend class aspects::Clickable<Tree>; @@ -109,21 +125,6 @@ }; /// Inserts a "node" into the TreeView - /** The return value from a call to this function is a Node. <br> - * If you later wish to inserts CHILDREN to that node, pass the return value - * from the first call as the second parameter into this function. <br> - * If you wish to insert a ( a TreeView can have several "root" nodes ) "root" - * node then don't pass anything as the second parameter. ( or pass Node() ) - * <br> - * The "param" parameter ( optionally ) is a unique unsigned integer which must - * be higher than 0 and can later be used to retrieve unique identification of - * which item was e.g. selected etc... <br> - * Especially useful when text of nodes is not unique or text might change. - * The "iconIndex" optionally specifies the icon index of the item in the - * associated image list, if there is one. <br> - * The "selectedIconIndex" optionally specifies the icon index of the item in the - * selected state (if not specified or -1, it defaults to the iconIndex) - */ HTREEITEM insert(const tstring& text, HTREEITEM parent = NULL, LPARAM param = 0, bool expanded = false, int iconIndex = - 1, int selectedIconIndex = - 1); HTREEITEM getNext(HTREEITEM node, unsigned flag); @@ -225,9 +226,6 @@ */ tstring getText( HTREEITEM node ); - /// Returns true if fired, else false - virtual bool handleMessage( const MSG & msg, LRESULT & retVal ); - /// Actually creates the TreeView /** You should call WidgetFactory::createTreeView if you instantiate class * directly. <br> @@ -235,6 +233,7 @@ */ void create( const Seed & cs = Seed() ); + virtual void layout(); protected: // Constructor Taking pointer to parent explicit Tree( Widget * parent ); @@ -244,13 +243,16 @@ virtual ~Tree() {} + HWND treeHandle() const { return tree->handle(); } private: - friend class ChainingDispatcher; - static const TCHAR windowClass[]; - ImageListPtr itsNormalImageList; ImageListPtr itsStateImageList; + TreeViewPtr tree; + HeaderPtr header; + + HeaderPtr getHeader(); + // aspects::Data LPARAM getDataImpl(HTREEITEM item); void setDataImpl(HTREEITEM item, LPARAM data); @@ -273,81 +275,90 @@ static Message getClickMessage(); static Message getRightClickMessage(); static Message getDblClickMessage(); + + // aspects::Columns + int insertColumnImpl(const Column& column, int after); + void eraseColumnImpl(unsigned column); + unsigned getColumnCountImpl() const; + std::vector<Column> getColumnsImpl() const; + Column getColumnImpl(unsigned column) const; + std::vector<int> getColumnOrderImpl() const; + void setColumnOrderImpl(const std::vector<int>& columns); + std::vector<int> getColumnWidthsImpl() const; + void setColumnWidthImpl( unsigned column, int width ); + + LRESULT draw(NMTVCUSTOMDRAW& x); }; -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Implementation of class -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - inline HTREEITEM Tree::getNext( HTREEITEM node, unsigned flag ) { - return TreeView_GetNextItem( handle(), node, flag ); + return TreeView_GetNextItem(treeHandle(), node, flag); } inline HTREEITEM Tree::getChild(HTREEITEM node) { - return TreeView_GetChild(handle(), node); + return TreeView_GetChild(treeHandle(), node); } inline HTREEITEM Tree::getNextSibling(HTREEITEM node) { - return TreeView_GetNextSibling(handle(), node); + return TreeView_GetNextSibling(treeHandle(), node); } inline HTREEITEM Tree::getParent(HTREEITEM node) { - return TreeView_GetParent(handle(), node); + return TreeView_GetParent(treeHandle(), node); } inline HTREEITEM Tree::getRoot() { - return TreeView_GetRoot(handle()); + return TreeView_GetRoot(treeHandle()); } inline HTREEITEM Tree::getFirst() { - return TreeView_GetFirstVisible(handle()); + return TreeView_GetFirstVisible(treeHandle()); } inline HTREEITEM Tree::getLast() { - return TreeView_GetLastVisible(handle()); + return TreeView_GetLastVisible(treeHandle()); } inline void Tree::setColorImpl(COLORREF text, COLORREF background) { - TreeView_SetTextColor(handle(), text); - TreeView_SetBkColor(handle(), background); + TreeView_SetTextColor(treeHandle(), text); + TreeView_SetBkColor(treeHandle(), background); } inline HTREEITEM Tree::hitTest(const ScreenCoordinate& pt) { ClientCoordinate cc(pt, this); TVHITTESTINFO tvhti = { cc.getPoint() }; - return TreeView_HitTest(handle(), &tvhti); + return TreeView_HitTest(treeHandle(), &tvhti); } inline bool Tree::isExpanded(HTREEITEM node) { - return TreeView_GetItemState(handle(), node, TVIS_EXPANDED) & TVIS_EXPANDED; + return TreeView_GetItemState(treeHandle(), node, TVIS_EXPANDED) & TVIS_EXPANDED; } inline void Tree::expand(HTREEITEM node) { - TreeView_Expand(handle(), node, TVE_EXPAND); + TreeView_Expand(treeHandle(), node, TVE_EXPAND); } inline void Tree::collapse(HTREEITEM node) { - TreeView_Expand(handle(), node, TVE_COLLAPSE); + TreeView_Expand(treeHandle(), node, TVE_COLLAPSE); } inline void Tree::clearImpl() { - TreeView_DeleteAllItems( handle() ); + TreeView_DeleteAllItems(treeHandle()); } inline void Tree::eraseImpl( HTREEITEM node ) { - TreeView_DeleteItem( handle(), node ); + TreeView_DeleteItem(treeHandle(), node); } inline size_t Tree::sizeImpl() const { - return static_cast<size_t>(TreeView_GetCount(handle())); + return static_cast<size_t>(TreeView_GetCount(treeHandle())); } inline void Tree::editLabel( HTREEITEM node ) { - static_cast<void>(TreeView_EditLabel( handle(), node )); + static_cast<void>(TreeView_EditLabel(treeHandle(), node)); } inline void Tree::ensureVisible( HTREEITEM node ) { - TreeView_EnsureVisible( handle(), node ); + TreeView_EnsureVisible(treeHandle(), node); } inline void Tree::setHasButtons( bool value ) { @@ -391,11 +402,11 @@ } inline HTREEITEM Tree::getSelectedImpl() const { - return TreeView_GetSelection( handle() ); + return TreeView_GetSelection(treeHandle()); } inline void Tree::setSelectedImpl(HTREEITEM item) { - TreeView_SelectItem( handle(), item ); + TreeView_SelectItem(treeHandle(), item ); } inline size_t Tree::countSelectedImpl() const { @@ -403,7 +414,7 @@ } inline Tree::Tree( Widget * parent ) - : BaseType(parent, ChainingDispatcher::superClass<Tree>()) + : BaseType(parent, NormalDispatcher::newClass<Tree>()), tree(nullptr), header(nullptr) { } === added file 'dwt/src/widgets/Header.cpp' --- dwt/src/widgets/Header.cpp 1970-01-01 00:00:00 +0000 +++ dwt/src/widgets/Header.cpp 2012-01-11 20:53:02 +0000 @@ -0,0 +1,97 @@ +/* + DC++ Widget Toolkit + + Copyright (c) 2007-2011, Jacek Sieka + + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the DWT nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include <dwt/widgets/Header.h> + +namespace dwt { + +const TCHAR Header::windowClass[] = WC_HEADER; + +Header::Seed::Seed() : +BaseType::Seed(WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS) +{ +} + +void Header::create( const Header::Seed & cs ) { + BaseType::create(cs); +} + +Point Header::getPreferredSize() { + RECT rc = { 0, 0, ::GetSystemMetrics(SM_CXSCREEN), ::GetSystemMetrics(SM_CYSCREEN) }; + WINDOWPOS wp = { 0 }; + HDLAYOUT hl = { &rc, &wp }; + if(Header_Layout(handle(), &hl)) { + return Point(wp.cx, wp.cy); + } + + return Point(0, 0); +} + +int Header::insert(const tstring& header, int width, LPARAM lParam, int after) { + if(after == -1) after = size(); + + HDITEM item = { HDI_FORMAT }; + item.fmt = HDF_LEFT;// TODO + if(!header.empty()) { + item.mask |= HDI_TEXT; + item.pszText = const_cast<LPTSTR>(header.c_str()); + } + + if(width >= 0) { + item.mask |= HDI_WIDTH; + item.cxy = width; + } + + return Header_InsertItem(handle(), after, &item); +} + +int Header::findDataImpl(LPARAM data, int start) { + LVFINDINFO fi = { LVFI_PARAM, NULL, data }; + return ListView_FindItem(handle(), start, &fi); +} + +LPARAM Header::getDataImpl(int idx) { + HDITEM item = { HDI_LPARAM }; + + if(!Header_GetItem(handle(), idx, &item)) { + return 0; + } + return item.lParam; +} + +void Header::setDataImpl(int idx, LPARAM data) { + LVITEM item = { HDI_LPARAM }; + item.lParam = data; + + Header_SetItem(handle(), idx, &item); +} + +} === modified file 'dwt/src/widgets/ModalDialog.cpp' --- dwt/src/widgets/ModalDialog.cpp 2011-07-05 12:16:32 +0000 +++ dwt/src/widgets/ModalDialog.cpp 2012-01-11 20:53:02 +0000 @@ -36,7 +36,7 @@ namespace dwt { -LPCTSTR ModalDialog::windowClass = WC_DIALOG; +const TCHAR* ModalDialog::windowClass = WC_DIALOG; ModalDialog::Seed::Seed(const Point& size, DWORD styles_) : BaseType::Seed(tstring(), styles_ | WS_POPUP | WS_CAPTION | WS_SYSMENU, WS_EX_CONTROLPARENT | WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE) === modified file 'dwt/src/widgets/ModelessDialog.cpp' --- dwt/src/widgets/ModelessDialog.cpp 2011-01-02 17:12:02 +0000 +++ dwt/src/widgets/ModelessDialog.cpp 2012-01-11 20:53:02 +0000 @@ -33,7 +33,7 @@ namespace dwt { -LPCTSTR ModelessDialog::windowClass = WC_DIALOG; +const TCHAR *ModelessDialog::windowClass = WC_DIALOG; ModelessDialog::Seed::Seed(const Point& size, DWORD styles_) : BaseType::Seed(tstring(), styles_ | DS_CONTROL | WS_CHILD, WS_EX_CONTROLPARENT) === modified file 'dwt/src/widgets/Tree.cpp' --- dwt/src/widgets/Tree.cpp 2011-06-28 20:07:49 +0000 +++ dwt/src/widgets/Tree.cpp 2012-01-11 20:53:02 +0000 @@ -30,10 +30,33 @@ */ #include <dwt/widgets/Tree.h> +#include <dwt/widgets/Header.h> +#include <dwt/WidgetCreator.h> namespace dwt { -const TCHAR Tree::windowClass[] = WC_TREEVIEW; +const TCHAR Tree::TreeView::windowClass[] = WC_TREEVIEW; + +Tree::TreeView::TreeView(Widget* parent) : Control(parent, ChainingDispatcher::superClass<TreeView>()) { } + +bool Tree::TreeView::handleMessage(const MSG& msg, LRESULT &retVal) { + if(BaseType::handleMessage(msg, retVal)) { + return true; + } + + if(msg.message == WM_NOTIFY) { + // Forward tree notifications + return getParent()->handleMessage(msg, retVal); + } + + if(msg.message == WM_RBUTTONDOWN) { + // Tree view control does strange things to rbuttondown, preventing wm_contextmenu from reaching it + retVal = ::DefWindowProc(msg.hwnd, msg.message, msg.wParam, msg.lParam); + return true; + } + + return false; +} Tree::Seed::Seed() : BaseType::Seed(WS_CHILD | WS_TABSTOP | TVS_DISABLEDRAGDROP | TVS_HASLINES | TVS_NONEVENHEIGHT | TVS_SHOWSELALWAYS), @@ -43,8 +66,17 @@ void Tree::create( const Seed & cs ) { - BaseType::create(cs); + Control::Seed mySeed(WS_CHILD); + + BaseType::create(mySeed); + tree = WidgetCreator<TreeView>::create(this, cs); + + onSized([&](const SizedEvent& e) { layout(); }); + + tree->onCustomDraw([=](NMTVCUSTOMDRAW& x) { return draw(x); }); + setFont(cs.font); + layout(); } HTREEITEM Tree::insert(const tstring& text, HTREEITEM parent, LPARAM param, bool expanded, int iconIndex, int selectedIconIndex) { @@ -73,11 +105,11 @@ #else tv.itemex = t; #endif - return TreeView_InsertItem(handle(), &tv); + return TreeView_InsertItem(treeHandle(), &tv); } tstring Tree::getSelectedText() { - return getText(TreeView_GetSelection(handle())); + return getText(TreeView_GetSelection(treeHandle())); } tstring Tree::getText( HTREEITEM node ) @@ -91,7 +123,7 @@ buffer[0] = '\0'; item.cchTextMax = 1022; item.pszText = buffer; - if ( TreeView_GetItem(handle(), &item) ) + if ( TreeView_GetItem(treeHandle(), &item) ) { return buffer; } @@ -116,17 +148,17 @@ void Tree::setNormalImageList( ImageListPtr imageList ) { itsNormalImageList = imageList; - TreeView_SetImageList(handle(), imageList->getImageList(), TVSIL_NORMAL); + TreeView_SetImageList(treeHandle(), imageList->getImageList(), TVSIL_NORMAL); } void Tree::setStateImageList( ImageListPtr imageList ) { itsStateImageList = imageList; - TreeView_SetImageList(handle(), imageList->getImageList(), TVSIL_STATE); + TreeView_SetImageList(treeHandle(), imageList->getImageList(), TVSIL_STATE); } LPARAM Tree::getDataImpl(HTREEITEM item) { TVITEM tvitem = { TVIF_PARAM | TVIF_HANDLE, item }; - if(!TreeView_GetItem(handle(), &tvitem)) { + if(!TreeView_GetItem(treeHandle(), &tvitem)) { return 0; } return tvitem.lParam; @@ -135,15 +167,15 @@ void Tree::setDataImpl(HTREEITEM item, LPARAM lParam) { TVITEM tvitem = { TVIF_PARAM | TVIF_HANDLE, item }; tvitem.lParam = lParam; - TreeView_SetItem(handle(), &tvitem); + TreeView_SetItem(treeHandle(), &tvitem); } int Tree::getItemHeight() { - return TreeView_GetItemHeight(handle()); + return TreeView_GetItemHeight(treeHandle()); } void Tree::setItemHeight(int h) { - TreeView_SetItemHeight(handle(), h); + TreeView_SetItemHeight(treeHandle(), h); } ScreenCoordinate Tree::getContextMenuPos() { @@ -166,19 +198,105 @@ Rectangle Tree::getItemRect(HTREEITEM item) { RECT rc; - TreeView_GetItemRect(handle(), item, &rc, TRUE); + TreeView_GetItemRect(treeHandle(), item, &rc, TRUE); return Rectangle(rc); } -/// Returns true if fired, else false -bool Tree::handleMessage( const MSG & msg, LRESULT & retVal ) { - bool handled = BaseType::handleMessage(msg, retVal); - if(!handled && msg.message == WM_RBUTTONDOWN) { - // Tree view control does strange things to rbuttondown, preventing wm_contextmenu from reaching it - retVal = ::DefWindowProc(msg.hwnd, msg.message, msg.wParam, msg.lParam); - return true; - } - return handled; +HeaderPtr Tree::getHeader() { + if(header == NULL) { + header = WidgetCreator<Header>::create(this); + layout(); + } + + return header; +} + +void Tree::layout() { + auto client = getClientSize(); + if(header) { + auto hsize = header->getPreferredSize(); + header->resize(Rectangle(0, 0, client.x, hsize.y)); + tree->resize(Rectangle(0, hsize.y, client.x, client.y - hsize.y)); + } else { + tree->resize(Rectangle(client)); + } +} + +int Tree::insertColumnImpl(const Column& column, int after) { + auto h = getHeader(); + + return h->insert(column.header, column.width, 0, after); +} + +void Tree::eraseColumnImpl(unsigned column) { + if(!header) { + return; + } + + header->erase(column); + if(getColumnCount() == 0) { + header->close(false); + header = 0; + + layout(); + } +} + +unsigned Tree::getColumnCountImpl() const { + return header ? header->size() : 0; +} + +Column Tree::getColumnImpl(unsigned column) const { + if(!header) { + return Column(); + } + + HDITEM item = { HDI_FORMAT | HDI_TEXT | HDI_WIDTH }; + TCHAR buf[1024] = { 0 }; + item.pszText = buf; + item.cchTextMax = 1023; + Header_GetItem(header->handle(), column, &item); + + return Column(item.pszText, item.cxy); // TODO fmt +} + +std::vector<Column> Tree::getColumnsImpl() const { + std::vector<Column> ret; + if(!header) { + return ret; + } + + ret.resize(getColumnCount()); + for(size_t i = 0; i < ret.size(); ++i) { + ret[i] = getColumn(i); + } + + return ret; +} + +std::vector<int> Tree::getColumnOrderImpl() const { + return std::vector<int>(); // TODO +} + +void Tree::setColumnOrderImpl(const std::vector<int>& columns) { + // TODO +} + +std::vector<int> Tree::getColumnWidthsImpl() const { + return std::vector<int>(); // TODO +} + +void Tree::setColumnWidthImpl(unsigned column, int width) { + // TODO +} + +LRESULT Tree::draw(NMTVCUSTOMDRAW& x) { + if(getColumnCount() < 2) { + return CDRF_DODEFAULT; + } + + //TODO + return CDRF_DODEFAULT; } } === added file 'dwt/test/TreeTest.cpp' --- dwt/test/TreeTest.cpp 1970-01-01 00:00:00 +0000 +++ dwt/test/TreeTest.cpp 2012-01-11 20:53:02 +0000 @@ -0,0 +1,49 @@ +#include <dwt/widgets/Window.h> +#include <dwt/widgets/Tree.h> +#include <dwt/Texts.h> + +#include <iostream> + +namespace dwt { +tstring Texts::get(Text text) { return _T("test"); } +} + +using dwt::tstring; + +int dwtMain(dwt::Application& app) +{ + auto window = new dwt::Window(); + window->create(); + window->onClosing([] { return ::PostQuitMessage(0), true; }); + + auto tree = window->addChild(dwt::Tree::Seed()); + //tree.setHeaderVisible(true); + + tree->addColumn(_T("Column 1"), 200, dwt::Column::LEFT); + tree->addColumn(_T("Column 2"), 200, dwt::Column::CENTER); + tree->addColumn(_T("Column 3"), 200, dwt::Column::RIGHT); + + for (int i = 0; i < 4; i++) { + tstring name(_T("item 1")); + name.back() += i; + + auto item = tree->insert(name, NULL, 1); + assert(tree->getData(item) == 1); + for (int j = 0; j < 4; j++) { + tstring subname(_T("item 1")); + subname.back() += j; + auto subItem = tree->insert(subname, item); + + } + } + + tree->resize(dwt::Rectangle(window->getClientSize())); + + app.run(); + + return 0; +} + + + + === modified file 'test/SConscript' --- test/SConscript 2012-01-10 18:45:17 +0000 +++ test/SConscript 2012-01-11 20:53:02 +0000 @@ -3,6 +3,11 @@ Import('dev source_path') def runUnitTest(env,target,source): + import sys + if sys.platform != 'win32': + open(str(target[0]),'w').write("SKIPPED\n") + return + import subprocess app = str(source[0].abspath) if not subprocess.call(app): === modified file 'win32/TypedTree.h' --- win32/TypedTree.h 2011-12-26 16:12:50 +0000 +++ win32/TypedTree.h 2012-01-11 20:53:02 +0000 @@ -77,7 +77,7 @@ } HTREEITEM insert(TVINSERTSTRUCT* tvis) { - return TreeView_InsertItem(this->handle(), tvis); + return TreeView_InsertItem(this->treeHandle(), tvis); } ContentType* getData(HTREEITEM item) { @@ -85,7 +85,7 @@ } void getItem(TVITEMEX* item) { - TreeView_GetItem(this->handle(), item); + TreeView_GetItem(this->treeHandle(), item); } ContentType* getSelectedData() { @@ -94,7 +94,7 @@ } void setItemState(HTREEITEM item, int state, int mask) { - TreeView_SetItemState(this->handle(), item, state, mask); + TreeView_SetItemState(this->treeHandle(), item, state, mask); } void clear() {
_______________________________________________ Mailing list: https://launchpad.net/~linuxdcpp-team Post to : linuxdcpp-team@lists.launchpad.net Unsubscribe : https://launchpad.net/~linuxdcpp-team More help : https://help.launchpad.net/ListHelp