You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

296 lines
11 KiB

#include "Window.h"
#include "../../../../parsers/markup/TagNode.h"
#include "../../../../parsers/markup/TextNode.h"
#include "../../../../networking/HTTPRequest.h"
#include "../../../../parsers/markup/html/HTMLParser.h"
#include "../../../../tools/StringUtils.h"
#include "../../../../tools/Log.h"
#include "../../../components/BoxComponent.h"
#include "../../../components/ImageComponent.h"
#include "../../../components/DocumentComponent.h"
#include "../../../components/TabbedComponent.h"
#include "../../../components/TextComponent.h"
#include "../../../components/TabbedComponent.h"
#include "../../../components/InputComponent.h"
#include "Shader.h"
#include "../../../../app/browser/browser.h"
#include <cmath>
#include <ctime>
#include <iostream>
extern std::unique_ptr<Browser> browser;
Window::~Window() {
glfwTerminate();
}
bool Window::init() {
Rect windowPosSize;
windowPosSize.x = 0;
windowPosSize.y = 0;
// these are set before init is called
windowPosSize.w = this->windowWidth;
windowPosSize.h = this->windowHeight;
OpenGL *pRenderer = dynamic_cast<OpenGL *>(renderer.get());
if (!pRenderer) {
//WindowHandle *tWin = renderer->createWindow("NeTRunner", &windowPosSize, 0);
//this->window = tWin->window;
std::cout << "Window::init - we only support OpenGL renderer" << std::endl;
return false;
}
this->openglWindow = pRenderer->createWindow("NeTRunner", &windowPosSize, 0);
this->window = this->openglWindow->window;
//std::cout << "OpenGL is set up" << std::endl;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &this->maxTextureSize);
std::cout << "Max texture size: " << this->maxTextureSize << std::endl;
// set up our UI with a new window
this->ui = std::make_unique<MultiComponent>(0, 0, this->windowWidth, this->windowHeight, this->windowWidth, this->windowHeight);
this->ui->windowed = true;
this->ui->win = shared_from_this();
this->cursorHand = pRenderer->cursorHand;
this->cursorArrow = pRenderer->cursorArrow;
this->cursorIbeam = pRenderer->cursorIbeam;
// relay events to our ui
// window
//this->openglWindow->onResize = this->ui->onResize;
// use our delayed resizer
this->openglWindow->onResize=[&](int w, int h) {
this->onResize(w, h);
};
// mouse
this->openglWindow->onMouseMove = this->ui->onMousemove;
this->openglWindow->onMouseDown = this->ui->onMousedown;
this->openglWindow->onMouseUp = this->ui->onMouseup;
this->openglWindow->onWheel = this->ui->onWheel;
// keyboard
this->openglWindow->onKeyUp = [&](int key, int scancode, int mods) {
this->ui->onKeyUp(key, scancode, 0, mods);
};
return true;
}
/*
bool Window::initGLFW() {
std::cout << "Window::initGLFW" << std::endl;
if (!glfwInit()) {
std::cout << "Could not initialize GLFW" << std::endl;
return false;
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_EGL_CONTEXT_API);
glfwSetErrorCallback([](int error, const char* description) {
std::cout << "glfw error [" << error << "]:" << description << std::endl;
});
GLFWwindow *context = nullptr;
if (browser->windows.size()) {
context = browser->windows.front().get()->window;
}
// after title, it's monitor
window = glfwCreateWindow(windowWidth, windowHeight, "NetRunner", nullptr, context);
if (!window) {
glfwTerminate();
std::cout << "Could not create window" << std::endl;
return false;
}
// replace first parameter of all these callbacks with our window object instead of a GLFWwindow
glfwSetWindowUserPointer(window, this);
// set window w/h
//glfwGetFramebufferSize(window, &windowWidth, &windowHeight); // in pixels
glfwGetWindowSize(window, &windowWidth, &windowHeight); // use screen coordinates (not pixels) more retina friendly
// set up event callbacks
glfwSetFramebufferSizeCallback(window, [](GLFWwindow *win, int width, int height) {
glViewport(0, 0, width, height);
});
glfwSetWindowSizeCallback(window, [](GLFWwindow *win, int width, int height) {
Window *thiz = reinterpret_cast<Window*>(glfwGetWindowUserPointer(win));
thiz->onResize(width, height);
});
cursorHand = glfwCreateStandardCursor(GLFW_HAND_CURSOR);
cursorArrow = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
cursorIbeam = glfwCreateStandardCursor(GLFW_IBEAM_CURSOR);
glfwSetCursorPosCallback(window, [](GLFWwindow *win, double xPos, double yPos) {
Window *thiz = reinterpret_cast<Window*>(glfwGetWindowUserPointer(win));
thiz->cursorX = xPos;
thiz->cursorY = yPos;
//std::cout << "Window::Window:onMousemove - at " << static_cast<int>(xPos) << "," << static_cast<int>(yPos) << std::endl;
if (xPos < 0 || yPos < 0) return;
if (xPos > thiz->windowWidth || yPos > thiz->windowHeight) return;
// p. much worthless on double
*/
/*
static double lx = 0;
static double ly = 0;
if (lx == xPos && ly == yPos) {
return;
}
lx = xPos;
ly = yPos;
std::cout << "Window::Window:onMousemove - noCache" << std::endl;
*/
/*
//std::cout << "Window::Window:onMousemove - begin search" << std::endl;
//std::cout << "Window::Window:onMousemove - windowHeight: " << thiz->windowHeight << " cursorY: " << thiz->cursorY << " scrollY: " << thiz->transformMatrix[13] << std::endl;
thiz->ui->onMousemove(thiz->cursorX, thiz->cursorY);
});
glfwSetScrollCallback(window, [](GLFWwindow *win, double xOffset, double yOffset) {
Window *thiz = reinterpret_cast<Window*>(glfwGetWindowUserPointer(win));
//std::cout << "glfwSetScrollCallback " << yOffset << " int" << (int)(yOffset * 10) << std::endl;
thiz->ui->onWheel(xOffset * 10, yOffset * 10);
});
glfwSetMouseButtonCallback(window, [](GLFWwindow *win, int button, int action, int mods) {
Window *thiz = reinterpret_cast<Window*>(glfwGetWindowUserPointer(win));
if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) {
//std::cout << "left press" << std::endl;
thiz->ui->onMousedown(thiz->cursorX, thiz->cursorY);
}
if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_RELEASE) {
//std::cout << "left release" << std::endl;
thiz->ui->onMouseup(thiz->cursorX, thiz->cursorY);
}
});
// works with utf-32 and os keyboard layout but we'll lkeep the low level for now
glfwSetCharCallback(window, [](GLFWwindow* win, unsigned int codepoint) {
Window *thiz = reinterpret_cast<Window*>(glfwGetWindowUserPointer(win));
//std::cout << "Window::glfwSetCharCallback - codepoint: " << codepoint << std::endl;
// should be used for inputComponent
});
glfwSetKeyCallback(window, [](GLFWwindow *win, int key, int scancode, int action, int mods) {
Window *thiz = reinterpret_cast<Window*>(glfwGetWindowUserPointer(win));
std::cout << "Key " << key << " action: " << action << "mods: " << mods << std::endl;
// command for OSX, otherwise control
#if defined(__APPLE__) && defined(__MACH__)
int attentionMod = GLFW_MOD_SUPER;
#else
int attentionMod = GLFW_MOD_CONTROL;
#endif
if (key == GLFW_KEY_N && action == GLFW_RELEASE && mods == attentionMod) {
browser->addWindow();
return;
}
if (key == GLFW_KEY_L && action == GLFW_RELEASE && mods == attentionMod) {
if (thiz->ui->focusedComponent && thiz->ui->focusedComponent->onBlur) {
thiz->ui->focusedComponent->onBlur();
}
if (thiz->addressComponent && thiz->addressComponent->onFocus) {
thiz->addressComponent->onFocus();
}
thiz->ui->focusedComponent = thiz->addressComponent;
return;
}
if (key == GLFW_KEY_T && action == GLFW_RELEASE && mods == attentionMod) {
TabbedComponent *p_tabComponent = dynamic_cast<TabbedComponent*>(thiz->tabComponent.get());
if (p_tabComponent) {
p_tabComponent->selectTab(p_tabComponent->addTab("New Tab"));
}
return;
}
if (action == GLFW_RELEASE) {
thiz->ui->onKeyUp(key, scancode, action, mods);
}
if (action == GLFW_REPEAT) {
//thiz->ui->onKeyRepeat(key, scancode, mods);
//thiz->ui->onKeyPress(key, scancode, action, mods);
}
if (action == GLFW_PRESS) {
//thiz->ui->onKeyDown(key, scancode, mods);
//thiz->ui->onKeyPress(key, scancode, action, mods);
}
});
glfwMakeContextCurrent(window);
return true;
}
*/
void Window::onResize(int passedWidth, int passedHeight) {
//std::cout << "Window::onResize" << std::endl;
this->windowWidth = passedWidth;
this->windowHeight = passedHeight;
this->delayResize = 1;
}
void Window::scrollDocument(int y) {
//TabbedComponent *p_TabComponent = dynamic_cast<TabbedComponent*>(this->tabComponent.get());
//if (p_TabComponent) {
// dynamic_cast<DocumentComponent*>(p_TabComponent->documentComponent.get());
DocumentComponent *p_DocComponent = this->getActiveDocumentComponent().get();
if (p_DocComponent) {
p_DocComponent->transformMatrix[13] += y;
p_DocComponent->textureTransformMatrix[13] += y;
p_DocComponent->transformMatrixDirty = true;
this->renderDirty = true;
//this->transformMatrixDirty = true;
} else {
std::cout << "Window::scrollDocument - no active docComponent" << std::endl;
}
//} else {
//std::cout << "Window::scrollDocument - no tabComponent" << std::endl;
//}
}
void Window::resize() {
ui->resize(this->windowWidth, this->windowHeight);
renderDirty = true;
}
void Window::render() {
if (delayResize) {
delayResize--;
if (delayResize) {
return;
}
//std::cout << "Window::render - restarting drawing" << std::endl;
this->resize();
}
if (renderDirty) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
ui->render();
glfwSwapBuffers(window);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
ui->render();
glfwSwapBuffers(window);
renderDirty = false;
}
glfwSwapBuffers(window);
glfwPollEvents();
}
std::shared_ptr<DocumentComponent> Window::getActiveDocumentComponent() {
// need to cast it first
TabbedComponent *p_tabComponent = dynamic_cast<TabbedComponent*>(this->tabComponent.get());
if (!p_tabComponent) {
std::cout << "Window::getActiveDocumentComponent - No active tab" << std::endl;
return nullptr;
}
std::shared_ptr<DocumentComponent> docComponent = std::static_pointer_cast<DocumentComponent>(p_tabComponent->documentComponent);
if (!docComponent) {
std::cout << "Window::getActiveDocumentComponent - No active document" << std::endl;
return nullptr;
}
return docComponent;
}