00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <stdio.h>
00010 #include <FL/fl_draw.H>
00011 #include <FL/forms.H>
00012 #include <FL/Fl.H>
00013 #include <FL/Fl_Window.H>
00014 #include <FL/Fl_Hold_Browser.H>
00015 #include <FL/Fl_Box.H>
00016 #include <FL/Fl_Tabs.H>
00017 #include <FL/Fl_Group.H>
00018 #include <FL/Fl_Value_Slider.H>
00019 #include <FL/Fl_Button.H>
00020 #include <FL/Fl_Choice.H>
00021 #include <FL/Fl_Value_Slider.H>
00022
00023 #include "ColorFltkMenu.h"
00024 #include "Command.h"
00025 #include "Scene.h"
00026 #include "VMDApp.h"
00027 #include "Inform.h"
00028
00030 class ColorscaleImage : public Fl_Box {
00031 VMDApp *app;
00032 unsigned char *data;
00033 public:
00034 ColorscaleImage(int myx, int myy, int myw, int myh, VMDApp *vmdapp)
00035 : Fl_Box(myx, myy, myw, myh), app(vmdapp) {
00036 data = new unsigned char[3*w()*h()];
00037 }
00038 ~ColorscaleImage() { delete [] data; }
00039 protected:
00040 virtual void draw() {
00041 for (int i=0; i<w(); i++) {
00042 const float *rgb = app->scene->color_value(i*MAPCLRS/w()+REGCLRS);
00043 unsigned char r = (unsigned char)(255*rgb[0]);
00044 unsigned char g = (unsigned char)(255*rgb[1]);
00045 unsigned char b = (unsigned char)(255*rgb[2]);
00046 for (int j=0; j<h(); j++) {
00047 data[3*w()*j + 3*i + 0] = r;
00048 data[3*w()*j + 3*i + 1] = g;
00049 data[3*w()*j + 3*i + 2] = b;
00050 }
00051 }
00052 fl_draw_image(data, x(), y(), w(), h());
00053 }
00054 };
00055
00056
00057 void ColorFltkMenu::make_window() {
00058 size(400, 305);
00059 {
00060 { Fl_Hold_Browser* o = categorybrowser = new Fl_Hold_Browser(10, 55, 125, 100, "Categories");
00061 o->align(FL_ALIGN_TOP);
00062 o->color(VMDMENU_BROWSER_BG, VMDMENU_BROWSER_SEL);
00063 o->callback(category_cb, this);
00064 VMDFLTKTOOLTIP(o, "Select color category then name to set active color")
00065 }
00066 { Fl_Hold_Browser* o = itembrowser = new Fl_Hold_Browser(140, 55, 120, 100, "Names");
00067 o->align(FL_ALIGN_TOP);
00068 o->color(VMDMENU_BROWSER_BG, VMDMENU_BROWSER_SEL);
00069 o->callback(item_cb, this);
00070 VMDFLTKTOOLTIP(o, "Select color category then name to set active color")
00071 }
00072 { Fl_Hold_Browser* o = colorbrowser = new Fl_Hold_Browser(265, 55, 125, 100, "Colors");
00073 o->align(FL_ALIGN_TOP);
00074 o->color(VMDMENU_BROWSER_BG, VMDMENU_BROWSER_SEL);
00075 o->callback(color_cb, this);
00076 VMDFLTKTOOLTIP(o, "Select color category then name to set active color")
00077 }
00078 new Fl_Box(10, 10, 190, 25, "Assign colors to categories:");
00079 { Fl_Tabs* o = new Fl_Tabs(0, 165, 400, 150);
00080 #if defined(VMDMENU_WINDOW)
00081 o->color(VMDMENU_WINDOW, FL_GRAY);
00082 o->selection_color(VMDMENU_WINDOW);
00083 #endif
00084
00085 { Fl_Group* o = new Fl_Group(0, 185, 400, 125, "Color Definitions");
00086 #if defined(VMDMENU_WINDOW)
00087 o->color(VMDMENU_WINDOW, FL_GRAY);
00088 o->selection_color(VMDMENU_WINDOW);
00089 #endif
00090 { Fl_Hold_Browser* o = colordefbrowser = new Fl_Hold_Browser(15, 195, 135, 100);
00091 o->labeltype(FL_NO_LABEL);
00092 o->color(VMDMENU_BROWSER_BG, VMDMENU_BROWSER_SEL);
00093 o->callback(colordef_cb, this);
00094 VMDFLTKTOOLTIP(o, "Select color name to adjust RGB color definition")
00095 }
00096 { Fl_Value_Slider* o = redscale = new Fl_Value_Slider(160, 195, 225, 20);
00097 o->type(FL_HORIZONTAL);
00098 o->color(VMDMENU_COLOR_RSLIDER);
00099 o->callback(rgb_cb, this);
00100 VMDFLTKTOOLTIP(o, "Adjust slider to change RGB color definition")
00101 }
00102 { Fl_Value_Slider* o = greenscale = new Fl_Value_Slider(160, 215, 225, 20);
00103 o->type(FL_HORIZONTAL);
00104 o->color(VMDMENU_COLOR_GSLIDER);
00105 o->callback(rgb_cb, this);
00106 VMDFLTKTOOLTIP(o, "Adjust slider to change RGB color definition")
00107 }
00108 { Fl_Value_Slider* o = bluescale = new Fl_Value_Slider(160, 235, 225, 20);
00109 o->type(FL_HORIZONTAL);
00110 o->color(VMDMENU_COLOR_BSLIDER);
00111 o->callback(rgb_cb, this);
00112 VMDFLTKTOOLTIP(o, "Adjust slider to change RGB color definition")
00113 }
00114 { Fl_Button* o = grayscalebutton = new Fl_Button(165, 265, 85, 25, "Grayscale");
00115 o->type(FL_TOGGLE_BUTTON);
00116 #if defined(VMDMENU_WINDOW)
00117 o->color(VMDMENU_WINDOW, FL_GRAY);
00118 #endif
00119 VMDFLTKTOOLTIP(o, "Lock sliders for grayscale color")
00120 }
00121 defaultbutton = new Fl_Button(290, 265, 85, 25, "Default");
00122 #if defined(VMDMENU_WINDOW)
00123 defaultbutton->color(VMDMENU_WINDOW, FL_GRAY);
00124 #endif
00125 defaultbutton->callback(default_cb, this);
00126 VMDFLTKTOOLTIP(defaultbutton, "Reset to original RGB color")
00127 o->end();
00128 }
00129 { Fl_Group* o = new Fl_Group(0, 185, 400, 125, "Color Scale");
00130 #if defined(VMDMENU_WINDOW)
00131 o->color(VMDMENU_WINDOW, FL_GRAY);
00132 o->selection_color(VMDMENU_WINDOW);
00133 #endif
00134 o->hide();
00135 { Fl_Choice* o = scalemethod = new Fl_Choice(15, 220, 80, 25, "Method");
00136 o->color(VMDMENU_CHOOSER_BG, VMDMENU_CHOOSER_SEL);
00137 o->down_box(FL_BORDER_BOX);
00138 o->align(FL_ALIGN_TOP);
00139 o->callback(scalemethod_cb, this);
00140 }
00141 offsetvalue = new Fl_Value_Slider(160, 205, 180, 20, "Offset");
00142 offsetvalue->type(FL_HORIZONTAL);
00143 offsetvalue->color(VMDMENU_SLIDER_BG, VMDMENU_SLIDER_FG);
00144 offsetvalue->align(FL_ALIGN_LEFT);
00145 offsetvalue->range(-1.0, 1.0);
00146 offsetvalue->callback(scalesettings_cb, this);
00147 { Fl_Value_Slider* o = midpointvalue = new Fl_Value_Slider(160, 235, 180, 20, "Midpoint");
00148 o->type(FL_HORIZONTAL);
00149 midpointvalue->align(FL_ALIGN_LEFT);
00150 midpointvalue->color(VMDMENU_SLIDER_BG, VMDMENU_SLIDER_FG);
00151 o->range(0.0, 1.0);
00152 o->callback(scalesettings_cb, this);
00153 }
00154 image = new ColorscaleImage(10, 265, 380, 25, app);
00155 o->end();
00156 }
00157 o->end();
00158 }
00159 end();
00160 }
00161 }
00162
00163 ColorFltkMenu::ColorFltkMenu(VMDApp *vmdapp)
00164 : VMDFltkMenu("color", "Color Controls", vmdapp) {
00165 make_window();
00166
00167 command_wanted(Command::COLOR_SCALE_METHOD);
00168 command_wanted(Command::COLOR_SCALE_SETTINGS);
00169 command_wanted(Command::COLOR_SCALE_COLORS);
00170 command_wanted(Command::COLOR_CHANGE);
00171 command_wanted(Command::COLOR_NAME);
00172 command_wanted(Command::MOL_RENAME);
00173 command_wanted(Command::COLOR_ADD_ITEM);
00174
00175
00176 for (int j=0; j<vmdapp->num_colorscale_methods(); j++)
00177 scalemethod->add(app->colorscale_method_name(j));
00178
00179 reset_color_categories();
00180 reset_color_names();
00181 reset_color_scale();
00182 }
00183
00184 void ColorFltkMenu::reset_color_categories() {
00185 categorybrowser->clear();
00186 int n = app->num_color_categories();
00187 for (int j=0; j<n; j++)
00188 categorybrowser->add(app->color_category(j));
00189 categorybrowser->value(0);
00190 }
00191
00192 void ColorFltkMenu::reset_color_names() {
00193 colorbrowser->clear();
00194 colordefbrowser->clear();
00195 int n = app->num_regular_colors();
00196 for (int j=0; j<n; j++) {
00197 char buf[128];
00198 sprintf(buf, "%d %s", j, app->color_name(j));
00199 colorbrowser->add(buf);
00200 colordefbrowser->add(buf);
00201 }
00202 colorbrowser->value(0);
00203 colordefbrowser->value(0);
00204 }
00205
00206 void ColorFltkMenu::reset_color_scale() {
00207 scalemethod->value(app->colorscale_method_current());
00208 float mid, min, max;
00209 app->colorscale_info(&mid, &min, &max);
00210 offsetvalue->value(min);
00211 midpointvalue->value(mid);
00212 image->redraw();
00213 }
00214
00215 void ColorFltkMenu::update_chosen_color() {
00216 int catval = categorybrowser->value();
00217 int itemval = itembrowser->value();
00218 if (!catval || !itemval) {
00219 colordefbrowser->value(0);
00220 return;
00221 }
00222 const char *category = categorybrowser->text(catval);
00223 const char *item = itembrowser->text(itemval);
00224 const char *color = app->color_mapping(category, item);
00225 int index = app->color_index(color);
00226 if (index < 0) {
00227 msgErr << "ColorFltkMenu::update_chosen_color: invalid color" << sendmsg;
00228 return;
00229 }
00230 colorbrowser->value(index+1);
00231 colorbrowser->visible(index+1);
00232 colordefbrowser->value(index+1);
00233 colordefbrowser->visible(index+1);
00234 update_color_definition();
00235 }
00236
00237 void ColorFltkMenu::update_color_definition() {
00238 float r, g, b;
00239 const char *colorname = app->color_name(colordefbrowser->value()-1);
00240 if (!app->color_value(colorname, &r, &g, &b)) return;
00241 redscale->value(r);
00242 greenscale->value(g);
00243 bluescale->value(b);
00244 }
00245
00246 int ColorFltkMenu::act_on_command(int type, Command *) {
00247 switch (type) {
00248 case Command::COLOR_SCALE_METHOD:
00249 case Command::COLOR_SCALE_SETTINGS:
00250 case Command::COLOR_SCALE_COLORS:
00251 reset_color_scale();
00252 break;
00253 case Command::COLOR_CHANGE:
00254 update_color_definition();
00255 break;
00256 case Command::COLOR_NAME:
00257 case Command::MOL_RENAME:
00258 update_chosen_color();
00259 break;
00260 case Command::COLOR_ADD_ITEM:
00261 category_cb(NULL, this);
00262 break;
00263 default:
00264 ;
00265 }
00266 return FALSE;
00267 }
00268
00269 void ColorFltkMenu::category_cb(Fl_Widget *, void *v) {
00270 ColorFltkMenu *self = (ColorFltkMenu *)v;
00271 int val = self->categorybrowser->value();
00272 if (!val) return;
00273 const char *category = self->categorybrowser->text(val);
00274 int n = self->app->num_color_category_items(category);
00275 self->itembrowser->clear();
00276 for (int i=0; i<n; i++)
00277 self->itembrowser->add(self->app->color_category_item(category, i));
00278 self->itembrowser->value(0);
00279 self->colorbrowser->value(0);
00280 }
00281
00282 void ColorFltkMenu::item_cb(Fl_Widget *, void *v) {
00283 ColorFltkMenu *self = (ColorFltkMenu *)v;
00284 self->update_chosen_color();
00285 }
00286
00287 void ColorFltkMenu::color_cb(Fl_Widget *, void *v) {
00288 ColorFltkMenu *self = (ColorFltkMenu *)v;
00289 int catval = self->categorybrowser->value();
00290 int itemval = self->itembrowser->value();
00291 int colorval = self->colorbrowser->value();
00292 if (!catval || !itemval || !colorval) return;
00293 const char *category = self->categorybrowser->text(catval);
00294 const char *item = self->itembrowser->text(itemval);
00295 const char *color = self->app->color_name(colorval-1);
00296 self->app->color_changename(category, item, color);
00297 self->update_chosen_color();
00298 }
00299
00300 void ColorFltkMenu::colordef_cb(Fl_Widget *, void *v) {
00301 ColorFltkMenu *self = (ColorFltkMenu *)v;
00302 self->update_color_definition();
00303 }
00304
00305 void ColorFltkMenu::rgb_cb(Fl_Widget *w, void *v) {
00306 ColorFltkMenu *self = (ColorFltkMenu *)v;
00307 int val = self->colordefbrowser->value();
00308 if (!val) return;
00309 const char *color = self->colordefbrowser->text(val);
00310 float r, g, b;
00311 if (self->grayscalebutton->value()) {
00312 r = g = b = (float)((Fl_Value_Slider *)w)->value();
00313 } else {
00314 r = (float)self->redscale->value();
00315 g = (float)self->greenscale->value();
00316 b = (float)self->bluescale->value();
00317 }
00318 self->app->color_changevalue(color, r, g, b);
00319 }
00320
00321 void ColorFltkMenu::default_cb(Fl_Widget *, void *v) {
00322 ColorFltkMenu *self = (ColorFltkMenu *)v;
00323 int val = self->colordefbrowser->value();
00324 if (!val) return;
00325 const char *color = self->colordefbrowser->text(val);
00326 float r, g, b;
00327 if (!self->app->color_default_value(color, &r, &g, &b)) {
00328 msgErr << "ColorFltkMenu::default_cb(): invalid color" << sendmsg;
00329 return;
00330 }
00331 self->app->color_changevalue(color, r, g, b);
00332 }
00333
00334 void ColorFltkMenu::scalemethod_cb(Fl_Widget *w, void *v) {
00335 ColorFltkMenu *self = (ColorFltkMenu *)v;
00336 Fl_Choice *choice = (Fl_Choice *)w;
00337 self->app->colorscale_setmethod(choice->value());
00338 }
00339
00340 void ColorFltkMenu::scalesettings_cb(Fl_Widget *, void *v) {
00341 ColorFltkMenu *self = (ColorFltkMenu *)v;
00342 float mid, min, max;
00343 self->app->colorscale_info(&mid, &min, &max);
00344 mid = (float)self->midpointvalue->value();
00345 min = (float)self->offsetvalue->value();
00346 self->app->colorscale_setvalues(mid, min, max);
00347 }