← Back to team overview

linuxdcpp-team team mailing list archive

[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2201: change how themes are managed to allow multiple themes per widget

 

------------------------------------------------------------
revno: 2201
committer: poy <poy@xxxxxxxxxx>
branch nick: repo
timestamp: Tue 2010-08-10 18:28:19 +0200
message:
  change how themes are managed to allow multiple themes per widget
renamed:
  dwt/include/dwt/Themed.h => dwt/include/dwt/Theme.h
  dwt/src/Themed.cpp => dwt/src/Theme.cpp
modified:
  dwt/include/dwt/widgets/Menu.h
  dwt/include/dwt/widgets/TabView.h
  dwt/src/widgets/Menu.cpp
  dwt/src/widgets/TabView.cpp
  dwt/include/dwt/Theme.h
  dwt/src/Theme.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
=== renamed file 'dwt/include/dwt/Themed.h' => 'dwt/include/dwt/Theme.h'
--- dwt/include/dwt/Themed.h	2010-03-04 21:48:18 +0000
+++ dwt/include/dwt/Theme.h	2010-08-10 16:28:19 +0000
@@ -29,8 +29,8 @@
   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-#ifndef DWT_THEMED_H
-#define DWT_THEMED_H
+#ifndef DWT_THEME_H
+#define DWT_THEME_H
 
 #include "CanvasClasses.h"
 
@@ -38,33 +38,34 @@
 
 namespace dwt {
 
-/** helper class a widget can derive from. this class:
+/** helper class to manage a theme. this class:
 - manages calls to visual styles APIs without having to link to uxtheme.lib.
 - handles opening and closing the theme on destruction and on WM_THEMECHANGED.
 */
-class Themed {
-protected:
-	explicit Themed(Widget* w_);
-	virtual ~Themed();
+class Theme {
+public:
+	Theme();
+	virtual ~Theme();
 
-	void loadTheme(LPCWSTR classes, bool handleThemeChanges = true);
+	void load(LPCWSTR classes, Widget* w_, bool handleThemeChanges = true);
 
 	/**
 	* @param drawParent if false, you have to call isThemeBackgroundPartiallyTransparent and handle
 	* drawing the transparent bits yourself.
 	*/
-	void drawThemeBackground(Canvas& canvas, int part, int state, const Rectangle& rect, bool drawParent = true);
-	void drawThemeText(Canvas& canvas, int part, int state, const tstring& text, DWORD flags, const Rectangle& rect);
-	bool getThemePartSize(Canvas& canvas, int part, int state, Point& ret);
-	bool isThemeBackgroundPartiallyTransparent(int part, int state);
+	void drawBackground(Canvas& canvas, int part, int state, const Rectangle& rect, bool drawParent = true);
+	void drawText(Canvas& canvas, int part, int state, const tstring& text, DWORD flags, const Rectangle& rect);
+	bool getPartSize(Canvas& canvas, int part, int state, Point& ret);
+	bool isBackgroundPartiallyTransparent(int part, int state);
 
-	HTHEME theme;
+	operator bool() const;
 
 private:
-	void openTheme(LPCWSTR classes);
-	void closeTheme();
+	void open(LPCWSTR classes);
+	void close();
 	void themeChanged(LPCWSTR classes);
 
+	HTHEME theme;
 	Widget* w;
 };
 

=== modified file 'dwt/include/dwt/widgets/Menu.h'
--- dwt/include/dwt/widgets/Menu.h	2010-07-10 15:49:05 +0000
+++ dwt/include/dwt/widgets/Menu.h	2010-08-10 16:28:19 +0000
@@ -39,7 +39,7 @@
 
 #include "../CanvasClasses.h"
 #include "../Dispatchers.h"
-#include <dwt/Themed.h>
+#include <dwt/Theme.h>
 
 namespace dwt {
 
@@ -51,7 +51,7 @@
 * Window. <br>
 * Note for Desktop version only! <br>
 */
-class Menu : private boost::noncopyable, private Themed
+class Menu : private boost::noncopyable
 {
 	friend class WidgetCreator<Menu>;
 
@@ -355,6 +355,8 @@
 	typedef std::unique_ptr<std::vector<Dispatcher::F> > commands_type;
 	commands_type commands; // just a pointer because sub-menus don't need this
 
+	Theme theme;
+
 	Point iconSize;
 
 	FontPtr font;

=== modified file 'dwt/include/dwt/widgets/TabView.h'
--- dwt/include/dwt/widgets/TabView.h	2010-08-07 16:35:11 +0000
+++ dwt/include/dwt/widgets/TabView.h	2010-08-10 16:28:19 +0000
@@ -39,7 +39,7 @@
 #include "../aspects/AspectSelection.h"
 #include "../aspects/AspectText.h"
 #include "Control.h"
-#include <dwt/Themed.h>
+#include <dwt/Theme.h>
 
 #include <list>
 #include <vector>
@@ -54,8 +54,7 @@
 	private AspectCollection<TabView, int>,
 	public AspectPainting< TabView >,
 	public AspectSelection< TabView, int >,
-	public AspectText< TabView >,
-	private Themed
+	public AspectText< TabView >
 {
 	typedef CommonControl BaseType;
 	friend class AspectCollection<TabView, int>;
@@ -146,6 +145,7 @@
 		TabInfo(TabView* control_, ContainerPtr w_) : control(control_), w(w_), handleContextMenu(0), marked(false) { }
 	};
 
+	Theme theme;
 	ToolTipPtr tip;
 
 	TitleChangedFunction titleChangedFunction;

=== renamed file 'dwt/src/Themed.cpp' => 'dwt/src/Theme.cpp'
--- dwt/src/Themed.cpp	2010-07-10 14:36:48 +0000
+++ dwt/src/Theme.cpp	2010-08-10 16:28:19 +0000
@@ -29,7 +29,7 @@
   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-#include <dwt/Themed.h>
+#include <dwt/Theme.h>
 
 #include <dwt/Dispatchers.h>
 #include <dwt/LibraryLoader.h>
@@ -61,16 +61,15 @@
 typedef HWND (WINAPI *t_OpenThemeData)(HTHEME, LPCWSTR);
 static t_OpenThemeData OpenThemeData;
 
-Themed::Themed(Widget* w_) : theme(0), w(w_)
+Theme::Theme() : theme(0)
 {
-	dwtassert(w, _T("Themed: no widget set"));
-}
-
-Themed::~Themed() {
-	closeTheme();
-}
-
-void Themed::loadTheme(LPCWSTR classes, bool handleThemeChanges) {
+}
+
+Theme::~Theme() {
+	close();
+}
+
+void Theme::load(LPCWSTR classes, Widget* w_, bool handleThemeChanges) {
 	static LibraryLoader lib(_T("uxtheme"), true);
 	if(lib.loaded()) {
 
@@ -85,29 +84,32 @@
 		get(OpenThemeData);
 #undef get
 
-		openTheme(classes);
+		w = w_;
+		dwtassert(w, _T("Theme: no widget set"));
+
+		open(classes);
 
 		if(handleThemeChanges) {
 			w->addCallback(Message(WM_THEMECHANGED),
-				Dispatchers::VoidVoid<0, false>(std::bind(&Themed::themeChanged, this, classes)));
+				Dispatchers::VoidVoid<0, false>(std::bind(&Theme::themeChanged, this, classes)));
 		}
 	}
 }
 
-void Themed::drawThemeBackground(Canvas& canvas, int part, int state, const Rectangle& rect, bool drawParent) {
+void Theme::drawBackground(Canvas& canvas, int part, int state, const Rectangle& rect, bool drawParent) {
 	::RECT rc = rect;
-	if(drawParent && isThemeBackgroundPartiallyTransparent(part, state)) {
+	if(drawParent && isBackgroundPartiallyTransparent(part, state)) {
 		DrawThemeParentBackground(w->handle(), canvas.handle(), &rc);
 	}
 	DrawThemeBackground(theme, canvas.handle(), part, state, &rc, 0);
 }
 
-void Themed::drawThemeText(Canvas& canvas, int part, int state, const tstring& text, DWORD flags, const Rectangle& rect) {
+void Theme::drawText(Canvas& canvas, int part, int state, const tstring& text, DWORD flags, const Rectangle& rect) {
 	::RECT rc = rect;
 	DrawThemeText(theme, canvas.handle(), part, state, text.c_str(), text.size(), flags, 0, &rc);
 }
 
-bool Themed::getThemePartSize(Canvas& canvas, int part, int state, Point& ret) {
+bool Theme::getPartSize(Canvas& canvas, int part, int state, Point& ret) {
 	SIZE size;
 	if(GetThemePartSize(theme, canvas.handle(), part, state, 0, TS_TRUE, &size) == S_OK) {
 		ret.x = size.cx;
@@ -117,26 +119,30 @@
 	return false;
 }
 
-bool Themed::isThemeBackgroundPartiallyTransparent(int part, int state) {
+bool Theme::isBackgroundPartiallyTransparent(int part, int state) {
 	return IsThemeBackgroundPartiallyTransparent(theme, part, state);
 }
 
-void Themed::openTheme(LPCWSTR classes) {
+Theme::operator bool() const {
+	return theme;
+}
+
+void Theme::open(LPCWSTR classes) {
 	if(IsAppThemed()) {
 		theme = OpenThemeData(w->handle(), classes);
 	}
 }
 
-void Themed::closeTheme() {
+void Theme::close() {
 	if(theme) {
 		CloseThemeData(theme);
 		theme = 0;
 	}
 }
 
-void Themed::themeChanged(LPCWSTR classes) {
-	closeTheme();
-	openTheme(classes);
+void Theme::themeChanged(LPCWSTR classes) {
+	close();
+	open(classes);
 }
 
 }

=== modified file 'dwt/src/widgets/Menu.cpp'
--- dwt/src/widgets/Menu.cpp	2010-08-08 12:10:20 +0000
+++ dwt/src/widgets/Menu.cpp	2010-08-10 16:28:19 +0000
@@ -85,7 +85,6 @@
 }
 
 Menu::Menu(Widget* parent) :
-Themed(parent),
 parentMenu(0),
 itsParent(parent),
 ownerDrawn(true),
@@ -114,7 +113,7 @@
 			itsTitleFont = boldFont = FontPtr(new Font(::CreateFontIndirect(&lf), true));
 		}
 
-		loadTheme(VSCLASS_MENU, !popup);
+		theme.load(VSCLASS_MENU, itsParent, !popup);
 	}
 }
 
@@ -199,7 +198,7 @@
 		Rectangle rect_bg = rect;
 		rect_bg.pos.x -= 1;
 		rect_bg.size.x += 1;
-		drawThemeBackground(canvas, MENU_BARBACKGROUND, MB_ACTIVE, rect_bg, false);
+		theme.drawBackground(canvas, MENU_BARBACKGROUND, MB_ACTIVE, rect_bg, false);
 
 		canvas.blast(rect);
 	}
@@ -511,16 +510,16 @@
 			state_bg = MB_ACTIVE;
 		}
 
-		if(isThemeBackgroundPartiallyTransparent(part, state)) {
+		if(theme.isBackgroundPartiallyTransparent(part, state)) {
 			Rectangle rect = itemRectangle;
 			if(part_bg == MENU_BARBACKGROUND) {
 				// avoid non-drawn edges
 				rect.pos.x -= 1;
 				rect.size.x += 2;
 			}
-			drawThemeBackground(canvas, part_bg, state_bg, rect, false);
+			theme.drawBackground(canvas, part_bg, state_bg, rect, false);
 		}
-		drawThemeBackground(canvas, part, state, itemRectangle, false);
+		theme.drawBackground(canvas, part, state, itemRectangle, false);
 
 	} else {
 		canvas.fill(itemRectangle, Brush(
@@ -540,9 +539,9 @@
 
 	if(isChecked && theme) {
 		/// @todo we should also support bullets
-		drawThemeBackground(canvas, MENU_POPUPCHECKBACKGROUND, icon ? MCB_BITMAP : MCB_NORMAL, stripRectangle, false);
+		theme.drawBackground(canvas, MENU_POPUPCHECKBACKGROUND, icon ? MCB_BITMAP : MCB_NORMAL, stripRectangle, false);
 		if(!icon)
-			drawThemeBackground(canvas, MENU_POPUPCHECK, MC_CHECKMARKNORMAL, stripRectangle, false);
+			theme.drawBackground(canvas, MENU_POPUPCHECK, MC_CHECKMARKNORMAL, stripRectangle, false);
 	}
 
 	if(popup && info.fType & MFT_SEPARATOR) {
@@ -552,11 +551,11 @@
 
 		if(theme) {
 			Point pt;
-			if(getThemePartSize(canvas, MENU_POPUPSEPARATOR, 0, pt)) {
+			if(theme.getPartSize(canvas, MENU_POPUPSEPARATOR, 0, pt)) {
 				rectangle.size.x = std::min(rectangle.size.x, pt.x);
 				rectangle.size.y = std::min(rectangle.size.y, pt.y);
 			}
-			drawThemeBackground(canvas, MENU_POPUPSEPARATOR, 0, rectangle, false);
+			theme.drawBackground(canvas, MENU_POPUPSEPARATOR, 0, rectangle, false);
 
 		} else {
 			// center in the item rectangle
@@ -617,9 +616,9 @@
 				drawTextFormat |= DT_WORD_ELLIPSIS;
 
 			if(theme) {
-				drawThemeText(canvas, part, state, text, drawTextFormat, textRectangle);
+				theme.drawText(canvas, part, state, text, drawTextFormat, textRectangle);
 				if(!accelerator.empty())
-					drawThemeText(canvas, part, state, accelerator, drawAccelFormat, textRectangle);
+					theme.drawText(canvas, part, state, accelerator, drawAccelFormat, textRectangle);
 
 			} else {
 				bool oldMode = canvas.setBkMode(true);
@@ -718,7 +717,7 @@
 		if(theme) {
 			UpdateCanvas canvas(getParent());
 			Point pt;
-			if(getThemePartSize(canvas, MENU_POPUPSEPARATOR, 0, pt)) {
+			if(theme.getPartSize(canvas, MENU_POPUPSEPARATOR, 0, pt)) {
 				itemWidth = pt.x;
 				itemHeight = pt.y;
 				return true;

=== modified file 'dwt/src/widgets/TabView.cpp'
--- dwt/src/widgets/TabView.cpp	2010-08-10 15:31:21 +0000
+++ dwt/src/widgets/TabView.cpp	2010-08-10 16:28:19 +0000
@@ -58,7 +58,6 @@
 
 TabView::TabView(Widget* w) :
 BaseType(w, ChainingDispatcher::superClass<TabView>()),
-Themed(this),
 tip(0),
 toggleActive(false),
 font(0),
@@ -100,7 +99,7 @@
 		lf.lfWeight = FW_BOLD;
 		boldFont = FontPtr(new Font(::CreateFontIndirect(&lf), true));
 
-		loadTheme(VSCLASS_TAB);
+		theme.load(VSCLASS_TAB, this);
 
 		if(!(cs.style & TCS_BUTTONS)) {
 			// we don't want pre-drawn borders to get in the way here, so we fully take over painting.
@@ -661,7 +660,7 @@
 		part = TABP_TABITEM;
 		state = isSelected ? TIS_SELECTED : isHighlighted ? TIS_HOT : TIS_NORMAL;
 
-		drawThemeBackground(canvas, part, state, rect);
+		theme.drawBackground(canvas, part, state, rect);
 
 	} else {
 		canvas.fill(rect, Brush(isSelected ? Brush::Window : isHighlighted ? Brush::HighLight : Brush::BtnFace));
@@ -696,7 +695,7 @@
 	const unsigned dtFormat = DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX | DT_WORD_ELLIPSIS;
 	Canvas::Selector select(canvas, *((isSelected || ti->marked) ? boldFont : font));
 	if(theme) {
-		drawThemeText(canvas, part, state, text, dtFormat, rect);
+		theme.drawText(canvas, part, state, text, dtFormat, rect);
 	} else {
 		canvas.setTextColor(::GetSysColor(isSelected ? COLOR_WINDOWTEXT : isHighlighted ? COLOR_HIGHLIGHTTEXT : COLOR_BTNTEXT));
 		canvas.drawText(text, rect, dtFormat);