NotificationBox/NotificationArea: Restrict rendering area to main frame
======================================================================== The NotificationBox is extended to take the QRect in global coordinates. Then it will try to dimension the label within this area. If a fixed width is provided, that is enforced (take precedence). The NotificationArea passes the QRect of the main window to the NotificationBox. This is intended to fix: https://github.com/FreeCAD/FreeCAD/issues/8940
This commit is contained in:
@@ -234,7 +234,7 @@ void NotificationAreaObserver::SendLog(const std::string& notifiername, const st
|
||||
.trimmed();// remove any leading and trailing whitespace character ('\n')
|
||||
|
||||
// avoid processing empty strings
|
||||
if(simplifiedstring.isEmpty())
|
||||
if (simplifiedstring.isEmpty())
|
||||
return;
|
||||
|
||||
if (level == Base::LogStyle::TranslatedNotification) {
|
||||
@@ -827,7 +827,7 @@ void NotificationArea::pushNotification(const QString& notifiername, const QStri
|
||||
auto timer_thread = pImp->inhibitTimer.thread();
|
||||
auto current_thread = QThread::currentThread();
|
||||
|
||||
if(timer_thread == current_thread)
|
||||
if (timer_thread == current_thread)
|
||||
pImp->inhibitTimer.start(pImp->inhibitNotificationTime);
|
||||
}
|
||||
|
||||
@@ -939,7 +939,8 @@ void NotificationArea::showInNotificationArea()
|
||||
iconstr = QStringLiteral(":/icons/info.svg");
|
||||
}
|
||||
|
||||
QString tmpmessage = convertFromPlainText(item->msg, Qt::WhiteSpaceMode::WhiteSpaceNormal);
|
||||
QString tmpmessage =
|
||||
convertFromPlainText(item->msg, Qt::WhiteSpaceMode::WhiteSpaceNormal);
|
||||
|
||||
msgw +=
|
||||
QString::fromLatin1(
|
||||
@@ -990,11 +991,17 @@ void NotificationArea::showInNotificationArea()
|
||||
|
||||
msgw += QString::fromLatin1("</table></p>");
|
||||
|
||||
// Calculate the main window QRect in global screen coordinates.
|
||||
auto mainwindow = getMainWindow();
|
||||
auto mainwindowrect = mainwindow->rect();
|
||||
auto globalmainwindowrect =
|
||||
QRect(mainwindow->mapToGlobal(mainwindowrect.topLeft()), mainwindowrect.size());
|
||||
|
||||
NotificationBox::showText(this->mapToGlobal(QPoint()),
|
||||
msgw,
|
||||
pImp->notificationExpirationTime,
|
||||
pImp->minimumOnScreenTime,
|
||||
globalmainwindowrect,
|
||||
pImp->notificationWidth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +73,8 @@ public:
|
||||
bool notificationLabelChanged(const QString& text);
|
||||
/// Place the notification at the given position
|
||||
void placeNotificationLabel(const QPoint& pos);
|
||||
/// Set the windowrect defining an area to which the label should be constrained
|
||||
void setTipRect(const QRect &restrictionarea);
|
||||
|
||||
/// The instance
|
||||
static qobject_delete_later_unique_ptr<NotificationLabel> instance;
|
||||
@@ -91,6 +93,8 @@ private:
|
||||
int minShowTime;
|
||||
QTimer hideTimer;
|
||||
QTimer expireTimer;
|
||||
|
||||
QRect restrictionArea;
|
||||
};
|
||||
|
||||
qobject_delete_later_unique_ptr<NotificationLabel> NotificationLabel::instance = nullptr;
|
||||
@@ -263,25 +267,36 @@ void NotificationLabel::placeNotificationLabel(const QPoint& pos)
|
||||
|
||||
p += offset;
|
||||
|
||||
QRect screenRect = screen->geometry();
|
||||
QRect actinglimit = screen->geometry();
|
||||
|
||||
if (p.x() + this->width() > screenRect.x() + screenRect.width())
|
||||
p.rx() -= 4 + this->width();
|
||||
if (p.y() + this->height() > screenRect.y() + screenRect.height())
|
||||
p.ry() -= 24 + this->height();
|
||||
if (p.y() < screenRect.y())
|
||||
p.setY(screenRect.y());
|
||||
if (p.x() + this->width() > screenRect.x() + screenRect.width())
|
||||
p.setX(screenRect.x() + screenRect.width() - this->width());
|
||||
if (p.x() < screenRect.x())
|
||||
p.setX(screenRect.x());
|
||||
if (p.y() + this->height() > screenRect.y() + screenRect.height())
|
||||
p.setY(screenRect.y() + screenRect.height() - this->height());
|
||||
if(!restrictionArea.isNull())
|
||||
actinglimit = restrictionArea;
|
||||
|
||||
const int standard_x_padding = 4;
|
||||
const int standard_y_padding = 24;
|
||||
|
||||
if (p.x() + this->width() > actinglimit.x() + actinglimit.width())
|
||||
p.rx() -= standard_x_padding + this->width();
|
||||
if (p.y() + standard_y_padding + this->height() > actinglimit.y() + actinglimit.height())
|
||||
p.ry() -= standard_y_padding + this->height();
|
||||
if (p.y() < actinglimit.y())
|
||||
p.setY(actinglimit.y());
|
||||
if (p.x() + this->width() > actinglimit.x() + actinglimit.width())
|
||||
p.setX(actinglimit.x() + actinglimit.width() - this->width());
|
||||
if (p.x() < actinglimit.x())
|
||||
p.setX(actinglimit.x());
|
||||
if (p.y() + this->height() > actinglimit.y() + actinglimit.height())
|
||||
p.setY(actinglimit.y() + actinglimit.height() - this->height());
|
||||
}
|
||||
|
||||
this->move(p);
|
||||
}
|
||||
|
||||
void NotificationLabel::setTipRect(const QRect &restrictionarea)
|
||||
{
|
||||
restrictionArea = restrictionarea;
|
||||
}
|
||||
|
||||
bool NotificationLabel::notificationLabelChanged(const QString& text)
|
||||
{
|
||||
return NotificationLabel::instance->text() != text;
|
||||
@@ -290,7 +305,7 @@ bool NotificationLabel::notificationLabelChanged(const QString& text)
|
||||
/***************************** NotificationBox **********************************/
|
||||
|
||||
void NotificationBox::showText(const QPoint& pos, const QString& text, int displayTime,
|
||||
unsigned int minShowTime, int width)
|
||||
unsigned int minShowTime, const QRect &restrictionarea, int width)
|
||||
{
|
||||
// a label does already exist
|
||||
if (NotificationLabel::instance && NotificationLabel::instance->isVisible()) {
|
||||
@@ -301,6 +316,7 @@ void NotificationBox::showText(const QPoint& pos, const QString& text, int displ
|
||||
else {
|
||||
// If the label has changed, reuse the one that is showing (removes flickering)
|
||||
if (NotificationLabel::instance->notificationLabelChanged(text)) {
|
||||
NotificationLabel::instance->setTipRect(restrictionarea);
|
||||
NotificationLabel::instance->reuseNotification(text, displayTime, pos, width);
|
||||
NotificationLabel::instance->placeNotificationLabel(pos);
|
||||
}
|
||||
@@ -310,12 +326,16 @@ void NotificationBox::showText(const QPoint& pos, const QString& text, int displ
|
||||
|
||||
// no label can be reused, create new label:
|
||||
if (!text.isEmpty()) {
|
||||
// Note: The Label takes no parent, as on windows, we can't use the widget as parent
|
||||
// otherwise the window will be raised when the tooltip will be shown. We do not use
|
||||
// it on Linux either for consistency.
|
||||
new NotificationLabel(text,
|
||||
pos,
|
||||
displayTime,
|
||||
minShowTime,
|
||||
width);// sets NotificationLabel::instance to itself
|
||||
|
||||
NotificationLabel::instance->setTipRect(restrictionarea);
|
||||
NotificationLabel::instance->placeNotificationLabel(pos);
|
||||
NotificationLabel::instance->setObjectName(QLatin1String("NotificationBox_label"));
|
||||
|
||||
|
||||
@@ -54,11 +54,16 @@ public:
|
||||
* an event, see class documentation above)
|
||||
* @param minShowTime Time during which the notification can only be made disappear by popping
|
||||
* it out (clicking inside it).
|
||||
* @param width Fixes the width of the notification. Default value makes the width to be system determined (dependent on
|
||||
* the text).
|
||||
* @param restrictionarea Try to keep the NotificationBox within this area. If this area is not
|
||||
* provided, the whole screen is used as restriction area. This are must be provided in global
|
||||
* screen coordinates.
|
||||
* @param width Fixes the width of the notification. Default value makes the width to be system
|
||||
* determined (dependent on the text). If a fixed width is provided it is enforced over the
|
||||
* restrictionarea.
|
||||
*/
|
||||
static void showText(const QPoint& pos, const QString& text, int displayTime = -1,
|
||||
unsigned int minShowTime = 0, int width = 0);
|
||||
unsigned int minShowTime = 0, const QRect& restrictionarea = {},
|
||||
int width = 0);
|
||||
/// Hides a notification.
|
||||
static inline void hideText()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user