feat: 修复任务栏鼠标放到日期时间控件上不显示当前时间的问题

1、增加当前时间的显示
2、实时更新任务栏的时间显示

Log:
Influence: 任务栏V23,查看插件区域时间的显示
Task: https://pms.uniontech.com/task-view-110311.html
Change-Id: I5cb1eb778c2351555cd736fb62525e130a13e3ff
This commit is contained in:
donghualin 2022-05-20 11:11:45 +08:00
parent 6d209d8ddb
commit fdfe0ba05c
2 changed files with 203 additions and 49 deletions

View File

@ -19,6 +19,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "datetimedisplayer.h"
#include "tipswidget.h"
#include "dockpopupwindow.h"
#include <DFontSizeManager>
#include <DDBusSender>
@ -28,6 +30,7 @@
#include <QFont>
DWIDGET_USE_NAMESPACE
DGUI_USE_NAMESPACE
#define DATETIMESIZE 40
#define ITEMSPACE 8
@ -40,15 +43,27 @@ DateTimeDisplayer::DateTimeDisplayer(QWidget *parent)
: QWidget (parent)
, m_timedateInter(new Timedate("com.deepin.daemon.Timedate", "/com/deepin/daemon/Timedate", QDBusConnection::sessionBus(), this))
, m_position(Dock::Position::Bottom)
, m_timeFont(DFontSizeManager::instance()->t6())
, m_dateFont(DFontSizeManager::instance()->t10())
, m_tipsWidget(new Dock::TipsWidget(this))
, m_tipsTimer(new QTimer(this))
, m_currentSize(0)
, m_oneRow(false)
{
m_tipPopupWindow.reset(new DockPopupWindow);
// 日期格式变化的时候,需要重绘
connect(m_timedateInter, &Timedate::ShortDateFormatChanged, this, [ this ] { update(); });
connect(m_timedateInter, &Timedate::ShortDateFormatChanged, this, &DateTimeDisplayer::onDateTimeFormatChanged);
// 时间格式变化的时候,需要重绘
connect(m_timedateInter, &Timedate::ShortTimeFormatChanged, this, [ this ] { update(); });
connect(m_timedateInter, &Timedate::ShortTimeFormatChanged, this, &DateTimeDisplayer::onDateTimeFormatChanged);
// 是否使用24小时制发生变化的时候也需要重绘
connect(m_timedateInter, &Timedate::Use24HourFormatChanged, this, &DateTimeDisplayer::onDateTimeFormatChanged);
// 连接日期时间修改信号,更新日期时间插件的布局
connect(m_timedateInter, &Timedate::TimeUpdate, this, [ this ] { update(); });
connect(m_timedateInter, &Timedate::TimeUpdate, this, static_cast<void (QWidget::*)()>(&DateTimeDisplayer::update));
// 连接定时器和时间显示的tips信号,一秒钟触发一次,显示时间
connect(m_tipsTimer, &QTimer::timeout, this, &DateTimeDisplayer::onTimeChanged);
m_tipsTimer->setInterval(1000);
m_tipsTimer->start();
updatePolicy();
m_tipPopupWindow->hide();
}
DateTimeDisplayer::~DateTimeDisplayer()
@ -61,21 +76,41 @@ void DateTimeDisplayer::setPositon(Dock::Position position)
return;
m_position = position;
setCurrentPolicy();
updatePolicy();
update();
}
void DateTimeDisplayer::setCurrentPolicy()
void DateTimeDisplayer::setOneRow(bool oneRow)
{
m_oneRow = oneRow;
update();
}
void DateTimeDisplayer::updatePolicy()
{
switch (m_position) {
case Dock::Position::Top:
case Dock::Position::Bottom: {
case Dock::Position::Top: {
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
m_tipPopupWindow->setArrowDirection(DArrowRectangle::ArrowDirection::ArrowTop);
m_tipPopupWindow->setContent(m_tipsWidget);
break;
}
case Dock::Position::Bottom: {
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
m_tipPopupWindow->setArrowDirection(DArrowRectangle::ArrowDirection::ArrowBottom);
m_tipPopupWindow->setContent(m_tipsWidget);
break;
}
case Dock::Position::Left: {
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
m_tipPopupWindow->setArrowDirection(DArrowRectangle::ArrowDirection::ArrowLeft);
m_tipPopupWindow->setContent(m_tipsWidget);
break;
}
case Dock::Position::Left:
case Dock::Position::Right: {
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
m_tipPopupWindow->setArrowDirection(DArrowRectangle::ArrowDirection::ArrowRight);
m_tipPopupWindow->setContent(m_tipsWidget);
break;
}
}
@ -102,43 +137,24 @@ void DateTimeDisplayer::mouseReleaseEvent(QMouseEvent *event)
.method("RaiseWindow").call();
}
DateTimeDisplayer::DateTimeInfo DateTimeDisplayer::dateTimeInfo()
QString DateTimeDisplayer::getTimeString() const
{
DateTimeInfo info;
const QDateTime current = QDateTime::currentDateTime();
QString tFormat = QString("hh:mm");
int type = m_timedateInter->shortTimeFormat();
if (timeFormat.contains(type))
tFormat = timeFormat[type];
info.m_timeRect = rect();
info.m_dateRect = rect();
QString format = getTimeFormat();
if (!m_timedateInter->use24HourFormat()) {
if (m_position == Dock::Top || m_position == Dock::Bottom)
format = format.append(" AP");
tFormat = tFormat.append(" AP");
else
format = format.append("\nAP");
tFormat = tFormat.append("\nAP");
}
info.m_time = current.toString(format);
info.m_date = current.toString(getDateFormat());
if (m_position == Dock::Top || m_position == Dock::Bottom) {
int timeWidth = QFontMetrics(m_timeFont).boundingRect(info.m_time).width() + 10;
int dateWidth = QFontMetrics(m_dateFont).boundingRect(info.m_date).width() + 2;
info.m_timeRect = QRect(ITEMSPACE, 0, timeWidth, height());
int dateX = rect().width() - QFontMetrics(m_dateFont).width(info.m_date) - 2 - ITEMSPACE;
// 如果时间的X坐标小于日期的X坐标需要手动设置坐标在日期坐标的右侧
if (dateX < info.m_timeRect.right())
dateX = info.m_timeRect.right();
info.m_dateRect = QRect(dateX, 0, dateWidth, height());
} else {
int textWidth = rect().width();
info.m_timeRect = QRect(0, 0, textWidth, DATETIMESIZE / 2);
info.m_dateRect = QRect(0, DATETIMESIZE / 2 + 1, textWidth, DATETIMESIZE / 2);
}
return info;
return QDateTime::currentDateTime().toString(tFormat);
}
QString DateTimeDisplayer::getDateFormat() const
QString DateTimeDisplayer::getDateString() const
{
int type = m_timedateInter->shortDateFormat();
QString shortDateFormat = "yyyy-MM-dd";
@ -156,16 +172,57 @@ QString DateTimeDisplayer::getDateFormat() const
}
}
return shortDateFormat;
return QDateTime::currentDateTime().toString(shortDateFormat);
}
QString DateTimeDisplayer::getTimeFormat() const
DateTimeDisplayer::DateTimeInfo DateTimeDisplayer::dateTimeInfo()
{
int type = m_timedateInter->shortTimeFormat();
if (timeFormat.contains(type))
return timeFormat[type];
DateTimeInfo info;
info.m_timeRect = rect();
info.m_dateRect = rect();
return QString("hh:mm");
info.m_time = getTimeString();
info.m_date = getDateString();
if (m_position == Dock::Top || m_position == Dock::Bottom) {
int timeWidth = QFontMetrics(timeFont()).boundingRect(info.m_time).width() + 3;
int dateWidth = QFontMetrics(m_dateFont).boundingRect(info.m_date).width() + 2;
info.m_timeRect = QRect(ITEMSPACE, 0, timeWidth, height());
int dateX = rect().width() - QFontMetrics(m_dateFont).width(info.m_date) - 2 - ITEMSPACE;
// 如果时间的X坐标小于日期的X坐标需要手动设置坐标在日期坐标的右侧
if (dateX < info.m_timeRect.right())
dateX = info.m_timeRect.right();
info.m_dateRect = QRect(dateX, 0, dateWidth, height());
} else {
int textWidth = rect().width();
info.m_timeRect = QRect(0, 0, textWidth, DATETIMESIZE / 2);
info.m_dateRect = QRect(0, DATETIMESIZE / 2 + 1, textWidth, DATETIMESIZE / 2);
}
return info;
}
void DateTimeDisplayer::onTimeChanged()
{
const QDateTime currentDateTime = QDateTime::currentDateTime();
if (m_timedateInter->use24HourFormat())
m_tipsWidget->setText(currentDateTime.date().toString(Qt::SystemLocaleLongDate) + currentDateTime.toString(" HH:mm:ss"));
else
m_tipsWidget->setText(currentDateTime.date().toString(Qt::SystemLocaleLongDate) + currentDateTime.toString(" hh:mm:ss AP"));
// 如果时间和日期有一个不等,则实时刷新界面
if (m_lastDateString != getDateString() || m_lastTimeString != getTimeString())
update();
}
void DateTimeDisplayer::onDateTimeFormatChanged()
{
int lastSize = m_currentSize;
// 此处需要强制重绘因为在重绘过程中才会改变m_currentSize信息方便在后面判断是否需要调整尺寸
repaint();
// 如果日期时间的格式发生了变化,需要通知外部来调整日期时间的尺寸
if (lastSize != m_currentSize)
Q_EMIT sizeChanged();
}
void DateTimeDisplayer::paintEvent(QPaintEvent *e)
@ -184,8 +241,82 @@ void DateTimeDisplayer::paintEvent(QPaintEvent *e)
timeTextFlag = Qt::AlignLeft | Qt::AlignVCenter;
dateTextFlag = Qt::AlignRight | Qt::AlignVCenter;
}
painter.setFont(m_timeFont);
painter.setFont(timeFont());
painter.drawText(info.m_timeRect, timeTextFlag, info.m_time);
painter.setFont(m_dateFont);
painter.drawText(info.m_dateRect, dateTextFlag, info.m_date);
updateLastData(info);
}
QPoint DateTimeDisplayer::tipsPoint() const
{
QPoint pointInTopWidget = parentWidget()->mapTo(topLevelWidget(), pos());
switch (m_position) {
case Dock::Position::Left: {
pointInTopWidget.setX(topLevelWidget()->x() + topLevelWidget()->width());
pointInTopWidget.setY(pointInTopWidget.y() + height() / 2);
break;
}
case Dock::Position::Top: {
pointInTopWidget.setY(y() + topLevelWidget()->y() + topLevelWidget()->height());
pointInTopWidget.setX(pointInTopWidget.x() + width() / 2);
break;
}
case Dock::Position::Right: {
pointInTopWidget.setY(pointInTopWidget.y() + height() / 2);
pointInTopWidget.setX(pointInTopWidget.x() - width() / 2);
break;
}
case Dock::Position::Bottom: {
pointInTopWidget.setY(0);
pointInTopWidget.setX(pointInTopWidget.x() + width() / 2);
break;
}
}
return topLevelWidget()->mapToGlobal(pointInTopWidget);
}
QFont DateTimeDisplayer::timeFont() const
{
if (m_position == Dock::Position::Left || m_position == Dock::Position::Right)
return DFontSizeManager::instance()->t6();
// 如果是上下方向,且当前只有一行,则始终显示小号字体
if (m_oneRow)
return DFontSizeManager::instance()->t10();
static QList<QFont> dateFontSize = { DFontSizeManager::instance()->t10(),
DFontSizeManager::instance()->t9(),
DFontSizeManager::instance()->t8(),
DFontSizeManager::instance()->t7(),
DFontSizeManager::instance()->t6() };
#define MINHEIGHT 16
// 获取最低高度为16找到对应的索引值
int index = qMin(qMax(static_cast<int>((rect().height() - MINHEIGHT) / 3), 0), dateFontSize.size() - 1);
return dateFontSize[index];
}
void DateTimeDisplayer::enterEvent(QEvent *event)
{
Q_UNUSED(event);
m_tipPopupWindow->show(tipsPoint());
}
void DateTimeDisplayer::leaveEvent(QEvent *event)
{
Q_UNUSED(event);
m_tipPopupWindow->hide();
}
void DateTimeDisplayer::updateLastData(const DateTimeInfo &info)
{
m_lastDateString = info.m_date;
m_lastTimeString = info.m_time;
QSize dateTimeSize = suitableSize();
if (m_position == Dock::Position::Top || m_position == Dock::Position::Bottom)
m_currentSize = dateTimeSize.width();
else
m_currentSize = dateTimeSize.height();
}

