diff --git a/src/fmri/Options.cpp b/src/fmri/Options.cpp index c778f9e..137b886 100644 --- a/src/fmri/Options.cpp +++ b/src/fmri/Options.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include "Options.hpp" #include "visualisations.hpp" @@ -67,6 +68,17 @@ static void parse_color(const char *input, Color &targetColor) throw std::invalid_argument(errorBuf); } +static inline void parse_color(const std::string& input, Color& targetColor) +{ + parse_color(input.c_str(), targetColor); +} + +static void use_color(const boost::program_options::variables_map& vm, const char* key, Color& target) { + if (vm.count(key)) { + parse_color(vm[key].as(), target); + } +} + Options::Options(int argc, char * const argv[]): layerTransparancy_(1), interactionTransparancy_(1), @@ -94,6 +106,10 @@ Options::Options(int argc, char * const argv[]): ("interaction-opacity", value_for(interactionTransparancy_), "Opacity for interactions") ("layer-distance", value_for(LAYER_X_OFFSET), "Distance between layers") ("interaction-limit", value_for(INTERACTION_LIMIT), "Maximum number of interactions per layer") + ("neutral-color", value(), "Color for showing neutral states") + ("positive-color", value(), "Color for showing positive states") + ("negative-color", value(), "Color for showing negative states") + ("background-color", value()->default_value("#00000000"), "Color for showing neutral states") ("dump,d", value(&dumpPath), "dump convolutional images in this directory"); options_description composed = desc; @@ -109,8 +125,15 @@ Options::Options(int argc, char * const argv[]): notify(vm); - if (vm.count("path-color")) { - parse_color(vm["path-color"].as().c_str(), pathColor_); + use_color(vm, "path-color", pathColor_); + use_color(vm, "neutral-color", NEUTRAL_COLOR); + use_color(vm, "positive-color", POSITIVE_COLOR); + use_color(vm, "negative-color", NEGATIVE_COLOR); + + if (vm.count("background-color")) { + Color bg; + parse_color(vm["background-color"].as(), bg); + glClearColor(bg[0], bg[1], bg[2], bg[3]); } // Sanity checks diff --git a/src/tools/launcher.cpp b/src/tools/launcher.cpp index f00409d..bbc3baa 100644 --- a/src/tools/launcher.cpp +++ b/src/tools/launcher.cpp @@ -98,6 +98,8 @@ public: private: int rows; + Gtk::Box box; + Gtk::ScrolledWindow scrolledWindow; Gtk::Grid grid; Gtk::FileChooserButton fmriChooser; Gtk::FileChooserButton modelChooser; @@ -106,6 +108,10 @@ private: Gtk::FileChooserButton meansChooser; Gtk::FileChooserButton inputChooser; Gtk::ColorButton pathColor; + Gtk::ColorButton bgColor; + Gtk::ColorButton neutralColor; + Gtk::ColorButton positiveColor; + Gtk::ColorButton negativeColor; Gtk::Scale layerDistance; Gtk::Scale layerTransparancy; Gtk::Scale interactionTransparancy; @@ -118,12 +124,14 @@ private: Gtk::Label* getManagedLabel(const std::string& contents); void findExecutable(); void addRowWithLabel(const std::string& label, Gtk::Widget& widget); + void addHeaderRow(const std::string& header); }; Launcher::Launcher() : Gtk::Window(), rows(0), + box(Gtk::Orientation::ORIENTATION_VERTICAL), fmriChooser("Select FMRI executable"), modelChooser("Select caffe model prototxt"), weightsChooser("Select caffe model weights"), @@ -131,15 +139,22 @@ Launcher::Launcher() meansChooser("Select means file"), inputChooser("Select input directory", Gtk::FileChooserAction::FILE_CHOOSER_ACTION_SELECT_FOLDER), pathColor(Gdk::RGBA("rgba(255, 255, 255, 0.1)")), + bgColor(Gdk::RGBA("rgba(0, 0, 0, 0)")), + neutralColor(Gdk::RGBA("rgba(255, 255, 255, 1)")), + positiveColor(Gdk::RGBA("rgba(0, 0, 255, 1)")), + negativeColor(Gdk::RGBA("rgba(255, 0, 0, 1)")), layerDistance(Gtk::Adjustment::create(10, 0, 100, 0, 0.1, 0)), layerTransparancy(Gtk::Adjustment::create(1, 0, 1, 0.0, 1.f / 256)), interactionTransparancy(Gtk::Adjustment::create(1, 0, 1, 0.0, 1.f / 256)), interactionLimit(Gtk::Adjustment::create(10000, 4096, std::numeric_limits::max()), 10000), startButton("Start FMRI") { - set_default_size(400, -1); - //set_size_request(400, -1); - add(grid); + set_default_size(480, 320); + add(box); + box.add(scrolledWindow); + scrolledWindow.set_vexpand(true); + box.add(startButton); + scrolledWindow.add(grid); // Configure all widgets fmriChooser.set_hexpand(true); @@ -168,14 +183,20 @@ Launcher::Launcher() addRowWithLabel("Labels (optional)", labelChooser); addRowWithLabel("Input directory", inputChooser); addRowWithLabel("Means (optional)", meansChooser); + addHeaderRow("Color settings"); addRowWithLabel("Path color", pathColor); + addRowWithLabel("Background color", bgColor); + addRowWithLabel("Neutral color", neutralColor); + addRowWithLabel("Positive color", positiveColor); + addRowWithLabel("Negative color", negativeColor); + addHeaderRow("Misc settings"); addRowWithLabel("Layer distance", layerDistance); addRowWithLabel("Layer transparancy", layerTransparancy); addRowWithLabel("Interaction transparancy", interactionTransparancy); addRowWithLabel("Interaction limit", interactionLimit); startButton.signal_clicked().connect(sigc::mem_fun(*this, &Launcher::start)); - grid.attach_next_to(startButton, Gtk::PositionType::POS_BOTTOM, 2, 1); + //grid.attach_next_to(startButton, Gtk::PositionType::POS_BOTTOM, 2, 1); show_all_children(true); } @@ -207,6 +228,14 @@ void Launcher::start() wrap_string(weights), wrap_string("-p"), color_string(pathColor), + wrap_string("--background-color"), + color_string(bgColor), + wrap_string("--neutral-color"), + color_string(neutralColor), + wrap_string("--positive-color"), + color_string(positiveColor), + wrap_string("--negative-color"), + color_string(negativeColor) }; float_parameter(argv, "--layer-opacity", layerTransparancy.get_value()); @@ -309,6 +338,14 @@ void Launcher::addRowWithLabel(const std::string &label, Gtk::Widget &widget) grid.attach_next_to(*getManagedLabel(label), widget, Gtk::PositionType::POS_LEFT, 1, 1); } +void Launcher::addHeaderRow(const std::string &header) +{ + int currentRow = rows++; + auto label = getManagedLabel(header); + label->set_markup("" + header + ""); + grid.attach(*label, 0, currentRow, 2, 1); +} + int main(int argc, char** argv) { auto app = Gtk::Application::create(argc, argv);