| @@ -111,13 +111,37 @@ struct PositionBase { | |||||
| /** An event prototype with a GLFW key. */ | /** An event prototype with a GLFW key. */ | ||||
| struct KeyBase { | struct KeyBase { | ||||
| /** GLFW_KEY_* */ | |||||
| /** The key corresponding to what it would be called in its position on a QWERTY US keyboard. | |||||
| For example, the WASD directional keys used for first-person shooters will always be reported as "WASD", regardless if they say "ZQSD" on an AZERTY keyboard. | |||||
| You should usually not use these for printable characters such as "Ctrl+V" key commands. Instead, use `keyName`. | |||||
| You *should* use these for non-printable keys, such as Escape, arrow keys, Home, F1-12, etc. | |||||
| You should also use this for Enter, Tab, and Space. Although they are printable keys, they do not appear in `keyName`. | |||||
| See GLFW_KEY_* for the list of possible values. | |||||
| */ | |||||
| int key; | int key; | ||||
| /** GLFW_KEY_*. You should usually use `key` instead. */ | |||||
| /** Platform-dependent "software" key code. | |||||
| This variable is only included for completion. There should be no reason for you to use this. | |||||
| You should instead use `key` (for non-printable characters) or `keyName` (for printable characters). | |||||
| Values are platform independent and can change between different keyboards or keyboard layouts on the same OS. | |||||
| */ | |||||
| int scancode; | int scancode; | ||||
| /** GLFW_RELEASE, GLFW_PRESS, GLFW_REPEAT, or RACK_HELD */ | |||||
| /** String containing the lowercase key name, if it produces a printable character. | |||||
| This is the only variable that correctly represents the label printed on any keyboard layout, whether it's QWERTY, AZERTY, QWERTZ, Dvorak, etc. | |||||
| For example, if the user presses the key labeled "q" regardless of the key position, `keyName` will be "q". | |||||
| For non-printable characters this is an empty string. | |||||
| Enter, Tab, and Space do not give a `keyName`. Use `key` instead. | |||||
| Shift has no effect on the key name. Shift+1 results in "1", Shift+q results in "q", etc. | |||||
| */ | |||||
| std::string keyName; | |||||
| /** The type of event occurring with the key. | |||||
| Possible values are GLFW_RELEASE, GLFW_PRESS, GLFW_REPEAT, or RACK_HELD. | |||||
| RACK_HELD is sent every frame while the key is held. | |||||
| */ | |||||
| int action; | int action; | ||||
| /** GLFW_MOD_* */ | |||||
| /** Bitwise OR of key modifiers, such as Ctrl or Shift. | |||||
| Use (mods & RACK_MOD_MASK) == RACK_MOD_CTRL to check for Ctrl on Linux and Windows but Cmd on Mac. | |||||
| See GLFW_MOD_* for the list of possible values. | |||||
| */ | |||||
| int mods; | int mods; | ||||
| }; | }; | ||||
| @@ -623,19 +623,17 @@ inline void TagItem::step() { | |||||
| inline void BrowserSearchField::onSelectKey(const event::SelectKey& e) { | inline void BrowserSearchField::onSelectKey(const event::SelectKey& e) { | ||||
| if (e.action == GLFW_PRESS || e.action == GLFW_REPEAT) { | if (e.action == GLFW_PRESS || e.action == GLFW_REPEAT) { | ||||
| switch (e.key) { | |||||
| case GLFW_KEY_ESCAPE: { | |||||
| BrowserOverlay* overlay = getAncestorOfType<BrowserOverlay>(); | |||||
| overlay->hide(); | |||||
| if (e.key == GLFW_KEY_ESCAPE) { | |||||
| BrowserOverlay* overlay = getAncestorOfType<BrowserOverlay>(); | |||||
| overlay->hide(); | |||||
| e.consume(this); | |||||
| } | |||||
| if (e.key == GLFW_KEY_BACKSPACE) { | |||||
| if (text == "") { | |||||
| ModuleBrowser* browser = getAncestorOfType<ModuleBrowser>(); | |||||
| browser->clear(); | |||||
| e.consume(this); | e.consume(this); | ||||
| } break; | |||||
| case GLFW_KEY_BACKSPACE: { | |||||
| if (text == "") { | |||||
| ModuleBrowser* browser = getAncestorOfType<ModuleBrowser>(); | |||||
| browser->clear(); | |||||
| e.consume(this); | |||||
| } | |||||
| } break; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -397,61 +397,40 @@ void ModuleWidget::onHoverKey(const event::HoverKey& e) { | |||||
| return; | return; | ||||
| if (e.action == GLFW_PRESS || e.action == GLFW_REPEAT) { | if (e.action == GLFW_PRESS || e.action == GLFW_REPEAT) { | ||||
| switch (e.key) { | |||||
| case GLFW_KEY_I: { | |||||
| if ((e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| resetAction(); | |||||
| e.consume(this); | |||||
| } | |||||
| } break; | |||||
| case GLFW_KEY_R: { | |||||
| if ((e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| randomizeAction(); | |||||
| e.consume(this); | |||||
| } | |||||
| } break; | |||||
| case GLFW_KEY_C: { | |||||
| if ((e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| copyClipboard(); | |||||
| e.consume(this); | |||||
| } | |||||
| } break; | |||||
| case GLFW_KEY_V: { | |||||
| if ((e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| pasteClipboardAction(); | |||||
| e.consume(this); | |||||
| } | |||||
| } break; | |||||
| case GLFW_KEY_D: { | |||||
| if ((e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| cloneAction(); | |||||
| e.consume(this); | |||||
| } | |||||
| } break; | |||||
| case GLFW_KEY_U: { | |||||
| if ((e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| disconnectAction(); | |||||
| e.consume(this); | |||||
| } | |||||
| } break; | |||||
| case GLFW_KEY_E: { | |||||
| if ((e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| bypassAction(); | |||||
| e.consume(this); | |||||
| } | |||||
| } break; | |||||
| if (e.keyName == "i" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| resetAction(); | |||||
| e.consume(this); | |||||
| } | |||||
| if (e.keyName == "r" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| randomizeAction(); | |||||
| e.consume(this); | |||||
| } | |||||
| if (e.keyName == "c" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| copyClipboard(); | |||||
| e.consume(this); | |||||
| } | |||||
| if (e.keyName == "v" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| pasteClipboardAction(); | |||||
| e.consume(this); | |||||
| } | |||||
| if (e.keyName == "d" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| cloneAction(); | |||||
| e.consume(this); | |||||
| } | |||||
| if (e.keyName == "u" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| disconnectAction(); | |||||
| e.consume(this); | |||||
| } | |||||
| if (e.keyName == "e" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| bypassAction(); | |||||
| e.consume(this); | |||||
| } | } | ||||
| } | } | ||||
| if (e.action == RACK_HELD) { | if (e.action == RACK_HELD) { | ||||
| switch (e.key) { | |||||
| case GLFW_KEY_DELETE: | |||||
| case GLFW_KEY_BACKSPACE: { | |||||
| if ((e.mods & RACK_MOD_MASK) == 0) { | |||||
| removeAction(); | |||||
| e.consume(NULL); | |||||
| } | |||||
| } break; | |||||
| if ((e.key == GLFW_KEY_DELETE || e.key == GLFW_KEY_BACKSPACE) && (e.mods & RACK_MOD_MASK) == 0) { | |||||
| removeAction(); | |||||
| e.consume(NULL); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -108,23 +108,21 @@ void RackScrollWidget::onHoverKey(const event::HoverKey& e) { | |||||
| arrowSpeed /= 4.0; | arrowSpeed /= 4.0; | ||||
| if (e.action == RACK_HELD) { | if (e.action == RACK_HELD) { | ||||
| switch (e.key) { | |||||
| case GLFW_KEY_LEFT: { | |||||
| offset.x -= arrowSpeed; | |||||
| e.consume(this); | |||||
| } break; | |||||
| case GLFW_KEY_RIGHT: { | |||||
| offset.x += arrowSpeed; | |||||
| e.consume(this); | |||||
| } break; | |||||
| case GLFW_KEY_UP: { | |||||
| offset.y -= arrowSpeed; | |||||
| e.consume(this); | |||||
| } break; | |||||
| case GLFW_KEY_DOWN: { | |||||
| offset.y += arrowSpeed; | |||||
| e.consume(this); | |||||
| } break; | |||||
| if (e.key == GLFW_KEY_LEFT) { | |||||
| offset.x -= arrowSpeed; | |||||
| e.consume(this); | |||||
| } | |||||
| if (e.key == GLFW_KEY_RIGHT) { | |||||
| offset.x += arrowSpeed; | |||||
| e.consume(this); | |||||
| } | |||||
| if (e.key == GLFW_KEY_UP) { | |||||
| offset.y -= arrowSpeed; | |||||
| e.consume(this); | |||||
| } | |||||
| if (e.key == GLFW_KEY_DOWN) { | |||||
| offset.y += arrowSpeed; | |||||
| e.consume(this); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -121,13 +121,9 @@ void RackWidget::onHoverKey(const event::HoverKey& e) { | |||||
| return; | return; | ||||
| if (e.action == GLFW_PRESS || e.action == GLFW_REPEAT) { | if (e.action == GLFW_PRESS || e.action == GLFW_REPEAT) { | ||||
| switch (e.key) { | |||||
| case GLFW_KEY_V: { | |||||
| if ((e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| pastePresetClipboardAction(); | |||||
| e.consume(this); | |||||
| } | |||||
| } break; | |||||
| if (e.keyName == "v" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| pastePresetClipboardAction(); | |||||
| e.consume(this); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -97,39 +97,40 @@ void Scene::onHoverKey(const event::HoverKey& e) { | |||||
| return; | return; | ||||
| if (e.action == GLFW_PRESS || e.action == GLFW_REPEAT) { | if (e.action == GLFW_PRESS || e.action == GLFW_REPEAT) { | ||||
| if (e.key == GLFW_KEY_N && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| // DEBUG("key '%d '%c' scancode %d '%c' keyName '%s'", e.key, e.key, e.scancode, e.scancode, e.keyName.c_str()); | |||||
| if (e.keyName == "n" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| APP->patch->loadTemplateDialog(); | APP->patch->loadTemplateDialog(); | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if (e.key == GLFW_KEY_Q && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| if (e.keyName == "q" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| APP->window->close(); | APP->window->close(); | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if (e.key == GLFW_KEY_O && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| if (e.keyName == "o" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| APP->patch->loadDialog(); | APP->patch->loadDialog(); | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if (e.key == GLFW_KEY_O && (e.mods & RACK_MOD_MASK) == (RACK_MOD_CTRL | GLFW_MOD_SHIFT)) { | |||||
| if (e.keyName == "o" && (e.mods & RACK_MOD_MASK) == (RACK_MOD_CTRL | GLFW_MOD_SHIFT)) { | |||||
| APP->patch->revertDialog(); | APP->patch->revertDialog(); | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if (e.key == GLFW_KEY_S && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| if (e.keyName == "s" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| APP->patch->saveDialog(); | APP->patch->saveDialog(); | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if (e.key == GLFW_KEY_S && (e.mods & RACK_MOD_MASK) == (RACK_MOD_CTRL | GLFW_MOD_SHIFT)) { | |||||
| if (e.keyName == "s" && (e.mods & RACK_MOD_MASK) == (RACK_MOD_CTRL | GLFW_MOD_SHIFT)) { | |||||
| APP->patch->saveAsDialog(); | APP->patch->saveAsDialog(); | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if (e.key == GLFW_KEY_Z && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| if (e.keyName == "z" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| APP->history->undo(); | APP->history->undo(); | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if (e.key == GLFW_KEY_Z && (e.mods & RACK_MOD_MASK) == (RACK_MOD_CTRL | GLFW_MOD_SHIFT)) { | |||||
| if (e.keyName == "z" && (e.mods & RACK_MOD_MASK) == (RACK_MOD_CTRL | GLFW_MOD_SHIFT)) { | |||||
| APP->history->redo(); | APP->history->redo(); | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if ((e.key == GLFW_KEY_MINUS || e.key == GLFW_KEY_KP_SUBTRACT) && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| if (e.keyName == "-" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| float zoom = settings::zoom; | float zoom = settings::zoom; | ||||
| zoom *= 2; | zoom *= 2; | ||||
| zoom = std::ceil(zoom - 0.01f) - 1; | zoom = std::ceil(zoom - 0.01f) - 1; | ||||
| @@ -137,7 +138,8 @@ void Scene::onHoverKey(const event::HoverKey& e) { | |||||
| settings::zoom = zoom; | settings::zoom = zoom; | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if ((e.key == GLFW_KEY_EQUAL || e.key == GLFW_KEY_KP_ADD) && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| // Numpad has a "+" key, but the main keyboard section hides it under "=" | |||||
| if ((e.keyName == "=" || e.keyName == "+") && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| float zoom = settings::zoom; | float zoom = settings::zoom; | ||||
| zoom *= 2; | zoom *= 2; | ||||
| zoom = std::floor(zoom + 0.01f) + 1; | zoom = std::floor(zoom + 0.01f) + 1; | ||||
| @@ -145,31 +147,31 @@ void Scene::onHoverKey(const event::HoverKey& e) { | |||||
| settings::zoom = zoom; | settings::zoom = zoom; | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if ((e.key == GLFW_KEY_0 || e.key == GLFW_KEY_KP_0) && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| if ((e.keyName == "0") && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| settings::zoom = 0.f; | settings::zoom = 0.f; | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if ((e.key == GLFW_KEY_ENTER || e.key == GLFW_KEY_KP_ENTER) && (e.mods & RACK_MOD_MASK) == 0) { | |||||
| if ((e.key == GLFW_KEY_ENTER || e.key == GLFW_KEY_KP_ENTER) && (e.mods & RACK_MOD_MASK) == 0) { | |||||
| moduleBrowser->show(); | moduleBrowser->show(); | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if (e.key == GLFW_KEY_F1 && (e.mods & RACK_MOD_MASK) == 0) { | |||||
| if (e.key == GLFW_KEY_F1 && (e.mods & RACK_MOD_MASK) == 0) { | |||||
| std::thread t([] { | std::thread t([] { | ||||
| system::openBrowser("https://vcvrack.com/manual/"); | system::openBrowser("https://vcvrack.com/manual/"); | ||||
| }); | }); | ||||
| t.detach(); | t.detach(); | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if (e.key == GLFW_KEY_F3 && (e.mods & RACK_MOD_MASK) == 0) { | |||||
| if (e.key == GLFW_KEY_F3 && (e.mods & RACK_MOD_MASK) == 0) { | |||||
| settings::cpuMeter ^= true; | settings::cpuMeter ^= true; | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if (e.key == GLFW_KEY_F11 && (e.mods & RACK_MOD_MASK) == 0) { | |||||
| if (e.key == GLFW_KEY_F11 && (e.mods & RACK_MOD_MASK) == 0) { | |||||
| APP->window->setFullScreen(!APP->window->isFullScreen()); | APP->window->setFullScreen(!APP->window->isFullScreen()); | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| // Alternate key command for exiting fullscreen, since F11 doesn't work reliably on Mac due to "Show desktop" OS binding. | // Alternate key command for exiting fullscreen, since F11 doesn't work reliably on Mac due to "Show desktop" OS binding. | ||||
| else if (e.key == GLFW_KEY_ESCAPE && (e.mods & RACK_MOD_MASK) == 0) { | |||||
| if (e.key == GLFW_KEY_ESCAPE && (e.mods & RACK_MOD_MASK) == 0) { | |||||
| if (APP->window->isFullScreen()) | if (APP->window->isFullScreen()) | ||||
| APP->window->setFullScreen(false); | APP->window->setFullScreen(false); | ||||
| e.consume(this); | e.consume(this); | ||||
| @@ -303,6 +303,9 @@ bool State::handleKey(math::Vec pos, int key, int scancode, int action, int mods | |||||
| eSelectKey.context = &cSelectKey; | eSelectKey.context = &cSelectKey; | ||||
| eSelectKey.key = key; | eSelectKey.key = key; | ||||
| eSelectKey.scancode = scancode; | eSelectKey.scancode = scancode; | ||||
| const char* keyName = glfwGetKeyName(key, scancode); | |||||
| if (keyName) | |||||
| eSelectKey.keyName = keyName; | |||||
| eSelectKey.action = action; | eSelectKey.action = action; | ||||
| eSelectKey.mods = mods; | eSelectKey.mods = mods; | ||||
| selectedWidget->onSelectKey(eSelectKey); | selectedWidget->onSelectKey(eSelectKey); | ||||
| @@ -317,6 +320,9 @@ bool State::handleKey(math::Vec pos, int key, int scancode, int action, int mods | |||||
| eHoverKey.pos = pos; | eHoverKey.pos = pos; | ||||
| eHoverKey.key = key; | eHoverKey.key = key; | ||||
| eHoverKey.scancode = scancode; | eHoverKey.scancode = scancode; | ||||
| const char* keyName = glfwGetKeyName(key, scancode); | |||||
| if (keyName) | |||||
| eHoverKey.keyName = keyName; | |||||
| eHoverKey.action = action; | eHoverKey.action = action; | ||||
| eHoverKey.mods = mods; | eHoverKey.mods = mods; | ||||
| rootWidget->onHoverKey(eHoverKey); | rootWidget->onHoverKey(eHoverKey); | ||||
| @@ -122,34 +122,34 @@ void ScrollWidget::onHoverKey(const event::HoverKey& e) { | |||||
| offset.y -= box.size.y * 0.5; | offset.y -= box.size.y * 0.5; | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if (e.key == GLFW_KEY_PAGE_UP && (e.mods & RACK_MOD_MASK) == GLFW_MOD_SHIFT) { | |||||
| if (e.key == GLFW_KEY_PAGE_UP && (e.mods & RACK_MOD_MASK) == GLFW_MOD_SHIFT) { | |||||
| offset.x -= box.size.x * 0.5; | offset.x -= box.size.x * 0.5; | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if (e.key == GLFW_KEY_PAGE_DOWN && (e.mods & RACK_MOD_MASK) == 0) { | |||||
| if (e.key == GLFW_KEY_PAGE_DOWN && (e.mods & RACK_MOD_MASK) == 0) { | |||||
| offset.y += box.size.y * 0.5; | offset.y += box.size.y * 0.5; | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if (e.key == GLFW_KEY_PAGE_DOWN && (e.mods & RACK_MOD_MASK) == GLFW_MOD_SHIFT) { | |||||
| if (e.key == GLFW_KEY_PAGE_DOWN && (e.mods & RACK_MOD_MASK) == GLFW_MOD_SHIFT) { | |||||
| offset.x += box.size.x * 0.5; | offset.x += box.size.x * 0.5; | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if (e.key == GLFW_KEY_HOME && (e.mods & RACK_MOD_MASK) == 0) { | |||||
| if (e.key == GLFW_KEY_HOME && (e.mods & RACK_MOD_MASK) == 0) { | |||||
| math::Rect containerBox = container->getChildrenBoundingBox(); | math::Rect containerBox = container->getChildrenBoundingBox(); | ||||
| offset.y = containerBox.getTop(); | offset.y = containerBox.getTop(); | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if (e.key == GLFW_KEY_HOME && (e.mods & RACK_MOD_MASK) == GLFW_MOD_SHIFT) { | |||||
| if (e.key == GLFW_KEY_HOME && (e.mods & RACK_MOD_MASK) == GLFW_MOD_SHIFT) { | |||||
| math::Rect containerBox = container->getChildrenBoundingBox(); | math::Rect containerBox = container->getChildrenBoundingBox(); | ||||
| offset.x = containerBox.getLeft(); | offset.x = containerBox.getLeft(); | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if (e.key == GLFW_KEY_END && (e.mods & RACK_MOD_MASK) == 0) { | |||||
| if (e.key == GLFW_KEY_END && (e.mods & RACK_MOD_MASK) == 0) { | |||||
| math::Rect containerBox = container->getChildrenBoundingBox(); | math::Rect containerBox = container->getChildrenBoundingBox(); | ||||
| offset.y = containerBox.getBottom(); | offset.y = containerBox.getBottom(); | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if (e.key == GLFW_KEY_END && (e.mods & RACK_MOD_MASK) == GLFW_MOD_SHIFT) { | |||||
| if (e.key == GLFW_KEY_END && (e.mods & RACK_MOD_MASK) == GLFW_MOD_SHIFT) { | |||||
| math::Rect containerBox = container->getChildrenBoundingBox(); | math::Rect containerBox = container->getChildrenBoundingBox(); | ||||
| offset.x = containerBox.getRight(); | offset.x = containerBox.getRight(); | ||||
| e.consume(this); | e.consume(this); | ||||
| @@ -76,7 +76,7 @@ void TextField::onSelectKey(const event::SelectKey& e) { | |||||
| } | } | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if (e.key == GLFW_KEY_DELETE && (e.mods & RACK_MOD_MASK) == 0) { | |||||
| if (e.key == GLFW_KEY_DELETE && (e.mods & RACK_MOD_MASK) == 0) { | |||||
| if (cursor == selection) { | if (cursor == selection) { | ||||
| text.erase(cursor, 1); | text.erase(cursor, 1); | ||||
| event::Change eChange; | event::Change eChange; | ||||
| @@ -91,7 +91,7 @@ void TextField::onSelectKey(const event::SelectKey& e) { | |||||
| } | } | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if (e.key == GLFW_KEY_LEFT) { | |||||
| if (e.key == GLFW_KEY_LEFT) { | |||||
| if (e.mods & RACK_MOD_CTRL) { | if (e.mods & RACK_MOD_CTRL) { | ||||
| while (--cursor > 0) { | while (--cursor > 0) { | ||||
| if (text[cursor - 1] == ' ') | if (text[cursor - 1] == ' ') | ||||
| @@ -106,7 +106,7 @@ void TextField::onSelectKey(const event::SelectKey& e) { | |||||
| } | } | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if (e.key == GLFW_KEY_RIGHT) { | |||||
| if (e.key == GLFW_KEY_RIGHT) { | |||||
| if (e.mods & RACK_MOD_CTRL) { | if (e.mods & RACK_MOD_CTRL) { | ||||
| while (++cursor < (int) text.size()) { | while (++cursor < (int) text.size()) { | ||||
| if (text[cursor] == ' ') | if (text[cursor] == ' ') | ||||
| @@ -121,29 +121,29 @@ void TextField::onSelectKey(const event::SelectKey& e) { | |||||
| } | } | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if (e.key == GLFW_KEY_HOME && (e.mods & RACK_MOD_MASK) == 0) { | |||||
| if (e.key == GLFW_KEY_HOME && (e.mods & RACK_MOD_MASK) == 0) { | |||||
| selection = cursor = 0; | selection = cursor = 0; | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if (e.key == GLFW_KEY_HOME && (e.mods & RACK_MOD_MASK) == GLFW_MOD_SHIFT) { | |||||
| if (e.key == GLFW_KEY_HOME && (e.mods & RACK_MOD_MASK) == GLFW_MOD_SHIFT) { | |||||
| cursor = 0; | cursor = 0; | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if (e.key == GLFW_KEY_END && (e.mods & RACK_MOD_MASK) == 0) { | |||||
| if (e.key == GLFW_KEY_END && (e.mods & RACK_MOD_MASK) == 0) { | |||||
| selection = cursor = text.size(); | selection = cursor = text.size(); | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if (e.key == GLFW_KEY_END && (e.mods & RACK_MOD_MASK) == GLFW_MOD_SHIFT) { | |||||
| if (e.key == GLFW_KEY_END && (e.mods & RACK_MOD_MASK) == GLFW_MOD_SHIFT) { | |||||
| cursor = text.size(); | cursor = text.size(); | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if (e.key == GLFW_KEY_V && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| if (e.keyName == "v" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| const char* newText = glfwGetClipboardString(APP->window->win); | const char* newText = glfwGetClipboardString(APP->window->win); | ||||
| if (newText) | if (newText) | ||||
| insertText(newText); | insertText(newText); | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if (e.key == GLFW_KEY_X && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| if (e.keyName == "x" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| if (cursor != selection) { | if (cursor != selection) { | ||||
| int begin = std::min(cursor, selection); | int begin = std::min(cursor, selection); | ||||
| std::string selectedText = text.substr(begin, std::abs(selection - cursor)); | std::string selectedText = text.substr(begin, std::abs(selection - cursor)); | ||||
| @@ -152,7 +152,7 @@ void TextField::onSelectKey(const event::SelectKey& e) { | |||||
| } | } | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if (e.key == GLFW_KEY_C && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| if (e.keyName == "c" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| if (cursor != selection) { | if (cursor != selection) { | ||||
| int begin = std::min(cursor, selection); | int begin = std::min(cursor, selection); | ||||
| std::string selectedText = text.substr(begin, std::abs(selection - cursor)); | std::string selectedText = text.substr(begin, std::abs(selection - cursor)); | ||||
| @@ -160,11 +160,11 @@ void TextField::onSelectKey(const event::SelectKey& e) { | |||||
| } | } | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if (e.key == GLFW_KEY_A && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| if (e.keyName == "a" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||||
| selectAll(); | selectAll(); | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if ((e.key == GLFW_KEY_ENTER || e.key == GLFW_KEY_KP_ENTER) && (e.mods & RACK_MOD_MASK) == 0) { | |||||
| if ((e.key == GLFW_KEY_ENTER || e.key == GLFW_KEY_KP_ENTER) && (e.mods & RACK_MOD_MASK) == 0) { | |||||
| if (multiline) { | if (multiline) { | ||||
| insertText("\n"); | insertText("\n"); | ||||
| } | } | ||||
| @@ -175,10 +175,10 @@ void TextField::onSelectKey(const event::SelectKey& e) { | |||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| // Consume all printable keys | // Consume all printable keys | ||||
| else if ((GLFW_KEY_SPACE <= e.key && e.key <= GLFW_KEY_WORLD_2) || (GLFW_KEY_KP_0 <= e.key && e.key <= GLFW_KEY_KP_EQUAL)) { | |||||
| if (e.keyName != "") { | |||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||
| else if (e.key == GLFW_KEY_ESCAPE && (e.mods & RACK_MOD_MASK) == 0) { | |||||
| if (e.key == GLFW_KEY_ESCAPE && (e.mods & RACK_MOD_MASK) == 0) { | |||||
| APP->event->setSelected(NULL); | APP->event->setSelected(NULL); | ||||
| e.consume(this); | e.consume(this); | ||||
| } | } | ||||