Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
An example of a calculator written (probably non-idomatic) factor.
! 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