PreviousUpNext

15.4.1339  src/lib/x-kit/tut/calculator/calculator.pkg

## calculator.pkg

# Compiled by:
#     src/lib/x-kit/tut/calculator/calculator-app.lib


# The calculator interface.


stipulate
    include threadkit;                                  # threadkit                     is from   src/lib/src/lib/thread-kit/src/core-thread-kit/threadkit.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 lbl =  label;                               # label                         is from   src/lib/x-kit/widget/leaf/label.pkg
    package low =  line_of_widgets;                     # line_of_widgets               is from   src/lib/x-kit/widget/layout/line-of-widgets.pkg
    package sz  =  size_preference_wrapper;             # size_preference_wrapper       is from   src/lib/x-kit/widget/wrapper/size-preference-wrapper.pkg
    package pb  =  pushbuttons;                         # pushbuttons                   is from   src/lib/x-kit/widget/leaf/pushbuttons.pkg
    package ts  =  toggleswitches;                      # toggleswitches                is from   src/lib/x-kit/widget/leaf/toggleswitches.pkg
    package wt  =  widget_types;                        # widget_types                  is from   src/lib/x-kit/widget/basic/widget-types.pkg
    #
    package acc =  accumulator;                         # accumulator                   is from   src/lib/x-kit/tut/calculator/accumulator.pkg
    #
    package xtr =  xlogger;                             # xlogger       is from   src/lib/x-kit/xclient/src/stuff/xlogger.pkg
    trace       =  xtr::log_if  xtr::io_logging 0;      # Conditionally write strings to tracing.log or whatever.
        #
        # To debug via tracelogging, annotate the code with lines like
        #
        #       trace .{ sprintf "foo/top: bar d=%d" bar; };
        #
herein

    package   calculator
    :         Calculator                                # Calculator                    is from   src/lib/x-kit/tut/calculator/calculator.api
    {
        fun make_display_line  w
            =
            low::HZ_CENTER
              [
                low::SPACER { min_size=>0,  ideal_size=>5, max_size=>NULL },
                low::WIDGET ( sz::make_tight_size_preference_wrapper  w),
                low::SPACER { min_size=>0,  ideal_size=>5, max_size=>NULL }
              ];

        fun make_switch_line sw
            =
            low::HZ_CENTER
              [
                low::SPACER { min_size=>0,  ideal_size=>5, max_size=>NULL },
                low::WIDGET sw,
                low::SPACER { min_size=>5,  ideal_size=>5, max_size=>THE 5 }
              ];

        fname = "-Adobe-Helvetica-Bold-R-Normal--*-120-*";


        fun make_calculator (root_window, view, args)
            =
            {   # As selfcheck() support, maintain a map
                # from button names to button widgets:
                #
                my  buttons:  Ref( string_map::Map( button_type::Button ) )
                    =
                    REF string_map::empty;      

                my display_update':  Ref (Null_Or( Mailqueue( String )))
                    =
                    REF NULL;

                fun make_line (root_window, view, args) itemlist
                    =
                    {   hglue = low::SPACER { min_size=>5,  ideal_size=>5, max_size=>THE 5 };

                        fun add_box ((name, act), l)
                            =
                            {   args = [ (wa::label, wa::STRING_VAL name),
                                         (wa::font,  wa::STRING_VAL fname)
                                       ];

                                fw =  pb::make_text_pushbutton_with_click_callback'
                                          #
                                          (root_window, view, args)
                                          #
                                          act;

                                buttons := string_map::set (*buttons, name, fw);

                                hglue ! (low::WIDGET (pb::as_widget fw)) ! l;
                            };

                        boxlist
                            =
                            list::fold_backward
                                #
                                add_box
                                #
                                [ hglue ]
                                #
                                itemlist;

                        low::HZ_CENTER boxlist;
                    };

                disp_args = [ (wa::label,  wa::STRING_VAL "          0"),
                              (wa::relief, wa::RELIEF_VAL  wg::SUNKEN),
                              (wa::halign, wa::HALIGN_VAL  wt::HRIGHT)
                            ];

                display
                    =
                    lbl::make_label' (root_window, view, disp_args);

                display_line
                    =
                    make_display_line  (lbl::as_widget  display);

                fun quit _
                    =
                    {   fun cleanup ()
                            =
                            {   sleep_for 0.5; 
                                #
                                wg::delete_root_window root_window; 
                                #
                                shut_down_thread_scheduler  winix__premicrothread::process::success;
                                #
                            };

                        threadkit::make_thread  "calc cleanup"  cleanup;

                        ();
                    };

                sw = ts::as_widget (ts::make_rocker_toggleswitch' (root_window, view, args) quit);

                switch_line = make_switch_line sw;

                accumulator = acc::make_accumulator ();

                send_to_accumulator = acc::send_to_accumulator accumulator;

                fun printer ()
                    =
                    loop ()
                    where
                        from_accumulator' =  acc::from_accumulator_mailop_of  accumulator;

                        fun show text
                            =
                            lbl::set_label display (lbl::TEXT text);

                        fun loop ()
                            =
                            for (;;) {
                                #
                                new_display_string
                                    =
                                    case (block_until_mailop_fires  from_accumulator')
                                        #
                                        acc::OVAL v    =>  (int::to_string v);
                                        acc::OINFINITY =>  "Infinity";
                                        acc::OOVERFLOW =>  "OVERFLOW";
                                    esac;

                                show new_display_string;

                                case *display_update'
                                    #
                                    THE mailqueue =>  put_in_mailqueue (mailqueue, new_display_string);
                                    NULL          =>  ();
                                esac;
                            };
                    end;

                stipulate
                    fun do plea () =  send_to_accumulator plea;
                herein

                    line1 = make_line   (root_window, view, args)
                              [
                                ("7", do (acc::DIGIT 7)),
                                ("8", do (acc::DIGIT 8)),
                                ("9", do (acc::DIGIT 9)),
                                ("+", do (acc::OP acc::PLUS))
                              ];

                    line2 = make_line   (root_window, view, args)
                              [
                                ("4", do (acc::DIGIT 4)),
                                ("5", do (acc::DIGIT 5)),
                                ("6", do (acc::DIGIT 6)),
                                ("-", do (acc::OP acc::MINUS))
                              ];

                    line3 = make_line   (root_window, view, args)
                              [
                                ("1", do (acc::DIGIT 1)),
                                ("2", do (acc::DIGIT 2)),
                                ("3", do (acc::DIGIT 3)),
                                ("*", do (acc::OP acc::TIMES))
                              ];

                    line4 = make_line   (root_window, view, args)
                              [
                                ("C", do (acc::CLEAR)),
                                ("0", do (acc::DIGIT 0)),
                                ("=", do (acc::EQUAL)),
                                ("/", do (acc::OP acc::DIVIDE))
                              ];
                end;

                vglue = low::SPACER { min_size=>1, ideal_size=>5, max_size=>NULL };

                make_thread "calc printer" printer;

                widgettree
                    =
                    low::as_widget
                        (low::line_of_widgets
                            (root_window, view, args)
                            (low::VT_CENTER
                              [
                                vglue,
                                display_line,
                                vglue,
                                switch_line,
                                vglue,
                                line1,
                                vglue,
                                line2,
                                vglue,
                                line3,
                                vglue,
                                line4,
                                vglue
                              ]
                        )   );

                { widgettree, selfcheck_interface => { buttons => *buttons, display_update' } };
            };                          # fun make_calculator 

    };                                  # package calculator 

end;


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext