PreviousUpNext

15.4.1543  src/lib/x-kit/widget/old/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 package   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/old/menu/popup-menu.pkg
    package ts =  toggleswitches;                               # toggleswitches                is from   src/lib/x-kit/widget/old/leaf/toggleswitches.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 wy =  widget_style_old;                             # widget_style_old              is from   src/lib/x-kit/widget/old/lib/widget-style-old.pkg
    package g2d=  geometry2d;                                   # geometry2d                    is from   src/lib/std/2d/geometry2d.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/old/menu/pulldown-menu-button.api
    {
        fun make_pulldown_menu_button  root_window  (label, menu)
            =
            {   w_slot = make_mailslot ();
                r_slot = make_mailslot ();

                all_buttons = 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)
                       ];

                button = ts::label_button
                         ( root_window,
                           ( name,
                             wg::style_of  root_window
                           ),
                           args
                         )
                         (\\ _ = ());

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

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


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


                (pu::attach_positioned_menu_to_widget (ts::as_widget button, all_buttons, menu, query))
                    ->
                    (widget, mailop);


                fun realize_widget { 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::get_contents_of_envelope  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::get_contents_of_envelope  envelope)
                                #
                                xc::ETC_RESIZE ({ wide, high, ... }: g2d::Box)
                                    => 
                                    {   put_in_mailslot (c_slot, envelope);
                                        { wide, high };
                                    };

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

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

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

                        wg::realize_widget  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 =>   \\ () = { background => NULL },

                        realize_widget,

                        size_preference_thunk_of
                            =>
                            wg::size_preference_thunk_of  widget
                      };

                (menu_widget, mailop);
            };
    };

end;



Comments and suggestions to: bugs@mythryl.org

PreviousUpNext