Browse Source

Add string::positionToLocation() and positionToLocation(). Handle up/down keys in TextField.

tags/v2.6.6
Andrew Belt 3 months ago
parent
commit
4eb3cf3533
3 changed files with 67 additions and 0 deletions
  1. +10
    -0
      include/string.hpp
  2. +46
    -0
      src/string.cpp
  3. +11
    -0
      src/ui/TextField.cpp

+ 10
- 0
include/string.hpp View File

@@ -47,6 +47,16 @@ bool startsWith(const std::string& str, const std::string& prefix);
/** Returns whether a string ends with the given substring. */
bool endsWith(const std::string& str, const std::string& suffix);

struct Location {
/** Line number, 0-indexed */
size_t line;
/** UTF-8 codepoint index, 0-indexed */
size_t column;
};
/** Given a byte position of s, returns the 2D UTF-8 location of the cursor. */
Location positionToLocation(const std::string& s, size_t pos);
size_t locationToPosition(const std::string& s, Location location);

/** Converts a byte array to a Base64-encoded string.
https://en.wikipedia.org/wiki/Base64
*/


+ 46
- 0
src/string.cpp View File

@@ -155,6 +155,52 @@ bool endsWith(const std::string& str, const std::string& suffix) {
}


Location positionToLocation(const std::string& s, size_t pos) {
if (pos > s.size())
pos = s.size();

// Count number of newlines until pos
size_t line = 0;
size_t linePos = 0;
for (size_t i = 0; i < pos; i++) {
if (s[i] == '\n') {
line++;
linePos = i + 1;
}
}

// Count number of codepoints from line until pos
size_t column = 0;
for (size_t i = linePos; i < pos;) {
i = UTF8NextCodepoint(s, i);
column++;
}

return {line, column};
}


size_t locationToPosition(const std::string& s, Location location) {
size_t pos = 0;

// Advance `location.line` newlines
for (size_t lines = 0; lines < location.line && pos < s.size(); pos++) {
if (s[pos] == '\n')
lines++;
}

// Advance `location.column` codepoints
for (size_t columns = 0; columns < location.column && pos < s.size(); columns++) {
// Stop if column is beyond newline
if (s[pos] == '\n')
break;
pos = UTF8NextCodepoint(s, pos);
}

return pos;
}


std::string toBase64(const uint8_t* data, size_t dataLen) {
static const char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";



+ 11
- 0
src/ui/TextField.cpp View File

@@ -198,10 +198,21 @@ void TextField::onSelectKey(const SelectKeyEvent& e) {
}
// Up (placeholder)
if (e.isKeyCommand(GLFW_KEY_UP)) {
string::Location location = string::positionToLocation(text, cursor);
if (location.line == 0)
location.column = 0;
else
location.line--;
cursor = locationToPosition(text, location);
selection = cursor;
e.consume(this);
}
// Down (placeholder)
if (e.isKeyCommand(GLFW_KEY_DOWN)) {
string::Location location = string::positionToLocation(text, cursor);
location.line++;
cursor = locationToPosition(text, location);
selection = cursor;
e.consume(this);
}
// Home


Loading…
Cancel
Save