Skip to content

Commit

Permalink
Moved spelling context menu item to nearest place to mouse.
Browse files Browse the repository at this point in the history
  • Loading branch information
23rd committed Mar 13, 2020
1 parent 18c8f21 commit 25f44d9
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 5 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ PRIVATE
spellcheck/spellcheck_types.h
spellcheck/spelling_highlighter.cpp
spellcheck/spelling_highlighter.h
spellcheck/spelling_highlighter_helper.cpp
spellcheck/spelling_highlighter_helper.h
spellcheck/spellcheck_value.cpp
spellcheck/spellcheck_value.h
)
Expand Down
18 changes: 14 additions & 4 deletions spellcheck/spelling_highlighter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include "spellcheck/spellcheck_value.h"
#include "spellcheck/spellcheck_utils.h"
#include "spellcheck/spelling_highlighter_helper.h"
#include "styles/palette.h"
#include "ui/text/text_entity.h"
#include "ui/text/text_utilities.h"
Expand Down Expand Up @@ -623,7 +624,8 @@ bool SpellingHighlighter::eventFilter(QObject *o, QEvent *e) {
addSpellcheckerActions(
std::move(menu),
_textEdit->cursorForPosition(c->pos()),
std::move(showMenu));
std::move(showMenu),
c->globalPos());
return true;
} else if (e->type() == QEvent::KeyPress) {
const auto k = static_cast<QKeyEvent *>(e);
Expand Down Expand Up @@ -708,7 +710,8 @@ int SpellingHighlighter::compareDocumentText(
void SpellingHighlighter::addSpellcheckerActions(
not_null<QMenu*> parentMenu,
QTextCursor cursorForPosition,
Fn<void()> showMenuCallback) {
Fn<void()> showMenuCallback,
QPoint mousePosition) {

const auto customItem = !Platform::Spellchecker::IsSystemSpellchecker()
&& _customContextMenuItem.has_value();
Expand All @@ -729,8 +732,15 @@ void SpellingHighlighter::addSpellcheckerActions(

auto addToParentAndShow = [=] {
if (!menu->isEmpty()) {
parentMenu->addSeparator();
parentMenu->addMenu(menu);
using namespace Spelling::Helper;
if (IsContextMenuTop(parentMenu, mousePosition)) {
parentMenu->addSeparator();
parentMenu->addMenu(menu);
} else {
const auto first = parentMenu->actions().first();
parentMenu->insertMenu(first, menu);
parentMenu->insertSeparator(first);
}
}
showMenuCallback();
};
Expand Down
3 changes: 2 additions & 1 deletion spellcheck/spelling_highlighter.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ class SpellingHighlighter final : public QSyntaxHighlighter {
void addSpellcheckerActions(
not_null<QMenu*> parentMenu,
QTextCursor cursorForPosition,
Fn<void()> showMenuCallback);
Fn<void()> showMenuCallback,
QPoint mousePosition);

protected:
void highlightBlock(const QString &text) override;
Expand Down
61 changes: 61 additions & 0 deletions spellcheck/spelling_highlighter_helper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// This file is part of Desktop App Toolkit,
// a set of libraries for developing nice desktop applications.
//
// For license and copyright information please follow this link:
// https://github.com/desktop-app/legal/blob/master/LEGAL
//

#include "spellcheck/spelling_highlighter.h"

#include "styles/palette.h"
#include "styles/style_widgets.h"
#include "ui/platform/ui_platform_utility.h"

#include <QtWidgets/QApplication>
#include <QtWidgets/QDesktopWidget>

namespace Spelling::Helper {

namespace {

const auto kFormattingItem = 1;
const auto kSpellingItem = 1;

}

bool IsContextMenuTop(not_null<QMenu*> menu, QPoint mousePosition) {
const auto &st = st::defaultMenu;
const auto &stPopup = st::defaultPopupMenu;

const auto itemHeight = st.itemPadding.top()
+ st.itemStyle.font->height
+ st.itemPadding.bottom();
const auto sepHeight = st.separatorPadding.top()
+ st.separatorWidth
+ st.separatorPadding.bottom();

const auto line = st::lineWidth;
const auto p = Ui::Platform::TranslucentWindowsSupported(mousePosition)
? stPopup.shadow.extend
: style::margins(line, line, line, line);

const auto additional = kFormattingItem + kSpellingItem;
const auto actions = menu->actions() | ranges::to_vector;
auto sepCount = ranges::count_if(actions, &QAction::isSeparator);
auto itemsCount = actions.size() - sepCount;
sepCount += additional;
itemsCount += additional;

const auto w = mousePosition - QPoint(0, p.top());
const auto r = QApplication::desktop()->screenGeometry(mousePosition);
const auto height = itemHeight * itemsCount
+ sepHeight * sepCount
+ p.top()
+ stPopup.scrollPadding.top()
+ stPopup.scrollPadding.bottom()
+ p.bottom();

return (w.y() + height - p.bottom() > r.y() + r.height());
}

} // namespace Spelling::Helper
14 changes: 14 additions & 0 deletions spellcheck/spelling_highlighter_helper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// This file is part of Desktop App Toolkit,
// a set of libraries for developing nice desktop applications.
//
// For license and copyright information please follow this link:
// https://github.com/desktop-app/legal/blob/master/LEGAL
//

namespace Spelling::Helper {

[[nodiscard]] bool IsContextMenuTop(
not_null<QMenu*> menu,
QPoint mousePosition);

} // namespace Spelling::Helper

0 comments on commit 25f44d9

Please sign in to comment.