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(360, 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(FL_DARKCYAN, FL_YELLOW);
00063 o->callback(category_cb, this);
00064 }
00065 { Fl_Hold_Browser* o = itembrowser = new Fl_Hold_Browser(140, 55, 90, 100, "Names");
00066 o->align(FL_ALIGN_TOP);
00067 o->color(FL_DARKCYAN, FL_YELLOW);
00068 o->callback(item_cb, this);
00069 }
00070 { Fl_Hold_Browser* o = colorbrowser = new Fl_Hold_Browser(245, 55, 95, 100, "Colors");
00071 o->align(FL_ALIGN_TOP);
00072 o->color(FL_DARKCYAN, FL_YELLOW);
00073 o->callback(color_cb, this);
00074 }
00075 new Fl_Box(10, 10, 190, 25, "Assign colors to categories:");
00076 { Fl_Tabs* o = new Fl_Tabs(0, 165, 365, 150);
00077 { Fl_Group* o = new Fl_Group(0, 185, 360, 125, "Color Definitions");
00078 { Fl_Hold_Browser* o = colordefbrowser = new Fl_Hold_Browser(15, 195, 95, 100);
00079 o->labeltype(FL_NO_LABEL);
00080 o->color(FL_DARKCYAN, FL_YELLOW);
00081 o->callback(colordef_cb, this);
00082 }
00083 { Fl_Value_Slider* o = redscale = new Fl_Value_Slider(120, 195, 225, 20);
00084 o->type(1);
00085 o->color(1);
00086 o->callback(rgb_cb, this);
00087 }
00088 { Fl_Value_Slider* o = greenscale = new Fl_Value_Slider(120, 215, 225, 20);
00089 o->type(1);
00090 o->color(2);
00091 o->callback(rgb_cb, this);
00092 }
00093 { Fl_Value_Slider* o = bluescale = new Fl_Value_Slider(120, 235, 225, 20);
00094 o->type(1);
00095 o->color(4);
00096 o->callback(rgb_cb, this);
00097 }
00098 { Fl_Button* o = grayscalebutton = new Fl_Button(125, 265, 85, 25, "Grayscale");
00099 o->type(1);
00100 }
00101 defaultbutton = new Fl_Button(250, 265, 85, 25, "Default");
00102 defaultbutton->callback(default_cb, this);
00103 o->end();
00104 }
00105 { Fl_Group* o = new Fl_Group(0, 185, 360, 125, "Color Scale");
00106 o->hide();
00107 { Fl_Choice* o = scalemethod = new Fl_Choice(15, 220, 80, 25, "Method");
00108 o->color(FL_PALEGREEN, FL_BLACK);
00109 o->down_box(FL_BORDER_BOX);
00110 o->align(FL_ALIGN_TOP);
00111 o->callback(scalemethod_cb, this);
00112 }
00113 offsetvalue = new Fl_Value_Slider(160, 205, 180, 20, "Offset");
00114 offsetvalue->type(1);
00115 offsetvalue->color(FL_WHITE, FL_BLACK);
00116 offsetvalue->align(FL_ALIGN_LEFT);
00117 offsetvalue->range(-1.0, 1.0);
00118 offsetvalue->callback(scalesettings_cb, this);
00119 { Fl_Value_Slider* o = midpointvalue = new Fl_Value_Slider(160, 235, 180, 20, "Midpoint");
00120 o->type(1);
00121 midpointvalue->align(FL_ALIGN_LEFT);
00122 midpointvalue->color(FL_WHITE, FL_BLACK);
00123 o->range(0.0, 1.0);
00124 o->callback(scalesettings_cb, this);
00125 }
00126 image = new ColorscaleImage(85, 265, 256, 25, app);
00127 o->end();
00128 }
00129 o->end();
00130 }
00131 end();
00132 }
00133 }
00134
00135 ColorFltkMenu::ColorFltkMenu(VMDApp *vmdapp)
00136 : VMDFltkMenu("color", "Color Controls", vmdapp) {
00137 make_window();
00138
00139 command_wanted(Command::COLOR_SCALE_METHOD);
00140 command_wanted(Command::COLOR_SCALE_SETTINGS);
00141 command_wanted(Command::COLOR_SCALE_COLORS);
00142 command_wanted(Command::COLOR_CHANGE);
00143 command_wanted(Command::COLOR_NAME);
00144 command_wanted(Command::MOL_RENAME);
00145 command_wanted(Command::COLOR_ADD_ITEM);
00146
00147
00148 for (int j=0; j<vmdapp->num_colorscale_methods(); j++)
00149 scalemethod->add(app->colorscale_method_name(j));
00150
00151 reset_color_categories();
00152 reset_color_names();
00153 reset_color_scale();
00154 }
00155
00156 void ColorFltkMenu::reset_color_categories() {
00157 categorybrowser->clear();
00158 int n = app->num_color_categories();
00159 for (int j=0; j<n; j++)
00160 categorybrowser->add(app->color_category(j));
00161 categorybrowser->value(0);
00162 }
00163
00164 void ColorFltkMenu::reset_color_names() {
00165 colorbrowser->clear();
00166 colordefbrowser->clear();
00167 int n = app->num_regular_colors();
00168 for (int j=0; j<n; j++) {
00169 char buf[128];
00170 sprintf(buf, "%d %s", j, app->color_name(j));
00171 colorbrowser->add(buf);
00172 colordefbrowser->add(buf);
00173 }
00174 colorbrowser->value(0);
00175 colordefbrowser->value(0);
00176 }
00177
00178 void ColorFltkMenu::reset_color_scale() {
00179 scalemethod->value(app->colorscale_method_current());
00180 float mid, min, max;
00181 app->colorscale_info(&mid, &min, &max);
00182 offsetvalue->value(min);
00183 midpointvalue->value(mid);
00184 image->redraw();
00185 }
00186
00187 void ColorFltkMenu::update_chosen_color() {
00188 int catval = categorybrowser->value();
00189 int itemval = itembrowser->value();
00190 if (!catval || !itemval) {
00191 colordefbrowser->value(0);
00192 return;
00193 }
00194 const char *category = categorybrowser->text(catval);
00195 const char *item = itembrowser->text(itemval);
00196 const char *color = app->color_mapping(category, item);
00197 int index = app->color_index(color);
00198 if (index < 0) {
00199 msgErr << "ColorFltkMenu::update_chosen_color: invalid color" << sendmsg;
00200 return;
00201 }
00202 colorbrowser->value(index+1);
00203 colorbrowser->visible(index+1);
00204 colordefbrowser->value(index+1);
00205 colordefbrowser->visible(index+1);
00206 update_color_definition();
00207 }
00208
00209 void ColorFltkMenu::update_color_definition() {
00210 float r, g, b;
00211 const char *colorname = app->color_name(colordefbrowser->value()-1);
00212 if (!app->color_value(colorname, &r, &g, &b)) return;
00213 redscale->value(r);
00214 greenscale->value(g);
00215 bluescale->value(b);
00216 }
00217
00218 int ColorFltkMenu::act_on_command(int type, Command *) {
00219 switch (type) {
00220 case Command::COLOR_SCALE_METHOD:
00221 case Command::COLOR_SCALE_SETTINGS:
00222 case Command::COLOR_SCALE_COLORS:
00223 reset_color_scale();
00224 break;
00225 case Command::COLOR_CHANGE:
00226 update_color_definition();
00227 break;
00228 case Command::COLOR_NAME:
00229 case Command::MOL_RENAME:
00230 update_chosen_color();
00231 break;
00232 case Command::COLOR_ADD_ITEM:
00233 category_cb(NULL, this);
00234 break;
00235 default:
00236 ;
00237 }
00238 return FALSE;
00239 }
00240
00241 void ColorFltkMenu::category_cb(Fl_Widget *, void *v) {
00242 ColorFltkMenu *self = (ColorFltkMenu *)v;
00243 int val = self->categorybrowser->value();
00244 if (!val) return;
00245 const char *category = self->categorybrowser->text(val);
00246 int n = self->app->num_color_category_items(category);
00247 self->itembrowser->clear();
00248 for (int i=0; i<n; i++)
00249 self->itembrowser->add(self->app->color_category_item(category, i));
00250 self->itembrowser->value(0);
00251 self->colorbrowser->value(0);
00252 }
00253
00254 void ColorFltkMenu::item_cb(Fl_Widget *, void *v) {
00255 ColorFltkMenu *self = (ColorFltkMenu *)v;
00256 self->update_chosen_color();
00257 }
00258
00259 void ColorFltkMenu::color_cb(Fl_Widget *, void *v) {
00260 ColorFltkMenu *self = (ColorFltkMenu *)v;
00261 int catval = self->categorybrowser->value();
00262 int itemval = self->itembrowser->value();
00263 int colorval = self->colorbrowser->value();
00264 if (!catval || !itemval || !colorval) return;
00265 const char *category = self->categorybrowser->text(catval);
00266 const char *item = self->itembrowser->text(itemval);
00267 const char *color = self->app->color_name(colorval-1);
00268 self->app->color_changename(category, item, color);
00269 self->update_chosen_color();
00270 }
00271
00272 void ColorFltkMenu::colordef_cb(Fl_Widget *, void *v) {
00273 ColorFltkMenu *self = (ColorFltkMenu *)v;
00274 self->update_color_definition();
00275 }
00276
00277 void ColorFltkMenu::rgb_cb(Fl_Widget *w, void *v) {
00278 ColorFltkMenu *self = (ColorFltkMenu *)v;
00279 int val = self->colordefbrowser->value();
00280 if (!val) return;
00281 const char *color = self->colordefbrowser->text(val);
00282 float r, g, b;
00283 if (self->grayscalebutton->value()) {
00284 r = g = b = (float)((Fl_Value_Slider *)w)->value();
00285 } else {
00286 r = (float)self->redscale->value();
00287 g = (float)self->greenscale->value();
00288 b = (float)self->bluescale->value();
00289 }
00290 self->app->color_changevalue(color, r, g, b);
00291 }
00292
00293 void ColorFltkMenu::default_cb(Fl_Widget *, void *v) {
00294 ColorFltkMenu *self = (ColorFltkMenu *)v;
00295 int val = self->colordefbrowser->value();
00296 if (!val) return;
00297 const char *color = self->colordefbrowser->text(val);
00298 float r, g, b;
00299 if (!self->app->color_default_value(color, &r, &g, &b)) {
00300 msgErr << "ColorFltkMenu::default_cb(): invalid color" << sendmsg;
00301 return;
00302 }
00303 self->app->color_changevalue(color, r, g, b);
00304 }
00305
00306 void ColorFltkMenu::scalemethod_cb(Fl_Widget *w, void *v) {
00307 ColorFltkMenu *self = (ColorFltkMenu *)v;
00308 Fl_Choice *choice = (Fl_Choice *)w;
00309 self->app->colorscale_setmethod(choice->value());
00310 }
00311
00312 void ColorFltkMenu::scalesettings_cb(Fl_Widget *, void *v) {
00313 ColorFltkMenu *self = (ColorFltkMenu *)v;
00314 float mid, min, max;
00315 self->app->colorscale_info(&mid, &min, &max);
00316 mid = (float)self->midpointvalue->value();
00317 min = (float)self->offsetvalue->value();
00318 self->app->colorscale_setvalues(mid, min, max);
00319 }