Microsoft Small Basic

Program Listing: XFZ657-7
' Shapes Editor 0.72
' Copyright (c) 2012 Nonki Takahashi. All rights reserved.
'
' History :
' 0.72 2012/09/11 Bug fixed (pen width). (XFZ657-7)
' 0.71 2012/09/11 Bug fixed (output). Minor change. (XFZ657-6)
' 0.7 2012/09/11 Supported color palette. (XFZ657-5)
' 0.6 2012/09/10 Supported cut menu. (XFZ657-4)
' 0.5 2012/09/09 Changed to add function of moving shapes. (XFZ657-3)
' 0.4 2012/09/09 Changed to add function of selecting shapes. (XFZ657-2)
' 0.3 2012/09/08 Changed to output shape array. (XFZ657-1)
' 0.2 2012/09/07 Bug fixed. Supported offset scale, and angle of shapes. (XFZ657-0)
' 0.1 2012/09/06 Created. (XFZ657)
'
title = "Shapes Editor 0.72"
GraphicsWindow.Title = title
debug = "False"
WQ = Text.GetCharacter(34)
CRLF = Text.GetCharacter(13) + Text.GetCharacter(10)
pw = "1=2;2=4;3=8;4=16;5=0;6=1;"
pen = 1
nPen = 6
pwidth = GraphicsWindow.PenWidth
pcolor = GraphicsWindow.PenColor
bcolor = GraphicsWindow.BrushColor
CS_InitPalette() ' initialize palette for color slider
DrawMenu()
shape = ""
nShapes = 0
cont = "True" ' continue
param = "down=True;move=False;up=False;" ' wait to click
Mouse_SetHandler()
While cont
If clicked Then
SearchClickedObject()
DoObject()
Else
Program.Delay(100)
EndIf
EndWhile
' end of program

Sub DoMenu
While Text.StartsWith(obj, "menu")
i = Text.GetSubTextToEnd(obj, 5)
obj = ""
func = menu[i]["func"]
select = "True"
ItemSelect() ' menu item select
If func = "cut" Then
If selectedshape <> "" Then
Shapes.Remove(shape[selectedshape]["obj"])
shape["clipboard"] = shape[selectedshape]
nShapes = nShapes - 1
For _i = selectedshape To nShapes
shape[_i] = shape[_i + 1]
EndFor
EndIf
ElseIf func = "rect" Then ' rectangle
needClick = "True" ' in DoShape()
WaitToClick()
SearchClickedObject()
If Text.StartsWith(obj, "menu") = "False" Then
WaitToRelease()
nShapes = nShapes + 1
obj = "shape" + nShapes
shape[nShapes]["func"] = "rect"
shape[nShapes]["bc"] = bcolor
shape[nShapes]["pw"] = pwidth
GraphicsWindow.BrushColor = bcolor
GraphicsWindow.PenWidth = pwidth
If pwidth > 0 Then
shape[nShapes]["pc"] = pcolor
GraphicsWindow.PenColor = pcolor
EndIf
xmin = Math.Min(mxD, mxU)
ymin = Math.Min(myD, myU)
xmax = Math.Max(mxD, mxU)
ymax = Math.Max(myD, myU)
w = xmax - xmin
h = ymax - ymin
shape[nShapes]["x"] = xmin
shape[nShapes]["y"] = ymin
shape[nShapes]["width"] = w
shape[nShapes]["height"] = h
shape[nShapes]["obj"] = Shapes.AddRectangle(w, h)
Shapes.Move(shape[nShapes]["obj"], xmin, ymin)
EndIf
ElseIf func = "ell" Then ' ellipse
needClick = "True" ' in DoShape()
WaitToClick()
SearchClickedObject()
If Text.StartsWith(obj, "menu") = "False" Then
WaitToRelease()
nShapes = nShapes + 1
obj = "shape" + nShapes
shape[nShapes]["func"] = "ell"
shape[nShapes]["bc"] = bcolor
shape[nShapes]["pw"] = pwidth
GraphicsWindow.BrushColor = bcolor
GraphicsWindow.PenWidth = pwidth
If pwidth > 0 Then
shape[nShapes]["pc"] = pcolor
GraphicsWindow.PenColor = pcolor
EndIf
xmin = Math.Min(mxD, mxU)
ymin = Math.Min(myD, myU)
xmax = Math.Max(mxD, mxU)
ymax = Math.Max(myD, myU)
w = xmax - xmin
h = ymax - ymin
shape[nShapes]["x"] = xmin
shape[nShapes]["y"] = ymin
shape[nShapes]["width"] = w
shape[nShapes]["height"] = h
shape[nShapes]["obj"] = Shapes.AddEllipse(w, h)
Shapes.Move(shape[nShapes]["obj"], xmin, ymin)
EndIf
ElseIf func = "tri" Then ' triangle
needClick = "True" ' in DoShape()
WaitToClick()
SearchClickedObject()
If Text.StartsWith(obj, "menu") = "False" Then
WaitToRelease()
nShapes = nShapes + 1
obj = "shape" + nShapes
shape[nShapes]["func"] = "tri"
shape[nShapes]["bc"] = bcolor
shape[nShapes]["pw"] = pwidth
shape[nShapes]["pc"] = pcolor
GraphicsWindow.BrushColor = bcolor
GraphicsWindow.PenWidth = pwidth
If pwidth > 0 Then
shape[nShapes]["pc"] = pcolor
GraphicsWindow.PenColor = pcolor
EndIf
xmin = Math.Min(mxD, mxU)
ymin = Math.Min(myD, myU)
xmax = Math.Max(mxD, mxU)
ymax = Math.Max(myD, myU)
xt = Math.Floor((xmax - xmin) / 2) ' x top
w = xmax - xmin ' width
h = ymax - ymin ' height
shape[nShapes]["x"] = xmin
shape[nShapes]["y"] = ymin
shape[nShapes]["width"] = w
shape[nShapes]["height"] = h
If myU <= myD Then
x1 = xt
y1 = h
x2 = 0
y2 = 0
x3 = w
y3 = 0
ElseIf myD < myU Then
x1 = xt
y1 = 0
x2 = 0
y2 = h
x3 = w
y3 = h
EndIf
shape[nShapes]["x1"] = x1
shape[nShapes]["y1"] = y1
shape[nShapes]["x2"] = x2
shape[nShapes]["y2"] = y2
shape[nShapes]["x3"] = x3
shape[nShapes]["y3"] = y3
shape[nShapes]["obj"] = Shapes.AddTriangle(x1, y1, x2, y2, x3, y3)
Shapes.Move(shape[nShapes]["obj"], xmin, ymin)
EndIf
ElseIf func = "line" Then ' line
needClick = "True" ' in DoShape()
WaitToClick()
SearchClickedObject()
If Text.StartsWith(obj, "menu") = "False" Then
WaitToRelease()
nShapes = nShapes + 1
obj = "shape" + nShapes
shape[nShapes]["func"] = "line"
shape[nShapes]["pw"] = pwidth
GraphicsWindow.PenWidth = pwidth
If pwidth > 0 Then
shape[nShapes]["pc"] = pcolor
GraphicsWindow.PenColor = pcolor
EndIf
xmin = Math.Min(mxD, mxU)
ymin = Math.Min(myD, myU)
xmax = Math.Max(mxD, mxU)
ymax = Math.Max(myD, myU)
shape[nShapes]["x"] = xmin
shape[nShapes]["y"] = ymin
shape[nShapes]["width"] = xmax - xmin
shape[nShapes]["height"] = ymax - ymin
shape[nShapes]["x1"] = mxD - xmin
shape[nShapes]["y1"] = myD - ymin
shape[nShapes]["x2"] = mxU - xmin
shape[nShapes]["y2"] = myU - ymin
shape[nShapes]["obj"] = Shapes.AddLine(mxD - xmin, myD - ymin, mxU - xmin, myU - ymin)
Shapes.Move(shape[nShapes]["obj"], xmin, ymin)
EndIf
ElseIf func = "pc" Then ' pen color
color = pcolor
CS_ShowPopup()
pcolor = color
DrawMenuItem()
ElseIf func = "pw" Then ' pen width
If pen = nPen Then
pen = 1
Else
pen = pen + 1
EndIf
pwidth = pw[pen]
x = menu[i]["x0"]
y = menu[i]["y0"]
size = menu[i]["x1"] - x
GraphicsWindow.BrushColor = "LightGray"
GraphicsWindow.FillRectangle(x, y, size, size)
DrawMenuItem()
ElseIf func = "bc" Then ' brush color
color = bcolor
CS_ShowPopup()
bcolor = color
DrawMenuItem()
ElseIf func = "save" Then ' save shapes
param = "down=False;move=False;up=False;" ' wait button pushed
Mouse_SetHandler()
DumpShapes()
EndIf
param = "down=True;move=False;up=False;" ' wait next obj click
Mouse_SetHandler()
select = "False"
ItemSelect() ' menu item unselect
EndWhile
EndSub

Sub DoObject
' param obj
While obj <> ""
fromMenu = "False"
DoMenu()
If obj <> "" Then
DoShape()
EndIf
EndWhile
EndSub

Sub DoShape
currentobj = ""
While Text.StartsWith(obj, "shape")
If currentobj <> obj Then
i = Text.GetSubTextToEnd(obj, 6)
func = shape[i]["func"]
select = "True"
ShapeSelect()
currentobj = obj
EndIf
If needClick Then
obj = ""
WaitToClick()
SearchClickedObject()
needClick = "False"
EndIf
If obj = currentobj Then
WaitToRelease2()
needClick = "True"
Else
_shape = selectedshape
select = "False"
ShapeSelect()
If obj = "menu2" Then ' for cut
selectedshape = _shape
EndIf
EndIf
EndWhile
EndSub

