#include "addsource.hpp" #include "../modules/addsource.hpp" #include "../widgets/combobox.hpp" #include <nanogui/layout.h> #include <nanogui/label.h> #include <nanogui/button.h> #include <nanogui/vscrollpanel.h> #include <nanogui/tabwidget.h> #include <loguru.hpp> using ftl::gui2::AddSourceWindow; AddSourceWindow::AddSourceWindow(nanogui::Widget* parent, AddCtrl *ctrl) : nanogui::Window(parent, ""), ctrl_(ctrl) { using namespace nanogui; auto t = dynamic_cast<ftl::gui2::Screen*>(screen())->getTheme("window_dark"); setTheme(t); //setFixedWidth(500); setFixedSize(Vector2i(500,300)); setLayout(new nanogui::BoxLayout (nanogui::Orientation::Vertical, nanogui::Alignment::Fill, 20, 10)); setPosition(Vector2i(parent->width()/2.0f - fixedWidth()/2.0f, parent->height()/2.0f - fixedHeight()/2.0f)); auto close = new nanogui::Button(buttonPanel(), "", ENTYPO_ICON_CROSS); close->setTheme(dynamic_cast<ftl::gui2::Screen*>(screen())->getTheme("window_dark")); close->setBackgroundColor(theme()->mWindowHeaderGradientBot); close->setCallback([this](){ dispose();}); rebuild(); new_source_handle_ = ctrl_->feed()->onNewSources([this](int a) { LOG(INFO) << "NEW SOURCES"; UNIQUE_LOCK(mutex_, lk); do_rebuild_ = true; return true; }); } AddSourceWindow::~AddSourceWindow() { } nanogui::Button *AddSourceWindow::_addButton(const std::string &s, nanogui::Widget *parent) { using namespace nanogui; ftl::URI uri(s); int icon = 0; switch (uri.getScheme()) { case ftl::URI::SCHEME_DEVICE : icon = ENTYPO_ICON_CAMERA; break; case ftl::URI::SCHEME_FILE : icon = ENTYPO_ICON_FOLDER_VIDEO; break; case ftl::URI::SCHEME_FTL : icon = ENTYPO_ICON_CLOUD; break; case ftl::URI::SCHEME_WS : case ftl::URI::SCHEME_TCP : icon = ENTYPO_ICON_CLASSIC_COMPUTER; break; default: break; } auto *button = new Button(parent, ctrl_->getSourceName(s), icon); if (ctrl_->isSourceActive(s)) { button->setBackgroundColor(Color(0, 255, 0, 25)); } button->setIconPosition(Button::IconPosition::Left); button->setIconExtraScale(1.2); button->setFontSize(18); button->setTooltip(s); button->setCallback([this, uri = s]() { ctrl_->add(uri); close(); }); return button; } void AddSourceWindow::rebuild() { using namespace nanogui; auto *title = new Label(this, "Add Source", "sans-bold"); title->setFontSize(28); auto *tabs = new TabWidget(this); auto *recent_tab = tabs->createTab("Recent"); recent_tab->setLayout(new nanogui::BoxLayout (nanogui::Orientation::Vertical, nanogui::Alignment::Fill, 0, 0)); VScrollPanel *vscroll = new VScrollPanel(recent_tab); vscroll->setFixedHeight(200); Widget *recentscroll = new Widget(vscroll); recentscroll->setLayout(new BoxLayout(Orientation::Vertical, Alignment::Fill, 10, 4)); Button *button; auto srcs = ctrl_->getRecent(); for (auto &s : srcs) { _addButton(s.uri, recentscroll); } auto *group_tab = tabs->createTab("Groups"); group_tab->setLayout(new nanogui::BoxLayout (nanogui::Orientation::Vertical, nanogui::Alignment::Fill, 0, 0)); vscroll = new VScrollPanel(group_tab); vscroll->setFixedHeight(150); Widget *groupscroll = new Widget(vscroll); groupscroll->setLayout(new BoxLayout(Orientation::Vertical, Alignment::Fill, 10, 4)); auto groups = ctrl_->getGroups(); for (auto &s : groups) { _addButton(s, groupscroll); } auto *dev_tab = tabs->createTab("Devices"); dev_tab->setLayout(new nanogui::BoxLayout (nanogui::Orientation::Vertical, nanogui::Alignment::Fill, 0, 0)); vscroll = new VScrollPanel(dev_tab); vscroll->setFixedHeight(150); Widget *devscroll = new Widget(vscroll); devscroll->setLayout(new BoxLayout(Orientation::Vertical, Alignment::Fill, 10, 4)); auto devsrcs = ctrl_->getDeviceSources(); for (auto &s : devsrcs) { _addButton(s, devscroll); } auto *host_tab = tabs->createTab("Hosts"); host_tab->setLayout(new nanogui::BoxLayout (nanogui::Orientation::Vertical, nanogui::Alignment::Fill, 0, 0)); vscroll = new VScrollPanel(host_tab); vscroll->setFixedHeight(150); Widget *hostscroll = new Widget(vscroll); hostscroll->setLayout(new BoxLayout(Orientation::Vertical, Alignment::Fill, 10, 4)); button = new Button(hostscroll, "Add Host", ENTYPO_ICON_PLUS); button->setIconPosition(Button::IconPosition::Left); button->setIconExtraScale(1.2); button->setFontSize(18); button->setTooltip("Manually add a new connection URI"); button->setCallback([this]() { }); auto hostsrcs = ctrl_->getHosts(); for (auto &s : hostsrcs) { _addButton(s, hostscroll); } auto *stream_tab = tabs->createTab("Streams"); stream_tab->setLayout(new nanogui::BoxLayout (nanogui::Orientation::Vertical, nanogui::Alignment::Fill, 0, 0)); vscroll = new VScrollPanel(stream_tab); vscroll->setFixedHeight(150); Widget *streamscroll = new Widget(vscroll); streamscroll->setLayout(new BoxLayout(Orientation::Vertical, Alignment::Fill, 10, 4)); auto streamsrcs = ctrl_->getNetSources(); for (auto &s : streamsrcs) { _addButton(s, streamscroll); } auto *file_tab = tabs->createTab("Files"); file_tab->setLayout(new nanogui::BoxLayout (nanogui::Orientation::Vertical, nanogui::Alignment::Fill, 0, 0)); vscroll = new VScrollPanel(file_tab); vscroll->setFixedHeight(150); Widget *filescroll = new Widget(vscroll); filescroll->setLayout(new BoxLayout(Orientation::Vertical, Alignment::Fill, 10, 4)); button = new Button(filescroll, "Open", ENTYPO_ICON_PLUS); button->setIconPosition(Button::IconPosition::Left); button->setIconExtraScale(1.2); button->setFontSize(18); button->setTooltip("Open FTL File"); button->setCallback([this]() { try { std::string filename = file_dialog({ {"ftl", "FTL Captures"} }, false); if (filename.size() > 0 && filename[0] == '/') { filename = std::string("file://") + filename; } else { filename = std::string("file:///") + filename; } #ifdef WIN32 auto p = filename.find_first_of('\\'); while (p != std::string::npos) { filename[p] = '/'; p = filename.find_first_of('\\'); } #endif ctrl_->add(filename); } catch (const std::exception &e) { LOG(ERROR) << "File load exception: " << e.what(); } close(); }); auto filesrcs = ctrl_->getFileSources(); for (auto &s : filesrcs) { _addButton(s, filescroll); } tabs->setActiveTab(0); /*button = new Button(devicebuttons, "Camera(s)"); button->setCallback([this]() { ctrl_->add("device:camera"); close(); }); button = new Button(devicebuttons, "Realsense"); button->setCallback([this]() { ctrl_->add("device:realsense"); close(); }); button = new Button(devicebuttons, "Screen"); button->setCallback([this]() { ctrl_->add("device:screen"); close(); }); button = new Button(devicebuttons, "3D Camera"); button->setCallback([this]() { ctrl_->add("device:render"); close(); }); button = new Button(devicebuttons, "OpenVR"); button->setCallback([this]() { ctrl_->add("device:openvr"); close(); });*/ /*new Label(this, "Network Sources", "sans-bold"); auto *netbuttons = new Widget(this); netbuttons->setLayout(new BoxLayout(Orientation::Horizontal, Alignment::Middle, 0, 4)); auto netsrcs = ctrl_->getNetSources(); for (auto &s : netsrcs) { button = new Button(netbuttons, ctrl_->getSourceName(s)); if (ctrl_->isSourceActive(s)) { button->setBackgroundColor(Color(0, 255, 0, 25)); } button->setCallback([this, s]() { ctrl_->add(s); close(); }); }*/ //new Label(this, "Files", "sans-bold"); //auto *filebuttons = new Widget(this); //filebuttons->setLayout(new BoxLayout(Orientation::Horizontal, Alignment::Middle, 0, 4)); /*auto filesrcs = ctrl_->getFileSources(); for (auto &s : filesrcs) { button = new Button(filebuttons, ctrl_->getSourceName(s)); if (ctrl_->isSourceActive(s)) { button->setBackgroundColor(Color(0, 255, 0, 25)); } button->setCallback([this, s]() { ctrl_->add(s); close(); }); }*/ } void AddSourceWindow::close() { setVisible(false); dispose(); } void AddSourceWindow::draw(NVGcontext *ctx) { { UNIQUE_LOCK(mutex_, lk); if (do_rebuild_) { do_rebuild_ = false; // Note the 1, first widget is the title bar buttons while(childCount() > 1) { removeChild(childCount()-1); } rebuild(); screen()->performLayout(); } } nanogui::Window::draw(ctx); }