Microsoft Small Basic

Program Listing: XZB099
' Scroll Bar Sample
' Copyright © 2015 Nonki Takahashi. The MIT License.
'
GraphicsWindow.Title = "Scroll Bar Sample"
WQ = Text.GetCharacter(34)
silverlight = "False"
Form()
Shapes_Init() ' rocket
iRocket = nGroup
grp = group[iRocket]
iMin = grp["iMin"]
iMax = grp["iMax"]
Shapes_Add()
Controls_Update()
Sub Form
gw = 598
gh = 428
GraphicsWindow.Width = gw
GraphicsWindow.Height = gh
GraphicsWindow.BackgroundColor = "Black"
DrawStars()
x = gw - 12
max = gh * 2
Controls_AddVScroll()
iScrollBar = nGroup
GraphicsWindow.MouseDown = OnMouseDown
GraphicsWindow.MouseMove = OnMouseMove
EndSub
Sub DrawStars
For i = 1 To 500
x = Math.GetRandomNumber(gw)
y = Math.GetRandomNumber(gh)
l = Text.GetSubText("0123456789ABCDEF", Math.GetRandomNumber(16), 1)
GraphicsWindow.BrushColor = "#" + l + l + l
r = Math.GetRandomNumber(2)
GraphicsWindow.FillEllipse(x - r, y - r, 2 * r, 2 * r)
EndFor
EndSub
Sub Group_Dump
For i = 1 To nGroup
TextWindow.WriteLine("group[" + i + "]=" + WQ + group[i] + WQ)
EndFor
EndSub
Sub Shapes_Init
' Shapes | Initialize shapes data
' return shX, shY - current position of shapes
' return shape - array of shapes
' return group - array of shapes groups
' return nShape - number of indices for shape array
' return nGroup - number of indices for group array
shX = 208 ' x offset
shY = 154 ' y offset
grp = ""
grp["x"] = shX
grp["y"] = shY
grp["iMin"] = nShape + 1
shape[nShape+1] = "func=tri;x=22;y=0;x1=70;y1=0;x2=0;y2=96;x3=140;y3=96;bc=#752424;pc=#000000;pw=2;"
shape[nShape+2] = "func=tri;x=0;y=194;x1=21;y1=0;x2=0;y2=79;x3=42;y3=79;bc=#6E6E6E;pc=#000000;pw=2;"
shape[nShape+3] = "func=tri;x=142;y=193;x1=20;y1=0;x2=0;y2=80;x3=41;y3=80;bc=#6E6E6E;pc=#000000;pw=2;"
shape[nShape+4] = "func=tri;x=52;y=189;x1=41;y1=0;x2=0;y2=70;x3=82;y3=70;bc=#1F1F1F;pc=#000000;pw=2;"
shape[nShape+5] = "func=rect;x=21;y=96;width=143;height=144;bc=#6E6E6E;pc=#000000;pw=2;"
shape[nShape+6] = "func=tri;x=73;y=192;x1=20;y1=0;x2=0;y2=81;x3=41;y3=81;bc=#6E6E6E;pc=#000000;pw=2;"
shape[nShape+7] = "func=ell;x=51;y=101;width=84;height=88;bc=#6E6E6E;pc=#000000;pw=2;"
shape[nShape+8] = "func=ell;x=59;y=110;width=68;height=71;bc=#217DBB;pc=#000000;pw=2;"
shape[nShape+9] = "func=ell;x=29;y=211;width=16;height=18;bc=#6E6E6E;pc=#000000;pw=2;"
shape[nShape+10] = "func=ell;x=56;y=213;width=16;height=17;bc=#6E6E6E;pc=#000000;pw=2;"
shape[nShape+11] = "func=ell;x=115;y=213;width=15;height=16;bc=#6E6E6E;pc=#000000;pw=2;"
shape[nShape+12] = "func=ell;x=140;y=213;width=12;height=15;bc=#6E6E6E;pc=#000000;pw=2;"
shape[nShape+13] = "func=ell;x=65;y=278;width=57;height=146;bc=#FF0F0F;pw=0;"
shape[nShape+14] = "func=ell;x=76;y=286;width=36;height=102;bc=#FF930F;pw=0;"
shape[nShape+15] = "func=ell;x=85;y=291;width=18;height=50;bc=#FFEF0F;pw=0;"
nShape = nShape + 15
grp["iMax"] = nShape
nGroup = nGroup + 1 ' number of group
group[nGroup] = grp
EndSub
Sub Controls_AddVScroll
' param x - left position x
' param max - maximum height
' return group - array of shapes groups
' return nShape - number of indices for shape array
' return nGroup - number of indices for group array
shX = x
shY = 0
grp = ""
grp["x"] = shX
grp["y"] = shY
grp["iMin"] = nShape + 1
shape[nShape+1] = "func=rect;x=0;y=0;width=12;height="+gw+";pw=0;bc=#99CCCCCC;"
shape[nShape+2] = "func=rect;x=0;y=0;width=12;height=12;pw=0;bc=#CCCCCC;"
shape[nShape+3] = "func=line;x=3;y=4;x1=0;y1=3;x2=3;y2=0;pw=1;pc=#666666;"
shape[nShape+4] = "func=line;x=6;y=4;x1=0;y1=0;x2=3;y2=3;pw=1;pc=#666666;"
shape[nShape+5] = "func=rect;x=0;y="+(gh-12)+";width=12;height=12;pw=0;bc=#CCCCCC;"
shape[nShape+6] = "func=line;x=3;y="+(gh-8)+";x1=0;y1=0;x2=3;y2=3;pw=1;pc=#666666;"
shape[nShape+7] = "func=line;x=6;y="+(gh-8)+";x1=0;y1=3;x2=3;y2=0;pw=1;pc=#666666;"
th = (gh - 24) * gh / max ' thumb heignt
shape[nShape+8] = "func=rect;x=0;y=12;width=12;height="+th+";pw=0;bc=#999999;"
nShape = nShape + 8
grp["iMax"] = nShape
nGroup = nGroup + 1 ' number of group
group[nGroup] = grp
yminThumb = 12
ymaxThumb = (gh - 12) - th
yminPic = -gh
ymaxPic = 0
ph = gh * 2 ' picture height
iMin = 1
iMax = Array.GetItemCount(shape)
scale = 1
Shapes_Add()
iMin = iMax
EndSub
Sub Controls_Update
While "True"
If mouseDown Then
grp = group[iScrollBar]
iMin = grp["iMin"]
shX = grp["x"]
shY = grp["y"]
shp = shape[iMin] ' vertical scroll bar
x1 = shX + shp["rx"]
x2 = shX + shp["rx"] + shp["width"]
y1 = shY + shp["ry"]
y2 = shY + shp["ry"] + shp["height"]
If x1 <= dx And dx <= x2 And y1 <= dy And dy <= y2 Then
shp = shape[iMin+1] ' line up button
y1 = shY + shp["ry"]
y2 = shY + shp["ry"] + shp["height"]
shp = shape[iMin+4] ' line down button
y3 = shY + shp["ry"]
y4 = shY + shp["ry"] + shp["height"]
shp = shape[iMin+7] ' thumb
y5 = shY + shp["ry"]
y6 = shY + shp["ry"] + shp["height"]
iMax = iMin+7
iMin = iMax
y = shY
yLast = y
If y1 <= dy And dy <= y2 Then
' line up
x = shX
y = shY - (ymaxThumb - yminThumb) / 10
If shp["ry"] + y < yminThumb Then
y = yminThumb - shp["ry"]
EndIf
ElseIf y3 <= dy And dy <= y4 Then
' line down
x = shX
y = shY + (ymaxThumb - yminThumb) / 10
If ymaxThumb < shp["ry"] + y Then
y = ymaxThumb - shp["ry"]
EndIf
ElseIf y5 <= dy And dy <= y6 Then
' thumb truck
yLast = shY
myLast = dy
While Mouse.IsLeftButtonDown
If mouseMove Then
x = shX
y = my - myLast
If ymaxThumb < shp["ry"] + y Then
y = ymaxThumb - shp["ry"]
ElseIf shp["ry"] + y < yminThumb Then
y = yminThumb - shp["ry"]
EndIf
If y <> yLast Then
shp["ry"] = shp["ry"] + y
shape[iMin] = shp
yMove = y
y = 0
Shapes_Move() ' move thumb
Controls_Scroll()
grp = group[iScrollBar]
iMin = grp["iMin"]
iMax = iMin+7
iMin = iMax
shX = grp["x"]
shY = grp["y"]
shp = shape[iMin] ' vertical scroll bar
yLast = y
EndIf
myLast = my
mouseMove = "False"
EndIf
EndWhile
ElseIf dy < y5 Then
' page up
x = shX
y = shY - (ymaxThumb - yminThumb)
If shp["ry"] + y < yminThumb Then
y = yminThumb - shp["ry"]
EndIf
ElseIf y6 < dy Then
' page down
x = shX
y = shY + ymaxThumb - yminThumb
If ymaxThumb < shp["ry"] + y Then
y = ymaxThumb - shp["ry"]
EndIf
EndIf
If y <> yLast Then
shp["ry"] = shp["ry"] + y
shape[iMin] = shp
yMove = y
y = 0
Shapes_Move() ' move thumb
Controls_Scroll()
EndIf
EndIf
mouseDown = "False"
EndIf
EndWhile
EndSub
Sub Controls_Scroll
grp = group[iRocket]
x = grp["x"]
y = grp["y"] - yMove * gh / (ymaxThumb - yminThumb)
iMin = grp["iMin"]
iMax = grp["iMax"]
Shapes_Move()
grp["y"] = y
group[iRocket] = grp
EndSub
Sub OnMouseDown
dx = GraphicsWindow.MouseX
dy = GraphicsWindow.MouseY
mouseDown = "True"
EndSub
Sub OnMouseMove
mx = GraphicsWindow.MouseX
my = GraphicsWindow.MouseY
mouseMove = "True"
EndSub
Sub SB_RotateWorkaround
' Small Basic | Rotate workaround for Silverlight
' param shp - current shape
' param x, y - original coordinate
' param alpha - angle [radian]
' returns x, y - workaround coordinate
If shp["func"] = "tri" Then
x1 = -Math.Floor(shp["x3"] / 2)
y1 = -Math.Floor(shp["y3"] / 2)
ElseIf shp["func"] = "line" Then
x1 = -Math.Floor(Math.Abs(shp["x1"] - shp["x2"]) / 2)
y1 = -Math.Floor(Math.Abs(shp["y1"] - shp["y2"]) / 2)
EndIf
ox = x - x1
oy = y - y1
x = x1 * Math.Cos(alpha) - y1 * Math.Sin(alpha) + ox
y = x1 * Math.Sin(alpha) + y1 * Math.Cos(alpha) + oy
EndSub
Sub Shapes_Add
' Shapes | add shapes as shapes data
' param iMin, iMax - shape indices to add
' param shape - array of shapes
' param scale - 1 if same scale
' return shWidth, shHeight - total size of shapes
' return shAngle - current angle of shapes
Stack.PushValue("local", i)
Stack.PushValue("local", x)
Stack.PushValue("local", y)
Shapes_CalcWidthAndHeight()
s = scale
For i = iMin To iMax
shp = shape[i]
GraphicsWindow.PenWidth = shp["pw"] * s
If shp["pw"] > 0 Then
GraphicsWindow.PenColor = shp["pc"]
EndIf
If Text.IsSubText("rect|ell|tri|text", shp["func"]) Then
GraphicsWindow.BrushColor = shp["bc"]
EndIf
If shp["func"] = "rect" Then
shp["obj"] = Shapes.AddRectangle(shp["width"] * s, shp["height"] * s)
ElseIf shp["func"] = "ell" Then
shp["obj"] = Shapes.AddEllipse(shp["width"] * s, shp["height"] * s)
ElseIf shp["func"] = "tri" Then
shp["obj"] = Shapes.AddTriangle(shp["x1"] * s, shp["y1"] * s, shp["x2"] * s, shp["y2"] * s, shp["x3"] * s, shp["y3"] * s)
ElseIf shp["func"] = "line" Then
shp["obj"] = Shapes.AddLine(shp["x1"] * s, shp["y1"] * s, shp["x2"] * s, shp["y2"] * s)
ElseIf shp["func"] = "text" Then
If silverlight Then
fs = Math.Floor(shp["fs"] * 0.9)
Else
fs = shp["fs"]
EndIf
GraphicsWindow.FontSize = fs * s
GraphicsWindow.FontName = shp["fn"]
shp["obj"] = Shapes.AddText(shp["text"])
EndIf
x = shp["x"]
y = shp["y"]
shp["rx"] = x
shp["ry"] = y
If silverlight And Text.IsSubText("tri|line", shp["func"]) Then
alpha = Math.GetRadians(shp["angle"])
SB_RotateWorkaround()
shp["wx"] = x
shp["wy"] = y
EndIf
Shapes.Move(shp["obj"], shX + x * s, shY + y * s)
If Text.IsSubText("rect|ell|tri|line|text", shp["func"]) And (shp["angle"] <> 0) And (shp["angle"] <> "") Then
Shapes.Rotate(shp["obj"], shp["angle"])
EndIf
shape[i] = shp
EndFor
shAngle = 0
y = Stack.PopValue("local")
x = Stack.PopValue("local")
i = Stack.PopValue("local")
EndSub
Sub Shapes_CalcWidthAndHeight
' Shapes | Calculate total width and height of shapes
' param iMin, iMax - shape indices to add
' return shWidth, shHeight - total size of shapes
For i = iMin To iMax
shp = shape[i]
If shp["func"] = "tri" Or shp["func"] = "line" Then
xmin = shp["x1"]
xmax = shp["x1"]
ymin = shp["y1"]
ymax = shp["y1"]
If shp["x2"] < xmin Then
xmin = shp["x2"]
EndIf
If xmax < shp["x2"] Then
xmax = shp["x2"]
EndIf
If shp["y2"] < ymin Then
ymin = shp["y2"]
EndIf
If ymax < shp["y2"] Then
ymax = shp["y2"]
EndIf
If shp["func"] = "tri" Then
If shp["x3"] < xmin Then
xmin = shp["x3"]
EndIf
If xmax < shp["x3"] Then
xmax = shp["x3"]
EndIf
If shp["y3"] < ymin Then
ymin = shp["y3"]
EndIf
If ymax < shp["y3"] Then
ymax = shp["y3"]
EndIf
EndIf
shp["width"] = xmax - xmin
shp["height"] = ymax - ymin
EndIf
If i = 1 Then
shWidth = shp["x"] + shp["width"]
shHeight = shp["y"] + shp["height"]
Else
If shWidth < shp["x"] + shp["width"] Then
shWidth = shp["x"] + shp["width"]
EndIf
If shHeight < shp["y"] + shp["height"] Then
shHeight = shp["y"] + shp["height"]
EndIf
EndIf
shape[i] = shp
EndFor
EndSub
Sub Shapes_Move
' Shapes | Move shapes
' param iMin, iMax - shape indices to add
' param shape - array of shapes
' param scale - to zoom
' param x, y - position to move
' return shX, shY - new position of shapes
Stack.PushValue("local", i)
s = scale
shX = x
shY = y
For i = iMin To iMax
shp = shape[i]
If silverlight And Text.IsSubText("tri|line", shp["func"]) Then
_x = shp["wx"]
_y = shp["wy"]
Else
_x = shp["rx"]
_y = shp["ry"]
EndIf
Shapes.Move(shp["obj"], shX + _x * s, shY + _y * s)
EndFor
i = Stack.PopValue("local")
EndSub