Sub DrawMenu
cxMenu = 10
cyMenu = 10
sizeMenu = 40
nMenu = 9
xMenu = cxMenu
For i = 1 To nMenu
yMenu = cyMenu + (i - 1) * (sizeMenu + 2)
GraphicsWindow.BrushColor = "LightGray"
GraphicsWindow.FillRectangle(xMenu, yMenu, sizeMenu, sizeMenu)
menu[i]["x0"] = xMenu
menu[i]["y0"] = yMenu
menu[i]["x1"] = xMenu + sizeMenu
menu[i]["y1"] = yMenu + sizeMenu
DrawMenuItem()
EndFor
EndSub

Sub DrawMenuItem
' param i - item number
' param pwidth - pen width
' param pcolor - pen color
' param bcolor - brush color
margin = 4
x = menu[i]["x0"]
y = menu[i]["y0"]
size = menu[i]["x1"] - x
GraphicsWindow.PenColor = "Black"
GraphicsWindow.PenWidth = 2
If i = 1 Then
menu[i]["func"] = "save"
GraphicsWindow.BrushColor = "SteelBlue"
GraphicsWindow.FillRectangle(x + margin, y + margin, size - margin * 2, size - margin * 2)
GraphicsWindow.BrushColor = "White"
GraphicsWindow.FillRectangle(x + margin + 4, y + margin, size - (margin + 4) * 2, (size - margin * 2) / 3)
GraphicsWindow.BrushColor = "Gray"
GraphicsWindow.FillRectangle(x + margin + 6, y + size - 15, size - (margin + 8) * 2, 15 - margin)
ElseIf i = 2 Then
menu[i]["func"] = "cut"
' initialize shapes
Scissors_Init()
' add shapes
scale = 0.11
Shapes_Add()
x = x + 14
Shapes_Move()
x = x - 14
nShapes = 3
For t = 0 To 360 * 0.3
angle = 30 - 30 * Math.Cos(t * Math.Pi / 180)
Shapes_Rotate()
EndFor
ElseIf i = 3 Then
menu[i]["func"] = "rect"
GraphicsWindow.DrawRectangle(x + margin, y + margin, size - margin * 2, size - margin * 2)
ElseIf i = 4 Then
menu[i]["func"] = "ell"
GraphicsWindow.DrawEllipse(x + margin, y + margin, size - margin * 2, size - margin * 2)
ElseIf i = 5 Then
menu[i]["func"] = "tri"
x1 = x + size / 2
y1 = y + margin
x2 = x + margin
y2 = y + size - margin
x3 = x + size - margin
y3 = y + size - margin
GraphicsWindow.DrawTriangle(x1, y1, x2, y2, x3, y3)
ElseIf i = 6 Then
menu[i]["func"] = "line"
x1 = x + margin
y1 = y + margin
x2 = x + size - margin
y2 = y + size - margin
GraphicsWindow.DrawLine(x1, y1, x2, y2)
ElseIf i = 7 Then
menu[i]["func"] = "pw"
GraphicsWindow.PenWidth = pwidth
x1 = x + margin
y1 = y + size / 2
x2 = x + size - margin
y2 = y + size / 2
GraphicsWindow.DrawLine(x1, y1, x2, y2)
ElseIf i = 8 Then
menu[i]["func"] = "pc"
margin = 6
GraphicsWindow.PenWidth = 4
GraphicsWindow.PenColor = pcolor
GraphicsWindow.DrawRectangle(x + margin, y + margin, size - margin * 2, size - margin * 2)
ElseIf i = 9 Then
menu[i]["func"] = "bc"
GraphicsWindow.BrushColor = bcolor
GraphicsWindow.FillRectangle(x + margin, y + margin, size - margin * 2, size - margin * 2)
GraphicsWindow.PenColor = "Black"
GraphicsWindow.PenWidth = 2
GraphicsWindow.DrawRectangle(x + margin, y + margin, size - margin * 2, size - margin * 2)
EndIf
EndSub

