| @@ -8,6 +8,8 @@ include dpf/Makefile.base.mk | |||
| all: dgl plugins gen | |||
| SKIP_NANOVG = true | |||
| # -------------------------------------------------------------- | |||
| dgl: | |||
| @@ -40,9 +42,13 @@ clean: | |||
| rm -rf plugins/CVCRack/Rack/dep/include | |||
| rm -rf plugins/CVCRack/Rack/dep/lib | |||
| rm -rf plugins/CVCRack/Rack/dep/share | |||
| rm -rf plugins/CVCRack/Rack/dep/curl-7.66.0 | |||
| rm -rf plugins/CVCRack/Rack/dep/glew-2.1.0 | |||
| rm -rf plugins/CVCRack/Rack/dep/jansson-2.12 | |||
| rm -rf plugins/CVCRack/Rack/dep/libarchive-3.4.3 | |||
| rm -rf plugins/CVCRack/Rack/dep/openssl-1.1.1d | |||
| rm -rf plugins/CVCRack/Rack/dep/speexdsp-SpeexDSP-1.2rc3 | |||
| rm -rf plugins/CVCRack/Rack/dep/zstd-1.4.5 | |||
| # -------------------------------------------------------------- | |||
| @@ -1 +1 @@ | |||
| Subproject commit 23f89562acbd637a23b9f0333877939ad26c0595 | |||
| Subproject commit c17c260d08613ab46e13dc578104c74b5713a435 | |||
| @@ -25,6 +25,9 @@ | |||
| #include <settings.hpp> | |||
| #include <system.hpp> | |||
| #include <ui/common.hpp> | |||
| #include <window/Window.hpp> | |||
| #include <osdialog.h> | |||
| #include "DistrhoPlugin.hpp" | |||
| @@ -53,6 +56,7 @@ struct Initializer { | |||
| // Load settings | |||
| settings::init(); | |||
| #if 0 | |||
| try { | |||
| settings::load(); | |||
| } | |||
| @@ -66,6 +70,7 @@ struct Initializer { | |||
| } | |||
| */ | |||
| } | |||
| #endif | |||
| // Check existence of the system res/ directory | |||
| std::string resDir = asset::system("res"); | |||
| @@ -88,12 +93,18 @@ struct Initializer { | |||
| plugin::init(); | |||
| library::init(); | |||
| // discord::init(); | |||
| ui::init(); | |||
| window::init(); | |||
| } | |||
| ~Initializer() | |||
| { | |||
| using namespace rack; | |||
| window::destroy(); | |||
| ui::destroy(); | |||
| // discord::destroy(); | |||
| library::destroy(); | |||
| midi::destroy(); | |||
| @@ -104,9 +115,9 @@ struct Initializer { | |||
| } | |||
| }; | |||
| static Initializer& getInitializerInstance() | |||
| static const Initializer& getInitializerInstance() | |||
| { | |||
| static Initializer init; | |||
| static const Initializer init; | |||
| return init; | |||
| } | |||
| @@ -23,6 +23,7 @@ | |||
| #include <window/Window.hpp> | |||
| #include "DistrhoUI.hpp" | |||
| #include "ResizeHandle.hpp" | |||
| GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window) { return nullptr; } | |||
| GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char*) {} | |||
| @@ -32,6 +33,10 @@ GLFWAPI int glfwGetKeyScancode(int key) { return 0; } | |||
| namespace rack { | |||
| namespace window { | |||
| DISTRHO_NAMESPACE::UI* lastUI = nullptr; | |||
| void mouseButtonCallback(Window* win, int button, int action, int mods); | |||
| void cursorPosCallback(Window* win, double xpos, double ypos); | |||
| void scrollCallback(Window* win, double x, double y); | |||
| } | |||
| } | |||
| @@ -39,35 +44,33 @@ START_NAMESPACE_DISTRHO | |||
| // ----------------------------------------------------------------------------------------------------------- | |||
| struct Initializer { | |||
| Initializer() | |||
| struct Initializer2 { | |||
| Initializer2() | |||
| { | |||
| using namespace rack; | |||
| ui::init(); | |||
| window::init(); | |||
| } | |||
| ~Initializer() | |||
| ~Initializer2() | |||
| { | |||
| using namespace rack; | |||
| window::destroy(); | |||
| ui::destroy(); | |||
| } | |||
| }; | |||
| static Initializer& getInitializerInstance() | |||
| static const Initializer2& getInitializer2Instance() | |||
| { | |||
| static Initializer init; | |||
| static const Initializer2 init; | |||
| return init; | |||
| } | |||
| class CVCRackUI : public UI | |||
| { | |||
| ResizeHandle fResizeHandle; | |||
| public: | |||
| CVCRackUI() | |||
| : UI(1280, 720) | |||
| : UI(1280, 720), | |||
| fResizeHandle(this) | |||
| { | |||
| using namespace rack; | |||
| @@ -97,11 +100,16 @@ public: | |||
| contextSet(NULL); | |||
| } | |||
| void onNanoDisplay() override | |||
| void onDisplay() override | |||
| { | |||
| APP->window->step(); | |||
| } | |||
| void uiIdle() override | |||
| { | |||
| repaint(); | |||
| } | |||
| protected: | |||
| /* -------------------------------------------------------------------------------------------------------- | |||
| * DSP/Plugin Callbacks */ | |||
| @@ -116,6 +124,61 @@ protected: | |||
| // ------------------------------------------------------------------------------------------------------- | |||
| bool onMouse(const MouseEvent& ev) override | |||
| { | |||
| int button; | |||
| int mods = 0; | |||
| int action = ev.press; | |||
| if (ev.mod & kModifierControl) | |||
| mods |= GLFW_MOD_CONTROL; | |||
| if (ev.mod & kModifierShift) | |||
| mods |= GLFW_MOD_SHIFT; | |||
| if (ev.mod & kModifierAlt) | |||
| mods |= GLFW_MOD_ALT; | |||
| switch (ev.button) | |||
| { | |||
| case 0: | |||
| button = GLFW_MOUSE_BUTTON_MIDDLE; | |||
| break; | |||
| case 1: | |||
| button = GLFW_MOUSE_BUTTON_LEFT; | |||
| break; | |||
| case 2: | |||
| button = GLFW_MOUSE_BUTTON_RIGHT; | |||
| break; | |||
| default: | |||
| button = 0; | |||
| break; | |||
| } | |||
| mouseButtonCallback(APP->window, button, action, mods); | |||
| return true; | |||
| } | |||
| bool onMotion(const MotionEvent& ev) override | |||
| { | |||
| cursorPosCallback(APP->window, ev.pos.getX(), ev.pos.getY()); | |||
| return true; | |||
| } | |||
| bool onScroll(const ScrollEvent& ev) override | |||
| { | |||
| scrollCallback(APP->window, ev.delta.getX(), ev.delta.getY()); | |||
| return true; | |||
| } | |||
| #if 0 | |||
| void onResize(const ResizeEvent& ev) override | |||
| { | |||
| UI::onResize(ev); | |||
| // APP->window->setSize(rack::math::Vec(ev.size.getWidth(), ev.size.getHeight())); | |||
| } | |||
| #endif | |||
| // TODO uiFocus | |||
| private: | |||
| /** | |||
| Set our UI class as non-copyable and add a leak detector just in case. | |||
| @@ -128,7 +191,7 @@ private: | |||
| UI* createUI() | |||
| { | |||
| getInitializerInstance(); | |||
| getInitializer2Instance(); | |||
| return new CVCRackUI(); | |||
| } | |||
| @@ -20,7 +20,7 @@ | |||
| #define DISTRHO_PLUGIN_BRAND "DISTRHO" | |||
| #define DISTRHO_PLUGIN_NAME "CVCRack" | |||
| #define DISTRHO_PLUGIN_URI "http://distrho.sf.net/plugins/glBars" | |||
| #define DISTRHO_PLUGIN_URI "http://distrho.sf.net/plugins/CVCRack" | |||
| #define DISTRHO_PLUGIN_HAS_UI 1 | |||
| #define DISTRHO_PLUGIN_NUM_INPUTS 2 | |||
| @@ -30,8 +30,8 @@ | |||
| // #define DISTRHO_PLUGIN_VST3_CATEGORIES "Fx|Analyzer" | |||
| // #define DISTRHO_PLUGIN_HAS_EMBED_UI 1 | |||
| // #define DISTRHO_PLUGIN_HAS_EXTERNAL_UI 1 | |||
| #define DISTRHO_UI_USE_NANOVG 1 | |||
| #define DISTRHO_UI_USER_RESIZABLE 1 | |||
| // #define DISTRHO_UI_USE_NANOVG 1 | |||
| #define DISTRHO_UI_USER_RESIZABLE 0 | |||
| enum Parameters { | |||
| kParameterCount | |||
| @@ -17,13 +17,13 @@ FILES_DSP = \ | |||
| FILES_UI = \ | |||
| CVCRackUI.cpp \ | |||
| dep.cpp \ | |||
| Window.cpp | |||
| # -------------------------------------------------------------- | |||
| # Import base definitions | |||
| # UI_TYPE = external | |||
| SKIP_NANOVG = true | |||
| include ../../dpf/Makefile.base.mk | |||
| # -------------------------------------------------------------- | |||
| @@ -33,6 +33,7 @@ FILES_DSP += Rack/dep/pffft/pffft.c | |||
| FILES_DSP += Rack/dep/pffft/fftpack.c | |||
| FILES_UI += Rack/dep/oui-blendish/blendish.c | |||
| FILES_UI += Rack/dep/nanovg/src/nanovg.c | |||
| # FIXME dont use this | |||
| FILES_UI += Rack/dep/osdialog/osdialog.c | |||
| @@ -46,7 +47,7 @@ endif | |||
| FILES_DSP += $(wildcard Rack/src/*.c) | |||
| FILES_DSP += $(wildcard Rack/src/*/*.c) | |||
| FILES_DSP += $(filter-out Rack/src/dep.cpp Rack/src/gamepad.cpp Rack/src/rtaudio.cpp Rack/src/rtmidi.cpp, $(wildcard Rack/src/*.cpp)) | |||
| FILES_DSP += $(filter-out Rack/src/gamepad.cpp Rack/src/rtaudio.cpp Rack/src/rtmidi.cpp, $(wildcard Rack/src/*.cpp)) | |||
| FILES_DSP += $(filter-out Rack/src/window/Window.cpp, $(wildcard Rack/src/*/*.cpp)) | |||
| EXTRA_LIBS = Rack/dep/lib/libcrypto.a | |||
| @@ -85,14 +86,14 @@ Rack/dep/lib/libcrypto.a: Rack/dep/lib/libssl.a | |||
| # Extra flags for VCV stuff | |||
| BASE_FLAGS += -D_APP_VERSION=2.git.0 | |||
| BASE_FLAGS += -I$(DPF_PATH)/dgl/src/nanovg | |||
| # BASE_FLAGS += -I$(DPF_PATH)/dgl/src/nanovg | |||
| BASE_FLAGS += -IRack/include | |||
| BASE_FLAGS += -IRack/dep/include | |||
| BASE_FLAGS += -IRack/dep/filesystem/include | |||
| BASE_FLAGS += -IRack/dep/fuzzysearchdatabase/src | |||
| BASE_FLAGS += -IRack/dep/glfw/deps | |||
| BASE_FLAGS += -IRack/dep/glfw/include | |||
| # BASE_FLAGS += -IRack/dep/nanovg/src | |||
| BASE_FLAGS += -IRack/dep/nanovg/src | |||
| BASE_FLAGS += -IRack/dep/nanosvg/src | |||
| BASE_FLAGS += -IRack/dep/osdialog | |||
| BASE_FLAGS += -IRack/dep/oui-blendish | |||
| @@ -0,0 +1,185 @@ | |||
| /* | |||
| * Resize handle for DPF | |||
| * Copyright (C) 2021 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | |||
| * or without fee is hereby granted, provided that the above copyright notice and this | |||
| * permission notice appear in all copies. | |||
| * | |||
| * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD | |||
| * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN | |||
| * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | |||
| * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | |||
| * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |||
| * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||
| */ | |||
| #pragma once | |||
| #include "TopLevelWidget.hpp" | |||
| #include "../dgl/Color.hpp" | |||
| START_NAMESPACE_DGL | |||
| /** Resize handle for DPF windows, will sit on bottom-right. */ | |||
| class ResizeHandle : public TopLevelWidget | |||
| { | |||
| public: | |||
| /** Constructor for placing this handle on top of a window. */ | |||
| explicit ResizeHandle(Window& window) | |||
| : TopLevelWidget(window), | |||
| handleSize(16), | |||
| resizing(false) | |||
| { | |||
| resetArea(); | |||
| } | |||
| /** Overloaded constructor, will fetch the window from an existing top-level widget. */ | |||
| explicit ResizeHandle(TopLevelWidget* const tlw) | |||
| : TopLevelWidget(tlw->getWindow()), | |||
| handleSize(16), | |||
| resizing(false) | |||
| { | |||
| resetArea(); | |||
| } | |||
| /** Set the handle size, minimum 16. */ | |||
| void setHandleSize(const uint size) | |||
| { | |||
| handleSize = std::max(16u, size); | |||
| resetArea(); | |||
| } | |||
| protected: | |||
| void onDisplay() override | |||
| { | |||
| const GraphicsContext& context(getGraphicsContext()); | |||
| const double lineWidth = 1.0 * getScaleFactor(); | |||
| #ifdef DGL_OPENGL | |||
| glUseProgram(0); | |||
| glMatrixMode(GL_MODELVIEW); | |||
| #endif | |||
| // draw white lines, 1px wide | |||
| Color(1.0f, 1.0f, 1.0f).setFor(context); | |||
| l1.draw(context, lineWidth); | |||
| l2.draw(context, lineWidth); | |||
| l3.draw(context, lineWidth); | |||
| // draw black lines, offset by 1px and 1px wide | |||
| Color(0.0f, 0.0f, 0.0f).setFor(context); | |||
| Line<double> l1b(l1), l2b(l2), l3b(l3); | |||
| l1b.moveBy(lineWidth, lineWidth); | |||
| l2b.moveBy(lineWidth, lineWidth); | |||
| l3b.moveBy(lineWidth, lineWidth); | |||
| l1b.draw(context, lineWidth); | |||
| l2b.draw(context, lineWidth); | |||
| l3b.draw(context, lineWidth); | |||
| } | |||
| bool onMouse(const MouseEvent& ev) override | |||
| { | |||
| if (ev.button != 1) | |||
| return false; | |||
| if (ev.press && area.contains(ev.pos)) | |||
| { | |||
| resizing = true; | |||
| resizingSize = Size<double>(getWidth(), getHeight()); | |||
| lastResizePoint = ev.pos; | |||
| return true; | |||
| } | |||
| if (resizing && ! ev.press) | |||
| { | |||
| resizing = false; | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| bool onMotion(const MotionEvent& ev) override | |||
| { | |||
| if (! resizing) | |||
| return false; | |||
| const Size<double> offset(ev.pos.getX() - lastResizePoint.getX(), | |||
| ev.pos.getY() - lastResizePoint.getY()); | |||
| resizingSize += offset; | |||
| lastResizePoint = ev.pos; | |||
| // TODO min width, min height | |||
| const uint minWidth = 16; | |||
| const uint minHeight = 16; | |||
| if (resizingSize.getWidth() < minWidth) | |||
| resizingSize.setWidth(minWidth); | |||
| if (resizingSize.getWidth() > 16384) | |||
| resizingSize.setWidth(16384); | |||
| if (resizingSize.getHeight() < minHeight) | |||
| resizingSize.setHeight(minHeight); | |||
| if (resizingSize.getHeight() > 16384) | |||
| resizingSize.setHeight(16384); | |||
| setSize(resizingSize.getWidth(), resizingSize.getHeight()); | |||
| return true; | |||
| } | |||
| void onResize(const ResizeEvent& ev) override | |||
| { | |||
| TopLevelWidget::onResize(ev); | |||
| resetArea(); | |||
| } | |||
| private: | |||
| Rectangle<uint> area; | |||
| Line<double> l1, l2, l3; | |||
| uint handleSize; | |||
| // event handling state | |||
| bool resizing; | |||
| Point<double> lastResizePoint; | |||
| Size<double> resizingSize; | |||
| void resetArea() | |||
| { | |||
| const double scaleFactor = getScaleFactor(); | |||
| const uint margin = 0.0 * scaleFactor; | |||
| const uint size = handleSize * scaleFactor; | |||
| area = Rectangle<uint>(getWidth() - size - margin, | |||
| getHeight() - size - margin, | |||
| size, size); | |||
| recreateLines(area.getX(), area.getY(), size); | |||
| } | |||
| void recreateLines(const uint x, const uint y, const uint size) | |||
| { | |||
| uint linesize = size; | |||
| uint offset = 0; | |||
| // 1st line, full diagonal size | |||
| l1.setStartPos(x + size, y); | |||
| l1.setEndPos(x, y + size); | |||
| // 2nd line, bit more to the right and down, cropped | |||
| offset += size / 3; | |||
| linesize -= size / 3; | |||
| l2.setStartPos(x + linesize + offset, y + offset); | |||
| l2.setEndPos(x + offset, y + linesize + offset); | |||
| // 3rd line, even more right and down | |||
| offset += size / 3; | |||
| linesize -= size / 3; | |||
| l3.setStartPos(x + linesize + offset, y + offset); | |||
| l3.setEndPos(x + offset, y + linesize + offset); | |||
| } | |||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ResizeHandle) | |||
| }; | |||
| END_NAMESPACE_DGL | |||
| @@ -68,6 +68,7 @@ std::shared_ptr<Image> Image::load(const std::string& filename) { | |||
| struct Window::Internal { | |||
| DISTRHO_NAMESPACE::UI* ui; | |||
| math::Vec size; | |||
| std::string lastWindowTitle; | |||
| @@ -94,11 +95,18 @@ struct Window::Internal { | |||
| Window::Window() { | |||
| internal = new Internal; | |||
| internal->ui = lastUI; | |||
| vg = lastUI->getContext(); | |||
| internal->size = minWindowSize; | |||
| int err; | |||
| // Set up GLEW | |||
| glewExperimental = GL_TRUE; | |||
| err = glewInit(); | |||
| if (err != GLEW_OK) { | |||
| osdialog_message(OSDIALOG_ERROR, OSDIALOG_OK, "Could not initialize GLEW. Does your graphics card support OpenGL 2.0 or greater? If so, make sure you have the latest graphics drivers installed."); | |||
| exit(1); | |||
| } | |||
| const GLubyte* vendor = glGetString(GL_VENDOR); | |||
| const GLubyte* renderer = glGetString(GL_RENDERER); | |||
| const GLubyte* version = glGetString(GL_VERSION); | |||
| @@ -109,6 +117,21 @@ Window::Window() { | |||
| // GLEW generates GL error because it calls glGetString(GL_EXTENSIONS), we'll consume it here. | |||
| glGetError(); | |||
| // Set up NanoVG | |||
| int nvgFlags = NVG_ANTIALIAS; | |||
| #if defined NANOVG_GL2 | |||
| vg = nvgCreateGL2(nvgFlags); | |||
| fbVg = nvgCreateSharedGL2(vg, nvgFlags); | |||
| #elif defined NANOVG_GL3 | |||
| vg = nvgCreateGL3(nvgFlags); | |||
| #elif defined NANOVG_GLES2 | |||
| vg = nvgCreateGLES2(nvgFlags); | |||
| #endif | |||
| if (!vg) { | |||
| osdialog_message(OSDIALOG_ERROR, OSDIALOG_OK, "Could not initialize NanoVG. Does your graphics card support OpenGL 2.0 or greater? If so, make sure you have the latest graphics drivers installed."); | |||
| exit(1); | |||
| } | |||
| // Load default Blendish font | |||
| uiFont = loadFont(asset::system("res/fonts/DejaVuSans.ttf")); | |||
| bndSetFont(uiFont->handle); | |||
| @@ -132,17 +155,26 @@ Window::~Window() { | |||
| // nvgDeleteClone(fbVg); | |||
| #if defined NANOVG_GL2 | |||
| nvgDeleteGL2(vg); | |||
| nvgDeleteGL2(fbVg); | |||
| #elif defined NANOVG_GL3 | |||
| nvgDeleteGL3(vg); | |||
| #elif defined NANOVG_GLES2 | |||
| nvgDeleteGLES2(vg); | |||
| #endif | |||
| delete internal; | |||
| } | |||
| math::Vec Window::getSize() { | |||
| return math::Vec(1280, 720); | |||
| return internal->size; | |||
| } | |||
| void Window::setSize(math::Vec size) { | |||
| size = size.max(minWindowSize); | |||
| internal->size = size.max(minWindowSize); | |||
| } | |||
| @@ -163,14 +195,12 @@ void Window::step() { | |||
| nvgReset(vg); | |||
| bndSetFont(uiFont->handle); | |||
| nvgFillColor(vg, nvgRGBf(1, 1, 1)); | |||
| nvgStrokeColor(vg, nvgRGBf(1, 1, 1)); | |||
| // Poll events | |||
| // Save and restore context because event handler set their own context based on which window they originate from. | |||
| Context* context = contextGet(); | |||
| // Context* context = contextGet(); | |||
| // glfwPollEvents(); | |||
| contextSet(context); | |||
| // contextSet(context); | |||
| // Set window title | |||
| std::string windowTitle = APP_NAME + " " + APP_EDITION_NAME + " " + APP_VERSION; | |||
| @@ -223,9 +253,9 @@ void Window::step() { | |||
| APP->scene->draw(args); | |||
| t3 = system::getTime(); | |||
| // glViewport(0, -winHeight, fbWidth, fbHeight); | |||
| // glClearColor(0.0, 0.0, 0.0, 1.0); | |||
| // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); | |||
| glViewport(0, 0, fbWidth, fbHeight); | |||
| glClearColor(0.0, 0.0, 0.0, 1.0); | |||
| glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); | |||
| nvgEndFrame(vg); | |||
| t4 = system::getTime(); | |||
| } | |||
| @@ -370,6 +400,56 @@ bool& Window::fbDirtyOnSubpixelChange() { | |||
| } | |||
| void mouseButtonCallback(Window* win, int button, int action, int mods) { | |||
| /* | |||
| #if defined ARCH_MAC | |||
| // Remap Ctrl-left click to right click on Mac | |||
| if (button == GLFW_MOUSE_BUTTON_LEFT && (mods & RACK_MOD_MASK) == GLFW_MOD_CONTROL) { | |||
| button = GLFW_MOUSE_BUTTON_RIGHT; | |||
| mods &= ~GLFW_MOD_CONTROL; | |||
| } | |||
| // Remap Ctrl-shift-left click to middle click on Mac | |||
| if (button == GLFW_MOUSE_BUTTON_LEFT && (mods & RACK_MOD_MASK) == (GLFW_MOD_CONTROL | GLFW_MOD_SHIFT)) { | |||
| button = GLFW_MOUSE_BUTTON_MIDDLE; | |||
| mods &= ~(GLFW_MOD_CONTROL | GLFW_MOD_SHIFT); | |||
| } | |||
| #endif | |||
| */ | |||
| APP->event->handleButton(win->internal->lastMousePos, button, action, mods); | |||
| } | |||
| void cursorPosCallback(Window* win, double xpos, double ypos) { | |||
| math::Vec mousePos = math::Vec(xpos, ypos).div(win->pixelRatio / win->windowRatio).round(); | |||
| math::Vec mouseDelta = mousePos.minus(win->internal->lastMousePos); | |||
| // Workaround for GLFW warping mouse to a different position when the cursor is locked or unlocked. | |||
| if (win->internal->ignoreNextMouseDelta) { | |||
| win->internal->ignoreNextMouseDelta = false; | |||
| mouseDelta = math::Vec(); | |||
| } | |||
| win->internal->lastMousePos = mousePos; | |||
| APP->event->handleHover(mousePos, mouseDelta); | |||
| // Keyboard/mouse MIDI driver | |||
| math::Vec scaledPos(xpos / win->internal->ui->getWidth(), ypos / win->internal->ui->getHeight()); | |||
| keyboard::mouseMove(scaledPos); | |||
| } | |||
| void scrollCallback(Window* win, double x, double y) { | |||
| math::Vec scrollDelta = math::Vec(x, y); | |||
| #if defined ARCH_MAC | |||
| scrollDelta = scrollDelta.mult(10.0); | |||
| #else | |||
| scrollDelta = scrollDelta.mult(50.0); | |||
| #endif | |||
| APP->event->handleScroll(win->internal->lastMousePos, scrollDelta); | |||
| } | |||
| void init() { | |||
| } | |||
| @@ -1,19 +0,0 @@ | |||
| // This source file compiles those annoying implementation-in-header libraries | |||
| #include <common.hpp> // for fopen_u8 | |||
| #define GLEW_STATIC | |||
| #define GLEW_NO_GLU | |||
| #include <GL/glew.h> | |||
| #include <nanovg.h> | |||
| #define BLENDISH_IMPLEMENTATION | |||
| #include <blendish.h> | |||
| #define NANOSVG_IMPLEMENTATION | |||
| #define NANOSVG_ALL_COLOR_KEYWORDS | |||
| #include <nanosvg.h> | |||
| #define STB_IMAGE_WRITE_IMPLEMENTATION | |||
| #include <stb_image_write.h> | |||