Re: Accessing context popup menues through keyboard



On Thu, 2002-04-18 at 18:38, Paul Davis wrote:
> >I have an app that displays a GtkCTree which registers a signal handler
> >for the button_press_event. When the signal handler is invoked, it
> >checks to see if the x and y pixel coordinates are within a valid row in
> >the GtkCTree (I use gtk_clist_get_selection_info() to verify). If so, I
> >see if the event button was for the right mouse button. If so, I create
> >a context popup at x,y for the row corresponding to x & y.
> >
> >This all works fine and dandy. I want to support using SHIFT-F10 to
> >access the context menu for a row. I can set up a hander for
> >"key_press_event" and recognize SHIFT + GDK_F10 just fine. But now what?
> 
> I'll come back to this later.
> 
> >The GdkEventKey doesn't provide x & y coordinates. How do I get the x &
> >y coordinates during the "key_press_event"?
> 
> there are none, because a key event doesn't have any coordinates. use
> gdk_window_get_pointer() but remember that under X, this requires a
> round-trip to the X server, so don't put it into a tight loop.
> 

Duh. My mistake.

> >The whole point of allowing SHIFT-F10 is to attempt to make the app more
> >accessible to folks with disabilities.
> 
> You have to make a choice here. Your initial design was based on using
> button_press_event, which is inextricably tied to use of a mouse. Now
> you've decided to let them do the same thing with Shift-F10. But what
> is the "same" thing? Its carrying out some operation based on a
> particular row. But which row? In the button press case, it was the
> row that was clicked. But there is no such "clicked" row in the case
> of Shift-F10. All there is the currently selected row, which you keep
> track of with the "select_row" event. You don't need x,y coordinates
> for this.
> 

I've figured out a working solution. Here is my new signal handler for
"key_press_event". It eventually calls a common routine that populates
the popup menu list with items for the row selected. Of interest is the
GtkMenuPositionFunc that is passed to the function to be used by
gtk_menu_popup. This is what positions the menu just under the row with
the current focus. The "button_press_event" does not need it since by
default it gets positioned next to the mouse pointer. I took some macros
from the gtkclist.c source to help with the relative x & y calculations
to the row in question. Suggestions for improvement are welcome although
everything works well now.

gboolean on_view_key_press_event (GtkWidget *widget, GdkEventKey *event,
                                  gpointer user_data)
{
    GtkCList *clist = GTK_CLIST (widget);
    
    if (event->keyval == GDK_Return    || 
        event->keyval == GDK_ISO_Enter || 
        event->keyval == GDK_KP_Enter  ||
        (event->keyval == GDK_F10 && (event->state | GDK_SHIFT_MASK)))
    {
        object_handle_t handle;
            
        handle = GPOINTER_TO_UINT (gtk_clist_get_row_data (clist,
clist->focus_row));
        
        gtk_clist_select_row (clist, clist->focus_row, 0);
        
        display_action_popup_menu_for_handle (handle, 0, 0, 
                                              (GtkMenuPositionFunc)
position_context_menu_over_clist_focus_row,
                                              clist);
    }
    
    return FALSE;
}

/* this defines the base grid spacing */
#define CELL_SPACING 1

/* gives the top pixel of the given row in context of
 * the clist's voffset */
#define ROW_TOP_YPIXEL(clist, row) (((clist)->row_height * (row)) + \
                                    (((row) + 1) * CELL_SPACING) + \
                                    (clist)->voffset)

/* gives the left pixel of the given column in context of
 * the clist's hoffset */
#define COLUMN_LEFT_XPIXEL(clist, colnum) 
((clist)->column[(colnum)].area.x + \
                                            (clist)->hoffset)

void position_context_menu_over_clist_focus_row (GtkMenu *menu, 
                                                 gint *x, gint *y,
                                                 GtkCList *clist)
{
    gint wx;
    gint wy;
    
    gdk_window_get_deskrelative_origin
(GTK_WIDGET(get_main_window_id())->window, &wx, &wy);
    
    *x = COLUMN_LEFT_XPIXEL (clist, 0) + wx + 15;
    *y = ROW_TOP_YPIXEL (clist, clist->focus_row) + wy + 100;
}


I sure hope GTK+ 2.0 makes this code obsolete.

> --p
> 
-- 
regards,

Luciano Chavez

lnx1138 us ibm com          
http://evms.sourceforge.net




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