------------------------------------------------------------ revno: 2814 committer: Jacek Sieka <arnethed...@gmail.com> branch nick: dcplusplus timestamp: Thu 2012-01-12 23:19:35 +0100 message: Draw tree subitem texts modified: dwt/include/dwt/widgets/Header.h dwt/include/dwt/widgets/Tree.h dwt/src/widgets/Header.cpp dwt/src/widgets/Tree.cpp dwt/test/TreeTest.cpp
-- 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/widgets/Header.h' --- dwt/include/dwt/widgets/Header.h 2012-01-11 20:53:02 +0000 +++ dwt/include/dwt/widgets/Header.h 2012-01-12 22:19:35 +0000 @@ -74,6 +74,8 @@ int insert(const tstring& header, int width, LPARAM lParam = 0, int after = -1); + int getWidth(int i) const; + virtual Point getPreferredSize(); protected: === modified file 'dwt/include/dwt/widgets/Tree.h' --- dwt/include/dwt/widgets/Tree.h 2012-01-11 20:53:02 +0000 +++ dwt/include/dwt/widgets/Tree.h 2012-01-12 22:19:35 +0000 @@ -32,6 +32,9 @@ #ifndef DWT_TREE_H #define DWT_TREE_H +#include <map> +#include <vector> + #include "../Rectangle.h" #include "../resources/ImageList.h" #include "../aspects/Clickable.h" @@ -224,7 +227,9 @@ /// Returns the text of a particular node /** Returns the text of a particular node. */ - tstring getText( HTREEITEM node ); + tstring getText( HTREEITEM node, int column = 0); + + void setText(HTREEITEM item, int column, const tstring& text); /// Actually creates the TreeView /** You should call WidgetFactory::createTreeView if you instantiate class @@ -251,6 +256,8 @@ TreeViewPtr tree; HeaderPtr header; + std::map<HTREEITEM, std::vector<tstring>> texts; + HeaderPtr getHeader(); // aspects::Data @@ -288,6 +295,10 @@ void setColumnWidthImpl( unsigned column, int width ); LRESULT draw(NMTVCUSTOMDRAW& x); + LRESULT prePaint(NMTVCUSTOMDRAW &nmdc); + LRESULT prePaintItem(NMTVCUSTOMDRAW &nmcd); + LRESULT postPaintItem(NMTVCUSTOMDRAW &nmcd); + LRESULT postPaint(NMTVCUSTOMDRAW &nmcd); }; inline HTREEITEM Tree::getNext( HTREEITEM node, unsigned flag ) { === modified file 'dwt/src/widgets/Header.cpp' --- dwt/src/widgets/Header.cpp 2012-01-11 20:53:02 +0000 +++ dwt/src/widgets/Header.cpp 2012-01-12 22:19:35 +0000 @@ -94,4 +94,13 @@ Header_SetItem(handle(), idx, &item); } +int Header::getWidth(int idx) const { + HDITEM item = { HDI_WIDTH }; + + if(!Header_GetItem(handle(), idx, &item)) { + return 0; + } + return item.cxy; +} + } === modified file 'dwt/src/widgets/Tree.cpp' --- dwt/src/widgets/Tree.cpp 2012-01-12 16:14:38 +0000 +++ dwt/src/widgets/Tree.cpp 2012-01-12 22:19:35 +0000 @@ -30,11 +30,18 @@ */ #include <dwt/widgets/Tree.h> + +#include <boost/range/adaptor/map.hpp> +#include <boost/range/algorithm/for_each.hpp> + #include <dwt/widgets/Header.h> #include <dwt/WidgetCreator.h> namespace dwt { +using boost::range::for_each; +using boost::adaptors::map_values; + const TCHAR Tree::TreeView::windowClass[] = WC_TREEVIEW; Tree::TreeView::TreeView(Widget* parent) : Control(parent, ChainingDispatcher::superClass<TreeView>()) { } @@ -112,24 +119,43 @@ return getText(TreeView_GetSelection(treeHandle())); } -tstring Tree::getText( HTREEITEM node ) +tstring Tree::getText( HTREEITEM node, int column) { if(node == NULL) { return tstring(); } - TVITEMEX item = { TVIF_HANDLE | TVIF_TEXT, node }; - TCHAR buffer[1024]; - buffer[0] = '\0'; - item.cchTextMax = 1022; - item.pszText = buffer; - if ( TreeView_GetItem(treeHandle(), &item) ) - { - return buffer; + if(column == 0) { + TVITEMEX item = { TVIF_HANDLE | TVIF_TEXT, node }; + TCHAR buffer[1024]; + buffer[0] = '\0'; + item.cchTextMax = 1022; + item.pszText = buffer; + if ( TreeView_GetItem(treeHandle(), &item) ) { + return buffer; + } + } else { + auto i = texts.find(node); + if(i != texts.end() && i->second.size() > column) { + return i->second[column]; + } } + return tstring(); } +void Tree::setText(HTREEITEM node, int column, const tstring& text) { + if(column == 0) { + TVITEMEX item = { TVIF_HANDLE | TVIF_TEXT, node }; + item.pszText = const_cast<LPTSTR>(text.c_str()); + TreeView_SetItem(treeHandle(), &item); + } else if(column < getColumnCount()) { + auto &v = texts[node]; + if(v.size() <= column) v.resize(column + 1); + v[column] = text; + } +} + void Tree::eraseChildren( HTREEITEM node ) { HTREEITEM next_node, current_node; @@ -240,6 +266,19 @@ layout(); } + + if(column == 0 && getColumnCount() >= 1) { + for_each(texts, [&](const std::pair<HTREEITEM, std::vector<tstring>> & item) { + setText(item.first, 0, item.second.empty() ? tstring() : item.second[0]); + }); + + } + + for_each(texts | map_values, [&](std::vector<tstring> & v) { + if(column < v.size()) { + v.erase(v.begin() + column); + } + }); } unsigned Tree::getColumnCountImpl() const { @@ -290,12 +329,89 @@ // TODO } -LRESULT Tree::draw(NMTVCUSTOMDRAW& x) { - if(getColumnCount() < 2) { +static const int INSET = 3; + +LRESULT Tree::prePaint(NMTVCUSTOMDRAW& nmcd) { + return CDRF_NOTIFYITEMDRAW | CDRF_NOTIFYPOSTPAINT; +} + +LRESULT Tree::prePaintItem(NMTVCUSTOMDRAW& nmcd) { + // Clip the default item drawing to the column width + auto clipRect = nmcd.nmcd.rc; + auto w = header->getWidth(0); + clipRect.right = clipRect.left + w; + + auto hRgn = ::CreateRectRgn (clipRect.left, clipRect.top, clipRect.right, clipRect.bottom); + POINT pt = { 0 }; + + auto hDC = nmcd.nmcd.hdc; + ::GetWindowOrgEx(hDC, &pt); + ::OffsetRgn (hRgn, -pt.x, -pt.y); + ::SelectClipRgn (hDC, hRgn); + ::DeleteObject (hRgn); + + ::SaveDC(hDC); + return CDRF_DODEFAULT | CDRF_NOTIFYPOSTPAINT; +} + +LRESULT Tree::postPaintItem(NMTVCUSTOMDRAW& nmcd) { + auto hDC = nmcd.nmcd.hdc; + ::RestoreDC (hDC, -1); + + // Remove previously set clip region + ::SelectClipRgn(hDC, NULL); + + auto item = (HTREEITEM)nmcd.nmcd.dwItemSpec; + + if (item == NULL) return CDRF_DODEFAULT; + + auto clientSize = tree->getClientSize(); + + int x = header->getWidth(0); + auto columns = getColumnCount(); + + ::SetTextColor(hDC, nmcd.clrText); + ::SetBkColor(hDC, nmcd.clrTextBk); + + for(size_t i = 1; i < columns; ++i) { + auto width = header->getWidth(i); + + RECT rect = { x, nmcd.nmcd.rc.top, x + width, nmcd.nmcd.rc.bottom }; + + rect.left += INSET - 1; + + if (rect.left < rect.right) { + auto text = getText(item, i); + + if (!text.empty()) { + int flags = DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS; + ::DrawText (hDC, text.c_str(), text.size (), &rect, flags); + } + } + + x += width; + if (x > clientSize.x) break; + } + + return CDRF_DODEFAULT; +} + +LRESULT Tree::postPaint(NMTVCUSTOMDRAW& nmcd) { + return CDRF_DODEFAULT; +} + +LRESULT Tree::draw(NMTVCUSTOMDRAW& nmcd) { + if(nmcd.nmcd.rc.left >= nmcd.nmcd.rc.right || nmcd.nmcd.rc.top >= nmcd.nmcd.rc.bottom || getColumnCount() < 2) { return CDRF_DODEFAULT; } - //TODO + switch(nmcd.nmcd.dwDrawStage) { + case CDDS_PREPAINT: return prePaint(nmcd); + case CDDS_ITEMPREPAINT: return prePaintItem(nmcd); + case CDDS_ITEMPOSTPAINT: return postPaintItem(nmcd); + case CDDS_POSTPAINT: return postPaint(nmcd); + } + return CDRF_DODEFAULT; } === modified file 'dwt/test/TreeTest.cpp' --- dwt/test/TreeTest.cpp 2012-01-11 20:53:02 +0000 +++ dwt/test/TreeTest.cpp 2012-01-12 22:19:35 +0000 @@ -28,12 +28,14 @@ name.back() += i; auto item = tree->insert(name, NULL, 1); + tree->setText(item, 1, _T("sub") + name); + 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->setText(subItem, 1, _T("sub") + subname); } }
_______________________________________________ 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