gtk_scrolled_window_set_policy(...GTK_NEVER...) question



When using gtk_scrolled_window_add_with_viewport and
gtk_scrolled_window_set_policy(...,GTK_POLICY_NEVER,...), and gtk+-1.2.7 on
an otherwise relatively vanilla Red Hat 6.0 Linux system, it seems to me that
widgets within the scrolledwindow are allocated all the size they request,
even though the allocated space can't be displayed or scrolled to, and this
allocation causes other widgets (which could otherwise fit in the displayed
area) also not to fit.  I've appended a program which demonstrates this
(hope it's not too long).

Is this supposed to happen (instead of the allocation being limited to the
size of the window)?  I can work around it in my application by catching
the size_request signal for the problematic widget (or, I guess, the viewport)
and setting its requisition to 0, but I'd like to know whether the comment
should say I'm fighting a feature or working around a bug, or whether there's
a better way.

The real UI problem I'm trying to solve is for a polyrhythm/drum-machine
program, which you can see at http://www.pobox.com/~asl2/music/RhythmLab/.
Moving the mouse over a particular beat of a particular track causes a
text widget to display variable-length info about its current volume and
other stuff.  If that text widget doesn't fit into the user's selected
window size, I'd rather have it truncated than have all the widgets change
size as the mouse moves about.  (If you really want to see a test version
with scrollbars exhibiting the behavior about which I'm complaining, see
ftp://ftp.enteract.com/users/asl2/RhythmLab-0.33.tar.gz.)  Suggestions
for other ways of going about this are welcome.

              Aaron Lav

/* 
   Compile as C++, then click on a row to watch it lengthen, and,
   eventually, the other rows center themselves in an increasingly
   large window and be truncated.
*/ 

#include <gtk/gtk.h>
#include <gdk/gdk.h>
#define __USE_ISOC9X
#include <stdio.h>
#include <string.h>
#define min(a,b) ((a) < (b) ? (a) : (b))

#define N_TRACKS 20

typedef struct {
  unsigned int cnt;
  GtkWidget *text;
} Track;

Track ts[N_TRACKS];

int button_release (GtkWidget *w, GdkEventButton *e, gpointer data)
{
  Track *t = (Track *) data;
  char buf [200];
  size_t to_set = min ((sizeof buf) - 1, t->cnt++);
  memset (buf, 'a', to_set);
  buf [to_set] = 0;
  gtk_label_set_text (GTK_LABEL(t->text), buf);
  return TRUE;
}

int size_request (GtkWidget *w, GtkRequisition *r)
{
  printf ("Request %d %d\n", r->width, r->height);
  return FALSE;
}

int size_allocate (GtkWidget *w, GtkAllocation *a)
{
  printf ("Allocation %d %d %d %d\n",a->x, a->y, a->width, a->height);
  return FALSE;
}

void add_tracks (GtkWidget *box)
{
  int i;

  for (i = 0; i < N_TRACKS; i++) {
    char buf [40];
    snprintf (buf, sizeof buf, "click me %d", i);
    ts[i].text = gtk_label_new (buf);
    if (!i) {
      gtk_signal_connect(GTK_OBJECT(ts[i].text), "size_request", 
			 GTK_SIGNAL_FUNC(size_request), 0);
      gtk_signal_connect(GTK_OBJECT(ts[i].text), "size_allocate", 
			 GTK_SIGNAL_FUNC(size_allocate), 0);
    }
    ts[i].cnt = 0;

    GtkWidget *ev_box = gtk_event_box_new ();
    gtk_widget_set_events (ev_box, 
			 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
    gtk_signal_connect (GTK_OBJECT(ev_box), "button_release_event", 
			GTK_SIGNAL_FUNC(button_release), ts + i);

    gtk_widget_show (ts[i].text);
    gtk_container_add (GTK_CONTAINER(ev_box), ts[i].text);
    gtk_box_pack_start (GTK_BOX(box), ev_box, FALSE, FALSE, 0);
    gtk_widget_show (ev_box);
  }
}

int main (int argc, char **argv)
{
  GtkWidget *mainwnd;

  GtkWidget *scroll_window;
  GtkWidget *display_area;

  GtkWidget *tracks_vbox;
  GtkWidget *to_add;

  gtk_init (&argc, &argv);

  mainwnd = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title (GTK_WINDOW(mainwnd), "click on row to lengthen");
 
  gtk_widget_show (mainwnd);
  display_area = gtk_vbox_new (FALSE, 5);
  gtk_container_add (GTK_CONTAINER (mainwnd), display_area);
  gtk_widget_show (display_area);

  tracks_vbox = gtk_vbox_new (FALSE, 5);

  scroll_window = gtk_scrolled_window_new (NULL, NULL);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(scroll_window),
				  GTK_POLICY_NEVER,
				  GTK_POLICY_AUTOMATIC);
  gtk_widget_show (scroll_window);

#if 1
  gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW(scroll_window),
					 tracks_vbox);
  to_add = scroll_window;
#else
  to_add = tracks_vbox;
#endif

  /* Without the scrolled window, changes in the size of 1 track
     don't affect the rest of the display. */
  gtk_box_pack_start (GTK_BOX(display_area), to_add, TRUE, TRUE, 0);
  gtk_widget_show (tracks_vbox);
  add_tracks (tracks_vbox);

  gtk_main ();
}















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