diff options
| author | Kevin Smith <git@kismith.co.uk> | 2010-05-23 12:10:55 (GMT) | 
|---|---|---|
| committer | Kevin Smith <git@kismith.co.uk> | 2010-05-23 19:05:31 (GMT) | 
| commit | 391f5f49b76a847113e1e27013a5d6027070bbd0 (patch) | |
| tree | a3fde8ecee56ac9ba92c78de51906e177a958d17 /Swift | |
| parent | 3dbd488df47475a6164345506a53d41cbc04d780 (diff) | |
| download | swift-391f5f49b76a847113e1e27013a5d6027070bbd0.zip swift-391f5f49b76a847113e1e27013a5d6027070bbd0.tar.bz2 | |
Start creating a prettier roster header.
Diffstat (limited to 'Swift')
| -rw-r--r-- | Swift/QtUI/QtRosterHeader.cpp | 174 | ||||
| -rw-r--r-- | Swift/QtUI/QtRosterHeader.h | 24 | ||||
| -rw-r--r-- | Swift/QtUI/QtStatusWidget.cpp | 161 | ||||
| -rw-r--r-- | Swift/QtUI/QtStatusWidget.h | 33 | 
4 files changed, 264 insertions, 128 deletions
| diff --git a/Swift/QtUI/QtRosterHeader.cpp b/Swift/QtUI/QtRosterHeader.cpp index 88fbf7b..3ab12dd 100644 --- a/Swift/QtUI/QtRosterHeader.cpp +++ b/Swift/QtUI/QtRosterHeader.cpp @@ -17,84 +17,68 @@  namespace Swift {  QtRosterHeader::QtRosterHeader(QWidget* parent) : QWidget(parent) { -	QVBoxLayout* vLayout = new QVBoxLayout(); -	vLayout->setSpacing(0); -	vLayout->setContentsMargins(0,0,0,0); -	setLayout(vLayout); +	QHBoxLayout* topLayout = new QHBoxLayout(); +	topLayout->setSpacing(0); +	topLayout->setContentsMargins(0,0,0,0); +	setLayout(topLayout); +	setMinimumHeight(64); +	setMaximumHeight(64); -	toolBar_ = new QToolBar(this); -	vLayout->addWidget(toolBar_); +	avatarLabel_ = new QLabel(this); +	avatarLabel_->setMinimumSize(64, 64); +	avatarLabel_->setMaximumSize(64, 64); +	setAvatar(":/icons/avatar.png"); +	avatarLabel_->setScaledContents(true); +	topLayout->addWidget(avatarLabel_); -	statusWidget_ = new QtStatusWidget(this); -	toolBar_->addWidget(statusWidget_); -	statusWidget_->setMaximumWidth(60); -	connect(statusWidget_, SIGNAL(onChangeStatusRequest(StatusShow::Type)), this, SLOT(handleChangeStatusRequest(StatusShow::Type))); +	QVBoxLayout* rightLayout = new QVBoxLayout(); +	rightLayout->setSpacing(4); +	rightLayout->setContentsMargins(4,4,4,4); +	topLayout->addLayout(rightLayout);  	nameLabel_ = new QLabel(this);  	setName("Me"); -	toolBar_->addWidget(nameLabel_); -	//nameLabel_->setMaximumWidth(width() - 5 - statusWidget_->width()); -		 -	expandedLayout_ = new QHBoxLayout(); -	expandedLayout_->setContentsMargins(0,0,0,0); -	expandedLayout_->setSpacing(0); -	 -	avatarLabel_ = new QLabel(this); -	setAvatar(":/icons/avatar.png"); -	expandedLayout_->addWidget(avatarLabel_); -	 -	statusEdit_ = new QtTextEdit(this); -	expandedLayout_->addWidget(statusEdit_); -	statusEdit_->resize(statusEdit_->width(), 64); -	statusEdit_->setAcceptRichText(false); -	statusEdit_->setReadOnly(false); -	setStatusText(""); - -	vLayout->addLayout(expandedLayout_); -	expanded_ = false; -	avatarLabel_->hide(); -	statusEdit_->hide(); -	connect(statusEdit_, SIGNAL(returnPressed()), this, SLOT(emitStatus())); - -	setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed)); +	rightLayout->addWidget(nameLabel_); + + +	statusWidget_ = new QtStatusWidget(this); +	connect(statusWidget_, SIGNAL(onChangeStatusRequest(StatusShow::Type, const QString&)), this, SLOT(handleChangeStatusRequest(StatusShow::Type, const QString&))); +	rightLayout->addWidget(statusWidget_); +	show(); +	//statusWidget_->setMaximumWidth(60); + +	// statusEdit_ = new QtTextEdit(this); +	// expandedLayout_->addWidget(statusEdit_); +	// statusEdit_->resize(statusEdit_->width(), 64); +	// statusEdit_->setAcceptRichText(false); +	// statusEdit_->setReadOnly(false); +	// setStatusText(""); +	// connect(statusEdit_, SIGNAL(returnPressed()), this, SLOT(emitStatus())); + +	//setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed));  } -void QtRosterHeader::mousePressEvent(QMouseEvent* event) { -	if (nameLabel_->underMouse() || (toolBar_->underMouse() && !statusWidget_->underMouse())) { -		toggleExpanded(); -		event->accept(); -	} else { -		event->ignore(); -	} +// void QtRosterHeader::mousePressEvent(QMouseEvent* event) { +// 	if (nameLabel_->underMouse() || (toolBar_->underMouse() && !statusWidget_->underMouse())) { +// 		toggleExpanded(); +// 		event->accept(); +// 	} else { +// 		event->ignore(); +// 	} -} +// } -void QtRosterHeader::toggleExpanded() { -	expanded_ = !expanded_; -	if (expanded_) { -		expandedLayout_->setContentsMargins(5,5,5,5); -		expandedLayout_->setSpacing(11); -		avatarLabel_->show(); -		statusEdit_->show(); -	} else { -		expandedLayout_->setContentsMargins(0,0,0,0); -		expandedLayout_->setSpacing(0); -		avatarLabel_->hide(); -		statusEdit_->hide(); -	} -} -void QtRosterHeader::handleChangeStatusRequest(StatusShow::Type type) { -	Q_UNUSED(type); -	emitStatus(); +void QtRosterHeader::handleChangeStatusRequest(StatusShow::Type type, const QString& text) { +	emit onChangeStatusRequest(type, text);  } -void QtRosterHeader::emitStatus() { -	emit onChangeStatusRequest(statusWidget_->getSelectedStatusShow(), statusEdit_->toPlainText()); -} +//void QtRosterHeader::emitStatus() { +//	emit onChangeStatusRequest(statusWidget_->getSelectedStatusShow(), statusEdit_->toPlainText()); +//}  void QtRosterHeader::setStatusText(const QString& statusMessage) { -	statusEdit_->setText(statusMessage); +	statusWidget_->setStatusText(statusMessage);  }  void QtRosterHeader::setStatusType(StatusShow::Type type) { @@ -103,40 +87,48 @@ void QtRosterHeader::setStatusType(StatusShow::Type type) {  void QtRosterHeader::setName(const QString& name) {  	name_ = name; -	resizeNameLabel(); -} - -void QtRosterHeader::resizeNameLabel() {	  	QString escapedName = name_;  	escapedName.replace("<","<"); -	nameLabel_->setText("<b>" + escapedName + "</b>"); -	return; -	//FIXME: Make this not an infinite loop, so it can be continued. -	 -	int reductionCount = 0; -	while (nameLabel_->sizeHint().width() + statusWidget_->width() + 30 > width()) { -		//qDebug() << nameLabel_->sizeHint().width() << " " << statusWidget_->width() << " " << width(); -		reductionCount++; -		QString reducedName = name_; -		reducedName.remove(name_.length() - reductionCount, reductionCount); -		reducedName.replace("<","<"); -		nameLabel_->setText("<b>" + reducedName +  + "...</b>"); -	//	qDebug() << "Shrunk " << escapedName << " down to " << reducedName; -	} -	nameLabel_->setToolTip(name_); + 	nameLabel_->setText("<b>" + escapedName + "</b>"); +//	resizeNameLabel();  } -void QtRosterHeader::resizeEvent(QResizeEvent* event) { -	QWidget::resizeEvent(event); -	resizeNameLabel(); -} +// void QtRosterHeader::resizeNameLabel() {	 +// 	QString escapedName = name_; +// 	escapedName.replace("<","<"); +// 	nameLabel_->setText("<b>" + escapedName + "</b>"); +// 	return; +// 	//FIXME: Make this not an infinite loop, so it can be continued. +	 +// 	int reductionCount = 0; +// 	while (nameLabel_->sizeHint().width() + statusWidget_->width() + 30 > width()) { +// 		//qDebug() << nameLabel_->sizeHint().width() << " " << statusWidget_->width() << " " << width(); +// 		reductionCount++; +// 		QString reducedName = name_; +// 		reducedName.remove(name_.length() - reductionCount, reductionCount); +// 		reducedName.replace("<","<"); +// 		nameLabel_->setText("<b>" + reducedName +  + "...</b>"); +// 	//	qDebug() << "Shrunk " << escapedName << " down to " << reducedName; +// 	} +// 	nameLabel_->setToolTip(name_); +// } + +//void QtRosterHeader::resizeEvent(QResizeEvent* event) { +//	QWidget::resizeEvent(event); +//	resizeNameLabel(); +//}  void QtRosterHeader::setAvatar(const QString& path) { -	avatarLabel_->setPixmap(QIcon(path).pixmap(64, 64)); +	QIcon avatar(path); +	if (avatar.isNull()) { +		qDebug() << "Setting null avatar"; +		avatar = QIcon(":/icons/avatar.png"); +	}  +	avatarLabel_->setPixmap(avatar.pixmap(64, 64));  } -QSize QtRosterHeader::sizeHint() const { -	return minimumSizeHint(); -} +//QSize QtRosterHeader::sizeHint() const { +//	return minimumSizeHint(); +//}  } diff --git a/Swift/QtUI/QtRosterHeader.h b/Swift/QtUI/QtRosterHeader.h index 719674e..7fed2c0 100644 --- a/Swift/QtUI/QtRosterHeader.h +++ b/Swift/QtUI/QtRosterHeader.h @@ -30,26 +30,28 @@ namespace Swift {  		void setName(const QString& name);  		void setStatusText(const QString& statusMessage);  		void setStatusType(StatusShow::Type type); -		QSize sizeHint() const; -	public slots: -		void emitStatus(); +//		QSize sizeHint() const; +//	public slots: +//		void emitStatus();  	signals:  		void onChangeStatusRequest(StatusShow::Type showType, const QString &statusMessage);  	private slots: -		void handleChangeStatusRequest(StatusShow::Type type); -	protected: -		virtual void resizeEvent(QResizeEvent* event); -		virtual void mousePressEvent(QMouseEvent* event); +		void handleChangeStatusRequest(StatusShow::Type type, const QString &statusMessage); +//	protected: +//		virtual void resizeEvent(QResizeEvent* event); +//		virtual void mousePressEvent(QMouseEvent* event);  	private: -		void resizeNameLabel(); -		void toggleExpanded(); +//		void resizeNameLabel(); +//		void toggleExpanded();  		QString name_;  		QLabel* avatarLabel_; +#warning FIXME - replace QLabel with override to do elide +//http://lists.trolltech.com/pipermail/qt-interest/2010-January/018056.html  		QLabel* nameLabel_;  		QtTextEdit* statusEdit_;  		QToolBar* toolBar_;  		QtStatusWidget* statusWidget_; -		QHBoxLayout* expandedLayout_; -		bool expanded_; +		//QHBoxLayout* expandedLayout_; +		//bool expanded_;  	};  } diff --git a/Swift/QtUI/QtStatusWidget.cpp b/Swift/QtUI/QtStatusWidget.cpp index 3de2641..c6b0464 100644 --- a/Swift/QtUI/QtStatusWidget.cpp +++ b/Swift/QtUI/QtStatusWidget.cpp @@ -9,40 +9,155 @@  #include <QBoxLayout>  #include <QComboBox>  #include <QLineEdit> - +#include <QLabel> +#include <QFrame> +#include <QPoint> +#include <QStackedWidget> +#include <QApplication> +#include <QDesktopWidget> +#include <qdebug.h> +#include <QListWidget> +#include <QListWidgetItem>  namespace Swift { -QtStatusWidget::QtStatusWidget(QWidget *parent) : QWidget(parent) { -	types_ = new QComboBox(this); -	types_->addItem(QIcon(":/icons/online.png"), "Available", QVariant(StatusShow::Online)); -	types_->addItem(QIcon(":/icons/online.png"), "Free For Chat", QVariant(StatusShow::FFC)); -	types_->addItem(QIcon(":/icons/away.png"), "Away", QVariant(StatusShow::Away)); -	types_->addItem(QIcon(":/icons/away.png"), "Extended Away", QVariant(StatusShow::XA)); -	types_->addItem(QIcon(":/icons/dnd.png"), "Do Not Disturb", QVariant(StatusShow::DND)); -	types_->addItem(QIcon(":/icons/offline.png"), "Offline", QVariant(StatusShow::None)); -	connect(types_, SIGNAL(activated(int)), this, SLOT(handleTypeSelected(int))); -	QBoxLayout *mainLayout = new QBoxLayout(QBoxLayout::TopToBottom, this); -	mainLayout->setContentsMargins(0,0,0,0); + +QtStatusWidget::QtStatusWidget(QWidget *parent) : QWidget(parent), editCursor_(Qt::IBeamCursor), viewCursor_(Qt::PointingHandCursor) { +	isClicking_ = false; +	setMaximumHeight(24); + +	QHBoxLayout* mainLayout = new QHBoxLayout(this);  	mainLayout->setSpacing(0); -	mainLayout->addWidget(types_); +	mainLayout->setContentsMargins(0,0,0,0); + +	stack_ = new QStackedWidget(this); +	stack_->setLineWidth(2); +	stack_->setFrameShape(QFrame::StyledPanel); +	mainLayout->addWidget(stack_); + +	QWidget* page1 = new QWidget(this); +	stack_->addWidget(page1); +	QHBoxLayout* page1Layout = new QHBoxLayout(page1); +	page1Layout->setSpacing(0); +	page1Layout->setContentsMargins(0,0,0,0); +	page1->setCursor(viewCursor_); + +	statusIcon_ = new QLabel(this); +	statusIcon_->setMinimumSize(16, 16); +	statusIcon_->setMaximumSize(16, 16); +	page1Layout->addWidget(statusIcon_); + +	statusTextLabel_ = new QLabel(this); +	page1Layout->addWidget(statusTextLabel_); + +	icons_[StatusShow::Online] = QIcon(":/icons/online.png"); +	icons_[StatusShow::Away] = QIcon(":/icons/away.png"); +	icons_[StatusShow::DND] = QIcon(":/icons/dnd.png"); +	icons_[StatusShow::None] = QIcon(":/icons/offline.png"); +	 +	setStatusType(StatusShow::None); + +	QWidget* page2 = new QWidget(this); +	QHBoxLayout* page2Layout = new QHBoxLayout(page2); +	page2Layout->setSpacing(0); +	page2Layout->setContentsMargins(0,0,0,0); +	stack_->addWidget(page2); +	 +	statusEdit_ = new QLineEdit(this); +	page2Layout->addWidget(statusEdit_); +	connect(statusEdit_, SIGNAL(returnPressed()), this, SLOT(handleEditComplete())); +	connect(statusEdit_, SIGNAL(textChanged(const QString&)), this, SLOT(generateList())); + +	setStatusText(""); + + +	menu_ = new QListWidget(); +	menu_->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); +	menu_->setAlternatingRowColors(true);		 + +	connect(menu_, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(handleItemClicked(QListWidgetItem*))); +	viewMode();  } -void QtStatusWidget::handleTypeSelected(int index) { -	Q_UNUSED(index); -	emit onChangeStatusRequest(getSelectedStatusShow()); +QtStatusWidget::~QtStatusWidget() { +	delete menu_; +} + +void QtStatusWidget::mousePressEvent(QMouseEvent*) { +	handleClicked(); +} + +void QtStatusWidget::generateList() { +	QString text = statusEdit_->text(); +	menu_->clear(); +	foreach (StatusShow::Type type, icons_.keys()) { +		QListWidgetItem* item = new QListWidgetItem(text, menu_); +		item->setIcon(icons_[type]); +		item->setData(Qt::UserRole, QVariant(type)); +	} +} + + +void QtStatusWidget::handleClicked() { +	QPoint point = mapToGlobal(QPoint(0, height())); +	int x = point.x(); +	int y = point.y(); +	int width = 200; +	int height = 80; +	int screenWidth = QApplication::desktop()->screenGeometry().width(); +	if (x + width > screenWidth) { +		x = screenWidth - width; +	} +	menu_->setGeometry(x, y, width, height); +	menu_->setMaximumWidth(width); +	QSizePolicy policy(menu_->sizePolicy()); +	policy.setVerticalPolicy(QSizePolicy::Expanding); +	menu_->setSizePolicy(policy); +	menu_->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); +	generateList(); + +	menu_->show(); +	activateWindow(); +	stack_->setCurrentIndex(1); +	statusEdit_->setFocus(); +} + +void QtStatusWidget::viewMode() { +	menu_->hide(); +	stack_->setCurrentIndex(0);	 +} + +void QtStatusWidget::handleEditComplete() { +	statusText_ = statusEdit_->text(); +	viewMode(); +	emit onChangeStatusRequest(selectedStatusType_, statusText_); +} + +void QtStatusWidget::handleEditCancelled() { +	setStatusText(statusText_); +	viewMode();  }  StatusShow::Type QtStatusWidget::getSelectedStatusShow() { -	return (StatusShow::Type)types_->itemData(types_->currentIndex()).toInt(); +	return selectedStatusType_; +} + +void QtStatusWidget::handleItemClicked(QListWidgetItem* item) { +	selectedStatusType_ = (StatusShow::Type)(item->data(Qt::UserRole).toInt()); +	handleEditComplete(); +} + + +void QtStatusWidget::setStatusText(const QString& text) { +	statusText_ = text; +	statusEdit_->setText(text); +	QString escapedText(text.isEmpty() ? "(No message)" : text); +	escapedText.replace("<","<"); +	statusTextLabel_->setText("<i>" + escapedText + "</i>");  }  void QtStatusWidget::setStatusType(StatusShow::Type type) { -	for (int i = 0; i < types_->count(); i++) { -		if (types_->itemData(i).toInt() == type) { -			types_->setCurrentIndex(i); -			break; -		} -	} +	selectedStatusType_ = icons_.contains(type) ? type : StatusShow::Online; +	statusIcon_->setPixmap(icons_[selectedStatusType_].pixmap(16, 16));  }  } diff --git a/Swift/QtUI/QtStatusWidget.h b/Swift/QtUI/QtStatusWidget.h index 95c1870..84994d8 100644 --- a/Swift/QtUI/QtStatusWidget.h +++ b/Swift/QtUI/QtStatusWidget.h @@ -10,23 +10,50 @@  #include "Swiften/Elements/StatusShow.h"  #include <QWidget> +#include <QMap> +#include <QIcon>  class QComboBox; +class QLabel; +class QStackedWidget;  class QLineEdit; +class QListWidget; +class QListWidgetItem;  namespace Swift {  	class QtStatusWidget : public QWidget {  		Q_OBJECT  		public:  			QtStatusWidget(QWidget *parent); +			~QtStatusWidget();  			StatusShow::Type getSelectedStatusShow();  			void setStatusType(StatusShow::Type type);  		signals: -			void onChangeStatusRequest(StatusShow::Type showType); +			void onChangeStatusRequest(StatusShow::Type showType, const QString& text); +		public slots: +			void setStatusText(const QString& text);  		private slots: -			void handleTypeSelected(int index); +			void generateList(); +			void handleClicked(); +			void handleEditComplete(); +			void handleEditCancelled(); +		protected slots: +			virtual void mousePressEvent(QMouseEvent* event); +			void handleItemClicked(QListWidgetItem* item);  		private: -			QComboBox *types_; +			void viewMode(); +			//QComboBox *types_; +			QStackedWidget* stack_; +			QLabel* statusIcon_; +			QLabel* statusTextLabel_; +			QLineEdit* statusEdit_; +			QString statusText_; +			QMap<StatusShow::Type, QIcon> icons_; +			StatusShow::Type selectedStatusType_; +			bool isClicking_; +			QListWidget* menu_; +			QCursor editCursor_; +			QCursor viewCursor_;  	};  } | 
 Swift
 Swift