View File

@ -28,6 +28,9 @@
#include <com_deepin_daemon_timedate.h>
namespace Dock { class TipsWidget; }
class DockPopupWindow;
using Timedate = com::deepin::daemon::Timedate;
class DateTimeDisplayer : public QWidget
@ -46,24 +49,44 @@ public:
explicit DateTimeDisplayer(QWidget *parent = nullptr);
~DateTimeDisplayer() override;
void setPositon(Dock::Position position);
void setOneRow(bool oneRow);
QSize suitableSize();
Q_SIGNALS:
void sizeChanged(); // 当日期时间格式发生变化的时候,需要通知外面来更新窗口尺寸
protected:
void mouseReleaseEvent(QMouseEvent *event) override;
void paintEvent(QPaintEvent *e) override;
void enterEvent(QEvent *event) override;
void leaveEvent(QEvent *event) override;
private:
void setCurrentPolicy();
void updatePolicy();
DateTimeInfo dateTimeInfo();
void updateLastData(const DateTimeInfo &info);
QString getDateFormat() const;
QString getTimeFormat() const;
QString getTimeString() const;
QString getDateString() const;
QPoint tipsPoint() const;
QFont timeFont() const;
private Q_SLOTS:
void onTimeChanged();
void onDateTimeFormatChanged();
private:
Timedate *m_timedateInter;
Dock::Position m_position;
mutable QFont m_timeFont;
mutable QFont m_dateFont;
QFont m_dateFont;
Dock::TipsWidget *m_tipsWidget;
QSharedPointer<DockPopupWindow> m_tipPopupWindow;
QTimer *m_tipsTimer;
QString m_lastDateString;
QString m_lastTimeString;
int m_currentSize;
bool m_oneRow;
};
#endif // DATETIMEDISPLAYER_H