/* * Cinelerra :: Blue Banana - color modification plugin for Cinelerra-CV * Copyright (C) 2012-2013 Monty * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include "bluebananaslider.h" #include "language.h" #undef CLAMP #define CLAMP(x, y, z) ((x) < (y) ? (y) : ((x) > (z) ? (z) : (x))) #define CW (get_h()/2+2) #define SW (get_h()*2/5+1) #define Z1 (get_h()/7+2) #define Z2 (get_h()*2/5+1) #define Z3 (get_h()-Z2-1) #define Z4 (get_h()-Z1-1) #define ZC ((Z3+Z2)/2) #define ZS 3 #define ZL 1 #define ZR 3 #include static int scale_color(int color, float scale){ int r = ((color >> 16) & 0xff)*scale; int g = ((color >> 8) & 0xff)*scale; int b = (color & 0xff)*scale; if(r>255)r=255; if(g>255)g=255; if(b>255)b=255; return (r<<16)|(g<<8)|b; } #if 0 static int mix_color(int c1, float s1, int c2, float s2){ int r = ((c1 >> 16) & 0xff)*s1 + ((c2 >> 16) & 0xff)*s2; int g = ((c1 >> 8) & 0xff)*s1 + ((c2 >> 8) & 0xff)*s2; int b = (c1 & 0xff)*s1 + (c2 & 0xff)*s2; if(r>255)r=255; if(g>255)g=255; if(b>255)b=255; return (r<<16)|(g<<8)|b; } #endif BluebananaSlider::BluebananaSlider(BluebananaMain *plugin, BluebananaWindow *gui, int x, int y, int w, int h, float minval, float maxval) : BC_SubWindow(x, y, w, h){ this->plugin = plugin; this->gui = gui; this->minval = minval; this->maxval = maxval; histval=NULL; histred=NULL; histgreen=NULL; histblue=NULL; drag = 0; light = -1; int bg_c = get_resources()->get_bg_color(); int bg_r = ((bg_c >> 16) & 0xff); int bg_g = ((bg_c >> 8) & 0xff); int bg_b = (bg_c & 0xff); int bg_v = (bg_r * 76 + bg_g *150 + bg_b *29) >> 8; int dt_c = get_resources()->default_text_color; int dt_r = ((dt_c >> 16) & 0xff); int dt_g = ((dt_c >> 8) & 0xff); int dt_b = (dt_c & 0xff); int dt_v = (dt_r * 76 + dt_g *150 + dt_b *29) >> 8; if(dt_v>bg_v){ /* light text, dark background */ int dg_c = get_resources()->default_text_color; int dg_r = (((dg_c >> 16) & 0xff) + bg_r*2) /3; int dg_g = (((dg_c >> 8) & 0xff) + bg_g*2) /3; int dg_b = ((dg_c & 0xff) + bg_b*2) /3; dg_c = (dg_r<<16) | (dg_g<<8) | dg_b; active_bordercolor = get_resources()->default_text_color; inactive_bordercolor = dg_c; dimtextcolor = dg_c; troughcolor = scale_color(dg_c,.5); slidercolor = (bg_v > 0xa0 ? 0x606060 : 0xa0a0a0); sliderlit = (bg_v > 0xa0 ? 0x909070 : 0xd0d0b0); outline = 0x000000; }else{ /* dark text, light background */ active_bordercolor = scale_color(bg_c,1.25); inactive_bordercolor = scale_color(bg_c,1.01); troughcolor = scale_color(bg_c,.8); dimtextcolor = this->troughcolor; sliderlit = scale_color(bg_c,1.75); slidercolor = scale_color(this->sliderlit,.90); outline = 0x606060; } needlecolor = 0xe07000; needlelit = 0xff9000; highlight = 0; trough = NULL; troughlines = Z4-Z1-1; troughcols = w-CW-CW-ZR-ZL; } BluebananaSlider::~BluebananaSlider(){ if(trough) delete trough; if(histval) delete[] histval; if(histred) delete[] histred; if(histgreen) delete[] histgreen; if(histblue) delete[] histblue; } void BluebananaSlider::reposition(int x, int y, int w, int h){ BC_WindowBase::reposition_window(x,y,w,h); if(trough) delete trough; trough=NULL; if(histval) delete[] histval; histval=NULL; if(histred) delete[] histred; histred=NULL; if(histgreen) delete[] histgreen; histgreen=NULL; if(histblue) delete[] histblue; histblue=NULL; troughlines = Z4-Z1-1; troughcols = w-CW-CW-ZR-ZL; update(); } int BluebananaSlider::fraction_to_pixel(float input){ return (int)rint((input*(troughcols-1)+CW+ZL)+.001); } int BluebananaSlider::value_to_pixel(float input){ return fraction_to_pixel((input-minval)/(maxval-minval)); } float BluebananaSlider::pixel_to_fraction(int pixel){ return (float)((pixel-CW-ZL)/(float)(troughcols-1)); } float BluebananaSlider::pixel_to_value(int pixel){ float fraction=((pixel-CW-ZL)/(float)(troughcols-1)); return fraction*(maxval-minval)+minval; } #if 0 static int inside_box(int cx, int cy, int x, int y, int w, int h){ return (cx>=x && cx=y && cy=y0 && cy<=y1)return 1; if(cy>=y1 && cy<=y0)return 1; } return 0; } static int inside_hline(int cx, int cy, int x0, int x1, int y){ if(cy==y){ if(cx>=x0 && cx<=x1)return 1; if(cx>=x1 && cx<=x0)return 1; } return 0; } int BluebananaSlider::in_midslider(int x, int cx,int cy){ int h = get_h(); int y = (Z4-Z1+h)/2; int r = Z1-2; if( (cx-x)*(cx-x) + (cy-y)*(cy-y) < r*r ) return 1; return 0; } int BluebananaSlider::in_leftslider(int x,int cx, int cy){ int i; int h = get_h(); if(inside_hline(cx,cy,x-1,x-Z1*2-1,Z4)) return 1; for(i=1;i=x-w2 && cx<=x+w2) return 1; return 0; } int BluebananaSlider::in_bottomslider(int x,int cx, int cy){ int i; int h = get_h(); if(inside_vline(cx,cy,x,h-Z1*2-1,h-2))return 1; for(i=1;ix-CW) return 1; return 0; } int BluebananaSlider::in_rightslider2(int x,int cx){ if(cx=x-2) return 1; return 0; } int BluebananaSlider::in_midslider2(int x,int cx){ if(cx>x-CW/2 && cxx-CW/2 && cxget_bg_color(); int bg_r = ((bg_c >> 16) & 0xff); int bg_g = ((bg_c >> 8) & 0xff); int bg_b = (bg_c & 0xff); float del = lit ? 1. : .9; set_color(((int)(bg_r*del) << 16) | ((int)(bg_g*del) << 8) | ((int)(bg_b*del))); draw_box(x-w2+1,0,w2*2-2,Z1); draw_box(x-w2,1,w2*2+1,Z1-2); set_color(lit?sliderlit:slidercolor); draw_box(x-w2+2,1,w2*2-3,Z1-2); draw_box(x-w2+1,2,w2*2-1,Z1-4); set_color(((int)(bg_r*del) << 16) | ((int)(bg_g*del) << 8) | ((int)(bg_b*del))); draw_line(x,2,x,Z1-3); } int BluebananaSlider::button_release_event(){ if(is_event_win()){ if(drag>0) { drag = 0; update(); cursor_motion_event(); } return 1; } return 0; } void BluebananaSlider::update(){ int w = get_w(); int h = get_h(); int bg_c = get_resources()->get_bg_color(); int bg_r = ((bg_c >> 16) & 0xff); int bg_g = ((bg_c >> 8) & 0xff); int bg_b = (bg_c & 0xff); int b_c = highlight ? active_bordercolor : inactive_bordercolor; int b_r = ((b_c >> 16) & 0xff); int b_g = ((b_c >> 8) & 0xff); int b_b = (b_c & 0xff); int tb_c = troughcolor; int tb_r = ((tb_c >> 16) & 0xff); int tb_g = ((tb_c >> 8) & 0xff); int tb_b = (tb_c & 0xff); int ZH = Z4-Z1+1; //int ZHC = Z4-ZC+1; int i,j; clear_box(0, 0, w, h); /* trough shadow */ float del = .9; int shadow_c = ((int)(bg_r*del) << 16) | ((int)(bg_g*del) << 8) | ((int)(bg_b*del)); set_color(shadow_c); draw_box (0,Z1,w,ZH+2); draw_box (1,Z1-1,w-2,ZH+4); del = .8; shadow_c = ((int)(bg_r*del) << 16) | ((int)(bg_g*del) << 8) | ((int)(bg_b*del)); set_color(shadow_c); draw_box (1,Z1+1,w-2,ZH); draw_box (2,Z1,w-4,ZH+2); del = .7; shadow_c = ((int)(bg_r*del) << 16) | ((int)(bg_g*del) << 8) | ((int)(bg_b*del)); set_color(shadow_c); draw_box (2,Z1+2,w-4,ZH-2); draw_box (3,Z1+1,w-6,ZH); /* trough border */ set_color(b_c); draw_box (1,Z1+1,w-4,ZH-2); draw_box (2,Z1,w-6,ZH); /* trough inner */ int ntw = troughcols; int nth = troughlines; int ntx = CW+ZL; int nty = Z1+1; if(!trough){ trough = new VFrame(ntw,nth,BC_RGBA8888); } if(!trough){ fprintf(stderr,_("Bluebanana: Unable to create Frame for slider\n")); }else{ unsigned char *data = trough->get_data(); long bpr = trough->get_bytes_per_line(); float ha = 1.; if(!highlight){ ha*=.25; tb_r = bg_r; tb_g = bg_g; tb_b = bg_b; } if(histval){ // trough is a histogram and has data long bpp = trough->get_bytes_per_pixel(); float rr,gg,bb,aa; for(i=0;i0?nth-histval[i-1]:y; float y1 = i+1get_bytes_per_pixel(); for(j=0;j display size static void resample_histogram(float *raw, float *raw_red, float *raw_green, float *raw_blue, float *out, float *out_red, float *out_green, float *out_blue, int raw_n, int raw_off, int out_n, int out_start, int out_end){ float coverage = (float)raw_n/out_n; float scale = coverage; if(coverage<1.)coverage=1.; float icoverage = 1./coverage; float raw_center = out_start*scale+raw_off; float raw_start = raw_center-coverage; float raw_end = raw_center+coverage; for(int i=out_start; iHISTSIZE)e=HISTSIZE; //int jj=j; float k = (j-raw_start)*icoverage-1.f; float a = 0; for(; j<=e; j++){ float ik = 1.-fabs(k); a += raw[j]*ik; k += icoverage; } out[i] = a; raw_start += scale; raw_end += scale; } if(raw_red){ coverage = (float)raw_n/out_n; scale = coverage; if(coverage<(1<HISTSIZE)e=HISTSIZE; //int jj=j; float k = (j-raw_start)*icoverage-1.f; float r=0.f, g=0.f, b=0.f, a=0.f; for(; j<=e; j++){ float ik = 1.-fabs(k); int sj = (j>>HRGBSHIFT); int sjs = sj<h)val=h; histval[i]=val; } } render(); } // ---------------------------- Single ---------------------------------- BluebananaSliderSingle::BluebananaSliderSingle(BluebananaMain *plugin, BluebananaWindow *gui, int x, int y, int w, int h, float minval, float maxval) : BluebananaSlider(plugin,gui,x,y,w,h,minval,maxval){ val = (minval+maxval)/2; increment = 1; } int BluebananaSliderSingle::button_press_event(){ if(is_event_win() && cursor_inside()){ //int min; //int max; int cx = get_cursor_x(); gui->deactivate(); if(get_buttonpress() == 4){ set_val(val - increment); return 1; }else if(get_buttonpress() == 5){ set_val(val + increment); return 1; } switch(light){ case 0: xoff = cx-value_to_pixel(val); break; default: return 1; } drag = 1; update(); return 1; } return 0; } int BluebananaSliderSingle::cursor_motion_event(){ int cx = get_cursor_x(); //int cy = get_cursor_y(); if(drag){ switch(light){ case 0: set_val(pixel_to_value(cx - xoff)); break; default: drag = 0; light = -1; update(); break; } return 1; }else{ if(is_event_win() && cursor_inside()){ if(in_midslider2(value_to_pixel(val),cx)){ if(light!=0){ light = 0; update(); } }else{ if(light!=-1){ light = -1; update(); } } return 1; }else{ if(light!=-1){ light = -1; update(); } } } return 0; } void BluebananaSliderSingle::set_val(float v){ val=v; if(valmaxval)val=maxval; handle_event(); update(); } void BluebananaSliderSingle::update(){ BluebananaSlider::update(); draw_bottomslider(value_to_pixel(val),light==0); flash(); flush(); } // ---------------------------- Bracket ---------------------------------- BluebananaSliderBracket::BluebananaSliderBracket(BluebananaMain *plugin, BluebananaWindow *gui, int x, int y, int w, int h, float minval, float maxval) : BluebananaSlider(plugin,gui,x,y,w,h,minval,maxval){ loval = minval; midval = (minval+maxval)/2; hival = maxval; overval = minval; increment = 1; } int BluebananaSliderBracket::button_press_event(){ if(is_event_win() && cursor_inside()){ //int min; //int max; int cx = get_cursor_x(); gui->deactivate(); if(shift_down()){ /* narrow/widen range */ if(get_buttonpress() == 4){ set_delta(increment*2); return 1; }else if(get_buttonpress() == 5){ set_delta(-increment*2); return 1; } }else if (ctrl_down()){ /* shift all vals up/down */ if(get_buttonpress() == 4){ set_mid(midval-increment); return 1; }else if(get_buttonpress() == 5){ set_mid(midval+increment); return 1; } }else{ /* increase/decrease overlap */ if(get_buttonpress() == 4){ set_over(overval-1); return 1; }else if(get_buttonpress() == 5){ set_over(overval+1); return 1; } } switch(light){ case 0: xoff = cx-value_to_pixel(loval); break; case 1: xoff = cx-value_to_pixel(midval); break; case 2: xoff = cx-value_to_pixel(hival); break; case 3: xoff = cx-value_to_pixel(overval); break; default: return 1; } drag = 1; update(); return 1; } return 0; } int BluebananaSliderBracket::cursor_motion_event(){ int cx = get_cursor_x(); int cy = get_cursor_y(); if(drag){ switch(light){ case 0: set_lo(pixel_to_value(cx - xoff)); break; case 1: set_mid(pixel_to_value(cx - xoff)); break; case 2: set_hi(pixel_to_value(cx - xoff)); break; case 3: set_over(pixel_to_value(cx - xoff)); break; default: drag = 0; light = -1; update(); break; } return 1; }else{ if(is_event_win() && cursor_inside()){ if(in_overslider(value_to_pixel(overval),cx,cy)){ if(light!=3){ light = 3; update(); } }else if(in_midslider(value_to_pixel(midval),cx,cy)){ if(light!=1){ light = 1; update(); } }else if(in_leftslider(value_to_pixel(loval),cx,cy)){ if(light!=0){ light = 0; update(); } }else if(in_rightslider(value_to_pixel(hival),cx,cy)){ if(light!=2){ light = 2; update(); } }else if(in_midslider2(value_to_pixel(midval),cx)){ if(light!=1){ light = 1; update(); } }else if(in_rightslider2(value_to_pixel(hival),cx)){ if(light!=2){ light = 2; update(); } }else if(in_leftslider2(value_to_pixel(loval),cx)){ if(light!=0){ light = 0; update(); } }else if(in_overslider2(value_to_pixel(overval),cx,cy)){ if(light!=3){ light = 3; update(); } }else{ if(light!=-1){ light = -1; update(); } } return 1; }else{ if(light!=-1){ light = -1; update(); } } } return 0; } void BluebananaSliderBracket::set_lo(float val){ if(valmaxval)val=maxval; if(val > hival) val=hival; loval=val; if(hivalmaxval)hival-=(maxval-minval); if(midval>maxval)midval-=(maxval-minval); if(loval>maxval)loval-=(maxval-minval); if(hivalmaxval)val=maxval; midval=val; float delta = (hival+loval)/2.; hival+=midval-delta; loval+=midval-delta; if(hival>maxval){ loval += maxval-hival; midval += maxval-hival; hival = maxval; } if(lovalmaxval)val=maxval; if(valhival)loval-=(maxval-minval); if(midval>hival)midval-=(maxval-minval); midval=(hival+loval)/2.; if(hival>maxval)hival-=(maxval-minval); if(midval>maxval)midval-=(maxval-minval); if(loval>maxval)loval-=(maxval-minval); if(hivalmaxval)delta=maxval; loval = midval-delta/2; hival = loval+delta; if(lovalmaxval){ loval-=(hival-maxval); midval-=(hival-maxval); hival=maxval; } handle_event(); update(); } void BluebananaSliderBracket::set_over(float val){ if(valmaxval)val=maxval; overval=val; handle_event(); update(); } void BluebananaSliderBracket::update(){ BluebananaSlider::update(); draw_overslider(value_to_pixel(overval),light==3); draw_leftslider(value_to_pixel(loval),light==0); draw_rightslider(value_to_pixel(hival),light==2); draw_midslider(value_to_pixel(midval),light==1); flash(); flush(); } // ----------------------- Circular Bracket ----------------------------- BluebananaSliderCircular::BluebananaSliderCircular(BluebananaMain *plugin, BluebananaWindow *gui, int x, int y, int w, int h, float minval, float maxval) : BluebananaSliderBracket(plugin,gui,x,y,w,h,minval,maxval){} void BluebananaSliderCircular::set_lo(float val){ if(valmaxval)val=maxval; loval=val; if(hivalmaxval)hival-=(maxval-minval); if(midval>maxval)midval-=(maxval-minval); if(loval>maxval)loval-=(maxval-minval); if(hivalmaxval)val=maxval; midval=val; if(hivaloldmid)loval-=(maxval-minval); float delta = hival-loval; loval = midval-delta/2; hival = loval+delta; if(hival>maxval)hival-=(maxval-minval); if(loval>maxval)loval-=(maxval-minval); if(hivalmaxval)val=maxval; hival=val; if(loval>hival)loval-=(maxval-minval); if(midval>hival)midval-=(maxval-minval); midval = (hival+loval)/2.; if(hival>maxval)hival-=(maxval-minval); if(midval>maxval)midval-=(maxval-minval); if(loval>maxval)loval-=(maxval-minval); if(hivalmidval)loval-=(maxval-minval); float delta = (hival-loval)+incr; if(deltamaxval)delta=maxval; loval = midval-delta/2; hival = loval+delta; if(hival>maxval)hival-=(maxval-minval); if(loval>maxval)loval-=(maxval-minval); if(hival .5f ? (1.f-unit) * mG2 + MIN_GAMMA : (.5f-unit) * MG2 + 1.f ); } float BluebananaSliderChannel::gamma_to_pixel(float gamma){ float fraction = gamma<1 ? 1.f - (gamma-MIN_GAMMA) / mG2 : .5f - (gamma-1.f) / MG2 ; return fraction_to_pixel((1.-fraction) * (FRAC100-FRAC0) + FRAC0); } float BluebananaSliderChannel::pixel_to_value(float pixel){ if(pixeldeactivate(); if(shift_down()){ /* narrow/widen range */ if(get_buttonpress() == 4){ set_range(hival-loval-2); return 1; }else if(get_buttonpress() == 5){ if(lovalhival)v=hival; if(v<-100)v=-100; if(v>100)v=100; loval=rint(v); handle_event(); update(); } void BluebananaSliderChannel::set_hi(float v){ if(v200)v=200; hival=rint(v); handle_event(); update(); } void BluebananaSliderChannel::set_mid(float v){ float mid = (hival+loval)*.5; float range = hival-loval; float del = v-mid; if(hival+del>200)del=200-hival; if(hival+del<0)del=0-hival; if(loval+del>100)del=100-loval; if(loval+del<-100)del=-100-loval; loval+=rint(del); hival=loval+rint(range); handle_event(); update(); } void BluebananaSliderChannel::set_range(float v){ //float mid = (hival+loval)*.5; float range = hival-loval; if(v>200)v=200; if(v<0)v=0; float del = (v-range)/2; if(hival+del>200)del=200-hival; if(hival+del<0)del=0-hival; if(loval-del>100)del=loval-100; if(loval-del<-100)del=loval+100; loval-=rint(del); hival=rint(loval+v); handle_event(); update(); } void BluebananaSliderChannel::set_gamma(float v){ if(v>MAX_GAMMA)v=MAX_GAMMA; if(vget_bg_color(); int bg_r = ((bg_c >> 16) & 0xff); int bg_g = ((bg_c >> 8) & 0xff); int bg_b = (bg_c & 0xff); int b_c = highlight ? active_bordercolor : inactive_bordercolor; int b_r = ((b_c >> 16) & 0xff); int b_g = ((b_c >> 8) & 0xff); int b_b = (b_c & 0xff); int tb_c = troughcolor; int tb_r = ((tb_c >> 16) & 0xff); int tb_g = ((tb_c >> 8) & 0xff); int tb_b = (tb_c & 0xff); int ZH = Z4-Z1+1; //int ZHC = Z4-ZC+1; int i,j; t_x0 = fraction_to_pixel(0); t_x1 = fraction_to_pixel(FRAC0); t_x2 = fraction_to_pixel(FRAC100); t_x3 = fraction_to_pixel(1.); t_w01 = t_x1-t_x0; t_w12 = t_x2-t_x1; t_w23 = t_x3-t_x2; int ntw = troughcols-6; int nth = troughlines; int ntx = t_x0; int nty = Z1+1; clear_box(0, 0, w, h); /* trough shadow */ /* w+4 h+4 x-1 y-1 */ float del = .9; int shadow_c = ((int)(bg_r*del) << 16) | ((int)(bg_g*del) << 8) | ((int)(bg_b*del)); set_color(shadow_c); draw_box (0,Z1,t_x1+3,ZH+2); draw_box (1,Z1-1,t_x1+1,ZH+4); draw_box (t_x1,Z1,t_w12+3,ZH+2); draw_box (t_x1+1,Z1-1,t_w12+1,ZH+4); draw_box (t_x2,Z1,w-t_x2,ZH-2+2); draw_box (t_x2+1,Z1-1,w-t_x2-2,ZH+4); /* w+2 h+2 x y */ del = .8; shadow_c = ((int)(bg_r*del) << 16) | ((int)(bg_g*del) << 8) | ((int)(bg_b*del)); set_color(shadow_c); draw_box (1,Z1+1,t_x1+1,ZH); draw_box (2,Z1,t_x1-1,ZH+2); draw_box (t_x1+1,Z1+1,t_w12+1,ZH); draw_box (t_x1+2,Z1,t_w12-1,ZH+2); draw_box (t_x2+1,Z1+1,w-t_x2-2,ZH); draw_box (t_x2+2,Z1,w-t_x2-4,ZH+2); /* w h x+1 y+1 */ del = .7; shadow_c = ((int)(bg_r*del) << 16) | ((int)(bg_g*del) << 8) | ((int)(bg_b*del)); set_color(shadow_c); draw_box (2,Z1+2,t_x1-1,ZH-2); draw_box (3,Z1+1,t_x1-3,ZH); draw_box (t_x1+2,Z1+2,t_w12-1,ZH-2); draw_box (t_x1+3,Z1+1,t_w12-3,ZH); draw_box (t_x2+2,Z1+2,w-t_x2-4,ZH-2); draw_box (t_x2+3,Z1+1,w-t_x2-6,ZH); /* trough border */ set_color(b_c); draw_box (1,Z1+1,t_x1-1,ZH-2); draw_box (2,Z1,t_x1-3,ZH); draw_box (t_x1+1,Z1+1,t_w12-1,ZH-2); draw_box (t_x1+2,Z1,t_w12-3,ZH); draw_box (t_x2+1,Z1+1,w-t_x2-4,ZH-2); draw_box (t_x2+2,Z1,w-t_x2-6,ZH); /* trough inner */ /* the trough in the three-part hist slider is slightly smaller than the full slider range, and cut into three sections */ if(!trough){ trough = new VFrame(ntw,nth,BC_RGBA8888); } if(!trough){ fprintf(stderr,_("Bluebanana: Unable to create Frame for slider\n")); }else{ unsigned char *data = trough->get_data(); float ha = 1.; long bpp = trough->get_bytes_per_pixel(); long bpr = trough->get_bytes_per_line(); float r,g,b,a,rr,gg,bb; if(!highlight){ ha*=.25; tb_r = bg_r; tb_g = bg_g; tb_b = bg_b; } if(!histval){ unsigned char *row = data; for(j=0;j0?nth-histval[i-1]:y; float y1 = i+1troughlines)val=troughlines; histval[i]=val; } } render(); } // ---------------------------- Fill ---------------------------------- int BluebananaSliderFill::over_to_pixel(float input){ return fraction_to_pixel(input/maxover); } float BluebananaSliderFill::pixel_to_over(int pixel){ return pixel_to_fraction(pixel)*maxover; } BluebananaSliderFill::BluebananaSliderFill(BluebananaMain *plugin, BluebananaWindow *gui, int x, int y, int w, int h, float minval, float maxval, float maxover) : BluebananaSlider(plugin,gui,x,y,w,h,minval,maxval){ loval = -2; midval = 0; hival = 2; overval = 0; this->maxover = maxover; } int BluebananaSliderFill::button_press_event(){ if(is_event_win() && cursor_inside()){ //int min; //int max; int cx = get_cursor_x(); gui->deactivate(); if(shift_down()){ /* narrow/widen range */ if(get_buttonpress() == 4){ set_delta(1); return 1; }else if(get_buttonpress() == 5){ set_delta(-1); return 1; } }else if (ctrl_down()){ /* shift all vals up/down */ if(get_buttonpress() == 4){ if(loval-increment>minval) set_fill(loval-1,midval-1,hival-1); return 1; }else if(get_buttonpress() == 5){ if(hival+increment0)lo=0; if(mid>maxval)mid=maxval; if(hi>maxval)hi=maxval; if(lo>midval)mid=lo; if(midhival)hi=mid; if(hi=minval && hival+del<=maxval){ loval-=del; hival+=del; if(loval>hival) loval=hival=rint((loval+hival)/2); if(midvalhival)midval=hival; handle_event(); update(); } } void BluebananaSliderFill::set_over(float over){ if(over>=0 && over<=maxover){ overval=over; handle_event(); update(); } } void BluebananaSliderFill::update(){ int w = get_w(); int h = get_h(); int bg_c = get_resources()->get_bg_color(); int bg_r = ((bg_c >> 16) & 0xff); int bg_g = ((bg_c >> 8) & 0xff); int bg_b = (bg_c & 0xff); int b_c = highlight ? active_bordercolor : inactive_bordercolor; //int b_r = ((b_c >> 16) & 0xff); //int b_g = ((b_c >> 8) & 0xff); //int b_b = (b_c & 0xff); int tb_c = troughcolor; int tb_r = ((tb_c >> 16) & 0xff); int tb_g = ((tb_c >> 8) & 0xff); int tb_b = (tb_c & 0xff); int ZH = Z4-Z1+1; //int ZHC = Z4-ZC+1; int i,j; int xC = value_to_pixel(0); int ntw = troughcols; int nth = troughlines; int ntx = CW+ZL; int nty = Z1+1; clear_box(0, 0, w, h); /* trough shadow */ /* w+4 h+4 x-1 y-1 */ float del = .9; int shadow_c = ((int)(bg_r*del) << 16) | ((int)(bg_g*del) << 8) | ((int)(bg_b*del)); set_color(shadow_c); draw_box (0,Z1,xC+3,ZH+2); draw_box (1,Z1-1,xC+1,ZH+4); draw_box (xC,Z1,w-xC,ZH+2); draw_box (xC+1,Z1-1,w-xC-2,ZH+4); /* w+2 h+2 x y */ del = .8; shadow_c = ((int)(bg_r*del) << 16) | ((int)(bg_g*del) << 8) | ((int)(bg_b*del)); set_color(shadow_c); draw_box (1,Z1+1,xC+1,ZH); draw_box (2,Z1,xC-1,ZH+2); draw_box (xC+1,Z1+1,w-xC-2,ZH); draw_box (xC+2,Z1,w-xC-4,ZH+2); /* w h x+1 y+1 */ del = .7; shadow_c = ((int)(bg_r*del) << 16) | ((int)(bg_g*del) << 8) | ((int)(bg_b*del)); set_color(shadow_c); draw_box (2,Z1+2,xC-1,ZH-2); draw_box (3,Z1+1,xC-3,ZH); draw_box (xC+2,Z1+2,w-xC-4,ZH-2); draw_box (xC+3,Z1+1,w-xC-6,ZH); /* trough border */ set_color(b_c); draw_box (1,Z1+1,xC-1,ZH-2); draw_box (2,Z1,xC-3,ZH); draw_box (xC+1,Z1+1,w-xC-4,ZH-2); draw_box (xC+2,Z1,w-xC-6,ZH); /* trough inner */ /* the trough in the two-part contour slider is slightly smaller than the full slider range, and cut into two sections */ if(!trough){ trough = new VFrame(ntw,nth,BC_RGBA8888); } /* Unlike the hist slider, we just drop the three pixel columns in the center */ if(!trough){ fprintf(stderr,_("Bluebanana: Unable to create Frame for slider\n")); }else{ unsigned char *data = trough->get_data(); long bpr = trough->get_bytes_per_line(); float ha = 1.; if(!highlight){ ha*=.25; tb_r = bg_r; tb_g = bg_g; tb_b = bg_b; } for(i=0;iget_bytes_per_pixel(); for(j=0;j