>
> 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

Reply via email to