Re: XForms: interrogating a scrollbar

From: Angus Leeming (a.leeming@ic.ac.uk)
Date: Tue Dec 03 2002 - 09:14:35 EST

  • Next message: Peter S Galbraith: "Re: XForms: problem with fl_set_idle_delta in 1.0 RC 5.2"

    On Monday 02 December 2002 7:36 pm, John Levon wrote:
    > 4. xforms should mediate these callbacks to a reasonable pace using a
    > timer.

    I've spent some time trying to ascertain exactly what we want and what xforms
    gives us at the moment. Allow me to take you through it. You'll find at the
    end that xforms already gives us what we want --- almost --- so bear with
    me...

    The problem is that we want quite fine-grained control over the scrollbar and
    it's only for one of these interactions that we need/want the mediation that
    John is suggesting.

    The scrollbar is actually a "complex widget" made up of three "simple
    widget"s, a "slider" and two buttons named "up" and "down" that are the
    little arrow buttons at the end of the slider.

    The user can control the slider position in several different ways:
    * Click on and drag the slider to the desired position.
    * Click in the slider trough with the LMB
    * Click in the slider trough with the RMB
    * Click on the up/down buttons with any mouse button.

    Each interaction results in a different behaviour. Specifically, if the
    scrollbar increment is set:
            fl_set_scrollbar_increment(scrollbar, lmb_inc, rmb_inc);
    then clicking in the slider trough with the LMB increments the slider by
    lmb_inc. Ditto, clicking in the slider trough with the RMB increments the
    slider by rmb_inc.
    Finally, clicking on the up and down buttons with any mouse button increments
    the slider by rmb_inc.

    All four types of "click-interaction" result in a call to the user-specified
    scrollbar->object_callback routine. The user has no way of differentiating
    between the different possible click behaviours.

    I have extracted this information through the use of judiciously placed print
    statements in the xforms source. It isn't woolly; it's an accurate
    description of the code.

    In our particular case,
            lmb_inc is "increment by 1 page" and
            rmb_inc is "increment by 1 line"
    Moreover, because the LMB click in the slider trough results in a large
    increment, we would like callbacks resulting from it to be mediated by a
    reasonable delay between callbacks.

    From all this, I conclude that we should focus our attention on the simple
    slider widget rather than the complex scrollbar widget. Moreover, an
    examination of slider.c's source shows that the code to do what we want is
    already there --- almost. We need merely modify slider.c's handle_mouse
    routine.

    I append the relevant code snippet below. Note how xforms currently uses a
    "timdel" variable to ignore the callbacks 1-10 after the mouse button is
    pressed. Thereafter, every other mouse event gets through.

    Proposal 1
            use the current approach, but reset timdel to 0 after it's reached 11.
            make 11 tunable from the outside.
    Proposal 2
            use a timer instead of timdel

    See below and try out the attached diagnostic patch to the xforms source.

    Does this make sense? Would you like to try and fix the source this way or
    are you set on your idea still?

    Regards,
    Angus (who's starting to get to grips with the xforms source...)

    ps. We've had similar problem reports about the counter from users. Note that
    it too has a handle_mouse routine using a timdel variable, so it looks to me
    that we can cure both problems in the same way.

    That's wasted the morning. Best do some proper work this afternoon.
    A.

    slider.c
    =====
    // Set to zero when the slider->handle routine is called due to a
    // /new/ mouse press.
    static int timdel;

    /* Handle a mouse position change */
    static int
    handle_mouse(FL_OBJECT * ob, FL_Coord mx, FL_Coord my, int key)
    {
        SPEC *sp = (SPEC *) ob->spec;
        float newval;

        /* mouse on trough */
        if (mpos && (sp->rdelta + sp->ldelta) > 0.0f)
        {
            if (timdel++ == 0 || (timdel > 11 && (timdel & 1) == 0))
            {
                if (key == FL_LEFT_MOUSE)
                    newval = sp->val + mpos * sp->ldelta;
                else
                    newval = sp->val + mpos * sp->rdelta;
            }
            else
                return 0;
        }
        else
            newval = get_newvalue(ob, mx, my);

        newval = fl_valuator_round_and_clamp(ob, newval);

        if (sp->val != newval)
        {
            sp->val = newval;
            sp->norm_val = (sp->min == sp->max) ? 0.5f :
                (sp->val - sp->min) / (sp->max - sp->min);
            sp->draw_type = mpos ? SLIDER_JUMP : SLIDER_MOTION;
            fl_redraw_object(ob);
            return 1;
        }
        return 0;
    }



    _________________________________________________
    To unsubscribe, send the message "unsubscribe" to
    xforms-request@bob.usuhs.mil or see
    http://bob.usuhs.mil/mailserv/xforms.html
    XForms Home Page: http://world.std.com/~xforms
    List Archive: http://bob.usuhs.mil/mailserv/list-archives/



    This archive was generated by hypermail 2b29 : Tue Dec 03 2002 - 09:13:13 EST