示例#1
0
static void
compute_bounding_box_subtree(TreeWidget tree, Widget w, int depth)
{
    TreeConstraints tc = TREE_CONSTRAINT(w);  /* info attached to all kids */
    int i;
    Bool horiz = IsHorizontal (tree);
    Dimension newwidth, newheight;
    Dimension bw2 = w->core.border_width * 2;

    /*
     * Set the max-size per level.
     */
    if (depth >= tree->tree.n_largest) {
	initialize_dimensions (&tree->tree.largest,
			       &tree->tree.n_largest, depth + 1);
    }
    newwidth = ((horiz ? w->core.width : w->core.height) + bw2);
    if (tree->tree.largest[depth] < newwidth)
      tree->tree.largest[depth] = newwidth;


    /*
     * initialize
     */
    tc->tree.bbwidth = w->core.width + bw2;
    tc->tree.bbheight = w->core.height + bw2;

    if (tc->tree.n_children == 0) return;

    /*
     * Figure the size of the opposite dimension (vertical if tree is 
     * horizontal, else vice versa).  The other dimension will be set 
     * in the second pass once we know the maximum dimensions.
     */
    newwidth = 0;
    newheight = 0;
    for (i = 0; i < tc->tree.n_children; i++) {
	Widget child = tc->tree.children[i];
	TreeConstraints cc = TREE_CONSTRAINT(child);
	    
	compute_bounding_box_subtree (tree, child, depth + 1);

	if (horiz) {
	    if (newwidth < cc->tree.bbwidth) newwidth = cc->tree.bbwidth;
	    newheight += tree->tree.vpad + cc->tree.bbheight;
	} else {
	    if (newheight < cc->tree.bbheight) newheight = cc->tree.bbheight;
	    newwidth += tree->tree.hpad + cc->tree.bbwidth;
	}
    }


    tc->tree.bbsubwidth = newwidth;
    tc->tree.bbsubheight = newheight;

    /*
     * Now fit parent onto side (or top) of bounding box and correct for
     * extra padding.  Be careful of unsigned arithmetic.
     */
    if (horiz) {
	tc->tree.bbwidth += tree->tree.hpad + newwidth;
	newheight -= tree->tree.vpad;
	if (newheight > tc->tree.bbheight) tc->tree.bbheight = newheight;
    } else {
	tc->tree.bbheight += tree->tree.vpad + newheight;
	newwidth -= tree->tree.hpad;
	if (newwidth > tc->tree.bbwidth) tc->tree.bbwidth = newwidth;
    }
}
示例#2
0
static void
arrange_subtree(TreeWidget tree, Widget w, int depth, int x, int y)
{
    TreeConstraints tc = TREE_CONSTRAINT(w);  /* info attached to all kids */
    TreeConstraints firstcc, lastcc;
    int i;
    int newx, newy;
    Bool horiz = IsHorizontal (tree);
    Widget child = NULL;
    Dimension tmp;
    Dimension bw2 = w->core.border_width * 2;
    Bool relayout = True;


    /*
     * If no children, then just lay out where requested.
     */
    tc->tree.x = x;
    tc->tree.y = y;

    if (horiz) {
	int myh = (w->core.height + bw2);

	if (myh > (int)tc->tree.bbsubheight) {
	    y += (myh - (int)tc->tree.bbsubheight) / 2;
	    relayout = False;
	}
    } else {
	int myw = (w->core.width + bw2);

	if (myw > (int)tc->tree.bbsubwidth) {
	    x += (myw - (int)tc->tree.bbsubwidth) / 2;
	    relayout = False;
	}
    }

    if ((tmp = ((Dimension) x) + tc->tree.bbwidth) > tree->tree.maxwidth)
      tree->tree.maxwidth = tmp;
    if ((tmp = ((Dimension) y) + tc->tree.bbheight) > tree->tree.maxheight)
      tree->tree.maxheight = tmp;

    if (tc->tree.n_children == 0) return;


    /*
     * Have children, so walk down tree laying out children, then laying
     * out parents.
     */
    if (horiz) {
	newx = x + tree->tree.largest[depth];
	if (depth > 0) newx += tree->tree.hpad;
	newy = y;
    } else {
	newx = x;
	newy = y + tree->tree.largest[depth];
	if (depth > 0) newy += tree->tree.vpad;
    }

    for (i = 0; i < tc->tree.n_children; i++) {
	TreeConstraints cc;

	child = tc->tree.children[i];	/* last value is used outside loop */
	cc = TREE_CONSTRAINT(child);

	arrange_subtree (tree, child, depth + 1, newx, newy);
	if (horiz) {
	    newy += tree->tree.vpad + cc->tree.bbheight;
	} else {
	    newx += tree->tree.hpad + cc->tree.bbwidth;
	}
    }

    /*
     * now layout parent between first and last children
     */
    if (relayout) {
	Position adjusted;
	firstcc = TREE_CONSTRAINT (tc->tree.children[0]);
	lastcc = TREE_CONSTRAINT (child);

	/* Adjustments are disallowed if they result in a position above
         * or to the left of the originally requested position, because
	 * this could collide with the position of the previous sibling.
	 */
	if (horiz) {
	    tc->tree.x = x;
	    adjusted = firstcc->tree.y +
	      ((lastcc->tree.y + (Position) child->core.height + 
		(Position) child->core.border_width * 2 -
		firstcc->tree.y - (Position) w->core.height - 
		(Position) w->core.border_width * 2 + 1) / 2);
	    if (adjusted > tc->tree.y) tc->tree.y = adjusted;
	} else {
	    adjusted = firstcc->tree.x +
	      ((lastcc->tree.x + (Position) child->core.width +
		(Position) child->core.border_width * 2 -
		firstcc->tree.x - (Position) w->core.width -
		(Position) w->core.border_width * 2 + 1) / 2);
	    if (adjusted > tc->tree.x) tc->tree.x = adjusted;
	    tc->tree.y = y;
	}
    }
}
示例#3
0
void GUISlider::Draw(Common::Bitmap *ds)
{
    Rect bar;
    Rect handle;
    int  thickness;

    if (MinValue >= MaxValue)
        MaxValue = MinValue + 1;
    Value = Math::Clamp(Value, MinValue, MaxValue);
  
    // it's a horizontal slider
    if (IsHorizontal())
    {
        thickness = Height / 3;
        bar.Left = X + 1;
        bar.Top = Y + Height / 2 - thickness;
        bar.Right = X + Width - 1;
        bar.Bottom = Y + Height / 2 + thickness + 1;
        handle.Left = (int)(((float)(Value - MinValue) / (float)(MaxValue - MinValue)) * (float)(Width - 4) - 2) + bar.Left + 1;
        handle.Top = bar.Top - (thickness - 1);
        handle.Right = handle.Left + 4;
        handle.Bottom = bar.Bottom + (thickness - 1);
        if (HandleImage > 0)
        {
            // store the centre of the pic rather than the top
            handle.Top = bar.Top + (bar.Bottom - bar.Top) / 2 + 1;
            handle.Left += 2;
        }
        handle.Top += HandleOffset;
        handle.Bottom += HandleOffset;
    }
    // vertical slider
    else
    {
        thickness = Width / 3;
        bar.Left = X + Width / 2 - thickness;
        bar.Top = Y + 1;
        bar.Right = X + Width / 2 + thickness + 1;
        bar.Bottom = Y + Height - 1;
        handle.Top = (int)(((float)(MaxValue - Value) / (float)(MaxValue - MinValue)) * (float)(Height - 4) - 2) + bar.Top + 1;
        handle.Left = bar.Left - (thickness - 1);
        handle.Bottom = handle.Top + 4;
        handle.Right = bar.Right + (thickness - 1);
        if (HandleImage > 0)
        {
            // store the centre of the pic rather than the left
            handle.Left = bar.Left + (bar.Right - bar.Left) / 2 + 1;
            handle.Top += 2;
        }
        handle.Left += HandleOffset;
        handle.Right += HandleOffset;
    }

    color_t draw_color;
    if (BgImage > 0)
    {
        // tiled image as slider background
        int x_inc = 0;
        int y_inc = 0;
        if (IsHorizontal())
        {
            x_inc = get_adjusted_spritewidth(BgImage);
            // centre the image vertically
            bar.Top = Y + (Height / 2) - get_adjusted_spriteheight(BgImage) / 2;
        }
        else
        {
            y_inc = get_adjusted_spriteheight(BgImage);
            // centre the image horizontally
            bar.Left = X + (Width / 2) - get_adjusted_spritewidth(BgImage) / 2;
        }
        int cx = bar.Left;
        int cy = bar.Top;
        // draw the tiled background image
        do
        {
            draw_gui_sprite(ds, BgImage, cx, cy, true);
            cx += x_inc;
            cy += y_inc;
            // done as a do..while so that at least one of the image is drawn
        }
        while ((cx + x_inc <= bar.Right) && (cy + y_inc <= bar.Bottom));
    }
    else
    {
        // normal grey background
        draw_color = ds->GetCompatibleColor(16);
        ds->FillRect(Rect(bar.Left + 1, bar.Top + 1, bar.Right - 1, bar.Bottom - 1), draw_color);
        draw_color = ds->GetCompatibleColor(8);
        ds->DrawLine(Line(bar.Left, bar.Top, bar.Left, bar.Bottom), draw_color);
        ds->DrawLine(Line(bar.Left, bar.Top, bar.Right, bar.Top), draw_color);
        draw_color = ds->GetCompatibleColor(15);
        ds->DrawLine(Line(bar.Right, bar.Top + 1, bar.Right, bar.Bottom), draw_color);
        ds->DrawLine(Line(bar.Left, bar.Bottom, bar.Right, bar.Bottom), draw_color);
    }

    if (HandleImage > 0)
    {
        // an image for the slider handle
        if (spriteset[HandleImage] == NULL)
            HandleImage = 0;

        handle.Left -= get_adjusted_spritewidth(HandleImage) / 2;
        handle.Top -= get_adjusted_spriteheight(HandleImage) / 2;
        draw_gui_sprite(ds, HandleImage, handle.Left, handle.Top, true);
        handle.Right = handle.Left + get_adjusted_spritewidth(HandleImage);
        handle.Bottom = handle.Top + get_adjusted_spriteheight(HandleImage);
    }
    else
    {
        // normal grey tracker handle
        draw_color = ds->GetCompatibleColor(7);
        ds->FillRect(Rect(handle.Left, handle.Top, handle.Right, handle.Bottom), draw_color);
        draw_color = ds->GetCompatibleColor(15);
        ds->DrawLine(Line(handle.Left, handle.Top, handle.Right, handle.Top), draw_color);
        ds->DrawLine(Line(handle.Left, handle.Top, handle.Left, handle.Bottom), draw_color);
        draw_color = ds->GetCompatibleColor(16);
        ds->DrawLine(Line(handle.Right, handle.Top + 1, handle.Right, handle.Bottom), draw_color);
        ds->DrawLine(Line(handle.Left + 1, handle.Bottom, handle.Right, handle.Bottom), draw_color);
    }

    _cachedHandle = handle;
}