>
> On 4 Jan 2012, at 13:50, N. Cassetta wrote:
>
> . . .
> I am interested in getting semi-transparent selection rectangles, i.e. =
> coloured boxes that allow to see widgets or text under them with > a
> "blended" colour (with any method!)
> > I tried to rielaborate the image.cxx demo which uses alpha-blending,
> but I don't get what I want:
> . . .
>
>
> Can you describe more of what it is you hope to achieve?
> I think I am not understanding your question, so if you cold outline =
> what you want to do, that might help bring forth some suggestions.
> However, looking at the code fragment you posted, I think that trying > to
> derive the transparent "overlay selection box" form Fl_Box is doomed to
> failure.
I apologize for my poor English, however I think you understood what I wanted:
draw a semi-transparent square on window.
After a few trials I succeeded, by slightly changing the code that I posted.
In the old code tried to derive a class from Fl_Box, putting
box(FL_NO_BOX)
image(img) // a RGB 32 bit image with translucent color
.... but the square was drawn with a solid color.
Instead things work if I write for the class a function fl_draw() that only
draws the image and returns (see the code below)
So, I got this, but I have two questions:
1) I think that the two methods (assign a transparent image as a label in a
FL_NO_BOX box or draw the image in the fl_draw() function) should produce the
same results. Isn'i t a little strange?
2) You have written in your reply:
>
> I think you would do better deriving your own window class, then in
> it's handle() method you can detect the mouse drag action, and in the >
> derived draw() method you simply draw the window content as normal
> (i.e. call the base class draw()...) and then draw a translucent
> rectangle on top of it.
>
But I read in the documentation (Drawing things in FLTK)
FLTK manages colors as 32-bit unsigned integers. Values from 0 to 255 represent
colors from the FLTK 1.0.x standard colormap and are allocated as needed on
screens without TrueColor support.
. . .
Color values greater than 255 are treated as 24-bit RGB values. These are
mapped to the closest color supported by the screen, either from one of the 256
colors in the FLTK 1.0.x colormap or a direct RGB value on TrueColor screens.
You can generate 24-bit RGB color values using the fl_rgb_color() function.
void fl_color(Fl_Color)
Sets the color for all subsequent drawing operations.
So, if I understood, there is no way to choose a translucent color via the
fl_color function: or it's a color-mapped solid color, or a 24 bit RGB (and the
fourth byte is ignored). the only way should be manage RGB images or using
Fl_Offscreen buffers. Is this right?
This is the working code, and thanks for your patience.
// *************************************
#include <FL/Fl.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_Value_Slider.H>
#include <FL/Fl_draw.H>
#include <FL/Fl_Image.H>
using namespace std;
class TransparentBox : public Fl_Box {
public:
TransparentBox(int x, int y, int w, int h, char* l = 0) :
Fl_Box(x, y, w, h) , alpha(0x80) {
box(FL_NO_BOX);
buffer = new unsigned char[4*w*h];
img = new Fl_RGB_Image(buffer, w, h, 4);
//image(img); // this is wrong!! You'll get a "solid" box
color((Fl_Color)0);
}
void color(Fl_Color c) {
r = (c >> 24);
g = (c >> 16);
b = (c >> 8);
fill_buffer();
img->uncache();
}
void set_alpha(unsigned char a) {
alpha = a;
fill_buffer();
img->uncache();
}
protected:
virtual int handle(int e) { // allows to drag the TransparentBox
static int xn, yn;
switch(e) {
case FL_PUSH:
xn = Fl::event_x() - x();
yn = Fl::event_y() - y();
return 1;
case FL_DRAG:
position(Fl::event_x() - xn, Fl::event_y() - yn);
window()->redraw();
return 1;
case FL_RELEASE:
return 1;
default:
return 0;
}
}
// ******** it's sufficient to add this function for getting alpha blending
virtual void draw() {
img->draw(x(), y());
}
// ********
private:
void fill_buffer() {
uchar *p = buffer;
for (int i = 0; i < 4*w()*h(); i+=4) {
*p++ = r;
*p++ = g;
*p++ = b;
*p++ = alpha;
}
}
unsigned char* buffer;
unsigned char r;
unsigned char g;
unsigned char b;
unsigned char alpha;
Fl_RGB_Image* img;
};
class MainWindow : public Fl_Double_Window {
public:
MainWindow(): Fl_Double_Window(100, 100, 600, 300, "Try to drag the square
over sliders!") {
Sl_R = new Fl_Value_Slider(40, 40, 30, 100, "Red");
Sl_R->range(0, 255); Sl_R->step(1);
Sl_R->callback(slider_cb);
Sl_G = new Fl_Value_Slider(80, 40, 30, 100, "Green");
Sl_G->range(0, 255);
Sl_G->step(1);
Sl_G->callback(slider_cb);
Sl_B = new Fl_Value_Slider(120, 40, 30, 100, "Blue");
Sl_B->range(0,255);
Sl_B->step(1);
Sl_B->callback(slider_cb);
Sl_a = new Fl_Value_Slider(160, 40, 30, 100, "alpha");
Sl_a->range(0, 255);
Sl_a->step(1);
Sl_a->callback(slider_cb);
Tbox = new TransparentBox(200, 20, 200, 200);
Tbox->box(FL_FLAT_BOX);
end();
}
private:
static void slider_cb(Fl_Widget* w, void* p) {
MainWindow* mw = (MainWindow* )(w->window());
if (w == mw->Sl_a)
mw->Tbox->set_alpha(mw->Sl_a->value());
else
mw->Tbox->color(fl_rgb_color(mw->Sl_R->value(), mw->Sl_G->value(),
mw->Sl_B->value()));
mw->Tbox->redraw();
}
Fl_Value_Slider* Sl_R;
Fl_Value_Slider* Sl_G;
Fl_Value_Slider* Sl_B;
Fl_Value_Slider* Sl_a;
Fl_Box* Lbox;
TransparentBox* Tbox;
};
int main()
{
MainWindow* mwin = new MainWindow ();
mwin->show();
return Fl::run();
}
_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk