Microsoft Small Basic

Program Listing: SNG664
'Simple-Talk Calculator Sim in 200 lines
'declare our variables here-----------
Accumulator=""
rows = 6
columns = 4
ButtonWidth=30
topPanelHeight=40
ButtonHeight = buttonWidth*1.1614
ButtonGap=3
ButtonWanted=0
lvalue=0
operator="+"
'now we create a table as an array, so we can keep track of buttons
'legend=What's shown on the button, Key=keypress to react to, Alt=other key to react to(e.g. numeric pad) , act=Type of action required, Color=color of button, X=X, Y=Y, Width=width
ButtonValue[1]="legend=mc;key=none;alt=none;act=mem;color=dimGray;"
ButtonValue[2]="legend=m+;key=none;alt=none;act=mem;color=dimGray;"
ButtonValue[3]="legend=m-;key=none;alt=none;act=mem;color=dimGray;"
ButtonValue[4]="legend=mr;key=none;alt=none;act=mem;color=dimGray;"
ButtonValue[5]="legend=C;key=C;alt=none;act=unary;color=Darkslategray"
ButtonValue[6]="legend=+/-;key=none;alt=none;act=unary;color=Darkslategray"
ButtonValue[7]="legend=/;key=/;alt=divide;act=binary;color=Darkslategray"
ButtonValue[8]="legend=X;key=x;alt=multiply;act=binary;color=Darkslategray"
ButtonValue[9]="legend=7;key=d7;alt=numpad7;act=num;color=black;"
ButtonValue[10]="legend=8;key=d8;alt=numpad8;act=num;color=black;"
ButtonValue[11]="legend=9;key=d9;alt=numpad9;act=num;color=black;"
ButtonValue[12]="legend=-;key=oemminus;alt=subtract;act=binary;color=DarkSlateGray;"
ButtonValue[13]="legend=4;key=d4;alt=numpad4;act=num;color=black;"
ButtonValue[14]="legend=5;key=d5;alt=numpad5;act=num;color=black;"
ButtonValue[15]="legend=6;key=d6;alt=numpad6;act=num;color=black;"
ButtonValue[16]="legend=+;key=add;alt=none;act=binary;color=DarkSlateGray;"
ButtonValue[17]="legend=1;key=d1;alt=numpad1;act=num;color=black;"
ButtonValue[18]="legend=2;key=d2;alt=numpad2;act=num;color=black;"
ButtonValue[19]="legend=3;key=d3;alt=numpad3;act=num;color=black;"
ButtonValue[20]="legend=√;key=none;alt=none;act=unary;color=DarkSlateGray;"
ButtonValue[21]="legend=0;key=d0;alt=numpad0;act=num;color=black;"
ButtonValue[22]="legend=.;key=.;alt=decimal;act=num;color=black;"
ButtonValue[23]["legend"]="="
ButtonValue[23]["alt"]="return"
ButtonValue[23]["color"]="Brown"
ButtonValue[23]["act"]="equ"
ButtonValue[23]["key"]=""
'now write in the coordinates for where they will be
For r = 1 To rows-1
For c = 1 To columns
ThisButtonx= ((c-1)*ButtonWidth) + (c*ButtonGap)
If ButtonValue[((r-1)*columns)+(c)]["legend"] = "=" then
ThisButtonx=((c)*ButtonWidth) + (c*ButtonGap)
endif
'calculate coordinates for the buttons
ButtonValue[((r-1)*columns)+(c)]["x"] = ((c-1)*ButtonWidth) + (c*ButtonGap)
ButtonValue[((r-1)*columns)+(c)]["y"] = ((r-1)*ButtonHeight) + (r*ButtonGap) + topPanelHeight
ButtonValue[((r-1)*columns)+(c)]["width"]=ButtonWidth
EndFor
EndFor
'and there is an irregular row for Zero
LastRow=((rows-1)*ButtonHeight) + (rows*ButtonGap) + topPanelHeight
ButtonValue[21]["x"]=ButtonGap
ButtonValue[21]["y"]=lastrow
ButtonValue[21]["width"]=buttonWidth
ButtonValue[22]["x"]=buttonwidth + (2*ButtonGap)
ButtonValue[22]["y"]=lastrow
ButtonValue[22]["width"]=(buttonWidth*2)+ButtonGap
ButtonValue[23]["x"]=(buttonwidth*3) + (4*ButtonGap)
ButtonValue[23]["y"]=lastrow
ButtonValue[23]["width"]=buttonWidth
WindowWidth=(ButtonWidth*columns)+(ButtonGap*(columns+1))
WindowHeight=(ButtonHeight*rows)+(ButtonGap*((columns)+2))+ topPanelHeight

'now we draw it all out
GraphicsWindow.BackgroundColor="burlywood"
'draw out the result pane
DrawResultPane()
GraphicsWindow.BrushColor = "SaddleBrown"
GraphicsWindow.penColor = "black"
GraphicsWindow.FontSize=10 'pixels
GraphicsWindow.penWidth=2
For i=1 to array.GetItemCount(ButtonValue)'Now draw each button in turn
GraphicsWindow.BrushColor=ButtonValue[i]["color"]
GraphicsWindow.FillRectangle(ButtonValue[i]["x"], ButtonValue[i]["y"],ButtonValue[i]["width"], ButtonHeight)
GraphicsWindow.PenColor="cornsilk"
GraphicsWindow.DrawLine(ButtonValue[i]["x"], ButtonValue[i]["y"],ButtonValue[i]["x"]+ButtonValue[i]["width"], ButtonValue[i]["y"])
GraphicsWindow.DrawLine(ButtonValue[i]["x"], ButtonValue[i]["y"],ButtonValue[i]["x"], ButtonValue[i]["y"]+ButtonHeight)
GraphicsWindow.penColor = "black"
GraphicsWindow.DrawLine(ButtonValue[i]["x"], ButtonValue[i]["y"]+ButtonHeight,ButtonValue[i]["x"]+ButtonValue[i]["width"], ButtonValue[i]["y"]+buttonheight)
GraphicsWindow.DrawLine(ButtonValue[i]["x"]+ButtonValue[i]["width"], ButtonValue[i]["y"],ButtonValue[i]["x"]+ButtonValue[i]["width"], ButtonValue[i]["y"]+ButtonHeight)
GraphicsWindow.BrushColor="white"
GraphicsWindow.DrawText(ButtonValue[i]["x"]+5, ButtonValue[i]["y"]+5,ButtonValue[i]["legend"])
EndFor
GraphicsWindow.height=WindowHeight
GraphicsWindow.width=WindowWidth
GraphicsWindow.CanResize = 0
GraphicsWindow.MouseDown = OnMouseDown
GraphicsWindow.KeyDown = OnKeyDown
GraphicsWindow.Title="Calculator"
GraphicsWindow.Show()

Sub OnMouseDown'find out which button was pressed if any
x=GraphicsWindow.MouseX
y=GraphicsWindow.MouseY
For i=1 to array.GetItemCount(ButtonValue)
If x > ButtonValue[i]["x"] And x < ButtonValue[i]["x"]+ButtonValue[i]["width"] And y>ButtonValue[i]["y"] And y< ButtonValue[i]["y"] +ButtonHeight Then
ButtonWanted=i
DoSomething()
EndIf
endfor
EndSub

Sub OnKeyDown 'was a key pressed that needs to go in?
KeyPressValue=Text.ConvertTolowerCase(GraphicsWindow.LastKey)
For i=1 to array.GetItemCount(ButtonValue)
If Text.ConvertTolowerCase(ButtonValue[i]["key"])=KeyPressValue or Text.ConvertTolowerCase(ButtonValue[i]["alt"])=KeyPressValue Then
ButtonWanted=i
DoSomething()
EndIf
EndFor
EndSub
'this is where all the calculation gets done.
Sub DoSomething
legend=ButtonValue[ButtonWanted]["legend"]
If ButtonValue[ButtonWanted]["act"]="num" then
If lastoperator="=" then
Accumulator=""
endif
Accumulator=Text.Append(accumulator,ButtonValue[ButtonWanted]["legend"])
DrawResultPane()
endif
If legend="m+" then
Memory=Memory+Accumulator
EndIf
If legend="m-" then
Memory=Memory-Accumulator
EndIf
If legend="mc" then
Memory=0
EndIf
If legend="mr" then
Accumulator=Memory
DrawResultPane()
EndIf
If legend="C" then
Accumulator=""
DrawResultPane()
EndIf
If ButtonValue[ButtonWanted]["act"]="binary" then
lvalue=Accumulator 'binary operator
operator=legend
Accumulator=""
EndIf
If legend="+/-" then 'now do the unary operators
Accumulator =-Accumulator
DrawResultPane()
EndIf
If legend="√" then
Accumulator = Math.SquareRoot(Accumulator)
DrawResultPane()
endif
If legend="="then 'now do any calculations
If lvalue<>"" and operator<>"" then
if operator="+" then
Accumulator=Lvalue+Accumulator
endif
if operator="-" then
Accumulator=Lvalue-Accumulator
endif
if operator="X" then
Accumulator=Lvalue*Accumulator
endif
if operator="/" then
Accumulator=Lvalue/Accumulator
endif
lvalue=Accumulator
operator=""
DrawResultPane()
endif
EndIf
lastOperator=Legend
EndSub
'this is called whenever a change happens that affects the results pane
Sub DrawResultPane
GraphicsWindow.BrushColor = "White"
GraphicsWindow.penColor = "black"
GraphicsWindow.penWidth=1
GraphicsWindow.DrawRectangle(buttonGap,buttonGap,WindowWidth-(buttonGap*2),topPanelHeight-ButtonGap)
GraphicsWindow.FillRectangle(buttonGap,buttonGap,WindowWidth-(buttonGap*2),topPanelHeight-ButtonGap)
GraphicsWindow.BrushColor="black"
GraphicsWindow.FontSize=20
GraphicsWindow.DrawBoundText(buttonGap+5,buttonGap+5,WindowWidth-(buttonGap*2)-10,accumulator)
GraphicsWindow.FontSize=10
EndSub