← Back to team overview

linuxdcpp-team team mailing list archive

[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2665: add a custom draw dispatcher

 

------------------------------------------------------------
revno: 2665
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Mon 2011-11-07 18:59:57 +0100
message:
  add a custom draw dispatcher
added:
  dwt/include/dwt/aspects/CustomDraw.h
modified:
  dwt/include/dwt/widgets/Rebar.h
  dwt/include/dwt/widgets/Table.h
  dwt/include/dwt/widgets/ToolBar.h
  dwt/include/dwt/widgets/ToolTip.h
  dwt/include/dwt/widgets/Tree.h
  dwt/src/widgets/Table.cpp
  win32/TransferView.cpp
  win32/TransferView.h
  win32/TypedTable.h
  win32/UCPage.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
=== added file 'dwt/include/dwt/aspects/CustomDraw.h'
--- dwt/include/dwt/aspects/CustomDraw.h	1970-01-01 00:00:00 +0000
+++ dwt/include/dwt/aspects/CustomDraw.h	2011-11-07 17:59:57 +0000
@@ -0,0 +1,63 @@
+/*
+  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.
+*/
+
+#ifndef DWT_CUSTOMDRAW_H
+#define DWT_CUSTOMDRAW_H
+
+#include "../Dispatchers.h"
+#include "../Message.h"
+
+namespace dwt { namespace aspects {
+
+template<typename WidgetType, typename DataType>
+class CustomDraw {
+	const WidgetType& W() const { return *static_cast<const WidgetType*>(this); }
+	WidgetType& W() { return *static_cast<WidgetType*>(this); }
+
+	struct Dispatcher : Dispatchers::Base<LRESULT (DataType&)> {
+		typedef Dispatchers::Base<LRESULT (DataType&)> BaseType;
+		Dispatcher(const F& f) : BaseType(f) { }
+
+		bool operator()(const MSG& msg, LRESULT& ret) const {
+			ret = f(*reinterpret_cast<DataType*>(msg.lParam));
+			return true;
+		}
+	};
+
+public:
+	void onCustomDraw(const typename Dispatcher::F& f) {
+		W().setCallback(Message(WM_NOTIFY, NM_CUSTOMDRAW), Dispatcher(f));
+	}
+};
+
+} }
+
+#endif

=== modified file 'dwt/include/dwt/widgets/Rebar.h'
--- dwt/include/dwt/widgets/Rebar.h	2011-03-15 21:16:24 +0000
+++ dwt/include/dwt/widgets/Rebar.h	2011-11-07 17:59:57 +0000
@@ -37,6 +37,7 @@
 #define DWT_Rebar_h
 
 #include "Control.h"
+#include "../aspects/CustomDraw.h"
 
 namespace dwt {
 
@@ -52,7 +53,8 @@
   * complex Widgets lke for instance a ComboBox, a TextBox and so on...
   */
 class Rebar :
-	public Control
+	public Control,
+	public aspects::CustomDraw<Rebar, NMCUSTOMDRAW>
 {
 	typedef Control BaseType;
 

=== modified file 'dwt/include/dwt/widgets/Table.h'
--- dwt/include/dwt/widgets/Table.h	2011-04-23 10:33:55 +0000
+++ dwt/include/dwt/widgets/Table.h	2011-11-07 17:59:57 +0000
@@ -42,6 +42,7 @@
 #include "../aspects/AspectClickable.h"
 #include "../aspects/AspectCollection.h"
 #include "../aspects/AspectColor.h"
+#include "../aspects/CustomDraw.h"
 #include "../aspects/AspectData.h"
 #include "../aspects/AspectScrollable.h"
 #include "../aspects/AspectSelection.h"
@@ -73,6 +74,7 @@
 	public AspectClickable< Table >,
 	public AspectCollection<Table, int>,
 	public AspectColor<Table>,
+	public aspects::CustomDraw<Table, NMLVCUSTOMDRAW>,
 	public AspectData<Table, int>,
 	public AspectScrollable< Table >,
 	public AspectSelection< Table, int >
@@ -618,41 +620,6 @@
 	);
 }
 
-
-void Table::onCustomPainting( typename MessageMapControl< EventHandlerClass, Table >::itsVoidUnsignedUnsignedBoolCanvasRectangle eventHandler )
-{
-	MessageMapType * ptrThis = boost::polymorphic_cast< MessageMapType * >( this );
-	ptrThis->addCallback(
-		typename MessageMapType::SignalTupleType(
-			private_::SignalContent(
-				Message( WM_NOTIFY, NM_CUSTOMDRAW ),
-				reinterpret_cast< itsVoidFunction >( eventHandler ),
-				ptrThis
-			),
-			typename MessageMapType::SignalType(
-				typename MessageMapType::SignalType::SlotType( & DispatcherList::dispatchDrawItemThis )
-			)
-		)
-	);
-}
-
-
-	void Table::onCustomPainting( typename MessageMapControl< EventHandlerClass, Table >::voidUnsignedUnsignedBoolCanvasRectangle eventHandler )
-{
-	MessageMapType * ptrThis = boost::polymorphic_cast< MessageMapType * >( this );
-	ptrThis->addCallback(
-		typename MessageMapType::SignalTupleType(
-			private_::SignalContent(
-				Message( WM_NOTIFY, NM_CUSTOMDRAW ),
-				reinterpret_cast< private_::SignalContent::voidFunctionTakingVoid >( eventHandler ),
-				ptrThis
-			),
-			typename MessageMapType::SignalType(
-				typename MessageMapType::SignalType::SlotType( & DispatcherList::dispatchDrawItem )
-			)
-		)
-	);
-}
 #endif
 
 inline void Table::onColumnClick( const HeaderDispatcher::F& f ) {

=== modified file 'dwt/include/dwt/widgets/ToolBar.h'
--- dwt/include/dwt/widgets/ToolBar.h	2011-03-18 21:48:06 +0000
+++ dwt/include/dwt/widgets/ToolBar.h	2011-11-07 17:59:57 +0000
@@ -37,6 +37,7 @@
 #define DWT_ToolBar_h
 
 #include "../Dispatchers.h"
+#include "../aspects/CustomDraw.h"
 #include "../resources/ImageList.h"
 #include "../DWTException.h"
 #include "Control.h"
@@ -54,7 +55,8 @@
   * to view the log of URL's you have been to etc...
   */
 class ToolBar :
-	public Control
+	public Control,
+	public aspects::CustomDraw<ToolBar, NMTBCUSTOMDRAW>
 {
 	typedef Control BaseType;
 	typedef Dispatchers::VoidVoid<> Dispatcher;

=== modified file 'dwt/include/dwt/widgets/ToolTip.h'
--- dwt/include/dwt/widgets/ToolTip.h	2011-01-02 17:12:02 +0000
+++ dwt/include/dwt/widgets/ToolTip.h	2011-11-07 17:59:57 +0000
@@ -33,6 +33,7 @@
 #define DWT_ToolTip_H_
 
 #include "../Widget.h"
+#include "../aspects/CustomDraw.h"
 #include "../aspects/AspectEnabled.h"
 #include "../aspects/AspectFont.h"
 #include "../aspects/AspectRaw.h"
@@ -43,8 +44,7 @@
 
 class ToolTip :
 	public Widget,
-
-	// Aspects
+	public aspects::CustomDraw<ToolTip, NMTTCUSTOMDRAW>,
 	public AspectEnabled< ToolTip >,
 	public AspectFont< ToolTip >,
 	public AspectRaw< ToolTip >,

=== modified file 'dwt/include/dwt/widgets/Tree.h'
--- dwt/include/dwt/widgets/Tree.h	2011-04-20 16:35:03 +0000
+++ dwt/include/dwt/widgets/Tree.h	2011-11-07 17:59:57 +0000
@@ -41,6 +41,7 @@
 #include "../aspects/AspectClickable.h"
 #include "../aspects/AspectCollection.h"
 #include "../aspects/AspectColor.h"
+#include "../aspects/CustomDraw.h"
 #include "../aspects/AspectData.h"
 #include "../aspects/AspectSelection.h"
 #include "Control.h"
@@ -72,10 +73,10 @@
    */
 class Tree :
 	public CommonControl,
-	// Aspects
 	public AspectClickable< Tree >,
 	public AspectCollection<Tree, HTREEITEM>,
 	public AspectColor<Tree>,
+	public aspects::CustomDraw<Tree, NMTVCUSTOMDRAW>,
 	public AspectData<Tree, HTREEITEM>,
 	public AspectSelection< Tree, HTREEITEM >
 {

=== modified file 'dwt/src/widgets/Table.cpp'
--- dwt/src/widgets/Table.cpp	2011-06-28 20:07:49 +0000
+++ dwt/src/widgets/Table.cpp	2011-11-07 17:59:57 +0000
@@ -373,45 +373,42 @@
 void Table::handleGroupDraw(COLORREF bgColor) {
 	theme.load(VSCLASS_LISTVIEW, this);
 
-	onRaw([this, bgColor](WPARAM, LPARAM lParam) -> LRESULT {
-		if(!grouped || !lParam)
+	onCustomDraw([this, bgColor](NMLVCUSTOMDRAW& data) -> LRESULT {
+		if(!grouped || data.dwItemType != LVCDI_GROUP)
 			return CDRF_DODEFAULT;
-		auto& data = *reinterpret_cast<LPNMLVCUSTOMDRAW>(lParam);
-		if(data.dwItemType == LVCDI_GROUP) {
-			switch(data.nmcd.dwDrawStage) {
-			case CDDS_PREPAINT:
+		switch(data.nmcd.dwDrawStage) {
+		case CDDS_PREPAINT:
+			{
+				// got a group! get the current theme text color and compare it to the bg.
+				COLORREF color = theme ? theme.getColor(LVP_GROUPHEADER, LVGH_OPEN, TMT_HEADING1TEXTCOLOR) : NaC;
+				if(color == NaC)
+					color = 0; // assume black
+				if(abs(GetRValue(color) + GetGValue(color) + GetBValue(color)
+					- GetRValue(bgColor) - GetGValue(bgColor) - GetBValue(bgColor)) < 300)
 				{
-					// got a group! get the current theme text color and compare it to the bg.
-					COLORREF color = theme ? theme.getColor(LVP_GROUPHEADER, LVGH_OPEN, TMT_HEADING1TEXTCOLOR) : NaC;
-					if(color == NaC)
-						color = 0; // assume black
-					if(abs(GetRValue(color) + GetGValue(color) + GetBValue(color)
-						- GetRValue(bgColor) - GetGValue(bgColor) - GetBValue(bgColor)) < 300)
-					{
-						/* the theme color and the bg color are too close to each other; start by
-						filling the canvas with an invert of the bg, then invert the whole canvas
-						after everything has been drawn (after CDDS_POSTPAINT). */
-						Rectangle rect(data.rcText);
-						if(!theme && util::win32::ensureVersion(util::win32::VISTA))
-							rect.size.y += 6;
-						FreeCanvas(data.nmcd.hdc).fill(rect, Brush(0xFFFFFF - bgColor));
+					/* the theme color and the bg color are too close to each other; start by
+					filling the canvas with an invert of the bg, then invert the whole canvas after
+					everything has been drawn (after CDDS_POSTPAINT). */
+					Rectangle rect(data.rcText);
+					if(!theme && util::win32::ensureVersion(util::win32::VISTA))
+						rect.size.y += 6;
+					FreeCanvas(data.nmcd.hdc).fill(rect, Brush(0xFFFFFF - bgColor));
 
-						// set a flag so we don't have to re-compare colors on CDDS_POSTPAINT.
-						data.nmcd.lItemlParam = 1;
-					}
-					break;
-				}
-			case CDDS_POSTPAINT:
-				{
-					if(data.nmcd.lItemlParam) {
-						FreeCanvas(data.nmcd.hdc).invert(Region(Rectangle(data.rcText)));
-					}
-					break;
-				}
+					// set a flag so we don't have to re-compare colors on CDDS_POSTPAINT.
+					data.nmcd.lItemlParam = 1;
+				}
+				break;
+			}
+		case CDDS_POSTPAINT:
+			{
+				if(data.nmcd.lItemlParam) {
+					FreeCanvas(data.nmcd.hdc).invert(Region(Rectangle(data.rcText)));
+				}
+				break;
 			}
 		}
 		return CDRF_DODEFAULT;
-	}, Message(WM_NOTIFY, NM_CUSTOMDRAW));
+	});
 }
 
 LPARAM Table::getDataImpl(int idx) {

=== modified file 'win32/TransferView.cpp'
--- win32/TransferView.cpp	2011-10-11 18:38:23 +0000
+++ win32/TransferView.cpp	2011-11-07 17:59:57 +0000
@@ -126,7 +126,7 @@
 		connections->onContextMenu([this](const dwt::ScreenCoordinate &sc) { return handleConnectionsMenu(sc); });
 		connections->onKeyDown([this](int c) { return handleKeyDown(c); });
 		connections->onDblClicked([this] { handleDblClicked(); });
-		connections->onRaw([this](WPARAM w, LPARAM l) { return handleCustomDraw(w, l); }, dwt::Message(WM_NOTIFY, NM_CUSTOMDRAW));
+		connections->onCustomDraw([this](NMLVCUSTOMDRAW& data) { return handleCustomDraw(data); });
 
 		prepareUserList(connections);
 	}
@@ -140,7 +140,7 @@
 		downloads->setSmallImageList(WinUtil::fileImages);
 
 		downloads->onContextMenu([this](const dwt::ScreenCoordinate &sc) { return handleDownloadsMenu(sc); });
-		downloads->onRaw([this](WPARAM w, LPARAM l) { return handleCustomDraw(w, l); }, dwt::Message(WM_NOTIFY, NM_CUSTOMDRAW));
+		downloads->onCustomDraw([this](NMLVCUSTOMDRAW& data) { return handleCustomDraw(data); });
 	}
 
 	onRaw([this](WPARAM, LPARAM) { return handleDestroy(); }, dwt::Message(WM_DESTROY));
@@ -376,12 +376,11 @@
 	::SetBkMode(hdc, oldMode);
 }
 
-LRESULT TransferView::handleCustomDraw(WPARAM wParam, LPARAM lParam) {
-	LPNMLVCUSTOMDRAW cd = (LPNMLVCUSTOMDRAW)lParam;
-	int item = (int)cd->nmcd.dwItemSpec;
-	int column = cd->iSubItem;
+LRESULT TransferView::handleCustomDraw(NMLVCUSTOMDRAW& data) {
+	int item = static_cast<int>(data.nmcd.dwItemSpec);
+	int column = data.iSubItem;
 
-	switch(cd->nmcd.dwDrawStage) {
+	switch(data.nmcd.dwDrawStage) {
 	case CDDS_PREPAINT:
 		return CDRF_NOTIFYITEMDRAW;
 
@@ -390,9 +389,9 @@
 
 	case CDDS_SUBITEM | CDDS_ITEMPREPAINT:
 		// Let's draw a box if needed...
-		if(cd->nmcd.hdr.hwndFrom == connections->handle() && column == CONNECTION_COLUMN_STATUS) {
-			HDC hdc = cd->nmcd.hdc;
-			ConnectionInfo* ci = reinterpret_cast<ConnectionInfo*>(cd->nmcd.lItemlParam);
+		if(data.nmcd.hdr.hwndFrom == connections->handle() && column == CONNECTION_COLUMN_STATUS) {
+			HDC hdc = data.nmcd.hdc;
+			ConnectionInfo* ci = reinterpret_cast<ConnectionInfo*>(data.nmcd.lItemlParam);
 
 			if(ci->status == ConnectionInfo::STATUS_RUNNING && ci->chunk > 0 && ci->chunkPos >= 0) {
 				const tstring& text = ci->columns[column];
@@ -406,9 +405,9 @@
 
 				return CDRF_SKIPDEFAULT;
 			}
-		} else if(cd->nmcd.hdr.hwndFrom == downloads->handle() && column == DOWNLOAD_COLUMN_STATUS) {
-			HDC hdc = cd->nmcd.hdc;
-			DownloadInfo* di = reinterpret_cast<DownloadInfo*>(cd->nmcd.lItemlParam);
+		} else if(data.nmcd.hdr.hwndFrom == downloads->handle() && column == DOWNLOAD_COLUMN_STATUS) {
+			HDC hdc = data.nmcd.hdc;
+			DownloadInfo* di = reinterpret_cast<DownloadInfo*>(data.nmcd.lItemlParam);
 			if(di->size > 0 && di->done >= 0) {
 				const tstring& text = di->columns[column];
 

=== modified file 'win32/TransferView.h'
--- win32/TransferView.h	2011-09-30 11:33:12 +0000
+++ win32/TransferView.h	2011-11-07 17:59:57 +0000
@@ -264,6 +264,7 @@
 	void runUserCommand(const UserCommand& uc);
 	bool handleKeyDown(int c);
 	void handleDblClicked();
+	LRESULT handleCustomDraw(NMLVCUSTOMDRAW& data);
 
 	int find(const string& path);
 
@@ -298,8 +299,6 @@
 	void onTransferComplete(Transfer* aTransfer, bool isDownload);
 	void onFailed(Download* aDownload, const string& aReason);
 	void starting(UpdateInfo* ui, Transfer* t);
-
-	LRESULT handleCustomDraw(WPARAM wParam, LPARAM lParam);
 };
 
 #endif // !defined(TRANSFER_VIEW_H)

=== modified file 'win32/TypedTable.h'
--- win32/TypedTable.h	2011-05-04 19:32:00 +0000
+++ win32/TypedTable.h	2011-11-07 17:59:57 +0000
@@ -102,8 +102,7 @@
 	};
 
 	void forEach(void (ContentType::*func)()) {
-		unsigned n = this->size();
-		for(unsigned i = 0; i < n; ++i)
+		for(size_t i = 0, n = this->size(); i < n; ++i)
 			(getData(i)->*func)();
 	}
 	void forEachSelected(void (ContentType::*func)(), bool removing = false) {
@@ -113,8 +112,7 @@
 	}
 	template<class _Function>
 	_Function forEachT(_Function pred) {
-		unsigned n = this->size();
-		for(unsigned i = 0; i < n; ++i)
+		for(size_t i = 0, n = this->size(); i < n; ++i)
 			pred(getData(i));
 		return pred;
 	}
@@ -122,9 +120,7 @@
 	_Function forEachSelectedT(_Function pred, bool removing = false) {
 		int i = -1;
 		while((i = ListView_GetNextItem(this->handle(), removing ? -1 : i, LVNI_SELECTED)) != -1) {
-			// Workaround for http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35569
-			ContentType* uib = getData(i);
-			pred(uib);
+			pred(getData(i));
 		}
 		return pred;
 	}

=== modified file 'win32/UCPage.cpp'
--- win32/UCPage.cpp	2011-10-22 16:41:13 +0000
+++ win32/UCPage.cpp	2011-11-07 17:59:57 +0000
@@ -170,7 +170,7 @@
 void UCPage::handleMoveDownClicked() {
 	if(commands->countSelected() == 1) {
 		auto i = commands->getSelected();
-		if(i == commands->size() - 1)
+		if(i == static_cast<int>(commands->size()) - 1)
 			return;
 		auto n = commands->getData(i);
 		FavoriteManager::getInstance()->moveUserCommand(n, 1);