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));
|
||||
|
||||
this->channelNameUpdated(this->channelName.getValue());
|
||||
|
||||
this->input.textInput.installEventFilter(parent);
|
||||
}
|
||||
|
||||
ChatWidget::~ChatWidget()
|
||||
|
@ -193,9 +195,14 @@ void ChatWidget::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 *)
|
||||
|
|
|
@ -53,7 +53,8 @@ public:
|
|||
void layoutMessages(bool forceUpdate = false);
|
||||
void updateGifEmotes();
|
||||
|
||||
void giveFocus();
|
||||
void giveFocus(Qt::FocusReason reason);
|
||||
bool hasFocus() const;
|
||||
|
||||
pajlada::Settings::Setting<std::string> channelName;
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "colorscheme.hpp"
|
||||
#include "completionmanager.hpp"
|
||||
#include "ircmanager.hpp"
|
||||
#include "notebookpage.hpp"
|
||||
#include "settingsmanager.hpp"
|
||||
|
||||
#include <QCompleter>
|
||||
|
@ -71,17 +72,61 @@ ChatWidgetInput::ChatWidgetInput(ChatWidget *_chatWidget)
|
|||
}
|
||||
prevIndex = prevMsg.size();
|
||||
} else if (event->key() == Qt::Key_Up) {
|
||||
if (prevMsg.size() && prevIndex) {
|
||||
prevIndex--;
|
||||
textInput.setText(prevMsg.at(prevIndex));
|
||||
if (event->modifiers() == Qt::AltModifier) {
|
||||
NotebookPage *page = static_cast<NotebookPage *>(this->chatWidget->parentWidget());
|
||||
|
||||
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) {
|
||||
if (prevIndex != (prevMsg.size() - 1) && prevIndex != prevMsg.size()) {
|
||||
prevIndex++;
|
||||
textInput.setText(prevMsg.at(prevIndex));
|
||||
if (event->modifiers() == Qt::AltModifier) {
|
||||
NotebookPage *page = static_cast<NotebookPage *>(this->chatWidget->parentWidget());
|
||||
|
||||
int reqX = page->currentX;
|
||||
int reqY = page->lastRequestedY[reqX] + 1;
|
||||
|
||||
qDebug() << "Alt+Down to" << reqX << "/" << reqY;
|
||||
|
||||
page->requestFocus(reqX, reqY);
|
||||
} else {
|
||||
prevIndex = prevMsg.size();
|
||||
textInput.setText(QString());
|
||||
if (prevIndex != (prevMsg.size() - 1) && prevIndex != prevMsg.size()) {
|
||||
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 *)
|
||||
{
|
||||
this->chatWidget->giveFocus();
|
||||
this->chatWidget->giveFocus(Qt::MouseFocusReason);
|
||||
}
|
||||
|
||||
} // namespace widgets
|
||||
|
|
|
@ -339,7 +339,7 @@ void ChatWidgetView::mousePressEvent(QMouseEvent *event)
|
|||
this->isMouseDown = true;
|
||||
this->lastPressPosition = event->screenPos();
|
||||
|
||||
this->chatWidget->giveFocus();
|
||||
this->chatWidget->giveFocus(Qt::MouseFocusReason);
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
this->chatWidgets.push_back(widget);
|
||||
widget->giveFocus();
|
||||
widget->giveFocus(Qt::MouseFocusReason);
|
||||
|
||||
// add vbox at the end
|
||||
if (position.first < 0 || position.first >= this->ui.hbox.count()) {
|
||||
|
@ -90,6 +90,7 @@ void NotebookPage::addToLayout(ChatWidget *widget,
|
|||
vbox->addWidget(widget);
|
||||
|
||||
this->ui.hbox.addLayout(vbox, 1);
|
||||
this->refreshCurrentFocusCoordinates();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -99,6 +100,7 @@ void NotebookPage::addToLayout(ChatWidget *widget,
|
|||
vbox->addWidget(widget);
|
||||
|
||||
this->ui.hbox.insertLayout(position.first, vbox, 1);
|
||||
this->refreshCurrentFocusCoordinates();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -106,6 +108,8 @@ void NotebookPage::addToLayout(ChatWidget *widget,
|
|||
auto vbox = static_cast<QVBoxLayout *>(this->ui.hbox.itemAt(position.first));
|
||||
|
||||
vbox->insertWidget(std::max(0, std::min(vbox->count(), position.second)), widget);
|
||||
|
||||
this->refreshCurrentFocusCoordinates();
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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 *)
|
||||
{
|
||||
if (this->ui.hbox.count() == 0) {
|
||||
|
@ -240,6 +341,17 @@ void NotebookPage::dropEvent(QDropEvent *event)
|
|||
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 *)
|
||||
{
|
||||
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)
|
||||
{
|
||||
for (int i = 0; i < layout->count(); ++i) {
|
||||
|
|
|
@ -44,9 +44,19 @@ public:
|
|||
static ChatWidget *draggingSplit;
|
||||
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:
|
||||
virtual bool eventFilter(QObject *object, QEvent *event) override;
|
||||
virtual void paintEvent(QPaintEvent *) override;
|
||||
|
||||
virtual void showEvent(QShowEvent *) override;
|
||||
|
||||
virtual void enterEvent(QEvent *) override;
|
||||
virtual void leaveEvent(QEvent *) override;
|
||||
virtual void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
|
|
Loading…
Reference in a new issue