From 45cf8c9168cbb5167c6355dbf80db5bd9ee01296 Mon Sep 17 00:00:00 2001 From: omigamedev Date: Mon, 17 Apr 2017 19:35:48 +0200 Subject: [PATCH] map keys and handle key events on Android and OS X --- android/src/main/cpp/keymap.h | 232 ++++++++++++++++++++++++++++++ android/src/main/cpp/main.cpp | 20 ++- engine.xcodeproj/project.pbxproj | 8 ++ engine/app.cpp | 10 +- engine/app.h | 6 +- engine/canvas.h | 4 +- engine/event.cpp | 3 + engine/event.h | 64 +++++++++ engine/keymap.h | 240 +++++++++++++++++++++++++++++++ engine/layout.h | 59 ++------ engine/main.cpp | 17 +++ 11 files changed, 595 insertions(+), 68 deletions(-) create mode 100644 android/src/main/cpp/keymap.h create mode 100644 engine/event.cpp create mode 100644 engine/event.h create mode 100644 engine/keymap.h diff --git a/android/src/main/cpp/keymap.h b/android/src/main/cpp/keymap.h new file mode 100644 index 0000000..c744aac --- /dev/null +++ b/android/src/main/cpp/keymap.h @@ -0,0 +1,232 @@ +kKey convert_key(int android_key) +{ +#define CASE(K,V) case K: return V; + switch(android_key) + { + CASE(AKEYCODE_UNKNOWN, kKey::Unknown); + CASE(AKEYCODE_SOFT_LEFT, kKey::Unknown); + CASE(AKEYCODE_SOFT_RIGHT, kKey::Unknown); + CASE(AKEYCODE_HOME, kKey::AndroidHome); + CASE(AKEYCODE_BACK, kKey::Unknown); + CASE(AKEYCODE_CALL, kKey::Unknown); + CASE(AKEYCODE_ENDCALL, kKey::Unknown); + CASE(AKEYCODE_0, kKey::Unknown); + CASE(AKEYCODE_1, kKey::Unknown); + CASE(AKEYCODE_2, kKey::Unknown); + CASE(AKEYCODE_3, kKey::Unknown); + CASE(AKEYCODE_4, kKey::Unknown); + CASE(AKEYCODE_5, kKey::Unknown); + CASE(AKEYCODE_6, kKey::Unknown); + CASE(AKEYCODE_7, kKey::Unknown); + CASE(AKEYCODE_8, kKey::Unknown); + CASE(AKEYCODE_9, kKey::Unknown); + CASE(AKEYCODE_STAR, kKey::Unknown); + CASE(AKEYCODE_POUND, kKey::Unknown); + CASE(AKEYCODE_DPAD_UP, kKey::Unknown); + CASE(AKEYCODE_DPAD_DOWN, kKey::Unknown); + CASE(AKEYCODE_DPAD_LEFT, kKey::Unknown); + CASE(AKEYCODE_DPAD_RIGHT, kKey::Unknown); + CASE(AKEYCODE_DPAD_CENTER, kKey::Unknown); + CASE(AKEYCODE_VOLUME_UP, kKey::AndroidVolumeUp); + CASE(AKEYCODE_VOLUME_DOWN, kKey::AndroidVolumeDown); + CASE(AKEYCODE_POWER, kKey::Unknown); + CASE(AKEYCODE_CAMERA, kKey::Unknown); + CASE(AKEYCODE_CLEAR, kKey::Unknown); + CASE(AKEYCODE_A, kKey::Unknown); + CASE(AKEYCODE_B, kKey::Unknown); + CASE(AKEYCODE_C, kKey::Unknown); + CASE(AKEYCODE_D, kKey::Unknown); + CASE(AKEYCODE_E, kKey::Unknown); + CASE(AKEYCODE_F, kKey::Unknown); + CASE(AKEYCODE_G, kKey::Unknown); + CASE(AKEYCODE_H, kKey::Unknown); + CASE(AKEYCODE_I, kKey::Unknown); + CASE(AKEYCODE_J, kKey::Unknown); + CASE(AKEYCODE_K, kKey::Unknown); + CASE(AKEYCODE_L, kKey::Unknown); + CASE(AKEYCODE_M, kKey::Unknown); + CASE(AKEYCODE_N, kKey::Unknown); + CASE(AKEYCODE_O, kKey::Unknown); + CASE(AKEYCODE_P, kKey::Unknown); + CASE(AKEYCODE_Q, kKey::Unknown); + CASE(AKEYCODE_R, kKey::Unknown); + CASE(AKEYCODE_S, kKey::Unknown); + CASE(AKEYCODE_T, kKey::Unknown); + CASE(AKEYCODE_U, kKey::Unknown); + CASE(AKEYCODE_V, kKey::Unknown); + CASE(AKEYCODE_W, kKey::Unknown); + CASE(AKEYCODE_X, kKey::Unknown); + CASE(AKEYCODE_Y, kKey::Unknown); + CASE(AKEYCODE_Z, kKey::Unknown); + CASE(AKEYCODE_COMMA, kKey::Unknown); + CASE(AKEYCODE_PERIOD, kKey::Unknown); + CASE(AKEYCODE_ALT_LEFT, kKey::Unknown); + CASE(AKEYCODE_ALT_RIGHT, kKey::Unknown); + CASE(AKEYCODE_SHIFT_LEFT, kKey::Unknown); + CASE(AKEYCODE_SHIFT_RIGHT, kKey::Unknown); + CASE(AKEYCODE_TAB, kKey::Unknown); + CASE(AKEYCODE_SPACE, kKey::Unknown); + CASE(AKEYCODE_SYM, kKey::Unknown); + CASE(AKEYCODE_EXPLORER, kKey::Unknown); + CASE(AKEYCODE_ENVELOPE, kKey::Unknown); + CASE(AKEYCODE_ENTER, kKey::Unknown); + CASE(AKEYCODE_DEL, kKey::Unknown); + CASE(AKEYCODE_GRAVE, kKey::Unknown); + CASE(AKEYCODE_MINUS, kKey::Unknown); + CASE(AKEYCODE_EQUALS, kKey::Unknown); + CASE(AKEYCODE_LEFT_BRACKET, kKey::Unknown); + CASE(AKEYCODE_RIGHT_BRACKET, kKey::Unknown); + CASE(AKEYCODE_BACKSLASH, kKey::Unknown); + CASE(AKEYCODE_SEMICOLON, kKey::Unknown); + CASE(AKEYCODE_APOSTROPHE, kKey::Unknown); + CASE(AKEYCODE_SLASH, kKey::Unknown); + CASE(AKEYCODE_AT, kKey::Unknown); + CASE(AKEYCODE_NUM, kKey::Unknown); + CASE(AKEYCODE_HEADSETHOOK, kKey::Unknown); + CASE(AKEYCODE_FOCUS, kKey::Unknown); + CASE(AKEYCODE_PLUS, kKey::Unknown); + CASE(AKEYCODE_MENU, kKey::Unknown); + CASE(AKEYCODE_NOTIFICATION, kKey::Unknown); + CASE(AKEYCODE_SEARCH, kKey::Unknown); + CASE(AKEYCODE_MEDIA_PLAY_PAUSE, kKey::Unknown); + CASE(AKEYCODE_MEDIA_STOP, kKey::Unknown); + CASE(AKEYCODE_MEDIA_NEXT, kKey::Unknown); + CASE(AKEYCODE_MEDIA_PREVIOUS, kKey::Unknown); + CASE(AKEYCODE_MEDIA_REWIND, kKey::Unknown); + CASE(AKEYCODE_MEDIA_FAST_FORWARD, kKey::Unknown); + CASE(AKEYCODE_MUTE, kKey::Unknown); + CASE(AKEYCODE_PAGE_UP, kKey::Unknown); + CASE(AKEYCODE_PAGE_DOWN, kKey::Unknown); + CASE(AKEYCODE_PICTSYMBOLS, kKey::Unknown); + CASE(AKEYCODE_SWITCH_CHARSET, kKey::Unknown); + CASE(AKEYCODE_BUTTON_A, kKey::Unknown); + CASE(AKEYCODE_BUTTON_B, kKey::Unknown); + CASE(AKEYCODE_BUTTON_C, kKey::Unknown); + CASE(AKEYCODE_BUTTON_X, kKey::Unknown); + CASE(AKEYCODE_BUTTON_Y, kKey::Unknown); + CASE(AKEYCODE_BUTTON_Z, kKey::Unknown); + CASE(AKEYCODE_BUTTON_L1, kKey::Unknown); + CASE(AKEYCODE_BUTTON_R1, kKey::Unknown); + CASE(AKEYCODE_BUTTON_L2, kKey::Unknown); + CASE(AKEYCODE_BUTTON_R2, kKey::Unknown); + CASE(AKEYCODE_BUTTON_THUMBL, kKey::Unknown); + CASE(AKEYCODE_BUTTON_THUMBR, kKey::Unknown); + CASE(AKEYCODE_BUTTON_START, kKey::Unknown); + CASE(AKEYCODE_BUTTON_SELECT, kKey::Unknown); + CASE(AKEYCODE_BUTTON_MODE, kKey::Unknown); + CASE(AKEYCODE_ESCAPE, kKey::Unknown); + CASE(AKEYCODE_FORWARD_DEL, kKey::Unknown); + CASE(AKEYCODE_CTRL_LEFT, kKey::Unknown); + CASE(AKEYCODE_CTRL_RIGHT, kKey::Unknown); + CASE(AKEYCODE_CAPS_LOCK, kKey::Unknown); + CASE(AKEYCODE_SCROLL_LOCK, kKey::Unknown); + CASE(AKEYCODE_META_LEFT, kKey::Unknown); + CASE(AKEYCODE_META_RIGHT, kKey::Unknown); + CASE(AKEYCODE_FUNCTION, kKey::Unknown); + CASE(AKEYCODE_SYSRQ, kKey::Unknown); + CASE(AKEYCODE_BREAK, kKey::Unknown); + CASE(AKEYCODE_MOVE_HOME, kKey::Unknown); + CASE(AKEYCODE_MOVE_END, kKey::Unknown); + CASE(AKEYCODE_INSERT, kKey::Unknown); + CASE(AKEYCODE_FORWARD, kKey::Unknown); + CASE(AKEYCODE_MEDIA_PLAY, kKey::Unknown); + CASE(AKEYCODE_MEDIA_PAUSE, kKey::Unknown); + CASE(AKEYCODE_MEDIA_CLOSE, kKey::Unknown); + CASE(AKEYCODE_MEDIA_EJECT, kKey::Unknown); + CASE(AKEYCODE_MEDIA_RECORD, kKey::Unknown); + CASE(AKEYCODE_F1, kKey::Unknown); + CASE(AKEYCODE_F2, kKey::Unknown); + CASE(AKEYCODE_F3, kKey::Unknown); + CASE(AKEYCODE_F4, kKey::Unknown); + CASE(AKEYCODE_F5, kKey::Unknown); + CASE(AKEYCODE_F6, kKey::Unknown); + CASE(AKEYCODE_F7, kKey::Unknown); + CASE(AKEYCODE_F8, kKey::Unknown); + CASE(AKEYCODE_F9, kKey::Unknown); + CASE(AKEYCODE_F10, kKey::Unknown); + CASE(AKEYCODE_F11, kKey::Unknown); + CASE(AKEYCODE_F12, kKey::Unknown); + CASE(AKEYCODE_NUM_LOCK, kKey::Unknown); + CASE(AKEYCODE_NUMPAD_0, kKey::Unknown); + CASE(AKEYCODE_NUMPAD_1, kKey::Unknown); + CASE(AKEYCODE_NUMPAD_2, kKey::Unknown); + CASE(AKEYCODE_NUMPAD_3, kKey::Unknown); + CASE(AKEYCODE_NUMPAD_4, kKey::Unknown); + CASE(AKEYCODE_NUMPAD_5, kKey::Unknown); + CASE(AKEYCODE_NUMPAD_6, kKey::Unknown); + CASE(AKEYCODE_NUMPAD_7, kKey::Unknown); + CASE(AKEYCODE_NUMPAD_8, kKey::Unknown); + CASE(AKEYCODE_NUMPAD_9, kKey::Unknown); + CASE(AKEYCODE_NUMPAD_DIVIDE, kKey::Unknown); + CASE(AKEYCODE_NUMPAD_MULTIPLY, kKey::Unknown); + CASE(AKEYCODE_NUMPAD_SUBTRACT, kKey::Unknown); + CASE(AKEYCODE_NUMPAD_ADD, kKey::Unknown); + CASE(AKEYCODE_NUMPAD_DOT, kKey::Unknown); + CASE(AKEYCODE_NUMPAD_COMMA, kKey::Unknown); + CASE(AKEYCODE_NUMPAD_ENTER, kKey::Unknown); + CASE(AKEYCODE_NUMPAD_EQUALS, kKey::Unknown); + CASE(AKEYCODE_NUMPAD_LEFT_PAREN, kKey::Unknown); + CASE(AKEYCODE_NUMPAD_RIGHT_PAREN, kKey::Unknown); + CASE(AKEYCODE_VOLUME_MUTE, kKey::Unknown); + CASE(AKEYCODE_INFO, kKey::Unknown); + CASE(AKEYCODE_CHANNEL_UP, kKey::Unknown); + CASE(AKEYCODE_CHANNEL_DOWN, kKey::Unknown); + CASE(AKEYCODE_ZOOM_IN, kKey::Unknown); + CASE(AKEYCODE_ZOOM_OUT, kKey::Unknown); + CASE(AKEYCODE_TV, kKey::Unknown); + CASE(AKEYCODE_WINDOW, kKey::Unknown); + CASE(AKEYCODE_GUIDE, kKey::Unknown); + CASE(AKEYCODE_DVR, kKey::Unknown); + CASE(AKEYCODE_BOOKMARK, kKey::Unknown); + CASE(AKEYCODE_CAPTIONS, kKey::Unknown); + CASE(AKEYCODE_SETTINGS, kKey::Unknown); + CASE(AKEYCODE_TV_POWER, kKey::Unknown); + CASE(AKEYCODE_TV_INPUT, kKey::Unknown); + CASE(AKEYCODE_STB_POWER, kKey::Unknown); + CASE(AKEYCODE_STB_INPUT, kKey::Unknown); + CASE(AKEYCODE_AVR_POWER, kKey::Unknown); + CASE(AKEYCODE_AVR_INPUT, kKey::Unknown); + CASE(AKEYCODE_PROG_RED, kKey::Unknown); + CASE(AKEYCODE_PROG_GREEN, kKey::Unknown); + CASE(AKEYCODE_PROG_YELLOW, kKey::Unknown); + CASE(AKEYCODE_PROG_BLUE, kKey::Unknown); + CASE(AKEYCODE_APP_SWITCH, kKey::Unknown); + CASE(AKEYCODE_BUTTON_1, kKey::Unknown); + CASE(AKEYCODE_BUTTON_2, kKey::Unknown); + CASE(AKEYCODE_BUTTON_3, kKey::Unknown); + CASE(AKEYCODE_BUTTON_4, kKey::Unknown); + CASE(AKEYCODE_BUTTON_5, kKey::Unknown); + CASE(AKEYCODE_BUTTON_6, kKey::Unknown); + CASE(AKEYCODE_BUTTON_7, kKey::Unknown); + CASE(AKEYCODE_BUTTON_8, kKey::Unknown); + CASE(AKEYCODE_BUTTON_9, kKey::Unknown); + CASE(AKEYCODE_BUTTON_10, kKey::Unknown); + CASE(AKEYCODE_BUTTON_11, kKey::Unknown); + CASE(AKEYCODE_BUTTON_12, kKey::Unknown); + CASE(AKEYCODE_BUTTON_13, kKey::Unknown); + CASE(AKEYCODE_BUTTON_14, kKey::Unknown); + CASE(AKEYCODE_BUTTON_15, kKey::Unknown); + CASE(AKEYCODE_BUTTON_16, kKey::Unknown); + CASE(AKEYCODE_LANGUAGE_SWITCH, kKey::Unknown); + CASE(AKEYCODE_MANNER_MODE, kKey::Unknown); + CASE(AKEYCODE_3D_MODE, kKey::Unknown); + CASE(AKEYCODE_CONTACTS, kKey::Unknown); + CASE(AKEYCODE_CALENDAR, kKey::Unknown); + CASE(AKEYCODE_MUSIC, kKey::Unknown); + CASE(AKEYCODE_CALCULATOR, kKey::Unknown); + CASE(AKEYCODE_ZENKAKU_HANKAKU, kKey::Unknown); + CASE(AKEYCODE_EISU, kKey::Unknown); + CASE(AKEYCODE_MUHENKAN, kKey::Unknown); + CASE(AKEYCODE_HENKAN, kKey::Unknown); + CASE(AKEYCODE_KATAKANA_HIRAGANA, kKey::Unknown); + CASE(AKEYCODE_YEN, kKey::Unknown); + CASE(AKEYCODE_RO, kKey::Unknown); + CASE(AKEYCODE_KANA, kKey::Unknown); + CASE(AKEYCODE_ASSIST, kKey::Unknown); + CASE(AKEYCODE_BRIGHTNESS_DOWN, kKey::Unknown); + CASE(AKEYCODE_BRIGHTNESS_UP, kKey::Unknown); + CASE(AKEYCODE_MEDIA_AUDIO_TRACK, kKey::Unknown); + default: + return kKey::Unknown; + } +} \ No newline at end of file diff --git a/android/src/main/cpp/main.cpp b/android/src/main/cpp/main.cpp index 8bedff9..ea9b25d 100755 --- a/android/src/main/cpp/main.cpp +++ b/android/src/main/cpp/main.cpp @@ -26,7 +26,8 @@ #include "pch.h" #include "app.h" -#include "../../../../engine/asset.h" +#include "asset.h" +#include "keymap.h" typedef void (*GLDEBUGPROC)(GLenum source, GLenum type, @@ -363,11 +364,8 @@ static void engine_term_display(struct engine* engine) { */ static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) { struct engine* engine = (struct engine*)app->userData; - float x = AMotionEvent_getX(event, 0); - float y = AMotionEvent_getY(event, 0); - //LOG("event source: %d", AInputEvent_getSource(event)); - MouseEvent e; int32_t eventType = AInputEvent_getType(event); + LOG("event type: %d", eventType); switch (eventType) { case AINPUT_EVENT_TYPE_MOTION: // switch (AInputEvent_getSource(event)) { @@ -375,6 +373,10 @@ static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) // case AINPUT_SOURCE_TOUCHSCREEN: { int action = AKeyEvent_getAction(event) & AMOTION_EVENT_ACTION_MASK; + float x = AMotionEvent_getX(event, 0); + float y = AMotionEvent_getY(event, 0); + //LOG("event source: %d", AInputEvent_getSource(event)); + MouseEvent e; switch (action) { case AMOTION_EVENT_ACTION_DOWN: App::I.mouse_down(0, x, y); @@ -395,8 +397,12 @@ static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) // } // end switch break; case AINPUT_EVENT_TYPE_KEY: - // handle key input... - break; + { + int32_t key_val = AKeyEvent_getKeyCode(event); + LOG("Received key event: %d\n", key_val); + App::I.key_down(convert_key(key_val)); + return 1; + } } // end switch return 0; } diff --git a/engine.xcodeproj/project.pbxproj b/engine.xcodeproj/project.pbxproj index ea7fbfe..4f9fc5d 100644 --- a/engine.xcodeproj/project.pbxproj +++ b/engine.xcodeproj/project.pbxproj @@ -32,6 +32,7 @@ AD8CF7231E914DE400083FFD /* libcurl.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = AD8CF7221E914DE400083FFD /* libcurl.tbd */; }; AD95AEC61E41EDEC002DD03A /* font.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD95AEC31E41EDEC002DD03A /* font.cpp */; }; AD95AEC71E41EDEC002DD03A /* pch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD95AEC51E41EDEC002DD03A /* pch.cpp */; }; + ADB1C3DA1EA3A156009A65BD /* event.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ADB1C3D81EA3A156009A65BD /* event.cpp */; }; ADB61C821E3D38450093280F /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ADB61C801E3D38450093280F /* util.cpp */; }; /* End PBXBuildFile section */ @@ -90,6 +91,9 @@ AD95AEC31E41EDEC002DD03A /* font.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = font.cpp; sourceTree = ""; }; AD95AEC41E41EDEC002DD03A /* font.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = font.h; sourceTree = ""; }; AD95AEC51E41EDEC002DD03A /* pch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pch.cpp; sourceTree = ""; }; + ADB1C3D81EA3A156009A65BD /* event.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = event.cpp; sourceTree = ""; }; + ADB1C3D91EA3A156009A65BD /* event.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = event.h; sourceTree = ""; }; + ADB1C3DB1EA531B0009A65BD /* keymap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = keymap.h; sourceTree = ""; }; ADB61C801E3D38450093280F /* util.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = util.cpp; sourceTree = ""; }; ADB61C811E3D38450093280F /* util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = util.h; sourceTree = ""; }; /* End PBXFileReference section */ @@ -136,6 +140,9 @@ AD58E0511E107411006ACC15 /* engine */ = { isa = PBXGroup; children = ( + ADB1C3DB1EA531B0009A65BD /* keymap.h */, + ADB1C3D81EA3A156009A65BD /* event.cpp */, + ADB1C3D91EA3A156009A65BD /* event.h */, AD29CC601EA2B214008C8BFA /* action.cpp */, AD29CC611EA2B214008C8BFA /* action.h */, AD8CF71F1E913F0500083FFD /* log.cpp */, @@ -253,6 +260,7 @@ AD4C08DC1E89BD0F0051D85F /* canvas.cpp in Sources */, AD95AEC61E41EDEC002DD03A /* font.cpp in Sources */, AD58E0531E107411006ACC15 /* main.cpp in Sources */, + ADB1C3DA1EA3A156009A65BD /* event.cpp in Sources */, AD4C08D91E89BD0F0051D85F /* asset.cpp in Sources */, AD58E0681E2A7741006ACC15 /* image.cpp in Sources */, AD58E0771E3421F2006ACC15 /* Yoga.c in Sources */, diff --git a/engine/app.cpp b/engine/app.cpp index f0bc32d..ef40384 100644 --- a/engine/app.cpp +++ b/engine/app.cpp @@ -652,7 +652,7 @@ bool App::mouse_scroll(float x, float y, float delta) layout[main_id]->update(); return ret == kEventResult::Consumed; } -bool App::key_down(int key) +bool App::key_down(kKey key) { KeyEvent e; e.m_type = kEventType::KeyDown; @@ -661,7 +661,7 @@ bool App::key_down(int key) layout[main_id]->update(); return ret == kEventResult::Consumed; } -bool App::key_up(int key) +bool App::key_up(kKey key) { KeyEvent e; e.m_type = kEventType::KeyUp; @@ -670,12 +670,12 @@ bool App::key_up(int key) layout[main_id]->update(); return ret == kEventResult::Consumed; } -bool App::key_char(int key) +bool App::key_char(char key) { KeyEvent e; e.m_type = kEventType::KeyChar; - e.m_key = key; + e.m_char = key; auto ret = layout[main_id]->on_event(&e); layout[main_id]->update(); return ret == kEventResult::Consumed; -} \ No newline at end of file +} diff --git a/engine/app.h b/engine/app.h index b21a5c8..e8f2d13 100644 --- a/engine/app.h +++ b/engine/app.h @@ -52,7 +52,7 @@ public: bool mouse_move(float x, float y); bool mouse_up(int button, float x, float y); bool mouse_scroll(float x, float y, float delta); - bool key_down(int key); - bool key_up(int key); - bool key_char(int key); + bool key_down(kKey key); + bool key_up(kKey key); + bool key_char(char key); }; diff --git a/engine/canvas.h b/engine/canvas.h index 27cf9db..88a94ef 100644 --- a/engine/canvas.h +++ b/engine/canvas.h @@ -58,12 +58,12 @@ public: } virtual void undo() override { - m_canvas->m_layers[m_stroke->m_layer].m_rtt.bindTexture(); + m_canvas->m_layers[m_layer_idx].m_rtt.bindTexture(); glm::vec2 box_sz = m_box.zw() - m_box.xy(); glTexSubImage2D(GL_TEXTURE_2D, 0, m_box.x, m_box.y, box_sz.x, box_sz.y, GL_RGBA, GL_UNSIGNED_BYTE, m_image.get()); - m_canvas->m_layers[m_stroke->m_layer].m_rtt.unbindTexture(); + m_canvas->m_layers[m_layer_idx].m_rtt.unbindTexture(); } }; diff --git a/engine/event.cpp b/engine/event.cpp new file mode 100644 index 0000000..a937f90 --- /dev/null +++ b/engine/event.cpp @@ -0,0 +1,3 @@ +#include "pch.h" +#include "event.h" + diff --git a/engine/event.h b/engine/event.h new file mode 100644 index 0000000..f3bfee9 --- /dev/null +++ b/engine/event.h @@ -0,0 +1,64 @@ +#pragma once + +enum class kKey : uint8_t +{ + Unknown, + AndroidVolumeUp, + AndroidVolumeDown, + AndroidHome, + KeySpacebar, + KeyE, +}; + +enum class kEventResult : uint8_t +{ + Consumed, + Available, +}; + +enum class kEventCategory : uint8_t +{ + MouseEvent, + KeyEvent, + ButtonEvent, +}; + +enum class kEventType : uint8_t +{ + MouseDownL, + MouseDownR, + MouseMove, + MouseUpL, + MouseUpR, + MouseEnter, + MouseLeave, + MouseScroll, + KeyDown, + KeyUp, + KeyChar, + ButtonDown, + ButtonUp, +}; + +class Event +{ +public: + kEventCategory m_cat; + kEventType m_type; +}; + +class MouseEvent : public Event +{ +public: + MouseEvent() { m_cat = kEventCategory::MouseEvent; } + glm::vec2 m_pos; + float m_scroll_delta; +}; + +class KeyEvent : public Event +{ +public: + KeyEvent() { m_cat = kEventCategory::KeyEvent; } + kKey m_key; + char m_char; +}; diff --git a/engine/keymap.h b/engine/keymap.h new file mode 100644 index 0000000..457dfe8 --- /dev/null +++ b/engine/keymap.h @@ -0,0 +1,240 @@ +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; + +kKey convert_key(int key) +{ +#define CASE(K,V) case K: return V; + switch(key) + { + CASE(kVK_ANSI_A, kKey::Unknown); + CASE(kVK_ANSI_S, kKey::Unknown); + CASE(kVK_ANSI_D, kKey::Unknown); + CASE(kVK_ANSI_F, kKey::Unknown); + CASE(kVK_ANSI_H, kKey::Unknown); + CASE(kVK_ANSI_G, kKey::Unknown); + CASE(kVK_ANSI_Z, kKey::Unknown); + CASE(kVK_ANSI_X, kKey::Unknown); + CASE(kVK_ANSI_C, kKey::Unknown); + CASE(kVK_ANSI_V, kKey::Unknown); + CASE(kVK_ANSI_B, kKey::Unknown); + CASE(kVK_ANSI_Q, kKey::Unknown); + CASE(kVK_ANSI_W, kKey::Unknown); + CASE(kVK_ANSI_E, kKey::KeyE); + CASE(kVK_ANSI_R, kKey::Unknown); + CASE(kVK_ANSI_Y, kKey::Unknown); + CASE(kVK_ANSI_T, kKey::Unknown); + CASE(kVK_ANSI_1, kKey::Unknown); + CASE(kVK_ANSI_2, kKey::Unknown); + CASE(kVK_ANSI_3, kKey::Unknown); + CASE(kVK_ANSI_4, kKey::Unknown); + CASE(kVK_ANSI_6, kKey::Unknown); + CASE(kVK_ANSI_5, kKey::Unknown); + CASE(kVK_ANSI_Equal, kKey::Unknown); + CASE(kVK_ANSI_9, kKey::Unknown); + CASE(kVK_ANSI_7, kKey::Unknown); + CASE(kVK_ANSI_Minus, kKey::Unknown); + CASE(kVK_ANSI_8, kKey::Unknown); + CASE(kVK_ANSI_0, kKey::Unknown); + CASE(kVK_ANSI_RightBracket, kKey::Unknown); + CASE(kVK_ANSI_O, kKey::Unknown); + CASE(kVK_ANSI_U, kKey::Unknown); + CASE(kVK_ANSI_LeftBracket, kKey::Unknown); + CASE(kVK_ANSI_I, kKey::Unknown); + CASE(kVK_ANSI_P, kKey::Unknown); + CASE(kVK_ANSI_L, kKey::Unknown); + CASE(kVK_ANSI_J, kKey::Unknown); + CASE(kVK_ANSI_Quote, kKey::Unknown); + CASE(kVK_ANSI_K, kKey::Unknown); + CASE(kVK_ANSI_Semicolon, kKey::Unknown); + CASE(kVK_ANSI_Backslash, kKey::Unknown); + CASE(kVK_ANSI_Comma, kKey::Unknown); + CASE(kVK_ANSI_Slash, kKey::Unknown); + CASE(kVK_ANSI_N, kKey::Unknown); + CASE(kVK_ANSI_M, kKey::Unknown); + CASE(kVK_ANSI_Period, kKey::Unknown); + CASE(kVK_ANSI_Grave, kKey::Unknown); + CASE(kVK_ANSI_KeypadDecimal, kKey::Unknown); + CASE(kVK_ANSI_KeypadMultiply, kKey::Unknown); + CASE(kVK_ANSI_KeypadPlus, kKey::Unknown); + CASE(kVK_ANSI_KeypadClear, kKey::Unknown); + CASE(kVK_ANSI_KeypadDivide, kKey::Unknown); + CASE(kVK_ANSI_KeypadEnter, kKey::Unknown); + CASE(kVK_ANSI_KeypadMinus, kKey::Unknown); + CASE(kVK_ANSI_KeypadEquals, kKey::Unknown); + CASE(kVK_ANSI_Keypad0, kKey::Unknown); + CASE(kVK_ANSI_Keypad1, kKey::Unknown); + CASE(kVK_ANSI_Keypad2, kKey::Unknown); + CASE(kVK_ANSI_Keypad3, kKey::Unknown); + CASE(kVK_ANSI_Keypad4, kKey::Unknown); + CASE(kVK_ANSI_Keypad5, kKey::Unknown); + CASE(kVK_ANSI_Keypad6, kKey::Unknown); + CASE(kVK_ANSI_Keypad7, kKey::Unknown); + CASE(kVK_ANSI_Keypad8, kKey::Unknown); + CASE(kVK_ANSI_Keypad9, kKey::Unknown); + CASE(kVK_Return, kKey::Unknown); + CASE(kVK_Tab, kKey::Unknown); + CASE(kVK_Space, kKey::Unknown); + CASE(kVK_Delete, kKey::Unknown); + CASE(kVK_Escape, kKey::Unknown); + CASE(kVK_Command, kKey::Unknown); + CASE(kVK_Shift, kKey::Unknown); + CASE(kVK_CapsLock, kKey::Unknown); + CASE(kVK_Option, kKey::Unknown); + CASE(kVK_Control, kKey::Unknown); + CASE(kVK_RightShift, kKey::Unknown); + CASE(kVK_RightOption, kKey::Unknown); + CASE(kVK_RightControl, kKey::Unknown); + CASE(kVK_Function, kKey::Unknown); + CASE(kVK_F17, kKey::Unknown); + CASE(kVK_VolumeUp, kKey::Unknown); + CASE(kVK_VolumeDown, kKey::Unknown); + CASE(kVK_Mute, kKey::Unknown); + CASE(kVK_F18, kKey::Unknown); + CASE(kVK_F19, kKey::Unknown); + CASE(kVK_F20, kKey::Unknown); + CASE(kVK_F5, kKey::Unknown); + CASE(kVK_F6, kKey::Unknown); + CASE(kVK_F7, kKey::Unknown); + CASE(kVK_F3, kKey::Unknown); + CASE(kVK_F8, kKey::Unknown); + CASE(kVK_F9, kKey::Unknown); + CASE(kVK_F11, kKey::Unknown); + CASE(kVK_F13, kKey::Unknown); + CASE(kVK_F16, kKey::Unknown); + CASE(kVK_F14, kKey::Unknown); + CASE(kVK_F10, kKey::Unknown); + CASE(kVK_F12, kKey::Unknown); + CASE(kVK_F15, kKey::Unknown); + CASE(kVK_Help, kKey::Unknown); + CASE(kVK_Home, kKey::Unknown); + CASE(kVK_PageUp, kKey::Unknown); + CASE(kVK_ForwardDelete, kKey::Unknown); + CASE(kVK_F4, kKey::Unknown); + CASE(kVK_End, kKey::Unknown); + CASE(kVK_F2, kKey::Unknown); + CASE(kVK_PageDown, kKey::Unknown); + CASE(kVK_F1, kKey::Unknown); + CASE(kVK_LeftArrow, kKey::Unknown); + CASE(kVK_RightArrow, kKey::Unknown); + CASE(kVK_DownArrow, kKey::Unknown); + CASE(kVK_UpArrow, kKey::Unknown); + default: + return kKey::Unknown; + } +} \ No newline at end of file diff --git a/engine/layout.h b/engine/layout.h index 135181a..d395e40 100644 --- a/engine/layout.h +++ b/engine/layout.h @@ -7,6 +7,7 @@ #include "rtt.h" #include "bezier.h" #include "canvas.h" +#include "event.h" #include #include @@ -85,54 +86,6 @@ enum class kShapeType : uint16_t Slice9 = const_hash("slice9"), }; -enum class kEventResult : uint8_t -{ - Consumed, - Available, -}; - -enum class kEventCategory : uint8_t -{ - MouseEvent, - KeyEvent, -}; -enum class kEventType : uint8_t -{ - MouseDownL, - MouseDownR, - MouseMove, - MouseUpL, - MouseUpR, - MouseEnter, - MouseLeave, - MouseScroll, - KeyDown, - KeyUp, - KeyChar, -}; - -class Event -{ -public: - kEventCategory m_cat; - kEventType m_type; -}; - -class MouseEvent : public Event -{ -public: - MouseEvent() { m_cat = kEventCategory::MouseEvent; } - glm::vec2 m_pos; - float m_scroll_delta; -}; - -class KeyEvent : public Event -{ -public: - KeyEvent() { m_cat = kEventCategory::KeyEvent; } - int m_key; -}; - class LayoutManager { std::map> m_layouts; @@ -754,7 +707,7 @@ public: // } break; case kEventType::KeyChar: - if (ke->m_key >= 32 && ke->m_key < 32+96) + if (ke->m_char >= 32 && ke->m_char < (32+96)) { m_string += (char)ke->m_key; m_text->set_text(m_string.c_str()); @@ -2030,11 +1983,15 @@ public: m_zoom_canvas += me->m_scroll_delta * 0.1f; break; case kEventType::KeyDown: - if (ke->m_key == 'E') + if (ke->m_key == kKey::KeyE) m_canvas->m_erase = true; + if (ke->m_key == kKey::AndroidVolumeUp) + m_zoom_canvas *= 0.9f; + if (ke->m_key == kKey::AndroidVolumeDown) + m_zoom_canvas *= 1.1f; break; case kEventType::KeyUp: - if (ke->m_key == 'E') + if (ke->m_key == kKey::KeyE) m_canvas->m_erase = false; default: break; diff --git a/engine/main.cpp b/engine/main.cpp index 895ebbd..1c8d8c9 100644 --- a/engine/main.cpp +++ b/engine/main.cpp @@ -5,6 +5,7 @@ #include "texture.h" #include "image.h" #include "app.h" +#include "keymap.h" #ifdef __APPLE__ #include @@ -252,6 +253,22 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime App::I.mouse_scroll(mouseLoc.x, App::I.height - mouseLoc.y - 1, [theEvent deltaY]); CGLUnlockContext([[self openGLContext] CGLContextObj]); } +- (void)keyDown:(NSEvent *)theEvent +{ + CGLLockContext([[self openGLContext] CGLContextObj]); + auto keyCode = [theEvent keyCode]; + auto chars = [theEvent characters]; + App::I.key_down(convert_key(keyCode)); + CGLUnlockContext([[self openGLContext] CGLContextObj]); +} +- (void)keyUp:(NSEvent *)theEvent +{ + CGLLockContext([[self openGLContext] CGLContextObj]); + auto keyCode = [theEvent keyCode]; + auto chars = [theEvent characters]; + App::I.key_up(convert_key(keyCode)); + CGLUnlockContext([[self openGLContext] CGLContextObj]); +} @end @interface Window : NSWindow