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.

Window.cpp 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. #include "Window.h"
  2. #include "../../../../parsers/markup/TagNode.h"
  3. #include "../../../../parsers/markup/TextNode.h"
  4. #include "../../../../networking/HTTPRequest.h"
  5. #include "../../../../parsers/markup/html/HTMLParser.h"
  6. #include "../../../../tools/StringUtils.h"
  7. #include "../../../../tools/Log.h"
  8. #include "../../../components/BoxComponent.h"
  9. #include "../../../components/ImageComponent.h"
  10. #include "../../../components/DocumentComponent.h"
  11. #include "../../../components/TabbedComponent.h"
  12. #include "../../../components/TextComponent.h"
  13. #include "../../../components/TabbedComponent.h"
  14. #include "../../../components/InputComponent.h"
  15. #include "Shader.h"
  16. #include "../../../../app/browser/Browser.h"
  17. #include <cmath>
  18. #include <ctime>
  19. #include <iostream>
  20. extern std::unique_ptr<Browser> browser;
  21. Window::~Window() {
  22. glfwTerminate();
  23. }
  24. bool Window::init() {
  25. Rect windowPosSize;
  26. windowPosSize.x = 0;
  27. windowPosSize.y = 0;
  28. // these are set before init is called
  29. windowPosSize.w = this->windowWidth;
  30. windowPosSize.h = this->windowHeight;
  31. OpenGL *pRenderer = dynamic_cast<OpenGL *>(renderer.get());
  32. if (!pRenderer) {
  33. //WindowHandle *tWin = renderer->createWindow("NeTRunner", &windowPosSize, 0);
  34. //this->window = tWin->window;
  35. std::cout << "Window::init - we only support OpenGL renderer" << std::endl;
  36. return false;
  37. }
  38. this->openglWindow = pRenderer->createWindow("NeTRunner", &windowPosSize, 0);
  39. this->window = this->openglWindow->window;
  40. //std::cout << "OpenGL is set up" << std::endl;
  41. glGetIntegerv(GL_MAX_TEXTURE_SIZE, &this->maxTextureSize);
  42. std::cout << "Max texture size: " << this->maxTextureSize << std::endl;
  43. // set up our UI with a new window
  44. this->ui = std::make_unique<MultiComponent>(0, 0, this->windowWidth, this->windowHeight, this->windowWidth, this->windowHeight);
  45. this->ui->windowed = true;
  46. this->ui->win = shared_from_this();
  47. this->cursorHand = pRenderer->cursorHand;
  48. this->cursorArrow = pRenderer->cursorArrow;
  49. this->cursorIbeam = pRenderer->cursorIbeam;
  50. // relay events to our ui
  51. // window
  52. //this->openglWindow->onResize = this->ui->onResize;
  53. // use our delayed resizer
  54. this->openglWindow->onResize=[&](int w, int h) {
  55. this->onResize(w, h);
  56. };
  57. // mouse
  58. this->openglWindow->onMouseMove = this->ui->onMousemove;
  59. this->openglWindow->onMouseDown = this->ui->onMousedown;
  60. this->openglWindow->onMouseUp = this->ui->onMouseup;
  61. this->openglWindow->onWheel = this->ui->onWheel;
  62. // keyboard
  63. this->openglWindow->onKeyUp = [&](int key, int scancode, int mods) {
  64. this->ui->onKeyUp(key, scancode, 0, mods);
  65. };
  66. return true;
  67. }
  68. /*
  69. bool Window::initGLFW() {
  70. std::cout << "Window::initGLFW" << std::endl;
  71. if (!glfwInit()) {
  72. std::cout << "Could not initialize GLFW" << std::endl;
  73. return false;
  74. }
  75. glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  76. glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
  77. glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
  78. glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  79. //glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_EGL_CONTEXT_API);
  80. glfwSetErrorCallback([](int error, const char* description) {
  81. std::cout << "glfw error [" << error << "]:" << description << std::endl;
  82. });
  83. GLFWwindow *context = nullptr;
  84. if (browser->windows.size()) {
  85. context = browser->windows.front().get()->window;
  86. }
  87. // after title, it's monitor
  88. window = glfwCreateWindow(windowWidth, windowHeight, "NetRunner", nullptr, context);
  89. if (!window) {
  90. glfwTerminate();
  91. std::cout << "Could not create window" << std::endl;
  92. return false;
  93. }
  94. // replace first parameter of all these callbacks with our window object instead of a GLFWwindow
  95. glfwSetWindowUserPointer(window, this);
  96. // set window w/h
  97. //glfwGetFramebufferSize(window, &windowWidth, &windowHeight); // in pixels
  98. glfwGetWindowSize(window, &windowWidth, &windowHeight); // use screen coordinates (not pixels) more retina friendly
  99. // set up event callbacks
  100. glfwSetFramebufferSizeCallback(window, [](GLFWwindow *win, int width, int height) {
  101. glViewport(0, 0, width, height);
  102. });
  103. glfwSetWindowSizeCallback(window, [](GLFWwindow *win, int width, int height) {
  104. Window *thiz = reinterpret_cast<Window*>(glfwGetWindowUserPointer(win));
  105. thiz->onResize(width, height);
  106. });
  107. cursorHand = glfwCreateStandardCursor(GLFW_HAND_CURSOR);
  108. cursorArrow = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
  109. cursorIbeam = glfwCreateStandardCursor(GLFW_IBEAM_CURSOR);
  110. glfwSetCursorPosCallback(window, [](GLFWwindow *win, double xPos, double yPos) {
  111. Window *thiz = reinterpret_cast<Window*>(glfwGetWindowUserPointer(win));
  112. thiz->cursorX = xPos;
  113. thiz->cursorY = yPos;
  114. //std::cout << "Window::Window:onMousemove - at " << static_cast<int>(xPos) << "," << static_cast<int>(yPos) << std::endl;
  115. if (xPos < 0 || yPos < 0) return;
  116. if (xPos > thiz->windowWidth || yPos > thiz->windowHeight) return;
  117. // p. much worthless on double
  118. */
  119. /*
  120. static double lx = 0;
  121. static double ly = 0;
  122. if (lx == xPos && ly == yPos) {
  123. return;
  124. }
  125. lx = xPos;
  126. ly = yPos;
  127. std::cout << "Window::Window:onMousemove - noCache" << std::endl;
  128. */
  129. /*
  130. //std::cout << "Window::Window:onMousemove - begin search" << std::endl;
  131. //std::cout << "Window::Window:onMousemove - windowHeight: " << thiz->windowHeight << " cursorY: " << thiz->cursorY << " scrollY: " << thiz->transformMatrix[13] << std::endl;
  132. thiz->ui->onMousemove(thiz->cursorX, thiz->cursorY);
  133. });
  134. glfwSetScrollCallback(window, [](GLFWwindow *win, double xOffset, double yOffset) {
  135. Window *thiz = reinterpret_cast<Window*>(glfwGetWindowUserPointer(win));
  136. //std::cout << "glfwSetScrollCallback " << yOffset << " int" << (int)(yOffset * 10) << std::endl;
  137. thiz->ui->onWheel(xOffset * 10, yOffset * 10);
  138. });
  139. glfwSetMouseButtonCallback(window, [](GLFWwindow *win, int button, int action, int mods) {
  140. Window *thiz = reinterpret_cast<Window*>(glfwGetWindowUserPointer(win));
  141. if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) {
  142. //std::cout << "left press" << std::endl;
  143. thiz->ui->onMousedown(thiz->cursorX, thiz->cursorY);
  144. }
  145. if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_RELEASE) {
  146. //std::cout << "left release" << std::endl;
  147. thiz->ui->onMouseup(thiz->cursorX, thiz->cursorY);
  148. }
  149. });
  150. // works with utf-32 and os keyboard layout but we'll lkeep the low level for now
  151. glfwSetCharCallback(window, [](GLFWwindow* win, unsigned int codepoint) {
  152. Window *thiz = reinterpret_cast<Window*>(glfwGetWindowUserPointer(win));
  153. //std::cout << "Window::glfwSetCharCallback - codepoint: " << codepoint << std::endl;
  154. // should be used for inputComponent
  155. });
  156. glfwSetKeyCallback(window, [](GLFWwindow *win, int key, int scancode, int action, int mods) {
  157. Window *thiz = reinterpret_cast<Window*>(glfwGetWindowUserPointer(win));
  158. std::cout << "Key " << key << " action: " << action << "mods: " << mods << std::endl;
  159. // command for OSX, otherwise control
  160. #if defined(__APPLE__) && defined(__MACH__)
  161. int attentionMod = GLFW_MOD_SUPER;
  162. #else
  163. int attentionMod = GLFW_MOD_CONTROL;
  164. #endif
  165. if (key == GLFW_KEY_N && action == GLFW_RELEASE && mods == attentionMod) {
  166. browser->addWindow();
  167. return;
  168. }
  169. if (key == GLFW_KEY_L && action == GLFW_RELEASE && mods == attentionMod) {
  170. if (thiz->ui->focusedComponent && thiz->ui->focusedComponent->onBlur) {
  171. thiz->ui->focusedComponent->onBlur();
  172. }
  173. if (thiz->addressComponent && thiz->addressComponent->onFocus) {
  174. thiz->addressComponent->onFocus();
  175. }
  176. thiz->ui->focusedComponent = thiz->addressComponent;
  177. return;
  178. }
  179. if (key == GLFW_KEY_T && action == GLFW_RELEASE && mods == attentionMod) {
  180. TabbedComponent *p_tabComponent = dynamic_cast<TabbedComponent*>(thiz->tabComponent.get());
  181. if (p_tabComponent) {
  182. p_tabComponent->selectTab(p_tabComponent->addTab("New Tab"));
  183. }
  184. return;
  185. }
  186. if (action == GLFW_RELEASE) {
  187. thiz->ui->onKeyUp(key, scancode, action, mods);
  188. }
  189. if (action == GLFW_REPEAT) {
  190. //thiz->ui->onKeyRepeat(key, scancode, mods);
  191. //thiz->ui->onKeyPress(key, scancode, action, mods);
  192. }
  193. if (action == GLFW_PRESS) {
  194. //thiz->ui->onKeyDown(key, scancode, mods);
  195. //thiz->ui->onKeyPress(key, scancode, action, mods);
  196. }
  197. });
  198. glfwMakeContextCurrent(window);
  199. return true;
  200. }
  201. */
  202. void Window::onResize(int passedWidth, int passedHeight) {
  203. //std::cout << "Window::onResize" << std::endl;
  204. this->windowWidth = passedWidth;
  205. this->windowHeight = passedHeight;
  206. this->delayResize = 1;
  207. }
  208. void Window::scrollDocument(int y) {
  209. //TabbedComponent *p_TabComponent = dynamic_cast<TabbedComponent*>(this->tabComponent.get());
  210. //if (p_TabComponent) {
  211. // dynamic_cast<DocumentComponent*>(p_TabComponent->documentComponent.get());
  212. DocumentComponent *p_DocComponent = this->getActiveDocumentComponent().get();
  213. if (p_DocComponent) {
  214. p_DocComponent->transformMatrix[13] += y;
  215. p_DocComponent->textureTransformMatrix[13] += y;
  216. p_DocComponent->transformMatrixDirty = true;
  217. this->renderDirty = true;
  218. //this->transformMatrixDirty = true;
  219. } else {
  220. std::cout << "Window::scrollDocument - no active docComponent" << std::endl;
  221. }
  222. //} else {
  223. //std::cout << "Window::scrollDocument - no tabComponent" << std::endl;
  224. //}
  225. }
  226. void Window::resize() {
  227. ui->resize(this->windowWidth, this->windowHeight);
  228. renderDirty = true;
  229. }
  230. void Window::render() {
  231. if (delayResize) {
  232. delayResize--;
  233. if (delayResize) {
  234. return;
  235. }
  236. //std::cout << "Window::render - restarting drawing" << std::endl;
  237. this->resize();
  238. }
  239. if (renderDirty) {
  240. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  241. ui->render();
  242. glfwSwapBuffers(window);
  243. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  244. ui->render();
  245. glfwSwapBuffers(window);
  246. renderDirty = false;
  247. }
  248. glfwSwapBuffers(window);
  249. glfwPollEvents();
  250. }
  251. std::shared_ptr<DocumentComponent> Window::getActiveDocumentComponent() {
  252. // need to cast it first
  253. TabbedComponent *p_tabComponent = dynamic_cast<TabbedComponent*>(this->tabComponent.get());
  254. if (!p_tabComponent) {
  255. std::cout << "Window::getActiveDocumentComponent - No active tab" << std::endl;
  256. return nullptr;
  257. }
  258. std::shared_ptr<DocumentComponent> docComponent = std::static_pointer_cast<DocumentComponent>(p_tabComponent->documentComponent);
  259. if (!docComponent) {
  260. std::cout << "Window::getActiveDocumentComponent - No active document" << std::endl;
  261. return nullptr;
  262. }
  263. return docComponent;
  264. }