consolidate features and add context menu to edge

This commit is contained in:
Akash Mozumdar 2021-11-28 04:41:42 -07:00
parent 5df90e2c01
commit 45279d26dc
3 changed files with 119 additions and 203 deletions

View File

@ -17,20 +17,16 @@
#include <QAbstractNativeEventFilter> #include <QAbstractNativeEventFilter>
extern const char* EXTRA_WINDOW_INFO; extern const char* EXTRA_WINDOW_INFO;
extern const char* SENTENCE_TOO_BIG;
extern const char* MAX_SENTENCE_SIZE;
extern const char* TOPMOST; extern const char* TOPMOST;
extern const char* OPACITY; extern const char* OPACITY;
extern const char* SHOW_ORIGINAL; extern const char* SHOW_ORIGINAL;
extern const char* SHOW_ORIGINAL_INFO; extern const char* ORIGINAL_AFTER_TRANSLATION;
extern const char* SHOW_ORIGINAL_AFTER_TRANSLATION;
extern const char* SIZE_LOCK; extern const char* SIZE_LOCK;
extern const char* POSITION_LOCK; extern const char* POSITION_LOCK;
extern const char* CENTERED_TEXT; extern const char* CENTERED_TEXT;
extern const char* AUTO_RESIZE_WINDOW_HEIGHT; extern const char* AUTO_RESIZE_WINDOW_HEIGHT;
extern const char* CLICK_THROUGH; extern const char* CLICK_THROUGH;
extern const char* HIDE_TEXT_MOUSEOVER; extern const char* HIDE_MOUSEOVER;
extern const char* HIDE_TEXT;
extern const char* DICTIONARY; extern const char* DICTIONARY;
extern const char* DICTIONARY_INSTRUCTIONS; extern const char* DICTIONARY_INSTRUCTIONS;
extern const char* BG_COLOR; extern const char* BG_COLOR;
@ -38,15 +34,11 @@ extern const char* TEXT_COLOR;
extern const char* TEXT_OUTLINE; extern const char* TEXT_OUTLINE;
extern const char* OUTLINE_COLOR; extern const char* OUTLINE_COLOR;
extern const char* OUTLINE_SIZE; extern const char* OUTLINE_SIZE;
extern const char* OUTLINE_LAST_SIZE;
extern const char* OUTLINE_SIZE_INFO; extern const char* OUTLINE_SIZE_INFO;
extern const char* FONT; extern const char* FONT;
extern const char* SAVE_SETTINGS;
constexpr auto DICTIONARY_SAVE_FILE = u8"SavedDictionary.txt"; constexpr auto DICTIONARY_SAVE_FILE = u8"SavedDictionary.txt";
const qreal COLOR_ALFAF_HIDE_WINDOW = 0.05;
constexpr int CLICK_THROUGH_HOTKEY = 0xc0d0; constexpr int CLICK_THROUGH_HOTKEY = 0xc0d0;
constexpr int HIDE_TEXT_HOTKEY = 0xc0d1;
QColor colorPrompt(QWidget* parent, QColor default, const QString& title, bool customOpacity = true) QColor colorPrompt(QWidget* parent, QColor default, const QString& title, bool customOpacity = true)
{ {
@ -57,9 +49,6 @@ QColor colorPrompt(QWidget* parent, QColor default, const QString& title, bool c
struct PrettyWindow : QDialog, Localizer struct PrettyWindow : QDialog, Localizer
{ {
QString savedSentence = "";
bool hideTextMouseover=false, hideText=false;
PrettyWindow(const char* name) PrettyWindow(const char* name)
{ {
ui.setupUi(this); ui.setupUi(this);
@ -74,13 +63,19 @@ struct PrettyWindow : QDialog, Localizer
SetTextColor(settings.value(TEXT_COLOR, TextColor()).value<QColor>()); SetTextColor(settings.value(TEXT_COLOR, TextColor()).value<QColor>());
outliner->color = settings.value(OUTLINE_COLOR, outliner->color).value<QColor>(); outliner->color = settings.value(OUTLINE_COLOR, outliner->color).value<QColor>();
outliner->size = settings.value(OUTLINE_SIZE, outliner->size).toDouble(); outliner->size = settings.value(OUTLINE_SIZE, outliner->size).toDouble();
autoHide = settings.value(HIDE_MOUSEOVER, autoHide).toBool();
menu.addAction(FONT, this, &PrettyWindow::RequestFont); menu.addAction(FONT, this, &PrettyWindow::RequestFont);
menu.addAction(BG_COLOR, [this] { SetBackgroundColor(colorPrompt(this, backgroundColor, BG_COLOR)); }); menu.addAction(BG_COLOR, [this] { SetBackgroundColor(colorPrompt(this, backgroundColor, BG_COLOR)); });
menu.addAction(TEXT_COLOR, [this] { SetTextColor(colorPrompt(this, TextColor(), TEXT_COLOR)); }); menu.addAction(TEXT_COLOR, [this] { SetTextColor(colorPrompt(this, TextColor(), TEXT_COLOR)); });
QAction* outlineAction = menu.addAction(TEXT_OUTLINE, this, &PrettyWindow::SetOutline); QAction* outlineAction = menu.addAction(TEXT_OUTLINE, this, &PrettyWindow::SetOutline);
outlineAction->setCheckable(true); outlineAction->setCheckable(true);
outlineAction->setChecked(outliner->size >= 0); outlineAction->setChecked(outliner->size >= 0);
connect(ui.display, &QLabel::customContextMenuRequested, [this](QPoint point) { menu.exec(mapToGlobal(point)); }); QAction* autoHideAction = menu.addAction(HIDE_MOUSEOVER, this, [this](bool autoHide) { settings.setValue(HIDE_MOUSEOVER, this->autoHide = autoHide); });
autoHideAction->setCheckable(true);
autoHideAction->setChecked(autoHide);
connect(this, &QDialog::customContextMenuRequested, [this](QPoint point) { menu.exec(mapToGlobal(point)); });
connect(ui.display, &QLabel::customContextMenuRequested, [this](QPoint point) { menu.exec(ui.display->mapToGlobal(point)); });
startTimer(50);
} }
~PrettyWindow() ~PrettyWindow()
@ -90,30 +85,27 @@ struct PrettyWindow : QDialog, Localizer
Ui::ExtraWindow ui; Ui::ExtraWindow ui;
void SetBackgroundColorHideText()
{
if (hideText)
{
QColor color = settings.value(BG_COLOR, backgroundColor).value<QColor>();
if (!color.isValid()) return;
color.setAlphaF(COLOR_ALFAF_HIDE_WINDOW);
backgroundColor = color;
repaint();
ui.display->setText("");
}
else
{
QColor color = settings.value(BG_COLOR, backgroundColor).value<QColor>();
if (!color.isValid()) return;
if (color.alpha() == 0) color.setAlpha(1);
backgroundColor = color;
repaint();
ui.display->setText(savedSentence);
}
}
protected: protected:
void timerEvent(QTimerEvent*) override
{
if (autoHide && !hidden && geometry().contains(QCursor::pos()))
{
if (backgroundColor.alphaF() > 0.05) backgroundColor.setAlphaF(0.05);
if (outliner->color.alphaF() > 0.05) outliner->color.setAlphaF(0.05);
QColor hiddenTextColor = TextColor();
if (hiddenTextColor.alphaF() > 0.05) hiddenTextColor.setAlphaF(0.05);
ui.display->setPalette(QPalette(hiddenTextColor, {}, {}, {}, {}, {}, {}));
hidden = true;
}
else if (hidden)
{
backgroundColor.setAlpha(settings.value(BG_COLOR).value<QColor>().alpha());
outliner->color.setAlpha(settings.value(OUTLINE_COLOR).value<QColor>().alpha());
ui.display->setPalette(QPalette(settings.value(TEXT_COLOR).value<QColor>(), {}, {}, {}, {}, {}, {}));
hidden = false;
}
}
QMenu menu{ ui.display }; QMenu menu{ ui.display };
Settings settings{ this }; Settings settings{ this };
@ -157,13 +149,9 @@ private:
{ {
QColor color = colorPrompt(this, outliner->color, OUTLINE_COLOR); QColor color = colorPrompt(this, outliner->color, OUTLINE_COLOR);
if (color.isValid()) outliner->color = color; if (color.isValid()) outliner->color = color;
outliner->size = QInputDialog::getDouble(this, OUTLINE_SIZE, OUTLINE_SIZE_INFO, settings.value(OUTLINE_LAST_SIZE, outliner->size).toDouble(), 0, INT_MAX, 2, nullptr, Qt::WindowCloseButtonHint); outliner->size = QInputDialog::getDouble(this, OUTLINE_SIZE, OUTLINE_SIZE_INFO, -outliner->size, 0, INT_MAX, 2, nullptr, Qt::WindowCloseButtonHint);
}
else
{
settings.setValue(OUTLINE_LAST_SIZE, outliner->size);
outliner->size = -1;
} }
else outliner->size = -outliner->size;
settings.setValue(OUTLINE_COLOR, outliner->color.name(QColor::HexArgb)); settings.setValue(OUTLINE_COLOR, outliner->color.name(QColor::HexArgb));
settings.setValue(OUTLINE_SIZE, outliner->size); settings.setValue(OUTLINE_SIZE, outliner->size);
} }
@ -173,6 +161,7 @@ private:
QPainter(this).fillRect(rect(), backgroundColor); QPainter(this).fillRect(rect(), backgroundColor);
} }
bool autoHide = false, hidden = false;
QColor backgroundColor{ palette().window().color() }; QColor backgroundColor{ palette().window().color() };
struct Outliner : QGraphicsEffect struct Outliner : QGraphicsEffect
{ {
@ -193,29 +182,8 @@ private:
painter->drawPixmap(offset, pixmap); painter->drawPixmap(offset, pixmap);
} }
QColor color{ Qt::black }; QColor color{ Qt::black };
double size = -1; double size = -0.5;
}* outliner; }* outliner;
void enterEvent(QEvent* event)
{
if (hideTextMouseover)
{
hideText = true;
SetBackgroundColorHideText();
}
QWidget::enterEvent(event);
}
void leaveEvent(QEvent* event)
{
if (hideTextMouseover)
{
hideText = false;
SetBackgroundColorHideText();
}
QWidget::leaveEvent(event);
}
}; };
class ExtraWindow : public PrettyWindow, QAbstractNativeEventFilter class ExtraWindow : public PrettyWindow, QAbstractNativeEventFilter
@ -225,18 +193,15 @@ public:
{ {
ui.display->setTextFormat(Qt::PlainText); ui.display->setTextFormat(Qt::PlainText);
if (settings.contains(WINDOW) && QApplication::screenAt(settings.value(WINDOW).toRect().bottomRight())) setGeometry(settings.value(WINDOW).toRect()); if (settings.contains(WINDOW) && QApplication::screenAt(settings.value(WINDOW).toRect().bottomRight())) setGeometry(settings.value(WINDOW).toRect());
maxSentenceSize = settings.value(MAX_SENTENCE_SIZE, maxSentenceSize).toInt();
for (auto [name, default, slot] : Array<const char*, bool, void(ExtraWindow::*)(bool)>{ for (auto [name, default, slot] : Array<const char*, bool, void(ExtraWindow::*)(bool)>{
{ TOPMOST, false, &ExtraWindow::SetTopmost }, { TOPMOST, false, &ExtraWindow::SetTopmost },
{ SIZE_LOCK, false, &ExtraWindow::SetLock }, { SIZE_LOCK, false, &ExtraWindow::SetSizeLock },
{ POSITION_LOCK, false, &ExtraWindow::SetPositionLock }, { POSITION_LOCK, false, &ExtraWindow::SetPositionLock },
{ CENTERED_TEXT, false, &ExtraWindow::SetCenteredText }, { CENTERED_TEXT, false, &ExtraWindow::SetCenteredText },
{ AUTO_RESIZE_WINDOW_HEIGHT, false, &ExtraWindow::SetAutoResizeHeight }, { AUTO_RESIZE_WINDOW_HEIGHT, false, &ExtraWindow::SetAutoResize },
{ HIDE_TEXT, false, &ExtraWindow::SetHideText },
{ HIDE_TEXT_MOUSEOVER, false, &ExtraWindow::SetHideTextMouseover },
{ SHOW_ORIGINAL, true, &ExtraWindow::SetShowOriginal }, { SHOW_ORIGINAL, true, &ExtraWindow::SetShowOriginal },
{ SHOW_ORIGINAL_AFTER_TRANSLATION, true, &ExtraWindow::SetShowOriginalAfterTranslation }, { ORIGINAL_AFTER_TRANSLATION, true, &ExtraWindow::SetShowOriginalAfterTranslation },
{ DICTIONARY, false, &ExtraWindow::SetUseDictionary }, { DICTIONARY, false, &ExtraWindow::SetUseDictionary },
}) })
{ {
@ -245,26 +210,16 @@ public:
auto action = menu.addAction(name, this, slot); auto action = menu.addAction(name, this, slot);
action->setCheckable(true); action->setCheckable(true);
action->setChecked(default); action->setChecked(default);
if (slot == &ExtraWindow::SetHideTextMouseover)
hideTextMouseoveAction = action;
if (slot == &ExtraWindow::SetHideText)
hideTextAction = action;
} }
menu.addAction(CLICK_THROUGH, this, &ExtraWindow::ToggleClickThrough); menu.addAction(CLICK_THROUGH, this, &ExtraWindow::ToggleClickThrough);
menu.addAction(MAX_SENTENCE_SIZE, this, [this]
{
settings.setValue(MAX_SENTENCE_SIZE, maxSentenceSize = QInputDialog::getInt(this, MAX_SENTENCE_SIZE, "", maxSentenceSize, 0, INT_MAX, 1, nullptr, Qt::WindowCloseButtonHint));
});
ui.display->installEventFilter(this); ui.display->installEventFilter(this);
ui.display->setMouseTracking(true);
qApp->installNativeEventFilter(this); qApp->installNativeEventFilter(this);
QMetaObject::invokeMethod(this, [this] QMetaObject::invokeMethod(this, [this]
{ {
RegisterHotKey((HWND)winId(), HIDE_TEXT_HOTKEY, MOD_ALT | MOD_SHIFT | MOD_NOREPEAT, 0x48); RegisterHotKey((HWND)winId(), CLICK_THROUGH_HOTKEY, MOD_SHIFT | MOD_NOREPEAT, 0x58);
RegisterHotKey((HWND)winId(), CLICK_THROUGH_HOTKEY, MOD_ALT | MOD_SHIFT | MOD_NOREPEAT, 0x54);
show(); show();
AddSentence(EXTRA_WINDOW_INFO); AddSentence(EXTRA_WINDOW_INFO);
}, Qt::QueuedConnection); }, Qt::QueuedConnection);
@ -277,23 +232,49 @@ public:
void AddSentence(QString sentence) void AddSentence(QString sentence)
{ {
if (sentence.size() > maxSentenceSize) sentence = SENTENCE_TOO_BIG;
if (showOriginal){
if (showOriginalAfterTranslation && sentence.contains(u8"\x200b \n"))
sentence = sentence.split(u8"\x200b \n")[1] + "\n" + sentence.split(u8"\x200b \n")[0];
} else
if (sentence.contains(u8"\x200b \n")) sentence = sentence.split(u8"\x200b \n")[1];
sanitize(sentence); sanitize(sentence);
sentence.chop(std::distance(std::remove(sentence.begin(), sentence.end(), QChar::Tabulation), sentence.end())); sentence.chop(std::distance(std::remove(sentence.begin(), sentence.end(), QChar::Tabulation), sentence.end()));
sentenceHistory.push_back(sentence); sentenceHistory.push_back(sentence);
if (sentenceHistory.size() > maxHistoryIndex) sentenceHistory.erase(sentenceHistory.begin()); if (sentenceHistory.size() > 1000) sentenceHistory.erase(sentenceHistory.begin());
historyIndex = sentenceHistory.size() - 1; historyIndex = sentenceHistory.size() - 1;
savedSentence = sentence; DisplaySentence();
if (!hideText) ui.display->setText(sentence);
AutoResize(sentence);
} }
private: private:
void DisplaySentence()
{
QString sentence = sentenceHistory[historyIndex];
if (sentence.contains(u8"\x200b \n"))
if (!showOriginal) sentence = sentence.split(u8"\x200b \n")[1];
else if (showOriginalAfterTranslation) sentence = sentence.split(u8"\x200b \n")[1] + "\n" + sentence.split(u8"\x200b \n")[0];
if (autoResize)
{
ui.display->resize(
ui.display->width(),
QFontMetrics(ui.display->font(), ui.display).boundingRect(0, 0, ui.display->width(), INT_MAX, Qt::TextWordWrap, sentence).height()
);
}
else if (locked)
{
QFontMetrics fontMetrics(ui.display->font(), ui.display);
int low = 0, high = sentence.size(), last = 0;
while (low < high)
{
int mid = (low + high) / 2;
if (fontMetrics.boundingRect(0, 0, ui.display->width(), INT_MAX, Qt::TextWordWrap, sentence.left(mid)).height() < ui.display->height())
{
last = mid;
low = mid + 1;
}
else high = mid;
}
sentence = sentence.left(last);
}
ui.display->setText(sentence);
}
void SetTopmost(bool topmost) void SetTopmost(bool topmost)
{ {
for (auto window : { winId(), dictionaryWindow.winId() }) for (auto window : { winId(), dictionaryWindow.winId() })
@ -306,97 +287,34 @@ private:
settings.setValue(POSITION_LOCK, this->locked = locked); settings.setValue(POSITION_LOCK, this->locked = locked);
}; };
void SetLock(bool locked) void SetSizeLock(bool locked)
{ {
setSizeGripEnabled(!locked); setSizeGripEnabled(!locked);
settings.setValue(SIZE_LOCK, locked); settings.setValue(SIZE_LOCK, locked);
}; };
void SetCenteredText(bool centeredCenter) void SetCenteredText(bool centeredText)
{ {
if (centeredCenter) ui.display->setAlignment(centeredText ? Qt::AlignHCenter : Qt::AlignLeft);
ui.display->setAlignment(Qt::AlignCenter); settings.setValue(CENTERED_TEXT, this->centeredText = centeredText);
else
ui.display->setAlignment(Qt::AlignLeft);
settings.setValue(CENTERED_TEXT, this->centeredCenter = centeredCenter);
}; };
void SetAutoResizeHeight(bool autoResizeHeight) void SetAutoResize(bool autoResize)
{ {
settings.setValue(AUTO_RESIZE_WINDOW_HEIGHT, this->autoResizeHeight = autoResizeHeight); settings.setValue(AUTO_RESIZE_WINDOW_HEIGHT, this->autoResize = autoResize);
if (autoResizeHeight) AutoResize(savedSentence); DisplaySentence();
};
void AutoResize(QString sentence)
{
if (!autoResizeHeight) return;
QFontMetrics fontMetrics(ui.display->font(), ui.display);
auto boundingRect = fontMetrics.boundingRect(0, 0, width()-20, INT_MAX, Qt::TextWordWrap, sentence);
int newHeight = boundingRect.height() + 30;
int currHeight = height();
if (newHeight != currHeight) {
QSize s = size();
s.setWidth(width());
s.setHeight(newHeight);
resize(s);
}
}
void ToggleClickThrough()
{
if (clickThrough = !clickThrough)
{
setAttribute(Qt::WA_TransparentForMouseEvents, true);
setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
} else {
setAttribute(Qt::WA_TransparentForMouseEvents , false);
//setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint); // doesn't work
setWindowFlags(Qt::FramelessWindowHint);
SetTopmost(settings.value(TOPMOST, false).toBool());
}
show();
};
void SetHideTextMouseover(bool hideTextMouseover)
{
this->hideTextMouseover = hideTextMouseover;
if (hideTextMouseover && this->hideText)
{
this->hideText = false;
hideTextAction->setChecked(false);
SetBackgroundColorHideText();
}
};
void SetHideText(bool hideText)
{
this->hideText = hideText;
if (this->hideTextMouseover)
{
this->hideTextMouseover = false;
hideTextMouseoveAction->setChecked(false);
}
SetBackgroundColorHideText();
};
void ToggleHideText()
{
hideTextAction->setChecked(!hideText);
SetHideText(!hideText);
}; };
void SetShowOriginal(bool showOriginal) void SetShowOriginal(bool showOriginal)
{ {
if (!showOriginal && settings.value(SHOW_ORIGINAL, false).toBool()) QMessageBox::information(this, SHOW_ORIGINAL, SHOW_ORIGINAL_INFO);
settings.setValue(SHOW_ORIGINAL, this->showOriginal = showOriginal); settings.setValue(SHOW_ORIGINAL, this->showOriginal = showOriginal);
DisplaySentence();
}; };
void SetShowOriginalAfterTranslation(bool showOriginalAfterTranslation) void SetShowOriginalAfterTranslation(bool showOriginalAfterTranslation)
{ {
settings.setValue(SHOW_ORIGINAL_AFTER_TRANSLATION, this->showOriginalAfterTranslation = showOriginalAfterTranslation); settings.setValue(ORIGINAL_AFTER_TRANSLATION, this->showOriginalAfterTranslation = showOriginalAfterTranslation);
DisplaySentence();
}; };
void SetUseDictionary(bool useDictionary) void SetUseDictionary(bool useDictionary)
@ -413,27 +331,40 @@ private:
settings.setValue(DICTIONARY, this->useDictionary = useDictionary); settings.setValue(DICTIONARY, this->useDictionary = useDictionary);
} }
void ComputeDictionaryPosition(QPoint mouse) void ToggleClickThrough()
{
clickThrough = !clickThrough;
for (auto window : { winId(), dictionaryWindow.winId() })
{
unsigned exStyle = GetWindowLongPtrW((HWND)window, GWL_EXSTYLE);
if (clickThrough) exStyle |= WS_EX_TRANSPARENT;
else exStyle &= ~WS_EX_TRANSPARENT;
SetWindowLongPtrW((HWND)window, GWL_EXSTYLE, exStyle);
}
};
void ShowDictionary(QPoint mouse)
{ {
QString sentence = ui.display->text(); QString sentence = ui.display->text();
const QFont& font = ui.display->font(); const QFont& font = ui.display->font();
if (cachedDisplayInfo.CompareExchange(ui.display)) if (cachedDisplayInfo.CompareExchange(ui.display))
{ {
QFontMetrics fontMetrics(font, ui.display); QFontMetrics fontMetrics(font, ui.display);
int flags = Qt::TextWordWrap | (ui.display->alignment() & (Qt::AlignLeft | Qt::AlignHCenter));
textPositionMap.clear(); textPositionMap.clear();
for (int i = 0, height = 0, lineBreak = 0; i < sentence.size(); ++i) for (int i = 0, height = 0, lineBreak = 0; i < sentence.size(); ++i)
{ {
int block = 1; int block = 1;
for (int charHeight = fontMetrics.boundingRect(0, 0, 1, INT_MAX, Qt::TextWordWrap, sentence.mid(i, 1)).height(); for (int charHeight = fontMetrics.boundingRect(0, 0, 1, INT_MAX, flags, sentence.mid(i, 1)).height();
i + block < sentence.size() && fontMetrics.boundingRect(0, 0, 1, INT_MAX, Qt::TextWordWrap, sentence.mid(i, block + 1)).height() < charHeight * 1.5; ++block); i + block < sentence.size() && fontMetrics.boundingRect(0, 0, 1, INT_MAX, flags, sentence.mid(i, block + 1)).height() < charHeight * 1.5; ++block);
auto boundingRect = fontMetrics.boundingRect(0, 0, ui.display->width(), INT_MAX, Qt::TextWordWrap, sentence.left(i + block)); auto boundingRect = fontMetrics.boundingRect(0, 0, ui.display->width(), INT_MAX, flags, sentence.left(i + block));
if (boundingRect.height() > height) if (boundingRect.height() > height)
{ {
height = boundingRect.height(); height = boundingRect.height();
lineBreak = i; lineBreak = i;
} }
textPositionMap.push_back({ textPositionMap.push_back({
fontMetrics.boundingRect(0, 0, ui.display->width(), INT_MAX, Qt::TextWordWrap, sentence.mid(lineBreak, i - lineBreak + 1)).width(), fontMetrics.boundingRect(0, 0, ui.display->width(), INT_MAX, flags, sentence.mid(lineBreak, i - lineBreak + 1)).right() + 1,
height height
}); });
} }
@ -454,31 +385,23 @@ private:
{ {
auto msg = (MSG*)message; auto msg = (MSG*)message;
if (msg->message == WM_HOTKEY) if (msg->message == WM_HOTKEY)
{ if (msg->wParam == CLICK_THROUGH_HOTKEY) return ToggleClickThrough(), true;
switch (msg->wParam)
{
case HIDE_TEXT_HOTKEY:
{
ToggleHideText();
return true;
}
case CLICK_THROUGH_HOTKEY:
{
ToggleClickThrough();
return true;
}
}
}
return false; return false;
} }
bool eventFilter(QObject*, QEvent* event) override bool eventFilter(QObject*, QEvent* event) override
{ {
if (useDictionary && event->type() == QEvent::MouseMove) ComputeDictionaryPosition(((QMouseEvent*)event)->localPos().toPoint()); if (event->type() == QEvent::MouseButtonPress) mousePressEvent((QMouseEvent*)event);
if (event->type() == QEvent::MouseButtonPress) dictionaryWindow.hide();
return false; return false;
} }
void timerEvent(QTimerEvent* event) override
{
if (useDictionary && QCursor::pos() != oldPos && (!dictionaryWindow.isVisible() || !dictionaryWindow.geometry().contains(QCursor::pos())))
ShowDictionary(ui.display->mapFromGlobal(QCursor::pos()));
PrettyWindow::timerEvent(event);
}
void mousePressEvent(QMouseEvent* event) override void mousePressEvent(QMouseEvent* event) override
{ {
dictionaryWindow.hide(); dictionaryWindow.hide();
@ -494,14 +417,12 @@ private:
void wheelEvent(QWheelEvent* event) override void wheelEvent(QWheelEvent* event) override
{ {
int scroll = event->angleDelta().y(); int scroll = event->angleDelta().y();
if (scroll > 0 && historyIndex > 0) ui.display->setText(sentenceHistory[--historyIndex]); if (scroll > 0 && historyIndex > 0) --historyIndex;
if (scroll < 0 && historyIndex + 1 < sentenceHistory.size()) ui.display->setText(sentenceHistory[++historyIndex]); if (scroll < 0 && historyIndex + 1 < sentenceHistory.size()) ++historyIndex;
AutoResize(sentenceHistory[historyIndex]); DisplaySentence();
} }
QAction *hideTextMouseoveAction, *hideTextAction; bool locked, centeredText, autoResize, showOriginal, showOriginalAfterTranslation, useDictionary, clickThrough;
bool locked, centeredCenter, autoResizeHeight, showOriginal, showOriginalAfterTranslation, useDictionary, clickThrough;
int maxSentenceSize = 1000;
QPoint oldPos; QPoint oldPos;
class class
@ -509,10 +430,11 @@ private:
public: public:
bool CompareExchange(QLabel* display) bool CompareExchange(QLabel* display)
{ {
if (display->text() == text && display->font() == font && display->width() == width) return false; if (display->text() == text && display->font() == font && display->width() == width && display->alignment() == alignment) return false;
text = display->text(); text = display->text();
font = display->font(); font = display->font();
width = display->width(); width = display->width();
alignment = display->alignment();
return true; return true;
} }
@ -520,12 +442,12 @@ private:
QString text; QString text;
QFont font; QFont font;
int width; int width;
Qt::Alignment alignment;
} cachedDisplayInfo; } cachedDisplayInfo;
std::vector<QPoint> textPositionMap; std::vector<QPoint> textPositionMap;
std::vector<QString> sentenceHistory; std::vector<QString> sentenceHistory;
int historyIndex = 0; int historyIndex = 0;
const int maxHistoryIndex = 20;
class DictionaryWindow : public PrettyWindow class DictionaryWindow : public PrettyWindow
{ {

View File

@ -10,6 +10,9 @@
<height>300</height> <height>300</height>
</rect> </rect>
</property> </property>
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<layout class="QHBoxLayout"> <layout class="QHBoxLayout">
<item> <item>
<widget class="QLabel" name="display"> <widget class="QLabel" name="display">

View File

@ -156,7 +156,6 @@ const char* AUTO_START = u8"Start automatically";
const wchar_t* ERROR_START_CHROME = L"failed to start Chrome or to connect to it"; const wchar_t* ERROR_START_CHROME = L"failed to start Chrome or to connect to it";
const char* EXTRA_WINDOW_INFO = u8R"(Right click to change settings const char* EXTRA_WINDOW_INFO = u8R"(Right click to change settings
Click and drag on window edges to move, or the bottom right corner to resize)"; Click and drag on window edges to move, or the bottom right corner to resize)";
const char* SENTENCE_TOO_BIG = u8"Sentence too large to display";
const char* MAX_SENTENCE_SIZE = u8"Max sentence size"; const char* MAX_SENTENCE_SIZE = u8"Max sentence size";
const char* TOPMOST = u8"Always on top"; const char* TOPMOST = u8"Always on top";
const char* DICTIONARY = u8"Dictionary"; const char* DICTIONARY = u8"Dictionary";
@ -178,21 +177,19 @@ This file must be encoded in UTF-8.)";
const char* SHOW_ORIGINAL = u8"Original text"; const char* SHOW_ORIGINAL = u8"Original text";
const char* SHOW_ORIGINAL_INFO = u8R"(Original text will not be shown const char* SHOW_ORIGINAL_INFO = u8R"(Original text will not be shown
Only works if this extension is used directly after a translation extension)"; Only works if this extension is used directly after a translation extension)";
const char* SHOW_ORIGINAL_AFTER_TRANSLATION = u8"Show original text after translation"; const char* ORIGINAL_AFTER_TRANSLATION = u8"Original text after translation";
const char* SIZE_LOCK = u8"Size lock"; const char* SIZE_LOCK = u8"Size lock";
const char* POSITION_LOCK = u8"Position lock"; const char* POSITION_LOCK = u8"Position lock";
const char* CENTERED_TEXT = u8"Centered text"; const char* CENTERED_TEXT = u8"Centered text";
const char* AUTO_RESIZE_WINDOW_HEIGHT = u8"Auto resize window height"; const char* AUTO_RESIZE_WINDOW_HEIGHT = u8"Auto resize window height";
const char* CLICK_THROUGH = u8"Click through\tAlt+Shift+T"; const char* CLICK_THROUGH = u8"Click through\tShift+X";
const char* HIDE_TEXT_MOUSEOVER = u8"Hide text mouseover"; const char* HIDE_MOUSEOVER = u8"Hide while mouse on top";
const char* HIDE_TEXT = u8"Hide text\tAlt+Shift+H";
const char* OPACITY = u8"Opacity"; const char* OPACITY = u8"Opacity";
const char* BG_COLOR = u8"Background color"; const char* BG_COLOR = u8"Background color";
const char* TEXT_COLOR = u8"Text color"; const char* TEXT_COLOR = u8"Text color";
const char* TEXT_OUTLINE = u8"Text outline"; const char* TEXT_OUTLINE = u8"Text outline";
const char* OUTLINE_COLOR = u8"Outline color"; const char* OUTLINE_COLOR = u8"Outline color";
const char* OUTLINE_SIZE = u8"Outline size"; const char* OUTLINE_SIZE = u8"Outline size";
const char* OUTLINE_LAST_SIZE = u8"Last used outline size";
const char* OUTLINE_SIZE_INFO = u8"Size in pixels (recommended to stay below 20% of the font size)"; const char* OUTLINE_SIZE_INFO = u8"Size in pixels (recommended to stay below 20% of the font size)";
const char* FONT = u8"Font"; const char* FONT = u8"Font";
const char* LUA_INTRO = u8R"(--[[ const char* LUA_INTRO = u8R"(--[[
@ -434,7 +431,6 @@ Clic y arrastra los bordes de la ventana para moverla, o en la esquina inferior
API_KEY = u8"API key"; API_KEY = u8"API key";
EXTRA_WINDOW_INFO = u8R"(右键修改设置 EXTRA_WINDOW_INFO = u8R"(右键修改设置
)"; )";
SENTENCE_TOO_BIG = u8"文本过长无法显示";
MAX_SENTENCE_SIZE = u8"最大文本长度"; MAX_SENTENCE_SIZE = u8"最大文本长度";
TOPMOST = u8"窗口总是置顶"; TOPMOST = u8"窗口总是置顶";
DICTIONARY = u8"字典"; DICTIONARY = u8"字典";
@ -609,7 +605,6 @@ padding: длина добавочных данных перед строкой
API_KEY = u8"Ключ API"; API_KEY = u8"Ключ API";
EXTRA_WINDOW_INFO = u8R"(Правый клик для изменения настроек EXTRA_WINDOW_INFO = u8R"(Правый клик для изменения настроек
Нажмите и перетащите за края - для перемещения, или за правый-нижний угол - для изменения размера)"; Нажмите и перетащите за края - для перемещения, или за правый-нижний угол - для изменения размера)";
SENTENCE_TOO_BIG = u8"Предложение слишком длинное для отображения";
MAX_SENTENCE_SIZE = u8"Максимальная длина предложения"; MAX_SENTENCE_SIZE = u8"Максимальная длина предложения";
TOPMOST = u8"Поверх всех окон"; TOPMOST = u8"Поверх всех окон";
DICTIONARY = u8"Словарь"; DICTIONARY = u8"Словарь";
@ -868,7 +863,6 @@ esempio: Textractor -p4466 -p"My Game.exe" sta tentando di inniettare i processi
API_KEY = u8"Chiave API"; API_KEY = u8"Chiave API";
EXTRA_WINDOW_INFO = u8R"(Tasto destro per cambiare le impostazioni EXTRA_WINDOW_INFO = u8R"(Tasto destro per cambiare le impostazioni
Clicca e trascina i bordi della finestra per muoverla, oppure nell'angolo in basso a destra per ridimensionare)"; Clicca e trascina i bordi della finestra per muoverla, oppure nell'angolo in basso a destra per ridimensionare)";
SENTENCE_TOO_BIG = u8"Sentenza troppo grande da visualizzare";
MAX_SENTENCE_SIZE = u8"Dimensione massima sentenza"; MAX_SENTENCE_SIZE = u8"Dimensione massima sentenza";
TOPMOST = u8"Sempre in primo piano"; TOPMOST = u8"Sempre in primo piano";
DICTIONARY = u8"Dizionario"; DICTIONARY = u8"Dizionario";
@ -891,21 +885,19 @@ Questo file deve essere codificato in UTF-8.)";
SHOW_ORIGINAL = u8"Testo originale"; SHOW_ORIGINAL = u8"Testo originale";
SHOW_ORIGINAL_INFO = u8R"(Testo originale non sarà mostrato SHOW_ORIGINAL_INFO = u8R"(Testo originale non sarà mostrato
Funziona solo se questa estenzione è usata direttamente dopo un'estensione di traduzione)"; Funziona solo se questa estenzione è usata direttamente dopo un'estensione di traduzione)";
SHOW_ORIGINAL_AFTER_TRANSLATION = u8"Mostra testo originale dopo traduzione"; ORIGINAL_AFTER_TRANSLATION = u8"Mostra testo originale dopo traduzione";
SIZE_LOCK = u8"Lock delle dimensione"; SIZE_LOCK = u8"Lock delle dimensione";
POSITION_LOCK = u8"Lock delle posizione"; POSITION_LOCK = u8"Lock delle posizione";
CENTERED_TEXT = u8"Testo centrato"; CENTERED_TEXT = u8"Testo centrato";
AUTO_RESIZE_WINDOW_HEIGHT = u8"Auto resize altezza finestra"; AUTO_RESIZE_WINDOW_HEIGHT = u8"Auto resize altezza finestra";
CLICK_THROUGH = u8"Clicca attraverso\tAlt+Shift+T"; CLICK_THROUGH = u8"Clicca attraverso\tAlt+Shift+T";
HIDE_TEXT_MOUSEOVER = u8"Nascondi testo mouseover"; HIDE_MOUSEOVER = u8"Nascondi testo mouseover";
HIDE_TEXT = u8"Nascondi testo\tAlt+Shift+H";
OPACITY = u8"Opacità"; OPACITY = u8"Opacità";
BG_COLOR = u8"Colore dello sfondo"; BG_COLOR = u8"Colore dello sfondo";
TEXT_COLOR = u8"Colore del testo"; TEXT_COLOR = u8"Colore del testo";
TEXT_OUTLINE = u8"Contorno del testo"; TEXT_OUTLINE = u8"Contorno del testo";
OUTLINE_COLOR = u8"Colore del contorno"; OUTLINE_COLOR = u8"Colore del contorno";
OUTLINE_SIZE = u8"Dimensione del contorno"; OUTLINE_SIZE = u8"Dimensione del contorno";
OUTLINE_LAST_SIZE = u8"Ultima dimensione del contorno utilizzata";
OUTLINE_SIZE_INFO = u8"Dimensione in pixel (consigliato di rimanere sotto il 20% della dimensione del font)"; OUTLINE_SIZE_INFO = u8"Dimensione in pixel (consigliato di rimanere sotto il 20% della dimensione del font)";
FONT = u8"Font"; FONT = u8"Font";
LUA_INTRO = u8R"(--[[ LUA_INTRO = u8R"(--[[
@ -1296,7 +1288,6 @@ example: Textractor -p4466 -p"My Game.exe" tries to inject processes with id 446
API_KEY = u8"API key"; API_KEY = u8"API key";
EXTRA_WINDOW_INFO = u8R"(Clic droit pour modifier les paramètres EXTRA_WINDOW_INFO = u8R"(Clic droit pour modifier les paramètres
Cliquez et faites glisser sur les bords de la fenêtre pour vous déplacer ou dans le coin inférieur droit pour redimensionner)"; Cliquez et faites glisser sur les bords de la fenêtre pour vous déplacer ou dans le coin inférieur droit pour redimensionner)";
SENTENCE_TOO_BIG = u8"Phrase trop grande pour être affichée";
MAX_SENTENCE_SIZE = u8"Taille maximale de la phrase"; MAX_SENTENCE_SIZE = u8"Taille maximale de la phrase";
TOPMOST = u8"Toujours au dessus"; TOPMOST = u8"Toujours au dessus";
DICTIONARY = u8"Dictionnaire"; DICTIONARY = u8"Dictionnaire";