rework keyframe hide popup, keyframe auto render, textbox set_selection wide text
[goodguy/history.git] / cinelerra-5.1 / plugins / bluebanana / bluebananawindow.C
1 /*
2  * Cinelerra :: Blue Banana - color modification plugin for Cinelerra-CV
3  * Copyright (C) 2012 Monty <monty@xiph.org>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  */
20
21 #include <unistd.h>
22 #include <math.h>
23 #include "bcdisplayinfo.h"
24 #include "bcsignals.h"
25 #include "cursors.h"
26 #include "bluebanana.h"
27 #include "bluebananaconfig.h"
28 #include "bluebananaslider.h"
29 #include "bluebananawindow.h"
30 #include "keys.h"
31 #include "language.h"
32 #include "brender.h"
33
34 #include "bluebananacolor.c"
35
36
37 class BluebananaHActive : public BC_CheckBox {
38 public:
39   BluebananaHActive(BluebananaMain *plugin, BluebananaWindow *gui);
40   virtual int handle_event();
41   void update();
42   BluebananaMain *plugin;
43   BluebananaWindow *gui;
44 };
45
46 class BluebananaSActive : public BC_CheckBox {
47 public:
48   BluebananaSActive(BluebananaMain *plugin, BluebananaWindow *gui);
49   virtual int handle_event();
50   void update();
51   BluebananaMain *plugin;
52   BluebananaWindow *gui;
53 };
54
55 class BluebananaVActive : public BC_CheckBox {
56 public:
57   BluebananaVActive(BluebananaMain *plugin, BluebananaWindow *gui);
58   virtual int handle_event();
59   void update();
60   BluebananaMain *plugin;
61   BluebananaWindow *gui;
62 };
63
64
65 // -------------------------------------------------------------------------------
66 // The below code is because the stock TextTumbler trips too many bugs
67 // in guicast to be useful. If this plugin is to be shipped standalone
68 // and work, we need an independent version that avoids the bugs here.
69
70 BB_Tumble::BB_Tumble(BluebananaMain *plugin,
71                      BluebananaWindow *gui,
72                      float min,
73                      float mid,
74                      float max,
75                      int precision,
76                      float increment,
77                      int text_w)
78   : BC_TextBox(-1,-1,text_w,1,mid,1,MEDIUMFONT,precision){
79
80   // We must pass in the precision for initialization to get the
81   // geometry right.  But then bctextbox.C immediately clobbers it, so
82   // set it again
83   set_precision(precision);
84
85   this->gui = gui;
86   this->plugin = plugin;
87   this->x = -1;
88   this->y = -1;
89   this->min = min;
90   this->mid = mid;
91   this->max = max;
92   this->text_w = text_w;
93   this->precision = precision;
94   this->increment = increment;
95   this->active = 0;
96   this->suppress_events = 0;
97 }
98
99 float BB_Tumble::get_value(){
100   const char *text = get_text();
101   if(!text || text[0]==0) return 0;
102   return atof(text);
103 }
104
105 int BB_Tumble::handle_event(){
106   if(!suppress_events) value_event();
107   return 1;
108 }
109
110 int BB_Tumble::activate(){
111   // we want to restore the previous value on ESC
112   prev = get_value();
113   // the textbox active member is private, make our own
114   active = 1;
115   return BC_TextBox::activate();
116 }
117
118 int BB_Tumble::deactivate(){
119   if(active){
120     // only fire an event if the value changed; this makes 0/360
121     // behavior in the hue selection readout stick with what the user
122     // actually sets (as opposed to sanity checking flipping the value
123     // if an event fires)
124     if(get_value()!=prev)
125       value_event();
126     active = 0;
127     suppress_events=0;
128   }
129   return BC_TextBox::deactivate();
130 }
131
132 int BB_Tumble::button_press_event(){
133   if(is_event_win()){
134     if(get_buttonpress() < 4) return BC_TextBox::button_press_event();
135     if(get_buttonpress() == 4){
136       float v = get_value()+increment;
137       if(v>max)v=max;
138       update(v);
139       value_event();
140     }else if(get_buttonpress() == 5){
141       float v = get_value()-increment;
142       if(v<min)v=min;
143       update(v);
144       value_event();
145     }
146     return 1;
147   }
148   return 0;
149 }
150
151 int BB_Tumble::keypress_event(){
152   if(active && get_keypress()==ESC)
153     update(prev);
154
155   // don't fire update events from every keypress when editing; that
156   // will trigger slider updates, which will then sanity-check/clamp
157   // values, and then update/clobber the readout text while we're
158   // editing it.
159   suppress_events=1;
160   int ret = BC_TextBox::keypress_event();
161   suppress_events=0;
162   return ret;
163 }
164
165 // --------------------------------------------------------------------------------
166 //  initialization:
167 //    1) create_objects() constructs sliders and readouts with
168 //       limits but no values
169 //    2) create_objects() then calls slider update()
170 //       update computes and sets slider vals from config
171 //       update computes and sets readout vals from config
172 //
173 //  slider drag event:
174 //    1) slider calls handle_event(). This updates config.
175 //    2) slider calls update()
176 //       update computes and [re]sets slider vals from config;
177 //          this is where the snap-to-value behavior comes from
178 //       update computes and sets readout vals from config
179 //
180 //  readout event:
181 //    1) readout calls handle_event(). This updates config.
182 //    2) readout calls slider update() directly
183 //       slider update computes and sets slider vals from config
184 //       slider update computes and [re]sets readout vals from config;
185 //           this does not result in a further handle_event() call, so
186 //           no infinite recursion.
187 //
188 //  importantly, readout and slider values are set from the config
189 //  (and vice-versa) in only one place each.
190
191 // ---------------------------- hue adjustment slider -------------------------------
192
193 class BluebananaHAReadout : public BB_Tumble {
194  public:
195   BluebananaHAReadout(BluebananaMain *plugin, BluebananaWindow *gui, int w)
196     : BB_Tumble(plugin,gui,rint(-180),0,rint(180), 0,1,w){}
197   int value_event();
198 };
199
200 class BluebananaHASlider : public BluebananaSliderSingle {
201 public:
202   BluebananaHASlider(BluebananaMain *plugin, BluebananaWindow *gui,
203                      int x, int y, int w, int h)
204     : BluebananaSliderSingle(plugin,gui,x,y,w,h,-180,180){
205   }
206   virtual int handle_event() {
207     plugin->config.Hadj_val = val;
208     return 1;
209   }
210   void reset(){
211     plugin->config.Hadj_val=0;
212     update();
213   }
214   void update(){
215     val=plugin->config.Hadj_val;
216     highlight = plugin->config.active && plugin->config.Hadj_active;
217     gui->Hadj_readout->update(plugin->config.Hadj_val);
218     gui->slider_labels[7]->set_color(highlight && plugin->config.Hadj_val ?
219                                      get_resources()->default_text_color : dimtextcolor);
220     gui->enter_config_change();
221     gui->commit_config_change();
222   }
223   void trough_color(float hdel, float vdel, float &r, float &g, float &b, float &a){
224     float Hshift = plugin->config.Hsel_active ? (plugin->config.Hsel_lo + plugin->config.Hsel_hi)/720.f-.5f : 0.f;
225     float deg = hdel+Hshift;
226     if(deg<0)deg+=1;
227     if(deg>1)deg-=1;
228     HSpV_to_RGB(deg*6.f,1.,.2,r,g,b);
229     a=1.;
230   }
231 };
232
233 int BluebananaHAReadout::value_event(){
234   float val = get_value();
235   if(val<-180)val=-180;
236   if(val>180)val=180;
237   plugin->config.Hadj_val = val;
238   gui->Hadj_slider->update();
239   return 1;
240 }
241
242 // ------------------------------ Filter selection slider --------------------------------
243 class BluebananaFSReadout0 : public BB_Tumble {
244  public:
245   BluebananaFSReadout0(BluebananaMain *plugin, BluebananaWindow *gui, int w)
246     : BB_Tumble(plugin,gui,-FSrange,0,FSrange, 0,1,w){}
247   int value_event();
248 };
249 class BluebananaFSReadout1 : public BB_Tumble {
250  public:
251   BluebananaFSReadout1(BluebananaMain *plugin, BluebananaWindow *gui, int w)
252     : BB_Tumble(plugin,gui,-FSrange,0,FSrange, 0,1,w){}
253   int value_event();
254 };
255 class BluebananaFSReadout2 : public BB_Tumble {
256  public:
257   BluebananaFSReadout2(BluebananaMain *plugin, BluebananaWindow *gui, int w)
258     : BB_Tumble(plugin,gui,-FSrange,0,FSrange, 0,1,w){}
259   int value_event();
260 };
261 class BluebananaFSReadout3 : public BB_Tumble {
262  public:
263   BluebananaFSReadout3(BluebananaMain *plugin, BluebananaWindow *gui, int w)
264     : BB_Tumble(plugin,gui,0.,0,FSovermax, 0,1,w){}
265   int value_event();
266 };
267
268 static void paint_dot(float *array,int w, int h, float cx, float cy, float r, int inv){
269   int x,y;
270   int x0 = floor(cx-r);
271   int x1 = ceil(cx+r)+1;
272   int y0 = floor(cy-r);
273   int y1 = ceil(cy+r)+1;
274
275   if(x0<0)x0=0;
276   if(x1<0)x1=0;
277   if(y0<0)y0=0;
278   if(y1<0)y1=0;
279
280   if(x0>w)x0=w;
281   if(x1>w)x1=w;
282   if(y0>h)y0=h;
283   if(y1>h)y1=h;
284
285   for(y=y0;y<y1;y++){
286     float *row = array+y*w;
287     for(x=x0;x<x1;x++){
288       float rr = hypotf(x-cx,y-cy);
289       /* not correct, but this is merely cosmetic anyway */
290       float v = (r-rr+.5);
291       if(v>0){
292         if(inv){
293           row[x] -= v;
294           if(row[x]>1.)row[x]=0.;
295         }else{
296           row[x] += v;
297           if(row[x]>1.)row[x]=1.;
298         }
299       }
300     }
301   }
302 }
303
304 class BluebananaFSSlider : public BluebananaSliderFill {
305 public:
306   BluebananaFSSlider(BluebananaMain *plugin, BluebananaWindow *gui,
307                      int x, int y, int w, int h)
308     : BluebananaSliderFill(plugin,gui,x,y,w,h,-FSrange,FSrange,FSovermax) {
309     trough_alpha=0;
310     recompute_trough_alpha = 1;
311     erode=-1;
312   }
313   ~BluebananaFSSlider(){
314     if(trough_alpha)delete[] trough_alpha;
315   }
316   virtual int handle_event() {
317     plugin->config.Fsel_lo = (int)rint(loval);
318     plugin->config.Fsel_mid = (int)rint(midval);
319     plugin->config.Fsel_hi = (int)rint(hival);
320     plugin->config.Fsel_over = (int)rint(overval);
321     recompute_trough_alpha = 1;
322     return 1;
323   }
324   void update(){
325     if(plugin->config.Fsel_lo>0)plugin->config.Fsel_lo=0;
326     if(plugin->config.Fsel_hi<0)plugin->config.Fsel_hi=0;
327
328     if(highlight!=plugin->config.Fsel_active ||
329        erode!=plugin->config.Fsel_erode ||
330        loval!=plugin->config.Fsel_lo ||
331        midval!=plugin->config.Fsel_mid ||
332        hival!=plugin->config.Fsel_hi ||
333        overval!=plugin->config.Fsel_over){
334       recompute_trough_alpha = 1;
335     }
336     erode = plugin->config.Fsel_erode;
337     loval = plugin->config.Fsel_lo;
338     midval = plugin->config.Fsel_mid;
339     hival = plugin->config.Fsel_hi;
340     overval = plugin->config.Fsel_over;
341     highlight = plugin->config.Fsel_active;
342     gui->Fsel_readout0->update(plugin->config.Fsel_lo);
343     gui->Fsel_readout1->update(plugin->config.Fsel_mid);
344     gui->Fsel_readout2->update(plugin->config.Fsel_hi);
345     gui->Fsel_readout3->update(plugin->config.Fsel_over);
346     gui->slider_labels[3]->set_color
347       (highlight &&
348        (plugin->config.Hsel_active || plugin->config.Ssel_active || plugin->config.Vsel_active) &&
349        (plugin->config.Fsel_lo  != 0 ||
350         plugin->config.Fsel_mid != 0 ||
351         plugin->config.Fsel_hi  != 0 ||
352         plugin->config.Fsel_over!= 0 ) ?
353        get_resources()->default_text_color : dimtextcolor);
354
355     gui->erode_label->set_color
356       (highlight && plugin->config.Fsel_lo && plugin->config.Fsel_hi &&
357        (plugin->config.Hsel_active || plugin->config.Ssel_active || plugin->config.Vsel_active)?
358        get_resources()->default_text_color : dimtextcolor);
359
360     gui->enter_config_change();
361     gui->commit_config_change();
362   }
363   void trough_color(float hdel, float vdel, float &r, float &g, float &b, float &a){
364     int x = rint(hdel*troughcols-.5);
365     int y = rint(vdel*troughlines-.5);
366     float deg = plugin->config.Hsel_active ?
367       vdel*(plugin->config.Hsel_hi-plugin->config.Hsel_lo)+plugin->config.Hsel_lo :
368       vdel*360.f;
369     float sat = plugin->config.Ssel_active ?
370       (plugin->config.Ssel_hi+plugin->config.Ssel_lo)/200.:
371       .5;
372     float val = plugin->config.Vsel_active ?
373       (plugin->config.Vsel_hi*3+plugin->config.Vsel_lo)/400:
374       .75;
375
376     if(deg>=360)deg-=360.f;
377     HSpV_to_RGB(deg/60.,sat,val,r,g,b);
378     a = trough_alpha[troughcols*y+x];
379   }
380   void render(){
381
382     if(!trough_alpha)
383       trough_alpha = new float[troughcols*troughlines];
384
385     if(recompute_trough_alpha){
386       int trough_border = FSrange;
387       int tw = troughcols*3+trough_border*2;
388       int th = troughlines*3+trough_border*2;
389
390       float work1[tw*th];
391       float work2[tw*th];
392
393       memset(work1,0,sizeof(work1));
394
395       float loval=1;
396       float hival=FSrange*2-1;
397       float y0 = (th-1)/2.;
398       float y1 = (th-1)/2.;
399
400       int spacing=rint(FSrange)*2;
401       int rowflag=0;
402       int x,y;
403
404       while((y0+spacing*.5)>0){
405         for(x=(rowflag?spacing/2.:0.);x-spacing*.5<tw;x+=spacing){
406           float r = (((float)x/tw)*(hival-loval)+loval)*.5;
407           if(y0==y1){
408             paint_dot(work1,tw,th,x,y0,r,0);
409           }else{
410             paint_dot(work1,tw,th,x,y0,r,0);
411             paint_dot(work1,tw,th,x,y1,r,0);
412           }
413         }
414         y0-=spacing/2.;
415         y1+=spacing/2.;
416         rowflag = (rowflag+1)&1;
417       }
418
419       float *final = work1;
420       if(plugin->config.Fsel_active &&
421          (plugin->config.Fsel_lo || plugin->config.Fsel_hi || plugin->config.Fsel_over))
422         final=plugin->fill_selection(work1,work2,tw,th,NULL);
423
424       /* subsample into trough */
425       float *in = final + (tw+1)*trough_border;
426       for(y=0;y<troughlines;y++){
427         float *out = trough_alpha + troughcols*y;
428         for(x=0;x<troughcols;x++)
429           out[x] = (in[x*3]+in[x*3+1]+in[x*3+2]+
430                     in[tw+x*3]+in[tw+x*3+1]+in[x*3+2]+
431                     in[tw*2+x*3]+in[tw*2+x*3+1]+in[tw*2+x*3+2])*.1111;
432         in += tw*3;
433       }
434
435     }
436     recompute_trough_alpha=0;
437     BluebananaSliderFill::update();
438   }
439
440   float *trough_alpha;
441   int trough_border;
442   int recompute_trough_alpha;
443   int erode;
444 };
445
446 int BluebananaFSReadout0::value_event(){
447   float val = rint(get_value());
448   if(val<-FSrange)val=-FSrange;
449   if(val>0)val=0;
450   if(val>plugin->config.Fsel_mid) val = plugin->config.Fsel_mid;
451   plugin->config.Fsel_lo = val;
452   gui->Fsel_slider->update();
453   return 1;
454 }
455
456 int BluebananaFSReadout1::value_event(){
457   float val = rint(get_value());
458   if(val<-FSrange)val=-FSrange;
459   if(val>FSrange)val=FSrange;
460   if(val<plugin->config.Fsel_lo) plugin->config.Fsel_lo=val;
461   if(val>plugin->config.Fsel_hi) plugin->config.Fsel_hi=val;
462   plugin->config.Fsel_mid = val;
463   gui->Fsel_slider->update();
464   return 1;
465 }
466
467 int BluebananaFSReadout2::value_event(){
468   float val = rint(get_value());
469   if(val<0)val=0;
470   if(val>FSrange)val=FSrange;
471   if(val<plugin->config.Fsel_mid) val = plugin->config.Fsel_mid;
472   plugin->config.Fsel_hi = val;
473   gui->Fsel_slider->update();
474   return 1;
475 }
476
477 int BluebananaFSReadout3::value_event(){
478   float val = rint(get_value());
479   if(val<0)val=0;
480   if(val>FSovermax)val=FSovermax;
481   plugin->config.Fsel_over = val;
482   gui->Fsel_slider->update();
483   return 1;
484 }
485
486 // ------------------------------ value selection slider --------------------------------
487 class BluebananaVSReadout0 : public BB_Tumble {
488  public:
489   BluebananaVSReadout0(BluebananaMain *plugin, BluebananaWindow *gui, int w)
490     : BB_Tumble(plugin,gui,0.,0,100., 0,1,w){}
491   int value_event();
492 };
493 class BluebananaVSReadout1 : public BB_Tumble {
494  public:
495   BluebananaVSReadout1(BluebananaMain *plugin, BluebananaWindow *gui, int w)
496     : BB_Tumble(plugin,gui,0.,0,100., 0,1,w){}
497   int value_event();
498 };
499 class BluebananaVSReadout2 : public BB_Tumble {
500  public:
501   BluebananaVSReadout2(BluebananaMain *plugin, BluebananaWindow *gui, int w)
502     : BB_Tumble(plugin,gui,0.,0,100., 0,1,w){}
503   int value_event();
504 };
505
506 class BluebananaVSSlider : public BluebananaSliderBracket {
507 public:
508   BluebananaVSSlider(BluebananaMain *plugin, BluebananaWindow *gui,
509                      int x, int y, int w, int h)
510     : BluebananaSliderBracket(plugin,gui,x,y,w,h,0,100) { }
511   virtual int handle_event() {
512     plugin->config.Vsel_lo = rint(loval);
513     plugin->config.Vsel_hi = rint(hival);
514     plugin->config.Vsel_over = rint(overval);
515     return 1;
516   }
517   void pick(){
518     int delta = plugin->config.Vsel_hi - plugin->config.Vsel_lo;
519     float r = plugin->get_red();
520     float g = plugin->get_green();
521     float b = plugin->get_blue();
522     float h,s,v;
523     RGB_to_HSpV(r,g,b,h,s,v);
524     h*=60.f;
525     v=rint(v*100.f);
526     if(v<0)v=0;
527     if(v>100)v=100;
528     if(delta>25)delta=25;
529     int lo = v - delta/2;
530     int hi = lo + delta;
531     /* shrink the brackets if necessary */
532     if(lo<0){
533       lo=0;
534       if(hi-lo<10)hi=10;
535     }
536     if(hi>100){
537       hi=100;
538       if(hi-lo<10)lo=90;
539     }
540     plugin->config.Vsel_lo=lo;
541     plugin->config.Vsel_hi=hi;
542     plugin->config.Vsel_active=1;
543     gui->Vsel_active->update(); // this will also call the slider update
544   }
545   void update(){
546     loval = plugin->config.Vsel_lo;
547     hival = plugin->config.Vsel_hi;
548     midval = (loval+hival)/2.f;
549     overval = plugin->config.Vsel_over;
550     highlight = plugin->config.Vsel_active;
551
552     gui->Vsel_readout0->update(plugin->config.Vsel_lo);
553     gui->Vsel_readout1->update(plugin->config.Vsel_hi);
554     gui->Vsel_readout2->update(plugin->config.Vsel_over);
555     gui->slider_labels[2]->set_color
556       (highlight && (plugin->config.Vsel_lo != 0 || plugin->config.Vsel_hi != 100) ?
557        get_resources()->default_text_color : dimtextcolor);
558
559     gui->enter_config_change();
560     if(gui->Fsel_slider)gui->Fsel_slider->update();
561     gui->commit_config_change();
562   }
563   void trough_color(float hdel, float vdel, float &r, float &g, float &b, float &a){
564     float deg = plugin->config.Hsel_active ?
565       vdel*(plugin->config.Hsel_hi-plugin->config.Hsel_lo)+plugin->config.Hsel_lo :
566       vdel*360.f;
567     float sat = plugin->config.Ssel_active ?
568       (plugin->config.Ssel_hi*3+plugin->config.Ssel_lo)/400.:
569       .5;
570
571     if(deg>=360)deg-=360.f;
572     HSpV_to_RGB(deg/60.,sat,hdel,r,g,b);
573     a= plugin->val_select_alpha(hdel);
574   }
575 };
576
577 int BluebananaVSReadout0::value_event(){
578   float val = get_value();
579   if(val<0)val=0;
580   if(val>100)val=100;
581   if(val>plugin->config.Vsel_hi) val = plugin->config.Vsel_hi;
582   plugin->config.Vsel_lo = val;
583   gui->Vsel_slider->update();
584   return 1;
585 }
586
587 int BluebananaVSReadout1::value_event(){
588   float val = get_value();
589   if(val<0)val=0;
590   if(val>100)val=100;
591   if(val<plugin->config.Vsel_lo) val = plugin->config.Vsel_lo;
592   plugin->config.Vsel_hi = val;
593   gui->Vsel_slider->update();
594   return 1;
595 }
596
597 int BluebananaVSReadout2::value_event(){
598   float val = get_value();
599   if(val<0)val=0;
600   if(val>100)val=100;
601   plugin->config.Vsel_over = val;
602   gui->Vsel_slider->update();
603   return 1;
604 }
605
606 // ----------------------------- saturation selection slider -----------------------------
607 class BluebananaSSReadout0 : public BB_Tumble {
608  public:
609   BluebananaSSReadout0(BluebananaMain *plugin, BluebananaWindow *gui, int w)
610     : BB_Tumble(plugin,gui,0.,0,100., 0,1,w){}
611   int value_event();
612 };
613 class BluebananaSSReadout1 : public BB_Tumble {
614  public:
615   BluebananaSSReadout1(BluebananaMain *plugin, BluebananaWindow *gui, int w)
616     : BB_Tumble(plugin,gui,0.,0,100., 0,1,w){}
617   int value_event();
618 };
619 class BluebananaSSReadout2 : public BB_Tumble {
620  public:
621   BluebananaSSReadout2(BluebananaMain *plugin, BluebananaWindow *gui, int w)
622     : BB_Tumble(plugin,gui,0.,0,100., 0,1,w){}
623   int value_event();
624 };
625
626 class BluebananaSSSlider : public BluebananaSliderBracket {
627 public:
628   BluebananaSSSlider(BluebananaMain *plugin, BluebananaWindow *gui,
629                      int x, int y, int w, int h)
630     : BluebananaSliderBracket(plugin,gui,x,y,w,h,0,100) { }
631   int handle_event() {
632     plugin->config.Ssel_lo = rint(loval);
633     plugin->config.Ssel_hi = rint(hival);
634     plugin->config.Ssel_over = rint(overval);
635     return 1;
636   }
637   void pick(){
638     int delta = plugin->config.Ssel_hi - plugin->config.Ssel_lo;
639     float r = plugin->get_red();
640     float g = plugin->get_green();
641     float b = plugin->get_blue();
642     float h,s,v;
643     RGB_to_HSpV(r,g,b,h,s,v);
644     h*=60.f;
645     s=rint(s*100.f);
646     if(s<0)s=0;
647     if(s>100)s=100;
648     if(delta>25)delta=25;
649     int lo = s - delta/2;
650     int hi = lo + delta;
651     /* shrink the brackets if necessary */
652     if(lo<0){
653       lo=0;
654       if(hi-lo<10)hi=10;
655     }
656     if(hi>100){
657       hi=100;
658       if(hi-lo<10)lo=90;
659     }
660     plugin->config.Ssel_lo=lo;
661     plugin->config.Ssel_hi=hi;
662     plugin->config.Ssel_active=1;
663     gui->Ssel_active->update(); // this will also call the slider update
664   }
665   void update(){
666     loval = plugin->config.Ssel_lo;
667     hival = plugin->config.Ssel_hi;
668     midval = (loval+hival)/2.f;
669     overval = plugin->config.Ssel_over;
670     highlight = plugin->config.Ssel_active;
671
672     gui->Ssel_readout0->update(plugin->config.Ssel_lo);
673     gui->Ssel_readout1->update(plugin->config.Ssel_hi);
674     gui->Ssel_readout2->update(plugin->config.Ssel_over);
675     gui->slider_labels[1]->set_color(highlight  &&
676                                      (plugin->config.Ssel_lo != 0 || plugin->config.Ssel_hi != 100) ?
677                                      get_resources()->default_text_color : dimtextcolor);
678
679     gui->enter_config_change();
680     if(gui->Fsel_slider)gui->Fsel_slider->update();
681     gui->commit_config_change();
682   }
683   void trough_color(float hdel, float vdel, float &r, float &g, float &b, float &a){
684     float deg = plugin->config.Hsel_active ?
685       vdel*(plugin->config.Hsel_hi-plugin->config.Hsel_lo)+plugin->config.Hsel_lo :
686       vdel*360.;
687     if(deg>=360)deg-=360.f;
688     HSpV_to_RGB(deg/60.f,hdel,.7+.3*hdel,r,g,b);
689     a = plugin->sat_select_alpha(hdel);
690   }
691 };
692
693 int BluebananaSSReadout0::value_event(){
694   float val = get_value();
695   if(val<0)val=0;
696   if(val>100)val=100;
697   if(val>plugin->config.Ssel_hi) val = plugin->config.Ssel_hi;
698   plugin->config.Ssel_lo = val;
699   gui->Ssel_slider->update();
700   return 1;
701 }
702
703 int BluebananaSSReadout1::value_event(){
704   float val = get_value();
705   if(val<0)val=0;
706   if(val>100)val=100;
707   if(val<plugin->config.Ssel_lo) val = plugin->config.Ssel_lo;
708   plugin->config.Ssel_hi = val;
709   gui->Ssel_slider->update();
710   return 1;
711 }
712
713 int BluebananaSSReadout2::value_event(){
714   float val = get_value();
715   if(val<0)val=0;
716   if(val>100)val=100;
717   plugin->config.Ssel_over = val;
718   gui->Ssel_slider->update();
719   return 1;
720 }
721
722 // ----------------------------- hue selection slider ---------------------------------
723 class BluebananaHSReadout0 : public BB_Tumble {
724  public:
725   BluebananaHSReadout0(BluebananaMain *plugin, BluebananaWindow *gui, int w)
726     : BB_Tumble(plugin,gui,0.,0,360., 0,1,w){}
727   int value_event();
728 };
729 class BluebananaHSReadout1 : public BB_Tumble {
730  public:
731   BluebananaHSReadout1(BluebananaMain *plugin, BluebananaWindow *gui, int w)
732     : BB_Tumble(plugin,gui,0.,0,360., 0,1,w){}
733   int value_event();
734 };
735 class BluebananaHSReadout2 : public BB_Tumble {
736  public:
737   BluebananaHSReadout2(BluebananaMain *plugin, BluebananaWindow *gui, int w)
738     : BB_Tumble(plugin,gui,0.,360.,360., 0,1,w){}
739   int value_event();
740 };
741
742 class BluebananaHSSlider : public BluebananaSliderCircular {
743 public:
744   BluebananaHSSlider(BluebananaMain *plugin, BluebananaWindow *gui,
745                      int x, int y, int w, int h)
746     : BluebananaSliderCircular(plugin,gui,x,y,w,h,0,360) {
747   }
748   int handle_event() {
749     plugin->config.Hsel_lo = rint(loval);
750     plugin->config.Hsel_hi = plugin->config.Hsel_lo +
751       (midval<loval ? rint(midval*2-loval*2+720) : rint(midval*2-loval*2));
752     plugin->config.Hsel_over = rint(overval);
753     return 1;
754   }
755   void pick(){
756     int delta = plugin->config.Hsel_hi - plugin->config.Hsel_lo;
757     float r = plugin->get_red();
758     float g = plugin->get_green();
759     float b = plugin->get_blue();
760     float h,s,v;
761     RGB_to_HSpV(r,g,b,h,s,v);
762     h=rint(h*60.f);
763     if(h<0)h=0;
764     if(h>360)h=360;
765     if(delta>30)delta=30;
766     int lo = h - delta/2;
767     int hi = lo + delta;
768     if(lo<0){
769       lo+=360;
770       hi+=360;
771     }
772     plugin->config.Hsel_lo=lo;
773     plugin->config.Hsel_hi=hi;
774     plugin->config.Hsel_active=1;
775     gui->Hsel_active->update(); // this will also call the slider update
776   }
777   void update(){
778     // Significantly more complex than the other sliders due to the
779     // circular scale.
780     //float delta = (plugin->config.Hsel_hi - plugin->config.Hsel_lo);
781     loval = plugin->config.Hsel_lo;
782     overval = plugin->config.Hsel_over;
783     float newhival = plugin->config.Hsel_hi;
784     float newmidval = (loval+newhival)/2.;
785     if(loval<0)loval+=360.;
786     if(loval>360.)loval-=360.;
787     if(newmidval<0)newmidval+=360.;
788     if(newmidval>360.)newmidval-=360.;
789     if(newhival<0)newhival+=360.;
790     if(newhival>360.)newhival-=360.;
791     highlight = plugin->config.Hsel_active;
792
793     float checkhi = plugin->config.Hsel_hi;
794     if(checkhi>360)checkhi-=360;
795
796     // one last weirdness; 0 and 360 are technically the same value on
797     // the circular scale, but the user can set either.  This isn't a
798     // problem with lo as it doesn't wrap, but mid/hi is computed for
799     // the slider and could end up at 0 or 360, and then clobber the
800     // slider/readout.  To avoid annoying the user, don't override an
801     // existing readout/slider setting with its equivalent.
802     if(newhival==0 && hival==360.){
803       newhival=360.;
804       checkhi=360;
805     }else if(newhival==360 && hival==0.){
806       newhival=0.;
807       checkhi=0;
808     }else if(checkhi==0 && gui->Hsel_readout2->get_value()==360){
809       newhival=360.;
810       checkhi=360;
811     }else if(checkhi==360 && gui->Hsel_readout2->get_value()==0){
812       newhival=0.;
813       checkhi=0;
814     }
815
816     if(newmidval<1 && midval>359){
817       newmidval=360.;
818     }else if(newmidval>359.f && midval<1.){
819       newmidval=0.;
820     }
821     midval=newmidval;
822     hival=newhival;
823
824     gui->Hsel_readout0->update(plugin->config.Hsel_lo);
825     gui->Hsel_readout1->update(checkhi);
826     gui->Hsel_readout2->update(plugin->config.Hsel_over);
827     gui->slider_labels[0]->set_color(highlight &&
828                                      (plugin->config.Hsel_hi - plugin->config.Hsel_lo != 360) ?
829                                      get_resources()->default_text_color : dimtextcolor);
830
831     gui->enter_config_change();
832     if(gui->Fsel_slider)gui->Fsel_slider->update();
833     gui->commit_config_change();
834   }
835   void trough_color(float hdel, float vdel, float &r, float &g, float &b, float &a){
836     float deg = hdel*360.f;
837     if(deg>=360)deg-=360.f;
838
839     HSpV_to_RGB(deg/60.f,1.f,1.f,r,g,b);
840     a = plugin->hue_select_alpha(hdel*360.f);
841   }
842   friend class BluebananaHSReadout1;
843   friend class BluebananaHSReadout2;
844 };
845
846 int BluebananaHSReadout0::value_event(){
847   plugin->config.Hsel_lo = get_value();
848   if(plugin->config.Hsel_lo<0)plugin->config.Hsel_lo=0;
849   if(plugin->config.Hsel_lo>360)plugin->config.Hsel_lo=360;
850   if(plugin->config.Hsel_hi - plugin->config.Hsel_lo > 360)
851     plugin->config.Hsel_hi-=360;
852   if(plugin->config.Hsel_lo > plugin->config.Hsel_hi)
853     plugin->config.Hsel_hi+=360;
854   gui->Hsel_slider->update();
855   return 1;
856 }
857
858 int BluebananaHSReadout1::value_event(){
859   plugin->config.Hsel_hi = get_value();
860   if(plugin->config.Hsel_hi<0)plugin->config.Hsel_hi=0;
861   if(plugin->config.Hsel_hi>360)plugin->config.Hsel_hi=360;
862   if(plugin->config.Hsel_lo > plugin->config.Hsel_hi)
863     plugin->config.Hsel_hi+=360;
864   gui->Hsel_slider->hival=-1; /* force update to hival, not the hi readout */
865   gui->Hsel_slider->update();
866   return 1;
867 }
868
869 int BluebananaHSReadout2::value_event(){
870   float val = get_value();
871   if(val<0)val=0;
872   if(val>360)val=360;
873   plugin->config.Hsel_over=val;
874   gui->Hsel_slider->update();
875   return 1;
876 }
877
878 // ---------------------------- saturation adjustment slider ----------------------------
879 class BluebananaSAReadout0 : public BB_Tumble {
880  public:
881   BluebananaSAReadout0(BluebananaMain *plugin, BluebananaWindow *gui, int w)
882     : BB_Tumble(plugin,gui,-100,0,100., 0,1,w){}
883   int value_event();
884 };
885 class BluebananaSAReadout1 : public BB_Tumble {
886  public:
887   BluebananaSAReadout1(BluebananaMain *plugin, BluebananaWindow *gui, int w)
888     : BB_Tumble(plugin,gui,0.,0,200., 0,1,w){}
889   int value_event();
890 };
891 class BluebananaSAReadout2 : public BB_Tumble {
892  public:
893   BluebananaSAReadout2(BluebananaMain *plugin, BluebananaWindow *gui, int w)
894     : BB_Tumble(plugin,gui,MIN_GAMMA,0,MAX_GAMMA,2,.01,w){}
895   int value_event();
896 };
897
898 class BluebananaSASlider : public BluebananaSliderChannel {
899 public:
900   BluebananaSASlider(BluebananaMain *plugin, BluebananaWindow *gui,
901                      int x, int y, int w, int h)
902     : BluebananaSliderChannel(plugin,gui,x,y,w,h) { }
903   virtual int handle_event() {
904     plugin->config.Sadj_lo = loval;
905     plugin->config.Sadj_hi = hival;
906     plugin->config.Sadj_gamma = gamma;
907     return 1;
908   }
909   void reset(){
910     plugin->config.Sadj_lo=0.;
911     plugin->config.Sadj_hi=100.;
912     plugin->config.Sadj_gamma=1.;
913     update();
914   }
915   void update(){
916     loval = plugin->config.Sadj_lo;
917     hival = plugin->config.Sadj_hi;
918     gamma = plugin->config.Sadj_gamma;
919
920     highlight = plugin->config.active && plugin->config.Sadj_active;
921
922     gui->Sadj_readout0->update(plugin->config.Sadj_lo);
923     gui->Sadj_readout1->update(plugin->config.Sadj_hi);
924     gui->Sadj_readout2->update(plugin->config.Sadj_gamma);
925     gui->slider_labels[8]->set_color(highlight &&
926                                      (plugin->config.Sadj_lo != 0 ||
927                                       plugin->config.Sadj_hi != 100 ||
928                                       plugin->config.Sadj_gamma != 1.) ?
929                                      get_resources()->default_text_color : dimtextcolor);
930
931     gui->enter_config_change();
932     gui->commit_config_change();
933   }
934   void trough_color(float hdel, float &r, float &g, float &b){
935     r=g=b=0;
936   }
937 };
938
939 #define BBCLAMP(x,y,z) ((x)<(y) ? (y) : (x)>(z) ? (z) : (x))
940
941 int BluebananaSAReadout0::value_event(){
942   plugin->config.Sadj_lo = BBCLAMP(get_value(),-100,plugin->config.Sadj_hi);
943   plugin->config.Sadj_lo = BBCLAMP(get_value(),-100,100);
944   gui->Sadj_slider->update();
945   return 1;
946 }
947 int BluebananaSAReadout1::value_event(){
948   plugin->config.Sadj_hi = BBCLAMP(get_value(),plugin->config.Sadj_lo,200);
949   plugin->config.Sadj_hi = BBCLAMP(get_value(),0,200);
950   gui->Sadj_slider->update();
951   return 1;
952 }
953 int BluebananaSAReadout2::value_event(){
954   plugin->config.Sadj_gamma = BBCLAMP(get_value(),MIN_GAMMA,MAX_GAMMA);
955   gui->Sadj_slider->update();
956   return 1;
957 }
958
959 // ------------------------------- value adjustment slider -------------------------------
960 class BluebananaVAReadout0 : public BB_Tumble {
961  public:
962   BluebananaVAReadout0(BluebananaMain *plugin, BluebananaWindow *gui, int w)
963     : BB_Tumble(plugin,gui,-100.,0,100., 0,1,w){}
964   int value_event();
965 };
966 class BluebananaVAReadout1 : public BB_Tumble {
967  public:
968   BluebananaVAReadout1(BluebananaMain *plugin, BluebananaWindow *gui, int w)
969     : BB_Tumble(plugin,gui,0.,0,200., 0,1,w){}
970   int value_event();
971 };
972 class BluebananaVAReadout2 : public BB_Tumble {
973  public:
974   BluebananaVAReadout2(BluebananaMain *plugin, BluebananaWindow *gui, int w)
975     : BB_Tumble(plugin,gui,MIN_GAMMA,0,MAX_GAMMA,2,.01,w){}
976   int value_event();
977 };
978
979 class BluebananaVASlider : public BluebananaSliderChannel {
980 public:
981   BluebananaVASlider(BluebananaMain *plugin, BluebananaWindow *gui,
982                      int x, int y, int w, int h)
983     : BluebananaSliderChannel(plugin,gui,x,y,w,h) { }
984   virtual int handle_event() {
985     plugin->config.Vadj_lo = loval;
986     plugin->config.Vadj_hi = hival;
987     plugin->config.Vadj_gamma = gamma;
988     return 1;
989   }
990   void reset(){
991     plugin->config.Vadj_lo=0;
992     plugin->config.Vadj_hi=100;
993     plugin->config.Vadj_gamma=1;
994     update();
995   }
996   void update(){
997     loval = plugin->config.Vadj_lo;
998     hival = plugin->config.Vadj_hi;
999     gamma = plugin->config.Vadj_gamma;
1000
1001     highlight = plugin->config.active && plugin->config.Vadj_active;
1002
1003     gui->Vadj_readout0->update(plugin->config.Vadj_lo);
1004     gui->Vadj_readout1->update(plugin->config.Vadj_hi);
1005     gui->Vadj_readout2->update(plugin->config.Vadj_gamma);
1006     gui->slider_labels[9]->set_color(highlight  &&
1007                                      (plugin->config.Vadj_lo != 0.f ||
1008                                       plugin->config.Vadj_hi != 100.f ||
1009                                       plugin->config.Vadj_gamma != 1.f) ?
1010                                      get_resources()->default_text_color : dimtextcolor);
1011
1012     gui->enter_config_change();
1013     gui->commit_config_change();
1014   }
1015   void trough_color(float hdel, float &r, float &g, float &b){
1016     r=g=b=0;
1017   }
1018 };
1019
1020 int BluebananaVAReadout0::value_event(){
1021   plugin->config.Vadj_lo = BBCLAMP(get_value(),-100,plugin->config.Vadj_hi);
1022   plugin->config.Vadj_lo = BBCLAMP(get_value(),-100,100);
1023   gui->Vadj_slider->update();
1024   return 1;
1025 }
1026 int BluebananaVAReadout1::value_event(){
1027   plugin->config.Vadj_hi = BBCLAMP(get_value(),plugin->config.Vadj_lo,200);
1028   plugin->config.Vadj_hi = BBCLAMP(get_value(),0,200);
1029   gui->Vadj_slider->update();
1030   return 1;
1031 }
1032 int BluebananaVAReadout2::value_event(){
1033   plugin->config.Vadj_gamma = BBCLAMP(get_value(),MIN_GAMMA,MAX_GAMMA);
1034   gui->Vadj_slider->update();
1035   return 1;
1036 }
1037
1038 // -------------------------------- red adjustment slider --------------------------------
1039 class BluebananaRAReadout0 : public BB_Tumble {
1040  public:
1041   BluebananaRAReadout0(BluebananaMain *plugin, BluebananaWindow *gui, int w)
1042     : BB_Tumble(plugin,gui,-100.,0,100., 0,1,w){}
1043   int value_event();
1044 };
1045 class BluebananaRAReadout1 : public BB_Tumble {
1046  public:
1047   BluebananaRAReadout1(BluebananaMain *plugin, BluebananaWindow *gui, int w)
1048     : BB_Tumble(plugin,gui,0.,0,200., 0,1,w){}
1049   int value_event();
1050 };
1051 class BluebananaRAReadout2 : public BB_Tumble {
1052  public:
1053   BluebananaRAReadout2(BluebananaMain *plugin, BluebananaWindow *gui, int w)
1054     : BB_Tumble(plugin,gui,MIN_GAMMA,0,MAX_GAMMA,2,.01,w){}
1055   int value_event();
1056 };
1057
1058 class BluebananaRASlider : public BluebananaSliderChannel {
1059 public:
1060   BluebananaRASlider(BluebananaMain *plugin, BluebananaWindow *gui,
1061                      int x, int y, int w, int h)
1062     : BluebananaSliderChannel(plugin,gui,x,y,w,h) { }
1063   virtual int handle_event() {
1064     plugin->config.Radj_lo = loval;
1065     plugin->config.Radj_hi = hival;
1066     plugin->config.Radj_gamma = gamma;
1067     return 1;
1068   }
1069   void reset(){
1070     plugin->config.Radj_lo=0;
1071     plugin->config.Radj_hi=100;
1072     plugin->config.Radj_gamma=1;
1073     update();
1074   }
1075   void update(){
1076     loval = plugin->config.Radj_lo;
1077     hival = plugin->config.Radj_hi;
1078     gamma = plugin->config.Radj_gamma;
1079
1080     highlight = plugin->config.active && plugin->config.Radj_active;
1081
1082     gui->Radj_readout0->update(plugin->config.Radj_lo);
1083     gui->Radj_readout1->update(plugin->config.Radj_hi);
1084     gui->Radj_readout2->update(plugin->config.Radj_gamma);
1085     gui->slider_labels[4]->set_color(highlight  &&
1086                                      (plugin->config.Radj_lo != 0 ||
1087                                       plugin->config.Radj_hi != 100 ||
1088                                       plugin->config.Radj_gamma != 1) ?
1089                                      get_resources()->default_text_color : dimtextcolor);
1090
1091     gui->enter_config_change();
1092     gui->commit_config_change();
1093   }
1094   void trough_color(float hdel, float &r, float &g, float &b){
1095     if(hdel<0){
1096       r=g=b=0.;
1097     }else if(hdel<=1.f){
1098       r=hdel;
1099       g=b=0.;
1100     }else{
1101       r=1.;
1102       g=b=0.;
1103     }
1104   }
1105 };
1106
1107 int BluebananaRAReadout0::value_event(){
1108   plugin->config.Radj_lo = BBCLAMP(get_value(),-100,plugin->config.Radj_hi);
1109   plugin->config.Radj_lo = BBCLAMP(get_value(),-100,100);
1110   gui->Radj_slider->update();
1111   return 1;
1112 }
1113 int BluebananaRAReadout1::value_event(){
1114   plugin->config.Radj_hi = BBCLAMP(get_value(),plugin->config.Radj_lo,200);
1115   plugin->config.Radj_hi = BBCLAMP(get_value(),0,200);
1116   gui->Radj_slider->update();
1117   return 1;
1118 }
1119 int BluebananaRAReadout2::value_event(){
1120   plugin->config.Radj_gamma = BBCLAMP(get_value(),MIN_GAMMA,MAX_GAMMA);
1121   gui->Radj_slider->update();
1122   return 1;
1123 }
1124
1125 // ---------------------------- green adjustment slider ----------------------------
1126 class BluebananaGAReadout0 : public BB_Tumble {
1127  public:
1128   BluebananaGAReadout0(BluebananaMain *plugin, BluebananaWindow *gui, int w)
1129     : BB_Tumble(plugin,gui,-100.,0,100., 0,1,w){}
1130   int value_event();
1131 };
1132 class BluebananaGAReadout1 : public BB_Tumble {
1133  public:
1134   BluebananaGAReadout1(BluebananaMain *plugin, BluebananaWindow *gui, int w)
1135     : BB_Tumble(plugin,gui,0.,0,200., 0,1,w){}
1136   int value_event();
1137 };
1138 class BluebananaGAReadout2 : public BB_Tumble {
1139  public:
1140   BluebananaGAReadout2(BluebananaMain *plugin, BluebananaWindow *gui, int w)
1141     : BB_Tumble(plugin,gui,MIN_GAMMA,0,MAX_GAMMA,2,.01,w){}
1142   int value_event();
1143 };
1144
1145 class BluebananaGASlider : public BluebananaSliderChannel {
1146 public:
1147   BluebananaGASlider(BluebananaMain *plugin, BluebananaWindow *gui,
1148                      int x, int y, int w, int h)
1149     : BluebananaSliderChannel(plugin,gui,x,y,w,h) { }
1150   virtual int handle_event() {
1151     plugin->config.Gadj_lo = loval;
1152     plugin->config.Gadj_hi = hival;
1153     plugin->config.Gadj_gamma = gamma;
1154     return 1;
1155   }
1156   void reset(){
1157     plugin->config.Gadj_lo=0;
1158     plugin->config.Gadj_hi=100;
1159     plugin->config.Gadj_gamma=1;
1160     update();
1161   }
1162   void update(){
1163     loval = plugin->config.Gadj_lo;
1164     hival = plugin->config.Gadj_hi;
1165     gamma = plugin->config.Gadj_gamma;
1166
1167     highlight = plugin->config.active && plugin->config.Gadj_active;
1168
1169     gui->Gadj_readout0->update(plugin->config.Gadj_lo);
1170     gui->Gadj_readout1->update(plugin->config.Gadj_hi);
1171     gui->Gadj_readout2->update(plugin->config.Gadj_gamma);
1172     gui->slider_labels[5]->set_color(highlight  &&
1173                                      (plugin->config.Gadj_lo != 0 ||
1174                                       plugin->config.Gadj_hi != 100 ||
1175                                       plugin->config.Gadj_gamma != 1) ?
1176                                      get_resources()->default_text_color : dimtextcolor);
1177
1178     gui->enter_config_change();
1179     gui->commit_config_change();
1180   }
1181   void trough_color(float hdel, float &r, float &g, float &b){
1182     if(hdel<0){
1183       r=g=b=0.;
1184     }else if(hdel<=1.f){
1185       g=hdel;
1186       r=b=0.;
1187     }else{
1188       g=1.;
1189       r=b=0.;
1190     }
1191   }
1192 };
1193
1194 int BluebananaGAReadout0::value_event(){
1195   plugin->config.Gadj_lo = BBCLAMP(get_value(),-100,plugin->config.Gadj_hi);
1196   plugin->config.Gadj_lo = BBCLAMP(get_value(),-100,100);
1197   gui->Gadj_slider->update();
1198   return 1;
1199 }
1200 int BluebananaGAReadout1::value_event(){
1201   plugin->config.Gadj_hi = BBCLAMP(get_value(),plugin->config.Gadj_lo,200);
1202   plugin->config.Gadj_hi = BBCLAMP(get_value(),0,200);
1203   gui->Gadj_slider->update();
1204   return 1;
1205 }
1206 int BluebananaGAReadout2::value_event(){
1207   plugin->config.Gadj_gamma = BBCLAMP(get_value(),MIN_GAMMA,MAX_GAMMA);
1208   gui->Gadj_slider->update();
1209   return 1;
1210 }
1211
1212 // ------------------------------- blue adjustment slider -------------------------------
1213 class BluebananaBAReadout0 : public BB_Tumble {
1214  public:
1215   BluebananaBAReadout0(BluebananaMain *plugin, BluebananaWindow *gui, int w)
1216     : BB_Tumble(plugin,gui,-100.,0,100., 0,1,w){}
1217   int value_event();
1218 };
1219 class BluebananaBAReadout1 : public BB_Tumble {
1220  public:
1221   BluebananaBAReadout1(BluebananaMain *plugin, BluebananaWindow *gui, int w)
1222     : BB_Tumble(plugin,gui,0.,0,200., 0,1,w){}
1223   int value_event();
1224 };
1225 class BluebananaBAReadout2 : public BB_Tumble {
1226  public:
1227   BluebananaBAReadout2(BluebananaMain *plugin, BluebananaWindow *gui, int w)
1228     : BB_Tumble(plugin,gui,MIN_GAMMA,0,MAX_GAMMA,2,.01,w){}
1229   int value_event();
1230 };
1231
1232 class BluebananaBASlider : public BluebananaSliderChannel {
1233 public:
1234   BluebananaBASlider(BluebananaMain *plugin, BluebananaWindow *gui,
1235                      int x, int y, int w, int h)
1236     : BluebananaSliderChannel(plugin,gui,x,y,w,h) { }
1237   virtual int handle_event() {
1238     plugin->config.Badj_lo = loval;
1239     plugin->config.Badj_hi = hival;
1240     plugin->config.Badj_gamma = gamma;
1241     return 1;
1242   }
1243   void reset(){
1244     plugin->config.Badj_lo=0;
1245     plugin->config.Badj_hi=100;
1246     plugin->config.Badj_gamma=1;
1247     update();
1248   }
1249   void update(){
1250     loval = plugin->config.Badj_lo;
1251     hival = plugin->config.Badj_hi;
1252     gamma = plugin->config.Badj_gamma;
1253
1254     highlight = plugin->config.active && plugin->config.Badj_active;
1255
1256     gui->Badj_readout0->update(plugin->config.Badj_lo);
1257     gui->Badj_readout1->update(plugin->config.Badj_hi);
1258     gui->Badj_readout2->update(plugin->config.Badj_gamma);
1259     gui->slider_labels[6]->set_color(highlight  &&
1260                                      (plugin->config.Badj_lo != 0 ||
1261                                       plugin->config.Badj_hi != 100 ||
1262                                       plugin->config.Badj_gamma != 1) ?
1263                                      get_resources()->default_text_color : dimtextcolor);
1264
1265     gui->enter_config_change();
1266     gui->commit_config_change();
1267   }
1268   void trough_color(float hdel, float &r, float &g, float &b){
1269     if(hdel<0){
1270       r=g=b=0.;
1271     }else if(hdel<=1.f){
1272       b=hdel;
1273       g=r=0.;
1274     }else{
1275       b=1.;
1276       g=r=0.;
1277     }
1278   }
1279 };
1280
1281 int BluebananaBAReadout0::value_event(){
1282   plugin->config.Badj_lo = BBCLAMP(get_value(),-100,plugin->config.Badj_hi);
1283   plugin->config.Badj_lo = BBCLAMP(get_value(),-100,100);
1284   gui->Badj_slider->update();
1285   return 1;
1286 }
1287 int BluebananaBAReadout1::value_event(){
1288   plugin->config.Badj_hi = BBCLAMP(get_value(),plugin->config.Badj_lo,200);
1289   plugin->config.Badj_hi = BBCLAMP(get_value(),0,200);
1290   gui->Badj_slider->update();
1291   return 1;
1292 }
1293 int BluebananaBAReadout2::value_event(){
1294   plugin->config.Badj_gamma = BBCLAMP(get_value(),MIN_GAMMA,MAX_GAMMA);
1295   gui->Badj_slider->update();
1296   return 1;
1297 }
1298
1299 // ---------------------------------- opacity slider ---------------------------------
1300 class BluebananaOAReadout : public BB_Tumble {
1301  public:
1302   BluebananaOAReadout(BluebananaMain *plugin, BluebananaWindow *gui, int w)
1303     : BB_Tumble(plugin,gui,0.,0,100., 0,1,w){}
1304   int value_event();
1305 };
1306
1307 class BluebananaOASlider : public BluebananaSliderSingle {
1308 public:
1309   BluebananaOASlider(BluebananaMain *plugin, BluebananaWindow *gui,
1310                      int x, int y, int w, int h)
1311     : BluebananaSliderSingle(plugin,gui,x,y,w,h,0,100) { }
1312   virtual int handle_event() {
1313     plugin->config.Oadj_val = val;
1314     return 1;
1315   }
1316   void reset(){
1317     plugin->config.Oadj_val=100;
1318     update();
1319   }
1320   void update(){
1321     val = plugin->config.Oadj_val;
1322     highlight = plugin->config.active && plugin->config.Oadj_active;
1323     gui->Oadj_readout->update(plugin->config.Oadj_val);
1324     gui->slider_labels[10]->set_color(highlight  &&
1325                                       plugin->config.Oadj_val != 100 ?
1326                                       get_resources()->default_text_color : dimtextcolor);
1327     gui->enter_config_change();
1328     gui->commit_config_change();
1329   }
1330   void trough_color(float hdel, float vdel, float &r, float &g, float &b, float &a){
1331     r=g=b=.8;
1332     a=1-cos(hdel*M_PI*.5);
1333   }
1334 };
1335
1336 int BluebananaOAReadout::value_event(){
1337   float val = get_value();
1338   plugin->config.Oadj_val = val;
1339   gui->Oadj_slider->update();
1340   return 1;
1341 }
1342
1343 // ------------------------------------- picker buttons -----------------------------------------
1344 class BluebananaHPicker : public BC_GenericButton{
1345  public:
1346   BluebananaHPicker(BluebananaWindow *gui, int w) : BC_GenericButton(-1, -1, w, _("Pick")){
1347     this->gui = gui;
1348   }
1349   int handle_event() { gui->Hsel_slider->pick(); return 1; }
1350   BluebananaWindow *gui;
1351 };
1352 class BluebananaSPicker : public BC_GenericButton{
1353  public:
1354   BluebananaSPicker(BluebananaWindow *gui, int w) : BC_GenericButton(-1, -1, w, _("Pick")){
1355     this->gui = gui;
1356   }
1357   int handle_event() { gui->Ssel_slider->pick(); return 1; }
1358   BluebananaWindow *gui;
1359 };
1360 class BluebananaVPicker : public BC_GenericButton{
1361  public:
1362   BluebananaVPicker(BluebananaWindow *gui, int w) : BC_GenericButton(-1, -1, w, _("Pick")){
1363     this->gui = gui;
1364   }
1365   int handle_event() { gui->Vsel_slider->pick(); return 1; }
1366   BluebananaWindow *gui;
1367 };
1368
1369 // -------------------------------------- reset buttons -----------------------------------------
1370
1371 class BluebananaHAReset : public BC_GenericButton{
1372  public:
1373   BluebananaHAReset(BluebananaWindow *gui, int w) : BC_GenericButton(-1, -1, w, _("Reset")){
1374     this->gui = gui;
1375   }
1376   int handle_event() { gui->Hadj_slider->reset(); return 1;}
1377   BluebananaWindow *gui;
1378 };
1379 class BluebananaSAReset : public BC_GenericButton{
1380  public:
1381   BluebananaSAReset(BluebananaWindow *gui, int w) : BC_GenericButton(-1, -1, w, _("Reset")){
1382     this->gui = gui;
1383   }
1384   int handle_event() { gui->Sadj_slider->reset(); return 1;}
1385   BluebananaWindow *gui;
1386 };
1387 class BluebananaVAReset : public BC_GenericButton{
1388  public:
1389   BluebananaVAReset(BluebananaWindow *gui, int w) : BC_GenericButton(-1, -1, w, _("Reset")){
1390     this->gui = gui;
1391   }
1392   int handle_event() { gui->Vadj_slider->reset(); return 1;}
1393   BluebananaWindow *gui;
1394 };
1395 class BluebananaRAReset : public BC_GenericButton{
1396  public:
1397   BluebananaRAReset(BluebananaWindow *gui, int w) : BC_GenericButton(-1, -1, w, _("Reset")){
1398     this->gui = gui;
1399   }
1400   int handle_event() { gui->Radj_slider->reset(); return 1;}
1401   BluebananaWindow *gui;
1402 };
1403 class BluebananaGAReset : public BC_GenericButton{
1404  public:
1405   BluebananaGAReset(BluebananaWindow *gui, int w) : BC_GenericButton(-1, -1, w, _("Reset")){
1406     this->gui = gui;
1407   }
1408   int handle_event() { gui->Gadj_slider->reset(); return 1;}
1409   BluebananaWindow *gui;
1410 };
1411 class BluebananaBAReset : public BC_GenericButton{
1412  public:
1413   BluebananaBAReset(BluebananaWindow *gui, int w) : BC_GenericButton(-1, -1, w, _("Reset")){
1414     this->gui = gui;
1415   }
1416   int handle_event() { gui->Badj_slider->reset(); return 1;}
1417   BluebananaWindow *gui;
1418 };
1419 class BluebananaOAReset : public BC_GenericButton{
1420  public:
1421   BluebananaOAReset(BluebananaWindow *gui, int w) : BC_GenericButton(-1, -1, w, _("Reset")){
1422     this->gui = gui;
1423   }
1424   int handle_event() { gui->Oadj_slider->reset(); return 1;}
1425   BluebananaWindow *gui;
1426 };
1427
1428 // ----------------------------------- slider active buttons ------------------------------------
1429
1430 BluebananaHActive::BluebananaHActive(BluebananaMain *plugin, BluebananaWindow *gui)
1431   : BC_CheckBox(-1, -1, &plugin->config.Hsel_active, ""){
1432   this->plugin = plugin;
1433   this->gui = gui;
1434 }
1435 int BluebananaHActive::handle_event(){
1436   plugin->config.Hsel_active = get_value();
1437   update();
1438   return 1;
1439 }
1440 void BluebananaHActive::update(){
1441   this->BC_CheckBox::update(plugin->config.Hsel_active,1);
1442   gui->Hsel_slider->update();
1443 }
1444
1445 BluebananaSActive::BluebananaSActive(BluebananaMain *plugin, BluebananaWindow *gui)
1446   : BC_CheckBox(-1, -1, &plugin->config.Ssel_active, ""){
1447   this->plugin = plugin;
1448   this->gui = gui;
1449 }
1450 int BluebananaSActive::handle_event(){
1451   plugin->config.Ssel_active = get_value();
1452   update();
1453   return 1;
1454 }
1455 void BluebananaSActive::update(){
1456   this->BC_CheckBox::update(plugin->config.Ssel_active,1);
1457   gui->Ssel_slider->update();
1458 }
1459
1460 BluebananaVActive::BluebananaVActive(BluebananaMain *plugin, BluebananaWindow *gui)
1461   : BC_CheckBox(-1, -1, &plugin->config.Vsel_active, ""){
1462   this->plugin = plugin;
1463   this->gui = gui;
1464 }
1465 int BluebananaVActive::handle_event(){
1466   plugin->config.Vsel_active = get_value();
1467   update();
1468   return 1;
1469 }
1470 void BluebananaVActive::update(){
1471   this->BC_CheckBox::update(plugin->config.Vsel_active,1);
1472   gui->Vsel_slider->update();
1473 }
1474
1475 class BluebananaFActive : public BC_CheckBox {
1476 public:
1477   BluebananaFActive(BluebananaMain *plugin, BluebananaWindow *gui)
1478   : BC_CheckBox(-1, -1, &plugin->config.Fsel_active, ""){
1479     this->plugin = plugin;
1480     this->gui = gui;
1481   }
1482   virtual int handle_event(){
1483     plugin->config.Fsel_active = get_value();
1484     update();
1485     return 1;
1486   }
1487   void update(){
1488     this->BC_CheckBox::update(plugin->config.Fsel_active,1);
1489     gui->Fsel_slider->update();
1490   }
1491   BluebananaMain *plugin;
1492   BluebananaWindow *gui;
1493 };
1494
1495 class BluebananaHAActive : public BC_CheckBox {
1496 public:
1497   BluebananaHAActive(BluebananaMain *plugin, BluebananaWindow *gui)
1498   : BC_CheckBox(-1, -1, &plugin->config.Hadj_active, ""){
1499     this->plugin = plugin;
1500     this->gui = gui;
1501   }
1502   virtual int handle_event(){
1503     plugin->config.Hadj_active = get_value();
1504     update();
1505     return 1;
1506   }
1507   void update(){
1508     this->BC_CheckBox::update(plugin->config.Hadj_active,1);
1509     gui->Hadj_slider->update();
1510   }
1511   BluebananaMain *plugin;
1512   BluebananaWindow *gui;
1513 };
1514
1515 class BluebananaSAActive : public BC_CheckBox {
1516 public:
1517   BluebananaSAActive(BluebananaMain *plugin, BluebananaWindow *gui)
1518   : BC_CheckBox(-1, -1, &plugin->config.Sadj_active, ""){
1519     this->plugin = plugin;
1520     this->gui = gui;
1521   }
1522   virtual int handle_event(){
1523     plugin->config.Sadj_active = get_value();
1524     update();
1525     return 1;
1526   }
1527   void update(){
1528     this->BC_CheckBox::update(plugin->config.Sadj_active,1);
1529     gui->Sadj_slider->update();
1530   }
1531   BluebananaMain *plugin;
1532   BluebananaWindow *gui;
1533 };
1534
1535 class BluebananaVAActive : public BC_CheckBox {
1536 public:
1537   BluebananaVAActive(BluebananaMain *plugin, BluebananaWindow *gui)
1538   : BC_CheckBox(-1, -1, &plugin->config.Vadj_active, ""){
1539     this->plugin = plugin;
1540     this->gui = gui;
1541   }
1542   virtual int handle_event(){
1543     plugin->config.Vadj_active = get_value();
1544     update();
1545     return 1;
1546   }
1547   void update(){
1548     this->BC_CheckBox::update(plugin->config.Vadj_active,1);
1549     gui->Vadj_slider->update();
1550   }
1551   BluebananaMain *plugin;
1552   BluebananaWindow *gui;
1553 };
1554
1555 class BluebananaRAActive : public BC_CheckBox {
1556 public:
1557   BluebananaRAActive(BluebananaMain *plugin, BluebananaWindow *gui)
1558   : BC_CheckBox(-1, -1, &plugin->config.Radj_active, ""){
1559     this->plugin = plugin;
1560     this->gui = gui;
1561   }
1562   virtual int handle_event(){
1563     plugin->config.Radj_active = get_value();
1564     update();
1565     return 1;
1566   }
1567   void update(){
1568     this->BC_CheckBox::update(plugin->config.Radj_active,1);
1569     gui->Radj_slider->update();
1570   }
1571   BluebananaMain *plugin;
1572   BluebananaWindow *gui;
1573 };
1574
1575 class BluebananaGAActive : public BC_CheckBox {
1576 public:
1577   BluebananaGAActive(BluebananaMain *plugin, BluebananaWindow *gui)
1578   : BC_CheckBox(-1, -1, &plugin->config.Gadj_active, ""){
1579     this->plugin = plugin;
1580     this->gui = gui;
1581   }
1582   virtual int handle_event(){
1583     plugin->config.Gadj_active = get_value();
1584     update();
1585     return 1;
1586   }
1587   void update(){
1588     this->BC_CheckBox::update(plugin->config.Gadj_active,1);
1589     gui->Gadj_slider->update();
1590   }
1591   BluebananaMain *plugin;
1592   BluebananaWindow *gui;
1593 };
1594
1595 class BluebananaBAActive : public BC_CheckBox {
1596 public:
1597   BluebananaBAActive(BluebananaMain *plugin, BluebananaWindow *gui)
1598   : BC_CheckBox(-1, -1, &plugin->config.Badj_active, ""){
1599     this->plugin = plugin;
1600     this->gui = gui;
1601   }
1602   virtual int handle_event(){
1603     plugin->config.Badj_active = get_value();
1604     update();
1605     return 1;
1606   }
1607   void update(){
1608     this->BC_CheckBox::update(plugin->config.Badj_active,1);
1609     gui->Badj_slider->update();
1610   }
1611   BluebananaMain *plugin;
1612   BluebananaWindow *gui;
1613 };
1614
1615 class BluebananaOAActive : public BC_CheckBox {
1616 public:
1617   BluebananaOAActive(BluebananaMain *plugin, BluebananaWindow *gui)
1618   : BC_CheckBox(-1, -1, &plugin->config.Oadj_active, ""){
1619     this->plugin = plugin;
1620     this->gui = gui;
1621   }
1622   virtual int handle_event(){
1623     plugin->config.Oadj_active = get_value();
1624     update();
1625     return 1;
1626   }
1627   void update(){
1628     this->BC_CheckBox::update(plugin->config.Oadj_active,1);
1629     gui->Oadj_slider->update();
1630   }
1631   BluebananaMain *plugin;
1632   BluebananaWindow *gui;
1633 };
1634
1635 // -------------------------------------------- Erode --------------------------------------------
1636 class BluebananaErode : public BC_CheckBox {
1637 public:
1638   BluebananaErode(BluebananaMain *plugin, BluebananaWindow *gui)
1639   : BC_CheckBox(-1, -1, &plugin->config.Fsel_erode, ""){
1640     this->plugin = plugin;
1641     this->gui = gui;
1642   }
1643   virtual int handle_event(){
1644     plugin->config.Fsel_erode = get_value();
1645     update();
1646     return 1;
1647   }
1648   void update(){
1649     this->BC_CheckBox::update(plugin->config.Fsel_erode,1);
1650     gui->Fsel_slider->update();
1651   }
1652   BluebananaMain *plugin;
1653   BluebananaWindow *gui;
1654 };
1655
1656
1657 // -------------------------------------- Invert Selection ---------------------------------------
1658 class BluebananaIS : public BC_CheckBox {
1659 public:
1660   BluebananaIS(BluebananaMain *plugin, BluebananaWindow *gui)
1661   : BC_CheckBox(-1, -1, &plugin->config.invert_selection, ""){
1662     this->plugin = plugin;
1663     this->gui = gui;
1664   }
1665   virtual int handle_event(){
1666     plugin->config.invert_selection = get_value();
1667     update();
1668     return 1;
1669   }
1670   void update(){
1671     this->BC_CheckBox::update(plugin->config.invert_selection,1);
1672     gui->enter_config_change();
1673     gui->commit_config_change();
1674   }
1675   BluebananaMain *plugin;
1676   BluebananaWindow *gui;
1677 };
1678
1679
1680 // -------------------------------------------- Mark --------------------------------------------
1681 class BluebananaMark : public BC_CheckBox {
1682 public:
1683   BluebananaMark(BluebananaMain *plugin, BluebananaWindow *gui)
1684     : BC_CheckBox(-1, -1, 0, ""){
1685     this->plugin = plugin;
1686     this->gui = gui;
1687   }
1688   virtual int handle_event() {
1689     if(plugin->config.mark != get_value()){
1690       plugin->config.mark = get_value();
1691       plugin->save_nonauto();
1692       if(plugin->config.mark){
1693         gui->set_repeat(207);
1694       }else{
1695         gui->unset_repeat(207);
1696       }
1697       plugin->server->mwindow->sync_parameters();
1698     }
1699     return 1;
1700   }
1701   void update (){
1702     if(plugin->config.mark != get_value()){
1703       this->BC_CheckBox::update(plugin->config.mark,1);
1704       if(plugin->config.mark){
1705         gui->set_repeat(207);
1706       }else{
1707         gui->unset_repeat(207);
1708       }
1709     }
1710   };
1711   BluebananaMain *plugin;
1712   BluebananaWindow *gui;
1713 };
1714
1715 // ------------------------------------------- Active -------------------------------------------
1716 class BluebananaActive : public BC_CheckBox {
1717 public:
1718   BluebananaActive(BluebananaMain *plugin, BluebananaWindow *gui)
1719     : BC_CheckBox(-1, -1, &plugin->config.active, ""){
1720     this->plugin = plugin;
1721     this->gui = gui;
1722     active=-1;
1723   }
1724   virtual int handle_event(){
1725     active = get_value();
1726     update();
1727     return 1;
1728   }
1729   void update(){
1730     if(active != plugin->config.active){
1731       plugin->config.active = active;
1732       this->BC_CheckBox::update(plugin->config.active,1);
1733       gui->enter_config_change();
1734       gui->Hadj_slider->update();
1735       gui->Sadj_slider->update();
1736       gui->Vadj_slider->update();
1737       gui->Radj_slider->update();
1738       gui->Gadj_slider->update();
1739       gui->Badj_slider->update();
1740       gui->Oadj_slider->update();
1741       gui->commit_config_change();
1742     }
1743   }
1744   BluebananaMain *plugin;
1745   BluebananaWindow *gui;
1746   int active;
1747 };
1748
1749 // ---------------------------------------- Capture mask ---------------------------------------
1750 class BluebananaUnmask : public BC_CheckBox {
1751 public:
1752   BluebananaUnmask(BluebananaMain *plugin, BluebananaWindow *gui,int padx)
1753     : BC_CheckBox(-1, -1, &plugin->config.capture_mask, ""){
1754     this->plugin = plugin;
1755     this->gui = gui;
1756     this->padx = padx;
1757     this->label = new BC_Title(-1,-1,_(" End Mask"));
1758     this->x=-1;
1759     this->y=-1;
1760     gui->add_subwindow(this->label);
1761     gui->add_subwindow(this);
1762     hidden = -1;
1763   }
1764   virtual int handle_event(){
1765     plugin->config.capture_mask=get_value();
1766     plugin->save_nonauto();
1767     update();
1768     gui->enter_config_change();
1769     gui->commit_config_change();
1770     return 1;
1771   }
1772   int get_h(){
1773     return label->get_h();
1774   }
1775   int get_w(){
1776     return BC_CheckBox::get_w()+label->get_w()+padx*4;
1777   }
1778   void reposition_window(int x, int y){
1779     int h = label->get_h();
1780     this->x = x;
1781     this->y = y;
1782     label->reposition_window(x+padx,y);
1783     BC_CheckBox::reposition_window(x+padx*2+label->get_w(),y+(h-BC_CheckBox::get_h())/2);
1784     update();
1785   }
1786   void update(){
1787     int w = get_w();
1788     int h = get_h();
1789     int f=0;
1790     int hideme = !plugin->config.use_mask;
1791     switch(plugin->colormodel){
1792     case BC_RGB888:
1793     case BC_RGB_FLOAT:
1794     case BC_YUV888:
1795     case BC_RGB161616:
1796     case BC_YUV161616:
1797       hideme=1;
1798       break;
1799     }
1800
1801     if(hideme && hidden!=1){
1802       hide_window();
1803       label->hide_window();
1804       gui->set_color(get_resources()->get_bg_color());
1805       gui->draw_box(x,y,w,h);
1806       gui->set_color(get_resources()->default_text_color);
1807       gui->draw_line(x,y+h/2,x+w,y+h/2);
1808       hidden=1;
1809       f=1;
1810     }
1811
1812     if(!hideme && hidden!=0){
1813       gui->set_color(get_resources()->get_bg_color());
1814       gui->draw_box(x,y,w,h);
1815       show_window();
1816       label->show_window();
1817       hidden=0;
1818       f=1;
1819     }
1820
1821     if(plugin->config.capture_mask != get_value())
1822       this->BC_CheckBox::update(plugin->config.capture_mask,1);
1823     if(f)
1824       gui->flash(x,y,w,h);
1825   }
1826   BluebananaMain *plugin;
1827   BluebananaWindow *gui;
1828   BC_Title *label;
1829   int x,y,padx,hidden;
1830 };
1831
1832 // ------------------------------------------ Use mask ----------------------------------------
1833 class BluebananaA2Sel : public BC_CheckBox {
1834 public:
1835   BluebananaA2Sel(BluebananaMain *plugin, BluebananaWindow *gui,int padx)
1836     : BC_CheckBox(-1, -1, &plugin->config.use_mask, ""){
1837     this->plugin = plugin;
1838     this->gui = gui;
1839     this->padx = padx;
1840     this->label = new BC_Title(-1,-1,_(" Mask Selection"));
1841     this->x=-1;
1842     this->y=-1;
1843     gui->add_subwindow(this->label);
1844     gui->add_subwindow(this);
1845     hidden = -1;
1846   }
1847   virtual int handle_event(){
1848     plugin->config.use_mask=get_value();
1849     plugin->save_nonauto();
1850     update();
1851     gui->enter_config_change();
1852     gui->commit_config_change();
1853     return 1;
1854   }
1855   int get_h(){
1856     return label->get_h();
1857   }
1858   int get_w(){
1859     return BC_CheckBox::get_w()+label->get_w()+padx*4;
1860   }
1861   void reposition_window(int x, int y){
1862     int h = label->get_h();
1863     this->x = x;
1864     this->y = y;
1865     label->reposition_window(x+padx,y);
1866     BC_CheckBox::reposition_window(x+padx*2+label->get_w(),y+(h-BC_CheckBox::get_h())/2);
1867     update();
1868   }
1869   void update(){
1870     int w = get_w();
1871     int h = get_h();
1872     int f=0;
1873
1874     if(gui->capture_mask)
1875       gui->capture_mask->update();
1876
1877     switch(plugin->colormodel){
1878     case BC_RGB888:
1879     case BC_RGB_FLOAT:
1880     case BC_YUV888:
1881     case BC_RGB161616:
1882     case BC_YUV161616:
1883       if(hidden!=1){
1884         hide_window();
1885         label->hide_window();
1886         gui->set_color(get_resources()->get_bg_color());
1887         gui->draw_box(x,y,w,h);
1888         gui->set_color(get_resources()->default_text_color);
1889         gui->draw_line(x,y+h/2,x+w,y+h/2);
1890         hidden=1;
1891         f=1;
1892       }
1893       break;
1894     case BC_RGBA8888:
1895     case BC_RGBA_FLOAT:
1896     case BC_YUVA8888:
1897     case BC_RGBA16161616:
1898     case BC_YUVA16161616:
1899       if(hidden!=0){
1900         gui->set_color(get_resources()->get_bg_color());
1901         gui->draw_box(x,y,w,h);
1902         show_window();
1903         label->show_window();
1904         hidden=0;
1905         f=1;
1906       }
1907       break;
1908     case -1:
1909       // not initialized yet
1910       return;
1911     default:
1912       fprintf(stderr,_("Unknown colormodel in BluebananaA2Sel:update()\n"));
1913       break;
1914     }
1915     if(plugin->config.use_mask != get_value())
1916       this->BC_CheckBox::update(plugin->config.use_mask,1);
1917     if(f)
1918       gui->flash(x,y,w,h);
1919   }
1920   BluebananaMain *plugin;
1921   BluebananaWindow *gui;
1922   BC_Title *label;
1923   int x,y,padx,hidden;
1924 };
1925
1926 // --------------------------------------- Main GUI window --------------------------------------
1927 BluebananaWindow::BluebananaWindow(BluebananaMain *plugin)
1928  : PluginClientWindow(plugin,1000,1000,0,1,1)
1929 {
1930   do_render=0;
1931   windowx = get_x();
1932   windowy = get_y();
1933   this->plugin = plugin;
1934   config_refcount=1; // suppress pushing config during startup
1935   config_change=0;
1936   config_produce=0;
1937   config_consume=0;
1938   config_pending=0;
1939
1940   Hsel_slider=NULL;
1941   Ssel_slider=NULL;
1942   Vsel_slider=NULL;
1943   Fsel_slider=NULL;
1944   Hadj_slider=NULL;
1945   Sadj_slider=NULL;
1946   Vadj_slider=NULL;
1947   Radj_slider=NULL;
1948   Gadj_slider=NULL;
1949   Badj_slider=NULL;
1950   Oadj_slider=NULL;
1951
1952   use_mask=0;
1953   capture_mask=0;
1954 }
1955
1956 BluebananaWindow::~BluebananaWindow()
1957 {
1958 }
1959
1960 void BluebananaWindow::create_objects()
1961 {
1962   int xmargin = 20, ymargin = 10;
1963   float row_padding = .1;
1964   float column_padding = .3;
1965   int padx=0;
1966
1967   int i;
1968   int row_h=0, row_adv=0;
1969   int label_x=0;
1970   int label_w=0;
1971   int slider_w=0;
1972   int picker_w=0;
1973   int reset_w=0;
1974   int tumbler_w=0,tumbler_ww=0,tumbler_h=0;
1975   int tumbler_col1_x=0,tumbler_col2_x=0,tumbler_col2_w=0;
1976   int y = ymargin;
1977
1978   //BluebananaHAReset *hareset=NULL;
1979
1980   config_refcount=0;
1981   enter_config_change();
1982
1983   /* window headline */
1984   {
1985     BC_Title *l = new BC_Title(xmargin,y,_("Color Selection"));
1986     BC_Title *l2 = new BC_Title(-1,-1,_(" Mark Selected Areas"));
1987     add_subwindow(mark = new BluebananaMark(plugin,this));
1988     add_subwindow(l);
1989     add_subwindow(l2);
1990     padx = l->get_h()*column_padding;
1991     label_x = xmargin + l->get_w();
1992
1993     int x0 = get_w()-xmargin-mark->get_w();
1994     mark->reposition_window(x0,y-(mark->get_h()-l->get_h())/2);
1995     x0 -= padx+l2->get_w();
1996     l2->reposition_window(x0,y);
1997     x0-=padx;
1998
1999     set_color(get_resources()->default_text_color);
2000     draw_line(label_x+padx, (int)(y+l->get_h()*.5), x0, (int)(y+l->get_h()*.5));
2001
2002     y += l->get_h()*(row_padding+1.);
2003   }
2004
2005   const char *labels[11]={_("hue"),_("saturation"),_("value"),_("fill"),_("red"),_("green"),_("blue"),_("hue"),_("saturation"),_("value"),_("fade")};
2006   for(i=0;i<11;i++){
2007     add_subwindow(slider_labels[i] = new BC_Title(-1,-1,labels[i]));
2008     if(slider_labels[i]->get_w()>label_w)label_w=slider_labels[i]->get_w();
2009   }
2010
2011   int tumbler_text_ww = MAX(get_text_width(MEDIUMFONT,"-000"),get_text_width(MEDIUMFONT,"5.00"))+8;
2012   int tumbler_text_w = get_text_width(MEDIUMFONT,"50")+8;
2013   if(tumbler_text_w*3<tumbler_text_ww*2){
2014     tumbler_text_ww = (tumbler_text_ww*2+2)/3*3/2;
2015     tumbler_text_w=tumbler_text_ww*2/3;
2016   }
2017
2018   erode_label = new BC_Title(xmargin,y,_("pre-erode"));
2019   BluebananaErode *erode = new BluebananaErode(plugin,this);
2020   add_subwindow(erode_label);
2021   add_subwindow(erode);
2022
2023   for(i=0;i<11;i++){
2024     BC_GenericButton *p=NULL;
2025     BluebananaSlider *s=NULL;
2026     BB_Tumble *t0 = NULL, *t1=NULL, *t2=NULL;
2027     BC_Toggle *a = NULL;
2028     BC_Title *l = slider_labels[i];
2029
2030     switch(i){
2031     case 0:
2032
2033       add_subwindow(t0 = Hsel_readout0 = new BluebananaHSReadout0(plugin,this,tumbler_text_ww));
2034       add_subwindow(t1 = Hsel_readout1 = new BluebananaHSReadout1(plugin,this,tumbler_text_ww));
2035       add_subwindow(t2 = Hsel_readout2 = new BluebananaHSReadout2(plugin,this,tumbler_text_ww));
2036       add_subwindow(a = Hsel_active = new BluebananaHActive(plugin,this));
2037
2038       /* need a narrow and a wide wide tumbler */
2039       add_subwindow(Fsel_readout0 = new BluebananaFSReadout0(plugin,this,tumbler_text_w));
2040       add_subwindow(Fsel_readout1 = new BluebananaFSReadout1(plugin,this,tumbler_text_w));
2041       add_subwindow(Fsel_readout2 = new BluebananaFSReadout2(plugin,this,tumbler_text_w));
2042       add_subwindow(Fsel_readout3 = new BluebananaFSReadout3(plugin,this,tumbler_text_ww));
2043       tumbler_w = Fsel_readout0->get_w();
2044       tumbler_ww = t0->get_w();
2045       tumbler_h = t0->get_h();
2046
2047       /* need a reset button's width */
2048       reset_w = BC_GenericButton::calculate_w(this, _("Reset"));
2049       picker_w = BC_GenericButton::calculate_w(this, _("Pick"));
2050
2051       /* determine row spacing */
2052       row_h = 30; /* minimum widget height allowance for the row
2053                      (really, min height for the slider) */
2054       if(row_h<a->get_h())row_h=a->get_h();
2055       if(row_h<l->get_h())row_h=l->get_h();
2056       if(row_h<BC_GenericButton::calculate_h())row_h=BC_GenericButton::calculate_h();
2057       if(row_h<t2->get_h())row_h=t2->get_h();
2058       row_adv = row_h*(1.+row_padding);
2059
2060       /* determine horizontal element positioning; two main setups */
2061       /* setup 1: three tumblers + button */
2062       tumbler_col2_w = MAX(reset_w,picker_w);
2063
2064       /* setup 2: four tumblers + erode */
2065       {
2066         int threew = tumbler_ww*3 + padx*4 + tumbler_col2_w;
2067         int fourw = tumbler_w*3 + tumbler_ww + padx*5 + erode->get_w() + erode_label->get_w();
2068         if(fourw>threew) tumbler_col2_w += fourw-threew;
2069       }
2070
2071       tumbler_col2_x = get_w()-xmargin-tumbler_col2_w;
2072       tumbler_col1_x = tumbler_col2_x - tumbler_ww*3 - padx*5;
2073       slider_x = label_x+padx;
2074       slider_w = (tumbler_col1_x - slider_x - padx*3);
2075
2076       /* make sure the label x doesn't cause any labels to go off the
2077          left of the pane */
2078       {
2079         int lx = label_x - padx - a->get_w();
2080         if (lx-label_w < xmargin){
2081           slider_x += ((xmargin+label_w)-lx);
2082           label_x += ((xmargin+label_w)-lx);
2083           slider_w -= ((xmargin+label_w)-lx);
2084         }
2085       }
2086
2087       y += row_adv/3; /* extra half row spacing under headline */
2088       s = Hsel_slider = new BluebananaHSSlider(plugin,this,slider_x,y,slider_w,row_h);
2089       add_subwindow(p = new BluebananaHPicker(this,tumbler_col2_w));
2090
2091       /* Move the upper alpha <->selection config buttons into place */
2092       {
2093         int x0 = slider_x+slider_w+padx*2;
2094         invert_selection = new BluebananaIS(plugin,this);
2095         BC_Title *l = new BC_Title(xmargin,y,_(" Invert Selection"));
2096         add_subwindow(l);
2097         add_subwindow(invert_selection);
2098         int w0 = padx+l->get_w()+padx+invert_selection->get_w()+padx*2;
2099         set_color(get_resources()->get_bg_color());
2100         draw_box(x0-w0,ymargin,w0,ymargin+l->get_h());
2101         x0-=padx*2;
2102         x0-=invert_selection->get_w();
2103         invert_selection->reposition_window(x0,ymargin+(l->get_h()-invert_selection->get_h())/2);
2104         x0-=padx;
2105         x0-=l->get_w();
2106         l->reposition_window(x0,ymargin);
2107         x0-=padx;
2108         x0-=padx*5;
2109
2110         use_mask = new BluebananaA2Sel(plugin,this,padx);
2111         x0-=use_mask->get_w();
2112         use_mask->reposition_window(x0, ymargin);
2113         capture_mask = new BluebananaUnmask(plugin,this,padx);
2114         x0-=padx*5 + capture_mask->get_w();
2115         capture_mask->reposition_window(x0, ymargin);
2116       }
2117
2118       break;
2119
2120     case 1:
2121
2122       add_subwindow(t0 = Ssel_readout0 = new BluebananaSSReadout0(plugin,this,tumbler_text_ww));
2123       add_subwindow(t1 = Ssel_readout1 = new BluebananaSSReadout1(plugin,this,tumbler_text_ww));
2124       add_subwindow(t2 = Ssel_readout2 = new BluebananaSSReadout2(plugin,this,tumbler_text_ww));
2125       add_subwindow(a = Ssel_active = new BluebananaSActive(plugin,this));
2126       add_subwindow(p = new BluebananaSPicker(this,tumbler_col2_w));
2127       s = Ssel_slider = new BluebananaSSSlider(plugin,this,slider_x,y,slider_w,row_h);
2128       break;
2129
2130     case 2:
2131
2132       add_subwindow(t0 = Vsel_readout0 = new BluebananaVSReadout0(plugin,this,tumbler_text_ww));
2133       add_subwindow(t1 = Vsel_readout1 = new BluebananaVSReadout1(plugin,this,tumbler_text_ww));
2134       add_subwindow(t2 = Vsel_readout2 = new BluebananaVSReadout2(plugin,this,tumbler_text_ww));
2135       add_subwindow(a = Vsel_active = new BluebananaVActive(plugin,this));
2136       add_subwindow(p = new BluebananaVPicker(this,tumbler_col2_w));
2137       s = Vsel_slider = new BluebananaVSSlider(plugin,this,slider_x,y,slider_w,row_h);
2138       break;
2139
2140     case 3:
2141
2142       add_subwindow(a = Fsel_active = new BluebananaFActive(plugin,this));
2143       s = Fsel_slider = new BluebananaFSSlider(plugin,this,slider_x,y,slider_w,row_h);
2144
2145       Fsel_readout0->reposition_window(tumbler_col1_x, y + (row_h-tumbler_h)/2 + 1);
2146       Fsel_readout1->reposition_window(tumbler_col1_x+tumbler_w, y + (row_h-tumbler_h)/2 + 1);
2147       Fsel_readout2->reposition_window(tumbler_col1_x+tumbler_w*2, y + (row_h-tumbler_h)/2 + 1);
2148       Fsel_readout3->reposition_window(tumbler_col1_x+tumbler_w*3+padx*2,
2149                                        y + (row_h-tumbler_h)/2 + 1);
2150
2151       {
2152         int x = get_w() - xmargin - erode->get_w();
2153         erode->reposition_window(x,y+(row_h-erode->get_h())/2);
2154         erode_label->reposition_window(x-erode_label->get_w()-padx,y+(row_h-erode_label->get_h())/2);
2155       }
2156
2157       break;
2158
2159     case 4:
2160
2161       add_subwindow(t0 = Radj_readout0 = new BluebananaRAReadout0(plugin,this,tumbler_text_ww));
2162       add_subwindow(t1 = Radj_readout1 = new BluebananaRAReadout1(plugin,this,tumbler_text_ww));
2163       add_subwindow(t2 = Radj_readout2 = new BluebananaRAReadout2(plugin,this,tumbler_text_ww));
2164       add_subwindow(a = Radj_active = new BluebananaRAActive(plugin,this));
2165       add_subwindow(p = new BluebananaRAReset(this,tumbler_col2_w));
2166       s = Radj_slider = new BluebananaRASlider(plugin,this,slider_x,y,slider_w,row_h);
2167       break;
2168
2169     case 5:
2170
2171       add_subwindow(t0 = Gadj_readout0 = new BluebananaGAReadout0(plugin,this,tumbler_text_ww));
2172       add_subwindow(t1 = Gadj_readout1 = new BluebananaGAReadout1(plugin,this,tumbler_text_ww));
2173       add_subwindow(t2 = Gadj_readout2 = new BluebananaGAReadout2(plugin,this,tumbler_text_ww));
2174       add_subwindow(a = Gadj_active = new BluebananaGAActive(plugin,this));
2175       add_subwindow(p = new BluebananaGAReset(this,tumbler_col2_w));
2176       s = Gadj_slider = new BluebananaGASlider(plugin,this,slider_x,y,slider_w,row_h);
2177       break;
2178
2179     case 6:
2180
2181       add_subwindow(t0 = Badj_readout0 = new BluebananaBAReadout0(plugin,this,tumbler_text_ww));
2182       add_subwindow(t1 = Badj_readout1 = new BluebananaBAReadout1(plugin,this,tumbler_text_ww));
2183       add_subwindow(t2 = Badj_readout2 = new BluebananaBAReadout2(plugin,this,tumbler_text_ww));
2184       add_subwindow(a = Badj_active = new BluebananaBAActive(plugin,this));
2185       add_subwindow(p = new BluebananaBAReset(this,tumbler_col2_w));
2186       s = Badj_slider = new BluebananaBASlider(plugin,this,slider_x,y,slider_w,row_h);
2187       break;
2188
2189     case 7:
2190
2191       add_subwindow(t0 = Hadj_readout = new BluebananaHAReadout(plugin,this,tumbler_text_ww));
2192       add_subwindow(a = Hadj_active = new BluebananaHAActive(plugin,this));
2193       add_subwindow(p = new BluebananaHAReset(this,tumbler_col2_w));
2194       s = Hadj_slider = new BluebananaHASlider(plugin,this,slider_x,y,slider_w,row_h);
2195       break;
2196
2197     case 8:
2198
2199       add_subwindow(t0 = Sadj_readout0 = new BluebananaSAReadout0(plugin,this,tumbler_text_ww));
2200       add_subwindow(t1 = Sadj_readout1 = new BluebananaSAReadout1(plugin,this,tumbler_text_ww));
2201       add_subwindow(t2 = Sadj_readout2 = new BluebananaSAReadout2(plugin,this,tumbler_text_ww));
2202
2203       add_subwindow(a = Sadj_active = new BluebananaSAActive(plugin,this));
2204       add_subwindow(p = new BluebananaSAReset(this,tumbler_col2_w));
2205       s = Sadj_slider = new BluebananaSASlider(plugin,this,slider_x,y,slider_w,row_h);
2206       break;
2207
2208     case 9:
2209
2210       add_subwindow(t0 = Vadj_readout0 = new BluebananaVAReadout0(plugin,this,tumbler_text_ww));
2211       add_subwindow(t1 = Vadj_readout1 = new BluebananaVAReadout1(plugin,this,tumbler_text_ww));
2212       add_subwindow(t2 = Vadj_readout2 = new BluebananaVAReadout2(plugin,this,tumbler_text_ww));
2213       add_subwindow(a = Vadj_active = new BluebananaVAActive(plugin,this));
2214       add_subwindow(p = new BluebananaVAReset(this,tumbler_col2_w));
2215       s = Vadj_slider = new BluebananaVASlider(plugin,this,slider_x,y,slider_w,row_h);
2216       break;
2217
2218     case 10:
2219
2220       add_subwindow(t0 = Oadj_readout = new BluebananaOAReadout(plugin,this,tumbler_text_ww));
2221       add_subwindow(a = Oadj_active = new BluebananaOAActive(plugin,this));
2222       add_subwindow(p = new BluebananaOAReset(this,tumbler_col2_w));
2223       s = Oadj_slider = new BluebananaOASlider(plugin,this,slider_x,y,slider_w,row_h);
2224       break;
2225
2226     }
2227     add_subwindow(s);
2228
2229     if(a)a->reposition_window(label_x - padx - a->get_w(), y + (row_h-a->get_h())/2 + 1);
2230     if(l)l->reposition(label_x - l->get_w() - padx*2 - a->get_w(), y + (row_h-l->get_h())/2 + 1);
2231
2232     if(p){
2233       p->BC_SubWindow::reposition_window(tumbler_col2_x, y + (row_h-p->get_h())/2 + 1,
2234                                          MAX(tumbler_col2_w,picker_w),p->get_h());
2235
2236       // work around bug; the reposition step does not fully redraw the button
2237       p->draw_face();
2238     }
2239
2240     if(t0)t0->reposition_window(tumbler_col1_x,
2241                                 y + (row_h-tumbler_h)/2 + 1);
2242
2243     if(t1)t1->reposition_window(tumbler_col1_x+tumbler_ww,
2244                                 y + (row_h-tumbler_h)/2 + 1);
2245
2246     if(t2)t2->reposition_window(tumbler_col1_x+tumbler_ww*2+padx*2+(tumbler_ww-t2->get_w())/2,
2247                                 y + (row_h-tumbler_h)/2 + 1);
2248
2249
2250     s->update();
2251
2252     y+=row_adv;
2253     if(i==3){
2254       y+=row_adv/3;
2255
2256       BC_Title *l = new BC_Title(xmargin,y,_("Color Adjustment"));
2257       BC_Title *l2 = new BC_Title(-1,-1,_(" Filter Active"));
2258       add_subwindow(l);
2259       add_subwindow(l2);
2260       add_subwindow(active = new BluebananaActive(plugin,this));
2261
2262       int x0 = get_w()-xmargin-mark->get_w();
2263       active->reposition_window(x0,y-(active->get_h()-l->get_h())/2);
2264       x0 -= padx+l2->get_w();
2265       l2->reposition_window(x0,y);
2266       x0 -= padx*2;
2267       set_color(get_resources()->default_text_color);
2268       draw_line(xmargin+l->get_w()+padx, y+l->get_h()*.5, x0, y+l->get_h()*.5);
2269
2270       y += l->get_h()*(row_padding+1.);
2271       y += row_adv/3;
2272     }
2273
2274
2275     if(i==6 || i==9){
2276       y+=row_adv/4;
2277
2278       set_color((s->dimtextcolor + get_resources()->default_text_color)/2);
2279       draw_line(slider_x+20, y+l->get_h()*.5, tumbler_col2_x-30, y+l->get_h()*.5);
2280
2281       y += l->get_h()*(row_padding+1.);
2282       y += row_adv/4;
2283     }
2284
2285
2286   }
2287   y += row_adv/2-4;
2288
2289   plugin->update_lookups(0);
2290   do_render=1;
2291
2292   resize_window(get_w(),y);
2293   show_window();
2294   reposition_window(windowx,windowy,get_w(),y);
2295   leave_config_change(); // also forces render
2296   plugin->server->mwindow->sync_parameters();
2297 }
2298
2299 int BluebananaWindow::close_event(){
2300   set_done(1);
2301   return 1;
2302 }
2303
2304 // adds one to config push refcount
2305 // updates any internal state immediately
2306 void BluebananaWindow::enter_config_change(){
2307   config_refcount++;
2308   if(!config_change && !plugin->update_cache.equivalent(plugin->config)){
2309     config_change=1;
2310   }
2311   plugin->update_lookups(0);
2312 }
2313
2314 // decrements one from config push refcount.  If refcount drops to
2315 // zero, pushes new config up to application
2316
2317 // also compresses events; waits 184ms for new events before pushing
2318 // configuration changes
2319 void BluebananaWindow::commit_config_change(){
2320   if(--config_refcount==0){
2321     if(config_change){
2322       config_change=0;
2323       config_produce++;
2324       config_pending=1;
2325       set_repeat(97);
2326     }
2327     render();
2328   }
2329 }
2330
2331 // decrements one from config push refcount.  Does not push config up
2332 // to application when refcount drops to zero (used to wrap update
2333 // requests coming from the application, not user-initiated state
2334 // changes)
2335 void BluebananaWindow::leave_config_change(){
2336   config_change=0;
2337   plugin->update_cache.copy_from(plugin->config);
2338   if(--config_refcount==0){
2339     render();
2340   }
2341 }
2342
2343 int BluebananaWindow::flush_config_change(){
2344   unset_repeat(97);
2345   if(config_pending){
2346     config_pending=0;
2347     plugin->update_cache.copy_from(plugin->config);
2348     plugin->send_configure_change();
2349   }
2350   config_consume=config_produce;
2351   return 0;
2352 }
2353
2354 int BluebananaWindow::repeat_event(int64_t d){
2355   if(d==97){
2356     if(config_consume==config_produce)
2357       flush_config_change();
2358     config_consume=config_produce;
2359   }
2360   if(d==207){
2361
2362     /* if background render is active and we're showing the zebra, mark
2363        the current frame uncached so that we can push zebra changes */
2364     if(plugin->config.mark && plugin->server->mwindow->brender)
2365       plugin->server->mwindow->brender->set_video_map(plugin->source_position, BRender::SCANNED);
2366
2367     /* push update request without an EDL update */
2368     plugin->server->mwindow->sync_parameters();
2369   }
2370   return 0;
2371 }
2372
2373 /* engine -> gui update; don't allow any EDL pushes */
2374 void BluebananaWindow::update(){
2375
2376   // called to suppress configuration pushes
2377   enter_config_change();
2378
2379   // full configuration recompute and redraw
2380   Hsel_slider->update();
2381   Ssel_slider->update();
2382   Vsel_slider->update();
2383   Fsel_slider->update();
2384   Hadj_slider->update();
2385   Sadj_slider->update();
2386   Vadj_slider->update();
2387   Radj_slider->update();
2388   Gadj_slider->update();
2389   Badj_slider->update();
2390   Oadj_slider->update();
2391
2392   active->update();
2393   mark->update();
2394   use_mask->update();
2395   capture_mask->update();
2396   invert_selection->update();
2397
2398   Hsel_active->update();
2399   Ssel_active->update();
2400   Vsel_active->update();
2401   Fsel_active->update();
2402
2403   Hadj_active->update();
2404   Sadj_active->update();
2405   Vadj_active->update();
2406   Radj_active->update();
2407   Gadj_active->update();
2408   Badj_active->update();
2409   Oadj_active->update();
2410
2411   // called to release configuration without pushing
2412   leave_config_change();
2413 }
2414
2415 void BluebananaWindow::render(){
2416   if(do_render){
2417     Hsel_slider->render();
2418     Ssel_slider->render();
2419     Vsel_slider->render();
2420     Fsel_slider->render();
2421     Hadj_slider->render();
2422     Sadj_slider->render();
2423     Vadj_slider->render();
2424     Radj_slider->render();
2425     Gadj_slider->render();
2426     Badj_slider->render();
2427     Oadj_slider->render();
2428   }
2429 }
2430
2431 void BluebananaWindow::update_histograms(BluebananaMain *plugin){
2432   int w = plugin->frame->get_w();
2433   int h = plugin->frame->get_h();
2434
2435   if(Radj_slider)Radj_slider->update_histogram(plugin->red_histogram,0,0,0,w*h);
2436   if(Gadj_slider)Gadj_slider->update_histogram(plugin->green_histogram,0,0,0,w*h);
2437   if(Badj_slider)Badj_slider->update_histogram(plugin->blue_histogram,0,0,0,w*h);
2438
2439   if(Hadj_slider)
2440     Hadj_slider->update_histogram(plugin->hue_histogram,
2441                                   plugin->hue_histogram_red,
2442                                   plugin->hue_histogram_green,
2443                                   plugin->hue_histogram_blue,w*h);
2444
2445   if(Sadj_slider)
2446     Sadj_slider->update_histogram(plugin->sat_histogram,
2447                                   plugin->sat_histogram_red,
2448                                   plugin->sat_histogram_green,
2449                                   plugin->sat_histogram_blue,w*h);
2450
2451   if(Vadj_slider)
2452     Vadj_slider->update_histogram(plugin->value_histogram,
2453                                   plugin->value_histogram_red,
2454                                   plugin->value_histogram_green,
2455                                   plugin->value_histogram_blue,w*h);
2456
2457 }