despair 5 years ago
parent
commit
c1769edba8
  1. 2
      Makefile
  2. 23
      data.enc
  3. 198
      src/TextBlock.cpp
  4. 22
      src/TextBlock.h
  5. 2
      src/browser.h
  6. 16
      src/graphics/components/DocumentComponent.cpp
  7. 251
      src/graphics/components/InputComponent.cpp
  8. 33
      src/graphics/components/InputComponent.h
  9. 14
      src/graphics/components/TabbedComponent.cpp
  10. 2
      src/graphics/components/TextComponent.cpp
  11. 4
      src/graphics/components/TextComponent.h
  12. 17
      src/graphics/text/TextRasterizer.cpp
  13. 3
      src/graphics/text/TextRasterizer.h
  14. 2
      src/networking/HTTPSRequest.cpp
  15. 18
      src/scheduler.cpp

2
Makefile

@ -8,7 +8,7 @@ PLATFORM := $(shell g++ -dumpmachine) @@ -8,7 +8,7 @@ PLATFORM := $(shell g++ -dumpmachine)
CXXFLAGS = -O3 -flto=8 -std=c++14 -DVERSION=\"$(GIT_VERSION)\" -DPLATFORM=\"$(PLATFORM)\"
CFLAGS = -O3 -flto=8 -std=c11 -DVERSION=\"$(GIT_VERSION)\"
CWARN = -pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wredundant-decls -Wshadow -Wsign-conversion -Wstrict-overflow=5 -Wswitch-default -Wundef -Wno-unused
WARNINGS = -Werror -pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wnoexcept -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-null-sentinel -Wstrict-overflow=5 -Wswitch-default -Wundef -Wno-unused -Wzero-as-null-pointer-constant -Wuseless-cast
WARNINGS = -Werror -pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wnoexcept -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-null-sentinel -Wstrict-overflow=5 -Wswitch-default -Wundef -Wno-unused -Wzero-as-null-pointer-constant -Wuseless-cast -Wno-strict-overflow
LIBS = -lglfw -lGL -lGLEW -lfreetype -lharfbuzz -lmbedtls -lmbedcrypto -lmbedx509
LDFLAGS = -O3 -flto=8
INCPATH = -I /usr/include/freetype2 -I /usr/include/harfbuzz

23
data.enc

@ -1,23 +0,0 @@ @@ -1,23 +0,0 @@
U2FsdGVkX1/4+8vApHbadOQy2u2pTKM/QdBEzFjwwY3Irl8pUdduxTC2Oi/iusTu
7ERNdrinJBcvrWfU8PhWP9CcpTvq3b93OO/i0wBTyrrQk4MdETdb8xiH/JwnxfpT
yAOTKTNL8iLKXqXcIU8pVDlnrVQqCyY1xX+HJ8P6b82Y6d5Du0E6VucuCkwpWzI8
Wl/9FsFqJ0ODGB3TGzVzXGcYqKmbgDjed8eNxJcwghQ3WfADR9Cbhu2KvQepc7hM
PtKsHYi85iy3yqX9gS3+Mue/0LIaRJv84QnPYcBcs0+FokYYqt76O95ZF17/9jlf
yRXDH1MVg7C+VBJJj6NLAdKK8tYZgJbQKk7fecEWRiyjCPeFfWoLFwq1YIOujkzE
7QAfBuiCucG3L2TfIZnThfP1qHoXsxExTwT0nInJEudcMQsXliJFBGpri4+VrXvN
uIJltZv3e4XCMZrm3USi++KO42SQI+ngUzPwysHoOOSkgroOIETlhd3Vgy7pxDcH
s8ubehYxQvfE1lEOTwR37v3IcI3ruZtZZ8cPu00D2UXR64ByJ3NjCnFgcPF4Rw4B
QSEVJ6YAdlB5qL3W8WOgPmhiCKWu2X9pYech4x7TL4h3xf7gjVitH/W5IC6ez/dD
iFGaCACMYGaqvuEd/rg7oeh0oecbQYVvA4+C6ZKSD9a5Y2RqrySJiUpyu3cO783Z
uQ9npfkG4/rpLspktumoiG4eQq9cfP33UtnfUyCmmVGRwndCdU2kAhjWN/n3tO1L
oGTV9VdUjovK1mp6Yqod2PatsUmhIrsYI1YaRFzoTKpapKbpRtheKdwFlDtMSKlS
MZVQPEenzKm9AQq4858Fj7BVJCqDrgahhRrSXSNvUimykRNkjx8ZGAgNRUmgNWLQ
JnzEqPXeRBqKW+YB2C7nbdpGiQdlYzrE3zWnDZk7e8IddhZHZEzpgcNiwq2FhJlM
qfsEh+AIJQrvtoJgOz/i4k0P/WEb7rBWeQpf91juA+AqubfL1Zdx2ARbeK25FW+D
UhwPaC1HFmHFCoPF2yBg62ijRURRQ8SFtc6vrqA7j4CCygix6MrQq/dyba1KY//9
Blmg9QrF8JQQ9V7QkIxwXn+FfIesG04CLijhFAd/TreA6xgShQASPjyXOwYvosSq
aYyF/i1m1UjDEH+GAsw+1KuPnZCtyb8aCDgYB4XfgTfNYqEsNZ1D7FtwLeBItWJc
3IGNpmHJLcIlfXYd/BCX8nSRNwYyvpjqT9jRIPtgLygO3D1Mbg8F4GB00FPovxXr
jl0nhsGBbH0jELEPQErxl/uhroBJjss3p9lKHAC2syXrUh/UnA8Y9VdA49bm8oGj
kdkGRbebqgs2NauKdRy739ecQm8ALhNlYDYGuBio4RN4iVYIDV57mSqOCAQKb8af
mTmWKmsZSVe52hZdRNxl7U834+2ICWvKWkkzv5ot6Z4qj8fClU8mqw==

198
src/TextBlock.cpp

