PreviousUpNext

15.4.1424  src/lib/x-kit/widget/menu/pulldown-menu-button.pkg

## pulldown-menu-button.pkg

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



###            "Truth is the daughter of time,
###              not of authority."
###
###                     -- Francis Bacon

stipulate
    include threadkit;                                          # threadkit                     is from   src/lib/src/lib/thread-kit/src/core-thread-kit/threadkit.pkg
    #
    package pu =  popup_menu;                                   # popup_menu                    is from   src/lib/x-kit/widget/menu/popup-menu.pkg
    package ts =  toggleswitches;                               # toggleswitches                is from   src/lib/x-kit/widget/leaf/toggleswitches.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 wy =  widget_style;                                 # widget_style                  is from   src/lib/x-kit/widget/lib/widget-style.pkg
    package xg =  xgeometry;                                    # xgeometry                     is from   src/lib/std/2d/xgeometry.pkg
    #
    package xc =  xclient;                                      # xclient                       is from   src/lib/x-kit/xclient/xclient.pkg
herein

    package   pulldown_menu_button
    : (weak)  Pulldown_Menu_Button                              # Pulldown_Menu_Button          is from   src/lib/x-kit/widget/menu/pulldown-menu-button.api
    {
        fun make_pulldown_menu_button  root_window  (label, menu)
            =
            {   w_slot = make_mailslot ();
                r_slot = make_mailslot ();

                all_bttns = map  xc::MOUSEBUTTON  [1, 2, 3, 4, 5];

                name = wy::make_view { name    =>  wy::style_name ["menuButton"],
                                       aliases =>  []
                                     };

                args = [ (wa::relief, wa::RELIEF_VAL wg::FLAT),
                         (wa::label,  wa::STRING_VAL label)
                       ];

                bttn = ts::label_button
                         ( root_window,
                           ( name,
                             wg::style_of  root_window
                           ),
                           args
                         )
                         (fn _ = ());

                fun pre_fn  () =  ts::set_button_on_off_flag (bttn, TRUE);
                fun post_fn () =  ts::set_button_on_off_flag (bttn, FALSE);

                fun query arg
                    =
                    {   put_in_mailslot (w_slot, arg);
                        take_from_mailslot r_slot;
                    };


                fun pos (pu::WHERE_INFO { screen_point=> xg::POINT { col=>sx, row=>sy },
                                          window_point=> xg::POINT { col=>x, row=>y },
                                          timestamp,
                                          mouse_button
                                        },
                         xg::SIZE { high, ... }
                        )
                    = 
                    pu::PUT_POPUP_MENU_UPPERLEFT_ON_SCREEN
                        (xg::POINT { col=>sx-x, row=>sy-y+high+1 } );


                my (widget, mailop)
                    = 
                    pu::attach_positioned_menu_to_widget (ts::as_widget bttn, all_bttns, menu, query);


                fun menu_realize { window, window_size, kidplug }
                    =
                    {   kidplug ->  xc::KIDPLUG { from_mouse', from_other', ... };

                        m_slot = make_mailslot ();
                        c_slot = make_mailslot ();

                        fun do_mouse  envelope
                            =
                            {   case (xc::envelope_contents  envelope)
                                    #                              
                                    xc::MOUSE_FIRST_DOWN _ => pre_fn  ();
                                    xc::MOUSE_LAST_UP    _ => post_fn ();
                                    _                      => ();
                                esac;

                                put_in_mailslot (m_slot, envelope);
                            };

                        fun do_mom (envelope, size)
                            =
                            case (xc::envelope_contents  envelope)
                                #
                                xc::ETC_RESIZE (xg::BOX { wide, high, ... } )
                                    => 
                                    {   put_in_mailslot (c_slot, envelope);
                                        xg::SIZE { wide, high };
                                    };

                               _ => {   put_in_mailslot (c_slot, envelope);
                                        size;
                                    };
                            esac;

                        fun loop window_size
                            =
                            loop (
                                do_one_mailop [
                                    from_mouse'  ==>  (fn mailop = {  do_mouse mailop;  window_size;  }),
                                    from_other'  ==>  (fn mailop =    do_mom (mailop, window_size)),
                                    take_from_mailslot' w_slot ==>  (fn msg    = {  put_in_mailslot (r_slot, pos (msg, window_size));   window_size;   })
                                ]
                            );

                        make_thread "menu_button" .{
                            #
                            loop window_size;
                        };

                        wg::realize_fn  widget
                          {
                            window,
                            window_size,
                            kidplug => xc::replace_other
                                           ( xc::replace_mouse  (kidplug,  take_from_mailslot'  m_slot),
                                             take_from_mailslot'  c_slot
                                           )
                          };
                    };

                menu_widget
                    =
                    wg::make_widget
                      {
                        root_window,

                        args =>   fn () = { background => NULL },

                        realize   => menu_realize,

                        size_preference_thunk_of
                            =>
                            wg::size_preference_thunk_of  widget
                      };

                (menu_widget, mailop);
            };
    };

end;



Comments and suggestions to: bugs@mythryl.org

PreviousUpNext