Sub DumpShapes
Stack.PushValue("local", i)
buf = "' " + Clock.Date + " " + Clock.Time + " Generated" + CRLF
buf = buf + "' by " + title + CRLF
buf = buf + "'" + CRLF
buf = buf + "' initialize shapes" + CRLF
buf = buf + "Shapes_Init()" + CRLF
buf = buf + "' add shapes" + CRLF
buf = buf + "scale = 1" + CRLF
buf = buf + "Shapes_Add()" + CRLF
buf = buf + "angle = 0" + CRLF
buf = buf + CRLF
buf = buf + "Sub Shapes_Init" + CRLF
buf = buf + " ' return shX, shY - current position of shapes" + CRLF
buf = buf + " ' return shape - array of shapes" + CRLF
If nShapes > 0 Then
xmin = shape[1]["x"]
ymin = shape[1]["y"]
xman = shape[1]["x"]
yman = shape[1]["y"]
EndIf
For i = 2 To nShapes
If shape[i]["x"] < xmin Then
xmin = shape[i]["x"]
EndIf
If shape[i]["y"] < ymin Then
ymin = shape[i]["y"]
EndIf
If xmax < shape[i]["x"] Then
xmax = shape[i]["x"]
EndIf
If ymax < shape[i]["y"] Then
ymax = shape[i]["y"]
EndIf
EndFor
buf = buf + " shX = " + xmin + " ' x offset" + CRLF
buf = buf + " shY = " + ymin + " ' y offset" + CRLF
For i = 1 To nShapes
If shape[i]["func"] = "rect" Then
buf = buf + " shape[" + i + "] = " + WQ + "func=rect;"
buf = buf + "x=" + (shape[i]["x"] - xmin) + ";"
buf = buf + "y=" + (shape[i]["y"] - ymin) + ";"
buf = buf + "width=" + shape[i]["width"] + ";"
buf = buf + "height=" + shape[i]["height"] + ";"
buf = buf + "bc=" + shape[i]["bc"] + ";"
ElseIf shape[i]["func"] = "ell" Then
buf = buf + " shape[" + i + "] = " + WQ + "func=ell;"
buf = buf + "x=" + (shape[i]["x"] - xmin) + ";"
buf = buf + "y=" + (shape[i]["y"] - ymin) + ";"
buf = buf + "width=" + shape[i]["width"] + ";"
buf = buf + "height=" + shape[i]["height"] + ";"
buf = buf + "bc=" + shape[i]["bc"] + ";"
ElseIf shape[i]["func"] = "tri" Then
buf = buf + " shape[" + i + "] = " + WQ + "func=tri;"
buf = buf + "x=" + (shape[i]["x"] - xmin) + ";"
buf = buf + "y=" + (shape[i]["y"] - ymin) + ";"
buf = buf + "x1=" + shape[i]["x1"] + ";"
buf = buf + "y1=" + shape[i]["y1"] + ";"
buf = buf + "x2=" + shape[i]["x2"] + ";"
buf = buf + "y2=" + shape[i]["y2"] + ";"
buf = buf + "x3=" + shape[i]["x3"] + ";"
buf = buf + "y3=" + shape[i]["y3"] + ";"
buf = buf + "bc=" + shape[i]["bc"] + ";"
ElseIf shape[i]["func"] = "line" Then
buf = buf + " shape[" + i + "] = " + WQ + "func=line;"
buf = buf + "x=" + (shape[i]["x"] - xmin) + ";"
buf = buf + "y=" + (shape[i]["y"] - ymin) + ";"
buf = buf + "x1=" + shape[i]["x1"] + ";"
buf = buf + "y1=" + shape[i]["y1"] + ";"
buf = buf + "x2=" + shape[i]["x2"] + ";"
buf = buf + "y2=" + shape[i]["y2"] + ";"
EndIf
If shape[i]["pw"] > 0 Then
buf = buf + "pc=" + shape[i]["pc"] + ";"
EndIf
buf = buf + "pw=" + shape[i]["pw"] + ";" + WQ + CRLF
EndFor
buf = buf + "EndSub" + CRLF
buf = buf + CRLF
buf = buf + "Sub Shapes_Add" + CRLF
buf = buf + " ' param shape - array of shapes" + CRLF
buf = buf + " ' param scale" + CRLF
buf = buf + " ' return shWidth, shHeight - total size of shapes" + CRLF
buf = buf + " ' return shAngle - current angle of shapes" + CRLF
buf = buf + " Stack.PushValue(" + WQ + "local" + WQ + ", i)" + CRLF
buf = buf + " Stack.PushValue(" + WQ + "local" + WQ + ", x)" + CRLF
buf = buf + " Stack.PushValue(" + WQ + "local" + WQ + ", y)" + CRLF
buf = buf + " Shapes_CalcWidthAndHeight()" + CRLF
buf = buf + " s = scale" + CRLF
buf = buf + " For i = 1 To nShapes" + CRLF
buf = buf + " GraphicsWindow.PenWidth = shape[i][" + WQ + "pw" + WQ + "] * s" + CRLF
buf = buf + " If shape[i][" + WQ + "pw" + WQ + "] > 0 Then" + CRLF
buf = buf + " GraphicsWindow.PenColor = shape[i][" + WQ + "pc" + WQ + "]" + CRLF
buf = buf + " EndIf" + CRLF
buf = buf + " If shape[i][" + WQ + "func" + WQ + "] = " + WQ + "rect" + WQ + " Then" + CRLF
buf = buf + " GraphicsWindow.BrushColor = shape[i][" + WQ + "bc" + WQ + "]" + CRLF
buf = buf + " x = shape[i][" + WQ + "x" + WQ + "]" + CRLF
buf = buf + " y = shape[i][" + WQ + "y" + WQ + "]" + CRLF
buf = buf + " width = shape[i][" + WQ + "width" + WQ + "]" + CRLF
buf = buf + " height = shape[i][" + WQ + "height" + WQ + "]" + CRLF
buf = buf + " shape[i][" + WQ + "obj" + WQ + "] = Shapes.AddRectangle(width * s, height * s)" + CRLF
buf = buf + " Shapes.Move(shape[i][" + WQ + "obj" + WQ + "], shX + x * s, shY + y * s)" + CRLF
buf = buf + " ElseIf shape[i][" + WQ + "func" + WQ + "] = " + WQ + "ell" + WQ + " Then" + CRLF
buf = buf + " GraphicsWindow.BrushColor = shape[i][" + WQ + "bc" + WQ + "]" + CRLF
buf = buf + " x = shape[i][" + WQ + "x" + WQ + "]" + CRLF
buf = buf + " y = shape[i][" + WQ + "y" + WQ + "]" + CRLF
buf = buf + " width = shape[i][" + WQ + "width" + WQ + "]" + CRLF
buf = buf + " height = shape[i][" + WQ + "height" + WQ + "]" + CRLF
buf = buf + " shape[i][" + WQ + "obj" + WQ + "] = Shapes.AddEllipse(width * s, height * s)" + CRLF
buf = buf + " Shapes.Move(shape[i][" + WQ + "obj" + WQ + "], shX + x * s, shY + y * s)" + CRLF
buf = buf + " ElseIf shape[i][" + WQ + "func" + WQ + "] = " + WQ + "tri" + WQ + " Then" + CRLF
buf = buf + " GraphicsWindow.BrushColor = shape[i][" + WQ + "bc" + WQ + "]" + CRLF
buf = buf + " x = shape[i][" + WQ + "x" + WQ + "]" + CRLF
buf = buf + " y = shape[i][" + WQ + "y" + WQ + "]" + CRLF
buf = buf + " x1 = shape[i][" + WQ + "x1" + WQ + "]" + CRLF
buf = buf + " y1 = shape[i][" + WQ + "y1" + WQ + "]" + CRLF
buf = buf + " x2 = shape[i][" + WQ + "x2" + WQ + "]" + CRLF
buf = buf + " y2 = shape[i][" + WQ + "y2" + WQ + "]" + CRLF
buf = buf + " x3 = shape[i][" + WQ + "x3" + WQ + "]" + CRLF
buf = buf + " y3 = shape[i][" + WQ + "y3" + WQ + "]" + CRLF
buf = buf + " shape[i][" + WQ + "obj" + WQ + "] = Shapes.AddTriangle(x1 * s, y1 * s, x2 * s, y2 * s, x3 * s, y3 * s)" + CRLF
buf = buf + " Shapes.Move(shape[i][" + WQ + "obj" + WQ + "], shX + x * s, shY + y * s)" + CRLF
buf = buf + " ElseIf shape[i][" + WQ + "func" + WQ + "] = " + WQ + "line" + WQ + " Then" + CRLF
buf = buf + " x = shape[i][" + WQ + "x" + WQ + "]" + CRLF
buf = buf + " y = shape[i][" + WQ + "y" + WQ + "]" + CRLF
buf = buf + " x1 = shape[i][" + WQ + "x1" + WQ + "]" + CRLF
buf = buf + " y1 = shape[i][" + WQ + "y1" + WQ + "]" + CRLF
buf = buf + " x2 = shape[i][" + WQ + "x2" + WQ + "]" + CRLF
buf = buf + " y2 = shape[i][" + WQ + "y2" + WQ + "]" + CRLF
buf = buf + " shape[i][" + WQ + "obj" + WQ + "] = Shapes.AddLine(x1 * s, y1 * s, x2 * s, y2 * s)" + CRLF
buf = buf + " Shapes.Move(shape[i][" + WQ + "obj" + WQ + "], shX + x * s, shY + y * s)" + CRLF
buf = buf + " EndIf" + CRLF
buf = buf + " EndFor" + CRLF
buf = buf + " shAngle = 0" + CRLF
buf = buf + " y = Stack.PopValue(" + WQ + "local" + WQ + ")" + CRLF
buf = buf + " x = Stack.PopValue(" + WQ + "local" + WQ + ")" + CRLF
buf = buf + " i = Stack.PopValue(" + WQ + "local" + WQ + ")" + CRLF
buf = buf + "EndSub" + CRLF
buf = buf + CRLF
buf = buf + "Sub Shapes_CalcWidthAndHeight" + CRLF
buf = buf + " ' return nShapes - number of shapes" + CRLF
buf = buf + " ' return shWidth, shHeight - total size of shapes" + CRLF
buf = buf + " nShapes = Array.GetItemCount(shape)" + CRLF
buf = buf + " For i = 1 To nShapes" + CRLF
buf = buf + " If shape[i][" + WQ + "func" + WQ + "] = " + WQ + "tri" + WQ + " Or shape[i][" + WQ + "func" + WQ + "] = " + WQ + "line" + WQ + " Then" + CRLF
buf = buf + " xmin = shape[i][" + WQ + "x1" + WQ + "]" + CRLF
buf = buf + " xmax = shape[i][" + WQ + "x1" + WQ + "]" + CRLF
buf = buf + " ymin = shape[i][" + WQ + "y1" + WQ + "]" + CRLF
buf = buf + " ymax = shape[i][" + WQ + "y1" + WQ + "]" + CRLF
buf = buf + " If shape[i][" + WQ + "x2" + WQ + "] < xmin Then" + CRLF
buf = buf + " xmin = shape[i][" + WQ + "x2" + WQ + "]" + CRLF
buf = buf + " EndIf" + CRLF
buf = buf + " If xmax < shape[i][" + WQ + "x2" + WQ + "] Then" + CRLF
buf = buf + " xmax = shape[i][" + WQ + "x2" + WQ + "]" + CRLF
buf = buf + " EndIf" + CRLF
buf = buf + " If shape[i][" + WQ + "y2" + WQ + "] < ymin Then" + CRLF
buf = buf + " ymin = shape[i][" + WQ + "y2" + WQ + "]" + CRLF
buf = buf + " EndIf" + CRLF
buf = buf + " If ymax < shape[i][" + WQ + "y2" + WQ + "] Then" + CRLF
buf = buf + " ymax = shape[i][" + WQ + "y2" + WQ + "]" + CRLF
buf = buf + " EndIf" + CRLF
buf = buf + " If shape[i][" + WQ + "func" + WQ + "] = " + WQ + "tri" + WQ + " Then" + CRLF
buf = buf + " If shape[i][" + WQ + "x3" + WQ + "] < xmin Then" + CRLF
buf = buf + " xmin = shape[i][" + WQ + "x3" + WQ + "]" + CRLF
buf = buf + " EndIf" + CRLF
buf = buf + " If xmax < shape[i][" + WQ + "x3" + WQ + "] Then" + CRLF
buf = buf + " xmax = shape[i][" + WQ + "x3" + WQ + "]" + CRLF
buf = buf + " EndIf" + CRLF
buf = buf + " If shape[i][" + WQ + "y3" + WQ + "] < ymin Then" + CRLF
buf = buf + " ymin = shape[i][" + WQ + "y3" + WQ + "]" + CRLF
buf = buf + " EndIf" + CRLF
buf = buf + " If ymax < shape[i][" + WQ + "y3" + WQ + "] Then" + CRLF
buf = buf + " ymax = shape[i][" + WQ + "y3" + WQ + "]" + CRLF
buf = buf + " EndIf" + CRLF
buf = buf + " EndIf" + CRLF
buf = buf + " shape[i][" + WQ + "width" + WQ + "] = xmax - xmin" + CRLF
buf = buf + " shape[i][" + WQ + "height" + WQ + "] = ymax - ymin" + CRLF
buf = buf + " EndIf" + CRLF
buf = buf + " If i = 1 Then" + CRLF
buf = buf + " shWidth = shape[i][" + WQ + "x" + WQ + "] + shape[i][" + WQ + "width" + WQ + "]" + CRLF
buf = buf + " shHeight = shape[i][" + WQ + "y" + WQ + "] + shape[i][" + WQ + "height" + WQ + "]" + CRLF
buf = buf + " Else" + CRLF
buf = buf + " If shWidth < shape[i][" + WQ + "x" + WQ + "] + shape[i][" + WQ + "width" + WQ + "] Then" + CRLF
buf = buf + " shWidth = shape[i][" + WQ + "x" + WQ + "] + shape[i][" + WQ + "width" + WQ + "]" + CRLF
buf = buf + " EndIf" + CRLF
buf = buf + " If shHeight < shape[i][" + WQ + "y" + WQ + "] + shape[i][" + WQ + "height" + WQ + "] Then" + CRLF
buf = buf + " shHeight = shape[i][" + WQ + "y" + WQ + "] + shape[i][" + WQ + "height" + WQ + "]" + CRLF
buf = buf + " EndIf" + CRLF
buf = buf + " EndIf" + CRLF
buf = buf + " EndFor" + CRLF
buf = buf + "EndSub" + CRLF
buf = buf + CRLF
buf = buf + "Sub Shapes_CalcRotatePos" + CRLF
buf = buf + " ' param x, y - position of a shape" + CRLF
buf = buf + " ' param width, height - size of a shape" + CRLF
buf = buf + " ' param cx, cy - center of shapes" + CRLF
buf = buf + " ' param shAngle - rotate angle" + CRLF
buf = buf + " ' return x, y - rotated position of a shape" + CRLF
buf = buf + " _cx = x + width / 2" + CRLF
buf = buf + " _cy = y + height / 2" + CRLF
buf = buf + " x = _cx - cx" + CRLF
buf = buf + " y = _cy - cy" + CRLF
buf = buf + " Math_CartesianToPolar()" + CRLF
buf = buf + " a = a + shAngle" + CRLF
buf = buf + " x = r * Math.Cos(a * Math.Pi / 180)" + CRLF
buf = buf + " y = r * Math.Sin(a * Math.Pi / 180)" + CRLF
buf = buf + " _cx = x + cx" + CRLF
buf = buf + " _cy = y + cy" + CRLF
buf = buf + " x = _cx - width / 2" + CRLF
buf = buf + " y = _cy - height / 2" + CRLF
buf = buf + "EndSub" + CRLF
buf = buf + CRLF
buf = buf + "Sub Shapes_Move" + CRLF
buf = buf + " ' param shape - array of shapes" + CRLF
buf = buf + " ' param scale" + CRLF
buf = buf + " ' param x, y - position to move" + CRLF
buf = buf + " ' return shX, shY - new position of shapes" + CRLF
buf = buf + " Stack.PushValue(" + WQ + "local" + WQ + ", i)" + CRLF
buf = buf + " Stack.PushValue(" + WQ + "local" + WQ + ", x)" + CRLF
buf = buf + " Stack.PushValue(" + WQ + "local" + WQ + ", y)" + CRLF
buf = buf + " shX = x" + CRLF
buf = buf + " shY = y" + CRLF
buf = buf + " For i = 1 To nShapes" + CRLF
buf = buf + " _x = shape[i][" + WQ + "x" + WQ + "]" + CRLF
buf = buf + " _y = shape[i][" + WQ + "y" + WQ + "]" + CRLF
buf = buf + " width = shape[i][" + WQ + "width" + WQ + "]" + CRLF
buf = buf + " height = shape[i][" + WQ + "height" + WQ + "]" + CRLF
buf = buf + " Shapes_CalcRotatePos()" + CRLF
buf = buf + " Shapes.Move(shape[i][" + WQ + "obj" + WQ + "], shX + _x * s, shY + _y * s)" + CRLF
buf = buf + " EndFor" + CRLF
buf = buf + " y = Stack.PopValue(" + WQ + "local" + WQ + ")" + CRLF
buf = buf + " x = Stack.PopValue(" + WQ + "local" + WQ + ")" + CRLF
buf = buf + " i = Stack.PopValue(" + WQ + "local" + WQ + ")" + CRLF
buf = buf + "EndSub" + CRLF
buf = buf + CRLF
buf = buf + "Sub Shapes_Remove" + CRLF
buf = buf + " ' param shape - array of shapes" + CRLF
buf = buf + " Stack.PushValue(" + WQ + "local" + WQ + ", i)" + CRLF
buf = buf + " For i = 1 To nShapes" + CRLF
buf = buf + " Shapes.Remove(shape[i][" + WQ + "obj" + WQ + "])" + CRLF
buf = buf + " EndFor" + CRLF
buf = buf + " i = Stack.PopValue(" + WQ + "local" + WQ + ")" + CRLF
buf = buf + "EndSub" + CRLF
buf = buf + CRLF
buf = buf + "Sub Shapes_Rotate" + CRLF
buf = buf + " ' param shape - array of shapes" + CRLF
buf = buf + " ' param scale" + CRLF
buf = buf + " ' param angle" + CRLF
buf = buf + " Stack.PushValue(" + WQ + "local" + WQ + ", i)" + CRLF
buf = buf + " Stack.PushValue(" + WQ + "local" + WQ + ", x)" + CRLF
buf = buf + " Stack.PushValue(" + WQ + "local" + WQ + ", y)" + CRLF
buf = buf + " s = scale" + CRLF
buf = buf + " shAngle = angle" + CRLF
buf = buf + " cx = shWidth / 2" + CRLF
buf = buf + " cy = shHeight / 2" + CRLF
buf = buf + " For i = 1 To nShapes" + CRLF
buf = buf + " x = shape[i][" + WQ + "x" + WQ + "]" + CRLF
buf = buf + " y = shape[i][" + WQ + "y" + WQ + "]" + CRLF
buf = buf + " width = shape[i][" + WQ + "width" + WQ + "]" + CRLF
buf = buf + " height = shape[i][" + WQ + "height" + WQ + "]" + CRLF
buf = buf + " Shapes_CalcRotatePos()" + CRLF
buf = buf + " Shapes.Move(shape[i][" + WQ + "obj" + WQ + "], shX + x * s, shY + y * s)" + CRLF
buf = buf + " Shapes.Rotate(shape[i][" + WQ + "obj" + WQ + "], shAngle)" + CRLF
buf = buf + " EndFor" + CRLF
buf = buf + " y = Stack.PopValue(" + WQ + "local" + WQ + ")" + CRLF
buf = buf + " x = Stack.PopValue(" + WQ + "local" + WQ + ")" + CRLF
buf = buf + " i = Stack.PopValue(" + WQ + "local" + WQ + ")" + CRLF
buf = buf + "EndSub" + CRLF
buf = buf + CRLF
buf = buf + "Sub Math_CartesianToPolar" + CRLF
buf = buf + " ' param x, y - cartesian coordinate" + CRLF
buf = buf + " ' return r, a - polar coordinate" + CRLF
buf = buf + " r = Math.SquareRoot(x * x + y * y)" + CRLF
buf = buf + " If x = 0 And y > 0 Then" + CRLF
buf = buf + " a = 90 ' [degree]" + CRLF
buf = buf + " ElseIf x = 0 And y < 0 Then" + CRLF
buf = buf + " a = -90" + CRLF
buf = buf + " Else" + CRLF
buf = buf + " a = Math.ArcTan(y / x) * 180 / Math.Pi" + CRLF
buf = buf + " EndIf" + CRLF
buf = buf + " If x < 0 Then" + CRLF
buf = buf + " a = a + 180" + CRLF
buf = buf + " ElseIf x > 0 And y < 0 Then" + CRLF
buf = buf + " a = a + 360" + CRLF
buf = buf + " EndIf" + CRLF
buf = buf + "EndSub" + CRLF
File_Save()
i = Stack.PopValue("local")
EndSub

Sub WaitToClick
param = "down=True;move=False;up=False;" ' wait to click
Mouse_SetHandler()
While clicked = "False"
Program.Delay(100)
EndWhile
EndSub

Sub WaitToRelease ' for sizing a shape
GraphicsWindow.PenWidth = 1
GraphicsWindow.PenColor = "Black"
GraphicsWindow.BrushColor = "White"
param = "down=False;move=True;up=True;" ' for sizing a shape / wait to release
Mouse_SetHandler()
While released = "False"
If moved Then
param = "move=False;" ' while sizing a shape
Mouse_SetHandler()
If func = "rect" Then
If oRect <> "" Then
Shapes.Remove(oRect)
EndIf
xmin = Math.Min(mxD, mxM)
ymin = Math.Min(myD, myM)
xmax = Math.Max(mxD, mxM)
ymax = Math.Max(myD, myM)
oRect = Shapes.AddRectangle(xmax - xmin, ymax - ymin)
Shapes.Move(oRect, xmin, ymin)
Shapes.SetOpacity(oRect, 50)
ElseIf func = "ell" Then
If oEll <> "" Then
Shapes.Remove(oEll)
EndIf
xmin = Math.Min(mxD, mxM)
ymin = Math.Min(myD, myM)
xmax = Math.Max(mxD, mxM)
ymax = Math.Max(myD, myM)
oEll = Shapes.AddEllipse(xmax - xmin, ymax - ymin)
Shapes.Move(oEll, xmin, ymin)
Shapes.SetOpacity(oEll, 50)
ElseIf func = "tri" Then
If oTri <> "" Then
Shapes.Remove(oTri)
EndIf
oTri = Shapes.AddTriangle((mxM - mxD) / 2, 0, 0, myM - myD, mxM - mxD, myM - myD)
Shapes.Move(oTri, mxD, myD)
Shapes.SetOpacity(oTri, 50)
ElseIf func = "line" Then
If oLine <> "" Then
Shapes.Remove(oLine)
EndIf
oLine = Shapes.AddLine(mxD, myD, mxM, myM)
Shapes.SetOpacity(oLine, 50)
EndIf
param = "move=True;" ' for next sizing a shape
Mouse_SetHandler()
Else
Program.Delay(100)
EndIf
EndWhile
param = "move=False;up=False;" ' mouse released
Mouse_SetHandler()
If oRect <> "" Then
Shapes.Remove(oRect)
oRect = ""
EndIf
If oEll <> "" Then
Shapes.Remove(oEll)
oEll = ""
EndIf
If oTri <> "" Then
Shapes.Remove(oTri)
oTri = ""
EndIf
If oLine <> "" Then
Shapes.Remove(oLine)
oLine = ""
EndIf
EndSub

Sub WaitToRelease2 ' for moving a shape
GraphicsWindow.PenWidth = 1
GraphicsWindow.PenColor = "Black"
GraphicsWindow.BrushColor = "White"
param = "down=False;move=True;up=True;" ' for moving a shape / wait to release
Mouse_SetHandler()
_x = shape[i]["x"]
_y = shape[i]["y"]
While released = "False"
If moved Then
param = "move=False;" ' while moving a shape
Mouse_SetHandler()
_x = shape[i]["x"] + mxM - mxD
_y = shape[i]["y"] + myM - myD
If func = "rect" Then
If oRect = "" Then
oRect = Shapes.AddRectangle(shape[i]["width"], shape[i]["height"])
Shapes.SetOpacity(oRect, 50)
EndIf
Shapes.Move(oRect, _x, _y)
ElseIf func = "ell" Then
If oEll = "" Then
oEll = Shapes.AddEllipse(shape[i]["width"], shape[i]["height"])
Shapes.SetOpacity(oEll, 50)
EndIf
Shapes.Move(oEll, _x, _y)
ElseIf func = "tri" Then
If oTri = "" Then
_x1 = shape[i]["x1"]
_y1 = shape[i]["y1"]
_x2 = shape[i]["x2"]
_y2 = shape[i]["y2"]
_x3 = shape[i]["x3"]
_y3 = shape[i]["y3"]
oTri = Shapes.AddTriangle(_x1, _y1, _x2, _y2, _x3, _y3)
Shapes.SetOpacity(oTri, 50)
EndIf
Shapes.Move(oTri, _x, _y)
ElseIf func = "line" Then
If oLine = "" Then
_x1 = shape[i]["x1"]
_y1 = shape[i]["y1"]
_x2 = shape[i]["x2"]
_y2 = shape[i]["y2"]
oLine = Shapes.AddLine(_x1, _y1, _x2, _y2)
Shapes.SetOpacity(oLine, 50)
EndIf
Shapes.Move(oLine, _x, _y)
EndIf
param = "move=True;" ' for next moving a shape
Mouse_SetHandler()
Else
Program.Delay(100)
EndIf
EndWhile
param = "move=False;up=False;" ' mouse released
Mouse_SetHandler()
shape[i]["x"] = _x
shape[i]["y"] = _y
Shapes.Move(shape[i]["obj"], _x, _y)
If shape[i]["func"] = "line" Then
_x1 = shape[i]["x"] + shape[i]["x1"] - size / 2
_y1 = shape[i]["y"] + shape[i]["y1"] - size / 2
_x2 = shape[i]["x"] + shape[i]["x2"] - size / 2
_y2 = shape[i]["y"] + shape[i]["y2"] - size / 2
Shapes.Move(oEll1, _x1, _y1)
Shapes.Move(oEll2, _x2, _y2)
Else
_x1 = shape[i]["x"] - size / 2
_y1 = shape[i]["y"] - size / 2
_x2 = shape[i]["x"] + shape[i]["width"] - size / 2
_y2 = shape[i]["y"] + shape[i]["height"] - size / 2
Shapes.Move(oEll1, _x1, _y1)
Shapes.Move(oEll2, _x2, _y1)
Shapes.Move(oEll3, _x1, _y2)
Shapes.Move(oEll4, _x2, _y2)
EndIf
If oRect <> "" Then
Shapes.Remove(oRect)
oRect = ""
EndIf
If oEll <> "" Then
Shapes.Remove(oEll)
oEll = ""
EndIf
If oTri <> "" Then
Shapes.Remove(oTri)
oTri = ""
EndIf
If oLine <> "" Then
Shapes.Remove(oLine)
oLine = ""
EndIf
EndSub

Sub ItemSelect
' i - menu index
' select - "True" if selected
If select Then
GraphicsWindow.PenColor = "Gray"
Else
GraphicsWindow.PenColor = "White"
EndIf
GraphicsWindow.PenWidth = 2
x = menu[i]["x0"] - 1
y = menu[i]["y0"] - 1
width = menu[i]["x1"] - x + 1
height = menu[i]["y1"] - y + 1
GraphicsWindow.DrawRectangle(x, y, width, height)
EndSub

Sub SearchClickedObject
' return obj
Stack.PushValue("local", i)
obj = ""
For i = 1 To nMenu
If menu[i]["x0"] <= mxD And mxD <= menu[i]["x1"] And menu[i]["y0"] <= myD And myD <= menu[i]["y1"] Then
obj = "menu" + i
Goto sco_exit
EndIf
EndFor
For i = nShapes To 1 Step -1
_x0 = shape[i]["x"]
_x1 = shape[i]["x"] + shape[i]["width"]
_y0 = shape[i]["y"]
_y1 = shape[i]["y"] + shape[i]["height"]
If _x0 <= mxD And mxD <= _x1 And _y0 <= myD And myD <= _y1 Then
If shape[i]["func"] = "rect" Then
obj = "shape" + i
Goto sco_exit
ElseIf shape[i]["func"] = "ell" Then
width = shape[i]["width"]
height = shape[i]["height"]
x = (mxD - (_x0 + width / 2)) / width * 2
y = (myD - (_y0 + height / 2)) / height * 2
r = Math.SquareRoot(x * x + y * y)
If r <= 1 Then
obj = "shape" + i
Goto sco_exit
EndIf
ElseIf shape[i]["func"] = "tri" Then
width = shape[i]["width"]
height = shape[i]["height"]
x = (mxD - (_x0 + width / 2)) / width * 2
If shape[i]["y1"] = 0 Then
y = (myD - _y1) / height
r = Math.Abs(x) + Math.Abs(y)
If r <= 1 And y <= 0 Then
obj = "shape" + i
Goto sco_exit
EndIf
Else
y = (myD - _y0) / height
r = Math.Abs(x) + Math.Abs(y)
If r <= 1 And y >= 0 Then
obj = "shape" + i
Goto sco_exit
EndIf
EndIf
ElseIf shape[i]["func"] = "line" Then
_x1 = _x0 + shape[i]["x1"]
_y1 = _y0 + shape[i]["y1"]
_x2 = _x0 + shape[i]["x2"]
_y2 = _y0 + shape[i]["y2"]
r1 = Math.SquareRoot(Math.Power(_x1 - mxD, 2) + Math.Power(_y1 - myD, 2))
r2 = Math.SquareRoot(Math.Power(_x2 - mxD, 2) + Math.Power(_y2 - myD, 2))
r = Math.SquareRoot(Math.Power(_x2 - _x1, 2) + Math.Power(_y2 - _y1, 2))
If r1 + r2 <= (r * 1.0001) Then
obj = "shape" + i
Goto sco_exit
EndIf
EndIf
EndIf
EndFor
sco_exit:
i = Stack.PopValue("local")
EndSub

Sub ShapeSelect
' i - shape index
' select - "True" if selected
If select Then
GraphicsWindow.PenColor = "Black"
GraphicsWindow.PenWidth = 1
GraphicsWindow.BrushColor = "#639AE7"
size = 10
selectedshape = i
If shape[i]["func"] = "line" Then
_x1 = shape[i]["x"] + shape[i]["x1"] - size / 2
_y1 = shape[i]["y"] + shape[i]["y1"] - size / 2
_x2 = shape[i]["x"] + shape[i]["x2"] - size / 2
_y2 = shape[i]["y"] + shape[i]["y2"] - size / 2
oEll1 = Shapes.AddEllipse(size, size)
Shapes.Move(oEll1, _x1, _y1)
oEll2 = Shapes.AddEllipse(size, size)
Shapes.Move(oEll2, _x2, _y2)
Else
_x1 = shape[i]["x"] - size / 2
_y1 = shape[i]["y"] - size / 2
_x2 = shape[i]["x"] + shape[i]["width"] - size / 2
_y2 = shape[i]["y"] + shape[i]["height"] - size / 2
oEll1 = Shapes.AddEllipse(size, size)
Shapes.Move(oEll1, _x1, _y1)
oEll2 = Shapes.AddEllipse(size, size)
Shapes.Move(oEll2, _x2, _y1)
oEll3 = Shapes.AddEllipse(size, size)
Shapes.Move(oEll3, _x1, _y2)
oEll4 = Shapes.AddEllipse(size, size)
Shapes.Move(oEll4, _x2, _y2)
EndIf
Else
selectedshape = ""
If shape[i]["func"] = "line" Then
Shapes.Remove(oEll1)
Shapes.Remove(oEll2)
Else
Shapes.Remove(oEll1)
Shapes.Remove(oEll2)
Shapes.Remove(oEll3)
Shapes.Remove(oEll4)
EndIf
EndIf
EndSub

Sub Color_ColorToRGB
' Color | Convert Color to RGB
' param sColor - "#rrggbb"
' return iR, iG, iB - [0, 255]
sR = Text.GetSubText(sColor, 2, 2)
sG = Text.GetSubText(sColor, 4, 2)
sB = Text.GetSubText(sColor, 6, 2)
sHex = sR
Math_Hex2Dec()
iR = iDec
sHex = sG
Math_Hex2Dec()
iG = iDec
sHex = sB
Math_Hex2Dec()
iB = iDec
EndSub

Sub Color_HSLtoRGB
' Color | Convert HSL to RGB
' param rHue - [0, 360) or UNDEFINED
' param rLightness - [0, 1]
' param rSaturation - [0, 1]
' return iR, iG, iB - RGB color
' return sColor - "#rrggbb"
If rLightness <= 0.5 Then
rN2 = rLightness * (1 + rSaturation)
Else
rN2 = rLightness + rSaturation - rLightness * rSaturation
EndIf
rN1 = 2 * rLightness - rN2
If rSaturation = 0 Then
iR = Math.Round(rLightness * 255)
iG = Math.Round(rLightness * 255)
iB = Math.Round(rLightness * 255)
Else
rH = rHue + 120
Color_Value()
iR = iValue
rH = rHue
Color_Value()
iG = iValue
rH = rHue - 120
Color_Value()
iB = iValue
EndIf
sColor = GraphicsWindow.GetColorFromRGB(iR, iG, iB)
EndSub

Sub Color_RGBtoHSL
' Color | Convert RGB to HSL
' param sColor - "#rrggbb"
' return rHue - [0, 360) or UNDEFINED
' return rLightness - (0, 1)
' return rSaturation - (0, 1)
Color_ColorToRGB()
' rR = iR / 255 ' occurs Math.Max() bug
rR = Math.Round(iR / 255 * 10000) / 10000
' rG = iG / 255 ' occurs Math.Max() bug
rG = Math.Round(iG / 255 * 10000) / 10000
' rB = iB / 255 ' occurs Math.Max() bug
rB = Math.Round(iB / 255 * 10000) / 10000
rMax = Math.Max(rR, rG)
rMax = Math.Max(rMax, rB)
rMin = Math.Min(rR, rG)
rMin = Math.Min(rMin, rB)
rLightness = (rMax + rMin) / 2
If rMax = rMin Then ' rR = rG = rB
rSaturation = 0
rHue = UNDEFINED
Else
If rLightness <= 0.5 Then
rSaturation = (rMax - rMin) / (rMax + rMin)
Else
rSaturation = (rMax - rMin) / (2 - rMax - rMin)
EndIf
rRC = (rMax - rR) / (rMax - rMin)
rGC = (rMax - rG) / (rMax - rMin)
rBC = (rMax - rB) / (rMax - rMin)
If rR = rMax Then ' between Yellow and Magenta
rHue = rBC - rGC
ElseIf rG = rMax Then ' between Cyan and Yellow
rHue = 2 + rRC - rBC
ElseIf rB = rMax Then ' between Magenta and Cyan
rHue = 4 + rGC - rRC
Else
TextWindow.WriteLine("Error:")
TextWindow.WriteLine("rMax=" + rMax)
TextWindow.WriteLine("rR=" + rR + ",sR=" + sR)
TextWindow.WriteLine("rG=" + rG + ",sG=" + sG)
TextWindow.WriteLine("rB=" + rB + ",sB=" + sB)
EndIf
rHue = rHue * 60
If rHue < 0 Then
rHue = rHue + 360
EndIf
EndIf
EndSub

