> > 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 fltk@easysw.com http://lists.easysw.com/mailman/listinfo/fltk