mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-21 22:24:07 +01:00
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:
parent
584a7c86fc
commit
812186dc4c
8 changed files with 381 additions and 38 deletions
|
@ -43,6 +43,7 @@
|
||||||
- Bugfix: Fixed lookahead/-behind not working in _Ignores_. (#4965)
|
- Bugfix: Fixed lookahead/-behind not working in _Ignores_. (#4965)
|
||||||
- Bugfix: Fixed Image Uploader accidentally deleting images with some hosts when link resolver was enabled. (#4971)
|
- Bugfix: Fixed Image Uploader accidentally deleting images with some hosts when link resolver was enabled. (#4971)
|
||||||
- Bugfix: Fixed rare crash with Image Uploader when closing a split right after starting an upload. (#4971)
|
- Bugfix: Fixed rare crash with Image Uploader when closing a split right after starting an upload. (#4971)
|
||||||
|
- Bugfix: Fixed support for Windows 11 Snap layouts. (#4994)
|
||||||
- Bugfix: Fixed some windows appearing between screens. (#4797)
|
- Bugfix: Fixed some windows appearing between screens. (#4797)
|
||||||
- Dev: Run miniaudio in a separate thread, and simplify it to not manage the device ourselves. There's a chance the simplification is a bad idea. (#4978)
|
- Dev: Run miniaudio in a separate thread, and simplify it to not manage the device ourselves. There's a chance the simplification is a bad idea. (#4978)
|
||||||
- Dev: Change clang-format from v14 to v16. (#4929)
|
- Dev: Change clang-format from v14 to v16. (#4929)
|
||||||
|
|
|
@ -626,6 +626,8 @@ set(SOURCE_FILES
|
||||||
widgets/helper/SignalLabel.hpp
|
widgets/helper/SignalLabel.hpp
|
||||||
widgets/helper/TitlebarButton.cpp
|
widgets/helper/TitlebarButton.cpp
|
||||||
widgets/helper/TitlebarButton.hpp
|
widgets/helper/TitlebarButton.hpp
|
||||||
|
widgets/helper/TitlebarButtons.cpp
|
||||||
|
widgets/helper/TitlebarButtons.hpp
|
||||||
|
|
||||||
widgets/listview/GenericItemDelegate.cpp
|
widgets/listview/GenericItemDelegate.cpp
|
||||||
widgets/listview/GenericItemDelegate.hpp
|
widgets/listview/GenericItemDelegate.hpp
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "util/PostToThread.hpp"
|
#include "util/PostToThread.hpp"
|
||||||
#include "util/WindowsHelper.hpp"
|
#include "util/WindowsHelper.hpp"
|
||||||
#include "widgets/helper/EffectLabel.hpp"
|
#include "widgets/helper/EffectLabel.hpp"
|
||||||
|
#include "widgets/helper/TitlebarButtons.hpp"
|
||||||
#include "widgets/Label.hpp"
|
#include "widgets/Label.hpp"
|
||||||
#include "widgets/TooltipWidget.hpp"
|
#include "widgets/TooltipWidget.hpp"
|
||||||
#include "widgets/Window.hpp"
|
#include "widgets/Window.hpp"
|
||||||
|
@ -180,9 +181,8 @@ void BaseWindow::init()
|
||||||
this->close();
|
this->close();
|
||||||
});
|
});
|
||||||
|
|
||||||
this->ui_.minButton = _minButton;
|
this->ui_.titlebarButtons = new TitleBarButtons(
|
||||||
this->ui_.maxButton = _maxButton;
|
this, _minButton, _maxButton, _exitButton);
|
||||||
this->ui_.exitButton = _exitButton;
|
|
||||||
|
|
||||||
this->ui_.buttons.push_back(_minButton);
|
this->ui_.buttons.push_back(_minButton);
|
||||||
this->ui_.buttons.push_back(_maxButton);
|
this->ui_.buttons.push_back(_maxButton);
|
||||||
|
@ -474,12 +474,9 @@ void BaseWindow::changeEvent(QEvent *)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USEWINSDK
|
#ifdef USEWINSDK
|
||||||
if (this->ui_.maxButton)
|
if (this->ui_.titlebarButtons)
|
||||||
{
|
{
|
||||||
this->ui_.maxButton->setButtonStyle(
|
this->ui_.titlebarButtons->updateMaxButton();
|
||||||
this->windowState() & Qt::WindowMaximized
|
|
||||||
? TitleBarButtonStyle::Unmaximize
|
|
||||||
: TitleBarButtonStyle::Maximize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->isVisible() && this->hasCustomWindowFrame())
|
if (this->isVisible() && this->hasCustomWindowFrame())
|
||||||
|
@ -585,6 +582,11 @@ bool BaseWindow::nativeEvent(const QByteArray &eventType, void *message,
|
||||||
|
|
||||||
bool returnValue = false;
|
bool returnValue = false;
|
||||||
|
|
||||||
|
auto isHoveringTitlebarButton = [&]() {
|
||||||
|
auto ht = msg->wParam;
|
||||||
|
return ht == HTMAXBUTTON || ht == HTMINBUTTON || ht == HTCLOSE;
|
||||||
|
};
|
||||||
|
|
||||||
switch (msg->message)
|
switch (msg->message)
|
||||||
{
|
{
|
||||||
case WM_DPICHANGED:
|
case WM_DPICHANGED:
|
||||||
|
@ -612,6 +614,91 @@ bool BaseWindow::nativeEvent(const QByteArray &eventType, void *message,
|
||||||
returnValue = this->handleNCHITTEST(msg, result);
|
returnValue = this->handleNCHITTEST(msg, result);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case WM_NCMOUSEHOVER:
|
||||||
|
case WM_NCMOUSEMOVE: {
|
||||||
|
// WM_NCMOUSEMOVE/WM_NCMOUSEHOVER gets sent when the mouse is
|
||||||
|
// moving/hovering in the non-client area
|
||||||
|
// - (mostly) the edges and the titlebar.
|
||||||
|
// We only need to handle the event for the titlebar buttons,
|
||||||
|
// as Qt doesn't create mouse events for these events.
|
||||||
|
if (!this->ui_.titlebarButtons)
|
||||||
|
{
|
||||||
|
// we don't consume the event if we don't have custom buttons
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isHoveringTitlebarButton())
|
||||||
|
{
|
||||||
|
*result = 0;
|
||||||
|
returnValue = true;
|
||||||
|
long x = GET_X_LPARAM(msg->lParam);
|
||||||
|
long y = GET_Y_LPARAM(msg->lParam);
|
||||||
|
|
||||||
|
RECT winrect;
|
||||||
|
GetWindowRect(HWND(winId()), &winrect);
|
||||||
|
QPoint globalPos(x, y);
|
||||||
|
this->ui_.titlebarButtons->hover(msg->wParam, globalPos);
|
||||||
|
this->lastEventWasNcMouseMove_ = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->ui_.titlebarButtons->leave();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WM_MOUSEMOVE: {
|
||||||
|
if (!this->lastEventWasNcMouseMove_)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this->lastEventWasNcMouseMove_ = false;
|
||||||
|
// Windows doesn't send WM_NCMOUSELEAVE in some cases,
|
||||||
|
// so the buttons show as hovered even though they're not hovered.
|
||||||
|
[[fallthrough]];
|
||||||
|
}
|
||||||
|
case WM_NCMOUSELEAVE: {
|
||||||
|
// WM_NCMOUSELEAVE gets sent when the mouse leaves any
|
||||||
|
// non-client area. In case we have titlebar buttons,
|
||||||
|
// we want to ensure they're deselected.
|
||||||
|
if (this->ui_.titlebarButtons)
|
||||||
|
{
|
||||||
|
this->ui_.titlebarButtons->leave();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WM_NCLBUTTONDOWN:
|
||||||
|
case WM_NCLBUTTONUP: {
|
||||||
|
// WM_NCLBUTTON{DOWN, UP} gets called when the left mouse button
|
||||||
|
// was pressed in a non-client area.
|
||||||
|
// We simulate a mouse down/up event for the titlebar buttons
|
||||||
|
// as Qt doesn't create an event in that case.
|
||||||
|
if (!this->ui_.titlebarButtons || !isHoveringTitlebarButton())
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
returnValue = true;
|
||||||
|
*result = 0;
|
||||||
|
|
||||||
|
auto ht = msg->wParam;
|
||||||
|
long x = GET_X_LPARAM(msg->lParam);
|
||||||
|
long y = GET_Y_LPARAM(msg->lParam);
|
||||||
|
|
||||||
|
RECT winrect;
|
||||||
|
GetWindowRect(HWND(winId()), &winrect);
|
||||||
|
QPoint globalPos(x, y);
|
||||||
|
if (msg->message == WM_NCLBUTTONDOWN)
|
||||||
|
{
|
||||||
|
this->ui_.titlebarButtons->mousePress(ht, globalPos);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->ui_.titlebarButtons->mouseRelease(ht, globalPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return QWidget::nativeEvent(eventType, message, result);
|
return QWidget::nativeEvent(eventType, message, result);
|
||||||
}
|
}
|
||||||
|
@ -668,29 +755,21 @@ void BaseWindow::calcButtonsSizes()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->frameless_)
|
if (this->frameless_ || !this->ui_.titlebarButtons)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((this->width() / this->scale()) < 300)
|
#ifdef USEWINSDK
|
||||||
|
if ((static_cast<float>(this->width()) / this->scale()) < 300)
|
||||||
{
|
{
|
||||||
if (this->ui_.minButton)
|
this->ui_.titlebarButtons->setSmallSize();
|
||||||
this->ui_.minButton->setScaleIndependantSize(30, 30);
|
|
||||||
if (this->ui_.maxButton)
|
|
||||||
this->ui_.maxButton->setScaleIndependantSize(30, 30);
|
|
||||||
if (this->ui_.exitButton)
|
|
||||||
this->ui_.exitButton->setScaleIndependantSize(30, 30);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (this->ui_.minButton)
|
this->ui_.titlebarButtons->setRegularSize();
|
||||||
this->ui_.minButton->setScaleIndependantSize(46, 30);
|
|
||||||
if (this->ui_.maxButton)
|
|
||||||
this->ui_.maxButton->setScaleIndependantSize(46, 30);
|
|
||||||
if (this->ui_.exitButton)
|
|
||||||
this->ui_.exitButton->setScaleIndependantSize(46, 30);
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseWindow::drawCustomWindowFrame(QPainter &painter)
|
void BaseWindow::drawCustomWindowFrame(QPainter &painter)
|
||||||
|
@ -943,32 +1022,55 @@ bool BaseWindow::handleNCHITTEST(MSG *msg, long *result)
|
||||||
|
|
||||||
if (*result == 0)
|
if (*result == 0)
|
||||||
{
|
{
|
||||||
bool client = false;
|
|
||||||
|
|
||||||
// Check the main layout first, as it's the largest area
|
// Check the main layout first, as it's the largest area
|
||||||
if (this->ui_.layoutBase->geometry().contains(point))
|
if (this->ui_.layoutBase->geometry().contains(point))
|
||||||
{
|
{
|
||||||
client = true;
|
*result = HTCLIENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the titlebar buttons
|
// Check the titlebar buttons
|
||||||
if (!client && this->ui_.titlebarBox->geometry().contains(point))
|
if (*result == 0 &&
|
||||||
|
this->ui_.titlebarBox->geometry().contains(point))
|
||||||
{
|
{
|
||||||
for (QWidget *widget : this->ui_.buttons)
|
for (const auto *widget : this->ui_.buttons)
|
||||||
{
|
{
|
||||||
if (widget->isVisible() &&
|
if (!widget->isVisible() ||
|
||||||
widget->geometry().contains(point))
|
!widget->geometry().contains(point))
|
||||||
{
|
{
|
||||||
client = true;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (const auto *btn =
|
||||||
|
dynamic_cast<const TitleBarButton *>(widget))
|
||||||
|
{
|
||||||
|
switch (btn->getButtonStyle())
|
||||||
|
{
|
||||||
|
case TitleBarButtonStyle::Minimize: {
|
||||||
|
*result = HTMINBUTTON;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TitleBarButtonStyle::Unmaximize:
|
||||||
|
case TitleBarButtonStyle::Maximize: {
|
||||||
|
*result = HTMAXBUTTON;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TitleBarButtonStyle::Close: {
|
||||||
|
*result = HTCLOSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
*result = HTCLIENT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*result = HTCLIENT;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client)
|
if (*result == 0)
|
||||||
{
|
|
||||||
*result = HTCLIENT;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
*result = HTCAPTION;
|
*result = HTCAPTION;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ namespace chatterino {
|
||||||
class Button;
|
class Button;
|
||||||
class EffectLabel;
|
class EffectLabel;
|
||||||
class TitleBarButton;
|
class TitleBarButton;
|
||||||
|
class TitleBarButtons;
|
||||||
enum class TitleBarButtonStyle;
|
enum class TitleBarButtonStyle;
|
||||||
|
|
||||||
class BaseWindow : public BaseWidget
|
class BaseWindow : public BaseWidget
|
||||||
|
@ -135,9 +136,7 @@ private:
|
||||||
QLayout *windowLayout = nullptr;
|
QLayout *windowLayout = nullptr;
|
||||||
QHBoxLayout *titlebarBox = nullptr;
|
QHBoxLayout *titlebarBox = nullptr;
|
||||||
QWidget *titleLabel = nullptr;
|
QWidget *titleLabel = nullptr;
|
||||||
TitleBarButton *minButton = nullptr;
|
TitleBarButtons *titlebarButtons = nullptr;
|
||||||
TitleBarButton *maxButton = nullptr;
|
|
||||||
TitleBarButton *exitButton = nullptr;
|
|
||||||
QWidget *layoutBase = nullptr;
|
QWidget *layoutBase = nullptr;
|
||||||
std::vector<Button *> buttons;
|
std::vector<Button *> buttons;
|
||||||
} ui_;
|
} ui_;
|
||||||
|
@ -148,6 +147,7 @@ private:
|
||||||
QRect nextBounds_;
|
QRect nextBounds_;
|
||||||
QTimer useNextBounds_;
|
QTimer useNextBounds_;
|
||||||
bool isNotMinimizedOrMaximized_{};
|
bool isNotMinimizedOrMaximized_{};
|
||||||
|
bool lastEventWasNcMouseMove_ = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pajlada::Signals::SignalHolder connections_;
|
pajlada::Signals::SignalHolder connections_;
|
||||||
|
|
|
@ -124,4 +124,39 @@ void TitleBarButton::paintEvent(QPaintEvent *event)
|
||||||
this->paintButton(painter);
|
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
|
} // namespace chatterino
|
||||||
|
|
|
@ -23,6 +23,24 @@ public:
|
||||||
TitleBarButtonStyle getButtonStyle() const;
|
TitleBarButtonStyle getButtonStyle() const;
|
||||||
void setButtonStyle(TitleBarButtonStyle style_);
|
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:
|
protected:
|
||||||
void paintEvent(QPaintEvent *) override;
|
void paintEvent(QPaintEvent *) override;
|
||||||
|
|
||||||
|
|
116
src/widgets/helper/TitlebarButtons.cpp
Normal file
116
src/widgets/helper/TitlebarButtons.cpp
Normal file
|
@ -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
|
69
src/widgets/helper/TitlebarButtons.hpp
Normal file
69
src/widgets/helper/TitlebarButtons.hpp
Normal file
|
@ -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
|
Loading…
Reference in a new issue