Re: See-through container



Tristan Van Berkom wrote:

> David E. Konerding wrote:
>
>> Hi folks,
>>
>> I previously posted a question about containers; specifically, i want to
>> have a layout container in which drawing
>> done to the parent window "shows through" layout where nothing is placed
>> on the layout.  Here's an example of what's not working for me.
>> The diagonal line is obscured by the inner_layout Layout container,
>> although I am setting the back_pixmap for the Layout's window and
>> bin_window to NULL, which is supposed to do what I want.  Anybody have
>> any suggestions?
>>  
>>
>
> You dont need to mess with gdk_window_set_back_pixmap(), it
> should be irrelevent in this context (it sets the X server with
> a default background for your GdkWindow)
>
Yes, and it's the default background being painted which is the
problem.  My read of the documentation
is that if you set a NULL back_pixmap, the window doesn't get painted
with anything and the original contents of the "underlying"
parent window shows through.  Right now, X is automatically painting a
single color to the region, whatever color
I set using gtk_widget_set_background.


> You should simply try doing:
>    GTK_WIDGET_SET_FLAGS (layout, GTK_NO_WINDOW)
> on your layout *before* it gets realized.
>
I tried this (inserting this line directly after gtk_layout_new).  It
doesn't work.  How could it?  The realize handler for gtk_layout_realize
always makes a child window and a child bin_window regardless of that
flag setting.

More importantly, a GtkFrame works just fine; if you place a GtkFrame
onto a Layout that has line drawing on it,
the line drawing does show through, even through the GtkFrame has a
window!  I've attached an example of code demonstrating just
that.  From my perspective, the only difference in a GtkFrame and 
GtkLayout is that the GtkFrame has the border and can contain only a
single child.


> Remember that GTK_NO_WINDOW widgets draw to there
> parent windows, so when you do gdk_draw_line, you should
> not ignore widget->allocation.[xy]  :)
>
Yes, and if I'm going to make a Layout be a GTK_NO_WINDOW, then I would
just write my own NO_WINDOW container, but
then obviously whenever I place children widgets in the layout I have to
adjust it for the allocation as you said.  That much I've
already got working.  I just wanted to find a much simpler solution.


#include <stdio.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>

static gboolean layout_expose(GtkWidget *widget, GdkEventExpose *event) {
  printf("expose, %d, %d\n", event->area.width, event->area.height);
  GtkLayout *layout = GTK_LAYOUT(widget);
  gdk_draw_line (layout->bin_window,
         widget->style->black_gc,
         0, 0,
         widget->allocation.width, widget->allocation.height);
}

static gboolean inner_layout_realize(GtkWidget *widget, GdkEventExpose
*event) {
  printf("realize\n");
  GtkLayout *layout = GTK_LAYOUT(widget);
  /* an attempt to make a 'see-through inner layout' which doesn't work */
#if 0
  gdk_window_set_back_pixmap(widget->window, NULL, FALSE);
  gdk_window_set_back_pixmap(layout->bin_window, NULL, FALSE);
#endif
}

int main( int   argc,
          char *argv[] ) {
  /* GtkWidget is the storage type for widgets */
  GtkWidget *window, *layout, *inner_layout, *label, *inner_frame,
*frame_label;
  GdkColor color;

  /* Initialise GTK */
  gtk_init (&argc, &argv);
   
  /* Create a new window */
  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title (GTK_WINDOW (window), "Frame Example");

  /* Here we connect the "destroy" event to a signal handler */
  g_signal_connect (G_OBJECT (window), "destroy",
            G_CALLBACK (gtk_main_quit), NULL);

  gtk_widget_set_size_request (window, 500, 500);

  /* Create a layout */
  layout = gtk_layout_new (NULL, NULL);
  gtk_container_add (GTK_CONTAINER (window), layout);
  gtk_widget_set_size_request (layout, 500, 500);
  gtk_widget_show (layout);

  /* Create an inner layout */
  inner_layout = gtk_layout_new (NULL, NULL);
  /* one attempt to make a 'see-through' inner layout; does not work */
  GTK_WIDGET_SET_FLAGS (inner_layout, GTK_NO_WINDOW);
  gtk_layout_put (GTK_LAYOUT (layout), inner_layout, 100, 100);
  gtk_widget_set_size_request (inner_layout, 200, 200);
  gtk_widget_show (inner_layout);

  /* Create a label in inner layout */
  label = gtk_label_new ("Test");
  gtk_layout_put (GTK_LAYOUT (inner_layout), label, 30, 30);
  gtk_widget_show (label);

  /* Create an frame */
  inner_frame = gtk_frame_new ("Test");
  gtk_layout_put (GTK_LAYOUT (layout), inner_frame, 400, 400);
  gtk_widget_show (inner_frame);
 
  /* Create a label in inner frame */
  frame_label = gtk_label_new ("Test2");
  gtk_container_add (GTK_CONTAINER (inner_frame), frame_label);
  gtk_widget_show (frame_label);

  g_signal_connect (G_OBJECT (layout), "expose_event",
            G_CALLBACK (layout_expose), NULL);
  g_signal_connect (G_OBJECT (inner_layout), "realize",
            G_CALLBACK (inner_layout_realize), NULL);



  /* Create a layout inside the layout */
  /* Display the window */
  gtk_widget_show (window);
   
  /* Enter the event loop */
  gtk_main ();
   
  return 0;
}


Dave



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]