2 * Cinelerra :: Blue Banana - color modification plugin for Cinelerra-CV
3 * Copyright (C) 2012 Monty <monty@xiph.org>
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.
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.
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
23 #include "bcdisplayinfo.h"
24 #include "bcsignals.h"
26 #include "bluebanana.h"
27 #include "bluebananaconfig.h"
28 #include "bluebananaslider.h"
29 #include "bluebananawindow.h"
35 #include "bluebananacolor.c"
38 class BluebananaHActive : public BC_CheckBox {
40 BluebananaHActive(BluebananaMain *plugin, BluebananaWindow *gui);
41 virtual int handle_event();
43 BluebananaMain *plugin;
44 BluebananaWindow *gui;
47 class BluebananaSActive : public BC_CheckBox {
49 BluebananaSActive(BluebananaMain *plugin, BluebananaWindow *gui);
50 virtual int handle_event();
52 BluebananaMain *plugin;
53 BluebananaWindow *gui;
56 class BluebananaVActive : public BC_CheckBox {
58 BluebananaVActive(BluebananaMain *plugin, BluebananaWindow *gui);
59 virtual int handle_event();
61 BluebananaMain *plugin;
62 BluebananaWindow *gui;
66 // -------------------------------------------------------------------------------
67 // The below code is because the stock TextTumbler trips too many bugs
68 // in guicast to be useful. If this plugin is to be shipped standalone
69 // and work, we need an independent version that avoids the bugs here.
71 BB_Tumble::BB_Tumble(BluebananaMain *plugin,
72 BluebananaWindow *gui,
79 : BC_TextBox(-1,-1,text_w,1,mid,1,MEDIUMFONT,precision){
81 // We must pass in the precision for initialization to get the
82 // geometry right. But then bctextbox.C immediately clobbers it, so
84 set_precision(precision);
87 this->plugin = plugin;
93 this->text_w = text_w;
94 this->precision = precision;
95 this->increment = increment;
97 this->suppress_events = 0;
100 float BB_Tumble::get_value(){
101 const char *text = get_text();
102 if(!text || text[0]==0) return 0;
106 int BB_Tumble::handle_event(){
107 if(!suppress_events) value_event();
111 int BB_Tumble::activate(){
112 // we want to restore the previous value on ESC
114 // the textbox active member is private, make our own
116 return BC_TextBox::activate();
119 int BB_Tumble::deactivate(){
121 // only fire an event if the value changed; this makes 0/360
122 // behavior in the hue selection readout stick with what the user
123 // actually sets (as opposed to sanity checking flipping the value
124 // if an event fires)
125 if(get_value()!=prev)
130 return BC_TextBox::deactivate();
133 int BB_Tumble::button_press_event(){
135 if(get_buttonpress() < 4) return BC_TextBox::button_press_event();
136 if(get_buttonpress() == 4){
137 float v = get_value()+increment;
141 }else if(get_buttonpress() == 5){
142 float v = get_value()-increment;
152 int BB_Tumble::keypress_event(){
153 if(active && get_keypress()==ESC)
156 // don't fire update events from every keypress when editing; that
157 // will trigger slider updates, which will then sanity-check/clamp
158 // values, and then update/clobber the readout text while we're
161 int ret = BC_TextBox::keypress_event();
166 // --------------------------------------------------------------------------------
168 // 1) create_objects() constructs sliders and readouts with
169 // limits but no values
170 // 2) create_objects() then calls slider update()
171 // update computes and sets slider vals from config
172 // update computes and sets readout vals from config
174 // slider drag event:
175 // 1) slider calls handle_event(). This updates config.
176 // 2) slider calls update()
177 // update computes and [re]sets slider vals from config;
178 // this is where the snap-to-value behavior comes from
179 // update computes and sets readout vals from config
182 // 1) readout calls handle_event(). This updates config.
183 // 2) readout calls slider update() directly
184 // slider update computes and sets slider vals from config
185 // slider update computes and [re]sets readout vals from config;
186 // this does not result in a further handle_event() call, so
187 // no infinite recursion.
189 // importantly, readout and slider values are set from the config
190 // (and vice-versa) in only one place each.
192 // ---------------------------- hue adjustment slider -------------------------------
194 class BluebananaHAReadout : public BB_Tumble {
196 BluebananaHAReadout(BluebananaMain *plugin, BluebananaWindow *gui, int w)
197 : BB_Tumble(plugin,gui,rint(-180),0,rint(180), 0,1,w){}
201 class BluebananaHASlider : public BluebananaSliderSingle {
203 BluebananaHASlider(BluebananaMain *plugin, BluebananaWindow *gui,
204 int x, int y, int w, int h)
205 : BluebananaSliderSingle(plugin,gui,x,y,w,h,-180,180){
207 virtual int handle_event() {
208 plugin->config.Hadj_val = val;
212 plugin->config.Hadj_val=0;
216 val=plugin->config.Hadj_val;
217 highlight = plugin->config.active && plugin->config.Hadj_active;
218 gui->Hadj_readout->update(plugin->config.Hadj_val);
219 gui->slider_labels[7]->set_color(highlight && plugin->config.Hadj_val ?
220 get_resources()->default_text_color : dimtextcolor);
221 gui->enter_config_change();
222 gui->commit_config_change();
224 void trough_color(float hdel, float vdel, float &r, float &g, float &b, float &a){
225 float Hshift = plugin->config.Hsel_active ? (plugin->config.Hsel_lo + plugin->config.Hsel_hi)/720.f-.5f : 0.f;
226 float deg = hdel+Hshift;
229 HSpV_to_RGB(deg*6.f,1.,.2,r,g,b);
234 int BluebananaHAReadout::value_event(){
235 float val = get_value();
236 if(val<-180)val=-180;
238 plugin->config.Hadj_val = val;
239 gui->Hadj_slider->update();
243 // ------------------------------ Filter selection slider --------------------------------
244 class BluebananaFSReadout0 : public BB_Tumble {
246 BluebananaFSReadout0(BluebananaMain *plugin, BluebananaWindow *gui, int w)
247 : BB_Tumble(plugin,gui,-FSrange,0,FSrange, 0,1,w){}
250 class BluebananaFSReadout1 : public BB_Tumble {
252 BluebananaFSReadout1(BluebananaMain *plugin, BluebananaWindow *gui, int w)
253 : BB_Tumble(plugin,gui,-FSrange,0,FSrange, 0,1,w){}
256 class BluebananaFSReadout2 : public BB_Tumble {
258 BluebananaFSReadout2(BluebananaMain *plugin, BluebananaWindow *gui, int w)
259 : BB_Tumble(plugin,gui,-FSrange,0,FSrange, 0,1,w){}
262 class BluebananaFSReadout3 : public BB_Tumble {
264 BluebananaFSReadout3(BluebananaMain *plugin, BluebananaWindow *gui, int w)
265 : BB_Tumble(plugin,gui,0.,0,FSovermax, 0,1,w){}
269 static void paint_dot(float *array,int w, int h, float cx, float cy, float r, int inv){
271 int x0 = floor(cx-r);
272 int x1 = ceil(cx+r)+1;
273 int y0 = floor(cy-r);
274 int y1 = ceil(cy+r)+1;
287 float *row = array+y*w;
289 float rr = hypotf(x-cx,y-cy);
290 /* not correct, but this is merely cosmetic anyway */
295 if(row[x]>1.)row[x]=0.;
298 if(row[x]>1.)row[x]=1.;
305 class BluebananaFSSlider : public BluebananaSliderFill {
307 BluebananaFSSlider(BluebananaMain *plugin, BluebananaWindow *gui,
308 int x, int y, int w, int h)
309 : BluebananaSliderFill(plugin,gui,x,y,w,h,-FSrange,FSrange,FSovermax) {
311 recompute_trough_alpha = 1;
314 ~BluebananaFSSlider(){
315 if(trough_alpha)delete[] trough_alpha;
317 virtual int handle_event() {
318 plugin->config.Fsel_lo = (int)rint(loval);
319 plugin->config.Fsel_mid = (int)rint(midval);
320 plugin->config.Fsel_hi = (int)rint(hival);
321 plugin->config.Fsel_over = (int)rint(overval);
322 recompute_trough_alpha = 1;
326 if(plugin->config.Fsel_lo>0)plugin->config.Fsel_lo=0;
327 if(plugin->config.Fsel_hi<0)plugin->config.Fsel_hi=0;
329 if(highlight!=plugin->config.Fsel_active ||
330 erode!=plugin->config.Fsel_erode ||
331 loval!=plugin->config.Fsel_lo ||
332 midval!=plugin->config.Fsel_mid ||
333 hival!=plugin->config.Fsel_hi ||
334 overval!=plugin->config.Fsel_over){
335 recompute_trough_alpha = 1;
337 erode = plugin->config.Fsel_erode;
338 loval = plugin->config.Fsel_lo;
339 midval = plugin->config.Fsel_mid;
340 hival = plugin->config.Fsel_hi;
341 overval = plugin->config.Fsel_over;
342 highlight = plugin->config.Fsel_active;
343 gui->Fsel_readout0->update(plugin->config.Fsel_lo);
344 gui->Fsel_readout1->update(plugin->config.Fsel_mid);
345 gui->Fsel_readout2->update(plugin->config.Fsel_hi);
346 gui->Fsel_readout3->update(plugin->config.Fsel_over);
347 gui->slider_labels[3]->set_color
349 (plugin->config.Hsel_active || plugin->config.Ssel_active || plugin->config.Vsel_active) &&
350 (plugin->config.Fsel_lo != 0 ||
351 plugin->config.Fsel_mid != 0 ||
352 plugin->config.Fsel_hi != 0 ||
353 plugin->config.Fsel_over!= 0 ) ?
354 get_resources()->default_text_color : dimtextcolor);
356 gui->erode_label->set_color
357 (highlight && plugin->config.Fsel_lo && plugin->config.Fsel_hi &&
358 (plugin->config.Hsel_active || plugin->config.Ssel_active || plugin->config.Vsel_active)?
359 get_resources()->default_text_color : dimtextcolor);
361 gui->enter_config_change();
362 gui->commit_config_change();
364 void trough_color(float hdel, float vdel, float &r, float &g, float &b, float &a){
365 int x = rint(hdel*troughcols-.5);
366 int y = rint(vdel*troughlines-.5);
367 float deg = plugin->config.Hsel_active ?
368 vdel*(plugin->config.Hsel_hi-plugin->config.Hsel_lo)+plugin->config.Hsel_lo :
370 float sat = plugin->config.Ssel_active ?
371 (plugin->config.Ssel_hi+plugin->config.Ssel_lo)/200.:
373 float val = plugin->config.Vsel_active ?
374 (plugin->config.Vsel_hi*3+plugin->config.Vsel_lo)/400:
377 if(deg>=360)deg-=360.f;
378 HSpV_to_RGB(deg/60.,sat,val,r,g,b);
379 a = trough_alpha[troughcols*y+x];
384 trough_alpha = new float[troughcols*troughlines];
386 if(recompute_trough_alpha){
387 int trough_border = FSrange;
388 int tw = troughcols*3+trough_border*2;
389 int th = troughlines*3+trough_border*2;
394 memset(work1,0,sizeof(work1));
397 float hival=FSrange*2-1;
398 float y0 = (th-1)/2.;
399 float y1 = (th-1)/2.;
401 int spacing=rint(FSrange)*2;
405 while((y0+spacing*.5)>0){
406 for(x=(rowflag?spacing/2.:0.);x-spacing*.5<tw;x+=spacing){
407 float r = (((float)x/tw)*(hival-loval)+loval)*.5;
409 paint_dot(work1,tw,th,x,y0,r,0);
411 paint_dot(work1,tw,th,x,y0,r,0);
412 paint_dot(work1,tw,th,x,y1,r,0);
417 rowflag = (rowflag+1)&1;
420 float *final = work1;
421 if(plugin->config.Fsel_active &&
422 (plugin->config.Fsel_lo || plugin->config.Fsel_hi || plugin->config.Fsel_over))
423 final=plugin->fill_selection(work1,work2,tw,th,NULL);
425 /* subsample into trough */
426 float *in = final + (tw+1)*trough_border;
427 for(y=0;y<troughlines;y++){
428 float *out = trough_alpha + troughcols*y;
429 for(x=0;x<troughcols;x++)
430 out[x] = (in[x*3]+in[x*3+1]+in[x*3+2]+
431 in[tw+x*3]+in[tw+x*3+1]+in[x*3+2]+
432 in[tw*2+x*3]+in[tw*2+x*3+1]+in[tw*2+x*3+2])*.1111;
437 recompute_trough_alpha=0;
438 BluebananaSliderFill::update();
443 int recompute_trough_alpha;
447 int BluebananaFSReadout0::value_event(){
448 float val = rint(get_value());
449 if(val<-FSrange)val=-FSrange;
451 if(val>plugin->config.Fsel_mid) val = plugin->config.Fsel_mid;
452 plugin->config.Fsel_lo = val;
453 gui->Fsel_slider->update();
457 int BluebananaFSReadout1::value_event(){
458 float val = rint(get_value());
459 if(val<-FSrange)val=-FSrange;
460 if(val>FSrange)val=FSrange;
461 if(val<plugin->config.Fsel_lo) plugin->config.Fsel_lo=val;
462 if(val>plugin->config.Fsel_hi) plugin->config.Fsel_hi=val;
463 plugin->config.Fsel_mid = val;
464 gui->Fsel_slider->update();
468 int BluebananaFSReadout2::value_event(){
469 float val = rint(get_value());
471 if(val>FSrange)val=FSrange;
472 if(val<plugin->config.Fsel_mid) val = plugin->config.Fsel_mid;
473 plugin->config.Fsel_hi = val;
474 gui->Fsel_slider->update();
478 int BluebananaFSReadout3::value_event(){
479 float val = rint(get_value());
481 if(val>FSovermax)val=FSovermax;
482 plugin->config.Fsel_over = val;
483 gui->Fsel_slider->update();
487 // ------------------------------ value selection slider --------------------------------
488 class BluebananaVSReadout0 : public BB_Tumble {
490 BluebananaVSReadout0(BluebananaMain *plugin, BluebananaWindow *gui, int w)
491 : BB_Tumble(plugin,gui,0.,0,100., 0,1,w){}
494 class BluebananaVSReadout1 : public BB_Tumble {
496 BluebananaVSReadout1(BluebananaMain *plugin, BluebananaWindow *gui, int w)
497 : BB_Tumble(plugin,gui,0.,0,100., 0,1,w){}
500 class BluebananaVSReadout2 : public BB_Tumble {
502 BluebananaVSReadout2(BluebananaMain *plugin, BluebananaWindow *gui, int w)
503 : BB_Tumble(plugin,gui,0.,0,100., 0,1,w){}
507 class BluebananaVSSlider : public BluebananaSliderBracket {
509 BluebananaVSSlider(BluebananaMain *plugin, BluebananaWindow *gui,
510 int x, int y, int w, int h)
511 : BluebananaSliderBracket(plugin,gui,x,y,w,h,0,100) { }
512 virtual int handle_event() {
513 plugin->config.Vsel_lo = rint(loval);
514 plugin->config.Vsel_hi = rint(hival);
515 plugin->config.Vsel_over = rint(overval);
519 int delta = plugin->config.Vsel_hi - plugin->config.Vsel_lo;
520 float r = plugin->get_red();
521 float g = plugin->get_green();
522 float b = plugin->get_blue();
524 RGB_to_HSpV(r,g,b,h,s,v);
529 if(delta>25)delta=25;
530 int lo = v - delta/2;
532 /* shrink the brackets if necessary */
541 plugin->config.Vsel_lo=lo;
542 plugin->config.Vsel_hi=hi;
543 plugin->config.Vsel_active=1;
544 gui->Vsel_active->update(); // this will also call the slider update
547 loval = plugin->config.Vsel_lo;
548 hival = plugin->config.Vsel_hi;
549 midval = (loval+hival)/2.f;
550 overval = plugin->config.Vsel_over;
551 highlight = plugin->config.Vsel_active;
553 gui->Vsel_readout0->update(plugin->config.Vsel_lo);
554 gui->Vsel_readout1->update(plugin->config.Vsel_hi);
555 gui->Vsel_readout2->update(plugin->config.Vsel_over);
556 gui->slider_labels[2]->set_color
557 (highlight && (plugin->config.Vsel_lo != 0 || plugin->config.Vsel_hi != 100) ?
558 get_resources()->default_text_color : dimtextcolor);
560 gui->enter_config_change();
561 if(gui->Fsel_slider)gui->Fsel_slider->update();
562 gui->commit_config_change();
564 void trough_color(float hdel, float vdel, float &r, float &g, float &b, float &a){
565 float deg = plugin->config.Hsel_active ?
566 vdel*(plugin->config.Hsel_hi-plugin->config.Hsel_lo)+plugin->config.Hsel_lo :
568 float sat = plugin->config.Ssel_active ?
569 (plugin->config.Ssel_hi*3+plugin->config.Ssel_lo)/400.:
572 if(deg>=360)deg-=360.f;
573 HSpV_to_RGB(deg/60.,sat,hdel,r,g,b);
574 a= plugin->val_select_alpha(hdel);
578 int BluebananaVSReadout0::value_event(){
579 float val = get_value();
582 if(val>plugin->config.Vsel_hi) val = plugin->config.Vsel_hi;
583 plugin->config.Vsel_lo = val;
584 gui->Vsel_slider->update();
588 int BluebananaVSReadout1::value_event(){
589 float val = get_value();
592 if(val<plugin->config.Vsel_lo) val = plugin->config.Vsel_lo;
593 plugin->config.Vsel_hi = val;
594 gui->Vsel_slider->update();
598 int BluebananaVSReadout2::value_event(){
599 float val = get_value();
602 plugin->config.Vsel_over = val;
603 gui->Vsel_slider->update();
607 // ----------------------------- saturation selection slider -----------------------------
608 class BluebananaSSReadout0 : public BB_Tumble {
610 BluebananaSSReadout0(BluebananaMain *plugin, BluebananaWindow *gui, int w)
611 : BB_Tumble(plugin,gui,0.,0,100., 0,1,w){}
614 class BluebananaSSReadout1 : public BB_Tumble {
616 BluebananaSSReadout1(BluebananaMain *plugin, BluebananaWindow *gui, int w)
617 : BB_Tumble(plugin,gui,0.,0,100., 0,1,w){}
620 class BluebananaSSReadout2 : public BB_Tumble {
622 BluebananaSSReadout2(BluebananaMain *plugin, BluebananaWindow *gui, int w)
623 : BB_Tumble(plugin,gui,0.,0,100., 0,1,w){}
627 class BluebananaSSSlider : public BluebananaSliderBracket {
629 BluebananaSSSlider(BluebananaMain *plugin, BluebananaWindow *gui,
630 int x, int y, int w, int h)
631 : BluebananaSliderBracket(plugin,gui,x,y,w,h,0,100) { }
633 plugin->config.Ssel_lo = rint(loval);
634 plugin->config.Ssel_hi = rint(hival);
635 plugin->config.Ssel_over = rint(overval);
639 int delta = plugin->config.Ssel_hi - plugin->config.Ssel_lo;
640 float r = plugin->get_red();
641 float g = plugin->get_green();
642 float b = plugin->get_blue();
644 RGB_to_HSpV(r,g,b,h,s,v);
649 if(delta>25)delta=25;
650 int lo = s - delta/2;
652 /* shrink the brackets if necessary */
661 plugin->config.Ssel_lo=lo;
662 plugin->config.Ssel_hi=hi;
663 plugin->config.Ssel_active=1;
664 gui->Ssel_active->update(); // this will also call the slider update
667 loval = plugin->config.Ssel_lo;
668 hival = plugin->config.Ssel_hi;
669 midval = (loval+hival)/2.f;
670 overval = plugin->config.Ssel_over;
671 highlight = plugin->config.Ssel_active;
673 gui->Ssel_readout0->update(plugin->config.Ssel_lo);
674 gui->Ssel_readout1->update(plugin->config.Ssel_hi);
675 gui->Ssel_readout2->update(plugin->config.Ssel_over);
676 gui->slider_labels[1]->set_color(highlight &&
677 (plugin->config.Ssel_lo != 0 || plugin->config.Ssel_hi != 100) ?
678 get_resources()->default_text_color : dimtextcolor);
680 gui->enter_config_change();
681 if(gui->Fsel_slider)gui->Fsel_slider->update();
682 gui->commit_config_change();
684 void trough_color(float hdel, float vdel, float &r, float &g, float &b, float &a){
685 float deg = plugin->config.Hsel_active ?
686 vdel*(plugin->config.Hsel_hi-plugin->config.Hsel_lo)+plugin->config.Hsel_lo :
688 if(deg>=360)deg-=360.f;
689 HSpV_to_RGB(deg/60.f,hdel,.7+.3*hdel,r,g,b);
690 a = plugin->sat_select_alpha(hdel);
694 int BluebananaSSReadout0::value_event(){
695 float val = get_value();
698 if(val>plugin->config.Ssel_hi) val = plugin->config.Ssel_hi;
699 plugin->config.Ssel_lo = val;
700 gui->Ssel_slider->update();
704 int BluebananaSSReadout1::value_event(){
705 float val = get_value();
708 if(val<plugin->config.Ssel_lo) val = plugin->config.Ssel_lo;
709 plugin->config.Ssel_hi = val;
710 gui->Ssel_slider->update();
714 int BluebananaSSReadout2::value_event(){
715 float val = get_value();
718 plugin->config.Ssel_over = val;
719 gui->Ssel_slider->update();
723 // ----------------------------- hue selection slider ---------------------------------
724 class BluebananaHSReadout0 : public BB_Tumble {
726 BluebananaHSReadout0(BluebananaMain *plugin, BluebananaWindow *gui, int w)
727 : BB_Tumble(plugin,gui,0.,0,360., 0,1,w){}
730 class BluebananaHSReadout1 : public BB_Tumble {
732 BluebananaHSReadout1(BluebananaMain *plugin, BluebananaWindow *gui, int w)
733 : BB_Tumble(plugin,gui,0.,0,360., 0,1,w){}
736 class BluebananaHSReadout2 : public BB_Tumble {
738 BluebananaHSReadout2(BluebananaMain *plugin, BluebananaWindow *gui, int w)
739 : BB_Tumble(plugin,gui,0.,360.,360., 0,1,w){}
743 class BluebananaHSSlider : public BluebananaSliderCircular {
745 BluebananaHSSlider(BluebananaMain *plugin, BluebananaWindow *gui,
746 int x, int y, int w, int h)
747 : BluebananaSliderCircular(plugin,gui,x,y,w,h,0,360) {
750 plugin->config.Hsel_lo = rint(loval);
751 plugin->config.Hsel_hi = plugin->config.Hsel_lo +
752 (midval<loval ? rint(midval*2-loval*2+720) : rint(midval*2-loval*2));
753 plugin->config.Hsel_over = rint(overval);
757 int delta = plugin->config.Hsel_hi - plugin->config.Hsel_lo;
758 float r = plugin->get_red();
759 float g = plugin->get_green();
760 float b = plugin->get_blue();
762 RGB_to_HSpV(r,g,b,h,s,v);
766 if(delta>30)delta=30;
767 int lo = h - delta/2;
773 plugin->config.Hsel_lo=lo;
774 plugin->config.Hsel_hi=hi;
775 plugin->config.Hsel_active=1;
776 gui->Hsel_active->update(); // this will also call the slider update
779 // Significantly more complex than the other sliders due to the
781 //float delta = (plugin->config.Hsel_hi - plugin->config.Hsel_lo);
782 loval = plugin->config.Hsel_lo;
783 overval = plugin->config.Hsel_over;
784 float newhival = plugin->config.Hsel_hi;
785 float newmidval = (loval+newhival)/2.;
786 if(loval<0)loval+=360.;
787 if(loval>360.)loval-=360.;
788 if(newmidval<0)newmidval+=360.;
789 if(newmidval>360.)newmidval-=360.;
790 if(newhival<0)newhival+=360.;
791 if(newhival>360.)newhival-=360.;
792 highlight = plugin->config.Hsel_active;
794 float checkhi = plugin->config.Hsel_hi;
795 if(checkhi>360)checkhi-=360;
797 // one last weirdness; 0 and 360 are technically the same value on
798 // the circular scale, but the user can set either. This isn't a
799 // problem with lo as it doesn't wrap, but mid/hi is computed for
800 // the slider and could end up at 0 or 360, and then clobber the
801 // slider/readout. To avoid annoying the user, don't override an
802 // existing readout/slider setting with its equivalent.
803 if(newhival==0 && hival==360.){
806 }else if(newhival==360 && hival==0.){
809 }else if(checkhi==0 && gui->Hsel_readout2->get_value()==360){
812 }else if(checkhi==360 && gui->Hsel_readout2->get_value()==0){
817 if(newmidval<1 && midval>359){
819 }else if(newmidval>359.f && midval<1.){
825 gui->Hsel_readout0->update(plugin->config.Hsel_lo);
826 gui->Hsel_readout1->update(checkhi);
827 gui->Hsel_readout2->update(plugin->config.Hsel_over);
828 gui->slider_labels[0]->set_color(highlight &&
829 (plugin->config.Hsel_hi - plugin->config.Hsel_lo != 360) ?
830 get_resources()->default_text_color : dimtextcolor);
832 gui->enter_config_change();
833 if(gui->Fsel_slider)gui->Fsel_slider->update();
834 gui->commit_config_change();
836 void trough_color(float hdel, float vdel, float &r, float &g, float &b, float &a){
837 float deg = hdel*360.f;
838 if(deg>=360)deg-=360.f;
840 HSpV_to_RGB(deg/60.f,1.f,1.f,r,g,b);
841 a = plugin->hue_select_alpha(hdel*360.f);
843 friend class BluebananaHSReadout1;
844 friend class BluebananaHSReadout2;
847 int BluebananaHSReadout0::value_event(){
848 plugin->config.Hsel_lo = get_value();
849 if(plugin->config.Hsel_lo<0)plugin->config.Hsel_lo=0;
850 if(plugin->config.Hsel_lo>360)plugin->config.Hsel_lo=360;
851 if(plugin->config.Hsel_hi - plugin->config.Hsel_lo > 360)
852 plugin->config.Hsel_hi-=360;
853 if(plugin->config.Hsel_lo > plugin->config.Hsel_hi)
854 plugin->config.Hsel_hi+=360;
855 gui->Hsel_slider->update();
859 int BluebananaHSReadout1::value_event(){
860 plugin->config.Hsel_hi = get_value();
861 if(plugin->config.Hsel_hi<0)plugin->config.Hsel_hi=0;
862 if(plugin->config.Hsel_hi>360)plugin->config.Hsel_hi=360;
863 if(plugin->config.Hsel_lo > plugin->config.Hsel_hi)
864 plugin->config.Hsel_hi+=360;
865 gui->Hsel_slider->hival=-1; /* force update to hival, not the hi readout */
866 gui->Hsel_slider->update();
870 int BluebananaHSReadout2::value_event(){
871 float val = get_value();
874 plugin->config.Hsel_over=val;
875 gui->Hsel_slider->update();
879 // ---------------------------- saturation adjustment slider ----------------------------
880 class BluebananaSAReadout0 : public BB_Tumble {
882 BluebananaSAReadout0(BluebananaMain *plugin, BluebananaWindow *gui, int w)
883 : BB_Tumble(plugin,gui,-100,0,100., 0,1,w){}
886 class BluebananaSAReadout1 : public BB_Tumble {
888 BluebananaSAReadout1(BluebananaMain *plugin, BluebananaWindow *gui, int w)
889 : BB_Tumble(plugin,gui,0.,0,200., 0,1,w){}
892 class BluebananaSAReadout2 : public BB_Tumble {
894 BluebananaSAReadout2(BluebananaMain *plugin, BluebananaWindow *gui, int w)
895 : BB_Tumble(plugin,gui,MIN_GAMMA,0,MAX_GAMMA,2,.01,w){}
899 class BluebananaSASlider : public BluebananaSliderChannel {
901 BluebananaSASlider(BluebananaMain *plugin, BluebananaWindow *gui,
902 int x, int y, int w, int h)
903 : BluebananaSliderChannel(plugin,gui,x,y,w,h) { }
904 virtual int handle_event() {
905 plugin->config.Sadj_lo = loval;
906 plugin->config.Sadj_hi = hival;
907 plugin->config.Sadj_gamma = gamma;
911 plugin->config.Sadj_lo=0.;
912 plugin->config.Sadj_hi=100.;
913 plugin->config.Sadj_gamma=1.;
917 loval = plugin->config.Sadj_lo;
918 hival = plugin->config.Sadj_hi;
919 gamma = plugin->config.Sadj_gamma;
921 highlight = plugin->config.active && plugin->config.Sadj_active;
923 gui->Sadj_readout0->update(plugin->config.Sadj_lo);
924 gui->Sadj_readout1->update(plugin->config.Sadj_hi);
925 gui->Sadj_readout2->update(plugin->config.Sadj_gamma);
926 gui->slider_labels[8]->set_color(highlight &&
927 (plugin->config.Sadj_lo != 0 ||
928 plugin->config.Sadj_hi != 100 ||
929 plugin->config.Sadj_gamma != 1.) ?
930 get_resources()->default_text_color : dimtextcolor);
932 gui->enter_config_change();
933 gui->commit_config_change();
935 void trough_color(float hdel, float &r, float &g, float &b){
940 #define BBCLAMP(x,y,z) ((x)<(y) ? (y) : (x)>(z) ? (z) : (x))
942 int BluebananaSAReadout0::value_event(){
943 plugin->config.Sadj_lo = BBCLAMP(get_value(),-100,plugin->config.Sadj_hi);
944 plugin->config.Sadj_lo = BBCLAMP(get_value(),-100,100);
945 gui->Sadj_slider->update();
948 int BluebananaSAReadout1::value_event(){
949 plugin->config.Sadj_hi = BBCLAMP(get_value(),plugin->config.Sadj_lo,200);
950 plugin->config.Sadj_hi = BBCLAMP(get_value(),0,200);
951 gui->Sadj_slider->update();
954 int BluebananaSAReadout2::value_event(){
955 plugin->config.Sadj_gamma = BBCLAMP(get_value(),MIN_GAMMA,MAX_GAMMA);
956 gui->Sadj_slider->update();
960 // ------------------------------- value adjustment slider -------------------------------
961 class BluebananaVAReadout0 : public BB_Tumble {
963 BluebananaVAReadout0(BluebananaMain *plugin, BluebananaWindow *gui, int w)
964 : BB_Tumble(plugin,gui,-100.,0,100., 0,1,w){}
967 class BluebananaVAReadout1 : public BB_Tumble {
969 BluebananaVAReadout1(BluebananaMain *plugin, BluebananaWindow *gui, int w)
970 : BB_Tumble(plugin,gui,0.,0,200., 0,1,w){}
973 class BluebananaVAReadout2 : public BB_Tumble {
975 BluebananaVAReadout2(BluebananaMain *plugin, BluebananaWindow *gui, int w)
976 : BB_Tumble(plugin,gui,MIN_GAMMA,0,MAX_GAMMA,2,.01,w){}
980 class BluebananaVASlider : public BluebananaSliderChannel {
982 BluebananaVASlider(BluebananaMain *plugin, BluebananaWindow *gui,
983 int x, int y, int w, int h)
984 : BluebananaSliderChannel(plugin,gui,x,y,w,h) { }
985 virtual int handle_event() {
986 plugin->config.Vadj_lo = loval;
987 plugin->config.Vadj_hi = hival;
988 plugin->config.Vadj_gamma = gamma;
992 plugin->config.Vadj_lo=0;
993 plugin->config.Vadj_hi=100;
994 plugin->config.Vadj_gamma=1;
998 loval = plugin->config.Vadj_lo;
999 hival = plugin->config.Vadj_hi;
1000 gamma = plugin->config.Vadj_gamma;
1002 highlight = plugin->config.active && plugin->config.Vadj_active;
1004 gui->Vadj_readout0->update(plugin->config.Vadj_lo);
1005 gui->Vadj_readout1->update(plugin->config.Vadj_hi);
1006 gui->Vadj_readout2->update(plugin->config.Vadj_gamma);
1007 gui->slider_labels[9]->set_color(highlight &&
1008 (plugin->config.Vadj_lo != 0.f ||
1009 plugin->config.Vadj_hi != 100.f ||
1010 plugin->config.Vadj_gamma != 1.f) ?
1011 get_resources()->default_text_color : dimtextcolor);
1013 gui->enter_config_change();
1014 gui->commit_config_change();
1016 void trough_color(float hdel, float &r, float &g, float &b){
1021 int BluebananaVAReadout0::value_event(){
1022 plugin->config.Vadj_lo = BBCLAMP(get_value(),-100,plugin->config.Vadj_hi);
1023 plugin->config.Vadj_lo = BBCLAMP(get_value(),-100,100);
1024 gui->Vadj_slider->update();
1027 int BluebananaVAReadout1::value_event(){
1028 plugin->config.Vadj_hi = BBCLAMP(get_value(),plugin->config.Vadj_lo,200);
1029 plugin->config.Vadj_hi = BBCLAMP(get_value(),0,200);
1030 gui->Vadj_slider->update();
1033 int BluebananaVAReadout2::value_event(){
1034 plugin->config.Vadj_gamma = BBCLAMP(get_value(),MIN_GAMMA,MAX_GAMMA);
1035 gui->Vadj_slider->update();
1039 // -------------------------------- red adjustment slider --------------------------------
1040 class BluebananaRAReadout0 : public BB_Tumble {
1042 BluebananaRAReadout0(BluebananaMain *plugin, BluebananaWindow *gui, int w)
1043 : BB_Tumble(plugin,gui,-100.,0,100., 0,1,w){}
1046 class BluebananaRAReadout1 : public BB_Tumble {
1048 BluebananaRAReadout1(BluebananaMain *plugin, BluebananaWindow *gui, int w)
1049 : BB_Tumble(plugin,gui,0.,0,200., 0,1,w){}
1052 class BluebananaRAReadout2 : public BB_Tumble {
1054 BluebananaRAReadout2(BluebananaMain *plugin, BluebananaWindow *gui, int w)
1055 : BB_Tumble(plugin,gui,MIN_GAMMA,0,MAX_GAMMA,2,.01,w){}
1059 class BluebananaRASlider : public BluebananaSliderChannel {
1061 BluebananaRASlider(BluebananaMain *plugin, BluebananaWindow *gui,
1062 int x, int y, int w, int h)
1063 : BluebananaSliderChannel(plugin,gui,x,y,w,h) { }
1064 virtual int handle_event() {
1065 plugin->config.Radj_lo = loval;
1066 plugin->config.Radj_hi = hival;
1067 plugin->config.Radj_gamma = gamma;
1071 plugin->config.Radj_lo=0;
1072 plugin->config.Radj_hi=100;
1073 plugin->config.Radj_gamma=1;
1077 loval = plugin->config.Radj_lo;
1078 hival = plugin->config.Radj_hi;
1079 gamma = plugin->config.Radj_gamma;
1081 highlight = plugin->config.active && plugin->config.Radj_active;
1083 gui->Radj_readout0->update(plugin->config.Radj_lo);
1084 gui->Radj_readout1->update(plugin->config.Radj_hi);
1085 gui->Radj_readout2->update(plugin->config.Radj_gamma);
1086 gui->slider_labels[4]->set_color(highlight &&
1087 (plugin->config.Radj_lo != 0 ||
1088 plugin->config.Radj_hi != 100 ||
1089 plugin->config.Radj_gamma != 1) ?
1090 get_resources()->default_text_color : dimtextcolor);
1092 gui->enter_config_change();
1093 gui->commit_config_change();
1095 void trough_color(float hdel, float &r, float &g, float &b){
1098 }else if(hdel<=1.f){
1108 int BluebananaRAReadout0::value_event(){
1109 plugin->config.Radj_lo = BBCLAMP(get_value(),-100,plugin->config.Radj_hi);
1110 plugin->config.Radj_lo = BBCLAMP(get_value(),-100,100);
1111 gui->Radj_slider->update();
1114 int BluebananaRAReadout1::value_event(){
1115 plugin->config.Radj_hi = BBCLAMP(get_value(),plugin->config.Radj_lo,200);
1116 plugin->config.Radj_hi = BBCLAMP(get_value(),0,200);
1117 gui->Radj_slider->update();
1120 int BluebananaRAReadout2::value_event(){
1121 plugin->config.Radj_gamma = BBCLAMP(get_value(),MIN_GAMMA,MAX_GAMMA);
1122 gui->Radj_slider->update();
1126 // ---------------------------- green adjustment slider ----------------------------
1127 class BluebananaGAReadout0 : public BB_Tumble {
1129 BluebananaGAReadout0(BluebananaMain *plugin, BluebananaWindow *gui, int w)
1130 : BB_Tumble(plugin,gui,-100.,0,100., 0,1,w){}
1133 class BluebananaGAReadout1 : public BB_Tumble {
1135 BluebananaGAReadout1(BluebananaMain *plugin, BluebananaWindow *gui, int w)
1136 : BB_Tumble(plugin,gui,0.,0,200., 0,1,w){}
1139 class BluebananaGAReadout2 : public BB_Tumble {
1141 BluebananaGAReadout2(BluebananaMain *plugin, BluebananaWindow *gui, int w)
1142 : BB_Tumble(plugin,gui,MIN_GAMMA,0,MAX_GAMMA,2,.01,w){}
1146 class BluebananaGASlider : public BluebananaSliderChannel {
1148 BluebananaGASlider(BluebananaMain *plugin, BluebananaWindow *gui,
1149 int x, int y, int w, int h)
1150 : BluebananaSliderChannel(plugin,gui,x,y,w,h) { }
1151 virtual int handle_event() {
1152 plugin->config.Gadj_lo = loval;
1153 plugin->config.Gadj_hi = hival;
1154 plugin->config.Gadj_gamma = gamma;
1158 plugin->config.Gadj_lo=0;
1159 plugin->config.Gadj_hi=100;
1160 plugin->config.Gadj_gamma=1;
1164 loval = plugin->config.Gadj_lo;
1165 hival = plugin->config.Gadj_hi;
1166 gamma = plugin->config.Gadj_gamma;
1168 highlight = plugin->config.active && plugin->config.Gadj_active;
1170 gui->Gadj_readout0->update(plugin->config.Gadj_lo);
1171 gui->Gadj_readout1->update(plugin->config.Gadj_hi);
1172 gui->Gadj_readout2->update(plugin->config.Gadj_gamma);
1173 gui->slider_labels[5]->set_color(highlight &&
1174 (plugin->config.Gadj_lo != 0 ||
1175 plugin->config.Gadj_hi != 100 ||
1176 plugin->config.Gadj_gamma != 1) ?
1177 get_resources()->default_text_color : dimtextcolor);
1179 gui->enter_config_change();
1180 gui->commit_config_change();
1182 void trough_color(float hdel, float &r, float &g, float &b){
1185 }else if(hdel<=1.f){
1195 int BluebananaGAReadout0::value_event(){
1196 plugin->config.Gadj_lo = BBCLAMP(get_value(),-100,plugin->config.Gadj_hi);
1197 plugin->config.Gadj_lo = BBCLAMP(get_value(),-100,100);
1198 gui->Gadj_slider->update();
1201 int BluebananaGAReadout1::value_event(){
1202 plugin->config.Gadj_hi = BBCLAMP(get_value(),plugin->config.Gadj_lo,200);
1203 plugin->config.Gadj_hi = BBCLAMP(get_value(),0,200);
1204 gui->Gadj_slider->update();
1207 int BluebananaGAReadout2::value_event(){
1208 plugin->config.Gadj_gamma = BBCLAMP(get_value(),MIN_GAMMA,MAX_GAMMA);
1209 gui->Gadj_slider->update();
1213 // ------------------------------- blue adjustment slider -------------------------------
1214 class BluebananaBAReadout0 : public BB_Tumble {
1216 BluebananaBAReadout0(BluebananaMain *plugin, BluebananaWindow *gui, int w)
1217 : BB_Tumble(plugin,gui,-100.,0,100., 0,1,w){}
1220 class BluebananaBAReadout1 : public BB_Tumble {
1222 BluebananaBAReadout1(BluebananaMain *plugin, BluebananaWindow *gui, int w)
1223 : BB_Tumble(plugin,gui,0.,0,200., 0,1,w){}
1226 class BluebananaBAReadout2 : public BB_Tumble {
1228 BluebananaBAReadout2(BluebananaMain *plugin, BluebananaWindow *gui, int w)
1229 : BB_Tumble(plugin,gui,MIN_GAMMA,0,MAX_GAMMA,2,.01,w){}
1233 class BluebananaBASlider : public BluebananaSliderChannel {
1235 BluebananaBASlider(BluebananaMain *plugin, BluebananaWindow *gui,
1236 int x, int y, int w, int h)
1237 : BluebananaSliderChannel(plugin,gui,x,y,w,h) { }
1238 virtual int handle_event() {
1239 plugin->config.Badj_lo = loval;
1240 plugin->config.Badj_hi = hival;
1241 plugin->config.Badj_gamma = gamma;
1245 plugin->config.Badj_lo=0;
1246 plugin->config.Badj_hi=100;
1247 plugin->config.Badj_gamma=1;
1251 loval = plugin->config.Badj_lo;
1252 hival = plugin->config.Badj_hi;
1253 gamma = plugin->config.Badj_gamma;
1255 highlight = plugin->config.active && plugin->config.Badj_active;
1257 gui->Badj_readout0->update(plugin->config.Badj_lo);
1258 gui->Badj_readout1->update(plugin->config.Badj_hi);
1259 gui->Badj_readout2->update(plugin->config.Badj_gamma);
1260 gui->slider_labels[6]->set_color(highlight &&
1261 (plugin->config.Badj_lo != 0 ||
1262 plugin->config.Badj_hi != 100 ||
1263 plugin->config.Badj_gamma != 1) ?
1264 get_resources()->default_text_color : dimtextcolor);
1266 gui->enter_config_change();
1267 gui->commit_config_change();
1269 void trough_color(float hdel, float &r, float &g, float &b){
1272 }else if(hdel<=1.f){
1282 int BluebananaBAReadout0::value_event(){
1283 plugin->config.Badj_lo = BBCLAMP(get_value(),-100,plugin->config.Badj_hi);
1284 plugin->config.Badj_lo = BBCLAMP(get_value(),-100,100);
1285 gui->Badj_slider->update();
1288 int BluebananaBAReadout1::value_event(){
1289 plugin->config.Badj_hi = BBCLAMP(get_value(),plugin->config.Badj_lo,200);
1290 plugin->config.Badj_hi = BBCLAMP(get_value(),0,200);
1291 gui->Badj_slider->update();
1294 int BluebananaBAReadout2::value_event(){
1295 plugin->config.Badj_gamma = BBCLAMP(get_value(),MIN_GAMMA,MAX_GAMMA);
1296 gui->Badj_slider->update();
1300 // ---------------------------------- opacity slider ---------------------------------
1301 class BluebananaOAReadout : public BB_Tumble {
1303 BluebananaOAReadout(BluebananaMain *plugin, BluebananaWindow *gui, int w)
1304 : BB_Tumble(plugin,gui,0.,0,100., 0,1,w){}
1308 class BluebananaOASlider : public BluebananaSliderSingle {
1310 BluebananaOASlider(BluebananaMain *plugin, BluebananaWindow *gui,
1311 int x, int y, int w, int h)
1312 : BluebananaSliderSingle(plugin,gui,x,y,w,h,0,100) { }
1313 virtual int handle_event() {
1314 plugin->config.Oadj_val = val;
1318 plugin->config.Oadj_val=100;
1322 val = plugin->config.Oadj_val;
1323 highlight = plugin->config.active && plugin->config.Oadj_active;
1324 gui->Oadj_readout->update(plugin->config.Oadj_val);
1325 gui->slider_labels[10]->set_color(highlight &&
1326 plugin->config.Oadj_val != 100 ?
1327 get_resources()->default_text_color : dimtextcolor);
1328 gui->enter_config_change();
1329 gui->commit_config_change();
1331 void trough_color(float hdel, float vdel, float &r, float &g, float &b, float &a){
1333 a=1-cos(hdel*M_PI*.5);
1337 int BluebananaOAReadout::value_event(){
1338 float val = get_value();
1339 plugin->config.Oadj_val = val;
1340 gui->Oadj_slider->update();
1344 // ---------------------------------- alpha slider ---------------------------------
1345 class BluebananaAAReadout : public BB_Tumble {
1347 BluebananaAAReadout(BluebananaMain *plugin, BluebananaWindow *gui, int w)
1348 : BB_Tumble(plugin,gui,0.,0,100., 0,1,w){}
1352 class BluebananaAASlider : public BluebananaSliderSingle {
1354 BluebananaAASlider(BluebananaMain *plugin, BluebananaWindow *gui,
1355 int x, int y, int w, int h)
1356 : BluebananaSliderSingle(plugin,gui,x,y,w,h,0,100) {}
1357 virtual int handle_event() {
1358 plugin->config.Aadj_val = val;
1362 plugin->config.Aadj_val=100;
1366 val = plugin->config.Aadj_val;
1367 if( BC_CModels::has_alpha(plugin->colormodel) ) {
1368 if( is_hidden() ) show_window();
1370 if( !is_hidden() ) hide_window();
1372 if( is_hidden() ) return;
1373 highlight = plugin->config.active && plugin->config.Aadj_active;
1374 gui->Aadj_readout->update(plugin->config.Aadj_val);
1375 gui->slider_labels[11]->set_color(highlight && plugin->config.Aadj_val != 100 ?
1376 get_resources()->default_text_color : dimtextcolor);
1377 gui->enter_config_change();
1378 gui->commit_config_change();
1380 void trough_color(float hdel, float vdel, float &r, float &g, float &b, float &a){
1382 a=1-cos(hdel*M_PI*.5);
1386 int BluebananaAAReadout::value_event(){
1387 float val = get_value();
1388 plugin->config.Aadj_val = val;
1389 gui->Aadj_slider->update();
1393 // ------------------------------------- picker buttons -----------------------------------------
1394 class BluebananaHPicker : public BC_GenericButton{
1396 BluebananaHPicker(BluebananaWindow *gui, int w) : BC_GenericButton(-1, -1, w, _("Pick")){
1399 int handle_event() { gui->Hsel_slider->pick(); return 1; }
1400 BluebananaWindow *gui;
1402 class BluebananaSPicker : public BC_GenericButton{
1404 BluebananaSPicker(BluebananaWindow *gui, int w) : BC_GenericButton(-1, -1, w, _("Pick")){
1407 int handle_event() { gui->Ssel_slider->pick(); return 1; }
1408 BluebananaWindow *gui;
1410 class BluebananaVPicker : public BC_GenericButton{
1412 BluebananaVPicker(BluebananaWindow *gui, int w) : BC_GenericButton(-1, -1, w, _("Pick")){
1415 int handle_event() { gui->Vsel_slider->pick(); return 1; }
1416 BluebananaWindow *gui;
1419 // -------------------------------------- reset buttons -----------------------------------------
1421 class BluebananaHAReset : public BC_GenericButton{
1423 BluebananaHAReset(BluebananaWindow *gui, int w) : BC_GenericButton(-1, -1, w, _("Reset")){
1426 int handle_event() { gui->Hadj_slider->reset(); return 1;}
1427 BluebananaWindow *gui;
1429 class BluebananaSAReset : public BC_GenericButton{
1431 BluebananaSAReset(BluebananaWindow *gui, int w) : BC_GenericButton(-1, -1, w, _("Reset")){
1434 int handle_event() { gui->Sadj_slider->reset(); return 1;}
1435 BluebananaWindow *gui;
1437 class BluebananaVAReset : public BC_GenericButton{
1439 BluebananaVAReset(BluebananaWindow *gui, int w) : BC_GenericButton(-1, -1, w, _("Reset")){
1442 int handle_event() { gui->Vadj_slider->reset(); return 1;}
1443 BluebananaWindow *gui;
1445 class BluebananaRAReset : public BC_GenericButton{
1447 BluebananaRAReset(BluebananaWindow *gui, int w) : BC_GenericButton(-1, -1, w, _("Reset")){
1450 int handle_event() { gui->Radj_slider->reset(); return 1;}
1451 BluebananaWindow *gui;
1453 class BluebananaGAReset : public BC_GenericButton{
1455 BluebananaGAReset(BluebananaWindow *gui, int w) : BC_GenericButton(-1, -1, w, _("Reset")){
1458 int handle_event() { gui->Gadj_slider->reset(); return 1;}
1459 BluebananaWindow *gui;
1461 class BluebananaBAReset : public BC_GenericButton{
1463 BluebananaBAReset(BluebananaWindow *gui, int w) : BC_GenericButton(-1, -1, w, _("Reset")){
1466 int handle_event() { gui->Badj_slider->reset(); return 1;}
1467 BluebananaWindow *gui;
1469 class BluebananaOAReset : public BC_GenericButton{
1471 BluebananaOAReset(BluebananaWindow *gui, int w) : BC_GenericButton(-1, -1, w, _("Reset")){
1474 int handle_event() { gui->Oadj_slider->reset(); return 1;}
1475 BluebananaWindow *gui;
1477 class BluebananaAAReset : public BC_GenericButton{
1479 BluebananaAAReset(BluebananaWindow *gui, int w) : BC_GenericButton(-1, -1, w, _("Reset")){
1482 int handle_event() { gui->Aadj_slider->reset(); return 1;}
1483 BluebananaWindow *gui;
1486 // ----------------------------------- slider active buttons ------------------------------------
1488 BluebananaHActive::BluebananaHActive(BluebananaMain *plugin, BluebananaWindow *gui)
1489 : BC_CheckBox(-1, -1, &plugin->config.Hsel_active, ""){
1490 this->plugin = plugin;
1493 int BluebananaHActive::handle_event(){
1494 plugin->config.Hsel_active = get_value();
1498 void BluebananaHActive::update(){
1499 this->BC_CheckBox::update(plugin->config.Hsel_active,1);
1500 gui->Hsel_slider->update();
1503 BluebananaSActive::BluebananaSActive(BluebananaMain *plugin, BluebananaWindow *gui)
1504 : BC_CheckBox(-1, -1, &plugin->config.Ssel_active, ""){
1505 this->plugin = plugin;
1508 int BluebananaSActive::handle_event(){
1509 plugin->config.Ssel_active = get_value();
1513 void BluebananaSActive::update(){
1514 this->BC_CheckBox::update(plugin->config.Ssel_active,1);
1515 gui->Ssel_slider->update();
1518 BluebananaVActive::BluebananaVActive(BluebananaMain *plugin, BluebananaWindow *gui)
1519 : BC_CheckBox(-1, -1, &plugin->config.Vsel_active, ""){
1520 this->plugin = plugin;
1523 int BluebananaVActive::handle_event(){
1524 plugin->config.Vsel_active = get_value();
1528 void BluebananaVActive::update(){
1529 this->BC_CheckBox::update(plugin->config.Vsel_active,1);
1530 gui->Vsel_slider->update();
1533 class BluebananaFActive : public BC_CheckBox {
1535 BluebananaFActive(BluebananaMain *plugin, BluebananaWindow *gui)
1536 : BC_CheckBox(-1, -1, &plugin->config.Fsel_active, ""){
1537 this->plugin = plugin;
1540 virtual int handle_event(){
1541 plugin->config.Fsel_active = get_value();
1546 this->BC_CheckBox::update(plugin->config.Fsel_active,1);
1547 gui->Fsel_slider->update();
1549 BluebananaMain *plugin;
1550 BluebananaWindow *gui;
1553 class BluebananaHAActive : public BC_CheckBox {
1555 BluebananaHAActive(BluebananaMain *plugin, BluebananaWindow *gui)
1556 : BC_CheckBox(-1, -1, &plugin->config.Hadj_active, ""){
1557 this->plugin = plugin;
1560 virtual int handle_event(){
1561 plugin->config.Hadj_active = get_value();
1566 this->BC_CheckBox::update(plugin->config.Hadj_active,1);
1567 gui->Hadj_slider->update();
1569 BluebananaMain *plugin;
1570 BluebananaWindow *gui;
1573 class BluebananaSAActive : public BC_CheckBox {
1575 BluebananaSAActive(BluebananaMain *plugin, BluebananaWindow *gui)
1576 : BC_CheckBox(-1, -1, &plugin->config.Sadj_active, ""){
1577 this->plugin = plugin;
1580 virtual int handle_event(){
1581 plugin->config.Sadj_active = get_value();
1586 this->BC_CheckBox::update(plugin->config.Sadj_active,1);
1587 gui->Sadj_slider->update();
1589 BluebananaMain *plugin;
1590 BluebananaWindow *gui;
1593 class BluebananaVAActive : public BC_CheckBox {
1595 BluebananaVAActive(BluebananaMain *plugin, BluebananaWindow *gui)
1596 : BC_CheckBox(-1, -1, &plugin->config.Vadj_active, ""){
1597 this->plugin = plugin;
1600 virtual int handle_event(){
1601 plugin->config.Vadj_active = get_value();
1606 this->BC_CheckBox::update(plugin->config.Vadj_active,1);
1607 gui->Vadj_slider->update();
1609 BluebananaMain *plugin;
1610 BluebananaWindow *gui;
1613 class BluebananaRAActive : public BC_CheckBox {
1615 BluebananaRAActive(BluebananaMain *plugin, BluebananaWindow *gui)
1616 : BC_CheckBox(-1, -1, &plugin->config.Radj_active, ""){
1617 this->plugin = plugin;
1620 virtual int handle_event(){
1621 plugin->config.Radj_active = get_value();
1626 this->BC_CheckBox::update(plugin->config.Radj_active,1);
1627 gui->Radj_slider->update();
1629 BluebananaMain *plugin;
1630 BluebananaWindow *gui;
1633 class BluebananaGAActive : public BC_CheckBox {
1635 BluebananaGAActive(BluebananaMain *plugin, BluebananaWindow *gui)
1636 : BC_CheckBox(-1, -1, &plugin->config.Gadj_active, ""){
1637 this->plugin = plugin;
1640 virtual int handle_event(){
1641 plugin->config.Gadj_active = get_value();
1646 this->BC_CheckBox::update(plugin->config.Gadj_active,1);
1647 gui->Gadj_slider->update();
1649 BluebananaMain *plugin;
1650 BluebananaWindow *gui;
1653 class BluebananaBAActive : public BC_CheckBox {
1655 BluebananaBAActive(BluebananaMain *plugin, BluebananaWindow *gui)
1656 : BC_CheckBox(-1, -1, &plugin->config.Badj_active, ""){
1657 this->plugin = plugin;
1660 virtual int handle_event(){
1661 plugin->config.Badj_active = get_value();
1666 this->BC_CheckBox::update(plugin->config.Badj_active,1);
1667 gui->Badj_slider->update();
1669 BluebananaMain *plugin;
1670 BluebananaWindow *gui;
1673 class BluebananaOAActive : public BC_CheckBox {
1675 BluebananaOAActive(BluebananaMain *plugin, BluebananaWindow *gui)
1676 : BC_CheckBox(-1, -1, &plugin->config.Oadj_active, ""){
1677 this->plugin = plugin;
1680 virtual int handle_event(){
1681 plugin->config.Oadj_active = get_value();
1686 this->BC_CheckBox::update(plugin->config.Oadj_active,1);
1687 gui->Oadj_slider->update();
1689 BluebananaMain *plugin;
1690 BluebananaWindow *gui;
1693 class BluebananaAAActive : public BC_CheckBox {
1696 BluebananaAAActive(BluebananaMain *plugin, BluebananaWindow *gui)
1697 : BC_CheckBox(-1, -1, &plugin->config.Aadj_active, ""){
1698 this->plugin = plugin;
1701 virtual int handle_event(){
1702 plugin->config.Aadj_active =
1703 !BC_CModels::has_alpha(plugin->colormodel) ? 0 : get_value();
1708 this->BC_CheckBox::update(plugin->config.Aadj_active,1);
1709 if( BC_CModels::has_alpha(plugin->colormodel) ) {
1710 if( is_hidden() ) show_window();
1712 if( !is_hidden() ) hide_window();
1714 if( is_hidden() ) return;
1715 gui->Aadj_slider->update();
1717 BluebananaMain *plugin;
1718 BluebananaWindow *gui;
1721 // -------------------------------------------- Erode --------------------------------------------
1722 class BluebananaErode : public BC_CheckBox {
1724 BluebananaErode(BluebananaMain *plugin, BluebananaWindow *gui)
1725 : BC_CheckBox(-1, -1, &plugin->config.Fsel_erode, ""){
1726 this->plugin = plugin;
1729 virtual int handle_event(){
1730 plugin->config.Fsel_erode = get_value();
1735 this->BC_CheckBox::update(plugin->config.Fsel_erode,1);
1736 gui->Fsel_slider->update();
1738 BluebananaMain *plugin;
1739 BluebananaWindow *gui;
1743 // -------------------------------------- Invert Selection ---------------------------------------
1744 class BluebananaIS : public BC_CheckBox {
1746 BluebananaIS(BluebananaMain *plugin, BluebananaWindow *gui)
1747 : BC_CheckBox(-1, -1, &plugin->config.invert_selection, ""){
1748 this->plugin = plugin;
1751 virtual int handle_event(){
1752 plugin->config.invert_selection = get_value();
1757 this->BC_CheckBox::update(plugin->config.invert_selection,1);
1758 gui->enter_config_change();
1759 gui->commit_config_change();
1761 BluebananaMain *plugin;
1762 BluebananaWindow *gui;
1766 // -------------------------------------------- Op --------------------------------------------
1767 class BluebananaOp : public BC_CheckBox {
1769 BluebananaOp(BluebananaMain *plugin, BluebananaWindow *gui)
1770 : BC_CheckBox(-1, -1, &plugin->config.op, ""){
1771 this->plugin = plugin;
1774 virtual int handle_event() {
1775 if(plugin->config.op != get_value()){
1776 plugin->config.op = get_value();
1777 gui->enter_config_change();
1778 gui->commit_config_change();
1783 if(plugin->config.op != get_value()){
1784 this->BC_CheckBox::update(plugin->config.op,1);
1787 BluebananaMain *plugin;
1788 BluebananaWindow *gui;
1791 // -------------------------------------------- Mark --------------------------------------------
1792 class BluebananaMark : public BC_CheckBox {
1794 BluebananaMark(BluebananaMain *plugin, BluebananaWindow *gui)
1795 : BC_CheckBox(-1, -1, 0, ""){
1796 this->plugin = plugin;
1799 virtual int handle_event() {
1800 if(plugin->config.mark != get_value()){
1801 plugin->config.mark = get_value();
1802 plugin->save_nonauto();
1803 if(plugin->config.mark){
1804 gui->set_repeat(207);
1806 gui->unset_repeat(207);
1808 plugin->server->mwindow->sync_parameters();
1813 if(plugin->config.mark != get_value()){
1814 this->BC_CheckBox::update(plugin->config.mark,1);
1815 if(plugin->config.mark){
1816 gui->set_repeat(207);
1818 gui->unset_repeat(207);
1822 BluebananaMain *plugin;
1823 BluebananaWindow *gui;
1826 // ------------------------------------------- Active -------------------------------------------
1827 class BluebananaActive : public BC_CheckBox {
1829 BluebananaActive(BluebananaMain *plugin, BluebananaWindow *gui)
1830 : BC_CheckBox(-1, -1, &plugin->config.active, ""){
1831 this->plugin = plugin;
1835 virtual int handle_event(){
1836 active = get_value();
1841 if(active != plugin->config.active){
1843 plugin->config.active = active;
1845 active = plugin->config.active;
1846 this->BC_CheckBox::update(active,1);
1847 gui->enter_config_change();
1848 gui->Hadj_slider->update();
1849 gui->Sadj_slider->update();
1850 gui->Vadj_slider->update();
1851 gui->Radj_slider->update();
1852 gui->Gadj_slider->update();
1853 gui->Badj_slider->update();
1854 gui->Oadj_slider->update();
1855 gui->Aadj_slider->update();
1856 gui->commit_config_change();
1859 BluebananaMain *plugin;
1860 BluebananaWindow *gui;
1864 // ---------------------------------------- Capture mask ---------------------------------------
1865 class BluebananaUnmask : public BC_CheckBox {
1867 BluebananaUnmask(BluebananaMain *plugin, BluebananaWindow *gui,int padx)
1868 : BC_CheckBox(-1, -1, &plugin->config.capture_mask, ""){
1869 this->plugin = plugin;
1872 this->label = new BC_Title(-1,-1,_(" End Mask"));
1875 gui->add_subwindow(this->label);
1876 gui->add_subwindow(this);
1878 virtual int handle_event(){
1879 plugin->config.capture_mask=get_value();
1880 plugin->save_nonauto();
1882 gui->enter_config_change();
1883 gui->commit_config_change();
1887 return label->get_h();
1890 return BC_CheckBox::get_w()+label->get_w()+padx*4;
1892 void reposition_window(int x, int y){
1893 int h = label->get_h();
1896 label->reposition_window(x+padx,y);
1897 BC_CheckBox::reposition_window(x+padx*2+label->get_w(),y+(h-BC_CheckBox::get_h())/2);
1904 int hideme = !plugin->config.use_mask;
1905 switch(plugin->colormodel){
1915 if(hideme && !is_hidden()){
1917 label->hide_window();
1918 gui->set_color(get_resources()->get_bg_color());
1919 gui->draw_box(x,y,w,h);
1920 gui->set_color(get_resources()->default_text_color);
1921 gui->draw_line(x,y+h/2,x+w,y+h/2);
1925 if(!hideme && is_hidden()){
1926 gui->set_color(get_resources()->get_bg_color());
1927 gui->draw_box(x,y,w,h);
1929 label->show_window();
1933 if(plugin->config.capture_mask != get_value())
1934 this->BC_CheckBox::update(plugin->config.capture_mask,1);
1936 gui->flash(x,y,w,h);
1938 BluebananaMain *plugin;
1939 BluebananaWindow *gui;
1944 // ------------------------------------------ Use mask ----------------------------------------
1945 class BluebananaA2Sel : public BC_CheckBox {
1947 BluebananaA2Sel(BluebananaMain *plugin, BluebananaWindow *gui,int padx)
1948 : BC_CheckBox(-1, -1, &plugin->config.use_mask, ""){
1949 this->plugin = plugin;
1952 this->label = new BC_Title(-1,-1,_(" Mask Selection"));
1955 gui->add_subwindow(this->label);
1956 gui->add_subwindow(this);
1958 virtual int handle_event(){
1959 plugin->config.use_mask=get_value();
1960 plugin->save_nonauto();
1962 gui->enter_config_change();
1963 gui->commit_config_change();
1967 return label->get_h();
1970 return BC_CheckBox::get_w()+label->get_w()+padx*4;
1972 void reposition_window(int x, int y){
1973 int h = label->get_h();
1976 label->reposition_window(x+padx,y);
1977 BC_CheckBox::reposition_window(x+padx*2+label->get_w(),y+(h-BC_CheckBox::get_h())/2);
1985 if(gui->capture_mask)
1986 gui->capture_mask->update();
1988 switch(plugin->colormodel){
1996 label->hide_window();
1997 gui->set_color(get_resources()->get_bg_color());
1998 gui->draw_box(x,y,w,h);
1999 gui->set_color(get_resources()->default_text_color);
2000 gui->draw_line(x,y+h/2,x+w,y+h/2);
2007 case BC_RGBA16161616:
2008 case BC_YUVA16161616:
2010 gui->set_color(get_resources()->get_bg_color());
2011 gui->draw_box(x,y,w,h);
2013 label->show_window();
2018 // not initialized yet
2021 fprintf(stderr,_("Unknown colormodel in BluebananaA2Sel:update()\n"));
2024 if(plugin->config.use_mask != get_value())
2025 this->BC_CheckBox::update(plugin->config.use_mask,1);
2027 gui->flash(x,y,w,h);
2029 BluebananaMain *plugin;
2030 BluebananaWindow *gui;
2035 // --------------------------------------- Main GUI window --------------------------------------
2036 BluebananaWindow::BluebananaWindow(BluebananaMain *plugin)
2037 : PluginClientWindow(plugin,xS(1000),yS(1000),0,1,1)
2042 this->plugin = plugin;
2043 config_refcount=1; // suppress pushing config during startup
2066 BluebananaWindow::~BluebananaWindow()
2070 void BluebananaWindow::create_objects()
2072 int xmargin = 20, ymargin = 10;
2073 float row_padding = .1;
2074 float column_padding = .3;
2078 int row_h=0, row_adv=0;
2084 int tumbler_w=0,tumbler_ww=0,tumbler_h=0;
2085 int tumbler_col1_x=0,tumbler_col2_x=0,tumbler_col2_w=0;
2088 //BluebananaHAReset *hareset=NULL;
2091 enter_config_change();
2093 /* window headline */
2095 BC_Title *l = new BC_Title(xmargin,y,_("Combine Selection"));
2096 BC_Title *l2 = new BC_Title(-1,-1,_(" Mark Selected Areas"));
2097 add_subwindow(mark = new BluebananaMark(plugin,this));
2100 padx = l->get_h()*column_padding;
2101 add_subwindow(op = new BluebananaOp(plugin,this));
2102 int x0 = xmargin + l->get_w() + padx;
2103 op->reposition_window(x0,y-(op->get_h()-l->get_h())/2);
2104 x0 += op->get_w() + padx;
2105 int x1 = get_w()-xmargin-mark->get_w();
2106 mark->reposition_window(x1,y-(mark->get_h()-l->get_h())/2);
2107 x1 -= padx+l2->get_w();
2108 l2->reposition_window(x1,y);
2111 set_color(get_resources()->default_text_color);
2112 int y0 = y+l->get_h()*.5;
2113 draw_line(x0,y0, x1,y0);
2115 y += l->get_h()*(row_padding+1.);
2118 label_x = xmargin + 100 + padx;
2119 const char *labels[12]={_("hue"),_("saturation"),_("value"),_("fill"),_("red"),_("green"),_("blue"),_("hue"),_("saturation"),_("value"),_("fade"),_("alpha")};
2121 add_subwindow(slider_labels[i] = new BC_Title(-1,-1,labels[i]));
2122 if(slider_labels[i]->get_w()>label_w)label_w=slider_labels[i]->get_w();
2125 int tumbler_text_ww = MAX(get_text_width(MEDIUMFONT,"-000"),get_text_width(MEDIUMFONT,"5.00"))+8;
2126 int tumbler_text_w = get_text_width(MEDIUMFONT,"50")+8;
2127 if(tumbler_text_w*3<tumbler_text_ww*2){
2128 tumbler_text_ww = (tumbler_text_ww*2+2)/3*3/2;
2129 tumbler_text_w=tumbler_text_ww*2/3;
2132 erode_label = new BC_Title(xmargin,y,_("pre-erode"));
2133 BluebananaErode *erode = new BluebananaErode(plugin,this);
2134 add_subwindow(erode_label);
2135 add_subwindow(erode);
2138 BC_GenericButton *p=NULL;
2139 BluebananaSlider *s=NULL;
2140 BB_Tumble *t0 = NULL, *t1=NULL, *t2=NULL;
2141 BC_Toggle *a = NULL;
2142 BC_Title *l = slider_labels[i];
2147 add_subwindow(t0 = Hsel_readout0 = new BluebananaHSReadout0(plugin,this,tumbler_text_ww));
2148 add_subwindow(t1 = Hsel_readout1 = new BluebananaHSReadout1(plugin,this,tumbler_text_ww));
2149 add_subwindow(t2 = Hsel_readout2 = new BluebananaHSReadout2(plugin,this,tumbler_text_ww));
2150 add_subwindow(a = Hsel_active = new BluebananaHActive(plugin,this));
2152 /* need a narrow and a wide wide tumbler */
2153 add_subwindow(Fsel_readout0 = new BluebananaFSReadout0(plugin,this,tumbler_text_w));
2154 add_subwindow(Fsel_readout1 = new BluebananaFSReadout1(plugin,this,tumbler_text_w));
2155 add_subwindow(Fsel_readout2 = new BluebananaFSReadout2(plugin,this,tumbler_text_w));
2156 add_subwindow(Fsel_readout3 = new BluebananaFSReadout3(plugin,this,tumbler_text_ww));
2157 tumbler_w = Fsel_readout0->get_w();
2158 tumbler_ww = t0->get_w();
2159 tumbler_h = t0->get_h();
2161 /* need a reset button's width */
2162 reset_w = BC_GenericButton::calculate_w(this, _("Reset"));
2163 picker_w = BC_GenericButton::calculate_w(this, _("Pick"));
2165 /* determine row spacing */
2166 row_h = 30; /* minimum widget height allowance for the row
2167 (really, min height for the slider) */
2168 if(row_h<a->get_h())row_h=a->get_h();
2169 if(row_h<l->get_h())row_h=l->get_h();
2170 if(row_h<BC_GenericButton::calculate_h())row_h=BC_GenericButton::calculate_h();
2171 if(row_h<t2->get_h())row_h=t2->get_h();
2172 row_adv = row_h*(1.+row_padding);
2174 /* determine horizontal element positioning; two main setups */
2175 /* setup 1: three tumblers + button */
2176 tumbler_col2_w = MAX(reset_w,picker_w);
2178 /* setup 2: four tumblers + erode */
2180 int threew = tumbler_ww*3 + padx*4 + tumbler_col2_w;
2181 int fourw = tumbler_w*3 + tumbler_ww + padx*5 + erode->get_w() + erode_label->get_w();
2182 if(fourw>threew) tumbler_col2_w += fourw-threew;
2185 tumbler_col2_x = get_w()-xmargin-tumbler_col2_w;
2186 tumbler_col1_x = tumbler_col2_x - tumbler_ww*3 - padx*5;
2187 slider_x = label_x+padx;
2188 slider_w = (tumbler_col1_x - slider_x - padx*3);
2190 /* make sure the label x doesn't cause any labels to go off the
2193 int lx = label_x - padx - a->get_w();
2194 if (lx-label_w < xmargin){
2195 slider_x += ((xmargin+label_w)-lx);
2196 label_x += ((xmargin+label_w)-lx);
2197 slider_w -= ((xmargin+label_w)-lx);
2201 y += row_adv/3; /* extra half row spacing under headline */
2202 s = Hsel_slider = new BluebananaHSSlider(plugin,this,slider_x,y,slider_w,row_h);
2203 add_subwindow(p = new BluebananaHPicker(this,tumbler_col2_w));
2205 /* Move the upper alpha <->selection config buttons into place */
2207 int x0 = slider_x+slider_w+padx*2;
2208 invert_selection = new BluebananaIS(plugin,this);
2209 BC_Title *l = new BC_Title(xmargin,y,_(" Invert Selection"));
2211 add_subwindow(invert_selection);
2212 int w0 = padx+l->get_w()+padx+invert_selection->get_w()+padx*2;
2213 set_color(get_resources()->get_bg_color());
2214 draw_box(x0-w0,ymargin,w0,ymargin+l->get_h());
2216 x0-=invert_selection->get_w();
2217 invert_selection->reposition_window(x0,ymargin+(l->get_h()-invert_selection->get_h())/2);
2220 l->reposition_window(x0,ymargin);
2224 use_mask = new BluebananaA2Sel(plugin,this,padx);
2225 x0-=use_mask->get_w();
2226 use_mask->reposition_window(x0, ymargin);
2227 capture_mask = new BluebananaUnmask(plugin,this,padx);
2228 x0-=padx*5 + capture_mask->get_w();
2229 capture_mask->reposition_window(x0, ymargin);
2236 add_subwindow(t0 = Ssel_readout0 = new BluebananaSSReadout0(plugin,this,tumbler_text_ww));
2237 add_subwindow(t1 = Ssel_readout1 = new BluebananaSSReadout1(plugin,this,tumbler_text_ww));
2238 add_subwindow(t2 = Ssel_readout2 = new BluebananaSSReadout2(plugin,this,tumbler_text_ww));
2239 add_subwindow(a = Ssel_active = new BluebananaSActive(plugin,this));
2240 add_subwindow(p = new BluebananaSPicker(this,tumbler_col2_w));
2241 s = Ssel_slider = new BluebananaSSSlider(plugin,this,slider_x,y,slider_w,row_h);
2246 add_subwindow(t0 = Vsel_readout0 = new BluebananaVSReadout0(plugin,this,tumbler_text_ww));
2247 add_subwindow(t1 = Vsel_readout1 = new BluebananaVSReadout1(plugin,this,tumbler_text_ww));
2248 add_subwindow(t2 = Vsel_readout2 = new BluebananaVSReadout2(plugin,this,tumbler_text_ww));
2249 add_subwindow(a = Vsel_active = new BluebananaVActive(plugin,this));
2250 add_subwindow(p = new BluebananaVPicker(this,tumbler_col2_w));
2251 s = Vsel_slider = new BluebananaVSSlider(plugin,this,slider_x,y,slider_w,row_h);
2256 add_subwindow(a = Fsel_active = new BluebananaFActive(plugin,this));
2257 s = Fsel_slider = new BluebananaFSSlider(plugin,this,slider_x,y,slider_w,row_h);
2259 Fsel_readout0->reposition_window(tumbler_col1_x, y + (row_h-tumbler_h)/2 + 1);
2260 Fsel_readout1->reposition_window(tumbler_col1_x+tumbler_w, y + (row_h-tumbler_h)/2 + 1);
2261 Fsel_readout2->reposition_window(tumbler_col1_x+tumbler_w*2, y + (row_h-tumbler_h)/2 + 1);
2262 Fsel_readout3->reposition_window(tumbler_col1_x+tumbler_w*3+padx*2,
2263 y + (row_h-tumbler_h)/2 + 1);
2266 int x = get_w() - xmargin - erode->get_w();
2267 erode->reposition_window(x,y+(row_h-erode->get_h())/2);
2268 erode_label->reposition_window(x-erode_label->get_w()-padx,y+(row_h-erode_label->get_h())/2);
2275 add_subwindow(t0 = Radj_readout0 = new BluebananaRAReadout0(plugin,this,tumbler_text_ww));
2276 add_subwindow(t1 = Radj_readout1 = new BluebananaRAReadout1(plugin,this,tumbler_text_ww));
2277 add_subwindow(t2 = Radj_readout2 = new BluebananaRAReadout2(plugin,this,tumbler_text_ww));
2278 add_subwindow(a = Radj_active = new BluebananaRAActive(plugin,this));
2279 add_subwindow(p = new BluebananaRAReset(this,tumbler_col2_w));
2280 s = Radj_slider = new BluebananaRASlider(plugin,this,slider_x,y,slider_w,row_h);
2285 add_subwindow(t0 = Gadj_readout0 = new BluebananaGAReadout0(plugin,this,tumbler_text_ww));
2286 add_subwindow(t1 = Gadj_readout1 = new BluebananaGAReadout1(plugin,this,tumbler_text_ww));
2287 add_subwindow(t2 = Gadj_readout2 = new BluebananaGAReadout2(plugin,this,tumbler_text_ww));
2288 add_subwindow(a = Gadj_active = new BluebananaGAActive(plugin,this));
2289 add_subwindow(p = new BluebananaGAReset(this,tumbler_col2_w));
2290 s = Gadj_slider = new BluebananaGASlider(plugin,this,slider_x,y,slider_w,row_h);
2295 add_subwindow(t0 = Badj_readout0 = new BluebananaBAReadout0(plugin,this,tumbler_text_ww));
2296 add_subwindow(t1 = Badj_readout1 = new BluebananaBAReadout1(plugin,this,tumbler_text_ww));
2297 add_subwindow(t2 = Badj_readout2 = new BluebananaBAReadout2(plugin,this,tumbler_text_ww));
2298 add_subwindow(a = Badj_active = new BluebananaBAActive(plugin,this));
2299 add_subwindow(p = new BluebananaBAReset(this,tumbler_col2_w));
2300 s = Badj_slider = new BluebananaBASlider(plugin,this,slider_x,y,slider_w,row_h);
2305 add_subwindow(t0 = Hadj_readout = new BluebananaHAReadout(plugin,this,tumbler_text_ww));
2306 add_subwindow(a = Hadj_active = new BluebananaHAActive(plugin,this));
2307 add_subwindow(p = new BluebananaHAReset(this,tumbler_col2_w));
2308 s = Hadj_slider = new BluebananaHASlider(plugin,this,slider_x,y,slider_w,row_h);
2313 add_subwindow(t0 = Sadj_readout0 = new BluebananaSAReadout0(plugin,this,tumbler_text_ww));
2314 add_subwindow(t1 = Sadj_readout1 = new BluebananaSAReadout1(plugin,this,tumbler_text_ww));
2315 add_subwindow(t2 = Sadj_readout2 = new BluebananaSAReadout2(plugin,this,tumbler_text_ww));
2317 add_subwindow(a = Sadj_active = new BluebananaSAActive(plugin,this));
2318 add_subwindow(p = new BluebananaSAReset(this,tumbler_col2_w));
2319 s = Sadj_slider = new BluebananaSASlider(plugin,this,slider_x,y,slider_w,row_h);
2324 add_subwindow(t0 = Vadj_readout0 = new BluebananaVAReadout0(plugin,this,tumbler_text_ww));
2325 add_subwindow(t1 = Vadj_readout1 = new BluebananaVAReadout1(plugin,this,tumbler_text_ww));
2326 add_subwindow(t2 = Vadj_readout2 = new BluebananaVAReadout2(plugin,this,tumbler_text_ww));
2327 add_subwindow(a = Vadj_active = new BluebananaVAActive(plugin,this));
2328 add_subwindow(p = new BluebananaVAReset(this,tumbler_col2_w));
2329 s = Vadj_slider = new BluebananaVASlider(plugin,this,slider_x,y,slider_w,row_h);
2334 add_subwindow(t0 = Oadj_readout = new BluebananaOAReadout(plugin,this,tumbler_text_ww));
2335 add_subwindow(a = Oadj_active = new BluebananaOAActive(plugin,this));
2336 add_subwindow(p = new BluebananaOAReset(this,tumbler_col2_w));
2337 s = Oadj_slider = new BluebananaOASlider(plugin,this,slider_x,y,slider_w,row_h);
2342 add_subwindow(t0 = Aadj_readout = new BluebananaAAReadout(plugin,this,tumbler_text_ww));
2343 add_subwindow(a = Aadj_active = new BluebananaAAActive(plugin,this));
2344 add_subwindow(p = new BluebananaAAReset(this,tumbler_col2_w));
2345 s = Aadj_slider = new BluebananaAASlider(plugin,this,slider_x,y,slider_w,row_h);
2351 if(a)a->reposition_window(label_x - padx - a->get_w(), y + (row_h-a->get_h())/2 + 1);
2352 if(l)l->reposition(label_x - l->get_w() - padx*2 - a->get_w(), y + (row_h-l->get_h())/2 + 1);
2355 p->BC_SubWindow::reposition_window(tumbler_col2_x, y + (row_h-p->get_h())/2 + 1,
2356 MAX(tumbler_col2_w,picker_w),p->get_h());
2358 // work around bug; the reposition step does not fully redraw the button
2362 if(t0)t0->reposition_window(tumbler_col1_x,
2363 y + (row_h-tumbler_h)/2 + 1);
2365 if(t1)t1->reposition_window(tumbler_col1_x+tumbler_ww,
2366 y + (row_h-tumbler_h)/2 + 1);
2368 if(t2)t2->reposition_window(tumbler_col1_x+tumbler_ww*2+padx*2+(tumbler_ww-t2->get_w())/2,
2369 y + (row_h-tumbler_h)/2 + 1);
2378 BC_Title *l = new BC_Title(xmargin,y,_("Color Adjustment"));
2379 BC_Title *l2 = new BC_Title(-1,-1,_(" Filter Active"));
2382 add_subwindow(active = new BluebananaActive(plugin,this));
2384 int x0 = get_w()-xmargin-mark->get_w();
2385 active->reposition_window(x0,y-(active->get_h()-l->get_h())/2);
2386 x0 -= padx+l2->get_w();
2387 l2->reposition_window(x0,y);
2389 set_color(get_resources()->default_text_color);
2390 draw_line(xmargin+l->get_w()+padx, y+l->get_h()*.5, x0, y+l->get_h()*.5);
2392 y += l->get_h()*(row_padding+1.);
2400 set_color((s->dimtextcolor + get_resources()->default_text_color)/2);
2401 draw_line(slider_x+20, y+l->get_h()*.5, tumbler_col2_x-30, y+l->get_h()*.5);
2403 y += l->get_h()*(row_padding+1.);
2411 plugin->update_lookups(0);
2414 resize_window(get_w(),y);
2416 reposition_window(windowx,windowy,get_w(),y);
2417 leave_config_change(); // also forces render
2418 plugin->server->mwindow->sync_parameters();
2421 int BluebananaWindow::close_event(){
2426 // adds one to config push refcount
2427 // updates any internal state immediately
2428 void BluebananaWindow::enter_config_change(){
2430 if(!config_change && !plugin->update_cache.equivalent(plugin->config)){
2433 plugin->update_lookups(0);
2436 // decrements one from config push refcount. If refcount drops to
2437 // zero, pushes new config up to application
2439 // also compresses events; waits 184ms for new events before pushing
2440 // configuration changes
2441 void BluebananaWindow::commit_config_change(){
2442 if(--config_refcount==0){
2453 // decrements one from config push refcount. Does not push config up
2454 // to application when refcount drops to zero (used to wrap update
2455 // requests coming from the application, not user-initiated state
2457 void BluebananaWindow::leave_config_change(){
2459 plugin->update_cache.copy_from(plugin->config);
2460 if(--config_refcount==0){
2465 int BluebananaWindow::flush_config_change(){
2469 plugin->update_cache.copy_from(plugin->config);
2470 plugin->send_configure_change();
2472 config_consume=config_produce;
2476 int BluebananaWindow::repeat_event(int64_t d){
2478 if(config_consume!=config_produce)
2479 flush_config_change();
2481 if(!plugin->server->plugin) return 0;
2482 if(!plugin->server->plugin->on) return 0;
2485 /* if background render is active and we're showing the zebra, mark
2486 the current frame uncached so that we can push zebra changes */
2487 if(plugin->config.mark && plugin->server->mwindow->brender)
2488 plugin->server->mwindow->brender->set_video_map(plugin->source_position, BRender::SCANNED);
2490 /* push update request without an EDL update */
2491 plugin->server->mwindow->sync_parameters();
2496 /* engine -> gui update; don't allow any EDL pushes */
2497 void BluebananaWindow::update(){
2499 // called to suppress configuration pushes
2500 enter_config_change();
2502 // full configuration recompute and redraw
2503 Hsel_slider->update();
2504 Ssel_slider->update();
2505 Vsel_slider->update();
2506 Fsel_slider->update();
2507 Hadj_slider->update();
2508 Sadj_slider->update();
2509 Vadj_slider->update();
2510 Radj_slider->update();
2511 Gadj_slider->update();
2512 Badj_slider->update();
2513 Oadj_slider->update();
2514 Aadj_slider->update();
2519 capture_mask->update();
2520 invert_selection->update();
2522 Hsel_active->update();
2523 Ssel_active->update();
2524 Vsel_active->update();
2525 Fsel_active->update();
2527 Hadj_active->update();
2528 Sadj_active->update();
2529 Vadj_active->update();
2530 Radj_active->update();
2531 Gadj_active->update();
2532 Badj_active->update();
2533 Oadj_active->update();
2534 Aadj_active->update();
2536 // called to release configuration without pushing
2537 leave_config_change();
2540 void BluebananaWindow::render(){
2542 Hsel_slider->render();
2543 Ssel_slider->render();
2544 Vsel_slider->render();
2545 Fsel_slider->render();
2546 Hadj_slider->render();
2547 Sadj_slider->render();
2548 Vadj_slider->render();
2549 Radj_slider->render();
2550 Gadj_slider->render();
2551 Badj_slider->render();
2552 Oadj_slider->render();
2553 Aadj_slider->render();
2557 void BluebananaWindow::update_histograms(BluebananaMain *plugin){
2558 int w = plugin->frame->get_w();
2559 int h = plugin->frame->get_h();
2561 if(Radj_slider)Radj_slider->update_histogram(plugin->red_histogram,0,0,0,w*h);
2562 if(Gadj_slider)Gadj_slider->update_histogram(plugin->green_histogram,0,0,0,w*h);
2563 if(Badj_slider)Badj_slider->update_histogram(plugin->blue_histogram,0,0,0,w*h);
2566 Hadj_slider->update_histogram(plugin->hue_histogram,
2567 plugin->hue_histogram_red,
2568 plugin->hue_histogram_green,
2569 plugin->hue_histogram_blue,w*h);
2572 Sadj_slider->update_histogram(plugin->sat_histogram,
2573 plugin->sat_histogram_red,
2574 plugin->sat_histogram_green,
2575 plugin->sat_histogram_blue,w*h);
2578 Vadj_slider->update_histogram(plugin->value_histogram,
2579 plugin->value_histogram_red,
2580 plugin->value_histogram_green,
2581 plugin->value_histogram_blue,w*h);