Beispiel #1
0
static UI_CALLBACK(submenu_popdown_callback)
{
    submenu_popped_up--;
#if 0   /* doesn't seem to be needed */
    if (XawSimpleMenuGetActiveEntry(w)) {
#if MENU_DEBUG 
        printf("calling XtPopdown(%p)\n", client_data);
#endif
        XtPopdown((Widget)client_data);
    }
#endif
    active_submenu = 0;
}
Beispiel #2
0
/*
 * Usually called from a key press, but there is no reason it can't
 * be called from a button event.
 *
 * Accepts 1 numeric parameter: if nonzero, the menu stays up instead
 * of popping down.
 */
static void menu_select_action(Widget w, XEvent *event, String *params, Cardinal *num_params)
{
    int keep_menu_up = 0;

    if (*num_params == 1) {
        keep_menu_up = atoi(*params);
    }

    if (event->type == KeyPress || event->type == KeyRelease) {
        XtWidgetGeometry geometry;
        Widget old_active_entry;

        /*
         * Keyboard events bubble up to the top menu, because the top is
         * "spring loaded", So we may get to see them multiple times for
         * different widgets, if the mouse happens to be in a submenu. To
         * put a stop to that: only listen to the top_menu.
         */
        if (w != top_menu) {
#if MENU_DEBUG 
            printf("menu_select_action: ignoring event, not top_menu\n");
#endif
            return;
        }

        /*
         * Apparently, notify() looks at the event coordinates to know
         * which item should be notify()d, instead of just doing the
         * active one. So fake them.
         * It also looks if the event's window matches the widget,
         * presumably also because of spring-loaded menus.  Fake that too.
         * To look at the coordinates, it checks the event type, and it
         * doesn't know about keys. More faking.
         */
        old_active_entry = XawSimpleMenuGetActiveEntry(active_keyboard_menu);
        if (!old_active_entry) {
            return;
        }

        fake_button_action(w, event, NULL, NULL);       /* notify() cares */

        XtQueryGeometry(old_active_entry, NULL, &geometry);
        event->xbutton.x = geometry.x + 1;
        event->xbutton.y = geometry.y + 1;

        w = active_keyboard_menu;
        event->xany.window = XtWindow(w);       /* notify() cares about this */
    }

    do_menu_select(w, event, keep_menu_up);
}
Beispiel #3
0
/*
 * Sub Popup Open [action]
 */
