gtkmm - drawing primitives (and text) on window with keeping an old content - c++

I want to draw some primitives (for example lines or text) on given window with gtkmm (gdkmm / gdk) with keeping old content of this window. I guess that using DrawingArea widget may be no helpful because I need draw on the old pixbuf.
Maybe I need to rearrange this pixbuf and load it again to this window? Is it possible?
Maybe I need to instert something between begin_paint_region() and end_paint()?
thanks.

Related

Render an user interface in memory

let's say I have hwnd handle and would like to add some GUI controls in memory. I also receive all user input via events.
So, is it possible to use wxwidgets to add a user interface to an image which will be drawn onto the a Window ( using such hwnd handle ). If so, does wxwidget have some facilities to keep track of state of the GUI?
I'm new to wxwidgets and so please excuse my general questions.
Many thanks,
Christian
The only way to add GUI controls to an image, is to draw them yourself. The only way to do that, would be to create an image GUI element, and position the other GUI elements relative to the image element. However, this will not do double-buffering of the UI like you want to do, it doesn't actually draw the UI elements in the image, just places them on top of the image.

resizing QGLWidget to fit with each sprite size I have

I'm creating 2D Map editor using opengl to draw simple 32x32 sprites but it seems that I cannot resize my QGLWidget to a large size (i.e size * sprite size -> 1024 * 32), using 1024 only seems to work fine (using glwidget->setMinimumSize(...)). I've been googling for a while now about this, the only interesting thing I found is subclassing QAbstractScrollArea and setting my QGLWidget as it's viewport (That's what QGraphicsView does), I also seen all Qt opengl examples but i couldn't find anything that could help (except Image Viewer example which is not exactly what I want), I also tried the following:
horizontalScrollBar()->setMaximum(width * 32);
verticalScrollBar()->setMaximum(height * 32);
with the widget resizable set to true/false on the scrollarea but still nothing.
Any ideas how would I do that? I can show more code if you ask me to.
Using Qt v4.7.3.
I have two ideas:
If it's possible, drop the idea of using a QGLWidget and place the sprites directly in a graphics scene (QGraphicsPixmapItem). Possibly not what you want, but the graphics scene is made to handle a lot of items, so most things you need (trigger mouse events on items for example) are already implemented.
Or just place the QGLWidget in a graphics scene using a QGraphicsWidget. This should automatically tell the scene its size, which then tells the view the size of the scene. The scroll bars appear automatically if the scene doesn't fit into the view.
Update:
As described in this link, you can use OpenGL in any graphics view:
view.setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers)));
view.setViewportUpdateMode(QGraphicsView::FullViewportUpdate);

what's the best way to display images in qt? also I would like to zoom in to particular areas as well

I've been using label to display images. I'd like to be able to click and create a bounding box then be able to drag the cursor to move around in the image. What would I need to do this? Thanks.
I'm not 100% sure I understand what you are trying to do, but I think the QGraphicsScene is what you are looking for. You can (among many other things):
Render images (QGraphicsPixmapItem, for example)
Change the zoom level when rendering the scene on a QGraphicsView.
Select things using a "rubber band"
Move items around with the mouse (see QGraphicsItem::ItemIsMovable)
etc.
You may need to get familiar with Qt's graphics view framework.

Coordinate confusion

I subclassed QGraphicsItem and reimplemented paint.
In paint I wrote something like this for labeling the item:
painter->drawText("Test",10,40);
After some time I think It may be useful to handle labeling with seperate item. So I wrote something like this.
QGraphicsTextItem *label = new QGraphicsTextItem("TEST",this);
setPos(10,40);
But two "TEST" drawing do not appear in the same place on screen. I guess difference may be related with item coordinates - scene coordinates. I tried all mapFrom... and mapTo... combinations inside QGraphicsItem interface but no progress. I want to drawings to appear in the same place on screen.
What I miss?
I assume that you are using the same font size and type in both cases. If the difference in position is very small the reason can be the QGraphicTextItem is using some padding for the text it contains. I would try to use QGraphicsSimpleTextItem that is not going to add fancy stuff internally and see if you still have the same problem. The coordinates system is the same one if you use painter or setPost so that is not the problem. If this doesn't help I will suggest to specify the same rect for both to avoid Qt adding it owns separation spaces.

Transparent window containing opaque text and buttons

I'm creating a non-intrusive popup window to notify the user when processing a time-consuming operation. At the moment I'm setting its transparency by calling SetLayeredWindowAttributes which gives me a reasonable result:
alt text http://img6.imageshack.us/img6/3144/transparentn.jpg
However I'd like the text and close button to appear opaque (it doesn't quite look right with white text) while keeping the background transparent - is there a way of doing this?
In order to do "proper" alpha in a layered window you need to supply the window manager with a PARGB bitmap by a call to UpdateLayeredWindow.
The cleanest way to achieve this that I know of is the following:
Create a GDI+ Bitmap object with the PixelFormat32bppPARGB pixel format.
Create a Graphics object to draw in this Bitmap object.
Do all your drawing into this object using GDI+.
Destroy the Graphics object created in step 2.
Call the GetHBITMAP method on the Bitmap object to get a Windows HBITMAP.
Destroy the Bitmap object.
Create a memory DC using CreateCompatibleDC and select the HBITMAP from step 5 into it.
Call UpdateLayeredWindow using the memory DC as a source.
Select previous bitmap and delete the memory DC.
Destroy the HBITMAP created in step 5.
This method should allow you to control the alpha channel of everything that is drawn: transparent for the background, opaque for the text and button.
Also, since you are going to be outputting text, I recommend that you call SystemParametersInfo to get the default antialiasing setting (SPI_GETFONTSMOOTHING), and then the SetTextRenderingHint on the Graphics object to set the antialiasing type to the same type that is configured by the user, for a nicer look.
I suspect you'll need two top level windows rather than one - one that has the alpha blend and a second that is display above the first with the opaque text and button but with a transparent background. To accomplish this with a single window you'll need to use the UpdateLayeredWindow API call, but using this will cause your buttons to not redraw when they are interacted with (hover highlights, focus etc.)
It is possible that if this application is for Vista only there is a new API call that you can use, but I do not believe it is available in XP or earlier.
I can't say for sure, you'll need to try it, but since everything is a window, you could try setting the layered attributes for your button to make it opaque.
As for the text, you may be able to put that in its own frame with a set background and foreground color, and modify its layered attributes to make the background color transparent...
But since these are child windows and not the top-level window, I really don't know that it'll work.