April 17, 2024, 10:41:59 PM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


A Simple Calculator

Started by GWS, August 01, 2011, 11:25:33 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

GWS

Hi folks,

Here's a program for a simple calculator. :)

The trickiest bits were positioning the buttons using as few statements as possible, processing the numbers typed in, and printing out the results to a decent precision.


' Creative Basic Calculator Example
' GWS 2011

def w:window
def Left,Top,Width,Height,bW,bH:int
def wW,wH,bleft,bxspace,byspace:int
def i,j,y,tbwidth,tbheight:int
def bchar[20],ba[20],ballow,state:int
def value1,value2,value3:double
def a$,b$,oper$,value3$:string

wW = 160
wH = 300

window w,-wW,-wH,wW,wH,0,0,"Calculator",main
setwindowcolor w, rgb(5,45,120)
centerwindow w

getclientsize w,Left,Top,Width,Height
rect w,0,0,Width,Height,rgb(0,0,40)

bchar[1] = 48,46,61,49,50,51,52,53,54,55,56,57,43,45,120,47
' (ie:  0,.,=,1,2,3,4,5,6,7,8,9,+,-,x,and divide)

bW = 35
bH = 30
bleft = 5
bxspace = bW + 2
byspace = bH + 2

tbwidth = 145
tbheight = 20

for i = 1 to 12
y = floor((i-1)/3)+1
control w,"B," + chr$(bchar[i]) +",bleft+((i-1) % 3)*bxspace,Height-y*byspace,bW,bH,0,i"
setfont w,"Arial",12,700,0,i
next i

control w,"B,+,4+3*bW+7,Height-byspace,bW,bH,0,13"
control w,"B," + chr$(150)+ ",3*bW+11,Height-2*byspace,bW,bH,0,14"
control w,"B,x,4+3*bW+7,Height-3*byspace,bW,bH,0,15"
for i = 13 to 15
setfont w,"Arial",12,700,0,i
next i 

control w,"B," + chr$(247)+ ",3*bW+11,Height-4*byspace,bW,bH,0,16"
setfont w,"Arial",14,600,0,16
control w,"B,CE,bleft,Height-5*byspace,bW,bH,0,17"
setfont w,"Arial",10,700,0,17
control w,"B,CLR,3*bW+11,Height-5*byspace,bW,bH,0,18" 
setfont w,"Arial",10,700,0,18

' set text boxes for input values and the result ..
for i = 20 to 23
control w,"T,,4,6 + (i-20)* (tbheight+6),tbwidth,tbheight,0x200,i"
setcontrolcolor w,i,0xffffff,rgb(5,45,120)
next i
setcontrolcolor w,23,0,rgb(245,245,220)

state = 0
' state 0 is when nothing has yet been entered
' set the allowed button presses for this state ..
stateset
setprecision 10

run = 1
waituntil run = 0
closewindow w
end

sub main
select @class
case @IDCloseWindow
' closing the window
run = 0
case @IDChar
' 'ESC'(ape) key pressed will close the program ...
key = @Code
if key = 27 then run = 0
case @IDControl
' button clicked ...
select state
case 0
' initial state when nothing has yet been entered
' check if this button press is allowed ..
ballow = 0 :' initially assume not allowed

' check for a reset using either the CE (Clear Entry) or CLR (Clear all) buttons ..
if @controlid = 17 | @controlid = 18
setcontroltext w,20,""
state = 0
stateset
endif

if ba[@controlid] > 0 :' allow this one ..
ballow = 1
if @controlid = 2 then ba[2] = 0 :' prevent more than one decimal point
' a minus sign is only allowed as the first character entered ..
if (@controlid = 14) & len(getcontroltext(w,20)) > 0
ballow = 0
' after a number of digits have been entered, this signals a subtract operation required ..
setcontroltext w,21,"-"
state = 1
endif
endif
' update the value entered ..
if ballow = 1
setcontroltext w,20,getcontroltext(w,20) + chr$(bchar[@controlid])
endif
' check for an operation button pressed (ie: + , X, or divide ) ..
if @controlid = 13 | @controlid = 15 | @controlid = 16
setcontroltext w,21,chr$(bchar[@controlid])
state = 1
endif
' return focus to the window, so any clicked buttons don't remain pressed ..
setfocus w

case 1
' first number has been entered, so get the next number ..
' check the button press is allowed ..
ballow = 0 :' initially assume not allowed

' check for a reset using the CE (Clear Entry) button ..
if @controlid = 17
setcontroltext w,22,""
ba[2] = 1 :' reset to allow decimal point
state = 1
endif
' check for a reset using the CLR (Clear All) button ..
if @controlid = 18
setcontroltext w,20,""
setcontroltext w,21,""
setcontroltext w,22,""
setcontroltext w,23,""
state = 0
stateset :' reset ecerything
endif

if ba[@controlid] > 0 :' allow this one ..
ballow = 1
if @controlid = 2 then ba[2] = 0 :' prevent more than one decimal point
' a minus sign is only allowed as the first character entered ..
if (@controlid = 14) & len(getcontroltext(w,22)) > 0 then ballow = 0
endif
' update the value entered ..
if ballow = 1
setcontroltext w,22,getcontroltext(w,22) + chr$(bchar[@controlid])
endif
' return focus to the window, so any clicked buttons don't remain pressed ..
setfocus w

' check for the '=' button pressed to calculate the result ..
if @controlid = 3
' calculate the result ..
a$ = getcontroltext(w,20)
value1 = val(a$)
b$ = getcontroltext(w,22)
value2 = val(b$)
oper$ = getcontroltext(w,21)
if oper$ = "+"
value3 = value1 + value2
' Note: This step with 'Using' is needed for precision, since str$() doesn't work for long numbers.
value3$ = USING("#.#########",value3)
setcontroltext w,23,"=  " + value3$
endif
if oper$ = "-"
value3 = value1 - value2
value3$ = USING("#.#########",value3)
setcontroltext w,23,"=  " + value3$
endif
if oper$ = "x"
value3 = value1 * value2
value3$ = USING("#.#########",value3)
setcontroltext w,23,"=  " + value3$
endif
if oper$ = "/"
value3 = value1 / value2
value3$ = USING("#.#########",value3)
setcontroltext w,23,"=  " + value3$
endif
endif

endselect
endselect
return

sub stateset
select state
case 0
' nothing yet entered - allow all numbers, a single decimal point, and the minus button as the first character ..
ba[0] = 0,1,1,0,1,1,1,1,1,1,1,1,1,0,1 :' (ie: Zero element not used, then 0,.,1 to 9, and minus)
setfocus w,14
case 1
' first number entered along with operation required - now get the second number ..
' the '=' button is now activated ..
ba[0] = 0,1,1,1,1,1,1,1,1,1,1,1,1,0,1 :' (ie: Zero element not used, then 0,.,=,1 to 9, and minus)
setfocus w,14
endselect

return


Not bad for a basic Basic .. with no OOP stuff in sight ..  ;D

best wishes, :)

Graham
Tomorrow may be too late ..

aurelCB

Nice Calc example Graham... ;)