Sub Color_Value
' Color | Function value
' param rN1, rN2
' param rH - [-120, 480)
' return iValue - 0..255
If rH >= 360 Then
rH = rH - 360
EndIF
If rH < 0 Then
rH = rH + 360
EndIF
If rH < 60 Then
rV = rN1 + (rN2 - rN1) * rH / 60
ElseIf rH < 180 Then
rV = rN2
ElseIf rH < 240 Then
rV = rN1 + (rN2 - rN1) * (240 - rH) / 60
Else
rV = rN1
EndIf
iValue = Math.Round(rV * 255)
EndSub

Sub CS_AddColorToPalette
' Color Selector | Add color to palette
' param color - color to set
' param maxPalette
' param nPalette
' param palette
' param tPalette - target palette
Stack.PushValue("local", i)
For i = 1 To nPalette
If color = palette[i]["color"] Then
Goto csactp_not_new_color
EndIf
EndFor
palette[tPalette]["color"] = color
If nPalette < maxPalette Then
nPalette = nPalette + 1
EndIf
tPalette = tPalette + 1
If maxPalette < tPalette Then
tPalette = 1
EndIf
csactp_not_new_color:
i = Stack.PopValue("local")
EndSub

Sub CS_AdjustSlider
' Color Selector | Adjust slider
' param iSlider - moved slider
Stack.PushValue("local", iSlider)
If iSlider = iHue Or iSlider = iLightness Or iSlider = iSaturation Then
If iSlider = iHue Then
Slider_GetLevel()
rHue = level
ElseIf iSlider = iLightness Then
Slider_GetLevel()
rLightness = level / 100
Else
Slider_GetLevel()
rSaturation = level / 100
EndIf
Color_HSLtoRGB()
iSlider = iRed
level = iR
Slider_SetLevel()
iSlider = iGreen
level = iG
Slider_SetLevel()
iSlider = iBlue
level = iB
Slider_SetLevel()
Else
CS_GetColorFromSlider()
sColor = GraphicsWindow.GetColorFromRGB(red, green, blue)
Color_RGBtoHSL()
If rHue = UNDEFINED Then
rHue = 0
EndIf
level = Math.Floor(rHue)
iSlider = iHue
Slider_SetLevel()
level = Math.Floor(rSaturation * 100)
iSlider = iSaturation
Slider_SetLevel()
level = Math.Floor(rLightness * 100)
iSlider = iLightness
Slider_SetLevel()
EndIf
iSlider = Stack.PopValue("local")
EndSub

Sub CS_DoObject
' Color Selector | Do object
' param - obj
While obj <> ""
CS_DoSlider()
If obj <> "" Then
CS_DoPalette()
EndIf
EndWhile
EndSub

Sub CS_DoPalette
' Color Selector | Do palette
' param obj - clicked object
If Text.StartsWith(obj, "palette") Then
iPalette = Text.GetSubTextToEnd(obj, 8)
color = palette[iPalette]["color"]
CS_SetColorToSlider() ' set color to slider
CS_ShowNewColor() ' show new color name
CS_DrawColorRect() ' draw new color rectangle
obj = ""
param = "down=True;move=False;up=False;" ' wait to click
Mouse_SetHandler()
EndIf
EndSub

Sub CS_DoSlider
' Color Selector | Do slider
' param obj - clicked object
' param iSlider - index of slider
If Text.StartsWith(obj, "slider") Then
Slider_WaitToRelease()
obj = ""
param = "down=True;move=False;up=False;" ' wait to click
Mouse_SetHandler()
EndIf
EndSub

Sub CS_DrawColorRect
' Color Selector | Draw color rectangle
' param color - color of rectangle
' param x, y - position of rectangle
' param width, height - size of rectangle
' return oRect - rectangle object
GraphicsWindow.BrushColor = color
GraphicsWindow.PenColor = BORDERCOLOR
If oRect <> "" Then
Shapes.Remove(oRect)
EndIf
oRect = Shapes.AddRectangle(width, height)
Shapes.Move(oRect, x, y)
EndSub

Sub CS_DrawPalette
' Color Selector | Draw palette
' param palette[] - color palette
' param nPalette - number of color in palette
' param x, y - position of rectangle
' param width, height - size of rectangle
' return oPalette[] - palette object array
Stack.PushValue("local", i)
GraphicsWindow.PenColor = BORDERCOLOR
For i = 1 To nPalette
GraphicsWindow.BrushColor = palette[i]["color"]
palette[i]["oCell"] = Shapes.AddRectangle(width, height)
dx = Math.Remainder((i - 1), 8) * (width + 4)
dy = Math.Floor((i - 1) / 8) * (height + 4)
Shapes.Move(palette[i]["oCell"], x + dx, y + dy)
palette[i]["x"] = x + dx
palette[i]["y"] = y + dy
palette[i]["width"] = width
palette[i]["height"] = height
EndFor
i = Stack.PopValue("local")
EndSub

Sub CS_GetColorFromSlider
' Color Selector | get color from slider
' return color
Stack.PushValue("local", iSlider)
iSlider = iRed ' slider index
Slider_GetLevel()
red = level
iSlider = iGreen ' slider index
Slider_GetLevel()
green = level
iSlider = iBlue ' slider index
Slider_GetLevel()
blue = level
color = GraphicsWindow.GetColorFromRGB(red, green, blue)
iSlider = Stack.PopValue("local")
EndSub

Sub CS_Init
' Color Selector | Initialize sliders
width = 256
min = 0
max = 255
left = 190
' add red slider
top = TOPY
caption = "R"
Slider_Add()
iRed = iSlider ' index of slider
' add green slider
top = top + DELTAY
caption = "G"
Slider_Add()
iGreen = iSlider ' index of slider
' add blue slider
top = top + DELTAY
caption = "B"
Slider_Add()
iBlue = iSlider ' index of slider
' add hue slider
width = 360
top = top + DELTAY
max = 360
caption = "H"
Slider_Add()
iHue = iSlider ' index of slider
' add saturation slider
width = 100
top = top + DELTAY
max = 100
caption = "S"
Slider_Add()
iSaturation = iSlider ' index of slider
' add lightness slider
width = 100
top = top + DELTAY
max = 100
caption = "L"
Slider_Add()
iLightness = iSlider ' index of slider
' draw color rectangle
CS_GetColorFromSlider()
CS_ShowNewColor()
x = LEFTX
y = TOPY + DELTAY * 4
width = 100
height = 100
CS_DrawColorRect()
' add text box
GraphicsWindow.BrushColor = CAPTIONCOLOR
top = y + height + 4
oNewColor = Shapes.AddText("")
Shapes.Move(oNewColor, LEFTX, top)
EndSub

Sub CS_DumpSlider
' Color Selector | Dump slider for debug
For i = 1 To numSlider
TextWindow.WriteLine("slider" + i)
TextWindow.WriteLine(slider[i])
EndFor
EndSub

Sub CS_InitPalette
' Color Selector | Initialize palette
' This subroutine should be called before CS_ShowPopup().
maxPalette = 16 ' max cell number of palette
nPalette = 2 ' number of palette in use
tPalette = 3 ' index of update target cell
palette[1]["color"] = pcolor
palette[2]["color"] = bcolor
EndSub

Sub CS_RemovePalette
' Color Selector | Remove palette
' param nPalette - number of color in palette
' return oPalette[] - palette object array
Stack.PushValue("local", i)
For i = 1 To nPalette
oPalette = "Palette" + i
Shapes.Remove(palette[i]["oCell"])
EndFor
i = Stack.PopValue("local")
EndSub

Sub CS_RemoveSliders
' Color Selector | Remove sliders
For iSlider = 1 To numSlider
Slider_Remove()
EndFor
numSlider = 0
EndSub

Sub CS_SearchClickedObject
' Color Selector | Check slider clicked
' param mxD, myD - clicked point
' return obj - clicked slider or palette
' return iSlider - index if obj is slider
' return iPalette - index if obj is palette
Stack.PushValue("local", i)
For iSlider = 1 To numSlider
obj = "slider" + iSlider
x2 = slider[iSlider]["x2"]
y2 = slider[iSlider]["y2"]
x3 = slider[iSlider]["x3"]
y3 = slider[iSlider]["y3"]
If x2 <= mxD And mxD <= x3 And y2 <= myD And myD <= y3 Then
Goto scco_obj_found
EndIf
EndFor
For iPalette = 1 To nPalette
obj = "palette" + iPalette
x2 = palette[iPalette]["x"]
y2 = palette[iPalette]["y"]
x3 = palette[iPalette]["x"] + palette[iPalette]["width"]
y3 = palette[iPalette]["y"] + palette[iPalette]["height"]
If x2 <= mxD And mxD <= x3 And y2 <= myD And myD <= y3 Then
Goto scco_obj_found
EndIf
EndFor
obj = ""
scco_obj_found:
i = Stack.PopValue("local")
EndSub

Sub CS_SetColorToSlider
' Color Selector | Set color to slider
' param color
Stack.PushValue("local", iSlider)
sColor = color
Color_ColorToRGB()
iSlider = iRed
level = iR
Slider_SetLevel()
iSlider = iGreen
level = iG
Slider_SetLevel()
iSlider = iBlue
level = iB
Slider_SetLevel()
CS_AdjustSlider()
iSlider = Stack.PopValue("local")
EndSub

Sub CS_ShowNewColor
' Color Selector | Show new color
' param oColor
' param color
Shapes.SetText(oNewColor, color)
EndSub

