diff --git a/Common/onelab.h b/Common/onelab.h index 5d95178f20b4e770f94dfc3a01d24f5c0573bd9b..9bee45d83d010f46c15b7471c1d0a64d9a28df91 100644 --- a/Common/onelab.h +++ b/Common/onelab.h @@ -70,6 +70,10 @@ namespace onelab{ { _attributes[key] = value; } + void setAttributes(const std::map<std::string, std::string> &attributes) + { + _attributes = attributes; + } void setClients(std::set<std::string> &clients){ _clients = clients; } void addClient(const std::string &client){ _clients.insert(client); } void addClients(std::set<std::string> &clients) @@ -92,6 +96,10 @@ namespace onelab{ if(it != _attributes.end()) return it->second; return ""; } + const std::map<std::string, std::string> &getAttributes() const + { + return _attributes; + } const std::set<std::string> &getClients() const { return _clients; } static char charSep(){ return '|' /* '\0' */; } static double maxNumber(){ return 1e200; } @@ -159,13 +167,13 @@ namespace onelab{ void setMin(double min){ _min = min; } void setMax(double max){ _max = max; } void setStep(double step){ _step = step; } - void setChoices(std::vector<double> &choices){ _choices = choices; } + void setChoices(const std::vector<double> &choices){ _choices = choices; } std::string getType() const { return "number"; } double getValue() const { return _value; } double getMin() const { return _min; } double getMax() const { return _max; } double getStep() const { return _step; } - const std::vector<double> &getChoices(){ return _choices; } + const std::vector<double> &getChoices() const { return _choices; } void update(const number &p) { if(p.getValue() != getValue()){ @@ -176,8 +184,16 @@ namespace onelab{ setMin(p.getMin()); if(p.getMax() != maxNumber()) setMax(p.getMax()); - if(p.getStep() != getStep()) + if(p.getStep()) setStep(p.getStep()); + if(p.getChoices().size()) + setChoices(p.getChoices()); + if(p.getShortHelp().size()) + setShortHelp(p.getShortHelp()); + if(p.getHelp().size()) + setHelp(p.getHelp()); + if(p.getAttributes().size()) + setAttributes(p.getAttributes()); } std::string toChar() { @@ -250,6 +266,12 @@ namespace onelab{ } if(p.getChoices().size()) setChoices(p.getChoices()); + if(p.getShortHelp().size()) + setShortHelp(p.getShortHelp()); + if(p.getHelp().size()) + setHelp(p.getHelp()); + if(p.getAttributes().size()) + setAttributes(p.getAttributes()); } std::string toChar() { diff --git a/Fltk/inputRange.h b/Fltk/inputRange.h new file mode 100644 index 0000000000000000000000000000000000000000..083c935772fbffc38ab8b69756359041840f78a7 --- /dev/null +++ b/Fltk/inputRange.h @@ -0,0 +1,137 @@ +// Gmsh - Copyright (C) 1997-2011 C. Geuzaine, J.-F. Remacle +// +// See the LICENSE.txt file for license information. Please report all +// bugs and problems to <gmsh@geuz.org>. + +#include <string> +#include <sstream> +#include <stdio.h> +#include <stdlib.h> +#include <FL/Fl.H> +#include <FL/Fl_Window.H> +#include <FL/Fl_Value_Input.H> +#include <FL/Fl_Toggle_Button.H> + +class inputRange : public Fl_Group { + private: + Fl_Value_Input *_input; + Fl_Input *_range; + Fl_Toggle_Button *_range_butt, *_loop_butt; + double _min, _max, _step, _max_number; + void _values2string() + { + // construct range string from min/max/step + std::ostringstream tmp; + if(_min != -_max_number){ + tmp << _min; + _input->minimum(_min); + } + tmp << ":"; + if(_max != _max_number){ + tmp << _max; + _input->maximum(_max); + } + if(_step){ + tmp << ":" << _step; + _input->step(_step); + } + _range->value(tmp.str().c_str()); + } + void _string2values() + { + // parse range string and affect min/max/step + std::string str(_range->value()), min, max, step; + std::string::size_type first = 0, last; + last = str.find_first_of(':', first); + min = str.substr(first, last - first); + if(last != std::string::npos){ + first = last + 1; + last = str.find_first_of(':', first); + max = str.substr(first, last - first); + if(last != std::string::npos) + step = str.substr(last + 1, str.size()); + } + if(min.size()){ + _min = atof(min.c_str()); + _input->minimum(_min); + } + if(max.size()){ + _max = atof(max.c_str()); + _input->maximum(_max); + } + if(step.size()){ + _step = atof(step.c_str()); + _input->step(_step); + } + } + void _show_range() + { + if(_range_butt->value()){ + _input->size(_input->w() - _range->w(), _input->h()); + _input->redraw(); + _range->show(); + } + else{ + _input->size(_input->w() + _range->w(), _input->h()); + _input->redraw(); + _range->hide(); + } + } + static void _input_cb(Fl_Widget *w, void *data) + { + ((inputRange*)data)->do_callback(); + } + static void _range_cb(Fl_Widget *w, void *data) + { + ((inputRange*)data)->_string2values(); + ((inputRange*)data)->do_callback(); + } + static void _range_butt_cb(Fl_Widget *w, void *data) + { + ((inputRange*)data)->_show_range(); + } + static void _loop_butt_cb(Fl_Widget *w, void *data) + { + ((inputRange*)data)->do_callback(); + } + public: + inputRange(int x, int y, int w, int h, double max_number, const char *l=0) + : Fl_Group(x,y,w,h,l), _min(-max_number), _max(max_number), _step(0), + _max_number(max_number) + { + int dot_w = FL_NORMAL_SIZE - 2, loop_w = FL_NORMAL_SIZE + 6; + int input_w = w - dot_w - loop_w; + int range_w = input_w / 2; + + _input = new Fl_Value_Input(x, y, input_w, h); + _input->callback(_input_cb, this); + _input->when(FL_WHEN_ENTER_KEY|FL_WHEN_RELEASE); + + _range = new Fl_Input(x + input_w - range_w, y, range_w, h); + _range->callback(_range_cb, this); + _range->when(FL_WHEN_ENTER_KEY|FL_WHEN_RELEASE); + _range->hide(); + + _range_butt = new Fl_Toggle_Button(x + input_w, y, dot_w, h, ":"); + _range_butt->callback(_range_butt_cb, this); + + _loop_butt = new Fl_Toggle_Button(x + input_w + dot_w, y, loop_w, h); + _loop_butt->label("@-1gmsh_rotate"); + _loop_butt->selection_color(FL_GREEN); + _loop_butt->align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE); + _loop_butt->callback(_loop_butt_cb, this); + + end(); // close the group + resizable(_input); + } + double value() { return _input->value(); } + void value(double val) { _input->value(val); } + void minimum(double val) { _min = val; _values2string(); } + double minimum() { return _min; } + void maximum(double val) { _max = val; _values2string(); } + double maximum() { return _max; } + void step(double val) { _step = val; _values2string(); } + double step() { return _step; } + void loop(int val) { _loop_butt->value(val); } + int loop() { return _loop_butt->value(); } +}; diff --git a/Fltk/onelabWindow.cpp b/Fltk/onelabWindow.cpp index 0142ec1f5fda94fdffc8d5baa5f118883f62f324..ef4b5fa1426b088a4de2c5d5b669328c7a1865f8 100644 --- a/Fltk/onelabWindow.cpp +++ b/Fltk/onelabWindow.cpp @@ -7,10 +7,10 @@ #include "GmshMessage.h" #include "onelab.h" #if (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3) -#include <FL/Fl_Value_Input.H> #include <FL/Fl_Input_Choice.H> #include <FL/Fl_Check_Button.H> #include <FL/Fl_Box.H> +#include "inputRange.h" #include "Context.h" #include "GModel.h" #include "GmshDefines.h" @@ -406,6 +406,9 @@ void onelab_cb(Fl_Widget *w, void *data) if(ps.size()) what += " " + ps[0].getValue(); c->run(what); } + else if(action == "kill"){ + c->kill(); + } } FlGui::instance()->onelab->activate(); @@ -423,19 +426,25 @@ static void onelab_check_button_cb(Fl_Widget *w, void *data) std::vector<onelab::number> numbers; onelab::server::instance()->get(numbers, name); if(numbers.size()){ - numbers[0].setValue(((Fl_Check_Button*)w)->value()); + Fl_Check_Button *o = (Fl_Check_Button*)w; + numbers[0].setValue(o->value()); onelab::server::instance()->set(numbers[0]); } } -static void onelab_value_input_cb(Fl_Widget *w, void *data) +static void onelab_input_range_cb(Fl_Widget *w, void *data) { if(!data) return; std::string name = FlGui::instance()->onelab->getPath((Fl_Tree_Item*)data); std::vector<onelab::number> numbers; onelab::server::instance()->get(numbers, name); if(numbers.size()){ - numbers[0].setValue(((Fl_Value_Input*)w)->value()); + inputRange *o = (inputRange*)w; + numbers[0].setValue(o->value()); + numbers[0].setMin(o->minimum()); + numbers[0].setMax(o->maximum()); + numbers[0].setStep(o->step()); + numbers[0].setAttribute("loop", o->loop() ? "true" : "false"); onelab::server::instance()->set(numbers[0]); } } @@ -447,7 +456,8 @@ static void onelab_input_choice_cb(Fl_Widget *w, void *data) std::vector<onelab::string> strings; onelab::server::instance()->get(strings, name); if(strings.size()){ - strings[0].setValue(((Fl_Input_Choice*)w)->value()); + Fl_Input_Choice *o = (Fl_Input_Choice*)w; + strings[0].setValue(o->value()); onelab::server::instance()->set(strings[0]); } } @@ -494,7 +504,7 @@ onelabWindow::onelabWindow(int deltaFontSize) { FL_NORMAL_SIZE -= deltaFontSize; - int width = 25 * FL_NORMAL_SIZE; + int width = 28 * FL_NORMAL_SIZE; int height = 15 * BH + 3 * WB; _win = new paletteWindow @@ -541,6 +551,8 @@ static std::string getShortName(const std::string &name) void onelabWindow::rebuildTree() { + int width = (3*IW)/2; + _tree->clear(); _tree->sortorder(FL_TREE_SORT_ASCENDING); _tree->selectmode(FL_TREE_SELECT_NONE); @@ -552,13 +564,13 @@ void onelabWindow::rebuildTree() onelab::server::instance()->get(numbers); for(unsigned int i = 0; i < numbers.size(); i++){ Fl_Tree_Item *n = _tree->add(numbers[i].getName().c_str()); - n->labelsize(FL_NORMAL_SIZE + 3); + n->labelsize(FL_NORMAL_SIZE + 5); std::string label = numbers[i].getShortHelp(); if(label.empty()) label = getShortName(numbers[i].getName()); _tree->begin(); if(numbers[i].getChoices().size() == 2 && numbers[i].getChoices()[0] == 0 && numbers[i].getChoices()[1] == 1){ - Fl_Check_Button *but = new Fl_Check_Button(1,1,IW,1); + Fl_Check_Button *but = new Fl_Check_Button(1, 1, width, 1); _treeWidgets.push_back(but); but->copy_label(label.c_str()); but->value(numbers[i].getValue()); @@ -566,18 +578,17 @@ void onelabWindow::rebuildTree() n->widget(but); } else{ - Fl_Value_Input *but = new Fl_Value_Input(1,1,IW,1); + inputRange *but = new inputRange + (1, 1, width, 1, onelab::parameter::maxNumber()); _treeWidgets.push_back(but); but->copy_label(label.c_str()); but->value(numbers[i].getValue()); - if(numbers[i].getMin() != -1.e200) - but->minimum(numbers[i].getMin()); - if(numbers[i].getMax() != 1.e200) - but->maximum(numbers[i].getMax()); - if(numbers[i].getStep()) - but->step(numbers[i].getStep()); + but->minimum(numbers[i].getMin()); + but->maximum(numbers[i].getMax()); + but->step(numbers[i].getStep()); + but->loop(numbers[i].getAttribute("loop") == "true"); but->align(FL_ALIGN_RIGHT); - but->callback(onelab_value_input_cb, (void*)n); + but->callback(onelab_input_range_cb, (void*)n); but->when(FL_WHEN_RELEASE|FL_WHEN_ENTER_KEY); n->widget(but); } @@ -588,11 +599,11 @@ void onelabWindow::rebuildTree() onelab::server::instance()->get(strings); for(unsigned int i = 0; i < strings.size(); i++){ Fl_Tree_Item *n = _tree->add(strings[i].getName().c_str()); - n->labelsize(FL_NORMAL_SIZE + 3); + n->labelsize(FL_NORMAL_SIZE + 5); std::string label = strings[i].getShortHelp(); if(label.empty()) label = getShortName(strings[i].getName()); _tree->begin(); - Fl_Input_Choice *but = new Fl_Input_Choice(1,1,IW,1); + Fl_Input_Choice *but = new Fl_Input_Choice(1, 1, width, 1); _treeWidgets.push_back(but); but->copy_label(label.c_str()); for(unsigned int j = 0; j < strings[i].getChoices().size(); j++) @@ -614,7 +625,7 @@ void onelabWindow::rebuildTree() for(Fl_Tree_Item *n = _tree->first(); n; n = n->next()){ if(n->has_children()){ _tree->begin(); - Fl_Box *but = new Fl_Box(1,1,IW,1); + Fl_Box *but = new Fl_Box(1, 1, width, 1); but->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE); _treeWidgets.push_back(but); but->copy_label(getShortName(n->label()).c_str()); @@ -647,6 +658,20 @@ void onelabWindow::rebuildSolverList() _win->label(_title.c_str()); } +void onelabWindow::activate() +{ + _butt[0]->label("Compute"); + _butt[0]->callback(onelab_cb, (void*)"compute"); + _butt[1]->activate(); +} + +void onelabWindow::deactivate() +{ + _butt[0]->label("Kill"); + _butt[0]->callback(onelab_cb, (void*)"kill"); + _butt[1]->deactivate(); +} + void onelabWindow::addSolver(const std::string &name, const std::string &commandLine, int index) { diff --git a/Fltk/onelabWindow.h b/Fltk/onelabWindow.h index b8648707d4117c32d2940ae0a5a2067660f5efa1..d26fafbc472a871cc47174efbd7da7f1556e3b27 100644 --- a/Fltk/onelabWindow.h +++ b/Fltk/onelabWindow.h @@ -32,8 +32,8 @@ class onelabWindow{ void rebuildSolverList(); void rebuildTree(); void redrawTree(){ _tree->redraw(); } - void activate(){ _butt[0]->activate(); _butt[1]->activate(); } - void deactivate(){ _butt[0]->deactivate(); _butt[1]->deactivate(); } + void activate(); + void deactivate(); void show(){ _win->show(); } int shown(){ return _win->shown(); } std::string getModelExtension(){ return _modelExtension; }