Support emoji in popup menu items.

This commit is contained in:
John Preston 2019-09-11 10:27:34 +03:00
parent 0c713a930a
commit b73390a3f6
4 changed files with 29 additions and 29 deletions

View File

@ -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;

View File

@ -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();

View File

@ -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;

View File

@ -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) {