Allow opening popup menu shifted to the cursor.

This commit is contained in:
John Preston 2023-02-03 19:31:57 +04:00
parent 30e7657859
commit 6c01a81900
6 changed files with 21 additions and 8 deletions

View file

@ -113,7 +113,8 @@ void Action::paint(Painter &p) {
p.setPen(selected ? _st.itemFgOver : (enabled ? _st.itemFg : _st.itemFgDisabled)); p.setPen(selected ? _st.itemFgOver : (enabled ? _st.itemFg : _st.itemFgDisabled));
paintText(p); paintText(p);
if (hasSubmenu()) { if (hasSubmenu()) {
const auto left = width() - _st.itemPadding.right() - _st.arrow.width(); const auto skip = _st.itemRightSkip;
const auto left = width() - skip - _st.arrow.width();
const auto top = (_height - _st.arrow.height()) / 2; const auto top = (_height - _st.arrow.height()) / 2;
if (enabled) { if (enabled) {
_st.arrow.paint(p, left, top, width()); _st.arrow.paint(p, left, top, width());
@ -159,14 +160,14 @@ void Action::processAction() {
const auto &padding = _st.itemPadding; const auto &padding = _st.itemPadding;
const auto additionalWidth = hasSubmenu() const auto additionalWidth = hasSubmenu()
? padding.right() + _st.arrow.width() ? (_st.itemRightSkip + _st.arrow.width())
: (!actionShortcut.isEmpty()) : (!actionShortcut.isEmpty())
? (padding.right() + _st.itemStyle.font->width(actionShortcut)) ? (_st.itemRightSkip + _st.itemStyle.font->width(actionShortcut))
: 0; : 0;
const auto goodWidth = padding.left() const auto goodWidth = padding.left()
+ textWidth + textWidth
+ padding.right() + additionalWidth
+ additionalWidth; + padding.right();
const auto w = std::clamp(goodWidth, _st.widthMin, _st.widthMax); const auto w = std::clamp(goodWidth, _st.widthMin, _st.widthMax);
_textWidth = w - (goodWidth - textWidth); _textWidth = w - (goodWidth - textWidth);

View file

@ -22,6 +22,7 @@ public:
Fn<void()> handler; Fn<void()> handler;
const style::icon *icon; const style::icon *icon;
Fn<void(not_null<Ui::PopupMenu*>)> fillSubmenu; Fn<void(not_null<Ui::PopupMenu*>)> fillSubmenu;
int addTopShift = 0;
bool isSeparator = false; bool isSeparator = false;
bool isAttention = false; bool isAttention = false;
}; };

View file

@ -15,8 +15,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Ui::Menu { namespace Ui::Menu {
MenuCallback CreateAddActionCallback(not_null<Ui::PopupMenu*> menu) { MenuCallback CreateAddActionCallback(not_null<Ui::PopupMenu*> menu) {
return MenuCallback([=](MenuCallback::Args a) { return MenuCallback([=](MenuCallback::Args a) -> QAction* {
if (a.fillSubmenu) { if (a.addTopShift) {
menu->setTopShift(a.addTopShift);
return nullptr;
} else if (a.fillSubmenu) {
const auto action = menu->addAction( const auto action = menu->addAction(
a.text, a.text,
std::move(a.handler), std::move(a.handler),

View file

@ -440,6 +440,10 @@ void PopupMenu::clearActions() {
return _menu->clearActions(); return _menu->clearActions();
} }
void PopupMenu::setTopShift(int topShift) {
_topShift = topShift;
}
void PopupMenu::setForceWidth(int forceWidth) { void PopupMenu::setForceWidth(int forceWidth) {
_menu->setForceWidth(forceWidth); _menu->setForceWidth(forceWidth);
} }
@ -993,7 +997,7 @@ bool PopupMenu::prepareGeometryFor(const QPoint &p, PopupMenu *parent) {
std::max( std::max(
_additionalMenuPadding.left() - _st.shadow.extend.left(), _additionalMenuPadding.left() - _st.shadow.extend.left(),
0), 0),
_padding.top()); _padding.top() - _topShift);
auto r = screen ? screen->availableGeometry() : QRect(); auto r = screen ? screen->availableGeometry() : QRect();
const auto parentWidth = _parent ? _parent->inner().width() : 0; const auto parentWidth = _parent ? _parent->inner().width() : 0;
if (style::RightToLeft()) { if (style::RightToLeft()) {

View file

@ -82,6 +82,7 @@ public:
bool prepareGeometryFor(const QPoint &p); bool prepareGeometryFor(const QPoint &p);
void popupPrepared(); void popupPrepared();
void hideMenu(bool fast = false); void hideMenu(bool fast = false);
void setTopShift(int topShift);
void setForceWidth(int forceWidth); void setForceWidth(int forceWidth);
void setForcedOrigin(PanelAnimation::Origin origin); void setForcedOrigin(PanelAnimation::Origin origin);
void setForcedVerticalOrigin(VerticalOrigin origin); void setForcedVerticalOrigin(VerticalOrigin origin);
@ -218,6 +219,7 @@ private:
bool _reactivateParent = true; bool _reactivateParent = true;
bool _grabbingForPanelAnimation = false; bool _grabbingForPanelAnimation = false;
int _topShift = 0;
bool _clearLastSeparator = true; bool _clearLastSeparator = true;
Fn<void()> _destroyedCallback; Fn<void()> _destroyedCallback;

View file

@ -230,6 +230,7 @@ Menu {
itemFgShortcutOver: color; itemFgShortcutOver: color;
itemFgShortcutDisabled: color; itemFgShortcutDisabled: color;
itemPadding: margins; itemPadding: margins;
itemRightSkip: pixels;
itemIconPosition: point; itemIconPosition: point;
itemStyle: TextStyle; itemStyle: TextStyle;
itemToggle: Toggle; itemToggle: Toggle;
@ -823,6 +824,7 @@ defaultMenu: Menu {
itemFgShortcutDisabled: menuFgDisabled; itemFgShortcutDisabled: menuFgDisabled;
itemIconPosition: point(0px, 0px); itemIconPosition: point(0px, 0px);
itemPadding: margins(17px, 8px, 17px, 7px); itemPadding: margins(17px, 8px, 17px, 7px);
itemRightSkip: 6px;
itemStyle: defaultTextStyle; itemStyle: defaultTextStyle;
itemToggle: defaultMenuToggle; itemToggle: defaultMenuToggle;
itemToggleOver: defaultMenuToggleOver; itemToggleOver: defaultMenuToggleOver;