Exemple #1
0
static void TXT_ScrollPaneMousePress(TXT_UNCAST_ARG(scrollpane),
                                     int x, int y, int b)
{
    TXT_CAST_ARG(txt_scrollpane_t, scrollpane);
    int scrollbars;
    int rel_x, rel_y;

    scrollbars = NeedsScrollbars(scrollpane);

    rel_x = x - scrollpane->widget.x;
    rel_y = y - scrollpane->widget.y;

    // Click on the horizontal scrollbar?
    if ((scrollbars & SCROLLBAR_HORIZONTAL) && rel_y == scrollpane->h)
    {
        if (rel_x == 0)
        {
            --scrollpane->x;
        }
        else if (rel_x == scrollpane->w - 1)
        {
            ++scrollpane->x;
        }
        else
        {
            int range = FullWidth(scrollpane) - scrollpane->w;

            scrollpane->x = ((rel_x - 1) * range) / (scrollpane->w - 3);
        }

        return;
    }

    // Click on the horizontal scrollbar?
    if ((scrollbars & SCROLLBAR_VERTICAL) && rel_x == scrollpane->w)
    {
        if (rel_y == 0)
        {
            --scrollpane->y;
        }
        else if (rel_y == scrollpane->h - 1)
        {
            ++scrollpane->y;
        }
        else
        {
            int range = FullHeight(scrollpane) - scrollpane->h;

            scrollpane->y = ((rel_y - 1) * range) / (scrollpane->h - 3);
        }

        return;
    }

    if (scrollpane->child != NULL)
    {
        TXT_WidgetMousePress(scrollpane->child, x, y, b);
    }

}
static void TXT_ScrollPaneSizeCalc(TXT_UNCAST_ARG(scrollpane))
{
    TXT_CAST_ARG(txt_scrollpane_t, scrollpane);
    int scrollbars;

    if (scrollpane->child != NULL)
    {
        TXT_CalcWidgetSize(scrollpane->child);
    }

    // Expand as necessary (to ensure that no scrollbars are needed)?

    if (scrollpane->expand_w)
    {
        scrollpane->w = FullWidth(scrollpane);
    }
    if (scrollpane->expand_h)
    {
        scrollpane->h = FullHeight(scrollpane);
    }

    scrollpane->widget.w = scrollpane->w;
    scrollpane->widget.h = scrollpane->h;

    // If we have scroll bars, we need to expand slightly to
    // accomodate them. Eg. if we have a vertical scrollbar, we
    // need to be an extra character wide.

    scrollbars = NeedsScrollbars(scrollpane);

    if (scrollbars & SCROLLBAR_HORIZONTAL)
    {
        ++scrollpane->widget.h;
    }
    if (scrollbars & SCROLLBAR_VERTICAL)
    {
        ++scrollpane->widget.w;
    }

    if (scrollpane->child != NULL)
    {
        if (scrollpane->child->w < scrollpane->w)
        {
            scrollpane->child->w = scrollpane->w;
        }
        if (scrollpane->child->h < scrollpane->h)
        {
            scrollpane->child->h = scrollpane->h;
        }
    }
}
static int NeedsScrollbars(txt_scrollpane_t *scrollpane)
{
    int result;

    result = 0;

    if (FullWidth(scrollpane) > scrollpane->w)
    {
        result |= SCROLLBAR_HORIZONTAL;
    }
    if (FullHeight(scrollpane) > scrollpane->h)
    {
        result |= SCROLLBAR_VERTICAL;
    }

    return result;
}
static void TXT_ScrollPaneDrawer(TXT_UNCAST_ARG(scrollpane))
{
    TXT_CAST_ARG(txt_scrollpane_t, scrollpane);
    int x1, y1, x2, y2;
    int scrollbars;

    // We set a clipping area of the scroll pane.

    x1 = scrollpane->widget.x,
    y1 = scrollpane->widget.y,
    x2 = x1 + scrollpane->w,
    y2 = y1 + scrollpane->h;

    scrollbars = NeedsScrollbars(scrollpane);

    if (scrollbars & SCROLLBAR_HORIZONTAL)
    {
        TXT_DrawHorizScrollbar(x1,
                               y1 + scrollpane->h,
                               scrollpane->w,
                               scrollpane->x,
                               FullWidth(scrollpane) - scrollpane->w);
    }

    if (scrollbars & SCROLLBAR_VERTICAL)
    {
        TXT_DrawVertScrollbar(x1 + scrollpane->w,
                              y1,
                              scrollpane->h,
                              scrollpane->y,
                              FullHeight(scrollpane) - scrollpane->h);
    }

    TXT_PushClipArea(x1, x2, y1, y2);

    // Draw the child widget

    if (scrollpane->child != NULL)
    {
        TXT_DrawWidget(scrollpane->child);
    }

    // Restore old clipping area.

    TXT_PopClipArea();
}
static void SanityCheckScrollbars(txt_scrollpane_t *scrollpane)
{
    int scrollbars;
    int max_x, max_y;

    scrollbars = NeedsScrollbars(scrollpane);

    if ((scrollbars & SCROLLBAR_HORIZONTAL) == 0)
    {
        scrollpane->x = 0;
    }
    if ((scrollbars & SCROLLBAR_VERTICAL) == 0)
    {
        scrollpane->y = 0;
    }

    max_x = FullWidth(scrollpane) - scrollpane->w;
    max_y = FullHeight(scrollpane) - scrollpane->h;

    if (scrollpane->x < 0)
    {
        scrollpane->x = 0;
    }
    else if (scrollpane->x > max_x)
    {
        scrollpane->x = max_x;
    }

    if (scrollpane->y < 0)
    {
        scrollpane->y = 0;
    }
    else if (scrollpane->y > max_y)
    {
        scrollpane->y = max_y;
    }
}
static int InterpretScrollKey(txt_scrollpane_t *scrollpane, int key)
{
    int maxy;

    switch (key)
    {
        case KEY_UPARROW:
            if (scrollpane->y > 0)
            {
                --scrollpane->y;
                return 1;
            }
            break;

        case KEY_DOWNARROW:
            if (scrollpane->y < FullHeight(scrollpane) - scrollpane->h)
            {
                ++scrollpane->y;
                return 1;
            }
            break;

        case KEY_LEFTARROW:
            if (scrollpane->x > 0)
            {
                --scrollpane->x;
                return 1;
            }
            break;

        case KEY_RIGHTARROW:
            if (scrollpane->x < FullWidth(scrollpane) - scrollpane->w)
            {
                ++scrollpane->x;
                return 1;
            }
            break;

        case KEY_PGUP:
            if (scrollpane->y > 0)
            {
                scrollpane->y -= scrollpane->h;
                if (scrollpane->y < 0)
                {
                    scrollpane->y = 0;
                }
                return 1;
            }
            break;

        case KEY_PGDN:
            maxy = FullHeight(scrollpane) - scrollpane->h;
            if (scrollpane->y < maxy)
            {
                scrollpane->y += scrollpane->h;
                if (scrollpane->y > maxy)
                {
                    scrollpane->y = maxy;
                }
                return 1;
            }
            break;

        default:
            break;
    }

    return 0;
}