⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sidemenu.cpp

📁 爱可视605看PDF程式源代码, 基于APDF
💻 CPP
字号:
#include "sidemenu.h"#include "fontchooser.h"#include "style.h"#include <qapplication.h>#include <qbitmap.h>#include <qpainter.h>#include <assert.h>#include <stdio.h>#include <qgfx_qws.h>using namespace archos;class SideMenuEntry { public:	SideMenuEntry();	SideMenuEntry(int id, int vis, const QString &label, const QString &icon_name);	int id;	QString label;	QPixmap icon;	bool visible;};SideMenuEntry::SideMenuEntry()	: id(0)	, visible(true){}SideMenuEntry::SideMenuEntry(int pid, int vis, const QString &plabel, const QString &icon_name)	: id(pid)	, label(plabel)	, icon(AStyle::iconpath + icon_name + ".png")	, visible(vis){}//--------------------------------///*!	@class SideMenu sidemenu.h	@brief A custom, nonhierarchical menu that matches the menu on coming Archos products in style.*//*!	@brief Creates a SideMenu object	@param itemcnt The maximum number of entries the menu will be able to hold	@param parent The parent widget	@param parent The name of the menu*/SideMenu::SideMenu(int itemcnt, QWidget *parent, const char *name)	: QWidget( parent, name, 		QWidget::WStyle_Customize | QWidget::WStyle_NoBorder | WRepaintNoErase | QWidget::WStyle_StaysOnTop)	, m_entries(new SideMenuEntry[itemcnt])	, m_cnt(itemcnt)	, m_selpos(0)	, m_visible_entries(0)	, m_trigger(false){	QString path = AStyle::iconpath + Screen::prefix();	menu_key_icon = QPixmap(path + "general/key_menu.png");	m_label_mask = QPixmap(path + "general/label_mask.png");	setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum));	qApp->installEventFilter(this);		m_labels= new SideMenuLabels(this);	connect(&m_hideTimer, SIGNAL(timeout()), this, SLOT(hide()));}SideMenu::~SideMenu(){	delete[] m_entries;	delete m_labels;}void SideMenu::showMenuAndLabels(){	show();	m_labels->show();	m_hideTimer.stop();}void SideMenu::strobeHideTimer(){	if (m_hideTimer.isActive()) {		m_hideTimer.start(timeoutInterval);	}}void SideMenu::hide(){	m_labels->hide();	m_hideTimer.stop();	QWidget::hide();	emit hideOn();}/*!	@brief Sets the data for an entry at a given position	@param index index of the entry to create or modify	@param visible whether the entry is displayed or visible	@param id identifyer of the entry (which will be reported by entryActivated() )	@param label textual representation of the entry	@param label file name of the icon (a .png suffix will be appended and the file		is expected to be relative to AStyle::iconpath)*/void SideMenu::setEntry(int index, int visible, int id, const QString &label, const QString &icon_name) {	assert(index < m_cnt);		m_entries[index]= SideMenuEntry(id, visible, label, icon_name);	if (visible) 		m_visible_entries++;	polish();	update();}/*!	@brief Shows or hides an entry at a given position	@param index index of the entry	@param visible whether the entry should be visible*/void SideMenu::setEntryVisible(int index, bool visible){	if (m_entries[index].visible != visible) {		if (visible) {			m_visible_entries++;		}		else {			if (m_selpos == index) {				qWarning("we just hide m_selpos!");				m_selpos = 0;				m_labels->setSelection(0);			}			m_visible_entries--;		}		m_entries[index].visible = visible;				polish();		update();	}}/*!	@brief Selects the entry at the given position	@param index index of the entry to select*/void SideMenu::setSelection(int index) {	if(index < 0 || index >= m_cnt) return;	if(index != m_selpos) {		m_selpos = index;		update();	}}int SideMenu::visibleEntries() const {	return m_visible_entries;}void SideMenu::showEvent(QShowEvent*){	qApp->installEventFilter(this);	m_hideTimer.start(timeoutInterval);}void SideMenu::hideEvent(QHideEvent*){	qApp->removeEventFilter(this);}void SideMenu::polish(){	if(backgroundPixmap() == NULL) {		QBitmap mask(size());		{	QPainter p(&mask);			paintButtonsMask(&p);		}		setMask(mask);	}}QSize SideMenu::sizeHint() const{	return QSize(		menu_key_icon.width(),		m_entries[0].icon.height()* m_visible_entries + menu_key_icon.height()	);}void SideMenu::paintEvent(QPaintEvent*) {	QPainter p(this);	paintButtons(&p);}void SideMenu::paintButtonsMask(QPainter *p){	int yofs = yOffset();	int iconh= m_label_mask.height();	int num_visible = 0;		for(int i= 0; i < m_cnt; i++) {		if (!m_entries[i].visible) continue;				p->drawPixmap(width() - menu_key_icon.width(), yofs + num_visible * iconh, m_label_mask);		num_visible++;	}	p->drawPixmap(width() - menu_key_icon.width(), yofs + num_visible * iconh, menu_key_icon);}void SideMenu::paintButtons(QPainter *p){	int yofs = yOffset();	int iconh= m_entries[0].icon.height();	int num_visible = 0;		for(int i= 0; i < m_cnt; i++) {		if (!m_entries[i].visible) continue;				p->drawPixmap(width() - menu_key_icon.width(), yofs + num_visible * iconh, m_entries[i].icon);		num_visible++;	}	p->drawPixmap(width() - menu_key_icon.width(), yofs + num_visible * iconh, menu_key_icon);}void SideMenu::selectLastEntry() {	int pos = visiblePosToPos(m_visible_entries - 1);	setSelection(pos);	m_labels->setSelection(pos);}void SideMenu::mousePressEvent(QMouseEvent * e){	if ( keyIconArea(e->y()) ) {		if ( m_labels->isVisible() ) {			m_labels->hide();		}		else {			m_labels->show();			m_hideTimer.stop();		}	}	else {		int iconh = m_entries[0].icon.height();		int icon_pos_clicked = (e->y() - yOffset()) / iconh;		int pos = visiblePosToPos(icon_pos_clicked);		if ( m_selpos == pos && m_labels->isVisible() ) {			m_trigger = true;		}		setSelection(pos);		m_labels->setSelection(pos);		m_labels->show();		m_hideTimer.stop();	}}void SideMenu::mouseReleaseEvent(QMouseEvent *e){	if ( m_trigger ) {		m_trigger = false;		m_labels->hide();		m_hideTimer.start(timeoutInterval);		if (e->y() > yOffset() && !keyIconArea(e->y()) &&			e->x() > - (m_labels->sizeHint().width())) {			emit entryActivated(m_entries[m_selpos].id);		}	}}bool SideMenu::keyIconArea(int y){	return y > yOffset() + m_entries[0].icon.height() * m_visible_entries;}void SideMenu::mouseMoveEvent ( QMouseEvent *e){	if (e->y() < yOffset() || keyIconArea(e->y()) || e->x() < - m_labels->sizeHint().width())		return;	int iconh = m_entries[0].icon.height();	int icon_pos_clicked = (e->y() - yOffset()) / iconh;	int pos = visiblePosToPos(icon_pos_clicked);	if (pos != m_selpos) {		m_trigger = false;		m_selpos = pos;		m_labels->setSelection(pos);		update();	}}bool SideMenu::eventFilter(QObject*, QEvent *evt) {	if(evt->type() == QEvent::KeyRelease) {		if(!isVisible()) return false;		if(((QKeyEvent*) evt)->key() == Key_F1) {			if(m_labels->isHidden()) {				m_labels->show();				m_hideTimer.stop();				return true;			}		}	}	return false;}int SideMenu::visiblePosToPos(int vpos) const{	int pos;	for(pos = 0; pos < m_cnt; pos++) { 	       if (!m_entries[pos].visible)			continue;		if (vpos-- == 0)			break;	}	return pos;}void SideMenu::hideLabels(){	m_trigger = false;	m_labels->hide();	m_hideTimer.start(SideMenu::timeoutInterval);}int SideMenu::posToVisiblePos(int pos) const{	int res = 0;	for (int i = 0; i < pos; i++) {		if (m_entries[i].visible)			res++;	}	return res;}int SideMenu::timeoutInterval = 5000;//--------------------------------//SideMenuLabels::SideMenuLabels(SideMenu *menu)	: QWidget(NULL, "menu labels", QWidget::WStyle_Customize | QWidget::WStyle_NoBorder | QWidget::WStyle_StaysOnTop)	, m_entries(menu->m_entries)	, m_menu(menu)	, m_selpos(-1)	, m_trigger(false){	setBackgroundMode(NoBackground);	QFont font = qApp->font();	if (Screen::mode() == wqvga) {		font.setPointSize(16);	}	else if (Screen::mode() == wvga) {		font.setPointSize(22);	}	else if (Screen::mode() == qvga) {		font.setPointSize(14);	}	else {  // tv		font.setPointSize(18);	}	setFont(font);}void SideMenuLabels::setSelection(int pos){	if(pos < 0 || pos >= m_menu->m_cnt)		return;	if(pos != m_selpos) {		m_selpos = pos;		update();	}}void SideMenuLabels::updateMask(){	// create mask	QBitmap mask(size());	{		QPainter p(&mask);		AStyle::get()->drawPanel(&p, rect());	}	setMask(mask);}int SideMenuLabels::lineHeight() const{	if (m_menu->m_visible_entries == 0)		return sizeHint().height();	return sizeHint().height()/ m_menu->m_visible_entries;}QRect SideMenuLabels::selectionArea() const{	int lineh = lineHeight();	int pos_visible = m_menu->posToVisiblePos(m_selpos);	int y_pos = 2 + pos_visible * (lineh + 1) + 1;	QRect textr(2, y_pos, width() - 14, lineh);		QPainter p(this);	QRect r(p.boundingRect(textr, AlignVCenter | AlignRight, m_entries[m_selpos].label));	return QRect(r.x() - 4, y_pos, r.width() + 8, lineh);}void SideMenuLabels::polish(){	updateMask();}void SideMenuLabels::showEvent(QShowEvent*){	// position on screen	int dw = qt_screen->width();	int dh = qt_screen->height();	int ww = sizeHint().width();	int wh = sizeHint().height();	setGeometry(dw - m_menu->width() - ww - 2, dh - m_menu->sizeHint().height() - 1, ww, wh + 1);	if (m_selpos == -1)	      setSelection(0);	updateMask();}void SideMenuLabels::paintEvent(QPaintEvent *evt){	QRect area(evt->rect());	// draw double buffered	QPixmap pix(area.size());	{		QPainter p(&pix, this);		p.translate(-area.x(), -area.y());		AStyle::get()->drawPanel(&p, rect());		AStyle::get()->drawSelection(&p, selectionArea());		drawLabels(&p);	}	QPainter p(this);	p.drawPixmap(area.topLeft(), pix);}void SideMenuLabels::drawLabels(QPainter *p) const{	if(m_menu->m_visible_entries == 0) return;	int ypos= 2;	int lineh = lineHeight();	for(int i = 0; i < m_menu->m_cnt; i++) {		if(m_entries[i].visible) {			p->setPen(i == m_selpos ? colorGroup().highlightedText() : colorGroup().text());			QRect textr(2, ypos, width() - 14, lineh - 1);			p->drawText(textr, AlignVCenter | AlignRight, m_entries[i].label);			ypos+= lineh + 1;		}	}}QSize SideMenuLabels::sizeHint() const{	QFontMetrics fm(font());		int w = 0;	for(int i= 0; i < m_menu->m_cnt; i++) {		if (m_entries[i].visible)			w= QMAX(w, fm.width(m_entries[i].label));	}		return QSize(		w + 26,		m_menu->sizeHint().height() - m_menu->menu_key_icon.height() - 1	);}bool SideMenuLabels::event(QEvent* e){	bool handled = false;	if (e->type() == QEvent::KeyRelease ||		(e->type() == QEvent::KeyPress && ((QKeyEvent*)e)->isAutoRepeat()) ) {		QKeyEvent* keyEvent = (QKeyEvent*)e;		switch(keyEvent->key()) {			case Key_F1 :			case Key_F2 :				m_menu->m_hideTimer.start(SideMenu::timeoutInterval);				hide();				handled = true;				break;			case Key_Up : {				int vpos = m_menu->posToVisiblePos(m_selpos);				vpos--;				if(vpos < 0)					vpos = m_menu->m_visible_entries - 1;				int pos = m_menu->visiblePosToPos(vpos);				m_menu->setSelection(pos);				setSelection(pos);				handled = true;				break;			}			case Key_Down : {				int vpos = m_menu->posToVisiblePos(m_selpos);				vpos++;				if(vpos >= m_menu->m_visible_entries)					vpos = 0;				int pos = m_menu->visiblePosToPos(vpos);				m_menu->setSelection(pos);				setSelection(pos);				handled = true;				break;			}			case Key_Return :				qWarning("selected entry %i", m_selpos);				m_menu->m_hideTimer.start(SideMenu::timeoutInterval);				hide();				m_menu->emit entryActivated(m_entries[m_selpos].id);				handled = true;				break;		}	}	if (!handled)		return QWidget::event(e);	return true;}void SideMenuLabels::mousePressEvent(QMouseEvent * e){	m_menu->m_hideTimer.stop();	int pos = m_menu->visiblePosToPos(e->y() / lineHeight());	if ( m_selpos == pos ) {		m_trigger = true;	}		m_menu->setSelection(pos);	setSelection(pos);}void SideMenuLabels::mouseReleaseEvent(QMouseEvent *e){	if ( m_trigger ) {		m_trigger = false;		QRect r = rect();		hide();		if(r.contains(e->x(), e->y()))			m_menu->emit entryActivated(m_entries[m_selpos].id);		m_menu->m_hideTimer.start(SideMenu::timeoutInterval);	}}void SideMenuLabels::mouseMoveEvent(QMouseEvent *e){	if (e->x() < 0 || e->y() < 0 || e->y() > height())		return;	int pos = m_menu->visiblePosToPos(e->y() / lineHeight());	if(pos != m_selpos) {		m_trigger = false;		setSelection(pos);		m_menu->setSelection(pos);	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -