Re: questions




Michal Vitecek <M.Vitecek@sh.cvut.cz> writes:

> hello,
> 
>  i've got some questions i'd like to know answers to. i'd be very grateful
> if someone could answer them. thanks a lot.
> 
> 	a) how can i the change behaviour of the TAB key in GtkTable
> 	widget ? i want to preset the order in which widgets in the table
> 	will get focused. i still hasn't got any reply to this question :(

At this moment, it is impossible. However, with a one-line change to
gtktable.c, it becomes possible:

diff -u -r1.18 gtkcontainer.c
--- gtkcontainer.c      1998/04/06 04:31:15     1.18
+++ gtkcontainer.c      1998/04/10 17:27:28
@@ -181,7 +181,7 @@
                     GTK_TYPE_C_CALLBACK);
   container_signals[FOCUS] =
     gtk_signal_new ("focus",
-                    GTK_RUN_FIRST,
+                    GTK_RUN_LAST,
                     object_class->type,
                     GTK_SIGNAL_OFFSET (GtkContainerClass, focus),
                     gtk_container_marshal_signal_3,

With that in place, it is possible to intercept the "focus" signal and
provide your own implementation. That, however, is not too simple.
The following is about the shortest I could come up with. What
it does is simply focus in the order that widgets were added to the
table. 

(Actually, it is general to all containers, and focuses in the order
that the container returns the children to gtk_container_children() -
which happens to work for tables)

The code is all cribbed from gtkcontainer.c. I haven't tested it
at all.

gint 
my_focus (GtkContainer *container, GtkDirectionType direction)
{
  GList *children;
  GList *tmp_list;
  gint return_val;

  GtkWidget *focus_child;
  GtkWidget *child;

  if ((direction != GTK_TAB_FORWARD) && (direction != GTK_TAB_BACKWARD))
    return FALSE;   /* Let the regular handler handle it */

  /* Stop the current signal, so the regular handler never sees it */
  gtk_signal_emit_stop_by_name (GTK_OBJECT (container), "focus");

  /* Fail if the container is insensitive
   */
  if (!GTK_WIDGET_SENSITIVE (container))
    return FALSE;

  return_val = FALSE;

  /* Get a list of the containers children
   */
  children = gtk_container_children (container);

  /* Now find the next focus widget */

  if (children)
    {
      if (direction == GTK_TAB_BACKWARD)
	children = g_list_reverse (children);
      
      focus_child = container->focus_child;
      container->focus_child = NULL;

      tmp_list = children;
      while (tmp_list)
	{
	  child = tmp_list->data;
	  tmp_list = tmp_list->next;
	  
	  if (focus_child)
	    {
	      if (focus_child == child)
		{
		  focus_child = NULL;
		  
		  if (GTK_WIDGET_VISIBLE (child) &&
		      GTK_IS_CONTAINER (child) &&
		      !GTK_WIDGET_HAS_FOCUS (child))
		    if (gtk_container_focus (GTK_CONTAINER (child), direction))
		      {
			return_val = TRUE;
			break;
		      }
		}
	    }
	  else if (GTK_WIDGET_SENSITIVE (child) && GTK_WIDGET_VISIBLE (child))
	    {
	      if (GTK_WIDGET_CAN_FOCUS (child))
		{
		  gtk_widget_grab_focus (child);
		  return_value = TRUE;
		  break;
		}
	      else if (GTK_IS_CONTAINER (child))
		{
		  if (gtk_container_focus (GTK_CONTAINER (child), direction))
		    {
		      return_value = TRUE;
		      break;
		    }
		}
	    }
	}
      
      g_list_free (children);
    }

  return return_val;
}

> 	b) why is in gtk_widget_install_accelerator the key defined as
> 	gchar, when in <gdk/gdkkeysyms.h> the keys are gint ? i'd like
> 	some button to be "clicked" when GDK_Return is pressed in a dialog
> 	box. or GDK_Escape will result in destroying the dialog.

Probably to make outputting the accelerator keys to a file simple.
It is an annoying restriction, though.

As a workaround, you can attach to "key_press_event" on the toplevel
window, and check for your keys explicitley.

(BTW, the RETURN behavior can be gotten by setting the default button:

      GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
      gtk_widget_grab_default (button);
)
 
> 	c) when i press any combination that is to send "clicked" to a
> 	button, the button is not drawn to be "pushed". when in the
> 	callback i added a line with 
> 		gtk_signal_emit_by_name(button, "pressed");
> 	the button doesn't redraw itself, only when i move the mouse
> 	pointer over it. so this item actually consists of two questions.
> 	how can i make the button when its accelerator has been pressed to
> 	be "pressed/pushed" and why doesn't the button widget redraw
> 	itself when a signal of its state changing has been emitted ?

GTK doesn't do that. That's the basic answer. It should be possible
to fake, using gtk_button_pressed() and gtk_button_released(), but
there are some tricky things to watch out for with prelight
highlighting.

You'll have to also worry figure what the behavior should be

 - When should the button undepress? When the key is released?
   (But unless you grab the keyboard (not current in GDK), you
    won't necessarily get the release) Some short time later?
  
 - When should the action be invoked? With the mouse, the action
   is invoked when the mouse button is released. But if the
   button is undepressed on a timeout, that would be just a 
   nuisance for the user.
  
> 	d) how can i remove a given accelerator from a widget? i know
> 	there's gtk_widget_remove_accelerator(), but this function seems
> 	quite well difficult ? couldn't there just be a function to which
> 	i'd only send as parameters the widget affected, the key, and the
> 	modifier mask ?

Well, here's a hack. Install another accelerator with the same key and
mask, and a known widget and signal. Then remove that accelerator.

> 	e) i want to make my program as accessible by the keyboard as
> 	possible so i installed accelerators to the menu items in the menu
> 	bar. the accelerator key are drawn there (in the menu bar) which
> 	obviously shouldn't happen. i think that the letter that
> 	activates the menu item should be underlined too and in case the
> 	menu item is not in the menu bar, also the accelerator should be
> 	shown on the right of the item.
> 
> 	f) this is related to e). after adding accelerators to the menu
> 	items in the menu bar, only that item that doesn't have a submenu
> 	is actually send the "activate" signal. but i want to press Alt+F
> 	for example (which is an accelerator for a menu item located
> 	in the menu bar File and has submenu with those familiar
> 	Open ..., Save, Save As ..., Close etc.) but when i press Alt+F
> 	nothing happens. i have to use mouse and send the "activate"
> 	signal with it, which is not quite the idea i want ;)

Keyboard navigation of menus is not yet implemented in GTK. Volunteers
would be welcome.

>   huh, that mail got long but i hope my questions are not dumb. and i
> wish, u ppl kept the good work and made GTK+ the X programming library
> most widespread.

Not dumb, but challenging to answer. :-)

Regards,
                                        Owen



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