## 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;