Browse Source

Merge remote-tracking branch 'origin/master'

master
despair 5 years ago
parent
commit
584ab9b8b8
  1. 2
      src/Log.cpp
  2. 2
      src/URL.cpp
  3. 96
      src/graphics/components/BoxComponent.cpp
  4. 8
      src/graphics/components/Component.cpp
  5. 3
      src/graphics/components/Component.h
  6. 24
      src/graphics/components/ComponentBuilder.cpp
  7. 1
      src/graphics/components/ComponentBuilder.h
  8. 9
      src/graphics/components/DocumentComponent.cpp
  9. 110
      src/graphics/components/InputComponent.cpp
  10. 5
      src/graphics/components/InputComponent.h
  11. 17
      src/graphics/components/MultiComponent.cpp
  12. 2
      src/graphics/components/MultiComponent.h
  13. 10
      src/graphics/components/TabbedComponent.cpp
  14. 8
      src/graphics/components/TextComponent.cpp
  15. 31
      src/graphics/opengl/Window.cpp
  16. 1
      src/graphics/opengl/Window.h
  17. 14
      src/graphics/text/TextRasterizer.cpp
  18. 2
      src/graphics/text/TextRasterizer.h
  19. 9
      src/graphics/text/TextRasterizerCache.cpp
  20. 27
      src/main.cpp
  21. 77
      src/scheduler.cpp
  22. 27
      src/scheduler.h

2
src/Log.cpp

@ -24,7 +24,7 @@ namespace { @@ -24,7 +24,7 @@ namespace {
loggerCache.insert(newEntry);
}
return loggerCache[lt]();
}
}
}
Logger::Logger() :

2
src/URL.cpp

