Allow arbitrary paddings around PopupMenu.
This commit is contained in:
parent
1cc74a41c4
commit
a76cdf7edf
16 changed files with 209 additions and 79 deletions
|
|
@ -438,7 +438,7 @@ bool IsApplicationActive() {
|
||||||
return QApplication::activeWindow() != nullptr;
|
return QApplication::activeWindow() != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslucentWindowsSupported(QPoint globalPosition) {
|
bool TranslucentWindowsSupported() {
|
||||||
if (::Platform::IsWayland()) {
|
if (::Platform::IsWayland()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
namespace Platform {
|
namespace Platform {
|
||||||
|
|
||||||
inline bool TranslucentWindowsSupported(QPoint globalPosition) {
|
inline bool TranslucentWindowsSupported() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ namespace Platform {
|
||||||
|
|
||||||
[[nodiscard]] bool IsApplicationActive();
|
[[nodiscard]] bool IsApplicationActive();
|
||||||
|
|
||||||
[[nodiscard]] bool TranslucentWindowsSupported(QPoint globalPosition);
|
[[nodiscard]] bool TranslucentWindowsSupported();
|
||||||
|
|
||||||
void InitOnTopPanel(not_null<QWidget*> panel);
|
void InitOnTopPanel(not_null<QWidget*> panel);
|
||||||
void DeInitOnTopPanel(not_null<QWidget*> panel);
|
void DeInitOnTopPanel(not_null<QWidget*> panel);
|
||||||
|
|
|
||||||
|
|
@ -339,8 +339,7 @@ QMargins DefaultWindowHelper::frameMargins() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DefaultWindowHelper::hasShadow() const {
|
bool DefaultWindowHelper::hasShadow() const {
|
||||||
const auto center = window()->geometry().center();
|
return WindowExtentsSupported() && TranslucentWindowsSupported();
|
||||||
return WindowExtentsSupported() && TranslucentWindowsSupported(center);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QMargins DefaultWindowHelper::resizeArea() const {
|
QMargins DefaultWindowHelper::resizeArea() const {
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ class QPaintEvent;
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
namespace Platform {
|
namespace Platform {
|
||||||
|
|
||||||
inline bool TranslucentWindowsSupported(QPoint globalPosition) {
|
inline bool TranslucentWindowsSupported() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,8 +62,9 @@ not_null<QAction*> DropdownMenu::addAction(const QString &text, Fn<void()> callb
|
||||||
return _menu->addAction(text, std::move(callback), icon, iconOver);
|
return _menu->addAction(text, std::move(callback), icon, iconOver);
|
||||||
}
|
}
|
||||||
|
|
||||||
not_null<QAction*> DropdownMenu::addSeparator() {
|
not_null<QAction*> DropdownMenu::addSeparator(
|
||||||
return _menu->addSeparator();
|
const style::MenuSeparator *st) {
|
||||||
|
return _menu->addSeparator(st);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DropdownMenu::clearActions() {
|
void DropdownMenu::clearActions() {
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,8 @@ public:
|
||||||
|
|
||||||
not_null<QAction*> addAction(base::unique_qptr<Menu::ItemBase> widget);
|
not_null<QAction*> addAction(base::unique_qptr<Menu::ItemBase> widget);
|
||||||
not_null<QAction*> addAction(const QString &text, Fn<void()> callback, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr);
|
not_null<QAction*> addAction(const QString &text, Fn<void()> callback, const style::icon *icon = nullptr, const style::icon *iconOver = nullptr);
|
||||||
not_null<QAction*> addSeparator();
|
not_null<QAction*> addSeparator(
|
||||||
|
const style::MenuSeparator *st = nullptr);
|
||||||
void clearActions();
|
void clearActions();
|
||||||
|
|
||||||
void setHiddenCallback(Fn<void()> callback) {
|
void setHiddenCallback(Fn<void()> callback) {
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
#include "ui/widgets/menu/menu_item_base.h"
|
#include "ui/widgets/menu/menu_item_base.h"
|
||||||
#include "ui/widgets/menu/menu_separator.h"
|
#include "ui/widgets/menu/menu_separator.h"
|
||||||
#include "ui/widgets/scroll_area.h"
|
#include "ui/widgets/scroll_area.h"
|
||||||
|
#include "styles/style_widgets.h"
|
||||||
|
|
||||||
#include <QtGui/QtEvents>
|
#include <QtGui/QtEvents>
|
||||||
|
|
||||||
|
|
@ -191,10 +192,14 @@ not_null<QAction*> Menu::addAction(base::unique_qptr<ItemBase> widget) {
|
||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
|
|
||||||
not_null<QAction*> Menu::addSeparator() {
|
not_null<QAction*> Menu::addSeparator(const style::MenuSeparator *st) {
|
||||||
const auto separator = new QAction(this);
|
const auto separator = new QAction(this);
|
||||||
separator->setSeparator(true);
|
separator->setSeparator(true);
|
||||||
auto item = base::make_unique_q<Separator>(this, _st, separator);
|
auto item = base::make_unique_q<Separator>(
|
||||||
|
this,
|
||||||
|
_st,
|
||||||
|
st ? *st : _st.separator,
|
||||||
|
separator);
|
||||||
return addAction(std::move(item));
|
return addAction(std::move(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@
|
||||||
#include "base/unique_qptr.h"
|
#include "base/unique_qptr.h"
|
||||||
#include "ui/rp_widget.h"
|
#include "ui/rp_widget.h"
|
||||||
#include "ui/widgets/menu/menu_common.h"
|
#include "ui/widgets/menu/menu_common.h"
|
||||||
#include "styles/style_widgets.h"
|
|
||||||
|
|
||||||
#include <QtWidgets/QMenu>
|
#include <QtWidgets/QMenu>
|
||||||
|
|
||||||
|
|
@ -17,6 +16,15 @@ namespace Ui {
|
||||||
struct ScrollToRequest;
|
struct ScrollToRequest;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
|
namespace style {
|
||||||
|
struct Menu;
|
||||||
|
struct MenuSeparator;
|
||||||
|
} // namespace style
|
||||||
|
|
||||||
|
namespace st {
|
||||||
|
extern const style::Menu &defaultMenu;
|
||||||
|
} // namespace st
|
||||||
|
|
||||||
namespace Ui::Menu {
|
namespace Ui::Menu {
|
||||||
|
|
||||||
class ItemBase;
|
class ItemBase;
|
||||||
|
|
@ -43,7 +51,8 @@ public:
|
||||||
std::unique_ptr<QMenu> submenu,
|
std::unique_ptr<QMenu> submenu,
|
||||||
const style::icon *icon = nullptr,
|
const style::icon *icon = nullptr,
|
||||||
const style::icon *iconOver = nullptr);
|
const style::icon *iconOver = nullptr);
|
||||||
not_null<QAction*> addSeparator();
|
not_null<QAction*> addSeparator(
|
||||||
|
const style::MenuSeparator *st = nullptr);
|
||||||
void clearActions();
|
void clearActions();
|
||||||
void finishAnimating();
|
void finishAnimating();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,17 +7,19 @@
|
||||||
#include "ui/widgets/menu/menu_separator.h"
|
#include "ui/widgets/menu/menu_separator.h"
|
||||||
|
|
||||||
#include "ui/painter.h"
|
#include "ui/painter.h"
|
||||||
|
#include "styles/style_widgets.h"
|
||||||
|
|
||||||
namespace Ui::Menu {
|
namespace Ui::Menu {
|
||||||
|
|
||||||
Separator::Separator(
|
Separator::Separator(
|
||||||
not_null<RpWidget*> parent,
|
not_null<RpWidget*> parent,
|
||||||
const style::Menu &st,
|
const style::Menu &st,
|
||||||
|
const style::MenuSeparator &separator,
|
||||||
not_null<QAction*> action)
|
not_null<QAction*> action)
|
||||||
: ItemBase(parent, st)
|
: ItemBase(parent, st)
|
||||||
, _lineWidth(st.separatorWidth)
|
, _lineWidth(separator.width)
|
||||||
, _padding(st.separatorPadding)
|
, _padding(separator.padding)
|
||||||
, _fg(st.separatorFg)
|
, _fg(separator.fg)
|
||||||
, _bg(st.itemBg)
|
, _bg(st.itemBg)
|
||||||
, _height(_padding.top() + _lineWidth + _padding.bottom())
|
, _height(_padding.top() + _lineWidth + _padding.bottom())
|
||||||
, _action(action) {
|
, _action(action) {
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,14 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "ui/widgets/menu/menu_item_base.h"
|
#include "ui/widgets/menu/menu_item_base.h"
|
||||||
#include "styles/style_widgets.h"
|
|
||||||
|
|
||||||
class Painter;
|
class Painter;
|
||||||
|
|
||||||
|
namespace style {
|
||||||
|
struct Menu;
|
||||||
|
struct MenuSeparator;
|
||||||
|
} // namespace style
|
||||||
|
|
||||||
namespace Ui::Menu {
|
namespace Ui::Menu {
|
||||||
|
|
||||||
class Separator : public ItemBase {
|
class Separator : public ItemBase {
|
||||||
|
|
@ -18,6 +22,7 @@ public:
|
||||||
Separator(
|
Separator(
|
||||||
not_null<RpWidget*> parent,
|
not_null<RpWidget*> parent,
|
||||||
const style::Menu &st,
|
const style::Menu &st,
|
||||||
|
const style::MenuSeparator &separator,
|
||||||
not_null<QAction*> action);
|
not_null<QAction*> action);
|
||||||
|
|
||||||
not_null<QAction*> action() const override;
|
not_null<QAction*> action() const override;
|
||||||
|
|
|
||||||
|
|
@ -248,8 +248,6 @@ void PopupMenu::init() {
|
||||||
_menu->setMousePressDelegate([this](QPoint globalPosition) { handleMousePress(globalPosition); });
|
_menu->setMousePressDelegate([this](QPoint globalPosition) { handleMousePress(globalPosition); });
|
||||||
_menu->setMouseReleaseDelegate([this](QPoint globalPosition) { handleMouseRelease(globalPosition); });
|
_menu->setMouseReleaseDelegate([this](QPoint globalPosition) { handleMouseRelease(globalPosition); });
|
||||||
|
|
||||||
handleCompositingUpdate();
|
|
||||||
|
|
||||||
setWindowFlags(Qt::WindowFlags(Qt::FramelessWindowHint) | Qt::BypassWindowManagerHint | Qt::Popup | Qt::NoDropShadowWindowHint);
|
setWindowFlags(Qt::WindowFlags(Qt::FramelessWindowHint) | Qt::BypassWindowManagerHint | Qt::Popup | Qt::NoDropShadowWindowHint);
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
|
|
||||||
|
|
@ -297,16 +295,26 @@ void PopupMenu::checkSubmenuShow() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopupMenu::handleCompositingUpdate() {
|
void PopupMenu::validateCompositingSupport() {
|
||||||
const auto line = st::lineWidth;
|
const auto line = st::lineWidth;
|
||||||
_padding = _useTransparency
|
_useTransparency = Platform::TranslucentWindowsSupported();
|
||||||
? _st.shadow.extend
|
if (!_useTransparency) {
|
||||||
: style::margins(line, line, line, line);
|
_padding = QMargins(line, line, line, line);
|
||||||
|
_extents = QMargins();
|
||||||
|
} else {
|
||||||
|
const auto &additional = _additionalMenuPadding;
|
||||||
|
_padding = QMargins(
|
||||||
|
std::max(_st.shadow.extend.left(), additional.left()),
|
||||||
|
std::max(_st.shadow.extend.top(), additional.top()),
|
||||||
|
std::max(_st.shadow.extend.right(), additional.right()),
|
||||||
|
std::max(_st.shadow.extend.bottom(), additional.bottom()));
|
||||||
|
_extents = _padding - (additional - _additionalMenuExtents);
|
||||||
|
}
|
||||||
if (windowHandle()) {
|
if (windowHandle()) {
|
||||||
if (_useTransparency) {
|
if (_extents.isNull()) {
|
||||||
Platform::SetWindowExtents(this, _padding);
|
|
||||||
} else {
|
|
||||||
Platform::UnsetWindowExtents(this);
|
Platform::UnsetWindowExtents(this);
|
||||||
|
} else {
|
||||||
|
Platform::SetWindowExtents(this, _extents);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_scroll->moveToLeft(_padding.left(), _padding.top());
|
_scroll->moveToLeft(_padding.left(), _padding.top());
|
||||||
|
|
@ -395,8 +403,8 @@ not_null<QAction*> PopupMenu::addAction(
|
||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
|
|
||||||
not_null<QAction*> PopupMenu::addSeparator() {
|
not_null<QAction*> PopupMenu::addSeparator(const style::MenuSeparator *st) {
|
||||||
return _menu->addSeparator();
|
return _menu->addSeparator(st);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopupMenu::clearActions() {
|
void PopupMenu::clearActions() {
|
||||||
|
|
@ -404,6 +412,10 @@ void PopupMenu::clearActions() {
|
||||||
return _menu->clearActions();
|
return _menu->clearActions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PopupMenu::setForceWidth(int forceWidth) {
|
||||||
|
_menu->setForceWidth(forceWidth);
|
||||||
|
}
|
||||||
|
|
||||||
const std::vector<not_null<QAction*>> &PopupMenu::actions() const {
|
const std::vector<not_null<QAction*>> &PopupMenu::actions() const {
|
||||||
return _menu->actions();
|
return _menu->actions();
|
||||||
}
|
}
|
||||||
|
|
@ -488,10 +500,14 @@ void PopupMenu::popupSubmenu(
|
||||||
currentSubmenu->hideMenu(true);
|
currentSubmenu->hideMenu(true);
|
||||||
}
|
}
|
||||||
if (submenu) {
|
if (submenu) {
|
||||||
QPoint p(_inner.x() + (style::RightToLeft() ? _padding.right() : _inner.width() - _padding.left()), _inner.y() + actionTop);
|
QPoint p(_inner.x() + (style::RightToLeft() ? _padding.right() : (_inner.width() - _padding.left())), _inner.y() + actionTop);
|
||||||
_activeSubmenu = submenu;
|
_activeSubmenu = submenu;
|
||||||
_activeSubmenu->showMenu(geometry().topLeft() + p, this, source);
|
if (_activeSubmenu->prepareGeometryFor(geometry().topLeft() + p, this)) {
|
||||||
_menu->setChildShownAction(action);
|
_activeSubmenu->showPrepared(source);
|
||||||
|
_menu->setChildShownAction(action);
|
||||||
|
} else {
|
||||||
|
_activeSubmenu = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -616,6 +632,22 @@ void PopupMenu::setForcedVerticalOrigin(VerticalOrigin origin) {
|
||||||
_forcedVerticalOrigin = origin;
|
_forcedVerticalOrigin = origin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PopupMenu::setAdditionalMenuPadding(
|
||||||
|
QMargins padding,
|
||||||
|
QMargins extents) {
|
||||||
|
Expects(padding.left() >= extents.left()
|
||||||
|
&& padding.right() >= extents.right()
|
||||||
|
&& padding.top() >= extents.top()
|
||||||
|
&& padding.bottom() >= extents.bottom());
|
||||||
|
|
||||||
|
if (_additionalMenuPadding != padding
|
||||||
|
|| _additionalMenuExtents != extents) {
|
||||||
|
_additionalMenuPadding = padding;
|
||||||
|
_additionalMenuExtents = extents;
|
||||||
|
_roundingOverlay = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PopupMenu::showAnimated(PanelAnimation::Origin origin) {
|
void PopupMenu::showAnimated(PanelAnimation::Origin origin) {
|
||||||
setOrigin(origin);
|
setOrigin(origin);
|
||||||
showStarted();
|
showStarted();
|
||||||
|
|
@ -759,23 +791,54 @@ void PopupMenu::deleteOnHide(bool del) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopupMenu::popup(const QPoint &p) {
|
void PopupMenu::popup(const QPoint &p) {
|
||||||
showMenu(p, nullptr, TriggeredSource::Mouse);
|
if (prepareGeometryFor(p)) {
|
||||||
|
popupPrepared();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_hiding = false;
|
||||||
|
_a_opacity.stop();
|
||||||
|
_a_show.stop();
|
||||||
|
_cache = QPixmap();
|
||||||
|
hide();
|
||||||
|
if (_deleteOnHide) {
|
||||||
|
deleteLater();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopupMenu::showMenu(const QPoint &p, PopupMenu *parent, TriggeredSource source) {
|
void PopupMenu::popupPrepared() {
|
||||||
|
showPrepared(TriggeredSource::Mouse);
|
||||||
|
}
|
||||||
|
|
||||||
|
PanelAnimation::Origin PopupMenu::preparedOrigin() const {
|
||||||
|
return _origin;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMargins PopupMenu::preparedPadding() const {
|
||||||
|
return _padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMargins PopupMenu::preparedExtents() const {
|
||||||
|
return _extents;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PopupMenu::useTransparency() const {
|
||||||
|
return _useTransparency;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PopupMenu::prepareGeometryFor(const QPoint &p) {
|
||||||
|
return prepareGeometryFor(p, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PopupMenu::prepareGeometryFor(const QPoint &p, PopupMenu *parent) {
|
||||||
const auto usingScreenGeometry = !::Platform::IsWayland();
|
const auto usingScreenGeometry = !::Platform::IsWayland();
|
||||||
const auto screen = usingScreenGeometry ? QGuiApplication::screenAt(p) : nullptr;
|
const auto screen = usingScreenGeometry
|
||||||
|
? QGuiApplication::screenAt(p)
|
||||||
|
: nullptr;
|
||||||
if ((usingScreenGeometry && !screen)
|
if ((usingScreenGeometry && !screen)
|
||||||
|| (!parent && ::Platform::IsMac() && !Platform::IsApplicationActive())) {
|
|| (!parent
|
||||||
_hiding = false;
|
&& ::Platform::IsMac()
|
||||||
_a_opacity.stop();
|
&& !Platform::IsApplicationActive())) {
|
||||||
_a_show.stop();
|
return false;
|
||||||
_cache = QPixmap();
|
|
||||||
hide();
|
|
||||||
if (_deleteOnHide) {
|
|
||||||
deleteLater();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
_parent = parent;
|
_parent = parent;
|
||||||
|
|
||||||
|
|
@ -785,6 +848,7 @@ void PopupMenu::showMenu(const QPoint &p, PopupMenu *parent, TriggeredSource sou
|
||||||
} else if (screen) {
|
} else if (screen) {
|
||||||
windowHandle()->setScreen(screen);
|
windowHandle()->setScreen(screen);
|
||||||
}
|
}
|
||||||
|
validateCompositingSupport();
|
||||||
|
|
||||||
using Origin = PanelAnimation::Origin;
|
using Origin = PanelAnimation::Origin;
|
||||||
auto origin = Origin::TopLeft;
|
auto origin = Origin::TopLeft;
|
||||||
|
|
@ -792,7 +856,7 @@ void PopupMenu::showMenu(const QPoint &p, PopupMenu *parent, TriggeredSource sou
|
||||||
&& (*_forcedOrigin == Origin::TopLeft
|
&& (*_forcedOrigin == Origin::TopLeft
|
||||||
|| *_forcedOrigin == Origin::BottomLeft);
|
|| *_forcedOrigin == Origin::BottomLeft);
|
||||||
const auto forceTop = (_forcedVerticalOrigin
|
const auto forceTop = (_forcedVerticalOrigin
|
||||||
&& (*_forcedVerticalOrigin == VerticalOrigin::Top))
|
&& (*_forcedVerticalOrigin == VerticalOrigin::Top))
|
||||||
|| (_forcedOrigin
|
|| (_forcedOrigin
|
||||||
&& (*_forcedOrigin == Origin::TopLeft
|
&& (*_forcedOrigin == Origin::TopLeft
|
||||||
|| *_forcedOrigin == Origin::TopRight));
|
|| *_forcedOrigin == Origin::TopRight));
|
||||||
|
|
@ -800,55 +864,74 @@ void PopupMenu::showMenu(const QPoint &p, PopupMenu *parent, TriggeredSource sou
|
||||||
&& (*_forcedOrigin == Origin::TopRight
|
&& (*_forcedOrigin == Origin::TopRight
|
||||||
|| *_forcedOrigin == Origin::BottomRight);
|
|| *_forcedOrigin == Origin::BottomRight);
|
||||||
const auto forceBottom = (_forcedVerticalOrigin
|
const auto forceBottom = (_forcedVerticalOrigin
|
||||||
&& (*_forcedVerticalOrigin == VerticalOrigin::Bottom))
|
&& (*_forcedVerticalOrigin == VerticalOrigin::Bottom))
|
||||||
|| (_forcedOrigin
|
|| (_forcedOrigin
|
||||||
&& (*_forcedOrigin == Origin::BottomLeft
|
&& (*_forcedOrigin == Origin::BottomLeft
|
||||||
|| *_forcedOrigin == Origin::BottomRight));
|
|| *_forcedOrigin == Origin::BottomRight));
|
||||||
auto w = p - QPoint(0, _padding.top());
|
auto w = p - QPoint(
|
||||||
|
std::max(
|
||||||
|
_additionalMenuPadding.left() - _st.shadow.extend.left(),
|
||||||
|
0),
|
||||||
|
_padding.top());
|
||||||
auto r = screen ? screen->availableGeometry() : QRect();
|
auto r = screen ? screen->availableGeometry() : QRect();
|
||||||
_useTransparency = Platform::TranslucentWindowsSupported(p);
|
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent, !_useTransparency);
|
|
||||||
handleCompositingUpdate();
|
|
||||||
if (style::RightToLeft()) {
|
if (style::RightToLeft()) {
|
||||||
const auto badLeft = !r.isNull() && w.x() - width() < r.x() - _padding.left();
|
const auto badLeft = !r.isNull() && w.x() - width() < r.x() - _extents.left();
|
||||||
if (forceRight || (badLeft && !forceLeft)) {
|
if (forceRight || (badLeft && !forceLeft)) {
|
||||||
if (_parent && (r.isNull() || w.x() + _parent->width() - _padding.left() - _padding.right() + width() - _padding.right() <= r.x() + r.width())) {
|
if (_parent && (r.isNull() || w.x() + _parent->width() - _extents.left() - _extents.right() + width() - _extents.right() <= r.x() + r.width())) {
|
||||||
w.setX(w.x() + _parent->width() - _padding.left() - _padding.right());
|
w.setX(w.x() + _parent->width() - _extents.left() - _extents.right());
|
||||||
} else {
|
} else {
|
||||||
w.setX(r.x() - _padding.left());
|
w.setX(r.x() - _extents.left());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
w.setX(w.x() - width());
|
w.setX(w.x() - width());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const auto badLeft = !r.isNull() && w.x() + width() - _padding.right() > r.x() + r.width();
|
const auto badLeft = !r.isNull() && w.x() + width() - _extents.right() > r.x() + r.width();
|
||||||
if (forceRight || (badLeft && !forceLeft)) {
|
if (forceRight || (badLeft && !forceLeft)) {
|
||||||
if (_parent && (r.isNull() || w.x() - _parent->width() + _padding.left() + _padding.right() - width() + _padding.right() >= r.x() - _padding.left())) {
|
if (_parent && (r.isNull() || w.x() - _parent->width() + _extents.left() + _extents.right() - width() + _extents.right() >= r.x() - _extents.left())) {
|
||||||
w.setX(w.x() + _padding.left() + _padding.right() - _parent->width() - width() + _padding.left() + _padding.right());
|
w.setX(w.x() + _extents.left() + _extents.right() - _parent->width() - width() + _extents.left() + _extents.right());
|
||||||
} else {
|
} else {
|
||||||
w.setX(p.x() - width() + _padding.right());
|
w.setX(p.x() - width() + std::max(
|
||||||
|
_additionalMenuPadding.right() - _st.shadow.extend.right(),
|
||||||
|
0));
|
||||||
}
|
}
|
||||||
origin = PanelAnimation::Origin::TopRight;
|
origin = PanelAnimation::Origin::TopRight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const auto badTop = !r.isNull() && w.y() + height() - _padding.bottom() > r.y() + r.height();
|
const auto badTop = !r.isNull() && w.y() + height() - _extents.bottom() > r.y() + r.height();
|
||||||
if (forceBottom || (badTop && !forceTop)) {
|
if (forceBottom || (badTop && !forceTop)) {
|
||||||
if (_parent) {
|
if (_parent) {
|
||||||
w.setY(r.y() + r.height() - height() + _padding.bottom());
|
w.setY(r.y() + r.height() - height() + _extents.bottom());
|
||||||
} else {
|
} else {
|
||||||
w.setY(p.y() - height() + _padding.bottom());
|
w.setY(p.y() - height() + _extents.bottom());
|
||||||
origin = (origin == PanelAnimation::Origin::TopRight) ? PanelAnimation::Origin::BottomRight : PanelAnimation::Origin::BottomLeft;
|
origin = (origin == PanelAnimation::Origin::TopRight)
|
||||||
|
? PanelAnimation::Origin::BottomRight
|
||||||
|
: PanelAnimation::Origin::BottomLeft;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!r.isNull() && w.x() < r.x()) {
|
if (!r.isNull()) {
|
||||||
w.setX(r.x());
|
if (w.x() + width() - _extents.right() > r.x() + r.width()) {
|
||||||
}
|
w.setX(r.x() + r.width() + _extents.right() - width());
|
||||||
if (!r.isNull() && w.y() < r.y()) {
|
}
|
||||||
w.setY(r.y());
|
if (w.x() + _extents.left() < r.x()) {
|
||||||
|
w.setX(r.x() - _extents.left());
|
||||||
|
}
|
||||||
|
if (w.y() + height() - _extents.bottom() > r.y() + r.height()) {
|
||||||
|
w.setY(r.y() + r.height() + _extents.bottom() - height());
|
||||||
|
}
|
||||||
|
if (w.y() + _extents.top() < r.y()) {
|
||||||
|
w.setY(r.y() - _extents.top());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
move(w);
|
move(w);
|
||||||
|
|
||||||
setOrigin(origin);
|
setOrigin(origin);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PopupMenu::showPrepared(TriggeredSource source) {
|
||||||
|
Expects(windowHandle() != nullptr);
|
||||||
|
|
||||||
_menu->setShowSource(source);
|
_menu->setShowSource(source);
|
||||||
|
|
||||||
startShowAnimation();
|
startShowAnimation();
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,10 @@
|
||||||
#include "base/object_ptr.h"
|
#include "base/object_ptr.h"
|
||||||
#include "base/unique_qptr.h"
|
#include "base/unique_qptr.h"
|
||||||
|
|
||||||
|
namespace style {
|
||||||
|
struct MenuSeparator;
|
||||||
|
} // namespace style
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|
||||||
class ScrollArea;
|
class ScrollArea;
|
||||||
|
|
@ -44,7 +48,8 @@ public:
|
||||||
std::unique_ptr<PopupMenu> submenu,
|
std::unique_ptr<PopupMenu> submenu,
|
||||||
const style::icon *icon = nullptr,
|
const style::icon *icon = nullptr,
|
||||||
const style::icon *iconOver = nullptr);
|
const style::icon *iconOver = nullptr);
|
||||||
not_null<QAction*> addSeparator();
|
not_null<QAction*> addSeparator(
|
||||||
|
const style::MenuSeparator *st = nullptr);
|
||||||
void clearActions();
|
void clearActions();
|
||||||
|
|
||||||
[[nodiscard]] const std::vector<not_null<QAction*>> &actions() const;
|
[[nodiscard]] const std::vector<not_null<QAction*>> &actions() const;
|
||||||
|
|
@ -57,9 +62,18 @@ public:
|
||||||
|
|
||||||
void deleteOnHide(bool del);
|
void deleteOnHide(bool del);
|
||||||
void popup(const QPoint &p);
|
void popup(const QPoint &p);
|
||||||
|
bool prepareGeometryFor(const QPoint &p);
|
||||||
|
void popupPrepared();
|
||||||
void hideMenu(bool fast = false);
|
void hideMenu(bool fast = false);
|
||||||
|
void setForceWidth(int forceWidth);
|
||||||
void setForcedOrigin(PanelAnimation::Origin origin);
|
void setForcedOrigin(PanelAnimation::Origin origin);
|
||||||
void setForcedVerticalOrigin(VerticalOrigin origin);
|
void setForcedVerticalOrigin(VerticalOrigin origin);
|
||||||
|
void setAdditionalMenuPadding(QMargins padding, QMargins extents);
|
||||||
|
|
||||||
|
[[nodiscard]] PanelAnimation::Origin preparedOrigin() const;
|
||||||
|
[[nodiscard]] QMargins preparedPadding() const;
|
||||||
|
[[nodiscard]] QMargins preparedExtents() const;
|
||||||
|
[[nodiscard]] bool useTransparency() const;
|
||||||
|
|
||||||
void setDestroyedCallback(Fn<void()> callback) {
|
void setDestroyedCallback(Fn<void()> callback) {
|
||||||
_destroyedCallback = std::move(callback);
|
_destroyedCallback = std::move(callback);
|
||||||
|
|
@ -104,7 +118,7 @@ private:
|
||||||
void showStarted();
|
void showStarted();
|
||||||
|
|
||||||
using TriggeredSource = Menu::TriggeredSource;
|
using TriggeredSource = Menu::TriggeredSource;
|
||||||
void handleCompositingUpdate();
|
void validateCompositingSupport();
|
||||||
void handleMenuResize();
|
void handleMenuResize();
|
||||||
void handleActivated(const Menu::CallbackData &data);
|
void handleActivated(const Menu::CallbackData &data);
|
||||||
void handleTriggered(const Menu::CallbackData &data);
|
void handleTriggered(const Menu::CallbackData &data);
|
||||||
|
|
@ -129,7 +143,8 @@ private:
|
||||||
not_null<PopupMenu*> submenu,
|
not_null<PopupMenu*> submenu,
|
||||||
int actionTop,
|
int actionTop,
|
||||||
TriggeredSource source);
|
TriggeredSource source);
|
||||||
void showMenu(const QPoint &p, PopupMenu *parent, TriggeredSource source);
|
bool prepareGeometryFor(const QPoint &p, PopupMenu *parent);
|
||||||
|
void showPrepared(TriggeredSource source);
|
||||||
void updateRoundingOverlay();
|
void updateRoundingOverlay();
|
||||||
|
|
||||||
const style::PopupMenu &_st;
|
const style::PopupMenu &_st;
|
||||||
|
|
@ -146,7 +161,10 @@ private:
|
||||||
PopupMenu *_parent = nullptr;
|
PopupMenu *_parent = nullptr;
|
||||||
|
|
||||||
QRect _inner;
|
QRect _inner;
|
||||||
style::margins _padding;
|
QMargins _padding;
|
||||||
|
QMargins _extents;
|
||||||
|
QMargins _additionalMenuPadding;
|
||||||
|
QMargins _additionalMenuExtents;
|
||||||
|
|
||||||
QPointer<PopupMenu> _activeSubmenu;
|
QPointer<PopupMenu> _activeSubmenu;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -526,7 +526,7 @@ void SeparatePanel::initGeometry(QSize size) {
|
||||||
if (center.y() - size.height() / 2 < available.y()) {
|
if (center.y() - size.height() / 2 < available.y()) {
|
||||||
center.setY(available.y() + size.height() / 2);
|
center.setY(available.y() + size.height() / 2);
|
||||||
}
|
}
|
||||||
_useTransparency = Ui::Platform::TranslucentWindowsSupported(center);
|
_useTransparency = Ui::Platform::TranslucentWindowsSupported();
|
||||||
_padding = _useTransparency
|
_padding = _useTransparency
|
||||||
? st::callShadow.extend
|
? st::callShadow.extend
|
||||||
: style::margins(
|
: style::margins(
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ void Tooltip::popup(const QPoint &m, const QString &text, const style::Tooltip *
|
||||||
_st = st;
|
_st = st;
|
||||||
_text = Text::String(_st->textStyle, text, kPlainTextOptions, _st->widthMax);
|
_text = Text::String(_st->textStyle, text, kPlainTextOptions, _st->widthMax);
|
||||||
|
|
||||||
_useTransparency = Platform::TranslucentWindowsSupported(_point);
|
_useTransparency = Platform::TranslucentWindowsSupported();
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent, !_useTransparency);
|
setAttribute(Qt::WA_OpaquePaintEvent, !_useTransparency);
|
||||||
|
|
||||||
int32 addw = 2 * st::lineWidth + _st->textPadding.left() + _st->textPadding.right();
|
int32 addw = 2 * st::lineWidth + _st->textPadding.left() + _st->textPadding.right();
|
||||||
|
|
|
||||||
|
|
@ -212,6 +212,12 @@ PanelAnimation {
|
||||||
shadow: Shadow;
|
shadow: Shadow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MenuSeparator {
|
||||||
|
padding: margins;
|
||||||
|
width: pixels;
|
||||||
|
fg: color;
|
||||||
|
}
|
||||||
|
|
||||||
Menu {
|
Menu {
|
||||||
skip: pixels;
|
skip: pixels;
|
||||||
|
|
||||||
|
|
@ -230,9 +236,7 @@ Menu {
|
||||||
itemToggleOver: Toggle;
|
itemToggleOver: Toggle;
|
||||||
itemToggleShift: pixels;
|
itemToggleShift: pixels;
|
||||||
|
|
||||||
separatorPadding: margins;
|
separator: MenuSeparator;
|
||||||
separatorWidth: pixels;
|
|
||||||
separatorFg: color;
|
|
||||||
|
|
||||||
arrow: icon;
|
arrow: icon;
|
||||||
|
|
||||||
|
|
@ -846,6 +850,11 @@ defaultMenuToggle: Toggle(defaultToggle) {
|
||||||
defaultMenuToggleOver: Toggle(defaultToggle) {
|
defaultMenuToggleOver: Toggle(defaultToggle) {
|
||||||
untoggledFg: menuIconFgOver;
|
untoggledFg: menuIconFgOver;
|
||||||
}
|
}
|
||||||
|
defaultMenuSeparator: MenuSeparator {
|
||||||
|
padding: margins(0px, 5px, 0px, 5px);
|
||||||
|
width: 1px;
|
||||||
|
fg: menuSeparatorFg;
|
||||||
|
}
|
||||||
defaultMenu: Menu {
|
defaultMenu: Menu {
|
||||||
skip: 0px;
|
skip: 0px;
|
||||||
|
|
||||||
|
|
@ -864,9 +873,7 @@ defaultMenu: Menu {
|
||||||
itemToggleOver: defaultMenuToggleOver;
|
itemToggleOver: defaultMenuToggleOver;
|
||||||
itemToggleShift: 0px;
|
itemToggleShift: 0px;
|
||||||
|
|
||||||
separatorPadding: margins(0px, 5px, 0px, 5px);
|
separator: defaultMenuSeparator;
|
||||||
separatorWidth: 1px;
|
|
||||||
separatorFg: menuSeparatorFg;
|
|
||||||
|
|
||||||
arrow: defaultMenuArrow;
|
arrow: defaultMenuArrow;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue