An example of a calculator written (probably non-idomatic) factor.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
! Copyright (C) 2018 Andrew Owen. | |
! See http://factorcode.org/license.txt for BSD license. | |
USING: | |
ui ui.gadgets ui.gadgets.tracks ui.gadgets.labels ui.gadgets.buttons ui.gadgets.packs ui.tools.operations | |
ui.pens.solid ui.pens.gradient | |
colors colors.constants | |
accessors math.parser vocabs.loader io locals | |
models models.arrow fry | |
kernel strings sequences math | |
; | |
IN: calculator | |
TUPLE: calculator-state | |
{ accum initial: "" } | |
{ prev initial: 0 } | |
{ op initial: [ drop drop ] } | |
; | |
: <calculator-state> ( -- new-calc-state ) calculator-state new ; | |
: calc-clear-all ( state -- ) | |
[ accum>> "" swap set-model ] keep | |
prev>> 0 swap set-model | |
; | |
: calc-clear ( state -- ) accum>> "" swap set-model ; | |
:: set-calc-op ( state quot -- ) | |
state quot >>op | |
! Move the accum value to the prev model | |
[ accum>> value>> string>number ] [ prev>> ] bi set-model | |
! Clear accum | |
"" state accum>> set-model | |
; | |
:: calculate ( state -- ) | |
state [ prev>> value>> ] [ accum>> value>> string>number ] bi state op>> call( x y -- result ) | |
number>string state accum>> set-model | |
; | |
: echoed ( track char model -- track ) | |
! Char is actually a string here. | |
[let :> model :> char | |
char <label> | |
! The value in the model here is a string | |
[ drop model dup value>> char append swap set-model ] | |
<border-button> 0.33 track-add | |
] | |
; | |
:: operators-layout-init ( state -- gadget ) | |
vertical <track> | |
horizontal <track> | |
"/" <label> [ drop state [ / ] set-calc-op ] <border-button> 0.5 track-add | |
"AC" <label> [ drop state calc-clear-all ] <border-button> 0.5 track-add | |
0.25 track-add | |
horizontal <track> | |
"*" <label> [ drop state [ * ] set-calc-op ] <border-button> 0.5 track-add | |
"C" <label> [ drop state calc-clear ] <border-button> 0.5 track-add | |
0.25 track-add | |
horizontal <track> | |
"-" <label> [ drop state [ - ] set-calc-op ] <border-button> 0.5 track-add | |
"" <label> 0.5 track-add | |
0.25 track-add | |
horizontal <track> | |
"+" <label> [ drop state [ + ] set-calc-op ] <border-button> 0.25 track-add | |
"=" <label> [ drop state calculate ] <border-button> 0.25 track-add | |
0.25 track-add | |
; | |
:: digits-layout-init ( calculator-state -- gadget ) | |
calculator-state accum>> :> accum | |
vertical <track> | |
! TODO: Figure out the way to build the tracks here. | |
horizontal <track> { "7" "8" "9" } [ accum echoed ] each 0.25 track-add | |
horizontal <track> { "4" "5" "6" } [ accum echoed ] each 0.25 track-add | |
horizontal <track> { "1" "2" "3" } [ accum echoed ] each 0.25 track-add | |
horizontal <track> { "." "0" "" } [ accum echoed ] each 0.25 track-add | |
; | |
:: calculator-init ( -- gadget ) | |
<calculator-state> | |
"" <model> >>accum | |
0 <model> >>prev | |
:> state | |
vertical <track> | |
state accum>> <label-control> 0.4 track-add | |
horizontal <track> | |
state digits-layout-init 0.6 track-add | |
state operators-layout-init 0.4 track-add | |
0.6 track-add | |
; | |
: calculator-show ( -- ) calculator-init "Calculator" open-window* { 200 300 } >>dim drop ; | |
<PRIVATE | |
:: alert ( message -- ) <shelf> message <label> add-gadget message open-window ; | |
PRIVATE> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment