Project

General

Profile

one widget overlaying another widget

Added by Arjan Vermeij over 12 years ago

I have a Wt::WImage widget that shows an mjpeg stream from a camera. The position of this widget is managed by a layout manager.

I would like to overlay this (bottom) widget with another (top) widget, which allows me to paint for example cross hairs over the image coming from the camera. The top widget would be mostly transparent, which allows the bottom widget to remain visible.

Is such a thing possible? Help is much appreciated. Thanks. Arjan.


Replies (13)

RE: one widget overlaying another widget - Added by Bart AM over 12 years ago

I asked a quite similar question on overlaying in this post :

http://redmine.webtoolkit.eu/boards/2/topics/2849

Maybe the "absolute positionning" thing will do the job (just replace the WPaintedWidget by your upper widget).

Hope it help.

Regards,

Bart

RE: one widget overlaying another widget - Added by Koen Deforche over 12 years ago

Hey,

That is not as straight forward because you also want to resize both the image and overlay at the same time using the layout manager.

Perhaps the easiest way to get there is by borrowing the way a WStackedWidget interacts with a layout manager to resize all its children, using the following structure inside the layout item:

 WStackedWidget
  WImage
  WPaintedWidget (or other)

Then you set the overlay widget to use absolute positioning, and make sure both are being shown (overriding the way a stack widget actually works).

 stack->setCurrentIndex(0); // show WImage
 overlay->show();           // override the overlay being hidden by the stack

Regards,

koen

RE: one widget overlaying another widget - Added by Arjan Vermeij over 12 years ago

Hi Koen.

After some trial and error I found that it actually works! This is what I had to do:

Wt::WStackedWidget * const wStackedWidget = new Wt::WStackedWidget ();
Wt::WImage * const wImage = new MyWImage ();
Wt::WPaintedWidget * const wPaintedWidget = new MyWPaintedWidget ();

wPaintedWidget->setWidth (Wt::WLength (80.0, Wt::WLength::Pixel));
wPaintedWidget->setHeight (Wt::WLength (80.0, Wt::WLength::Pixel));
wStackedWidget->addWidget (wImage);
wStackedWidget->addWidget (wPaintedWidget);
wStackedWidget->setCurrentIndex (0);
wImage->setPositionScheme (Wt::Absolute);
wPaintedWidget->setPositionScheme (Wt::Absolute);
wPaintedWidget->show ();

It apparently only works when both widgets use absolute positioning.

Another caveat that took me a while to figure out is that the painted widget needs to be given an explicit size. The next step is to see if I can make the size of the painted widget the same as the size of the image.

Thanks a lot. Arjan.

RE: one widget overlaying another widget - Added by Arjan Vermeij over 12 years ago

Koen,

I managed to make the painted widget the same size as the image, it's very simple, the image is layout size aware and whenever its size changes it calls the setWidth and setHeight method of the painted widget, so it all works perfectly well now.

I stumbled across a peculiar phenomenon, though, see attached screen captures. One is with a stacked widget that is not layout size aware, which shows the intended behaviour: an image with a box and a few lines painted over it. The other screen capture shows the result with a stacked widget that is layout size aware. My image is no longer fitted to its container, and my painted widget has disappeared.

class MyWStackedWidget : public Wt::WStackedWidget
{
  public:

    MyWStackedWidget ()
      : Wt::WStackedWidget ()                                           
    { 
      setLayoutSizeAware (false); // or true
    } 
};

...

  Wt::WStackedWidget * const wStackedWidget = new MyWStackedWidget ();
  // rest of the code as in previous comment

RE: one widget overlaying another widget - Added by Arjan Vermeij over 12 years ago

Something else came up. If I add a painted widget that is layout size aware:

setLayoutSizeAware (true);

Then my painted widget does not show up. If I set the width and height to some initial value, like one pixel:

setWidth (Wt::WLength (1.0, Wt::WLength::Pixel));
setHeight (Wt::WLength (1.0, Wt::WLength::Pixel));
setLayoutSizeAware (true);

Then my painted widget does show up!

RE: one widget overlaying another widget - Added by Koen Deforche over 12 years ago

Hey Arjan,

w.r.t. first problem: this is an interference between internal use of hook for reacting to layout size changes and the layoutSizeAware() feature --- something that came up also in another forum thread.

This should be fixed in Wt --- can you file a bug for that ?

setLayoutSizeAware(true) for a WPaintedWidget should not fail (and in fact, is not necessary --- a WPaintedWidget is already layout size aware). So that is a second bug.

Regards,

koen

RE: one widget overlaying another widget - Added by Arjan Vermeij over 12 years ago

Filed a bug report for both issues. Cheers, Arjan.

RE: one widget overlaying another widget - Added by Mohammed Rashad over 12 years ago

plot_ = new Plot(canvasWidth, canvasHeight, this);

plot_->setPositionScheme(Absolute);

plot_->setOffset(Left | Top, 0);

editor_ = new Editor(canvasWidth, canvasHeight, this);

editor_->setPositionScheme(Absolute);

editor_->setOffset(Left | Top, 0);

editor_->setPopup(true);

This will put 'Editor' on top of 'Plot'

RE: one widget overlaying another widget - Added by Arjan Vermeij over 12 years ago

All worked great, until I started playing around with WSlider's: it is as if the absolute positioning for widgets on top of a WSlider does not work.

In the attached screen shot you see a stack with 5 child widgets that all use absolute positioning. The first widget is an image widget showing the bicycle. The second one idem, showing the blueish moon, nicely painted on top of the first image. The third widget is a slider widget, also nicely painted on top of the first two images. The fourth widget is an image widget showing the warning hand. It should have been painted over the first three widgets. The fifth widget is the second slider bar, painted over the warning hand.

What could possibly cause this behaviour?

Thanks a lot. Arjan.

RE: one widget overlaying another widget - Added by Koen Deforche over 12 years ago

Hey,

Did you set the offsets (left and top) to 0 of the absolutely positioned widgets ?

Regards,

koen

RE: one widget overlaying another widget - Added by Arjan Vermeij over 12 years ago

Thanks for the suggestion Koen, I tried it, there is definitely an improvement, the fourth widget (the warning hand) is now painted in the correct spot. But the fifth widget (the second slider) is still in the wrong place, see screen shot.

Something else has changed too: the images are no longer in the middle of the encompassing panel widget. Again it is as if the panel widget is too high, see http://redmine.emweb.be/boards/2/topics/3118

Thanks a lot. Arjan.

RE: one widget overlaying another widget - Added by Arjan Vermeij over 12 years ago

By the way, is it correct that the knob of the slider is painted on top of the warning hand, where the rest of the slider is behind the warning hand?

Arjan.

    (1-13/13)