~aleteoryx/muditaos

ref: 11f39b1caf15de0d5366b7d2d43567370b8dced6 muditaos/module-gui/gui/widgets/TextLineCursor.cpp -rw-r--r-- 3.1 KiB
11f39b1c — PrzeBrudny [EGD-4517] Added Text Up/Down navigation with tests. (#1089) 5 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "TextLineCursor.hpp"
#include "Text.hpp"
#include "log/log.hpp"

#define debug_text_cursor(...)
// #define debug_text_cursor(...) LOG_DEBUG(__VA_ARGS__)

gui::TextLineCursor::TextLineCursor(gui::Text *parent, unsigned int pos, unsigned int block)
    : TextCursor(parent, pos, block)
{}

auto gui::TextLineCursor::moveCursor(gui::NavigationDirection direction) -> gui::TextCursor::Move
{
    debug_text_cursor("Before move cursor: screen pos: %d block: %d pos: %d %s",
                      pos_on_screen,
                      getBlockNr(),
                      BlockCursor::getPosition(),
                      atBegin() ? "at begin" : "middle");

    if (!checkDocument()) {
        return Move::Error;
    }

    auto [selectedLine, selectedLineCursorPos, selectedLineNr] = getSelectedLine();

    /// up - corner case
    if ((checkNpos() || (direction == NavigationDirection::UP && selectedLineNr == 0))) {
        return Move::Start;
    }

    /// down - corner case
    if ((checkNpos() || (direction == NavigationDirection::DOWN && selectedLineNr == text->lines->size() - 1))) {
        return Move::End;
    }

    if (direction == NavigationDirection::UP) {

        auto previousLine            = text->lines->getLine(selectedLineNr - 1);
        auto previousLineEndAddition = previousLine->getEnd() == TextBlock::End::Newline ? 1 : 0;

        auto previousLineMoveCount = previousLine->length() > selectedLineCursorPos
                                         ? previousLine->length() - previousLineEndAddition - selectedLineCursorPos
                                         : 0;

        auto moveCount = selectedLineCursorPos + previousLineEndAddition + previousLineMoveCount;

        TextCursor::moveCursor(NavigationDirection::LEFT, moveCount);

        debug_text_cursor("After move cursor: screen pos: %d block: %d pos: %d %s",
                          pos_on_screen,
                          getBlockNr(),
                          BlockCursor::getPosition(),
                          atBegin() ? "at begin" : "middle");

        return Move::Up;
    }

    if (direction == NavigationDirection::DOWN) {

        auto nextLine            = text->lines->getLine(selectedLineNr + 1);
        auto nextLineEndAddition = nextLine->getEnd() == TextBlock::End::Newline ? 1 : 0;

        auto nextLineMoveCount = nextLine->length() > selectedLineCursorPos ? selectedLineCursorPos
                                                                            : nextLine->length() - nextLineEndAddition;

        auto moveCount = (selectedLine->length() - selectedLineCursorPos) + nextLineMoveCount;

        TextCursor::moveCursor(NavigationDirection::RIGHT, moveCount);

        debug_text_cursor("After move cursor: screen pos: %d block: %d pos: %d %s",
                          pos_on_screen,
                          getBlockNr(),
                          BlockCursor::getPosition(),
                          atBegin() ? "at begin" : "middle");

        return Move::Down;
    }

    return TextCursor::moveCursor(direction);
}