diff options
Diffstat (limited to 'src/ui/inputwidget.c')
-rw-r--r-- | src/ui/inputwidget.c | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/src/ui/inputwidget.c b/src/ui/inputwidget.c index 8ed52022..bd6927a6 100644 --- a/src/ui/inputwidget.c +++ b/src/ui/inputwidget.c | |||
@@ -39,7 +39,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
39 | # include "macos.h" | 39 | # include "macos.h" |
40 | #endif | 40 | #endif |
41 | 41 | ||
42 | static const int refreshInterval_InputWidget_ = 256; | 42 | static const int refreshInterval_InputWidget_ = 512; |
43 | static const size_t maxUndo_InputWidget_ = 64; | 43 | static const size_t maxUndo_InputWidget_ = 64; |
44 | static const int unlimitedWidth_InputWidget_ = 1000000; /* TODO: WrapText disables some functionality if maxWidth==0 */ | 44 | static const int unlimitedWidth_InputWidget_ = 1000000; /* TODO: WrapText disables some functionality if maxWidth==0 */ |
45 | 45 | ||
@@ -216,6 +216,7 @@ struct Impl_InputWidget { | |||
216 | iArray undoStack; | 216 | iArray undoStack; |
217 | int font; | 217 | int font; |
218 | iClick click; | 218 | iClick click; |
219 | int wheelAccum; | ||
219 | int cursorVis; | 220 | int cursorVis; |
220 | uint32_t timer; | 221 | uint32_t timer; |
221 | iTextBuf * buffered; /* pre-rendered static text */ | 222 | iTextBuf * buffered; /* pre-rendered static text */ |
@@ -600,6 +601,7 @@ void init_InputWidget(iInputWidget *d, size_t maxLen) { | |||
600 | splitToLines_(&iStringLiteral(""), &d->lines); | 601 | splitToLines_(&iStringLiteral(""), &d->lines); |
601 | setFlags_Widget(w, fixedHeight_WidgetFlag, iTrue); /* resizes its own height */ | 602 | setFlags_Widget(w, fixedHeight_WidgetFlag, iTrue); /* resizes its own height */ |
602 | init_Click(&d->click, d, SDL_BUTTON_LEFT); | 603 | init_Click(&d->click, d, SDL_BUTTON_LEFT); |
604 | d->wheelAccum = 0; | ||
603 | d->timer = 0; | 605 | d->timer = 0; |
604 | d->cursorVis = 0; | 606 | d->cursorVis = 0; |
605 | d->buffered = NULL; | 607 | d->buffered = NULL; |
@@ -1467,6 +1469,31 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { | |||
1467 | ? SDL_SYSTEM_CURSOR_IBEAM | 1469 | ? SDL_SYSTEM_CURSOR_IBEAM |
1468 | : SDL_SYSTEM_CURSOR_ARROW); | 1470 | : SDL_SYSTEM_CURSOR_ARROW); |
1469 | } | 1471 | } |
1472 | if (ev->type == SDL_MOUSEWHEEL && contains_Widget(w, coord_MouseWheelEvent(&ev->wheel))) { | ||
1473 | const int lineHeight = lineHeight_Text(d->font); | ||
1474 | if (isPerPixel_MouseWheelEvent(&ev->wheel)) { | ||
1475 | d->wheelAccum -= ev->wheel.y; | ||
1476 | } | ||
1477 | else { | ||
1478 | d->wheelAccum -= ev->wheel.y * 3 * lineHeight; | ||
1479 | } | ||
1480 | int lineDelta = d->wheelAccum / lineHeight; | ||
1481 | if (lineDelta < 0) { | ||
1482 | lineDelta = iMax(lineDelta, -d->visWrapLines.start); | ||
1483 | if (!lineDelta) d->wheelAccum = 0; | ||
1484 | } | ||
1485 | else if (lineDelta > 0) { | ||
1486 | lineDelta = iMin(lineDelta, | ||
1487 | lastLine_InputWidget_(d)->wrapLines.end - d->visWrapLines.end); | ||
1488 | if (!lineDelta) d->wheelAccum = 0; | ||
1489 | } | ||
1490 | d->wheelAccum -= lineDelta * lineHeight; | ||
1491 | d->visWrapLines.start += lineDelta; | ||
1492 | d->visWrapLines.end += lineDelta; | ||
1493 | d->inFlags |= needUpdateBuffer_InputWidgetFlag; | ||
1494 | refresh_Widget(d); | ||
1495 | return iTrue; | ||
1496 | } | ||
1470 | switch (processEvent_Click(&d->click, ev)) { | 1497 | switch (processEvent_Click(&d->click, ev)) { |
1471 | case none_ClickResult: | 1498 | case none_ClickResult: |
1472 | break; | 1499 | break; |
@@ -1497,6 +1524,7 @@ static iBool processEvent_InputWidget_(iInputWidget *d, const SDL_Event *ev) { | |||
1497 | selectAll_InputWidget(d); | 1524 | selectAll_InputWidget(d); |
1498 | } | 1525 | } |
1499 | } | 1526 | } |
1527 | refresh_Widget(d); | ||
1500 | return iTrue; | 1528 | return iTrue; |
1501 | } | 1529 | } |
1502 | case aborted_ClickResult: | 1530 | case aborted_ClickResult: |
@@ -1889,12 +1917,11 @@ static void draw_InputWidget_(const iInputWidget *d) { | |||
1889 | wrapText.wrapFunc = NULL; | 1917 | wrapText.wrapFunc = NULL; |
1890 | wrapText.context = NULL; | 1918 | wrapText.context = NULL; |
1891 | } | 1919 | } |
1892 | unsetClip_Paint(&p); | ||
1893 | /* Draw the insertion point. */ | 1920 | /* Draw the insertion point. */ |
1894 | if (isFocused && d->cursorVis) { | 1921 | if (isFocused && d->cursorVis && contains_Range(&visLines, d->cursor.y)) { |
1895 | iInt2 curSize; | 1922 | iInt2 curSize; |
1896 | iRangecc cursorChar = iNullRange; | 1923 | iRangecc cursorChar = iNullRange; |
1897 | int visWrapsAbove = 0; | 1924 | int visWrapsAbove = 0; |
1898 | for (int i = d->cursor.y - 1; i >= visLines.start; i--) { | 1925 | for (int i = d->cursor.y - 1; i >= visLines.start; i--) { |
1899 | const iInputLine *line = constAt_Array(&d->lines, i); | 1926 | const iInputLine *line = constAt_Array(&d->lines, i); |
1900 | visWrapsAbove += numWrapLines_InputLine_(line); | 1927 | visWrapsAbove += numWrapLines_InputLine_(line); |
@@ -1938,6 +1965,7 @@ static void draw_InputWidget_(const iInputWidget *d) { | |||
1938 | cursorChar); | 1965 | cursorChar); |
1939 | } | 1966 | } |
1940 | } | 1967 | } |
1968 | unsetClip_Paint(&p); | ||
1941 | drawChildren_Widget(w); | 1969 | drawChildren_Widget(w); |
1942 | } | 1970 | } |
1943 | 1971 | ||