← Back to team overview

linuxdcpp-team team mailing list archive

[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2510: rework how status bar parts embed widgets

 

------------------------------------------------------------
revno: 2510
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Sun 2011-04-24 17:09:54 +0200
message:
  rework how status bar parts embed widgets
modified:
  dwt/include/dwt/widgets/StatusBar.h
  dwt/src/widgets/StatusBar.cpp
  win32/FinishedFrameBase.h
  win32/HubFrame.cpp
  win32/MainWindow.cpp
  win32/MainWindow.h
  win32/QueueFrame.cpp
  win32/SearchFrame.cpp
  win32/SpyFrame.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/StatusBar.h'
--- dwt/include/dwt/widgets/StatusBar.h	2011-04-16 15:22:56 +0000
+++ dwt/include/dwt/widgets/StatusBar.h	2011-04-24 15:09:54 +0000
@@ -38,7 +38,7 @@
 
 #include "Control.h"
 
-#include <vector>
+#include <boost/ptr_container/ptr_vector.hpp>
 
 namespace dwt {
 
@@ -118,7 +118,8 @@
 	/// Sets the help id of the given part. If not set, the help id of the whole status bar is used instead.
 	void setHelpId(unsigned part, unsigned id);
 
-	void mapWidget(unsigned part, Widget* widget, const Rectangle& padding = Rectangle(0, 0, 0, 0));
+	/// embed a widget into a part. the widget will be automatically positioned.
+	void setWidget(unsigned part, Control* widget, const Rectangle& padding = Rectangle(0, 0, 0, 0));
 
 	void onClicked(unsigned part, const F& f);
 	void onRightClicked(unsigned part, const F& f);
@@ -148,25 +149,41 @@
 	friend class ChainingDispatcher;
 	static const TCHAR windowClass[];
 
-	struct Part {
-		Part() : size(0), icon(0), helpId(0), clickF(0), rightClickF(0), dblClickF(0) { }
+	// base class for all kinds of parts.
+	struct PartBase {
+		PartBase() : size(0), helpId(0) { }
+		virtual ~PartBase() { }
 
 		unsigned size;
+		unsigned helpId;
+	};
+
+	// standard part (with icon / text).
+	struct Part : PartBase {
+		Part() : PartBase(), icon(0), clickF(0), rightClickF(0), dblClickF(0) { }
 
 		tstring text;
 		IconPtr icon;
 		tstring tip;
 
-		unsigned helpId;
-
 		F clickF;
 		F rightClickF;
 		F dblClickF;
 
 		void updateSize(StatusBar* bar, bool alwaysResize);
 	};
-	typedef std::vector<Part> Parts;
-	Parts parts;
+
+	// part that embeds an external widget.
+	struct WidgetPart : PartBase {
+		WidgetPart(Control* widget, const Rectangle& padding) : PartBase(), widget(widget), padding(padding) { }
+
+		Control* widget;
+		Rectangle padding;
+
+		void layout(POINT* offset);
+	};
+
+	boost::ptr_vector<PartBase> parts;
 	unsigned fill;
 
 	ToolTipPtr tip;
@@ -174,6 +191,7 @@
 	std::vector<tstring> lastLines;
 	enum { MAX_LINES = 10 }; /// @todo configurable?
 
+	Part& getPart(unsigned part);
 	void layoutSections();
 	void layoutSections(const Point& sz);
 	Part* getClickedPart();

=== modified file 'dwt/src/widgets/StatusBar.cpp'
--- dwt/src/widgets/StatusBar.cpp	2011-04-16 15:22:56 +0000
+++ dwt/src/widgets/StatusBar.cpp	2011-04-24 15:09:54 +0000
@@ -41,7 +41,7 @@
 const TCHAR StatusBar::windowClass[] = STATUSCLASSNAME;
 
 StatusBar::Seed::Seed(unsigned parts_, unsigned fill_, bool sizeGrip) :
-BaseType::Seed(WS_CHILD),
+BaseType::Seed(WS_CHILD | WS_CLIPSIBLINGS),
 parts(parts_),
 fill(fill_)
 {
@@ -79,7 +79,7 @@
 
 void StatusBar::setText(unsigned part, const tstring& text, bool alwaysResize) {
 	dwtassert(part < parts.size(), _T("Invalid part number."));
-	Part& info = parts[part];
+	Part& info = getPart(part);
 	info.text = text;
 	if(part != fill) {
 		info.updateSize(this, alwaysResize);
@@ -102,7 +102,7 @@
 
 void StatusBar::setIcon(unsigned part, const IconPtr& icon, bool alwaysResize) {
 	dwtassert(part < parts.size(), _T("Invalid part number."));
-	Part& info = parts[part];
+	Part& info = getPart(part);
 	info.icon = icon;
 	if(part != fill)
 		info.updateSize(this, alwaysResize);
@@ -111,29 +111,25 @@
 
 void StatusBar::setToolTip(unsigned part, const tstring& text) {
 	dwtassert(part < parts.size(), _T("Invalid part number."));
-	parts[part].tip = text;
+	getPart(part).tip = text;
 }
 
 void StatusBar::setHelpId(unsigned part, unsigned id) {
 	dwtassert(part < parts.size(), _T("Invalid part number."));
-	parts[part].helpId = id;
+	getPart(part).helpId = id;
 }
 
-void StatusBar::mapWidget(unsigned part, Widget* widget, const Rectangle& padding) {
+void StatusBar::setWidget(unsigned part, Control* widget, const Rectangle& padding) {
 	dwtassert(part < parts.size(), _T("Invalid part number."));
-	POINT p[2];
-	sendMessage(SB_GETRECT, part, reinterpret_cast<LPARAM>(p));
-	::MapWindowPoints(handle(), getParent()->handle(), (POINT*)p, 2);
-	::SetWindowPos(widget->handle(), handle(),
-		p[0].x + padding.left(),
-		p[0].y + padding.top(),
-		p[1].x - p[0].x - padding.right(),
-		p[1].y - p[0].y - padding.bottom(), SWP_NOACTIVATE | SWP_NOOWNERZORDER);
+	auto p = new WidgetPart(widget, padding);
+	p->size = widget->getPreferredSize().x;
+	p->helpId = widget->getHelpId();
+	parts.insert(parts.erase(parts.begin() + part), p);
 }
 
 void StatusBar::onClicked(unsigned part, const F& f) {
 	dwtassert(part < parts.size(), _T("Invalid part number."));
-	parts[part].clickF = f;
+	getPart(part).clickF = f;
 
 	// imitate the default onClicked but with a setCallback.
 	setCallback(Message(WM_NOTIFY, NM_CLICK), Dispatchers::VoidVoid<>([this] { handleClicked(); }));
@@ -141,7 +137,7 @@
 
 void StatusBar::onRightClicked(unsigned part, const F& f) {
 	dwtassert(part < parts.size(), _T("Invalid part number."));
-	parts[part].rightClickF = f;
+	getPart(part).rightClickF = f;
 
 	// imitate the default onRightClicked but with a setCallback.
 	setCallback(Message(WM_NOTIFY, NM_RCLICK), Dispatchers::VoidVoid<>([this] { handleRightClicked(); }));
@@ -149,7 +145,7 @@
 
 void StatusBar::onDblClicked(unsigned part, const F& f) {
 	dwtassert(part < parts.size(), _T("Invalid part number."));
-	parts[part].dblClickF = f;
+	getPart(part).dblClickF = f;
 
 	// imitate the default onDblClicked but with a setCallback.
 	setCallback(Message(WM_NOTIFY, NM_DBLCLK), Dispatchers::VoidVoid<>([this] { handleDblClicked(); }));
@@ -196,14 +192,31 @@
 	}
 }
 
+void StatusBar::WidgetPart::layout(POINT* offset) {
+	::SetWindowPos(widget->handle(), HWND_TOP,
+		offset[0].x + padding.left(), offset[0].y + padding.top(),
+		offset[1].x - offset[0].x - padding.right(), offset[1].y - offset[0].y - padding.bottom(),
+		SWP_NOACTIVATE | SWP_NOOWNERZORDER);
+}
+
+StatusBar::Part& StatusBar::getPart(unsigned part) {
+	auto& ret = parts[part];
+	if(!dynamic_cast<Part*>(&ret)) {
+		auto p = new Part();
+		parts.insert(parts.erase(parts.begin() + part), p);
+		return *p;
+	}
+	return static_cast<Part&>(ret);
+}
+
 void StatusBar::layoutSections() {
 	layoutSections(getWindowSize());
 }
 
 void StatusBar::layoutSections(const Point& sz) {
-	std::vector<unsigned> sizes;
-	for(Parts::const_iterator i = parts.begin(); i != parts.end(); ++i)
-		sizes.push_back(i->size);
+	std::vector<unsigned> sizes(parts.size());
+	for(size_t i = 0, n = sizes.size(); i < n; ++i)
+		sizes[i] = parts[i].size;
 
 	sizes[fill] = 0;
 	parts[fill].size = sizes[fill] = sz.x - std::accumulate(sizes.begin(), sizes.end(), 0);
@@ -218,15 +231,26 @@
 	const unsigned * intArr = & newVec[0];
 	const size_t size = newVec.size();
 	sendMessage(SB_SETPARTS, static_cast< WPARAM >( size ), reinterpret_cast< LPARAM >( intArr ) );
+
+	// reposition embedded widgets.
+	for(auto i = parts.begin(); i != parts.end(); ++i) {
+		auto wp = dynamic_cast<WidgetPart*>(&*i);
+		if(wp) {
+			POINT p[2];
+			sendMessage(SB_GETRECT, i - parts.begin(), reinterpret_cast<LPARAM>(p));
+			::MapWindowPoints(handle(), getParent()->handle(), p, 2);
+			wp->layout(p);
+		}
+	}
 }
 
 StatusBar::Part* StatusBar::getClickedPart() {
 	unsigned x = ClientCoordinate(ScreenCoordinate(Point::fromLParam(::GetMessagePos())), this).x();
 	unsigned total = 0;
-	for(Parts::iterator i = parts.begin(); i != parts.end(); ++i) {
+	for(auto i = parts.begin(); i != parts.end(); ++i) {
 		total += i->size;
 		if(total > x)
-			return &*i;
+			return dynamic_cast<Part*>(&*i);
 	}
 
 	return 0;

=== modified file 'win32/FinishedFrameBase.h'
--- win32/FinishedFrameBase.h	2011-04-15 21:51:55 +0000
+++ win32/FinishedFrameBase.h	2011-04-24 15:09:54 +0000
@@ -123,6 +123,8 @@
 			users->onContextMenu([this](const dwt::ScreenCoordinate &sc) { return this->handleUsersContextMenu(sc); });
 		}
 
+		this->initStatus();
+
 		if(!in_UL) {
 			bOnlyFull = BOOLSETTING(FINISHED_DL_ONLY_FULL);
 			{
@@ -132,15 +134,16 @@
 				onlyFull->setHelpId(IDH_FINISHED_DL_ONLY_FULL);
 				onlyFull->setChecked(bOnlyFull);
 				onlyFull->onClicked([this] { this->handleOnlyFullClicked(); });
+				this->status->setWidget(STATUS_ONLY_FULL, onlyFull);
 			}
 
 			filesWindow->onVisibilityChanged([this](bool b) { this->onlyFull->setVisible(b); });
 		}
 
-		this->initStatus();
-		if(onlyFull)
-			this->status->setSize(STATUS_ONLY_FULL, onlyFull->getPreferredSize().x);
-		this->status->onDblClicked(STATUS_STATUS, [] { WinUtil::openFile(Text::toT(Util::validateFileName(LogManager::getInstance()->getPath(in_UL ? LogManager::UPLOAD : LogManager::DOWNLOAD)))); });
+		this->status->onDblClicked(STATUS_STATUS, [] {
+			WinUtil::openFile(Text::toT(Util::validateFileName(LogManager::getInstance()->getPath(
+				in_UL ? LogManager::UPLOAD : LogManager::DOWNLOAD))));
+		});
 
 		this->status->setHelpId(STATUS_COUNT, in_UL ? IDH_FINISHED_UL_COUNT : IDH_FINISHED_DL_COUNT);
 		this->status->setHelpId(STATUS_BYTES, in_UL ? IDH_FINISHED_UL_BYTES : IDH_FINISHED_DL_BYTES);
@@ -162,8 +165,6 @@
 		dwt::Rectangle r(this->getClientSize());
 
 		r.size.y -= this->status->refresh();
-		if(onlyFull)
-			this->status->mapWidget(STATUS_ONLY_FULL, onlyFull);
 
 		tabs->resize(r);
 	}

=== modified file 'win32/HubFrame.cpp'
--- win32/HubFrame.cpp	2011-04-23 10:33:55 +0000
+++ win32/HubFrame.cpp	2011-04-24 15:09:54 +0000
@@ -190,14 +190,15 @@
 	}
 
 	initStatus();
+
+	status->onDblClicked(STATUS_STATUS, [this] { openLog(false); });
+
+	status->setIcon(STATUS_USERS, WinUtil::statusIcon(IDI_USER));
+
 	showUsers = addChild(WinUtil::Seeds::splitCheckBox);
 	showUsers->setHelpId(IDH_HUB_SHOW_USERS);
 	showUsers->setChecked(BOOLSETTING(GET_USER_INFO));
-
-	status->setSize(STATUS_SHOW_USERS, showUsers->getPreferredSize().x);
-	status->onDblClicked(STATUS_STATUS, [this] { openLog(false); });
-
-	status->setIcon(STATUS_USERS, WinUtil::statusIcon(IDI_USER));
+	status->setWidget(STATUS_SHOW_USERS, showUsers);
 
 	status->setHelpId(STATUS_STATUS, IDH_HUB_STATUS);
 	status->setHelpId(STATUS_SECURE, IDH_HUB_SECURE_STATUS);
@@ -264,7 +265,6 @@
 	dwt::Rectangle r(getClientSize());
 
 	r.size.y -= status->refresh();
-	status->mapWidget(STATUS_SHOW_USERS, showUsers);
 
 	dwt::util::HoldResize hr(this, 2);
 	int ymessage = message->getTextSize(_T("A")).y * messageLines + 10;

=== modified file 'win32/MainWindow.cpp'
--- win32/MainWindow.cpp	2011-04-23 10:33:55 +0000
+++ win32/MainWindow.cpp	2011-04-24 15:09:54 +0000
@@ -434,18 +434,19 @@
 		return;
 
 	dcdebug("initStatusBar\n");
+	initStatus(true);
+
+	updateAwayStatus();
 
 	slotsSpin = addChild(Spinner::Seed(1));
 	slotsSpin->setHelpId(IDH_MAIN_SLOTS_SPIN);
 	slotsSpin->onUpdate([this](int, int delta) { return handleSlotsUpdate(delta); });
-
-	initStatus(true);
+	status->setWidget(STATUS_SLOTS_SPIN, slotsSpin, dwt::Rectangle(0, 1, 3, 2));
 	status->setSize(STATUS_SLOTS_SPIN, 22);
-	///@todo set to checkbox width + resizedrag width really
+
+	/// @todo set to resizedrag width really
 	status->setSize(STATUS_DUMMY, 32);
 
-	updateAwayStatus();
-
 	status->setIcon(STATUS_COUNTS, WinUtil::statusIcon(IDI_HUB));
 	status->setIcon(STATUS_SLOTS, WinUtil::statusIcon(IDI_SLOTS));
 	{
@@ -941,16 +942,11 @@
 
 	if(status) {
 		r.size.y -= status->refresh();
-		layoutSlotsSpin();
 	}
 
 	paned->resize(r);
 }
 
-void MainWindow::layoutSlotsSpin() {
-	status->mapWidget(STATUS_SLOTS_SPIN, slotsSpin, dwt::Rectangle(0, 1, 3, 2));
-}
-
 LRESULT MainWindow::handleWhereAreYou() {
 	return SingleInstance::WMU_WHERE_ARE_YOU;
 }
@@ -1019,8 +1015,6 @@
 	s = Text::toT(Util::formatBytes(ThrottleManager::getUpLimit() * 1024));
 	status->setText(STATUS_UP_LIMIT, str(TF_("U Lim: %1%/s") % s));
 	status->setToolTip(STATUS_UP_LIMIT, str(TF_("Upload limit: %1%/s - Click to adjust") % s));
-
-	layoutSlotsSpin();
 }
 
 void MainWindow::updateAwayStatus() {

=== modified file 'win32/MainWindow.h'
--- win32/MainWindow.h	2011-04-23 10:33:55 +0000
+++ win32/MainWindow.h	2011-04-24 15:09:54 +0000
@@ -190,7 +190,6 @@
 	void handleTrayUpdate();
 
 	void layout();
-	void layoutSlotsSpin();
 	void updateStatus();
 	void updateAwayStatus();
 	void showPortsError(const string& port);

=== modified file 'win32/QueueFrame.cpp'
--- win32/QueueFrame.cpp	2011-04-05 19:16:53 +0000
+++ win32/QueueFrame.cpp	2011-04-24 15:09:54 +0000
@@ -89,13 +89,13 @@
 		files->onContextMenu([this](const dwt::ScreenCoordinate &sc) { return handleFilesContextMenu(sc); });
 	}
 
+	initStatus();
+
 	showTree = addChild(WinUtil::Seeds::splitCheckBox);
 	showTree->setHelpId(IDH_QUEUE_SHOW_TREE);
 	showTree->setChecked(BOOLSETTING(QUEUEFRAME_SHOW_TREE));
 	showTree->onClicked([this] { handleShowTreeClicked(); });
-
-	initStatus();
-	status->setSize(STATUS_SHOW_TREE, showTree->getPreferredSize().x);
+	status->setWidget(STATUS_SHOW_TREE, showTree);
 
 	status->setHelpId(STATUS_PARTIAL_COUNT, IDH_QUEUE_PARTIAL_COUNT);
 	status->setHelpId(STATUS_PARTIAL_BYTES, IDH_QUEUE_PARTIAL_BYTES);
@@ -117,7 +117,6 @@
 	dwt::Rectangle r(getClientSize());
 
 	r.size.y -= status->refresh();
-	status->mapWidget(STATUS_SHOW_TREE, showTree);
 
 	paned->resize(r);
 }

=== modified file 'win32/SearchFrame.cpp'
--- win32/SearchFrame.cpp	2011-04-24 11:27:49 +0000
+++ win32/SearchFrame.cpp	2011-04-24 15:09:54 +0000
@@ -249,12 +249,12 @@
 	results->onKeyDown([this](int c) { return handleKeyDown(c); });
 	results->onContextMenu([this](const dwt::ScreenCoordinate &sc) { return handleContextMenu(sc); });
 
+	initStatus();
+
 	showUI = addChild(WinUtil::Seeds::splitCheckBox);
 	showUI->setChecked(true);
 	showUI->onClicked([this] { handleShowUIClicked(); });
-
-	initStatus();
-	status->setSize(STATUS_SHOW_UI, showUI->getPreferredSize().x);
+	status->setWidget(STATUS_SHOW_UI, showUI);
 
 	layout();
 	activate();
@@ -330,7 +330,6 @@
 	dwt::Rectangle r(getClientSize());
 
 	r.size.y -= status->refresh();
-	status->mapWidget(STATUS_SHOW_UI, showUI);
 
 	paned->resize(r);
 }

=== modified file 'win32/SpyFrame.cpp'
--- win32/SpyFrame.cpp	2011-04-15 20:53:17 +0000
+++ win32/SpyFrame.cpp	2011-04-24 15:09:54 +0000
@@ -65,6 +65,8 @@
 		searches->onContextMenu([this](const dwt::ScreenCoordinate &sc) { return handleContextMenu(sc); });
 	}
 
+	initStatus();
+
 	{
 		CheckBox::Seed seed = WinUtil::Seeds::checkBox;
 		seed.caption = T_("Ignore TTH searches");
@@ -72,11 +74,9 @@
 		ignoreTTH->setHelpId(IDH_SPY_IGNORE_TTH);
 		ignoreTTH->setChecked(bIgnoreTTH);
 		ignoreTTH->onClicked([this] { handleIgnoreTTHClicked(); });
+		status->setWidget(STATUS_IGNORE_TTH, ignoreTTH);
 	}
 
-	initStatus();
-	status->setSize(STATUS_IGNORE_TTH, ignoreTTH->getPreferredSize().x);
-
 	status->setHelpId(STATUS_TOTAL, IDH_SPY_TOTAL);
 	status->setHelpId(STATUS_AVG_PER_SECOND, IDH_SPY_AVG_PER_SECOND);
 	status->setHelpId(STATUS_HITS, IDH_SPY_HITS);
@@ -98,7 +98,6 @@
 	dwt::Rectangle r(this->getClientSize());
 
 	r.size.y -= status->refresh();
-	status->mapWidget(STATUS_IGNORE_TTH, ignoreTTH);
 
 	searches->resize(r);
 }