@ -0,0 +1,198 @@ @@ -0,0 +1,198 @@
#include "TextBlock.h"
#include <iostream>
void TextBlock::print() {
std::cout << "TextBlock::print - " << this->lines.size() << std::endl;
for(auto line: this->lines) {
std::cout << "[" << line << "]" << std::endl;
}
std::cout << "TextBlock::print - trailingNewline " << this->trailingNewline << std::endl;
}
// only safe to one char rn
void TextBlock::insertAt(std::string str, size_t x, size_t y) {
if (y > this->lines.size()) {
std::cout << "TextArea::insertCharAt - y: " << y << " lines: " << this->lines.size() << std::endl;
return;
}
if (!this->lines.size()) {
this->lines.push_back(str);
return;
}
if (x > this->lines[y].size()) {
this->lines[y] += str;
return;
}
// FIXME: search entire str for any \r
if (str == "\r") {
this->lines.push_back("");
// does this mean we need to insert one
// or that we have one?
// what problem was it originally trying to solve?
//this->trailingNewline = true;
// not sure what up's with this shit but it breaks a lot...
//this->setValue(this->getValue()); // in-efficient but should give a correctish algorithm
} else {
//std::cout << "TextBlock::insertAt - [" << this->lines[y].substr(0, x) << "]+[" << str << "]+[" << this->lines[y].substr(x) << "]" << std::endl;
this->lines[y] = this->lines[y].substr(0, x) + str + this->lines[y].substr(x);
}
//std::cout << "TextBlock::insertAt - lines: " << this->lines.size() << std::endl;
}
// only tested to one char atm
void TextBlock::deleteAt(size_t x, size_t y, size_t count) {
//std::cout << "TextBlock::deleteAt - start delete " << count << " chars @ " << x << "," << y << std::endl;
if (y > this->lines.size()) {
std::cout << "TextArea::deleteAt - y: " << y << " lines: " << this->lines.size() << std::endl;
return;
}
// could we just remove the if?
if (count) {
if (x == 0) {
if (y) {
//std::cout << "TextArea::deleteAt - y!=0, lines: " << this->lines.size() << std::endl;
if (y < this->lines.size()) {
//std::cout << "TextArea::deleteAt - nuked line [" << y << "] chars on line: " << this->lineLength(y) << std::endl;
if (this->lineLength(y)) {
this->trailingNewline = true;
}
this->lines.erase(this->lines.begin() + static_cast<int>(y));
return;
} else {
if (y == this->lines.size()) {
// delete the last line
if (this->trailingNewline) {
this->trailingNewline = false;
} else {
std::cout << "TextArea::deleteAt - do nothing" << std::endl;
}
return;
}
std::cout << "TextArea::deleteAt - requesting deletion at " << x << "," << y << " but only " << this->lines.size() << std::endl;
}
} // else we're at 0,0 deleting a char
}
if (x >= this->lineLength(y)) {
//std::cout << "TextArea::deleteAt - x == lineLength [" << this->lines[y].substr(0, x - 1) << "]" << std::endl;
if (x) {
this->lines[y] = this->lines[y].substr(0, x - 1);
} else {
this->trailingNewline = false;
}
} else {
if (x) {
if (x == this->lineLength(y) - 1) {
//std::cout << "TextArea::deleteAt - endOfLine [" << this->lines[y].substr(0, x) << "]+[" << this->lines[y].substr(x + count) << "]" << std::endl;
this->lines[y] = this->lines[y].substr(0, x) + this->lines[y].substr(x + count);
} else {
//std::cout << "TextArea::deleteAt - x>0 [" << this->lines[y].substr(0, x) << "]+[" << this->lines[y].substr(x + count) << "]" << std::endl;
this->lines[y] = this->lines[y].substr(0, x) + this->lines[y].substr(x + count);
}
} else {
//std::cout << "TextArea::deleteAt - x@0 [" << this->lines[y].substr(x + count) << "]" << std::endl;
this->lines[y] = this->lines[y].substr(x + count);
}
}
} else {
this->lines[y] = this->lines[y].substr(0, x);
}
}
size_t TextBlock::setValue(std::string value) {
// split on \n
std::string delimiter(1, '\r');
this->lines.clear();
size_t pos = 0;
size_t lPos = 0;
size_t tLines = 0; // start at 0 (should this start at 1?)
this->trailingNewline = false;
while ((pos = value.find(delimiter, lPos)) != std::string::npos) {
//std::cout << "TextBlock::setValue pushing [" << value.substr(lPos, pos) << "]" << std::endl;
std::string token = value.substr(lPos, pos);
if (token[token.size() - 1] == '\r') {
token.pop_back();
//std::cout << "TextBlock::setValue adjusted [" << token << "]" << std::endl;
//std::cout << "lPos: " << lPos << " pos: " << pos << " size: " << value.size() << std::endl;
if (pos == value.size() - 1) {
//std::cout << "TextBlock::setValue - enabling trailing line" << std::endl;
this->trailingNewline = true;
}
}
this->lines.push_back(token);
//value.erase(0, pos + delimiter.length());
lPos = pos + delimiter.length();
tLines++;
}
//std::cout << "lPos: " << lPos << " pos: " << pos << " size: " << value.size() << " last: [" << value.substr(lPos) << "]" << std::endl;
// if we're not at the end of the string, we don't end on a trailing slash
// lPos == value.size()? true :
if (value.substr(lPos) != "") {
//std::cout << "Pushing back [" << value.substr(lPos) << "]" << std::endl;
this->lines.push_back(value.substr(lPos));
} else {
if (lPos == 1) {
this->trailingNewline = true;
}
}
return tLines;
}
std::string TextBlock::getValue() {
std::string value;
for(auto s : this->lines) {
value += s + '\r';
}
//std::cout << "TextBlock::getValue before strip[" << !this->trailingNewline << "] [" << value << "] lines[" << this->lines.size() << "]" << std::endl;
if (!this->trailingNewline) {
value.pop_back();
}
return value;
}
std::string TextBlock::getValueUpTo(size_t x, size_t y) {
std::string value;
if (y && this->lines.size()) {
for(size_t cy = 0; cy < y; cy++) {
value += this->lines[cy] + "\r";
}
// we don't want this because 1st char on the 2nd line breaks
/*
// if we're not at the start of a new line, remove the newline
if (this->lineLength(y)) {
std::cout << "TextBlock::getValueUpTo - removing added newline because this line has text" << std::endl;
value.pop_back();
}
*/
//std::cout << "TextBlock::getValueUpTo y read[" << value << "]" << std::endl;
}
if (x) {
//std::cout << "TextBlock::getValueUpTo value pre x [" << value << "]" << std::endl;
value += this->lines[y].substr(0, x);
//std::cout << "TextBlock::getValueUpTo x [" << value << "]" << std::endl;
}
//std::cout << "TextBlock::getValueUpTo trailingNewline: " << this->trailingNewline << std::endl;
/*
if (this->trailingNewline) {
// and we're at the end of the last line
//std::cout << "lines: " << this->lines.size() << " lineLength: " << this->lineLength(y) << std::endl;
// x can't be at the start of the line
//if (y == this->lines.size() - 1 && x == this->lineLength(y) && x) {
//std::cout << "TextBlock::getValueUpTo adding a trailingNewline" << std::endl;
//value += "\r";
//}
}
*/
return value;
}
size_t TextBlock::lineLength(size_t y) {
if (y >= this->lines.size()) {
if (!this->trailingNewline) {
std::cout << "TextArea::lengthLine - y: " << y << " lines: " << this->lines.size() << std::endl;
}
return 0;
}
return this->lines[y].size();
}