XtActionProc SubPopup(Widget w,XEvent *e,String *par,Cardinal *n)
{
  int ex,ey;
  Position x,y;
  Dimension xw,yh;
  Widget cur_item,item,menu;

  Window tmp1;
  int tmp2;

  cur_item = XawSimpleMenuGetActiveEntry(w);
  if (cur_item == pmColor) {
    item = pmColor;
    menu = pcTop;
  }
  else if (cur_item == pmFont) {
    item = pmFont;
    menu = pfTop;
  }
  else
    return;

  ex = e->xmotion.x;
  ey = e->xmotion.y;

  XtVaGetValues(item,
		XtNx,&x,
		XtNy,&y,
		XtNwidth,&xw,
		XtNheight,&yh,
		NULL);

  if ((ex < x + xw*3/4)
    ||(ey < y)
    ||(ey > y + yh))
	return;


  x = e->xmotion.x_root;
  y = e->xmotion.y_root;

  XtVaGetValues(menu,XtNwidth,&xw,NULL);
  x -= xw/2;
  y -= 8;
  XtVaSetValues(menu,XtNx,x,XtNy,y,NULL);

  XtPopup(menu,XtGrabExclusive);
}
Beispiel #4
0
/* Yes, this sucks.  Sorry.  */
static void position_submenu_action(Widget w, XEvent *event, String *params, Cardinal *num_params)
{
    Widget new_active_submenu, new_active_entry;

    new_active_entry = XawSimpleMenuGetActiveEntry(w);
    if (new_active_entry != active_entry) {
        int i, level;
        int level_found, active_found;

        new_active_submenu = NULL;

        /* Find the submenu for the current active menu item and the level of
           this submenu.  */
        for (level_found = active_found = 0, level = 0, i = 0; i < num_submenus && !(level_found && active_found); i++) {
            if (!active_found && submenus[i].parent == new_active_entry) {
                new_active_submenu = submenus[i].widget;
                active_found = 1;
            }
            if (!level_found && submenus[i].widget == w) {
                level = submenus[i].level;
                level_found = 1;
            }
        }

        /* Remove all the submenus whose level is higher than this submenu.  */
        for (i = 0; i < num_submenus; i++) {
            if (submenus[i].level > level) {
                XtPopdown(submenus[i].widget);
            }
        }

        /* Position the submenu for this menu item.  */
        if (new_active_submenu != NULL && new_active_entry != NULL) {
            position_submenu(new_active_submenu, new_active_entry);
        }

        active_submenu = new_active_submenu;
        active_entry = new_active_entry;
    }
}
Beispiel #5
0
/* ARGSUSED */
static void
XawSmeBSBRedisplay(Widget w, XEvent *event, Region region)
{
    GC gc;
    SmeBSBObject entry = (SmeBSBObject)w;
    int	font_ascent, font_descent, y_loc;
    int	fontset_ascent, fontset_descent;
    XFontSetExtents *ext = XExtentsOfFontSet(entry->sme_bsb.fontset);

    font_ascent = font_descent = fontset_ascent = fontset_descent = 0;
    entry->sme_bsb.set_values_area_cleared = False;

    if (entry->sme.international == True) {
	fontset_ascent = XawAbs(ext->max_ink_extent.y);
	fontset_descent = ext->max_ink_extent.height - fontset_ascent;
    }
    else {
	font_ascent = entry->sme_bsb.font->max_bounds.ascent;
	font_descent = entry->sme_bsb.font->max_bounds.descent;
    }
    y_loc = XtY(entry);

    if (XtIsSensitive(w) && XtIsSensitive(XtParent(w))) {
	if (w == XawSimpleMenuGetActiveEntry(XtParent(w))) {
	    XFillRectangle(XtDisplayOfObject(w), XtWindowOfObject(w), 
			   entry->sme_bsb.norm_gc, XtX(w), y_loc,
			   XtWidth(entry), XtHeight(entry));
	    gc = entry->sme_bsb.rev_gc;
	}
	else
	    gc = entry->sme_bsb.norm_gc;
    }
    else
	gc = entry->sme_bsb.norm_gray_gc;
    
    if (entry->sme_bsb.label != NULL) {
	int x_loc = entry->sme_bsb.left_margin;
	int len = strlen(entry->sme_bsb.label);
	char *label = entry->sme_bsb.label;
	 int width, t_width;

	switch(entry->sme_bsb.justify) {
	    case XtJustifyCenter:
		if (entry->sme.international == True) {
		    t_width = XmbTextEscapement(entry->sme_bsb.fontset,label,
						len);
		    width = XtWidth(entry) - (entry->sme_bsb.left_margin +
					      entry->sme_bsb.right_margin);
		}
		else {
		    t_width = XTextWidth(entry->sme_bsb.font, label, len);
		    width = XtWidth(entry) - (entry->sme_bsb.left_margin +
					      entry->sme_bsb.right_margin);
		}
		x_loc += (width - t_width) >> 1;
		break;
	    case XtJustifyRight:
		if (entry->sme.international == True) {
		    t_width = XmbTextEscapement(entry->sme_bsb.fontset,label,
						len);
		    x_loc = XtWidth(entry) - (entry->sme_bsb.right_margin +
					      t_width);
		}
		else {
		    t_width = XTextWidth(entry->sme_bsb.font, label, len);
		    x_loc = XtWidth(entry) - (entry->sme_bsb.right_margin +
					      t_width);
		}
		break;
	    case XtJustifyLeft:
		/*FALLTHROUGH*/
	    default:
		break;
	}

	/* this will center the text in the gadget top-to-bottom */
	if (entry->sme.international == True) {
	    y_loc += ((XtHeight(entry) -
		      (fontset_ascent + fontset_descent)) >> 1) +
		       fontset_ascent;

	    XmbDrawString(XtDisplayOfObject(w), XtWindowOfObject(w),
		          entry->sme_bsb.fontset, gc,
			  XtX(w) + x_loc, y_loc, label, len);
	}
Beispiel #6
0
static void menu_nextprev_item(Widget w, XEvent *event, int incr)
{
    Widget old_active_entry;
    Widget new_active_entry = NULL;
    WidgetList children;
    Cardinal numChildren;
    int i = 0, found = 0, wrapped = 0;

    if (w != top_menu) {
#if MENU_DEBUG 
        printf("menu_nextprev_item_action: ignoring event, not top_menu\n");
#endif
        return;
    }

    /*
     * Find which smeBSB object is the active one.
     */
    XtVaGetValues(active_keyboard_menu, XtNchildren, &children,
                                        XtNnumChildren, &numChildren, NULL);

    /*
     * If there are not at least 2 children
     * then there is no point in even trying to go up or down.
     * Besides, might go out of the array's bounds.
     */
    if (numChildren < 2) {
        return;
    }

    old_active_entry = XawSimpleMenuGetActiveEntry(active_keyboard_menu);

    if (old_active_entry) {
        for (i = 0; i < numChildren; i++) {
            if (children[i] == old_active_entry) {
                found = 1;
                break;
            }
        }
    }

    /*
     * If no item was active, start at the top or the bottom.
     */
    if (!found) {
        i = (incr > 0) ? -incr : numChildren;
    }

    /*
     * Find the next sensitive item, going either up or down.
     * Note that we made the separator lines non-sensitive, just for this.
     * Do wrap around, but no more than once, that would be an endless loop.
     */
    while (wrapped < 2) {
        Boolean flag;

        i += incr;

        if (i < 0) {
            i = numChildren - 1;
            wrapped++;
        } else if (i >= numChildren) {
            i = 0;
            wrapped++;
        }

        XtVaGetValues(children[i], XtNsensitive, &flag, NULL);
        if (flag) {
            new_active_entry = children[i];
            break;
        }
    }

    if (new_active_entry && new_active_entry != old_active_entry) {
        XtWidgetGeometry geometry;
        int x, y;

        XtQueryGeometry(new_active_entry, NULL, &geometry);
        x = geometry.x + 1;
        y = geometry.y + 1;

        do_fake_motion(active_keyboard_menu, event, x, y);
    }
}