← Back to team overview

linuxdcpp-team team mailing list archive

[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2676: add custom draw handling to TypedTable

 

------------------------------------------------------------
revno: 2676
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Sun 2011-11-13 17:46:43 +0100
message:
  add custom draw handling to TypedTable
modified:
  dwt/include/dwt/aspects/Colorable.h
  win32/HubFrame.cpp
  win32/HubFrame.h
  win32/TransferView.cpp
  win32/TypedTable.h
  win32/TypedTree.h
  win32/forward.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/aspects/Colorable.h'
--- dwt/include/dwt/aspects/Colorable.h	2011-11-07 22:11:39 +0000
+++ dwt/include/dwt/aspects/Colorable.h	2011-11-13 16:46:43 +0000
@@ -42,7 +42,7 @@
 namespace dwt { namespace aspects {
 
 /// Aspect class used by Widgets that have the possibility of changing colors
-template<class WidgetType>
+template<typename WidgetType>
 class Colorable {
 	WidgetType& W() { return *static_cast<WidgetType*>(this); }
 public:
@@ -52,7 +52,7 @@
 };
 
 /// Helper class for controls that are colorable via WM_CTLCOLOR
-template< class WidgetType >
+template<typename WidgetType>
 class ColorableCtlImpl {
 	friend class Colorable<WidgetType>;
 
@@ -65,7 +65,7 @@
 			HDC dc = reinterpret_cast<HDC>(msg.wParam);
 			::SetTextColor(dc, text);
 			::SetBkColor(dc, background);
-			ret = brush ? reinterpret_cast<LRESULT>(brush->handle()) : 0;
+			ret = reinterpret_cast<LRESULT>(brush->handle());
 			return true;
 		});
 	}

=== modified file 'win32/HubFrame.cpp'
--- win32/HubFrame.cpp	2011-11-12 19:36:12 +0000
+++ win32/HubFrame.cpp	2011-11-13 16:46:43 +0000
@@ -771,6 +771,15 @@
 	return image;
 }
 
+int HubFrame::UserInfo::getColor(COLORREF& text, COLORREF& bg, int) const {
+	if(identity.isOp()) {
+		text = 0xFFFFFF - text;
+		bg = 0xFFFFFF - bg;
+		return CDRF_NEWFONT;
+	}
+	return CDRF_DODEFAULT;
+}
+
 HubFrame::UserTask::UserTask(const OnlineUser& ou) :
 user(ou.getUser(), ou.getClient().getHubUrl()),
 identity(ou.getIdentity())

=== modified file 'win32/HubFrame.h'
--- win32/HubFrame.h	2011-10-30 14:24:14 +0000
+++ win32/HubFrame.h	2011-11-13 16:46:43 +0000
@@ -129,6 +129,7 @@
 			return columns[col];
 		}
 		int getImage(int col) const;
+		int getColor(COLORREF& text, COLORREF& bg, int) const;
 
 		static int compareItems(const UserInfo* a, const UserInfo* b, int col);
 		bool update(const Identity& identity, int sortCol);
@@ -160,7 +161,7 @@
 
 	GridPtr userGrid;
 
-	typedef TypedTable<UserInfo, false> WidgetUsers;
+	typedef TypedTable<UserInfo, false, true> WidgetUsers;
 	typedef WidgetUsers* WidgetUsersPtr;
 	WidgetUsersPtr users;
 