Sub CS_ShowPopup
' Color Selector | Show popup
' param color - current color
' return color - new color
' define constant
Stack.PushValue("local", cont)
colorInit = color ' initial color
TOPY = 80 ' top y
LEFTX = 36 ' left x
BORDERCOLOR = "#666666"
BOXCOLOR = "LightGray"
CAPTIONCOLOR = "White"
DELTAY = 36 ' delta y
SLITCOLOR = "#555555"
TEXTCOLOR = "Black"
UNDEFINED = "N/A"
POPUPCOLOR = "Black"
GraphicsWindow.PenWidth = 2
GraphicsWindow.PenColor = POPUPCOLOR
GraphicsWindow.BrushColor = POPUPCOLOR
oPopup = Shapes.AddRectangle(570, 310)
Shapes.SetOpacity(oPopup, 64)
Shapes.Move(oPopup, LEFTX - 10, TOPY - 10)
oOK = Controls.AddButton("OK", LEFTX + 440, TOPY + 260)
oCancel = Controls.AddButton("Cancel", LEFTX + 480, TOPY + 260)
Controls.ButtonClicked = CS_OnButtonClicked
CS_Init()
Stack.PushValue("local", y)
y = TOPY
color = colorInit
CS_DrawColorRect() ' original color
oRectCurrent = oRect
oRect = "" ' keep current color
GraphicsWindow.SetPixel(0, 0, colorInit)
color = GraphicsWindow.GetPixel(0, 0)
GraphicsWindow.SetPixel(0, 0, "LightGray")
GraphicsWindow.BrushColor = CAPTIONCOLOR
oColor = Shapes.AddText(colorInit)
Shapes.Move(oColor, x, y + height + 2)
If color <> colorInit Then
oColor2 = Shapes.AddText(color)
Shapes.Move(oColor2, x, y + height + 14)
EndIf
y = Stack.PopValue("local")
CS_SetColorToSlider()
CS_DrawColorRect() ' draw new color rectangle
CS_ShowNewColor() ' show new color name
Stack.PushValue("local", x)
Stack.PushValue("local", y)
Stack.PushValue("local", width)
Stack.PushValue("local", height)
x = x + width + 30
y = TOPY + height * 2 + 24
width = 30
height = 30
CS_DrawPalette()
height = Stack.PopValue("local")
width = Stack.PopValue("local")
y = Stack.PopValue("local")
x = Stack.PopValue("local")
cont = "True" ' continue
param = "down=True;move=False;up=False;" ' wait click
Mouse_SetHandler()
While cont
If clicked Then
CS_SearchClickedObject()
CS_DoObject()
Else
Program.Delay(100)
EndIf
EndWhile
If cancel Then
color = colorInit
Else
CS_AddColorToPalette()
EndIf
CS_RemovePalette()
CS_RemoveSliders()
Shapes.Remove(oColor)
Shapes.Remove(oColor2)
Shapes.Remove(oNewColor)
Shapes.Remove(oRectCurrent)
Shapes.Remove(oRect)
Controls.Remove(oOK)
Controls.Remove(oCancel)
Shapes.Remove(oPopup)
cont = Stack.PopValue("local")
EndSub

Sub CS_OnButtonClicked
' Color Selector | Event handler on button clicked
cont = "False"
If Controls.LastClickedButton = oCancel Then
cancel = "True"
Else
cancel = "False"
EndIf
EndSub

Sub File_Save
' File | Show output program to save
' param buf - program buffer
' define constant
Stack.PushValue("local", cont)
colorInit = color ' initial color
TOPY = 80 ' top y
LEFTX = 36 ' left x
DELTAY = 40 ' delta y
CAPTIONCOLOR = "White"
POPUPCOLOR = "Black"
TEXTCOLOR = "Black"
GraphicsWindow.PenWidth = 0
GraphicsWindow.BrushColor = POPUPCOLOR
oPopup = Shapes.AddRectangle(570, 310)
Shapes.SetOpacity(oPopup, 64)
Shapes.Move(oPopup, LEFTX - 10, TOPY - 10)
oText = Controls.AddTextBox(LEFTX, TOPY)
Controls.SetSize(oText, 550, 240)
Controls.SetTextBoxText(oText, buf)
oOK = Controls.AddButton("OK", LEFTX + 500, TOPY + 260)
cont = "True" ' continue
Controls.ButtonClicked = File_OnButtonClicked
While cont
Program.Delay(200)
EndWhile
Controls.Remove(oText)
Controls.Remove(oOK)
Controls.Remove(oPopup)
cont = Stack.PopValue("local")
EndSub

Sub File_OnButtonClicked
' File | Button event handler
cont = "False"
EndSub

Sub Math_CartesianToPolar
' Math | convert cartesian coodinate to polar coordinate
' param x, y - cartesian coordinate
' return r, a - polar coordinate
r = Math.SquareRoot(x * x + y * y)
If x = 0 And y > 0 Then
a = 90 ' [degree]
ElseIf x = 0 And y < 0 Then
a = -90
Else
a = Math.ArcTan(y / x) * 180 / Math.Pi
EndIf
If x < 0 Then
a = a + 180
ElseIf x > 0 And y < 0 Then
a = a + 360
EndIf
EndSub

Sub Math_Hex2Dec
' Math | Convert hexadecimal to decimal
' param sHex
' return iDec
iDec = 0
iLen = Text.GetLength(sHex)
For iPtr = 1 To iLen
iDec = iDec * 16 + Text.GetIndexOf("0123456789ABCDEF", Text.GetSubText(sHex, iPtr, 1)) - 1
EndFor
EndSub

Sub Scissors_Init
' Scissors | Initialize shapes data
' return shX, shY - current position of shapes
' return shape - array of shapes
shX = 237 ' x offset
shY = 30 ' y offset
shape[1] = "func=tri;x=45;y=0;x1=22;y1=0;x2=0;y2=213;x3=44;y3=213;bc=#6E6E6E;pw=0;"
shape[2] = "func=rect;x=45;y=212;width=15;height=47;bc=#6E6E6E;pw=0;"
shape[3] = "func=ell;x=0;y=235;width=66;height=104;bc=LightGray;pc=#0C95BB;pw=16;"
shape[4] = "func=tri;x=45;y=0;x1=22;y1=0;x2=0;y2=213;x3=44;y3=213;bc=#939393;pw=0;"
shape[5] = "func=rect;x=75;y=212;width=14;height=49;bc=#919191;pw=0;"
shape[6] = "func=ell;x=61;y=163;width=13;height=15;bc=#6E6E6E;pw=0;"
shape[7] = "func=ell;x=70;y=236;width=64;height=104;bc=LightGray;pc=#0C95BB;pw=16;"
EndSub

Sub Shapes_Add
' Shapes | add shapes data as shapes
' param shape - array of shapes
' param 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 = 1 To nShapes
GraphicsWindow.PenWidth = shape[i]["pw"] * s
If shape[i]["pw"] > 0 Then
GraphicsWindow.PenColor = shape[i]["pc"]
EndIf
If shape[i]["func"] = "rect" Then
GraphicsWindow.BrushColor = shape[i]["bc"]
x = shape[i]["x"]
y = shape[i]["y"]
width = shape[i]["width"]
height = shape[i]["height"]
shape[i]["obj"] = Shapes.AddRectangle(width * s, height * s)
Shapes.Move(shape[i]["obj"], shX + x * s, shY + y * s)
ElseIf shape[i]["func"] = "ell" Then
GraphicsWindow.BrushColor = shape[i]["bc"]
x = shape[i]["x"]
y = shape[i]["y"]
width = shape[i]["width"]
height = shape[i]["height"]
shape[i]["obj"] = Shapes.AddEllipse(width * s, height * s)
Shapes.Move(shape[i]["obj"], shX + x * s, shY + y * s)
ElseIf shape[i]["func"] = "tri" Then
GraphicsWindow.BrushColor = shape[i]["bc"]
x = shape[i]["x"]
y = shape[i]["y"]
x1 = shape[i]["x1"]
y1 = shape[i]["y1"]
x2 = shape[i]["x2"]
y2 = shape[i]["y2"]
x3 = shape[i]["x3"]
y3 = shape[i]["y3"]
shape[i]["obj"] = Shapes.AddTriangle(x1 * s, y1 * s, x2 * s, y2 * s, x3 * s, y3 * s)
Shapes.Move(shape[i]["obj"], shX + x * s, shY + y * s)
ElseIf shape[i]["func"] = "line" Then
x = shape[i]["x"]
y = shape[i]["y"]
x1 = shape[i]["x1"]
y1 = shape[i]["y1"]
x2 = shape[i]["x2"]
y2 = shape[i]["y2"]
shape[i]["obj"] = Shapes.AddLine(x1 * s, y1 * s, x2 * s, y2 * s)
Shapes.Move(shape[i]["obj"], shX + x * s, shY + y * s)
EndIf
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
' return nShapes - number of shapes
' return shWidth, shHeight - total size of shapes
nShapes = Array.GetItemCount(shape)
For i = 1 To nShapes
If shape[i]["func"] = "tri" Or shape[i]["func"] = "line" Then
xmin = shape[i]["x1"]
xmax = shape[i]["x1"]
ymin = shape[i]["y1"]
ymax = shape[i]["y1"]
If shape[i]["x2"] < xmin Then
xmin = shape[i]["x2"]
EndIf
If xmax < shape[i]["x2"] Then
xmax = shape[i]["x2"]
EndIf
If shape[i]["y2"] < ymin Then
ymin = shape[i]["y2"]
EndIf
If ymax < shape[i]["y2"] Then
ymax = shape[i]["y2"]
EndIf
If shape[i]["func"] = "tri" Then
If shape[i]["x3"] < xmin Then
xmin = shape[i]["x3"]
EndIf
If xmax < shape[i]["x3"] Then
xmax = shape[i]["x3"]
EndIf
If shape[i]["y3"] < ymin Then
ymin = shape[i]["y3"]
EndIf
If ymax < shape[i]["y3"] Then
ymax = shape[i]["y3"]
EndIf
EndIf
shape[i]["width"] = xmax - xmin
shape[i]["height"] = ymax - ymin
EndIf
If i = 1 Then
shWidth = shape[i]["x"] + shape[i]["width"]
shHeight = shape[i]["y"] + shape[i]["height"]
Else
If shWidth < shape[i]["x"] + shape[i]["width"] Then
shWidth = shape[i]["x"] + shape[i]["width"]
EndIf
If shHeight < shape[i]["y"] + shape[i]["height"] Then
shHeight = shape[i]["y"] + shape[i]["height"]
EndIf
EndIf
EndFor
EndSub

