From 406229eb9f239f84d03393a4559430dbaa4b5856 Mon Sep 17 00:00:00 2001 From: nakst <> Date: Fri, 17 Sep 2021 16:45:27 +0100 Subject: [PATCH] improve scrolling on elements with borders --- desktop/gui.cpp | 32 +++++++++++++++++--------------- desktop/os.header | 2 +- desktop/text.cpp | 2 +- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/desktop/gui.cpp b/desktop/gui.cpp index 162de9a..ebabf51 100644 --- a/desktop/gui.cpp +++ b/desktop/gui.cpp @@ -160,6 +160,10 @@ struct EsElement : EsElementPublic { return m.zOrder.child; } + inline EsRectangle GetInternalOffset() { + return ES_RECT_4(internalOffsetLeft, internalOffsetRight, internalOffsetTop, internalOffsetBottom); + } + void BringToFront() { for (uintptr_t i = 0; i < parent->children.Length(); i++) { if (parent->children[i] == this) { @@ -2902,21 +2906,23 @@ void ScrollPane::Refresh() { SetPosition(0, position[0], true); SetPosition(1, position[1], true); + EsRectangle border = parent->currentStyle->borders; + if (bar[0]) { - bar[0]->InternalMove(parent->width - parent->internalOffsetRight, bar[0]->currentStyle->preferredHeight, - 0, parent->height - parent->internalOffsetBottom); + bar[0]->InternalMove(parent->width - parent->internalOffsetRight - border.r - border.l, bar[0]->currentStyle->preferredHeight, + border.l, parent->height - parent->internalOffsetBottom - border.b); enabled[0] = ~bar[0]->flags & ES_ELEMENT_DISABLED; } if (bar[1]) { - bar[1]->InternalMove(bar[1]->currentStyle->preferredWidth, parent->height - parent->internalOffsetBottom, - parent->width - parent->internalOffsetRight, 0); + bar[1]->InternalMove(bar[1]->currentStyle->preferredWidth, parent->height - parent->internalOffsetBottom - border.b - border.t, + parent->width - parent->internalOffsetRight - border.r, border.t); enabled[1] = ~bar[1]->flags & ES_ELEMENT_DISABLED; } if (pad) { pad->InternalMove(parent->internalOffsetRight, parent->internalOffsetBottom, - parent->width - parent->internalOffsetRight, parent->height - parent->internalOffsetBottom); + parent->width - parent->internalOffsetRight - border.r, parent->height - parent->internalOffsetBottom - border.b); } } @@ -6092,21 +6098,17 @@ void EsElementRepaint(EsElement *element, const EsRectangle *region) { else element->Repaint(true /* repaint all */); } -void EsElementRepaintForScroll(EsElement *element, EsMessage *message) { - // TODO Support custom border sizes. - - EsRectangle borders = ES_RECT_4(element->internalOffsetLeft, element->internalOffsetRight, - element->internalOffsetTop, element->internalOffsetBottom); - EsRectangle content = ES_RECT_4(borders.l, element->width - borders.r, borders.t, element->height - borders.b); +void EsElementRepaintForScroll(EsElement *element, EsMessage *message, EsRectangle border) { + EsRectangle content = ES_RECT_4(border.l, element->width - border.r, border.t, element->height - border.b); EsRectangle repaint = content; int64_t delta = message->scrollbarMoved.scroll - message->scrollbarMoved.previous; if (message->type == ES_MSG_SCROLL_Y) { - if (delta > 0) repaint.t = element->height - delta - borders.b; - else repaint.b = borders.t - delta; + if (delta > 0) repaint.t = element->height - delta - border.b; + else repaint.b = border.t - delta; } else if (message->type == ES_MSG_SCROLL_X) { - if (delta > 0) repaint.l = element->width - delta - borders.r; - else repaint.r = borders.l - delta; + if (delta > 0) repaint.l = element->width - delta - border.r; + else repaint.r = border.l - delta; } else { EsAssert(false); } diff --git a/desktop/os.header b/desktop/os.header index c3c3f71..9222442 100644 --- a/desktop/os.header +++ b/desktop/os.header @@ -2321,7 +2321,7 @@ function bool EsElementIsHidden(EsElement *element); function void EsElementSetCallback(EsElement *element, EsUICallback callback); function void EsElementGetSize(EsElement *element, int *width, int *height); function void EsElementRepaint(EsElement *element, const EsRectangle *region = ES_NULL); // Mark an element to be repainted. If region is null, then the whole element is repainted. -function void EsElementRepaintForScroll(EsElement *element, EsMessage *message); // Minimal repaint for ES_MSG_SCROLL_X/Y. +function void EsElementRepaintForScroll(EsElement *element, EsMessage *message, EsRectangle border); // Minimal repaint for ES_MSG_SCROLL_X/Y. function void EsElementRelayout(EsElement *element); function void EsElementSetCellRange(EsElement *element, int xFrom, int yFrom, int xTo = -1, int yTo = -1); // Use only if the parent is a ES_PANEL_TABLE. function EsRectangle EsElementGetInsets(EsElement *element); diff --git a/desktop/text.cpp b/desktop/text.cpp index e437d01..c2b6b9a 100644 --- a/desktop/text.cpp +++ b/desktop/text.cpp @@ -4634,7 +4634,7 @@ int ProcessTextboxMessage(EsElement *element, EsMessage *message) { TextboxSetHorizontalScroll(textbox, message->scrollbarMoved.scroll); } else if (message->type == ES_MSG_SCROLL_Y) { TextboxRefreshVisibleLines(textbox, false); - EsElementRepaintForScroll(textbox, message); + EsElementRepaintForScroll(textbox, message, EsRectangleAdd(element->GetInternalOffset(), element->currentStyle->borders)); } else if (message->type == ES_MSG_GET_INSPECTOR_INFORMATION) { DocumentLine *firstLine = &textbox->lines.First(); EsBufferFormat(message->getContent.buffer, "'%s'", firstLine->lengthBytes, firstLine->GetBuffer(textbox));