Re: locating a widget in a scrolled window

2005-04-10 Thread Stephen Bach
Hi Irtza, 

On Sun, Apr 10, 2005 at 09:48:24PM -0400, Irtza Sharif wrote:
 Thank you for your response.  Let me clarify my situation.
 
 I have a Scrolled Window within which I add a vbox
 
 The widgets inside the vbox are held in a linked list that I have
 setup.  New widgets can be created and added to this vbox within the
 scrolled window while the program is running.  When these new widgets
 are created and added, I would like to shift the scrolled window to
 show this widget.

If the new widgets are direct children of the vbox (which is a direct
child of the scrolled window's viewport), you should be able to do
something like this:

void scroll_to(GtkWidget* scrolled_window, GtkWidget* widget) {

gdouble page_inc, step_inc, upper, lower, pos;

GtkAdjustment* vadj = gtk_scrolled_window_get_vadjustment(
GTK_SCROLLED_WINDOW(scrolled_window));

page_inc = vadj-page_increment;
step_inc = vadj-step_increment;
lower = vadj-lower;

/* Otherwise we sometimes scroll down into a page of black. */
upper = vadj-upper - page_inc - step_inc;

/* Center on the widget. */
pos = (gdouble)widget-allocation.y - page_inc/2;

gtk_adjustment_set_value(vadj, CLAMP(pos, lower, upper));
}


This only takes into account the vertical, but I think the horizontal
could be done similarly.

If the new widgets aren't direct children of the vbox, you could still
probably do this by recursing up through widget-parent until you get to
the vbox, remapping the coordinates along the way.

Hope this helps,

Stephen

___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


GtkAdjustment smooth scrolling

2005-03-31 Thread Stephen Bach
Hello,

I use a scrolled window in a program of mine, and I've noticed that if I
set the value of its adjustment manually, the window is immediately
scrolled to the given position.  For example, with something like the
following code (where vadj is the vertical adjustment of the window):

gdouble current = gtk_adjustment_get_value(vadj);
gtk_adjustment_set_value(vadj,
CLAMP(current + vadj-page_increment, vadj-lower, vadj-upper));

The scrolled window appears at the given area instantly.  If I just use
the Page Down key, however, the scrolling is smooth, gradual.  I have no
real preference to either behaviour -- what I don't like is the
inconsistency.

I glanced through the source for GtkAdjustment and GtkScrolledWindow, but
nothing jumped out at me as being the implementation of the smooth
scrolling.  Could someone here help me out or point me in the right
direction?

Thanks,

Stephen

___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: gtk_widget_queue_resize() forgetting allocation

2004-09-27 Thread Stephen Bach
On Mon, Sep 27, 2004 at 12:35:54PM -0400, Owen Taylor wrote:
 So, I'd actually appreciate it if you could file a bug in bugzilla
 with your test case as an attachment and a link to this analysis
 in the mail.gnome.org archives.

Done.

 Two easy workarounds for your problem you might want to try:
 
  - Change the resize mode on the Viewport to PARENT after creating it.
 
  - Do your label_resize in a handler for 'size-allocate' on the
toplevel rather than '::configure-event'.

I went with a modified version of the second one, and all is well.  Thanks --
your input was invaluable.

Stephen

___
gtk-list mailing list
[EMAIL PROTECTED]
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: gtk_widget_queue_resize() forgetting allocation

2004-09-25 Thread Stephen Bach
For posterity:

I isolated the issue to the GtkViewport widget.  I found that if I packed the
label/vbox into a GtkLayout and packed that into the GtkScrolledWindow,
the size negotiations worked the way they should.  I don't know if the
problem is caused by some function of the viewport that I don't understand,
but I'm not going to spend any more time on it.  Using a layout works, though
it requires a little more massaging.

The only problem I have now is that the step_increment field of the vertical
GtkAdjustment in the scrolled window doesn't update itself upon resize, and
indeed sits at zero.  But I can deal with that.

On Sun, Sep 19, 2004 at 12:02:48PM -0400, Stephen Bach wrote:
 
 stuff

___
gtk-list mailing list
[EMAIL PROTECTED]
http://mail.gnome.org/mailman/listinfo/gtk-list


GtkLayout and {h,v}adjustment-step_increment

2004-09-25 Thread Stephen Bach
Just a quick question.  The gtk_layout_size_allocate() function seems to set
the page_increment fields of its layout's GtkAdjustments, but not the
step_increment fields.

So in, say, gtk_set_hadjustment_values() and gtk_set_vadjustment_values()
(called in gtk_viewport_size_allocate()) of gtkviewport.c:
...
hadjustment-page_size = view_allocation.width;
hadjustment-step_increment = view_allocation.width * 0.1;
hadjustment-page_increment = view_allocation.width * 0.9;
hadjustment-lower = 0;
...
vadjustment-page_size = view_allocation.height;
vadjustment-step_increment = view_allocation.height * 0.1;
vadjustment-page_increment = view_allocation.height * 0.9;
vadjustment-lower = 0;
...

But in gtk_layout_size_allocate() of gtklayout.c:
...
layout-hadjustment-page_size = allocation-width;
layout-hadjustment-page_increment = allocation-width * 0.9;
layout-hadjustment-lower = 0;
...
layout-vadjustment-page_size = allocation-height;
layout-vadjustment-page_increment = allocation-height * 0.9;
layout-vadjustment-lower = 0;
...

This means that clicking the steppers in the scrollbars for the layout do
nothing.  In my program I've set step_increment manually by connecting to the
allocate signal of the layout, but I'm wondering what the reason is for the
missing functionality.

Thanks,

Stephen

___
gtk-list mailing list
[EMAIL PROTECTED]
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: gtk_widget_queue_resize() forgetting allocation

2004-09-22 Thread Stephen Bach
No one has any insight here?  It seems to me that a call to
gtk_widget_size_request() should be followed by a gtk_widget_size_allocate()
when generated by a gtk_widget_queue_resize(), especially if the program goes
idle.

Is there something about the size negotiation process that I'm
misunderstanding?

Thanks

On Sun, Sep 19, 2004 at 12:02:48PM -0400, Stephen Bach wrote:
 Hello,
 
 I've run into an issue in a program I'm writing where sometimes a call to
 gtk_widget_queue_resize() ends in a request rather than an allocate.  I've
 put together a short test case (tested in GTK+ 2.4.4) which keeps the spirit
 of the program intact (see below).
 
 First, a little context -- connecting to the toplevel window's
 configure-event to queue a resize on one of its grandchildren probably seems
 unconventional and even redundant, but it's a requirement of my program (not
 this test case) because the request function of that grandchild optimizes
 itself to the window's width (i.e. the grandchild needs more information than
 just the size requests of its children).  In the real program the change in
 the window's width is passed on and then the queue_resize is made.
 
 All of that is beside the point.  Here is the problem: _sometimes_ when the
 window is resized, there is no allocation of the grandchild label after a
 request.  If the window is resized again, _then_ the allocation happens
 (usually followed by another unfulfilled size request).
 
 One thing that's kind-of strange is that if the label is added directly to
 the scrolledwindow (without being added to the vbox, which then gets put into
 the scrolledwindow), everything works as it should -- every size request is
 followed by a size allocate.  I also tried using a table instead of a vbox,
 but the result is the same.
 
 Insight welcome.
 
 Thanks,
 
 Stephen
 
 =
 
 #include gtk/gtk.h
 
 static void
 allocate_callback(GtkWidget *label, GtkAllocation *allocation, gpointer data) {
   g_print((allocate));
 }
 
 static void
 request_callback(GtkWidget *label, GtkRequisition *requisition, gpointer data) {
   g_print((request));
 }
 
 static gboolean
 configure_callback(GtkWidget* window, GdkEventConfigure* event, gpointer data) {
   GtkWidget* label = data;
 
   /* Only queue resize if the width is changed */
   if (event-width != window-allocation.width)
   gtk_widget_queue_resize(label);
 
   return FALSE;
 }
 
 int
 main(int argc, char* argv[]) {
 
   GtkWidget* window;
   GtkWidget* scrolled_window;
   GtkWidget* vbox;
   GtkWidget* label;
 
   gtk_init (argc, argv);
 
   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
   scrolled_window = gtk_scrolled_window_new(NULL, NULL);
   vbox = gtk_vbox_new(FALSE, 0);
   label = gtk_label_new(Testing);
 
   g_signal_connect(G_OBJECT(label), size-allocate,
G_CALLBACK(allocate_callback), NULL);
   g_signal_connect(G_OBJECT(label), size-request,
G_CALLBACK(request_callback), NULL);
   g_signal_connect(G_OBJECT(window), configure-event,
G_CALLBACK(configure_callback), label);
 
   gtk_scrolled_window_set_policy(
   GTK_SCROLLED_WINDOW(scrolled_window),
   GTK_POLICY_NEVER,
   GTK_POLICY_ALWAYS);
 
   gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
   gtk_scrolled_window_add_with_viewport(
   GTK_SCROLLED_WINDOW(scrolled_window), vbox);
   gtk_container_add(GTK_CONTAINER(window), scrolled_window);
 
   gtk_widget_show(label);
   gtk_widget_show(vbox);
   gtk_widget_show(scrolled_window);
   gtk_widget_show(window);
 
   gtk_main();
 
   return 0;
 }
 
 ___
 gtk-list mailing list
 [EMAIL PROTECTED]
 http://mail.gnome.org/mailman/listinfo/gtk-list
 
 
