Return correct hit-test values for title bar buttons on Windows (#4994)
Co-authored-by: Rasmus Karlsson <rasmus.karlsson@pajlada.com>
This commit is contained in:
@@ -124,4 +124,39 @@ void TitleBarButton::paintEvent(QPaintEvent *event)
|
||||
this->paintButton(painter);
|
||||
}
|
||||
|
||||
void TitleBarButton::ncEnter()
|
||||
{
|
||||
this->enterEvent(nullptr);
|
||||
this->update();
|
||||
}
|
||||
|
||||
void TitleBarButton::ncLeave()
|
||||
{
|
||||
this->leaveEvent(nullptr);
|
||||
this->update();
|
||||
}
|
||||
|
||||
void TitleBarButton::ncMove(QPoint at)
|
||||
{
|
||||
QMouseEvent evt(QMouseEvent::MouseMove, at, Qt::NoButton, Qt::NoButton,
|
||||
Qt::NoModifier);
|
||||
this->mouseMoveEvent(&evt);
|
||||
}
|
||||
|
||||
void TitleBarButton::ncMousePress(QPoint at)
|
||||
{
|
||||
QMouseEvent evt(QMouseEvent::MouseButtonPress, at, Qt::LeftButton,
|
||||
Qt::NoButton, Qt::NoModifier);
|
||||
this->mousePressEvent(&evt);
|
||||
this->update();
|
||||
}
|
||||
|
||||
void TitleBarButton::ncMouseRelease(QPoint at)
|
||||
{
|
||||
QMouseEvent evt(QMouseEvent::MouseButtonRelease, at, Qt::LeftButton,
|
||||
Qt::NoButton, Qt::NoModifier);
|
||||
this->mouseReleaseEvent(&evt);
|
||||
this->update();
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
|
||||
@@ -23,6 +23,24 @@ public:
|
||||
TitleBarButtonStyle getButtonStyle() const;
|
||||
void setButtonStyle(TitleBarButtonStyle style_);
|
||||
|
||||
/// Simulate a `mouseEnter` event.
|
||||
void ncEnter();
|
||||
|
||||
/// Simulate a `mouseLeave` event.
|
||||
void ncLeave();
|
||||
|
||||
/// Simulate a `mouseMove` event.
|
||||
/// @param at a local position relative to this widget
|
||||
void ncMove(QPoint at);
|
||||
|
||||
/// Simulate a `mousePress` event with the left mouse button.
|
||||
/// @param at a local position relative to this widget
|
||||
void ncMousePress(QPoint at);
|
||||
|
||||
/// Simulate a `mouseRelease` event with the left mouse button.
|
||||
/// @param at a local position relative to this widget
|
||||
void ncMouseRelease(QPoint at);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *) override;
|
||||
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
#include "widgets/helper/TitlebarButtons.hpp"
|
||||
|
||||
#ifdef USEWINSDK
|
||||
|
||||
# include "widgets/helper/TitlebarButton.hpp"
|
||||
|
||||
# include <Windows.h>
|
||||
|
||||
# include <cassert>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
TitleBarButtons::TitleBarButtons(QWidget *window, TitleBarButton *minButton,
|
||||
TitleBarButton *maxButton,
|
||||
TitleBarButton *closeButton)
|
||||
: QObject(window)
|
||||
, window_(window)
|
||||
, minButton_(minButton)
|
||||
, maxButton_(maxButton)
|
||||
, closeButton_(closeButton)
|
||||
{
|
||||
}
|
||||
|
||||
void TitleBarButtons::hover(size_t ht, QPoint at)
|
||||
{
|
||||
TitleBarButton *hovered{};
|
||||
TitleBarButton *other1{};
|
||||
TitleBarButton *other2{};
|
||||
switch (ht)
|
||||
{
|
||||
case HTMAXBUTTON:
|
||||
hovered = this->maxButton_;
|
||||
other1 = this->minButton_;
|
||||
other2 = this->closeButton_;
|
||||
break;
|
||||
case HTMINBUTTON:
|
||||
hovered = this->minButton_;
|
||||
other1 = this->maxButton_;
|
||||
other2 = this->closeButton_;
|
||||
break;
|
||||
case HTCLOSE:
|
||||
hovered = this->closeButton_;
|
||||
other1 = this->minButton_;
|
||||
other2 = this->maxButton_;
|
||||
break;
|
||||
default:
|
||||
assert(false && "TitleBarButtons::hover precondition violated");
|
||||
return;
|
||||
}
|
||||
hovered->ncEnter();
|
||||
hovered->ncMove(hovered->mapFromGlobal(at));
|
||||
other1->ncLeave();
|
||||
other2->ncLeave();
|
||||
}
|
||||
|
||||
void TitleBarButtons::leave()
|
||||
{
|
||||
this->minButton_->ncLeave();
|
||||
this->maxButton_->ncLeave();
|
||||
this->closeButton_->ncLeave();
|
||||
}
|
||||
|
||||
void TitleBarButtons::mousePress(size_t ht, QPoint at)
|
||||
{
|
||||
auto *button = this->buttonForHt(ht);
|
||||
button->ncMousePress(button->mapFromGlobal(at));
|
||||
}
|
||||
|
||||
void TitleBarButtons::mouseRelease(size_t ht, QPoint at)
|
||||
{
|
||||
auto *button = this->buttonForHt(ht);
|
||||
button->ncMouseRelease(button->mapFromGlobal(at));
|
||||
}
|
||||
|
||||
void TitleBarButtons::updateMaxButton()
|
||||
{
|
||||
this->maxButton_->setButtonStyle(
|
||||
this->window_->windowState().testFlag(Qt::WindowMaximized)
|
||||
? TitleBarButtonStyle::Unmaximize
|
||||
: TitleBarButtonStyle::Maximize);
|
||||
}
|
||||
|
||||
void TitleBarButtons::setSmallSize()
|
||||
{
|
||||
this->minButton_->setScaleIndependantSize(30, 30);
|
||||
this->maxButton_->setScaleIndependantSize(30, 30);
|
||||
this->closeButton_->setScaleIndependantSize(30, 30);
|
||||
}
|
||||
|
||||
void TitleBarButtons::setRegularSize()
|
||||
{
|
||||
this->minButton_->setScaleIndependantSize(46, 30);
|
||||
this->maxButton_->setScaleIndependantSize(46, 30);
|
||||
this->closeButton_->setScaleIndependantSize(46, 30);
|
||||
}
|
||||
|
||||
TitleBarButton *TitleBarButtons::buttonForHt(size_t ht) const
|
||||
{
|
||||
switch (ht)
|
||||
{
|
||||
case HTMAXBUTTON:
|
||||
return this->maxButton_;
|
||||
case HTMINBUTTON:
|
||||
return this->minButton_;
|
||||
case HTCLOSE:
|
||||
return this->closeButton_;
|
||||
default:
|
||||
assert(false &&
|
||||
"TitleBarButtons::buttonForHt precondition violated");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace chatterino
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,69 @@
|
||||
#pragma once
|
||||
|
||||
class QPoint;
|
||||
class QWidget;
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
#ifdef USEWINSDK
|
||||
|
||||
class TitleBarButton;
|
||||
class TitleBarButtons : QObject
|
||||
{
|
||||
public:
|
||||
/// The parent of this object is set to `window`.
|
||||
///
|
||||
/// All parameters must have a parent;
|
||||
/// they're not deleted in the destructor.
|
||||
TitleBarButtons(QWidget *window, TitleBarButton *minButton,
|
||||
TitleBarButton *maxButton, TitleBarButton *closeButton);
|
||||
|
||||
/// Hover over the button `ht` at the global position `at`.
|
||||
///
|
||||
/// @pre `ht` must be one of { HTMAXBUTTON, HTMINBUTTON, HTCLOSE }.
|
||||
/// @param ht The hovered button
|
||||
/// @param at The global position of the event
|
||||
void hover(size_t ht, QPoint at);
|
||||
|
||||
/// Leave all buttons - simulate `leaveEvent` for all buttons.
|
||||
void leave();
|
||||
|
||||
/// Press the left mouse over the button `ht` at the global position `at`.
|
||||
///
|
||||
/// @pre `ht` must be one of { HTMAXBUTTON, HTMINBUTTON, HTCLOSE }.
|
||||
/// @param ht The clicked button
|
||||
/// @param at The global position of the event
|
||||
void mousePress(size_t ht, QPoint at);
|
||||
|
||||
/// Release the left mouse button over the button `ht` at the
|
||||
/// global position `at`.
|
||||
///
|
||||
/// @pre `ht` must be one of { HTMAXBUTTON, HTMINBUTTON, HTCLOSE }.
|
||||
/// @param ht The clicked button
|
||||
/// @param at The global position of the event
|
||||
void mouseRelease(size_t ht, QPoint at);
|
||||
|
||||
/// Update the maximize/restore button to show the correct image
|
||||
/// according to the current window state.
|
||||
void updateMaxButton();
|
||||
|
||||
/// Set buttons to be narrow.
|
||||
void setSmallSize();
|
||||
/// Set buttons to be regular size.
|
||||
void setRegularSize();
|
||||
|
||||
private:
|
||||
/// @pre ht must be one of { HTMAXBUTTON, HTMINBUTTON, HTCLOSE }.
|
||||
TitleBarButton *buttonForHt(size_t ht) const;
|
||||
|
||||
QWidget *window_ = nullptr;
|
||||
TitleBarButton *minButton_ = nullptr;
|
||||
TitleBarButton *maxButton_ = nullptr;
|
||||
TitleBarButton *closeButton_ = nullptr;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace chatterino
|
||||
Reference in New Issue
Block a user