linuxdcpp-team team mailing list archive
-
linuxdcpp-team team
-
Mailing list archive
-
Message #05199
[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2814: Draw tree subitem texts
------------------------------------------------------------
revno: 2814
committer: Jacek Sieka <arnetheduck@xxxxxxxxx>
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);
}
}