mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-02-19 14:36:58 +00:00
Support emoji in popup menu items.
This commit is contained in:
parent
0c713a930a
commit
b73390a3f6
@ -9,14 +9,24 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
#include "ui/effects/ripple_animation.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/text/text.h"
|
||||
|
||||
namespace Ui {
|
||||
|
||||
Menu::ActionData::~ActionData() = default;
|
||||
struct Menu::ActionData {
|
||||
Ui::Text::String text;
|
||||
QString shortcut;
|
||||
const style::icon *icon = nullptr;
|
||||
const style::icon *iconOver = nullptr;
|
||||
std::unique_ptr<RippleAnimation> ripple;
|
||||
std::unique_ptr<ToggleView> toggle;
|
||||
int textWidth = 0;
|
||||
bool hasSubmenu = false;
|
||||
};
|
||||
|
||||
Menu::Menu(QWidget *parent, const style::Menu &st) : TWidget(parent)
|
||||
, _st(st)
|
||||
, _itemHeight(_st.itemPadding.top() + _st.itemFont->height + _st.itemPadding.bottom())
|
||||
, _itemHeight(_st.itemPadding.top() + _st.itemStyle.font->height + _st.itemPadding.bottom())
|
||||
, _separatorHeight(_st.separatorPadding.top() + _st.separatorWidth + _st.separatorPadding.bottom()) {
|
||||
init();
|
||||
}
|
||||
@ -24,7 +34,7 @@ Menu::Menu(QWidget *parent, const style::Menu &st) : TWidget(parent)
|
||||
Menu::Menu(QWidget *parent, QMenu *menu, const style::Menu &st) : TWidget(parent)
|
||||
, _st(st)
|
||||
, _wappedMenu(menu)
|
||||
, _itemHeight(_st.itemPadding.top() + _st.itemFont->height + _st.itemPadding.bottom())
|
||||
, _itemHeight(_st.itemPadding.top() + _st.itemStyle.font->height + _st.itemPadding.bottom())
|
||||
, _separatorHeight(_st.separatorPadding.top() + _st.separatorWidth + _st.separatorPadding.bottom()) {
|
||||
init();
|
||||
|
||||
@ -35,6 +45,8 @@ Menu::Menu(QWidget *parent, QMenu *menu, const style::Menu &st) : TWidget(parent
|
||||
_wappedMenu->hide();
|
||||
}
|
||||
|
||||
Menu::~Menu() = default;
|
||||
|
||||
void Menu::init() {
|
||||
resize(_forceWidth ? _forceWidth : _st.widthMin, _st.skip * 2);
|
||||
|
||||
@ -114,17 +126,19 @@ void Menu::finishAnimating() {
|
||||
int Menu::processAction(not_null<QAction*> action, int index, int width) {
|
||||
auto &data = _actionsData[index];
|
||||
if (action->isSeparator() || action->text().isEmpty()) {
|
||||
data.text = data.shortcut = QString();
|
||||
data.shortcut = QString();
|
||||
data.text.clear();
|
||||
} else {
|
||||
auto actionTextParts = action->text().split('\t');
|
||||
auto actionText = actionTextParts.empty() ? QString() : actionTextParts[0];
|
||||
auto actionShortcut = (actionTextParts.size() > 1) ? actionTextParts[1] : QString();
|
||||
int textw = _st.itemFont->width(actionText);
|
||||
data.text.setText(_st.itemStyle, actionText);
|
||||
const auto textw = data.text.maxWidth();
|
||||
int goodw = _st.itemPadding.left() + textw + _st.itemPadding.right();
|
||||
if (data.hasSubmenu) {
|
||||
goodw += _st.itemPadding.right() + _st.arrow.width();
|
||||
} else if (!actionShortcut.isEmpty()) {
|
||||
goodw += _st.itemPadding.right() + _st.itemFont->width(actionShortcut);
|
||||
goodw += _st.itemPadding.right() + _st.itemStyle.font->width(actionShortcut);
|
||||
}
|
||||
if (action->isCheckable()) {
|
||||
auto updateCallback = [this, index] { updateItem(index); };
|
||||
@ -138,8 +152,8 @@ int Menu::processAction(not_null<QAction*> action, int index, int width) {
|
||||
} else {
|
||||
data.toggle.reset();
|
||||
}
|
||||
width = snap(goodw, width, _st.widthMax);
|
||||
data.text = (width < goodw) ? _st.itemFont->elided(actionText, width - (goodw - textw)) : actionText;
|
||||
width = std::clamp(goodw, width, _st.widthMax);
|
||||
data.textWidth = width - (goodw - textw);
|
||||
data.shortcut = actionShortcut;
|
||||
}
|
||||
return width;
|
||||
@ -186,7 +200,7 @@ void Menu::paintEvent(QPaintEvent *e) {
|
||||
|
||||
int top = _st.skip;
|
||||
p.translate(0, top);
|
||||
p.setFont(_st.itemFont);
|
||||
p.setFont(_st.itemStyle.font);
|
||||
for (int i = 0, count = int(_actions.size()); i != count; ++i) {
|
||||
if (clip.top() + clip.height() <= top) break;
|
||||
|
||||
@ -212,7 +226,7 @@ void Menu::paintEvent(QPaintEvent *e) {
|
||||
icon->paint(p, _st.itemIconPosition, width());
|
||||
}
|
||||
p.setPen(selected ? _st.itemFgOver : (enabled ? _st.itemFg : _st.itemFgDisabled));
|
||||
p.drawTextLeft(_st.itemPadding.left(), _st.itemPadding.top(), width(), data.text);
|
||||
data.text.drawLeftElided(p, _st.itemPadding.left(), _st.itemPadding.top(), data.textWidth, width());
|
||||
if (data.hasSubmenu) {
|
||||
const auto left = width() - _st.itemPadding.right() - _st.arrow.width();
|
||||
const auto top = (_itemHeight - _st.arrow.height()) / 2;
|
||||
|
@ -22,6 +22,7 @@ class Menu : public TWidget {
|
||||
public:
|
||||
Menu(QWidget *parent, const style::Menu &st = st::defaultMenu);
|
||||
Menu(QWidget *parent, QMenu *menu, const style::Menu &st = st::defaultMenu);
|
||||
~Menu();
|
||||
|
||||
not_null<QAction*> addAction(const QString &text, const QObject *receiver, const char* member, 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);
|
||||
@ -87,22 +88,7 @@ private slots:
|
||||
void actionChanged();
|
||||
|
||||
private:
|
||||
struct ActionData {
|
||||
ActionData() = default;
|
||||
ActionData(const ActionData &other) = delete;
|
||||
ActionData &operator=(const ActionData &other) = delete;
|
||||
ActionData(ActionData &&other) = default;
|
||||
ActionData &operator=(ActionData &&other) = default;
|
||||
~ActionData();
|
||||
|
||||
bool hasSubmenu = false;
|
||||
QString text;
|
||||
QString shortcut;
|
||||
const style::icon *icon = nullptr;
|
||||
const style::icon *iconOver = nullptr;
|
||||
std::unique_ptr<RippleAnimation> ripple;
|
||||
std::unique_ptr<ToggleView> toggle;
|
||||
};
|
||||
struct ActionData;
|
||||
|
||||
void updateSelected(QPoint globalPosition);
|
||||
void init();
|
||||
|
@ -398,7 +398,7 @@ Menu {
|
||||
itemFgShortcutDisabled: color;
|
||||
itemPadding: margins;
|
||||
itemIconPosition: point;
|
||||
itemFont: font;
|
||||
itemStyle: TextStyle;
|
||||
itemToggle: Toggle;
|
||||
itemToggleOver: Toggle;
|
||||
itemToggleShift: pixels;
|
||||
@ -906,7 +906,7 @@ defaultMenu: Menu {
|
||||
itemFgShortcutDisabled: menuFgDisabled;
|
||||
itemIconPosition: point(0px, 0px);
|
||||
itemPadding: margins(17px, 8px, 17px, 7px);
|
||||
itemFont: normalFont;
|
||||
itemStyle: defaultTextStyle;
|
||||
itemToggle: defaultMenuToggle;
|
||||
itemToggleOver: defaultMenuToggleOver;
|
||||
itemToggleShift: 0px;
|
||||
|
@ -117,7 +117,7 @@ mainMenuSkip: 13px;
|
||||
mainMenu: Menu(defaultMenu) {
|
||||
itemFg: windowBoldFg;
|
||||
itemFgOver: windowBoldFgOver;
|
||||
itemFont: semiboldFont;
|
||||
itemStyle: semiboldTextStyle;
|
||||
itemIconPosition: point(26px, 8px);
|
||||
itemPadding: margins(76px, 13px, 28px, 13px);
|
||||
itemToggle: Toggle(defaultMenuToggle) {
|
||||
|
Loading…
Reference in New Issue
Block a user