PreviousUpNext

15.4.1400  src/lib/x-kit/widget/leaf/rockerbutton-look.pkg

## rockerbutton-look.pkg
#
# View for rocker switch.

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






###         "Inventions have long since reached their limit,
###          and I see no hope for further developments."
###
###                         -- Julius Sextus Frontinus, 10 AD


# This package gets used in:
#
#     src/lib/x-kit/widget/leaf/toggleswitches.pkg

stipulate
    package f  =  sfprintf;                                             # sfprintf              is from   src/lib/src/sfprintf.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
    #
    package wg =  widget;                                               # widget                is from   src/lib/x-kit/widget/basic/widget.pkg
    package wa =  widget_attribute;                                     # widget_attribute      is from   src/lib/x-kit/widget/lib/widget-attribute.pkg
    package wt =  widget_types;                                         # widget_types          is from   src/lib/x-kit/widget/basic/widget-types.pkg
herein

    package rockerbutton_look: (weak)  Button_Look {    # Button_Look   is from   src/lib/x-kit/widget/leaf/button-look.api

        on_switch_data = xc::make_clientside_pixmap_from_ascii (32, [[
          "0x0C000000", "0x1B000000", "0x28C00000", "0x5A300000",
          "0xA88C0000", "0xDA230000", "0xA888FFFE", "0xDA228002",
          "0xA888AAAA", "0xDA228002", "0xA888AAAA", "0xDA228002",
          "0xAC88AAAA", "0xDF228002", "0xBFC8AAAA", "0xFFF28002",
          "0xFFFCAAAA", "0xFFFF8002", "0xFFFFFFFE", "0xFFFFFFFE",
          "0x7FFFFFFC"
        ]]);

        on_switch_mask = xc::make_clientside_pixmap_from_ascii (32, [[
          "0x0c000000", "0x1f000000", "0x3fc00000", "0x7ff00000",
          "0xfffc0000", "0xffff0000", "0xfffffffe", "0xfffffffe",
          "0xfffffffe", "0xfffffffe", "0xfffffffe", "0xfffffffe",
          "0xfffffffe", "0xfffffffe", "0xfffffffe", "0xfffffffe",
          "0xfffffffe", "0xfffffffe", "0xfffffffe", "0xfffffffe",
          "0x7ffffffc"
        ]]);

        off_switch_data = xc::make_clientside_pixmap_from_ascii (32, [[
          "0x00000060", "0x000001B0", "0x00000628", "0x000018B4",
          "0x0000622A", "0x000188B6", "0xFFFE222A", "0x800288B6",
          "0xAAAA222A", "0x800288B6", "0xAAAA222A", "0x800288B6",
          "0xAAAA226A", "0x800289F6", "0xAAAA27FA", "0x80029FFE",
          "0xAAAA7FFE", "0x8003FFFE", "0xFFFFFFFE", "0xFFFFFFFE",
          "0x7FFFFFFC"
        ]]);

        off_switch_mask = xc::make_clientside_pixmap_from_ascii (32, [[
          "0x00000060", "0x000001f0", "0x000007f8", "0x00001ffc",
          "0x00007ffe", "0x0001fffe", "0xfffffffe", "0xfffffffe",
          "0xfffffffe", "0xfffffffe", "0xfffffffe", "0xfffffffe",
          "0xfffffffe", "0xfffffffe", "0xfffffffe", "0xfffffffe",
          "0xfffffffe", "0xfffffffe", "0xfffffffe", "0xfffffffe",
          "0x7ffffffc"
        ]]);

        attributes
            =
            [ (wa::color,          wa::COLOR,  wa::NO_VAL),
              (wa::ready_color,    wa::COLOR,  wa::NO_VAL),
              (wa::background,     wa::COLOR,  wa::STRING_VAL "white"),
              (wa::foreground,     wa::COLOR,  wa::STRING_VAL "black")
            ];

         Button_Look
             =
             BUTTON_LOOK
             { fg:        xc::Rgb,
               bg:        xc::Rgb,
               color:     xc::Rgb,
               readyc:    xc::Rgb,
               #        
               on_src:    xc::Ro_Pixmap,
               off_src:   xc::Ro_Pixmap,
               on_mask:   xc::Ro_Pixmap,
               off_mask:  xc::Ro_Pixmap,
               #        
               inactive_on_mask:  xc::Ro_Pixmap,
               inactive_off_mask: xc::Ro_Pixmap,
               #        
               iwid:  Int,
               iht:   Int
             };

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

                fg = wa::get_color (attributes wa::foreground); 
                bg = wa::get_color (attributes wa::background); 

                color  = case (wa::get_color_opt (attributes wa::color))   
                             #
                             THE c => c;
                             NULL  => bg;
                         esac;

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

                screen = wg::screen_of root;

                stipple = wg::ro_pixmap root "gray";

                on_src      = xc::make_readonly_pixmap_from_clientside_pixmap screen on_switch_data;
                off_src     = xc::make_readonly_pixmap_from_clientside_pixmap screen off_switch_data;

                on_pattern  = xc::make_readwrite_pixmap_from_clientside_pixmap screen on_switch_mask;
                off_pattern = xc::make_readwrite_pixmap_from_clientside_pixmap screen off_switch_mask;

                on_mask     = xc::make_readonly_pixmap_from_readwrite_pixmap   on_pattern;
                off_mask    = xc::make_readonly_pixmap_from_readwrite_pixmap  off_pattern;

                # Create stippled masks:
                #
                size =   xc::size_of_rw_pixmap   on_pattern;

                spen = xc::make_pen                                     # "spen" may be "stipple pen"
                         [ xc::p::STIPPLE stipple,
                           xc::p::FILL_STYLE_OPAQUE_STIPPLED,
                           xc::p::FOREGROUND  xc::rgb8_color1,
                           xc::p::BACKGROUND  xc::rgb8_color0,
                           xc::p::FUNCTION    xc::OP_AND
                         ]; 

                xc::fill_box (xc::drawable_of_rw_pixmap  off_pattern) spen (xg::box::make (xg::point::zero, size));
                xc::fill_box (xc::drawable_of_rw_pixmap   on_pattern) spen (xg::box::make (xg::point::zero, size));

                inactive_on_mask  = xc::make_readonly_pixmap_from_readwrite_pixmap   on_pattern;
                inactive_off_mask = xc::make_readonly_pixmap_from_readwrite_pixmap  off_pattern;

                my { size=>xg::SIZE { wide=>twid, high=>tht }, ... }
                    =
                    xc::shape_of_ro_pixmap  on_src;

    #         destroy_pixmap on_pattern
    #         destroy_pixmap off_pattern

                BUTTON_LOOK
                  {
                    fg,
                    bg,
                    color,
                    readyc,
                    on_src,
                    off_src,
                    on_mask,
                    off_mask,
                    inactive_on_mask,
                    inactive_off_mask,
                    iwid => twid,
                    iht => tht
                  };
            };

        fun bounds (BUTTON_LOOK { iwid, iht, ... } )
            =
            wg::make_tight_size_preference (iwid, iht);


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


        fun config (BUTTON_LOOK (v as { iwid, iht, color, readyc, ... } ), window, xg::SIZE { wide, high } )
            =
            setf
            where
                drawable =  xc::drawable_of_window  window;

                on_src   =  v.on_src;
                off_src  =  v.off_src;

                on_mask  =  v.on_mask;
                off_mask =  v.off_mask;

                inactive_on_mask  =  v.inactive_on_mask;
                inactive_off_mask =  v.inactive_off_mask;

                # Compute point at which
                # to blt centered icon: 
                #
                pt = xg::POINT { col=>(wide-iwid) / 2,
                                 row=>(high-iht)  / 2
                               };

                on_pen = xc::make_pen
                           [ xc::p::FOREGROUND (xc::rgb8_from_rgb v.fg),
                             xc::p::BACKGROUND (xc::rgb8_from_rgb color),
                             xc::p::CLIP_MASK on_mask,
                             xc::p::CLIP_ORIGIN pt
                           ];

                off_pen = xc::clone_pen (on_pen, [xc::p::CLIP_MASK off_mask]);

                my (ready_on_pen, ready_off_pen)
                    =
                    if (xc::same_rgb (color, readyc))
                        ( on_pen,
                          off_pen
                        );
                    else
                        ( xc::clone_pen (on_pen,  [xc::p::BACKGROUND (xc::rgb8_from_rgb readyc)]),
                          xc::clone_pen (off_pen, [xc::p::BACKGROUND (xc::rgb8_from_rgb readyc)])
                        );
                    fi;

                inactive_on_pen  =  xc::clone_pen (on_pen,  [xc::p::CLIP_MASK inactive_on_mask ]);
                inactive_off_pen =  xc::clone_pen (off_pen, [xc::p::CLIP_MASK inactive_off_mask]);

                fun draw (from, pen)
                    =
                    {   xc::clear_drawable drawable;
                        xc::texture_blt drawable pen { from, to_pos=>pt };
                    };

                fun setf { button_state => wt::INACTIVE TRUE, ... }
                        =>
                        draw (on_src,  inactive_on_pen);

                    setf { button_state => wt::INACTIVE FALSE, ... }
                        =>
                        draw (off_src, inactive_off_pen);

                    setf { button_state => wt::ACTIVE FALSE, has_mouse_focus, mousebutton_is_down => FALSE }
                        => 
                        if has_mouse_focus  draw (off_src, ready_off_pen);
                        else                draw (off_src, off_pen);
                        fi;

                    setf { button_state => wt::ACTIVE FALSE, has_mouse_focus, mousebutton_is_down => TRUE }
                        =>
                        if has_mouse_focus  draw (on_src, ready_on_pen);
                        else                draw (on_src, on_pen);
                        fi;

                    setf { button_state => wt::ACTIVE TRUE, has_mouse_focus, mousebutton_is_down => FALSE }
                        =>
                        if has_mouse_focus  draw (on_src, ready_on_pen);
                        else                draw (on_src, on_pen);
                        fi;

                    setf { button_state => wt::ACTIVE TRUE, has_mouse_focus, mousebutton_is_down => TRUE }
                        =>
                        if has_mouse_focus  draw (off_src, ready_off_pen);
                        else                draw (off_src, off_pen);
                        fi;
                end;
      /*
                setf = fn (a as (wg::INACTIVE s, r, d)) =>
                        (file::print (f::sprintf "Inactive %B %B %B\n"
                            [f::BOOL s, f::BOOL r, f::BOOL d]); setf a)
                            | (a as (wg::Active s, r, d)) =>
                        (file::print (f::sprintf "Active %B %B %B\n"
                            [f::BOOL s, f::BOOL r, f::BOOL d]); setf a)
      */
            end;

    };                                  # package rockerbutton_look 

end;


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext