PreviousUpNext

15.4.1373  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 package   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/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 lbl =  label;                               # label                         is from   src/lib/x-kit/widget/old/leaf/label.pkg
    package low =  line_of_widgets;                     # line_of_widgets               is from   src/lib/x-kit/widget/old/layout/line-of-widgets.pkg
    package sz  =  size_preference_wrapper;             # size_preference_wrapper       is from   src/lib/x-kit/widget/old/wrapper/size-preference-wrapper.pkg
    package pb  =  pushbuttons;                         # pushbuttons                   is from   src/lib/x-kit/widget/old/leaf/pushbuttons.pkg
    package ts  =  toggleswitches;                      # toggleswitches                is from   src/lib/x-kit/widget/old/leaf/toggleswitches.pkg
    package wt  =  widget_types;                        # widget_types                  is from   src/lib/x-kit/widget/old/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,  best_size=>5, max_size=>NULL },
                low::WIDGET ( sz::make_tight_size_preference_wrapper  w),
                low::SPACER { min_size=>0,  best_size=>5, max_size=>NULL }
              ];

        fun make_switch_line sw
            =
            low::HZ_CENTER
              [
                low::SPACER { min_size=>0,  best_size=>5, max_size=>NULL },
                low::WIDGET sw,
                low::SPACER { min_size=>5,  best_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:
                #
                buttons =   REF  string_map::empty
                        :   Ref( string_map::Map( button_type::Button ) )
                        ;

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

                fun make_line (root_window, view, args) itemlist
                    =
                    {   hglue =  low::SPACER { min_size=>5,  best_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, best_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