From e635ad00a802128ff37d48870230fe8c1ff373f5 Mon Sep 17 00:00:00 2001 From: omigamedev Date: Mon, 18 Mar 2019 20:26:18 +0100 Subject: [PATCH] add experimental menu --- data/layout.xml | 29 +++++++++- src/app.h | 8 +-- src/app_layout.cpp | 133 +++++++++++++++++++++++++++++++++------------ src/app_vr.cpp | 20 +++++++ src/main.cpp | 132 +++++++++++++++++++++++--------------------- 5 files changed, 217 insertions(+), 105 deletions(-) diff --git a/data/layout.xml b/data/layout.xml index 8695b3c..a5bebbf 100644 --- a/data/layout.xml +++ b/data/layout.xml @@ -1447,6 +1447,29 @@ Here's a list of what's available in this release. + + + + + + + + + + + + + + + + + + + + + + + @@ -1536,7 +1559,7 @@ Here's a list of what's available in this release. - + @@ -1572,8 +1595,8 @@ Here's a list of what's available in this release. - - + + diff --git a/src/app.h b/src/app.h index de4df43..d3eccab 100644 --- a/src/app.h +++ b/src/app.h @@ -57,9 +57,6 @@ public: LayoutManager layout; NodeMessageBox* msgbox; NodeSettings* settings; - NodePopupMenu* menu_file = nullptr; - NodePopupMenu* menu_edit = nullptr; - NodePopupMenu* menu_layers = nullptr; NodeBorder* sidebar = nullptr; std::shared_ptr layers; std::shared_ptr color; @@ -68,7 +65,6 @@ public: std::shared_ptr presets; NodePanelQuick* quick; NodeCanvas* canvas; - Node* current_panel = nullptr; const uint16_t main_id = const_hash("main"); const std::array res_map{ 512, 1024, 1536, 2048, 4096, 8192 }; const std::array res_map_str{ "2K", "4K", "6K", "8K", "16K", "32K" }; @@ -134,6 +130,8 @@ public: void clear(); void tick(float dt); void update(float dt); + bool vr_start(); + void vr_stop(); void vr_draw(const glm::mat4& proj, const glm::mat4& view, const glm::mat4& pose); void async_start(); void async_update(); @@ -169,7 +167,7 @@ public: void init_menu_file(); void init_menu_edit(); void init_menu_layer(); - void init_menu_timelapse(); + void init_menu_experimental(); void init_menu_about(); void dialog_usermanual(); void dialog_changelog(); diff --git a/src/app_layout.cpp b/src/app_layout.cpp index 9eb8bac..b9b482c 100644 --- a/src/app_layout.cpp +++ b/src/app_layout.cpp @@ -660,50 +660,111 @@ void App::init_menu_edit() } } -void App::init_menu_timelapse() +void App::init_menu_experimental() { - if (auto* menu_file = layout[main_id]->find("menu-timelapse")) + auto main = layout[main_id]; + + if (auto menu_exp = main->find("menu-experimental")) { - menu_file->on_click = [=](Node*) { - glm::vec2 pos = menu_file->m_pos + glm::vec2(0, menu_file->m_size.y); - auto popup = (NodePopupMenu*)layout[const_hash("timelapse-menu")]->m_children[0]->clone(); - popup->update(); + menu_exp->on_click = [this, menu_exp, main](Node*) { + glm::vec2 pos = menu_exp->m_pos + glm::vec2(0, menu_exp->m_size.y); + auto popup_exp = (NodePopupMenu*)layout[const_hash("experimental-menu")]->m_children[0]->clone(); + popup_exp->update(); if (YGNodeStyleGetDirection(layout[main_id]->y_node) == YGDirectionRTL) - pos.x = pos.x - popup->m_size.x + menu_file->m_size.x; - popup->SetPositioning(YGPositionTypeAbsolute); - popup->SetPosition(pos.x, pos.y); - layout[main_id]->add_child(popup); + pos.x = pos.x - popup_exp->m_size.x + menu_exp->m_size.x; + popup_exp->SetPositioning(YGPositionTypeAbsolute); + popup_exp->SetPosition(pos.x, pos.y); + layout[main_id]->add_child(popup_exp); layout[main_id]->update(); - popup->mouse_capture(); - popup->m_mouse_ignore = false; - popup->m_flood_events = true; - popup->m_capture_children = false; - - if (auto item = popup->find("timelapse-start")) + popup_exp->mouse_capture(); + popup_exp->m_mouse_ignore = false; + popup_exp->m_flood_events = true; + popup_exp->m_capture_children = false; + + if (auto tick = popup_exp->find("experimental-timelapse-tick")) tick->on_click = [this, popup_exp](Node* b) { - if (auto text = popup->find("menu-label")) + if (auto menu_time = popup_exp->find("experimental-timelapse")) { - text->set_text(App::I.rec_running ? "Stop Recording" : "Start Recording"); + glm::vec2 pos = b->m_pos + glm::vec2(b->m_size.x, 0); + auto popup_time = (NodePopupMenu*)layout[const_hash("timelapse-menu")]->m_children[0]->clone(); + popup_time->update(); + if (YGNodeStyleGetDirection(layout[main_id]->y_node) == YGDirectionRTL) + pos.x = pos.x - popup_time->m_size.x + b->m_size.x; + popup_time->SetPositioning(YGPositionTypeAbsolute); + popup_time->SetPosition(pos.x, pos.y); + layout[main_id]->add_child(popup_time); + layout[main_id]->update(); + popup_time->mouse_capture(); + popup_time->m_mouse_ignore = false; + popup_time->m_flood_events = true; + popup_time->m_capture_children = false; + + if (auto item = popup_time->find("timelapse-start")) + { + if (auto text = popup_time->find("menu-label")) + { + text->set_text(App::I.rec_running ? "Stop Recording" : "Start Recording"); + } + } + + popup_time->find("timelapse-start")->on_click = [this, popup_time, popup_exp](Node*) { + App::I.rec_running ? App::I.rec_stop() : App::I.rec_start(); + popup_time->destroy(); + popup_exp->destroy(); + }; + + popup_time->find("timelapse-clear")->on_click = [this, popup_time, popup_exp](Node*) { + App::I.rec_clear(); + popup_time->destroy(); + popup_exp->destroy(); + }; + + popup_time->find("timelapse-export")->on_click = [this, popup_time, popup_exp](Node*) { + popup_time->destroy(); + popup_exp->destroy(); + App::I.rec_export(""); + }; } + }; + + if (auto rtl_btn = popup_exp->find("experimental-rtl")) + { + rtl_btn->on_click = [this, popup_exp, rtl_btn](Node* b) + { + NodeCheckBox* cb = rtl_btn->find("experimental-rtl-check"); + cb->set_value(!cb->checked, true); + }; + rtl_btn->find("experimental-rtl-check")->on_value_changed = [this, main](Node*, bool checked) + { + auto ui = main->find("ui-root"); + ui->SetRTL(checked ? YGDirectionRTL : YGDirectionLTR); + }; } - popup->find("timelapse-start")->on_click = [this, popup](Node*) { - App::I.rec_running ? App::I.rec_stop() : App::I.rec_start(); - popup->mouse_release(); - popup->destroy(); - }; - - popup->find("timelapse-clear")->on_click = [this, popup](Node*) { - App::I.rec_clear(); - popup->mouse_release(); - popup->destroy(); - }; - - popup->find("timelapse-export")->on_click = [this, popup](Node*) { - popup->mouse_release(); - popup->destroy(); - App::I.rec_export(""); - }; + if (auto vr_btn = popup_exp->find("experimental-vr")) + { + vr_btn->on_click = [this, popup_exp, vr_btn](Node* b) + { + NodeCheckBox* cb = vr_btn->find("experimental-vr-check"); + cb->set_value(!cb->checked, true); + }; + vr_btn->find("experimental-vr-check")->on_value_changed = [this, main](Node* target, bool checked) + { + if (checked) + { + if (!App::I.vr_start()) + { + auto cb = static_cast(target); + cb->set_value(false); + App::I.message_box("VR Failed", "Couldn't start Virtual Reality mode"); + } + } + else + { + App::I.vr_stop(); + } + }; + } }; } } @@ -939,7 +1000,7 @@ void App::initLayout() init_menu_file(); init_menu_edit(); init_menu_layer(); - init_menu_timelapse(); + init_menu_experimental(); init_menu_about(); // set version string diff --git a/src/app_vr.cpp b/src/app_vr.cpp index 3441d49..641cd03 100644 --- a/src/app_vr.cpp +++ b/src/app_vr.cpp @@ -1,6 +1,26 @@ #include "pch.h" #include "app.h" +#ifdef _WIN32 +bool win32_vr_start(); +void win32_vr_stop(); +#endif + + +bool App::vr_start() +{ +#ifdef _WIN32 + return win32_vr_start(); +#endif +} + +void App::vr_stop() +{ +#ifdef _WIN32 + win32_vr_stop(); +#endif +} + void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat4& pose) { //glm::mat4 ortho_proj = glm::ortho(0.f, box.z, 0.f, box.w, -1000.f, 1000.f); diff --git a/src/main.cpp b/src/main.cpp index 831ac56..bdb0d46 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -446,6 +446,77 @@ void init_vk_map() } } +std::mutex hmd_render_mutex; +std::condition_variable hmd_render_cv; +Vive* vive = nullptr; +bool win32_vr_start() +{ + if (sandboxed) + return false; + + vive = new Vive; + vive->on_draw = [](const glm::mat4& proj, const glm::mat4& view, const glm::mat4& pose) { App::I.vr_draw(proj, view, pose); }; + async_lock(); + if (!vive->Initialize()) + { + delete vive; + vive = nullptr; + LOG("VR: failed to initialize vive"); + async_unlock(); + return false; + } + async_unlock(); + + hmd_renderer = std::thread([&] { + if (!vive) + return; + + BT_SetTerminate(); + LOG("start hmd render thread"); + App::I.has_vr = true; + + const float target_tick_rate = 90; + unsigned long t0 = GetTickCount(); + while (running == 1 && vive->Valid()) + { + std::unique_lock lock(hmd_render_mutex); + unsigned long t1 = GetTickCount(); + float dt = (float)(t1 - t0) / 1000.0f; + + vive->Update(); + App::I.vr_active = vive->m_active; + + if (vive->m_active) + { + async_lock(); + vive->Draw(); + async_unlock(); + } + + const int framerate = (1.f / target_tick_rate) * 1000; + const int diff = framerate - (t1 - t0); + hmd_render_cv.wait_for(lock, std::chrono::milliseconds(diff)); + } + App::I.vr_active = false; + App::I.has_vr = false; + async_lock(); + vive->Terminate(); + async_unlock(); + LOG("hmd renderer terminated"); + }); + return true; +} + +void win32_vr_stop() +{ + if (vive) + { + vive->Terminate(); + delete vive; + vive = nullptr; + } +} + int main(int argc, char** argv) { WNDCLASS wc; @@ -620,21 +691,6 @@ int main(int argc, char** argv) LOG("init app"); App::I.init(); - Vive* vive = nullptr; - if (!sandboxed) - { - vive = new Vive; - vive->on_draw = [](const glm::mat4& proj, const glm::mat4& view, const glm::mat4& pose) { App::I.vr_draw(proj, view, pose); }; - async_lock(); - if (!vive->Initialize()) - { - delete vive; - vive = nullptr; - LOG("VR: failed to initialize vive"); - } - async_unlock(); - } - LOG("show main window"); ShowWindow(hWnd, SW_NORMAL); @@ -654,11 +710,6 @@ int main(int argc, char** argv) SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(GetModuleHandle(0), MAKEINTRESOURCE(IDI_ICON1))); - //LOG("set redraw interval"); - //SetTimer(hWnd, 1, 500, [](HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) { - // App::I.redraw = true; - //}); - running = 1; renderer = std::thread([&] { @@ -766,47 +817,6 @@ int main(int argc, char** argv) LOG("renderer terminated"); }); - std::mutex hmd_render_mutex; - std::condition_variable hmd_render_cv; - - hmd_renderer = std::thread([&] { - if (!vive) - return; - - BT_SetTerminate(); - LOG("start hmd render thread"); - App::I.has_vr = true; - - const float target_tick_rate = 90; - unsigned long t0 = GetTickCount(); - while (running == 1 && vive->Valid()) - { - std::unique_lock lock(hmd_render_mutex); - unsigned long t1 = GetTickCount(); - float dt = (float)(t1 - t0) / 1000.0f; - - vive->Update(); - App::I.vr_active = vive->m_active; - - if (vive->m_active) - { - async_lock(); - vive->Draw(); - async_unlock(); - } - - const int framerate = (1.f / target_tick_rate) * 1000; - const int diff = framerate - (t1 - t0); - hmd_render_cv.wait_for(lock, std::chrono::milliseconds(diff)); - } - App::I.vr_active = false; - App::I.has_vr = false; - async_lock(); - vive->Terminate(); - async_unlock(); - LOG("hmd renderer terminated"); - }); - SetTimer(hWnd, 1, 500, NULL); MSG msg;