=== modified file 'win32/TransferView.cpp'
--- win32/TransferView.cpp	2011-11-12 19:36:12 +0000
+++ win32/TransferView.cpp	2011-11-13 16:46:43 +0000
@@ -377,9 +377,6 @@
 }
 
 LRESULT TransferView::handleCustomDraw(NMLVCUSTOMDRAW& data) {
-	int item = static_cast<int>(data.nmcd.dwItemSpec);
-	int column = data.iSubItem;
-
 	switch(data.nmcd.dwDrawStage) {
 	case CDDS_PREPAINT:
 		return CDRF_NOTIFYITEMDRAW;
@@ -388,6 +385,10 @@
 		return CDRF_NOTIFYSUBITEMDRAW;
 
 	case CDDS_SUBITEM | CDDS_ITEMPREPAINT:
+	{
+		int item = static_cast<int>(data.nmcd.dwItemSpec);
+		int column = data.iSubItem;
+
 		// Let's draw a box if needed...
 		if(data.nmcd.hdr.hwndFrom == connections->handle() && column == CONNECTION_COLUMN_STATUS) {
 			HDC hdc = data.nmcd.hdc;
@@ -421,6 +422,7 @@
 				return CDRF_SKIPDEFAULT;
 			}
 		}
+	}
 		// Fall through
 	default:
 		return CDRF_DODEFAULT;

=== modified file 'win32/TypedTable.h'
--- win32/TypedTable.h	2011-11-12 19:36:12 +0000
+++ win32/TypedTable.h	2011-11-13 16:46:43 +0000
@@ -16,18 +16,31 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-#ifndef DCPLUSPLUS_WIN32_TYPED_LIST_VIEW_H
-#define DCPLUSPLUS_WIN32_TYPED_LIST_VIEW_H
+#ifndef DCPLUSPLUS_WIN32_TYPED_TABLE_H
+#define DCPLUSPLUS_WIN32_TYPED_TABLE_H
 
 #include "forward.h"
 #include "Table.h"
 #include "WinUtil.h"
 
-template<class ContentType, bool managed>
+/** Table with an object associated to each item.
+
+@tparam ContentType Type of the objects associated to each item.
+
+@tparam managed Whether this class should handle deleting associated objects.
+
+@tparam customColors Custom colors per item (whole row) or per sub-item (each cell).
+The ContentType class must provide a int getColor(COLORREF& text, COLORREF& bg, int col) function.
+It is called a first time with col=-1 to set colors for the whole item. It can return:
+- CDRF_DODEFAULT to keep default colors for the item.
+- CDRF_NEWFONT to change colors for the item.
+- CDRF_NOTIFYSUBITEMDRAW to request custom colors for each sub-item (get Color will then be called
+for each sub-item). */
+template<typename ContentType, bool managed, bool customColors>
 class TypedTable : public Table
 {
 	typedef Table BaseType;
-	typedef TypedTable<ContentType, managed> ThisType;
+	typedef TypedTable<ContentType, managed, customColors> ThisType;
 
 public:
 	typedef ThisType* ObjectType;
@@ -39,7 +52,7 @@
 	struct Seed : public BaseType::Seed {
 		typedef ThisType WidgetType;
 
-		explicit Seed(const BaseType::Seed& seed) : BaseType::Seed(seed) {
+		Seed(const BaseType::Seed& seed) : BaseType::Seed(seed) {
 		}
 	};
 
@@ -48,14 +61,17 @@
 			this->clear();
 	}
 
-	void create( const typename BaseType::Seed & cs = BaseType::Seed() ) {
-		BaseType::create(cs);
+	void create(const Seed& seed) {
+		BaseType::create(seed);
 
-		this->addCallback(
-			dwt::Message( WM_NOTIFY, LVN_GETDISPINFO ), &ThisType::TypedTableDispatcher
-		);
+		this->onRaw([this](WPARAM, LPARAM lParam) -> LRESULT {
+			auto& data = *reinterpret_cast<NMLVDISPINFO*>(lParam);
+			this->handleDisplay(data);
+			return 0;
+		}, dwt::Message(WM_NOTIFY, LVN_GETDISPINFO));
 		this->onColumnClick([this](int column) { this->handleColumnClick(column); });
 		this->onSortItems([this](LPARAM lhs, LPARAM rhs) { return this->handleSort(lhs, rhs); });
+		addColorEvent<void>();
 	}
 
 	int insert(ContentType* item) {
@@ -171,27 +187,26 @@
 	void setSort(int col = -1, bool ascending = true) {
 		BaseType::setSort(col, BaseType::SORT_CALLBACK, ascending);
 	}
+
 private:
-
-	int handleSort(LPARAM lhs, LPARAM rhs) {
-		return ContentType::compareItems(reinterpret_cast<ContentType*>(lhs), reinterpret_cast<ContentType*>(rhs), this->getSortColumn());
+	template<typename Ret> typename std::enable_if<customColors, Ret>::type addColorEvent() {
+		this->onCustomDraw([this](NMLVCUSTOMDRAW& data) { return this->handleCustomDraw<LRESULT>(data); });
 	}
+	template<typename Ret> typename std::enable_if<!customColors, Ret>::type addColorEvent() { }
 
-	static bool TypedTableDispatcher(const MSG& msg, LRESULT& res) {
-		NMLVDISPINFO * nm = reinterpret_cast< NMLVDISPINFO * >( msg.lParam );
-		if(nm->item.mask & LVIF_TEXT) {
-			ContentType* content = reinterpret_cast<ContentType*>(nm->item.lParam);
-			const tstring& text = content->getText(nm->item.iSubItem);
-			_tcsncpy(nm->item.pszText, text.data(), std::min(text.size(), (size_t)nm->item.cchTextMax));
-			if(text.size() < static_cast<size_t>(nm->item.cchTextMax)) {
-				nm->item.pszText[text.size()] = 0;
+	void handleDisplay(NMLVDISPINFO& data) {
+		if(data.item.mask & LVIF_TEXT) {
+			ContentType* content = reinterpret_cast<ContentType*>(data.item.lParam);
+			const tstring& text = content->getText(data.item.iSubItem);
+			_tcsncpy(data.item.pszText, text.data(), std::min(text.size(), static_cast<size_t>(data.item.cchTextMax)));
+			if(text.size() < static_cast<size_t>(data.item.cchTextMax)) {
+				data.item.pszText[text.size()] = 0;
 			}
 		}
-		if(nm->item.mask & LVIF_IMAGE) {
-			ContentType* content = reinterpret_cast<ContentType*>(nm->item.lParam);
-			nm->item.iImage = content->getImage(nm->item.iSubItem);
+		if(data.item.mask & LVIF_IMAGE) {
+			ContentType* content = reinterpret_cast<ContentType*>(data.item.lParam);
+			data.item.iImage = content->getImage(data.item.iSubItem);
 		}
-		return true;
 	}
 
 	void handleColumnClick(int column) {
@@ -204,6 +219,25 @@
 		}
 	}
 
+	int handleSort(LPARAM lhs, LPARAM rhs) {
+		return ContentType::compareItems(reinterpret_cast<ContentType*>(lhs), reinterpret_cast<ContentType*>(rhs), this->getSortColumn());
+	}
+
+	template<typename Ret> typename std::enable_if<customColors, Ret>::type handleCustomDraw(NMLVCUSTOMDRAW& data) {
+		switch(data.nmcd.dwDrawStage) {
+		case CDDS_PREPAINT:
+			return CDRF_NOTIFYITEMDRAW;
+
+		case CDDS_ITEMPREPAINT:
+			return reinterpret_cast<ContentType*>(data.nmcd.lItemlParam)->getColor(data.clrText, data.clrTextBk, -1);
+
+		case CDDS_SUBITEM | CDDS_ITEMPREPAINT:
+			return reinterpret_cast<ContentType*>(data.nmcd.lItemlParam)->getColor(data.clrText, data.clrTextBk, data.iSubItem);
+
+		default:
+			return CDRF_DODEFAULT;
+		}
+	}
 };
 
-#endif // !defined(TYPED_LIST_VIEW_CTRL_H)
+#endif

=== modified file 'win32/TypedTree.h'
--- win32/TypedTree.h	2011-11-12 19:36:12 +0000
+++ win32/TypedTree.h	2011-11-13 16:46:43 +0000
@@ -16,12 +16,12 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-#ifndef DCPLUSPLUS_WIN32_TYPED_TREE_VIEW_H
-#define DCPLUSPLUS_WIN32_TYPED_TREE_VIEW_H
+#ifndef DCPLUSPLUS_WIN32_TYPED_TREE_H
+#define DCPLUSPLUS_WIN32_TYPED_TREE_H
 
 #include "WinUtil.h"
 
-template<class ContentType>
+template<typename ContentType>
 class TypedTree : public dwt::Tree
 {
 	typedef typename dwt::Tree BaseType;
@@ -35,15 +35,18 @@
 	struct Seed : public BaseType::Seed {
 		typedef ThisType WidgetType;
 
-		explicit Seed(const BaseType::Seed& seed) : BaseType::Seed(seed) {
+		Seed(const BaseType::Seed& seed) : BaseType::Seed(seed) {
 		}
 	};
 
-	void create( const typename BaseType::Seed & cs = BaseType::Seed() ) {
-		BaseType::create(cs);
-		this->addCallback(
-			dwt::Message( WM_NOTIFY, TVN_GETDISPINFO ), &TypedTreeDispatcher
-		);
+	void create(const Seed& seed) {
+		BaseType::create(seed);
+
+		this->onRaw([this](WPARAM, LPARAM lParam) -> LRESULT {
+			auto& data = *reinterpret_cast<NMTVDISPINFO*>(lParam);
+			this->handleDisplay(data);
+			return 0;
+		}, dwt::Message(WM_NOTIFY, TVN_GETDISPINFO));
 	}
 
 	HTREEITEM insert(HTREEITEM parent, ContentType* data, bool expanded = false) {
@@ -80,29 +83,26 @@
 	void setItemState(HTREEITEM item, int state, int mask) {
 		TreeView_SetItemState(this->handle(), item, state, mask);
 	}
+
 private:
-
-	static bool TypedTreeDispatcher(const MSG& msg, LRESULT& res) {
-		NMTVDISPINFO * nm = reinterpret_cast< NMTVDISPINFO * >( msg.lParam );
-		if(nm->item.mask & TVIF_TEXT) {
-			ContentType* content = reinterpret_cast<ContentType*>(nm->item.lParam);
+	void handleDisplay(NMTVDISPINFO& data) {
+		if(data.item.mask & TVIF_TEXT) {
+			ContentType* content = reinterpret_cast<ContentType*>(data.item.lParam);
 			const tstring& text = content->getText();
-			_tcsncpy(nm->item.pszText, text.data(), std::min(text.size(), (size_t)nm->item.cchTextMax));
-			if(text.size() < static_cast<size_t>(nm->item.cchTextMax)) {
-				nm->item.pszText[text.size()] = 0;
+			_tcsncpy(data.item.pszText, text.data(), std::min(text.size(), static_cast<size_t>(data.item.cchTextMax)));
+			if(text.size() < static_cast<size_t>(data.item.cchTextMax)) {
+				data.item.pszText[text.size()] = 0;
 			}
 		}
-		if(nm->item.mask & TVIF_IMAGE) {
-			ContentType* content = reinterpret_cast<ContentType*>(nm->item.lParam);
-			nm->item.iImage = content->getImage();
-		}
-		if(nm->item.mask & TVIF_SELECTEDIMAGE) {
-			ContentType* content = reinterpret_cast<ContentType*>(nm->item.lParam);
-			nm->item.iSelectedImage = content->getSelectedImage();
-		}
-		return 0;
+		if(data.item.mask & TVIF_IMAGE) {
+			ContentType* content = reinterpret_cast<ContentType*>(data.item.lParam);
+			data.item.iImage = content->getImage();
+		}
+		if(data.item.mask & TVIF_SELECTEDIMAGE) {
+			ContentType* content = reinterpret_cast<ContentType*>(data.item.lParam);
+			data.item.iSelectedImage = content->getSelectedImage();
+		}
 	}
-
 };
 
-#endif // !defined(TYPED_TREE_VIEW_H)
+#endif

=== modified file 'win32/forward.h'
--- win32/forward.h	2011-05-04 19:32:00 +0000
+++ win32/forward.h	2011-11-13 16:46:43 +0000
@@ -57,10 +57,10 @@
 
 class TransferView;
 
-template<class ContentType, bool managed = true>
+template<typename ContentType, bool managed = true, bool customColors = false>
 class TypedTable;
 
-template<class ContentType>
+template<typename ContentType>
 class TypedTree;
 
 #endif /* FORWARD_H_ */