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) {
|
void FlatLabel::mouseMoveEvent(QMouseEvent *e) {
|
||||||
_lastMousePos = e->globalPos();
|
_lastMousePos = e->globalPos();
|
||||||
dragActionUpdate();
|
dragActionUpdate();
|
||||||
|
|
@ -579,7 +583,7 @@ void FlatLabel::keyPressEvent(QKeyEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlatLabel::contextMenuEvent(QContextMenuEvent *e) {
|
void FlatLabel::contextMenuEvent(QContextMenuEvent *e) {
|
||||||
if (!_selectable && !_text.hasLinks()) {
|
if (!_contextMenuHook && !_selectable && !_text.hasLinks()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -661,42 +665,27 @@ void FlatLabel::showContextMenu(QContextMenuEvent *e, ContextMenuReason reason)
|
||||||
} else {
|
} else {
|
||||||
_lastMousePos = QCursor::pos();
|
_lastMousePos = QCursor::pos();
|
||||||
}
|
}
|
||||||
auto state = dragActionUpdate();
|
const auto state = dragActionUpdate();
|
||||||
|
|
||||||
const auto hasSelection = _selectable && !_selection.empty();
|
const auto hasSelection = _selectable && !_selection.empty();
|
||||||
const auto uponSelection = _selectable
|
const auto uponSelection = _selectable
|
||||||
&& ((reason == ContextMenuReason::FromTouch && hasSelection)
|
&& ((reason == ContextMenuReason::FromTouch && hasSelection)
|
||||||
|| (state.uponSymbol
|
|| (state.uponSymbol
|
||||||
&& (state.symbol >= _selection.from)
|
&& (state.symbol >= _selection.from)
|
||||||
&& (state.symbol < _selection.to)));
|
&& (state.symbol < _selection.to)));
|
||||||
const auto fullSelection = _selectable
|
|
||||||
&& _text.isFullSelection(_selection);
|
|
||||||
|
|
||||||
_contextMenu = base::make_unique_q<PopupMenu>(this, _stMenu);
|
_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()) {
|
if (_contextMenuHook) {
|
||||||
_contextMenu->addAction(
|
_contextMenuHook(request);
|
||||||
_contextCopyText,
|
} else {
|
||||||
[=] { copyContextText(); });
|
fillContextMenu(request);
|
||||||
} 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 (_contextMenu->empty()) {
|
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() {
|
void FlatLabel::copySelectedText() {
|
||||||
const auto selection = _selection.empty() ? (_contextMenu ? _savedSelection : _selection) : _selection;
|
const auto selection = _selection.empty() ? (_contextMenu ? _savedSelection : _selection) : _selection;
|
||||||
if (!selection.empty()) {
|
if (!selection.empty()) {
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,15 @@ public:
|
||||||
void overrideLinkClickHandler(Fn<void()> handler);
|
void overrideLinkClickHandler(Fn<void()> handler);
|
||||||
void overrideLinkClickHandler(Fn<void(QString url)> 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
|
// ClickHandlerHost interface
|
||||||
void clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) override;
|
void clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) override;
|
||||||
void clickHandlerPressedChanged(const ClickHandlerPtr &action, bool pressed) override;
|
void clickHandlerPressedChanged(const ClickHandlerPtr &action, bool pressed) override;
|
||||||
|
|
@ -201,6 +210,7 @@ private:
|
||||||
FromTouch,
|
FromTouch,
|
||||||
};
|
};
|
||||||
void showContextMenu(QContextMenuEvent *e, ContextMenuReason reason);
|
void showContextMenu(QContextMenuEvent *e, ContextMenuReason reason);
|
||||||
|
void fillContextMenu(ContextMenuRequest request);
|
||||||
|
|
||||||
Text::String _text;
|
Text::String _text;
|
||||||
const style::FlatLabel &_st;
|
const style::FlatLabel &_st;
|
||||||
|
|
@ -237,6 +247,7 @@ private:
|
||||||
base::Timer _trippleClickTimer;
|
base::Timer _trippleClickTimer;
|
||||||
|
|
||||||
base::unique_qptr<PopupMenu> _contextMenu;
|
base::unique_qptr<PopupMenu> _contextMenu;
|
||||||
|
Fn<void(ContextMenuRequest)> _contextMenuHook;
|
||||||
QString _contextCopyText;
|
QString _contextCopyText;
|
||||||
|
|
||||||
ClickHandlerFilter _clickHandlerFilter;
|
ClickHandlerFilter _clickHandlerFilter;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue