PreviousUpNext

15.4.1403  src/lib/x-kit/widget/leaf/scrollbar-look.pkg

## scrollbar-look.pkg
#
# Scrollbar views.

# Compiled by:
#     src/lib/x-kit/widget/xkit-widget.sublib






###                "My view of the matter was, the reason large programs are
###                 so confusing is that we don't know how to write them."
###
###                                        -- Whitfield Diffie


stipulate
    package d3 =  three_d;                                              # three_d               is from   src/lib/x-kit/widget/lib/three-d.pkg
    package wg =  widget;                                               # widget                is from   src/lib/x-kit/widget/basic/widget.pkg
    #
    package xc =  xclient;                                              # xclient               is from   src/lib/x-kit/xclient/xclient.pkg
    package xg =  xgeometry;                                            # xgeometry             is from   src/lib/std/2d/xgeometry.pkg
herein

    package   scrollbar_look
    : (weak)  Scrollbar_Look                                            # Scrollbar_Look        is from   src/lib/x-kit/widget/leaf/scrollbar-look.api
    {
        Scrollbar_State
          = 
          { size:   Int,
            coord:  xg::Point -> Int,
            draw:  (Int, Int) -> Void,
            move:  (Int, Int, Int, Int) -> Void
          };

        Scrollbar_Look
          =
          { size_preference_thunk_of
                :
                Int -> Void -> wg::Widget_Size_Preference,

            realize
                :
                (wg::Root_Window, xc::Rgb)
                -> xc::Drawable
                -> xg::Size
                -> Scrollbar_State
          };

        inset = 1;
        bwidth = 2;

        fun move_fn (clear, fill) (x: Int, w: Int, x', w')
            =
            {   e = x+w;
                e' = x'+w';

                if (x < x' )

                    if (e <= x' )  clear (x, w);
                    elif (e < e' ) clear (x, x'-x);
                    else           clear (x, x'-x);
                                   clear (e', e-e');
                    fi;

                elif (x == x' )
                    if (e > e')    clear (e', e-e'); fi;
                elif (x < e' )
                  if (e > e' )     clear (e', e-e'); fi;
                else
                                   clear (x, w);
                fi;

                fill (x', w');
            };

        fun vertical_realize (root, color)
            =
            {   my shades as { base, ... }
                    =
                    wg::shades root color;

                fn dr
                    =
                    {   dr =  xc::make_unbuffered_drawable  dr;

                        clear =  xc::clear_box  dr;

                        fun config (xg::SIZE { wide, high } )
                            =
                            {
                                rwid = wide - 2*inset;

                                fun draw_fn (x, w)
                                    =
                                    {   r = xg::BOX { col=>inset, row=>x, wide=>rwid, high=>w };

                                        xc::clear_drawable dr;
                                        xc::fill_box dr base r;
                                        d3::draw_box dr { box=>r, width=>bwidth, relief=>d3::RAISED } shades;
                                    };

                                fun clr (x, w)
                                    =
                                    clear (xg::BOX { col=>inset, row=>x, high=>w, wide=>rwid } );


                                move_fn = move_fn (clr, draw_fn);


                                { size  =>  high,
                                  coord =>  fn xg::POINT { col, row } = row,
                                  draw  =>  draw_fn,
                                  move  =>  move_fn
                                };
                            };

                          config;
                      };
              };

        fun vertical_size_preference  dim
            =
            {   swid = dim / 3;

                size_preferences
                    =
                    { col_preference => wg::tight_preference dim,
                      row_preference => wg::INT_PREFERENCE { start_at=>swid, step_by=>1, min_steps=>0, ideal_steps=>0, max_steps=>NULL }
                    };

               fn ()
                    =
                    size_preferences;
            };

        fun horizontal_realize (root, color)
            =
            {   my shades as { base, ... }
                    =
                    wg::shades root color;

                fn dr
                    =
                    {   dr = xc::make_unbuffered_drawable  dr;

                        clear =  xc::clear_box  dr;

                        fun config (xg::SIZE { wide, high } )
                            =
                            {   rht = high - 2*inset;

                                fun draw_fn (x, w)
                                    =
                                    {   r = xg::BOX { col=>x, row=>inset, wide=>w, high=>rht };

                                        xc::clear_drawable dr;
                                        xc::fill_box dr base r;
                                        d3::draw_box dr { box=>r, width=>bwidth, relief=>d3::RAISED } shades;
                                    };

                                fun clr (x, w)
                                    =
                                    clear (xg::BOX { col=>x, row=>inset, wide=>w, high=>rht } );

                                move_fn = move_fn (clr, draw_fn);

                                { size  => wide,
                                  coord => fn xg::POINT { col, row } = col,
                                  draw  => draw_fn,
                                  move  => move_fn
                                };
                            };

                          config;
                  };
              };

        fun horizontal_size_preference  dim
            =
            {
                swid = dim / 3;

                size_preferences
                    =
                    { row_preference =>  wg::tight_preference dim,
                      col_preference =>  wg::INT_PREFERENCE { start_at=>swid, step_by=>1, min_steps=>0, ideal_steps=>0, max_steps=>NULL }
                    };

                fn ()
                    =
                    size_preferences;
            };

        horizontal_scrollbar = { size_preference_thunk_of => horizontal_size_preference,  realize => horizontal_realize };
        vertical_scrollbar   = { size_preference_thunk_of =>   vertical_size_preference,  realize =>   vertical_realize };

    };                  # package scrollbar_look

end;


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext