diff --git a/applications/gui/src/main.cpp b/applications/gui/src/main.cpp index 7875e52bb04afc59953ac1a728dafe64008b6d6c..5ebc552fa0ee0664c7a0b7898a723b90bf87f29c 100644 --- a/applications/gui/src/main.cpp +++ b/applications/gui/src/main.cpp @@ -25,10 +25,12 @@ int main(int argc, char **argv) { std::map<ftl::UUID, std::vector<ftl::NetConfigurable*>> peerConfigurables; + // FIXME: Move this elsewhere, it is not just for GUI net->onConnect([&controller, &peerConfigurables](ftl::net::Peer *p) { ftl::UUID peer = p->id(); auto cs = controller->getConfigurables(peer); for (auto c : cs) { + //LOG(INFO) << "NET CONFIG: " << c; ftl::config::json_t *configuration = new ftl::config::json_t; *configuration = controller->get(peer, c); if (!configuration->empty()) { diff --git a/applications/gui/src/screen.cpp b/applications/gui/src/screen.cpp index 811d96cf851781add465e4ec58ee97e93e5c98f2..76665281fc1b9fcbb1b0b45609c509d02f88a69d 100644 --- a/applications/gui/src/screen.cpp +++ b/applications/gui/src/screen.cpp @@ -84,6 +84,8 @@ ftl::gui::Screen::Screen(ftl::Configurable *proot, ftl::net::Universe *pnet, ftl pos_y_ = root_->value("position_y", 0.0f); }); + shortcuts_ = ftl::create<ftl::Configurable>(root_, "shortcuts"); + setSize(Vector2i(1280,720)); toolbuttheme = new Theme(*theme()); @@ -434,12 +436,31 @@ bool ftl::gui::Screen::mouseButtonEvent(const nanogui::Vector2i &p, int button, } } +static std::string generateKeyComboStr(int key, int modifiers) { + std::string res = ""; + + switch(modifiers) { + case 1: res += "Shift+"; break; + case 2: res += "Ctrl+"; break; + case 3: res += "Ctrl+Shift+"; break; + case 4: res += "Alt+"; break; + default: break; + } + + if (key < 127 && key >= 32) { + char buf[2] = { (char)key, 0 }; + return res + std::string(buf); + } else { + return ""; + } +} + bool ftl::gui::Screen::keyboardEvent(int key, int scancode, int action, int modifiers) { using namespace Eigen; if (nanogui::Screen::keyboardEvent(key, scancode, action, modifiers)) { return true; } else { - LOG(INFO) << "Key press " << key << " - " << action << " - " << modifiers; + //LOG(INFO) << "Key press " << key << " - " << action << " - " << modifiers; if (key >= 262 && key <= 267) { if (camera_) camera_->keyMovement(key, modifiers); @@ -447,9 +468,42 @@ bool ftl::gui::Screen::keyboardEvent(int key, int scancode, int action, int modi } else if (action == 1 && key == 'H') { swindow_->setVisible(false); cwindow_->setVisible(false); - } else if (action == 1 && key == 32) { - ctrl_->pause(); - return true; + } else if (action == 1) { + std::string combo = generateKeyComboStr(key, modifiers); + + if (combo.size() > 0) { + LOG(INFO) << "Key combo = " << combo; + + auto s = shortcuts_->get<nlohmann::json>(combo); + if (s) { + //LOG(INFO) << "FOUND KEYBOARD SHORTCUT"; + std::string op = (*s).value("op",std::string("=")); + std::string uri = (*s).value("uri",std::string("")); + + if (op == "toggle") { + auto v = ftl::config::get(uri); + if (v.is_boolean()) { + ftl::config::update(uri, !v.get<bool>()); + } + } else if (op == "+=") { + auto v = ftl::config::get(uri); + if (v.is_number_float()) { + ftl::config::update(uri, v.get<float>() + (*s).value("value",0.0f)); + } else if (v.is_number_integer()) { + ftl::config::update(uri, v.get<int>() + (*s).value("value",0)); + } + } else if (op == "-=") { + auto v = ftl::config::get(uri); + if (v.is_number_float()) { + ftl::config::update(uri, v.get<float>() - (*s).value("value",0.0f)); + } else if (v.is_number_integer()) { + ftl::config::update(uri, v.get<int>() - (*s).value("value",0)); + } + } else if (op == "=") { + ftl::config::update(uri, (*s)["value"]); + } + } + } } return false; } diff --git a/applications/gui/src/screen.hpp b/applications/gui/src/screen.hpp index 9dbed7ead2c064394e1eb877a6a9043ed5b364b4..90cd519bb3681126f4dc4f0d258e342953562433 100644 --- a/applications/gui/src/screen.hpp +++ b/applications/gui/src/screen.hpp @@ -101,6 +101,8 @@ class Screen : public nanogui::Screen { bool show_two_images_ = false; + ftl::Configurable *shortcuts_; + #ifdef HAVE_OPENVR vr::IVRSystem *HMD_; #endif diff --git a/applications/reconstruct/src/main.cpp b/applications/reconstruct/src/main.cpp index 551a2dfe309bf8a5a29c17cc4856acb48f70f09c..0dd0a51912e10157a44ea26d793d8364dd60a441 100644 --- a/applications/reconstruct/src/main.cpp +++ b/applications/reconstruct/src/main.cpp @@ -241,7 +241,7 @@ static void run(ftl::Configurable *root) { //ftl::voxhash::SceneRep *scene = ftl::create<ftl::voxhash::SceneRep>(root, "voxelhash"); ftl::rgbd::Streamer *stream = ftl::create<ftl::rgbd::Streamer>(root, "stream", net); ftl::rgbd::VirtualSource *virt = ftl::create<ftl::rgbd::VirtualSource>(root, "virtual"); - root->set("tags", nlohmann::json::array({ root->getID()+"/virtual" })); + //root->set("tags", nlohmann::json::array({ root->getID()+"/virtual" })); ftl::render::Triangular *splat = ftl::create<ftl::render::Triangular>(root, "renderer", &scene_B); ftl::rgbd::Group *group = new ftl::rgbd::Group; ftl::ILW *align = ftl::create<ftl::ILW>(root, "merge"); diff --git a/components/common/cpp/include/ftl/configuration.hpp b/components/common/cpp/include/ftl/configuration.hpp index 9e4ba8aed4bcf8b5f2c8cec2c1079edb945359c3..18aaf89f9433911dd71ec3d3519ff2125317e78e 100644 --- a/components/common/cpp/include/ftl/configuration.hpp +++ b/components/common/cpp/include/ftl/configuration.hpp @@ -47,6 +47,8 @@ void removeConfigurable(Configurable *cfg); */ bool update(const std::string &puri, const json_t &value); +json_t &get(const std::string &puri); + /** * Resolve a JSON schema reference, but do not wait for a remote reference * if it is not available. A null entity is returned if not resolved. diff --git a/components/common/cpp/src/configuration.cpp b/components/common/cpp/src/configuration.cpp index aa236c8a06772e71d59edd3886ce7a9cb14e2eec..aea0f1b209019332334a8530594d6ba1a84e4587 100644 --- a/components/common/cpp/src/configuration.cpp +++ b/components/common/cpp/src/configuration.cpp @@ -194,6 +194,7 @@ ftl::Configurable *ftl::config::find(const std::string &uri) { actual_uri = rootCFG->getID() + uri; } } + auto ix = config_instance.find(actual_uri); if (ix == config_instance.end()) return nullptr; else return (*ix).second; @@ -228,6 +229,7 @@ void ftl::config::registerConfigurable(ftl::Configurable *cfg) { auto tags = cfg->get<vector<string>>("tags"); if (tags) { for (auto &t : *tags) { + //LOG(INFO) << "REGISTER TAG: " << t; tag_index[t].push_back(cfg); } } @@ -236,22 +238,47 @@ void ftl::config::registerConfigurable(ftl::Configurable *cfg) { json_t null_json; +/* To allow for custom tag format */ +static std::string preprocessURI(const std::string &uri) { + if (uri[0] == '[') { + size_t closing = uri.find_last_of(']'); + string tags = uri.substr(1, closing-1); + + // TODO: Allow for multiple tags + + const auto &cfgs = ftl::config::findByTag(tags); + + // FIXME: Check for more than one tag result + if (cfgs.size() > 0) { + //LOG(INFO) << "PREPROC URI " << cfgs[0]->getID() + uri.substr(closing+1); + return cfgs[0]->getID() + uri.substr(closing+1); + } else { + return uri; + } + } else if (uri[0] == '/') { + return rootCFG->getID() + uri; + } else { + return uri; + } +} + bool ftl::config::update(const std::string &puri, const json_t &value) { // Remove last component of URI string tail = ""; string head = ""; - size_t last_hash = puri.find_last_of('#'); + string uri = preprocessURI(puri); + size_t last_hash = uri.find_last_of('#'); if (last_hash != string::npos) { - size_t last = puri.find_last_of('/'); + size_t last = uri.find_last_of('/'); if (last != string::npos && last > last_hash) { - tail = puri.substr(last+1); - head = puri.substr(0, last); + tail = uri.substr(last+1); + head = uri.substr(0, last); } else { - tail = puri.substr(last_hash+1); - head = puri.substr(0, last_hash); + tail = uri.substr(last_hash+1); + head = uri.substr(0, last_hash); } } else { - LOG(WARNING) << "Expected a # in an update URI: " << puri; + LOG(WARNING) << "Expected a # in an update URI: " << uri; return false; } @@ -284,6 +311,35 @@ bool ftl::config::update(const std::string &puri, const json_t &value) { } } +json_t &ftl::config::get(const std::string &puri) { + // Remove last component of URI + string tail = ""; + string head = ""; + string uri = preprocessURI(puri); + size_t last_hash = uri.find_last_of('#'); + if (last_hash != string::npos) { + size_t last = uri.find_last_of('/'); + if (last != string::npos && last > last_hash) { + tail = uri.substr(last+1); + head = uri.substr(0, last); + } else { + tail = uri.substr(last_hash+1); + head = uri.substr(0, last_hash); + } + } else { + LOG(WARNING) << "Expected a # in an update URI: " << uri; + return null_json; + } + + Configurable *cfg = find(head); + + if (cfg) { + return cfg->getConfig()[tail]; + } else { + return null_json; + } +} + json_t &ftl::config::resolve(const std::string &puri, bool eager) { string uri_str = puri;