PreviousUpNext

15.4.1506  src/lib/x-kit/widget/old/leaf/button-look-from-drawfn-and-sizefn-g.pkg

## button-look-from-drawfn-and-sizefn-g.pkg

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



# Generic for producing simple shape button views.



###         "[By the end of the 20th Century there will be a generation]
###          to whom it will not be injurious to read a dozen quire
###          of newspapers daily, to be constantly called to the telephone
###          [and] to live half their time in a railway carriage
###          or in a flying machine."
###
###                                      -- Max Nordau 1895


stipulate
    package bst =  button_shape_types;                          # button_shape_types                    is from   src/lib/x-kit/widget/old/leaf/button-shape-types.pkg
    package wg  =  widget;                                      # widget                                is from   src/lib/x-kit/widget/old/basic/widget.pkg
    package wa  =  widget_attribute_old;                        # widget_attribute_old                  is from   src/lib/x-kit/widget/old/lib/widget-attribute-old.pkg
    package wt  =  widget_types;                                # widget_types                          is from   src/lib/x-kit/widget/old/basic/widget-types.pkg
    package xc  =  xclient;                                     # xclient                               is from   src/lib/x-kit/xclient/xclient.pkg
herein

    # This generic is invoked in:
    #
    #     src/lib/x-kit/widget/old/leaf/diamondbutton-look.pkg
    #     src/lib/x-kit/widget/old/leaf/boxbutton-look.pkg
    #     src/lib/x-kit/widget/old/leaf/roundbutton-look.pkg
    #     src/lib/x-kit/widget/old/leaf/arrowbutton-look.pkg
    #
    generic package  button_look_from_drawfn_and_sizefn_g  (    # 
        #            ====================================
        #
        s:  Button_Drawfn_And_Sizefn                            # Button_Drawfn_And_Sizefn              is from   src/lib/x-kit/widget/old/leaf/button-drawfn-and-sizefn.api
                                                                # arrowbutton_drawfn_and_sizefn         is from   src/lib/x-kit/widget/old/leaf/arrowbutton-drawfn-and-sizefn.pkg
                                                                # roundbutton_drawfn_and_sizefn         is from   src/lib/x-kit/widget/old/leaf/roundbutton-drawfn-and-sizefn.pkg
                                                                # boxbutton_drawfn_and_sizefn           is from   src/lib/x-kit/widget/old/leaf/boxbutton-drawfn-and-sizefn.pkg
                                                                # diamondbutton_drawfn_and_sizefn       is from   src/lib/x-kit/widget/old/leaf/diamondbutton-drawfn-and-sizefn.pkg
    )
    : (weak)  Button_Look                                       # Button_Look                           is from   src/lib/x-kit/widget/old/leaf/button-look.api
    {
        attributes
           = (wa::border_thickness, wa::INT,    wa::INT_VAL 2)
           ! (wa::width,            wa::INT,    wa::INT_VAL 30)
           ! (wa::height,           wa::INT,    wa::NO_VAL)
           ! (wa::background,       wa::COLOR,  wa::STRING_VAL "white")
           ! (wa::color,            wa::COLOR,  wa::NO_VAL)
           ! (wa::ready_color,      wa::COLOR,  wa::NO_VAL)
           ! (wa::foreground,       wa::COLOR,  wa::NO_VAL)
           ! s::attributes
           ;

         Button_Look
             =
             BUTTON_LOOK
               {
                 bw:            Int,

                 shades:        wg::Shades,
                 rshades:       wg::Shades,

                 stipple:       xc::Ro_Pixmap,
                 drawfn:        bst::Drawfn,

                 fg:            Null_Or( xc::Rgb ),
                 bg:                     xc::Rgb,

                 size:          wg::Widget_Size_Preference
               };

        fun make_button_look (root, view, args)
            =
            {   attributes
                    =
                    wg::find_attribute (wg::attributes (view, attributes, args));

                (s::make_button_drawfn_and_sizefn attributes)
                    ->
                    (drawfn, sizefn);

                stipple = wg::ro_pixmap root "gray";

                wide =  wa::get_int     (attributes wa::width);
                high =  wa::get_int_opt (attributes wa::height);

                foreground_color = wa::get_color_opt (attributes wa::foreground);
                background_color = wa::get_color     (attributes wa::background);

                color  = case (wa::get_color_opt (attributes wa::color))   
                             #
                             THE color => color;
                              _ => background_color;
                         esac;

                readyc = case (wa::get_color_opt (attributes wa::ready_color))   
                             #
                             THE color => color;
                              _        => color;
                         esac;

                bwid = wa::get_int (attributes wa::border_thickness);

                shades = wg::shades root color;

                BUTTON_LOOK
                  {
                    bg => background_color,
                    fg => foreground_color,

                    bw => bwid,
                    stipple,
                    shades,                                                     # Three shades used for body, edge-light and edge-dark when we do NOT have mouse focus.

                    rshades => (xc::same_rgb (color, readyc))                   # Three shades used for body, edge-light and edge-dark when we DO     have mouse focus.
                                 ?? shades
                                 :: wg::shades root readyc,
                    drawfn,
                    size => sizefn (wide, high)
                  };
              };

        fun make_button_drawfn (BUTTON_LOOK v, window, size)
            =
            case fg
                #
                NULL =>   setf;
                   _ =>  fsetf;
            esac
            where
                dr = xc::drawable_of_window window;
                #
                v ->  { fg, bw, drawfn, shades, rshades, ... };

                draw = drawfn (dr, size, bw);

                fun add_stipple p
                    =
                    xc::clone_pen
                      ( p,
                        [ xc::p::FILL_STYLE_STIPPLED, 
                          xc::p::STIPPLE v.stipple
                        ]
                      );

                shades  ->  { light, base, dark };                              # base color becomes foreground color unless overridden.
                rshades ->  { light=>rlight, base=>rbase, dark=>rdark };        # 'r' is for 'ready', used when we have mouse focus.

                ilight =  add_stipple  light;                                   # 'i' is for 'inactive', used when button state is INACTIVE ("grayed-out").
                idark  =  add_stipple  dark;
                ibase  =  add_stipple  base;

                my (fore, ifore)
                    = 
                    case fg
                        #
                        NULL  => (base, ibase);
                        #
                        THE c => {   forepen = xc::make_pen [xc::p::FOREGROUND (xc::rgb8_from_rgb c) ];
                                     (forepen, add_stipple forepen);
                                 };
                    esac;

                fun setf { button_state => wt::INACTIVE TRUE,  ... }
                        =>
                        draw (ibase, idark, ilight);                            # First color fills in button, other two are used for the 3D outline effect. We reverse the latter two if the button is set, also if the mousebutton is pushed.

                    setf { button_state => wt::INACTIVE FALSE, ... }
                        =>
                        draw (ibase, ilight, idark);

                    setf { button_state => wt::ACTIVE FALSE, has_mouse_focus, mousebutton_is_down => FALSE }
                        => 
                        if has_mouse_focus  draw (rbase, rlight, rdark);
                        else                draw ( base,  light,  dark);
                        fi;

                    setf { button_state => wt::ACTIVE FALSE, has_mouse_focus, mousebutton_is_down => TRUE }
                        =>
                        if has_mouse_focus  draw (rbase, rdark, rlight);
                        else                draw ( base,  dark,  light);
                        fi;

                    setf { button_state => wt::ACTIVE TRUE, has_mouse_focus, mousebutton_is_down => FALSE }
                        =>
                        if has_mouse_focus  draw (rbase, rdark, rlight);
                        else                draw ( base,  dark,  light);
                        fi;

                    setf { button_state => wt::ACTIVE TRUE, has_mouse_focus, mousebutton_is_down => TRUE }
                        =>
                        if has_mouse_focus  draw (rbase, rdark, rlight);
                        else                draw ( base,  dark,  light);
                        fi;
                end;

                fun fsetf { button_state => wt::INACTIVE TRUE, ... }
                        =>
                        draw (ifore, ilight, idark);

                    fsetf { button_state => wt::INACTIVE FALSE, ... }
                        =>
                        draw (ibase, ilight, idark);

                    fsetf { button_state => wt::ACTIVE FALSE, has_mouse_focus, mousebutton_is_down => FALSE }
                        => 
                        if has_mouse_focus  draw (rbase, rlight, rdark);
                        else                draw ( base,  light,  dark);
                        fi;

                    fsetf { button_state => wt::ACTIVE FALSE, has_mouse_focus, mousebutton_is_down => TRUE }
                        =>
                        if has_mouse_focus  draw (rbase, rdark, rlight);
                        else                draw ( base,  dark,  light);
                        fi;

                    fsetf { button_state => wt::ACTIVE TRUE, has_mouse_focus, mousebutton_is_down => FALSE }
                        =>
                        if has_mouse_focus  draw (fore, rlight, rdark);
                        else                draw (fore,  light,  dark);
                        fi;

                    fsetf { button_state => wt::ACTIVE TRUE, has_mouse_focus, mousebutton_is_down => TRUE }
                        =>
                        if has_mouse_focus  draw (fore, rdark, rlight);
                        else                draw (fore,  dark,  light);
                        fi;
                 end;
            end;

        fun bounds (BUTTON_LOOK { size, ... } )
            =
            size;


        fun window_args (BUTTON_LOOK { bg, ... } )
            =
            { background => THE bg };

    };                                          # generic package button_look_from_drawfn_and_sizefn_g 

end;


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext