Skip to content

Commit

Permalink
Ability to move buffer cursor using mouse clicks.
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolasnoble committed Aug 22, 2021
1 parent 249dafe commit fe2a6a4
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 3 deletions.
2 changes: 2 additions & 0 deletions include/zep/window.h
Expand Up @@ -241,6 +241,8 @@ class ZepWindow : public ZepComponent
// Cursor
GlyphIterator m_bufferCursor; // Location in buffer coordinates. Each window has a different buffer cursor
long m_lastCursorColumn = 0; // The last cursor column (could be removed and recalculated)
NVec2f m_mousePos; // Current mouse location
GlyphIterator m_mouseIterator; // Current iterator for the mouse cursor

// Visual stuff
std::vector<std::string> m_statusLines; // Status information, shown under the buffer
Expand Down
34 changes: 31 additions & 3 deletions src/window.cpp
Expand Up @@ -211,6 +211,7 @@ void ZepWindow::Notify(std::shared_ptr<ZepMessage> payload)
}
else if (payload->messageId == Msg::MouseMove)
{
m_mousePos = payload->pos;
if (!m_toolTips.empty())
{
if (ManhattanDistance(m_mouseHoverPos, payload->pos) > 4.0f)
Expand All @@ -232,6 +233,13 @@ void ZepWindow::Notify(std::shared_ptr<ZepMessage> payload)
{
m_layoutDirty = true;
}
else if (payload->messageId == Msg::MouseDown)
{
if (payload->button == ZepMouseButton::Left && m_textRegion->rect.Contains(m_mousePos) && m_mouseIterator.Valid())
{
SetBufferCursor(m_mouseIterator);
}
}
}

void ZepWindow::SetDisplayRegion(const NRectf& region)
Expand Down Expand Up @@ -1109,30 +1117,44 @@ bool ZepWindow::DisplayLine(SpanInfo& lineInfo, int displayPass)
auto dotSize = display.GetFont(ZepTextType::Text).GetDotSize();
auto whiteSpaceCol = m_pBuffer->GetTheme().GetColor(ThemeColor::Whitespace);
auto widgetMargins = DPI_VEC2(GetEditor().GetConfig().widgetMargins);
auto height = lineInfo.FullLineHeightPx();
bool isLineHovered = false;

// Drawing commands for the whole line
if (displayPass == WindowPass::Background)
{
display.SetClipRect(m_textRegion->rect);
DisplayLineBackground(lineInfo, pSyntax);
NRectf lineRect(NVec2f(m_textRegion->rect.Left(), ToWindowY(lineInfo.yOffsetPx)), NVec2f(m_textRegion->rect.Right(), ToWindowY(lineInfo.yOffsetPx + height)));
isLineHovered = lineRect.Contains(m_mousePos);
}

display.SetClipRect(m_textRegion->rect);

bool lineStart = true;
bool hasBeenHovered = false;

// Walk from the start of the line to the end of the line (in buffer chars)
for (auto cp : lineInfo.lineCodePoints)
for (auto& cp : lineInfo.lineCodePoints)
{
const uint8_t* pCh;
const uint8_t* pEnd;
SpecialChar special;
GetCharPointer(cp.iterator, pCh, pEnd, special);
bool isHovered = false;
bool isLast = &cp == &lineInfo.lineCodePoints.back();

// TODO : Cache this for speed - a little sluggish on debug builds.
if (displayPass == WindowPass::Background)
{
NRectf charRect(NVec2f(cp.pos.x, ToWindowY(lineInfo.yOffsetPx)), NVec2f(cp.pos.x + cp.size.x, ToWindowY(lineInfo.yOffsetPx + lineInfo.FullLineHeightPx())));
NRectf charRect(NVec2f(cp.pos.x, ToWindowY(lineInfo.yOffsetPx)), NVec2f(cp.pos.x + cp.size.x, ToWindowY(lineInfo.yOffsetPx + height)));
if (charRect.Contains(m_mousePos) || (isLast && !hasBeenHovered && isLineHovered))
{
m_mouseIterator = cp.iterator;
isHovered = true;
hasBeenHovered = true;
}

if (charRect.Contains(m_mouseHoverPos))
{
// Record the mouse-over buffer location
Expand All @@ -1157,7 +1179,6 @@ bool ZepWindow::DisplayLine(SpanInfo& lineInfo, int displayPass)
// If active window and this is the cursor char then display the marker as a priority over what we would have shown
if (IsActiveWindow() && (cp.iterator == m_bufferCursor) && (!cursorBlink || cursorType == CursorType::LineMarker))
{
auto height = lineInfo.FullLineHeightPx();
switch (cursorType)
{
default:
Expand Down Expand Up @@ -1196,6 +1217,13 @@ bool ZepWindow::DisplayLine(SpanInfo& lineInfo, int displayPass)
break;
}
}
else if (isHovered)
{
GetEditor().GetDisplay().DrawRectFilled(NRectf(
NVec2f(cp.pos.x, ToWindowY(lineInfo.yOffsetPx)),
NVec2f(cp.pos.x + cp.size.x, ToWindowY(lineInfo.yOffsetPx + height))),
m_pBuffer->GetTheme().GetColor(ThemeColor::AirlineBackground));
}
}
// Second pass, characters
else
Expand Down

0 comments on commit fe2a6a4

Please sign in to comment.