one widget overlaying another widget
Added by Arjan Vermeij about 13 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 about 13 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 about 13 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 about 13 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 about 13 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 about 13 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 about 13 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 about 13 years ago
Filed a bug report for both issues. Cheers, Arjan.
RE: one widget overlaying another widget - Added by Arjan Vermeij about 13 years ago
For the first issue: http://redmine.emweb.be/issues/1020
The second issue: http://redmine.emweb.be/issues/1021
Good luck. Arjan.
RE: one widget overlaying another widget - Added by Mohammed Rashad about 13 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 about 13 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 about 13 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 about 13 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.
moon-ahead-2.png (135 KB) moon-ahead-2.png |
RE: one widget overlaying another widget - Added by Arjan Vermeij about 13 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.