diff --git a/android/src/main/cpp/keymap.h b/android/src/main/cpp/keymap.h index c744aac..62ac6c5 100644 --- a/android/src/main/cpp/keymap.h +++ b/android/src/main/cpp/keymap.h @@ -7,7 +7,7 @@ kKey convert_key(int android_key) CASE(AKEYCODE_SOFT_LEFT, kKey::Unknown); CASE(AKEYCODE_SOFT_RIGHT, kKey::Unknown); CASE(AKEYCODE_HOME, kKey::AndroidHome); - CASE(AKEYCODE_BACK, kKey::Unknown); + CASE(AKEYCODE_BACK, kKey::AndroidBack); CASE(AKEYCODE_CALL, kKey::Unknown); CASE(AKEYCODE_ENDCALL, kKey::Unknown); CASE(AKEYCODE_0, kKey::Unknown); diff --git a/android/src/main/cpp/main.cpp b/android/src/main/cpp/main.cpp index 69546e8..74886bf 100755 --- a/android/src/main/cpp/main.cpp +++ b/android/src/main/cpp/main.cpp @@ -406,11 +406,11 @@ static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) switch (action) { case AMOTION_EVENT_ACTION_DOWN: { - float y = AMotionEvent_getY(event, 0); float x = AMotionEvent_getX(event, 0); + float y = AMotionEvent_getY(event, 0); p0.id = AMotionEvent_getPointerId(event, 0); p0.pos = {x, y}; - p0.idx = index; + p0.idx = index; App::I.mouse_down(0, x, y); tracked = 1; //LOG("first down"); @@ -421,15 +421,18 @@ static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) //LOG("pointer down index %d", index); if (count == 2) { - float y = AMotionEvent_getY(event, 1); float x = AMotionEvent_getX(event, 1); + float y = AMotionEvent_getY(event, 1); p1.id = AMotionEvent_getPointerId(event, 1); p1.idx = index; p1.pos = {x, y}; - tracked = 2; + p0.pos.x = AMotionEvent_getX(event, 0); + p0.pos.y = AMotionEvent_getY(event, 0); //LOG("second down"); - App::I.mouse_cancel(0); + if (tracked == 1) + App::I.mouse_cancel(0); App::I.gesture_start(p0.pos, p1.pos); + tracked = 2; } return 1; } @@ -500,9 +503,19 @@ static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) break; case AINPUT_EVENT_TYPE_KEY: { + int action = AKeyEvent_getAction(event); int32_t key_val = AKeyEvent_getKeyCode(event); - LOG("Received key event: %d\n", key_val); - App::I.key_down(convert_key(key_val)); + switch (action) + { + case AKEY_EVENT_ACTION_DOWN: + LOG("Received key down event: %d\n", key_val); + App::I.key_down(convert_key(key_val)); + break; + case AKEY_EVENT_ACTION_UP: + LOG("Received key up event: %d\n", key_val); + App::I.key_up(convert_key(key_val)); + break; + } return 1; } } // end switch diff --git a/data/layout.xml b/data/layout.xml index 4337143..0649ddd 100644 --- a/data/layout.xml +++ b/data/layout.xml @@ -333,7 +333,10 @@ - + + + + diff --git a/engine/action.cpp b/engine/action.cpp index 4f3a7bf..453a809 100644 --- a/engine/action.cpp +++ b/engine/action.cpp @@ -21,3 +21,12 @@ void ActionManager::undo() LOG("History: %.2f KB", I.m_memory / 1024.f); App::I.update_memory_usage(I.m_memory); } + +void ActionManager::clear() +{ + while (!I.m_actions.empty()) + I.m_actions.pop(); + I.m_memory = 0; + LOG("History: %.2f KB", I.m_memory / 1024.f); + App::I.update_memory_usage(I.m_memory); +} diff --git a/engine/action.h b/engine/action.h index 10a6768..b707a72 100644 --- a/engine/action.h +++ b/engine/action.h @@ -17,6 +17,7 @@ public: size_t m_memory = 0; static void add(Action* action); static void undo(); + static void clear(); static bool empty() { return I.m_actions.empty(); diff --git a/engine/app.cpp b/engine/app.cpp index 4375a66..86a4670 100644 --- a/engine/app.cpp +++ b/engine/app.cpp @@ -636,6 +636,12 @@ void App::initLayout() ActionManager::undo(); }; } + if (auto* button = layout[main_id]->find("btn-clean-memory")) + { + button->on_click = [this](Node*) { + ActionManager::clear(); + }; + } if (auto* button = layout[main_id]->find("btn-clear")) { button->on_click = [this](Node*) { @@ -961,7 +967,7 @@ void App::update_memory_usage(size_t bytes) if (auto txt = layout[main_id]->find("txt-memory")) { static char buffer[128]; - sprintf(buffer, "History memory: %.2f Kb", bytes / 1024.f); + sprintf(buffer, "History memory: %.2f Mb", bytes / 1024.f / 1024.f); txt->set_text(buffer); layout[main_id]->update(); } diff --git a/engine/canvas.cpp b/engine/canvas.cpp index 61761cd..254da8a 100644 --- a/engine/canvas.cpp +++ b/engine/canvas.cpp @@ -63,6 +63,13 @@ void ui::Canvas::stroke_end() m_show_tmp = false; } } +void ui::Canvas::stroke_cancel() +{ + if (!m_current_stroke) + return; + m_current_stroke = nullptr; + m_show_tmp = false; +} void ui::Canvas::stroke_draw() { if (!(m_current_stroke && m_current_stroke->has_sample())) diff --git a/engine/canvas.h b/engine/canvas.h index c47b654..7d2119d 100644 --- a/engine/canvas.h +++ b/engine/canvas.h @@ -103,6 +103,7 @@ public: void stroke_update(glm::vec2 point, float pressure); void stroke_draw(); void stroke_end(); + void stroke_cancel(); void stroke_commit(); void clear(const glm::vec4& color = { 1, 1, 1, 0 }); void snapshot_save(std::string data_path); @@ -169,8 +170,6 @@ public: } virtual ~ActionStroke() { - - LOG("ActionStroke destroyed: free %zu bytes", memory()); } }; diff --git a/engine/canvas_modes.cpp b/engine/canvas_modes.cpp index 967e4d1..7428c28 100644 --- a/engine/canvas_modes.cpp +++ b/engine/canvas_modes.cpp @@ -84,7 +84,7 @@ void CanvasModePen::on_MouseEvent(MouseEvent* me, glm::vec2& loc) canvas->stroke_update(loc, 1.f); break; case kEventType::MouseCancel: - canvas->stroke_end(); + canvas->stroke_cancel(); m_dragging = false; node->mouse_release(); break; @@ -348,11 +348,17 @@ void CanvasModeFill::on_MouseEvent(MouseEvent* me, glm::vec2& loc) } case kEventType::MouseCancel: if (m_dragging) + { m_points.pop_back(); + m_shape.update_vertices(m_points.data(), m_points.size()); + } m_dragging = false; node->mouse_release(); if (m_points.size() < 4) + { m_points.clear(); + m_shape.update_vertices(m_points.data(), m_points.size()); + } break; default: break; diff --git a/engine/event.h b/engine/event.h index 62a0660..2cabda6 100644 --- a/engine/event.h +++ b/engine/event.h @@ -6,6 +6,7 @@ enum class kKey : uint8_t AndroidVolumeUp, AndroidVolumeDown, AndroidHome, + AndroidBack, KeySpacebar, KeyE, }; diff --git a/engine/layout.h b/engine/layout.h index 7133df7..55a70ce 100644 --- a/engine/layout.h +++ b/engine/layout.h @@ -2043,7 +2043,7 @@ public: auto blend = glIsEnabled(GL_BLEND); glEnable(GL_BLEND); - glEnable(GL_DEPTH_TEST); + //glEnable(GL_DEPTH_TEST); glClear(GL_DEPTH_BUFFER_BIT); for (int plane_index = 0; plane_index < 6; plane_index++) { @@ -2144,6 +2144,9 @@ public: // m_zoom_canvas *= 0.9f; // if (ke->m_key == kKey::AndroidVolumeDown) // m_zoom_canvas *= 1.1f; + if (ke->m_key == kKey::AndroidBack) + if (!ActionManager::empty()) + ActionManager::undo(); break; case kEventType::KeyUp: // if (ke->m_key == kKey::KeyE) diff --git a/engine/log.cpp b/engine/log.cpp index 57942ec..dc9ecfc 100644 --- a/engine/log.cpp +++ b/engine/log.cpp @@ -12,7 +12,7 @@ static size_t data_handler(void *contents, size_t size, size_t nmemb, void *user void LogRemote::start() { - if (m_running) + if (m_running || m_error) return; // already running m_running = true; @@ -20,7 +20,7 @@ void LogRemote::start() net_init(); auto session_string = net_request("/start"); m_session = atoi(session_string.c_str()); - while (m_running) + while (m_running && !m_error) { auto m = m_mq.Get(); auto escaped = curl_easy_escape(curl, m.c_str(), (int)m.size()); @@ -30,6 +30,7 @@ void LogRemote::start() net_request("/log", std::string(data.get(), sz)); } net_close(); + LOG("NET thread loop exit"); }); } void LogRemote::net_init() @@ -50,7 +51,11 @@ std::string LogRemote::net_request(std::string cmd, std::string data /*= ""*/) curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); res = curl_easy_perform(curl); if (res != CURLcode::CURLE_OK) + { + LOG("NET error, closed"); m_running = false; + m_error = true; + } return readBuffer; } void LogRemote::net_close() @@ -58,6 +63,7 @@ void LogRemote::net_close() if (curl) curl_easy_cleanup(curl); curl = nullptr; + m_running = false; } void LogRemote::log(const char* format, ...) { diff --git a/engine/log.h b/engine/log.h index 93ad779..640d610 100644 --- a/engine/log.h +++ b/engine/log.h @@ -14,7 +14,8 @@ class LogRemote { public: static LogRemote I; - bool m_running; + bool m_running = false; + bool m_error = false; std::thread m_thread; ui::BlockingQueue m_mq; CURL *curl = nullptr;