@ -102,7 +102,7 @@ std::tuple<std::unique_ptr<URL>,enum URIParseError> parseUri(std::string raw) { @@ -102,7 +102,7 @@ std::tuple<std::unique_ptr<URL>,enum URIParseError> parseUri(std::string raw) {
last = cursor + 1;
state = AUTHORITY;
if (uri->scheme == "file") {
std::cout << "file scheme, current path[" << uri->path << "]" << std::endl;
//std::cout << "URL:::parseUri file scheme, current path[" << uri->path << "]" << std::endl;
state = PATH;
}
} else {

96
src/graphics/components/BoxComponent.cpp

@ -151,6 +151,26 @@ void BoxComponent::render() { @@ -151,6 +151,26 @@ void BoxComponent::render() {
// can actuall delete vertices here
}
void BoxComponent::changeColor(const unsigned int hexColor) {
// really a texture swap
// set texture color
data[0][0][0] = (hexColor >> 24) & 0xFF;
data[0][0][1] = (hexColor >> 16) & 0xFF;
data[0][0][2] = (hexColor >> 8) & 0xFF;
data[0][0][3] = (hexColor >> 0) & 0xFF;
glBindVertexArray(vertexArrayObject);
// now replace existing texture
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
glBindVertexArray(0); // unbind to prevent anything from accidentally changing it
}
// this seems to work 17-08-10
// for box
// anime girl, we'll get aspect ratio breakage
@ -158,7 +178,7 @@ void BoxComponent::resize(const int passedWindowWidth, const int passedWindowHei @@ -158,7 +178,7 @@ void BoxComponent::resize(const int passedWindowWidth, const int passedWindowHei
//std::cout << "BoxComponent::resize" << std::endl;
windowWidth = passedWindowWidth;
windowHeight = passedWindowHeight;
//std::cout << "BoxComponent::resize - boundToPage " << boundToPage << std::endl;
// figure out new vertices
float vx = x;
@ -185,77 +205,3 @@ void BoxComponent::resize(const int passedWindowWidth, const int passedWindowHei @@ -185,77 +205,3 @@ void BoxComponent::resize(const int passedWindowWidth, const int passedWindowHei
verticesDirty = true;
}
void BoxComponent::changeColor(const unsigned int hexColor) {
// really a texture swap
// set texture color
data[0][0][0] = (hexColor >> 24) & 0xFF;
data[0][0][1] = (hexColor >> 16) & 0xFF;
data[0][0][2] = (hexColor >> 8) & 0xFF;
data[0][0][3] = (hexColor >> 0) & 0xFF;
glBindVertexArray(vertexArrayObject);
// now replace existing texture
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
glBindVertexArray(0); // unbind to prevent anything from accidentally changing it
}
/*
void BoxComponent::resize(const int passedWindowWidth, const int passedWindowHeight) {
std::cout << "BoxComponent::resize" << std::endl;
windowWidth = passedWindowWidth;
windowHeight = passedWindowHeight;
if (boundToPage) {
std::cout << "BoxComponent::resize - boundToPage doing nothing" << std::endl;
} else {
// figure out our percentages
// 0 / WW = 0
// 768 / 1024 = 75%
float xPer = initialX / (float)initialWindowWidth;
float yPer = initialY / (float)initialWindowHeight;
// adjust width
float wPer = initialWidth / (float)initialWindowWidth;
//float hPer = initialHeight / (float)initialWindowHeight;
float vx = xPer * windowWidth;
float vy = yPer * windowHeight;
// nah I don't think we want things to stretch
//float vWidth = wPer * windowWidth;
//float vHeight = hPer * windowHeight;
// ugh these just need to be relaid out
//float vWidth = width;
float vWidth = wPer * windowWidth;
float vHeight = height;
//std::cout << "initial: " << initialX << "x" << initialY << " size: " << initialWidth << "x" << initialHeight << " window size: " << initialWindowWidth << "x" << initialWindowHeight << std::endl;
//std::cout << "scaled to: " << (int)vx << "x" << (int)vy << " size: " << (int)vWidth << "x" << (int)vHeight << " window size: " << windowWidth << "x" << windowHeight << std::endl;
pointToViewport(vx, vy);
distanceToViewport(vWidth, vHeight);
vertices[(0 * 5) + 0] = vx;
vertices[(0 * 5) + 1] = vy + vHeight;
vertices[(1 * 5) + 0] = vx + vWidth;
vertices[(1 * 5) + 1] = vy + vHeight;
vertices[(2 * 5) + 0] = vx + vWidth;
vertices[(2 * 5) + 1] = vy;
vertices[(3 * 5) + 0] = vx;
vertices[(3 * 5) + 1] = vy;
verticesDirty = true;
}
}
*/

8
src/graphics/components/Component.cpp

@ -107,7 +107,7 @@ void Component::layout() { @@ -107,7 +107,7 @@ void Component::layout() {
std::cout << "Component::layout[" << textComponent->text << "]" << std::endl;
}
*/
//std::cout << "Component::layout - name: " << name << " boundToPage: " << boundToPage << std::endl;
//std::cout << "Component::layout - name: " << name << " type " << typeOfComponent(this) << " boundToPage: " << boundToPage << std::endl;
// if we're a child, get our parents position
if (parent && boundToPage) {
@ -216,6 +216,7 @@ void Component::layout() { @@ -216,6 +216,7 @@ void Component::layout() {
// resize/wordwrap to available width
// our position is required
void Component::wrap() {
//std::cout << "Component::wrap - " << typeOfComponent(this) << std::endl;
float lW = width;
float lH = height;
resize(windowWidth, windowHeight); // this may change our w/h
@ -232,6 +233,7 @@ void Component::wrap() { @@ -232,6 +233,7 @@ void Component::wrap() {
// measure current, apply changes to parent
// our size is required
void Component::updateParentSize() {
//std::cout << "Component::updateParentSize - " << typeOfComponent(this) << std::endl;
if (!parent) {
//std::cout << "Component::updateParentSize - can't update parent size, no parent" << std::endl;
return;
@ -246,7 +248,6 @@ void Component::updateParentSize() { @@ -246,7 +248,6 @@ void Component::updateParentSize() {
// find max width of all siblings
unsigned int maxWidth = width; // float?
unsigned int heightAccum = 0;
bool wasInline = false;
unsigned int totalHeight = 0;
// integrity check
@ -257,6 +258,7 @@ void Component::updateParentSize() { @@ -257,6 +258,7 @@ void Component::updateParentSize() {
}
// look at siblings
bool wasInline = false;
for (std::shared_ptr<Component> child : parent->children) {
maxWidth = std::max(maxWidth, static_cast<unsigned int>(child->width));
if (child->isInline) {
@ -421,7 +423,7 @@ void Component::printComponentTree(const std::shared_ptr<Component> &component, @@ -421,7 +423,7 @@ void Component::printComponentTree(const std::shared_ptr<Component> &component,
}
InputComponent *inputComponent = dynamic_cast<InputComponent*>(component.get());
if (inputComponent) {
std::cout << std::fixed << "X: " << static_cast<int>(inputComponent->x) << " Y: " << static_cast<int>(inputComponent->y) << " WIDTH: " << static_cast<int>(inputComponent->width) << " HEIGHT: " << static_cast<int>(inputComponent->height) << " INLINE: " << inputComponent->isInline << " INPUT: " << inputComponent->value << std::endl;
std::cout << std::fixed << "X: " << static_cast<int>(inputComponent->x) << " Y: " << static_cast<int>(inputComponent->y) << " WIDTH: " << static_cast<int>(inputComponent->width) << " HEIGHT: " << static_cast<int>(inputComponent->height) << " INLINE: " << inputComponent->isInline << " Bound: " << inputComponent->boundToPage << " INPUT: " << inputComponent->value << std::endl;
} else {
TextComponent *textComponent = dynamic_cast<TextComponent*>(component.get());
if (textComponent) {

3
src/graphics/components/Component.h

@ -167,7 +167,10 @@ public: @@ -167,7 +167,10 @@ public:
std::function<void(int x, int y)> onMouseup = nullptr;
std::function<void(int x, int y)> onMousemove = nullptr;
std::function<void(int x, int y)> onWheel = nullptr;
// https://www.quirksmode.org/dom/events/keys.html
std::function<void(int key, int scancode, int action, int mods)> onKeyup = nullptr;
// "Fires when an actual character is being inserted in, for instance, a text input. It repeats while the user keeps the key depressed."
std::function<void(int key, int scancode, int action, int mods)> onKeyPress = nullptr;
std::function<void()> onClick = nullptr;
std::function<void()> onFocus = nullptr;
std::function<void()> onBlur = nullptr;

24
src/graphics/components/ComponentBuilder.cpp

@ -95,6 +95,8 @@ std::shared_ptr<Component> ComponentBuilder::build(const std::shared_ptr<Node> n @@ -95,6 +95,8 @@ std::shared_ptr<Component> ComponentBuilder::build(const std::shared_ptr<Node> n
if (inputComponent) {
// any input set up we need to do?
// boundToPage defaults to true for components, InputComponent doesn't have it overridded
//std::cout << "Just built an inputComponent" << std::endl;
inputComponent->win = window.get();
}
//std::cout << "composting component, initial: " << (int)component->width << "x" << (int)component->height << std::endl;
@ -123,7 +125,10 @@ std::shared_ptr<Component> ComponentBuilder::build(const std::shared_ptr<Node> n @@ -123,7 +125,10 @@ std::shared_ptr<Component> ComponentBuilder::build(const std::shared_ptr<Node> n
std::cout << "ComponentBuilder::build - Just laid out input component" << std::endl;
}
*/
// not sure why only this component needs this but it fixes it
if (inputComponent) {
inputComponent->updateParentSize();
}
//std::cout << "post layout placed: " << (int)component->x << "x" << (int)component->y << " w/h: " << (int)component->width << "x" << (int)component->height << std::endl;
return component;
}
@ -148,3 +153,20 @@ std::string typeOfComponent(const std::shared_ptr<Component> &component) { @@ -148,3 +153,20 @@ std::string typeOfComponent(const std::shared_ptr<Component> &component) {
if (boxComponent) return "box";
return "";
}
std::string typeOfComponent(Component *component) {
TabbedComponent *tabComponent = dynamic_cast<TabbedComponent*>(component);
if (tabComponent) return "tab";
DocumentComponent *docComponent = dynamic_cast<DocumentComponent*>(component);
if (docComponent) return "doc";
TextComponent *textComponent = dynamic_cast<TextComponent*>(component);
if (textComponent) return "text";
InputComponent *inputComponent = dynamic_cast<InputComponent*>(component);
if (inputComponent) return "input";
AnimeComponent *animeComponent = dynamic_cast<AnimeComponent*>(component);
if (animeComponent) return "anime";
BoxComponent *boxComponent = dynamic_cast<BoxComponent*>(component);
if (boxComponent) return "box";
return "";
}

1
src/graphics/components/ComponentBuilder.h

@ -21,5 +21,6 @@ public: @@ -21,5 +21,6 @@ public:
// getComponentType
std::string typeOfComponent(const std::shared_ptr<Component> &component);
std::string typeOfComponent(Component *component);
#endif

9
src/graphics/components/DocumentComponent.cpp

@ -111,7 +111,7 @@ DocumentComponent::DocumentComponent(const float rawX, const float rawY, const f @@ -111,7 +111,7 @@ DocumentComponent::DocumentComponent(const float rawX, const float rawY, const f
//this->renderDirty = true;
};
onMousedown=[this](int passedX, int passedY) {
std::cout << "document left press" << std::endl;
//std::cout << "document left press" << std::endl;
if (this->hoverComponent) {
if (this->focusedComponent != this->hoverComponent) {
// blur old component
@ -133,7 +133,7 @@ DocumentComponent::DocumentComponent(const float rawX, const float rawY, const f @@ -133,7 +133,7 @@ DocumentComponent::DocumentComponent(const float rawX, const float rawY, const f
}
};
onMouseup=[this](int passedX, int passedY) {
std::cout << "document left release" << std::endl;
//std::cout << "document left release" << std::endl;
if (this->hoverComponent) {
//std::cout << "DocumentComponent::DocumentComponent:onMouseup - hovering over " << typeOfComponent(this->hoverComponent) << " component" << std::endl;
if (this->focusedComponent != this->hoverComponent) {
@ -149,6 +149,7 @@ DocumentComponent::DocumentComponent(const float rawX, const float rawY, const f @@ -149,6 +149,7 @@ DocumentComponent::DocumentComponent(const float rawX, const float rawY, const f
}
}
this->focusedComponent = this->hoverComponent;
//std::cout << "DocumentComponent::DocumentComponent:onMouseup - hovering over " << typeOfComponent(this->hoverComponent) << " component, focused on " << typeOfComponent(this->focusedComponent) << std::endl;
if (this->focusedComponent->onMouseup) {
//std::cout << "click event" << std::endl;
this->focusedComponent->onMouseup(passedX, passedY);
@ -160,7 +161,7 @@ DocumentComponent::DocumentComponent(const float rawX, const float rawY, const f @@ -160,7 +161,7 @@ DocumentComponent::DocumentComponent(const float rawX, const float rawY, const f
}
};
onKeyup=[this](int key, int scancode, int action, int mods) {
//std::cout << "DocumentComponent::DocumentComponent:onKeyup" << std::endl;
//std::cout << "DocumentComponent::DocumentComponent:onKeyup" << typeOfComponent(this->focusedComponent) << std::endl;
InputComponent *inputComponent = dynamic_cast<InputComponent*>(this->focusedComponent.get());
if (inputComponent) {
//std::cout << "inputComponent is focused, key pressed " << key << " action: " <<action << std::endl;
@ -318,7 +319,7 @@ std::shared_ptr<Component> DocumentComponent::searchComponentTree(const std::sha @@ -318,7 +319,7 @@ std::shared_ptr<Component> DocumentComponent::searchComponentTree(const std::sha
if (-component->y < passedY && -component->y + component->height > passedY) {
//std::cout << "DocumentComponent::searchComponentTree - x search: " << static_cast<int>(component->x) << "<" << static_cast<int>(passedX) << "<" << static_cast<int>(component->x + component->width) << std::endl;
if (component->x < passedX && component->x + component->width > passedX) {
//std::cout << "hit " << typeOfComponent(component) << std::endl;
//std::cout << "DocumentComponent::searchComponentTree - hit " << typeOfComponent(component) << std::endl;
return component;
}
}

110
src/graphics/components/InputComponent.cpp

@ -1,14 +1,15 @@ @@ -1,14 +1,15 @@
#include "InputComponent.h"
#include <iostream>
#include "../opengl/Window.h"
#include "../text/TextRasterizerCache.h"
#include "../../scheduler.h"
extern TextRasterizerCache *rasterizerCache;
extern std::unique_ptr<Scheduler> scheduler;
// : BoxComponent(rawX, rawY, rawWidth, rawHeight, passedWindowWidth, passedWindowHeight)
InputComponent::InputComponent(const float rawX, const float rawY, const float rawWidth, const float rawHeight, const int passedWindowWidth, const int passedWindowHeight) {
//std::cout << "InputComponent::InputComponent - data" << std::endl;
//std::cout << "InputComponent::InputComponent - create, boundToPage" << boundToPage << std::endl;
//std::cout << "InputComponent::InputComponent - window: " << windowWidth << "x" << windowHeight << " passed " << passedWindowWidth << "x" << passedWindowHeight << std::endl;
//boundToPage = true;
@ -17,12 +18,41 @@ InputComponent::InputComponent(const float rawX, const float rawY, const float r @@ -17,12 +18,41 @@ InputComponent::InputComponent(const float rawX, const float rawY, const float r
// set up state
windowWidth = passedWindowWidth;
windowHeight = passedWindowHeight;
// lets not set, like resize set, and then maybe parent width will be correct
// didn't really changed anything
width = rawWidth;
height = rawHeight;
// ugh
x = rawX;
y = rawY;
lastRenderedWindowHeight = windowHeight;
// const float rawX, const float rawY, const float rawWidth, const float rawHeight, const unsigned int hexColor, const int passedWindowWidth, const int passedWindowHeight
this->cursorBox = new BoxComponent(x, y, 2, rawHeight, 0x000000FF, windowWidth, windowHeight);
this->cursorBox->boundToPage = this->boundToPage;
this->cursorBox->x = x;
this->cursorBox->y = y;
if (boundToPage) {
this->cursorBox->y = this->windowHeight + y - 13;
}
this->cursorBox->resize(this->windowWidth, this->windowHeight);
this->updateText();
onFocus=[this]() {
this->focused = true;
this->cursorBox->x = x ;
this->cursorBox->y = y;
if (this->boundToPage) {
this->cursorBox->y = this->windowHeight + y - 13;
}
this->cursorBox->resize(this->windowWidth, this->windowHeight);
this->win->renderDirty = true;
};
onBlur=[this]() {
this->focused = false;
this->win->renderDirty = true;
};
//std::cout << "InputComponent::InputComponent - placing box at " << (int)x << "," << (int)y << " size: " << (int)width << "x" << (int)height << std::endl;
@ -90,7 +120,8 @@ InputComponent::InputComponent(const float rawX, const float rawY, const float r @@ -90,7 +120,8 @@ InputComponent::InputComponent(const float rawX, const float rawY, const float r
}
void InputComponent::render() {
//std::cout << "InputComponent::render" << std::endl;
//std::cout << "InputComponent::render - at " << (int)x << "," << (int)y << std::endl;
//std::cout << "InputComponent::render - boundToPage " << boundToPage << std::endl;
GLenum glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "InputComponent::render - start not ok: " << glErr << std::endl;
@ -135,6 +166,7 @@ void InputComponent::render() { @@ -135,6 +166,7 @@ void InputComponent::render() {
if(glErr != GL_NO_ERROR) {
std::cout << "InputComponent::render - glGetUniformLocation not ok: " << glErr << std::endl;
}
// it's about the document transformMatrix
glUniformMatrix4fv(transformLocation, 1, GL_FALSE, window->transformMatrix);
glErr=glGetError();
if(glErr != GL_NO_ERROR) {
@ -145,10 +177,26 @@ void InputComponent::render() { @@ -145,10 +177,26 @@ void InputComponent::render() {
userInputText->render();
glUseProgram(window->textureProgram);
}
if (focused) {
//std::cout << "Rendering cursor" << std::endl;
// blink cursor
if (cursorTimer != nullptr) {
scheduler->clearInterval(cursorTimer);
}
cursorTimer = scheduler->setInterval([this]() {
this->showCursor = !this->showCursor;
//std::cout << "showCursor " << this->showCursor << std::endl;
this->win->renderDirty = true;
}, 500);
// render it if we need to
if (showCursor) {
cursorBox->render();
}
}
}
// this doesn't seem to work
// text is fine though
void InputComponent::resize(const int passedWindowWidth, const int passedWindowHeight) {
//std::cout << "InputComponent::resize" << std::endl;
//std::cout << "InputComponent::resize - rasterizing at " << (int)x << "x" << (int)y << " size: " << (int)width << "x" << (int)height << std::endl;
@ -157,7 +205,9 @@ void InputComponent::resize(const int passedWindowWidth, const int passedWindowH @@ -157,7 +205,9 @@ void InputComponent::resize(const int passedWindowWidth, const int passedWindowH
// set up state
windowWidth = passedWindowWidth;
windowHeight = passedWindowHeight;
//std::cout << "InputComponent::resize - boxShader: " << useBoxShader << " boundToPage: " << boundToPage << std::endl;
/*
if (!boundToPage) {
// ok because box shader is anchored to the bottom of the screen
@ -184,25 +234,11 @@ void InputComponent::resize(const int passedWindowWidth, const int passedWindowH @@ -184,25 +234,11 @@ void InputComponent::resize(const int passedWindowWidth, const int passedWindowH
float vx = x;
float vy = y;
//float vx1 = x + width;
//float vy1 = y - height;
/*
std::cout << "placing box at " << (int)vx << "," << (int)vy << " size: " << (int)width << "x" << (int)height << " v1: " << (int)vx1 << "," << (int)vy1 << std::endl;
//float vWidth = width;
//float vHeight = height;
boundToPage = true;
pointToViewport(vx, vy);
pointToViewport(vx1, vy1);
std::cout << "TRUE placing box at GL v: " << vx << "," << vy << " v1: " << vx1 << "," << vy1 << std::endl;
vx = x;
vy = y;
vx1 = x + width;
vy1 = y - height;
boundToPage = false;
*/
if (boundToPage) {
vy = this->windowHeight + y - height;
//std::cout << "InputComponent::resize - Adjust y to " << vy << " from " << y << " h: " << (int)height << std::endl;
}
pointToViewport(vx, vy);
//pointToViewport(vx1, vy1);
float vWidth = width;
float vHeight = height;
@ -210,15 +246,8 @@ void InputComponent::resize(const int passedWindowWidth, const int passedWindowH @@ -210,15 +246,8 @@ void InputComponent::resize(const int passedWindowWidth, const int passedWindowH
float vx1 = vx + vWidth;
float vy1 = vy + vHeight;
//std::cout << "FALSE placing box at GL v: " << vx << "," << vy << " v1: " << vx1 << "," << vy1 << std::endl;
//std::cout << "InputComponent::resize - placing box at GL " << vx << "," << vy << " to " << vx1 << "," << vy1 << " size: " << vWidth << "x" << vHeight << std::endl;
// converts 512 to 1 and 1 to 2
//std::cout << "vWidth before: " << (int)vWidth << std::endl;
//distanceToViewport(vWidth, vHeight);
//std::cout << "vWidth after: " << (int)vWidth << std::endl;
vertices[(0 * 5) + 0] = vx;
vertices[(0 * 5) + 1] = vy1;
@ -232,19 +261,15 @@ void InputComponent::resize(const int passedWindowWidth, const int passedWindowH @@ -232,19 +261,15 @@ void InputComponent::resize(const int passedWindowWidth, const int passedWindowH
vertices[(3 * 5) + 1] = vy;
glBindVertexArray(vertexArrayObject);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBufferObject);
//glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glBindVertexArray(0); // protect what we created against any further modification
//updateText();
if (userInputText) {
// do we need updateText here?
userInputText->resize(passedWindowWidth, passedWindowHeight);
}
}
@ -273,6 +298,7 @@ void InputComponent::updateText() { @@ -273,6 +298,7 @@ void InputComponent::updateText() {
} else {
userInputText->y = y - windowHeight + 16;
}
userInputText->boundToPage = this->boundToPage;
//std::cout << "placed userInputText at " << static_cast<int>(x) << "," << static_cast<int>(y - windowHeight) << std::endl;
// 125 pixels width
// but first we need to know how wide the text is
@ -299,6 +325,16 @@ void InputComponent::updateText() { @@ -299,6 +325,16 @@ void InputComponent::updateText() {
//std::cout << "scrolling text" << std::endl;
userInputText->rasterStartX = estWidth - width;
}
// this is texture shader coordinates now (not text shader coords)
cursorBox->x = x + estWidth;
if (boundToPage) {
cursorBox->y = windowHeight + y - 13;
} else {
cursorBox->y = y;
}
//std::cout << "placing cursor at " << (int)cursorBox->x << "," << (int)cursorBox->y << std::endl;
cursorBox->resize(windowWidth, windowHeight);
userInputText->noWrap = true;
// why does changing the width mess shit up?
//std::cout << "InputComponent::updateText - our width: " << static_cast<int>(width) << " windowWidth: " << windowWidth << std::endl;

5
src/graphics/components/InputComponent.h

@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
#include "BoxComponent.h"
#include "TextComponent.h"
#include "../opengl/Window.h"
#include "../../scheduler.h"
class Window;
@ -22,9 +23,13 @@ public: @@ -22,9 +23,13 @@ public:
void updateText();
std::string value="";
TextComponent *userInputText = nullptr;
BoxComponent *cursorBox = nullptr;
std::function<void(std::string value)> onEnter = nullptr;
// needed for our shader's resizing
int lastRenderedWindowHeight;
bool focused = false;
bool showCursor = true;
std::shared_ptr<timer_handle> cursorTimer = nullptr;
// handle to signal that a redraw is needed, and access to shader programs
Window *win;
};

17
src/graphics/components/MultiComponent.cpp

@ -111,7 +111,16 @@ MultiComponent::MultiComponent(const float rawX, const float rawY, const float r @@ -111,7 +111,16 @@ MultiComponent::MultiComponent(const float rawX, const float rawY, const float r
// should we mark win->renderDirty = true?
};
onKeyup=[this](int key, int scancode, int action, int mods) {
//std::cout << "MultiComponent::MultiComponent:onKeyup" << std::endl;
//std::cout << "MultiComponent::MultiComponent:onKeyup - focused on " << typeOfComponent(this->focusedComponent) << std::endl;
DocumentComponent *docComponent = dynamic_cast<DocumentComponent*>(this->focusedComponent.get());
if (docComponent) {
if (action == 0) {
if (docComponent->onKeyup) {
docComponent->onKeyup(key, scancode, action, mods);
}
}
return;
}
InputComponent *inputComponent = dynamic_cast<InputComponent*>(this->focusedComponent.get());
if (inputComponent) {
//std::cout << "inputComponent is focused, key pressed " << key << " action: " <<action << std::endl;
@ -216,12 +225,12 @@ void MultiComponent::render() { @@ -216,12 +225,12 @@ void MultiComponent::render() {
GLint transformLocation = glGetUniformLocation(win->fontProgram, "transform");
GLenum glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "InputComponent::render - glGetUniformLocation not ok: " << glErr << std::endl;
std::cout << "MultiComponent::render - glGetUniformLocation not ok: " << glErr << std::endl;
}
glUniformMatrix4fv(transformLocation, 1, GL_FALSE, win->transformMatrix);
glErr=glGetError();
if(glErr != GL_NO_ERROR) {
std::cout << "InputComponent::render - glUniformMatrix4fv not ok: " << glErr << std::endl;
std::cout << "MultiComponent::render - glUniformMatrix4fv not ok: " << glErr << std::endl;
}
}
renderComponents(rootComponent);
@ -294,7 +303,7 @@ void MultiComponent::renderBoxComponents(std::shared_ptr<Component> component) { @@ -294,7 +303,7 @@ void MultiComponent::renderBoxComponents(std::shared_ptr<Component> component) {
void MultiComponent::renderComponentType(std::string str, std::shared_ptr<Component> component) {
if (!component) {
std::cout << "Window::renderComponentType - got null passed" << std::endl;
std::cout << "MultiComponent::renderComponentType - got null passed" << std::endl;
return;
}
if (typeOfComponent(component) == str) {

2
src/graphics/components/MultiComponent.h

@ -50,6 +50,6 @@ public: @@ -50,6 +50,6 @@ public:
double cursorY = 0;
};
extern const std::unique_ptr<Window> window;
//extern const std::unique_ptr<Window> window;
#endif

10
src/graphics/components/TabbedComponent.cpp

@ -355,11 +355,11 @@ void TabbedComponent::selectTab(std::shared_ptr<Tab> tab) { @@ -355,11 +355,11 @@ void TabbedComponent::selectTab(std::shared_ptr<Tab> tab) {
// we're not going to do a full set up uiContorl, we'll expect those to be set up and just adjust them
// but then, we can't just call this to place things where we want in the cstr... hrm..
void TabbedComponent::layoutTab(std::vector<std::shared_ptr<Tab>>::iterator tab) {
std::cout << "TabbedComponent::layoutTab - id: " << tab->get()->id << std::endl;
//std::cout << "TabbedComponent::layoutTab - id: " << tab->get()->id << std::endl;
// find text
TextComponent *textComponent = tab->get()->titleBox.get();
if (!textComponent) {
std::cout << "TabbedComponent::loadDomIntoTab - titleBox isn't a TextComponent" << std::endl;
std::cout << "TabbedComponent::layoutTab - titleBox isn't a TextComponent" << std::endl;
return;
}
@ -369,13 +369,13 @@ void TabbedComponent::layoutTab(std::vector<std::shared_ptr<Tab>>::iterator tab) @@ -369,13 +369,13 @@ void TabbedComponent::layoutTab(std::vector<std::shared_ptr<Tab>>::iterator tab)
//Tab *prev = it->get();
Tab *prev = tab->get()->previousTab.get();
if (prev == nullptr) {
std::cout << "relaying out first tab, no prev" << std::endl;
//std::cout << "TabbedComponent::layoutTab - relaying out first tab, no prev" << std::endl;
//prev = nullptr;
tab->get()->x = x + 32; // our start + 32px for new tab button
} else {
tab->get()->x = prev->x + static_cast<int>(prev->w);
}
std::cout << "placing tab at " << tab->get()->x << std::endl;
//std::cout << "TabbedComponent::layoutTab - placing tab at " << tab->get()->x << std::endl;
// get text size for it's current string
// we don't always need to adjust textWidth, only on text change
@ -417,7 +417,7 @@ void TabbedComponent::layoutTab(std::vector<std::shared_ptr<Tab>>::iterator tab) @@ -417,7 +417,7 @@ void TabbedComponent::layoutTab(std::vector<std::shared_ptr<Tab>>::iterator tab)
// maybe take in a starting tab? as tabs to left aren't affected
void TabbedComponent::layoutTabs(std::vector<std::shared_ptr<Tab>>::iterator startTab, int xAdj) {
std::cout << "TabbedComponent::layoutTabs - startId: " << startTab->get()->id << " xadj: " << xAdj << std::endl;
//std::cout << "TabbedComponent::layoutTabs - startId: " << startTab->get()->id << " xadj: " << xAdj << std::endl;
// luckily only one component at a time changes, we'll need to know how much x shifted
for(std::vector<std::shared_ptr<Tab>>::iterator it = startTab; it!=this->tabs.end(); ++it) {
//it->get()->x += xAdj; // adjust position

8
src/graphics/components/TextComponent.cpp

@ -110,14 +110,11 @@ void TextComponent::rasterize(const int rawX, const int rawY) { @@ -110,14 +110,11 @@ void TextComponent::rasterize(const int rawX, const int rawY) {
//glyphs = textRasterizer->rasterize(text, rawX, windowWidth, wrapToX, width, height, glyphCount, endingX, endingY, wrapped);
rasterizationRequest request;
request.text = text;
// startX needs to be relative to the parent x. Why?
// I think for non-boundComponents
request.startX = rawX; // - x
/*
if (!boundToPage) {
// startX needs to be relative to the parent x. Why?
request.startX -= x;
}
*/
//std::cout << "TextComponent::rasterize - [" << text << "] request.startX: " << request.startX << " x: " << x << " rawX: " << rawX << std::endl;
request.availableWidth = availableWidth;
request.sourceStartX = rasterStartX;
@ -126,7 +123,8 @@ void TextComponent::rasterize(const int rawX, const int rawY) { @@ -126,7 +123,8 @@ void TextComponent::rasterize(const int rawX, const int rawY) {
//std::cout << "rasterizing [" << text << "] @" << rawX << " availableWidth: " << availableWidth << " sourceStartX: " << rasterStartX << " noWrap: " << noWrap << std::endl;
std::shared_ptr<rasterizationResponse> response = textRasterizer->rasterize(request);
if (response.get() == nullptr) {
std::cout << "TextComponent::rasterize - got nullptr from rasterizer" << std::endl;
// window could be minimized
//std::cout << "TextComponent::rasterize - got nullptr from rasterizer" << std::endl;
return;
}
width = response->width;

31
src/graphics/opengl/Window.cpp

@ -207,6 +207,7 @@ bool Window::init() { @@ -207,6 +207,7 @@ bool Window::init() {
navAddressBar->uiControl.h = { 0, 24 }; // 24px
navAddressBar->name = "navAddressBar";
navAddressBar->boundToPage = false;
navAddressBar->win = this;
//navAddressBar->y = -48; // this works but breaks picking
navAddressBar->value = currentURL.toString();
navAddressBar->updateText();
@ -401,10 +402,12 @@ bool Window::initGLFW() { @@ -401,10 +402,12 @@ bool Window::initGLFW() {
}
}
thiz->focusedComponent = thiz->hoverComponent;
/*
InputComponent *inputComponent = dynamic_cast<InputComponent*>(thiz->focusedComponent.get());
if (inputComponent) {
std::cout << "inputComponent focus" << std::endl;
}
*/
if (thiz->focusedComponent && thiz->focusedComponent->onMouseup) {
//std::cout << "click event" << std::endl;
thiz->focusedComponent->onMouseup(thiz->cursorX, thiz->cursorY);
@ -428,7 +431,25 @@ bool Window::initGLFW() { @@ -428,7 +431,25 @@ bool Window::initGLFW() {
glfwSetKeyCallback(window, [](GLFWwindow *win, int key, int scancode, int action, int mods) {
Window *thiz = reinterpret_cast<Window*>(glfwGetWindowUserPointer(win));
// we're focused on something
//std::cout << "glfwSetKeyCallback" << std::endl;
if (thiz->focusedComponent) {
//std::cout << "glfwSetKeyCallback - focused on " << typeOfComponent(thiz->focusedComponent) << std::endl;
TabbedComponent *p_tabComponent = dynamic_cast<TabbedComponent*>(thiz->focusedComponent.get());
if (p_tabComponent) {
// repeat or key up
if (action == 2 || action == 0) {
if (p_tabComponent->onKeyPress) {
p_tabComponent->onKeyPress(key, scancode, action, mods);
}
if (action == 0) {
if (p_tabComponent->onKeyup) {
p_tabComponent->onKeyup(key, scancode, action, mods);
}
}
}
return;
}
DocumentComponent *docComponent = dynamic_cast<DocumentComponent*>(thiz->focusedComponent.get());
if (docComponent) {
if (action == 0) {
@ -526,7 +547,11 @@ bool Window::initGLFW() { @@ -526,7 +547,11 @@ bool Window::initGLFW() {
}
printf("\n\n");
}
if (key == GLFW_KEY_F && action == GLFW_RELEASE) {
printf("Printing UI ComponentTree\n\n");
Component::printComponentTree(thiz->rootComponent, 0);
printf("\n\n");
}
int yOffsetScroll = 1;
if (key == GLFW_KEY_PAGE_UP && (action == GLFW_PRESS || action == GLFW_REPEAT)) {
TabbedComponent *p_TabComponent = dynamic_cast<TabbedComponent*>(thiz->tabComponent.get());
@ -634,7 +659,9 @@ bool Window::initGL() { @@ -634,7 +659,9 @@ bool Window::initGL() {
}
//std::cout << "OpenGL is set up" << std::endl;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
return true;
}

1
src/graphics/opengl/Window.h

@ -39,6 +39,7 @@ public: @@ -39,6 +39,7 @@ public:
void navTo(std::string url);
// properties
int maxTextureSize = 0;
float transformMatrix[16] = {
1, 0, 0, 0,
0, 1, 0, 0,

14
src/graphics/text/TextRasterizer.cpp

@ -37,7 +37,10 @@ TextRasterizer::~TextRasterizer() { @@ -37,7 +37,10 @@ TextRasterizer::~TextRasterizer() {
}
std::unique_ptr<std::pair<int, int>> TextRasterizer::size(const rasterizationRequest &request) const {
if (!request.availableWidth) {
// window is likely minimized, so no output
return nullptr;
}
if (request.startX == request.availableWidth) {
std::cout << "TextRasterizer::size - x [" << static_cast<int>(request.startX) << "] matches window width [" << static_cast<int>(request.availableWidth)<< "] for text[" << request.text << "] no room to render anything" << std::endl;
return nullptr;
@ -151,6 +154,7 @@ std::unique_ptr<std::pair<int, int>> TextRasterizer::size(const rasterizationReq @@ -151,6 +154,7 @@ std::unique_ptr<std::pair<int, int>> TextRasterizer::size(const rasterizationReq
response->height = y1max;
//std::cout << "adjusted:" << (int)width << "x" << (int)height << std::endl;
}
// FIXME: how about endingX,Y?
return std::make_unique<std::pair<int, int>>(std::pair<int, int>(response->width, response->height));
}
@ -310,12 +314,10 @@ std::unique_ptr<rasterizationResponse> TextRasterizer::rasterize(const rasteriza @@ -310,12 +314,10 @@ std::unique_ptr<rasterizationResponse> TextRasterizer::rasterize(const rasteriza
response->y1 = -response->height;
//std::cout << "xd: " << static_cast<int>(response->x1-response->x0) << " yd: " << static_cast<int>(response->y0-response->y1) << std::endl;
GLint max;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max);
std::cout << "Requesting texture of " << response->textureWidth << "x" << response->textureHeight << "max: " << max << std::endl;
if (response->textureHeight > static_cast<unsigned int>(max)) {
//std::cout << "Requesting texture of " << response->textureWidth << "x" << response->textureHeight << "max: " << win->maxTextureSize << std::endl;
if (response->textureHeight > static_cast<unsigned int>(win->maxTextureSize)) {
std::cout << "Truncating text texture to fit in your video card" << std::endl;
response->textureHeight = static_cast<unsigned int>(max);
response->textureHeight = static_cast<unsigned int>(win->maxTextureSize);
}
// texture coords

2
src/graphics/text/TextRasterizer.h

@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
#include <memory>
#include <string>
#include <algorithm>
#include "../opengl/Window.h"
struct Glyph {
float x0;
@ -76,6 +77,7 @@ public: @@ -76,6 +77,7 @@ public:
hb_font_t *font;
hb_buffer_t *buffer;
std::unique_ptr<FT_Face> face;
Window *win;
};
#endif

9
src/graphics/text/TextRasterizerCache.cpp

@ -1,7 +1,10 @@ @@ -1,7 +1,10 @@
#include "TextRasterizerCache.h"
#include <iostream>
TextRasterizerCache *rasterizerCache=new TextRasterizerCache;
extern const std::unique_ptr<Window> window;
// reduces this:
// Updated DOM in: 6.787870 seconds
// to this:
@ -9,14 +12,18 @@ TextRasterizerCache *rasterizerCache=new TextRasterizerCache; @@ -9,14 +12,18 @@ TextRasterizerCache *rasterizerCache=new TextRasterizerCache;
std::shared_ptr<TextRasterizer> TextRasterizerCache::loadFont(const unsigned int size, const bool bold) {
if (bold) {
if (fontSizes_bold.find(size) == fontSizes_bold.end()) {
//std::cout << "Making bold font" << std::endl;
fontSizes_bold[size]=std::make_shared<TextRasterizer>("DejaVuSerif.ttf", size, 72, bold);
fontSizes_bold[size]->win = window.get();
}
return fontSizes_bold[size];
}
else {
if (fontSizes_notbold.find(size) == fontSizes_notbold.end()) {
//std::cout << "Making font" << std::endl;
fontSizes_notbold[size]=std::make_shared<TextRasterizer>("DejaVuSerif.ttf", size, 72, bold);
fontSizes_notbold[size]->win = window.get();
}
return fontSizes_notbold[size];
}
}
}

27
src/main.cpp

@ -5,6 +5,8 @@ @@ -5,6 +5,8 @@
#include "URL.h"
#include "WebResource.h"
#include "tlsf.h"
#include "scheduler.h"
#include <ctime>
#include <iostream>
#include <sys/stat.h>
@ -21,8 +23,11 @@ extern "C"{ @@ -21,8 +23,11 @@ extern "C"{
#endif
const std::unique_ptr<Window> window = std::make_unique<Window>();
// why can't I const this?
std::unique_ptr<Scheduler> scheduler = std::make_unique<Scheduler>();
//URL currentURL;
bool setWindowContent(URL const& url) {
logDebug() << "main::setWindowContent - " << url << std::endl;
@ -47,17 +52,19 @@ bool setWindowContent(URL const& url) { @@ -47,17 +52,19 @@ bool setWindowContent(URL const& url) {
std::cout << "Rendering text document" << std::endl;
std::shared_ptr<Node> rootNode = std::make_shared<Node>(NodeType::ROOT);
std::shared_ptr<TagNode> tagNode = std::make_shared<TagNode>();
tagNode->tag="p";
// bind tag to root
tagNode->parent = rootNode;
rootNode->children.push_back(tagNode);
std::shared_ptr<TextNode> textNode = std::make_shared<TextNode>();
textNode->text = res.raw;
tagNode->tag="p";
// bind text to tag
textNode->parent = tagNode;
tagNode->children.push_back(textNode);
// bind tag to root
tagNode->parent = rootNode;
rootNode->children.push_back(tagNode);
// send NodeTree to window
window->setDOM(rootNode);
} else {
@ -124,11 +131,19 @@ int main(int argc, char *argv[]) { @@ -124,11 +131,19 @@ int main(int argc, char *argv[]) {
}
}
while (!glfwWindowShouldClose(window->window)) {
//const std::clock_t begin = clock();
window->render();
glfwWaitEvents(); // block until something changes
scheduler->fireTimers(); // render may have taken some time
double next = scheduler->getNext();
//std::cout << "next timer at " << next << std::endl;
if (next == LONG_MAX) {
glfwWaitEvents(); // block until something changes
} else {
glfwWaitEventsTimeout(next / 1000);
}
scheduler->fireTimers(); // check before we go into render again
//glfwWaitEventsTimeout(1.0 / 60.0); // increase the cpu from 0% to 2% on idle
//const std::clock_t end = clock();
//std::cout << '\r' << std::fixed << (((static_cast<double>(end - begin)) / CLOCKS_PER_SEC) * 1000) << std::scientific << " ms/f " << std::flush;
}

77
src/scheduler.cpp

@ -0,0 +1,77 @@ @@ -0,0 +1,77 @@
#include "scheduler.h"
#include <GLFW/glfw3.h>
#include <iostream>
#include <algorithm>
std::shared_ptr<timer_handle> Scheduler::setTimeout(std::function<void()> callback, unsigned long delay) {
double now = glfwGetTime() * 1000;
std::shared_ptr<timer_handle> handle = std::make_shared<timer_handle>();
handle->callback = callback;
handle->nextAt = now + delay;
handle->timeout = true;
this->timers.push_back(handle);
return handle;
}
std::shared_ptr<timer_handle> Scheduler::setInterval(std::function<void()> callback, unsigned long delay) {
double now = glfwGetTime() * 1000;
//std::cout << "Scheduler::setInterval at " << (int)now << std::endl;
std::shared_ptr<timer_handle> handle = std::make_shared<timer_handle>();
handle->callback = callback;
handle->nextAt = now + delay;
handle->timeout = false;
this->timers.push_back(handle);
//std::cout << "scheduled at " << (int)handle->nextAt << std::endl;
return handle;
}
unsigned long Scheduler::getNext() {
unsigned long lowest = LONG_MAX;
double now = glfwGetTime() * 1000; // it's number of ms since start up
//std::cout << "there are " << this->timers.size() << std::endl;
for(std::vector<std::shared_ptr<timer_handle>>::iterator it=this->timers.begin(); it!=this->timers.end(); ++it) {
//std::cout << "nextAt " << (int)it->get()->nextAt << " long " << (int)(now - it->get()->nextAt) << std::endl;
//std::cout << "now " << (int)now << " nextAt: " << (int)it->get()->nextAt << std::endl;
int diff = now - it->get()->nextAt;
if (diff < 0) diff = 0;
//std::cout << "timer fires in " << diff << std::endl;
lowest = std::min(lowest, static_cast<unsigned long>(diff));
}
//std::cout << "returning " << lowest << std::endl;
return lowest;
}
bool Scheduler::fireTimer(std::shared_ptr<timer_handle> timer, double now) {
timer->callback();
if (timer->timeout) {
return true;
}
// schedule the next one
timer->nextAt = now + timer->nextAt;
return false;
}
void Scheduler::fireTimers() {
double now = glfwGetTime() * 1000;
for(std::vector<std::shared_ptr<timer_handle>>::iterator it=this->timers.begin(); it!=this->timers.end(); ++it) {
if (it->get()->nextAt < now) {
if (this->fireTimer(*it, now)) {
it = this->timers.erase(it);
if (it == this->timers.end()) break;
}
}
}
}
bool Scheduler::clearInterval(std::shared_ptr<timer_handle> timer) {
// find and remove it
//it2 = std::find(this->rootComponent->children.begin(), this->rootComponent->children.end(), it->get()->selectorBox);
std::vector<std::shared_ptr<timer_handle>>::iterator it = std::find(this->timers.begin(), this->timers.end(), timer);
if (it != this->timers.end()) {
//std::cout << "Clearing Interval" << std::endl;
this->timers.erase(it);
} else {
std::cout << "Couldnt find timer" << std::endl;
}
return true;
}

27
src/scheduler.h

@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
#ifndef SCHEDULER_H
#define SCHEDULER_H
#include <memory>
#include <vector>
#include <functional>
#include <limits.h>
class timer_handle {
public:
double nextAt; // in milliseconds
bool timeout;
std::function<void()> callback;
};
class Scheduler {
public:
std::shared_ptr<timer_handle> setTimeout(std::function<void()> callback, unsigned long delay);
std::shared_ptr<timer_handle> setInterval(std::function<void()> callback, unsigned long delay);
unsigned long getNext();
bool fireTimer(std::shared_ptr<timer_handle> timer, double now);
void fireTimers();
bool clearInterval(std::shared_ptr<timer_handle> timer);
std::vector<std::shared_ptr<timer_handle>> timers;
};
#endif
Loading…
Cancel
Save