___
gtk-list mailing list
[EMAIL PROTECTED]
http://mail.gnome.org/mailman/listinfo/gtk-list


gtk_widget_queue_resize() forgetting allocation

2004-09-19 Thread Stephen Bach
Hello,

I've run into an issue in a program I'm writing where sometimes a call to
gtk_widget_queue_resize() ends in a request rather than an allocate.  I've
put together a short test case (tested in GTK+ 2.4.4) which keeps the spirit
of the program intact (see below).

First, a little context -- connecting to the toplevel window's
configure-event to queue a resize on one of its grandchildren probably seems
unconventional and even redundant, but it's a requirement of my program (not
this test case) because the request function of that grandchild optimizes
itself to the window's width (i.e. the grandchild needs more information than
just the size requests of its children).  In the real program the change in
the window's width is passed on and then the queue_resize is made.

All of that is beside the point.  Here is the problem: _sometimes_ when the
window is resized, there is no allocation of the grandchild label after a
request.  If the window is resized again, _then_ the allocation happens
(usually followed by another unfulfilled size request).

One thing that's kind-of strange is that if the label is added directly to
the scrolledwindow (without being added to the vbox, which then gets put into
the scrolledwindow), everything works as it should -- every size request is
followed by a size allocate.  I also tried using a table instead of a vbox,
but the result is the same.

