mirror-chatterino2/src/messages/Selection.hpp
nerix 6860c7007e
Fix selection rendering (#4830)
The rendering of selections was not aligned to the actual selection that took place for newlines at the end of messages, if they were the only part that was selected of that message.

In addition to that fix, we've already refactored the MessageLayoutContainer to try to make it a little bit more sane to work with in the future.

Co-authored-by: Rasmus Karlsson <rasmus.karlsson@pajlada.com>
2023-09-23 15:09:56 +00:00

131 lines
2.9 KiB
C++

#pragma once
#include <cstddef>
#include <cstdint>
#include <tuple>
#include <utility>
namespace chatterino {
struct SelectionItem {
size_t messageIndex{0};
size_t charIndex{0};
SelectionItem() = default;
SelectionItem(size_t _messageIndex, size_t _charIndex)
: messageIndex(_messageIndex)
, charIndex(_charIndex)
{
}
bool operator<(const SelectionItem &b) const
{
return std::tie(this->messageIndex, this->charIndex) <
std::tie(b.messageIndex, b.charIndex);
}
bool operator>(const SelectionItem &b) const
{
return !this->operator==(b) && b.operator<(*this);
}
bool operator==(const SelectionItem &b) const
{
return this->messageIndex == b.messageIndex &&
this->charIndex == b.charIndex;
}
bool operator!=(const SelectionItem &b) const
{
return this->operator==(b);
}
};
struct Selection {
SelectionItem start;
SelectionItem end;
SelectionItem selectionMin;
SelectionItem selectionMax;
Selection() = default;
Selection(const SelectionItem &start, const SelectionItem &end)
: start(start)
, end(end)
, selectionMin(start)
, selectionMax(end)
{
if (selectionMin > selectionMax)
{
std::swap(this->selectionMin, this->selectionMax);
}
}
bool isEmpty() const
{
return this->start == this->end;
}
bool isSingleMessage() const
{
return this->selectionMin.messageIndex ==
this->selectionMax.messageIndex;
}
// Shift all message selection indices `offset` back
void shiftMessageIndex(size_t offset)
{
if (offset > this->selectionMin.messageIndex)
{
this->selectionMin.messageIndex = 0;
this->selectionMin.charIndex = 0;
}
else
{
this->selectionMin.messageIndex -= offset;
}
if (offset > this->selectionMax.messageIndex)
{
this->selectionMax.messageIndex = 0;
this->selectionMax.charIndex = 0;
}
else
{
this->selectionMax.messageIndex -= offset;
}
if (offset > this->start.messageIndex)
{
this->start.messageIndex = 0;
this->start.charIndex = 0;
}
else
{
this->start.messageIndex -= offset;
}
if (offset > this->end.messageIndex)
{
this->end.messageIndex = 0;
this->end.charIndex = 0;
}
else
{
this->end.messageIndex -= offset;
}
}
};
struct DoubleClickSelection {
uint32_t originalStart{0};
uint32_t originalEnd{0};
uint32_t origMessageIndex{0};
bool selectingLeft{false};
bool selectingRight{false};
SelectionItem origStartItem;
SelectionItem origEndItem;
};
} // namespace chatterino