22
src/TextBlock.h

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
#ifndef TEXTBLOCK_H
#define TEXTBLOCK_H
#include <string>
#include <vector>
class TextBlock {
public:
// methods
void print();
void insertAt(std::string str, size_t x, size_t y);
void deleteAt(size_t x, size_t y, size_t count);
std::string getValue();
std::string getValueUpTo(size_t x, size_t y);
size_t setValue(std::string value);
size_t lineLength(size_t y);
// properties
std::vector<std::string> lines;
bool trailingNewline = false;
};
#endif

2
src/browser.h

@ -55,6 +55,4 @@ public: @@ -55,6 +55,4 @@ public:
//bool setWindowContent(URL const& url);
//void handleRequest(const HTTPResponse &response);
extern const std::unique_ptr<Window> window;
#endif

16
src/graphics/components/DocumentComponent.cpp

@ -171,6 +171,7 @@ DocumentComponent::DocumentComponent(const float rawX, const float rawY, const f @@ -171,6 +171,7 @@ DocumentComponent::DocumentComponent(const float rawX, const float rawY, const f
lineData = getLine(focusedInputComponent->value, 1);
std::cout << "line 1 is " << focusedInputComponent->value.substr(lineData.first, lineData.second) << " start: " << lineData.first << " end: " << lineData.second << std::endl;
*/
/*
if (focusedInputComponent->multiLine) {
//std::pair<int, int> lineData = getLine(focusedInputComponent->value, 0);
focusedInputComponent->cursorCharY--;
@ -181,8 +182,10 @@ DocumentComponent::DocumentComponent(const float rawX, const float rawY, const f @@ -181,8 +182,10 @@ DocumentComponent::DocumentComponent(const float rawX, const float rawY, const f
} else {
focusedInputComponent->cursorCharX = 0;
}
focusedInputComponent->updateCursor();
*/
focusedInputComponent->updateCursor(0, -1);
} else if (key == GLFW_KEY_DOWN) {
/*
if (focusedInputComponent->multiLine) {
//std::pair<int, int> lineData = getLine(focusedInputComponent->value, 0);
focusedInputComponent->cursorCharY++;
@ -194,8 +197,10 @@ DocumentComponent::DocumentComponent(const float rawX, const float rawY, const f @@ -194,8 +197,10 @@ DocumentComponent::DocumentComponent(const float rawX, const float rawY, const f
} else {
focusedInputComponent->cursorCharX = focusedInputComponent->getValue().size();
}
focusedInputComponent->updateCursor();
*/
focusedInputComponent->updateCursor(0, 1);
} else if (key == GLFW_KEY_LEFT) {
/*
focusedInputComponent->cursorCharX--;
if (focusedInputComponent->cursorCharX < 0) {
if (focusedInputComponent->multiLine) {
@ -211,8 +216,10 @@ DocumentComponent::DocumentComponent(const float rawX, const float rawY, const f @@ -211,8 +216,10 @@ DocumentComponent::DocumentComponent(const float rawX, const float rawY, const f
}
focusedInputComponent->cursorCharX = 0;
}
focusedInputComponent->updateCursor();
*/
focusedInputComponent->updateCursor(-1, 0);
} else if (key == GLFW_KEY_RIGHT) {
/*
focusedInputComponent->cursorCharX++;
if (focusedInputComponent->cursorCharX > static_cast<int>(focusedInputComponent->getValue().size())) {
if (focusedInputComponent->multiLine) {
@ -227,7 +234,8 @@ DocumentComponent::DocumentComponent(const float rawX, const float rawY, const f @@ -227,7 +234,8 @@ DocumentComponent::DocumentComponent(const float rawX, const float rawY, const f
focusedInputComponent->cursorCharX = focusedInputComponent->getValue().size();
}
}
focusedInputComponent->updateCursor();
*/
focusedInputComponent->updateCursor(1, 0);
} else if (key == GLFW_KEY_ENTER) {
//std::cout << "DocumentComponent::onKeyUp - enter!" << std::endl;
if (focusedInputComponent->multiLine) {

251
src/graphics/components/InputComponent.cpp

@ -6,35 +6,6 @@ @@ -6,35 +6,6 @@
#include "../opengl/Shader.h"
void TextBlock::addChar(char chr) {
if (chr==10 || chr==13) {
this->lineChars.push_back(this->currentLineChars);
this->currentLineChars = 0;
lines++;
}
this->text += std::string(&chr);
this->currentLineChars++;
}
void TextBlock::delLastChar() {
// get last char
char lastChar = this->text.at(this->text.size() - 1);
this->text = this->text.substr(0, this->text.size() - 2);
this->currentLineChars--;
if (lastChar == 10 || lastChar == 13) {
this->lineChars.pop_back();
this->currentLineChars = 0;
}
}
void TextBlock::insertCharAt(char chr, size_t pos) {
}
void TextBlock::delCharAt(size_t pos) {
}
extern TextRasterizerCache *rasterizerCache;
extern std::unique_ptr<Scheduler> scheduler;
@ -83,7 +54,7 @@ InputComponent::InputComponent(const float rawX, const float rawY, const float r @@ -83,7 +54,7 @@ InputComponent::InputComponent(const float rawX, const float rawY, const float r
this->win->renderDirty = true;
}
}, 500);
this->updateCursor();
this->updateCursor(0, 0);
this->win->renderDirty = true;
};
onBlur=[this]() {
@ -310,19 +281,22 @@ void InputComponent::resize(const int passedWindowWidth, const int passedWindowH @@ -310,19 +281,22 @@ void InputComponent::resize(const int passedWindowWidth, const int passedWindowH
}
std::string InputComponent::getValue() {
return this->value;
//return this->value;
return this->text.getValue();
}
void InputComponent::setValue(std::string newValue) {
this->value = newValue;
//this->value = newValue;
this->text.setValue(newValue);
if (!this->multiLine) {
this->cursorCharX = static_cast<int>(this->value.size() & INT_MAX);
this->cursorCharX = static_cast<int>(newValue.size() & INT_MAX);
}
// if we pasted in a middle of block
}
void InputComponent::addChar(char c) {
value += c;
this->text.insertAt(std::string(1, c), static_cast<size_t>(this->cursorCharX), static_cast<size_t>(this->cursorCharY));
//this->value += c;
//std::cout << "InputComponent::addChar - was cursor at " << this->cursorCharX << "," << this->cursorCharY << std::endl;
if (c == '\r') {
if (this->multiLine) {
@ -333,47 +307,123 @@ void InputComponent::addChar(char c) { @@ -333,47 +307,123 @@ void InputComponent::addChar(char c) {
this->cursorCharX++;
}
//std::cout << "InputComponent::addChar - at " << (int)x << "," << (int)y << std::endl;
updateText();
this->updateCursor(0, 0);
this->updateText();
}
void InputComponent::backSpace() {
char last = '\0';
if (value.length()) {
last = value.at(value.length() - 1);
if (this->text.getValue().length()) {
last = this->text.getValue().at(this->text.getValue().length() - 1);
}
value = value.substr(0, value.length() - 1);
//std::cout << "InputComponent::backSpace - was cursor at " << this->cursorCharX << "," << this->cursorCharY << std::endl;
//value = value.substr(0, value.length() - 1);
if (this->cursorCharX) {
// since this backSpace, we want to remove the character before this cursor
// 0,A,1,S,2,D,3,F,4
// ^ means remove char 2 (starting at 0)
//
this->text.deleteAt(static_cast<size_t>(this->cursorCharX - 1), static_cast<size_t>(this->cursorCharY), 1);
} else {
// maybe delete line
this->text.deleteAt(static_cast<size_t>(this->cursorCharX), static_cast<size_t>(this->cursorCharY), 1);
}
//std::cout << "InputComponent::backSpace - removed [" << last << "]" << std::endl;
if (last == '\r') {
if (this->multiLine) {
this->cursorCharY--;
if (this->cursorCharY < 0) this->cursorCharY = 0;
std::pair<int, int> lineData = getLine(this->value, this->cursorCharY);
this->cursorCharX = lineData.second - lineData.first;
if (this->cursorCharY < 0) {
this->cursorCharY = 0;
this->cursorCharX = 0;
} else {
this->cursorCharX = this->text.lineLength(static_cast<size_t>(this->cursorCharY));
}
//std::pair<int, int> lineData = getLine(this->text.getValue(), this->cursorCharY);
//this->cursorCharX = lineData.second - lineData.first + 1;
}
} else {
this->cursorCharX--;
if (this->cursorCharX < 0) this->cursorCharX = 0;
}
//std::cout << "InputComponent::backSpace - at " << (int)x << "," << (int)y << std::endl;
updateText();
this->updateCursor(0, 0);
this->updateText();
}
void InputComponent::updateCursor() {
std::cout << "InputComponent::updateCursor - cursor at " << this->cursorCharX << "," << this->cursorCharY << std::endl;
void InputComponent::updateCursor(int mX, int mY) {
//std::cout << "InputComponent::updateCursor - at " << this->cursorCharX << "," << this->cursorCharY << " move: " << mX << "," << mY << std::endl;
bool moved = false;
if (mX || mY) {
if (this->multiLine) {
if (mY < 0) {
// up
this->cursorCharY--;
if (this->cursorCharY < 0) {
this->cursorCharX = 0;
this->cursorCharY = 0;
}
} else if (mY > 0) {
// down
this->cursorCharY++;
if (static_cast<size_t>(this->cursorCharY) >= this->text.lines.size()) {
this->cursorCharY = this->text.lines.size() - 1;
this->cursorCharX = this->text.lineLength(static_cast<size_t>(this->cursorCharY));
}
}
} else {
if (mY < 0) {
// up
this->cursorCharX = 0;
} else if (mY > 0) {
// down
this->cursorCharX = this->text.lineLength(0);
}
}
if (mX < 0) {
// left
this->cursorCharX--;
if (this->cursorCharX < 0) {
this->cursorCharX = 0;
this->cursorCharY--;
if (this->cursorCharY < 0) {
this->cursorCharY = 0;
} else {
this->cursorCharX = this->text.lineLength(static_cast<size_t>(this->cursorCharY));
}
}
} else if (mX > 0) {
// right
this->cursorCharX++;
if (static_cast<size_t>(this->cursorCharX) > this->text.lineLength(static_cast<size_t>(this->cursorCharY))) {
this->cursorCharY++;
if (static_cast<size_t>(this->cursorCharY) >= this->text.lines.size()) {
this->cursorCharY = this->text.lines.size() - 1;
this->cursorCharX = this->text.lineLength(static_cast<size_t>(this->cursorCharY));
} else {
this->cursorCharX = 0;
}
}
}
//std::cout << "InputComponent::updateCursor - cursor now at " << this->cursorCharX << "," << this-> cursorCharY << std::endl;
}
if (this->cursorLastX != this->cursorCharX || this->cursorLastY != this->cursorCharY) {
moved = true;
}
//std::cout << "InputComponent::updateCursor - text[" << this->value << "]" << std::endl;
std::pair<int, int> lineData = getLine(this->value, this->cursorCharY);
std::cout << "InputComponent::updateCursor - line " << this->cursorCharY << " starts at " << lineData.first << std::endl;
size_t pos = static_cast<size_t>(lineData.first + this->cursorCharX);
//std::pair<int, int> lineData = getLine(this->text.getValue(), this->cursorCharY);
//std::cout << "InputComponent::updateCursor - line " << this->cursorCharY << " starts at " << lineData.first << std::endl;
//size_t pos = static_cast<size_t>(lineData.first + this->cursorCharX);
//std::cout << "InputComponent::updateCursor - cx " << this->cursorCharX << " starts at value pos " << pos << std::endl;
if (pos < this->value.size()) {
//if (pos < this->text.getValue().size()) {
//std::cout << "InputComponent::updateCursor - Cursor at " << this->cursorCharX << "," << this->cursorCharY << " " << this->value.at(pos) << std::endl;
}
//}
const std::shared_ptr<TextRasterizer> textRasterizer = rasterizerCache->loadFont(12, false); // fontSize, bold
rasterizationRequest request;
request.text = value.substr(0, pos);
std::cout << "InputComponent::updateCursor - sizeText[" << request.text << "]" << std::endl;
//request.text = text.getValue().substr(0, pos);
request.text = this->text.getValueUpTo(static_cast<size_t>(this->cursorCharX), static_cast<size_t>(this->cursorCharY));
//std::cout << "InputComponent::updateCursor - sizeText[" << request.text << "]" << std::endl;
request.startX = x;
request.availableWidth = windowWidth;
request.sourceStartX = 0;
@ -384,18 +434,29 @@ void InputComponent::updateCursor() { @@ -384,18 +434,29 @@ void InputComponent::updateCursor() {
request.noWrap = true;
}
std::unique_ptr<sizeResponse> textInfo = textRasterizer->size(request);
std::cout << "InputComponent::updateCursor - response at [" << textInfo->endingX << "," << textInfo->endingY << "]" << std::endl;
this->cursorStartAtX = textInfo->endingX;
this->cursorStartAtY = textInfo->endingY;
//std::cout << "InputComponent::updateCursor - response at [" << textInfo->endingX << "," << textInfo->endingY << "]" << std::endl;
int textEndingX = textInfo->endingX;
int textEndingY = textInfo->endingY;
// adjust text crop
//std::cout << "c.endingY: " << textInfo->endingY << " c.y:" << endingY << "" << std::endl;
this->textCropX = std::max(textInfo->endingX, static_cast<int>(this->width));
this->textCropY = std::max(-textInfo->endingY, static_cast<int>(this->height));
this->textScrollY = 0; // reset scroll
//this->cursorStartAtX = textInfo->endingX;
//this->cursorStartAtY = textInfo->endingY;
// adjust our scroll
//std::cout << "cursor height" << (int)textInfo->height << " > " << (int)this->height << " (" << this->textScrollY << ")" << std::endl;
if (textInfo->height > this->height) {
this->cursorStartAtY += textInfo->height - this->height;
textEndingY += textInfo->height - this->height;
this->textScrollY = textInfo->height - this->height;
}
// this is texture shader coordinates now (not text shader coords)
//
cursorBox->x = x + this->cursorStartAtX;
cursorBox->x = x + textEndingX;
if (boundToPage) {
cursorBox->y = this->windowHeight + y + this->cursorStartAtY;
cursorBox->y = this->windowHeight + this->y + textEndingY;
} else {
// + this->cursorStartAtY
cursorBox->y = this->y + 5;
@ -403,6 +464,25 @@ void InputComponent::updateCursor() { @@ -403,6 +464,25 @@ void InputComponent::updateCursor() {
//std::cout << "placing cursor at " << (int)cursorBox->x << "," << (int)cursorBox->y << std::endl;
cursorBox->resize(this->windowWidth, this->windowHeight);
// ok placement of the cursor may trigger the text to scroll and need to be re-rasterized
if (moved) {
/*
if (userInputText) {
std::cout << "cursor at " << (int)textInfo->endingY << " to " << textInfo->endingY << " textScrollY: " << this->textScrollY << " inputHeight: " << (int)this->height << " textHeight: " << (int)this->userInputText->height << " adjHeight: " << (int)(this->height - this->textScrollY) << std::endl;
// if we're at the top of input comp moving up
// or at the bottom of the input comp going down
if (-endingY > this->height - this->textScrollY) {
//this->textScrollY = this->height + endingY;
std::cout << "set textScrollY: " << this->textScrollY << std::endl;
}
}
*/
this->updateText();
// we're updated
this->cursorLastX = this->cursorCharX;
this->cursorLastY = this->cursorCharY;
}
// if we move the cursor, redraw immediately
this->showCursor = true;
if (this->win) {
@ -416,9 +496,9 @@ void InputComponent::updateText() { @@ -416,9 +496,9 @@ void InputComponent::updateText() {
if (this->node) {
std::map<std::string, std::string>::iterator it = this->node->properties.find("value");
if (it == this->node->properties.end()) {
this->node->properties.insert(std::make_pair("value", this->value));
this->node->properties.insert(std::make_pair("value", this->text.getValue()));
} else {
it->second = this->value;
it->second = this->text.getValue();
}
}
@ -427,11 +507,12 @@ void InputComponent::updateText() { @@ -427,11 +507,12 @@ void InputComponent::updateText() {
// but first we need to know how wide the text is
const std::shared_ptr<TextRasterizer> textRasterizer = rasterizerCache->loadFont(12, false); // fontSize, bold
rasterizationRequest request;
request.text = value;
request.text = text.getValue();
request.startX = x;
request.availableWidth = windowWidth;
request.sourceStartX = 0;
request.sourceStartY = 0;
// don't wrap if ML, otherwise do
if (this->multiLine) {
request.noWrap = false;
} else {
@ -439,18 +520,23 @@ void InputComponent::updateText() { @@ -439,18 +520,23 @@ void InputComponent::updateText() {
}
std::unique_ptr<sizeResponse> textInfo = textRasterizer->size(request);
if (textInfo.get() == nullptr) {
std::cout << "InputComponent::updateText - couldn't estimate value[" << this->value << "] size" << std::endl;
std::cout << "InputComponent::updateText - couldn't estimate value[" << this->text.getValue() << "] size" << std::endl;
return;
}
//int textWidth = textInfo->first;
int estWidth = textInfo->width;
int estHeight = textInfo->height;
this->cursorStartAtX = textInfo->endingX;
this->cursorStartAtY = textInfo->endingY;
//int estWidth = textInfo->width;
//int estHeight = textInfo->height;
//this->cursorStartAtX = textInfo->endingX;
//this->cursorStartAtY = textInfo->endingY;
// if textHeight is bigger than window, adjust cursor too
/*
if (estHeight > this->height) {
this->cursorStartAtY += estHeight - this->height;
std::cout << "InputComponent::updateText - used to adj cursorStartAtY += " << (int)(estHeight - this->height) << " (" << estHeight << " - " << (int)this->height << ")" << std::endl;
//this->cursorStartAtY += estHeight - this->height;
}
this->updateCursor();
*/
//this->updateCursor(0, 0);
// why does changing the width mess shit up?
//std::cout << "InputComponent::updateText - our width: " << static_cast<int>(width) << " windowWidth: " << windowWidth << std::endl;
@ -459,7 +545,7 @@ void InputComponent::updateText() { @@ -459,7 +545,7 @@ void InputComponent::updateText() {
if (this->userInputText) {
delete this->userInputText;
}
this->userInputText = new TextComponent(value, 0, 0, 12, false, 0x000000FF, this->windowWidth, this->windowHeight);
this->userInputText = new TextComponent(this->text.getValue(), 0, 0, 12, false, 0x000000FF, this->windowWidth, this->windowHeight);
if (!userInputText->win && this->win) {
userInputText->win = this->win;
}
@ -473,10 +559,14 @@ void InputComponent::updateText() { @@ -473,10 +559,14 @@ void InputComponent::updateText() {
userInputText->y = this->y - this->windowHeight + 16;
}
userInputText->boundToPage = this->boundToPage;
userInputText->rasterStartX = 0;
userInputText->rasterStartY = 0;
userInputText->rasterStartX = this->textScrollX;
userInputText->rasterStartY = this->textScrollY;
userInputText->rasterCropX = this->textCropX;
userInputText->rasterCropY = this->textCropY;
//std::cout << "InputComponent::updateText - estWidth: " << estWidth << " width: " << static_cast<int>(this->width) << " eX: " << textInfo->endingX << std::endl;
// no longer scroll to end of text
/*
if (estWidth > this->width) {
//std::cout << "scrolling text" << std::endl;
userInputText->rasterStartX = estWidth - this->width;
@ -486,8 +576,23 @@ void InputComponent::updateText() { @@ -486,8 +576,23 @@ void InputComponent::updateText() {
//std::cout << "scrolling text" << std::endl;
userInputText->rasterStartY = estHeight - this->height; // start at one widget height from the bottom
}
*/
//
/*
// translate cursor in scroll
std::cout << "cursor at " << this->cursorStartAtX << "," << this->cursorStartAtY << " size: " << (int)this->width << "," << (int)this->height << std::endl;
// so we only care about cursorStartAtY here atm
// we get values like -58, -43, -28, -13
if (this->cursorStartAtX > this->width) {
userInputText->rasterStartX = this->cursorStartAtX - this->width;
}
if (this->multiLine && -(this->cursorStartAtY + userInputText->height) > this->height) {
std::cout << "scrolling y start: " << (-(this->cursorStartAtY + userInputText->height) - this->height) << std::endl;
userInputText->rasterStartY = -this->cursorStartAtY - this->height;
}
*/
//std::cout << "InputComponent::updateText - textHeight: " << estHeight << " inputHeight: " << static_cast<int>(height) << " eY: " << textInfo->endingY << " y0max:" << textInfo->y0max << " rasterStartY: " << userInputText->rasterStartY << " lines: " << textInfo->lines << std::endl;
// wrap if multiLine, otherwise don't
// don't wrap if multiLine, otherwise wrap
userInputText->noWrap = !this->multiLine;
userInputText->resize(this->windowWidth, this->windowHeight, this->width); // need to make sure there's a texture

33
src/graphics/components/InputComponent.h

@ -6,25 +6,10 @@ @@ -6,25 +6,10 @@
#include "BoxComponent.h"
#include "TextComponent.h"
#include "../../scheduler.h"
#include "../../TextBlock.h"
class Window;
class TextBlock {
public:
// methods
void addChar(char chr);
void delLastChar();
void insertCharAt(char chr, size_t pos);
void delCharAt(size_t pos);
std::pair<size_t, size_t> getXYPos(size_t pos);
size_t getPosXY(size_t x, size_t y);
// properties
size_t lines;
std::vector<size_t> lineChars;
size_t currentLineChars = 0;
std::string text;
};
class InputComponent : public BoxComponent {
public:
//: BoxComponent(rawX, rawY, rawWidth, rawHeight, passedWindowWidth, passedWindowHeight) { }
@ -35,9 +20,10 @@ public: @@ -35,9 +20,10 @@ public:
void render();
std::string getValue();
void setValue(std::string newValue);
// FIXME: change to using std::string
void addChar(char c);
void backSpace();
void updateCursor();
void updateCursor(int x, int y);
void updateText();
TextComponent *userInputText = nullptr;
BoxComponent *cursorBox = nullptr;
@ -48,14 +34,19 @@ public: @@ -48,14 +34,19 @@ public:
bool showCursor = true;
std::shared_ptr<timer_handle> cursorTimer = nullptr;
// store for cursor
int cursorStartAtX;
int cursorStartAtY;
int textScrollX = 0;
int textScrollY = 0;
int textCropX = 0;
int textCropY = 0;
int cursorLastX = 0;
int cursorLastY = 0;
int cursorCharX = 0;
int cursorCharY = 0;
TextBlock text;
TagNode *node = nullptr;
bool multiLine = false; // textarea control
protected:
std::string value="";
//protected:
//std::string value="";
};
#endif

14
src/graphics/components/TabbedComponent.cpp

@ -361,7 +361,7 @@ void TabbedComponent::selectTab(std::shared_ptr<Tab> tab) { @@ -361,7 +361,7 @@ void TabbedComponent::selectTab(std::shared_ptr<Tab> tab) {
i++;
}
//std::cout << "i" << i << "/" << this->tabs.size() << std::endl;
std::cout << "TabbedComponent::selectTab - selector found: " << found << std::endl;
//std::cout << "TabbedComponent::selectTab - selector found: " << found << std::endl;
if (found) {
// was there a previously selected tab?
//if (this->selectedTab != this->tabs.end() && this->selectedTab != this->tabs.begin()) {
@ -408,7 +408,11 @@ void TabbedComponent::selectTab(std::shared_ptr<Tab> tab) { @@ -408,7 +408,11 @@ void TabbedComponent::selectTab(std::shared_ptr<Tab> tab) {
// doesn't move, will this double free?
this->mpSelectedTab = tab; // pointer
this->updateWindowState(ab->getValue());
if (ab) {
this->updateWindowState(ab->getValue());
} else {
std::cout << "TabbedComponent::selectTab - cant update window no address bar" << std::endl;
}
}
// we expect the tab to be set up (all components allocated)
@ -572,7 +576,7 @@ void TabbedComponent::removeTab(size_t tabId) { @@ -572,7 +576,7 @@ void TabbedComponent::removeTab(size_t tabId) {
std::vector<std::shared_ptr<Tab>>::iterator prev = this->tabs.begin();
for(std::vector<std::shared_ptr<Tab>>::iterator it = this->tabs.begin(); it!=this->tabs.end(); prev = it, ++it) {
if (it->get()->id == tabId) {
std::cout << "TabbedComponent::removeTab - found our tab" << std::endl;
//std::cout << "TabbedComponent::removeTab - found our tab" << std::endl;
// remove our components form the component tree
std::vector<std::shared_ptr<Component>>::iterator it2;
it2 = std::find(this->rootComponent->children.begin(), this->rootComponent->children.end(), it->get()->selectorBox);
@ -601,7 +605,7 @@ void TabbedComponent::removeTab(size_t tabId) { @@ -601,7 +605,7 @@ void TabbedComponent::removeTab(size_t tabId) {
// unload components
docComponent->setDOM(std::make_shared<Node>(NodeType::ROOT));
} else {
std::cout << "our contents aren't a document component" << std::endl;
std::cout << "TabbedComponent::removeTab - our contents aren't a document component" << std::endl;
}
it2->get()->parent = nullptr;
this->rootComponent->children.erase(it2);
@ -650,7 +654,7 @@ void TabbedComponent::removeTab(size_t tabId) { @@ -650,7 +654,7 @@ void TabbedComponent::removeTab(size_t tabId) {
}
// we need to move (relayout) all remove tabs after this id
if (found) {
std::cout << "TabbedComponent::removeTab - Need to adjust: " << it->get()->id << std::endl;
//std::cout << "TabbedComponent::removeTab - Need to adjust: " << it->get()->id << std::endl;
it->get()->titleBox->x -= widthToRemove;
it->get()->titleBox->resize(windowWidth, windowHeight); // TextComponent, need a resize() to move vertices
it->get()->selectorBox->x -= widthToRemove;

2
src/graphics/components/TextComponent.cpp

@ -120,6 +120,8 @@ void TextComponent::rasterize(const int rawX, const int rawY) { @@ -120,6 +120,8 @@ void TextComponent::rasterize(const int rawX, const int rawY) {
request.availableWidth = this->availableWidth;
request.sourceStartX = this->rasterStartX;
request.sourceStartY = this->rasterStartY;
request.cropWidth = this->rasterCropX;
request.cropHeight = this->rasterCropY;
if (this->win) {
request.maxTextureSize = this->win->maxTextureSize & INT_MAX;
} // else called from input cstr, no win yet

4
src/graphics/components/TextComponent.h

@ -33,9 +33,11 @@ public: @@ -33,9 +33,11 @@ public:
void updateHighlight();
std::unique_ptr<sizeResponse> size() const;
// input needed stuff
// input needed stuff for scrollin
int rasterStartX = 0; // start reading text source at and place at destination 0
int rasterStartY = 0;
int rasterCropX = 0;
int rasterCropY = 0;
bool noWrap = false; // different than overflow but related
bool textSelected = false;
int availableWidth = 0;

17
src/graphics/text/TextRasterizer.cpp

@ -60,7 +60,7 @@ std::unique_ptr<sizeResponse> TextRasterizer::size(const rasterizationRequest &r @@ -60,7 +60,7 @@ std::unique_ptr<sizeResponse> TextRasterizer::size(const rasterizationRequest &r
return nullptr;
}
if (!buffer) {
std::cout << "TextRasterizer::rasterize - no font loaded" << std::endl;
std::cout << "TextRasterizer::size - no font loaded" << std::endl;
return nullptr;
}
@ -133,7 +133,7 @@ std::unique_ptr<sizeResponse> TextRasterizer::size(const rasterizationRequest &r @@ -133,7 +133,7 @@ std::unique_ptr<sizeResponse> TextRasterizer::size(const rasterizationRequest &r
if (request.noWrap) {
glyphCount = i;
// we're done
std::cout << "TextRasterizer::rasterize - newline found no wrap is on" << std::endl;
std::cout << "TextRasterizer::size - newline found no wrap is on" << std::endl;
break;
} else {
xmax=std::max(xmax, cx);
@ -167,6 +167,7 @@ std::unique_ptr<sizeResponse> TextRasterizer::size(const rasterizationRequest &r @@ -167,6 +167,7 @@ std::unique_ptr<sizeResponse> TextRasterizer::size(const rasterizationRequest &r
// update glyph space allocation
cx += xa;
// note all over cy is in -
cy += ya; // is normal for y0 at bottom
// update glyph maxes
@ -180,6 +181,10 @@ std::unique_ptr<sizeResponse> TextRasterizer::size(const rasterizationRequest &r @@ -180,6 +181,10 @@ std::unique_ptr<sizeResponse> TextRasterizer::size(const rasterizationRequest &r
// track new max width
xmax=std::max(xmax, cx);
// crop overflow
if (request.cropHeight && cy > request.cropHeight) {
break; // stop adding characters
}
}
if (response->leftPadding) {
xmax += response->leftPadding; // increase width;
@ -189,9 +194,12 @@ std::unique_ptr<sizeResponse> TextRasterizer::size(const rasterizationRequest &r @@ -189,9 +194,12 @@ std::unique_ptr<sizeResponse> TextRasterizer::size(const rasterizationRequest &r
response->height = -cy;
response->width = xmax;
//std::cout << "lines: " << lines << " wrapToX: " << wrapToX << " startX: " << x << " xmax: " << xmax << std::endl;
// confirmed we aren't the same
/*
if (response->y0max != maxy0) {
std::cout << "TextRasterizer::size - resp.y0max: " << response->y0max << " maxy0: " << maxy0 << std::endl;
}
*/
//std::cout << "y1max: " << y1max << " lines: " << response->lines << std::endl;
int textureHeight = (y1max - response->y0max) * static_cast<int>(response->lines);
//int textureHeight = y1max * response->lines;
@ -346,6 +354,11 @@ std::unique_ptr<rasterizationResponse> TextRasterizer::rasterize(const rasteriza @@ -346,6 +354,11 @@ std::unique_ptr<rasterizationResponse> TextRasterizer::rasterize(const rasteriza
//std::cout << "textWrap - cx reset to: " << cx << " cy is now: " << cy << std::endl;
}
//std::cout << "placing glyph[" << text[i] << "] at " << cx << " cy is now: " << cy << std::endl;
// crop overflow
if (request.cropHeight && cy > request.cropHeight) {
break; // stop adding characters
}
if (cx < request.sourceStartX) {
// skip ahead

3
src/graphics/text/TextRasterizer.h

@ -40,6 +40,9 @@ struct rasterizationRequest { @@ -40,6 +40,9 @@ struct rasterizationRequest {
// scrolling basically:
int sourceStartX = 0; // start reading text source at and place at destination 0
int sourceStartY = 0;
// overflow (0 means no limit)
int cropWidth = 0;
int cropHeight = 0;
bool noWrap = false; // different than overflow but related
unsigned int maxTextureSize = 0;
};

2
src/networking/HTTPSRequest.cpp

@ -86,7 +86,7 @@ bool HTTPSRequest::sendRequest(std::function<void(const HTTPResponse&)> response @@ -86,7 +86,7 @@ bool HTTPSRequest::sendRequest(std::function<void(const HTTPResponse&)> response
std::cout << "HTTPS Request: " << request << std::endl;
while( ( state = mbedtls_ssl_write( &ssl, reinterpret_cast<const unsigned char*>(request.c_str()), request.length() ) ) <= 0 ){
if( state != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE ){
if( state != MBEDTLS_ERR_SSL_WANT_READ && state != MBEDTLS_ERR_SSL_WANT_WRITE ){
printf( " failed\n ! mbedtls_ssl_write returned %d\n\n", state );
return false;
}

18
src/scheduler.cpp

@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
#include <GLFW/glfw3.h>
#include <iostream>
#include <algorithm>
#include <stdlib.h>
std::shared_ptr<timer_handle> Scheduler::setTimeout(std::function<void()> callback, unsigned long delay) {
double now = glfwGetTime() * 1000;
@ -56,15 +57,28 @@ bool Scheduler::fireTimer(std::shared_ptr<timer_handle> timer, double now) { @@ -56,15 +57,28 @@ bool Scheduler::fireTimer(std::shared_ptr<timer_handle> timer, double now) {
void Scheduler::fireTimers() {
double now = glfwGetTime() * 1000;
size_t unfired = 0;
int next = INT_MAX;
for(std::vector<std::shared_ptr<timer_handle>>::iterator it=this->timers.begin(); it!=this->timers.end(); ++it) {
// if it's the timer time to fire
if (it->get()->nextAt < now) {
int left = abs(static_cast<int>(it->get()->nextAt - now)); // maybe remove the ABS
if (left <= 10 || it->get()->nextAt < now) {
// fire it, do we need to clean it up
if (this->fireTimer(*it, now)) {
// clena up
// clean up
it = this->timers.erase(it);
if (it == this->timers.end()) break;
}
} else {
//std::cout << "left" << left << std::endl;
next = std::min(left, next);
unfired++;
}
}
if (unfired) {
if (next < 10) {
std::cout << "There are " << unfired << "/" << this->timers.size() << " unfired timers left, next at " << next << std::endl;
std::cout << "Scheduler::fireTimers - failed" << std::endl;
}
}
}

Loading…
Cancel
Save