mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-13 19:49:51 +01:00
parent
a6573e83e0
commit
ce61351fe3
|
@ -68,6 +68,8 @@ ChatWidget::ChatWidget(ChannelManager &_channelManager, NotebookPage *parent)
|
||||||
std::bind(&ChatWidget::channelNameUpdated, this, std::placeholders::_1));
|
std::bind(&ChatWidget::channelNameUpdated, this, std::placeholders::_1));
|
||||||
|
|
||||||
this->channelNameUpdated(this->channelName.getValue());
|
this->channelNameUpdated(this->channelName.getValue());
|
||||||
|
|
||||||
|
this->input.textInput.installEventFilter(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatWidget::~ChatWidget()
|
ChatWidget::~ChatWidget()
|
||||||
|
@ -193,9 +195,14 @@ void ChatWidget::updateGifEmotes()
|
||||||
this->view.updateGifEmotes();
|
this->view.updateGifEmotes();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatWidget::giveFocus()
|
void ChatWidget::giveFocus(Qt::FocusReason reason)
|
||||||
{
|
{
|
||||||
this->input.textInput.setFocus();
|
this->input.textInput.setFocus(reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ChatWidget::hasFocus() const
|
||||||
|
{
|
||||||
|
return this->input.textInput.hasFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatWidget::paintEvent(QPaintEvent *)
|
void ChatWidget::paintEvent(QPaintEvent *)
|
||||||
|
|
|
@ -53,7 +53,8 @@ public:
|
||||||
void layoutMessages(bool forceUpdate = false);
|
void layoutMessages(bool forceUpdate = false);
|
||||||
void updateGifEmotes();
|
void updateGifEmotes();
|
||||||
|
|
||||||
void giveFocus();
|
void giveFocus(Qt::FocusReason reason);
|
||||||
|
bool hasFocus() const;
|
||||||
|
|
||||||
pajlada::Settings::Setting<std::string> channelName;
|
pajlada::Settings::Setting<std::string> channelName;
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "colorscheme.hpp"
|
#include "colorscheme.hpp"
|
||||||
#include "completionmanager.hpp"
|
#include "completionmanager.hpp"
|
||||||
#include "ircmanager.hpp"
|
#include "ircmanager.hpp"
|
||||||
|
#include "notebookpage.hpp"
|
||||||
#include "settingsmanager.hpp"
|
#include "settingsmanager.hpp"
|
||||||
|
|
||||||
#include <QCompleter>
|
#include <QCompleter>
|
||||||
|
@ -71,17 +72,61 @@ ChatWidgetInput::ChatWidgetInput(ChatWidget *_chatWidget)
|
||||||
}
|
}
|
||||||
prevIndex = prevMsg.size();
|
prevIndex = prevMsg.size();
|
||||||
} else if (event->key() == Qt::Key_Up) {
|
} else if (event->key() == Qt::Key_Up) {
|
||||||
if (prevMsg.size() && prevIndex) {
|
if (event->modifiers() == Qt::AltModifier) {
|
||||||
prevIndex--;
|
NotebookPage *page = static_cast<NotebookPage *>(this->chatWidget->parentWidget());
|
||||||
textInput.setText(prevMsg.at(prevIndex));
|
|
||||||
|
int reqX = page->currentX;
|
||||||
|
int reqY = page->lastRequestedY[reqX] - 1;
|
||||||
|
|
||||||
|
qDebug() << "Alt+Down to" << reqX << "/" << reqY;
|
||||||
|
|
||||||
|
page->requestFocus(reqX, reqY);
|
||||||
|
} else {
|
||||||
|
if (prevMsg.size() && prevIndex) {
|
||||||
|
prevIndex--;
|
||||||
|
textInput.setText(prevMsg.at(prevIndex));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (event->key() == Qt::Key_Down) {
|
} else if (event->key() == Qt::Key_Down) {
|
||||||
if (prevIndex != (prevMsg.size() - 1) && prevIndex != prevMsg.size()) {
|
if (event->modifiers() == Qt::AltModifier) {
|
||||||
prevIndex++;
|
NotebookPage *page = static_cast<NotebookPage *>(this->chatWidget->parentWidget());
|
||||||
textInput.setText(prevMsg.at(prevIndex));
|
|
||||||
|
int reqX = page->currentX;
|
||||||
|
int reqY = page->lastRequestedY[reqX] + 1;
|
||||||
|
|
||||||
|
qDebug() << "Alt+Down to" << reqX << "/" << reqY;
|
||||||
|
|
||||||
|
page->requestFocus(reqX, reqY);
|
||||||
} else {
|
} else {
|
||||||
prevIndex = prevMsg.size();
|
if (prevIndex != (prevMsg.size() - 1) && prevIndex != prevMsg.size()) {
|
||||||
textInput.setText(QString());
|
prevIndex++;
|
||||||
|
textInput.setText(prevMsg.at(prevIndex));
|
||||||
|
} else {
|
||||||
|
prevIndex = prevMsg.size();
|
||||||
|
textInput.setText(QString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (event->key() == Qt::Key_Left) {
|
||||||
|
if (event->modifiers() == Qt::AltModifier) {
|
||||||
|
NotebookPage *page = static_cast<NotebookPage *>(this->chatWidget->parentWidget());
|
||||||
|
|
||||||
|
int reqX = page->currentX - 1;
|
||||||
|
int reqY = page->lastRequestedY[reqX];
|
||||||
|
|
||||||
|
qDebug() << "Alt+Left to" << reqX << "/" << reqY;
|
||||||
|
|
||||||
|
page->requestFocus(reqX, reqY);
|
||||||
|
}
|
||||||
|
} else if (event->key() == Qt::Key_Right) {
|
||||||
|
if (event->modifiers() == Qt::AltModifier) {
|
||||||
|
NotebookPage *page = static_cast<NotebookPage *>(this->chatWidget->parentWidget());
|
||||||
|
|
||||||
|
int reqX = page->currentX + 1;
|
||||||
|
int reqY = page->lastRequestedY[reqX];
|
||||||
|
|
||||||
|
qDebug() << "Alt+Right to" << reqX << "/" << reqY;
|
||||||
|
|
||||||
|
page->requestFocus(reqX, reqY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -148,7 +193,7 @@ void ChatWidgetInput::resizeEvent(QResizeEvent *)
|
||||||
|
|
||||||
void ChatWidgetInput::mousePressEvent(QMouseEvent *)
|
void ChatWidgetInput::mousePressEvent(QMouseEvent *)
|
||||||
{
|
{
|
||||||
this->chatWidget->giveFocus();
|
this->chatWidget->giveFocus(Qt::MouseFocusReason);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace widgets
|
} // namespace widgets
|
||||||
|
|
|
@ -339,7 +339,7 @@ void ChatWidgetView::mousePressEvent(QMouseEvent *event)
|
||||||
this->isMouseDown = true;
|
this->isMouseDown = true;
|
||||||
this->lastPressPosition = event->screenPos();
|
this->lastPressPosition = event->screenPos();
|
||||||
|
|
||||||
this->chatWidget->giveFocus();
|
this->chatWidget->giveFocus(Qt::MouseFocusReason);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatWidgetView::mouseReleaseEvent(QMouseEvent *event)
|
void ChatWidgetView::mouseReleaseEvent(QMouseEvent *event)
|
||||||
|
|
|
@ -82,7 +82,7 @@ void NotebookPage::addToLayout(ChatWidget *widget,
|
||||||
std::pair<int, int> position = std::pair<int, int>(-1, -1))
|
std::pair<int, int> position = std::pair<int, int>(-1, -1))
|
||||||
{
|
{
|
||||||
this->chatWidgets.push_back(widget);
|
this->chatWidgets.push_back(widget);
|
||||||
widget->giveFocus();
|
widget->giveFocus(Qt::MouseFocusReason);
|
||||||
|
|
||||||
// add vbox at the end
|
// add vbox at the end
|
||||||
if (position.first < 0 || position.first >= this->ui.hbox.count()) {
|
if (position.first < 0 || position.first >= this->ui.hbox.count()) {
|
||||||
|
@ -90,6 +90,7 @@ void NotebookPage::addToLayout(ChatWidget *widget,
|
||||||
vbox->addWidget(widget);
|
vbox->addWidget(widget);
|
||||||
|
|
||||||
this->ui.hbox.addLayout(vbox, 1);
|
this->ui.hbox.addLayout(vbox, 1);
|
||||||
|
this->refreshCurrentFocusCoordinates();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,6 +100,7 @@ void NotebookPage::addToLayout(ChatWidget *widget,
|
||||||
vbox->addWidget(widget);
|
vbox->addWidget(widget);
|
||||||
|
|
||||||
this->ui.hbox.insertLayout(position.first, vbox, 1);
|
this->ui.hbox.insertLayout(position.first, vbox, 1);
|
||||||
|
this->refreshCurrentFocusCoordinates();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,6 +108,8 @@ void NotebookPage::addToLayout(ChatWidget *widget,
|
||||||
auto vbox = static_cast<QVBoxLayout *>(this->ui.hbox.itemAt(position.first));
|
auto vbox = static_cast<QVBoxLayout *>(this->ui.hbox.itemAt(position.first));
|
||||||
|
|
||||||
vbox->insertWidget(std::max(0, std::min(vbox->count(), position.second)), widget);
|
vbox->insertWidget(std::max(0, std::min(vbox->count(), position.second)), widget);
|
||||||
|
|
||||||
|
this->refreshCurrentFocusCoordinates();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<ChatWidget *> &NotebookPage::getChatWidgets() const
|
const std::vector<ChatWidget *> &NotebookPage::getChatWidgets() const
|
||||||
|
@ -134,6 +138,103 @@ void NotebookPage::addChat(bool openChannelNameDialog)
|
||||||
this->addToLayout(w, std::pair<int, int>(-1, -1));
|
this->addToLayout(w, std::pair<int, int>(-1, -1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NotebookPage::refreshCurrentFocusCoordinates(bool alsoSetLastRequested)
|
||||||
|
{
|
||||||
|
int setX = -1;
|
||||||
|
int setY = -1;
|
||||||
|
bool doBreak = false;
|
||||||
|
for (int x = 0; x < this->ui.hbox.count(); ++x) {
|
||||||
|
QLayoutItem *item = this->ui.hbox.itemAt(x);
|
||||||
|
if (item->isEmpty()) {
|
||||||
|
setX = x;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
QVBoxLayout *vbox = static_cast<QVBoxLayout *>(item->layout());
|
||||||
|
|
||||||
|
for (int y = 0; y < vbox->count(); ++y) {
|
||||||
|
QLayoutItem *innerItem = vbox->itemAt(y);
|
||||||
|
|
||||||
|
if (innerItem->isEmpty()) {
|
||||||
|
setX = x;
|
||||||
|
setY = y;
|
||||||
|
doBreak = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *w = innerItem->widget();
|
||||||
|
if (w) {
|
||||||
|
ChatWidget *chatWidget = static_cast<ChatWidget *>(w);
|
||||||
|
if (chatWidget->hasFocus()) {
|
||||||
|
setX = x;
|
||||||
|
setY = y;
|
||||||
|
doBreak = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doBreak) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setX != -1) {
|
||||||
|
this->currentX = setX;
|
||||||
|
|
||||||
|
if (setY != -1) {
|
||||||
|
this->currentY = setY;
|
||||||
|
|
||||||
|
if (alsoSetLastRequested) {
|
||||||
|
this->lastRequestedY[setX] = setY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotebookPage::requestFocus(int requestedX, int requestedY)
|
||||||
|
{
|
||||||
|
// XXX: Perhaps if we request an Y coordinate out of bounds, we shuold set all previously set
|
||||||
|
// requestedYs to 0 (if -1 is requested) or that x-coordinates vbox count (if requestedY >=
|
||||||
|
// currentvbox.count() is requested)
|
||||||
|
if (requestedX < 0 || requestedX >= this->ui.hbox.count()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QLayoutItem *item = this->ui.hbox.itemAt(requestedX);
|
||||||
|
QWidget *xW = item->widget();
|
||||||
|
if (item->isEmpty()) {
|
||||||
|
qDebug() << "Requested hbox item " << requestedX << "is empty";
|
||||||
|
if (xW) {
|
||||||
|
qDebug() << "but xW is not null";
|
||||||
|
// TODO: figure out what to do here
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVBoxLayout *vbox = static_cast<QVBoxLayout *>(item->layout());
|
||||||
|
|
||||||
|
if (requestedY < 0) {
|
||||||
|
requestedY = 0;
|
||||||
|
} else if (requestedY >= vbox->count()) {
|
||||||
|
requestedY = vbox->count() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->lastRequestedY[requestedX] = requestedY;
|
||||||
|
|
||||||
|
QLayoutItem *innerItem = vbox->itemAt(requestedY);
|
||||||
|
|
||||||
|
if (innerItem->isEmpty()) {
|
||||||
|
qDebug() << "Requested vbox item " << requestedY << "is empty";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *w = innerItem->widget();
|
||||||
|
if (w) {
|
||||||
|
ChatWidget *chatWidget = static_cast<ChatWidget *>(w);
|
||||||
|
chatWidget->giveFocus(Qt::OtherFocusReason);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void NotebookPage::enterEvent(QEvent *)
|
void NotebookPage::enterEvent(QEvent *)
|
||||||
{
|
{
|
||||||
if (this->ui.hbox.count() == 0) {
|
if (this->ui.hbox.count() == 0) {
|
||||||
|
@ -240,6 +341,17 @@ void NotebookPage::dropEvent(QDropEvent *event)
|
||||||
this->dropPreview.hide();
|
this->dropPreview.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NotebookPage::eventFilter(QObject *object, QEvent *event)
|
||||||
|
{
|
||||||
|
if (event->type() == QEvent::FocusIn) {
|
||||||
|
QFocusEvent *focusEvent = static_cast<QFocusEvent *>(event);
|
||||||
|
|
||||||
|
this->refreshCurrentFocusCoordinates((focusEvent->reason() == Qt::MouseFocusReason));
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void NotebookPage::paintEvent(QPaintEvent *)
|
void NotebookPage::paintEvent(QPaintEvent *)
|
||||||
{
|
{
|
||||||
QPainter painter(this);
|
QPainter painter(this);
|
||||||
|
@ -259,6 +371,14 @@ void NotebookPage::paintEvent(QPaintEvent *)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NotebookPage::showEvent(QShowEvent *event)
|
||||||
|
{
|
||||||
|
// Whenever this notebook page is shown, give focus to the last focused chat widget
|
||||||
|
// If this is the first time this notebook page is shown, it will give focus to the top-left
|
||||||
|
// chat widget
|
||||||
|
this->requestFocus(this->currentX, this->currentY);
|
||||||
|
}
|
||||||
|
|
||||||
static std::pair<int, int> getWidgetPositionInLayout(QLayout *layout, const ChatWidget *chatWidget)
|
static std::pair<int, int> getWidgetPositionInLayout(QLayout *layout, const ChatWidget *chatWidget)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < layout->count(); ++i) {
|
for (int i = 0; i < layout->count(); ++i) {
|
||||||
|
|
|
@ -44,9 +44,19 @@ public:
|
||||||
static ChatWidget *draggingSplit;
|
static ChatWidget *draggingSplit;
|
||||||
static std::pair<int, int> dropPosition;
|
static std::pair<int, int> dropPosition;
|
||||||
|
|
||||||
|
int currentX = 0;
|
||||||
|
int currentY = 0;
|
||||||
|
std::map<int, int> lastRequestedY;
|
||||||
|
|
||||||
|
void refreshCurrentFocusCoordinates(bool alsoSetLastRequested = false);
|
||||||
|
void requestFocus(int x, int y);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
virtual bool eventFilter(QObject *object, QEvent *event) override;
|
||||||
virtual void paintEvent(QPaintEvent *) override;
|
virtual void paintEvent(QPaintEvent *) override;
|
||||||
|
|
||||||
|
virtual void showEvent(QShowEvent *) override;
|
||||||
|
|
||||||
virtual void enterEvent(QEvent *) override;
|
virtual void enterEvent(QEvent *) override;
|
||||||
virtual void leaveEvent(QEvent *) override;
|
virtual void leaveEvent(QEvent *) override;
|
||||||
virtual void mouseReleaseEvent(QMouseEvent *event) override;
|
virtual void mouseReleaseEvent(QMouseEvent *event) override;
|
||||||
|
|
Loading…
Reference in a new issue