← Back to team overview

linuxdcpp-team team mailing list archive

[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2684: No need to restart DC++ to apply new fonts

 

------------------------------------------------------------
revno: 2684
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Sun 2011-11-20 17:59:46 +0100
message:
  No need to restart DC++ to apply new fonts
modified:
  changelog.txt
  dwt/include/dwt/aspects/Colorable.h
  dwt/include/dwt/aspects/Fonts.h
  dwt/include/dwt/widgets/Menu.h
  dwt/include/dwt/widgets/RichTextBox.h
  dwt/include/dwt/widgets/TabView.h
  dwt/include/dwt/widgets/TextBox.h
  dwt/src/widgets/Menu.cpp
  dwt/src/widgets/RichTextBox.cpp
  dwt/src/widgets/TabView.cpp
  dwt/src/widgets/TextBox.cpp
  win32/MainWindow.cpp
  win32/WinUtil.cpp
  win32/WinUtil.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 'changelog.txt'
--- changelog.txt	2011-11-19 00:10:54 +0000
+++ changelog.txt	2011-11-20 16:59:46 +0000
@@ -50,7 +50,7 @@
 * [L#874282] Fix the "Close disconnected hubs" command (poy)
 * [L#721102] Close tabs when releasing the mouse button (poy)
 * [L#729684] Fix the /userlist chat command (poy)
-* No need to restart DC++ to apply new colors (poy)
+* No need to restart DC++ to apply new styles (poy)
 
 -- 0.782 2011-03-05 --
 * Prevent a remote crash triggered via malformed user commands (poy)

=== modified file 'dwt/include/dwt/aspects/Colorable.h'
--- dwt/include/dwt/aspects/Colorable.h	2011-11-19 00:10:54 +0000
+++ dwt/include/dwt/aspects/Colorable.h	2011-11-20 16:59:46 +0000
@@ -53,7 +53,7 @@
 		W().setColorImpl(text, background);
 	}
 
-private:
+protected:
 	virtual void setColorImpl(COLORREF text, COLORREF background) {
 		BrushPtr brush(new Brush(background));
 		W().setCallback(Message(WM_CTLCOLOR), [text, background, brush](const MSG& msg, LRESULT& ret) -> bool {

=== modified file 'dwt/include/dwt/aspects/Fonts.h'
--- dwt/include/dwt/aspects/Fonts.h	2011-11-07 20:53:49 +0000
+++ dwt/include/dwt/aspects/Fonts.h	2011-11-20 16:59:46 +0000
@@ -41,69 +41,54 @@
 
 namespace dwt { namespace aspects {
 
-/// Aspect class used by Widgets that have the possibility of setting the
-/// "font" property of their objects.
-template< class WidgetType >
+/** Aspect class used by Widgets that have the possibility of changing their main font. By default,
+this is done by sending a WM_SETFONT message. Widgets that want to customize this behavior can
+provide a void setFontImpl(FontPtr font) function. */
+template<typename WidgetType>
 class Fonts
 {
 	WidgetType& W() { return *static_cast<WidgetType*>(this); }
+
 public:
 	/// Fills a Point with the size of text to be drawn in the Widget's font.
 	/** getTextSize determines the height and width that text will take. <br>
 	  * This is useful if you want to allocate enough space to fit known text. <br>
 	  * It accounts for the set font too.
 	  */
-	Point getTextSize(const tstring& text);
+	Point getTextSize(const tstring& text) {
+		UpdateCanvas c(&W());
+		auto select(c.select(*W().getFont()));
+
+		Rectangle rect;
+		c.drawText(text, rect, DT_CALCRECT | DT_NOPREFIX);
+
+		return rect.size;
+	}
 
 	/// Sets the font used by the Widget
-	/** Changes the font of the Widget to the given font. Use the class Font to
-	  * construct a font in which to set by this function.
-	  */
-	void setFont( const FontPtr& font, bool forceUpdate = true );
+	void setFont(FontPtr font) {
+		this->font = font ? font : new Font(Font::DefaultGui);
+		W().setFontImpl(this->font);
+	}
 
 	/// Returns the font used by the Widget
-	/** Returns the Font object currently being used by the Widget
-	  */
-	const FontPtr& getFont();
+	const FontPtr& getFont() {
+		if(!font) {
+			font = new Font(reinterpret_cast<HFONT>(W().sendMessage(WM_GETFONT)), false);
+		}
+		return font;
+	}
+
+protected:
+	virtual void setFontImpl(FontPtr) {
+		W().sendMessage(WM_SETFONT, reinterpret_cast<WPARAM>(font->handle()), TRUE);
+	}
 
 private:
 	// Keep a reference around so it doesn't get deleted
 	FontPtr font;
 };
 
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Implementation of class
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-template< class WidgetType >
-Point Fonts< WidgetType >::getTextSize( const tstring & text )
-{
-	UpdateCanvas c(&W());
-	auto select(c.select(*W().getFont()));
-
-	Rectangle rect;
-	c.drawText(text, rect, DT_CALCRECT | DT_NOPREFIX);
-
-	return rect.size;
-}
-
-
-template< class WidgetType >
-void Fonts< WidgetType >::setFont( const FontPtr& font_, bool forceUpdate )
-{
-	font = font_ ? font_ : new Font(Font::DefaultGui);
-	W().sendMessage(WM_SETFONT, reinterpret_cast< WPARAM >( font->handle() ), static_cast< LPARAM >( forceUpdate ) );
-}
-
-template< class WidgetType >
-const FontPtr& Fonts< WidgetType >::getFont()
-{
-	if(!font) {
-		font = new Font(reinterpret_cast<HFONT>(W().sendMessage(WM_GETFONT)), false);
-	}
-	return font;
-}
-
 } }
 
 #endif

=== modified file 'dwt/include/dwt/widgets/Menu.h'
--- dwt/include/dwt/widgets/Menu.h	2011-06-02 18:20:54 +0000
+++ dwt/include/dwt/widgets/Menu.h	2011-11-20 16:59:46 +0000
@@ -204,11 +204,13 @@
 	*/
 	void setTitle(const tstring& title, const IconPtr& icon = IconPtr(), bool drawSidebar = false);
 
+	void setFont(FontPtr font);
+
 	/// Sets title font
 	/** Create a font through e.g. createFont in WidgetFactory or similar and set the
 	* title font to the menu title through using this function
 	*/
-	void setTitleFont( FontPtr font );
+	void setTitleFont(FontPtr font);
 
 	/// Removes menu title
 	/** If clearSidebar is true, sidebar is removed
@@ -339,13 +341,11 @@
 
 	FontPtr font;
 	FontPtr boldFont; // for default items
+	FontPtr titleFont; // Menu title font
 
 	// Menu title
 	tstring itsTitle;
 
-	// Menu title font
-	FontPtr itsTitleFont;
-
 	// if true title is drawn as sidebar
 	bool drawSidebar;
 

=== modified file 'dwt/include/dwt/widgets/RichTextBox.h'
--- dwt/include/dwt/widgets/RichTextBox.h	2011-11-19 00:10:54 +0000
+++ dwt/include/dwt/widgets/RichTextBox.h	2011-11-20 16:59:46 +0000
@@ -79,8 +79,6 @@
 		typedef RichTextBox::ThisType WidgetType;
 
 		FontPtr font;
-		COLORREF foregroundColor; /// the text color, or NaC for the default
-		COLORREF backgroundColor; /// the background color, or NaC for the default
 		bool scrollBarHorizontallyFlag;
 		bool scrollBarVerticallyFlag;
 
@@ -126,6 +124,9 @@
 	/// escape Rich Edit control chars: {, }, and \, as well as \n which becomes \line.
 	static tstring rtfEscape(const tstring& str);
 
+	void setTextColor(COLORREF color);
+	void setBgColor(COLORREF color);
+
 protected:
 	tstring currentNeedle;		// search in chat window
 	int currentNeedlePos;		// search in chat window
@@ -155,10 +156,17 @@
 	void setTextA(const std::string& txt);
 	void setTextEx(const std::string& txt, DWORD format);
 
+	void updateTextColor();
+
 	// aspects::Colorable
 	void setColorImpl(COLORREF text, COLORREF background);
 
-	COLORREF bgColor; // store the current bg color for the onPrinting handler.
+	// aspects::Font
+	void setFontImpl(FontPtr font);
+
+	// store current colors for the onPrinting handler and for setFontImpl.
+	COLORREF textColor;
+	COLORREF bgColor;
 };
 
 // end namespace dwt

=== modified file 'dwt/include/dwt/widgets/TabView.h'
--- dwt/include/dwt/widgets/TabView.h	2011-11-07 20:53:49 +0000
+++ dwt/include/dwt/widgets/TabView.h	2011-11-20 16:59:46 +0000
@@ -229,6 +229,9 @@
 	void clearImpl();
 	size_t sizeImpl() const;
 
+	// aspects::Font
+	void setFontImpl(FontPtr font);
+
 	// aspects::Help
 	void helpImpl(unsigned& id);
 

=== modified file 'dwt/include/dwt/widgets/TextBox.h'
--- dwt/include/dwt/widgets/TextBox.h	2011-11-19 00:10:54 +0000
+++ dwt/include/dwt/widgets/TextBox.h	2011-11-20 16:59:46 +0000
@@ -192,6 +192,9 @@
 
 	void create(const Seed& cs);
 
+	// aspects::Font
+	virtual void setFontImpl(FontPtr font);
+
 	// Contract needed by aspects::Update Aspect class
 	static Message getUpdateMessage();
 

=== modified file 'dwt/src/widgets/Menu.cpp'
--- dwt/src/widgets/Menu.cpp	2011-06-28 20:07:49 +0000
+++ dwt/src/widgets/Menu.cpp	2011-11-20 16:59:46 +0000
@@ -98,8 +98,7 @@
 	if(ownerDrawn) {
 		iconSize = cs.iconSize;
 
-		font = cs.font ? cs.font : new Font(Font::DefaultGui);
-		itsTitleFont = boldFont = font->makeBold();
+		setFont(cs.font);
 
 		if(!popup) {
 			getParent()->addCallback(Message(WM_SYSCOLORCHANGE), Dispatchers::VoidVoid<0, false>([] { colors.reset(); }));
@@ -301,9 +300,14 @@
 	wrapper = 0;
 }
 
-void Menu::setTitleFont( FontPtr font )
-{
-	itsTitleFont = font;
+void Menu::setFont(FontPtr font) {
+	this->font = font ? font : new Font(Font::DefaultGui);
+	titleFont = boldFont = this->font->makeBold();
+	std::for_each(itsChildren.begin(), itsChildren.end(), [this](MenuPtr sub) { sub->setFont(this->font); });
+}
+
+void Menu::setTitleFont(FontPtr font) {
+	titleFont = font;
 }
 
 void Menu::clearTitle( bool clearSidebar /* = false */)
@@ -440,7 +444,7 @@
 	if(drawSidebar) {
 		// get logical info for title font
 		LOGFONT lf;
-		::GetObject(itsTitleFont->handle(), sizeof(lf), &lf);
+		::GetObject(titleFont->handle(), sizeof(lf), &lf);
 
 		// 90 degree rotation and bold
 		lf.lfOrientation = lf.lfEscapement = 900;
@@ -591,7 +595,7 @@
 
 			// Select item font
 			auto select(canvas.select(*(
-				wrapper.isTitle ? itsTitleFont :
+				wrapper.isTitle ? titleFont :
 				wrapper.isDefault ? boldFont :
 				font)));
 
@@ -759,7 +763,7 @@
 	}
 
 	Point textSize = getTextSize(getText(wrapper.index),
-		wrapper.isTitle ? itsTitleFont :
+		wrapper.isTitle ? titleFont :
 		wrapper.isDefault ? boldFont :
 		font);
 	if(!wrapper.isTitle) // the title will adjust its hor size per others and add ellipsis if needed
@@ -781,7 +785,7 @@
 
 	// adjust width for sidebar
 	if(drawSidebar)
-		itemWidth += getTextSize(getText(0), itsTitleFont).y; // 0 is the title index
+		itemWidth += getTextSize(getText(0), titleFont).y; // 0 is the title index
 
 	// make sure the calculated size is acceptable
 	if(getRootMenu()->popup) {

=== modified file 'dwt/src/widgets/RichTextBox.cpp'
--- dwt/src/widgets/RichTextBox.cpp	2011-11-18 18:27:17 +0000
+++ dwt/src/widgets/RichTextBox.cpp	2011-11-20 16:59:46 +0000
@@ -49,8 +49,6 @@
 RichTextBox::Seed::Seed() :
 	BaseType::Seed(WS_CHILD | WS_TABSTOP | WS_VSCROLL | ES_LEFT | ES_AUTOVSCROLL | ES_MULTILINE | ES_NOHIDESEL),
 	font(0),
-	foregroundColor(NaC),
-	backgroundColor(NaC),
 	scrollBarHorizontallyFlag(false),
 	scrollBarVerticallyFlag(false)
 {
@@ -325,13 +323,24 @@
 	return escaped;
 }
 
-void RichTextBox::setColorImpl(COLORREF text, COLORREF background) {
+void RichTextBox::updateTextColor() {
 	CHARFORMAT textFormat = { sizeof(CHARFORMAT), CFM_COLOR };
-	textFormat.crTextColor = text;
+	textFormat.crTextColor = textColor;
 	sendMessage(EM_SETCHARFORMAT, SCF_DEFAULT, reinterpret_cast<LPARAM>(&textFormat));
+}
+
+void RichTextBox::setColorImpl(COLORREF text, COLORREF background) {
+	textColor = text;
+	updateTextColor();
 
 	bgColor = background;
 	sendMessage(EM_SETBKGNDCOLOR, 0, static_cast<LPARAM>(bgColor));
 }
 
+void RichTextBox::setFontImpl(FontPtr font) {
+	// changing the default font resets the default text color.
+	BaseType::setFontImpl(font);
+	updateTextColor();
+}
+
 }

=== modified file 'dwt/src/widgets/TabView.cpp'
--- dwt/src/widgets/TabView.cpp	2011-10-30 15:24:29 +0000
+++ dwt/src/widgets/TabView.cpp	2011-11-20 16:59:46 +0000
@@ -83,7 +83,6 @@
 
 	BaseType::create(cs);
 	setFont(cs.font);
-	font = getFont();
 
 	widthConfig = cs.widthConfig;
 	toggleActive = cs.toggleActive;
@@ -95,8 +94,6 @@
 			widthConfig = 100;
 		TabCtrl_SetMinTabWidth(handle(), widthConfig);
 
-		boldFont = font->makeBold();
-
 		closeIcon = cs.closeIcon;
 
 		if(cs.tabStyle == Seed::WinBrowser && util::win32::ensureVersion(util::win32::VISTA)) {
@@ -819,6 +816,14 @@
 	return false;
 }
 
+void TabView::setFontImpl(FontPtr font) {
+	BaseType::setFontImpl(font);
+	this->font = getFont(); // might be a default font, so get it this way.
+	if(hasStyle(TCS_OWNERDRAWFIXED)) {
+		boldFont = this->font->makeBold();
+	}
+}
+
 void TabView::helpImpl(unsigned& id) {
 	// we have the help id of the whole tab control; convert to the one of the specific tab the user just clicked on
 	TabInfo* ti = getTabInfo(hitTest(ScreenCoordinate(Point::fromLParam(::GetMessagePos()))));

=== modified file 'dwt/src/widgets/TextBox.cpp'
--- dwt/src/widgets/TextBox.cpp	2011-11-19 00:10:54 +0000
+++ dwt/src/widgets/TextBox.cpp	2011-11-20 16:59:46 +0000
@@ -237,6 +237,11 @@
 	return handled;
 }
 
+void TextBoxBase::setFontImpl(FontPtr font) {
+	BaseType::setFontImpl(font);
+	menuSeed.font = font;
+}
+
 bool TextBox::handleMessage(const MSG& msg, LRESULT& retVal) {
 	if(BaseType::handleMessage(msg, retVal))
 		return true;

=== modified file 'win32/MainWindow.cpp'
--- win32/MainWindow.cpp	2011-11-19 00:10:54 +0000
+++ win32/MainWindow.cpp	2011-11-20 16:59:46 +0000
@@ -1052,9 +1052,18 @@
 
 namespace {
 
+BOOL CALLBACK updateFont(HWND hwnd, LPARAM prevFont) {
+	dwt::Control* widget = dwt::hwnd_cast<dwt::Control*>(hwnd);
+	if(widget && widget->getFont()->handle() == reinterpret_cast<HFONT>(prevFont)) {
+		widget->setFont(WinUtil::font);
+	}
+	return TRUE;
+}
+
 BOOL CALLBACK updateColors(HWND hwnd, LPARAM) {
 	dwt::Control* widget = dwt::hwnd_cast<dwt::Control*>(hwnd);
 	if(widget) {
+		// not every widget is custom colored; those that are also catch ID_UPDATECOLOR (see WinUtil::setColor).
 		widget->sendCommand(ID_UPDATECOLOR);
 	}
 	return TRUE;
@@ -1078,6 +1087,8 @@
 	auto prevGeo = BOOLSETTING(GET_USER_COUNTRY);
 	auto prevGeoFormat = SETTING(COUNTRY_FORMAT);
 
+	auto prevFont = SETTING(MAIN_FONT);
+
 	auto prevTray = BOOLSETTING(ALWAYS_TRAY);
 	auto prevSortFavUsersFirst = BOOLSETTING(SORT_FAVUSERS_FIRST);
 	auto prevURLReg = BOOLSETTING(URL_HANDLER);
@@ -1111,6 +1122,14 @@
 			GeoManager::getInstance()->rebuild();
 		}
 
+		if(SETTING(MAIN_FONT) != prevFont) {
+			auto prev = WinUtil::font;
+			WinUtil::initFont();
+			::EnumChildWindows(handle(), updateFont, reinterpret_cast<LPARAM>(prev->handle()));
+			mainMenu->setFont(WinUtil::font);
+			::DrawMenuBar(handle());
+		}
+
 		bool newColors = false;
 		if(static_cast<COLORREF>(SETTING(TEXT_COLOR)) != WinUtil::textColor) {
 			WinUtil::textColor = SETTING(TEXT_COLOR);

=== modified file 'win32/WinUtil.cpp'
--- win32/WinUtil.cpp	2011-11-19 00:10:54 +0000
+++ win32/WinUtil.cpp	2011-11-20 16:59:46 +0000
@@ -145,11 +145,7 @@
 		SettingsManager::getInstance()->setDefault(SettingsManager::MAIN_FONT, Text::fromT(encodeFont(metrics.lfMessageFont)));
 	}
 
-	{
-		LOGFONT lf;
-		decodeFont(Text::toT(SETTING(MAIN_FONT)), lf);
-		font = dwt::FontPtr(new dwt::Font(lf));
-	}
+	initFont();
 
 	fileImages = dwt::ImageListPtr(new dwt::ImageList(dwt::Point(16, 16)));
 
@@ -207,6 +203,23 @@
 	registerHubHandlers();
 	registerMagnetHandler();
 
+	initHelpPath();
+
+	if(!helpPath.empty()) {
+		// load up context-sensitive help texts
+		try {
+			helpTexts = StringTokenizer<string> (File(Util::getFilePath(Text::fromT(helpPath)) + "cshelp.rtf",
+				File::READ, File::OPEN).read(), "\r\n").getTokens();
+		} catch (const FileException&) {
+		}
+	}
+
+#ifdef HAVE_HTMLHELP_H
+	::HtmlHelp(NULL, NULL, HH_INITIALIZE, reinterpret_cast<DWORD_PTR> (&helpCookie));
+#endif
+}
+
+void WinUtil::initSeeds() {
 	// Const so that noone else will change them after they've been initialized
 	Button::Seed& xbutton = const_cast<Button::Seed&> (Seeds::button);
 	ComboBox::Seed& xcomboBoxEdit = const_cast<ComboBox::Seed&> (Seeds::comboBoxEdit);
@@ -285,24 +298,9 @@
 	xdTextBox.menuSeed = Seeds::menu;
 	xRichTextBox.menuSeed = Seeds::menu;
 	xdRichTextBox.menuSeed = Seeds::menu;
-
-	init_helpPath();
-
-	if(!helpPath.empty()) {
-		// load up context-sensitive help texts
-		try {
-			helpTexts = StringTokenizer<string> (File(Util::getFilePath(Text::fromT(helpPath)) + "cshelp.rtf",
-				File::READ, File::OPEN).read(), "\r\n").getTokens();
-		} catch (const FileException&) {
-		}
-	}
-
-#ifdef HAVE_HTMLHELP_H
-	::HtmlHelp(NULL, NULL, HH_INITIALIZE, reinterpret_cast<DWORD_PTR> (&helpCookie));
-#endif
 }
 
-void WinUtil::init_helpPath() {
+void WinUtil::initHelpPath() {
 	// find the current locale
 	string lang = SETTING(LANGUAGE);
 	if(lang.empty())
@@ -351,6 +349,14 @@
 	}
 }
 
+void WinUtil::initFont() {
+	LOGFONT lf;
+	decodeFont(Text::toT(SETTING(MAIN_FONT)), lf);
+	font.reset(new dwt::Font(lf));
+
+	initSeeds();
+}
+
 tstring WinUtil::encodeFont(LOGFONT const& font) {
 	tstring res(font.lfFaceName);
 	res += _T(',');

=== modified file 'win32/WinUtil.h'
--- win32/WinUtil.h	2011-11-19 00:10:54 +0000
+++ win32/WinUtil.h	2011-11-20 16:59:46 +0000
@@ -161,6 +161,9 @@
 
 	static void enableDEP();
 
+	static void initSeeds();
+
+	static void initFont();
 	static tstring encodeFont(LOGFONT const& font);
 	static void decodeFont(const tstring& setting, LOGFONT &dest);
 
@@ -301,7 +304,7 @@
 private:
 	static bool handleBoxDblClick(dwt::TextBoxBase* box, const dwt::MouseEvent& ev);
 
-	static void init_helpPath();
+	static void initHelpPath();
 
 	static DWORD helpCookie;
 	static tstring helpPath;