Insight welcome.

Thanks,

Stephen

=

#include gtk/gtk.h

static void
allocate_callback(GtkWidget *label, GtkAllocation *allocation, gpointer data) {
g_print((allocate));
}

static void
request_callback(GtkWidget *label, GtkRequisition *requisition, gpointer data) {
g_print((request));
}

static gboolean
configure_callback(GtkWidget* window, GdkEventConfigure* event, gpointer data) {
GtkWidget* label = data;

/* Only queue resize if the width is changed */
if (event-width != window-allocation.width)
gtk_widget_queue_resize(label);

return FALSE;
}

int
main(int argc, char* argv[]) {

GtkWidget* window;
GtkWidget* scrolled_window;
GtkWidget* vbox;
GtkWidget* label;

gtk_init (argc, argv);

window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
scrolled_window = gtk_scrolled_window_new(NULL, NULL);
vbox = gtk_vbox_new(FALSE, 0);
label = gtk_label_new(Testing);

g_signal_connect(G_OBJECT(label), size-allocate,
 G_CALLBACK(allocate_callback), NULL);
g_signal_connect(G_OBJECT(label), size-request,
 G_CALLBACK(request_callback), NULL);
g_signal_connect(G_OBJECT(window), configure-event,
 G_CALLBACK(configure_callback), label);

gtk_scrolled_window_set_policy(
GTK_SCROLLED_WINDOW(scrolled_window),
GTK_POLICY_NEVER,
GTK_POLICY_ALWAYS);

gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
gtk_scrolled_window_add_with_viewport(
GTK_SCROLLED_WINDOW(scrolled_window), vbox);
gtk_container_add(GTK_CONTAINER(window), scrolled_window);

gtk_widget_show(label);
gtk_widget_show(vbox);
gtk_widget_show(scrolled_window);
gtk_widget_show(window);

gtk_main();

return 0;
}

___
gtk-list mailing list
[EMAIL PROTECTED]
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: GtkTreeView with multicolumn mode

