Allow custom context menus on labels.
This commit is contained in:
parent
e6064719df
commit
0937ac0ad0
2 changed files with 57 additions and 28 deletions
|
|
@ -403,6 +403,10 @@ void FlatLabel::overrideLinkClickHandler(Fn<void(QString url)> handler) {
|
|||
});
|
||||
}
|
||||
|
||||
void FlatLabel::setContextMenuHook(Fn<void(ContextMenuRequest)> hook) {
|
||||
_contextMenuHook = std::move(hook);
|
||||
}
|
||||
|
||||
void FlatLabel::mouseMoveEvent(QMouseEvent *e) {
|
||||
_lastMousePos = e->globalPos();
|
||||
dragActionUpdate();
|
||||
|
|
@ -579,7 +583,7 @@ void FlatLabel::keyPressEvent(QKeyEvent *e) {
|
|||
}
|
||||
|
||||
void FlatLabel::contextMenuEvent(QContextMenuEvent *e) {
|
||||
if (!_selectable && !_text.hasLinks()) {
|
||||
if (!_contextMenuHook && !_selectable && !_text.hasLinks()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -661,42 +665,27 @@ void FlatLabel::showContextMenu(QContextMenuEvent *e, ContextMenuReason reason)
|
|||
} else {
|
||||
_lastMousePos = QCursor::pos();
|
||||
}
|
||||
auto state = dragActionUpdate();
|
||||
|
||||
const auto state = dragActionUpdate();
|
||||
const auto hasSelection = _selectable && !_selection.empty();
|
||||
const auto uponSelection = _selectable
|
||||
&& ((reason == ContextMenuReason::FromTouch && hasSelection)
|
||||
|| (state.uponSymbol
|
||||
&& (state.symbol >= _selection.from)
|
||||
&& (state.symbol < _selection.to)));
|
||||
const auto fullSelection = _selectable
|
||||
&& _text.isFullSelection(_selection);
|
||||
|
||||
_contextMenu = base::make_unique_q<PopupMenu>(this, _stMenu);
|
||||
const auto request = ContextMenuRequest{
|
||||
.menu = _contextMenu.get(),
|
||||
.link = ClickHandler::getActive(),
|
||||
.hasSelection = hasSelection,
|
||||
.uponSelection = uponSelection,
|
||||
.fullSelection = _selectable && _text.isFullSelection(_selection),
|
||||
};
|
||||
|
||||
if (fullSelection && !_contextCopyText.isEmpty()) {
|
||||
_contextMenu->addAction(
|
||||
_contextCopyText,
|
||||
[=] { copyContextText(); });
|
||||
} else if (uponSelection && !fullSelection) {
|
||||
_contextMenu->addAction(
|
||||
Integration::Instance().phraseContextCopySelected(),
|
||||
[=] { copySelectedText(); });
|
||||
} else if (_selectable && !hasSelection && !_contextCopyText.isEmpty()) {
|
||||
_contextMenu->addAction(
|
||||
_contextCopyText,
|
||||
[=] { copyContextText(); });
|
||||
}
|
||||
|
||||
if (const auto link = ClickHandler::getActive()) {
|
||||
const auto actionText = link->copyToClipboardContextItemText();
|
||||
if (!actionText.isEmpty()) {
|
||||
_contextMenu->addAction(
|
||||
actionText,
|
||||
[text = link->copyToClipboardText()] {
|
||||
QGuiApplication::clipboard()->setText(text);
|
||||
});
|
||||
}
|
||||
if (_contextMenuHook) {
|
||||
_contextMenuHook(request);
|
||||
} else {
|
||||
fillContextMenu(request);
|
||||
}
|
||||
|
||||
if (_contextMenu->empty()) {
|
||||
|
|
@ -707,6 +696,35 @@ void FlatLabel::showContextMenu(QContextMenuEvent *e, ContextMenuReason reason)
|
|||
}
|
||||
}
|
||||
|
||||
void FlatLabel::fillContextMenu(ContextMenuRequest request) {
|
||||
if (request.fullSelection && !_contextCopyText.isEmpty()) {
|
||||
request.menu->addAction(
|
||||
_contextCopyText,
|
||||
[=] { copyContextText(); });
|
||||
} else if (request.uponSelection && !request.fullSelection) {
|
||||
request.menu->addAction(
|
||||
Integration::Instance().phraseContextCopySelected(),
|
||||
[=] { copySelectedText(); });
|
||||
} else if (_selectable
|
||||
&& !request.hasSelection
|
||||
&& !_contextCopyText.isEmpty()) {
|
||||
request.menu->addAction(
|
||||
_contextCopyText,
|
||||
[=] { copyContextText(); });
|
||||
}
|
||||
|
||||
if (request.link) {
|
||||
const auto label = request.link->copyToClipboardContextItemText();
|
||||
if (!label.isEmpty()) {
|
||||
request.menu->addAction(
|
||||
label,
|
||||
[text = request.link->copyToClipboardText()] {
|
||||
QGuiApplication::clipboard()->setText(text);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FlatLabel::copySelectedText() {
|
||||
const auto selection = _selection.empty() ? (_contextMenu ? _savedSelection : _selection) : _selection;
|
||||
if (!selection.empty()) {
|
||||
|
|
|
|||
|
|
@ -142,6 +142,15 @@ public:
|
|||
void overrideLinkClickHandler(Fn<void()> handler);
|
||||
void overrideLinkClickHandler(Fn<void(QString url)> handler);
|
||||
|
||||
struct ContextMenuRequest {
|
||||
not_null<PopupMenu*> menu;
|
||||
ClickHandlerPtr link;
|
||||
bool hasSelection = false;
|
||||
bool uponSelection = false;
|
||||
bool fullSelection = false;
|
||||
};
|
||||
void setContextMenuHook(Fn<void(ContextMenuRequest)> hook);
|
||||
|
||||
// ClickHandlerHost interface
|
||||
void clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) override;
|
||||
void clickHandlerPressedChanged(const ClickHandlerPtr &action, bool pressed) override;
|
||||
|
|
@ -201,6 +210,7 @@ private:
|
|||
FromTouch,
|
||||
};
|
||||
void showContextMenu(QContextMenuEvent *e, ContextMenuReason reason);
|
||||
void fillContextMenu(ContextMenuRequest request);
|
||||
|
||||
Text::String _text;
|
||||
const style::FlatLabel &_st;
|
||||
|
|
@ -237,6 +247,7 @@ private:
|
|||
base::Timer _trippleClickTimer;
|
||||
|
||||
base::unique_qptr<PopupMenu> _contextMenu;
|
||||
Fn<void(ContextMenuRequest)> _contextMenuHook;
|
||||
QString _contextCopyText;
|
||||
|
||||
ClickHandlerFilter _clickHandlerFilter;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue