/* $Id: Menubar.c,v 1.4 1997/04/22 15:35:24 archer Exp $
 *	MENUBAR.C - Handle Menu Bars
 *
 * A MenuBar is a specific container to holds a set of MenuItems *or*
 * of MenuButtons, usually at the top of a shell. It is a sub-class of
 * Menu, to allow the grabbing of the Menubar...
 */
#include <Widget/WidgetsP.h>
#include <Widget/MenuBarP.h>
#include <Widget/MenuP.h>
#include <Widget/drawP.h>


/**
 ** Globally visible class name
 **/
char	x11__menubar_class[]="MenuBar";


/**
 ** Internal: MENUBAR_EXPOSE
 **	The ButtonBar draws "shadows" around
 **/
static void menubar_expose(X11_widget wdg, XEvent *dummy)
{
	x11__draw_start(wdg);
	x11__shadows_gc();
	x11__draw_upshadow(wdg->shadow_thickness);
}


/**
 ** Internal: MENUBAR_RESIZE
 **	Geometry of the menubar has changed
 **/
static void menubar_resize(X11_widget wdg, XEvent *dummy)
{
X11_widget	child;
unsigned int	h_max, h;
unsigned int	m;
int		x, y;
boolean		single;
/*
 * Resize the XWindow object
 */
	x11__core_resize(wdg, dummy);
	h_max  = wdg->h - wdg->border2;
	m      = wdg->margin_inside + wdg->shadow_thickness;
	x      = m;
	h_max -= m + m;
/*
 * Now, apply on all widgets
 */
	single = True;
	for (child = wdg->child; child; child = child->sibling) {
		if (child->unmanaged)
			continue;
/*
 * Last widget is always to the far right. But if last is first (i.e. only one
 * widget on button bar) then it's centered
 */
		if (!child->sibling) {
			x = wdg->w - (wdg->border2 + child->w_min);
			if (single)
				x /= 2;
			else
				x -= m;
		}
		single = False;
/*
 * Resize needed?
 */
		y = 0;
		h = h_max;
		if (child->fixed_h) {
			y = (h - child->h_min) / 2;
			h = child->h_min;
		}
		if (child->w_min != child->w || h != child->h) {
			child->w = child->w_min;
			child->h = h;
			(*child->on_resize_window)(child, (XEvent *)0);
		}
/*
 * Reposition needed?
 */
		y += m;
		if (x != child->x || y != child->y) {
			child->x = x;
			child->y = y;
			if (child->id)
				XMoveWindow(x11__screen, child->id, x, y);
		}
/*
 * Move to next child
 */
		x += child->w;
	}
}


/**
 ** Internal: MENUBAR_GEOMETRY
 **	Compute the geometry needed by a menu Bar
 **/
static void menubar_geometry(X11_widget wdg, XEvent *dummy)
{
X11_widget child;
unsigned int	h;
unsigned int	w;
unsigned int	v;
/*
 * Margins between children?
 */
	h = 0;
	w = 10;
/*
 * Loop on all children
 */
	for (child = wdg->child; child; child = child->sibling) {
		if (child->unmanaged)
			continue;
		(*child->on_geometry_check)(child, dummy);
/*
 * What has the child to say?
 */
		w += child->w_min;
		v  = child->h_min;
		if (v > h)
			h = v;
	}
/*
 * Add margins, and shadow thickness
 */
	v  = wdg->margin_inside + wdg->shadow_thickness;
	v *= 2;
	v += wdg->border2;
	w += v;
	h += v;
/*
 * Apply new geometry
 */
	wdg->w_min = w;
	wdg->h_min = h;
	x11__widget_grow(wdg);
}


/**
 ** X11_MENUBAR
 **	Create a Menu Bar window
 **/
X11_widget X11_MenuBar(X11_widget parent)
{
x11__menubar	*object;
/*
 * Get resource
 */
	object = allocator(x11__menubar);
	x11__core_setup(&object->menu.label.core, parent, x11__menubar_class, "menubar");
/*
 * Initialize fields
 */
	object->menu.label.core.event_mask      = ButtonPressMask|ButtonReleaseMask|
						PointerMotionMask|PointerMotionHintMask|
						ExposureMask;
	object->menu.label.core.on_button_press   = x11__menu_open;
	object->menu.label.core.on_expose         = menubar_expose;
	object->menu.label.core.on_geometry_check = menubar_geometry;
	object->menu.label.core.on_resize_window  = menubar_resize;
/*
 * Default values depend on the style
 */
	object->menu.label.core.margin_inside    = 2;
	object->menu.label.core.shadow_thickness = 2;
/*
 * These do not depend on the style
 */
	object->menu.label.core.fixed_w = False;
	object->menu.label.core.fixed_h = True;
/*
 * Get resources
 */
	x11__resource_basic(&object->menu.label.core);
/*
 * Ok
 */
	return OBJECT_P;
}