2004-08-25 Thread Stephen Bach
I don't know if there's a tree view for this (I don't think so), but there
are a pair of widgets called GtkHWrapBox and GtkVWrapBox that may do what you
want.  They work on an arbitrary group of widgets, but in a project I'm
working on I'm sort-of using them with labels to emulate a wrapping list.

For some reason they're not in the official GTK+ package, but you can get
them from the Gimp 2.0 sources (gimp-2.0.0/app/widgets/).  I seem to remember
that in order for them to work well you need to specify an aspect-ratio,
which may or may not be an issue for you (if you decide they're useful).

On Wed, Aug 25, 2004 at 04:45:47PM +0200, [EMAIL PROTECTED] wrote:
 Hi,
 
 can someone give me a hint if a GtkTreeView already exists
 where the list is shown in multicolumns.
 
 That means, if you have a list
 
 1 bla
 2 blu
 3 foo
 4 hey
 
 depending on the size or some parameter it is rendered like
 
 1 bla   3 foo
 2 blu   4 hey
 
 or
 
 1 bla  2 blu  3 foo  4 hey
 
 or as original shown.
 
 Thanks for any help!
 
 Sebastian
 
___
gtk-list mailing list
[EMAIL PROTECTED]
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: Muffling widget repaints

2004-08-24 Thread Stephen Bach
I've come up with an acceptable solution to my problem, which I'll post here
for posterity.  First my observations:

- The expose signal for the container was emitted only once, and after all the
  widgets had been added/removed.  This is good and means GTK is being smart,
  and that gdk_window_freeze_updates() wouldn't help me.

- If I left the container showing, a changeover involving 2000 widgets took
  about 30 seconds, with X cpu usage hovering at about 85% and the program's
  cpu usage at about 15% (i.e. all of it).  During the switchover, I could
  see widgets in the container shifting periodically, but the container never
  fully redrew itself during the switchover (and expose-event was not
  emitted).

- If I hid the container immediately before the changeover and showed it
  directly afterwards, the changeover took only about 3 seconds, and X cpu
  usage only seemed to reach about 40% and the program's about the same.

Eventually I found that most of the processing was because of (or related to)
size negotiations.  The container received size-request and size-allocate
signals for each widget added/removed.  Since only the final
size-request/size-allocate pair was relevant, I took out the
gtk_widget_queue_resize() calls from the pack and remove functions of the
container.

This worked great for the removal, but for the packing I'd still get the size
negotiation thrashing as soon as I gtk_widget_show'd the new children
(whether I did so before adding them or after they were all added).  So I
connected to the size-request signal of the container and added a condition
to prevent signal propagation if it was during a switchover.

This works okay -- it takes about 8 seconds for a changeover.  Certainly
there's a more complete solution, and hopefully something a little more
elegant (insight welcome), but it'll do for now.

___
gtk-list mailing list
[EMAIL PROTECTED]
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: Muffling widget repaints

2004-08-24 Thread Stephen Bach
Hi Todd,

 This sounds like a very similar problem I'm having.  I'm curious if you 
 have some test case code that you could
 post?

My testing was all done within the context of my program, but I can try.  The
containers in question are WrapBox, which I've based on the GtkWrapBox class
from Gimp 2.0, and its subclass FileBox.

Here's most of the packing function, with the relevant changes commented.
Both this and the removal function are called with do_resize == FALSE during
the changeover.

void wrap_box_pack_pos(WrapBox* wbox, GtkWidget* child, guint pos,
   gboolean do_resize) {  /* This variable added. */
WrapBoxChild* child_info;

g_return_if_fail(IS_WRAP_BOX (wbox));
g_return_if_fail(GTK_IS_WIDGET (child));
g_return_if_fail(child-parent == NULL);

child_info = g_new(WrapBoxChild, 1);
child_info-widget = child;

/* snipping out irrelevant child insertion code */

gtk_widget_set_parent(child, GTK_WIDGET(wbox));

if (GTK_WIDGET_REALIZED(wbox))
gtk_widget_realize(child);

if (GTK_WIDGET_VISIBLE(wbox)  GTK_WIDGET_VISIBLE(child)) {
if (GTK_WIDGET_MAPPED(wbox))
gtk_widget_map(child);

if (do_resize)   /* This conditional added. */
gtk_widget_queue_resize (child);
}
}


And the removal function with a similar change:

void wrap_box_remove(GtkContainer* container, GtkWidget* widget,
  gboolean do_resize) {  /* This variable added. */
WrapBox* wbox = WRAP_BOX(container);
WrapBoxChild *child, *last = NULL;

child = wbox-children;
while (child) {
if (child-widget == widget) {
gboolean was_visible;

was_visible = GTK_WIDGET_VISIBLE(widget);
gtk_widget_unparent(widget);

if (last)
last-next = child-next;
else
wbox-children = child-next;
g_free(child);
wbox-n_children--;

if (was_visible  do_resize)  /*  do_resize added here */
gtk_widget_queue_resize(GTK_WIDGET (container));

break;
}

last = child;
child = last-next;
}
}


In the initialization of the subclass object:

static void file_box_init(FileBox *fbox) {
GTK_WIDGET_SET_FLAGS (fbox, GTK_NO_WINDOW);

fbox-optimal_width = 0;
fbox-show_hidden_files = FALSE;
fbox-n_files = 0;
fbox-file_max = 32767;
fbox-file_display_limit = DEFAULT_FILE_DISPLAY_LIMIT;
fbox-fi_slist = NULL;

/* This class variable and the next line added. */
fbox-eat_size_requests = FALSE;
g_signal_connect(fbox, size-request,
 G_CALLBACK(size_request_kludge), NULL);
}

And the callback function:

static gboolean size_request_kludge(GtkWidget* widget,
GtkRequisition* requisition, gpointer data) {
FileBox* fbox = FILE_BOX(widget);
return fbox-eat_size_requests;
}


Then before entering the add/remove loop, this function is called with FALSE,
and then with TRUE afterward:

static void file_box_allow_size_requests(FileBox* fbox, gboolean allow) {

if (fbox-eat_size_requests != allow)
return;

if (allow) {
fbox-eat_size_requests = FALSE;
gtk_widget_queue_resize(GTK_WIDGET(fbox));
/* ^^^ This is the final size request, and the only one
   to go through. */
}
else
fbox-eat_size_requests = TRUE;
}


Hopefully that's clear and of some use.

___
gtk-list mailing list
[EMAIL PROTECTED]
http://mail.gnome.org/mailman/listinfo/gtk-list


Muffling widget repaints

2004-08-21 Thread Stephen Bach
Hello,

I have a container which periodically loses some of its widgets and gains
others, sometimes on the order of hundreds.  The changeover happens all at
once (i.e. there's a big loop which does all the adding and destroying), but
it's still pretty ugly and slow because sometimes many repaints are done.  I
only care about the final repaint.

Is there some way that I can prevent the intervening repaints from happening?
I've tested hiding and reshowing the container, and it is indeed much faster,
but of course I don't want the user to see the container disappear.  Ideally
I'd have the before painting sit until the widget switch-over is done, and
then display the after painting.

I was hoping gdk_window_freeze_updates() and gdk_window_thaw_updates() would
help, but they don't seem to do anything.  As a test I even tried freezing
the root gdk window right before calling gtk_main() (and after showing its
widget), but the program proceeded normally.  Maybe I'm not understanding
what these functions are for.

Any insight would be very welcome.

Thanks

___
gtk-list mailing list
[EMAIL PROTECTED]
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: Muffling widget repaints

2004-08-21 Thread Stephen Bach
BTW, I'm writing towards GTK+ 2.4.

On Sat, Aug 21, 2004 at 02:16:52PM -0400, Stephen Bach wrote:
 Hello,
 
 I have a container which periodically loses some of its widgets and gains
 others, sometimes on the order of hundreds.  The changeover happens all at
 once (i.e. there's a big loop which does all the adding and destroying), but
 it's still pretty ugly and slow because sometimes many repaints are done.  I
 only care about the final repaint.
 
 Is there some way that I can prevent the intervening repaints from happening?
 I've tested hiding and reshowing the container, and it is indeed much faster,
 but of course I don't want the user to see the container disappear.  Ideally
 I'd have the before painting sit until the widget switch-over is done, and
 then display the after painting.
 
 I was hoping gdk_window_freeze_updates() and gdk_window_thaw_updates() would
 help, but they don't seem to do anything.  As a test I even tried freezing
 the root gdk window right before calling gtk_main() (and after showing its
 widget), but the program proceeded normally.  Maybe I'm not understanding
 what these functions are for.
 
 Any insight would be very welcome.
 
 Thanks
 
 ___
 gtk-list mailing list
 [EMAIL PROTECTED]
 http://mail.gnome.org/mailman/listinfo/gtk-list
 
 
___
gtk-list mailing list
[EMAIL PROTECTED]
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: Muffling widget repaints

2004-08-21 Thread Stephen Bach
When I say repaint I just mean that the there is a visible change in the
widget.  I guess I'm not using the word in its conventional GTK sense.

FWIW, I did connect to the expose signal of the container and found that it's
only called once, after the widget switchover is finished.  Which I guess is
ideal.  But the container still appears to be being updated (repainted in
my incorrect terminology) many times during the switchover.  For example, I
can sometimes see the the container's children repositioning themselves.

On Sat, Aug 21, 2004 at 02:22:56PM -0400, Paul Davis wrote:
 I have a container which periodically loses some of its widgets and gains
 others, sometimes on the order of hundreds.  The changeover happens all at
 once (i.e. there's a big loop which does all the adding and destroying), but
 it's still pretty ugly and slow because sometimes many repaints are done.  I
 only care about the final repaint.
 
 by repaint do you mean an expose signal? you should only be
 drawing within an expose handler (there is one exception: drawing into
 an off-screen drawable, typically a pixmap). drawing at any other time
 is just not the correct model.
 
 --p
 
 
___
gtk-list mailing list
[EMAIL PROTECTED]
http://mail.gnome.org/mailman/listinfo/gtk-list