Sub Shapes_CalcRotatePos
' Shapes | Calculate position for rotated shape
' param x, y - position of a shape
' param width, height - size of a shape
' param cx, cy - center of shapes
' param shAngle - rotate angle
' return x, y - rotated position of a shape
_cx = x + width / 2
_cy = y + height / 2
x = _cx - cx
y = _cy - cy
Math_CartesianToPolar()
a = a + shAngle
x = r * Math.Cos(a * Math.Pi / 180)
y = r * Math.Sin(a * Math.Pi / 180)
_cx = x + cx
_cy = y + cy
x = _cx - width / 2
y = _cy - height / 2
EndSub

Sub Shapes_Move
' Shapes | Move shapes
' param shape - array of shapes
' param scale
' param x, y - position to move
' return shX, shY - new position of shapes
Stack.PushValue("local", i)
Stack.PushValue("local", x)
Stack.PushValue("local", y)
shX = x
shY = y
For i = 1 To nShapes
_x = shape[i]["x"]
_y = shape[i]["y"]
width = shape[i]["width"]
height = shape[i]["height"]
Shapes_CalcRotatePos()
Shapes.Move(shape[i]["obj"], shX + _x * s, shY + _y * s)
EndFor
y = Stack.PopValue("local")
x = Stack.PopValue("local")
i = Stack.PopValue("local")
EndSub

Sub Shapes_Remove
' Shapes | Remove shapes
' param shape - array of shapes
Stack.PushValue("local", i)
For i = 1 To nShapes
Shapes.Remove(shape[i]["obj"])
EndFor
i = Stack.PopValue("local")
EndSub

Sub Shapes_Rotate
' Shapes | Rotate shapes
' param shape - array of shapes
' param scale
' param angle
Stack.PushValue("local", i)
Stack.PushValue("local", x)
Stack.PushValue("local", y)
s = scale
shAngle = angle
cx = shWidth / 2
cy = shHeight / 2
For i = 1 To nShapes
x = shape[i]["x"]
y = shape[i]["y"]
width = shape[i]["width"]
height = shape[i]["height"]
Shapes_CalcRotatePos()
Shapes.Move(shape[i]["obj"], shX + x * s, shY + y * s)
Shapes.Rotate(shape[i]["obj"], shAngle)
EndFor
y = Stack.PopValue("local")
x = Stack.PopValue("local")
i = Stack.PopValue("local")
EndSub

Sub Slider_Add
' Slider | Add slider as shapes and property
' param width
' param caption
' param min, max
' param left, top
' return iSlider
numSlider = numSlider + 1
iSlider = numSlider
' add shapes for slider
GraphicsWindow.BrushColor = CAPTIONCOLOR
len = Text.GetLength(caption)
slider[iSlider]["oCaption"] = Shapes.AddText(caption)
Shapes.Move(slider[iSlider]["oCaption"], left - (len * 5 + 10), top + 1)
level = Math.Floor((min + max) / 2)
slider[iSlider]["level"] = level ' property
slider[iSlider]["min"] = min
slider[iSlider]["max"] = max
GraphicsWindow.PenColor = BORDERCOLOR
mag = (level - min) / (max - min)
GraphicsWindow.BrushColor = SLITCOLOR
slider[iSlider]["oSlit"] = Shapes.AddRectangle(width, 10)
GraphicsWindow.PenColor = BORDERCOLOR
GraphicsWindow.BrushColor = BOXCOLOR
slider[iSlider]["oBox"] = Shapes.AddRectangle(10, 18)
GraphicsWindow.BrushColor = CAPTIONCOLOR
slider[iSlider]["oLevel"] = Shapes.AddText(level)
slider[iSlider]["x0"] = left
slider[iSlider]["x1"] = left + width
slider[iSlider]["y0"] = top
Shapes.Move(slider[iSlider]["oLevel"], left + width + 5, top)
' move and zoom shapes for slider
Shapes.Move(slider[iSlider]["oSlit"], left, top + 4)
Slider_SetLevel()
EndSub

Sub Slider_CallBack
' Slider | Call back
' param iSlider - changed slider
CS_AdjustSlider()
CS_GetColorFromSlider()
CS_ShowNewColor() ' show new color name
CS_DrawColorRect() ' draw new color rectangle
EndSub

Sub Slider_GetLevel
' Slider | Get latest level of slider
' param iSlider
' return level
level = slider[iSlider]["level"]
EndSub

Sub Slider_GetMouseLevel
' Slider | Get mouse level of slider
' param iSlider
' return level
x0 = slider[iSlider]["x0"]
x1 = slider[iSlider]["x1"]
max = slider[iSlider]["max"]
min = slider[iSlider]["min"]
level = min + Math.Floor((max - min) * (mxM - x0) / (x1 - x0))
EndSub

Sub Slider_WaitToRelease
' Slider | Get released point for slider moving
' param iSlider
param = "down=False;move=True;up=True;" ' for slider moving / wait to release
Mouse_SetHandler()
While released = "False"
If moved Then
param = "move=False;" ' while slider moving
Mouse_SetHandler()
x0_ = slider[iSlider]["x0"]
x1_ = slider[iSlider]["x1"]
If mxM < x0_ Then
mxM = x0_
EndIf
If x1_ < mxM Then
mxM = x1_
EndIf
Slider_GetMouseLevel() ' get mouse level of slider
Slider_SetLevel() ' set slider level and move slider box
Slider_CallBack()
param = "move=True;" ' for next slider moving
Mouse_SetHandler()
Else
Program.Delay(100)
EndIf
EndWhile
param = "move=False;up=False;" ' mouse released
Mouse_SetHandler()
EndSub

Sub Slider_Remove
' Slider | Remove a slider
' param iSlider
Shapes.Remove(slider[iSlider]["oCaption"])
Shapes.Remove(slider[iSlider]["oSlit"])
Shapes.Remove(slider[iSlider]["oBox"])
Shapes.Remove(slider[iSlider]["oLevel"])
EndSub

Sub Slider_SetLevel
' Slider | Set slider level and move slider box
' param iSlider
' param level
Stack.PushValue("local", width)
x0 = slider[iSlider]["x0"]
x1 = slider[iSlider]["x1"]
y0 = slider[iSlider]["y0"]
width = x1 - x0
slider[iSlider]["level"] = level
Shapes.SetText(slider[iSlider]["oLevel"], level)
' move bar
min = slider[iSlider]["min"]
max = slider[iSlider]["max"]
mag = (level - min) / (max - min)
' move box
Shapes.Move(slider[iSlider]["oBox"], x0 + Math.Floor(width * mag) - 5, y0)
slider[iSlider]["x2"] = x0 + Math.Floor(width * mag) - 5
slider[iSlider]["x3"] = x0 + Math.Floor(width * mag) - 5 + 10
slider[iSlider]["y2"] = y0
slider[iSlider]["y3"] = y0 + 18
width = Stack.PopValue("local")
EndSub

Sub Mouse_SetHandler
' Mouse | Common event handler setting
' param["down"] - "True" if set, "False" if reset mouse event handler
' param["move"] - "True" if set, "False" if reset mouse event handler
' param["up"] - - "True" if set, "False" if reset mouse event handler
' return clicked - "False" if set MouseDown
' return moved - "False" if set MouseMove
' return released - "False" if set MouseUp
' return dmu - which handlers are set for debug
If param["down"] Then
clicked = "False"
GraphicsWindow.MouseDown = Mouse_OnDown
handler["down"] = "D"
ElseIf param["down"] = "False" Then
GraphicsWindow.MouseDown = Mouse_DoNothing
handler["down"] = ""
EndIf
If param["move"] Then
moved = "False"
GraphicsWindow.MouseMove = Mouse_OnMove
handler["move"] = "M"
ElseIf param["move"] = "False" Then
GraphicsWindow.MouseMove = Mouse_DoNothing
handler["move"] = ""
EndIf
If param["up"] Then
released = "False"
GraphicsWindow.MouseUp = Mouse_OnUp
handler["up"] = "U"
ElseIf param["up"] = "False" Then
GraphicsWindow.MouseUp = Mouse_DoNothing
handler["up"] = ""
EndIf
dmu = handler["down"] + handler["move"] + handler["up"]
If debug Then
GraphicsWindow.Title = title + " set " + dmu
EndIf
EndSub

Sub Mouse_OnDown
' Mouse | Common event handler on mouse down
' return mxD, myD - position on mouse down
mxD = GraphicsWindow.MouseX
myD = GraphicsWindow.MouseY
clicked = "True"
If debug Then
GraphicsWindow.Title = title + " clicked " + mxD + "," + myD + " " + dmu
EndIf
EndSub

Sub Mouse_DoNothing
' Mouse | Common event handler to do nothing
EndSub

Sub Mouse_OnMove
' Mouse | Common event handler on mouse move
' return mxM, myM - position on mouse move
mxM = GraphicsWindow.MouseX
myM = GraphicsWindow.MouseY
moved = "True"
If debug Then
GraphicsWindow.Title = title + " moved " + mxM + "," + myM + " " + dmu
EndIf
EndSub

Sub Mouse_OnUp
' Mouse | Common event handler on mouse up
' return mxU, myU - position on mouse up
mxU = GraphicsWindow.MouseX
myU = GraphicsWindow.MouseY
released = "True"
If debug Then
GraphicsWindow.Title = title + " released " + mxU + "," + myU + " " + dmu
EndIf
EndSub